diff --git a/OptiScaler/OptiScaler.vcxproj b/OptiScaler/OptiScaler.vcxproj
index 5a36d05d..9de465cb 100644
--- a/OptiScaler/OptiScaler.vcxproj
+++ b/OptiScaler/OptiScaler.vcxproj
@@ -518,6 +518,9 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
+
+
+
@@ -819,6 +822,7 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
+
diff --git a/OptiScaler/OptiScaler.vcxproj.filters b/OptiScaler/OptiScaler.vcxproj.filters
index 33b8a434..823faad9 100644
--- a/OptiScaler/OptiScaler.vcxproj.filters
+++ b/OptiScaler/OptiScaler.vcxproj.filters
@@ -188,6 +188,15 @@
Config
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
Header Files
@@ -1280,6 +1289,9 @@
Source Files
+
+ Source Files
+
Source Files
diff --git a/OptiScaler/shaders/auto_exposure/AE_Common.h b/OptiScaler/shaders/auto_exposure/AE_Common.h
new file mode 100644
index 00000000..95d90298
--- /dev/null
+++ b/OptiScaler/shaders/auto_exposure/AE_Common.h
@@ -0,0 +1,122 @@
+#pragma once
+
+#include "SysUtils.h"
+
+static std::string aeShader = R"(
+// Auto exposure from the log average luminance of the renderSize part of color, same as FSR2.
+// FSR3 clamps the log luma instead of the luma, which makes every pixel darker than 1 count as 1
+// and caps the exposure way too low for typical pre-exposed input.
+
+cbuffer Params : register(b0)
+{
+ uint2 RenderSize;
+ uint GroupCountX;
+ uint GroupCount;
+ float DeltaTime; // seconds
+ uint Reset;
+ uint PassIndex;
+ float PreExposure;
+};
+
+Texture2D Color : register(t0);
+// [0] smoothed log luma carried between frames, [1..] per group log luma sums
+RWStructuredBuffer Data : register(u0);
+RWTexture2D Exposure : register(u1);
+
+#define THREADS 256
+#define TILE 32
+
+static const float Epsilon = 6.10e-05f;
+static const float Fp16Max = 65504.0f;
+
+groupshared float Shared[THREADS];
+
+float LogLuma(uint2 pos)
+{
+ // Exposure is applied after FSR removes pre-exposure, so it has to be measured without it too
+ const float3 rgb = max(0.0f, Color.Load(int3(pos, 0)).rgb) / PreExposure;
+ const float luma = min(dot(rgb, float3(0.2126f, 0.7152f, 0.0722f)), Fp16Max);
+ return log(max(Epsilon, luma));
+}
+
+float GroupSum(float value, uint tid)
+{
+ Shared[tid] = value;
+ GroupMemoryBarrierWithGroupSync();
+
+ [unroll]
+ for (uint stride = THREADS / 2; stride > 0; stride >>= 1)
+ {
+ if (tid < stride)
+ Shared[tid] += Shared[tid + stride];
+
+ GroupMemoryBarrierWithGroupSync();
+ }
+
+ return Shared[0];
+}
+
+float ComputeAutoExposureFromLavg(float Lavg)
+{
+ Lavg = exp(Lavg);
+
+ const float S = 100.0f; // ISO arithmetic speed
+ const float K = 12.5f;
+ const float ExposureISO100 = log2((Lavg * S) / K);
+
+ const float q = 0.65f;
+ const float Lmax = (78.0f / (q * S)) * pow(2.0f, ExposureISO100);
+
+ return 1.0f / Lmax;
+}
+
+[numthreads(16, 16, 1)]
+void CSMain(uint3 gid : SV_GroupID, uint3 gtid : SV_GroupThreadID, uint tid : SV_GroupIndex)
+{
+ if (PassIndex == 0)
+ {
+ float sum = 0.0f;
+
+ [unroll]
+ for (uint y = 0; y < TILE; y += 16)
+ {
+ [unroll]
+ for (uint x = 0; x < TILE; x += 16)
+ {
+ const uint2 pos = gid.xy * TILE + gtid.xy + uint2(x, y);
+
+ if (all(pos < RenderSize))
+ sum += LogLuma(pos);
+ }
+ }
+
+ const float total = GroupSum(sum, tid);
+
+ if (tid == 0)
+ Data[1 + gid.y * GroupCountX + gid.x] = total;
+ }
+ else
+ {
+ float sum = 0.0f;
+
+ for (uint i = tid; i < GroupCount; i += THREADS)
+ sum += Data[1 + i];
+
+ const float total = GroupSum(sum, tid);
+
+ if (tid == 0)
+ {
+ float logLuma = total / (float(RenderSize.x) * float(RenderSize.y));
+
+ if (Reset == 0)
+ {
+ const float prevLogLuma = Data[0];
+ logLuma = prevLogLuma + (logLuma - prevLogLuma) * (1.0f - exp(-DeltaTime));
+ }
+
+ Data[0] = logLuma;
+ Exposure[uint2(0, 0)] = ComputeAutoExposureFromLavg(logLuma);
+ }
+ }
+}
+)";
diff --git a/OptiScaler/shaders/auto_exposure/AE_Dx12.cpp b/OptiScaler/shaders/auto_exposure/AE_Dx12.cpp
new file mode 100644
index 00000000..169df5dc
--- /dev/null
+++ b/OptiScaler/shaders/auto_exposure/AE_Dx12.cpp
@@ -0,0 +1,215 @@
+#include "pch.h"
+#include "AE_Dx12.h"
+
+#include "AE_Common.h"
+#include "precompile/AE_Shader.h"
+
+#include
+
+using Microsoft::WRL::ComPtr;
+
+static constexpr uint32_t AE_THREADS = 256;
+static constexpr uint32_t AE_TILE = 32;
+
+bool AE_Dx12::CreateRootSignature(ID3D12Device* InDevice)
+{
+ CD3DX12_DESCRIPTOR_RANGE1 ranges[2];
+ ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0);
+ ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 2, 0);
+
+ // Root constants, so every dispatch has its own values without a constant buffer per frame
+ CD3DX12_ROOT_PARAMETER1 rootParameters[2];
+ rootParameters[0].InitAsConstants(sizeof(InternalConstants) / sizeof(uint32_t), 0);
+ rootParameters[1].InitAsDescriptorTable(_countof(ranges), ranges);
+
+ CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSigDesc {};
+ rootSigDesc.Init_1_1(_countof(rootParameters), rootParameters);
+
+ ComPtr errorBlob;
+ ComPtr signatureBlob;
+
+ auto hr = D3D12SerializeVersionedRootSignature(&rootSigDesc, &signatureBlob, &errorBlob);
+
+ if (FAILED(hr))
+ {
+ LOG_ERROR("[{0}] D3D12SerializeVersionedRootSignature error {1:x}", _name, hr);
+ return false;
+ }
+
+ hr = InDevice->CreateRootSignature(0, signatureBlob->GetBufferPointer(), signatureBlob->GetBufferSize(),
+ IID_PPV_ARGS(&_rootSignature));
+
+ if (FAILED(hr))
+ {
+ LOG_ERROR("[{0}] CreateRootSignature error {1:x}", _name, hr);
+ return false;
+ }
+
+ return true;
+}
+
+bool AE_Dx12::EnsureDataBuffer(uint32_t InElements)
+{
+ if (_data != nullptr && _dataElements >= InElements)
+ return true;
+
+ // Previous frames can still be using it
+ DeferredRelease::Release(_data);
+ _dataElements = 0;
+ _historyValid = false;
+
+ auto heapProps = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);
+ auto desc = CD3DX12_RESOURCE_DESC::Buffer(InElements * sizeof(float), D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
+
+ auto hr = _device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc,
+ D3D12_RESOURCE_STATE_UNORDERED_ACCESS, nullptr, IID_PPV_ARGS(&_data));
+
+ if (hr != S_OK)
+ {
+ LOG_ERROR("[{0}] CreateCommittedResource error {1:x}", _name, (unsigned int) hr);
+ return false;
+ }
+
+ _data->SetName(L"AE_Data");
+ _dataElements = InElements;
+
+ return true;
+}
+
+bool AE_Dx12::Dispatch(ID3D12GraphicsCommandList* InCmdList, ID3D12Resource* InColor, uint32_t InRenderWidth,
+ uint32_t InRenderHeight, float InPreExposure, float InDeltaTimeSeconds, bool InReset)
+{
+ if (!_init || _device == nullptr || InCmdList == nullptr || InColor == nullptr || InRenderWidth == 0 ||
+ InRenderHeight == 0)
+ return false;
+
+ LOG_DEBUG("[{0}] Start!", _name);
+
+ const uint32_t groupCountX = (InRenderWidth + AE_TILE - 1) / AE_TILE;
+ const uint32_t groupCountY = (InRenderHeight + AE_TILE - 1) / AE_TILE;
+ const uint32_t groupCount = groupCountX * groupCountY;
+
+ if (!EnsureDataBuffer(groupCount + 1))
+ return false;
+
+ ScopedGpuTime_Dx12 scopedGpuTime(GpuTime.get(), InCmdList);
+
+ _counter++;
+ _counter = _counter % AE_NUM_OF_HEAPS;
+ FrameDescriptorHeap& currentHeap = _frameHeaps[_counter];
+
+ CreateShaderResourceView(_device, InColor, currentHeap.GetSrvCPU(0));
+
+ D3D12_UNORDERED_ACCESS_VIEW_DESC dataUav {};
+ dataUav.Format = DXGI_FORMAT_UNKNOWN;
+ dataUav.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
+ dataUav.Buffer.NumElements = _dataElements;
+ dataUav.Buffer.StructureByteStride = sizeof(float);
+ _device->CreateUnorderedAccessView(_data, nullptr, &dataUav, currentHeap.GetUavCPU(0));
+
+ CreateUnorderedAccessView(_device, _exposure, currentHeap.GetUavCPU(1), 0);
+
+ SetBufferState(InCmdList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, _exposure, &_exposureState);
+
+ // Previous pass 1 may still be reading the sums
+ auto dataBarrier = CD3DX12_RESOURCE_BARRIER::UAV(_data);
+ InCmdList->ResourceBarrier(1, &dataBarrier);
+
+ ID3D12DescriptorHeap* heaps[] = { currentHeap.GetHeapCSU() };
+ InCmdList->SetDescriptorHeaps(_countof(heaps), heaps);
+
+ InCmdList->SetComputeRootSignature(_rootSignature);
+ InCmdList->SetPipelineState(_pipelineState);
+ InCmdList->SetComputeRootDescriptorTable(1, currentHeap.GetTableGPUStart());
+
+ InternalConstants constants {};
+ constants.RenderWidth = InRenderWidth;
+ constants.RenderHeight = InRenderHeight;
+ constants.GroupCountX = groupCountX;
+ constants.GroupCount = groupCount;
+ constants.DeltaTime = std::clamp(InDeltaTimeSeconds, 0.0f, 1.0f);
+ constants.PreExposure = InPreExposure > 0.0f ? InPreExposure : 1.0f;
+ // Without history the scene luma is taken as is instead of adapting from a stale value
+ constants.Reset = (InReset || !_historyValid) ? 1 : 0;
+
+ // Per tile log luma sums
+ constants.PassIndex = 0;
+ InCmdList->SetComputeRoot32BitConstants(0, sizeof(constants) / sizeof(uint32_t), &constants, 0);
+ InCmdList->Dispatch(groupCountX, groupCountY, 1);
+
+ InCmdList->ResourceBarrier(1, &dataBarrier);
+
+ // Average, temporal adaptation and exposure
+ constants.PassIndex = 1;
+ InCmdList->SetComputeRoot32BitConstants(0, sizeof(constants) / sizeof(uint32_t), &constants, 0);
+ InCmdList->Dispatch(1, 1, 1);
+
+ SetBufferState(InCmdList, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, _exposure, &_exposureState);
+
+ _historyValid = true;
+
+ return true;
+}
+
+AE_Dx12::AE_Dx12(std::string InName, ID3D12Device* InDevice) : Shader_Dx12(InName, InDevice)
+{
+ if (InDevice == nullptr)
+ {
+ LOG_ERROR("InDevice is nullptr!");
+ return;
+ }
+
+ LOG_DEBUG("{0} start!", _name);
+
+ if (!CreateRootSignature(InDevice))
+ {
+ LOG_ERROR("Failed to create root signature");
+ return;
+ }
+
+ if (!CreateComputePipeline(InDevice, &_pipelineState, AE_cso, sizeof(AE_cso), aeShader.c_str()))
+ {
+ LOG_ERROR("[{0}] Failed to create compute pipeline", _name);
+ return;
+ }
+
+ auto heapProps = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);
+ auto desc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R32_FLOAT, 1, 1, 1, 1, 1, 0,
+ D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
+
+ auto hr = InDevice->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc, _exposureState, nullptr,
+ IID_PPV_ARGS(&_exposure));
+
+ if (hr != S_OK)
+ {
+ LOG_ERROR("[{0}] CreateCommittedResource error {1:x}", _name, (unsigned int) hr);
+ return;
+ }
+
+ _exposure->SetName(L"AE_Exposure");
+
+ ScopedSkipHeapCapture skipHeapCapture {};
+
+ for (int i = 0; i < AE_NUM_OF_HEAPS; i++)
+ {
+ if (!_frameHeaps[i].Initialize(InDevice, 1, 2, 0))
+ {
+ LOG_ERROR("[{0}] Failed to init heap", _name);
+ return;
+ }
+ }
+
+ _init = true;
+}
+
+AE_Dx12::~AE_Dx12()
+{
+ if (State::Instance().isShuttingDown)
+ return;
+
+ for (int i = 0; i < AE_NUM_OF_HEAPS; i++)
+ _frameHeaps[i].ReleaseHeaps();
+
+ DeferredRelease::Release(_data);
+ DeferredRelease::Release(_exposure);
+}
diff --git a/OptiScaler/shaders/auto_exposure/AE_Dx12.h b/OptiScaler/shaders/auto_exposure/AE_Dx12.h
new file mode 100644
index 00000000..13a3d40f
--- /dev/null
+++ b/OptiScaler/shaders/auto_exposure/AE_Dx12.h
@@ -0,0 +1,49 @@
+#pragma once
+#include
+#include
+#include
+#include
+
+#define AE_NUM_OF_HEAPS 2
+
+// Computes an FSR2 style auto exposure from the renderSize part of color into a 1x1 R32_FLOAT texture
+class AE_Dx12 : public Shader_Dx12
+{
+ private:
+ struct InternalConstants
+ {
+ uint32_t RenderWidth;
+ uint32_t RenderHeight;
+ uint32_t GroupCountX;
+ uint32_t GroupCount;
+ float DeltaTime;
+ uint32_t Reset;
+ uint32_t PassIndex;
+ float PreExposure;
+ };
+
+ FrameDescriptorHeap _frameHeaps[AE_NUM_OF_HEAPS];
+
+ // [0] smoothed log luma, [1..] per group sums
+ ID3D12Resource* _data = nullptr;
+ uint32_t _dataElements = 0;
+
+ ID3D12Resource* _exposure = nullptr;
+ D3D12_RESOURCE_STATES _exposureState = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
+
+ bool _historyValid = false;
+
+ bool CreateRootSignature(ID3D12Device* InDevice);
+ bool EnsureDataBuffer(uint32_t InElements);
+
+ public:
+ // Leaves Exposure() in NON_PIXEL_SHADER_RESOURCE
+ bool Dispatch(ID3D12GraphicsCommandList* InCmdList, ID3D12Resource* InColor, uint32_t InRenderWidth,
+ uint32_t InRenderHeight, float InPreExposure, float InDeltaTimeSeconds, bool InReset);
+
+ ID3D12Resource* Exposure() { return _exposure; }
+
+ AE_Dx12(std::string InName, ID3D12Device* InDevice);
+
+ ~AE_Dx12();
+};
diff --git a/OptiScaler/shaders/auto_exposure/precompile/AE.hlsl b/OptiScaler/shaders/auto_exposure/precompile/AE.hlsl
new file mode 100644
index 00000000..94a9a35f
--- /dev/null
+++ b/OptiScaler/shaders/auto_exposure/precompile/AE.hlsl
@@ -0,0 +1,116 @@
+// Auto exposure from the log average luminance of the renderSize part of color, same as FSR2.
+// FSR3 clamps the log luma instead of the luma, which makes every pixel darker than 1 count as 1
+// and caps the exposure way too low for typical pre-exposed input.
+
+cbuffer Params : register(b0)
+{
+ uint2 RenderSize;
+ uint GroupCountX;
+ uint GroupCount;
+ float DeltaTime; // seconds
+ uint Reset;
+ uint PassIndex;
+ float PreExposure;
+};
+
+Texture2D Color : register(t0);
+// [0] smoothed log luma carried between frames, [1..] per group log luma sums
+RWStructuredBuffer Data : register(u0);
+RWTexture2D Exposure : register(u1);
+
+#define THREADS 256
+#define TILE 32
+
+static const float Epsilon = 6.10e-05f;
+static const float Fp16Max = 65504.0f;
+
+groupshared float Shared[THREADS];
+
+float LogLuma(uint2 pos)
+{
+ // Exposure is applied after FSR removes pre-exposure, so it has to be measured without it too
+ const float3 rgb = max(0.0f, Color.Load(int3(pos, 0)).rgb) / PreExposure;
+ const float luma = min(dot(rgb, float3(0.2126f, 0.7152f, 0.0722f)), Fp16Max);
+ return log(max(Epsilon, luma));
+}
+
+float GroupSum(float value, uint tid)
+{
+ Shared[tid] = value;
+ GroupMemoryBarrierWithGroupSync();
+
+ [unroll]
+ for (uint stride = THREADS / 2; stride > 0; stride >>= 1)
+ {
+ if (tid < stride)
+ Shared[tid] += Shared[tid + stride];
+
+ GroupMemoryBarrierWithGroupSync();
+ }
+
+ return Shared[0];
+}
+
+float ComputeAutoExposureFromLavg(float Lavg)
+{
+ Lavg = exp(Lavg);
+
+ const float S = 100.0f; // ISO arithmetic speed
+ const float K = 12.5f;
+ const float ExposureISO100 = log2((Lavg * S) / K);
+
+ const float q = 0.65f;
+ const float Lmax = (78.0f / (q * S)) * pow(2.0f, ExposureISO100);
+
+ return 1.0f / Lmax;
+}
+
+[numthreads(16, 16, 1)]
+void CSMain(uint3 gid : SV_GroupID, uint3 gtid : SV_GroupThreadID, uint tid : SV_GroupIndex)
+{
+ if (PassIndex == 0)
+ {
+ float sum = 0.0f;
+
+ [unroll]
+ for (uint y = 0; y < TILE; y += 16)
+ {
+ [unroll]
+ for (uint x = 0; x < TILE; x += 16)
+ {
+ const uint2 pos = gid.xy * TILE + gtid.xy + uint2(x, y);
+
+ if (all(pos < RenderSize))
+ sum += LogLuma(pos);
+ }
+ }
+
+ const float total = GroupSum(sum, tid);
+
+ if (tid == 0)
+ Data[1 + gid.y * GroupCountX + gid.x] = total;
+ }
+ else
+ {
+ float sum = 0.0f;
+
+ for (uint i = tid; i < GroupCount; i += THREADS)
+ sum += Data[1 + i];
+
+ const float total = GroupSum(sum, tid);
+
+ if (tid == 0)
+ {
+ float logLuma = total / (float(RenderSize.x) * float(RenderSize.y));
+
+ if (Reset == 0)
+ {
+ const float prevLogLuma = Data[0];
+ logLuma = prevLogLuma + (logLuma - prevLogLuma) * (1.0f - exp(-DeltaTime));
+ }
+
+ Data[0] = logLuma;
+ Exposure[uint2(0, 0)] = ComputeAutoExposureFromLavg(logLuma);
+ }
+ }
+}
diff --git a/OptiScaler/shaders/auto_exposure/precompile/AE_Shader.cso b/OptiScaler/shaders/auto_exposure/precompile/AE_Shader.cso
new file mode 100644
index 00000000..5f0c3efa
Binary files /dev/null and b/OptiScaler/shaders/auto_exposure/precompile/AE_Shader.cso differ
diff --git a/OptiScaler/shaders/auto_exposure/precompile/AE_Shader.h b/OptiScaler/shaders/auto_exposure/precompile/AE_Shader.h
new file mode 100644
index 00000000..a3e8855c
--- /dev/null
+++ b/OptiScaler/shaders/auto_exposure/precompile/AE_Shader.h
@@ -0,0 +1,270 @@
+#pragma once
+
+inline static const unsigned char AE_cso[] = {
+ 0x44, 0x58, 0x42, 0x43, 0xd2, 0x6a, 0x7a, 0xda, 0xbb, 0xd6, 0x4d, 0xc4, 0xb8, 0x47, 0xc3, 0x30, 0x1f, 0x66, 0xb0,
+ 0x6d, 0x01, 0x00, 0x00, 0x00, 0xb4, 0x13, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x48, 0x00,
+ 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x3c, 0x01, 0x00, 0x00, 0x53,
+ 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x53, 0x56, 0x30, 0xb0, 0x00, 0x00, 0x00, 0x34, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+ 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x43, 0x53, 0x4d, 0x61, 0x69, 0x6e, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x0c, 0x61, 0x0f,
+ 0xc3, 0xec, 0x9f, 0x9f, 0x6a, 0x57, 0x95, 0xca, 0xfe, 0x32, 0x60, 0xf8, 0x44, 0x58, 0x49, 0x4c, 0x70, 0x12, 0x00,
+ 0x00, 0x60, 0x00, 0x05, 0x00, 0x9c, 0x04, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00,
+ 0x00, 0x00, 0x58, 0x12, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x93, 0x04, 0x00, 0x00, 0x0b,
+ 0x82, 0x20, 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, 0xe4, 0x48, 0x0e, 0x90, 0x11, 0x23, 0xc4, 0x50, 0x41,
+ 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x31, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
+ 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03,
+ 0x20, 0x6d, 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x36, 0x18, 0xc4, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x03, 0x48, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20,
+ 0x4c, 0x08, 0x86, 0x09, 0x01, 0x01, 0x00, 0x89, 0x20, 0x00, 0x00, 0x78, 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, 0xdc, 0xc1, 0x0c, 0x40, 0x02, 0x0a, 0x00, 0x83, 0x08, 0xc1, 0x30, 0x02, 0x50,
+ 0x82, 0x81, 0x88, 0x39, 0x02, 0x30, 0x28, 0x83, 0x61, 0x18, 0x74, 0x14, 0xc1, 0x30, 0x28, 0x29, 0x03, 0x60, 0x00,
+ 0xb4, 0xcc, 0x11, 0x20, 0xd4, 0xdc, 0x33, 0x5c, 0xfe, 0x84, 0x3d, 0x84, 0xe4, 0x87, 0x40, 0x33, 0x2c, 0x04, 0x0a,
+ 0x9c, 0xb2, 0x0c, 0xc6, 0x63, 0x18, 0x06, 0x00, 0x00, 0x40, 0x43, 0x50, 0x21, 0x00, 0x03, 0x00, 0x48, 0xba, 0x69,
+ 0xb8, 0xfc, 0x09, 0x7b, 0x08, 0xc9, 0x5f, 0x09, 0x69, 0x25, 0x26, 0xbf, 0xb8, 0x6d, 0x54, 0x00, 0x00, 0x00, 0x18,
+ 0x45, 0xa1, 0x8c, 0xc7, 0x30, 0x0c, 0xc3, 0x30, 0x0c, 0xaa, 0x0a, 0x02, 0x18, 0x00, 0x00, 0x00, 0x00, 0x40, 0x57,
+ 0x19, 0x06, 0xc3, 0xa0, 0xec, 0xa8, 0xe1, 0xf2, 0x27, 0xec, 0x21, 0x24, 0x9f, 0xdb, 0xa8, 0x62, 0x25, 0x26, 0xbf,
+ 0xb8, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x14, 0x62, 0x33, 0x1e, 0x83, 0xb8, 0xa3, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90,
+ 0x7c, 0x6e, 0xa3, 0x8a, 0x95, 0x98, 0x7c, 0xe4, 0xb6, 0x11, 0x61, 0x18, 0x86, 0x51, 0x08, 0xcf, 0x78, 0x0c, 0xfa,
+ 0xe6, 0x08, 0x82, 0x62, 0x3c, 0x46, 0x63, 0x18, 0x21, 0x89, 0x45, 0x19, 0x8c, 0xc7, 0x30, 0x00, 0x00, 0x00, 0x1a,
+ 0x22, 0x4b, 0x41, 0x19, 0x8f, 0x61, 0x90, 0x39, 0x10, 0x30, 0x8c, 0x40, 0x00, 0x33, 0xb5, 0xc1, 0x38, 0xb0, 0x43,
+ 0x38, 0xcc, 0xc3, 0x3c, 0xb8, 0x01, 0x2d, 0x94, 0x03, 0x3e, 0xd0, 0x43, 0x3d, 0xc8, 0x43, 0x39, 0xc8, 0x01, 0x29,
+ 0xf0, 0x81, 0x3d, 0x94, 0xc3, 0x38, 0xd0, 0xc3, 0x3b, 0xc8, 0x03, 0x1f, 0x98, 0x03, 0x3b, 0xbc, 0x43, 0x38, 0xd0,
+ 0x03, 0x1b, 0x80, 0x01, 0x1d, 0xf8, 0x01, 0x18, 0xf8, 0x81, 0x1e, 0xe8, 0x41, 0x3b, 0xa4, 0x03, 0x3c, 0xcc, 0xc3,
+ 0x2f, 0xd0, 0x43, 0x3e, 0xc0, 0x43, 0x39, 0xa0, 0xc0, 0x98, 0x49, 0x0c, 0xc6, 0x81, 0x1d, 0xc2, 0x61, 0x1e, 0xe6,
+ 0xc1, 0x0d, 0x68, 0xa1, 0x1c, 0xf0, 0x81, 0x1e, 0xea, 0x41, 0x1e, 0xca, 0x41, 0x0e, 0x48, 0x81, 0x0f, 0xec, 0xa1,
+ 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xf8, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0xd8, 0x00, 0x0c,
+ 0xe8, 0xc0, 0x0f, 0xc0, 0xc0, 0x0f, 0x90, 0x90, 0xaa, 0xb4, 0xce, 0xf4, 0x8d, 0x03, 0x3b, 0x84, 0xc3, 0x3c, 0xcc,
+ 0x83, 0x1b, 0xc8, 0xc2, 0x2d, 0xcc, 0x02, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xd4, 0x83, 0x3c, 0x94, 0x03,
+ 0x39, 0x88, 0x42, 0x3d, 0x98, 0x83, 0x39, 0x94, 0x83, 0x3c, 0xf0, 0x81, 0x39, 0xb0, 0xc3, 0x3b, 0x84, 0x03, 0x3d,
+ 0xf8, 0x01, 0x0a, 0x00, 0x6a, 0x67, 0xc2, 0xc6, 0x81, 0x1d, 0xc2, 0x61, 0x1e, 0xe6, 0xc1, 0x0d, 0x64, 0xe1, 0x16,
+ 0x68, 0xa1, 0x1c, 0xf0, 0x81, 0x1e, 0xea, 0x41, 0x1e, 0xca, 0x41, 0x0e, 0x48, 0x81, 0x0f, 0xcc, 0x81, 0x1d, 0xde,
+ 0x21, 0x1c, 0xe8, 0xc1, 0x0f, 0x50, 0x00, 0xd0, 0x3b, 0x8c, 0x20, 0x18, 0x67, 0xa4, 0x40, 0x04, 0x30, 0x12, 0x3a,
+ 0x62, 0xc3, 0x00, 0x0c, 0x03, 0x20, 0x79, 0x8e, 0x00, 0x14, 0xa6, 0x00, 0x06, 0x11, 0x80, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d,
+ 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73,
+ 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20,
+ 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07,
+ 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76,
+ 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60,
+ 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07,
+ 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x3a, 0x0f, 0x24, 0x90, 0x21, 0x23, 0x45, 0x44, 0x00, 0x76, 0x00, 0xf0, 0x90,
+ 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0xcf, 0x01, 0x04, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x9e, 0x03, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x86, 0x3c, 0x09, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x16, 0x20, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x40, 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0xe4, 0x91, 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x53, 0x01, 0x01,
+ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0xe7, 0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x21, 0x4f, 0x06, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x1e, 0x0e,
+ 0x08, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x1f, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0xc4, 0x00, 0x08, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86,
+ 0x3c, 0x64, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x1e, 0x33, 0x00, 0x02, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18,
+ 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x32, 0x4a, 0x60, 0x04, 0xa0, 0x24, 0x8a, 0xa1,
+ 0x08, 0x0a, 0xa3, 0x10, 0x0a, 0xa8, 0x40, 0x28, 0x1c, 0x01, 0x20, 0x7a, 0x04, 0xa0, 0x40, 0x08, 0x9e, 0x01, 0xa0,
+ 0x79, 0x06, 0x80, 0xdc, 0x19, 0x00, 0x62, 0x67, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x1a,
+ 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x8f, 0x0c, 0x6f, 0xec, 0xed, 0x4d, 0x0c, 0x24, 0xc6, 0x25, 0xc7, 0x45,
+ 0xc6, 0x06, 0x46, 0xc6, 0x25, 0xe6, 0x06, 0x04, 0x45, 0x26, 0x86, 0x4c, 0x06, 0xc7, 0xec, 0x46, 0xe6, 0x26, 0x65,
+ 0x43, 0x10, 0x4c, 0x10, 0x0c, 0x68, 0x82, 0x60, 0x44, 0x1b, 0x84, 0x81, 0x98, 0x20, 0x18, 0xd2, 0x06, 0x61, 0x30,
+ 0x28, 0x8c, 0xcd, 0x4d, 0x10, 0x8c, 0x69, 0xc3, 0x80, 0x24, 0xc4, 0x04, 0x81, 0x0d, 0x3e, 0x02, 0x13, 0x04, 0x83,
+ 0xda, 0x20, 0x10, 0xc6, 0x86, 0x84, 0x58, 0x18, 0x82, 0x18, 0x1a, 0xc2, 0xd9, 0x10, 0x3c, 0x13, 0x04, 0x37, 0xf0,
+ 0x26, 0x08, 0x46, 0x35, 0x41, 0x08, 0x83, 0x6c, 0x82, 0x60, 0x58, 0x1b, 0x84, 0x81, 0xda, 0xb0, 0x10, 0x11, 0x43,
+ 0x10, 0x83, 0x34, 0x4d, 0x53, 0x35, 0x41, 0x80, 0x03, 0x6e, 0xc3, 0x32, 0x5c, 0x0c, 0x31, 0x0c, 0xcd, 0x34, 0x4d,
+ 0xce, 0x06, 0xc1, 0xc2, 0x26, 0x08, 0x73, 0xd0, 0x4d, 0x10, 0x8c, 0x6b, 0x03, 0x42, 0x68, 0x0c, 0x41, 0x0c, 0x1b,
+ 0xb0, 0x21, 0xe0, 0x36, 0x10, 0x50, 0xd6, 0x01, 0x13, 0x84, 0x22, 0xa0, 0x31, 0x34, 0xd5, 0x14, 0x96, 0xe6, 0x36,
+ 0x41, 0xa0, 0x83, 0x6d, 0x82, 0x60, 0x60, 0x1b, 0x06, 0x31, 0x10, 0x83, 0x61, 0x03, 0x41, 0x84, 0x01, 0x35, 0x06,
+ 0x1b, 0x8a, 0x0f, 0x0c, 0x00, 0x8f, 0x0c, 0x58, 0x98, 0xb1, 0xbd, 0x85, 0xd1, 0xf1, 0x79, 0x6b, 0x73, 0x4b, 0x83,
+ 0x7b, 0xa3, 0x2b, 0x73, 0xa3, 0x03, 0x19, 0x43, 0x0b, 0x93, 0x63, 0x34, 0x95, 0xd6, 0x06, 0xc7, 0x56, 0x06, 0x32,
+ 0xf4, 0x32, 0xb4, 0xb2, 0x02, 0x42, 0x25, 0x14, 0x14, 0xb4, 0x21, 0x40, 0x83, 0x09, 0x02, 0x1d, 0x68, 0x1b, 0x86,
+ 0x33, 0x48, 0x03, 0x35, 0xd8, 0x30, 0x98, 0xc1, 0x1a, 0xa8, 0xc1, 0x86, 0x81, 0x0d, 0xd8, 0x40, 0x0d, 0xaa, 0xb0,
+ 0xb1, 0xd9, 0xb5, 0xb9, 0xa4, 0x91, 0x95, 0xb9, 0xd1, 0x4d, 0x09, 0x82, 0x2a, 0x64, 0x78, 0x2e, 0x76, 0x65, 0x72,
+ 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x02, 0xa2, 0x09, 0x19, 0x9e, 0x8b, 0x5d, 0x18, 0x9b, 0x5d, 0x99, 0xdc, 0x94, 0xc0,
+ 0xa8, 0x43, 0x86, 0xe7, 0x32, 0x87, 0x16, 0x46, 0x56, 0x26, 0xd7, 0xf4, 0x46, 0x56, 0xc6, 0x36, 0x25, 0x48, 0xca,
+ 0x90, 0xe1, 0xb9, 0xc8, 0x95, 0xcd, 0xbd, 0xd5, 0xc9, 0x8d, 0x95, 0xcd, 0x4d, 0x09, 0xba, 0x3a, 0x64, 0x78, 0x2e,
+ 0x65, 0x6e, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x53, 0x02, 0x32, 0x00, 0x00, 0x00, 0x79, 0x18,
+ 0x00, 0x00, 0x55, 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, 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xca, 0xc3, 0x0e,
+ 0xec, 0x60, 0x0f, 0xed, 0xe0, 0x06, 0xec, 0xf0, 0x0e, 0xef, 0x00, 0x0f, 0x33, 0x22, 0x88, 0x1c, 0xf0, 0xc1, 0x0d,
+ 0xc8, 0x41, 0x1c, 0xce, 0xc1, 0x0d, 0xec, 0x21, 0x1c, 0xe4, 0x81, 0x1d, 0xc2, 0x21, 0x1f, 0xde, 0xa1, 0x1e, 0xe8,
+ 0x61, 0x06, 0x13, 0x91, 0x03, 0x3e, 0xb8, 0x81, 0x38, 0xc8, 0x43, 0x39, 0x84, 0xc3, 0x3a, 0xb8, 0x81, 0x38, 0xc8,
+ 0x03, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x05, 0xf0, 0x04, 0x7e, 0x53, 0x74, 0x58,
+ 0x5e, 0x26, 0x03, 0x81, 0x33, 0x68, 0xb0, 0x19, 0xb4, 0x00, 0x83, 0x63, 0x4d, 0x00, 0x69, 0x4c, 0xa1, 0x19, 0x2e,
+ 0xdf, 0x79, 0xfc, 0x00, 0x88, 0x22, 0x84, 0x88, 0xec, 0x00, 0x1a, 0x2e, 0xdf, 0x79, 0xfc, 0x00, 0x69, 0x80, 0x08,
+ 0xf3, 0x8b, 0xdb, 0xb6, 0x07, 0x6a, 0xb8, 0x7c, 0xe7, 0xf1, 0x03, 0xaa, 0x28, 0x88, 0xa8, 0x74, 0x80, 0xc1, 0x2f,
+ 0x6e, 0xdb, 0x1c, 0xaa, 0xe1, 0xf2, 0x9d, 0xc7, 0x0f, 0xa8, 0xa2, 0x20, 0x22, 0x76, 0x72, 0x22, 0xc2, 0x2f, 0x6e,
+ 0xdb, 0x16, 0xb6, 0xe1, 0xf2, 0x9d, 0xc7, 0x17, 0x02, 0xaa, 0x28, 0x88, 0xa8, 0x74, 0x80, 0xa1, 0x24, 0x0c, 0x40,
+ 0xc0, 0xfc, 0xe2, 0xb6, 0x8d, 0x61, 0x1b, 0x2e, 0xdf, 0x79, 0x7c, 0x21, 0xa0, 0x8a, 0x82, 0x88, 0x4a, 0x07, 0x18,
+ 0x4a, 0xc2, 0x00, 0x04, 0xcc, 0x47, 0x6e, 0xdb, 0x1a, 0xa4, 0xe1, 0xf2, 0x9d, 0xc7, 0x17, 0x22, 0x02, 0x98, 0x88,
+ 0x10, 0x68, 0x86, 0x85, 0xb0, 0x04, 0x67, 0xb8, 0x7c, 0xe7, 0xf1, 0x07, 0x67, 0xba, 0xfd, 0xe2, 0xb6, 0x8d, 0x40,
+ 0x0c, 0x86, 0xcb, 0x77, 0x1e, 0xbf, 0x58, 0x80, 0x69, 0x22, 0x1a, 0x62, 0x68, 0x8f, 0x88, 0x00, 0x06, 0x71, 0x10,
+ 0x1b, 0x30, 0x72, 0xa8, 0xc7, 0x47, 0x6e, 0xdb, 0x04, 0xa2, 0xe1, 0xf2, 0x9d, 0xc7, 0x37, 0x22, 0x87, 0x7a, 0xc4,
+ 0xc1, 0x47, 0x6e, 0xdb, 0x10, 0xaa, 0xe1, 0xf2, 0x9d, 0xc7, 0x9f, 0x88, 0x6b, 0xa2, 0x22, 0xa2, 0x74, 0x80, 0xc1,
+ 0x2f, 0x6e, 0xdb, 0x0c, 0xac, 0xe1, 0xf2, 0x9d, 0xc7, 0x9f, 0x88, 0x6b, 0xa2, 0x22, 0x82, 0x9d, 0x9c, 0x88, 0xf0,
+ 0x8b, 0xdb, 0xb6, 0x81, 0x6c, 0xb8, 0x7c, 0xe7, 0xf1, 0xa7, 0x23, 0x22, 0x80, 0x41, 0x1c, 0xc4, 0x06, 0x8c, 0x1c,
+ 0xea, 0xf1, 0x91, 0xdb, 0xb6, 0x82, 0x67, 0xb8, 0x7c, 0xe7, 0xf1, 0xa9, 0x06, 0x88, 0x30, 0xbf, 0xb8, 0x6d, 0x00,
+ 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x8e, 0x02, 0x00, 0x00, 0x13, 0x04, 0x74, 0x10, 0x0b, 0x04, 0x00, 0x00,
+ 0x25, 0x00, 0x00, 0x00, 0xd4, 0x94, 0x47, 0x11, 0x8c, 0x00, 0x94, 0x00, 0x19, 0x65, 0x18, 0x50, 0x80, 0x04, 0x05,
+ 0x1c, 0x50, 0x88, 0x01, 0xa5, 0x18, 0x50, 0x0a, 0xe5, 0x1b, 0x50, 0xbc, 0x01, 0xa5, 0x52, 0xa0, 0x01, 0x33, 0x00,
+ 0x65, 0x54, 0x76, 0xe5, 0x52, 0x72, 0x45, 0x18, 0x50, 0x6e, 0x85, 0x54, 0x80, 0x02, 0x05, 0x18, 0x50, 0x10, 0x04,
+ 0x8c, 0x11, 0xd4, 0x6a, 0xad, 0xd6, 0xdf, 0x18, 0x01, 0x08, 0x82, 0x20, 0x0c, 0x06, 0x63, 0x04, 0x7b, 0xac, 0xc6,
+ 0xfb, 0x37, 0x46, 0x00, 0x82, 0x20, 0x88, 0x7f, 0x63, 0x04, 0x7b, 0xac, 0xc6, 0xfb, 0x2f, 0x8c, 0x11, 0xe0, 0x30,
+ 0x2f, 0xce, 0xdf, 0x18, 0x01, 0x28, 0xdb, 0xff, 0xc9, 0x8d, 0x11, 0x80, 0x20, 0xfe, 0xdf, 0x63, 0x30, 0x46, 0x80,
+ 0xb3, 0xf7, 0x99, 0x7b, 0x63, 0x04, 0xb9, 0x5e, 0xba, 0xf3, 0x37, 0x46, 0x00, 0xfb, 0xec, 0x5c, 0x7e, 0x33, 0x00,
+ 0x23, 0x00, 0x64, 0x0f, 0x75, 0x04, 0x02, 0x60, 0x44, 0x46, 0x34, 0xd4, 0x11, 0x08, 0x80, 0x11, 0x19, 0x10, 0x00,
+ 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x20, 0x06, 0x7b, 0x60, 0x95, 0x01, 0x1e, 0xe0, 0xc1, 0x1b, 0x8c, 0x18, 0x24,
+ 0x00, 0x08, 0x82, 0x81, 0x18, 0xf0, 0xc1, 0x65, 0x06, 0x78, 0x80, 0x07, 0x70, 0x30, 0x62, 0x90, 0x00, 0x20, 0x08,
+ 0x06, 0x62, 0xd0, 0x07, 0x18, 0x1a, 0xe4, 0x41, 0x1e, 0xc4, 0xc1, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x88, 0x81,
+ 0x1f, 0x64, 0x6a, 0xa0, 0x07, 0x7a, 0x20, 0x07, 0x23, 0x06, 0x06, 0x00, 0x82, 0x60, 0x70, 0xa8, 0x42, 0x18, 0xec,
+ 0xc1, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x1c, 0xab, 0x20, 0x06, 0x7d, 0x30, 0x62, 0x50, 0x00, 0x20, 0x08, 0x06,
+ 0x89, 0x2a, 0xa0, 0xc1, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x7c, 0xa3, 0xf0, 0x11, 0x7f, 0x30, 0x9a, 0x10, 0x08,
+ 0xc3, 0x0d, 0x01, 0x28, 0x80, 0xc1, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x7c, 0xa6, 0x20, 0x06, 0x47, 0x28, 0xcc,
+ 0x32, 0x04, 0x9b, 0x30, 0x62, 0x60, 0x00, 0x20, 0x08, 0x06, 0x07, 0x2c, 0xa4, 0xc1, 0x28, 0x8c, 0x18, 0x18, 0x00,
+ 0x08, 0x82, 0xc1, 0x11, 0x0b, 0x6a, 0x30, 0x0a, 0x95, 0xb0, 0xc1, 0x55, 0xd2, 0x06, 0x57, 0x83, 0x00, 0x55, 0x08,
+ 0x30, 0x9a, 0x70, 0x00, 0xa3, 0x09, 0x48, 0x30, 0xdc, 0x40, 0x08, 0x64, 0x30, 0xdc, 0x40, 0x08, 0x64, 0x50, 0x42,
+ 0xa0, 0xb3, 0x0c, 0xc2, 0x10, 0x8c, 0x18, 0x34, 0x00, 0x08, 0x82, 0x41, 0x65, 0x0b, 0x6b, 0x40, 0xb5, 0xc2, 0x61,
+ 0xc0, 0x01, 0x1c, 0xc0, 0x01, 0x1c, 0x8c, 0x26, 0x04, 0xc0, 0x68, 0x82, 0x10, 0x8c, 0x26, 0x0c, 0xc2, 0x88, 0xc1,
+ 0x01, 0x80, 0x20, 0x18, 0x48, 0xbb, 0x30, 0x07, 0xdd, 0x30, 0x62, 0x70, 0x00, 0x20, 0x08, 0x06, 0x12, 0x2f, 0xd0,
+ 0x81, 0x37, 0x8c, 0x18, 0x1c, 0x00, 0x08, 0x82, 0x81, 0xd4, 0x0b, 0x75, 0xf0, 0x0d, 0x23, 0x06, 0x07, 0x00, 0x82,
+ 0x60, 0xc0, 0xe9, 0x42, 0x1d, 0x68, 0xb5, 0x30, 0x9a, 0x10, 0x0c, 0x56, 0x04, 0xf4, 0xb1, 0x42, 0xa0, 0x8f, 0x15,
+ 0x03, 0x7d, 0x46, 0x0c, 0x16, 0x00, 0x04, 0xc1, 0xe0, 0x0a, 0x07, 0x3b, 0x18, 0x84, 0xe0, 0x0c, 0xd0, 0x20, 0x0d,
+ 0x46, 0x0c, 0x0e, 0x00, 0x04, 0xc1, 0x40, 0x22, 0x07, 0x3b, 0x08, 0xd6, 0x60, 0xc4, 0xe0, 0x00, 0x40, 0x10, 0x0c,
+ 0xa4, 0x72, 0xe8, 0x83, 0x36, 0x08, 0x46, 0x0c, 0x0c, 0x00, 0x04, 0xc1, 0x60, 0x41, 0x07, 0x3e, 0x08, 0x2c, 0x80,
+ 0x03, 0xf9, 0xcc, 0x12, 0x0c, 0x03, 0x15, 0x80, 0x20, 0xd0, 0x42, 0x50, 0x19, 0x2e, 0xc0, 0x70, 0x43, 0x80, 0x91,
+ 0x41, 0x05, 0x96, 0xce, 0x32, 0x10, 0x45, 0x30, 0x62, 0xd0, 0x00, 0x20, 0x08, 0x06, 0xd5, 0x3a, 0x80, 0x42, 0x1a,
+ 0x88, 0xc3, 0xb0, 0x95, 0x42, 0x29, 0x94, 0x42, 0x29, 0x8c, 0x26, 0x04, 0xc0, 0x68, 0x82, 0x10, 0x8c, 0x26, 0x0c,
+ 0xc2, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x48, 0xf0, 0x80, 0x0a, 0x72, 0x30, 0x8c, 0x18, 0x1c, 0x00, 0x08, 0x82,
+ 0x81, 0x14, 0x0f, 0xa9, 0x30, 0x07, 0xc3, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x48, 0xf2, 0xa0, 0x0a, 0x74, 0x30,
+ 0x8c, 0x18, 0x1c, 0x00, 0x08, 0x82, 0x01, 0xf7, 0x0e, 0xaa, 0xf0, 0x06, 0xea, 0x30, 0x9a, 0x10, 0x0c, 0x56, 0x04,
+ 0xf4, 0xb1, 0x42, 0xa0, 0x8f, 0x15, 0x03, 0x7d, 0x46, 0x0c, 0x16, 0x00, 0x04, 0xc1, 0xe0, 0xb2, 0x87, 0x55, 0x18,
+ 0x84, 0x80, 0x0f, 0xfa, 0xc0, 0x0f, 0x46, 0x0c, 0x0e, 0x00, 0x04, 0xc1, 0x40, 0xca, 0x87, 0x55, 0x08, 0x40, 0x61,
+ 0xc4, 0xe0, 0x00, 0x40, 0x10, 0x0c, 0x24, 0x7d, 0x90, 0x05, 0x51, 0x08, 0x46, 0x0c, 0x0c, 0x00, 0x04, 0xc1, 0x60,
+ 0xe9, 0x87, 0x58, 0x08, 0x2c, 0x28, 0x05, 0xf9, 0x58, 0x50, 0xc1, 0x67, 0x96, 0xa0, 0x18, 0xa8, 0x00, 0x04, 0x82,
+ 0x0d, 0x86, 0x72, 0x03, 0x77, 0x80, 0xe1, 0x86, 0xa0, 0x0d, 0xc8, 0xa0, 0xda, 0x20, 0xd0, 0x59, 0x06, 0xe3, 0x08,
+ 0x46, 0x0c, 0x1a, 0x00, 0x04, 0xc1, 0xa0, 0x0a, 0x09, 0x5b, 0xf8, 0x03, 0x7c, 0x90, 0x83, 0x61, 0x17, 0x76, 0x61,
+ 0x17, 0x76, 0x61, 0x34, 0x21, 0x00, 0x46, 0x13, 0x84, 0x60, 0x34, 0x61, 0x10, 0x46, 0x0c, 0x0e, 0x00, 0x04, 0xc1,
+ 0x40, 0x32, 0x09, 0x5f, 0x40, 0x85, 0x61, 0xc4, 0xe0, 0x00, 0x40, 0x10, 0x0c, 0xa4, 0x93, 0xf8, 0x85, 0x54, 0x18,
+ 0x46, 0x0c, 0x0e, 0x00, 0x04, 0xc1, 0x40, 0x42, 0x09, 0x70, 0x50, 0x85, 0x61, 0xc4, 0xe0, 0x00, 0x40, 0x10, 0x0c,
+ 0xb8, 0x92, 0x00, 0x87, 0x52, 0x00, 0x89, 0xd1, 0x84, 0x60, 0xb0, 0x22, 0xa0, 0x8f, 0x15, 0x02, 0x7d, 0xac, 0x18,
+ 0xe8, 0x33, 0x62, 0xb0, 0x00, 0x20, 0x08, 0x06, 0x17, 0x4b, 0x84, 0xc3, 0x20, 0x04, 0xb2, 0x30, 0x0b, 0xb4, 0x30,
+ 0x62, 0x70, 0x00, 0x20, 0x08, 0x06, 0xd2, 0x4b, 0x84, 0x43, 0x60, 0x0b, 0x23, 0x06, 0x07, 0x00, 0x82, 0x60, 0x20,
+ 0xc1, 0x04, 0x3a, 0xe0, 0x42, 0x30, 0x62, 0x60, 0x00, 0x20, 0x08, 0x06, 0xcb, 0x4c, 0x9c, 0x43, 0x60, 0xc1, 0x2e,
+ 0xc8, 0xc7, 0x82, 0x0a, 0x3e, 0xb3, 0x04, 0xc7, 0x40, 0x05, 0x20, 0x18, 0x6c, 0x50, 0xd4, 0x1a, 0x54, 0x3a, 0xcb,
+ 0x80, 0x24, 0xc1, 0x88, 0x41, 0x03, 0x80, 0x20, 0x18, 0x54, 0x35, 0xa1, 0x0e, 0xb3, 0xc0, 0x12, 0x6d, 0x70, 0xbd,
+ 0xc3, 0x3b, 0xbc, 0xc3, 0x3b, 0x8c, 0x26, 0x04, 0xc0, 0x68, 0x82, 0x10, 0x8c, 0x26, 0x0c, 0xc2, 0x88, 0xc1, 0x01,
+ 0x80, 0x20, 0x18, 0x48, 0x3a, 0x21, 0x0f, 0xbc, 0x30, 0x8c, 0x18, 0x1c, 0x00, 0x08, 0x82, 0x81, 0xb4, 0x13, 0xf3,
+ 0xd0, 0x0b, 0xc3, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x48, 0x3c, 0x41, 0x0f, 0xbe, 0x30, 0x8c, 0x18, 0x1c, 0x00,
+ 0x08, 0x82, 0x01, 0x97, 0x13, 0xf4, 0x90, 0x0b, 0x34, 0x31, 0x9a, 0x10, 0x0c, 0x56, 0x04, 0xf4, 0xb1, 0x42, 0xa0,
+ 0x8f, 0x15, 0x03, 0x7d, 0x46, 0x0c, 0x16, 0x00, 0x04, 0xc1, 0xe0, 0x02, 0x8b, 0x7a, 0x18, 0x84, 0xc0, 0x1c, 0xce,
+ 0x01, 0x1d, 0x46, 0x0c, 0x0e, 0x00, 0x04, 0xc1, 0x40, 0x1a, 0x8b, 0x7a, 0x08, 0xd4, 0x61, 0xc4, 0xe0, 0x00, 0x40,
+ 0x10, 0x0c, 0x24, 0xb2, 0xe0, 0x07, 0x76, 0x08, 0x46, 0x0c, 0x0c, 0x00, 0x04, 0xc1, 0x60, 0x39, 0x8b, 0x7d, 0x08,
+ 0x2c, 0x78, 0x07, 0xf9, 0x58, 0x30, 0xc1, 0x67, 0x96, 0x20, 0x19, 0xa8, 0x00, 0x04, 0x04, 0x0d, 0x8e, 0x15, 0x0c,
+ 0x70, 0xf1, 0x13, 0xe2, 0x30, 0x6c, 0x40, 0x04, 0xc2, 0x00, 0x8c, 0x18, 0x18, 0x00, 0x08, 0x82, 0x41, 0x76, 0x16,
+ 0x24, 0xf1, 0x13, 0xc3, 0x0d, 0xe3, 0xb0, 0x0f, 0x64, 0x30, 0xcb, 0xa0, 0x2c, 0x41, 0x91, 0x03, 0x3f, 0xc0, 0x0a,
+ 0x86, 0xb9, 0x10, 0x8b, 0x80, 0x02, 0x60, 0x50, 0x01, 0x0c, 0x0b, 0x04, 0xf8, 0x0c, 0x1b, 0x10, 0x47, 0x30, 0x00,
+ 0xb3, 0x04, 0xcb, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x64, 0x6d, 0xa1, 0x12, 0x65, 0x31, 0xdc, 0x90, 0x0e, 0x20,
+ 0x41, 0x06, 0xb3, 0x0c, 0x4c, 0x13, 0x94, 0x3a, 0x84, 0x04, 0xac, 0x60, 0xc8, 0x0b, 0xb4, 0x08, 0x28, 0x00, 0x06,
+ 0x2d, 0xc0, 0xb0, 0x40, 0x80, 0xcf, 0xb0, 0x01, 0xd1, 0x04, 0x03, 0x30, 0x4b, 0xd0, 0x8c, 0x18, 0x18, 0x00, 0x08,
+ 0x82, 0x41, 0x36, 0x17, 0x30, 0xb1, 0x16, 0xc3, 0x0d, 0xef, 0x60, 0x16, 0x64, 0x30, 0xcb, 0xe0, 0x3c, 0x41, 0xc1,
+ 0xc3, 0x59, 0xc0, 0x0a, 0x86, 0xbf, 0x70, 0x8b, 0x80, 0x02, 0x60, 0x50, 0x04, 0x0c, 0x0b, 0x04, 0xf8, 0x0c, 0x1b,
+ 0x10, 0x53, 0x30, 0x00, 0xb3, 0x04, 0xcf, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x64, 0x79, 0x61, 0x13, 0x71, 0x31,
+ 0xdc, 0x50, 0x0f, 0x6b, 0x41, 0x06, 0xb3, 0x0c, 0x50, 0x14, 0x94, 0x3d, 0xb0, 0x05, 0xac, 0x60, 0x28, 0x0d, 0xba,
+ 0x08, 0x28, 0x00, 0x06, 0x5d, 0xc0, 0xb0, 0x40, 0x80, 0xcf, 0xb0, 0x01, 0x91, 0x05, 0x03, 0x30, 0x4b, 0x10, 0x8d,
+ 0x18, 0x18, 0x00, 0x08, 0x82, 0x41, 0xf6, 0x17, 0x3c, 0x71, 0x17, 0xc3, 0x0d, 0xfb, 0x10, 0x13, 0x64, 0x30, 0xcb,
+ 0x20, 0x4d, 0x41, 0xf1, 0x83, 0x4c, 0xc0, 0x0a, 0x86, 0xd5, 0xd0, 0x8b, 0x80, 0x02, 0x60, 0x50, 0x07, 0x0c, 0x0b,
+ 0x04, 0xf8, 0x0c, 0x1b, 0x10, 0x5f, 0x30, 0x00, 0xb3, 0x04, 0xd3, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x64, 0xa5,
+ 0x21, 0x16, 0x7d, 0x31, 0xdc, 0x10, 0x12, 0x79, 0x41, 0x06, 0xb3, 0x0c, 0x54, 0x15, 0x94, 0x48, 0xe8, 0x05, 0xac,
+ 0x60, 0x88, 0x0d, 0xd0, 0x08, 0x28, 0x00, 0x06, 0x8d, 0x01, 0x30, 0x2c, 0x10, 0xe0, 0x33, 0x6c, 0x40, 0x94, 0x41,
+ 0x30, 0x00, 0xb3, 0x04, 0xd5, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x64, 0xab, 0x81, 0x16, 0xa3, 0x31, 0xdc, 0x70,
+ 0x12, 0xa1, 0x41, 0x06, 0xb3, 0x0c, 0xd6, 0x15, 0x14, 0x4a, 0x88, 0x06, 0xac, 0x60, 0xb8, 0x0d, 0xd3, 0x08, 0x28,
+ 0x00, 0x06, 0xa5, 0x01, 0x30, 0x2c, 0x10, 0xe0, 0x33, 0x6c, 0x40, 0xac, 0x41, 0x30, 0x00, 0xb3, 0x04, 0xd7, 0x88,
+ 0x81, 0x01, 0x80, 0x20, 0x18, 0x64, 0xb1, 0xe1, 0x16, 0xa9, 0x31, 0xdc, 0xd0, 0x12, 0xaa, 0x01, 0x06, 0xb3, 0x0c,
+ 0x58, 0x16, 0x50, 0x4d, 0x00, 0x83, 0x6e, 0x02, 0x18, 0x16, 0x08, 0xf0, 0x19, 0x36, 0x20, 0x72, 0x22, 0x18, 0x80,
+ 0x59, 0x82, 0x6c, 0xa0, 0x22, 0x0c, 0x10, 0x8c, 0x65, 0xae, 0x11, 0x03, 0x03, 0x00, 0x41, 0x30, 0xc8, 0x6c, 0x63,
+ 0x2e, 0x5c, 0x63, 0x96, 0x41, 0x9b, 0x83, 0x80, 0x74, 0x02, 0x18, 0x23, 0x06, 0x07, 0x00, 0x82, 0x60, 0xf0, 0xd5,
+ 0x46, 0x5c, 0xd8, 0x04, 0x6c, 0x8c, 0x26, 0x04, 0x42, 0x05, 0x36, 0x21, 0x85, 0x13, 0xb4, 0x01, 0x15, 0x08, 0x30,
+ 0x62, 0xd0, 0x00, 0x20, 0x08, 0x06, 0x64, 0x80, 0x1b, 0x7e, 0xd1, 0x13, 0x41, 0x6d, 0x18, 0x62, 0x21, 0x16, 0x62,
+ 0x31, 0x1a, 0xb3, 0x04, 0x73, 0x30, 0x9a, 0x40, 0x13, 0xc3, 0x70, 0x43, 0x4e, 0x04, 0x64, 0x30, 0xcb, 0xc0, 0x7d,
+ 0xc1, 0x2c, 0x41, 0x37, 0x50, 0x01, 0x2c, 0x9d, 0xa9, 0x70, 0x03, 0x15, 0xc6, 0xd2, 0xd9, 0x09, 0x57, 0x81, 0x6e,
+ 0xc0, 0x88, 0x01, 0x02, 0x80, 0x20, 0x18, 0x98, 0x01, 0x6f, 0x90, 0x86, 0x58, 0x04, 0xba, 0x31, 0x9a, 0x10, 0x00,
+ 0x16, 0x14, 0xf0, 0xa9, 0x22, 0x35, 0x60, 0xc4, 0xe0, 0x00, 0x40, 0x10, 0x0c, 0xbe, 0xf1, 0xf8, 0x0b, 0xb2, 0xf0,
+ 0x8d, 0xd1, 0x84, 0x60, 0x18, 0x6e, 0x18, 0x02, 0x32, 0x98, 0x65, 0xe8, 0xbc, 0x60, 0x96, 0xe0, 0x1b, 0xa8, 0x00,
+ 0x74, 0x65, 0x53, 0xbc, 0x15, 0x0c, 0xf3, 0x21, 0x1e, 0x65, 0x31, 0x6c, 0x40, 0x04, 0xc2, 0x00, 0x8c, 0x18, 0x18,
+ 0x00, 0x08, 0x82, 0x41, 0xa6, 0x1e, 0xa7, 0x21, 0x1e, 0xc3, 0x0d, 0x66, 0xe1, 0x17, 0x64, 0x30, 0xcb, 0x00, 0x06,
+ 0x61, 0x10, 0xd4, 0x59, 0xfc, 0x05, 0xac, 0x60, 0xb0, 0x8f, 0xf2, 0x08, 0x28, 0x00, 0x06, 0x15, 0xc0, 0xb0, 0x40,
+ 0x80, 0xcf, 0xb0, 0x01, 0x71, 0x04, 0x03, 0x30, 0x4b, 0x10, 0x06, 0x23, 0x06, 0x06, 0x00, 0x82, 0x60, 0x90, 0xc1,
+ 0x47, 0x6b, 0xa0, 0xc7, 0x70, 0x03, 0x5b, 0x8c, 0x06, 0x19, 0xcc, 0x32, 0x88, 0xc1, 0x18, 0x04, 0xd5, 0x16, 0xa4,
+ 0x01, 0x2b, 0x18, 0xf8, 0x63, 0x3d, 0x02, 0x0a, 0x80, 0x41, 0x0b, 0x30, 0x2c, 0x10, 0xe0, 0x33, 0x6c, 0x40, 0x34,
+ 0xc1, 0x00, 0xcc, 0x12, 0x8c, 0xc1, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x64, 0xf6, 0x31, 0x1b, 0xee, 0x31, 0xdc,
+ 0x20, 0x17, 0xe9, 0x41, 0x06, 0xb3, 0x0c, 0x64, 0x50, 0x06, 0x41, 0xcd, 0x85, 0x7a, 0xc0, 0x0a, 0x06, 0x11, 0x89,
+ 0x8f, 0x80, 0x02, 0x60, 0x50, 0x04, 0x0c, 0x0b, 0x04, 0xf8, 0x0c, 0x1b, 0x10, 0x53, 0x30, 0x00, 0xb3, 0x04, 0x65,
+ 0x30, 0x62, 0x60, 0x00, 0x20, 0x08, 0x06, 0x19, 0x7f, 0xe4, 0x06, 0x7d, 0x0c, 0x37, 0xe0, 0x85, 0x7b, 0x90, 0xc1,
+ 0x2c, 0x83, 0x19, 0x9c, 0x41, 0x50, 0x79, 0xf1, 0x1e, 0xb0, 0x82, 0x01, 0x45, 0xee, 0x23, 0xa0, 0x00, 0x18, 0x74,
+ 0x01, 0xc3, 0x02, 0x01, 0x3e, 0xc3, 0x06, 0x44, 0x16, 0x0c, 0xc0, 0x2c, 0xc1, 0x19, 0x8c, 0x18, 0x18, 0x00, 0x08,
+ 0x82, 0x41, 0x26, 0x22, 0xbf, 0xa1, 0x1f, 0xc3, 0x0d, 0x7e, 0x41, 0x1b, 0x64, 0x30, 0xcb, 0x80, 0x06, 0x69, 0x10,
+ 0xd4, 0x5f, 0xd4, 0x06, 0xac, 0x60, 0x70, 0x91, 0xfe, 0x08, 0x28, 0x00, 0x06, 0x75, 0xc0, 0xb0, 0x40, 0x80, 0xcf,
+ 0xb0, 0x01, 0xf1, 0x05, 0x03, 0x30, 0x4b, 0x90, 0x06, 0x23, 0x06, 0x06, 0x00, 0x82, 0x60, 0x90, 0xa1, 0x48, 0x79,
+ 0x80, 0xc8, 0x70, 0x03, 0x69, 0xf0, 0x07, 0x19, 0xcc, 0x32, 0xa8, 0xc1, 0x1a, 0x04, 0x55, 0x1a, 0xfd, 0x01, 0x2b,
+ 0x18, 0x68, 0x64, 0x44, 0x02, 0x0a, 0x80, 0x41, 0x63, 0x00, 0x0c, 0x0b, 0x04, 0xf8, 0x0c, 0x1b, 0x10, 0x65, 0x10,
+ 0x0c, 0xc0, 0x2c, 0xc1, 0x1a, 0x8c, 0x18, 0x18, 0x00, 0x08, 0x82, 0x41, 0xe6, 0x22, 0xeb, 0x61, 0x22, 0xc3, 0x0d,
+ 0xaa, 0x41, 0x22, 0x64, 0x30, 0xcb, 0xc0, 0x06, 0x6d, 0x10, 0xd4, 0x6a, 0x94, 0x08, 0xac, 0x60, 0xd0, 0x91, 0x14,
+ 0x09, 0x28, 0x00, 0x06, 0xa5, 0x01, 0x30, 0x2c, 0x10, 0xe0, 0x33, 0x6c, 0x40, 0xac, 0x41, 0x30, 0x00, 0xb3, 0x04,
+ 0x6d, 0x30, 0x62, 0x60, 0x00, 0x20, 0x08, 0x06, 0x19, 0x8d, 0xc4, 0x07, 0x8b, 0x0c, 0x37, 0xc0, 0x46, 0x8b, 0x80,
+ 0xc1, 0x2c, 0x83, 0x1b, 0xbc, 0x41, 0x40, 0xb8, 0x01, 0x0c, 0xd2, 0x0d, 0x60, 0x58, 0x20, 0xc0, 0x67, 0xd8, 0x80,
+ 0xe0, 0x8d, 0x60, 0x00, 0x66, 0x09, 0xde, 0x60, 0xa0, 0x22, 0x0c, 0x10, 0x37, 0x90, 0xa1, 0x36, 0x18, 0x31, 0x30,
+ 0x00, 0x10, 0x04, 0x83, 0x2c, 0x47, 0xec, 0x23, 0x46, 0x66, 0x19, 0xe0, 0x60, 0x0e, 0x02, 0xea, 0x0d, 0x60, 0x8c,
+ 0x18, 0x1c, 0x00, 0x08, 0x82, 0xc1, 0x87, 0x23, 0xf4, 0x91, 0x1b, 0x33, 0x32, 0x9a, 0x10, 0x00, 0x17, 0x00, 0x35,
+ 0x9a, 0x30, 0x04, 0x17, 0x00, 0x65, 0xc1, 0x20, 0x1f, 0x3b, 0x02, 0xfa, 0x8c, 0x18, 0x1c, 0x00, 0x08, 0x82, 0xc1,
+ 0xf7, 0x23, 0xfb, 0x01, 0x1e, 0x3b, 0x32, 0x9a, 0x10, 0x04, 0xc3, 0x0d, 0x01, 0x8f, 0x80, 0xc1, 0x2c, 0x43, 0x1c,
+ 0xc8, 0x41, 0x30, 0x62, 0x80, 0x00, 0x20, 0x08, 0x06, 0x66, 0xf0, 0x23, 0x27, 0x52, 0x1e, 0x3d, 0xd2, 0x23, 0xa3,
+ 0x09, 0x01, 0x60, 0x46, 0x10, 0x9f, 0x11, 0x83, 0x03, 0x00, 0x41, 0x30, 0xe0, 0xcc, 0x24, 0x44, 0xcc, 0x23, 0x4c,
+ 0x46, 0x13, 0x02, 0xc0, 0x02, 0xfb, 0x90, 0xcf, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x2c, 0x6f, 0x82, 0x22, 0x81,
+ 0xe5, 0x47, 0x10, 0x1f, 0x0b, 0x0c, 0xf9, 0x58, 0x80, 0xc0, 0x67, 0x96, 0x40, 0x0e, 0x06, 0x2a, 0x00, 0x21, 0x0e,
+ 0x38, 0x38, 0x18, 0x31, 0x68, 0x00, 0x10, 0x04, 0x03, 0x32, 0x58, 0x93, 0x18, 0x81, 0x0f, 0x34, 0x41, 0x93, 0xa0,
+ 0x3e, 0xea, 0xa3, 0x3e, 0x6c, 0xc4, 0x02, 0xff, 0x90, 0xcf, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x2c, 0x75, 0xe2,
+ 0x22, 0x81, 0x05, 0x21, 0x22, 0x9f, 0x11, 0x03, 0x03, 0x00, 0x41, 0x30, 0x58, 0xee, 0x64, 0x45, 0x82, 0x11, 0x03,
+ 0x03, 0x00, 0x41, 0x30, 0x58, 0xf0, 0x24, 0x46, 0x02, 0x2b, 0x91, 0x80, 0x3e, 0x23, 0x06, 0x0e, 0x00, 0x82, 0x60,
+ 0x00, 0xe5, 0xc9, 0x8e, 0xdc, 0x87, 0x9b, 0xb8, 0x49, 0x8c, 0x04, 0x41, 0x10, 0xfc, 0xc8, 0x2c, 0xc1, 0x1c, 0x60,
+ 0x40, 0x0c, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x5b, 0x06, 0x79, 0x08, 0xd8, 0x60, 0xcb, 0x80, 0x0f, 0x01,
+ 0x1b, 0x6c, 0x19, 0xf2, 0x21, 0x60, 0x83, 0x2d, 0xc3, 0x3e, 0x04, 0x6c, 0xb0, 0x65, 0x10, 0x89, 0x80, 0x0d, 0xb6,
+ 0x0c, 0x23, 0x11, 0xb0, 0xc1, 0x96, 0xa1, 0x24, 0x02, 0x36, 0xd8, 0x32, 0xb0, 0x44, 0xc0, 0x06, 0x5b, 0x86, 0x96,
+ 0x08, 0xd8, 0x60, 0xcb, 0xf0, 0x12, 0x01, 0x1b, 0x6c, 0x19, 0x6c, 0x22, 0x60, 0x83, 0x2d, 0xc3, 0x4d, 0x04, 0x6c,
+ 0xb0, 0x65, 0xc8, 0x89, 0x80, 0x0d, 0xb6, 0x0c, 0x60, 0x11, 0xb0, 0xc1, 0x96, 0x21, 0x2c, 0x02, 0x36, 0xd8, 0x32,
+ 0x8c, 0x45, 0xc0, 0x06, 0x5b, 0x06, 0xb5, 0x08, 0xd8, 0x60, 0xcb, 0xb0, 0x16, 0x01, 0x1b, 0x6c, 0x19, 0xda, 0x22,
+ 0x60, 0x83, 0x2d, 0x03, 0x5d, 0x04, 0x6c, 0xb0, 0x65, 0xa8, 0x8b, 0x80, 0x0d, 0xb6, 0x0c, 0x77, 0x11, 0xb0, 0xc1,
+ 0x96, 0x81, 0x2f, 0x02, 0x36, 0xd8, 0x32, 0xf4, 0x45, 0xc0, 0x06, 0x5b, 0x86, 0xbf, 0x08, 0xd8, 0x60, 0xcb, 0x40,
+ 0x1a, 0x01, 0x1b, 0x6c, 0x19, 0x7c, 0x23, 0x60, 0x83, 0x2d, 0x03, 0x79, 0x04, 0x6c, 0xb0, 0x65, 0x28, 0x8f, 0x80,
+ 0x0d, 0xb6, 0x0c, 0xe7, 0x11, 0xb0, 0xc1, 0x96, 0xc1, 0x3d, 0x02, 0x36, 0xd8, 0x32, 0xbc, 0x47, 0xc0, 0x06, 0x5b,
+ 0x86, 0xf8, 0x08, 0xd8, 0x60, 0xcb, 0x80, 0x1f, 0x01, 0x1b, 0x6c, 0x19, 0xf2, 0x23, 0x60, 0x83, 0x2d, 0xc3, 0x7e,
+ 0x04, 0x6c, 0xb0, 0x65, 0x10, 0x91, 0x80, 0x0d, 0xb6, 0x0c, 0x23, 0x12, 0xb0, 0xc1, 0x96, 0xa1, 0x44, 0x02, 0x36,
+ 0xd8, 0x32, 0xb0, 0x48, 0xc0, 0x06, 0x5b, 0x86, 0x16, 0x09, 0xd8, 0x60, 0xcb, 0xf0, 0x22, 0x01, 0x1b, 0x6c, 0x19,
+ 0x6c, 0x24, 0x60, 0x83, 0x2d, 0xc3, 0x8d, 0x04, 0x6c, 0xb0, 0x65, 0xc8, 0x91, 0x80, 0x0d, 0xb6, 0x0c, 0x60, 0x12,
+ 0xb0, 0xc1, 0x96, 0x21, 0x4c, 0x02, 0x36, 0xd8, 0x32, 0x8c, 0x49, 0xc0, 0x06, 0x5b, 0x06, 0x34, 0x09, 0xd8, 0x60,
+ 0xcb, 0x90, 0x26, 0x01, 0x1b, 0x6c, 0x19, 0xd6, 0x24, 0x60, 0x83, 0x2d, 0x03, 0x9c, 0x04, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
diff --git a/OptiScaler/upscalers/ffx/FFXFeature_Dx12.cpp b/OptiScaler/upscalers/ffx/FFXFeature_Dx12.cpp
index 1f6cac64..e61dd06b 100644
--- a/OptiScaler/upscalers/ffx/FFXFeature_Dx12.cpp
+++ b/OptiScaler/upscalers/ffx/FFXFeature_Dx12.cpp
@@ -38,57 +38,6 @@ bool FFXFeatureDx12::InitInternal(ID3D12GraphicsCommandList* InCommandList, NVSD
return InitFFX(InParameters);
}
-bool CreateBufferResourceWithSize(ID3D12Device* device, ID3D12Resource* source, D3D12_RESOURCE_STATES state,
- ID3D12Resource** target, UINT width, UINT height)
-{
- if (device == nullptr || source == nullptr)
- return false;
-
- auto inDesc = source->GetDesc();
-
- if (*target != nullptr)
- {
- auto bufDesc = (*target)->GetDesc();
-
- if (bufDesc.Width != width || bufDesc.Height != height || bufDesc.Format != inDesc.Format ||
- bufDesc.Flags != inDesc.Flags)
- {
- // Previous frames can still be using it
- DeferredRelease::Release(*target);
- }
- else
- {
- return true;
- }
- }
-
- D3D12_HEAP_PROPERTIES heapProperties;
- D3D12_HEAP_FLAGS heapFlags;
- HRESULT hr = source->GetHeapProperties(&heapProperties, &heapFlags);
-
- if (hr != S_OK)
- {
- LOG_ERROR("GetHeapProperties result: {:X}", (UINT64) hr);
- return false;
- }
-
- inDesc.Width = width;
- inDesc.Height = height;
-
- hr = device->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &inDesc, state, nullptr,
- IID_PPV_ARGS(target));
-
- if (hr != S_OK)
- {
- LOG_ERROR("CreateCommittedResource result: {:X}", (UINT64) hr);
- return false;
- }
-
- LOG_DEBUG("Created new one: {}x{}", inDesc.Width, inDesc.Height);
-
- return true;
-}
-
bool FFXFeatureDx12::EvaluateInternal(ID3D12GraphicsCommandList* InCommandList, NVSDK_NGX_Parameter* InParameters)
{
LOG_FUNC();
@@ -161,70 +110,6 @@ bool FFXFeatureDx12::EvaluateInternal(ID3D12GraphicsCommandList* InCommandList,
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
}
- // WAR for FSR 4's autoexposure shader reading entire underlying resource
- // instead of what's specified by renderSize or color's FfxApiResourceDescription.
- // Only linear has this issue
- if (Version().major >= 4 && AutoExposure() && !Config::Instance()->FsrNonLinearPQ.value_or_default() &&
- !Config::Instance()->FsrNonLinearSRGB.value_or_default() &&
- !Config::Instance()->FsrNonLinearColorSpace.value_or_default())
- {
- D3D12_RESOURCE_DESC desc = paramColor->GetDesc();
-
- const auto diffW = static_cast(desc.Width) - static_cast(params.renderSize.width);
- const auto diffH = static_cast(desc.Height) - static_cast(params.renderSize.height);
-
- // Seemingly it may only be happening when both axes are 1 pixel too big
- // But let's be conservative here and also trigger when just one axis is too big
- const bool validW = (diffW >= 0 && diffW <= 2);
- const bool validH = (diffH >= 0 && diffH <= 2);
- const bool isPadded = (diffW > 0 || diffH > 0);
-
- if (validW && validH && isPadded)
- {
- static size_t count = 0;
- const size_t index = count % 2;
-
- CreateBufferResourceWithSize(Device, paramColor, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE,
- &smallerColor[index], params.renderSize.width, params.renderSize.height);
-
- if (smallerColor[index])
- {
- ResourceBarrier(InCommandList, paramColor, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE,
- D3D12_RESOURCE_STATE_COPY_SOURCE);
-
- ResourceBarrier(InCommandList, smallerColor[index], D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE,
- D3D12_RESOURCE_STATE_COPY_DEST);
-
- D3D12_BOX srcBox {};
- srcBox.left = 0;
- srcBox.top = 0;
- srcBox.right = params.renderSize.width;
- srcBox.bottom = params.renderSize.height;
- srcBox.front = 0;
- srcBox.back = 1;
-
- D3D12_TEXTURE_COPY_LOCATION dstLocation {};
- dstLocation.pResource = smallerColor[index];
- dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
- dstLocation.SubresourceIndex = 0;
-
- D3D12_TEXTURE_COPY_LOCATION srcLocation {};
- srcLocation.pResource = paramColor;
- srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
- srcLocation.SubresourceIndex = 0;
-
- InCommandList->CopyTextureRegion(&dstLocation, 0, 0, 0, &srcLocation, &srcBox);
-
- ResourceBarrier(InCommandList, smallerColor[index], D3D12_RESOURCE_STATE_COPY_DEST,
- D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
-
- paramColor = smallerColor[index];
- }
-
- count++;
- }
- }
-
params.color = ffxApiGetResourceDX12(paramColor, FFX_API_RESOURCE_STATE_COMPUTE_READ);
}
else
@@ -579,6 +464,19 @@ bool FFXFeatureDx12::EvaluateInternal(ID3D12GraphicsCommandList* InCommandList,
params.upscaleSize.height = TargetHeight();
}
+ if (_customAutoExposure)
+ {
+ if (_autoExposure->Dispatch(InCommandList, paramColor, params.renderSize.width, params.renderSize.height,
+ params.preExposure, params.frameTimeDelta / 1000.0f, params.reset))
+ {
+ params.exposure = ffxApiGetResourceDX12(_autoExposure->Exposure(), FFX_API_RESOURCE_STATE_COMPUTE_READ);
+ }
+ else
+ {
+ LOG_ERROR("Auto exposure dispatch failed");
+ }
+ }
+
LOG_DEBUG("Dispatch!!");
auto result = FfxApiProxy::D3D12_Dispatch(&_context, ¶ms.header);
@@ -663,12 +561,36 @@ bool FFXFeatureDx12::InitFFX(const NVSDK_NGX_Parameter* InParameters)
State::Instance().ffxUpscalerVersionsDx12.ids.size())
Config::Instance()->FfxUpscalerIndex.set_volatile_value(0);
+ parse_version(
+ State::Instance().ffxUpscalerVersionsDx12.names[Config::Instance()->FfxUpscalerIndex.value_or_default()]);
+
ffxOverrideVersion override = { 0 };
override.header.type = FFX_API_DESC_TYPE_OVERRIDE_VERSION;
override.versionId =
State::Instance().ffxUpscalerVersionsDx12.ids[Config::Instance()->FfxUpscalerIndex.value_or_default()];
backendDesc.header.pNext = &override.header;
+ // FSR4's own auto exposure reads the whole color texture instead of just renderSize. On UE the padding
+ // outside the view can hold garbage that makes it think the scene is very bright and black out the frame.
+ // Run our own auto exposure instead and hand FSR4 the result as a regular exposure texture.
+ // Only linear input is affected, color space changes recreate the feature.
+ _customAutoExposure = false;
+ auto& cfg = *Config::Instance();
+
+ if (Version().major >= 4 && AutoExposure() && !cfg.FsrNonLinearPQ.value_or_default() &&
+ !cfg.FsrNonLinearSRGB.value_or_default() && !cfg.FsrNonLinearColorSpace.value_or_default())
+ {
+ if (_autoExposure == nullptr)
+ _autoExposure = std::make_unique("AutoExposure", Device);
+
+ if (_autoExposure->IsInit())
+ {
+ _customAutoExposure = true;
+ _contextDesc.flags &= ~FFX_UPSCALE_ENABLE_AUTO_EXPOSURE;
+ LOG_INFO("Using OptiScaler auto exposure instead of FSR's");
+ }
+ }
+
LOG_DEBUG("_createContext!");
{
@@ -683,10 +605,7 @@ bool FFXFeatureDx12::InitFFX(const NVSDK_NGX_Parameter* InParameters)
}
}
- auto version =
- State::Instance().ffxUpscalerVersionsDx12.names[Config::Instance()->FfxUpscalerIndex.value_or_default()];
_name = "FSR";
- parse_version(version);
}
SetInit(true);
diff --git a/OptiScaler/upscalers/ffx/FFXFeature_Dx12.h b/OptiScaler/upscalers/ffx/FFXFeature_Dx12.h
index 885085b4..debcac0f 100644
--- a/OptiScaler/upscalers/ffx/FFXFeature_Dx12.h
+++ b/OptiScaler/upscalers/ffx/FFXFeature_Dx12.h
@@ -4,11 +4,13 @@
#include "dx12/ffx_api_dx12.h"
#include "proxies/FfxApi_Proxy.h"
+#include
class FFXFeatureDx12 : public FFXFeature, public IFeature_Dx12
{
private:
- ID3D12Resource* smallerColor[2] {};
+ std::unique_ptr _autoExposure;
+ bool _customAutoExposure = false;
NVSDK_NGX_Parameter* SetParameters(NVSDK_NGX_Parameter* InParameters);
@@ -44,8 +46,5 @@ class FFXFeatureDx12 : public FFXFeature, public IFeature_Dx12
if (_context != nullptr)
FfxApiProxy::D3D12_DestroyContext(&_context, NULL);
-
- SAFE_RELEASE(smallerColor[0]);
- SAFE_RELEASE(smallerColor[1]);
}
};