From b07d90c0a249616af61f7805ef57f30658c1155a Mon Sep 17 00:00:00 2001 From: tino <79853146+tinodin@users.noreply.github.com> Date: Mon, 19 May 2025 17:34:30 +0200 Subject: [PATCH 1/7] Add files via upload --- mods/auto-theme-switcher.wh.cpp | 168 ++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 mods/auto-theme-switcher.wh.cpp diff --git a/mods/auto-theme-switcher.wh.cpp b/mods/auto-theme-switcher.wh.cpp new file mode 100644 index 000000000..7a748d5e7 --- /dev/null +++ b/mods/auto-theme-switcher.wh.cpp @@ -0,0 +1,168 @@ +// ==WindhawkMod== +// @id auto-theme-switcher +// @name Auto Theme Switcher +// @description Automatically changes between light and dark mode based on a set schedule +// @version 1.0 +// @author tinodin +// @github https://github.com/tinodin +// @include explorer.exe +// ==/WindhawkMod== + +// ==WindhawkModSettings== +/* +- Light: 07:00 +- Dark: 19:00 +*/ +// ==/WindhawkModSettings== + +#include +#include +#include + +HANDLE g_timerThread = nullptr; +HANDLE g_wakeEvent = nullptr; +bool g_exitThread = false; +SYSTEMTIME g_lightTime, g_darkTime; + +void SetTheme(bool light) { + DWORD value = light ? 1 : 0; + Wh_Log(L"[Theme] Switching to %s mode", light ? L"Light" : L"Dark"); + + RegSetKeyValueW(HKEY_CURRENT_USER, + L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", + L"AppsUseLightTheme", REG_DWORD, &value, sizeof(DWORD)); + RegSetKeyValueW(HKEY_CURRENT_USER, + L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", + L"SystemUsesLightTheme", REG_DWORD, &value, sizeof(DWORD)); + + SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0, + (LPARAM)L"ImmersiveColorSet", SMTO_ABORTIFHUNG, 100, nullptr); +} + +SYSTEMTIME ParseTime(const wchar_t* timeStr) { + SYSTEMTIME st = {}; + swscanf_s(timeStr, L"%hu:%hu", &st.wHour, &st.wMinute); + return st; +} + +time_t GetNextSwitchTime(const SYSTEMTIME& light, const SYSTEMTIME& dark, bool& nextIsLight) { + time_t now = time(nullptr); + struct tm localTime; + localtime_s(&localTime, &now); + + auto MakeTodayTime = [&](const SYSTEMTIME& st) { + struct tm t = localTime; + t.tm_hour = st.wHour; + t.tm_min = st.wMinute; + t.tm_sec = 0; + return mktime(&t); + }; + + time_t lightTime = MakeTodayTime(light); + time_t darkTime = MakeTodayTime(dark); + + if (now < lightTime) { + nextIsLight = true; + return lightTime; + } else if (now < darkTime) { + nextIsLight = false; + return darkTime; + } else { + nextIsLight = true; + lightTime += 86400; + return lightTime; + } +} + +bool IsLightTime(const SYSTEMTIME& light, const SYSTEMTIME& dark) { + time_t now = time(nullptr); + struct tm t; + localtime_s(&t, &now); + + struct tm lt = t; + lt.tm_hour = light.wHour; + lt.tm_min = light.wMinute; + lt.tm_sec = 0; + time_t lightTime = mktime(<); + + lt.tm_hour = dark.wHour; + lt.tm_min = dark.wMinute; + time_t darkTime = mktime(<); + + if (now < lightTime) + return false; + if (now < darkTime) + return true; + return false; +} + +DWORD WINAPI TimerLoop(LPVOID) { + while (!g_exitThread) { + bool nextIsLight; + time_t now = time(nullptr); + time_t target = GetNextSwitchTime(g_lightTime, g_darkTime, nextIsLight); + int sleepSec = (int)(target - now); + + Wh_Log(L"[Scheduler] Next switch to %s in %d seconds", nextIsLight ? L"Light" : L"Dark", sleepSec); + + DWORD result = WaitForSingleObject(g_wakeEvent, sleepSec * 1000); + if (g_exitThread) + break; + + if (result == WAIT_OBJECT_0) { + Wh_Log(L"[Scheduler] Woken up early for reschedule"); + continue; + } + + SetTheme(nextIsLight); + } + return 0; +} + +void StartOrRestartThread() { + if (g_timerThread) { + SetEvent(g_wakeEvent); + return; + } + + g_wakeEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr); + g_timerThread = CreateThread(nullptr, 0, TimerLoop, nullptr, 0, nullptr); +} + +void ApplyCurrentThemeAndSchedule() { + bool useLight = IsLightTime(g_lightTime, g_darkTime); + SetTheme(useLight); + StartOrRestartThread(); +} + +void LoadSettingsAndApply() { + const wchar_t* lightStr = Wh_GetStringSetting(L"Light"); + const wchar_t* darkStr = Wh_GetStringSetting(L"Dark"); + Wh_Log(L"[Settings] Light=%s, Dark=%s", lightStr, darkStr); + + g_lightTime = ParseTime(lightStr); + g_darkTime = ParseTime(darkStr); + + ApplyCurrentThemeAndSchedule(); +} + +BOOL Wh_ModInit() { + LoadSettingsAndApply(); + return TRUE; +} + +void Wh_ModSettingsChanged() { + LoadSettingsAndApply(); +} + +void Wh_ModUninit() { + g_exitThread = true; + if (g_wakeEvent) + SetEvent(g_wakeEvent); + if (g_timerThread) { + WaitForSingleObject(g_timerThread, INFINITE); + CloseHandle(g_timerThread); + } + if (g_wakeEvent) + CloseHandle(g_wakeEvent); +} \ No newline at end of file From c0ade654c03336c4be9df580a4553c096b4b97f0 Mon Sep 17 00:00:00 2001 From: tino <79853146+tinodin@users.noreply.github.com> Date: Thu, 22 May 2025 18:01:12 +0200 Subject: [PATCH 2/7] Add .theme support using ThemeTool.exe --- mods/auto-theme-switcher.wh.cpp | 723 +++++++++++++++++++++++++++----- 1 file changed, 628 insertions(+), 95 deletions(-) diff --git a/mods/auto-theme-switcher.wh.cpp b/mods/auto-theme-switcher.wh.cpp index 7a748d5e7..97efb67bf 100644 --- a/mods/auto-theme-switcher.wh.cpp +++ b/mods/auto-theme-switcher.wh.cpp @@ -1,7 +1,7 @@ // ==WindhawkMod== // @id auto-theme-switcher // @name Auto Theme Switcher -// @description Automatically changes between light and dark mode based on a set schedule +// @description Automatically changes between light and dark mode/themes based on a set schedule // @version 1.0 // @author tinodin // @github https://github.com/tinodin @@ -11,158 +11,691 @@ // ==WindhawkModSettings== /* - Light: 07:00 + $name: Light mode time - Dark: 19:00 + $name: Dark mode time +- LightThemePath: "C:\\Windows\\Resources\\Themes\\aero.theme" + $name: Light mode theme path (.theme) +- DarkThemePath: "C:\\Windows\\Resources\\Themes\\dark.theme" + $name: Dark mode theme path (.theme) +- LockScreen: true + $name: Apply Wallpaper to Lock screen */ // ==/WindhawkModSettings== -#include #include #include +#include +#include +#include + +const unsigned char themeToolData[] = { +0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, +0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, +0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4, 0x09, 0xCD, 0x21, 0xB8, 0x01, 0x4C, 0xCD, 0x21, 0x54, 0x68, +0x69, 0x73, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20, 0x63, 0x61, 0x6E, 0x6E, 0x6F, +0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6E, 0x20, 0x69, 0x6E, 0x20, 0x44, 0x4F, 0x53, 0x20, +0x6D, 0x6F, 0x64, 0x65, 0x2E, 0x0D, 0x0D, 0x0A, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x50, 0x45, 0x00, 0x00, 0x4C, 0x01, 0x03, 0x00, 0x01, 0x5C, 0x31, 0x5B, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x02, 0x01, 0x0B, 0x01, 0x08, 0x00, 0x00, 0x0E, 0x00, 0x00, +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x2D, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, +0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, +0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x80, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x85, +0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x38, 0x2D, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xA8, 0x02, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x60, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, +0x94, 0x0D, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, +0x2E, 0x72, 0x73, 0x72, 0x63, 0x00, 0x00, 0x00, 0xA8, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, +0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x2E, 0x72, 0x65, 0x6C, 0x6F, 0x63, 0x00, 0x00, +0x0C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x42, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x70, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, +0x60, 0x21, 0x00, 0x00, 0xD8, 0x0B, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x06, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x42, 0x7E, 0x01, 0x00, 0x00, 0x04, 0x6F, 0x09, 0x00, 0x00, 0x06, 0x6F, 0x07, 0x00, 0x00, 0x06, +0x2A, 0x32, 0x7E, 0x01, 0x00, 0x00, 0x04, 0x02, 0x6F, 0x0A, 0x00, 0x00, 0x06, 0x2A, 0x56, 0x7E, +0x01, 0x00, 0x00, 0x04, 0x6F, 0x09, 0x00, 0x00, 0x06, 0x6F, 0x08, 0x00, 0x00, 0x06, 0x28, 0x04, +0x00, 0x00, 0x0A, 0x2A, 0x4E, 0x28, 0x0E, 0x00, 0x00, 0x06, 0x2D, 0x06, 0x72, 0x01, 0x00, 0x00, +0x70, 0x2A, 0x72, 0x11, 0x00, 0x00, 0x70, 0x2A, 0x1B, 0x30, 0x03, 0x00, 0x9D, 0x00, 0x00, 0x00, +0x01, 0x00, 0x00, 0x11, 0x02, 0x8E, 0x69, 0x17, 0x2F, 0x01, 0x2A, 0x72, 0x21, 0x00, 0x00, 0x70, +0x0A, 0x02, 0x16, 0x9A, 0x28, 0x06, 0x00, 0x00, 0x0A, 0x6F, 0x07, 0x00, 0x00, 0x0A, 0x0B, 0x07, +0x72, 0x23, 0x00, 0x00, 0x70, 0x28, 0x08, 0x00, 0x00, 0x0A, 0x2D, 0x08, 0x28, 0x01, 0x00, 0x00, +0x06, 0x0A, 0x2B, 0x4B, 0x07, 0x72, 0x4B, 0x00, 0x00, 0x70, 0x28, 0x08, 0x00, 0x00, 0x0A, 0x2D, +0x12, 0x02, 0x8E, 0x69, 0x18, 0x2F, 0x02, 0xDE, 0x57, 0x02, 0x17, 0x9A, 0x28, 0x02, 0x00, 0x00, +0x06, 0x2B, 0x2C, 0x07, 0x72, 0x63, 0x00, 0x00, 0x70, 0x28, 0x08, 0x00, 0x00, 0x0A, 0x2D, 0x08, +0x28, 0x03, 0x00, 0x00, 0x06, 0x0A, 0x2B, 0x17, 0x07, 0x72, 0x97, 0x00, 0x00, 0x70, 0x28, 0x08, +0x00, 0x00, 0x0A, 0x2D, 0x08, 0x28, 0x04, 0x00, 0x00, 0x06, 0x0A, 0x2B, 0x02, 0xDE, 0x21, 0xDE, +0x09, 0x26, 0x72, 0x21, 0x00, 0x00, 0x70, 0x0A, 0xDE, 0x00, 0x28, 0x06, 0x00, 0x00, 0x0A, 0x06, +0x16, 0x8D, 0x01, 0x00, 0x00, 0x01, 0x28, 0x09, 0x00, 0x00, 0x0A, 0x28, 0x0A, 0x00, 0x00, 0x0A, +0x2A, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x62, 0x7D, 0x00, 0x09, +0x01, 0x00, 0x00, 0x01, 0x2E, 0x73, 0x0D, 0x00, 0x00, 0x06, 0x80, 0x01, 0x00, 0x00, 0x04, 0x2A, +0x42, 0x53, 0x4A, 0x42, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, +0x76, 0x32, 0x2E, 0x30, 0x2E, 0x35, 0x30, 0x37, 0x32, 0x37, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, +0x6C, 0x00, 0x00, 0x00, 0x24, 0x04, 0x00, 0x00, 0x23, 0x7E, 0x00, 0x00, 0x90, 0x04, 0x00, 0x00, +0x28, 0x04, 0x00, 0x00, 0x23, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x73, 0x00, 0x00, 0x00, 0x00, +0xB8, 0x08, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x23, 0x55, 0x53, 0x00, 0x70, 0x09, 0x00, 0x00, +0x10, 0x00, 0x00, 0x00, 0x23, 0x47, 0x55, 0x49, 0x44, 0x00, 0x00, 0x00, 0x80, 0x09, 0x00, 0x00, +0x58, 0x02, 0x00, 0x00, 0x23, 0x42, 0x6C, 0x6F, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x00, 0x00, 0x01, 0x57, 0x77, 0xA2, 0x15, 0x09, 0x02, 0x00, 0x00, 0x00, 0xFA, 0x01, 0x33, +0x00, 0x16, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, +0x01, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, +0x15, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, +0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, +0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, +0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, +0x89, 0x00, 0x82, 0x00, 0x06, 0x00, 0x80, 0x01, 0x60, 0x01, 0x06, 0x00, 0xA0, 0x01, 0x60, 0x01, +0x06, 0x00, 0xE4, 0x01, 0xC8, 0x01, 0x06, 0x00, 0xFB, 0x01, 0xC8, 0x01, 0x06, 0x00, 0x22, 0x02, +0x18, 0x02, 0x06, 0x00, 0x33, 0x02, 0x82, 0x00, 0x06, 0x00, 0x60, 0x02, 0x4B, 0x02, 0x06, 0x00, +0x81, 0x02, 0x82, 0x00, 0x06, 0x00, 0x98, 0x02, 0x82, 0x00, 0x06, 0x00, 0xAF, 0x02, 0x82, 0x00, +0x06, 0x00, 0xE7, 0x02, 0xC8, 0x02, 0x06, 0x00, 0xFA, 0x02, 0xC8, 0x02, 0x06, 0x00, 0x08, 0x03, +0xC8, 0x02, 0x06, 0x00, 0x1F, 0x03, 0xC8, 0x02, 0x06, 0x00, 0x30, 0x03, 0x60, 0x01, 0x06, 0x00, +0x44, 0x03, 0x60, 0x01, 0x06, 0x00, 0x56, 0x03, 0xC8, 0x02, 0x06, 0x00, 0x69, 0x03, 0xC8, 0x02, +0x06, 0x00, 0x77, 0x03, 0xC8, 0x02, 0x06, 0x00, 0x95, 0x03, 0xC8, 0x02, 0x06, 0x00, 0xA1, 0x03, +0xC8, 0x02, 0x06, 0x00, 0xB2, 0x03, 0x82, 0x00, 0x06, 0x00, 0xB7, 0x03, 0xC8, 0x02, 0x06, 0x00, +0xCF, 0x03, 0xC8, 0x02, 0x06, 0x00, 0xE2, 0x03, 0xC8, 0x02, 0x06, 0x00, 0xF7, 0x03, 0xC8, 0x02, +0x06, 0x00, 0x08, 0x04, 0xC8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x00, 0x01, 0x00, 0x81, 0x01, 0x10, 0x00, 0x18, 0x00, 0x2E, 0x00, 0x05, 0x00, 0x01, 0x00, +0x01, 0x00, 0xA2, 0x10, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x07, 0x00, +0xA2, 0x10, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x09, 0x00, 0xA2, 0x10, +0x00, 0x00, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0B, 0x00, 0x02, 0x10, 0x10, 0x00, +0x59, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x00, 0x0B, 0x00, 0x83, 0x01, 0x10, 0x00, 0x6B, 0x00, +0x00, 0x00, 0x05, 0x00, 0x02, 0x00, 0x0E, 0x00, 0x11, 0x00, 0x90, 0x00, 0x0A, 0x00, 0x50, 0x20, +0x00, 0x00, 0x00, 0x00, 0x96, 0x40, 0x9D, 0x00, 0x0E, 0x00, 0x01, 0x00, 0x61, 0x20, 0x00, 0x00, +0x00, 0x00, 0x96, 0x40, 0xB1, 0x00, 0x12, 0x00, 0x01, 0x00, 0x6E, 0x20, 0x00, 0x00, 0x00, 0x00, +0x96, 0x40, 0xBD, 0x00, 0x0E, 0x00, 0x02, 0x00, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x96, 0x00, +0xD7, 0x00, 0x0E, 0x00, 0x02, 0x00, 0x98, 0x20, 0x00, 0x00, 0x00, 0x00, 0x96, 0x40, 0xE6, 0x00, +0x17, 0x00, 0x02, 0x00, 0x54, 0x21, 0x00, 0x00, 0x00, 0x00, 0x91, 0x18, 0xC1, 0x02, 0xF6, 0x00, +0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 0xC6, 0x0D, 0xEB, 0x00, 0x1D, 0x00, 0x03, 0x00, +0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 0xC6, 0x0D, 0xFB, 0x00, 0x1D, 0x00, 0x04, 0x00, 0x00, 0x00, +0x00, 0x00, 0x03, 0x10, 0xC6, 0x0D, 0x23, 0x01, 0x25, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, +0x03, 0x10, 0xC6, 0x05, 0x34, 0x01, 0x2A, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, +0xC6, 0x01, 0x34, 0x01, 0x2A, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 0xC6, 0x09, +0x23, 0x01, 0x25, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 0x86, 0x18, 0x4C, 0x01, +0x34, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x96, 0x20, 0x52, 0x01, 0x38, 0x00, +0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x02, 0x00, 0x00, 0x01, 0x00, 0x46, 0x02, 0x00, 0x20, +0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, +0x01, 0x20, 0x01, 0x00, 0x87, 0x03, 0x01, 0x20, 0x01, 0x00, 0x87, 0x03, 0x00, 0x20, 0x00, 0x00, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x10, 0x00, 0x06, 0x00, 0x14, 0x00, +0x06, 0x00, 0x10, 0x00, 0x11, 0x00, 0x4C, 0x01, 0x3C, 0x00, 0x19, 0x00, 0x4C, 0x01, 0x34, 0x00, +0x21, 0x00, 0x4C, 0x01, 0x41, 0x00, 0x31, 0x00, 0x27, 0x02, 0xCD, 0x00, 0x39, 0x00, 0x4C, 0x01, +0x34, 0x00, 0x41, 0x00, 0x6C, 0x02, 0xD7, 0x00, 0x49, 0x00, 0x88, 0x02, 0xDC, 0x00, 0x49, 0x00, +0x90, 0x02, 0xE2, 0x00, 0x49, 0x00, 0xA8, 0x02, 0xE8, 0x00, 0x59, 0x00, 0xB7, 0x02, 0x12, 0x00, +0x61, 0x00, 0x4C, 0x01, 0x34, 0x00, 0x69, 0x00, 0x4C, 0x01, 0x2A, 0x00, 0x71, 0x00, 0x4C, 0x01, +0x24, 0x01, 0x81, 0x00, 0x4C, 0x01, 0x33, 0x01, 0x91, 0x00, 0x4C, 0x01, 0x39, 0x01, 0xA1, 0x00, +0x4C, 0x01, 0x3C, 0x00, 0xA9, 0x00, 0x4C, 0x01, 0x34, 0x00, 0xB1, 0x00, 0x4C, 0x01, 0xA9, 0x01, +0xC1, 0x00, 0x4C, 0x01, 0x0F, 0x02, 0xD1, 0x00, 0x4C, 0x01, 0x1E, 0x02, 0xE1, 0x00, 0x4C, 0x01, +0x2A, 0x00, 0x29, 0x00, 0x83, 0x00, 0x41, 0x01, 0x2E, 0x00, 0x0B, 0x00, 0x2F, 0x02, 0x2E, 0x00, +0x13, 0x00, 0x38, 0x02, 0x49, 0x00, 0x83, 0x00, 0x4A, 0x01, 0x63, 0x00, 0x6B, 0x00, 0x2A, 0x01, +0x63, 0x00, 0x63, 0x00, 0xFA, 0x00, 0x69, 0x00, 0x83, 0x00, 0x41, 0x01, 0x83, 0x00, 0x63, 0x00, +0x53, 0x01, 0x83, 0x00, 0x6B, 0x00, 0x2A, 0x01, 0x89, 0x00, 0x83, 0x00, 0x41, 0x01, 0xA0, 0x00, +0x2B, 0x00, 0xD2, 0x00, 0xA3, 0x00, 0x93, 0x00, 0xAF, 0x01, 0xA3, 0x00, 0x63, 0x00, 0x7F, 0x01, +0xC3, 0x00, 0x9B, 0x00, 0x15, 0x02, 0xC3, 0x00, 0xA3, 0x00, 0x24, 0x02, 0xC3, 0x00, 0x63, 0x00, +0xE5, 0x01, 0x07, 0x00, 0x3F, 0x01, 0x09, 0x00, 0x3F, 0x01, 0x0B, 0x00, 0x7D, 0x01, 0x0D, 0x00, +0x3F, 0x01, 0x0F, 0x00, 0x3F, 0x01, 0x11, 0x00, 0x7D, 0x01, 0x13, 0x00, 0x2D, 0x02, 0x06, 0x00, +0x05, 0x00, 0x47, 0x00, 0x06, 0x00, 0x09, 0x00, 0x47, 0x00, 0x06, 0x00, 0x0D, 0x00, 0x47, 0x00, +0x06, 0x00, 0x15, 0x00, 0x47, 0x00, 0xF1, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x03, 0x00, +0x06, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0B, 0x01, 0x21, 0x00, 0x00, 0x00, 0x17, 0x01, 0x21, 0x00, +0x00, 0x00, 0x3F, 0x01, 0x2F, 0x00, 0x00, 0x00, 0x3F, 0x01, 0x2F, 0x00, 0x02, 0x00, 0x07, 0x00, +0x03, 0x00, 0x02, 0x00, 0x08, 0x00, 0x05, 0x00, 0x02, 0x00, 0x09, 0x00, 0x07, 0x00, 0x02, 0x00, +0x0C, 0x00, 0x09, 0x00, 0x1B, 0x04, 0x00, 0x01, 0x1D, 0x00, 0x52, 0x01, 0x01, 0x00, 0x04, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xBE, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x00, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, +0x05, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x3C, 0x4D, 0x6F, 0x64, 0x75, 0x6C, 0x65, 0x3E, 0x00, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x54, +0x6F, 0x6F, 0x6C, 0x2E, 0x65, 0x78, 0x65, 0x00, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x4D, 0x61, 0x6E, +0x61, 0x67, 0x65, 0x72, 0x48, 0x65, 0x6C, 0x70, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x00, 0x54, 0x68, +0x65, 0x6D, 0x65, 0x41, 0x70, 0x69, 0x00, 0x49, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x00, 0x49, 0x54, +0x68, 0x65, 0x6D, 0x65, 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x72, 0x00, 0x54, 0x68, 0x65, 0x6D, +0x65, 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x72, 0x00, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x4D, 0x61, +0x6E, 0x61, 0x67, 0x65, 0x72, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x00, 0x4E, 0x61, 0x74, 0x69, 0x76, +0x65, 0x4D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x73, 0x00, 0x6D, 0x73, 0x63, 0x6F, 0x72, 0x6C, 0x69, +0x62, 0x00, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x00, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x00, +0x74, 0x68, 0x65, 0x6D, 0x65, 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x72, 0x00, 0x47, 0x65, 0x74, +0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x4E, 0x61, 0x6D, 0x65, +0x00, 0x43, 0x68, 0x61, 0x6E, 0x67, 0x65, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x00, 0x47, 0x65, 0x74, +0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x56, 0x69, 0x73, 0x75, 0x61, 0x6C, 0x53, 0x74, 0x79, +0x6C, 0x65, 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x47, 0x65, 0x74, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x53, +0x74, 0x61, 0x74, 0x75, 0x73, 0x00, 0x4D, 0x61, 0x69, 0x6E, 0x00, 0x67, 0x65, 0x74, 0x5F, 0x44, +0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x67, 0x65, 0x74, 0x5F, 0x56, +0x69, 0x73, 0x75, 0x61, 0x6C, 0x53, 0x74, 0x79, 0x6C, 0x65, 0x00, 0x44, 0x69, 0x73, 0x70, 0x6C, +0x61, 0x79, 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x56, 0x69, 0x73, 0x75, 0x61, 0x6C, 0x53, 0x74, 0x79, +0x6C, 0x65, 0x00, 0x67, 0x65, 0x74, 0x5F, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x68, +0x65, 0x6D, 0x65, 0x00, 0x41, 0x70, 0x70, 0x6C, 0x79, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x00, 0x43, +0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x00, 0x2E, 0x63, 0x74, 0x6F, +0x72, 0x00, 0x49, 0x73, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, +0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x52, 0x75, 0x6E, 0x74, 0x69, 0x6D, 0x65, 0x2E, 0x43, +0x6F, 0x6D, 0x70, 0x69, 0x6C, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x00, +0x43, 0x6F, 0x6D, 0x70, 0x69, 0x6C, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x52, 0x65, 0x6C, 0x61, 0x78, +0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, +0x52, 0x75, 0x6E, 0x74, 0x69, 0x6D, 0x65, 0x43, 0x6F, 0x6D, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, +0x6C, 0x69, 0x74, 0x79, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x54, 0x68, +0x65, 0x6D, 0x65, 0x54, 0x6F, 0x6F, 0x6C, 0x00, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x53, +0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2E, 0x50, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, +0x6F, 0x6E, 0x73, 0x00, 0x50, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x53, 0x65, +0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x53, 0x65, 0x63, 0x75, 0x72, +0x69, 0x74, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x74, 0x68, 0x65, 0x6D, 0x65, 0x46, +0x69, 0x6C, 0x65, 0x50, 0x61, 0x74, 0x68, 0x00, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, +0x4F, 0x00, 0x50, 0x61, 0x74, 0x68, 0x00, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6C, 0x65, 0x4E, 0x61, +0x6D, 0x65, 0x00, 0x53, 0x54, 0x41, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x41, 0x74, 0x74, 0x72, +0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x61, 0x72, 0x67, 0x73, 0x00, 0x53, 0x79, 0x73, 0x74, 0x65, +0x6D, 0x2E, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x69, 0x7A, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x00, +0x43, 0x75, 0x6C, 0x74, 0x75, 0x72, 0x65, 0x49, 0x6E, 0x66, 0x6F, 0x00, 0x67, 0x65, 0x74, 0x5F, +0x49, 0x6E, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6E, 0x74, 0x43, 0x75, 0x6C, 0x74, 0x75, 0x72, 0x65, +0x00, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x00, 0x54, 0x6F, 0x4C, 0x6F, 0x77, 0x65, 0x72, 0x00, +0x43, 0x6F, 0x6D, 0x70, 0x61, 0x72, 0x65, 0x00, 0x49, 0x46, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x50, +0x72, 0x6F, 0x76, 0x69, 0x64, 0x65, 0x72, 0x00, 0x46, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x00, 0x43, +0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x00, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4C, 0x69, 0x6E, 0x65, +0x00, 0x2E, 0x63, 0x63, 0x74, 0x6F, 0x72, 0x00, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x52, +0x75, 0x6E, 0x74, 0x69, 0x6D, 0x65, 0x2E, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6F, 0x70, 0x53, 0x65, +0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x00, 0x43, 0x6F, 0x6D, 0x49, 0x6D, 0x70, 0x6F, 0x72, 0x74, +0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x47, 0x75, 0x69, 0x64, 0x41, 0x74, +0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, +0x65, 0x54, 0x79, 0x70, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x43, +0x6F, 0x6D, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x00, +0x4D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x49, 0x6D, 0x70, 0x6C, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, +0x75, 0x74, 0x65, 0x00, 0x4D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x49, 0x6D, 0x70, 0x6C, 0x4F, 0x70, +0x74, 0x69, 0x6F, 0x6E, 0x73, 0x00, 0x4D, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6C, 0x41, 0x73, 0x41, +0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x55, 0x6E, 0x6D, 0x61, 0x6E, 0x61, 0x67, +0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x00, 0x44, 0x69, 0x73, 0x70, 0x49, 0x64, 0x41, 0x74, 0x74, +0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x62, 0x73, 0x74, 0x72, 0x54, 0x68, 0x65, 0x6D, 0x65, +0x50, 0x61, 0x74, 0x68, 0x00, 0x49, 0x6E, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, +0x00, 0x43, 0x6F, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, +0x65, 0x00, 0x54, 0x79, 0x70, 0x65, 0x00, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x49, 0x6E, 0x74, 0x65, +0x72, 0x66, 0x61, 0x63, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x43, +0x6C, 0x61, 0x73, 0x73, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, +0x65, 0x00, 0x54, 0x79, 0x70, 0x65, 0x4C, 0x69, 0x62, 0x54, 0x79, 0x70, 0x65, 0x41, 0x74, 0x74, +0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x54, 0x79, 0x70, 0x65, 0x4C, 0x69, 0x62, 0x54, 0x79, +0x70, 0x65, 0x46, 0x6C, 0x61, 0x67, 0x73, 0x00, 0x44, 0x6C, 0x6C, 0x49, 0x6D, 0x70, 0x6F, 0x72, +0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x55, 0x78, 0x54, 0x68, 0x65, +0x6D, 0x65, 0x2E, 0x64, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x0F, 0x73, 0x00, 0x74, 0x00, 0x6F, 0x00, +0x70, 0x00, 0x70, 0x00, 0x65, 0x00, 0x64, 0x00, 0x00, 0x0F, 0x72, 0x00, 0x75, 0x00, 0x6E, 0x00, +0x6E, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x67, 0x00, 0x00, 0x01, 0x00, 0x27, 0x67, 0x00, 0x65, 0x00, +0x74, 0x00, 0x63, 0x00, 0x75, 0x00, 0x72, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x74, 0x00, +0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x61, 0x00, 0x6D, 0x00, +0x65, 0x00, 0x00, 0x17, 0x63, 0x00, 0x68, 0x00, 0x61, 0x00, 0x6E, 0x00, 0x67, 0x00, 0x65, 0x00, +0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x00, 0x33, 0x67, 0x00, 0x65, 0x00, +0x74, 0x00, 0x63, 0x00, 0x75, 0x00, 0x72, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x74, 0x00, +0x76, 0x00, 0x69, 0x00, 0x73, 0x00, 0x75, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x73, 0x00, 0x74, 0x00, +0x79, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x00, 0x1D, +0x67, 0x00, 0x65, 0x00, 0x74, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6D, 0x00, 0x65, 0x00, +0x73, 0x00, 0x74, 0x00, 0x61, 0x00, 0x74, 0x00, 0x75, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, +0x61, 0xE5, 0xD9, 0xBD, 0x60, 0x8C, 0xBA, 0x42, 0xA9, 0x91, 0xE8, 0x47, 0xCD, 0xA9, 0x15, 0x97, +0x00, 0x08, 0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89, 0x03, 0x06, 0x12, 0x10, 0x03, 0x00, +0x00, 0x0E, 0x04, 0x00, 0x01, 0x01, 0x0E, 0x05, 0x00, 0x01, 0x01, 0x1D, 0x0E, 0x03, 0x20, 0x00, +0x0E, 0x03, 0x28, 0x00, 0x0E, 0x04, 0x20, 0x00, 0x12, 0x0C, 0x04, 0x20, 0x01, 0x01, 0x0E, 0x04, +0x28, 0x00, 0x12, 0x0C, 0x03, 0x20, 0x00, 0x01, 0x03, 0x00, 0x00, 0x02, 0x04, 0x20, 0x01, 0x01, +0x08, 0x05, 0x20, 0x01, 0x01, 0x11, 0x15, 0x80, 0x84, 0x2E, 0x01, 0x7F, 0x53, 0x79, 0x73, 0x74, +0x65, 0x6D, 0x2E, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2E, 0x50, 0x65, 0x72, 0x6D, +0x69, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x73, 0x2E, 0x50, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, +0x6F, 0x6E, 0x53, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x2C, 0x20, +0x6D, 0x73, 0x63, 0x6F, 0x72, 0x6C, 0x69, 0x62, 0x2C, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, +0x6E, 0x3D, 0x32, 0x2E, 0x30, 0x2E, 0x30, 0x2E, 0x30, 0x2C, 0x20, 0x43, 0x75, 0x6C, 0x74, 0x75, +0x72, 0x65, 0x3D, 0x6E, 0x65, 0x75, 0x74, 0x72, 0x61, 0x6C, 0x2C, 0x20, 0x50, 0x75, 0x62, 0x6C, +0x69, 0x63, 0x4B, 0x65, 0x79, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x3D, 0x62, 0x37, 0x37, 0x61, 0x35, +0x63, 0x35, 0x36, 0x31, 0x39, 0x33, 0x34, 0x65, 0x30, 0x38, 0x39, 0x01, 0x00, 0x04, 0x00, 0x01, +0x0E, 0x0E, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x12, 0x21, 0x05, 0x20, 0x01, 0x0E, +0x12, 0x21, 0x05, 0x00, 0x02, 0x08, 0x0E, 0x0E, 0x08, 0x00, 0x03, 0x0E, 0x12, 0x29, 0x0E, 0x1D, +0x1C, 0x04, 0x07, 0x02, 0x0E, 0x0E, 0x03, 0x00, 0x00, 0x01, 0x29, 0x01, 0x00, 0x24, 0x44, 0x32, +0x33, 0x43, 0x43, 0x37, 0x33, 0x33, 0x2D, 0x35, 0x35, 0x32, 0x32, 0x2D, 0x34, 0x30, 0x36, 0x44, +0x2D, 0x38, 0x44, 0x46, 0x42, 0x2D, 0x42, 0x33, 0x43, 0x46, 0x35, 0x45, 0x46, 0x35, 0x32, 0x41, +0x37, 0x31, 0x00, 0x00, 0x05, 0x20, 0x01, 0x01, 0x11, 0x3D, 0x08, 0x01, 0x00, 0x01, 0x00, 0x00, +0x00, 0x00, 0x00, 0x05, 0x20, 0x01, 0x01, 0x11, 0x45, 0x05, 0x20, 0x01, 0x01, 0x11, 0x4D, 0x01, +0x13, 0x08, 0x01, 0x00, 0x00, 0x00, 0x01, 0x60, 0x00, 0x00, 0x08, 0x01, 0x00, 0x01, 0x00, 0x01, +0x60, 0x00, 0x00, 0x29, 0x01, 0x00, 0x24, 0x30, 0x36, 0x34, 0x36, 0x45, 0x42, 0x42, 0x45, 0x2D, +0x43, 0x31, 0x42, 0x37, 0x2D, 0x34, 0x30, 0x34, 0x35, 0x2D, 0x38, 0x46, 0x44, 0x30, 0x2D, 0x46, +0x46, 0x44, 0x36, 0x35, 0x44, 0x33, 0x46, 0x43, 0x37, 0x39, 0x32, 0x00, 0x00, 0x01, 0x1C, 0x29, +0x01, 0x00, 0x24, 0x41, 0x32, 0x43, 0x35, 0x36, 0x43, 0x32, 0x41, 0x2D, 0x45, 0x36, 0x33, 0x41, +0x2D, 0x34, 0x33, 0x33, 0x45, 0x2D, 0x39, 0x39, 0x35, 0x33, 0x2D, 0x39, 0x32, 0x45, 0x39, 0x34, +0x46, 0x30, 0x31, 0x32, 0x32, 0x45, 0x41, 0x00, 0x00, 0x05, 0x20, 0x01, 0x01, 0x12, 0x5D, 0x35, +0x01, 0x00, 0x30, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x41, 0x70, 0x69, 0x2E, 0x54, 0x68, 0x65, 0x6D, +0x65, 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x72, 0x48, 0x65, 0x6C, 0x70, 0x43, 0x6C, 0x61, 0x73, +0x73, 0x2B, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x72, 0x43, 0x6C, +0x61, 0x73, 0x73, 0x00, 0x00, 0x29, 0x01, 0x00, 0x24, 0x43, 0x30, 0x34, 0x42, 0x33, 0x32, 0x39, +0x45, 0x2D, 0x35, 0x38, 0x32, 0x33, 0x2D, 0x34, 0x34, 0x31, 0x35, 0x2D, 0x39, 0x43, 0x39, 0x33, +0x2D, 0x42, 0x41, 0x34, 0x34, 0x36, 0x38, 0x38, 0x39, 0x34, 0x37, 0x42, 0x30, 0x00, 0x00, 0x05, +0x20, 0x01, 0x01, 0x11, 0x65, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, +0x01, 0x01, 0x11, 0x6D, 0x08, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x08, +0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x01, 0x00, 0x01, 0x00, 0x54, 0x02, 0x16, +0x57, 0x72, 0x61, 0x70, 0x4E, 0x6F, 0x6E, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6F, 0x6E, +0x54, 0x68, 0x72, 0x6F, 0x77, 0x73, 0x01, 0x00, 0x60, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x7E, 0x2D, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x70, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x5F, 0x43, 0x6F, 0x72, 0x45, 0x78, 0x65, 0x4D, 0x61, 0x69, 0x6E, 0x00, 0x6D, 0x73, +0x63, 0x6F, 0x72, 0x65, 0x65, 0x2E, 0x64, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x25, +0x00, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, +0x10, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, +0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x58, 0x40, 0x00, 0x00, 0x4C, 0x02, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x02, 0x34, 0x00, 0x00, 0x00, 0x56, 0x00, +0x53, 0x00, 0x5F, 0x00, 0x56, 0x00, 0x45, 0x00, 0x52, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4F, 0x00, +0x4E, 0x00, 0x5F, 0x00, 0x49, 0x00, 0x4E, 0x00, 0x46, 0x00, 0x4F, 0x00, 0x00, 0x00, 0x00, 0x00, +0xBD, 0x04, 0xEF, 0xFE, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x00, 0x61, 0x00, 0x72, 0x00, +0x46, 0x00, 0x69, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x49, 0x00, 0x6E, 0x00, 0x66, 0x00, 0x6F, 0x00, +0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x54, 0x00, 0x72, 0x00, 0x61, 0x00, +0x6E, 0x00, 0x73, 0x00, 0x6C, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x04, 0xAC, 0x01, 0x00, 0x00, 0x01, 0x00, 0x53, 0x00, +0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x67, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6C, 0x00, +0x65, 0x00, 0x49, 0x00, 0x6E, 0x00, 0x66, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x88, 0x01, 0x00, 0x00, +0x01, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x34, 0x00, 0x62, 0x00, +0x30, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x02, 0x00, 0x01, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6C, 0x00, +0x65, 0x00, 0x44, 0x00, 0x65, 0x00, 0x73, 0x00, 0x63, 0x00, 0x72, 0x00, 0x69, 0x00, 0x70, 0x00, +0x74, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, +0x30, 0x00, 0x08, 0x00, 0x01, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x56, 0x00, +0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, +0x30, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x00, 0x00, +0x3C, 0x00, 0x0E, 0x00, 0x01, 0x00, 0x49, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, +0x6E, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x4E, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x00, 0x00, +0x54, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x54, 0x00, 0x6F, 0x00, 0x6F, 0x00, +0x6C, 0x00, 0x2E, 0x00, 0x65, 0x00, 0x78, 0x00, 0x65, 0x00, 0x00, 0x00, 0x28, 0x00, 0x02, 0x00, +0x01, 0x00, 0x4C, 0x00, 0x65, 0x00, 0x67, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x43, 0x00, 0x6F, 0x00, +0x70, 0x00, 0x79, 0x00, 0x72, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 0x00, 0x74, 0x00, 0x00, 0x00, +0x20, 0x00, 0x00, 0x00, 0x44, 0x00, 0x0E, 0x00, 0x01, 0x00, 0x4F, 0x00, 0x72, 0x00, 0x69, 0x00, +0x67, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6C, 0x00, +0x65, 0x00, 0x6E, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x00, 0x00, 0x54, 0x00, 0x68, 0x00, +0x65, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x54, 0x00, 0x6F, 0x00, 0x6F, 0x00, 0x6C, 0x00, 0x2E, 0x00, +0x65, 0x00, 0x78, 0x00, 0x65, 0x00, 0x00, 0x00, 0x34, 0x00, 0x08, 0x00, 0x01, 0x00, 0x50, 0x00, +0x72, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x75, 0x00, 0x63, 0x00, 0x74, 0x00, 0x56, 0x00, 0x65, 0x00, +0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, +0x30, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0x08, 0x00, +0x01, 0x00, 0x41, 0x00, 0x73, 0x00, 0x73, 0x00, 0x65, 0x00, 0x6D, 0x00, 0x62, 0x00, 0x6C, 0x00, +0x79, 0x00, 0x20, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6F, 0x00, +0x6E, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x2E, 0x00, +0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x20, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x90, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +const size_t themeToolSize = sizeof(themeToolData); HANDLE g_timerThread = nullptr; HANDLE g_wakeEvent = nullptr; -bool g_exitThread = false; +bool g_exitFlag = false; SYSTEMTIME g_lightTime, g_darkTime; +std::wstring g_lightThemePath, g_darkThemePath; + +enum Appearance { + light, + dark +}; + +void ApplyLockScreen() { + std::wstring wallpaperPath; + wchar_t currentWallpaper[MAX_PATH] = {0}; + DWORD size = sizeof(currentWallpaper); + + if (RegGetValueW(HKEY_CURRENT_USER, L"Control Panel\\Desktop", L"WallPaper", RRF_RT_REG_SZ, nullptr, currentWallpaper, &size) != ERROR_SUCCESS) + { + return; + } + + wallpaperPath = currentWallpaper; -void SetTheme(bool light) { - DWORD value = light ? 1 : 0; - Wh_Log(L"[Theme] Switching to %s mode", light ? L"Light" : L"Dark"); + HKEY hKey; + if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Policies\\Microsoft\\Windows\\Personalization", 0, nullptr, 0, KEY_SET_VALUE, nullptr, &hKey, nullptr) == ERROR_SUCCESS) + { + RegSetValueExW(hKey, L"LockScreenImage", 0, REG_SZ, (const BYTE*)wallpaperPath.c_str(), (DWORD)((wallpaperPath.size() + 1) * sizeof(wchar_t))); + RegCloseKey(hKey); + } - RegSetKeyValueW(HKEY_CURRENT_USER, - L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", - L"AppsUseLightTheme", REG_DWORD, &value, sizeof(DWORD)); - RegSetKeyValueW(HKEY_CURRENT_USER, - L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", - L"SystemUsesLightTheme", REG_DWORD, &value, sizeof(DWORD)); + if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\PersonalizationCSP", 0, nullptr, 0, KEY_SET_VALUE, nullptr, &hKey, nullptr) == ERROR_SUCCESS) + { + for (const wchar_t* valueName : { L"LockScreenImagePath", L"LockScreenImageUrl" }) { + RegSetValueExW(hKey, valueName, 0, REG_SZ, (const BYTE*)wallpaperPath.c_str(), (DWORD)((wallpaperPath.size() + 1) * sizeof(wchar_t))); + } + RegCloseKey(hKey); + } - SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0, - (LPARAM)L"ImmersiveColorSet", SMTO_ABORTIFHUNG, 100, nullptr); + Wh_Log(L"[Theme] Applied as Lock Screen"); } -SYSTEMTIME ParseTime(const wchar_t* timeStr) { - SYSTEMTIME st = {}; - swscanf_s(timeStr, L"%hu:%hu", &st.wHour, &st.wMinute); - return st; +bool IsAppearanceApplied(Appearance appearance) { + DWORD val = (appearance == light) ? 1 : 0, current = 1, size = sizeof(DWORD); + + RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"AppsUseLightTheme", RRF_RT_REG_DWORD, nullptr, ¤t, &size); + if (current != val) return false; + + RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"SystemUsesLightTheme", RRF_RT_REG_DWORD, nullptr, ¤t, &size); + return current == val; } -time_t GetNextSwitchTime(const SYSTEMTIME& light, const SYSTEMTIME& dark, bool& nextIsLight) { - time_t now = time(nullptr); - struct tm localTime; - localtime_s(&localTime, &now); - - auto MakeTodayTime = [&](const SYSTEMTIME& st) { - struct tm t = localTime; - t.tm_hour = st.wHour; - t.tm_min = st.wMinute; - t.tm_sec = 0; - return mktime(&t); - }; +bool IsThemeApplied(const wchar_t* themePath) { + wchar_t currentTheme[MAX_PATH] = {0}; + DWORD size = sizeof(currentTheme); + + if (RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes", L"CurrentTheme", RRF_RT_REG_SZ, nullptr, currentTheme, &size) != ERROR_SUCCESS) + return false; + if (_wcsicmp(currentTheme, themePath) != 0) + return false; - time_t lightTime = MakeTodayTime(light); - time_t darkTime = MakeTodayTime(dark); + DWORD appsLight = 1, systemLight = 1, dataSize = sizeof(DWORD); + RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"AppsUseLightTheme", RRF_RT_REG_DWORD, nullptr, &appsLight, &dataSize); + RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"SystemUsesLightTheme", RRF_RT_REG_DWORD, nullptr, &systemLight, &dataSize); - if (now < lightTime) { - nextIsLight = true; - return lightTime; - } else if (now < darkTime) { - nextIsLight = false; - return darkTime; - } else { - nextIsLight = true; - lightTime += 86400; - return lightTime; + std::wifstream file(themePath); + if (!file) + return false; + + std::wstring line, systemMode, appMode; + bool inVisualStyles = false; + while (std::getline(file, line)) { + if (line.empty() || line[0] == L';') continue; + if (line[0] == L'[') { + inVisualStyles = (line == L"[VisualStyles]"); + continue; + } + if (inVisualStyles) { + if (line.find(L"SystemMode=") == 0) + systemMode = line.substr(11); + else if (line.find(L"AppMode=") == 0) + appMode = line.substr(8); + if (!systemMode.empty() && !appMode.empty()) + break; + } } + + auto isLight = [](const std::wstring& s) { return _wcsicmp(s.c_str(), L"Light") == 0; }; + bool themeLight = isLight(systemMode) && isLight(appMode); + + return (appsLight == (themeLight ? 1 : 0)) && (systemLight == (themeLight ? 1 : 0)); } -bool IsLightTime(const SYSTEMTIME& light, const SYSTEMTIME& dark) { - time_t now = time(nullptr); - struct tm t; - localtime_s(&t, &now); +void ApplyAppearance(Appearance appearance) { + DWORD val = (appearance == light) ? 1 : 0; - struct tm lt = t; - lt.tm_hour = light.wHour; - lt.tm_min = light.wMinute; - lt.tm_sec = 0; - time_t lightTime = mktime(<); + // change appearance + RegSetKeyValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"AppsUseLightTheme", REG_DWORD, &val, sizeof(val)); + RegSetKeyValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"SystemUsesLightTheme", REG_DWORD, &val, sizeof(val)); - lt.tm_hour = dark.wHour; - lt.tm_min = dark.wMinute; - time_t darkTime = mktime(<); + // broadcast the change + SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)L"ImmersiveColorSet", SMTO_ABORTIFHUNG, 100, nullptr); - if (now < lightTime) - return false; - if (now < darkTime) - return true; - return false; + Wh_Log(L"[Theme] Applied %s Mode.", appearance == light ? L"Light" : L"Dark"); + + // apply wallpaper to lock screen + if (Wh_GetIntSetting(L"LockScreen")) + ApplyLockScreen(); } -DWORD WINAPI TimerLoop(LPVOID) { - while (!g_exitThread) { - bool nextIsLight; - time_t now = time(nullptr); - time_t target = GetNextSwitchTime(g_lightTime, g_darkTime, nextIsLight); - int sleepSec = (int)(target - now); +void ApplyTheme(const wchar_t* themePath) { + std::thread([=]() { + // check if explorer is loaded + Wh_Log(L"[Theme] Waiting for explorer to load..."); + for (;;) { + HWND progman = FindWindowW(L"Progman", nullptr); + HWND tray = FindWindowW(L"Shell_TrayWnd", nullptr); + if (progman && tray && IsWindowVisible(tray)) break; + Sleep(500); + } + Wh_Log(L"[Theme] Explorer loaded"); - Wh_Log(L"[Scheduler] Next switch to %s in %d seconds", nextIsLight ? L"Light" : L"Dark", sleepSec); + wchar_t toolPath[MAX_PATH]; + GetTempPathW(MAX_PATH, toolPath); + wcscat_s(toolPath, L"ThemeTool.exe"); - DWORD result = WaitForSingleObject(g_wakeEvent, sleepSec * 1000); - if (g_exitThread) - break; + // write themetool to temp + std::ofstream file(toolPath, std::ios::binary); + if (!file) { + Wh_Log(L"[ThemeTool] Failed to write ThemeTool: %s", toolPath); + return; + } + file.write(reinterpret_cast(themeToolData), themeToolSize); + file.close(); - if (result == WAIT_OBJECT_0) { - Wh_Log(L"[Scheduler] Woken up early for reschedule"); - continue; + Wh_Log(L"[ThemeTool] Written to %s", toolPath); + + // change theme using themetool + wchar_t cmd[1024]; + swprintf(cmd, 1024, L"\"%s\" ChangeTheme \"%s\"", toolPath, themePath); + Wh_Log(L"[ThemeTool] Changing theme using ThemeTool"); + + STARTUPINFOW si = { sizeof(si) }; + PROCESS_INFORMATION pi; + + if (CreateProcessW(nullptr, cmd, nullptr, nullptr, FALSE, CREATE_NO_WINDOW, nullptr, nullptr, &si, &pi)) { + CloseHandle(pi.hThread); + WaitForSingleObject(pi.hProcess, INFINITE); + CloseHandle(pi.hProcess); + } else { + DWORD err = GetLastError(); + Wh_Log(L"[ThemeTool] Failed to launch theme tool. Error code: %u", err); } - SetTheme(nextIsLight); + // delete themetool + if (DeleteFileW(toolPath)) { + Wh_Log(L"[ThemeTool] Deleted %s", toolPath); + } else { + Wh_Log(L"[ThemeTool] Failed to delete %s", toolPath); + } + + // apply wallpaper to lock screen + if (Wh_GetIntSetting(L"LockScreen")) + ApplyLockScreen(); + }).detach(); +} + +SYSTEMTIME ParseScheduleTime(const wchar_t* timeStr) { + SYSTEMTIME st = {}; + swscanf_s(timeStr, L"%hu:%hu", &st.wHour, &st.wMinute); + return st; +} + +time_t GetNextSwitch(const SYSTEMTIME& light, const SYSTEMTIME& dark, bool& nextLight) { + time_t now = time(nullptr); + struct tm local; + localtime_s(&local, &now); + + auto makeTime = [&](const SYSTEMTIME& st) { + struct tm t = local; + t.tm_hour = st.wHour; t.tm_min = st.wMinute; t.tm_sec = 0; + return mktime(&t); + }; + + time_t lightT = makeTime(light); + time_t darkT = makeTime(dark); + + bool isLightNow; + if (lightT < darkT) + isLightNow = now >= lightT && now < darkT; + else + isLightNow = now >= lightT || now < darkT; + + if (isLightNow) { + nextLight = false; + if (darkT <= now) darkT += 86400; + return darkT; + } else { + nextLight = true; + if (lightT <= now) lightT += 86400; + return lightT; + } +} + +DWORD WINAPI ThemeScheduler(LPVOID) { + while (!g_exitFlag) { + bool nextLight; + time_t now = time(nullptr); + time_t nextSwitch = GetNextSwitch(g_lightTime, g_darkTime, nextLight); + int waitTime = (int)(nextSwitch - now); + DWORD res = WaitForSingleObject(g_wakeEvent, waitTime * 1000); + if (g_exitFlag) break; + if (res == WAIT_OBJECT_0) continue; + + const wchar_t* themePath = nextLight ? g_lightThemePath.c_str() : g_darkThemePath.c_str(); + + if (*themePath) { + if (IsThemeApplied(themePath)) { + Wh_Log(L"[Theme] Theme already applied."); + continue; + } + ApplyTheme(themePath); + } else { + if (IsAppearanceApplied(nextLight ? light : dark)) { + Wh_Log(L"[Theme] Appearance already applied."); + continue; + } + ApplyAppearance(nextLight ? light : dark); + } } return 0; } -void StartOrRestartThread() { +void StartScheduler() { if (g_timerThread) { SetEvent(g_wakeEvent); return; } - g_wakeEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr); - g_timerThread = CreateThread(nullptr, 0, TimerLoop, nullptr, 0, nullptr); + g_timerThread = CreateThread(nullptr, 0, ThemeScheduler, nullptr, 0, nullptr); } -void ApplyCurrentThemeAndSchedule() { - bool useLight = IsLightTime(g_lightTime, g_darkTime); - SetTheme(useLight); - StartOrRestartThread(); +std::wstring TrimQuotes(const std::wstring& str) { + size_t start = 0; + size_t end = str.length(); + if (!str.empty() && str.front() == L'"') start = 1; + if (end > start && str[end - 1] == L'"') end--; + return str.substr(start, end - start); } -void LoadSettingsAndApply() { - const wchar_t* lightStr = Wh_GetStringSetting(L"Light"); - const wchar_t* darkStr = Wh_GetStringSetting(L"Dark"); - Wh_Log(L"[Settings] Light=%s, Dark=%s", lightStr, darkStr); +void LoadSettings() { + g_lightTime = ParseScheduleTime(Wh_GetStringSetting(L"Light")); + g_darkTime = ParseScheduleTime(Wh_GetStringSetting(L"Dark")); - g_lightTime = ParseTime(lightStr); - g_darkTime = ParseTime(darkStr); + auto rawLightPath = Wh_GetStringSetting(L"LightThemePath"); + g_lightThemePath = rawLightPath ? TrimQuotes(rawLightPath) : L""; - ApplyCurrentThemeAndSchedule(); + auto rawDarkPath = Wh_GetStringSetting(L"DarkThemePath"); + g_darkThemePath = rawDarkPath ? TrimQuotes(rawDarkPath) : L""; + + time_t now = time(nullptr); + struct tm local; + localtime_s(&local, &now); + + auto makeTime = [&](const SYSTEMTIME& st) { + struct tm t = local; + t.tm_hour = st.wHour; t.tm_min = st.wMinute; t.tm_sec = 0; + return mktime(&t); + }; + + time_t lightT = makeTime(g_lightTime); + time_t darkT = makeTime(g_darkTime); + + bool isLightNow; + if (lightT < darkT) + isLightNow = now >= lightT && now < darkT; + else + isLightNow = now >= lightT || now < darkT; + + const wchar_t* themePath = isLightNow ? g_lightThemePath.c_str() : g_darkThemePath.c_str(); + if (*themePath) { + if (IsThemeApplied(themePath)) { + Wh_Log(L"[Theme] Theme already applied."); + return; + } + ApplyTheme(themePath); + } else { + if (IsAppearanceApplied(isLightNow ? light : dark)) { + Wh_Log(L"[Theme] Appearance already applied."); + return; + } + ApplyAppearance(isLightNow ? light : dark); + } + + StartScheduler(); } BOOL Wh_ModInit() { - LoadSettingsAndApply(); + LoadSettings(); return TRUE; } void Wh_ModSettingsChanged() { - LoadSettingsAndApply(); + LoadSettings(); } void Wh_ModUninit() { - g_exitThread = true; - if (g_wakeEvent) - SetEvent(g_wakeEvent); + g_exitFlag = true; + if (g_wakeEvent) SetEvent(g_wakeEvent); if (g_timerThread) { WaitForSingleObject(g_timerThread, INFINITE); CloseHandle(g_timerThread); } - if (g_wakeEvent) - CloseHandle(g_wakeEvent); -} \ No newline at end of file + if (g_wakeEvent) CloseHandle(g_wakeEvent); +} From b709ceddab2ab382cd3698f33b7fb384074b5e71 Mon Sep 17 00:00:00 2001 From: tino <79853146+tinodin@users.noreply.github.com> Date: Thu, 22 May 2025 22:27:12 +0200 Subject: [PATCH 3/7] Implement native theme switching --- mods/auto-theme-switcher.wh.cpp | 492 ++++++-------------------------- 1 file changed, 84 insertions(+), 408 deletions(-) diff --git a/mods/auto-theme-switcher.wh.cpp b/mods/auto-theme-switcher.wh.cpp index 97efb67bf..1e515eed8 100644 --- a/mods/auto-theme-switcher.wh.cpp +++ b/mods/auto-theme-switcher.wh.cpp @@ -6,6 +6,7 @@ // @author tinodin // @github https://github.com/tinodin // @include explorer.exe +// @compilerOptions -lole32 -loleaut32 // ==/WindhawkMod== // ==WindhawkModSettings== @@ -23,367 +24,11 @@ */ // ==/WindhawkModSettings== -#include -#include -#include -#include #include - -const unsigned char themeToolData[] = { -0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, -0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, -0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4, 0x09, 0xCD, 0x21, 0xB8, 0x01, 0x4C, 0xCD, 0x21, 0x54, 0x68, -0x69, 0x73, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20, 0x63, 0x61, 0x6E, 0x6E, 0x6F, -0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6E, 0x20, 0x69, 0x6E, 0x20, 0x44, 0x4F, 0x53, 0x20, -0x6D, 0x6F, 0x64, 0x65, 0x2E, 0x0D, 0x0D, 0x0A, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x50, 0x45, 0x00, 0x00, 0x4C, 0x01, 0x03, 0x00, 0x01, 0x5C, 0x31, 0x5B, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x02, 0x01, 0x0B, 0x01, 0x08, 0x00, 0x00, 0x0E, 0x00, 0x00, -0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x2D, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, -0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x80, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x85, -0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x38, 0x2D, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xA8, 0x02, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x60, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, -0x94, 0x0D, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, -0x2E, 0x72, 0x73, 0x72, 0x63, 0x00, 0x00, 0x00, 0xA8, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, -0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x2E, 0x72, 0x65, 0x6C, 0x6F, 0x63, 0x00, 0x00, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x42, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x70, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, -0x60, 0x21, 0x00, 0x00, 0xD8, 0x0B, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x42, 0x7E, 0x01, 0x00, 0x00, 0x04, 0x6F, 0x09, 0x00, 0x00, 0x06, 0x6F, 0x07, 0x00, 0x00, 0x06, -0x2A, 0x32, 0x7E, 0x01, 0x00, 0x00, 0x04, 0x02, 0x6F, 0x0A, 0x00, 0x00, 0x06, 0x2A, 0x56, 0x7E, -0x01, 0x00, 0x00, 0x04, 0x6F, 0x09, 0x00, 0x00, 0x06, 0x6F, 0x08, 0x00, 0x00, 0x06, 0x28, 0x04, -0x00, 0x00, 0x0A, 0x2A, 0x4E, 0x28, 0x0E, 0x00, 0x00, 0x06, 0x2D, 0x06, 0x72, 0x01, 0x00, 0x00, -0x70, 0x2A, 0x72, 0x11, 0x00, 0x00, 0x70, 0x2A, 0x1B, 0x30, 0x03, 0x00, 0x9D, 0x00, 0x00, 0x00, -0x01, 0x00, 0x00, 0x11, 0x02, 0x8E, 0x69, 0x17, 0x2F, 0x01, 0x2A, 0x72, 0x21, 0x00, 0x00, 0x70, -0x0A, 0x02, 0x16, 0x9A, 0x28, 0x06, 0x00, 0x00, 0x0A, 0x6F, 0x07, 0x00, 0x00, 0x0A, 0x0B, 0x07, -0x72, 0x23, 0x00, 0x00, 0x70, 0x28, 0x08, 0x00, 0x00, 0x0A, 0x2D, 0x08, 0x28, 0x01, 0x00, 0x00, -0x06, 0x0A, 0x2B, 0x4B, 0x07, 0x72, 0x4B, 0x00, 0x00, 0x70, 0x28, 0x08, 0x00, 0x00, 0x0A, 0x2D, -0x12, 0x02, 0x8E, 0x69, 0x18, 0x2F, 0x02, 0xDE, 0x57, 0x02, 0x17, 0x9A, 0x28, 0x02, 0x00, 0x00, -0x06, 0x2B, 0x2C, 0x07, 0x72, 0x63, 0x00, 0x00, 0x70, 0x28, 0x08, 0x00, 0x00, 0x0A, 0x2D, 0x08, -0x28, 0x03, 0x00, 0x00, 0x06, 0x0A, 0x2B, 0x17, 0x07, 0x72, 0x97, 0x00, 0x00, 0x70, 0x28, 0x08, -0x00, 0x00, 0x0A, 0x2D, 0x08, 0x28, 0x04, 0x00, 0x00, 0x06, 0x0A, 0x2B, 0x02, 0xDE, 0x21, 0xDE, -0x09, 0x26, 0x72, 0x21, 0x00, 0x00, 0x70, 0x0A, 0xDE, 0x00, 0x28, 0x06, 0x00, 0x00, 0x0A, 0x06, -0x16, 0x8D, 0x01, 0x00, 0x00, 0x01, 0x28, 0x09, 0x00, 0x00, 0x0A, 0x28, 0x0A, 0x00, 0x00, 0x0A, -0x2A, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x62, 0x7D, 0x00, 0x09, -0x01, 0x00, 0x00, 0x01, 0x2E, 0x73, 0x0D, 0x00, 0x00, 0x06, 0x80, 0x01, 0x00, 0x00, 0x04, 0x2A, -0x42, 0x53, 0x4A, 0x42, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, -0x76, 0x32, 0x2E, 0x30, 0x2E, 0x35, 0x30, 0x37, 0x32, 0x37, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, -0x6C, 0x00, 0x00, 0x00, 0x24, 0x04, 0x00, 0x00, 0x23, 0x7E, 0x00, 0x00, 0x90, 0x04, 0x00, 0x00, -0x28, 0x04, 0x00, 0x00, 0x23, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x73, 0x00, 0x00, 0x00, 0x00, -0xB8, 0x08, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x23, 0x55, 0x53, 0x00, 0x70, 0x09, 0x00, 0x00, -0x10, 0x00, 0x00, 0x00, 0x23, 0x47, 0x55, 0x49, 0x44, 0x00, 0x00, 0x00, 0x80, 0x09, 0x00, 0x00, -0x58, 0x02, 0x00, 0x00, 0x23, 0x42, 0x6C, 0x6F, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0x00, 0x00, 0x01, 0x57, 0x77, 0xA2, 0x15, 0x09, 0x02, 0x00, 0x00, 0x00, 0xFA, 0x01, 0x33, -0x00, 0x16, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, -0x01, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, -0x15, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, -0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, -0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, -0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, -0x89, 0x00, 0x82, 0x00, 0x06, 0x00, 0x80, 0x01, 0x60, 0x01, 0x06, 0x00, 0xA0, 0x01, 0x60, 0x01, -0x06, 0x00, 0xE4, 0x01, 0xC8, 0x01, 0x06, 0x00, 0xFB, 0x01, 0xC8, 0x01, 0x06, 0x00, 0x22, 0x02, -0x18, 0x02, 0x06, 0x00, 0x33, 0x02, 0x82, 0x00, 0x06, 0x00, 0x60, 0x02, 0x4B, 0x02, 0x06, 0x00, -0x81, 0x02, 0x82, 0x00, 0x06, 0x00, 0x98, 0x02, 0x82, 0x00, 0x06, 0x00, 0xAF, 0x02, 0x82, 0x00, -0x06, 0x00, 0xE7, 0x02, 0xC8, 0x02, 0x06, 0x00, 0xFA, 0x02, 0xC8, 0x02, 0x06, 0x00, 0x08, 0x03, -0xC8, 0x02, 0x06, 0x00, 0x1F, 0x03, 0xC8, 0x02, 0x06, 0x00, 0x30, 0x03, 0x60, 0x01, 0x06, 0x00, -0x44, 0x03, 0x60, 0x01, 0x06, 0x00, 0x56, 0x03, 0xC8, 0x02, 0x06, 0x00, 0x69, 0x03, 0xC8, 0x02, -0x06, 0x00, 0x77, 0x03, 0xC8, 0x02, 0x06, 0x00, 0x95, 0x03, 0xC8, 0x02, 0x06, 0x00, 0xA1, 0x03, -0xC8, 0x02, 0x06, 0x00, 0xB2, 0x03, 0x82, 0x00, 0x06, 0x00, 0xB7, 0x03, 0xC8, 0x02, 0x06, 0x00, -0xCF, 0x03, 0xC8, 0x02, 0x06, 0x00, 0xE2, 0x03, 0xC8, 0x02, 0x06, 0x00, 0xF7, 0x03, 0xC8, 0x02, -0x06, 0x00, 0x08, 0x04, 0xC8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x01, 0x00, 0x81, 0x01, 0x10, 0x00, 0x18, 0x00, 0x2E, 0x00, 0x05, 0x00, 0x01, 0x00, -0x01, 0x00, 0xA2, 0x10, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x07, 0x00, -0xA2, 0x10, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x09, 0x00, 0xA2, 0x10, -0x00, 0x00, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0B, 0x00, 0x02, 0x10, 0x10, 0x00, -0x59, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x00, 0x0B, 0x00, 0x83, 0x01, 0x10, 0x00, 0x6B, 0x00, -0x00, 0x00, 0x05, 0x00, 0x02, 0x00, 0x0E, 0x00, 0x11, 0x00, 0x90, 0x00, 0x0A, 0x00, 0x50, 0x20, -0x00, 0x00, 0x00, 0x00, 0x96, 0x40, 0x9D, 0x00, 0x0E, 0x00, 0x01, 0x00, 0x61, 0x20, 0x00, 0x00, -0x00, 0x00, 0x96, 0x40, 0xB1, 0x00, 0x12, 0x00, 0x01, 0x00, 0x6E, 0x20, 0x00, 0x00, 0x00, 0x00, -0x96, 0x40, 0xBD, 0x00, 0x0E, 0x00, 0x02, 0x00, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x96, 0x00, -0xD7, 0x00, 0x0E, 0x00, 0x02, 0x00, 0x98, 0x20, 0x00, 0x00, 0x00, 0x00, 0x96, 0x40, 0xE6, 0x00, -0x17, 0x00, 0x02, 0x00, 0x54, 0x21, 0x00, 0x00, 0x00, 0x00, 0x91, 0x18, 0xC1, 0x02, 0xF6, 0x00, -0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 0xC6, 0x0D, 0xEB, 0x00, 0x1D, 0x00, 0x03, 0x00, -0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 0xC6, 0x0D, 0xFB, 0x00, 0x1D, 0x00, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x03, 0x10, 0xC6, 0x0D, 0x23, 0x01, 0x25, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, -0x03, 0x10, 0xC6, 0x05, 0x34, 0x01, 0x2A, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, -0xC6, 0x01, 0x34, 0x01, 0x2A, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 0xC6, 0x09, -0x23, 0x01, 0x25, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 0x86, 0x18, 0x4C, 0x01, -0x34, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x96, 0x20, 0x52, 0x01, 0x38, 0x00, -0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x02, 0x00, 0x00, 0x01, 0x00, 0x46, 0x02, 0x00, 0x20, -0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, -0x01, 0x20, 0x01, 0x00, 0x87, 0x03, 0x01, 0x20, 0x01, 0x00, 0x87, 0x03, 0x00, 0x20, 0x00, 0x00, -0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x10, 0x00, 0x06, 0x00, 0x14, 0x00, -0x06, 0x00, 0x10, 0x00, 0x11, 0x00, 0x4C, 0x01, 0x3C, 0x00, 0x19, 0x00, 0x4C, 0x01, 0x34, 0x00, -0x21, 0x00, 0x4C, 0x01, 0x41, 0x00, 0x31, 0x00, 0x27, 0x02, 0xCD, 0x00, 0x39, 0x00, 0x4C, 0x01, -0x34, 0x00, 0x41, 0x00, 0x6C, 0x02, 0xD7, 0x00, 0x49, 0x00, 0x88, 0x02, 0xDC, 0x00, 0x49, 0x00, -0x90, 0x02, 0xE2, 0x00, 0x49, 0x00, 0xA8, 0x02, 0xE8, 0x00, 0x59, 0x00, 0xB7, 0x02, 0x12, 0x00, -0x61, 0x00, 0x4C, 0x01, 0x34, 0x00, 0x69, 0x00, 0x4C, 0x01, 0x2A, 0x00, 0x71, 0x00, 0x4C, 0x01, -0x24, 0x01, 0x81, 0x00, 0x4C, 0x01, 0x33, 0x01, 0x91, 0x00, 0x4C, 0x01, 0x39, 0x01, 0xA1, 0x00, -0x4C, 0x01, 0x3C, 0x00, 0xA9, 0x00, 0x4C, 0x01, 0x34, 0x00, 0xB1, 0x00, 0x4C, 0x01, 0xA9, 0x01, -0xC1, 0x00, 0x4C, 0x01, 0x0F, 0x02, 0xD1, 0x00, 0x4C, 0x01, 0x1E, 0x02, 0xE1, 0x00, 0x4C, 0x01, -0x2A, 0x00, 0x29, 0x00, 0x83, 0x00, 0x41, 0x01, 0x2E, 0x00, 0x0B, 0x00, 0x2F, 0x02, 0x2E, 0x00, -0x13, 0x00, 0x38, 0x02, 0x49, 0x00, 0x83, 0x00, 0x4A, 0x01, 0x63, 0x00, 0x6B, 0x00, 0x2A, 0x01, -0x63, 0x00, 0x63, 0x00, 0xFA, 0x00, 0x69, 0x00, 0x83, 0x00, 0x41, 0x01, 0x83, 0x00, 0x63, 0x00, -0x53, 0x01, 0x83, 0x00, 0x6B, 0x00, 0x2A, 0x01, 0x89, 0x00, 0x83, 0x00, 0x41, 0x01, 0xA0, 0x00, -0x2B, 0x00, 0xD2, 0x00, 0xA3, 0x00, 0x93, 0x00, 0xAF, 0x01, 0xA3, 0x00, 0x63, 0x00, 0x7F, 0x01, -0xC3, 0x00, 0x9B, 0x00, 0x15, 0x02, 0xC3, 0x00, 0xA3, 0x00, 0x24, 0x02, 0xC3, 0x00, 0x63, 0x00, -0xE5, 0x01, 0x07, 0x00, 0x3F, 0x01, 0x09, 0x00, 0x3F, 0x01, 0x0B, 0x00, 0x7D, 0x01, 0x0D, 0x00, -0x3F, 0x01, 0x0F, 0x00, 0x3F, 0x01, 0x11, 0x00, 0x7D, 0x01, 0x13, 0x00, 0x2D, 0x02, 0x06, 0x00, -0x05, 0x00, 0x47, 0x00, 0x06, 0x00, 0x09, 0x00, 0x47, 0x00, 0x06, 0x00, 0x0D, 0x00, 0x47, 0x00, -0x06, 0x00, 0x15, 0x00, 0x47, 0x00, 0xF1, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x03, 0x00, -0x06, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0B, 0x01, 0x21, 0x00, 0x00, 0x00, 0x17, 0x01, 0x21, 0x00, -0x00, 0x00, 0x3F, 0x01, 0x2F, 0x00, 0x00, 0x00, 0x3F, 0x01, 0x2F, 0x00, 0x02, 0x00, 0x07, 0x00, -0x03, 0x00, 0x02, 0x00, 0x08, 0x00, 0x05, 0x00, 0x02, 0x00, 0x09, 0x00, 0x07, 0x00, 0x02, 0x00, -0x0C, 0x00, 0x09, 0x00, 0x1B, 0x04, 0x00, 0x01, 0x1D, 0x00, 0x52, 0x01, 0x01, 0x00, 0x04, 0x80, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xBE, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, -0x05, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x3C, 0x4D, 0x6F, 0x64, 0x75, 0x6C, 0x65, 0x3E, 0x00, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x54, -0x6F, 0x6F, 0x6C, 0x2E, 0x65, 0x78, 0x65, 0x00, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x4D, 0x61, 0x6E, -0x61, 0x67, 0x65, 0x72, 0x48, 0x65, 0x6C, 0x70, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x00, 0x54, 0x68, -0x65, 0x6D, 0x65, 0x41, 0x70, 0x69, 0x00, 0x49, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x00, 0x49, 0x54, -0x68, 0x65, 0x6D, 0x65, 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x72, 0x00, 0x54, 0x68, 0x65, 0x6D, -0x65, 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x72, 0x00, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x4D, 0x61, -0x6E, 0x61, 0x67, 0x65, 0x72, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x00, 0x4E, 0x61, 0x74, 0x69, 0x76, -0x65, 0x4D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x73, 0x00, 0x6D, 0x73, 0x63, 0x6F, 0x72, 0x6C, 0x69, -0x62, 0x00, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x00, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x00, -0x74, 0x68, 0x65, 0x6D, 0x65, 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x72, 0x00, 0x47, 0x65, 0x74, -0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x4E, 0x61, 0x6D, 0x65, -0x00, 0x43, 0x68, 0x61, 0x6E, 0x67, 0x65, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x00, 0x47, 0x65, 0x74, -0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x56, 0x69, 0x73, 0x75, 0x61, 0x6C, 0x53, 0x74, 0x79, -0x6C, 0x65, 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x47, 0x65, 0x74, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x53, -0x74, 0x61, 0x74, 0x75, 0x73, 0x00, 0x4D, 0x61, 0x69, 0x6E, 0x00, 0x67, 0x65, 0x74, 0x5F, 0x44, -0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x67, 0x65, 0x74, 0x5F, 0x56, -0x69, 0x73, 0x75, 0x61, 0x6C, 0x53, 0x74, 0x79, 0x6C, 0x65, 0x00, 0x44, 0x69, 0x73, 0x70, 0x6C, -0x61, 0x79, 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x56, 0x69, 0x73, 0x75, 0x61, 0x6C, 0x53, 0x74, 0x79, -0x6C, 0x65, 0x00, 0x67, 0x65, 0x74, 0x5F, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x68, -0x65, 0x6D, 0x65, 0x00, 0x41, 0x70, 0x70, 0x6C, 0x79, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x00, 0x43, -0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x00, 0x2E, 0x63, 0x74, 0x6F, -0x72, 0x00, 0x49, 0x73, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, -0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x52, 0x75, 0x6E, 0x74, 0x69, 0x6D, 0x65, 0x2E, 0x43, -0x6F, 0x6D, 0x70, 0x69, 0x6C, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x00, -0x43, 0x6F, 0x6D, 0x70, 0x69, 0x6C, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x52, 0x65, 0x6C, 0x61, 0x78, -0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, -0x52, 0x75, 0x6E, 0x74, 0x69, 0x6D, 0x65, 0x43, 0x6F, 0x6D, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, -0x6C, 0x69, 0x74, 0x79, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x54, 0x68, -0x65, 0x6D, 0x65, 0x54, 0x6F, 0x6F, 0x6C, 0x00, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x53, -0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2E, 0x50, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, -0x6F, 0x6E, 0x73, 0x00, 0x50, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x53, 0x65, -0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x53, 0x65, 0x63, 0x75, 0x72, -0x69, 0x74, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x74, 0x68, 0x65, 0x6D, 0x65, 0x46, -0x69, 0x6C, 0x65, 0x50, 0x61, 0x74, 0x68, 0x00, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, -0x4F, 0x00, 0x50, 0x61, 0x74, 0x68, 0x00, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6C, 0x65, 0x4E, 0x61, -0x6D, 0x65, 0x00, 0x53, 0x54, 0x41, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x41, 0x74, 0x74, 0x72, -0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x61, 0x72, 0x67, 0x73, 0x00, 0x53, 0x79, 0x73, 0x74, 0x65, -0x6D, 0x2E, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x69, 0x7A, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x00, -0x43, 0x75, 0x6C, 0x74, 0x75, 0x72, 0x65, 0x49, 0x6E, 0x66, 0x6F, 0x00, 0x67, 0x65, 0x74, 0x5F, -0x49, 0x6E, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6E, 0x74, 0x43, 0x75, 0x6C, 0x74, 0x75, 0x72, 0x65, -0x00, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x00, 0x54, 0x6F, 0x4C, 0x6F, 0x77, 0x65, 0x72, 0x00, -0x43, 0x6F, 0x6D, 0x70, 0x61, 0x72, 0x65, 0x00, 0x49, 0x46, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x50, -0x72, 0x6F, 0x76, 0x69, 0x64, 0x65, 0x72, 0x00, 0x46, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x00, 0x43, -0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x00, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4C, 0x69, 0x6E, 0x65, -0x00, 0x2E, 0x63, 0x63, 0x74, 0x6F, 0x72, 0x00, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x52, -0x75, 0x6E, 0x74, 0x69, 0x6D, 0x65, 0x2E, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6F, 0x70, 0x53, 0x65, -0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x00, 0x43, 0x6F, 0x6D, 0x49, 0x6D, 0x70, 0x6F, 0x72, 0x74, -0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x47, 0x75, 0x69, 0x64, 0x41, 0x74, -0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, -0x65, 0x54, 0x79, 0x70, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x43, -0x6F, 0x6D, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x00, -0x4D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x49, 0x6D, 0x70, 0x6C, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, -0x75, 0x74, 0x65, 0x00, 0x4D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x49, 0x6D, 0x70, 0x6C, 0x4F, 0x70, -0x74, 0x69, 0x6F, 0x6E, 0x73, 0x00, 0x4D, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6C, 0x41, 0x73, 0x41, -0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x55, 0x6E, 0x6D, 0x61, 0x6E, 0x61, 0x67, -0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x00, 0x44, 0x69, 0x73, 0x70, 0x49, 0x64, 0x41, 0x74, 0x74, -0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x62, 0x73, 0x74, 0x72, 0x54, 0x68, 0x65, 0x6D, 0x65, -0x50, 0x61, 0x74, 0x68, 0x00, 0x49, 0x6E, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, -0x00, 0x43, 0x6F, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, -0x65, 0x00, 0x54, 0x79, 0x70, 0x65, 0x00, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x49, 0x6E, 0x74, 0x65, -0x72, 0x66, 0x61, 0x63, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x43, -0x6C, 0x61, 0x73, 0x73, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, -0x65, 0x00, 0x54, 0x79, 0x70, 0x65, 0x4C, 0x69, 0x62, 0x54, 0x79, 0x70, 0x65, 0x41, 0x74, 0x74, -0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x54, 0x79, 0x70, 0x65, 0x4C, 0x69, 0x62, 0x54, 0x79, -0x70, 0x65, 0x46, 0x6C, 0x61, 0x67, 0x73, 0x00, 0x44, 0x6C, 0x6C, 0x49, 0x6D, 0x70, 0x6F, 0x72, -0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x55, 0x78, 0x54, 0x68, 0x65, -0x6D, 0x65, 0x2E, 0x64, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x0F, 0x73, 0x00, 0x74, 0x00, 0x6F, 0x00, -0x70, 0x00, 0x70, 0x00, 0x65, 0x00, 0x64, 0x00, 0x00, 0x0F, 0x72, 0x00, 0x75, 0x00, 0x6E, 0x00, -0x6E, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x67, 0x00, 0x00, 0x01, 0x00, 0x27, 0x67, 0x00, 0x65, 0x00, -0x74, 0x00, 0x63, 0x00, 0x75, 0x00, 0x72, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x74, 0x00, -0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x61, 0x00, 0x6D, 0x00, -0x65, 0x00, 0x00, 0x17, 0x63, 0x00, 0x68, 0x00, 0x61, 0x00, 0x6E, 0x00, 0x67, 0x00, 0x65, 0x00, -0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x00, 0x33, 0x67, 0x00, 0x65, 0x00, -0x74, 0x00, 0x63, 0x00, 0x75, 0x00, 0x72, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x74, 0x00, -0x76, 0x00, 0x69, 0x00, 0x73, 0x00, 0x75, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x73, 0x00, 0x74, 0x00, -0x79, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x00, 0x1D, -0x67, 0x00, 0x65, 0x00, 0x74, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6D, 0x00, 0x65, 0x00, -0x73, 0x00, 0x74, 0x00, 0x61, 0x00, 0x74, 0x00, 0x75, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, -0x61, 0xE5, 0xD9, 0xBD, 0x60, 0x8C, 0xBA, 0x42, 0xA9, 0x91, 0xE8, 0x47, 0xCD, 0xA9, 0x15, 0x97, -0x00, 0x08, 0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89, 0x03, 0x06, 0x12, 0x10, 0x03, 0x00, -0x00, 0x0E, 0x04, 0x00, 0x01, 0x01, 0x0E, 0x05, 0x00, 0x01, 0x01, 0x1D, 0x0E, 0x03, 0x20, 0x00, -0x0E, 0x03, 0x28, 0x00, 0x0E, 0x04, 0x20, 0x00, 0x12, 0x0C, 0x04, 0x20, 0x01, 0x01, 0x0E, 0x04, -0x28, 0x00, 0x12, 0x0C, 0x03, 0x20, 0x00, 0x01, 0x03, 0x00, 0x00, 0x02, 0x04, 0x20, 0x01, 0x01, -0x08, 0x05, 0x20, 0x01, 0x01, 0x11, 0x15, 0x80, 0x84, 0x2E, 0x01, 0x7F, 0x53, 0x79, 0x73, 0x74, -0x65, 0x6D, 0x2E, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2E, 0x50, 0x65, 0x72, 0x6D, -0x69, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x73, 0x2E, 0x50, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, -0x6F, 0x6E, 0x53, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x2C, 0x20, -0x6D, 0x73, 0x63, 0x6F, 0x72, 0x6C, 0x69, 0x62, 0x2C, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, -0x6E, 0x3D, 0x32, 0x2E, 0x30, 0x2E, 0x30, 0x2E, 0x30, 0x2C, 0x20, 0x43, 0x75, 0x6C, 0x74, 0x75, -0x72, 0x65, 0x3D, 0x6E, 0x65, 0x75, 0x74, 0x72, 0x61, 0x6C, 0x2C, 0x20, 0x50, 0x75, 0x62, 0x6C, -0x69, 0x63, 0x4B, 0x65, 0x79, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x3D, 0x62, 0x37, 0x37, 0x61, 0x35, -0x63, 0x35, 0x36, 0x31, 0x39, 0x33, 0x34, 0x65, 0x30, 0x38, 0x39, 0x01, 0x00, 0x04, 0x00, 0x01, -0x0E, 0x0E, 0x04, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x12, 0x21, 0x05, 0x20, 0x01, 0x0E, -0x12, 0x21, 0x05, 0x00, 0x02, 0x08, 0x0E, 0x0E, 0x08, 0x00, 0x03, 0x0E, 0x12, 0x29, 0x0E, 0x1D, -0x1C, 0x04, 0x07, 0x02, 0x0E, 0x0E, 0x03, 0x00, 0x00, 0x01, 0x29, 0x01, 0x00, 0x24, 0x44, 0x32, -0x33, 0x43, 0x43, 0x37, 0x33, 0x33, 0x2D, 0x35, 0x35, 0x32, 0x32, 0x2D, 0x34, 0x30, 0x36, 0x44, -0x2D, 0x38, 0x44, 0x46, 0x42, 0x2D, 0x42, 0x33, 0x43, 0x46, 0x35, 0x45, 0x46, 0x35, 0x32, 0x41, -0x37, 0x31, 0x00, 0x00, 0x05, 0x20, 0x01, 0x01, 0x11, 0x3D, 0x08, 0x01, 0x00, 0x01, 0x00, 0x00, -0x00, 0x00, 0x00, 0x05, 0x20, 0x01, 0x01, 0x11, 0x45, 0x05, 0x20, 0x01, 0x01, 0x11, 0x4D, 0x01, -0x13, 0x08, 0x01, 0x00, 0x00, 0x00, 0x01, 0x60, 0x00, 0x00, 0x08, 0x01, 0x00, 0x01, 0x00, 0x01, -0x60, 0x00, 0x00, 0x29, 0x01, 0x00, 0x24, 0x30, 0x36, 0x34, 0x36, 0x45, 0x42, 0x42, 0x45, 0x2D, -0x43, 0x31, 0x42, 0x37, 0x2D, 0x34, 0x30, 0x34, 0x35, 0x2D, 0x38, 0x46, 0x44, 0x30, 0x2D, 0x46, -0x46, 0x44, 0x36, 0x35, 0x44, 0x33, 0x46, 0x43, 0x37, 0x39, 0x32, 0x00, 0x00, 0x01, 0x1C, 0x29, -0x01, 0x00, 0x24, 0x41, 0x32, 0x43, 0x35, 0x36, 0x43, 0x32, 0x41, 0x2D, 0x45, 0x36, 0x33, 0x41, -0x2D, 0x34, 0x33, 0x33, 0x45, 0x2D, 0x39, 0x39, 0x35, 0x33, 0x2D, 0x39, 0x32, 0x45, 0x39, 0x34, -0x46, 0x30, 0x31, 0x32, 0x32, 0x45, 0x41, 0x00, 0x00, 0x05, 0x20, 0x01, 0x01, 0x12, 0x5D, 0x35, -0x01, 0x00, 0x30, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x41, 0x70, 0x69, 0x2E, 0x54, 0x68, 0x65, 0x6D, -0x65, 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x72, 0x48, 0x65, 0x6C, 0x70, 0x43, 0x6C, 0x61, 0x73, -0x73, 0x2B, 0x54, 0x68, 0x65, 0x6D, 0x65, 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x72, 0x43, 0x6C, -0x61, 0x73, 0x73, 0x00, 0x00, 0x29, 0x01, 0x00, 0x24, 0x43, 0x30, 0x34, 0x42, 0x33, 0x32, 0x39, -0x45, 0x2D, 0x35, 0x38, 0x32, 0x33, 0x2D, 0x34, 0x34, 0x31, 0x35, 0x2D, 0x39, 0x43, 0x39, 0x33, -0x2D, 0x42, 0x41, 0x34, 0x34, 0x36, 0x38, 0x38, 0x39, 0x34, 0x37, 0x42, 0x30, 0x00, 0x00, 0x05, -0x20, 0x01, 0x01, 0x11, 0x65, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, -0x01, 0x01, 0x11, 0x6D, 0x08, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x08, -0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x01, 0x00, 0x01, 0x00, 0x54, 0x02, 0x16, -0x57, 0x72, 0x61, 0x70, 0x4E, 0x6F, 0x6E, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6F, 0x6E, -0x54, 0x68, 0x72, 0x6F, 0x77, 0x73, 0x01, 0x00, 0x60, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x7E, 0x2D, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x70, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x5F, 0x43, 0x6F, 0x72, 0x45, 0x78, 0x65, 0x4D, 0x61, 0x69, 0x6E, 0x00, 0x6D, 0x73, -0x63, 0x6F, 0x72, 0x65, 0x65, 0x2E, 0x64, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x25, -0x00, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, -0x10, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x80, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, -0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x58, 0x40, 0x00, 0x00, 0x4C, 0x02, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x02, 0x34, 0x00, 0x00, 0x00, 0x56, 0x00, -0x53, 0x00, 0x5F, 0x00, 0x56, 0x00, 0x45, 0x00, 0x52, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4F, 0x00, -0x4E, 0x00, 0x5F, 0x00, 0x49, 0x00, 0x4E, 0x00, 0x46, 0x00, 0x4F, 0x00, 0x00, 0x00, 0x00, 0x00, -0xBD, 0x04, 0xEF, 0xFE, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x00, 0x61, 0x00, 0x72, 0x00, -0x46, 0x00, 0x69, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x49, 0x00, 0x6E, 0x00, 0x66, 0x00, 0x6F, 0x00, -0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x54, 0x00, 0x72, 0x00, 0x61, 0x00, -0x6E, 0x00, 0x73, 0x00, 0x6C, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x04, 0xAC, 0x01, 0x00, 0x00, 0x01, 0x00, 0x53, 0x00, -0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x67, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6C, 0x00, -0x65, 0x00, 0x49, 0x00, 0x6E, 0x00, 0x66, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x88, 0x01, 0x00, 0x00, -0x01, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x34, 0x00, 0x62, 0x00, -0x30, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x02, 0x00, 0x01, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6C, 0x00, -0x65, 0x00, 0x44, 0x00, 0x65, 0x00, 0x73, 0x00, 0x63, 0x00, 0x72, 0x00, 0x69, 0x00, 0x70, 0x00, -0x74, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, -0x30, 0x00, 0x08, 0x00, 0x01, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x56, 0x00, -0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x30, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x00, 0x00, -0x3C, 0x00, 0x0E, 0x00, 0x01, 0x00, 0x49, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, -0x6E, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x4E, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x00, 0x00, -0x54, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x54, 0x00, 0x6F, 0x00, 0x6F, 0x00, -0x6C, 0x00, 0x2E, 0x00, 0x65, 0x00, 0x78, 0x00, 0x65, 0x00, 0x00, 0x00, 0x28, 0x00, 0x02, 0x00, -0x01, 0x00, 0x4C, 0x00, 0x65, 0x00, 0x67, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x43, 0x00, 0x6F, 0x00, -0x70, 0x00, 0x79, 0x00, 0x72, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 0x00, 0x74, 0x00, 0x00, 0x00, -0x20, 0x00, 0x00, 0x00, 0x44, 0x00, 0x0E, 0x00, 0x01, 0x00, 0x4F, 0x00, 0x72, 0x00, 0x69, 0x00, -0x67, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6C, 0x00, -0x65, 0x00, 0x6E, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x00, 0x00, 0x54, 0x00, 0x68, 0x00, -0x65, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x54, 0x00, 0x6F, 0x00, 0x6F, 0x00, 0x6C, 0x00, 0x2E, 0x00, -0x65, 0x00, 0x78, 0x00, 0x65, 0x00, 0x00, 0x00, 0x34, 0x00, 0x08, 0x00, 0x01, 0x00, 0x50, 0x00, -0x72, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x75, 0x00, 0x63, 0x00, 0x74, 0x00, 0x56, 0x00, 0x65, 0x00, -0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, -0x30, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0x08, 0x00, -0x01, 0x00, 0x41, 0x00, 0x73, 0x00, 0x73, 0x00, 0x65, 0x00, 0x6D, 0x00, 0x62, 0x00, 0x6C, 0x00, -0x79, 0x00, 0x20, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6F, 0x00, -0x6E, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x2E, 0x00, -0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x20, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x90, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; -const size_t themeToolSize = sizeof(themeToolData); +#include +#include +#include +#define THEME_MUTEX_NAME L"Local\\OnlyOneExplorer" HANDLE g_timerThread = nullptr; HANDLE g_wakeEvent = nullptr; @@ -417,7 +62,7 @@ void ApplyLockScreen() { if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\PersonalizationCSP", 0, nullptr, 0, KEY_SET_VALUE, nullptr, &hKey, nullptr) == ERROR_SUCCESS) { - for (const wchar_t* valueName : { L"LockScreenImagePath", L"LockScreenImageUrl" }) { + for (PCWSTR valueName : { L"LockScreenImagePath", L"LockScreenImageUrl" }) { RegSetValueExW(hKey, valueName, 0, REG_SZ, (const BYTE*)wallpaperPath.c_str(), (DWORD)((wallpaperPath.size() + 1) * sizeof(wchar_t))); } RegCloseKey(hKey); @@ -436,25 +81,26 @@ bool IsAppearanceApplied(Appearance appearance) { return current == val; } -bool IsThemeApplied(const wchar_t* themePath) { +bool IsThemeApplied(PCWSTR themePath) { wchar_t currentTheme[MAX_PATH] = {0}; DWORD size = sizeof(currentTheme); - if (RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes", L"CurrentTheme", RRF_RT_REG_SZ, nullptr, currentTheme, &size) != ERROR_SUCCESS) return false; if (_wcsicmp(currentTheme, themePath) != 0) return false; DWORD appsLight = 1, systemLight = 1, dataSize = sizeof(DWORD); - RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"AppsUseLightTheme", RRF_RT_REG_DWORD, nullptr, &appsLight, &dataSize); - RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"SystemUsesLightTheme", RRF_RT_REG_DWORD, nullptr, &systemLight, &dataSize); + if (RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"AppsUseLightTheme", RRF_RT_REG_DWORD, nullptr, &appsLight, &dataSize) != ERROR_SUCCESS) + return false; + if (RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"SystemUsesLightTheme", RRF_RT_REG_DWORD, nullptr, &systemLight, &dataSize) != ERROR_SUCCESS) + return false; std::wifstream file(themePath); if (!file) return false; - std::wstring line, systemMode, appMode; bool inVisualStyles = false; + std::wstring line, systemMode, appMode; while (std::getline(file, line)) { if (line.empty() || line[0] == L';') continue; if (line[0] == L'[') { @@ -494,64 +140,68 @@ void ApplyAppearance(Appearance appearance) { ApplyLockScreen(); } -void ApplyTheme(const wchar_t* themePath) { +// Based on: +// https://github.com/qwerty12/AutoHotkeyScripts/blob/a9423f59c945a3a031cb38b25cf461a34de9a6d3/SetThemeFromdotThemeFile.ahk +void ApplyTheme(PCWSTR themePath) { std::thread([=]() { - // check if explorer is loaded Wh_Log(L"[Theme] Waiting for explorer to load..."); for (;;) { HWND progman = FindWindowW(L"Progman", nullptr); HWND tray = FindWindowW(L"Shell_TrayWnd", nullptr); - if (progman && tray && IsWindowVisible(tray)) break; + if (progman && tray && IsWindowVisible(tray)) + break; Sleep(500); } Wh_Log(L"[Theme] Explorer loaded"); - wchar_t toolPath[MAX_PATH]; - GetTempPathW(MAX_PATH, toolPath); - wcscat_s(toolPath, L"ThemeTool.exe"); - - // write themetool to temp - std::ofstream file(toolPath, std::ios::binary); - if (!file) { - Wh_Log(L"[ThemeTool] Failed to write ThemeTool: %s", toolPath); + if (!themePath || !*themePath) { + Wh_Log(L"[Theme] No theme path specified."); return; } - file.write(reinterpret_cast(themeToolData), themeToolSize); - file.close(); - - Wh_Log(L"[ThemeTool] Written to %s", toolPath); - - // change theme using themetool - wchar_t cmd[1024]; - swprintf(cmd, 1024, L"\"%s\" ChangeTheme \"%s\"", toolPath, themePath); - Wh_Log(L"[ThemeTool] Changing theme using ThemeTool"); - STARTUPINFOW si = { sizeof(si) }; - PROCESS_INFORMATION pi; - - if (CreateProcessW(nullptr, cmd, nullptr, nullptr, FALSE, CREATE_NO_WINDOW, nullptr, nullptr, &si, &pi)) { - CloseHandle(pi.hThread); - WaitForSingleObject(pi.hProcess, INFINITE); - CloseHandle(pi.hProcess); - } else { - DWORD err = GetLastError(); - Wh_Log(L"[ThemeTool] Failed to launch theme tool. Error code: %u", err); + CoInitialize(nullptr); + + // {C04B329E-5823-4415-9C93-BA44688947B0} + constexpr winrt::guid CLSID_IThemeManager{ + 0xC04B329E, + 0x5823, + 0x4415, + {0x9C, 0x93, 0xBA, 0x44, 0x68, 0x89, 0x47, 0xB0}}; + + // {0646EBBE-C1B7-4045-8FD0-FFD65D3FC792} + constexpr winrt::guid IID_IThemeManager{ + 0x0646EBBE, + 0xC1B7, + 0x4045, + {0x8F, 0xD0, 0xFF, 0xD6, 0x5D, 0x3F, 0xC7, 0x92}}; + + winrt::com_ptr pThemeManager; + HRESULT hr = + CoCreateInstance(CLSID_IThemeManager, nullptr, CLSCTX_INPROC_SERVER, + IID_IThemeManager, pThemeManager.put_void()); + if (FAILED(hr) || !pThemeManager) { + Wh_Log(L"[Theme] Failed to apply theme."); } - // delete themetool - if (DeleteFileW(toolPath)) { - Wh_Log(L"[ThemeTool] Deleted %s", toolPath); - } else { - Wh_Log(L"[ThemeTool] Failed to delete %s", toolPath); + _bstr_t bstrTheme(themePath); + void** vtable = *(void***)pThemeManager.get(); + using ApplyThemeFunc = HRESULT(WINAPI*)(IUnknown*, BSTR); + ApplyThemeFunc ApplyThemeMethod = (ApplyThemeFunc)vtable[4]; + hr = ApplyThemeMethod(pThemeManager.get(), bstrTheme); + if (FAILED(hr)) { + Wh_Log(L"[Theme] Failed to apply theme."); } - // apply wallpaper to lock screen + Wh_Log(L"[Theme] Successfully applied theme"); + + CoUninitialize(); + if (Wh_GetIntSetting(L"LockScreen")) ApplyLockScreen(); }).detach(); } -SYSTEMTIME ParseScheduleTime(const wchar_t* timeStr) { +SYSTEMTIME ParseScheduleTime(PCWSTR timeStr) { SYSTEMTIME st = {}; swscanf_s(timeStr, L"%hu:%hu", &st.wHour, &st.wMinute); return st; @@ -595,10 +245,12 @@ DWORD WINAPI ThemeScheduler(LPVOID) { time_t nextSwitch = GetNextSwitch(g_lightTime, g_darkTime, nextLight); int waitTime = (int)(nextSwitch - now); DWORD res = WaitForSingleObject(g_wakeEvent, waitTime * 1000); - if (g_exitFlag) break; - if (res == WAIT_OBJECT_0) continue; + if (res == WAIT_OBJECT_0) { + if (g_exitFlag) break; + continue; + } - const wchar_t* themePath = nextLight ? g_lightThemePath.c_str() : g_darkThemePath.c_str(); + PCWSTR themePath = nextLight ? g_lightThemePath.c_str() : g_darkThemePath.c_str(); if (*themePath) { if (IsThemeApplied(themePath)) { @@ -663,7 +315,7 @@ void LoadSettings() { else isLightNow = now >= lightT || now < darkT; - const wchar_t* themePath = isLightNow ? g_lightThemePath.c_str() : g_darkThemePath.c_str(); + PCWSTR themePath = isLightNow ? g_lightThemePath.c_str() : g_darkThemePath.c_str(); if (*themePath) { if (IsThemeApplied(themePath)) { Wh_Log(L"[Theme] Theme already applied."); @@ -681,13 +333,31 @@ void LoadSettings() { StartScheduler(); } +HANDLE g_hMutex = nullptr; + BOOL Wh_ModInit() { + g_hMutex = CreateMutexW(nullptr, FALSE, THEME_MUTEX_NAME); + if (!g_hMutex) { + return FALSE; + } + + DWORD waitResult = WaitForSingleObject(g_hMutex, 0); + if (waitResult == WAIT_TIMEOUT) { + CloseHandle(g_hMutex); + g_hMutex = nullptr; + return FALSE; + } + LoadSettings(); return TRUE; } void Wh_ModSettingsChanged() { - LoadSettings(); + if (g_hMutex && WaitForSingleObject(g_hMutex, 0) == WAIT_OBJECT_0) { + LoadSettings(); + } else { + Wh_Log(L"[Theme] Settings changed ignored, not the owner."); + } } void Wh_ModUninit() { @@ -698,4 +368,10 @@ void Wh_ModUninit() { CloseHandle(g_timerThread); } if (g_wakeEvent) CloseHandle(g_wakeEvent); + + if (g_hMutex) { + ReleaseMutex(g_hMutex); + CloseHandle(g_hMutex); + g_hMutex = nullptr; + } } From cb4609017e6fa92f1f42bdbf483e7bbcf14261c4 Mon Sep 17 00:00:00 2001 From: tino <79853146+tinodin@users.noreply.github.com> Date: Fri, 23 May 2025 20:33:13 +0200 Subject: [PATCH 4/7] Improved apply theme, move apply current theme to a new function, add Wh_FreeStringSetting --- mods/auto-theme-switcher.wh.cpp | 359 ++++++++++++++++++++++---------- 1 file changed, 250 insertions(+), 109 deletions(-) diff --git a/mods/auto-theme-switcher.wh.cpp b/mods/auto-theme-switcher.wh.cpp index 1e515eed8..788294439 100644 --- a/mods/auto-theme-switcher.wh.cpp +++ b/mods/auto-theme-switcher.wh.cpp @@ -5,7 +5,7 @@ // @version 1.0 // @author tinodin // @github https://github.com/tinodin -// @include explorer.exe +// @include windhawk.exe // @compilerOptions -lole32 -loleaut32 // ==/WindhawkMod== @@ -28,7 +28,6 @@ #include #include #include -#define THEME_MUTEX_NAME L"Local\\OnlyOneExplorer" HANDLE g_timerThread = nullptr; HANDLE g_wakeEvent = nullptr; @@ -143,7 +142,47 @@ void ApplyAppearance(Appearance appearance) { // Based on: // https://github.com/qwerty12/AutoHotkeyScripts/blob/a9423f59c945a3a031cb38b25cf461a34de9a6d3/SetThemeFromdotThemeFile.ahk void ApplyTheme(PCWSTR themePath) { - std::thread([=]() { + // {C04B329E-5823-4415-9C93-BA44688947B0} + constexpr winrt::guid CLSID_IThemeManager{ + 0xC04B329E, + 0x5823, + 0x4415, + {0x9C, 0x93, 0xBA, 0x44, 0x68, 0x89, 0x47, 0xB0}}; + + // {0646EBBE-C1B7-4045-8FD0-FFD65D3FC792} + constexpr winrt::guid IID_IThemeManager{ + 0x0646EBBE, + 0xC1B7, + 0x4045, + {0x8F, 0xD0, 0xFF, 0xD6, 0x5D, 0x3F, 0xC7, 0x92}}; + + winrt::com_ptr pThemeManager; + HRESULT hr = + CoCreateInstance(CLSID_IThemeManager, nullptr, CLSCTX_INPROC_SERVER, + IID_IThemeManager, pThemeManager.put_void()); + if (FAILED(hr) || !pThemeManager) { + Wh_Log(L"[Theme] Failed to apply theme."); + } + + _bstr_t bstrTheme(themePath); + void** vtable = *(void***)pThemeManager.get(); + using ApplyThemeFunc = HRESULT(WINAPI*)(IUnknown*, BSTR); + ApplyThemeFunc ApplyThemeMethod = (ApplyThemeFunc)vtable[4]; + hr = ApplyThemeMethod(pThemeManager.get(), bstrTheme); + if (FAILED(hr)) { + Wh_Log(L"[Theme] Failed to apply theme."); + } + + Wh_Log(L"[Theme] Successfully applied theme"); + + if (Wh_GetIntSetting(L"LockScreen")) + ApplyLockScreen(); +} + +void ApplyThemeOrAppearance(bool useLightTheme) { + PCWSTR themePath = useLightTheme ? g_lightThemePath.c_str() : g_darkThemePath.c_str(); + + if (*themePath) { Wh_Log(L"[Theme] Waiting for explorer to load..."); for (;;) { HWND progman = FindWindowW(L"Progman", nullptr); @@ -154,51 +193,44 @@ void ApplyTheme(PCWSTR themePath) { } Wh_Log(L"[Theme] Explorer loaded"); - if (!themePath || !*themePath) { - Wh_Log(L"[Theme] No theme path specified."); + if (IsThemeApplied(themePath)) { + Wh_Log(L"[Theme] Theme already applied."); return; } CoInitialize(nullptr); - - // {C04B329E-5823-4415-9C93-BA44688947B0} - constexpr winrt::guid CLSID_IThemeManager{ - 0xC04B329E, - 0x5823, - 0x4415, - {0x9C, 0x93, 0xBA, 0x44, 0x68, 0x89, 0x47, 0xB0}}; - - // {0646EBBE-C1B7-4045-8FD0-FFD65D3FC792} - constexpr winrt::guid IID_IThemeManager{ - 0x0646EBBE, - 0xC1B7, - 0x4045, - {0x8F, 0xD0, 0xFF, 0xD6, 0x5D, 0x3F, 0xC7, 0x92}}; - - winrt::com_ptr pThemeManager; - HRESULT hr = - CoCreateInstance(CLSID_IThemeManager, nullptr, CLSCTX_INPROC_SERVER, - IID_IThemeManager, pThemeManager.put_void()); - if (FAILED(hr) || !pThemeManager) { - Wh_Log(L"[Theme] Failed to apply theme."); + ApplyTheme(themePath); + CoUninitialize(); + } else { + if (IsAppearanceApplied(useLightTheme ? light : dark)) { + Wh_Log(L"[Theme] Appearance already applied."); + return; } + ApplyAppearance(useLightTheme ? light : dark); + } +} - _bstr_t bstrTheme(themePath); - void** vtable = *(void***)pThemeManager.get(); - using ApplyThemeFunc = HRESULT(WINAPI*)(IUnknown*, BSTR); - ApplyThemeFunc ApplyThemeMethod = (ApplyThemeFunc)vtable[4]; - hr = ApplyThemeMethod(pThemeManager.get(), bstrTheme); - if (FAILED(hr)) { - Wh_Log(L"[Theme] Failed to apply theme."); - } +void ApplyCurrentTheme() { + time_t now = time(nullptr); + struct tm local; + localtime_s(&local, &now); - Wh_Log(L"[Theme] Successfully applied theme"); + auto makeTime = [&](const SYSTEMTIME& st) { + struct tm t = local; + t.tm_hour = st.wHour; t.tm_min = st.wMinute; t.tm_sec = 0; + return mktime(&t); + }; - CoUninitialize(); + time_t lightT = makeTime(g_lightTime); + time_t darkT = makeTime(g_darkTime); + + bool isLightNow; + if (lightT < darkT) + isLightNow = now >= lightT && now < darkT; + else + isLightNow = now >= lightT || now < darkT; - if (Wh_GetIntSetting(L"LockScreen")) - ApplyLockScreen(); - }).detach(); + ApplyThemeOrAppearance(isLightNow); } SYSTEMTIME ParseScheduleTime(PCWSTR timeStr) { @@ -250,26 +282,15 @@ DWORD WINAPI ThemeScheduler(LPVOID) { continue; } - PCWSTR themePath = nextLight ? g_lightThemePath.c_str() : g_darkThemePath.c_str(); + ApplyThemeOrAppearance(nextLight); - if (*themePath) { - if (IsThemeApplied(themePath)) { - Wh_Log(L"[Theme] Theme already applied."); - continue; - } - ApplyTheme(themePath); - } else { - if (IsAppearanceApplied(nextLight ? light : dark)) { - Wh_Log(L"[Theme] Appearance already applied."); - continue; - } - ApplyAppearance(nextLight ? light : dark); - } } return 0; } void StartScheduler() { + ApplyCurrentTheme(); + if (g_timerThread) { SetEvent(g_wakeEvent); return; @@ -287,91 +308,211 @@ std::wstring TrimQuotes(const std::wstring& str) { } void LoadSettings() { - g_lightTime = ParseScheduleTime(Wh_GetStringSetting(L"Light")); - g_darkTime = ParseScheduleTime(Wh_GetStringSetting(L"Dark")); + auto rawLight = Wh_GetStringSetting(L"Light"); + g_lightTime = ParseScheduleTime(rawLight); + if (rawLight) Wh_FreeStringSetting(rawLight); + + auto rawDark = Wh_GetStringSetting(L"Dark"); + g_darkTime = ParseScheduleTime(rawDark); + if (rawDark) Wh_FreeStringSetting(rawDark); auto rawLightPath = Wh_GetStringSetting(L"LightThemePath"); g_lightThemePath = rawLightPath ? TrimQuotes(rawLightPath) : L""; + if (rawLightPath) Wh_FreeStringSetting(rawLightPath); auto rawDarkPath = Wh_GetStringSetting(L"DarkThemePath"); g_darkThemePath = rawDarkPath ? TrimQuotes(rawDarkPath) : L""; + if (rawDarkPath) Wh_FreeStringSetting(rawDarkPath); +} - time_t now = time(nullptr); - struct tm local; - localtime_s(&local, &now); +BOOL WhTool_ModInit() { + LoadSettings(); + StartScheduler(); + return TRUE; +} - auto makeTime = [&](const SYSTEMTIME& st) { - struct tm t = local; - t.tm_hour = st.wHour; t.tm_min = st.wMinute; t.tm_sec = 0; - return mktime(&t); - }; +void WhTool_ModSettingsChanged() { + LoadSettings(); + StartScheduler(); +} - time_t lightT = makeTime(g_lightTime); - time_t darkT = makeTime(g_darkTime); +void WhTool_ModUninit() { + g_exitFlag = true; + if (g_wakeEvent) SetEvent(g_wakeEvent); + if (g_timerThread) { + WaitForSingleObject(g_timerThread, INFINITE); + CloseHandle(g_timerThread); + } + if (g_wakeEvent) CloseHandle(g_wakeEvent); +} - bool isLightNow; - if (lightT < darkT) - isLightNow = now >= lightT && now < darkT; - else - isLightNow = now >= lightT || now < darkT; - - PCWSTR themePath = isLightNow ? g_lightThemePath.c_str() : g_darkThemePath.c_str(); - if (*themePath) { - if (IsThemeApplied(themePath)) { - Wh_Log(L"[Theme] Theme already applied."); - return; - } - ApplyTheme(themePath); - } else { - if (IsAppearanceApplied(isLightNow ? light : dark)) { - Wh_Log(L"[Theme] Appearance already applied."); - return; +//////////////////////////////////////////////////////////////////////////////// +// Windhawk tool mod implementation for mods which don't need to inject to other +// processes or hook other functions. Context: +// https://github.com/ramensoftware/windhawk-mods/pull/1916 +// +// The mod will load and run in a dedicated windhawk.exe process. +// +// Paste the code below as part of the mod code, and use these callbacks: +// * WhTool_ModInit +// * WhTool_ModSettingsChanged +// * WhTool_ModUninit +// +// Currently, other callbacks are not supported. + +bool g_isToolModProcessLauncher; +HANDLE g_toolModProcessMutex; + +void WINAPI EntryPoint_Hook() { + Wh_Log(L">"); + ExitThread(0); +} + +BOOL Wh_ModInit() { + bool isService = false; + bool isToolModProcess = false; + bool isCurrentToolModProcess = false; + int argc; + LPWSTR* argv = CommandLineToArgvW(GetCommandLine(), &argc); + if (!argv) { + Wh_Log(L"CommandLineToArgvW failed"); + return FALSE; + } + + for (int i = 1; i < argc; i++) { + if (wcscmp(argv[i], L"-service") == 0) { + isService = true; + break; } - ApplyAppearance(isLightNow ? light : dark); } - StartScheduler(); -} + for (int i = 1; i < argc - 1; i++) { + if (wcscmp(argv[i], L"-tool-mod") == 0) { + isToolModProcess = true; + if (wcscmp(argv[i + 1], WH_MOD_ID) == 0) { + isCurrentToolModProcess = true; + } + break; + } + } -HANDLE g_hMutex = nullptr; + LocalFree(argv); -BOOL Wh_ModInit() { - g_hMutex = CreateMutexW(nullptr, FALSE, THEME_MUTEX_NAME); - if (!g_hMutex) { + if (isService) { return FALSE; } - DWORD waitResult = WaitForSingleObject(g_hMutex, 0); - if (waitResult == WAIT_TIMEOUT) { - CloseHandle(g_hMutex); - g_hMutex = nullptr; + if (isCurrentToolModProcess) { + g_toolModProcessMutex = + CreateMutex(nullptr, TRUE, L"windhawk-tool-mod_" WH_MOD_ID); + if (!g_toolModProcessMutex) { + Wh_Log(L"CreateMutex failed"); + ExitProcess(1); + } + + if (GetLastError() == ERROR_ALREADY_EXISTS) { + Wh_Log(L"Tool mod already running (%s)", WH_MOD_ID); + ExitProcess(1); + } + + if (!WhTool_ModInit()) { + ExitProcess(1); + } + + IMAGE_DOS_HEADER* dosHeader = + (IMAGE_DOS_HEADER*)GetModuleHandle(nullptr); + IMAGE_NT_HEADERS* ntHeaders = + (IMAGE_NT_HEADERS*)((BYTE*)dosHeader + dosHeader->e_lfanew); + + DWORD entryPointRVA = ntHeaders->OptionalHeader.AddressOfEntryPoint; + void* entryPoint = (BYTE*)dosHeader + entryPointRVA; + + Wh_SetFunctionHook(entryPoint, (void*)EntryPoint_Hook, nullptr); + return TRUE; + } + + if (isToolModProcess) { return FALSE; } - LoadSettings(); + g_isToolModProcessLauncher = true; return TRUE; } +void Wh_ModAfterInit() { + if (!g_isToolModProcessLauncher) { + return; + } + + WCHAR currentProcessPath[MAX_PATH]; + switch (GetModuleFileName(nullptr, currentProcessPath, + ARRAYSIZE(currentProcessPath))) { + case 0: + case ARRAYSIZE(currentProcessPath): + Wh_Log(L"GetModuleFileName failed"); + return; + } + + WCHAR + commandLine[MAX_PATH + 2 + + (sizeof(L" -tool-mod \"" WH_MOD_ID "\"") / sizeof(WCHAR)) - 1]; + swprintf_s(commandLine, L"\"%s\" -tool-mod \"%s\"", currentProcessPath, + WH_MOD_ID); + + HMODULE kernelModule = GetModuleHandle(L"kernelbase.dll"); + if (!kernelModule) { + kernelModule = GetModuleHandle(L"kernel32.dll"); + if (!kernelModule) { + Wh_Log(L"No kernelbase.dll/kernel32.dll"); + return; + } + } + + using CreateProcessInternalW_t = BOOL(WINAPI*)( + HANDLE hUserToken, LPCWSTR lpApplicationName, LPWSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, WINBOOL bInheritHandles, + DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, + LPSTARTUPINFOW lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation, + PHANDLE hRestrictedUserToken); + CreateProcessInternalW_t pCreateProcessInternalW = + (CreateProcessInternalW_t)GetProcAddress(kernelModule, + "CreateProcessInternalW"); + if (!pCreateProcessInternalW) { + Wh_Log(L"No CreateProcessInternalW"); + return; + } + + STARTUPINFO si{ + .cb = sizeof(STARTUPINFO), + .dwFlags = STARTF_FORCEOFFFEEDBACK, + }; + PROCESS_INFORMATION pi; + if (!pCreateProcessInternalW(nullptr, currentProcessPath, commandLine, + nullptr, nullptr, FALSE, NORMAL_PRIORITY_CLASS, + nullptr, nullptr, &si, &pi, nullptr)) { + Wh_Log(L"CreateProcess failed"); + return; + } + + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); +} + void Wh_ModSettingsChanged() { - if (g_hMutex && WaitForSingleObject(g_hMutex, 0) == WAIT_OBJECT_0) { - LoadSettings(); - } else { - Wh_Log(L"[Theme] Settings changed ignored, not the owner."); + if (g_isToolModProcessLauncher) { + return; } + + WhTool_ModSettingsChanged(); } void Wh_ModUninit() { - g_exitFlag = true; - if (g_wakeEvent) SetEvent(g_wakeEvent); - if (g_timerThread) { - WaitForSingleObject(g_timerThread, INFINITE); - CloseHandle(g_timerThread); + if (g_isToolModProcessLauncher) { + return; } - if (g_wakeEvent) CloseHandle(g_wakeEvent); - if (g_hMutex) { - ReleaseMutex(g_hMutex); - CloseHandle(g_hMutex); - g_hMutex = nullptr; - } + WhTool_ModUninit(); + ExitProcess(0); } From 4e1d660dfa6368caa26c4ad5d298d391ccefaf09 Mon Sep 17 00:00:00 2001 From: tino <79853146+tinodin@users.noreply.github.com> Date: Fri, 23 May 2025 22:56:37 +0200 Subject: [PATCH 5/7] Return if ApplyTheme failed, Move ApplyLockScreen into ApplyThemeOrAppearance, Return out of loop if exiting --- mods/auto-theme-switcher.wh.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/mods/auto-theme-switcher.wh.cpp b/mods/auto-theme-switcher.wh.cpp index 788294439..6ba30545c 100644 --- a/mods/auto-theme-switcher.wh.cpp +++ b/mods/auto-theme-switcher.wh.cpp @@ -133,10 +133,6 @@ void ApplyAppearance(Appearance appearance) { SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)L"ImmersiveColorSet", SMTO_ABORTIFHUNG, 100, nullptr); Wh_Log(L"[Theme] Applied %s Mode.", appearance == light ? L"Light" : L"Dark"); - - // apply wallpaper to lock screen - if (Wh_GetIntSetting(L"LockScreen")) - ApplyLockScreen(); } // Based on: @@ -162,6 +158,7 @@ void ApplyTheme(PCWSTR themePath) { IID_IThemeManager, pThemeManager.put_void()); if (FAILED(hr) || !pThemeManager) { Wh_Log(L"[Theme] Failed to apply theme."); + return; } _bstr_t bstrTheme(themePath); @@ -174,9 +171,6 @@ void ApplyTheme(PCWSTR themePath) { } Wh_Log(L"[Theme] Successfully applied theme"); - - if (Wh_GetIntSetting(L"LockScreen")) - ApplyLockScreen(); } void ApplyThemeOrAppearance(bool useLightTheme) { @@ -185,6 +179,9 @@ void ApplyThemeOrAppearance(bool useLightTheme) { if (*themePath) { Wh_Log(L"[Theme] Waiting for explorer to load..."); for (;;) { + if (g_exitFlag) { + return; + } HWND progman = FindWindowW(L"Progman", nullptr); HWND tray = FindWindowW(L"Shell_TrayWnd", nullptr); if (progman && tray && IsWindowVisible(tray)) @@ -201,12 +198,18 @@ void ApplyThemeOrAppearance(bool useLightTheme) { CoInitialize(nullptr); ApplyTheme(themePath); CoUninitialize(); + + if (Wh_GetIntSetting(L"LockScreen")) + ApplyLockScreen(); } else { if (IsAppearanceApplied(useLightTheme ? light : dark)) { Wh_Log(L"[Theme] Appearance already applied."); return; } ApplyAppearance(useLightTheme ? light : dark); + + if (Wh_GetIntSetting(L"LockScreen")) + ApplyLockScreen(); } } From 23f1b16b6e91955f1ecbf9d404177c96447ad577 Mon Sep 17 00:00:00 2001 From: tino <79853146+tinodin@users.noreply.github.com> Date: Sat, 24 May 2025 00:08:13 +0200 Subject: [PATCH 6/7] Add README --- mods/auto-theme-switcher.wh.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/mods/auto-theme-switcher.wh.cpp b/mods/auto-theme-switcher.wh.cpp index 6ba30545c..f393c1ee9 100644 --- a/mods/auto-theme-switcher.wh.cpp +++ b/mods/auto-theme-switcher.wh.cpp @@ -1,7 +1,7 @@ // ==WindhawkMod== // @id auto-theme-switcher // @name Auto Theme Switcher -// @description Automatically changes between light and dark mode/themes based on a set schedule +// @description Automatically switch between light and dark mode/theme based on a set schedule // @version 1.0 // @author tinodin // @github https://github.com/tinodin @@ -9,6 +9,31 @@ // @compilerOptions -lole32 -loleaut32 // ==/WindhawkMod== +// ==WindhawkModReadme== +/* +# Auto Theme Switcher + +Configure the schedule for light and dark mode/theme under settings + (By default: `07:00` for light, `19:00` for dark) + +Provide paths to your desired `.theme` files + (By default: `aero.theme` for light, `dark.theme` for dark) + +- Themes shipped with Windows are located in: + `C:\Windows\Resources\Themes` + +- Saved or imported themes are located in: + `C:\Users\user\AppData\Local\Microsoft\Windows\Themes` + +- If no `.theme` file is provided, the mod will default to only changing the appearance + +- To create custom `.theme` files, use the Personalization settings in Windows + [Video guide](https://www.youtube.com/watch?v=-QWR6NQZAUg) + +If you do not want the wallpaper to be applied to the lock screen, disable *Apply Wallpaper to Lock screen* under settings +*/ +// ==/WindhawkModReadme== + // ==WindhawkModSettings== /* - Light: 07:00 From 349d54623a2f54cd33fae634c662138a5f24cbb2 Mon Sep 17 00:00:00 2001 From: tino <79853146+tinodin@users.noreply.github.com> Date: Sat, 24 May 2025 00:14:20 +0200 Subject: [PATCH 7/7] Change to %LOCALAPPDATA% instead of having to fill in username --- mods/auto-theme-switcher.wh.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/auto-theme-switcher.wh.cpp b/mods/auto-theme-switcher.wh.cpp index f393c1ee9..d9d35c076 100644 --- a/mods/auto-theme-switcher.wh.cpp +++ b/mods/auto-theme-switcher.wh.cpp @@ -23,7 +23,7 @@ Provide paths to your desired `.theme` files `C:\Windows\Resources\Themes` - Saved or imported themes are located in: - `C:\Users\user\AppData\Local\Microsoft\Windows\Themes` + `%LOCALAPPDATA%\Microsoft\Windows\Themes` - If no `.theme` file is provided, the mod will default to only changing the appearance