Added velocity buffer + start of TAA implementation

This commit is contained in:
antopilo
2024-09-24 21:19:56 -04:00
parent bf75c04a8c
commit 6e8f14c5da
10 changed files with 436 additions and 398 deletions

View File

@@ -178,6 +178,10 @@ namespace Nuake {
{
texture = Engine::GetCurrentScene()->m_SceneRenderer->GetScaledDepthTexture();
}
else if (SelectedViewport == 4)
{
texture = Engine::GetCurrentScene()->m_SceneRenderer->GetGBuffer().GetTexture(GL_COLOR_ATTACHMENT5);
}
ImVec2 imagePos = ImGui::GetWindowPos() + ImGui::GetCursorPos();
@@ -195,7 +199,6 @@ namespace Nuake {
const bool isInsideHeight = mousePos.y > windowPos.y && mousePos.y < windowPos.y + windowSize.y;
m_IsHoveringViewport = isInsideWidth && isInsideHeight;
if (ImGui::BeginDragDropTarget())
{
auto& gbuffer = Engine::GetCurrentScene()->m_SceneRenderer->GetGBuffer();
@@ -2766,7 +2769,7 @@ namespace Nuake {
ImGui::PushStyleColor(ImGuiCol_FrameBg, IM_COL32(20, 20, 20, 0));
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, IM_COL32(20, 20, 20, 60));
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, IM_COL32(33, 33, 33, 45));
const char* items[] = { "Shaded", "Albedo", "Normal", "Depth"};
const char* items[] = { "Shaded", "Albedo", "Normal", "Depth", "Velocity"};
ImGui::SetNextItemWidth(128);
if (ImGui::BeginCombo("##Output", items[SelectedViewport]))
{

View File

@@ -15,6 +15,7 @@ namespace Nuake
Ref<Mesh> mesh;
Matrix4 transform;
int32_t entityId;
Matrix4 previousTransform;
};
class RenderList
@@ -25,7 +26,7 @@ namespace Nuake
this->m_RenderList = std::unordered_map<Ref<Material>, std::vector<RenderMesh>>();
}
void AddToRenderList(Ref<Mesh> mesh, const Matrix4& transform, const int32_t entityId = -1)
void AddToRenderList(Ref<Mesh> mesh, const Matrix4& transform, const int32_t entityId = -1, const Matrix4& previousTransform = Matrix4(0.0f) )
{
Ref<Material> material = mesh->GetMaterial();
@@ -39,7 +40,7 @@ namespace Nuake
m_RenderList[material] = std::vector<RenderMesh>();
}
m_RenderList[material].push_back({std::move(mesh), std::move(transform), entityId});
m_RenderList[material].push_back({std::move(mesh), std::move(transform), entityId, previousTransform});
}
void Flush(Shader* shader, bool depthOnly = false)
@@ -52,6 +53,7 @@ namespace Nuake
}
const uint32_t modelMatrixUniformLocation = shader->FindUniformLocation("u_Model");
const int previousTransformUniformLocation = shader->FindUniformLocation("u_PreviousViewModel");
for (auto& i : m_RenderList)
{
if (!depthOnly)
@@ -66,6 +68,11 @@ namespace Nuake
shader->SetUniform(entityIdUniformLocation, m.entityId + 1);
}
if (previousTransformUniformLocation != -1)
{
shader->SetUniform(previousTransformUniformLocation, m.previousTransform);
}
shader->SetUniform(modelMatrixUniformLocation, m.transform);
m.mesh->Draw(shader, false);
}

View File

@@ -108,9 +108,9 @@ namespace Nuake
}
void Renderer::SubmitMesh(Ref<Mesh> mesh, Matrix4 transform, const int32_t entityId)
void Renderer::SubmitMesh(Ref<Mesh> mesh, const Matrix4& transform, const int32_t entityId, const Matrix4& previousTransform)
{
m_RenderList.AddToRenderList(mesh, transform, entityId);
m_RenderList.AddToRenderList(mesh, transform, entityId, previousTransform);
}
void Renderer::SubmitCube(Matrix4 transform)

View File

@@ -63,7 +63,7 @@ namespace Nuake
static void Init();
static void LoadShaders();
static void SubmitMesh(Ref<Mesh> mesh, Matrix4 transform, const int32_t entityId = -1);
static void SubmitMesh(Ref<Mesh> mesh, const Matrix4& transform, const int32_t entityId = -1, const Matrix4& previousTransform = Matrix4(1.0f));
static void SubmitCube(Matrix4 transform);
static void Flush(Shader* shader, bool depthOnly = false);

View File

@@ -22,19 +22,43 @@
namespace Nuake
{
std::vector<Vector2> SceneRenderer::mJitterOffsets = []{
return std::vector<Vector2> {
Vector2(0.500000, 0.333333),
Vector2(0.250000, 0.666667),
Vector2(0.750000, 0.111111),
Vector2(0.125000, 0.444444),
Vector2(0.625000, 0.777778),
Vector2(0.375000, 0.222222),
Vector2(0.875000, 0.555556),
Vector2(0.062500, 0.888889),
Vector2(0.562500, 0.037037),
Vector2(0.312500, 0.370370),
Vector2(0.812500, 0.703704),
Vector2(0.187500, 0.148148),
Vector2(0.687500, 0.481481),
Vector2(0.437500, 0.814815),
Vector2(0.937500, 0.259259),
Vector2(0.031250, 0.592593)
};
}();
void SceneRenderer::Init()
{
const auto defaultResolution = Vector2(1920, 1080);
auto entityTexture = CreateRef<Texture>(defaultResolution, GL_RED_INTEGER, GL_R32I, GL_INT);
entityTexture->SetParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
mGBuffer = CreateScope<FrameBuffer>(false, defaultResolution);
mGBuffer->SetTexture(CreateRef<Texture>(defaultResolution, GL_DEPTH_COMPONENT), GL_DEPTH_ATTACHMENT); // Depth
mGBuffer->SetTexture(CreateRef<Texture>(defaultResolution, GL_RGB), GL_COLOR_ATTACHMENT0); // Albedo
mGBuffer->SetTexture(CreateRef<Texture>(defaultResolution, GL_RGB), GL_COLOR_ATTACHMENT1); // Normal
mGBuffer->SetTexture(CreateRef<Texture>(defaultResolution, GL_RGBA), GL_COLOR_ATTACHMENT2); // Material + unlit
auto entityTexture = CreateRef<Texture>(defaultResolution, GL_RED_INTEGER, GL_R32I, GL_INT);
entityTexture->SetParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
mGBuffer->SetTexture(entityTexture, GL_COLOR_ATTACHMENT3); // Entity ID
mGBuffer->SetTexture(CreateRef<Texture>(defaultResolution, GL_RED, GL_R16F, GL_FLOAT), GL_COLOR_ATTACHMENT4); // Emissive
mGBuffer->SetTexture(CreateRef<Texture>(defaultResolution, GL_RGB), GL_COLOR_ATTACHMENT5); // Velocity
mShadingBuffer = CreateScope<FrameBuffer>(true, defaultResolution);
mShadingBuffer->SetTexture(CreateRef<Texture>(defaultResolution, GL_RGB, GL_RGB16F, GL_FLOAT));
@@ -91,6 +115,9 @@ namespace Nuake
mDebugLines = std::vector<DebugLine>();
mDebugShapes = std::vector<DebugShape>();
mScaledJitterOffets.reserve(mJitterOffsets.size());
UpdateJitterOffsets(defaultResolution);
}
void SceneRenderer::Cleanup()
@@ -148,12 +175,35 @@ namespace Nuake
const Vector2 framebufferResolution = framebuffer.GetSize();
if (framebufferResolution != GetGBuffer().GetSize())
{
UpdateJitterOffsets({ 1600, 1200 });
}
if (renderUI)
{
mGBuffer->QueueResize(framebufferResolution);
}
GBufferPass(scene);
if (framebuffer.GetSize() != GetGBuffer().GetSize())
{
// UpdateJitterOffsets(framebuffer.GetSize());
}
// Save previous Matrix
auto modelView = scene.m_Registry.view<TransformComponent, ModelComponent, VisibilityComponent>();
for (auto e : modelView)
{
auto [transform, mesh, visibility] = modelView.get<TransformComponent, ModelComponent, VisibilityComponent>(e);
Entity entity = { (entt::entity)e, Engine::GetCurrentScene().get() };
Logger::Log("Setting previous pos of : " + entity.GetComponent<NameComponent>().Name);
if (mesh.ModelResource && visibility.Visible)
{
transform.PreviousTransform = mProjection * mView * transform.GetGlobalTransform();
}
}
if(renderUI)
{
mTempFrameBuffer->QueueResize(framebuffer.GetSize());
@@ -805,6 +855,10 @@ namespace Nuake
gBufferShader->Bind();
gBufferShader->SetUniform("u_Projection", mProjection);
gBufferShader->SetUniform("u_View", mView);
gBufferShader->SetUniform("u_Jitter", mScaledJitterOffets[mJitterIndex]);
mJitterIndex++;
mJitterIndex = mJitterIndex % mScaledJitterOffets.size();
// Models
{
@@ -818,7 +872,7 @@ namespace Nuake
{
for (auto& m : mesh.ModelResource->GetMeshes())
{
Renderer::SubmitMesh(m, transform.GetGlobalTransform(), (uint32_t)e);
Renderer::SubmitMesh(m, transform.GetGlobalTransform(), (uint32_t)e, transform.PreviousTransform);
}
}
}
@@ -1291,4 +1345,20 @@ namespace Nuake
}
}
void SceneRenderer::UpdateJitterOffsets(const Vector2& viewportSize)
{
mScaledJitterOffets.clear();
uint32_t index = 0;
for (auto& jitterPoint : mJitterOffsets)
{
mScaledJitterOffets.push_back({
((jitterPoint.x - 0.5f) / viewportSize.x) * 2.0f,
((jitterPoint.y - 0.5f) / viewportSize.y) * 2.0f
});
index++;
}
}
}

View File

@@ -108,6 +108,10 @@ namespace Nuake
std::vector<DebugLine> mDebugLines;
std::vector<DebugShape> mDebugShapes;
static std::vector<Vector2> mJitterOffsets;
std::vector<Vector2> mScaledJitterOffets;
uint32_t mJitterIndex = 0;
void ShadowPass(Scene& scene);
void GBufferPass(Scene& scene);
void ShadingPass(Scene& scene);
@@ -115,5 +119,7 @@ namespace Nuake
void DebugRendererPass(Scene& scene);
void SetSkeletonBoneTransformRecursive(Scene& scene, SkeletonNode& skeletonNode, Shader* shader);
void UpdateJitterOffsets(const Vector2& viewportSize);
};
}

View File

@@ -222,7 +222,7 @@ namespace Nuake
{
int addr = glGetUniformLocation(programId, uniform.c_str());
ASSERT(addr != -1);
// ASSERT(addr != -1);
UniformCache[uniform] = addr;

View File

@@ -270949,377 +270949,340 @@ namespace Nuake {
0x6D, 0x61, 0x74, 0x34, 0x20, 0x75, 0x5F, 0x56, 0x69, 0x65, 0x77, 0x3B,
0x0D, 0x0A, 0x75, 0x6E, 0x69, 0x66, 0x6F, 0x72, 0x6D, 0x20, 0x6D, 0x61,
0x74, 0x34, 0x20, 0x75, 0x5F, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74,
0x69, 0x6F, 0x6E, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x6F, 0x75, 0x74, 0x20,
0x76, 0x65, 0x63, 0x34, 0x20, 0x46, 0x72, 0x61, 0x67, 0x50, 0x6F, 0x73,
0x3B, 0x0D, 0x0A, 0x6F, 0x75, 0x74, 0x20, 0x6D, 0x61, 0x74, 0x33, 0x20,
0x54, 0x42, 0x4E, 0x3B, 0x0D, 0x0A, 0x6F, 0x75, 0x74, 0x20, 0x76, 0x65,
0x63, 0x32, 0x20, 0x55, 0x56, 0x3B, 0x0D, 0x0A, 0x6F, 0x75, 0x74, 0x20,
0x6D, 0x61, 0x74, 0x34, 0x20, 0x49, 0x6E, 0x76, 0x5F, 0x50, 0x72, 0x6F,
0x6A, 0x3B, 0x0D, 0x0A, 0x6F, 0x75, 0x74, 0x20, 0x6D, 0x61, 0x74, 0x34,
0x20, 0x49, 0x6E, 0x76, 0x5F, 0x56, 0x69, 0x65, 0x77, 0x3B, 0x0D, 0x0A,
0x6F, 0x75, 0x74, 0x20, 0x6D, 0x61, 0x74, 0x34, 0x20, 0x76, 0x69, 0x65,
0x77, 0x3B, 0x0D, 0x0A, 0x6F, 0x75, 0x74, 0x20, 0x76, 0x65, 0x63, 0x33,
0x20, 0x6F, 0x5F, 0x54, 0x61, 0x6E, 0x67, 0x65, 0x6E, 0x74, 0x3B, 0x0D,
0x0A, 0x0D, 0x0A, 0x76, 0x6F, 0x69, 0x64, 0x20, 0x6D, 0x61, 0x69, 0x6E,
0x28, 0x29, 0x0D, 0x0A, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x2F,
0x2F, 0x6D, 0x61, 0x74, 0x33, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C,
0x4D, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x3D, 0x20, 0x74, 0x72, 0x61,
0x6E, 0x73, 0x70, 0x6F, 0x73, 0x65, 0x28, 0x69, 0x6E, 0x76, 0x65, 0x72,
0x73, 0x65, 0x28, 0x6D, 0x61, 0x74, 0x33, 0x28, 0x75, 0x5F, 0x4D, 0x6F,
0x64, 0x65, 0x6C, 0x29, 0x29, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20,
0x20, 0x2F, 0x2F, 0x76, 0x65, 0x63, 0x33, 0x20, 0x54, 0x20, 0x3D, 0x20,
0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x69, 0x7A, 0x65, 0x28, 0x6E, 0x6F,
0x72, 0x6D, 0x61, 0x6C, 0x4D, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x2A,
0x20, 0x54, 0x61, 0x6E, 0x67, 0x65, 0x6E, 0x74, 0x29, 0x3B, 0x0D, 0x0A,
0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x76, 0x65, 0x63, 0x33, 0x20, 0x4E,
0x20, 0x3D, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x69, 0x7A, 0x65,
0x28, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x4D, 0x61, 0x74, 0x72, 0x69,
0x78, 0x20, 0x2A, 0x20, 0x4E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x29, 0x3B,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x54, 0x20, 0x3D, 0x20,
0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x69, 0x7A, 0x65, 0x28, 0x54, 0x20,
0x2D, 0x20, 0x64, 0x6F, 0x74, 0x28, 0x54, 0x2C, 0x20, 0x4E, 0x29, 0x20,
0x2A, 0x20, 0x4E, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x2F,
0x2F, 0x76, 0x65, 0x63, 0x33, 0x20, 0x42, 0x20, 0x3D, 0x20, 0x63, 0x72,
0x6F, 0x73, 0x73, 0x28, 0x4E, 0x2C, 0x20, 0x54, 0x29, 0x3B, 0x0D, 0x0A,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x54,
0x20, 0x3D, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x69, 0x7A, 0x65,
0x28, 0x28, 0x75, 0x5F, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x20, 0x2A, 0x20,
0x76, 0x65, 0x63, 0x34, 0x28, 0x54, 0x61, 0x6E, 0x67, 0x65, 0x6E, 0x74,
0x2C, 0x20, 0x30, 0x2E, 0x30, 0x66, 0x29, 0x29, 0x2E, 0x78, 0x79, 0x7A,
0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33,
0x69, 0x6F, 0x6E, 0x3B, 0x0D, 0x0A, 0x75, 0x6E, 0x69, 0x66, 0x6F, 0x72,
0x6D, 0x20, 0x6D, 0x61, 0x74, 0x34, 0x20, 0x75, 0x5F, 0x50, 0x72, 0x65,
0x76, 0x69, 0x6F, 0x75, 0x73, 0x56, 0x69, 0x65, 0x77, 0x4D, 0x6F, 0x64,
0x65, 0x6C, 0x3B, 0x0D, 0x0A, 0x75, 0x6E, 0x69, 0x66, 0x6F, 0x72, 0x6D,
0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x75, 0x5F, 0x4A, 0x69, 0x74, 0x74,
0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x6F, 0x75, 0x74, 0x20, 0x76,
0x65, 0x63, 0x34, 0x20, 0x46, 0x72, 0x61, 0x67, 0x50, 0x6F, 0x73, 0x3B,
0x0D, 0x0A, 0x6F, 0x75, 0x74, 0x20, 0x6D, 0x61, 0x74, 0x33, 0x20, 0x54,
0x42, 0x4E, 0x3B, 0x0D, 0x0A, 0x6F, 0x75, 0x74, 0x20, 0x76, 0x65, 0x63,
0x32, 0x20, 0x55, 0x56, 0x3B, 0x0D, 0x0A, 0x6F, 0x75, 0x74, 0x20, 0x6D,
0x61, 0x74, 0x34, 0x20, 0x49, 0x6E, 0x76, 0x5F, 0x50, 0x72, 0x6F, 0x6A,
0x3B, 0x0D, 0x0A, 0x6F, 0x75, 0x74, 0x20, 0x6D, 0x61, 0x74, 0x34, 0x20,
0x49, 0x6E, 0x76, 0x5F, 0x56, 0x69, 0x65, 0x77, 0x3B, 0x0D, 0x0A, 0x6F,
0x75, 0x74, 0x20, 0x6D, 0x61, 0x74, 0x34, 0x20, 0x76, 0x69, 0x65, 0x77,
0x3B, 0x0D, 0x0A, 0x6F, 0x75, 0x74, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20,
0x6F, 0x5F, 0x54, 0x61, 0x6E, 0x67, 0x65, 0x6E, 0x74, 0x3B, 0x0D, 0x0A,
0x6F, 0x75, 0x74, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x50, 0x72, 0x65,
0x76, 0x69, 0x6F, 0x75, 0x73, 0x46, 0x72, 0x61, 0x67, 0x50, 0x6F, 0x73,
0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x76, 0x6F, 0x69, 0x64, 0x20, 0x6D, 0x61,
0x69, 0x6E, 0x28, 0x29, 0x0D, 0x0A, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20,
0x20, 0x2F, 0x2F, 0x6D, 0x61, 0x74, 0x33, 0x20, 0x6E, 0x6F, 0x72, 0x6D,
0x61, 0x6C, 0x4D, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x3D, 0x20, 0x74,
0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x73, 0x65, 0x28, 0x69, 0x6E, 0x76,
0x65, 0x72, 0x73, 0x65, 0x28, 0x6D, 0x61, 0x74, 0x33, 0x28, 0x75, 0x5F,
0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x29, 0x29, 0x29, 0x3B, 0x0D, 0x0A, 0x20,
0x20, 0x20, 0x20, 0x2F, 0x2F, 0x76, 0x65, 0x63, 0x33, 0x20, 0x54, 0x20,
0x3D, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x69, 0x7A, 0x65, 0x28,
0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x4D, 0x61, 0x74, 0x72, 0x69, 0x78,
0x20, 0x2A, 0x20, 0x54, 0x61, 0x6E, 0x67, 0x65, 0x6E, 0x74, 0x29, 0x3B,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x76, 0x65, 0x63, 0x33,
0x20, 0x4E, 0x20, 0x3D, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x69,
0x7A, 0x65, 0x28, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x4D, 0x61, 0x74,
0x72, 0x69, 0x78, 0x20, 0x2A, 0x20, 0x4E, 0x6F, 0x72, 0x6D, 0x61, 0x6C,
0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x54, 0x20,
0x3D, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x69, 0x7A, 0x65, 0x28,
0x54, 0x20, 0x2D, 0x20, 0x64, 0x6F, 0x74, 0x28, 0x54, 0x2C, 0x20, 0x4E,
0x29, 0x20, 0x2A, 0x20, 0x4E, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20,
0x20, 0x2F, 0x2F, 0x76, 0x65, 0x63, 0x33, 0x20, 0x42, 0x20, 0x3D, 0x20,
0x63, 0x72, 0x6F, 0x73, 0x73, 0x28, 0x4E, 0x2C, 0x20, 0x54, 0x29, 0x3B,
0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33,
0x20, 0x54, 0x20, 0x3D, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x69,
0x7A, 0x65, 0x28, 0x28, 0x75, 0x5F, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x20,
0x2A, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x4E, 0x6F, 0x72, 0x6D, 0x61,
0x6C, 0x2C, 0x20, 0x30, 0x2E, 0x30, 0x66, 0x29, 0x29, 0x2E, 0x78, 0x79,
0x7A, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63,
0x33, 0x20, 0x42, 0x20, 0x3D, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C,
0x69, 0x7A, 0x65, 0x28, 0x28, 0x75, 0x5F, 0x4D, 0x6F, 0x64, 0x65, 0x6C,
0x20, 0x2A, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x42, 0x69, 0x74, 0x61,
0x6E, 0x67, 0x65, 0x6E, 0x74, 0x2C, 0x20, 0x30, 0x2E, 0x30, 0x66, 0x29,
0x29, 0x2E, 0x78, 0x79, 0x7A, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20,
0x20, 0x54, 0x42, 0x4E, 0x20, 0x3D, 0x20, 0x6D, 0x61, 0x74, 0x33, 0x28,
0x54, 0x2C, 0x20, 0x42, 0x2C, 0x20, 0x4E, 0x29, 0x3B, 0x0D, 0x0A, 0x0D,
0x0A, 0x20, 0x20, 0x20, 0x20, 0x55, 0x56, 0x20, 0x3D, 0x20, 0x55, 0x56,
0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3B, 0x0D, 0x0A, 0x20,
0x20, 0x20, 0x20, 0x49, 0x6E, 0x76, 0x5F, 0x50, 0x72, 0x6F, 0x6A, 0x20,
0x3D, 0x20, 0x75, 0x5F, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x69,
0x6F, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6E, 0x76,
0x5F, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3D, 0x20, 0x75, 0x5F, 0x56, 0x69,
0x65, 0x77, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x6F, 0x5F, 0x54,
0x61, 0x6E, 0x67, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x54, 0x61, 0x6E,
0x67, 0x65, 0x6E, 0x74, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20,
0x20, 0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E,
0x20, 0x3D, 0x20, 0x75, 0x5F, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74,
0x69, 0x6F, 0x6E, 0x20, 0x2A, 0x20, 0x75, 0x5F, 0x56, 0x69, 0x65, 0x77,
0x20, 0x2A, 0x20, 0x75, 0x5F, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x20, 0x2A,
0x2A, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x54, 0x61, 0x6E, 0x67, 0x65,
0x6E, 0x74, 0x2C, 0x20, 0x30, 0x2E, 0x30, 0x66, 0x29, 0x29, 0x2E, 0x78,
0x79, 0x7A, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65,
0x63, 0x33, 0x20, 0x4E, 0x20, 0x3D, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61,
0x6C, 0x69, 0x7A, 0x65, 0x28, 0x28, 0x75, 0x5F, 0x4D, 0x6F, 0x64, 0x65,
0x6C, 0x20, 0x2A, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x4E, 0x6F, 0x72,
0x6D, 0x61, 0x6C, 0x2C, 0x20, 0x30, 0x2E, 0x30, 0x66, 0x29, 0x29, 0x2E,
0x78, 0x79, 0x7A, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76,
0x65, 0x63, 0x33, 0x20, 0x42, 0x20, 0x3D, 0x20, 0x6E, 0x6F, 0x72, 0x6D,
0x61, 0x6C, 0x69, 0x7A, 0x65, 0x28, 0x28, 0x75, 0x5F, 0x4D, 0x6F, 0x64,
0x65, 0x6C, 0x20, 0x2A, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x42, 0x69,
0x74, 0x61, 0x6E, 0x67, 0x65, 0x6E, 0x74, 0x2C, 0x20, 0x30, 0x2E, 0x30,
0x66, 0x29, 0x29, 0x2E, 0x78, 0x79, 0x7A, 0x29, 0x3B, 0x0D, 0x0A, 0x20,
0x20, 0x20, 0x20, 0x54, 0x42, 0x4E, 0x20, 0x3D, 0x20, 0x6D, 0x61, 0x74,
0x33, 0x28, 0x54, 0x2C, 0x20, 0x42, 0x2C, 0x20, 0x4E, 0x29, 0x3B, 0x0D,
0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x55, 0x56, 0x20, 0x3D, 0x20,
0x55, 0x56, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3B, 0x0D,
0x0A, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6E, 0x76, 0x5F, 0x50, 0x72, 0x6F,
0x6A, 0x20, 0x3D, 0x20, 0x75, 0x5F, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63,
0x74, 0x69, 0x6F, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x49,
0x6E, 0x76, 0x5F, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3D, 0x20, 0x75, 0x5F,
0x56, 0x69, 0x65, 0x77, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x6F,
0x5F, 0x54, 0x61, 0x6E, 0x67, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x54,
0x61, 0x6E, 0x67, 0x65, 0x6E, 0x74, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20,
0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x63, 0x6C, 0x69, 0x70,
0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x3D, 0x20, 0x75,
0x5F, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20,
0x2A, 0x20, 0x75, 0x5F, 0x56, 0x69, 0x65, 0x77, 0x20, 0x2A, 0x20, 0x75,
0x5F, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x20, 0x2A, 0x20, 0x76, 0x65, 0x63,
0x34, 0x28, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x50, 0x6F, 0x73, 0x69,
0x74, 0x69, 0x6F, 0x6E, 0x2C, 0x20, 0x31, 0x2E, 0x30, 0x66, 0x29, 0x3B,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x73,
0x69, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x3D, 0x20, 0x63, 0x6C, 0x69, 0x70,
0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x2B, 0x20, 0x75,
0x5F, 0x4A, 0x69, 0x74, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20,
0x20, 0x20, 0x46, 0x72, 0x61, 0x67, 0x50, 0x6F, 0x73, 0x20, 0x3D, 0x20,
0x63, 0x6C, 0x69, 0x70, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E,
0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x50, 0x72, 0x65,
0x76, 0x69, 0x6F, 0x75, 0x73, 0x46, 0x72, 0x61, 0x67, 0x50, 0x6F, 0x73,
0x20, 0x3D, 0x20, 0x75, 0x5F, 0x50, 0x72, 0x65, 0x76, 0x69, 0x6F, 0x75,
0x73, 0x56, 0x69, 0x65, 0x77, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x20, 0x2A,
0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78,
0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x2C, 0x20, 0x31, 0x2E,
0x30, 0x66, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x46, 0x72,
0x61, 0x67, 0x50, 0x6F, 0x73, 0x20, 0x3D, 0x20, 0x67, 0x6C, 0x5F, 0x50,
0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3B, 0x0D, 0x0A, 0x7D, 0x0D,
0x0A, 0x0D, 0x0A, 0x23, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x66,
0x72, 0x61, 0x67, 0x6D, 0x65, 0x6E, 0x74, 0x0D, 0x0A, 0x23, 0x76, 0x65,
0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x34, 0x34, 0x30, 0x20, 0x63, 0x6F,
0x72, 0x65, 0x0D, 0x0A, 0x0D, 0x0A, 0x6C, 0x61, 0x79, 0x6F, 0x75, 0x74,
0x28, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x3D, 0x20,
0x30, 0x29, 0x20, 0x6F, 0x75, 0x74, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20,
0x67, 0x41, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x3B, 0x0D, 0x0A, 0x6C, 0x61,
0x79, 0x6F, 0x75, 0x74, 0x28, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F,
0x6E, 0x20, 0x3D, 0x20, 0x31, 0x29, 0x20, 0x6F, 0x75, 0x74, 0x20, 0x76,
0x65, 0x63, 0x34, 0x20, 0x67, 0x4E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x3B,
0x30, 0x66, 0x29, 0x3B, 0x0D, 0x0A, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x23,
0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x66, 0x72, 0x61, 0x67, 0x6D,
0x65, 0x6E, 0x74, 0x0D, 0x0A, 0x23, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F,
0x6E, 0x20, 0x34, 0x34, 0x30, 0x20, 0x63, 0x6F, 0x72, 0x65, 0x0D, 0x0A,
0x0D, 0x0A, 0x6C, 0x61, 0x79, 0x6F, 0x75, 0x74, 0x28, 0x6C, 0x6F, 0x63,
0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x3D, 0x20, 0x32, 0x29, 0x20, 0x6F,
0x75, 0x74, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x67, 0x4D, 0x61, 0x74,
0x65, 0x72, 0x69, 0x61, 0x6C, 0x3B, 0x0D, 0x0A, 0x6C, 0x61, 0x79, 0x6F,
0x75, 0x74, 0x28, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20,
0x3D, 0x20, 0x33, 0x29, 0x20, 0x6F, 0x75, 0x74, 0x20, 0x69, 0x6E, 0x74,
0x20, 0x67, 0x45, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x49, 0x44, 0x3B, 0x0D,
0x0A, 0x6C, 0x61, 0x79, 0x6F, 0x75, 0x74, 0x28, 0x6C, 0x6F, 0x63, 0x61,
0x74, 0x69, 0x6F, 0x6E, 0x20, 0x3D, 0x20, 0x34, 0x29, 0x20, 0x6F, 0x75,
0x74, 0x20, 0x66, 0x6C, 0x6F, 0x61, 0x74, 0x20, 0x67, 0x45, 0x6D, 0x69,
0x73, 0x73, 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, 0x6C, 0x61, 0x79, 0x6F,
0x75, 0x74, 0x28, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20,
0x3D, 0x20, 0x35, 0x29, 0x20, 0x6F, 0x75, 0x74, 0x20, 0x76, 0x65, 0x63,
0x34, 0x20, 0x67, 0x54, 0x65, 0x78, 0x65, 0x6C, 0x4F, 0x66, 0x66, 0x73,
0x65, 0x74, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x69, 0x6E, 0x20, 0x76, 0x65,
0x63, 0x34, 0x20, 0x46, 0x72, 0x61, 0x67, 0x50, 0x6F, 0x73, 0x3B, 0x0D,
0x0A, 0x69, 0x6E, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x55, 0x56, 0x3B,
0x0D, 0x0A, 0x69, 0x6E, 0x20, 0x6D, 0x61, 0x74, 0x33, 0x20, 0x54, 0x42,
0x4E, 0x3B, 0x0D, 0x0A, 0x69, 0x6E, 0x20, 0x6D, 0x61, 0x74, 0x34, 0x20,
0x49, 0x6E, 0x76, 0x5F, 0x50, 0x72, 0x6F, 0x6A, 0x3B, 0x0D, 0x0A, 0x69,
0x6E, 0x20, 0x6D, 0x61, 0x74, 0x34, 0x20, 0x49, 0x6E, 0x76, 0x5F, 0x56,
0x69, 0x65, 0x77, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x0D, 0x0A, 0x2F, 0x2F,
0x20, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x0D, 0x0A, 0x75,
0x6E, 0x69, 0x66, 0x6F, 0x72, 0x6D, 0x20, 0x73, 0x61, 0x6D, 0x70, 0x6C,
0x65, 0x72, 0x32, 0x44, 0x20, 0x6D, 0x5F, 0x41, 0x6C, 0x62, 0x65, 0x64,
0x6F, 0x3B, 0x0D, 0x0A, 0x75, 0x6E, 0x69, 0x66, 0x6F, 0x72, 0x6D, 0x20,
0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x3D, 0x20, 0x30, 0x29, 0x20, 0x6F,
0x75, 0x74, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x67, 0x41, 0x6C, 0x62,
0x65, 0x64, 0x6F, 0x3B, 0x0D, 0x0A, 0x6C, 0x61, 0x79, 0x6F, 0x75, 0x74,
0x28, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x3D, 0x20,
0x31, 0x29, 0x20, 0x6F, 0x75, 0x74, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20,
0x67, 0x4E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x3B, 0x0D, 0x0A, 0x6C, 0x61,
0x79, 0x6F, 0x75, 0x74, 0x28, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F,
0x6E, 0x20, 0x3D, 0x20, 0x32, 0x29, 0x20, 0x6F, 0x75, 0x74, 0x20, 0x76,
0x65, 0x63, 0x34, 0x20, 0x67, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61,
0x6C, 0x3B, 0x0D, 0x0A, 0x6C, 0x61, 0x79, 0x6F, 0x75, 0x74, 0x28, 0x6C,
0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x3D, 0x20, 0x33, 0x29,
0x20, 0x6F, 0x75, 0x74, 0x20, 0x69, 0x6E, 0x74, 0x20, 0x67, 0x45, 0x6E,
0x74, 0x69, 0x74, 0x79, 0x49, 0x44, 0x3B, 0x0D, 0x0A, 0x6C, 0x61, 0x79,
0x6F, 0x75, 0x74, 0x28, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E,
0x20, 0x3D, 0x20, 0x34, 0x29, 0x20, 0x6F, 0x75, 0x74, 0x20, 0x66, 0x6C,
0x6F, 0x61, 0x74, 0x20, 0x67, 0x45, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x76,
0x65, 0x3B, 0x0D, 0x0A, 0x6C, 0x61, 0x79, 0x6F, 0x75, 0x74, 0x28, 0x6C,
0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x3D, 0x20, 0x35, 0x29,
0x20, 0x6F, 0x75, 0x74, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x67, 0x56,
0x65, 0x6C, 0x6F, 0x63, 0x69, 0x74, 0x79, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A,
0x69, 0x6E, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x46, 0x72, 0x61, 0x67,
0x50, 0x6F, 0x73, 0x3B, 0x0D, 0x0A, 0x69, 0x6E, 0x20, 0x76, 0x65, 0x63,
0x32, 0x20, 0x55, 0x56, 0x3B, 0x0D, 0x0A, 0x69, 0x6E, 0x20, 0x6D, 0x61,
0x74, 0x33, 0x20, 0x54, 0x42, 0x4E, 0x3B, 0x0D, 0x0A, 0x69, 0x6E, 0x20,
0x6D, 0x61, 0x74, 0x34, 0x20, 0x49, 0x6E, 0x76, 0x5F, 0x50, 0x72, 0x6F,
0x6A, 0x3B, 0x0D, 0x0A, 0x69, 0x6E, 0x20, 0x6D, 0x61, 0x74, 0x34, 0x20,
0x49, 0x6E, 0x76, 0x5F, 0x56, 0x69, 0x65, 0x77, 0x3B, 0x0D, 0x0A, 0x69,
0x6E, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x50, 0x72, 0x65, 0x76, 0x69,
0x6F, 0x75, 0x73, 0x46, 0x72, 0x61, 0x67, 0x50, 0x6F, 0x73, 0x3B, 0x0D,
0x0A, 0x0D, 0x0A, 0x2F, 0x2F, 0x20, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69,
0x61, 0x6C, 0x0D, 0x0A, 0x75, 0x6E, 0x69, 0x66, 0x6F, 0x72, 0x6D, 0x20,
0x73, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x72, 0x32, 0x44, 0x20, 0x6D, 0x5F,
0x4D, 0x65, 0x74, 0x61, 0x6C, 0x6E, 0x65, 0x73, 0x73, 0x3B, 0x0D, 0x0A,
0x75, 0x6E, 0x69, 0x66, 0x6F, 0x72, 0x6D, 0x20, 0x73, 0x61, 0x6D, 0x70,
0x6C, 0x65, 0x72, 0x32, 0x44, 0x20, 0x6D, 0x5F, 0x52, 0x6F, 0x75, 0x67,
0x68, 0x6E, 0x65, 0x73, 0x73, 0x3B, 0x0D, 0x0A, 0x75, 0x6E, 0x69, 0x66,
0x6F, 0x72, 0x6D, 0x20, 0x73, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x72, 0x32,
0x44, 0x20, 0x6D, 0x5F, 0x41, 0x4F, 0x3B, 0x0D, 0x0A, 0x75, 0x6E, 0x69,
0x41, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x3B, 0x0D, 0x0A, 0x75, 0x6E, 0x69,
0x66, 0x6F, 0x72, 0x6D, 0x20, 0x73, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x72,
0x32, 0x44, 0x20, 0x6D, 0x5F, 0x4E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x3B,
0x32, 0x44, 0x20, 0x6D, 0x5F, 0x4D, 0x65, 0x74, 0x61, 0x6C, 0x6E, 0x65,
0x73, 0x73, 0x3B, 0x0D, 0x0A, 0x75, 0x6E, 0x69, 0x66, 0x6F, 0x72, 0x6D,
0x20, 0x73, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x72, 0x32, 0x44, 0x20, 0x6D,
0x5F, 0x52, 0x6F, 0x75, 0x67, 0x68, 0x6E, 0x65, 0x73, 0x73, 0x3B, 0x0D,
0x0A, 0x75, 0x6E, 0x69, 0x66, 0x6F, 0x72, 0x6D, 0x20, 0x73, 0x61, 0x6D,
0x70, 0x6C, 0x65, 0x72, 0x32, 0x44, 0x20, 0x6D, 0x5F, 0x41, 0x4F, 0x3B,
0x0D, 0x0A, 0x75, 0x6E, 0x69, 0x66, 0x6F, 0x72, 0x6D, 0x20, 0x73, 0x61,
0x6D, 0x70, 0x6C, 0x65, 0x72, 0x32, 0x44, 0x20, 0x6D, 0x5F, 0x44, 0x69,
0x73, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x3B, 0x0D,
0x0A, 0x75, 0x6E, 0x69, 0x66, 0x6F, 0x72, 0x6D, 0x20, 0x69, 0x6E, 0x74,
0x20, 0x75, 0x5F, 0x45, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x49, 0x44, 0x3B,
0x0D, 0x0A, 0x0D, 0x0A, 0x6C, 0x61, 0x79, 0x6F, 0x75, 0x74, 0x28, 0x73,
0x74, 0x64, 0x31, 0x34, 0x30, 0x2C, 0x20, 0x62, 0x69, 0x6E, 0x64, 0x69,
0x6E, 0x67, 0x20, 0x3D, 0x20, 0x33, 0x32, 0x29, 0x20, 0x75, 0x6E, 0x69,
0x66, 0x6F, 0x72, 0x6D, 0x20, 0x75, 0x5F, 0x4D, 0x61, 0x74, 0x65, 0x72,
0x69, 0x61, 0x6C, 0x55, 0x6E, 0x69, 0x66, 0x6F, 0x72, 0x6D, 0x0D, 0x0A,
0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x74, 0x20, 0x75,
0x5F, 0x48, 0x61, 0x73, 0x41, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x3B, 0x0D,
0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x6D, 0x5F,
0x41, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x3B,
0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x20, 0x31, 0x36, 0x20,
0x62, 0x79, 0x74, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E,
0x74, 0x20, 0x75, 0x5F, 0x48, 0x61, 0x73, 0x4D, 0x65, 0x74, 0x61, 0x6C,
0x6E, 0x65, 0x73, 0x73, 0x3B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F,
0x20, 0x20, 0x33, 0x32, 0x20, 0x62, 0x79, 0x74, 0x65, 0x0D, 0x0A, 0x20,
0x20, 0x20, 0x20, 0x66, 0x6C, 0x6F, 0x61, 0x74, 0x20, 0x75, 0x5F, 0x4D,
0x65, 0x74, 0x61, 0x6C, 0x6E, 0x65, 0x73, 0x73, 0x56, 0x61, 0x6C, 0x75,
0x65, 0x3B, 0x20, 0x2F, 0x2F, 0x20, 0x20, 0x33, 0x36, 0x20, 0x62, 0x79,
0x74, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x74, 0x20,
0x75, 0x5F, 0x48, 0x61, 0x73, 0x52, 0x6F, 0x75, 0x67, 0x68, 0x6E, 0x65,
0x73, 0x73, 0x3B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x20,
0x34, 0x30, 0x20, 0x62, 0x79, 0x74, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20,
0x20, 0x66, 0x6C, 0x6F, 0x61, 0x74, 0x20, 0x75, 0x5F, 0x52, 0x6F, 0x75,
0x67, 0x68, 0x6E, 0x65, 0x73, 0x73, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3B,
0x20, 0x2F, 0x2F, 0x20, 0x20, 0x34, 0x34, 0x20, 0x62, 0x79, 0x74, 0x65,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x74, 0x20, 0x75, 0x5F,
0x48, 0x61, 0x73, 0x41, 0x4F, 0x3B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x20, 0x34, 0x38,
0x20, 0x62, 0x79, 0x74, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x66,
0x6C, 0x6F, 0x61, 0x74, 0x20, 0x75, 0x5F, 0x41, 0x4F, 0x56, 0x61, 0x6C,
0x75, 0x65, 0x3B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F,
0x2F, 0x20, 0x20, 0x35, 0x32, 0x20, 0x62, 0x79, 0x74, 0x65, 0x0D, 0x0A,
0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x74, 0x20, 0x75, 0x5F, 0x48, 0x61,
0x73, 0x4E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x3B, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x20, 0x35, 0x36, 0x20, 0x62,
0x6D, 0x70, 0x6C, 0x65, 0x72, 0x32, 0x44, 0x20, 0x6D, 0x5F, 0x4E, 0x6F,
0x72, 0x6D, 0x61, 0x6C, 0x3B, 0x0D, 0x0A, 0x75, 0x6E, 0x69, 0x66, 0x6F,
0x72, 0x6D, 0x20, 0x73, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x72, 0x32, 0x44,
0x20, 0x6D, 0x5F, 0x44, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x6D,
0x65, 0x6E, 0x74, 0x3B, 0x0D, 0x0A, 0x75, 0x6E, 0x69, 0x66, 0x6F, 0x72,
0x6D, 0x20, 0x69, 0x6E, 0x74, 0x20, 0x75, 0x5F, 0x45, 0x6E, 0x74, 0x69,
0x74, 0x79, 0x49, 0x44, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x6C, 0x61, 0x79,
0x6F, 0x75, 0x74, 0x28, 0x73, 0x74, 0x64, 0x31, 0x34, 0x30, 0x2C, 0x20,
0x62, 0x69, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x3D, 0x20, 0x33, 0x32,
0x29, 0x20, 0x75, 0x6E, 0x69, 0x66, 0x6F, 0x72, 0x6D, 0x20, 0x75, 0x5F,
0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x55, 0x6E, 0x69, 0x66,
0x6F, 0x72, 0x6D, 0x0D, 0x0A, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
0x69, 0x6E, 0x74, 0x20, 0x75, 0x5F, 0x48, 0x61, 0x73, 0x41, 0x6C, 0x62,
0x65, 0x64, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65,
0x63, 0x33, 0x20, 0x6D, 0x5F, 0x41, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x43,
0x6F, 0x6C, 0x6F, 0x72, 0x3B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F,
0x20, 0x20, 0x31, 0x36, 0x20, 0x62, 0x79, 0x74, 0x65, 0x0D, 0x0A, 0x20,
0x20, 0x20, 0x20, 0x69, 0x6E, 0x74, 0x20, 0x75, 0x5F, 0x48, 0x61, 0x73,
0x4D, 0x65, 0x74, 0x61, 0x6C, 0x6E, 0x65, 0x73, 0x73, 0x3B, 0x20, 0x20,
0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x20, 0x33, 0x32, 0x20, 0x62, 0x79,
0x74, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6C, 0x6F, 0x61,
0x74, 0x20, 0x75, 0x5F, 0x4D, 0x65, 0x74, 0x61, 0x6C, 0x6E, 0x65, 0x73,
0x73, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3B, 0x20, 0x2F, 0x2F, 0x20, 0x20,
0x33, 0x36, 0x20, 0x62, 0x79, 0x74, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20,
0x20, 0x69, 0x6E, 0x74, 0x20, 0x75, 0x5F, 0x48, 0x61, 0x73, 0x52, 0x6F,
0x75, 0x67, 0x68, 0x6E, 0x65, 0x73, 0x73, 0x3B, 0x20, 0x20, 0x20, 0x20,
0x20, 0x2F, 0x2F, 0x20, 0x20, 0x34, 0x30, 0x20, 0x62, 0x79, 0x74, 0x65,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6C, 0x6F, 0x61, 0x74, 0x20,
0x75, 0x5F, 0x52, 0x6F, 0x75, 0x67, 0x68, 0x6E, 0x65, 0x73, 0x73, 0x56,
0x61, 0x6C, 0x75, 0x65, 0x3B, 0x20, 0x2F, 0x2F, 0x20, 0x20, 0x34, 0x34,
0x20, 0x62, 0x79, 0x74, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x69,
0x6E, 0x74, 0x20, 0x75, 0x5F, 0x48, 0x61, 0x73, 0x41, 0x4F, 0x3B, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F,
0x2F, 0x20, 0x20, 0x34, 0x38, 0x20, 0x62, 0x79, 0x74, 0x65, 0x0D, 0x0A,
0x20, 0x20, 0x20, 0x20, 0x66, 0x6C, 0x6F, 0x61, 0x74, 0x20, 0x75, 0x5F,
0x41, 0x4F, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3B, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x20, 0x35, 0x32, 0x20, 0x62,
0x79, 0x74, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x74,
0x20, 0x75, 0x5F, 0x48, 0x61, 0x73, 0x44, 0x69, 0x73, 0x70, 0x6C, 0x61,
0x63, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x3B, 0x20, 0x20, 0x2F, 0x2F, 0x20,
0x20, 0x36, 0x30, 0x20, 0x62, 0x79, 0x74, 0x65, 0x0D, 0x0A, 0x20, 0x20,
0x20, 0x20, 0x69, 0x6E, 0x74, 0x20, 0x75, 0x5F, 0x55, 0x6E, 0x6C, 0x69,
0x74, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6C, 0x6F, 0x61,
0x74, 0x20, 0x75, 0x5F, 0x45, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x76, 0x65,
0x3B, 0x0D, 0x0A, 0x7D, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x76, 0x65, 0x63,
0x33, 0x20, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x54, 0x6F, 0x57,
0x6F, 0x72, 0x6C, 0x64, 0x28, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65,
0x78, 0x43, 0x6F, 0x6F, 0x72, 0x64, 0x2C, 0x20, 0x6D, 0x61, 0x74, 0x34,
0x20, 0x76, 0x69, 0x65, 0x77, 0x4D, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2C,
0x20, 0x6D, 0x61, 0x74, 0x34, 0x20, 0x69, 0x6E, 0x76, 0x50, 0x72, 0x6F,
0x6A, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4D, 0x61, 0x74, 0x72, 0x69,
0x78, 0x29, 0x0D, 0x0A, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x2F,
0x2F, 0x20, 0x43, 0x6F, 0x6D, 0x62, 0x69, 0x6E, 0x65, 0x20, 0x74, 0x65,
0x78, 0x74, 0x75, 0x72, 0x65, 0x20, 0x63, 0x6F, 0x6F, 0x72, 0x64, 0x69,
0x6E, 0x61, 0x74, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x64, 0x65,
0x70, 0x74, 0x68, 0x20, 0x74, 0x6F, 0x20, 0x6F, 0x62, 0x74, 0x61, 0x69,
0x6E, 0x20, 0x63, 0x6C, 0x69, 0x70, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65,
0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x0D, 0x0A, 0x20,
0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x63, 0x6C, 0x69, 0x70,
0x43, 0x6F, 0x6F, 0x72, 0x64, 0x20, 0x3D, 0x20, 0x76, 0x65, 0x63, 0x34,
0x28, 0x74, 0x65, 0x78, 0x43, 0x6F, 0x6F, 0x72, 0x64, 0x20, 0x2A, 0x20,
0x32, 0x2E, 0x30, 0x20, 0x2D, 0x20, 0x31, 0x2E, 0x30, 0x2C, 0x20, 0x30,
0x2E, 0x30, 0x2C, 0x20, 0x31, 0x2E, 0x30, 0x29, 0x3B, 0x0D, 0x0A, 0x0D,
0x0A, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x54, 0x72, 0x61, 0x6E,
0x73, 0x66, 0x6F, 0x72, 0x6D, 0x20, 0x63, 0x6C, 0x69, 0x70, 0x20, 0x73,
0x70, 0x61, 0x63, 0x65, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F,
0x6E, 0x20, 0x74, 0x6F, 0x20, 0x76, 0x69, 0x65, 0x77, 0x20, 0x73, 0x70,
0x61, 0x63, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63,
0x34, 0x20, 0x76, 0x69, 0x65, 0x77, 0x43, 0x6F, 0x6F, 0x72, 0x64, 0x20,
0x3D, 0x20, 0x69, 0x6E, 0x76, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74,
0x69, 0x6F, 0x6E, 0x4D, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x2A, 0x20,
0x63, 0x6C, 0x69, 0x70, 0x43, 0x6F, 0x6F, 0x72, 0x64, 0x3B, 0x0D, 0x0A,
0x20, 0x20, 0x20, 0x20, 0x76, 0x69, 0x65, 0x77, 0x43, 0x6F, 0x6F, 0x72,
0x64, 0x20, 0x2F, 0x3D, 0x20, 0x76, 0x69, 0x65, 0x77, 0x43, 0x6F, 0x6F,
0x72, 0x64, 0x2E, 0x77, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20,
0x20, 0x2F, 0x2F, 0x20, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72,
0x6D, 0x20, 0x76, 0x69, 0x65, 0x77, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65,
0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x6F,
0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x77,
0x6F, 0x72, 0x6C, 0x64, 0x43, 0x6F, 0x6F, 0x72, 0x64, 0x20, 0x3D, 0x20,
0x76, 0x69, 0x65, 0x77, 0x4D, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x2A,
0x20, 0x76, 0x69, 0x65, 0x77, 0x43, 0x6F, 0x6F, 0x72, 0x64, 0x3B, 0x0D,
0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72,
0x6E, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x43, 0x6F, 0x6F, 0x72, 0x64,
0x2E, 0x78, 0x79, 0x7A, 0x3B, 0x0D, 0x0A, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A,
0x76, 0x6F, 0x69, 0x64, 0x20, 0x6D, 0x61, 0x69, 0x6E, 0x28, 0x29, 0x0D,
0x0A, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x4E,
0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76,
0x65, 0x63, 0x33, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x20, 0x3D,
0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x30, 0x2E, 0x35, 0x2C, 0x20, 0x30,
0x2E, 0x35, 0x2C, 0x20, 0x31, 0x2E, 0x30, 0x29, 0x3B, 0x0D, 0x0A, 0x20,
0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x75, 0x5F, 0x48, 0x61, 0x73,
0x4E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x20, 0x3D, 0x3D, 0x20, 0x31, 0x29,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x20,
0x3D, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x6D, 0x5F,
0x4E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x2C, 0x20, 0x55, 0x56, 0x29, 0x2E,
0x72, 0x67, 0x62, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D,
0x0A, 0x20, 0x20, 0x20, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x20,
0x3D, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x20, 0x2A, 0x20, 0x32,
0x2E, 0x30, 0x20, 0x2D, 0x20, 0x31, 0x2E, 0x30, 0x3B, 0x0D, 0x0A, 0x20,
0x20, 0x20, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x20, 0x3D, 0x20,
0x54, 0x42, 0x4E, 0x20, 0x2A, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C,
0x69, 0x7A, 0x65, 0x28, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x29, 0x3B,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x67, 0x4E, 0x6F, 0x72, 0x6D, 0x61,
0x6C, 0x20, 0x3D, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x6E, 0x6F, 0x72,
0x6D, 0x61, 0x6C, 0x20, 0x2F, 0x20, 0x32, 0x2E, 0x30, 0x20, 0x2B, 0x20,
0x30, 0x2E, 0x35, 0x2C, 0x20, 0x31, 0x2E, 0x30, 0x66, 0x29, 0x3B, 0x0D,
0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x41, 0x6C,
0x62, 0x65, 0x64, 0x6F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x67, 0x41,
0x6C, 0x62, 0x65, 0x64, 0x6F, 0x20, 0x3D, 0x20, 0x76, 0x65, 0x63, 0x34,
0x28, 0x6D, 0x5F, 0x41, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x43, 0x6F, 0x6C,
0x6F, 0x72, 0x2C, 0x20, 0x31, 0x2E, 0x30, 0x66, 0x29, 0x3B, 0x0D, 0x0A,
0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x75, 0x5F, 0x48, 0x61,
0x73, 0x41, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x20, 0x3D, 0x3D, 0x20, 0x31,
0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x61,
0x6C, 0x62, 0x65, 0x64, 0x6F, 0x53, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x20,
0x3D, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x6D, 0x5F,
0x41, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x2C, 0x20, 0x55, 0x56, 0x29, 0x3B,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x67, 0x41,
0x6C, 0x62, 0x65, 0x64, 0x6F, 0x2E, 0x72, 0x67, 0x62, 0x20, 0x3D, 0x20,
0x61, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x53, 0x61, 0x6D, 0x70, 0x6C, 0x65,
0x2E, 0x72, 0x67, 0x62, 0x20, 0x2A, 0x20, 0x6D, 0x5F, 0x41, 0x6C, 0x62,
0x65, 0x64, 0x6F, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x2E, 0x72, 0x67, 0x62,
0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x67,
0x41, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x2E, 0x61, 0x20, 0x3D, 0x20, 0x61,
0x6C, 0x62, 0x65, 0x64, 0x6F, 0x53, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x2E,
0x61, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x61, 0x6C, 0x62, 0x65, 0x64, 0x6F,
0x53, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x2E, 0x61, 0x20, 0x3C, 0x20, 0x30,
0x2E, 0x31, 0x66, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64,
0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20,
0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69,
0x61, 0x6C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6C, 0x6F, 0x61,
0x74, 0x20, 0x66, 0x69, 0x6E, 0x61, 0x6C, 0x4D, 0x65, 0x74, 0x61, 0x6C,
0x6E, 0x65, 0x73, 0x73, 0x20, 0x3D, 0x20, 0x75, 0x5F, 0x4D, 0x65, 0x74,
0x61, 0x6C, 0x6E, 0x65, 0x73, 0x73, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3B,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x75, 0x5F,
0x48, 0x61, 0x73, 0x4D, 0x65, 0x74, 0x61, 0x6C, 0x6E, 0x65, 0x73, 0x73,
0x20, 0x75, 0x5F, 0x48, 0x61, 0x73, 0x4E, 0x6F, 0x72, 0x6D, 0x61, 0x6C,
0x3B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20,
0x20, 0x35, 0x36, 0x20, 0x62, 0x79, 0x74, 0x65, 0x0D, 0x0A, 0x20, 0x20,
0x20, 0x20, 0x69, 0x6E, 0x74, 0x20, 0x75, 0x5F, 0x48, 0x61, 0x73, 0x44,
0x69, 0x73, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x3B,
0x20, 0x20, 0x2F, 0x2F, 0x20, 0x20, 0x36, 0x30, 0x20, 0x62, 0x79, 0x74,
0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x74, 0x20, 0x75,
0x5F, 0x55, 0x6E, 0x6C, 0x69, 0x74, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20,
0x20, 0x66, 0x6C, 0x6F, 0x61, 0x74, 0x20, 0x75, 0x5F, 0x45, 0x6D, 0x69,
0x73, 0x73, 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, 0x7D, 0x3B, 0x0D, 0x0A,
0x0D, 0x0A, 0x76, 0x65, 0x63, 0x33, 0x20, 0x54, 0x65, 0x78, 0x74, 0x75,
0x72, 0x65, 0x54, 0x6F, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x28, 0x76, 0x65,
0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x43, 0x6F, 0x6F, 0x72, 0x64, 0x2C,
0x20, 0x6D, 0x61, 0x74, 0x34, 0x20, 0x76, 0x69, 0x65, 0x77, 0x4D, 0x61,
0x74, 0x72, 0x69, 0x78, 0x2C, 0x20, 0x6D, 0x61, 0x74, 0x34, 0x20, 0x69,
0x6E, 0x76, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
0x4D, 0x61, 0x74, 0x72, 0x69, 0x78, 0x29, 0x0D, 0x0A, 0x7B, 0x0D, 0x0A,
0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x43, 0x6F, 0x6D, 0x62, 0x69,
0x6E, 0x65, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x20, 0x63,
0x6F, 0x6F, 0x72, 0x64, 0x69, 0x6E, 0x61, 0x74, 0x65, 0x20, 0x77, 0x69,
0x74, 0x68, 0x20, 0x64, 0x65, 0x70, 0x74, 0x68, 0x20, 0x74, 0x6F, 0x20,
0x6F, 0x62, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x63, 0x6C, 0x69, 0x70, 0x20,
0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69,
0x6F, 0x6E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x34,
0x20, 0x63, 0x6C, 0x69, 0x70, 0x43, 0x6F, 0x6F, 0x72, 0x64, 0x20, 0x3D,
0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x74, 0x65, 0x78, 0x43, 0x6F, 0x6F,
0x72, 0x64, 0x20, 0x2A, 0x20, 0x32, 0x2E, 0x30, 0x20, 0x2D, 0x20, 0x31,
0x2E, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x30, 0x2C, 0x20, 0x31, 0x2E, 0x30,
0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F,
0x20, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x20, 0x63,
0x6C, 0x69, 0x70, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x70, 0x6F,
0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x76, 0x69,
0x65, 0x77, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x0D, 0x0A, 0x20, 0x20,
0x20, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x76, 0x69, 0x65, 0x77, 0x43,
0x6F, 0x6F, 0x72, 0x64, 0x20, 0x3D, 0x20, 0x69, 0x6E, 0x76, 0x50, 0x72,
0x6F, 0x6A, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4D, 0x61, 0x74, 0x72,
0x69, 0x78, 0x20, 0x2A, 0x20, 0x63, 0x6C, 0x69, 0x70, 0x43, 0x6F, 0x6F,
0x72, 0x64, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x69, 0x65,
0x77, 0x43, 0x6F, 0x6F, 0x72, 0x64, 0x20, 0x2F, 0x3D, 0x20, 0x76, 0x69,
0x65, 0x77, 0x43, 0x6F, 0x6F, 0x72, 0x64, 0x2E, 0x77, 0x3B, 0x0D, 0x0A,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x54, 0x72, 0x61,
0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x20, 0x76, 0x69, 0x65, 0x77, 0x20,
0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69,
0x6F, 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x20,
0x73, 0x70, 0x61, 0x63, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76,
0x65, 0x63, 0x34, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x43, 0x6F, 0x6F,
0x72, 0x64, 0x20, 0x3D, 0x20, 0x76, 0x69, 0x65, 0x77, 0x4D, 0x61, 0x74,
0x72, 0x69, 0x78, 0x20, 0x2A, 0x20, 0x76, 0x69, 0x65, 0x77, 0x43, 0x6F,
0x6F, 0x72, 0x64, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64,
0x43, 0x6F, 0x6F, 0x72, 0x64, 0x2E, 0x78, 0x79, 0x7A, 0x3B, 0x0D, 0x0A,
0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x76, 0x6F, 0x69, 0x64, 0x20, 0x6D, 0x61,
0x69, 0x6E, 0x28, 0x29, 0x0D, 0x0A, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20,
0x20, 0x2F, 0x2F, 0x20, 0x4E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x0D, 0x0A,
0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x6E, 0x6F, 0x72,
0x6D, 0x61, 0x6C, 0x20, 0x3D, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x30,
0x2E, 0x35, 0x2C, 0x20, 0x30, 0x2E, 0x35, 0x2C, 0x20, 0x31, 0x2E, 0x30,
0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28,
0x75, 0x5F, 0x48, 0x61, 0x73, 0x4E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x20,
0x3D, 0x3D, 0x20, 0x31, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x7B,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6E, 0x6F,
0x72, 0x6D, 0x61, 0x6C, 0x20, 0x3D, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75,
0x72, 0x65, 0x28, 0x6D, 0x5F, 0x4E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x2C,
0x20, 0x55, 0x56, 0x29, 0x2E, 0x72, 0x67, 0x62, 0x3B, 0x0D, 0x0A, 0x20,
0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x6E, 0x6F,
0x72, 0x6D, 0x61, 0x6C, 0x20, 0x3D, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61,
0x6C, 0x20, 0x2A, 0x20, 0x32, 0x2E, 0x30, 0x20, 0x2D, 0x20, 0x31, 0x2E,
0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x6E, 0x6F, 0x72, 0x6D,
0x61, 0x6C, 0x20, 0x3D, 0x20, 0x54, 0x42, 0x4E, 0x20, 0x2A, 0x20, 0x6E,
0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x69, 0x7A, 0x65, 0x28, 0x6E, 0x6F, 0x72,
0x6D, 0x61, 0x6C, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x67,
0x4E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x20, 0x3D, 0x20, 0x76, 0x65, 0x63,
0x34, 0x28, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x20, 0x2F, 0x20, 0x32,
0x2E, 0x30, 0x20, 0x2B, 0x20, 0x30, 0x2E, 0x35, 0x2C, 0x20, 0x31, 0x2E,
0x30, 0x66, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
0x2F, 0x2F, 0x20, 0x41, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x0D, 0x0A, 0x20,
0x20, 0x20, 0x20, 0x67, 0x41, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x20, 0x3D,
0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x6D, 0x5F, 0x41, 0x6C, 0x62, 0x65,
0x64, 0x6F, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x2C, 0x20, 0x31, 0x2E, 0x30,
0x66, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20,
0x28, 0x75, 0x5F, 0x48, 0x61, 0x73, 0x41, 0x6C, 0x62, 0x65, 0x64, 0x6F,
0x20, 0x3D, 0x3D, 0x20, 0x31, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6E, 0x61, 0x6C, 0x4D, 0x65, 0x74,
0x61, 0x6C, 0x6E, 0x65, 0x73, 0x73, 0x20, 0x3D, 0x20, 0x74, 0x65, 0x78,
0x74, 0x75, 0x72, 0x65, 0x28, 0x6D, 0x5F, 0x4D, 0x65, 0x74, 0x61, 0x6C,
0x6E, 0x65, 0x73, 0x73, 0x2C, 0x20, 0x55, 0x56, 0x29, 0x2E, 0x72, 0x3B,
0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6C, 0x6F, 0x61,
0x74, 0x20, 0x66, 0x69, 0x6E, 0x61, 0x6C, 0x41, 0x4F, 0x20, 0x3D, 0x20,
0x75, 0x5F, 0x41, 0x4F, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3B, 0x0D, 0x0A,
0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x75, 0x5F, 0x48, 0x61,
0x73, 0x41, 0x4F, 0x20, 0x3D, 0x3D, 0x20, 0x31, 0x29, 0x0D, 0x0A, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6E, 0x61, 0x6C,
0x41, 0x4F, 0x20, 0x3D, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65,
0x28, 0x6D, 0x5F, 0x41, 0x4F, 0x2C, 0x20, 0x55, 0x56, 0x29, 0x2E, 0x72,
0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6C, 0x6F,
0x61, 0x74, 0x20, 0x66, 0x69, 0x6E, 0x61, 0x6C, 0x52, 0x6F, 0x75, 0x67,
0x68, 0x6E, 0x65, 0x73, 0x73, 0x20, 0x3D, 0x20, 0x75, 0x5F, 0x52, 0x6F,
0x75, 0x67, 0x68, 0x6E, 0x65, 0x73, 0x73, 0x56, 0x61, 0x6C, 0x75, 0x65,
0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x75,
0x5F, 0x48, 0x61, 0x73, 0x52, 0x6F, 0x75, 0x67, 0x68, 0x6E, 0x65, 0x73,
0x73, 0x20, 0x3D, 0x3D, 0x20, 0x31, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6E, 0x61, 0x6C, 0x52, 0x6F,
0x75, 0x67, 0x68, 0x6E, 0x65, 0x73, 0x73, 0x20, 0x3D, 0x20, 0x74, 0x65,
0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x6D, 0x5F, 0x52, 0x6F, 0x75, 0x67,
0x68, 0x6E, 0x65, 0x73, 0x73, 0x2C, 0x20, 0x55, 0x56, 0x29, 0x2E, 0x72,
0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x67, 0x4D, 0x61,
0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x20, 0x3D, 0x20, 0x76, 0x65, 0x63,
0x34, 0x28, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x75,
0x5F, 0x55, 0x6E, 0x6C, 0x69, 0x74, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20,
0x20, 0x20, 0x67, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x2E,
0x72, 0x20, 0x3D, 0x20, 0x66, 0x69, 0x6E, 0x61, 0x6C, 0x4D, 0x65, 0x74,
0x61, 0x6C, 0x6E, 0x65, 0x73, 0x73, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20,
0x20, 0x67, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x2E, 0x67,
0x20, 0x3D, 0x20, 0x66, 0x69, 0x6E, 0x61, 0x6C, 0x41, 0x4F, 0x3B, 0x0D,
0x0A, 0x20, 0x20, 0x20, 0x20, 0x67, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69,
0x61, 0x6C, 0x2E, 0x62, 0x20, 0x3D, 0x20, 0x66, 0x69, 0x6E, 0x61, 0x6C,
0x52, 0x6F, 0x75, 0x67, 0x68, 0x6E, 0x65, 0x73, 0x73, 0x3B, 0x0D, 0x0A,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x67, 0x45, 0x6E, 0x74, 0x69, 0x74,
0x79, 0x49, 0x44, 0x20, 0x3D, 0x20, 0x69, 0x6E, 0x74, 0x28, 0x75, 0x5F,
0x45, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x49, 0x44, 0x29, 0x3B, 0x0D, 0x0A,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x67, 0x45, 0x6D, 0x69, 0x73, 0x73,
0x69, 0x76, 0x65, 0x20, 0x3D, 0x20, 0x75, 0x5F, 0x45, 0x6D, 0x69, 0x73,
0x73, 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20,
0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20,
0x3D, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x31, 0x2E, 0x30, 0x2C, 0x20,
0x30, 0x2C, 0x20, 0x30, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3D, 0x20, 0x54, 0x42, 0x4E, 0x20,
0x2A, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x69, 0x7A, 0x65, 0x28,
0x72, 0x69, 0x67, 0x68, 0x74, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20,
0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x75, 0x70, 0x20, 0x3D, 0x20, 0x54,
0x42, 0x4E, 0x20, 0x2A, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x69,
0x7A, 0x65, 0x28, 0x76, 0x65, 0x63, 0x33, 0x28, 0x30, 0x2C, 0x20, 0x31,
0x2C, 0x20, 0x30, 0x29, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20,
0x20, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75,
0x72, 0x65, 0x53, 0x69, 0x7A, 0x65, 0x32, 0x64, 0x20, 0x3D, 0x20, 0x74,
0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, 0x69, 0x7A, 0x65, 0x28, 0x6D,
0x5F, 0x41, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x2C, 0x20, 0x30, 0x29, 0x3B,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x70,
0x69, 0x78, 0x65, 0x6C, 0x50, 0x6F, 0x73, 0x20, 0x3D, 0x20, 0x55, 0x56,
0x20, 0x2A, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, 0x69,
0x7A, 0x65, 0x32, 0x64, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76,
0x65, 0x63, 0x32, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x4F, 0x66,
0x50, 0x69, 0x78, 0x65, 0x6C, 0x20, 0x3D, 0x20, 0x28, 0x76, 0x65, 0x63,
0x32, 0x28, 0x30, 0x2E, 0x35, 0x29, 0x20, 0x2B, 0x20, 0x66, 0x6C, 0x6F,
0x6F, 0x72, 0x28, 0x70, 0x69, 0x78, 0x65, 0x6C, 0x50, 0x6F, 0x73, 0x29,
0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x32,
0x20, 0x75, 0x76, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x3D, 0x20,
0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x4F, 0x66, 0x50, 0x69, 0x78, 0x65,
0x6C, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65,
0x63, 0x33, 0x20, 0x75, 0x76, 0x44, 0x69, 0x66, 0x66, 0x20, 0x3D, 0x20,
0x76, 0x65, 0x63, 0x33, 0x28, 0x75, 0x76, 0x43, 0x65, 0x6E, 0x74, 0x65,
0x72, 0x2E, 0x78, 0x20, 0x2D, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6C, 0x50,
0x6F, 0x73, 0x2E, 0x78, 0x2C, 0x20, 0x75, 0x76, 0x43, 0x65, 0x6E, 0x74,
0x65, 0x72, 0x2E, 0x79, 0x20, 0x2D, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6C,
0x50, 0x6F, 0x73, 0x2E, 0x79, 0x2C, 0x20, 0x30, 0x2E, 0x30, 0x66, 0x29,
0x20, 0x2F, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x74, 0x65, 0x78, 0x74,
0x75, 0x72, 0x65, 0x53, 0x69, 0x7A, 0x65, 0x32, 0x64, 0x2E, 0x78, 0x2C,
0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, 0x69, 0x7A, 0x65,
0x32, 0x64, 0x2E, 0x79, 0x2C, 0x20, 0x31, 0x2E, 0x30, 0x66, 0x29, 0x3B,
0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x75, 0x76, 0x44, 0x69,
0x66, 0x66, 0x20, 0x3D, 0x20, 0x75, 0x76, 0x44, 0x69, 0x66, 0x66, 0x2E,
0x78, 0x20, 0x2A, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3B, 0x0D, 0x0A,
0x20, 0x20, 0x20, 0x20, 0x75, 0x76, 0x44, 0x69, 0x66, 0x66, 0x20, 0x3D,
0x20, 0x75, 0x76, 0x44, 0x69, 0x66, 0x66, 0x2E, 0x79, 0x20, 0x2A, 0x20,
0x75, 0x70, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x75,
0x76, 0x44, 0x69, 0x66, 0x66, 0x20, 0x2A, 0x20, 0x72, 0x69, 0x67, 0x68,
0x74, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x75, 0x76, 0x44, 0x69,
0x66, 0x66, 0x20, 0x3D, 0x20, 0x75, 0x76, 0x44, 0x69, 0x66, 0x66, 0x20,
0x2A, 0x20, 0x31, 0x30, 0x30, 0x2E, 0x30, 0x66, 0x3B, 0x0D, 0x0A, 0x20,
0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x6F, 0x66, 0x66, 0x73,
0x65, 0x74, 0x20, 0x3D, 0x20, 0x28, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72,
0x4F, 0x66, 0x50, 0x69, 0x78, 0x65, 0x6C, 0x20, 0x2D, 0x20, 0x76, 0x65,
0x63, 0x32, 0x28, 0x46, 0x72, 0x61, 0x67, 0x50, 0x6F, 0x73, 0x2E, 0x78,
0x2C, 0x20, 0x46, 0x72, 0x61, 0x67, 0x50, 0x6F, 0x73, 0x2E, 0x79, 0x29,
0x29, 0x20, 0x2A, 0x20, 0x31, 0x30, 0x2E, 0x30, 0x66, 0x3B, 0x0D, 0x0A,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x66,
0x69, 0x6E, 0x61, 0x6C, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72,
0x6D, 0x65, 0x64, 0x20, 0x3D, 0x20, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61,
0x6C, 0x69, 0x7A, 0x65, 0x28, 0x75, 0x76, 0x44, 0x69, 0x66, 0x66, 0x29,
0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20,
0x63, 0x6F, 0x6E, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x3D,
0x20, 0x49, 0x6E, 0x76, 0x5F, 0x50, 0x72, 0x6F, 0x6A, 0x20, 0x2A, 0x20,
0x49, 0x6E, 0x76, 0x5F, 0x56, 0x69, 0x65, 0x77, 0x20, 0x2A, 0x20, 0x76,
0x65, 0x63, 0x34, 0x28, 0x66, 0x69, 0x6E, 0x61, 0x6C, 0x54, 0x72, 0x61,
0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x65, 0x64, 0x2C, 0x20, 0x31, 0x2E,
0x30, 0x66, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x67, 0x54,
0x65, 0x78, 0x65, 0x6C, 0x4F, 0x66, 0x66, 0x73, 0x65, 0x74, 0x20, 0x3D,
0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x63, 0x6F, 0x6E, 0x76, 0x65, 0x72,
0x73, 0x69, 0x6F, 0x6E, 0x2E, 0x78, 0x20, 0x2F, 0x20, 0x32, 0x2E, 0x30,
0x20, 0x2B, 0x20, 0x30, 0x2E, 0x35, 0x66, 0x2C, 0x20, 0x63, 0x6F, 0x6E,
0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x2E, 0x79, 0x20, 0x2F, 0x20,
0x32, 0x2E, 0x30, 0x20, 0x2B, 0x20, 0x30, 0x2E, 0x35, 0x66, 0x2C, 0x20,
0x30, 0x2C, 0x20, 0x31, 0x29, 0x3B, 0x0D, 0x0A, 0x7D,
0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76,
0x65, 0x63, 0x34, 0x20, 0x61, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x53, 0x61,
0x6D, 0x70, 0x6C, 0x65, 0x20, 0x3D, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75,
0x72, 0x65, 0x28, 0x6D, 0x5F, 0x41, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x2C,
0x20, 0x55, 0x56, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x67, 0x41, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x2E, 0x72,
0x67, 0x62, 0x20, 0x3D, 0x20, 0x61, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x53,
0x61, 0x6D, 0x70, 0x6C, 0x65, 0x2E, 0x72, 0x67, 0x62, 0x20, 0x2A, 0x20,
0x6D, 0x5F, 0x41, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x43, 0x6F, 0x6C, 0x6F,
0x72, 0x2E, 0x72, 0x67, 0x62, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x67, 0x41, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x2E,
0x61, 0x20, 0x3D, 0x20, 0x61, 0x6C, 0x62, 0x65, 0x64, 0x6F, 0x53, 0x61,
0x6D, 0x70, 0x6C, 0x65, 0x2E, 0x61, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x61,
0x6C, 0x62, 0x65, 0x64, 0x6F, 0x53, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x2E,
0x61, 0x20, 0x3C, 0x20, 0x30, 0x2E, 0x31, 0x66, 0x29, 0x0D, 0x0A, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69,
0x73, 0x63, 0x61, 0x72, 0x64, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x7D,
0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x4D,
0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x0D, 0x0A, 0x20, 0x20, 0x20,
0x20, 0x66, 0x6C, 0x6F, 0x61, 0x74, 0x20, 0x66, 0x69, 0x6E, 0x61, 0x6C,
0x4D, 0x65, 0x74, 0x61, 0x6C, 0x6E, 0x65, 0x73, 0x73, 0x20, 0x3D, 0x20,
0x75, 0x5F, 0x4D, 0x65, 0x74, 0x61, 0x6C, 0x6E, 0x65, 0x73, 0x73, 0x56,
0x61, 0x6C, 0x75, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x69,
0x66, 0x20, 0x28, 0x75, 0x5F, 0x48, 0x61, 0x73, 0x4D, 0x65, 0x74, 0x61,
0x6C, 0x6E, 0x65, 0x73, 0x73, 0x20, 0x3D, 0x3D, 0x20, 0x31, 0x29, 0x0D,
0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6E,
0x61, 0x6C, 0x4D, 0x65, 0x74, 0x61, 0x6C, 0x6E, 0x65, 0x73, 0x73, 0x20,
0x3D, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x6D, 0x5F,
0x4D, 0x65, 0x74, 0x61, 0x6C, 0x6E, 0x65, 0x73, 0x73, 0x2C, 0x20, 0x55,
0x56, 0x29, 0x2E, 0x72, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20,
0x20, 0x66, 0x6C, 0x6F, 0x61, 0x74, 0x20, 0x66, 0x69, 0x6E, 0x61, 0x6C,
0x41, 0x4F, 0x20, 0x3D, 0x20, 0x75, 0x5F, 0x41, 0x4F, 0x56, 0x61, 0x6C,
0x75, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20,
0x28, 0x75, 0x5F, 0x48, 0x61, 0x73, 0x41, 0x4F, 0x20, 0x3D, 0x3D, 0x20,
0x31, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x66, 0x69, 0x6E, 0x61, 0x6C, 0x41, 0x4F, 0x20, 0x3D, 0x20, 0x74, 0x65,
0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x6D, 0x5F, 0x41, 0x4F, 0x2C, 0x20,
0x55, 0x56, 0x29, 0x2E, 0x72, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20,
0x20, 0x20, 0x66, 0x6C, 0x6F, 0x61, 0x74, 0x20, 0x66, 0x69, 0x6E, 0x61,
0x6C, 0x52, 0x6F, 0x75, 0x67, 0x68, 0x6E, 0x65, 0x73, 0x73, 0x20, 0x3D,
0x20, 0x75, 0x5F, 0x52, 0x6F, 0x75, 0x67, 0x68, 0x6E, 0x65, 0x73, 0x73,
0x56, 0x61, 0x6C, 0x75, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
0x69, 0x66, 0x20, 0x28, 0x75, 0x5F, 0x48, 0x61, 0x73, 0x52, 0x6F, 0x75,
0x67, 0x68, 0x6E, 0x65, 0x73, 0x73, 0x20, 0x3D, 0x3D, 0x20, 0x31, 0x29,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x69,
0x6E, 0x61, 0x6C, 0x52, 0x6F, 0x75, 0x67, 0x68, 0x6E, 0x65, 0x73, 0x73,
0x20, 0x3D, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x6D,
0x5F, 0x52, 0x6F, 0x75, 0x67, 0x68, 0x6E, 0x65, 0x73, 0x73, 0x2C, 0x20,
0x55, 0x56, 0x29, 0x2E, 0x72, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20,
0x20, 0x20, 0x67, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x20,
0x3D, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x30, 0x2C, 0x20, 0x30, 0x2C,
0x20, 0x30, 0x2C, 0x20, 0x75, 0x5F, 0x55, 0x6E, 0x6C, 0x69, 0x74, 0x29,
0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x67, 0x4D, 0x61, 0x74, 0x65,
0x72, 0x69, 0x61, 0x6C, 0x2E, 0x72, 0x20, 0x3D, 0x20, 0x66, 0x69, 0x6E,
0x61, 0x6C, 0x4D, 0x65, 0x74, 0x61, 0x6C, 0x6E, 0x65, 0x73, 0x73, 0x3B,
0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x67, 0x4D, 0x61, 0x74, 0x65, 0x72,
0x69, 0x61, 0x6C, 0x2E, 0x67, 0x20, 0x3D, 0x20, 0x66, 0x69, 0x6E, 0x61,
0x6C, 0x41, 0x4F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x67, 0x4D,
0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x2E, 0x62, 0x20, 0x3D, 0x20,
0x66, 0x69, 0x6E, 0x61, 0x6C, 0x52, 0x6F, 0x75, 0x67, 0x68, 0x6E, 0x65,
0x73, 0x73, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x67,
0x45, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x49, 0x44, 0x20, 0x3D, 0x20, 0x69,
0x6E, 0x74, 0x28, 0x75, 0x5F, 0x45, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x49,
0x44, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x67, 0x45, 0x6D,
0x69, 0x73, 0x73, 0x69, 0x76, 0x65, 0x20, 0x3D, 0x20, 0x75, 0x5F, 0x45,
0x6D, 0x69, 0x73, 0x73, 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A,
0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x70, 0x6F, 0x73,
0x69, 0x74, 0x69, 0x6F, 0x6E, 0x44, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65,
0x6E, 0x63, 0x65, 0x20, 0x3D, 0x20, 0x46, 0x72, 0x61, 0x67, 0x50, 0x6F,
0x73, 0x20, 0x2D, 0x20, 0x50, 0x72, 0x65, 0x76, 0x69, 0x6F, 0x75, 0x73,
0x46, 0x72, 0x61, 0x67, 0x50, 0x6F, 0x73, 0x3B, 0x0D, 0x0A, 0x20, 0x20,
0x20, 0x20, 0x67, 0x56, 0x65, 0x6C, 0x6F, 0x63, 0x69, 0x74, 0x79, 0x20,
0x3D, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x28, 0x70, 0x6F, 0x73, 0x69,
0x74, 0x69, 0x6F, 0x6E, 0x44, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6E,
0x63, 0x65, 0x2E, 0x78, 0x20, 0x2B, 0x20, 0x31, 0x2E, 0x30, 0x29, 0x20,
0x2F, 0x20, 0x32, 0x2E, 0x30, 0x2C, 0x20, 0x28, 0x70, 0x6F, 0x73, 0x69,
0x74, 0x69, 0x6F, 0x6E, 0x44, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6E,
0x63, 0x65, 0x2E, 0x79, 0x20, 0x2B, 0x20, 0x31, 0x2E, 0x30, 0x29, 0x20,
0x2F, 0x20, 0x32, 0x2E, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x30, 0x66, 0x2C,
0x20, 0x31, 0x29, 0x3B, 0x0D, 0x0A, 0x7D,
};
unsigned int Resources_Shaders_gbuffer_shader_len = sizeof(Resources_Shaders_gbuffer_shader);

View File

@@ -16,6 +16,8 @@ namespace Nuake
Matrix4 LocalTransform;
Matrix4 GlobalTransform;
Matrix4 PreviousTransform;
public:
bool Dirty = true;
bool GlobalDirty = true;

View File

@@ -10,6 +10,8 @@ layout(location = 4) in vec3 Bitangent;
uniform mat4 u_Model;
uniform mat4 u_View;
uniform mat4 u_Projection;
uniform mat4 u_PreviousViewModel;
uniform vec2 u_Jitter;
out vec4 FragPos;
out mat3 TBN;
@@ -18,6 +20,7 @@ out mat4 Inv_Proj;
out mat4 Inv_View;
out mat4 view;
out vec3 o_Tangent;
out vec4 PreviousFragPos;
void main()
{
@@ -37,8 +40,11 @@ void main()
Inv_View = u_View;
o_Tangent = Tangent;
gl_Position = u_Projection * u_View * u_Model * vec4(VertexPosition, 1.0f);
FragPos = gl_Position;
vec4 clipPosition = u_Projection * u_View * u_Model * vec4(VertexPosition, 1.0f);
FragPos = clipPosition;
gl_Position = clipPosition;
PreviousFragPos = u_PreviousViewModel * vec4(VertexPosition, 1.0f);
}
#shader fragment
@@ -49,14 +55,14 @@ layout(location = 1) out vec4 gNormal;
layout(location = 2) out vec4 gMaterial;
layout(location = 3) out int gEntityID;
layout(location = 4) out float gEmissive;
layout(location = 5) out vec4 gTexelOffset;
layout(location = 5) out vec4 gVelocity;
in vec4 FragPos;
in vec2 UV;
in mat3 TBN;
in mat4 Inv_Proj;
in mat4 Inv_View;
in vec4 PreviousFragPos;
// Material
uniform sampler2D m_Albedo;
@@ -143,27 +149,8 @@ void main()
gMaterial.b = finalRoughness;
gEntityID = int(u_EntityID);
gEmissive = u_Emissive;
vec3 right = vec3(1.0, 0, 0);
right = TBN * normalize(right);
vec3 up = TBN * normalize(vec3(0, 1, 0));
vec2 textureSize2d = textureSize(m_Albedo, 0);
vec2 pixelPos = UV * textureSize2d;
vec2 centerOfPixel = (vec2(0.5) + floor(pixelPos));
vec2 uvCenter = centerOfPixel;
vec3 uvDiff = vec3(uvCenter.x - pixelPos.x, uvCenter.y - pixelPos.y, 0.0f) / vec3(textureSize2d.x, textureSize2d.y, 1.0f);
uvDiff = uvDiff.x * right;
uvDiff = uvDiff.y * up;
//uvDiff * right;
uvDiff = uvDiff * 100.0f;
vec2 offset = (centerOfPixel - vec2(FragPos.x, FragPos.y)) * 10.0f;
vec3 finalTransformed = normalize(uvDiff);
vec4 conversion = Inv_Proj * Inv_View * vec4(finalTransformed, 1.0f);
gTexelOffset = vec4(conversion.x / 2.0 + 0.5f, conversion.y / 2.0 + 0.5f, 0, 1);
vec4 positionDifference = FragPos - PreviousFragPos;
gVelocity = vec4((positionDifference.x + 1.0) / 2.0, (positionDifference.y + 1.0) / 2.0, 0.0f, 1);
}