From 83e13e814b927c89884103823bd3870ef89942ca Mon Sep 17 00:00:00 2001 From: Stefan Markovic <57057282+stefansjfw@users.noreply.github.com> Date: Tue, 21 Jan 2025 14:28:51 +0100 Subject: [PATCH] Mere PT upstream #8 (#346) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Workspaces] implement the move feature (#35480) * [Workspaces] Add move functionality * spell checker * [Workspaces] Modify Arranger to move apps without launch * moved ipc helper * removed callback * use LauncherStatus in WindowArranger * wait for launching next app * launch in a separate thread and protect by mutexes * update app version in advance * changed canceling launch * increased waiting time * Fix optional parameter load from json * changed arranger waiting time * additional waiting time for Outlook * added app id * ensure ids before launch * set id in editor * minor updates * [Workspaces] Move: Get the nearest window when moving a window * [Workspaces] convert optional boolean to enum to avoid json problems * Handle case when the new Application Property "moveIfExists" does not exist * Re-implementing app-window pairing for moving feature. * spell checker * XAML formatting * Fixing bug: IPC message not arriving * spell checker * Removing app-level-setting for move app. Also fixed compiler errors due styling. * Updating editor window layout * Re-implementing window positioning UI elements * XAML formatting * Code review findings * Code cleanup * Code cleanup * Code cleanup * code cleanup * Code cleanup * Code cleanup * fix Move attribute after launch and snapshot * Extend WindowArranger with PWA functionality to detect different PWA apps. PwaHelper moved to the common library * fix repeat counter in the editor * Code optimization * code cleanup, optimization * fix double-processing window --------- Co-authored-by: Seraphima Co-authored-by: donlaci * [KeyboardManager]Fix mapping shift to numpad (#35890) * Keyboard Manger fix numpad as shift Fixed shift not being released if a numpad key as shift. * Added comments * Fix typo * Fix the numpad unlocked key not working if the locked version is overridden by shift * Fix spelling check. * Revert the VK_CLEAR change. --------- Co-authored-by: Jaime Bernardo * [Analyzers] Update .editorconfig with rules to relax IDE errors (#36095) * [Analyzers] Remove duplicate pascal case style from .editorconfig * [Analyzers] Configured severity for individual IDE and CA rules showing as errors in VS Set severity for IDE0005, IDE0008, IDE0016, IDE0018, IDE0019, IDE0021, IDE0022, IDE0023, IDE0025, IDE0027, IDE0028, IDE0029, IDE0031, IDE0032, IDE0034, IDE0036, IDE0039, IDE0042, IDE0044, IDE0045, IDE0046, IDE0047, IDE0057, IDE0051, IDE0052, IDE0054, IDE0055, IDE0056, IDE0057, IDE0059, IDE0060, IDE0061, IDE0063, IDE0071, IDE0073, IDE0074, IDE0075, IDE0077, IDE0078, IDE0083, IDE0090, IDE0100, IDE0130, IDE160, IDE180, IDE0200, IDE0240, IDE0250, IDE0251, IDE0260, IDE0270, IDE0290, IDE0300, IDE0301, IDE0305, IDE1005, IDE1006, CA1859, CA2022, CA2263 * [Analyzers] Fix mismatched analyzer descriptions * [Analyzers] Fix misspelling * Update .editorconfig Made the following style rules `silent` instead of `suggestion`: - Use explicit type instead of 'var' - Use expression body for ... - Use block-scoped namespace * [Analyzers] Set IDE0290 to silent * [Analyzers] Remove IDE1006 configuration from .editorconfig in favor of making exclusions for the few entries * [Analyzers][Indexer] Add IDE1006 suppressions * [Analyzers][Peek] Add IDE1006 suppression * [Analyzers][MWB] Add IDE1006 suppression. * [Analyzers][Plugins] Add IDE1006 suppression * [Analyzers][ImageResizer] Suppress IDE0073 to retain original copyright * [Analyzers] Remove IDE0073 severity change in .editorconfig --------- Co-authored-by: Ani <115020168+drawbyperpetual@users.noreply.github.com> * [Workspaces] PWA follow-up (#36217) * [PTRun][Calculator]Allow scientific notation with lowercase 'e' (#36187) * [Workspaces] Add encoder parameter to bitmap.save() (#36228) * [Workspaces] Add encoder parameter to bitmap.save() * 1 more call fixed * Move repeated code to the csharp library * [Workspaces] Implement store of app window's size and position (#36086) * [Workspaces] Implement store of app window's size and position * Modifying the default values to -1. The program will use the original default values for the first run. * [ScreenRuler]Add setting to show the measurement in an extra unit (#35887) * display ruler: supporting millimeter and other units * Measurement Tool: UI Setting for an extra unit * Update images * spelling * spelling * suit code style * Fix for code review * remove weird file * rename field * [Deps]Update MSTest from 3.5.0 to 3.6.3 (#36115) * Update MSTest from 3.5.0 to 3.6.3 * Use STA attributes that are now part of MSTest * Adding Jerry to community.md (#36232) Update COMMUNITY.md * [Workspaces] Arranger: smart timer (#36096) * [Workspaces] Add move functionality * spell checker * [Workspaces] Modify Arranger to move apps without launch * moved ipc helper * removed callback * use LauncherStatus in WindowArranger * wait for launching next app * launch in a separate thread and protect by mutexes * update app version in advance * changed canceling launch * increased waiting time * Fix optional parameter load from json * changed arranger waiting time * additional waiting time for Outlook * added app id * ensure ids before launch * set id in editor * minor updates * [Workspaces] Move: Get the nearest window when moving a window * [Workspaces] convert optional boolean to enum to avoid json problems * Handle case when the new Application Property "moveIfExists" does not exist * Re-implementing app-window pairing for moving feature. * spell checker * XAML formatting * Fixing bug: IPC message not arriving * spell checker * Removing app-level-setting for move app. Also fixed compiler errors due styling. * Updating editor window layout * Re-implementing window positioning UI elements * XAML formatting * Code review findings * Code cleanup * Code cleanup * Code cleanup * code cleanup * Code cleanup * Code cleanup * [Workspaces] Arranger: Reset wait timer after each successful arrange action * fix merge error --------- Co-authored-by: Seraphima Co-authored-by: donlaci * Upgrade to check-spelling v0.0.24 (#36235) This upgrades to [v0.0.24](https://github.com/check-spelling/check-spelling/releases/tag/v0.0.24). A number of GitHub APIs are being turned off shortly, so you need to upgrade or various uncertain outcomes will occur. There's a new accessibility forbidden pattern: > Do not use `(click) here` links > For more information, see: > * https://www.w3.org/QA/Tips/noClickHere > * https://webaim.org/techniques/hypertext/link_text > * https://granicus.com/blog/why-click-here-links-are-bad/ > * https://heyoka.medium.com/dont-use-click-here-f32f445d1021 ```pl (?i)(?:>|\[)(?:(?:click |)here|link|(?:read |)more)(?: * Awake Updates - `TILLSON_11272024` (#36049) * Update with bug fixes for tray icon and support for parent process * Process information enum * Update the docs * Fix spelling * Make sure that PID is used in PT config flow * Logic for checks based on #34148 * Update with link to PR * Fixes #34717 * Small cleanup * Proper task segmentation in a function * Cleanup the code * Fix synchronization context issue * Update planning doc * Test disabling caching to see if that manages to pass CI * Cleanup to make sure that we're logging things properly. * Update ci.yml * Disable cache to pass CI * Retry logic * Cleanup * Code cleanup * Fixes #35848 * Update notes and codename * After third attempt, log error instead of throwing exception * More cleanup to avoid double execution * Add expected word * Safeguards for bad values for timed keep-awake * More updates to make sure I am using uint * Update error message * Update packages * Fix notice and revert CsWinRT upgrade * Codename update * Update expect.txt * Update the struct * Ensuring we're properly awaiting tray initialization * Update to make sure tray reflects the bound process * Cleanup, proper JSON serialization for logs. * Not needed. * Add command validation logic * Moving the initialization logic earlier * Make sure we show the display state in the tooltip * Update tray string * Update src/modules/awake/Awake/Core/Manager.cs Co-authored-by: Jaime Bernardo * Update src/modules/awake/Awake/Core/Manager.cs Co-authored-by: Jaime Bernardo * Update src/modules/awake/Awake/Core/Manager.cs Co-authored-by: Jaime Bernardo * Update src/modules/awake/Awake/Core/Manager.cs Co-authored-by: Jaime Bernardo * Update logic for icon resets * Update doc * Simplify function for setting mode shell icon * Issues should be properly linked * Minor cleanup * Update timed behavior --------- Co-authored-by: Jaime Bernardo Co-authored-by: Clint Rutkas * [Workspaces] detecting right app version (#36100) * [Workspaces] Add move functionality * spell checker * [Workspaces] Modify Arranger to move apps without launch * moved ipc helper * removed callback * use LauncherStatus in WindowArranger * wait for launching next app * launch in a separate thread and protect by mutexes * update app version in advance * changed canceling launch * increased waiting time * Fix optional parameter load from json * changed arranger waiting time * additional waiting time for Outlook * added app id * ensure ids before launch * set id in editor * minor updates * [Workspaces] Move: Get the nearest window when moving a window * [Workspaces] convert optional boolean to enum to avoid json problems * Handle case when the new Application Property "moveIfExists" does not exist * Re-implementing app-window pairing for moving feature. * spell checker * XAML formatting * Fixing bug: IPC message not arriving * spell checker * Removing app-level-setting for move app. Also fixed compiler errors due styling. * Updating editor window layout * Re-implementing window positioning UI elements * XAML formatting * Code review findings * Code cleanup * Code cleanup * Code cleanup * code cleanup * Code cleanup * Code cleanup * [Workspaces] fix detection of specific version of apps --------- Co-authored-by: Seraphima Co-authored-by: donlaci * Move the XamlStyler config to src/ (#36202) my never ending goal to minimize files in the root dir * [AdvancedPaste]Add Semantic Kernel opt-in to allow chaining of paste actions (#35902) * [AdvancedPaste] Semantic Kernel support * Changed log-line with potentially sensitive info * Spellcheck issues * Various improvements for Semantic Kernel * Spellcheck issue * Refactored Clipboard routines * Added integration tests for KernelService * Extra telemetry for AdvancedPaste * Added 'Hotkey' suffix to AdvancedPaste_Settings telemetry event * Added IsSavedQuery * Added KernelQueryCache * Refactoring * Added KernelQueryCache to BugReportTool delete list * Added opt-n for Semantic Kernel * Fixed bug with KernelQueryCache * Ability to view last AI chat message on error * Improved kernel query cache * Used System.IO.Abstractions and improved tests * Fixed under-count of token usage * Used Semantic Kernel icon * Cleanup * Add missing EndProject line * Fix dependency version conflicts * Fix NOTICE.md * Correct place of SemanticKernel in NOTICE.md * Unlinked CustomPreview toggle from AI * Added Microsoft.Bcl.AsyncInterfaces dependency to AdvancedPaste * Fixed NOTICE.md order * Moved Custom Preview to behaviour section * Made Image to Text raise error on empty output * Added AIServiceBatchIntegrationTests * Updated AIServiceBatchIntegrationTests * Added prompt moderation * Moved GPO Infobar to better location * [Launcher]Port from WPF-UI to .NET 9 WPF (#36215) * Initial implementation * Fix fluent style * Fix no endline * Update expect.txt * Fix formatting * Fix light theme looking bad on Windows 10 * fix formatting * test change * Now really fixed W10 * Add a comment * Fix typos * Fix spellcheck errors * Fix spellcheck pattern for websites * Change patterns for spellcheck in the right file * Fix XAML styling * Fix contrast colors on W11 * Fix formatting * Removed emty line * Fix formatting * Added comment to fluentHC file * fix comment * Fix Windows10 again. Adress feedback. * W11 fix chaning from high contrast to normal not having correct background * W10 Fix high contrast not working after switching from light/dark moed * Address feedback * Fix formatting * Second W11 fix chaning from high contrast to normal not having correct background * [UX]Updating New+ and Settings icons (#36290) * Updated icons * Updating more icons and icos * [Settings][Dashboard] Accessibility fixes (#36280) * make narrator announce buttons/toggles * add toggles module name * [ci]Sign OpenAI dll that's not signed (#36299) * Update CODEOWNERS to include gordon, jerry and kayla (#36308) * Update CODEOWNERS * Update names.txt * Making the powertoys-code-owners team code owners (#36310) * Update CODEOWNERS * Update names.txt * Update CODEOWNERS * [FZEditor]Fix Create new layout dialog radio buttons IsChecked values (#36320) * 0.87 changelog (#36335) * 0.87 changelog * Fix spellcheck * Update README.md Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com> --------- Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com> * [PTRun]Fix WPF transparent border issue on Windows 10 (#36392) * Added border on W10 * Added a comment --------- Co-authored-by: Davide Giacometti <25966642+davidegiacometti@users.noreply.github.com> * [PTRun]Fix .NET 9 crash in OneNote (#36417) * Fix crash in OneNote Run * added better comment * [AdvancedPaste]Fix NullReferenceException on Dispose (#36428) [AdvancedPaste] Fixed NullReferenceException on Dispose * [Fuzz] Add fuzz testing for AdvancedPaste and new pipeline for onboarding OneFuzz (#36329) * add fuzz * install .net8 * add spelling check * refine the pipeline * add readme and update the test code * fix spelling error * change to weekly run * Add New CI Pipeline for Latest WindowsAppSDK (#36282) This PR introduces the following changes to the CI pipeline and version management: Pipeline Enhancements: 1. Added a new script UpdateVersions.ps1 to automate the update of Microsoft.WindowsAppSDK versions across various project files. 2. Introduced a new pipeline configuration ci-using-the-latest-winappsdk.yml to build using the latest Microsoft.WindowsAppSDK. 3. Updated existing pipeline configurations to support the new useLatestWinAppSDK parameter. Pipeline Configuration Updates: 1. Updated job-build-project.yml to handle the useLatestWinAppSDK parameter and adjust the RestoreAdditionalProjectSourcesArg accordingly. 2. Added a new template steps-update-winappsdk-and-restore-nuget.yml for updating and restoring NuGet packages with the latest Microsoft.WindowsAppSDK. 3. Added WinAPPSDK version selection, the pipeline can be manually triggered to use the specified version. --------- Signed-off-by: Shawn Yuan Co-authored-by: Clint Rutkas * [AOT compatible] Make HostsUILib become AOT compatible (#36136) * Remove AOT configuration * Refer to AOT compatibility props --------- Co-authored-by: Yu Leng (from Dev Box) * [AOT compatible] Clean up some AOT build issue in FilePreviewCommon and MarkdownPreviewHandler (#36207) * Use AppContext.BaseDirectory to replace assembly.GetExeAseembly.Location. Fix json serilizer aot issue. * clean up some AOT build issue * Update src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandlerControl.cs Co-authored-by: Jeremy Sinclair <4016293+snickler@users.noreply.github.com> * Update src/common/FilePreviewCommon/Formatters/JsonFormatter.cs Co-authored-by: Jeremy Sinclair <4016293+snickler@users.noreply.github.com> --------- Co-authored-by: Yu Leng (from Dev Box) Co-authored-by: Jeremy Sinclair <4016293+snickler@users.noreply.github.com> * Add new pipeline using the latest webview2 from Edge Canary (#36317) * using the latest webview2 for testing --------- Signed-off-by: Shawn Yuan Co-authored-by: Clint Rutkas * [Bug fix] Making the OpenAI key configuration page scrollable. (#36359) * Fixed #34470 --------- Signed-off-by: Shawn Yuan * [Bug fix] Add a format validation step before format conversion. (#36404) This PR aims to fix the bug #35225 by introducing a new method IsJson to determine if a given text is in JSON format. The IsJson method is then utilized in the ToJsonFromXmlOrCsvAsync method to optimize the processing logic. If the text is already in JSON format, it is returned directly without further conversion from XML or CSV. Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com> --------- Signed-off-by: Shawn Yuan Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com> * Add more STCA team members (#36438) * Add more STCA team members * Include more spelling check errors * Remove non-alpha in dictionary * Add Zhaopeng Wang * Fix spell checking error * Remove "prerelease: true" (#36484) * Remove "prerelease: true" The Microsoft.WinGet.DSC module is GA so prerelease: true is no longer needed. * Update expect.txt fixing spellcheck warning --------- Co-authored-by: Clint Rutkas * [Docs]Update README for 0.87.1 release (#36534) * [CI] Enhance build Pipeline Reliability with Retry Logic and Improved Error Messaging (#36529) * update pipeline with retry * remove tests * Add team member (#36590) * [New+]Don't override New actions from Explorer on Windows 10 (#36467) * [New+]Don't override New actions from Explorer * Update src/modules/NewPlus/NewShellExtensionContextMenu.win10/shell_context_menu_win10.cpp * Update src/modules/NewPlus/NewShellExtensionContextMenu.win10/shell_context_menu_win10.cpp * Add pattern for learn.microsoft links * Also only Query for context menu * [PTRun][Calculator]Handle hexadecimal numbers to not return divide by 0 error (#36390) * add '0x' handling for divide by 0 scenarios * fix comment on division by 0 check --------- Co-authored-by: Connor Plante * [TextExtractor]Minor UI/Accessibility fixes in the overlay UI (#36356) minor UI and accessibility fixes * [PTRun][Calculator]Update mages to v3.0.0 and support for `randi(n)` (#36560) * update to mages 3.0.0 * allow randi() in calculator plugin * fix tests and input validation * fix spell check * [QuickAccent]Added ć for Slovenian (#36336) (#36338) * Fix snapping Workspaces Editor to Fancy Zones (#36463) * Remove Workspaces Editor from Fancy Zone's excluded app list * removed unused string --------- Co-authored-by: Seraphima * [PTRun]Fix drag on .NET 9 WPF (#36635) * [CQ]Continued to move stuff out of root - Solution.props (#36244) * [QuickAccent]Add Proto-Indo-European (#36408) * Add ḱ to PowerAccent for Proto-Indo-European * Fix Spelling Check * Add more letters to PIE * Order PIE after PI --------- Co-authored-by: Hao Liu (from Dev Box) Co-authored-by: Jaime Bernardo * [PTRun]Add context buttons for VSCodeWorkspaces plugin (#36517) * [Settings][QuickAccent]Change 'character set' to plural form (#36565) * [PTRun][Calculator]Fix unit tests on non-english systems (#36569) * fix tests * update comment * [PTRun][Calc]Improve handling of non-base 10 numbers (#36700) * [Settings][PTRun]Show plugin version and website (#36580) * [Monaco]Add support for .resx and .resw preview support. (#36499) Added support for .resx and .resw preview support. These files are XML based files so I added the file extensions as part of the registerAdditionalLanguage("xmlExt"...) function. * [Settings] Add Workspaces' workspaces.json file to backup/restore list (#36714) * [Localization] Fix loc pipeline to send downloaded localized files to TDBuild upon retry after failure (#36766) * [AdvancedPaste]Fixed issues with Screen Reader integration (#36778) * Remove Advent calendar from README (#36777) * Remove Advent calendar from README * Update hero image * Delete doc/images/overview/PT_holiday_hero_image.png * [AdvancedPaste]Add all BitmapDecoder supported image filetypes to ImageToText (#35600) Adds support to ImageToText for all image filetypes supported by BitmapDecoder. * [AOT]Clean up some AOT build issues in PowerAccent.Core (#36264) * init * Use AotCompatibility instead * Replace typeof(Lanaguge) with GetValues * Create new folder to place source generation context file. --------- Co-authored-by: Yu Leng (from Dev Box) * [WinUI3]Fix Windows 10 title bar borders (#36429) * Fix borders for windows in the Settings UI * Fix HOSTS window * Fix Advanced Paste * Fix Environment Variables * Fix File Locksmith * Fix Peek, with a caveat * Fix Registry Preview * Remove unused imports * Clean up imports in OobeShellPage * Move OSVersionHelper from Common.UI up into ManagedCommon * [QuickAccent]Fix unstable language loading (#36721) * [Peek]Bring into foreground if previously minimized (#36506) Added Activate() to bring Peek.UI window into focus upon Toggle. This allows the UI to be presented even if it was previously minimized. * Update Run docs README (#36857) * Update Run docs README * Remove System dupe * [Monaco]Make minimap toggleable (#33742) * [Monaco]Fix Json format preview setting (#36867) * [KBM]Added option for exact match shortcut (#36000) * Added option for exact match shortcut * Fix spell-check * [Deps][Security]Update .NET Packages from 9.0.0 to 9.0.1 (#36879) * [Deps] Update NuGet packages to version 9.0.1 Updated several NuGet packages from version 9.0.0 to 9.0.1, including: - Microsoft.Data.Sqlite - Microsoft.Bcl.AsyncInterfaces - Microsoft.Extensions.DependencyInjection - Microsoft.Extensions.Logging - Microsoft.Extensions.Logging.Abstractions - Microsoft.Extensions.Hosting - Microsoft.Extensions.Hosting.WindowsServices - Microsoft.Win32.SystemEvents - Microsoft.Windows.Compatibility - System.CodeDom - System.ComponentModel.Composition - System.Configuration.ConfigurationManager - System.Data.OleDb - System.Diagnostics.EventLog - System.Diagnostics.PerformanceCounter - System.Drawing.Common - System.Management - System.Runtime.Caching - System.ServiceProcess.ServiceController - System.Text.Encoding.CodePages - System.Text.Json * [Deps] Update NOTICE.md * [Peek]Fix using the correct Monaco assets at runtime (#36890) * [Workspaces] fixing bug: editor starts outside of visible desktop area (#36769) * [Workspaces] fixing bug: editor starts outside of visible desktop area * Update src/modules/Workspaces/WorkspacesEditor/MainWindow.xaml.cs Co-authored-by: Seraphima Zykova --------- Co-authored-by: Seraphima Zykova * [Workspaces] Saving app properties on launch and recapture (#36751) * [Workspaces] Implementing set and get GUID to/from HWND to distinguish windows moved by the Workspaces tool * After launch and capture copy the CLI args from the "original" project * Fix getting GUID * spell check * modification to be able to handle different data sizes on different systems * code optimisation * Replacing string parameter by InvokePoint * renaming variable * [AdvancedPaste]Use background thread for interactions between runner and Advanced Paste (#36858) * [Advanced Paste] Use background thread for runner-Advanced Paste interaction * Fixed typo * [VCM]Deprecate the Video Conference Mute utility (#36772) * Remove all VideoConferenceMute related code and files * Clean up vcm driver registry keys * Also remove the Webcam report tool * Also clean out video conference on the installer * Fix spellcheck * Remove comment about video conf * Update gpo files revision * Revert removing the VCM policies * Deprecate VCM GPO policy * Change deprecation message to show first supported version * Tweak supported strings in the adml * Goodbye friends, you are forever part of the team (#36905) * Goodbye friends Forever part of the team 😢 * Update COMMUNITY.md * Fix formatting issues in COMMUNITY.md * [New utility]Sysinternals ZoomIt (#35880) * ZoomIt initial code dump * Change vcxproj to normalize dependency versions * Fix code quality to build * Add to PowerToys solution * Clean out C-style casts * Fix some more analyzer errors * Constexpr a function * Disable some warnings locally that it seemed better not to touch * Add ZoomIt module interface * Add GPO * Add Settings page with Enable button * Output as PowerToys.ZoomIt.exe * Extract ZoomIt Settings definition to its own header * Make ZoomItModuleInterface build with ZoomItSettings too * WinRT C++ interop for ZoomItSettings * From Registry To PowerToys Json * Properly fix const_cast analyzer error * Initial Settings page loading from registry * Zoom mode settings * Save settings * Add file picker and DemoType file support * Remaining DemoType settings * Have ZoomIt properly reloading Settings and exiting * Remove context menu entries for Options and Exit * ZoomIt simple Break Options * Break advanced options * Simple Record settings * Record Microphone setting * Fix break background file picker title * Font setting * Fix build issues after merge * Add ZoomIt conflict warning to Settings * Exclude Eula from spell checking * Fix spellcheck errors * Fix spell check for accelerated menu items * Remove cursor files from spellcheck. They're binary * Fix forbidden patterns * Fix XAML style * Fix C# analyzers * Fix signing * Also sign module interface dll * Use actual ZoomIt icon * Add OOBE page for ZoomIt * ZoomIt image for Settings * Flyout and Dashboard entries * Fix type speed slider labels * Correctly load default Font * Correctly register shortcuts on ZoomIt startup first run * Fix modifier keys not changing until restart * Show MsgBox on taken shortcut * Start PowerToys Settings * Normalize ZoomIt file properties with rest of PowerToys * Add attribution * Add ZoomIt team to Community.md * More copyright adjustments * Fix spellcheck * Fix MsgBox simultaneous instance to the front * Add mention of capturevideosample code use * Add ZoomIt to process lists * Add telemetry * Add logging * React to gpo * Normalize code to space identation * Fix installer build * Localize percent setting * Fix XAML styling * Update src/settings-ui/Settings.UI/Strings/en-us/Resources.resw Co-authored-by: Stefan Markovic <57057282+stefansjfw@users.noreply.github.com> * Fix spellcheck * One more spellcheck fix * Integrate LiveDraw feature changes from upstream * Fix name reuse in same scope * Fix c-style casts * Also register LIVEDRAW_HOTKEY * Fix newLiveZoomToggleKey * Update LiveZoom description in Settings to take LiveDraw into account * Fix spellcheck * Fix more spellcheck * Fix Sysinternals capitalization * Fix ARM64 Debug build * Support Sysinternals build (#36873) * Remove unneeded files * Make build compatible with Sysinternals * Separate PowerToys ZoomIt product name (#36887) * Separate PowerToys ZoomIt product name To help maintain the Sysinternals branding in the standalone version. * Clarify branding-related includes * Remove ZoomIt.sln * Add foxmsft to spell-check names * Add ZoomIt to README * Add ZoomIt to GH templates * Add ZoomIt events to DATA_AND_PRIVACY.md * Remove publish_config.json * Remove publish_config.json from vcxproj too --------- Co-authored-by: Mark Russinovich Co-authored-by: Alex Mihaiuc <69110671+foxmsft@users.noreply.github.com> Co-authored-by: John Stephens Co-authored-by: Stefan Markovic <57057282+stefansjfw@users.noreply.github.com> * [PTRun]Add hotkey to the show telemetry event (#36869) * [PTRun]Update the code for .NET 9.0.1 - remove workarounds (#36909) * Revove some unneeded changes after pdating to .net9.1 * [RegistryPreview]Copy context menu, data tooltip, MULTI_SZ fix (#36631) * add context menus * string resources for contextmenu * fix line break parsing for MULTI_SZ * better presentation of multiline values and value tooltip * cleanup * [MWB] - refactoring "Common" classes - Common.Log.cs, Common.Receiver.cs (#35726) * [PTRun]Add setting for different trigonometric units in Calculator (#36717) * Added angle units to PowerToys Run Calculator plugin. * Update Resources.resx * Added GitHub SpellCheck rule for 'gradians'. --------- Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com> * [ci]Remove steps to build abstracted utilities packages (#36934) * [Settings]Update GPO infobar icon, improve some pages and fix bugs (#33703) * changes part 1 * fix xaml code * changes part 2 * fix cmdNotFound page * Update PowerOcrPage * More Pages changed * More Pages changed * revert temporary change * fix spelling * add resw comment * add resw comment * Update MouseWihtoutBorderPage.xaml * PowerPreview page * workspaces page * fix awake page gpo handling * NewPlus page * update new+ page! * AdvancedPaste.xaml: Move Info bar. * Update MouseJumpPanel.xaml * Update GeneralPage.xaml * fix position of info bar and some ui quirks * fix xaml style * fix string resources * string changes * prepare megre main * update new+ page * zoomit page * various fixes * [Common]NotificationUtil helper class with FileWatcher (#36720) * add NotificationUtil helper with file watcher and cache * fix spellcheck * indentation * [PTRun][Docs]Add YubicoOauthOTP to Third-Party plugins (#36761) * [PTRun]Fixed typo in Value Generator messages (#36951) * [AOT] Clean up some AOT issues in Advanced Paste module (#36297) * Clean up the aot build issue. * Merge main and clean up new AOT build issue * Update LogEvent define. * Update src/modules/AdvancedPaste/AdvancedPaste/Helpers/LogEvent.cs Co-authored-by: Jeremy Sinclair <4016293+snickler@users.noreply.github.com> * update typo bug * Remove unused allow list item * Create a new folder to place source generation context * Merge main and rename LogEvent to AIServiceFormatEvent --------- Co-authored-by: Yu Leng (from Dev Box) Co-authored-by: Jeremy Sinclair <4016293+snickler@users.noreply.github.com> * xaml format * [check-spelling] Update metadata Update for https://github.com/zadjii-msft/PowerToys/actions/runs/12884838755/attempts/1 Accepted in https://github.com/zadjii-msft/PowerToys/pull/346#issuecomment-2604315393 Signed-off-by: check-spelling-bot on-behalf-of: @check-spelling --------- Signed-off-by: Shawn Yuan Signed-off-by: check-spelling-bot Co-authored-by: Laszlo Nemeth <57342539+donlaci@users.noreply.github.com> Co-authored-by: Seraphima Co-authored-by: donlaci Co-authored-by: Ionuț Manța Co-authored-by: Jaime Bernardo Co-authored-by: Jeremy Sinclair <4016293+snickler@users.noreply.github.com> Co-authored-by: Ani <115020168+drawbyperpetual@users.noreply.github.com> Co-authored-by: PesBandi <127593627+PesBandi@users.noreply.github.com> Co-authored-by: Wenjian Chern <55335597+Sophanatprime@users.noreply.github.com> Co-authored-by: Youssef Victor Co-authored-by: Clint Rutkas Co-authored-by: Josh Soref <2119212+jsoref@users.noreply.github.com> Co-authored-by: leileizhang Co-authored-by: Den Delimarsky 🔐 Co-authored-by: Niels Laute Co-authored-by: Davide Giacometti <25966642+davidegiacometti@users.noreply.github.com> Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com> Co-authored-by: Shuai Yuan <128874481+shuaiyuanxx@users.noreply.github.com> Co-authored-by: moooyo <42196638+moooyo@users.noreply.github.com> Co-authored-by: Yu Leng (from Dev Box) Co-authored-by: Jerry Xu Co-authored-by: Demitrius Nelon Co-authored-by: Kai Tao <69313318+vanzue@users.noreply.github.com> Co-authored-by: Connor Plante <150482134+plante-msft@users.noreply.github.com> Co-authored-by: Connor Plante Co-authored-by: Domen Soklič Co-authored-by: Hao Liu Co-authored-by: Hao Liu (from Dev Box) Co-authored-by: immi Co-authored-by: Asif Islam <77113884+asif4318@users.noreply.github.com> Co-authored-by: Kayla Cinnamon Co-authored-by: Dave Rayment Co-authored-by: Neil McAlister Co-authored-by: Mark Russinovich Co-authored-by: Alex Mihaiuc <69110671+foxmsft@users.noreply.github.com> Co-authored-by: John Stephens Co-authored-by: Michael Clayton Co-authored-by: Nathan Gill Co-authored-by: Daniel Nilsson Co-authored-by: Stefan Markovic --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/ISSUE_TEMPLATE/translation_issue.yml | 2 +- .github/actions/spell-check/allow/code.txt | 3 + .github/actions/spell-check/allow/names.txt | 7 +- .github/actions/spell-check/excludes.txt | 2 + .github/actions/spell-check/expect.txt | 233 +- .github/actions/spell-check/patterns.txt | 4 + .../ESRPSigning_abstracted_utils_dll.json | 52 - .pipelines/ESRPSigning_core.json | 8 +- .pipelines/ESRPSigning_vcm.json | 50 - .pipelines/v2/templates/job-build-project.yml | 45 +- COMMUNITY.md | 27 +- DATA_AND_PRIVACY.md | 64 +- PowerToys.sln | 99 +- README.md | 3 +- doc/devdocs/akaLinks.md | 3 - doc/devdocs/readme.md | 7 - doc/devdocs/tools/build-tools.md | 4 - doc/devdocs/tools/readme.md | 1 - doc/devdocs/tools/webcam-report-tool.md | 6 - .../overview/Original/VideoConference.png | Bin 98862 -> 0 bytes doc/images/overview/VideoConference_large.png | Bin 55499 -> 0 bytes doc/images/overview/VideoConference_small.png | Bin 22289 -> 0 bytes doc/thirdPartyRunPlugins.md | 1 + installer/PowerToysSetup/Common.wxi | 1 - .../PowerToysSetup/PowerToysInstaller.wixproj | 2 - installer/PowerToysSetup/Product.wxs | 12 +- installer/PowerToysSetup/Tools.wxs | 7 - installer/PowerToysSetup/VideoConference.wxs | 56 - .../CustomAction.cpp | 175 +- .../CustomAction.def | 4 +- .../PowerToysSetupCustomActions.vcxproj | 1 - src/common/Common.UI/SettingsDeepLink.cs | 6 +- src/common/FilePreviewCommon/MonacoHelper.cs | 4 + src/common/GPOWrapper/GPOWrapper.cpp | 4 +- src/common/GPOWrapper/GPOWrapper.h | 2 +- src/common/GPOWrapper/GPOWrapper.idl | 2 +- src/common/ManagedCommon/ModuleType.cs | 1 + src/common/SettingsAPI/FileWatcher.h | 3 + src/common/SettingsAPI/pch.h | 1 - src/common/SettingsAPI/settings_objects.cpp | 9 + src/common/SettingsAPI/settings_objects.h | 1 + src/common/interop/CommonManaged.cpp | 27 - src/common/interop/CommonManaged.h | 2 - src/common/interop/CommonManaged.idl | 2 - src/common/interop/PowerToys.Interop.vcxproj | 4 - .../interop/PowerToys.Interop.vcxproj.filters | 12 - src/common/interop/shared_constants.h | 4 + src/common/logger/logger_settings.h | 1 + src/common/notifications/NotificationUtil.cpp | 56 + src/common/notifications/NotificationUtil.h | 44 +- .../notifications/notifications.vcxproj | 3 +- src/common/sysinternals/Eula/Eula.txt | 75 + src/common/sysinternals/Eula/eula.c | 702 ++ src/common/sysinternals/Eula/eula.h | 17 + src/common/sysinternals/Eula/eula.rtf | 76 + src/common/sysinternals/WindowsVersions.cpp | 24 + src/common/sysinternals/WindowsVersions.h | 32 + src/common/sysinternals/dll.c | 74 + src/common/sysinternals/dll.h | 26 + src/common/utils/clean_video_conference.h | 18 + src/common/utils/gpo.h | 6 +- src/common/version/version.vcxproj | 2 +- .../examples/disableAllModules.dsc.yaml | 2 - .../examples/enableAllModules.dsc.yaml | 2 - src/gpo/assets/PowerToys.admx | 21 +- src/gpo/assets/en-US/PowerToys.adml | 6 +- .../Helpers/AIServiceFormatEvent.cs | 45 + .../AdvancedPaste/Helpers/NativeMethods.cs | 2 +- .../AdvancedPaste/Helpers/UserSettings.cs | 2 +- .../Models/KernelQueryCache/PersistedCache.cs | 13 +- .../SourceGenerationContext.cs | 16 + .../Services/KernelServiceBase.cs | 5 +- .../OpenAI/CustomTextTransformService.cs | 4 +- .../AdvancedPasteModuleInterface.vcxproj | 5 +- ...vancedPasteModuleInterface.vcxproj.filters | 9 +- .../AdvancedPasteProcessManager.cpp | 267 + .../AdvancedPasteProcessManager.h | 36 + .../AdvancedPasteModuleInterface/dllmain.cpp | 181 +- .../CropAndLock/CropAndLock.vcxproj | 4 +- .../CropAndLock/CropAndLock/packages.config | 2 +- src/modules/CropAndLock/CropAndLock/pch.h | 4 +- .../CropAndLockModuleInterface.vcxproj | 4 +- .../App/Class/Common.Clipboard.cs | 17 +- .../App/Class/Common.DragDrop.cs | 4 +- .../App/Class/Common.Event.cs | 4 +- .../App/Class/Common.InitAndCleanup.cs | 2 + .../App/Class/Common.Log.cs | 119 - .../App/Class/Common.MachineStuff.cs | 10 +- .../App/Class/Common.Receiver.cs | 431 - .../App/Class/Common.WinAPI.cs | 2 + .../MouseWithoutBorders/App/Class/Common.cs | 12 +- .../App/Class/IClipboardHelper.cs | 3 + .../MouseWithoutBorders/App/Class/Program.cs | 1 + .../MouseWithoutBorders/App/Class/Setting.cs | 3 +- .../App/Class/SocketStuff.cs | 4 +- .../App/Class/TcpServer.cs | 2 + .../MouseWithoutBorders/App/Core/Logger.cs | 12 +- .../MouseWithoutBorders/App/Core/Receiver.cs | 429 + .../MouseWithoutBorders/App/Core/Thread.cs | 105 + .../Core/Logger.PrivateDump.expected.txt | 188 +- .../Core/LoggerTests.cs | 11 +- .../WorkspacesWindowPropertyUtils.h | 60 + .../WorkspacesEditor/MainWindow.xaml.cs | 21 +- .../WorkspacesEditor/Models/Project.cs | 18 +- .../ViewModels/MainViewModel.cs | 13 +- .../Workspaces/WorkspacesLib/AppUtils.cpp | 1 - src/modules/Workspaces/WorkspacesLib/utils.h | 22 +- .../WorkspacesSnapshotTool/SnapshotUtils.cpp | 19 +- .../WorkspacesSnapshotTool/SnapshotUtils.h | 2 +- .../WorkspacesSnapshotTool/main.cpp | 7 +- .../WindowArranger.cpp | 1 + .../Workspaces/workspaces-common/GuidUtils.h | 2 + .../ZoomIt/ZoomIt/AudioSampleGenerator.cpp | 168 + .../ZoomIt/ZoomIt/AudioSampleGenerator.h | 48 + .../ZoomIt/ZoomIt/CaptureFrameWait.cpp | 147 + src/modules/ZoomIt/ZoomIt/CaptureFrameWait.h | 142 + src/modules/ZoomIt/ZoomIt/DemoType.cpp | 1447 ++++ src/modules/ZoomIt/ZoomIt/DemoType.h | 26 + .../ZoomIt/ZoomIt/PowerToys/branding.h | 3 + src/modules/ZoomIt/ZoomIt/Registry.h | 324 + src/modules/ZoomIt/ZoomIt/SelectRectangle.cpp | 269 + src/modules/ZoomIt/ZoomIt/SelectRectangle.h | 44 + src/modules/ZoomIt/ZoomIt/Utility.cpp | 153 + src/modules/ZoomIt/ZoomIt/Utility.h | 18 + src/modules/ZoomIt/ZoomIt/VersionHelper.cpp | 129 + src/modules/ZoomIt/ZoomIt/VersionHelper.h | 48 + .../ZoomIt/ZoomIt/VideoRecordingSession.cpp | 391 + .../ZoomIt/ZoomIt/VideoRecordingSession.h | 71 + src/modules/ZoomIt/ZoomIt/ZoomIt.h | 223 + src/modules/ZoomIt/ZoomIt/ZoomIt.idc | 1 + src/modules/ZoomIt/ZoomIt/ZoomIt.rc | 484 ++ src/modules/ZoomIt/ZoomIt/ZoomIt.vcxproj | 370 + .../ZoomIt/ZoomIt/ZoomIt.vcxproj.filters | 130 + src/modules/ZoomIt/ZoomIt/ZoomItSettings.h | 83 + src/modules/ZoomIt/ZoomIt/Zoomit.cpp | 7674 +++++++++++++++++ src/modules/ZoomIt/ZoomIt/Zoomit.exe.manifest | 36 + src/modules/ZoomIt/ZoomIt/appicon.ico | Bin 0 -> 83812 bytes src/modules/ZoomIt/ZoomIt/binres.rc | 18 + src/modules/ZoomIt/ZoomIt/cursor1.cur | Bin 0 -> 326 bytes src/modules/ZoomIt/ZoomIt/drawingc.cur | Bin 0 -> 326 bytes .../VCM/black.bmp => ZoomIt/ZoomIt/icon1.ico} | Bin 822 -> 766 bytes src/modules/ZoomIt/ZoomIt/makefile | 58 + .../ZoomIt}/packages.config | 1 + src/modules/ZoomIt/ZoomIt/pch.cpp | 1 + src/modules/ZoomIt/ZoomIt/pch.h | 97 + src/modules/ZoomIt/ZoomIt/resource.h | 115 + .../ZoomItModuleInterface.rc} | 0 .../ZoomItModuleInterface.vcxproj | 113 + .../ZoomItModuleInterface.vcxproj.filters | 47 + .../ZoomIt/ZoomItModuleInterface/dllmain.cpp | 233 + .../ZoomItModuleInterface}/packages.config | 1 - .../ZoomItModuleInterface}/pch.cpp | 0 .../ZoomIt/ZoomItModuleInterface/pch.h | 9 + .../ZoomIt/ZoomItModuleInterface/resource.h | 13 + .../ZoomIt/ZoomItModuleInterface/trace.cpp | 93 + .../ZoomIt/ZoomItModuleInterface/trace.h | 17 + .../ZoomItSettingsInterop/PropertySheet.props | 16 + .../ZoomItSettingsInterop/ZoomItSettings.cpp | 274 + .../ZoomItSettingsInterop/ZoomItSettings.h | 20 + .../ZoomItSettingsInterop/ZoomItSettings.idl | 10 + .../ZoomItSettingsInterop.def | 3 + .../ZoomItSettingsInterop.rc | 2 +- .../ZoomItSettingsInterop.vcxproj} | 169 +- .../ZoomItSettingsInterop.vcxproj.filters | 35 + .../ZoomItSettingsInterop}/packages.config | 0 .../ZoomIt/ZoomItSettingsInterop/pch.cpp | 1 + .../ZoomIt/ZoomItSettingsInterop/pch.h | 22 + .../ZoomIt/ZoomItSettingsInterop/resource.h | 13 + .../alwaysontop/AlwaysOnTop/AlwaysOnTop.cpp | 10 +- .../alwaysontop/AlwaysOnTop/AlwaysOnTop.h | 2 + .../fancyzones/FancyZonesLib/FancyZones.cpp | 9 +- .../FancyZonesLib/WindowMouseSnap.cpp | 15 +- .../FancyZonesLib/WindowMouseSnap.h | 3 +- .../InputParser.cs | 2 +- .../ExtendedCalculatorParserTests.cs | 62 + .../CalculateEngine.cs | 10 + .../CalculateHelper.cs | 86 + .../Main.cs | 26 + .../Properties/Resources.Designer.cs | 45 + .../Properties/Resources.resx | 20 + .../Events/LauncherShowEvent.cs | 7 + src/modules/launcher/PowerLauncher/App.xaml | 1 + .../Helper/AnimationFactorToValueConverter.cs | 45 - .../Helper/FallbackBrushConverter.cs | 44 - .../PowerLauncher/Helper/ThemeManager.cs | 34 +- .../PowerLauncher/Styles/FluentHC.xaml | 6710 -------------- .../launcher/PowerLauncher/Styles/Styles.xaml | 93 +- .../PowerLauncher/ViewModel/MainViewModel.cs | 2 +- .../RegistryPreviewUILib/ClipboardHelper.cs | 33 + .../RegistryPreviewUILib/RegistryKey.xaml.cs | 18 + .../RegistryPreviewMainPage.Utilities.cs | 21 +- .../RegistryPreviewMainPage.xaml | 59 +- .../RegistryPreviewMainPage.xaml.cs | 1 + .../RegistryValue.xaml.cs | 47 +- .../Strings/en-US/Resources.resw | 24 + .../Assets/VCM/Off-NotInUse Dark.png | Bin 13104 -> 0 bytes .../Assets/VCM/Off-NotInUse Dark.svg | 19 - .../Assets/VCM/Off-NotInUse Light.png | Bin 12931 -> 0 bytes .../Assets/VCM/Off-NotInUse Light.svg | 19 - .../Assets/VCM/Off-Off Dark.png | Bin 11546 -> 0 bytes .../Assets/VCM/Off-Off Dark.svg | 19 - .../Assets/VCM/Off-Off Light.png | Bin 11488 -> 0 bytes .../Assets/VCM/Off-Off Light.svg | 19 - .../Assets/VCM/Off-On Dark.png | Bin 5664 -> 0 bytes .../Assets/VCM/Off-On Dark.svg | 19 - .../Assets/VCM/Off-On Light.png | Bin 5678 -> 0 bytes .../Assets/VCM/Off-On Light.svg | 19 - .../Assets/VCM/On-NotInUse Dark.png | Bin 6016 -> 0 bytes .../Assets/VCM/On-NotInUse Dark.svg | 19 - .../Assets/VCM/On-NotInUse Light.png | Bin 6321 -> 0 bytes .../Assets/VCM/On-NotInUse Light.svg | 19 - .../Assets/VCM/On-Off Dark.png | Bin 5808 -> 0 bytes .../Assets/VCM/On-Off Dark.svg | 19 - .../Assets/VCM/On-Off Light.png | Bin 10232 -> 0 bytes .../Assets/VCM/On-Off Light.svg | 19 - .../Assets/VCM/On-On Dark.png | Bin 4975 -> 0 bytes .../Assets/VCM/On-On Dark.svg | 19 - .../Assets/VCM/On-On Light.png | Bin 4976 -> 0 bytes .../Assets/VCM/On-On Light.svg | 19 - .../AudioDeviceNotificationClient.cpp | 78 - .../AudioDeviceNotificationClient.h | 30 - .../VideoConferenceModule/README.md | 14 - .../VideoConferenceModule/Toolbar.cpp | 390 - .../VideoConferenceModule/Toolbar.h | 64 - .../VideoConference.filters | 55 - .../VideoConference.vcxproj | 189 - .../VideoConference.vcxproj.filters | 78 - .../VideoConferenceModule.cpp | 733 -- .../VideoConferenceModule.h | 102 - .../VideoConferenceModule/dllmain.cpp | 35 - .../VideoConferenceModule/framework.h | 5 - .../VideoConferenceModule/pch.h | 23 - .../VideoConferenceModule/resource.h | 13 - .../VideoConferenceModule/trace.cpp | 60 - .../VideoConferenceModule/trace.h | 13 - .../DirectShowUtils.cpp | 113 - .../DirectShowUtils.h | 87 - .../ImageLoading.cpp | 424 - .../VideoConferenceProxyFilter/Resources.resx | 124 - .../VideoCaptureDevice.cpp | 636 -- .../VideoCaptureDevice.h | 62 - .../VideoCaptureProxyFilter.cpp | 937 -- .../VideoCaptureProxyFilter.h | 120 - .../VideoConferenceProxyFilter.rc | 47 - .../VideoConferenceProxyFilter.vcxproj | 157 - .../VideoConferenceProxyFilterx86.sln | 51 - .../build_vcm_x86.cmd | 3 - .../VideoConferenceProxyFilter/dllmain.cpp | 242 - .../VideoConferenceProxyFilter/module.def | 7 - .../packages.config | 4 - .../VideoConferenceProxyFilter/resource.h | 11 - .../VideoConferenceProxyFilter/resource.x86.h | 11 - .../CameraStateUpdateChannels.cpp | 15 - .../CameraStateUpdateChannels.h | 23 - .../DLLProviderHelpers.h | 33 - .../VideoConferenceShared/Logging.cpp | 202 - .../VideoConferenceShared/Logging.h | 62 - .../MediaFoundationAPIProvider.h | 14 - .../MicrophoneDevice.cpp | 154 - .../VideoConferenceShared/MicrophoneDevice.h | 64 - .../SerializedSharedMemory.cpp | 190 - .../SerializedSharedMemory.h | 54 - .../VideoCaptureDeviceList.cpp | 107 - .../VideoCaptureDeviceList.h | 33 - .../VideoConferenceShared/naming.cpp | 19 - .../VideoConferenceShared/naming.h | 5 - .../VideoConferenceShared/pch.h | 2 - .../VideoConferenceShared/username.cpp | 20 - .../VideoConferenceShared/username.h | 9 - src/modules/videoconference/make_cab.ddf | 20 - src/runner/main.cpp | 17 +- src/runner/settings_window.cpp | 12 +- src/runner/settings_window.h | 2 +- .../Settings.UI.Library/EnabledModules.cs | 33 +- .../Settings.UI.Library.csproj | 1 + .../SndVideoConferenceSettings.cs | 25 - .../VideoConferenceConfigProperties.cs | 113 - .../VideoConferenceSettingsIPCMessage.cs | 29 - .../Settings.UI.Library/ZoomItProperties.cs | 107 + ...onferenceSettings.cs => ZoomItSettings.cs} | 20 +- .../Settings/Icons/VideoConferenceMute.png | Bin 1155 -> 0 bytes .../Assets/Settings/Icons/ZoomIt.png | Bin 0 -> 1837 bytes .../Modules/OOBE/VideoConferenceMute.png | Bin 56878 -> 0 bytes .../Assets/Settings/Modules/OOBE/ZoomIt.gif | Bin 0 -> 1089718 bytes .../Settings/Modules/VideoConference.png | Bin 55499 -> 0 bytes .../Assets/Settings/Modules/ZoomIt.png | Bin 0 -> 23370 bytes .../Converters/ZoomItInitialZoomConverter.cs | 34 + .../ZoomItTypeSpeedSliderConverter.cs | 27 + .../Settings.UI/Helpers/CHOOSEFONT.cs | 70 + .../Settings.UI/Helpers/LOGFONT.cs | 125 + .../Settings.UI/Helpers/ModuleHelper.cs | 4 + .../Settings.UI/Helpers/NativeMethods.cs | 6 + .../OOBE/Enums/PowerToysModules.cs | 2 +- .../Settings.UI/PowerToys.Settings.csproj | 3 +- .../Settings.UI/SettingsXAML/App.xaml.cs | 2 +- .../OOBE/Views/OobeShellPage.xaml | 8 +- .../OOBE/Views/OobeShellPage.xaml.cs | 32 +- .../OOBE/Views/OobeVideoConference.xaml | 35 - .../SettingsXAML/OOBE/Views/OobeZoomIt.xaml | 27 + ...oConference.xaml.cs => OobeZoomIt.xaml.cs} | 15 +- .../SettingsXAML/Panels/MouseJumpPanel.xaml | 8 +- .../SettingsXAML/Views/AdvancedPaste.xaml | 33 +- .../SettingsXAML/Views/AlwaysOnTopPage.xaml | 6 +- .../SettingsXAML/Views/AwakePage.xaml | 6 +- .../SettingsXAML/Views/AwakePage.xaml.cs | 2 +- .../SettingsXAML/Views/CmdNotFoundPage.xaml | 40 +- .../SettingsXAML/Views/ColorPickerPage.xaml | 6 +- .../SettingsXAML/Views/CropAndLockPage.xaml | 6 +- .../Views/EnvironmentVariablesPage.xaml | 6 +- .../SettingsXAML/Views/FancyZonesPage.xaml | 6 +- .../SettingsXAML/Views/FileLocksmithPage.xaml | 6 +- .../SettingsXAML/Views/GeneralPage.xaml | 37 +- .../SettingsXAML/Views/HostsPage.xaml | 6 +- .../SettingsXAML/Views/ImageResizerPage.xaml | 6 +- .../Views/KeyboardManagerPage.xaml | 6 +- .../SettingsXAML/Views/MeasureToolPage.xaml | 6 +- .../SettingsXAML/Views/MouseUtilsPage.xaml | 18 +- .../Views/MouseWithoutBordersPage.xaml | 22 +- .../SettingsXAML/Views/NewPlusPage.xaml | 11 +- .../SettingsXAML/Views/PeekPage.xaml | 6 +- .../SettingsXAML/Views/PowerAccentPage.xaml | 6 +- .../SettingsXAML/Views/PowerLauncherPage.xaml | 12 +- .../SettingsXAML/Views/PowerOcrPage.xaml | 19 +- .../SettingsXAML/Views/PowerPreviewPage.xaml | 12 +- .../SettingsXAML/Views/PowerRenamePage.xaml | 6 +- .../Views/RegistryPreviewPage.xaml | 6 +- .../SettingsXAML/Views/ShellPage.xaml | 10 +- .../SettingsXAML/Views/ShortcutGuidePage.xaml | 6 +- .../SettingsXAML/Views/VideoConference.xaml | 171 - .../Views/VideoConference.xaml.cs | 65 - .../SettingsXAML/Views/WorkspacesPage.xaml | 6 +- .../SettingsXAML/Views/ZoomItPage.xaml | 235 + .../SettingsXAML/Views/ZoomItPage.xaml.cs | 117 + .../Settings.UI/Strings/en-us/Resources.resw | 481 +- .../Settings.UI/ViewModels/AwakeViewModel.cs | 27 +- .../ViewModels/CmdNotFoundViewModel.cs | 19 +- .../ViewModels/DashboardViewModel.cs | 10 + .../ViewModels/PowerOcrViewModel.cs | 6 + .../Settings.UI/ViewModels/ShellViewModel.cs | 15 - .../ViewModels/VideoConferenceViewModel.cs | 586 -- .../Settings.UI/ViewModels/ZoomItViewModel.cs | 764 ++ tools/BugReportTool/BugReportTool/Main.cpp | 9 - .../BugReportTool/ProcessesList.cpp | 95 +- .../BugReportTool/ReportGPOValues.cpp | 2 +- tools/WebcamReportTool/DirectShowUtils.cpp | 26 - tools/WebcamReportTool/DirectShowUtils.h | 31 - tools/WebcamReportTool/WebcamReportTool.sln | 31 - .../WebcamReportTool/WebcamReportTool.vcxproj | 75 - tools/WebcamReportTool/main.cpp | 240 - tools/WebcamReportTool/resource.h | 13 - tools/build/video_conference_make_cab.ps1 | 13 - 352 files changed, 19190 insertions(+), 16603 deletions(-) delete mode 100644 .pipelines/ESRPSigning_abstracted_utils_dll.json delete mode 100644 .pipelines/ESRPSigning_vcm.json delete mode 100644 doc/devdocs/tools/webcam-report-tool.md delete mode 100644 doc/images/overview/Original/VideoConference.png delete mode 100644 doc/images/overview/VideoConference_large.png delete mode 100644 doc/images/overview/VideoConference_small.png delete mode 100644 installer/PowerToysSetup/VideoConference.wxs create mode 100644 src/common/notifications/NotificationUtil.cpp create mode 100644 src/common/sysinternals/Eula/Eula.txt create mode 100644 src/common/sysinternals/Eula/eula.c create mode 100644 src/common/sysinternals/Eula/eula.h create mode 100644 src/common/sysinternals/Eula/eula.rtf create mode 100644 src/common/sysinternals/WindowsVersions.cpp create mode 100644 src/common/sysinternals/WindowsVersions.h create mode 100644 src/common/sysinternals/dll.c create mode 100644 src/common/sysinternals/dll.h create mode 100644 src/common/utils/clean_video_conference.h create mode 100644 src/modules/AdvancedPaste/AdvancedPaste/Helpers/AIServiceFormatEvent.cs create mode 100644 src/modules/AdvancedPaste/AdvancedPaste/SerializationContext/SourceGenerationContext.cs create mode 100644 src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteProcessManager.cpp create mode 100644 src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteProcessManager.h delete mode 100644 src/modules/MouseWithoutBorders/App/Class/Common.Log.cs delete mode 100644 src/modules/MouseWithoutBorders/App/Class/Common.Receiver.cs create mode 100644 src/modules/MouseWithoutBorders/App/Core/Receiver.cs create mode 100644 src/modules/MouseWithoutBorders/App/Core/Thread.cs create mode 100644 src/modules/ZoomIt/ZoomIt/AudioSampleGenerator.cpp create mode 100644 src/modules/ZoomIt/ZoomIt/AudioSampleGenerator.h create mode 100644 src/modules/ZoomIt/ZoomIt/CaptureFrameWait.cpp create mode 100644 src/modules/ZoomIt/ZoomIt/CaptureFrameWait.h create mode 100644 src/modules/ZoomIt/ZoomIt/DemoType.cpp create mode 100644 src/modules/ZoomIt/ZoomIt/DemoType.h create mode 100644 src/modules/ZoomIt/ZoomIt/PowerToys/branding.h create mode 100644 src/modules/ZoomIt/ZoomIt/Registry.h create mode 100644 src/modules/ZoomIt/ZoomIt/SelectRectangle.cpp create mode 100644 src/modules/ZoomIt/ZoomIt/SelectRectangle.h create mode 100644 src/modules/ZoomIt/ZoomIt/Utility.cpp create mode 100644 src/modules/ZoomIt/ZoomIt/Utility.h create mode 100644 src/modules/ZoomIt/ZoomIt/VersionHelper.cpp create mode 100644 src/modules/ZoomIt/ZoomIt/VersionHelper.h create mode 100644 src/modules/ZoomIt/ZoomIt/VideoRecordingSession.cpp create mode 100644 src/modules/ZoomIt/ZoomIt/VideoRecordingSession.h create mode 100644 src/modules/ZoomIt/ZoomIt/ZoomIt.h create mode 100644 src/modules/ZoomIt/ZoomIt/ZoomIt.idc create mode 100644 src/modules/ZoomIt/ZoomIt/ZoomIt.rc create mode 100644 src/modules/ZoomIt/ZoomIt/ZoomIt.vcxproj create mode 100644 src/modules/ZoomIt/ZoomIt/ZoomIt.vcxproj.filters create mode 100644 src/modules/ZoomIt/ZoomIt/ZoomItSettings.h create mode 100644 src/modules/ZoomIt/ZoomIt/Zoomit.cpp create mode 100644 src/modules/ZoomIt/ZoomIt/Zoomit.exe.manifest create mode 100644 src/modules/ZoomIt/ZoomIt/appicon.ico create mode 100644 src/modules/ZoomIt/ZoomIt/binres.rc create mode 100644 src/modules/ZoomIt/ZoomIt/cursor1.cur create mode 100644 src/modules/ZoomIt/ZoomIt/drawingc.cur rename src/modules/{videoconference/VideoConferenceModule/Assets/VCM/black.bmp => ZoomIt/ZoomIt/icon1.ico} (54%) create mode 100644 src/modules/ZoomIt/ZoomIt/makefile rename src/modules/{videoconference/VideoConferenceShared => ZoomIt/ZoomIt}/packages.config (76%) create mode 100644 src/modules/ZoomIt/ZoomIt/pch.cpp create mode 100644 src/modules/ZoomIt/ZoomIt/pch.h create mode 100644 src/modules/ZoomIt/ZoomIt/resource.h rename src/modules/{videoconference/VideoConferenceModule/VideoConferenceModule.rc => ZoomIt/ZoomItModuleInterface/ZoomItModuleInterface.rc} (100%) create mode 100644 src/modules/ZoomIt/ZoomItModuleInterface/ZoomItModuleInterface.vcxproj create mode 100644 src/modules/ZoomIt/ZoomItModuleInterface/ZoomItModuleInterface.vcxproj.filters create mode 100644 src/modules/ZoomIt/ZoomItModuleInterface/dllmain.cpp rename {tools/WebcamReportTool => src/modules/ZoomIt/ZoomItModuleInterface}/packages.config (59%) rename src/modules/{videoconference/VideoConferenceModule => ZoomIt/ZoomItModuleInterface}/pch.cpp (100%) create mode 100644 src/modules/ZoomIt/ZoomItModuleInterface/pch.h create mode 100644 src/modules/ZoomIt/ZoomItModuleInterface/resource.h create mode 100644 src/modules/ZoomIt/ZoomItModuleInterface/trace.cpp create mode 100644 src/modules/ZoomIt/ZoomItModuleInterface/trace.h create mode 100644 src/modules/ZoomIt/ZoomItSettingsInterop/PropertySheet.props create mode 100644 src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.cpp create mode 100644 src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.h create mode 100644 src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.idl create mode 100644 src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.def rename tools/WebcamReportTool/WebcamReportTool.rc => src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.rc (95%) rename src/modules/{videoconference/VideoConferenceShared/VideoConferenceShared.vcxproj => ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.vcxproj} (50%) create mode 100644 src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.vcxproj.filters rename src/modules/{videoconference/VideoConferenceModule => ZoomIt/ZoomItSettingsInterop}/packages.config (100%) create mode 100644 src/modules/ZoomIt/ZoomItSettingsInterop/pch.cpp create mode 100644 src/modules/ZoomIt/ZoomItSettingsInterop/pch.h create mode 100644 src/modules/ZoomIt/ZoomItSettingsInterop/resource.h delete mode 100644 src/modules/launcher/PowerLauncher/Helper/AnimationFactorToValueConverter.cs delete mode 100644 src/modules/launcher/PowerLauncher/Helper/FallbackBrushConverter.cs delete mode 100644 src/modules/launcher/PowerLauncher/Styles/FluentHC.xaml create mode 100644 src/modules/registrypreview/RegistryPreviewUILib/ClipboardHelper.cs delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-NotInUse Dark.png delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-NotInUse Dark.svg delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-NotInUse Light.png delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-NotInUse Light.svg delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-Off Dark.png delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-Off Dark.svg delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-Off Light.png delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-Off Light.svg delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-On Dark.png delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-On Dark.svg delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-On Light.png delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-On Light.svg delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-NotInUse Dark.png delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-NotInUse Dark.svg delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-NotInUse Light.png delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-NotInUse Light.svg delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-Off Dark.png delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-Off Dark.svg delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-Off Light.png delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-Off Light.svg delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-On Dark.png delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-On Dark.svg delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-On Light.png delete mode 100644 src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-On Light.svg delete mode 100644 src/modules/videoconference/VideoConferenceModule/AudioDeviceNotificationClient.cpp delete mode 100644 src/modules/videoconference/VideoConferenceModule/AudioDeviceNotificationClient.h delete mode 100644 src/modules/videoconference/VideoConferenceModule/README.md delete mode 100644 src/modules/videoconference/VideoConferenceModule/Toolbar.cpp delete mode 100644 src/modules/videoconference/VideoConferenceModule/Toolbar.h delete mode 100644 src/modules/videoconference/VideoConferenceModule/VideoConference.filters delete mode 100644 src/modules/videoconference/VideoConferenceModule/VideoConference.vcxproj delete mode 100644 src/modules/videoconference/VideoConferenceModule/VideoConference.vcxproj.filters delete mode 100644 src/modules/videoconference/VideoConferenceModule/VideoConferenceModule.cpp delete mode 100644 src/modules/videoconference/VideoConferenceModule/VideoConferenceModule.h delete mode 100644 src/modules/videoconference/VideoConferenceModule/dllmain.cpp delete mode 100644 src/modules/videoconference/VideoConferenceModule/framework.h delete mode 100644 src/modules/videoconference/VideoConferenceModule/pch.h delete mode 100644 src/modules/videoconference/VideoConferenceModule/resource.h delete mode 100644 src/modules/videoconference/VideoConferenceModule/trace.cpp delete mode 100644 src/modules/videoconference/VideoConferenceModule/trace.h delete mode 100644 src/modules/videoconference/VideoConferenceProxyFilter/DirectShowUtils.cpp delete mode 100644 src/modules/videoconference/VideoConferenceProxyFilter/DirectShowUtils.h delete mode 100644 src/modules/videoconference/VideoConferenceProxyFilter/ImageLoading.cpp delete mode 100644 src/modules/videoconference/VideoConferenceProxyFilter/Resources.resx delete mode 100644 src/modules/videoconference/VideoConferenceProxyFilter/VideoCaptureDevice.cpp delete mode 100644 src/modules/videoconference/VideoConferenceProxyFilter/VideoCaptureDevice.h delete mode 100644 src/modules/videoconference/VideoConferenceProxyFilter/VideoCaptureProxyFilter.cpp delete mode 100644 src/modules/videoconference/VideoConferenceProxyFilter/VideoCaptureProxyFilter.h delete mode 100644 src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilter.rc delete mode 100644 src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilter.vcxproj delete mode 100644 src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilterx86.sln delete mode 100644 src/modules/videoconference/VideoConferenceProxyFilter/build_vcm_x86.cmd delete mode 100644 src/modules/videoconference/VideoConferenceProxyFilter/dllmain.cpp delete mode 100644 src/modules/videoconference/VideoConferenceProxyFilter/module.def delete mode 100644 src/modules/videoconference/VideoConferenceProxyFilter/packages.config delete mode 100644 src/modules/videoconference/VideoConferenceProxyFilter/resource.h delete mode 100644 src/modules/videoconference/VideoConferenceProxyFilter/resource.x86.h delete mode 100644 src/modules/videoconference/VideoConferenceShared/CameraStateUpdateChannels.cpp delete mode 100644 src/modules/videoconference/VideoConferenceShared/CameraStateUpdateChannels.h delete mode 100644 src/modules/videoconference/VideoConferenceShared/DLLProviderHelpers.h delete mode 100644 src/modules/videoconference/VideoConferenceShared/Logging.cpp delete mode 100644 src/modules/videoconference/VideoConferenceShared/Logging.h delete mode 100644 src/modules/videoconference/VideoConferenceShared/MediaFoundationAPIProvider.h delete mode 100644 src/modules/videoconference/VideoConferenceShared/MicrophoneDevice.cpp delete mode 100644 src/modules/videoconference/VideoConferenceShared/MicrophoneDevice.h delete mode 100644 src/modules/videoconference/VideoConferenceShared/SerializedSharedMemory.cpp delete mode 100644 src/modules/videoconference/VideoConferenceShared/SerializedSharedMemory.h delete mode 100644 src/modules/videoconference/VideoConferenceShared/VideoCaptureDeviceList.cpp delete mode 100644 src/modules/videoconference/VideoConferenceShared/VideoCaptureDeviceList.h delete mode 100644 src/modules/videoconference/VideoConferenceShared/naming.cpp delete mode 100644 src/modules/videoconference/VideoConferenceShared/naming.h delete mode 100644 src/modules/videoconference/VideoConferenceShared/pch.h delete mode 100644 src/modules/videoconference/VideoConferenceShared/username.cpp delete mode 100644 src/modules/videoconference/VideoConferenceShared/username.h delete mode 100644 src/modules/videoconference/make_cab.ddf delete mode 100644 src/settings-ui/Settings.UI.Library/SndVideoConferenceSettings.cs delete mode 100644 src/settings-ui/Settings.UI.Library/VideoConferenceConfigProperties.cs delete mode 100644 src/settings-ui/Settings.UI.Library/VideoConferenceSettingsIPCMessage.cs create mode 100644 src/settings-ui/Settings.UI.Library/ZoomItProperties.cs rename src/settings-ui/Settings.UI.Library/{VideoConferenceSettings.cs => ZoomItSettings.cs} (57%) delete mode 100644 src/settings-ui/Settings.UI/Assets/Settings/Icons/VideoConferenceMute.png create mode 100644 src/settings-ui/Settings.UI/Assets/Settings/Icons/ZoomIt.png delete mode 100644 src/settings-ui/Settings.UI/Assets/Settings/Modules/OOBE/VideoConferenceMute.png create mode 100644 src/settings-ui/Settings.UI/Assets/Settings/Modules/OOBE/ZoomIt.gif delete mode 100644 src/settings-ui/Settings.UI/Assets/Settings/Modules/VideoConference.png create mode 100644 src/settings-ui/Settings.UI/Assets/Settings/Modules/ZoomIt.png create mode 100644 src/settings-ui/Settings.UI/Converters/ZoomItInitialZoomConverter.cs create mode 100644 src/settings-ui/Settings.UI/Converters/ZoomItTypeSpeedSliderConverter.cs create mode 100644 src/settings-ui/Settings.UI/Helpers/CHOOSEFONT.cs create mode 100644 src/settings-ui/Settings.UI/Helpers/LOGFONT.cs delete mode 100644 src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeVideoConference.xaml create mode 100644 src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeZoomIt.xaml rename src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/{OobeVideoConference.xaml.cs => OobeZoomIt.xaml.cs} (53%) delete mode 100644 src/settings-ui/Settings.UI/SettingsXAML/Views/VideoConference.xaml delete mode 100644 src/settings-ui/Settings.UI/SettingsXAML/Views/VideoConference.xaml.cs create mode 100644 src/settings-ui/Settings.UI/SettingsXAML/Views/ZoomItPage.xaml create mode 100644 src/settings-ui/Settings.UI/SettingsXAML/Views/ZoomItPage.xaml.cs delete mode 100644 src/settings-ui/Settings.UI/ViewModels/VideoConferenceViewModel.cs create mode 100644 src/settings-ui/Settings.UI/ViewModels/ZoomItViewModel.cs delete mode 100644 tools/WebcamReportTool/DirectShowUtils.cpp delete mode 100644 tools/WebcamReportTool/DirectShowUtils.h delete mode 100644 tools/WebcamReportTool/WebcamReportTool.sln delete mode 100644 tools/WebcamReportTool/WebcamReportTool.vcxproj delete mode 100644 tools/WebcamReportTool/main.cpp delete mode 100644 tools/WebcamReportTool/resource.h delete mode 100644 tools/build/video_conference_make_cab.ps1 diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index f2eb897a4d56..37ba10bc4d85 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -77,9 +77,9 @@ body: - Shortcut Guide - System tray interaction - TextExtractor - - Video Conference Mute - Workspaces - Welcome / PowerToys Tour window + - ZoomIt validations: required: true diff --git a/.github/ISSUE_TEMPLATE/translation_issue.yml b/.github/ISSUE_TEMPLATE/translation_issue.yml index 69787a3ed685..ffddacb9aac8 100644 --- a/.github/ISSUE_TEMPLATE/translation_issue.yml +++ b/.github/ISSUE_TEMPLATE/translation_issue.yml @@ -51,9 +51,9 @@ body: - Shortcut Guide - System tray interaction - TextExtractor - - Video Conference Mute - Workspaces - Welcome / PowerToys Tour window + - ZoomIt validations: required: true - type: input diff --git a/.github/actions/spell-check/allow/code.txt b/.github/actions/spell-check/allow/code.txt index 787715190015..f8097284ff2f 100644 --- a/.github/actions/spell-check/allow/code.txt +++ b/.github/actions/spell-check/allow/code.txt @@ -86,6 +86,9 @@ howto onefuzzconfig oip onefuzzingestionpreparationtool +OTP +Yubi +Yubico # KEYS diff --git a/.github/actions/spell-check/allow/names.txt b/.github/actions/spell-check/allow/names.txt index c851fbf45f6a..a398a4724f4e 100644 --- a/.github/actions/spell-check/allow/names.txt +++ b/.github/actions/spell-check/allow/names.txt @@ -23,7 +23,6 @@ registrypreview rooler scoobe shortcutguide -videoconference # USERS @@ -34,6 +33,7 @@ Adoumie Advaith alekhyareddy Aleks +amihaiuc angularsen Anirudha arjunbalgovind @@ -68,6 +68,7 @@ Essey Feng ethanfangg ferraridavide +foxmsft frankychen Gaarden gaardmark @@ -116,6 +117,7 @@ martinchrzan martinmoene Melman Mengyuan +Mihaiuc Mikhayelyan msft Mykhailo @@ -143,6 +145,7 @@ ricardosantos riri ritchielawrence robmikh +Russinovich Rutkas ryanbodrug saahmedm @@ -187,9 +190,11 @@ Zykova Bilibili BVID +capturevideosample cmdow Controlz cortana +dlnilsson fancymouse firefox gpt diff --git a/.github/actions/spell-check/excludes.txt b/.github/actions/spell-check/excludes.txt index 5e2a5ffff135..2a50b77f1daa 100644 --- a/.github/actions/spell-check/excludes.txt +++ b/.github/actions/spell-check/excludes.txt @@ -16,6 +16,7 @@ (?:|$^ 92.31% - excluded 12/13)/editor/[^/]+$ /images/launcher/[^/]+$ /TestFiles/ +[^/]\.cur$ [^/]\.gcode$ [^/]\.rgs$ \.a$ @@ -122,5 +123,6 @@ ^src/modules/MouseWithoutBorders/App/Helper/.*\.resx$ ^src/modules/previewpane/UnitTests-MarkdownPreviewHandler/HelperFiles/MarkdownWithHTMLImageTag\.txt$ ^src/Monaco/ +^src/common/sysinternals/Eula/ ^tools/Verification scripts/Check preview handler registration\.ps1$ ignore$ diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index 60b8a9f9dce2..1fd5d1c36efa 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -15,6 +15,7 @@ ACTIVATEAPP activationaction ACVS adaptivecards +ADDSTRING ADDUNDORECORD ADifferent adml @@ -29,18 +30,19 @@ ahk AHybrid akv ALarger +ALIGNRIGHT ALLAPPS +ALLCHILDREN ALLINPUT Allman ALLOWUNDO ALLVIEW ALPHATYPE AModifier -AMPROPERTY -AMPROPSETID amr ANDSCANS animatedvisuals +Animnate ansicolor ANull AOC @@ -72,6 +74,7 @@ ARemapped ARPINSTALLLOCATION ARPPRODUCTICON ARRAYSIZE +ARROWKEYS asf AShortcut ASingle @@ -85,9 +88,14 @@ atleast ATRIOX aumid Authenticode +AUTOBUDDY +AUTOCHECKBOX AUTOHIDE +AUTOHSCROLL AUTOMATIONPROPERTIES +AUTORADIOBUTTON Autorun +AUTOTICKS AUTOUPDATE AValid AVery @@ -105,12 +113,17 @@ BIF bigbar bigobj binlog +binres BITMAPFILEHEADER bitmapimage BITMAPINFO BITMAPINFOHEADER +Bitmaps +BITSPERPEL BITSPIXEL bla +BLACKFRAME +BLENDFUNCTION Blockquotes blogs Blt @@ -120,6 +133,7 @@ bmi bms BNDBk BNumber +BODGY bodgy BOOTSTRAPPERINSTALLFOLDER bostrot @@ -128,7 +142,6 @@ boxmodel BPBF bpmf bpp -Breadcrumb Browsable BROWSEINFO bsd @@ -145,6 +158,7 @@ BValue byapp BYEXENAME BYPOSITION +CALCRECT CALG callbackptr calpwstr @@ -161,7 +175,6 @@ CCHFORMNAME CCom CContext CDeclaration -CDEF cdn CElems CENTERALIGN @@ -173,6 +186,7 @@ changecursor channelurl CHILDACTIVATE CHILDWINDOW +CHOOSEFONT cidl cim CImage @@ -211,6 +225,7 @@ colorformat colorhistory colorhistorylimit COLORKEY +comctl comdlg comexp cominterop @@ -228,15 +243,18 @@ contractversion CONTROLL CONTROLPARENT copiedcolorrepresentation +COPYPEN COREWINDOW cotaskmem COULDNOT countof cpcontrols cph +cplusplus CPower cppwinrt createdump +CREATEPROCESS CREATESCHEDULEDTASK CREATESTRUCT CREATETHREAD @@ -253,7 +271,9 @@ CSRW CStyle cswin CTest +CTEXT Ctl +CTLCOLORSTATIC currentculture CURRENTDIR CURSORINFO @@ -297,7 +317,6 @@ DDEIf DDEIFEXEC DDETOPIC DDevice -ddf DDxgi Deact debugbreak @@ -323,32 +342,34 @@ DELEGATEEXECUTE DELETEDKEYIMAGE DELETESCANS deletethis +DEMOTYPE DENORMAL depersist deprioritized Depsx DESELECTOTHERS +DESIGNINFO DESKTOPABSOLUTEEDITING DESKTOPABSOLUTEPARSING desktopshorcutinstalled devblogs devdocs -devenum devmgmt DEVMODE DEVMODEW -DEVMON devpal -DEVSOURCE -DGR +DIALOGEX dic -DIIRFLAG dimm DISABLEASACTIONKEY +DISABLENOSCROLL diskmgmt DISPLAYCHANGE DISPLAYCONFIG +DISPLAYFLAGS +DISPLAYFREQUENCY displayname +DISPLAYORIENTATION divyan Dlg DLGFRAME @@ -372,19 +393,17 @@ drawingcolor dreamsofameaningfullife drivedetectionwarning Droid +DROPFILES DROPTARGET -dshow DSTINVERT +DSurface +DTexture DUMMYUNIONNAME Dutil DVASPECT DVASPECTINFO DVD -DVH -DVHD dvr -DVSD -DVSL DVTARGETDEVICE dwl dwm @@ -405,14 +424,16 @@ dwrite dxgi easeofaccess ecount -EData Edid EDITKEYBOARD EDITSHORTCUTS +EDITTEXT EFile ekus ENABLEDELAYEDEXPANSION ENABLEDPOPUP +ENABLETAB +ENABLETEMPLATE encodedlaunch encryptor ENDSESSION @@ -425,15 +446,16 @@ epu ERASEBKGND EREOF EResize -ERole ERRORIMAGE ERRORTITLE erwrite ESettings ESPN esrp +ETDT etl etw +eula eurochange eventlog eventvwr @@ -462,12 +484,12 @@ exstyle EXTENDEDKEY EXTENDEDVERBS extensionsdk +EXTRALIGHT EXTRINSICPROPERTIES eyetracker FANCYZONESDRAWLAYOUTTEST FANCYZONESEDITOR FARPROC -fdw fff FILEEXPLORER FILEFLAGS @@ -479,17 +501,18 @@ FILELOCKSMITHLIBINTEROP filemgmt FILEMUSTEXIST FILEOP +FILEOPENDIALOGOPTIONS FILEOS FILESUBTYPE FILESYSPATH Filetime FILEVERSION -Filtergraph Filterkeyboard -Filterx +FILTERMODE findfast Fira FIXEDFILEINFO +FIXEDSYS flac flaticon flyouts @@ -499,8 +522,11 @@ FOF FOFX FOLDERID folderpath +FONTTYPE footgunning +FORCEFILESYSTEM FORCEMINIMIZE +FORMATDLGORD formatetc FORPARSING fpvm @@ -520,18 +546,23 @@ GC'ed GCLP gdi gdiplus +GDIPVER GDISCALED GEmoji GETCLIENTAREAANIMATION +GETCURSEL GETDESKWALLPAPER GETDLGCODE GETDPISCALEDSIZE getfilesiginforedist +GETHOTKEY GETICON GETMINMAXINFO +GETNONCLIENTMETRICS GETPROPERTYSTOREFLAGS GETSCREENSAVERRUNNING GETSECKEY +GETSTICKYKEYS GETTEXTLENGTH GHND gifv @@ -542,6 +573,7 @@ gpo GPOCA gpp gpu +gradians gsl GSM gtm @@ -565,13 +597,14 @@ hbm hbmp hbr HBRBACKGROUND +hbrush hcblack -HCERTSTORE HCRYPTHASH HCRYPTPROV hcursor hcwhite hdc +hdr hdrop hdwwiz Helpline @@ -584,6 +617,7 @@ Hiber Hiberboot HIBYTE hicon +HIDEREADONLY HIDEWINDOW Hif HIMAGELIST @@ -592,10 +626,12 @@ hinst HIWORD HKC HKCC +HKCOMB HKCR HKCU hkey HKLM +HKM HKPD HKU HMD @@ -604,9 +640,11 @@ hmodule hmonitor homies homljgmgpmcbpjbnjpfijnhipfkiclkd +HORZRES HORZSIZE Hostbackdropbrush hotkeycontrol +HOTKEYF hotkeys hotlight hotspot @@ -635,6 +673,7 @@ hwnd HWNDFIRST HWNDLAST HWNDNEXT +HWNDPARENT HWNDPREV hyjiacan IAI @@ -642,10 +681,13 @@ IBeam icf ICONERROR ICONLOCATION +idc +IDCANCEL IDD idk idl idlist +IDOK IDR IDXGI ietf @@ -660,7 +702,6 @@ IGo iid Iindex Ijwhost -IKs IMAGEHLP IMAGERESIZERCONTEXTMENU IMAGERESIZEREXT @@ -670,12 +711,16 @@ imagingdevices ime imgflip inbox +INCONTACT Indo inetcpl Infobar INFOEXAMPLE +Infotip infotip +INITDIALOG INITGUID +INITTOLOGFONTSTRUCT INLINEPREFIX inorder INPC @@ -721,7 +766,6 @@ IUnknown IUse IWIC iwr -IYUV jfif jgeosdfsdsgmkedfgdfgdfgbkmhcgcflmi jjw @@ -749,7 +793,6 @@ KILLFOCUS killrunner kinda kmph -KSPROPERTY Kybd lastcodeanalysissucceeded Lastdevice @@ -758,20 +801,23 @@ LAYOUTRTL LCIDTo Lclean Ldone -ldx +Ldr LEFTSCROLLBAR +LEFTTEXT LError LEVELID LExit lhwnd LIBID libraryincludes +LIMITSIZE +LIMITTEXT lindex linkid LINKOVERLAY LINQTo listview -lld +LIVEZOOM LLKH llkhf LMEM @@ -788,12 +834,16 @@ LOGFONT LOGFONTW logon LOGPIXELSX +LOGPIXELSY longdate +LONGNAMES lowlevel LOWORD lparam LPBITMAPINFOHEADER +LPCFHOOKPROC LPCITEMIDLIST +LPCLSID lpcmi LPCMINVOKECOMMANDINFO LPCREATESTRUCT @@ -817,6 +867,7 @@ LPTOP lptpm LPTR LPTSTR +lpv LPW lpwcx lpwndpl @@ -825,7 +876,9 @@ LRESULT LSTATUS lstrcmp lstrcmpi +lstrcpyn lstrlen +LTEXT LTk LTRREADING luid @@ -837,12 +890,14 @@ lvm LWA lwin LZero -majortype -makecab +MAGTRANSFORM MAKEINTRESOURCE MAKEINTRESOURCEA MAKEINTRESOURCEW MAKELANGID +MAKELONG +MAKELPARAM +MAKEWPARAM manifestdependency MAPPEDTOSAMEKEY MAPTOSAMESHORTCUT @@ -859,8 +914,6 @@ mdpvm mdtext mdtxt mdwn -MEDIASUBTYPE -mediatype meme memicmp MENUITEMINFO @@ -870,9 +923,7 @@ MERGEPAINT Metadatas metafile mfc -mfplat Mgmt -mic Microwaved midl mii @@ -882,10 +933,10 @@ MINIMIZEBOX MINIMIZEEND MINIMIZESTART miniz +MINMAXINFO minwindef Mip Miracast -mjpg mkdn mlcfg mmc @@ -895,6 +946,7 @@ mmi mmsys mobileredirect mockapi +MODALFRAME MODESPRUNED MONITORENUMPROC MONITORINFO @@ -916,6 +968,7 @@ MRT mru msc mscorlib +msctls msdata MSDL MSGFLT @@ -934,6 +987,7 @@ msrc msstore mst msvcp +msvsmon MTND mtu MULTIPLEUSE @@ -987,28 +1041,34 @@ nicksnettravels NIF NLog NLSTEXT +NMAKE NNN NOACTIVATE NOAGGREGATION NOASYNC +NOCLIP NOCLOSEPROCESS NOCOALESCE NOCOMM NOCONFIRMMKDIR NOCOPYBITS NOCOPYSECURITYATTRIBS +NOCRLF nodeca NODRAWCAPTION NODRAWICON NOFIXUPS NOINHERITLAYOUT NOINTERFACE +NOINVERT NOLINKINFO NOMCX NOMINMAX NOMIRRORBITMAP NOMOVE +NONANTIALIASED nonclient +NONCLIENTMETRICSW NONELEVATED NONINFRINGEMENT nonspace @@ -1016,6 +1076,7 @@ nonstd NOOPEN NOOWNERZORDER NOPARENTNOTIFY +NOPREFIX NOREDIRECTIONBITMAP NOREDRAW NOREMAPCLSID @@ -1029,6 +1090,8 @@ NORMALUSER NOSEARCH NOSENDCHANGING NOSIZE +NOTHOUSANDS +NOTICKS NOTIFICATIONSDLL NOTIFYICONDATA NOTIFYICONDATAW @@ -1038,6 +1101,7 @@ NOTRACK NOTRUNCATE NOTSRCCOPY NOTSRCERASE +NOTXORPEN NOUSERSETTINGS NOZORDER NPH @@ -1047,13 +1111,16 @@ nsunt NTAPI ntdll NTSTATUS +NTSYSAPI NTZm +NULLCURSOR nullonfailure numberbox nwc ocr Ocrsettings odbccp +OEMCONVERT officehubintl OFN ofs @@ -1069,23 +1136,24 @@ OPENFILENAME opensource openxmlformats OPTIMIZEFORINVOKE -ORAW ORPHANEDDIALOGTITLE ORSCANS oss ostr +OSVERSIONINFO OSVERSIONINFOEX OSVERSIONINFOEXW +OSVERSIONINFOW osvi OUTOFCONTEXT -outpin Outptr outsettings OVERLAPPEDWINDOW -overlaywindow Oversampling +OVERWRITEPROMPT OWMt OWNDC +OWNERDRAWFIXED OWRj Packagemanager PACL @@ -1101,7 +1169,6 @@ PATCOPY PATHMUSTEXIST PATINVERT PATPAINT -PAUDIO pbc pbi PBlob @@ -1114,7 +1181,9 @@ PCIDLIST PCTSTR PCWSTR pdbs +PDEVMODE pdisp +PDLL pdo pdto pdtobj @@ -1122,6 +1191,8 @@ pdw Peb PElems Pels +PELSHEIGHT +PELSWIDTH PERCEIVEDFLAG perfmon pesi @@ -1138,7 +1209,6 @@ phwnd pici pidl PIDLIST -PINDIR pinfo pinvoke pipename @@ -1149,10 +1219,14 @@ ploc ploca plocm pluginsmodel +PMAGTRANSFORM PMSIHANDLE pnid +PNMLINK Poc Podcasts +POINTERID +POINTERUPDATE Pokedex Popups POPUPWINDOW @@ -1166,7 +1240,6 @@ powertoysusersetup Powrprof ppenum ppidl -ppmt pprm pproc ppshv @@ -1185,7 +1258,6 @@ prepopulate prevhost previewer PREVIEWHANDLERFRAMEINFO -previouscamera PREVIOUSINSTALLFOLDER PREVIOUSVERSIONSINSTALLED prevpane @@ -1200,15 +1272,16 @@ proactively PROCESSENTRY PROCESSKEY PROCESSTRACE +procmon PRODEXT PRODUCTVERSION Progman programdata projectname -PROPBAG PROPERTYKEY Propset PROPVARIANT +PRTL prvpane psapi pscid @@ -1220,13 +1293,14 @@ psrm psrree pstatstg pstm -pstr +PStr pstream pstrm PSYSTEM psz ptb ptc +PTCHAR ptd PTOKEN PToy @@ -1262,6 +1336,8 @@ RAWMODE RAWPATH rbhid rclsid +RCZOOMIT +RDW READMODE READOBJECTS reblogs @@ -1271,15 +1347,10 @@ rectp RECTSOURCE recyclebin Redist -reencode -reencoded REFCLSID -REFGUID REFIID REGCLS regfile -REGFILTER -REGFILTERPINS REGISTERCLASSEX REGISTERCLASSFAILED REGISTRYHEADER @@ -1287,9 +1358,7 @@ registrypath REGISTRYPREVIEWEXT registryroot regkey -REGPINTYPES regroot -regsvr REINSTALLMODE reloadable remappings @@ -1363,6 +1432,7 @@ SCID Scip scipbe Scode +SCREENFONTS screensaver screenshots scrollviewer @@ -1372,18 +1442,29 @@ sdns searchterm searchtext SEARCHUI +SECONDARYDISPLAY secpol SEEMASKINVOKEIDLIST +SELCHANGE SENDCHANGE sendvirtualinput seperators serverside +SETBUDDYINT SETCONTEXT +SETCURSEL setcursor SETFOCUS SETFOREGROUND +SETHOTKEY SETICON +SETLOWPOWERACTIVE +SETPOWEROFFACTIVE +SETRANGE SETREDRAW +SETRULES +SETSCREENSAVEACTIVE +SETSTICKYKEYS SETTEXT SETTINGCHANGE SETTINGSCHANGED @@ -1394,6 +1475,7 @@ SETWORKAREA SFBS sfgao SFGAOF +SHACF SHANDLE sharepoint sharpkeys @@ -1415,7 +1497,6 @@ SHGDNF SHGFI shinfo shlwapi -shmem SHNAMEMAPPING shobjidl SHORTCUTATLEAST @@ -1430,6 +1511,7 @@ shortsplit showcolorname SHOWDEFAULT SHOWELEVATIONPROMPT +SHOWMAGNIFIEDCURSOR SHOWMAXIMIZED SHOWMINIMIZED SHOWMINNOACTIVE @@ -1453,7 +1535,6 @@ Sizename SIZENESW SIZENS SIZENWSE -sizeread SIZEWE SKEXP SKIPOWNPROCESS @@ -1508,6 +1589,7 @@ STATICEDGE STATSTG stdafx STDAPI +stdc stdcpp stdcpplatest STDMETHODCALLTYPE @@ -1515,20 +1597,24 @@ STDMETHODIMP STGC STGM STGMEDIUM +STICKYKEYS sticpl storelogo +stprintf streamjsonrpc STRINGIZE stringtable stringval Strm strret +stscanf sttngs Stubless STYLECHANGED STYLECHANGING subkeys sublang +SUBMODULEUPDATE Superbar sut svchost @@ -1543,7 +1629,6 @@ symbolrequestprod SYMCACHE SYMED SYMOPT -SYNCMFT SYNCPAINT SYSCHAR SYSCOLORCHANGE @@ -1557,6 +1642,7 @@ SYSKEYUP SYSLIB SYSMENU SYSTEMAPPS +SYSTEMMODAL SYSTEMTIME TApplication TApplied @@ -1569,9 +1655,18 @@ targetver taskkill taskschd TCHAR +TCIF +TCITEM +TCN Tcollab tcs +tcscat +tcschr +tcscmp tcscpy +tcsdup +tcslen +tcsrchr TCustom tdbuild TDefault @@ -1582,6 +1677,7 @@ testprocess TEXCOORD TEXTEXTRACTOR TEXTINCLUDE +tfopen tgz themeresources THH @@ -1597,6 +1693,7 @@ timedate timediff timeunion timeutil +TITLEBARINFO Titlecase tkcontrols tkconverters @@ -1604,7 +1701,6 @@ TLayout tlb tlbimp tlc -TMPVAR TNP Toolhelp toolkitconverters @@ -1615,6 +1711,7 @@ TOUCHINPUT TRACEHANDLE tracelogging tracerpt +trackbar trafficmanager traies transicc @@ -1624,6 +1721,7 @@ trl trx tsa TServer +tstoi TStr tweakme TWF @@ -1632,8 +1730,10 @@ TYPEKEYBOARD TYPEMOUSE TYPESHORTCUT UAC +UACUI UAL uap +UBR UCallback ucrt ucrtd @@ -1649,6 +1749,7 @@ ums uncompilable UNCPRIORITY UNDNAME +unhiding UNICODETEXT uninstalls Uniquifies @@ -1659,9 +1760,13 @@ UNORM unremapped unvirtualized unwide +unzoom UOffset UOI Updatelayout +UPDATENOW +UPDATEREGISTRY +updown UPGRADINGPRODUCTCODE Uptool urld @@ -1674,38 +1779,34 @@ USRDLL UType uuidv uwp +uxtheme vabdq validmodulename valuegenerator VARENUM variantassignment vcamp -vcdl +VCENTER vcgtq VCINSTALLDIR -vcm Vcpkg VCRT vcruntime vcvars VDesktop -vdi vdupq VERBSONLY VERBW VERIFYCONTEXT VERSIONINFO +VERTRES VERTSIZE VFT vget vgetq -vid -VIDCAP -videoconferencevirtualdriver -VIDEOINFOHEADER videourl viewmodel -vih +VIRTKEY VIRTUALDESK VISEGRADRELAY visiblecolorformats @@ -1733,6 +1834,7 @@ vsonline vstemplate vstest VSTHRD +vstprintf VSTT vswhere Vtbl @@ -1750,16 +1852,17 @@ wcsncpy wcsnicmp WCT WDA +wdm wdp wdupenv webbrowsers -webcam webpage websites wekyb wgpocpl WHEREID Wholegrain +WIC wic wifi wil @@ -1769,6 +1872,7 @@ wincolor windir WINDOWCREATED WINDOWEDGE +WINDOWINFO WINDOWNAME WINDOWPLACEMENT WINDOWPOSCHANGED @@ -1793,7 +1897,6 @@ winsta WINTHRESHOLD WINVER winxamlmanager -wistd withinrafael Withscript wixproj @@ -1844,7 +1947,6 @@ WTS WTSAT Wubi WUX -WVC Wwanpp XAxis xclip @@ -1881,6 +1983,9 @@ ZEROINIT zonable zoneset Zoneszonabletester +Zoomin +zoomit +ZOOMITX ZXk ZXNs zzz diff --git a/.github/actions/spell-check/patterns.txt b/.github/actions/spell-check/patterns.txt index 457e7e080015..6bd99fb83ee2 100644 --- a/.github/actions/spell-check/patterns.txt +++ b/.github/actions/spell-check/patterns.txt @@ -240,3 +240,7 @@ _SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING # Process Process (typename varname) Process Process + +# ZoomIt menu items with accelerator keys +E&xit +St&yle diff --git a/.pipelines/ESRPSigning_abstracted_utils_dll.json b/.pipelines/ESRPSigning_abstracted_utils_dll.json deleted file mode 100644 index 7655bbee5628..000000000000 --- a/.pipelines/ESRPSigning_abstracted_utils_dll.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "Version": "1.0.0", - "UseMinimatch": false, - "SignBatches": [ - { - "MatchedPath": [ - "PowerToys.HostsUILib.dll", - "PowerToys.EnvironmentVariablesUILib.dll", - "PowerToys.RegistryPreviewUILib.dll" - ], - "SigningInfo": { - "Operations": [ - { - "KeyCode": "CP-230012", - "OperationSetCode": "SigntoolSign", - "Parameters": [ - { - "parameterName": "OpusName", - "parameterValue": "Microsoft" - }, - { - "parameterName": "OpusInfo", - "parameterValue": "http://www.microsoft.com" - }, - { - "parameterName": "FileDigest", - "parameterValue": "/fd \"SHA256\"" - }, - { - "parameterName": "PageHash", - "parameterValue": "/NPH" - }, - { - "parameterName": "TimeStamp", - "parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256" - } - ], - "ToolName": "sign", - "ToolVersion": "1.0" - }, - { - "KeyCode": "CP-230012", - "OperationSetCode": "SigntoolVerify", - "Parameters": [], - "ToolName": "sign", - "ToolVersion": "1.0" - } - ] - } - } - ] -} diff --git a/.pipelines/ESRPSigning_core.json b/.pipelines/ESRPSigning_core.json index 75597143a50b..b0fa0bcd5c8f 100644 --- a/.pipelines/ESRPSigning_core.json +++ b/.pipelines/ESRPSigning_core.json @@ -17,7 +17,6 @@ "PowerToys.FilePreviewCommon.dll", "PowerToys.Interop.dll", "Tools\\PowerToys.BugReportTool.exe", - "WebcamReportTool\\PowerToys.WebcamReportTool.exe", "StylesReportTool\\PowerToys.StylesReportTool.exe", "Telemetry.dll", "PowerToys.ManagedTelemetry.dll", @@ -212,10 +211,9 @@ "PowerToys.ShortcutGuide.exe", "PowerToys.ShortcutGuideModuleInterface.dll", - "PowerToys.VideoConferenceModule.dll", - "PowerToys.VideoConferenceProxyFilter_x86.dll", - "PowerToys.VideoConferenceProxyFilter_x64.dll", - "PowerToys.VideoConferenceProxyFilter_arm64.dll", + "PowerToys.ZoomIt.exe", + "PowerToys.ZoomItModuleInterface.dll", + "PowerToys.ZoomItSettingsInterop.dll", "WinUI3Apps\\PowerToys.Settings.dll", "WinUI3Apps\\PowerToys.Settings.exe", diff --git a/.pipelines/ESRPSigning_vcm.json b/.pipelines/ESRPSigning_vcm.json deleted file mode 100644 index e9f2309cc413..000000000000 --- a/.pipelines/ESRPSigning_vcm.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "Version": "1.0.0", - "UseMinimatch": false, - "SignBatches": [ - { - "MatchedPath": [ - "PowerToys.VideoConferenceProxyFilter_x86.dll" - ], - "SigningInfo": { - "Operations": [ - { - "KeyCode": "CP-230012", - "OperationSetCode": "SigntoolSign", - "Parameters": [ - { - "parameterName": "OpusName", - "parameterValue": "Microsoft" - }, - { - "parameterName": "OpusInfo", - "parameterValue": "http://www.microsoft.com" - }, - { - "parameterName": "FileDigest", - "parameterValue": "/fd \"SHA256\"" - }, - { - "parameterName": "PageHash", - "parameterValue": "/NPH" - }, - { - "parameterName": "TimeStamp", - "parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256" - } - ], - "ToolName": "sign", - "ToolVersion": "1.0" - }, - { - "KeyCode": "CP-230012", - "OperationSetCode": "SigntoolVerify", - "Parameters": [], - "ToolName": "sign", - "ToolVersion": "1.0" - } - ] - } - } - ] -} diff --git a/.pipelines/v2/templates/job-build-project.yml b/.pipelines/v2/templates/job-build-project.yml index b22308bda4d6..229b05998f34 100644 --- a/.pipelines/v2/templates/job-build-project.yml +++ b/.pipelines/v2/templates/job-build-project.yml @@ -173,7 +173,6 @@ jobs: - pwsh: |- & '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\PowerToys.sln' & '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\tools\BugReportTool\BugReportTool.sln' - & '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\tools\WebcamReportTool\WebcamReportTool.sln' & '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\tools\StylesReportTool\StylesReportTool.sln' & '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\installer\PowerToysSetup.sln' displayName: Verify ARM64 configurations @@ -244,17 +243,6 @@ jobs: env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) - - ${{ if eq(parameters.codeSign, true) }}: - - template: steps-esrp-signing.yml - parameters: - displayName: Sign Utilities - signingIdentity: ${{ parameters.signingIdentity }} - inputs: - FolderPath: 'src/modules' - signType: batchSigning - batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_abstracted_utils_dll.json' - ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml' - - task: CopyFiles@2 displayName: Stage SDK/build inputs: @@ -302,27 +290,6 @@ jobs: env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) - - task: VSBuild@1 - displayName: Build WebcamReportTool - inputs: - solution: '**/tools/WebcamReportTool/WebcamReportTool.sln' - vsVersion: 17.0 - msbuildArgs: >- - -restore -graph - /p:RestorePackagesConfig=true - /p:CIBuild=true - /bl:$(LogOutputDirectory)\build-webcam-report.binlog - ${{ parameters.additionalBuildOptions }} - $(MSBuildCacheParameters) - $(RestoreAdditionalProjectSourcesArg) - platform: $(BuildPlatform) - configuration: $(BuildConfiguration) - msbuildArchitecture: x64 - maximumCpuCount: true - ${{ if eq(parameters.enableMsBuildCaching, true) }}: - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - - task: VSBuild@1 displayName: Build StylesReportTool inputs: @@ -452,7 +419,7 @@ jobs: displayName: Sign Core PowerToys signingIdentity: ${{ parameters.signingIdentity }} inputs: - FolderPath: '$(BuildPlatform)/$(BuildConfiguration)' # Video conf uses x86 and x64. + FolderPath: '$(BuildPlatform)/$(BuildConfiguration)' signType: batchSigning batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_core.json' ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml' @@ -467,16 +434,6 @@ jobs: batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_DSC.json' ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml' - - template: steps-esrp-signing.yml - parameters: - displayName: Sign x86 DirectShow VCM - signingIdentity: ${{ parameters.signingIdentity }} - inputs: - FolderPath: 'x86/$(BuildConfiguration)' # Video conf uses x86 and x64. - signType: batchSigning - batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_vcm.json' - ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml' - - template: steps-build-installer.yml parameters: codeSign: ${{ parameters.codeSign }} diff --git a/COMMUNITY.md b/COMMUNITY.md index 64d77c9f37c8..8b3d7035da08 100644 --- a/COMMUNITY.md +++ b/COMMUNITY.md @@ -15,15 +15,21 @@ Christian contributed New+ utility ### [@CleanCodeDeveloper](https://github.com/CleanCodeDeveloper) CleanCodeDeveloper helped do massive amounts of code stability and image resizer work. +### [@plante-msft](https://github.com/plante-msft) - Connor Plante +Connor was the creator of Workspaces and helped create PowerToys Run v2 + ### [@damienleroy](https://github.com/damienleroy) - [Damien Leroy](https://www.linkedin.com/in/Damien-Leroy-b2734416a/) Damien has helped out by developing and contributing the Quick Accent utility. -### [@daverayment ](https://github.com/daverayment ) - [David Rayment](https://www.linkedin.com/in/david-rayment-168b5251/) +### [@daverayment ](https://github.com/daverayment) - [David Rayment](https://www.linkedin.com/in/david-rayment-168b5251/) Dave has helped improve the experience inside of Peek by adding in new features and fixing bugs. ### [@davidegiacometti](https://github.com/davidegiacometti) - [Davide Giacometti](https://www.linkedin.com/in/davidegiacometti/) Davide has helped fix multiple bugs, added new utilities, features, as well as help us with the ARM64 effort by porting applications to .NET Core. +### [@ethanfangg](https://github.com/ethanfangg) - Ethan Fang +Ethan helped run PowerToys and worked on improving and prototyping out next generation PowerToys + ### [@franky920920](https://github.com/franky920920) - [Franky Chen](https://frankychen.net) Franky has helped triaging, discussing, and creating a substantial number of issues and contributed features/fixes to PowerToys. @@ -39,6 +45,9 @@ Jeff added in multiple new features into Keyboard manager, such as key chord sup ### [@TheJoeFin](https://github.com/TheJoeFin) - [Joe Finney](https://joefinapps.com) Joe has helped triaging, discussing, issues as well as fixing bugs and building features for Text Extractor. +### [@joadoumie](https://github.com/joadoumie) - Jordi Adoumie +Jordi helped innovate amazing new features into Advanced Paste and helped create PowerToys Run v2 + ### [@jsoref](https://github.com/jsoref) - [Josh Soref](https://check-spelling.dev/) Helping keep our spelling correct :) @@ -121,6 +130,8 @@ Find My Mouse is based on Raymond Chen's SuperSonar. Crop And Lock is based on the original work of Robert Mikhayelyan, with Program Manager support from [@kevinguo305](https://github.com/kevinguo305) - Kevin Guo. +ZoomIt's Video Recording Session code is based on Robert Mikhayelyan's https://github.com/robmikh/capturevideosample code. + ### Microsoft InVEST team This amazing team helped PowerToys develop PowerToys Run and Keyboard manager as well as update our Settings to v2. @alekhyareddy28, @arjunbalgovind, @jyuwono @laviusmotileng-ms, @ryanbodrug-microsoft, @saahmedm, @somil55, @traies, @udit3333 @@ -160,14 +171,19 @@ Other contributors: * Paul Schmitt - WWL * And many other Users! +## ZoomIt original contributors + +ZoomIt source code was originally implemented by [Sysinternals](https://sysinternals.com): + +- [@markrussinovich](https://github.com/markrussinovich) - Mark Russinovich +- [@foxmsft](https://github.com/foxmsft) - Alex Mihaiuc +- [@johnstep](https://github.com/johnstep) - John Stephens + ## PowerToys core team - [@crutkas](https://github.com/crutkas/) - Clint Rutkas - Lead - [@cinnamon-msft](https://github.com/cinnamon-msft) - Kayla Cinnamon - Lead -- [@ethanfangg](https://github.com/ethanfangg) - Ethan Fang - Product Manager -- [@plante-msft](https://github.com/plante-msft) - Connor Plante - Product Manager - [@nguyen-dows](https://github.com/nguyen-dows) - Christopher Nguyen - Product Manager -- [@joadoumie](https://github.com/joadoumie) - Jordi Adoumie - Product Manager - [@jaimecbernardo](https://github.com/jaimecbernardo) - Jaime Bernardo - Dev lead - [@dhowett](https://github.com/dhowett) - Dustin Howett - Dev lead - [@yeelam-gordon](https://github.com/yeelam-gordon) - Gordon Lam - Dev lead @@ -193,6 +209,9 @@ Other contributors: # Former PowerToys core team members - [@indierawk2k2](https://github.com/indierawk2k2) - Mike Harsh - Product Manager +- [@ethanfangg](https://github.com/ethanfangg) - Ethan Fang - Product Manager +- [@plante-msft](https://github.com/plante-msft) - Connor Plante - Product Manager +- [@joadoumie](https://github.com/joadoumie) - Jordi Adoumie - Product Manager - [@enricogior](https://github.com/enricogior) - Enrico Giordani - Dev Lead - [@bzoz](https://github.com/bzoz) - Bartosz Sosnowski - Dev - [@ivan100sic](https://github.com/ivan100sic) - Ivan Stošić - Dev diff --git a/DATA_AND_PRIVACY.md b/DATA_AND_PRIVACY.md index 5570729c202a..92711f00ddef 100644 --- a/DATA_AND_PRIVACY.md +++ b/DATA_AND_PRIVACY.md @@ -941,26 +941,6 @@ _If you want to find diagnostic data events in the source code, these two links -### Video Conference Mute - - - - - - - - - - - - - - - - - -
Event NameDescription
Microsoft.PowerToys.VideoConference_CameraMutedTriggered when the camera is turned off by Video Conference Mute.
Microsoft.PowerToys.VideoConference_EnableVideoConferenceOccurs when Video Conference Mute is enabled.
Microsoft.PowerToys.VideoConference_MicrophoneMutedOccurs when the microphone is muted by Video Conference Mute.
- ### Workspaces @@ -997,6 +977,50 @@ _If you want to find diagnostic data events in the source code, these two links
+### ZoomIt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Event NameDescription
Microsoft.PowerToys.ZoomIt_EnableZoomItTriggered when ZoomIt is enabled/disabled.
Microsoft.PowerToys.ZoomIt_StartedTriggered when the ZoomIt process starts.
Microsoft.PowerToys.ZoomIt_ActivateBreakTriggered when the Break mode is entered.
Microsoft.PowerToys.ZoomIt_ActivateDrawTriggered when the Draw mode is entered.
Microsoft.PowerToys.ZoomIt_ActivateZoomTriggered when the Zoom mode is entered.
Microsoft.PowerToys.ZoomIt_ActivateLiveZoomTriggered when the Live Zoom mode is entered.
Microsoft.PowerToys.ZoomIt_ActivateDemoTypeTriggered when the DemoType mode is entered.
Microsoft.PowerToys.ZoomIt_ActivateRecordTriggered when the Record mode is entered.
Microsoft.PowerToys.ZoomIt_ActivateSnipTriggered when the Snip mode is entered.
+ + NOT Installed + + + - - - - - - @@ -34,7 +28,6 @@ - diff --git a/installer/PowerToysSetup/VideoConference.wxs b/installer/PowerToysSetup/VideoConference.wxs deleted file mode 100644 index 04bdb1e5066e..000000000000 --- a/installer/PowerToysSetup/VideoConference.wxs +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - WINDOWSBUILDNUMBER >= 19041 - - - - - - - - - - - - - WINDOWSBUILDNUMBER >= 19041 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/installer/PowerToysSetupCustomActions/CustomAction.cpp b/installer/PowerToysSetupCustomActions/CustomAction.cpp index 22357043435c..5473fffbf000 100644 --- a/installer/PowerToysSetupCustomActions/CustomAction.cpp +++ b/installer/PowerToysSetupCustomActions/CustomAction.cpp @@ -12,6 +12,7 @@ #include "../../src/common/version/version.h" #include "../../src/common/Telemetry/EtwTrace/EtwTrace.h" #include "../../src/common/utils/package.h" +#include "../../src/common/utils/clean_video_conference.h" #include #include @@ -330,6 +331,19 @@ UINT __stdcall CheckGPOCA(MSIHANDLE hInstall) return WcaFinalize(er); } +// We've deprecated Video Conference Mute. This Custom Action cleans up any stray registry entry for the driver dll. +UINT __stdcall CleanVideoConferenceRegistryCA(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + hr = WcaInitialize(hInstall, "CleanVideoConferenceRegistry"); + ExitOnFailure(hr, "Failed to initialize"); + clean_video_conference(); +LExit: + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + UINT __stdcall ApplyModulesRegistryChangeSetsCA(MSIHANDLE hInstall) { HRESULT hr = S_OK; @@ -1026,164 +1040,6 @@ UINT __stdcall DetectPrevInstallPathCA(MSIHANDLE hInstall) return WcaFinalize(er); } -UINT __stdcall CertifyVirtualCameraDriverCA(MSIHANDLE hInstall) -{ -#ifdef CIBuild // On pipeline we are using microsoft certification - WcaInitialize(hInstall, "CertifyVirtualCameraDriverCA"); - return WcaFinalize(ERROR_SUCCESS); -#else - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - LPWSTR certificatePath = nullptr; - HCERTSTORE hCertStore = nullptr; - HANDLE hfile = nullptr; - DWORD size = INVALID_FILE_SIZE; - char* pFileContent = nullptr; - - hr = WcaInitialize(hInstall, "CertifyVirtualCameraDriverCA"); - ExitOnFailure(hr, "Failed to initialize", hr); - - hr = WcaGetProperty(L"CustomActionData", &certificatePath); - ExitOnFailure(hr, "Failed to get install property", hr); - - hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, L"AuthRoot"); - if (!hCertStore) - { - hr = GetLastError(); - ExitOnFailure(hr, "Cannot put principal run level: %x", hr); - } - - hfile = CreateFile(certificatePath, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); - if (hfile == INVALID_HANDLE_VALUE) - { - hr = GetLastError(); - ExitOnFailure(hr, "Certificate file open failed", hr); - } - - size = GetFileSize(hfile, nullptr); - if (size == INVALID_FILE_SIZE) - { - hr = GetLastError(); - ExitOnFailure(hr, "Certificate file size not valid", hr); - } - - pFileContent = static_cast(malloc(size)); - - DWORD sizeread; - if (!ReadFile(hfile, pFileContent, size, &sizeread, nullptr)) - { - hr = GetLastError(); - ExitOnFailure(hr, "Certificate file read failed", hr); - } - - if (!CertAddEncodedCertificateToStore(hCertStore, - X509_ASN_ENCODING, - reinterpret_cast(pFileContent), - size, - CERT_STORE_ADD_ALWAYS, - nullptr)) - { - hr = GetLastError(); - ExitOnFailure(hr, "Adding certificate failed", hr); - } - - free(pFileContent); - -LExit: - ReleaseStr(certificatePath); - if (hCertStore) - { - CertCloseStore(hCertStore, 0); - } - if (hfile) - { - CloseHandle(hfile); - } - - if (!SUCCEEDED(hr)) - { - PMSIHANDLE hRecord = MsiCreateRecord(0); - MsiRecordSetString(hRecord, 0, TEXT("Failed to add certificate to store")); - MsiProcessMessage(hInstall, static_cast(INSTALLMESSAGE_WARNING + MB_OK), hRecord); - } - - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -#endif -} - -UINT __stdcall InstallVirtualCameraDriverCA(MSIHANDLE hInstall) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - LPWSTR driverPath = nullptr; - - hr = WcaInitialize(hInstall, "InstallVirtualCameraDriverCA"); - ExitOnFailure(hr, "Failed to initialize"); - - hr = WcaGetProperty(L"CustomActionData", &driverPath); - ExitOnFailure(hr, "Failed to get install property"); - - BOOL requiresReboot; - DiInstallDriverW(GetConsoleWindow(), driverPath, DIIRFLAG_FORCE_INF, &requiresReboot); - - hr = GetLastError(); - ExitOnFailure(hr, "Failed to install driver"); - -LExit: - - if (!SUCCEEDED(hr)) - { - PMSIHANDLE hRecord = MsiCreateRecord(0); - MsiRecordSetString(hRecord, 0, TEXT("Failed to install virtual camera driver")); - MsiProcessMessage(hInstall, static_cast(INSTALLMESSAGE_WARNING + MB_OK), hRecord); - } - - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} - -UINT __stdcall UninstallVirtualCameraDriverCA(MSIHANDLE hInstall) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - LPWSTR driverPath = nullptr; - - hr = WcaInitialize(hInstall, "UninstallVirtualCameraDriverCA"); - ExitOnFailure(hr, "Failed to initialize"); - - hr = WcaGetProperty(L"CustomActionData", &driverPath); - ExitOnFailure(hr, "Failed to get uninstall property"); - - BOOL requiresReboot; - DiUninstallDriverW(GetConsoleWindow(), driverPath, 0, &requiresReboot); - - switch (GetLastError()) - { - case ERROR_ACCESS_DENIED: - case ERROR_FILE_NOT_FOUND: - case ERROR_INVALID_FLAGS: - case ERROR_IN_WOW64: - { - hr = GetLastError(); - ExitOnFailure(hr, "Failed to uninstall driver"); - break; - } - } - -LExit: - - if (!SUCCEEDED(hr)) - { - PMSIHANDLE hRecord = MsiCreateRecord(0); - MsiRecordSetString(hRecord, 0, TEXT("Failed to uninstall virtual camera driver")); - MsiProcessMessage(hInstall, static_cast(INSTALLMESSAGE_WARNING + MB_OK), hRecord); - } - - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} - UINT __stdcall InstallCmdPalPackageCA(MSIHANDLE hInstall) { using namespace winrt::Windows::Foundation; @@ -1279,7 +1135,7 @@ UINT __stdcall TerminateProcessesCA(MSIHANDLE hInstall) } processes.resize(bytes / sizeof(processes[0])); - std::array processesToTerminate = { + std::array processesToTerminate = { L"PowerToys.PowerLauncher.exe", L"PowerToys.Settings.exe", L"PowerToys.AdvancedPaste.exe", @@ -1317,6 +1173,7 @@ UINT __stdcall TerminateProcessesCA(MSIHANDLE hInstall) L"PowerToys.WorkspacesEditor.exe", L"PowerToys.WorkspacesWindowArranger.exe", L"Microsoft.CmdPal.UI.exe", + L"PowerToys.ZoomIt.exe", L"PowerToys.exe", }; diff --git a/installer/PowerToysSetupCustomActions/CustomAction.def b/installer/PowerToysSetupCustomActions/CustomAction.def index 3b3365330110..e91060b764d8 100644 --- a/installer/PowerToysSetupCustomActions/CustomAction.def +++ b/installer/PowerToysSetupCustomActions/CustomAction.def @@ -3,6 +3,7 @@ LIBRARY "PowerToysSetupCustomActions" EXPORTS LaunchPowerToysCA CheckGPOCA + CleanVideoConferenceRegistryCA ApplyModulesRegistryChangeSetsCA DetectPrevInstallPathCA RemoveScheduledTasksCA @@ -15,13 +16,10 @@ EXPORTS TelemetryLogRepairCancelCA TelemetryLogRepairFailCA TerminateProcessesCA - CertifyVirtualCameraDriverCA - InstallVirtualCameraDriverCA InstallEmbeddedMSIXCA InstallDSCModuleCA InstallCmdPalPackageCA UnApplyModulesRegistryChangeSetsCA - UninstallVirtualCameraDriverCA UnRegisterContextMenuPackagesCA UninstallEmbeddedMSIXCA UninstallDSCModuleCA diff --git a/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj b/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj index f3fb23d2514b..09ed1ee31a88 100644 --- a/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj +++ b/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj @@ -75,7 +75,6 @@ call cmd /C "copy ""$(ProjectDir)..\PowerToysSetup\Settings.wxs"" ""$(ProjectDir)..\PowerToysSetup\Settings.wxs.bk"""" call cmd /C "copy ""$(ProjectDir)..\PowerToysSetup\ShortcutGuide.wxs"" ""$(ProjectDir)..\PowerToysSetup\ShortcutGuide.wxs.bk"""" call cmd /C "copy ""$(ProjectDir)..\PowerToysSetup\Tools.wxs"" ""$(ProjectDir)..\PowerToysSetup\Tools.wxs.bk"""" - call cmd /C "copy ""$(ProjectDir)..\PowerToysSetup\VideoConference.wxs"" ""$(ProjectDir)..\PowerToysSetup\VideoConference.wxs.bk"""" call cmd /C "copy ""$(ProjectDir)..\PowerToysSetup\WinAppSDK.wxs"" ""$(ProjectDir)..\PowerToysSetup\WinAppSDK.wxs.bk"""" call cmd /C "copy ""$(ProjectDir)..\PowerToysSetup\WinUI3Applications.wxs"" ""$(ProjectDir)..\PowerToysSetup\WinUI3Applications.wxs.bk"""" call cmd /C "copy ""$(ProjectDir)..\PowerToysSetup\Workspaces.wxs"" ""$(ProjectDir)..\PowerToysSetup\Workspaces.wxs.bk"""" diff --git a/src/common/Common.UI/SettingsDeepLink.cs b/src/common/Common.UI/SettingsDeepLink.cs index f9fac2df1998..141a39cf2449 100644 --- a/src/common/Common.UI/SettingsDeepLink.cs +++ b/src/common/Common.UI/SettingsDeepLink.cs @@ -22,7 +22,6 @@ public enum SettingsWindow PowerRename, FileExplorer, ShortcutGuide, - VideoConference, Hosts, MeasureTool, PowerOCR, @@ -33,6 +32,7 @@ public enum SettingsWindow AdvancedPaste, Workspaces, CmdPal, + ZoomIt, } private static string SettingsWindowNameToString(SettingsWindow value) @@ -61,8 +61,6 @@ private static string SettingsWindowNameToString(SettingsWindow value) return "FileExplorer"; case SettingsWindow.ShortcutGuide: return "ShortcutGuide"; - case SettingsWindow.VideoConference: - return "VideoConference"; case SettingsWindow.Hosts: return "Hosts"; case SettingsWindow.MeasureTool: @@ -83,6 +81,8 @@ private static string SettingsWindowNameToString(SettingsWindow value) return "Workspaces"; case SettingsWindow.CmdPal: return "CmdPal"; + case SettingsWindow.ZoomIt: + return "ZoomIt"; default: { return string.Empty; diff --git a/src/common/FilePreviewCommon/MonacoHelper.cs b/src/common/FilePreviewCommon/MonacoHelper.cs index 303cacbde287..3aff51fe6ec0 100644 --- a/src/common/FilePreviewCommon/MonacoHelper.cs +++ b/src/common/FilePreviewCommon/MonacoHelper.cs @@ -38,7 +38,11 @@ private static string GetRuntimeMonacoDirectory() { string baseDirectory = AppContext.BaseDirectory ?? string.Empty; + // AppContext.BaseDirectory returns a stray \\ so we want to remove that. + baseDirectory = Path.TrimEndingDirectorySeparator(baseDirectory); + // If the executable is within "WinUI3Apps", correct the path first. + // The idea of GetFileName here is getting the last directory in the path. if (Path.GetFileName(baseDirectory) == "WinUI3Apps") { baseDirectory = Path.Combine(baseDirectory, ".."); diff --git a/src/common/GPOWrapper/GPOWrapper.cpp b/src/common/GPOWrapper/GPOWrapper.cpp index 87033256a0ea..14bf81031e55 100644 --- a/src/common/GPOWrapper/GPOWrapper.cpp +++ b/src/common/GPOWrapper/GPOWrapper.cpp @@ -132,9 +132,9 @@ namespace winrt::PowerToys::GPOWrapper::implementation { return static_cast(powertoys_gpo::getConfiguredAdvancedPasteEnabledValue()); } - GpoRuleConfigured GPOWrapper::GetConfiguredVideoConferenceMuteEnabledValue() + GpoRuleConfigured GPOWrapper::GetConfiguredZoomItEnabledValue() { - return static_cast(powertoys_gpo::getConfiguredVideoConferenceMuteEnabledValue()); + return static_cast(powertoys_gpo::getConfiguredZoomItEnabledValue()); } GpoRuleConfigured GPOWrapper::GetConfiguredMouseWithoutBordersEnabledValue() { diff --git a/src/common/GPOWrapper/GPOWrapper.h b/src/common/GPOWrapper/GPOWrapper.h index b4ba8d2845c9..318aa9aa1b7e 100644 --- a/src/common/GPOWrapper/GPOWrapper.h +++ b/src/common/GPOWrapper/GPOWrapper.h @@ -40,7 +40,7 @@ namespace winrt::PowerToys::GPOWrapper::implementation static GpoRuleConfigured GetConfiguredShortcutGuideEnabledValue(); static GpoRuleConfigured GetConfiguredTextExtractorEnabledValue(); static GpoRuleConfigured GetConfiguredAdvancedPasteEnabledValue(); - static GpoRuleConfigured GetConfiguredVideoConferenceMuteEnabledValue(); + static GpoRuleConfigured GetConfiguredZoomItEnabledValue(); static GpoRuleConfigured GetConfiguredPeekEnabledValue(); static GpoRuleConfigured GetDisableNewUpdateToastValue(); static GpoRuleConfigured GetDisableAutomaticUpdateDownloadValue(); diff --git a/src/common/GPOWrapper/GPOWrapper.idl b/src/common/GPOWrapper/GPOWrapper.idl index d406c38b0033..4ce050c6fdde 100644 --- a/src/common/GPOWrapper/GPOWrapper.idl +++ b/src/common/GPOWrapper/GPOWrapper.idl @@ -44,7 +44,7 @@ namespace PowerToys static GpoRuleConfigured GetConfiguredShortcutGuideEnabledValue(); static GpoRuleConfigured GetConfiguredTextExtractorEnabledValue(); static GpoRuleConfigured GetConfiguredAdvancedPasteEnabledValue(); - static GpoRuleConfigured GetConfiguredVideoConferenceMuteEnabledValue(); + static GpoRuleConfigured GetConfiguredZoomItEnabledValue(); static GpoRuleConfigured GetConfiguredPeekEnabledValue(); static GpoRuleConfigured GetDisableNewUpdateToastValue(); static GpoRuleConfigured GetDisableAutomaticUpdateDownloadValue(); diff --git a/src/common/ManagedCommon/ModuleType.cs b/src/common/ManagedCommon/ModuleType.cs index cabc32f6d0df..65b00d4b5a9f 100644 --- a/src/common/ManagedCommon/ModuleType.cs +++ b/src/common/ManagedCommon/ModuleType.cs @@ -33,5 +33,6 @@ public enum ModuleType ShortcutGuide, PowerOCR, Workspaces, + ZoomIt, } } diff --git a/src/common/SettingsAPI/FileWatcher.h b/src/common/SettingsAPI/FileWatcher.h index 073a33a0c81c..5ac2a55f0ef8 100644 --- a/src/common/SettingsAPI/FileWatcher.h +++ b/src/common/SettingsAPI/FileWatcher.h @@ -9,6 +9,9 @@ #include #include +#include +#include + class FileWatcher { std::wstring m_path; diff --git a/src/common/SettingsAPI/pch.h b/src/common/SettingsAPI/pch.h index 86f6eff28321..8644dfaaafc0 100644 --- a/src/common/SettingsAPI/pch.h +++ b/src/common/SettingsAPI/pch.h @@ -10,4 +10,3 @@ #include #include -#include diff --git a/src/common/SettingsAPI/settings_objects.cpp b/src/common/SettingsAPI/settings_objects.cpp index 6f3aa4c792dc..f9a72cee6244 100644 --- a/src/common/SettingsAPI/settings_objects.cpp +++ b/src/common/SettingsAPI/settings_objects.cpp @@ -331,6 +331,15 @@ namespace PowerToysSettings return static_cast(m_json.GetNamedObject(L"properties").GetNamedObject(property_name).GetNamedNumber(L"value")); } + std::optional PowerToyValues::get_uint_value(std::wstring_view property_name) const + { + if (!has_property(m_json, property_name, json::JsonValueType::Number)) + { + return std::nullopt; + } + return static_cast(m_json.GetNamedObject(L"properties").GetNamedObject(property_name).GetNamedNumber(L"value")); + } + std::optional PowerToyValues::get_string_value(std::wstring_view property_name) const { if (!has_property(m_json, property_name, json::JsonValueType::String)) diff --git a/src/common/SettingsAPI/settings_objects.h b/src/common/SettingsAPI/settings_objects.h index 1c84ac19b7d5..84b064d5af55 100644 --- a/src/common/SettingsAPI/settings_objects.h +++ b/src/common/SettingsAPI/settings_objects.h @@ -83,6 +83,7 @@ namespace PowerToysSettings std::optional get_bool_value(std::wstring_view property_name) const; std::optional get_int_value(std::wstring_view property_name) const; + std::optional get_uint_value(std::wstring_view property_name) const; std::optional get_string_value(std::wstring_view property_name) const; std::optional get_json(std::wstring_view property_name) const; json::JsonObject get_raw_json(); diff --git a/src/common/interop/CommonManaged.cpp b/src/common/interop/CommonManaged.cpp index 39ae2967b42c..d59741fef6eb 100644 --- a/src/common/interop/CommonManaged.cpp +++ b/src/common/interop/CommonManaged.cpp @@ -2,8 +2,6 @@ #include "CommonManaged.h" #include "CommonManaged.g.cpp" #include -#include "../../modules/videoconference/VideoConferenceShared/MicrophoneDevice.h" -#include "../../modules/videoconference/VideoConferenceShared/VideoCaptureDeviceList.h" namespace winrt::PowerToys::Interop::implementation { @@ -11,29 +9,4 @@ namespace winrt::PowerToys::Interop::implementation { return hstring{ get_product_version() }; } - winrt::Windows::Foundation::Collections::IVector CommonManaged::GetAllActiveMicrophoneDeviceNames() - { - auto names = std::vector(); - for (const auto& device : MicrophoneDevice::getAllActive()) - { - names.push_back(device->name().data()); - } - return winrt::multi_threaded_vector(std::move(names)); - } - winrt::Windows::Foundation::Collections::IVector CommonManaged::GetAllVideoCaptureDeviceNames() - { - auto names = std::vector(); - VideoCaptureDeviceList vcdl; - vcdl.EnumerateDevices(); - - for (UINT32 i = 0; i < vcdl.Count(); ++i) - { - auto name = vcdl.GetDeviceName(i).data(); - if (name != L"PowerToys VideoConference Mute") - { - names.push_back(name); - } - } - return winrt::multi_threaded_vector(std::move(names)); - } } diff --git a/src/common/interop/CommonManaged.h b/src/common/interop/CommonManaged.h index 96d6f5d8a549..7196699ae996 100644 --- a/src/common/interop/CommonManaged.h +++ b/src/common/interop/CommonManaged.h @@ -8,8 +8,6 @@ namespace winrt::PowerToys::Interop::implementation CommonManaged() = default; static hstring GetProductVersion(); - static winrt::Windows::Foundation::Collections::IVector GetAllActiveMicrophoneDeviceNames(); - static winrt::Windows::Foundation::Collections::IVector GetAllVideoCaptureDeviceNames(); }; } namespace winrt::PowerToys::Interop::factory_implementation diff --git a/src/common/interop/CommonManaged.idl b/src/common/interop/CommonManaged.idl index 0a523e790a52..38e9225bb529 100644 --- a/src/common/interop/CommonManaged.idl +++ b/src/common/interop/CommonManaged.idl @@ -4,8 +4,6 @@ namespace PowerToys { [default_interface] static runtimeclass CommonManaged { static String GetProductVersion(); - static Windows.Foundation.Collections.IVector GetAllActiveMicrophoneDeviceNames(); - static Windows.Foundation.Collections.IVector GetAllVideoCaptureDeviceNames(); } } } \ No newline at end of file diff --git a/src/common/interop/PowerToys.Interop.vcxproj b/src/common/interop/PowerToys.Interop.vcxproj index 88115f9eabc5..aadd8b2ebb97 100644 --- a/src/common/interop/PowerToys.Interop.vcxproj +++ b/src/common/interop/PowerToys.Interop.vcxproj @@ -93,8 +93,6 @@ - - CommonManaged.idl @@ -123,8 +121,6 @@ - - CommonManaged.idl diff --git a/src/common/interop/PowerToys.Interop.vcxproj.filters b/src/common/interop/PowerToys.Interop.vcxproj.filters index 5df4afc36889..6fa51a327571 100644 --- a/src/common/interop/PowerToys.Interop.vcxproj.filters +++ b/src/common/interop/PowerToys.Interop.vcxproj.filters @@ -21,12 +21,6 @@ Header Files - - Header Files - - - Header Files - Header Files @@ -65,12 +59,6 @@ Source Files - - Source Files - - - Source Files - Source Files diff --git a/src/common/interop/shared_constants.h b/src/common/interop/shared_constants.h index d16f49d8f1a9..1c4808ad6a21 100644 --- a/src/common/interop/shared_constants.h +++ b/src/common/interop/shared_constants.h @@ -124,6 +124,10 @@ namespace CommonSharedConstants const wchar_t SHOW_ENVIRONMENT_VARIABLES_EVENT[] = L"Local\\PowerToysEnvironmentVariables-ShowEnvironmentVariablesEvent-1021f616-e951-4d64-b231-a8f972159978"; const wchar_t SHOW_ENVIRONMENT_VARIABLES_ADMIN_EVENT[] = L"Local\\PowerToysEnvironmentVariables-EnvironmentVariablesAdminEvent-8c95d2ad-047c-49a2-9e8b-b4656326cfb2"; + // Path to the events used by ZoomIt + const wchar_t ZOOMIT_REFRESH_SETTINGS_EVENT[] = L"Local\\PowerToysZoomIt-RefreshSettingsEvent-f053a563-d519-4b0d-8152-a54489c13324"; + const wchar_t ZOOMIT_EXIT_EVENT[] = L"Local\\PowerToysZoomIt-ExitEvent-36641ce6-df02-4eac-abea-a3fbf9138220"; + // Max DWORD for key code to disable keys. const DWORD VK_DISABLED = 0x100; } diff --git a/src/common/logger/logger_settings.h b/src/common/logger/logger_settings.h index e20bc999d9c5..dab7ad64a22e 100644 --- a/src/common/logger/logger_settings.h +++ b/src/common/logger/logger_settings.h @@ -76,6 +76,7 @@ struct LogSettings inline const static std::wstring workspacesWindowArrangerLogPath = L"workspaces-window-arranger-log.txt"; inline const static std::string workspacesSnapshotToolLoggerName = "workspaces-snapshot-tool"; inline const static std::wstring workspacesSnapshotToolLogPath = L"workspaces-snapshot-tool-log.txt"; + inline const static std::string zoomItLoggerName = "zoom-it"; inline const static int retention = 30; std::wstring logLevel; LogSettings(); diff --git a/src/common/notifications/NotificationUtil.cpp b/src/common/notifications/NotificationUtil.cpp new file mode 100644 index 000000000000..082b11a23d5e --- /dev/null +++ b/src/common/notifications/NotificationUtil.cpp @@ -0,0 +1,56 @@ +#include "pch.h" +#include "NotificationUtil.h" + +#include +#include +#include +#include + +// Non-Localizable strings +namespace NonLocalizable +{ + const wchar_t RunAsAdminInfoPage[] = L"https://aka.ms/powertoysDetectedElevatedHelp"; + const wchar_t ToastNotificationButtonUrl[] = L"powertoys://cant_drag_elevated_disable/"; +} + +namespace notifications +{ + NotificationUtil::NotificationUtil() + { + ReadSettings(); + auto settingsFileName = PTSettingsHelper::get_powertoys_general_save_file_location(); + + m_settingsFileWatcher = std::make_unique(settingsFileName, [this]() { + ReadSettings(); + }); + } + + NotificationUtil::~NotificationUtil() + { + m_settingsFileWatcher.reset(); + } + + void NotificationUtil::WarnIfElevationIsRequired(std::wstring title, std::wstring message, std::wstring button1, std::wstring button2) + { + if (m_warningsElevatedApps && !m_warningShown && !is_toast_disabled(ElevatedDontShowAgainRegistryPath, ElevatedDisableIntervalInDays)) + { + std::vector actions = { + link_button{ button1, NonLocalizable::RunAsAdminInfoPage }, + link_button{ button2, NonLocalizable::ToastNotificationButtonUrl } + }; + + show_toast_with_activations(message, + title, + {}, + std::move(actions)); + + m_warningShown = true; + } + } + + void NotificationUtil::ReadSettings() + { + auto settings = PTSettingsHelper::load_general_settings(); + m_warningsElevatedApps = settings.GetNamedBoolean(L"enable_warnings_elevated_apps", true); + } +} diff --git a/src/common/notifications/NotificationUtil.h b/src/common/notifications/NotificationUtil.h index 8fcf3d91d8c3..736eabaf0c7d 100644 --- a/src/common/notifications/NotificationUtil.h +++ b/src/common/notifications/NotificationUtil.h @@ -1,40 +1,22 @@ #pragma once -#include -#include -#include -#include - -#include "Generated Files/resource.h" +#include namespace notifications { - // Non-Localizable strings - namespace NonLocalizable + class NotificationUtil { - const wchar_t RunAsAdminInfoPage[] = L"https://aka.ms/powertoysDetectedElevatedHelp"; - const wchar_t ToastNotificationButtonUrl[] = L"powertoys://cant_drag_elevated_disable/"; - } + public: + NotificationUtil(); + ~NotificationUtil(); - inline void WarnIfElevationIsRequired(std::wstring title, std::wstring message, std::wstring button1, std::wstring button2) - { - using namespace NonLocalizable; + void WarnIfElevationIsRequired(std::wstring title, std::wstring message, std::wstring button1, std::wstring button2); - auto settings = PTSettingsHelper::load_general_settings(); - auto enableWarningsElevatedApps = settings.GetNamedBoolean(L"enable_warnings_elevated_apps", true); + private: + std::unique_ptr m_settingsFileWatcher; + bool m_warningsElevatedApps; + bool m_warningShown = false; - static bool warning_shown = false; - if (enableWarningsElevatedApps && !warning_shown && !is_toast_disabled(ElevatedDontShowAgainRegistryPath, ElevatedDisableIntervalInDays)) - { - std::vector actions = { - link_button{ button1, RunAsAdminInfoPage }, - link_button{ button2, ToastNotificationButtonUrl } - }; - show_toast_with_activations(message, - title, - {}, - std::move(actions)); - warning_shown = true; - } - } -} \ No newline at end of file + void ReadSettings(); + }; +} diff --git a/src/common/notifications/notifications.vcxproj b/src/common/notifications/notifications.vcxproj index 8c6808cf6c9e..b55d67e7b344 100644 --- a/src/common/notifications/notifications.vcxproj +++ b/src/common/notifications/notifications.vcxproj @@ -27,13 +27,14 @@ - + + Create diff --git a/src/common/sysinternals/Eula/Eula.txt b/src/common/sysinternals/Eula/Eula.txt new file mode 100644 index 000000000000..8efa71167cc3 --- /dev/null +++ b/src/common/sysinternals/Eula/Eula.txt @@ -0,0 +1,75 @@ +Sysinternals Software License Terms +These license terms are an agreement between Sysinternals (a wholly owned subsidiary of Microsoft Corporation) and you. Please read them. They apply to the software you are downloading from technet.microsoft.com/sysinternals, which includes the media on which you received it, if any. The terms also apply to any Sysinternals +* updates, +* supplements, +* Internet-based services, +* and support services +for this software, unless other terms accompany those items. If so, those terms apply. +BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS. IF YOU DO NOT ACCEPT THEM, DO NOT USE THE SOFTWARE. +If you comply with these license terms, you have the rights below. + +Installation and User Rights + +You may install and use any number of copies of the software on your devices. + +Scope of License + +The software is licensed, not sold. This agreement only gives you some rights to use the software. Sysinternals reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. You may not +* work around any technical limitations in the software; +* reverse engineer, decompile or disassemble the software, except and only to the extent that applicable law expressly permits, despite this limitation; +* make more copies of the software than specified in this agreement or allowed by applicable law, despite this limitation; +* publish the software for others to copy; +* rent, lease or lend the software; +* transfer the software or this agreement to any third party; or +* use the software for commercial software hosting services. + +Sensitive Information + +Please be aware that, similar to other debug tools that capture “process state” information, files saved by Sysinternals tools may include personally identifiable or other sensitive information (such as usernames, passwords, paths to files accessed, and paths to registry accessed). By using this software, you acknowledge that you are aware of this and take sole responsibility for any personally identifiable or other sensitive information provided to Microsoft or any other party through your use of the software. + +Documentation + +Any person that has valid access to your computer or internal network may copy and use the documentation for your internal, reference purposes. + +Export Restrictions + +The software is subject to United States export laws and regulations. You must comply with all domestic and international export laws and regulations that apply to the software. These laws include restrictions on destinations, end users and end use. For additional information, see www.microsoft.com/exporting . + +Support Services + +Because this software is "as is," we may not provide support services for it. + +Entire Agreement + +This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services. + +Applicable Law + +United States . If you acquired the software in the United States , Washington state law governs the interpretation of this agreement and applies to claims for breach of it, regardless of conflict of laws principles. The laws of the state where you live govern all other claims, including claims under state consumer protection laws, unfair competition laws, and in tort. +Outside the United States . If you acquired the software in any other country, the laws of that country apply. + +Legal Effect + +This agreement describes certain legal rights. You may have other rights under the laws of your country. You may also have rights with respect to the party from whom you acquired the software. This agreement does not change your rights under the laws of your country if the laws of your country do not permit it to do so. + +Disclaimer of Warranty + +The software is licensed "as-is." You bear the risk of using it. Sysinternals gives no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this agreement cannot change. To the extent permitted under your local laws, sysinternals excludes the implied warranties of merchantability, fitness for a particular purpose and non-infringement. + +Limitation on and Exclusion of Remedies and Damages + +You can recover from sysinternals and its suppliers only direct damages up to U.S. $5.00. You cannot recover any other damages, including consequential, lost profits, special, indirect or incidental damages. +This limitation applies to +* anything related to the software, services, content (including code) on third party Internet sites, or third party programs; and +* claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law. + +It also applies even if Sysinternals knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages. +Please note: As this software is distributed in Quebec , Canada , some of the clauses in this agreement are provided below in French. +Remarque : Ce logiciel étant distribué au Québec, Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en français. +EXONÉRATION DE GARANTIE. Le logiciel visé par une licence est offert « tel quel ». Toute utilisation de ce logiciel est à votre seule risque et péril. Sysinternals n'accorde aucune autre garantie expresse. Vous pouvez bénéficier de droits additionnels en vertu du droit local sur la protection dues consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualité marchande, d'adéquation à un usage particulier et d'absence de contrefaçon sont exclues. +LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES DOMMAGES. Vous pouvez obtenir de Sysinternals et de ses fournisseurs une indemnisation en cas de dommages directs uniquement à hauteur de 5,00 $ US. Vous ne pouvez prétendre à aucune indemnisation pour les autres dommages, y compris les dommages spéciaux, indirects ou accessoires et pertes de bénéfices. +Cette limitation concerne : +tout ce qui est relié au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers ; et +les réclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilité stricte, de négligence ou d'une autre faute dans la limite autorisée par la loi en vigueur. +Elle s'applique également, même si Sysinternals connaissait ou devrait connaître l'éventualité d'un tel dommage. Si votre pays n'autorise pas l'exclusion ou la limitation de responsabilité pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l'exclusion ci-dessus ne s'appliquera pas à votre égard. +EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous pourriez avoir d'autres droits prévus par les lois de votre pays. Le présent contrat ne modifie pas les droits que vous confèrent les lois de votre pays si celles-ci ne le permettent pas. diff --git a/src/common/sysinternals/Eula/eula.c b/src/common/sysinternals/Eula/eula.c new file mode 100644 index 000000000000..eaf35e9be54c --- /dev/null +++ b/src/common/sysinternals/Eula/eula.c @@ -0,0 +1,702 @@ +#pragma once + +#pragma warning( disable: 4996) + +#include +#include +#include +#include +#include +#include +#include +#include "Eula.h" +#include "dll.h" + +#define IDC_TEXT 500 +#define IDC_PRINT 501 +#define IDC_TEXT1 502 + +static const char * EulaText[] = { +"{\\rtf1\\ansi\\ansicpg1252\\deff0\\nouicompat\\deflang1033{\\fonttbl{\\f0\\fswiss\\fprq2\\fcharset0 Tahoma;}{\\f1\\fnil\\fcharset0 Calibri;}}", +"{\\colortbl ;\\red0\\green0\\blue255;\\red0\\green0\\blue0;}", +"{\\*\\generator Riched20 10.0.10240}\\viewkind4\\uc1 ", +"\\pard\\brdrb\\brdrs\\brdrw10\\brsp20 \\sb120\\sa120\\b\\f0\\fs24 SYSINTERNALS SOFTWARE LICENSE TERMS\\fs28\\par", +"\\pard\\sb120\\sa120\\b0\\fs19 These license terms are an agreement between Sysinternals (a wholly owned subsidiary of Microsoft Corporation) and you. Please read them. They apply to the software you are downloading from Sysinternals.com, which includes the media on which you received it, if any. The terms also apply to any Sysinternals\\par", +"\\pard\\fi-363\\li720\\sb120\\sa120\\tx720\\'b7\\tab updates,\\par", +"\\pard\\fi-363\\li720\\sb120\\sa120\\'b7\\tab supplements,\\par", +"\\'b7\\tab Internet-based services, and \\par", +"\\'b7\\tab support services\\par", +"\\pard\\sb120\\sa120 for this software, unless other terms accompany those items. If so, those terms apply.\\par", +"\\b BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS. IF YOU DO NOT ACCEPT THEM, DO NOT USE THE SOFTWARE.\\par", +"\\pard\\brdrt\\brdrs\\brdrw10\\brsp20 \\sb120\\sa120 If you comply with these license terms, you have the rights below.\\par", +"\\pard\\fi-357\\li357\\sb120\\sa120\\tx360\\fs20 1.\\tab\\fs19 INSTALLATION AND USE RIGHTS. \\b0 You may install and use any number of copies of the software on your devices.\\b\\par", +"\\caps\\fs20 2.\\tab\\fs19 Scope of License\\caps0 .\\b0 The software is licensed, not sold. This agreement only gives you some rights to use the software. Sysinternals reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. You may not\\b\\par", +"\\pard\\fi-363\\li720\\sb120\\sa120\\tx720\\b0\\'b7\\tab work around any technical limitations in the binary versions of the software;\\par", +"\\pard\\fi-363\\li720\\sb120\\sa120\\'b7\\tab reverse engineer, decompile or disassemble the binary versions of the software, except and only to the extent that applicable law expressly permits, despite this limitation;\\par", +"\\'b7\\tab make more copies of the software than specified in this agreement or allowed by applicable law, despite this limitation;\\par", +"\\'b7\\tab publish the software for others to copy;\\par", +"\\'b7\\tab rent, lease or lend the software;\\par", +"\\'b7\\tab transfer the software or this agreement to any third party; or\\par", +"\\'b7\\tab use the software for commercial software hosting services.\\par", +"\\pard\\fi-357\\li357\\sb120\\sa120\\tx360\\b\\fs20 3.\\tab SENSITIVE INFORMATION. \\b0 Please be aware that, similar to other debug tools that capture \\ldblquote process state\\rdblquote information, files saved by Sysinternals tools may include personally identifiable or other sensitive information (such as usernames, passwords, paths to files accessed, and paths to registry accessed). By using this software, you acknowledge that you are aware of this and take sole responsibility for any personally identifiable or other sensitive information provided to Microsoft or any other party through your use of the software.\\b\\par", +"5. \\tab\\fs19 DOCUMENTATION.\\b0 Any person that has valid access to your computer or internal network may copy and use the documentation for your internal, reference purposes.\\b\\par", +"\\caps\\fs20 6.\\tab\\fs19 Export Restrictions\\caps0 .\\b0 The software is subject to United States export laws and regulations. You must comply with all domestic and international export laws and regulations that apply to the software. These laws include restrictions on destinations, end users and end use. For additional information, see {\\cf1\\ul{\\field{\\*\\fldinst{HYPERLINK www.microsoft.com/exporting }}{\\fldrslt{www.microsoft.com/exporting}}}}\\cf1\\ul\\f0\\fs19 <{{\\field{\\*\\fldinst{HYPERLINK \"http://www.microsoft.com/exporting\"}}{\\fldrslt{http://www.microsoft.com/exporting}}}}\\f0\\fs19 >\\cf0\\ulnone .\\b\\par", +"\\caps\\fs20 7.\\tab\\fs19 SUPPORT SERVICES.\\caps0 \\b0 Because this software is \"as is, \" we may not provide support services for it.\\b\\par", +"\\caps\\fs20 8.\\tab\\fs19 Entire Agreement.\\b0\\caps0 This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.\\par", +"\\pard\\keepn\\fi-360\\li360\\sb120\\sa120\\tx360\\cf2\\b\\caps\\fs20 9.\\tab\\fs19 Applicable Law\\caps0 .\\par", +"\\pard\\fi-363\\li720\\sb120\\sa120\\tx720\\cf0\\fs20 a.\\tab\\fs19 United States.\\b0 If you acquired the software in the United States, Washington state law governs the interpretation of this agreement and applies to claims for breach of it, regardless of conflict of laws principles. The laws of the state where you live govern all other claims, including claims under state consumer protection laws, unfair competition laws, and in tort.\\b\\par", +"\\pard\\fi-363\\li720\\sb120\\sa120\\fs20 b.\\tab\\fs19 Outside the United States.\\b0 If you acquired the software in any other country, the laws of that country apply.\\b\\par", +"\\pard\\fi-357\\li357\\sb120\\sa120\\tx360\\caps\\fs20 10.\\tab\\fs19 Legal Effect.\\b0\\caps0 This agreement describes certain legal rights. You may have other rights under the laws of your country. You may also have rights with respect to the party from whom you acquired the software. This agreement does not change your rights under the laws of your country if the laws of your country do not permit it to do so.\\b\\caps\\par", +"\\fs20 11.\\tab\\fs19 Disclaimer of Warranty.\\caps0 \\caps The software is licensed \"as - is.\" You bear the risk of using it. SYSINTERNALS gives no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this agreement cannot change. To the extent permitted under your local laws, SYSINTERNALS excludes the implied warranties of merchantability, fitness for a particular purpose and non-infringement.\\par", +"\\pard\\fi-360\\li360\\sb120\\sa120\\tx360\\fs20 12.\\tab\\fs19 Limitation on and Exclusion of Remedies and Damages. You can recover from SYSINTERNALS and its suppliers only direct damages up to U.S. $5.00. You cannot recover any other damages, including consequential, lost profits, special, indirect or incidental damages.\\par", +"\\pard\\li357\\sb120\\sa120\\b0\\caps0 This limitation applies to\\par", +"\\pard\\fi-363\\li720\\sb120\\sa120\\tx720\\'b7\\tab anything related to the software, services, content (including code) on third party Internet sites, or third party programs; and\\par", +"\\pard\\fi-363\\li720\\sb120\\sa120\\'b7\\tab claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.\\par", +"\\pard\\li360\\sb120\\sa120 It also applies even if Sysinternals knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.\\par", +"\\pard\\b Please note: As this software is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in French.\\par", +"\\pard\\sb240\\lang1036 Remarque : Ce logiciel \\'e9tant distribu\\'e9 au Qu\\'e9bec, Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en fran\\'e7ais.\\par", +"\\pard\\sb120\\sa120 EXON\\'c9RATION DE GARANTIE.\\b0 Le logiciel vis\\'e9 par une licence est offert \\'ab tel quel \\'bb. Toute utilisation de ce logiciel est \\'e0 votre seule risque et p\\'e9ril. Sysinternals n'accorde aucune autre garantie expresse. Vous pouvez b\\'e9n\\'e9ficier de droits additionnels en vertu du droit local sur la protection dues consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualit\\'e9 marchande, d'ad\\'e9quation \\'e0 un usage particulier et d'absence de contrefa\\'e7on sont exclues.\\par", +"\\pard\\keepn\\sb120\\sa120\\b LIMITATION DES DOMMAGES-INT\\'c9R\\'caTS ET EXCLUSION DE RESPONSABILIT\\'c9 POUR LES DOMMAGES.\\b0 Vous pouvez obtenir de Sysinternals et de ses fournisseurs une indemnisation en cas de dommages directs uniquement \\'e0 hauteur de 5,00 $ US. Vous ne pouvez pr\\'e9tendre \\'e0 aucune indemnisation pour les autres dommages, y compris les dommages sp\\'e9ciaux, indirects ou accessoires et pertes de b\\'e9n\\'e9fices.\\par", +"\\lang1033 Cette limitation concerne :\\par", +"\\pard\\keepn\\fi-360\\li720\\sb120\\sa120\\tx720\\lang1036\\'b7\\tab tout ce qui est reli\\'e9 au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers ; et\\par", +"\\pard\\fi-363\\li720\\sb120\\sa120\\tx720\\'b7\\tab les r\\'e9clamations au titre de violation de contrat ou de garantie, ou au titre de responsabilit\\'e9 stricte, de n\\'e9gligence ou d'une autre faute dans la limite autoris\\'e9e par la loi en vigueur.\\par", +"\\pard\\sb120\\sa120 Elle s'applique \\'e9galement, m\\'eame si Sysinternals connaissait ou devrait conna\\'eetre l'\\'e9ventualit\\'e9 d'un tel dommage. Si votre pays n'autorise pas l'exclusion ou la limitation de responsabilit\\'e9 pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l'exclusion ci-dessus ne s'appliquera pas \\'e0 votre \\'e9gard.\\par", +"\\b EFFET JURIDIQUE.\\b0 Le pr\\'e9sent contrat d\\'e9crit certains droits juridiques. Vous pourriez avoir d'autres droits pr\\'e9vus par les lois de votre pays. Le pr\\'e9sent contrat ne modifie pas les droits que vous conf\\'e8rent les lois de votre pays si celles-ci ne le permettent pas.\\b\\par", +"\\pard\\b0\\fs20\\lang1033\\par", +"\\pard\\sa200\\sl276\\slmult1\\f1\\fs22\\lang9\\par", +"}", +NULL +}; + +static const wchar_t *Raw_EulaText = L"SYSINTERNALS SOFTWARE LICENSE TERMS\nThese license terms are an agreement between Sysinternals(a wholly owned subsidiary of Microsoft Corporation) and you.Please read them.They apply to the software you are downloading from technet.microsoft.com / sysinternals, which includes the media on which you received it, if any.The terms also apply to any Sysinternals\n* updates,\n*supplements,\n*Internet - based services,\n*and support services\nfor this software, unless other terms accompany those items.If so, those terms apply.\nBY USING THE SOFTWARE, YOU ACCEPT THESE TERMS.IF YOU DO NOT ACCEPT THEM, DO NOT USE THE SOFTWARE.\n\nIf you comply with these license terms, you have the rights below.\nINSTALLATION AND USER RIGHTS\nYou may install and use any number of copies of the software on your devices.\n\nSCOPE OF LICENSE\nThe software is licensed, not sold.This agreement only gives you some rights to use the software.Sysinternals reserves all other rights.Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement.In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways.You may not\n* work around any technical limitations in the software;\n*reverse engineer, decompile or disassemble the software, except and only to the extent that applicable law expressly permits, despite this limitation;\n*make more copies of the software than specified in this agreement or allowed by applicable law, despite this limitation;\n*publish the software for others to copy;\n*rent, lease or lend the software;\n*transfer the software or this agreement to any third party; or\n* use the software for commercial software hosting services.\n\nSENSITIVE INFORMATION\nPlease be aware that, similar to other debug tools that capture “process state” information, files saved by Sysinternals tools may include personally identifiable or other sensitive information(such as usernames, passwords, paths to files accessed, and paths to registry accessed).By using this software, you acknowledge that you are aware of this and take sole responsibility for any personally identifiable or other sensitive information provided to Microsoft or any other party through your use of the software.\n\nDOCUMENTATION\nAny person that has valid access to your computer or internal network may copy and use the documentation for your internal, reference purposes.\n\nEXPORT RESTRICTIONS\nThe software is subject to United States export laws and regulations.You must comply with all domestic and international export laws and regulations that apply to the software.These laws include restrictions on destinations, end users and end use.For additional information, see www.microsoft.com / exporting .\n\nSUPPORT SERVICES\nBecause this software is \"as is, \" we may not provide support services for it.\n\nENTIRE AGREEMENT\nThis agreement, and the terms for supplements, updates, Internet - based services and support services that you use, are the entire agreement for the software and support services.\n\nAPPLICABLE LAW\nUnited States.If you acquired the software in the United States, Washington state law governs the interpretation of this agreement and applies to claims for breach of it, regardless of conflict of laws principles.The laws of the state where you live govern all other claims, including claims under state consumer protection laws, unfair competition laws, and in tort.\nOutside the United States.If you acquired the software in any other country, the laws of that country apply.\n\nLEGAL EFFECT\nThis agreement describes certain legal rights.You may have other rights under the laws of your country.You may also have rights with respect to the party from whom you acquired the software.This agreement does not change your rights under the laws of your country if the laws of your country do not permit it to do so.\n\nDISCLAIMER OF WARRANTY\nThe software is licensed \"as - is.\" You bear the risk of using it.Sysinternals gives no express warranties, guarantees or conditions.You may have additional consumer rights under your local laws which this agreement cannot change.To the extent permitted under your local laws, sysinternals excludes the implied warranties of merchantability, fitness for a particular purpose and non - infringement.\n\nLIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES\nYou can recover from sysinternals and its suppliers only direct damages up to U.S.$5.00.You cannot recover any other damages, including consequential, lost profits, special, indirect or incidental damages.\nThis limitation applies to\n* anything related to the software, services, content(including code) on third party Internet sites, or third party programs; and\n* claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.\nIt also applies even if Sysinternals knew or should have known about the possibility of the damages.The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.\nPlease note : As this software is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in French.\nRemarque : Ce logiciel étant distribué au Québec, Canada, certaines des clauses dans ce contrat sont fournies ci - dessous en français.\n EXONÉRATION DE GARANTIE.Le logiciel visé par une licence est offert « tel quel ».Toute utilisation de ce logiciel est à votre seule risque et péril.Sysinternals n'accorde aucune autre garantie expresse. Vous pouvez bénéficier de droits additionnels en vertu du droit local sur la protection dues consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualité marchande, d'adéquation à un usage particulier et d'absence de contrefaçon sont exclues.\n LIMITATION DES DOMMAGES - INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES DOMMAGES.Vous pouvez obtenir de Sysinternals et de ses fournisseurs une indemnisation en cas de dommages directs uniquement à hauteur de 5, 00 $ US.Vous ne pouvez prétendre à aucune indemnisation pour les autres dommages, y compris les dommages spéciaux, indirects ou accessoires et pertes de bénéfices.\n\n Cette limitation concerne :\ntout ce qui est relié au logiciel, aux services ou au contenu(y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers; et\nles réclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilité stricte, de négligence ou d'une autre faute dans la limite autorisée par la loi en vigueur.\n\nElle s'applique également, même si Sysinternals connaissait ou devrait connaître l'éventualité d'un tel dommage. Si votre pays n'autorise pas l'exclusion ou la limitation de responsabilité pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l'exclusion ci - dessus ne s'appliquera pas à votre égard.\nEFFET JURIDIQUE.Le présent contrat décrit certains droits juridiques.Vous pourriez avoir d'autres droits prévus par les lois de votre pays. Le présent contrat ne modifie pas les droits que vous confèrent les lois de votre pays si celles-ci ne le permettent pas.\n\n"; + +BOOL IsEulaRegkeyAdded(const TCHAR * ToolName); + +static BOOL EulaCenter( HWND hwndChild, HWND hwndParent ) +{ + RECT rcChild, rcParent; + int cxChild, cyChild, cxParent, cyParent; + int cxScreen, cyScreen, xNew, yNew; + HDC hdc; + + // Get the Height and Width of the child window + GetWindowRect(hwndChild, &rcChild); + cxChild = rcChild.right - rcChild.left; + cyChild = rcChild.bottom - rcChild.top; + + // Get the Height and Width of the parent window + GetWindowRect(hwndParent, &rcParent); + cxParent = rcParent.right - rcParent.left; + cyParent = rcParent.bottom - rcParent.top; + + // Get the display limits + hdc = GetDC(hwndChild); + cxScreen = GetDeviceCaps(hdc, HORZRES); + cyScreen = GetDeviceCaps(hdc, VERTRES); + ReleaseDC(hwndChild, hdc); + + // Calculate new X position, then adjust for screen + xNew = rcParent.left + ((cxParent - cxChild) / 2); + if (xNew < 0) + { + xNew = 0; + } + else if ((xNew + cxChild) > cxScreen) + { + xNew = cxScreen - cxChild; + } + + // Calculate new Y position, then adjust for screen + yNew = rcParent.top + ((cyParent - cyChild) / 2); + if (yNew < 0) + { + yNew = 0; + } + else if ((yNew + cyChild) > cyScreen) + { + yNew = cyScreen - cyChild; + } + + // Set it, and return + return SetWindowPos(hwndChild, + NULL, + xNew, yNew, + 0, 0, + SWP_NOSIZE | SWP_NOZORDER); +} + + + +static BOOL PrintRichedit( HWND hRichedit ) +{ + // Get the printer. + PRINTDLG pd = { 0 }; + + pd.lStructSize = sizeof pd; + pd.hwndOwner = hRichedit; + pd.hInstance = GetModuleHandle(NULL); + pd.Flags = PD_RETURNDC | PD_NOPAGENUMS | PD_NOSELECTION | PD_PRINTSETUP; + if ( !PrintDlg( &pd ) ) + return FALSE; + + { + HCURSOR oldCursor = SetCursor( LoadCursor( NULL, IDC_WAIT ) ); + int nHorzRes = GetDeviceCaps( pd.hDC, HORZRES ); + int nVertRes = GetDeviceCaps( pd.hDC, VERTRES ); + int nLogPixelsX = GetDeviceCaps( pd.hDC, LOGPIXELSX ); + int nLogPixelsY = GetDeviceCaps( pd.hDC, LOGPIXELSY ); + FORMATRANGE fr = { 0 }; + DOCINFO di = { 0 }; + int TotalLength; + + // Ensure the printer DC is in MM_TEXT mode. + SetMapMode( pd.hDC, MM_TEXT ); + + // Rendering to the same DC we are measuring. + fr.hdc = pd.hDC; + fr.hdcTarget = pd.hDC; + + // Set up the page. + fr.rcPage.top = 0; + fr.rcPage.left = 0; + fr.rcPage.bottom = (nVertRes/nLogPixelsY) * 1440; + fr.rcPage.right = (nHorzRes/nLogPixelsX) * 1440; + + // Set up 1" margins all around. + fr.rc = fr.rcPage; + InflateRect( &fr.rc, -1440, -1440 ); + + // Default the range of text to print as the entire document. + fr.chrg.cpMin = 0; + fr.chrg.cpMax = -1; + + // Set up the print job (standard printing stuff here). + di.cbSize = sizeof di; + di.lpszDocName = _T("Sysinternals License"); + + // Start the document. + StartDoc( pd.hDC, &di ); + + // Find out real size of document in characters. + TotalLength = (int) SendMessage ( hRichedit, WM_GETTEXTLENGTH, 0, 0 ); + for (;;) { + int NextPage; + + // Start the page. + StartPage( pd.hDC ); + + // Print as much text as can fit on a page. The return value is + // the index of the first character on the next page. + NextPage = (int) SendMessage( hRichedit, EM_FORMATRANGE, TRUE, (LPARAM)&fr ); + + // Print last page. + EndPage( pd.hDC ); + + if ( NextPage >= TotalLength ) + break; + + // Adjust the range of characters to start printing at the first character of the next page. + fr.chrg.cpMin = NextPage; + fr.chrg.cpMax = -1; + } + + // Tell the control to release cached information. + SendMessage( hRichedit, EM_FORMATRANGE, 0, (LPARAM)NULL ); + EndDoc( pd.hDC ); + + SetCursor( oldCursor ); + } + + return TRUE; +} + +// combine all text strings into a single string +char * GetEulaText() +{ + char * text; + DWORD len = 1; + int i; + for ( i = 0; EulaText[i]; ++i ) + len += (DWORD) strlen( EulaText[i] ); + text = (char *) malloc( len ); + len = 0; + for ( i = 0; EulaText[i]; ++i ) { + strcpy( text+len, EulaText[i] ); + len += (DWORD) strlen( EulaText[i] ); + } + text[len] = 0; + return text; +} + +DWORD CALLBACK StreamCallback( DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb ) +{ + const char ** ptr = (const char **) dwCookie; + LONG_PTR len = strlen(*ptr); + if ( cb > len ) + cb = (int) len; + memcpy( pbBuff, *ptr, cb ); + *pcb = cb; + *ptr += cb; + return 0; +} + +static INT_PTR CALLBACK EulaProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + switch ( uMsg ) { + case WM_INITDIALOG: + { + TCHAR title[MAX_PATH]; + char * text = GetEulaText(); + char * textptr = text; + EDITSTREAM stream = { 0, 0, StreamCallback }; + stream.dwCookie = (DWORD_PTR) &textptr; + _stprintf_s( title, MAX_PATH, _T("%s License Agreement"), (TCHAR *) lParam ); + SetWindowText( hwndDlg, title ); + + // enter RTF into edit box + SendMessage( GetDlgItem(hwndDlg,IDC_TEXT), EM_EXLIMITTEXT, 0, 1024*1024 ); + SendMessage( GetDlgItem(hwndDlg,IDC_TEXT), EM_STREAMIN, SF_RTF, (LPARAM)&stream ); + free( text ); + } + return TRUE; + + case WM_CTLCOLORSTATIC: + // force background of read-only text window to be white + if ( (HWND)lParam == GetDlgItem( hwndDlg, IDC_TEXT) ) { + return (INT_PTR)GetSysColorBrush( COLOR_WINDOW ); + } + break; + + case WM_COMMAND: + switch( LOWORD( wParam )) { + case IDOK: + EndDialog( hwndDlg, TRUE ); + return TRUE; + case IDCANCEL: + EndDialog( hwndDlg, FALSE ); + return TRUE; + case IDC_PRINT: + PrintRichedit( GetDlgItem(hwndDlg,IDC_TEXT) ); + return TRUE; + } + break; + } + return FALSE; +} + + +static WORD * Align2( WORD * pos ) +{ + return (WORD *)(((DWORD_PTR)pos + 1) & ~((DWORD_PTR) 1)); +} +static WORD * Align4( WORD * pos ) +{ + return (WORD *)(((DWORD_PTR)pos + 3) & ~((DWORD_PTR) 3)); +} + +static int CopyText( WORD * pos, const WCHAR * text ) +{ + int len = (int) wcslen( text ) + 1; + wcscpy( (PWCHAR) pos, text ); + return len; +} + +BOOL ShowEulaInternal( const TCHAR * ToolName, DWORD eulaAccepted ) +{ +#if !defined(SYSMON_SHARED) + HKEY hKey = NULL; + TCHAR keyName[MAX_PATH]; + + _stprintf_s( keyName, MAX_PATH, _T("Software\\Sysinternals\\%s"), ToolName ); + + // + // check the regkey value if no -accepteula switch append + // + if (!eulaAccepted) + { + eulaAccepted = IsEulaRegkeyAdded(ToolName); + } +#endif + + if( !eulaAccepted ) { + if (IsIoTEdition()) + { + eulaAccepted = ShowEulaConsole(); // display Eula to console and prompt for Eula Accepted. + { + } + } + else if (IsRemoteOnlyEdition() || IsRunningRemotely()) // Nano and in remote session will not be able to accept eula from prompt + { + ShowEulaConsoleNoPrompt(); + } + else + { + DLGTEMPLATE * dlg = (DLGTEMPLATE *)LocalAlloc(LPTR, 1000); + WORD * extra = (WORD *)(dlg + 1); + DLGITEMTEMPLATE * item; + +#if defined(SYSMON_SHARED) + printf( "Displaying EULA Gui dialog box ... (use -accepteula to avoid).\n" ); +#endif + + LoadLibrarySafe(_T("Riched32.dll"), DLL_LOAD_LOCATION_SYSTEM ); // Richedit 1.0 library + + // header + dlg->style = DS_MODALFRAME | DS_CENTER | DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_NOFAILCREATE; + dlg->x = 0; + dlg->y = 0; + dlg->cx = 312; + dlg->cy = 180; + dlg->cdit = 0; // number of controls + + *extra++ = 0; // menu + *extra++ = 0; // class + extra += CopyText(extra, L"License Agreement"); + *extra++ = 8; // font size + extra += CopyText(extra, L"MS Shell Dlg"); + + // Command-line message + item = (DLGITEMTEMPLATE *)Align4(extra); + item->x = 7; + item->y = 3; + item->cx = 298; + item->cy = 14; + item->id = IDC_TEXT1; + item->style = WS_CHILD | WS_VISIBLE; + extra = (WORD *)(item + 1); + *extra++ = 0xFFFF; // class is ordinal + *extra++ = 0x0082; // class is static + extra += CopyText(extra, L"You can also use the /accepteula command-line switch to accept the EULA."); + *extra++ = 0; // creation data + dlg->cdit++; + + // Agree button + item = (DLGITEMTEMPLATE *)Align4(extra); + item->x = 201; + item->y = 159; + item->cx = 50; + item->cy = 14; + item->id = IDOK; + item->style = BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP; // | WS_DEFAULT; + extra = (WORD *)(item + 1); + *extra++ = 0xFFFF; // class is ordinal + *extra++ = 0x0080; // class is button + extra += CopyText(extra, L"&Agree"); + *extra++ = 0; // creation data + dlg->cdit++; + + // Decline button + item = (DLGITEMTEMPLATE *)Align4(extra); + item->x = 255; + item->y = 159; + item->cx = 50; + item->cy = 14; + item->id = IDCANCEL; + item->style = BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP; + extra = (WORD *)(item + 1); + *extra++ = 0xFFFF; // class is ordinal + *extra++ = 0x0080; // class is button + extra += CopyText(extra, L"&Decline"); + *extra++ = 0; // creation data + dlg->cdit++; + + // Print button + item = (DLGITEMTEMPLATE *)Align4(extra); + item->x = 7; + item->y = 159; + item->cx = 50; + item->cy = 14; + item->id = IDC_PRINT; + item->style = BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP; + extra = (WORD *)(item + 1); + *extra++ = 0xFFFF; // class is ordinal + *extra++ = 0x0080; // class is button + extra += CopyText(extra, L"&Print"); + *extra++ = 0; // creation data + dlg->cdit++; + + // Edit box + item = (DLGITEMTEMPLATE *)Align4(extra); + item->x = 7; + item->y = 14; + item->cx = 298; + item->cy = 140; + item->id = IDC_TEXT; + item->style = WS_BORDER | ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_TABSTOP; + extra = (WORD *)(item + 1); + extra += CopyText(extra, L"RICHEDIT"); + extra += CopyText(extra, L"&Decline"); + *extra++ = 0; // creation data + dlg->cdit++; + + eulaAccepted = (DWORD)DialogBoxIndirectParam(NULL, dlg, NULL, EulaProc, (LPARAM)ToolName); + LocalFree(dlg); + } + } +#if !defined(SYSMON_SHARED) + if ( eulaAccepted ) { + if (RegCreateKey(HKEY_CURRENT_USER, keyName, &hKey) == ERROR_SUCCESS) { + RegSetValueEx(hKey, _T("EulaAccepted"), 0, REG_DWORD, (BYTE *)&eulaAccepted, sizeof(eulaAccepted)); + RegCloseKey(hKey); + } + } +#endif + + return eulaAccepted != 0; +} + +BOOL ShowEulaW( const TCHAR * ToolName, int *argc, PWCHAR argv[] ) +{ + DWORD eulaAccepted = 0; + int i; + + if ( argc == NULL || argv == NULL ) { + typedef LPWSTR * (WINAPI * type_CommandLineToArgvW)( LPCWSTR lpCmdLine, int *pNumArgs ); + type_CommandLineToArgvW pCommandLineToArgvW = (type_CommandLineToArgvW) GetProcAddress( LoadLibrarySafe(_T("Shell32.dll"), DLL_LOAD_LOCATION_SYSTEM), "CommandLineToArgvW" ); + if ( pCommandLineToArgvW ) { + static int argc2; + argc = &argc2; + argv = (*pCommandLineToArgvW)( GetCommandLineW(), argc ); + } else { + argc = NULL; + } + } + + + // + // See if its accepted via command line switch + // + if( argc ) { + + for( i = 0; i < *argc; i++ ) { + + eulaAccepted = (!_wcsicmp( argv[i], L"/accepteula") || + !_wcsicmp( argv[i], L"-accepteula")); + if( eulaAccepted ) { + + for( ; i < *argc - 1; i++ ) { + + argv[i] = argv[i+1]; + } + (*argc)--; + break; + } + } + } + if( ShowEulaInternal( ToolName, eulaAccepted )) { + + eulaAccepted = 1; + } + return eulaAccepted != 0; +} + + +BOOL ShowEula( const TCHAR * ToolName, int *argc, PTCHAR argv[] ) +{ + DWORD eulaAccepted = 0; + int i; + + if ( argc == NULL || argv == NULL ) { + return ShowEulaW( ToolName, NULL, NULL ); + } + + // + // See if its accepted via command line switch + // + if( argc ) { + + for( i = 0; i < *argc; i++ ) { + + eulaAccepted = (!_tcsicmp( argv[i], _T("/accepteula")) || + !_tcsicmp( argv[i], _T("-accepteula"))); + if( eulaAccepted ) { + + for( ; i < *argc - 1; i++ ) { + + argv[i] = argv[i+1]; + } + (*argc)--; + break; + } + } + } + if( ShowEulaInternal( ToolName, eulaAccepted )) { + + eulaAccepted = 1; + } + return eulaAccepted != 0; +} + +// Determine whether we are on the IoT SKU by looking at the ProductName. +BOOL IsIoTEdition() +{ + HKEY hKey = NULL; + wchar_t ProductName[MAX_PATH]; + BOOL bRet = FALSE; // assume "not" IoT Edition + DWORD dwSize = sizeof(ProductName); + DWORD type = 0; + + if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\windows nt\\currentversion"), &hKey)) + { + if (ERROR_SUCCESS == RegQueryValueExW(hKey, L"ProductName", 0, &type, (LPBYTE)ProductName, &dwSize)) + { + if (!_wcsicmp(L"iotuap", ProductName)) + bRet = TRUE; + } + RegCloseKey(hKey); + } + + return bRet; +} + +// Determine whether we are on the remote only edition, where we cannot prompt for user input. +BOOL IsRemoteOnlyEdition() +{ + HKEY hKey = NULL; + DWORD dwNanoServer = 0; + BOOL bRet = FALSE; + DWORD dwSize = sizeof(dwNanoServer); + DWORD type = 0; + + // Currently Nano is the only remote only edtion. + if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\Server\\ServerLevels"), &hKey)) + { + if (ERROR_SUCCESS == RegQueryValueEx(hKey, _T("NanoServer"), 0, &type, (LPBYTE)&dwNanoServer, &dwSize)) + { + if (type == REG_DWORD && dwNanoServer == 1) + bRet = TRUE; + } + RegCloseKey(hKey); + } + + return bRet; +} + +BOOL IsRunningRemotely() +{ + // running from a remote session will not support input interaction + DWORD fileType = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)); + return fileType == FILE_TYPE_PIPE; +} + +DWORD ShowEulaConsole() +{ + DWORD dwRet = 0; + char ch; + BOOLEAN eulaAcknowledged = FALSE; + + wprintf(Raw_EulaText); + + while( eulaAcknowledged != TRUE ) + { + printf("Accept Eula (Y/N)?"); + ch = (char) _getch(); + printf("%c\n", ch); + if ('y' == ch || 'Y' == ch) + { + dwRet = 1; // EULA Accepted. + eulaAcknowledged = TRUE; + } + + if ('n' == ch || 'N' == ch) + { + // EULA not accepted. + eulaAcknowledged = TRUE; + } + } + return dwRet; +} + +void ShowEulaConsoleNoPrompt() +{ + wprintf_s(L"%ls", Raw_EulaText); + wprintf_s(L"This is the first run of this program. You must accept EULA to continue.\n"); + wprintf_s(L"Use -accepteula to accept EULA.\n\n"); + + // exit here to avoid printing the misleading "Eula declined". + exit(1); +} + +BOOL IsEulaAcceptedValueExist(HKEY hKeyRoot, LPCTSTR lpSubKey) +{ + HKEY hKey = NULL; + DWORD length; + DWORD eulaAccepted = 0; + DWORD ret; + + // + // check if it is set by external channel for all tools + // assuming external channel do not set to WOW6432Node + // + if (RegOpenKeyEx(hKeyRoot, lpSubKey, 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS) + { + length = sizeof(eulaAccepted); + ret = RegQueryValueEx(hKey, _T("EulaAccepted"), NULL, NULL, (LPBYTE)&eulaAccepted, &length); + RegCloseKey(hKey); + + if (ret == ERROR_SUCCESS && eulaAccepted) + { + return TRUE; + } + } + + return FALSE; +} + +BOOL IsEulaRegkeyAdded(const TCHAR * ToolName) +{ + TCHAR perToolRegKey[MAX_PATH]; + PTCHAR suiteRegKey = _T("Software\\Sysinternals"); + + _stprintf_s(perToolRegKey, MAX_PATH, _T("%s\\%s"), suiteRegKey, ToolName); + + // + // check if it is set by external channel for all tools + // assuming external channel do not set to WOW6432Node + // + if (IsEulaAcceptedValueExist(HKEY_LOCAL_MACHINE, suiteRegKey) || + IsEulaAcceptedValueExist(HKEY_CURRENT_USER, suiteRegKey)) + { + return TRUE; + } + + // + // per tool check + // + if (IsEulaAcceptedValueExist(HKEY_CURRENT_USER, perToolRegKey)) + { + return TRUE; + } + + return FALSE; +} + +BOOL IsEulaSwitchAppended(int *argc, PTCHAR argv[]) +{ + DWORD eulaAccepted = 0; + int i; + + // + // See if its accepted via command line switch + // + if (*argc > 1) { + for (i = 1; i < *argc; i++) { + eulaAccepted = (!_tcsicmp(argv[i], _T("/accepteula")) || + !_tcsicmp(argv[i], _T("-accepteula"))); + if (eulaAccepted) { + break; + } + } + } + + return eulaAccepted; +} + +// +// Determine if Eula is accepted, either already have regkey added +// or have -accepteula switch appended +// +BOOL IsEulaAccepted(const TCHAR * ToolName, int *argc, PTCHAR argv[]) +{ + return IsEulaRegkeyAdded(ToolName) || IsEulaSwitchAppended(argc, argv); +} diff --git a/src/common/sysinternals/Eula/eula.h b/src/common/sysinternals/Eula/eula.h new file mode 100644 index 000000000000..450031583e95 --- /dev/null +++ b/src/common/sysinternals/Eula/eula.h @@ -0,0 +1,17 @@ +#ifdef __cplusplus +extern "C" { +#endif + + +BOOL ShowEulaW( const TCHAR * ToolName, int *argc, PWCHAR argv[] ); +BOOL ShowEula( const TCHAR * ToolName, int *argc, TCHAR *argv[] ); +DWORD ShowEulaConsole(); +void ShowEulaConsoleNoPrompt(); +BOOL IsIoTEdition(); +BOOL IsRemoteOnlyEdition(); +BOOL IsRunningRemotely(); +BOOL IsEulaAccepted(const TCHAR * ToolName, int *argc, PTCHAR argv[]); + +#ifdef __cplusplus +} +#endif diff --git a/src/common/sysinternals/Eula/eula.rtf b/src/common/sysinternals/Eula/eula.rtf new file mode 100644 index 000000000000..4f8c495bf30d --- /dev/null +++ b/src/common/sysinternals/Eula/eula.rtf @@ -0,0 +1,76 @@ +{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Tahoma;}{\f1\fnil\fcharset0 Calibri;}} +{\colortbl ;\red0\green0\blue255;\red0\green0\blue0;} +{\*\generator Riched20 10.0.10240}\viewkind4\uc1 +\pard\brdrb\brdrs\brdrw10\brsp20 \sb120\sa120\b\f0\fs24 SYSINTERNALS SOFTWARE LICENSE TERMS\fs28\par + +\pard\sb120\sa120\b0\fs19 These license terms are an agreement between Sysinternals (a wholly owned subsidiary of Microsoft Corporation) and you. Please read them. They apply to the software you are downloading from Sysinternals.com, which includes the media on which you received it, if any. The terms also apply to any Sysinternals\par + +\pard\fi-363\li720\sb120\sa120\tx720\'b7\tab updates,\par + +\pard\fi-363\li720\sb120\sa120\'b7\tab supplements,\par +\'b7\tab Internet-based services, and \par +\'b7\tab support services\par + +\pard\sb120\sa120 for this software, unless other terms accompany those items. If so, those terms apply.\par +\b BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS. IF YOU DO NOT ACCEPT THEM, DO NOT USE THE SOFTWARE.\par + +\pard\brdrt\brdrs\brdrw10\brsp20 \sb120\sa120 If you comply with these license terms, you have the rights below.\par + +\pard\fi-357\li357\sb120\sa120\tx360\fs20 1.\tab\fs19 INSTALLATION AND USE RIGHTS. \b0 You may install and use any number of copies of the software on your devices.\b\par +\caps\fs20 2.\tab\fs19 Scope of License\caps0 .\b0 The software is licensed, not sold. This agreement only gives you some rights to use the software. Sysinternals reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. You may not\b\par + +\pard\fi-363\li720\sb120\sa120\tx720\b0\'b7\tab work around any technical limitations in the binary versions of the software;\par + +\pard\fi-363\li720\sb120\sa120\'b7\tab reverse engineer, decompile or disassemble the binary versions of the software, except and only to the extent that applicable law expressly permits, despite this limitation;\par +\'b7\tab make more copies of the software than specified in this agreement or allowed by applicable law, despite this limitation;\par +\'b7\tab publish the software for others to copy;\par +\'b7\tab rent, lease or lend the software;\par +\'b7\tab transfer the software or this agreement to any third party; or\par +\'b7\tab use the software for commercial software hosting services.\par + +\pard\fi-357\li357\sb120\sa120\tx360\b\fs20 3.\tab SENSITIVE INFORMATION. \b0 Please be aware that, similar to other debug tools that capture \ldblquote process state\rdblquote information, files saved by Sysinternals tools may include personally identifiable or other sensitive information (such as usernames, passwords, paths to files accessed, and paths to registry accessed). By using this software, you acknowledge that you are aware of this and take sole responsibility for any personally identifiable or other sensitive information provided to Microsoft or any other party through your use of the software.\b\par +5. \tab\fs19 DOCUMENTATION.\b0 Any person that has valid access to your computer or internal network may copy and use the documentation for your internal, reference purposes.\b\par +\caps\fs20 6.\tab\fs19 Export Restrictions\caps0 .\b0 The software is subject to United States export laws and regulations. You must comply with all domestic and international export laws and regulations that apply to the software. These laws include restrictions on destinations, end users and end use. For additional information, see {\cf1\ul{\field{\*\fldinst{HYPERLINK www.microsoft.com/exporting }}{\fldrslt{www.microsoft.com/exporting}}}}\cf1\ul\f0\fs19 <{{\field{\*\fldinst{HYPERLINK "http://www.microsoft.com/exporting"}}{\fldrslt{http://www.microsoft.com/exporting}}}}\f0\fs19 >\cf0\ulnone .\b\par +\caps\fs20 7.\tab\fs19 SUPPORT SERVICES.\caps0 \b0 Because this software is "as is," we may not provide support services for it.\b\par +\caps\fs20 8.\tab\fs19 Entire Agreement.\b0\caps0 This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.\par + +\pard\keepn\fi-360\li360\sb120\sa120\tx360\cf2\b\caps\fs20 9.\tab\fs19 Applicable Law\caps0 .\par + +\pard\fi-363\li720\sb120\sa120\tx720\cf0\fs20 a.\tab\fs19 United States.\b0 If you acquired the software in the United States, Washington state law governs the interpretation of this agreement and applies to claims for breach of it, regardless of conflict of laws principles. The laws of the state where you live govern all other claims, including claims under state consumer protection laws, unfair competition laws, and in tort.\b\par + +\pard\fi-363\li720\sb120\sa120\fs20 b.\tab\fs19 Outside the United States.\b0 If you acquired the software in any other country, the laws of that country apply.\b\par + +\pard\fi-357\li357\sb120\sa120\tx360\caps\fs20 10.\tab\fs19 Legal Effect.\b0\caps0 This agreement describes certain legal rights. You may have other rights under the laws of your country. You may also have rights with respect to the party from whom you acquired the software. This agreement does not change your rights under the laws of your country if the laws of your country do not permit it to do so.\b\caps\par +\fs20 11.\tab\fs19 Disclaimer of Warranty.\caps0 \caps The software is licensed "as-is." You bear the risk of using it. SYSINTERNALS gives no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this agreement cannot change. To the extent permitted under your local laws, SYSINTERNALS excludes the implied warranties of merchantability, fitness for a particular purpose and non-infringement.\par + +\pard\fi-360\li360\sb120\sa120\tx360\fs20 12.\tab\fs19 Limitation on and Exclusion of Remedies and Damages. You can recover from SYSINTERNALS and its suppliers only direct damages up to U.S. $5.00. You cannot recover any other damages, including consequential, lost profits, special, indirect or incidental damages.\par + +\pard\li357\sb120\sa120\b0\caps0 This limitation applies to\par + +\pard\fi-363\li720\sb120\sa120\tx720\'b7\tab anything related to the software, services, content (including code) on third party Internet sites, or third party programs; and\par + +\pard\fi-363\li720\sb120\sa120\'b7\tab claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.\par + +\pard\li360\sb120\sa120 It also applies even if Sysinternals knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.\par + +\pard\b Please note: As this software is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in French.\par + +\pard\sb240\lang1036 Remarque : Ce logiciel \'e9tant distribu\'e9 au Qu\'e9bec, Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en fran\'e7ais.\par + +\pard\sb120\sa120 EXON\'c9RATION DE GARANTIE.\b0 Le logiciel vis\'e9 par une licence est offert \'ab tel quel \'bb. Toute utilisation de ce logiciel est \'e0 votre seule risque et p\'e9ril. Sysinternals n'accorde aucune autre garantie expresse. Vous pouvez b\'e9n\'e9ficier de droits additionnels en vertu du droit local sur la protection dues consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualit\'e9 marchande, d'ad\'e9quation \'e0 un usage particulier et d'absence de contrefa\'e7on sont exclues.\par + +\pard\keepn\sb120\sa120\b LIMITATION DES DOMMAGES-INT\'c9R\'caTS ET EXCLUSION DE RESPONSABILIT\'c9 POUR LES DOMMAGES.\b0 Vous pouvez obtenir de Sysinternals et de ses fournisseurs une indemnisation en cas de dommages directs uniquement \'e0 hauteur de 5,00 $ US. Vous ne pouvez pr\'e9tendre \'e0 aucune indemnisation pour les autres dommages, y compris les dommages sp\'e9ciaux, indirects ou accessoires et pertes de b\'e9n\'e9fices.\par +\lang1033 Cette limitation concerne :\par + +\pard\keepn\fi-360\li720\sb120\sa120\tx720\lang1036\'b7\tab tout ce qui est reli\'e9 au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers ; et\par + +\pard\fi-363\li720\sb120\sa120\tx720\'b7\tab les r\'e9clamations au titre de violation de contrat ou de garantie, ou au titre de responsabilit\'e9 stricte, de n\'e9gligence ou d'une autre faute dans la limite autoris\'e9e par la loi en vigueur.\par + +\pard\sb120\sa120 Elle s'applique \'e9galement, m\'eame si Sysinternals connaissait ou devrait conna\'eetre l'\'e9ventualit\'e9 d'un tel dommage. Si votre pays n'autorise pas l'exclusion ou la limitation de responsabilit\'e9 pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l'exclusion ci-dessus ne s'appliquera pas \'e0 votre \'e9gard.\par +\b EFFET JURIDIQUE.\b0 Le pr\'e9sent contrat d\'e9crit certains droits juridiques. Vous pourriez avoir d'autres droits pr\'e9vus par les lois de votre pays. Le pr\'e9sent contrat ne modifie pas les droits que vous conf\'e8rent les lois de votre pays si celles-ci ne le permettent pas.\b\par + +\pard\b0\fs20\lang1033\par + +\pard\sa200\sl276\slmult1\f1\fs22\lang9\par +} + \ No newline at end of file diff --git a/src/common/sysinternals/WindowsVersions.cpp b/src/common/sysinternals/WindowsVersions.cpp new file mode 100644 index 000000000000..6b12d86d2a80 --- /dev/null +++ b/src/common/sysinternals/WindowsVersions.cpp @@ -0,0 +1,24 @@ +#include + +#include "WindowsVersions.h" + +// Declared in wdm.h +typedef NTSYSAPI NTSTATUS (NTAPI *RtlGetVersionType)( PRTL_OSVERSIONINFOW ); + +DWORD GetWindowsBuild( DWORD* revision ) +{ + if( revision ) { + + DWORD size = sizeof( *revision ); + if( RegGetValueW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", L"UBR", RRF_RT_REG_DWORD, NULL, revision, &size ) != ERROR_SUCCESS ) { + + *revision = 0; + } + } + + RtlGetVersionType pRtlGetVersion = reinterpret_cast(GetProcAddress( GetModuleHandleW( L"ntdll.dll" ), "RtlGetVersion" )); + + RTL_OSVERSIONINFOW version; + pRtlGetVersion( &version ); + return version.dwBuildNumber; +} diff --git a/src/common/sysinternals/WindowsVersions.h b/src/common/sysinternals/WindowsVersions.h new file mode 100644 index 000000000000..de06ab7e562f --- /dev/null +++ b/src/common/sysinternals/WindowsVersions.h @@ -0,0 +1,32 @@ +//---------------------------------------------------------------------- +// +// WindowsVersions.h +// +// Provides helpers for Windows builds and versions. +// +//---------------------------------------------------------------------- + +#pragma once + +#define BUILD_WINDOWS_SERVER_2008 6003 +#define BUILD_WINDOWS_SERVER_2008_R2 7601 +#define BUILD_WINDOWS_SERVER_2012 9200 +#define BUILD_WINDOWS_8_1 9600 +#define BUILD_WINDOWS_SERVER_2012_R2 9600 +#define BUILD_WINDOWS_10_1507 10240 +#define BUILD_WINDOWS_10_1607 14393 +#define BUILD_WINDOWS_SERVER_2016 14393 +#define BUILD_WINDOWS_10_1809 17763 +#define BUILD_WINDOWS_SERVER_2019 17763 +#define BUILD_WINDOWS_10_1903 18362 +#define BUILD_WINDOWS_10_1909 18363 +#define BUILD_WINDOWS_10_2004 19041 +#define BUILD_WINDOWS_10_20H2 19042 +#define BUILD_WINDOWS_SERVER_20H2 19042 +#define BUILD_WINDOWS_10_21H1 19043 +#define BUILD_WINDOWS_10_21H2 19044 +#define BUILD_WINDOWS_SERVER_2022 20348 +#define BUILD_WINDOWS_11_21H2 22000 +#define BUILD_WINDOWS_11_22H2 22621 + +DWORD GetWindowsBuild( DWORD* revision ); diff --git a/src/common/sysinternals/dll.c b/src/common/sysinternals/dll.c new file mode 100644 index 000000000000..8498db813c18 --- /dev/null +++ b/src/common/sysinternals/dll.c @@ -0,0 +1,74 @@ +//=========================================================================-== +// +// dll.c +// +// DLL support functions +// +//============================================================================ + +#include +#include +#include +#include +#include "dll.h" + +#ifndef LOAD_LIBRARY_SEARCH_SYSTEM32 + #define LOAD_LIBRARY_SEARCH_SYSTEM32 0x800 +#endif + + +//=========================================================================-== +// +// ExtendedFlagsSupported +// +// Returns TRUE if running on Windows 7 or later and FALSE otherwise +// +//============================================================================ +static BOOLEAN ExtendedFlagsSupported() +{ + OSVERSIONINFO osInfo; + BOOLEAN rc = FALSE; + + ZeroMemory(&osInfo, sizeof(OSVERSIONINFO)); + osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + +#pragma warning ( disable : 4996 ) // deprecated in favour of version helper functions which we can't use + + if (GetVersionEx(&osInfo) && (osInfo.dwMajorVersion > 6 || (osInfo.dwMajorVersion == 6 && osInfo.dwMinorVersion > 0))) + rc = TRUE; + +#pragma warning ( default : 4996 ) + + return rc; +} + +//=========================================================================-== +// +// LoadLibrarySafe +// +// Loads a DLL from the system folder in a way that mitigates DLL spoofing / +// side-loading attacks +// +//============================================================================ +HMODULE LoadLibrarySafe(LPCTSTR libraryName, DLL_LOAD_LOCATION location) +{ + HMODULE hMod = NULL; + + if (NULL == libraryName || location <= DLL_LOAD_LOCATION_MIN || location >= DLL_LOAD_LOCATION_MAX) { + + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + // LOAD_LIBRARY_SEARCH_SYSTEM32 is only supported on Window 7 or later. On earlier SKUs we could use a fully + // qualified path to the system folder but specifying a path causes Ldr to skip SxS file redirection. This can + // cause the wrong library to be loaded if the application is using a manifest that defines a specific version + // of Microsoft.Windows.Common-Controls when loading comctl32.dll + if (DLL_LOAD_LOCATION_SYSTEM == location) { + + DWORD flags = ExtendedFlagsSupported() ? LOAD_LIBRARY_SEARCH_SYSTEM32 : 0; + hMod = LoadLibraryEx(libraryName, NULL, flags); + } + + return hMod; +} diff --git a/src/common/sysinternals/dll.h b/src/common/sysinternals/dll.h new file mode 100644 index 000000000000..80c60a72ca07 --- /dev/null +++ b/src/common/sysinternals/dll.h @@ -0,0 +1,26 @@ +//=========================================================================-== +// +// dll.h +// +// DLL support functions +// +//============================================================================ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + + typedef enum + { + DLL_LOAD_LOCATION_MIN = 0, + DLL_LOAD_LOCATION_SYSTEM = 1, + DLL_LOAD_LOCATION_MAX + } DLL_LOAD_LOCATION, *PDLL_LOAD_LOCATION; + + HMODULE LoadLibrarySafe(LPCTSTR libraryName, DLL_LOAD_LOCATION location); + +#ifdef __cplusplus +} +#endif + diff --git a/src/common/utils/clean_video_conference.h b/src/common/utils/clean_video_conference.h new file mode 100644 index 000000000000..f90a3ad1ee2b --- /dev/null +++ b/src/common/utils/clean_video_conference.h @@ -0,0 +1,18 @@ +#pragma once + +// Video Conference Mute was a utility we deprecated. However, this required a manual user disable of the module to remove the camera registration, so we include the disable code here to be able to clean up. +void clean_video_conference() +{ + // 31AD75E9-8C3A-49C8-B9ED-5880D6B4A764 is the CLSID GUID for the 64 video conference mute driver. + // 31AD75E9-8C3A-49C8-B9ED-5880D6B4A732 is the CLSID GUID for the 32 video conference mute driver. + // 860BB310-5D01-11D0-BD3B-00A0C911CE86 is the CLSID GUID for CLSID_VideoInputDeviceCategory. + + // Unregister the 64 bit driver CLSID: + RegDeleteTreeW(HKEY_CLASSES_ROOT, L"CLSID\\{31AD75E9-8C3A-49C8-B9ED-5880D6B4A764}"); + // Unregister the 64 bit driver CLSID from Video Input Devices: + RegDeleteTreeW(HKEY_CLASSES_ROOT, L"CLSID\\{860BB310-5D01-11D0-BD3B-00A0C911CE86}\\Instance\\{31AD75E9-8C3A-49C8-B9ED-5880D6B4A764}"); + // Unregister the 32 bit driver CLSID: + RegDeleteTreeW(HKEY_LOCAL_MACHINE, L"Software\\WOW6432Node\\Classes\\CLSID\\{31AD75E9-8C3A-49C8-B9ED-5880D6B4A732}"); + // Unregister the 32 bit driver CLSID from Video Input Devices: + RegDeleteTreeW(HKEY_LOCAL_MACHINE, L"Software\\WOW6432Node\\Classes\\CLSID\\{860BB310-5D01-11D0-BD3B-00A0C911CE86}\\Instance\\{31AD75E9-8C3A-49C8-B9ED-5880D6B4A732}"); +} diff --git a/src/common/utils/gpo.h b/src/common/utils/gpo.h index 599389c1b6cd..4a1984c7507e 100644 --- a/src/common/utils/gpo.h +++ b/src/common/utils/gpo.h @@ -54,7 +54,7 @@ namespace powertoys_gpo { const std::wstring POLICY_CONFIGURE_ENABLED_TEXT_EXTRACTOR = L"ConfigureEnabledUtilityTextExtractor"; const std::wstring POLICY_CONFIGURE_ENABLED_ADVANCED_PASTE = L"ConfigureEnabledUtilityAdvancedPaste"; const std::wstring POLICY_CONFIGURE_ENABLED_CMD_PAL = L"ConfigureEnabledUtilityCmdPal"; - const std::wstring POLICY_CONFIGURE_ENABLED_VIDEO_CONFERENCE_MUTE = L"ConfigureEnabledUtilityVideoConferenceMute"; + const std::wstring POLICY_CONFIGURE_ENABLED_ZOOM_IT = L"ConfigureEnabledUtilityZoomIt"; const std::wstring POLICY_CONFIGURE_ENABLED_REGISTRY_PREVIEW = L"ConfigureEnabledUtilityRegistryPreview"; const std::wstring POLICY_CONFIGURE_ENABLED_MOUSE_WITHOUT_BORDERS = L"ConfigureEnabledUtilityMouseWithoutBorders"; const std::wstring POLICY_CONFIGURE_ENABLED_PEEK = L"ConfigureEnabledUtilityPeek"; @@ -420,9 +420,9 @@ namespace powertoys_gpo { return getUtilityEnabledValue(POLICY_CONFIGURE_ENABLED_WORKSPACES); } - inline gpo_rule_configured_t getConfiguredVideoConferenceMuteEnabledValue() + inline gpo_rule_configured_t getConfiguredZoomItEnabledValue() { - return getUtilityEnabledValue(POLICY_CONFIGURE_ENABLED_VIDEO_CONFERENCE_MUTE); + return getUtilityEnabledValue(POLICY_CONFIGURE_ENABLED_ZOOM_IT); } inline gpo_rule_configured_t getConfiguredMouseWithoutBordersEnabledValue() diff --git a/src/common/version/version.vcxproj b/src/common/version/version.vcxproj index f6ad515137eb..b045d8f5a58d 100644 --- a/src/common/version/version.vcxproj +++ b/src/common/version/version.vcxproj @@ -10,7 +10,7 @@ - + Debug diff --git a/src/dsc/Microsoft.PowerToys.Configure/examples/disableAllModules.dsc.yaml b/src/dsc/Microsoft.PowerToys.Configure/examples/disableAllModules.dsc.yaml index 5324df75ea0d..92986e81071e 100644 --- a/src/dsc/Microsoft.PowerToys.Configure/examples/disableAllModules.dsc.yaml +++ b/src/dsc/Microsoft.PowerToys.Configure/examples/disableAllModules.dsc.yaml @@ -63,8 +63,6 @@ properties: Enabled: false ShortcutGuide: Enabled: false - VideoConference: - Enabled: false MeasureTool: Enabled: false Hosts: diff --git a/src/dsc/Microsoft.PowerToys.Configure/examples/enableAllModules.dsc.yaml b/src/dsc/Microsoft.PowerToys.Configure/examples/enableAllModules.dsc.yaml index 5fa895ddfd32..5ff4dcfe7192 100644 --- a/src/dsc/Microsoft.PowerToys.Configure/examples/enableAllModules.dsc.yaml +++ b/src/dsc/Microsoft.PowerToys.Configure/examples/enableAllModules.dsc.yaml @@ -63,8 +63,6 @@ properties: Enabled: true ShortcutGuide: Enabled: true - VideoConference: - Enabled: true MeasureTool: Enabled: true Hosts: diff --git a/src/gpo/assets/PowerToys.admx b/src/gpo/assets/PowerToys.admx index ed2b214dc0ad..2aef2d3768a7 100644 --- a/src/gpo/assets/PowerToys.admx +++ b/src/gpo/assets/PowerToys.admx @@ -1,11 +1,11 @@ - + - + @@ -23,6 +23,8 @@ + + @@ -45,6 +47,9 @@ + + + @@ -451,8 +456,18 @@ + + + + + + + + + + - + diff --git a/src/gpo/assets/en-US/PowerToys.adml b/src/gpo/assets/en-US/PowerToys.adml index 7a8f037eee5c..68da74c6debb 100644 --- a/src/gpo/assets/en-US/PowerToys.adml +++ b/src/gpo/assets/en-US/PowerToys.adml @@ -1,7 +1,7 @@ - + PowerToys PowerToys @@ -13,6 +13,7 @@ Mouse Without Borders General settings New+ + Deprecated policies PowerToys version 0.64.0 or later PowerToys version 0.68.0 or later @@ -29,6 +30,8 @@ PowerToys version 0.84.0 or later PowerToys version 0.85.0 or later PowerToys version 0.86.0 or later + PowerToys version 0.88.0 or later + From PowerToys version 0.64.0 until PowerToys version 0.87.1 This policy configures the enabled state for all PowerToys utilities. @@ -245,6 +248,7 @@ If you don't configure this policy, the user takes control over the setting and Shortcut Guide: Configure enabled state Text Extractor: Configure enabled state Video Conference Mute: Configure enabled state + Zoom It: Configure enabled state Disable per-user installation Disable automatic downloads Do not show the release notes after updates diff --git a/src/modules/AdvancedPaste/AdvancedPaste/Helpers/AIServiceFormatEvent.cs b/src/modules/AdvancedPaste/AdvancedPaste/Helpers/AIServiceFormatEvent.cs new file mode 100644 index 000000000000..1ab58bf26943 --- /dev/null +++ b/src/modules/AdvancedPaste/AdvancedPaste/Helpers/AIServiceFormatEvent.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Text.Json; +using AdvancedPaste.Models.KernelQueryCache; +using AdvancedPaste.SerializationContext; +using AdvancedPaste.Telemetry; + +namespace AdvancedPaste.Helpers +{ + public class AIServiceFormatEvent + { + public AIServiceFormatEvent(AdvancedPasteSemanticKernelFormatEvent semanticKernelFormatEvent) + { + CacheUsed = semanticKernelFormatEvent.CacheUsed; + IsSavedQuery = semanticKernelFormatEvent.IsSavedQuery; + PromptTokens = semanticKernelFormatEvent.PromptTokens; + CompletionTokens = semanticKernelFormatEvent.CompletionTokens; + ModelName = semanticKernelFormatEvent.ModelName; + ActionChain = semanticKernelFormatEvent.ActionChain; + } + + public AIServiceFormatEvent(AdvancedPasteGenerateCustomFormatEvent generateCustomFormatEvent) + { + PromptTokens = generateCustomFormatEvent.PromptTokens; + CompletionTokens = generateCustomFormatEvent.CompletionTokens; + ModelName = generateCustomFormatEvent.ModelName; + } + + public bool IsSavedQuery { get; set; } + + public bool CacheUsed { get; set; } + + public int PromptTokens { get; set; } + + public int CompletionTokens { get; set; } + + public string ModelName { get; set; } + + public string ActionChain { get; set; } + + public string ToJsonString() => JsonSerializer.Serialize(this, SourceGenerationContext.Default.AIServiceFormatEvent); + } +} diff --git a/src/modules/AdvancedPaste/AdvancedPaste/Helpers/NativeMethods.cs b/src/modules/AdvancedPaste/AdvancedPaste/Helpers/NativeMethods.cs index 8ddb1e7778bf..a28626ca1f21 100644 --- a/src/modules/AdvancedPaste/AdvancedPaste/Helpers/NativeMethods.cs +++ b/src/modules/AdvancedPaste/AdvancedPaste/Helpers/NativeMethods.cs @@ -18,7 +18,7 @@ internal struct INPUT internal static int Size { - get { return Marshal.SizeOf(typeof(INPUT)); } + get { return Marshal.SizeOf(); } } } diff --git a/src/modules/AdvancedPaste/AdvancedPaste/Helpers/UserSettings.cs b/src/modules/AdvancedPaste/AdvancedPaste/Helpers/UserSettings.cs index 8d5f51314db5..70a4cf0f9e4d 100644 --- a/src/modules/AdvancedPaste/AdvancedPaste/Helpers/UserSettings.cs +++ b/src/modules/AdvancedPaste/AdvancedPaste/Helpers/UserSettings.cs @@ -16,7 +16,7 @@ namespace AdvancedPaste.Settings { - internal sealed class UserSettings : IUserSettings, IDisposable + internal sealed partial class UserSettings : IUserSettings, IDisposable { private readonly SettingsUtils _settingsUtils; private readonly TaskScheduler _taskScheduler; diff --git a/src/modules/AdvancedPaste/AdvancedPaste/Models/KernelQueryCache/PersistedCache.cs b/src/modules/AdvancedPaste/AdvancedPaste/Models/KernelQueryCache/PersistedCache.cs index 928ba7ab3751..721d9a24ed55 100644 --- a/src/modules/AdvancedPaste/AdvancedPaste/Models/KernelQueryCache/PersistedCache.cs +++ b/src/modules/AdvancedPaste/AdvancedPaste/Models/KernelQueryCache/PersistedCache.cs @@ -7,6 +7,7 @@ using System.Text.Json.Serialization; using AdvancedPaste.Helpers; +using AdvancedPaste.SerializationContext; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; namespace AdvancedPaste.Models.KernelQueryCache; @@ -15,15 +16,7 @@ public sealed class PersistedCache : ISettingsConfig { public record class CacheItem(CacheKey CacheKey, CacheValue CacheValue); - private static readonly JsonSerializerOptions SerializerOptions = new() - { - Converters = - { - new JsonStringEnumConverter(), - }, - }; - - public static PersistedCache FromJsonString(string json) => JsonSerializer.Deserialize(json, SerializerOptions); + public static PersistedCache FromJsonString(string json) => JsonSerializer.Deserialize(json, SourceGenerationContext.Default.PersistedCache); public string Version { get; init; } @@ -31,7 +24,7 @@ public record class CacheItem(CacheKey CacheKey, CacheValue CacheValue); public string GetModuleName() => Constants.AdvancedPasteModuleName; - public string ToJsonString() => JsonSerializer.Serialize(this, SerializerOptions); + public string ToJsonString() => JsonSerializer.Serialize(this, SourceGenerationContext.Default.PersistedCache); public override string ToString() => ToJsonString(); diff --git a/src/modules/AdvancedPaste/AdvancedPaste/SerializationContext/SourceGenerationContext.cs b/src/modules/AdvancedPaste/AdvancedPaste/SerializationContext/SourceGenerationContext.cs new file mode 100644 index 000000000000..dadb2d80c112 --- /dev/null +++ b/src/modules/AdvancedPaste/AdvancedPaste/SerializationContext/SourceGenerationContext.cs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Text.Json.Serialization; +using AdvancedPaste.Helpers; +using AdvancedPaste.Models.KernelQueryCache; + +namespace AdvancedPaste.SerializationContext; + +[JsonSerializable(typeof(PersistedCache))] +[JsonSerializable(typeof(AIServiceFormatEvent))] +[JsonSourceGenerationOptions(UseStringEnumConverter = true)] +public sealed partial class SourceGenerationContext : JsonSerializerContext +{ +} diff --git a/src/modules/AdvancedPaste/AdvancedPaste/Services/KernelServiceBase.cs b/src/modules/AdvancedPaste/AdvancedPaste/Services/KernelServiceBase.cs index 08526d0b0cc7..c988d2f8ced8 100644 --- a/src/modules/AdvancedPaste/AdvancedPaste/Services/KernelServiceBase.cs +++ b/src/modules/AdvancedPaste/AdvancedPaste/Services/KernelServiceBase.cs @@ -174,9 +174,8 @@ private void LogResult(bool cacheUsed, bool isSavedQuery, IEnumerable TransformTextAsync(string prompt, string inputText) var usage = response.Usage; AdvancedPasteGenerateCustomFormatEvent telemetryEvent = new(usage.PromptTokens, usage.CompletionTokens, ModelName); PowerToysTelemetry.Log.WriteEvent(telemetryEvent); + var logEvent = new AIServiceFormatEvent(telemetryEvent); - var logEvent = new { telemetryEvent.PromptTokens, telemetryEvent.CompletionTokens, telemetryEvent.ModelName }; - Logger.LogDebug($"{nameof(TransformTextAsync)} complete; {JsonSerializer.Serialize(logEvent)}"); + Logger.LogDebug($"{nameof(TransformTextAsync)} complete; {logEvent.ToJsonString()}"); return response.Choices[0].Text; } diff --git a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteModuleInterface.vcxproj b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteModuleInterface.vcxproj index dc666513d206..083aa868d3e2 100644 --- a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteModuleInterface.vcxproj +++ b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteModuleInterface.vcxproj @@ -1,6 +1,5 @@ - + @@ -41,6 +40,7 @@ + @@ -48,6 +48,7 @@ + Create diff --git a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteModuleInterface.vcxproj.filters b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteModuleInterface.vcxproj.filters index bb7e50932cb2..aa107e28db23 100644 --- a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteModuleInterface.vcxproj.filters +++ b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteModuleInterface.vcxproj.filters @@ -1,6 +1,5 @@  - + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} @@ -31,6 +30,9 @@ Header Files + + Header Files + @@ -42,6 +44,9 @@ Source Files + + Source Files + diff --git a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteProcessManager.cpp b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteProcessManager.cpp new file mode 100644 index 000000000000..b202f93f4e10 --- /dev/null +++ b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteProcessManager.cpp @@ -0,0 +1,267 @@ +#include "pch.h" +#include "AdvancedPasteProcessManager.h" + +#include +#include +#include +#include + +namespace +{ + std::optional get_pipe_name(const std::wstring& prefix) + { + UUID temp_uuid; + wchar_t* uuid_chars = nullptr; + if (UuidCreate(&temp_uuid) == RPC_S_UUID_NO_ADDRESS) + { + const auto val = get_last_error_message(GetLastError()); + Logger::error(L"UuidCreate cannot create guid. {}", val.has_value() ? val.value() : L""); + return std::nullopt; + } + else if (UuidToString(&temp_uuid, reinterpret_cast(&uuid_chars)) != RPC_S_OK) + { + const auto val = get_last_error_message(GetLastError()); + Logger::error(L"UuidToString cannot convert to string. {}", val.has_value() ? val.value() : L""); + return std::nullopt; + } + + const auto pipe_name = std::format(L"{}{}", prefix, std::wstring(uuid_chars)); + RpcStringFree(reinterpret_cast(&uuid_chars)); + + return pipe_name; + } +} + +void AdvancedPasteProcessManager::start() +{ + m_enabled = true; + submit_task([this]() { refresh(); }); +} + +void AdvancedPasteProcessManager::stop() +{ + m_enabled = false; + submit_task([this]() { refresh(); }); +} + +void AdvancedPasteProcessManager::send_message(const std::wstring& message_type, const std::wstring& message_arg) +{ + submit_task([this, message_type, message_arg] { + send_named_pipe_message(message_type, message_arg); + }); +} + +void AdvancedPasteProcessManager::bring_to_front() +{ + submit_task([this] { + if (!is_process_running()) + { + return; + } + + const auto enum_windows = [](HWND hwnd, LPARAM param) -> BOOL { + const auto process_handle = reinterpret_cast(param); + DWORD window_process_id = 0; + + GetWindowThreadProcessId(hwnd, &window_process_id); + if (GetProcessId(process_handle) == window_process_id) + { + SetForegroundWindow(hwnd); + return FALSE; + } + return TRUE; + }; + + EnumWindows(enum_windows, reinterpret_cast(m_hProcess)); + }); +} + +void AdvancedPasteProcessManager::submit_task(std::function task) +{ + m_thread_executor.submit(OnThreadExecutor::task_t{ task }); +} + +bool AdvancedPasteProcessManager::is_process_running() const +{ + return m_hProcess != 0 && WaitForSingleObject(m_hProcess, 0) == WAIT_TIMEOUT; +} + +void AdvancedPasteProcessManager::terminate_process() +{ + if (m_hProcess != 0) + { + TerminateProcess(m_hProcess, 1); + CloseHandle(m_hProcess); + m_hProcess = 0; + } +} + +HRESULT AdvancedPasteProcessManager::start_process(const std::wstring& pipe_name) +{ + const unsigned long powertoys_pid = GetCurrentProcessId(); + + const auto executable_args = std::format(L"{} {}", std::to_wstring(powertoys_pid), pipe_name); + + SHELLEXECUTEINFOW sei{ sizeof(sei) }; + sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI }; + sei.lpFile = L"WinUI3Apps\\PowerToys.AdvancedPaste.exe"; + sei.nShow = SW_SHOWNORMAL; + sei.lpParameters = executable_args.data(); + if (ShellExecuteExW(&sei)) + { + Logger::trace("Successfully started Advanced Paste process"); + terminate_process(); + m_hProcess = sei.hProcess; + return S_OK; + } + else + { + Logger::error(L"Advanced Paste process failed to start. {}", get_last_error_or_default(GetLastError())); + return E_FAIL; + } +} + +HRESULT AdvancedPasteProcessManager::start_named_pipe_server(const std::wstring& pipe_name) +{ + m_write_pipe = nullptr; + + const constexpr DWORD BUFSIZE = 4096 * 4; + + const auto full_pipe_name = std::format(L"\\\\.\\pipe\\{}", pipe_name); + + const auto hPipe = CreateNamedPipe( + full_pipe_name.c_str(), // pipe name + PIPE_ACCESS_OUTBOUND | // write access + FILE_FLAG_OVERLAPPED, // overlapped mode + PIPE_TYPE_MESSAGE | // message type pipe + PIPE_READMODE_MESSAGE | // message-read mode + PIPE_WAIT, // blocking mode + 1, // max. instances + BUFSIZE, // output buffer size + 0, // input buffer size + 0, // client time-out + NULL); // default security attribute + + if (hPipe == NULL || hPipe == INVALID_HANDLE_VALUE) + { + Logger::error(L"Error creating handle for named pipe"); + return E_FAIL; + } + + // Create overlapped event to wait for client to connect to pipe. + OVERLAPPED overlapped = { 0 }; + overlapped.hEvent = CreateEvent(nullptr, true, false, nullptr); + if (!overlapped.hEvent) + { + Logger::error(L"Error creating overlapped event for named pipe"); + CloseHandle(hPipe); + return E_FAIL; + } + + const auto clean_up_and_fail = [&]() { + CloseHandle(overlapped.hEvent); + CloseHandle(hPipe); + return E_FAIL; + }; + + if (!ConnectNamedPipe(hPipe, &overlapped)) + { + const auto lastError = GetLastError(); + + if (lastError != ERROR_IO_PENDING && lastError != ERROR_PIPE_CONNECTED) + { + Logger::error(L"Error connecting to named pipe"); + return clean_up_and_fail(); + } + } + + // Wait for client. + const constexpr DWORD client_timeout_millis = 5000; + switch (WaitForSingleObject(overlapped.hEvent, client_timeout_millis)) + { + case WAIT_OBJECT_0: + { + DWORD bytes_transferred = 0; + if (GetOverlappedResult(hPipe, &overlapped, &bytes_transferred, FALSE)) + { + CloseHandle(overlapped.hEvent); + m_write_pipe = std::make_unique(hPipe); + + Logger::trace(L"Advanced Paste successfully connected to named pipe"); + + return S_OK; + } + else + { + Logger::error(L"Error waiting for Advanced Paste to connect to named pipe"); + return clean_up_and_fail(); + } + } + + case WAIT_TIMEOUT: + case WAIT_FAILED: + default: + Logger::error(L"Error waiting for Advanced Paste to connect to named pipe"); + return clean_up_and_fail(); + } +} + +void AdvancedPasteProcessManager::refresh() +{ + if (m_enabled == is_process_running()) + { + return; + } + + if (m_enabled) + { + Logger::trace(L"Starting Advanced Paste process"); + + const auto pipe_name = get_pipe_name(L"powertoys_advanced_paste_"); + + if (!pipe_name) + { + return; + } + + if (start_process(pipe_name.value()) != S_OK) + { + return; + } + + if (start_named_pipe_server(pipe_name.value()) != S_OK) + { + Logger::error(L"Named pipe initialization failed; terminating Advanced Paste process"); + terminate_process(); + } + } + else + { + Logger::trace(L"Exiting Advanced Paste process"); + + send_named_pipe_message(CommonSharedConstants::ADVANCED_PASTE_TERMINATE_APP_MESSAGE); + WaitForSingleObject(m_hProcess, 5000); + + if (is_process_running()) + { + Logger::error(L"Advanced Paste process failed to gracefully exit; terminating"); + } + else + { + Logger::trace(L"Advanced Paste process successfully exited"); + } + + terminate_process(); + } +} + +void AdvancedPasteProcessManager::send_named_pipe_message(const std::wstring& message_type, const std::wstring& message_arg) +{ + if (m_write_pipe) + { + const auto message = message_arg.empty() ? std::format(L"{}\r\n", message_type) : std::format(L"{} {}\r\n", message_type, message_arg); + + const CString file_name(message.c_str()); + m_write_pipe->Write(file_name, file_name.GetLength() * sizeof(TCHAR)); + } +} \ No newline at end of file diff --git a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteProcessManager.h b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteProcessManager.h new file mode 100644 index 000000000000..acef16bcee18 --- /dev/null +++ b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteProcessManager.h @@ -0,0 +1,36 @@ +#pragma once +#include "pch.h" +#include +#include +#include +#include +#include +#include +#include + +class AdvancedPasteProcessManager +{ +public: + AdvancedPasteProcessManager() = default; + AdvancedPasteProcessManager(const AdvancedPasteProcessManager&) = delete; + AdvancedPasteProcessManager& operator=(const AdvancedPasteProcessManager&) = delete; + + void start(); + void stop(); + void send_message(const std::wstring& message_type, const std::wstring& message_arg = L""); + void bring_to_front(); + +private: + void submit_task(std::function task); + bool is_process_running() const; + void terminate_process(); + HRESULT start_process(const std::wstring& pipe_name); + HRESULT start_named_pipe_server(const std::wstring& pipe_name); + void refresh(); + void send_named_pipe_message(const std::wstring& message_type, const std::wstring& message_arg = L""); + + OnThreadExecutor m_thread_executor; // all internal operations are done on background thread with task queue + std::atomic m_enabled = false; // written on main thread, read on background thread + HANDLE m_hProcess = 0; + std::unique_ptr m_write_pipe; +}; \ No newline at end of file diff --git a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/dllmain.cpp b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/dllmain.cpp index 9fd120dca048..56fde2622c5f 100644 --- a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/dllmain.cpp +++ b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/dllmain.cpp @@ -2,6 +2,7 @@ #include "pch.h" #include "AdvancedPasteConstants.h" +#include "AdvancedPasteProcessManager.h" #include #include "trace.h" #include "Generated Files/resource.h" @@ -16,8 +17,6 @@ #include #include -#include -#include #include BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*lpReserved*/) @@ -66,6 +65,7 @@ namespace class AdvancedPaste : public PowertoyModuleIface { private: + AdvancedPasteProcessManager m_process_manager; bool m_enabled = false; std::wstring app_name; @@ -73,13 +73,6 @@ class AdvancedPaste : public PowertoyModuleIface //contains the non localized key of the powertoy std::wstring app_key; - HANDLE m_hProcess; - - std::unique_ptr m_write_pipe; - - // Time to wait for process to close after sending WM_CLOSE signal - static const constexpr int MAX_WAIT_MILLISEC = 10000; - static const constexpr int NUM_DEFAULT_HOTKEYS = 4; Hotkey m_paste_as_plain_hotkey = { .win = true, .ctrl = true, .shift = false, .alt = true, .key = 'V' }; @@ -371,84 +364,6 @@ class AdvancedPaste : public PowertoyModuleIface } } - bool is_process_running() const - { - return WaitForSingleObject(m_hProcess, 0) == WAIT_TIMEOUT; - } - - void launch_process(const std::wstring& pipe_name) - { - Logger::trace(L"Starting AdvancedPaste process"); - const unsigned long powertoys_pid = GetCurrentProcessId(); - - const auto executable_args = std::format(L"{} {}", std::to_wstring(powertoys_pid), pipe_name); - - SHELLEXECUTEINFOW sei{ sizeof(sei) }; - sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI }; - sei.lpFile = L"WinUI3Apps\\PowerToys.AdvancedPaste.exe"; - sei.nShow = SW_SHOWNORMAL; - sei.lpParameters = executable_args.data(); - if (ShellExecuteExW(&sei)) - { - Logger::trace("Successfully started the Advanced Paste process"); - } - else - { - Logger::error(L"AdvancedPaste failed to start. {}", get_last_error_or_default(GetLastError())); - } - - TerminateProcess(m_hProcess, 1); - m_hProcess = sei.hProcess; - } - - std::optional get_pipe_name(const std::wstring& prefix) const - { - UUID temp_uuid; - wchar_t* uuid_chars = nullptr; - if (UuidCreate(&temp_uuid) == RPC_S_UUID_NO_ADDRESS) - { - const auto val = get_last_error_message(GetLastError()); - Logger::error(L"UuidCreate cannot create guid. {}", val.has_value() ? val.value() : L""); - return std::nullopt; - } - else if (UuidToString(&temp_uuid, reinterpret_cast(&uuid_chars)) != RPC_S_OK) - { - const auto val = get_last_error_message(GetLastError()); - Logger::error(L"UuidToString cannot convert to string. {}", val.has_value() ? val.value() : L""); - return std::nullopt; - } - - const auto pipe_name = std::format(L"{}{}", prefix, std::wstring(uuid_chars)); - RpcStringFree(reinterpret_cast(&uuid_chars)); - - return pipe_name; - } - - void launch_process_and_named_pipe() - { - const auto pipe_name = get_pipe_name(L"powertoys_advanced_paste_"); - - if (!pipe_name) - { - return; - } - - std::thread create_pipe_thread ([&]{ start_named_pipe_server(pipe_name.value()); }); - launch_process(pipe_name.value()); - create_pipe_thread.join(); - } - - void send_named_pipe_message(const std::wstring& message_type, const std::wstring& message_arg = L"") - { - if (m_write_pipe) - { - const auto message = message_arg.empty() ? std::format(L"{}\r\n", message_type) : std::format(L"{} {}\r\n", message_type, message_arg); - - const CString file_name(message.c_str()); - m_write_pipe->Write(file_name, file_name.GetLength() * sizeof(TCHAR)); - } - } - // Load the settings file. void init_settings() { @@ -691,66 +606,6 @@ class AdvancedPaste : public PowertoyModuleIface } } - void bring_process_to_front() - { - auto enum_windows = [](HWND hwnd, LPARAM param) -> BOOL { - HANDLE process_handle = reinterpret_cast(param); - DWORD window_process_id = 0; - - GetWindowThreadProcessId(hwnd, &window_process_id); - if (GetProcessId(process_handle) == window_process_id) - { - SetForegroundWindow(hwnd); - return FALSE; - } - return TRUE; - }; - - EnumWindows(enum_windows, (LPARAM)m_hProcess); - } - - HRESULT start_named_pipe_server(const std::wstring& pipe_name) - { - const constexpr DWORD BUFSIZE = 4096 * 4; - - const auto full_pipe_name = std::format(L"\\\\.\\pipe\\{}", pipe_name); - - const auto hPipe = CreateNamedPipe( - full_pipe_name.c_str(), // pipe name - PIPE_ACCESS_OUTBOUND, // write access - PIPE_TYPE_MESSAGE | // message type pipe - PIPE_READMODE_MESSAGE | // message-read mode - PIPE_WAIT, // blocking mode - 1, // max. instances - BUFSIZE, // output buffer size - 0, // input buffer size - 0, // client time-out - NULL); // default security attribute - - if (hPipe == NULL || hPipe == INVALID_HANDLE_VALUE) - { - return E_FAIL; - } - - // This call blocks until a client process connects to the pipe - BOOL connected = ConnectNamedPipe(hPipe, NULL); - if (!connected) - { - if (GetLastError() == ERROR_PIPE_CONNECTED) - { - return S_OK; - } - else - { - CloseHandle(hPipe); - } - return E_FAIL; - } - - m_write_pipe = std::make_unique(hPipe); - return S_OK; - } - public: AdvancedPaste() { @@ -854,28 +709,19 @@ class AdvancedPaste : public PowertoyModuleIface Logger::trace("AdvancedPaste::enable()"); Trace::AdvancedPaste_Enable(true); m_enabled = true; - - launch_process_and_named_pipe(); + m_process_manager.start(); }; void Disable(bool traceEvent) { if (m_enabled) { - send_named_pipe_message(CommonSharedConstants::ADVANCED_PASTE_TERMINATE_APP_MESSAGE); - WaitForSingleObject(m_hProcess, 1500); - - m_write_pipe = nullptr; - - TerminateProcess(m_hProcess, 1); + m_process_manager.stop(); if (traceEvent) { Trace::AdvancedPaste_Enable(false); } - - CloseHandle(m_hProcess); - m_hProcess = 0; } m_enabled = false; @@ -892,11 +738,7 @@ class AdvancedPaste : public PowertoyModuleIface Logger::trace(L"AdvancedPaste hotkey pressed"); if (m_enabled) { - if (!is_process_running()) - { - Logger::trace(L"Launching new process"); - launch_process_and_named_pipe(); - } + m_process_manager.start(); // hotkeyId in same order as set by get_hotkeys if (hotkeyId == 0) @@ -917,27 +759,26 @@ class AdvancedPaste : public PowertoyModuleIface { // m_advanced_paste_ui_hotkey Logger::trace(L"Setting start up event"); - bring_process_to_front(); - send_named_pipe_message(CommonSharedConstants::ADVANCED_PASTE_SHOW_UI_MESSAGE); + m_process_manager.bring_to_front(); + m_process_manager.send_message(CommonSharedConstants::ADVANCED_PASTE_SHOW_UI_MESSAGE); Trace::AdvancedPaste_Invoked(L"AdvancedPasteUI"); return true; } if (hotkeyId == 2) { // m_paste_as_markdown_hotkey Logger::trace(L"Starting paste as markdown directly"); - send_named_pipe_message(CommonSharedConstants::ADVANCED_PASTE_MARKDOWN_MESSAGE); + m_process_manager.send_message(CommonSharedConstants::ADVANCED_PASTE_MARKDOWN_MESSAGE); Trace::AdvancedPaste_Invoked(L"MarkdownDirect"); return true; } if (hotkeyId == 3) { // m_paste_as_json_hotkey Logger::trace(L"Starting paste as json directly"); - send_named_pipe_message(CommonSharedConstants::ADVANCED_PASTE_JSON_MESSAGE); + m_process_manager.send_message(CommonSharedConstants::ADVANCED_PASTE_JSON_MESSAGE); Trace::AdvancedPaste_Invoked(L"JsonDirect"); return true; } - const auto additional_action_index = hotkeyId - NUM_DEFAULT_HOTKEYS; if (additional_action_index < m_additional_actions.size()) { @@ -947,7 +788,7 @@ class AdvancedPaste : public PowertoyModuleIface Trace::AdvancedPaste_Invoked(std::format(L"{}Direct", kebab_to_pascal_case(id))); - send_named_pipe_message(CommonSharedConstants::ADVANCED_PASTE_ADDITIONAL_ACTION_MESSAGE, id); + m_process_manager.send_message(CommonSharedConstants::ADVANCED_PASTE_ADDITIONAL_ACTION_MESSAGE, id); return true; } @@ -958,7 +799,7 @@ class AdvancedPaste : public PowertoyModuleIface Logger::trace(L"Starting custom action id={}", id); - send_named_pipe_message(CommonSharedConstants::ADVANCED_PASTE_CUSTOM_ACTION_MESSAGE, std::to_wstring(id)); + m_process_manager.send_message(CommonSharedConstants::ADVANCED_PASTE_CUSTOM_ACTION_MESSAGE, std::to_wstring(id)); Trace::AdvancedPaste_Invoked(L"CustomActionDirect"); return true; } diff --git a/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj b/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj index 89177bd56f2d..f3ce71829ffd 100644 --- a/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj +++ b/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj @@ -159,7 +159,7 @@ - + @@ -168,7 +168,7 @@ - + \ No newline at end of file diff --git a/src/modules/CropAndLock/CropAndLock/packages.config b/src/modules/CropAndLock/CropAndLock/packages.config index f53ff9a92d4f..691158d1b2a7 100644 --- a/src/modules/CropAndLock/CropAndLock/packages.config +++ b/src/modules/CropAndLock/CropAndLock/packages.config @@ -2,5 +2,5 @@ - + \ No newline at end of file diff --git a/src/modules/CropAndLock/CropAndLock/pch.h b/src/modules/CropAndLock/CropAndLock/pch.h index 75bb5f4a616f..c159b433a112 100644 --- a/src/modules/CropAndLock/CropAndLock/pch.h +++ b/src/modules/CropAndLock/CropAndLock/pch.h @@ -52,13 +52,13 @@ // robmikh.common #include #include -#include +#include #include // robmikh.common needs to be updated to support newer versions of C++/WinRT https://github.com/robmikh/robmikh.common/issues/2 // Applying workaround from https://github.com/robmikh/Win32CaptureSample/commit/fc758e343ca886795b05af5003d9a3bb85ff4da2 // #include #include "DispatcherQueue.desktop.interop.h" -#include +#include #include #include #include diff --git a/src/modules/CropAndLock/CropAndLockModuleInterface/CropAndLockModuleInterface.vcxproj b/src/modules/CropAndLock/CropAndLockModuleInterface/CropAndLockModuleInterface.vcxproj index 0917a14602f7..c7fccf462a95 100644 --- a/src/modules/CropAndLock/CropAndLockModuleInterface/CropAndLockModuleInterface.vcxproj +++ b/src/modules/CropAndLock/CropAndLockModuleInterface/CropAndLockModuleInterface.vcxproj @@ -102,7 +102,7 @@ - + @@ -112,7 +112,7 @@ - + \ No newline at end of file diff --git a/src/modules/MouseWithoutBorders/App/Class/Common.Clipboard.cs b/src/modules/MouseWithoutBorders/App/Class/Common.Clipboard.cs index 91fdfad11b5c..7654b0452d04 100644 --- a/src/modules/MouseWithoutBorders/App/Class/Common.Clipboard.cs +++ b/src/modules/MouseWithoutBorders/App/Class/Common.Clipboard.cs @@ -32,12 +32,17 @@ using MouseWithoutBorders.Exceptions; using SystemClipboard = System.Windows.Forms.Clipboard; +using Thread = MouseWithoutBorders.Core.Thread; namespace MouseWithoutBorders { internal partial class Common { - private const uint BIG_CLIPBOARD_DATA_TIMEOUT = 30000; + internal static readonly char[] Comma = new char[] { ',' }; + internal static readonly char[] Star = new char[] { '*' }; + internal static readonly char[] NullSeparator = new char[] { '\0' }; + + internal const uint BIG_CLIPBOARD_DATA_TIMEOUT = 30000; private const uint MAX_CLIPBOARD_DATA_SIZE_CAN_BE_SENT_INSTANTLY_TCP = 1024 * 1024; // 1MB private const uint MAX_CLIPBOARD_FILE_SIZE_CAN_BE_SENT = 100 * 1024 * 1024; // 100MB private const int TEXT_HEADER_SIZE = 12; @@ -46,11 +51,9 @@ internal partial class Common private static long lastClipboardEventTime; private static string lastMachineWithClipboardData; private static string lastDragDropFile; - private static long clipboardCopiedTime; - - internal static readonly char[] Comma = new char[] { ',' }; - internal static readonly char[] Star = new char[] { '*' }; - internal static readonly char[] NullSeparator = new char[] { '\0' }; +#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter + internal static long clipboardCopiedTime; +#pragma warning restore SA1307 internal static ID LastIDWithClipboardData { get; set; } @@ -332,7 +335,7 @@ internal static void ReceiveClipboardDataUsingTCP(DATA data, bool image, TcpSk t break; default: - ProcessPackage(data, tcp); + Receiver.ProcessPackage(data, tcp); if (++unexpectedCount > 100) { Logger.Log("ReceiveClipboardDataUsingTCP: unexpectedCount > 100!"); diff --git a/src/modules/MouseWithoutBorders/App/Class/Common.DragDrop.cs b/src/modules/MouseWithoutBorders/App/Class/Common.DragDrop.cs index f3ef0f139539..5426f93db062 100644 --- a/src/modules/MouseWithoutBorders/App/Class/Common.DragDrop.cs +++ b/src/modules/MouseWithoutBorders/App/Class/Common.DragDrop.cs @@ -22,6 +22,8 @@ using MouseWithoutBorders.Class; using MouseWithoutBorders.Core; +using Thread = MouseWithoutBorders.Core.Thread; + namespace MouseWithoutBorders { /* Common.DragDrop.cs @@ -238,7 +240,7 @@ internal static void DragDropStep06() internal static void DragDropStep08(DATA package) { - GetNameOfMachineWithClipboardData(package); + Receiver.GetNameOfMachineWithClipboardData(package); Logger.LogDebug("DragDropStep08: ClipboardDragDrop Received. machine with drag file was set"); } diff --git a/src/modules/MouseWithoutBorders/App/Class/Common.Event.cs b/src/modules/MouseWithoutBorders/App/Class/Common.Event.cs index e50e87b8f95e..fc581a3de26a 100644 --- a/src/modules/MouseWithoutBorders/App/Class/Common.Event.cs +++ b/src/modules/MouseWithoutBorders/App/Class/Common.Event.cs @@ -21,6 +21,8 @@ using MouseWithoutBorders.Core; using MouseWithoutBorders.Form; +using Thread = MouseWithoutBorders.Core.Thread; + namespace MouseWithoutBorders { internal partial class Common @@ -145,7 +147,7 @@ internal static void MouseEvent(MOUSEDATA e, int dx, int dy) } } - private static bool IsSwitchingByMouseEnabled() + internal static bool IsSwitchingByMouseEnabled() { return (EasyMouseOption)Setting.Values.EasyMouse == EasyMouseOption.Enable || InputHook.EasyMouseKeyDown; } diff --git a/src/modules/MouseWithoutBorders/App/Class/Common.InitAndCleanup.cs b/src/modules/MouseWithoutBorders/App/Class/Common.InitAndCleanup.cs index da52a60db2da..b733e17830d0 100644 --- a/src/modules/MouseWithoutBorders/App/Class/Common.InitAndCleanup.cs +++ b/src/modules/MouseWithoutBorders/App/Class/Common.InitAndCleanup.cs @@ -23,6 +23,8 @@ using MouseWithoutBorders.Form; using Windows.UI.Input.Preview.Injection; +using Thread = MouseWithoutBorders.Core.Thread; + namespace MouseWithoutBorders { internal partial class Common diff --git a/src/modules/MouseWithoutBorders/App/Class/Common.Log.cs b/src/modules/MouseWithoutBorders/App/Class/Common.Log.cs deleted file mode 100644 index 773564fe7f04..000000000000 --- a/src/modules/MouseWithoutBorders/App/Class/Common.Log.cs +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Sockets; -using System.Reflection; -using System.Text; -using System.Threading; -using System.Windows.Forms; - -// -// Logging. -// -// -// 2008 created by Truong Do (ductdo). -// 2009-... modified by Truong Do (TruongDo). -// 2023- Included in PowerToys. -// -using MouseWithoutBorders.Class; -using MouseWithoutBorders.Core; -using MouseWithoutBorders.Exceptions; - -namespace MouseWithoutBorders -{ - public class Thread - { - private static readonly Lock ThreadsLock = new(); - private static List threads; - - private readonly System.Threading.Thread thread; - - internal Thread(ThreadStart callback, string name) - { - UpdateThreads(thread = new System.Threading.Thread(callback) { Name = name }); - } - - internal Thread(ParameterizedThreadStart callback, string name) - { - UpdateThreads(thread = new System.Threading.Thread(callback) { Name = name }); - } - - internal static void UpdateThreads(System.Threading.Thread thread) - { - lock (ThreadsLock) - { - bool found = false; - List toBeRemovedThreads = new(); - threads ??= new List(); - - foreach (System.Threading.Thread t in threads) - { - if (!t.IsAlive) - { - toBeRemovedThreads.Add(t); - } - else if (t.ManagedThreadId == thread.ManagedThreadId) - { - found = true; - } - } - - foreach (System.Threading.Thread t in toBeRemovedThreads) - { - _ = threads.Remove(t); - } - - if (!found) - { - threads.Add(thread); - } - } - } - - internal static string DumpThreadsStack() - { - string stack = "\r\nMANAGED THREADS: " + threads.Count.ToString(CultureInfo.InvariantCulture) + "\r\n"; - stack += Logger.GetStackTrace(new StackTrace()); - return stack; - } - - internal void SetApartmentState(ApartmentState apartmentState) - { - thread.SetApartmentState(apartmentState); - } - - internal void Start() - { - thread.Start(); - } - - internal void Start(object parameter) - { - thread.Start(parameter); - } - - internal static void Sleep(int millisecondsTimeout) - { - System.Threading.Thread.Sleep(millisecondsTimeout); - } - - internal static System.Threading.Thread CurrentThread => System.Threading.Thread.CurrentThread; - - internal ThreadPriority Priority - { - get => thread.Priority; - set => thread.Priority = value; - } - - internal System.Threading.ThreadState ThreadState => thread.ThreadState; - } -} diff --git a/src/modules/MouseWithoutBorders/App/Class/Common.MachineStuff.cs b/src/modules/MouseWithoutBorders/App/Class/Common.MachineStuff.cs index 2072478f2dad..cbf11ca16e0d 100644 --- a/src/modules/MouseWithoutBorders/App/Class/Common.MachineStuff.cs +++ b/src/modules/MouseWithoutBorders/App/Class/Common.MachineStuff.cs @@ -51,10 +51,14 @@ internal partial class Common private const int SKIP_PIXELS = 1; private const int JUMP_PIXELS = 2; - private static ID desMachineID; +#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter + internal static ID desMachineID; +#pragma warning restore SA1307 internal static string DesMachineName = string.Empty; private static ID newDesMachineID; - private static ID newDesMachineIdEx; +#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter + internal static ID newDesMachineIdEx; +#pragma warning restore SA1307 private static ID dropMachineID; private static long lastJump = Common.GetTick(); @@ -720,7 +724,7 @@ internal static void RemoveDeadMachines() } } - private static string AddToMachinePool(DATA package) + internal static string AddToMachinePool(DATA package) { // Log("********** AddToMachinePool called: " + package.src.ToString(CultureInfo.InvariantCulture)); diff --git a/src/modules/MouseWithoutBorders/App/Class/Common.Receiver.cs b/src/modules/MouseWithoutBorders/App/Class/Common.Receiver.cs deleted file mode 100644 index 5b17801450f0..000000000000 --- a/src/modules/MouseWithoutBorders/App/Class/Common.Receiver.cs +++ /dev/null @@ -1,431 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Drawing; -using System.Globalization; -using System.IO; -using System.Threading.Tasks; -using System.Windows.Forms; - -// -// Back-end thread for the socket. -// -// -// 2008 created by Truong Do (ductdo). -// 2009-... modified by Truong Do (TruongDo). -// 2023- Included in PowerToys. -// -using MouseWithoutBorders.Class; -using MouseWithoutBorders.Core; - -[module: SuppressMessage("Microsoft.Reliability", "CA2002:DoNotLockOnObjectsWithWeakIdentity", Scope = "member", Target = "MouseWithoutBorders.Common.#PreProcess(MouseWithoutBorders.DATA)", Justification = "Dotnet port with style preservation")] - -namespace MouseWithoutBorders -{ - internal partial class Common - { - private static readonly uint QUEUE_SIZE = 50; - private static readonly int[] RecentProcessedPackageIDs = new int[QUEUE_SIZE]; - private static int recentProcessedPackageIndex; -#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter - internal static long processedPackageCount; - internal static long skippedPackageCount; -#pragma warning restore SA1307 - - internal static long JustGotAKey { get; set; } - - private static bool PreProcess(DATA package) - { - if (package.Type == PackageType.Invalid) - { - if ((Common.InvalidPackageCount % 100) == 0) - { - ShowToolTip("Invalid packages received!", 1000, ToolTipIcon.Warning, false); - } - - Common.InvalidPackageCount++; - Logger.Log("Invalid packages received!"); - return false; - } - else if (package.Type == 0) - { - Logger.Log("Got an unknown package!"); - return false; - } - else if (package.Type is not PackageType.ClipboardText and not PackageType.ClipboardImage - - // BEGIN: These package types are sent by TcpSend which is single direction. - and not PackageType.Handshake and not PackageType.HandshakeAck) - { - // END - lock (RecentProcessedPackageIDs) - { - for (int i = 0; i < QUEUE_SIZE; i++) - { - if (RecentProcessedPackageIDs[i] == package.Id) - { - skippedPackageCount++; - return false; - } - } - - processedPackageCount++; - recentProcessedPackageIndex = (int)((recentProcessedPackageIndex + 1) % QUEUE_SIZE); - RecentProcessedPackageIDs[recentProcessedPackageIndex] = package.Id; - } - } - - return true; - } - - private static System.Drawing.Point lastXY; - - internal static void ProcessPackage(DATA package, TcpSk tcp) - { - if (!PreProcess(package)) - { - return; - } - - switch (package.Type) - { - case PackageType.Keyboard: - PackageReceived.Keyboard++; - if (package.Des == MachineID || package.Des == ID.ALL) - { - JustGotAKey = GetTick(); - - // NOTE(@yuyoyuppe): disabled to drop elevation requirement - bool nonElevated = Common.RunWithNoAdminRight && false; - if (nonElevated && Setting.Values.OneWayControlMode) - { - if ((package.Kd.dwFlags & (int)Common.LLKHF.UP) == (int)Common.LLKHF.UP) - { - Common.ShowOneWayModeMessage(); - } - - return; - } - - InputSimulation.SendKey(package.Kd); - } - - break; - - case PackageType.Mouse: - PackageReceived.Mouse++; - - if (package.Des == MachineID || package.Des == ID.ALL) - { - if (desMachineID != MachineID) - { - NewDesMachineID = DesMachineID = MachineID; - } - - // NOTE(@yuyoyuppe): disabled to drop elevation requirement - bool nonElevated = Common.RunWithNoAdminRight && false; - if (nonElevated && Setting.Values.OneWayControlMode && package.Md.dwFlags != Common.WM_MOUSEMOVE) - { - if (!IsDropping) - { - if (package.Md.dwFlags is WM_LBUTTONDOWN or WM_RBUTTONDOWN) - { - Common.ShowOneWayModeMessage(); - } - } - else if (package.Md.dwFlags is WM_LBUTTONUP or WM_RBUTTONUP) - { - IsDropping = false; - } - - return; - } - - if (Math.Abs(package.Md.X) >= MOVE_MOUSE_RELATIVE && Math.Abs(package.Md.Y) >= MOVE_MOUSE_RELATIVE) - { - if (package.Md.dwFlags == Common.WM_MOUSEMOVE) - { - InputSimulation.MoveMouseRelative( - package.Md.X < 0 ? package.Md.X + MOVE_MOUSE_RELATIVE : package.Md.X - MOVE_MOUSE_RELATIVE, - package.Md.Y < 0 ? package.Md.Y + MOVE_MOUSE_RELATIVE : package.Md.Y - MOVE_MOUSE_RELATIVE); - _ = NativeMethods.GetCursorPos(ref lastXY); - - Point p = MoveToMyNeighbourIfNeeded(lastXY.X, lastXY.Y, MachineID); - - if (!p.IsEmpty) - { - HasSwitchedMachineSinceLastCopy = true; - - Logger.LogDebug(string.Format( - CultureInfo.CurrentCulture, - "***** Controlled Machine: newDesMachineIdEx set = [{0}]. Mouse is now at ({1},{2})", - newDesMachineIdEx, - lastXY.X, - lastXY.Y)); - - SendNextMachine(package.Src, newDesMachineIdEx, p); - } - } - else - { - _ = NativeMethods.GetCursorPos(ref lastXY); - package.Md.X = lastXY.X * 65535 / screenWidth; - package.Md.Y = lastXY.Y * 65535 / screenHeight; - _ = InputSimulation.SendMouse(package.Md); - } - } - else - { - _ = InputSimulation.SendMouse(package.Md); - _ = NativeMethods.GetCursorPos(ref lastXY); - } - - LastX = lastXY.X; - LastY = lastXY.Y; - CustomCursor.ShowFakeMouseCursor(LastX, LastY); - } - - DragDropStep01(package.Md.dwFlags); - DragDropStep09(package.Md.dwFlags); - break; - - case PackageType.NextMachine: - Logger.LogDebug("PackageType.NextMachine received!"); - - if (IsSwitchingByMouseEnabled()) - { - PrepareToSwitchToMachine((ID)package.Md.WheelDelta, new Point(package.Md.X, package.Md.Y)); - } - - break; - - case PackageType.ExplorerDragDrop: - PackageReceived.ExplorerDragDrop++; - DragDropStep03(package); - break; - - case PackageType.Heartbeat: - case PackageType.Heartbeat_ex: - PackageReceived.Heartbeat++; - - Common.GeneratedKey = Common.GeneratedKey || package.Type == PackageType.Heartbeat_ex; - - if (Common.GeneratedKey) - { - Setting.Values.MyKey = Common.MyKey; - SendPackage(ID.ALL, PackageType.Heartbeat_ex_l2); - } - - string desMachine = Common.AddToMachinePool(package); - - if (Setting.Values.FirstRun && !string.IsNullOrEmpty(desMachine)) - { - Common.UpdateSetupMachineMatrix(desMachine); - Common.UpdateClientSockets("UpdateSetupMachineMatrix"); - } - - break; - - case PackageType.Heartbeat_ex_l2: - Common.GeneratedKey = true; - Setting.Values.MyKey = Common.MyKey; - SendPackage(ID.ALL, PackageType.Heartbeat_ex_l3); - - break; - - case PackageType.Heartbeat_ex_l3: - Common.GeneratedKey = true; - Setting.Values.MyKey = Common.MyKey; - - break; - - case PackageType.Awake: - PackageReceived.Heartbeat++; - _ = Common.AddToMachinePool(package); - Common.HumanBeingDetected(); - break; - - case PackageType.Hello: - PackageReceived.Hello++; - SendHeartBeat(); - string newMachine = Common.AddToMachinePool(package); - if (Setting.Values.MachineMatrixString == null) - { - string tip = newMachine + " saying Hello!"; - tip += "\r\n Right Click to setup your machine Matrix"; - ShowToolTip(tip); - } - - break; - - case PackageType.Hi: - PackageReceived.Hello++; - break; - - case PackageType.ByeBye: - PackageReceived.ByeBye++; - ProcessByeByeMessage(package); - break; - - case PackageType.Clipboard: - PackageReceived.Clipboard++; - if (!RunOnLogonDesktop && !RunOnScrSaverDesktop) - { - clipboardCopiedTime = GetTick(); - GetNameOfMachineWithClipboardData(package); - SignalBigClipboardData(); - } - - break; - - case PackageType.MachineSwitched: - if (GetTick() - clipboardCopiedTime < BIG_CLIPBOARD_DATA_TIMEOUT && (package.Des == MachineID)) - { - clipboardCopiedTime = 0; - Common.GetRemoteClipboard("PackageType.MachineSwitched"); - } - - break; - - case PackageType.ClipboardCapture: - PackageReceived.Clipboard++; - if (!RunOnLogonDesktop && !RunOnScrSaverDesktop) - { - if (package.Des == MachineID || package.Des == ID.ALL) - { - GetNameOfMachineWithClipboardData(package); - GetRemoteClipboard("mspaint," + LastMachineWithClipboardData); - } - } - - break; - - case PackageType.CaptureScreenCommand: - PackageReceived.Clipboard++; - if (package.Des == MachineID || package.Des == ID.ALL) - { - Common.SendImage(package.Src, Common.CaptureScreen()); - } - - break; - - case PackageType.ClipboardAsk: - PackageReceived.ClipboardAsk++; - - if (package.Des == MachineID) - { - _ = Task.Run(() => - { - try - { - System.Threading.Thread thread = Thread.CurrentThread; - thread.Name = $"{nameof(PackageType.ClipboardAsk)}.{thread.ManagedThreadId}"; - Thread.UpdateThreads(thread); - - string remoteMachine = package.MachineName; - System.Net.Sockets.TcpClient client = ConnectToRemoteClipboardSocket(remoteMachine); - bool clientPushData = true; - - if (ShakeHand(ref remoteMachine, client.Client, out Stream enStream, out Stream deStream, ref clientPushData, ref package.PostAction)) - { - SocketStuff.SendClipboardData(client.Client, enStream); - } - } - catch (Exception e) - { - Logger.Log(e); - } - }); - } - - break; - - case PackageType.ClipboardDragDrop: - PackageReceived.ClipboardDragDrop++; - DragDropStep08(package); - break; - - case PackageType.ClipboardDragDropOperation: - PackageReceived.ClipboardDragDrop++; - DragDropStep08_2(package); - break; - - case PackageType.ClipboardDragDropEnd: - PackageReceived.ClipboardDragDropEnd++; - DragDropStep12(); - break; - - case PackageType.ClipboardText: - case PackageType.ClipboardImage: - clipboardCopiedTime = 0; - if (package.Type == PackageType.ClipboardImage) - { - PackageReceived.ClipboardImage++; - } - else - { - PackageReceived.ClipboardText++; - } - - if (tcp != null) - { - Common.ReceiveClipboardDataUsingTCP( - package, - package.Type == PackageType.ClipboardImage, - tcp); - } - - break; - - case PackageType.HideMouse: - HasSwitchedMachineSinceLastCopy = true; - HideMouseCursor(true); - MainFormDotEx(false); - ReleaseAllKeys(); - break; - - default: - if ((package.Type & PackageType.Matrix) == PackageType.Matrix) - { - PackageReceived.Matrix++; - UpdateMachineMatrix(package); - break; - } - else - { - // We should never get to this point! - Logger.Log("Invalid package received!"); - return; - } - } - } - - private static void GetNameOfMachineWithClipboardData(DATA package) - { - LastIDWithClipboardData = package.Src; - List matchingMachines = Common.MachinePool.TryFindMachineByID(LastIDWithClipboardData); - if (matchingMachines.Count >= 1) - { - LastMachineWithClipboardData = matchingMachines[0].Name.Trim(); - } - - /* - lastMachineWithClipboardData = - Common.GetString(BitConverter.GetBytes(package.machineNameHead)); - lastMachineWithClipboardData += - Common.GetString(BitConverter.GetBytes(package.machineNameTail)); - lastMachineWithClipboardData = lastMachineWithClipboardData.Trim(); - * */ - } - - private static void SignalBigClipboardData() - { - Logger.LogDebug("SignalBigClipboardData"); - SetToggleIcon(new int[TOGGLE_ICONS_SIZE] { ICON_BIG_CLIPBOARD, -1, ICON_BIG_CLIPBOARD, -1 }); - } - } -} diff --git a/src/modules/MouseWithoutBorders/App/Class/Common.WinAPI.cs b/src/modules/MouseWithoutBorders/App/Class/Common.WinAPI.cs index 722590ef811a..006c5d862c20 100644 --- a/src/modules/MouseWithoutBorders/App/Class/Common.WinAPI.cs +++ b/src/modules/MouseWithoutBorders/App/Class/Common.WinAPI.cs @@ -23,6 +23,8 @@ using MouseWithoutBorders.Class; using MouseWithoutBorders.Core; +using Thread = MouseWithoutBorders.Core.Thread; + namespace MouseWithoutBorders { // Desktops, and GetScreenConfig routines diff --git a/src/modules/MouseWithoutBorders/App/Class/Common.cs b/src/modules/MouseWithoutBorders/App/Class/Common.cs index f3cf4a86fde2..1131893ec42c 100644 --- a/src/modules/MouseWithoutBorders/App/Class/Common.cs +++ b/src/modules/MouseWithoutBorders/App/Class/Common.cs @@ -32,6 +32,8 @@ using MouseWithoutBorders.Core; using MouseWithoutBorders.Exceptions; +using Thread = MouseWithoutBorders.Core.Thread; + // Log is enough [module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.Common.#CheckClipboard()", Justification = "Dotnet port with style preservation")] [module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.Common.#CheckForDesktopSwitchEvent(System.Boolean)", Justification = "Dotnet port with style preservation")] @@ -88,8 +90,10 @@ internal Common() private static FrmInputCallback inputCallbackForm; private static FrmAbout aboutForm; private static Thread helper; - private static int screenWidth; - private static int screenHeight; +#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter + internal static int screenWidth; + internal static int screenHeight; +#pragma warning restore SA1307 private static int lastX; private static int lastY; @@ -552,7 +556,7 @@ internal static void SendAwakeBeat() lastRealInputEventCount = Common.RealInputEventCount; } - private static void HumanBeingDetected() + internal static void HumanBeingDetected() { if (lastInputEventCount == Common.InputEventCount) { @@ -613,7 +617,7 @@ internal static void SendClipboardBeat() SendPackage(ID.ALL, PackageType.Clipboard); } - private static void ProcessByeByeMessage(DATA package) + internal static void ProcessByeByeMessage(DATA package) { if (package.Src == desMachineID) { diff --git a/src/modules/MouseWithoutBorders/App/Class/IClipboardHelper.cs b/src/modules/MouseWithoutBorders/App/Class/IClipboardHelper.cs index ecaeef77db65..9621c54bc411 100644 --- a/src/modules/MouseWithoutBorders/App/Class/IClipboardHelper.cs +++ b/src/modules/MouseWithoutBorders/App/Class/IClipboardHelper.cs @@ -27,6 +27,9 @@ #endif using SystemClipboard = System.Windows.Forms.Clipboard; +#if !MM_HELPER +using Thread = MouseWithoutBorders.Core.Thread; +#endif namespace MouseWithoutBorders { diff --git a/src/modules/MouseWithoutBorders/App/Class/Program.cs b/src/modules/MouseWithoutBorders/App/Class/Program.cs index ac33da9ae983..011b1cfdc975 100644 --- a/src/modules/MouseWithoutBorders/App/Class/Program.cs +++ b/src/modules/MouseWithoutBorders/App/Class/Program.cs @@ -35,6 +35,7 @@ using StreamJsonRpc; using Logger = MouseWithoutBorders.Core.Logger; +using Thread = MouseWithoutBorders.Core.Thread; [module: SuppressMessage("Microsoft.MSInternal", "CA904:DeclareTypesInMicrosoftOrSystemNamespace", Scope = "namespace", Target = "MouseWithoutBorders", Justification = "Dotnet port with style preservation")] [module: SuppressMessage("Microsoft.Design", "CA1014:MarkAssembliesWithClsCompliant", Justification = "Dotnet port with style preservation")] diff --git a/src/modules/MouseWithoutBorders/App/Class/Setting.cs b/src/modules/MouseWithoutBorders/App/Class/Setting.cs index a49b98d4f7c2..23ca49309c49 100644 --- a/src/modules/MouseWithoutBorders/App/Class/Setting.cs +++ b/src/modules/MouseWithoutBorders/App/Class/Setting.cs @@ -13,7 +13,6 @@ using System.Linq; using System.Security.Cryptography; using System.Text.Json.Serialization; -using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; @@ -33,6 +32,8 @@ using MouseWithoutBorders.Core; using Settings.UI.Library.Attributes; +using Lock = System.Threading.Lock; + [module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.Properties.Setting.Values.#LoadIntSetting(System.String,System.Int32)", Justification = "Dotnet port with style preservation")] [module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.Properties.Setting.Values.#SaveSetting(System.String,System.Object)", Justification = "Dotnet port with style preservation")] [module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.Properties.Setting.Values.#LoadStringSetting(System.String,System.String)", Justification = "Dotnet port with style preservation")] diff --git a/src/modules/MouseWithoutBorders/App/Class/SocketStuff.cs b/src/modules/MouseWithoutBorders/App/Class/SocketStuff.cs index 6f354e4af174..31b047a837e5 100644 --- a/src/modules/MouseWithoutBorders/App/Class/SocketStuff.cs +++ b/src/modules/MouseWithoutBorders/App/Class/SocketStuff.cs @@ -29,6 +29,8 @@ // using MouseWithoutBorders.Exceptions; +using Thread = MouseWithoutBorders.Core.Thread; + [module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.SocketStuff.#SendData(System.Byte[])", Justification = "Dotnet port with style preservation")] [module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.SocketStuff.#Close()", Justification = "Dotnet port with style preservation")] [module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.SocketStuff.#CreateSocket(System.Boolean)", Justification = "Dotnet port with style preservation")] @@ -1524,7 +1526,7 @@ private void MainTCPRoutine(TcpSk tcp, string machineName, bool isClient) } else { - Common.ProcessPackage(package, currentTcp); + Receiver.ProcessPackage(package, currentTcp); } } } diff --git a/src/modules/MouseWithoutBorders/App/Class/TcpServer.cs b/src/modules/MouseWithoutBorders/App/Class/TcpServer.cs index ffff1ce76bf6..f915ae94e057 100644 --- a/src/modules/MouseWithoutBorders/App/Class/TcpServer.cs +++ b/src/modules/MouseWithoutBorders/App/Class/TcpServer.cs @@ -23,6 +23,8 @@ // using MouseWithoutBorders.Exceptions; +using Thread = MouseWithoutBorders.Core.Thread; + [module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.TcpServer.#Close()", Justification = "Dotnet port with style preservation")] namespace MouseWithoutBorders.Class diff --git a/src/modules/MouseWithoutBorders/App/Core/Logger.cs b/src/modules/MouseWithoutBorders/App/Core/Logger.cs index c6e62139ba4a..c561d5ff42da 100644 --- a/src/modules/MouseWithoutBorders/App/Core/Logger.cs +++ b/src/modules/MouseWithoutBorders/App/Core/Logger.cs @@ -15,6 +15,9 @@ using System.Threading; using System.Windows.Forms; +using MouseWithoutBorders.Class; +using MouseWithoutBorders.Exceptions; + // // Logging. // @@ -23,9 +26,6 @@ // 2009-... modified by Truong Do (TruongDo). // 2023- Included in PowerToys. // -using MouseWithoutBorders.Class; -using MouseWithoutBorders.Exceptions; - namespace MouseWithoutBorders.Core; internal static class Logger @@ -163,8 +163,8 @@ internal static void LogAll() Common.PackageReceived.ExplorerDragDrop, Common.invalidPackageCount, Common.PackageReceived.Nil, - Common.processedPackageCount, - Common.skippedPackageCount); + Receiver.processedPackageCount, + Receiver.skippedPackageCount); Log(log); lastPackageReceived = Common.PackageReceived; } @@ -201,6 +201,8 @@ internal static void DumpObjects(int level) _ = Logger.PrivateDump(sb, new Common(), "[Other Logs]\r\n===============\r\n", 0, level, false); sb.AppendLine("[Logger]\r\n==============="); Logger.DumpType(sb, typeof(Logger), 0, level); + sb.AppendLine("[Receiver]\r\n==============="); + Logger.DumpType(sb, typeof(Receiver), 0, level); log = string.Format( CultureInfo.CurrentCulture, diff --git a/src/modules/MouseWithoutBorders/App/Core/Receiver.cs b/src/modules/MouseWithoutBorders/App/Core/Receiver.cs new file mode 100644 index 000000000000..4ef8a8ccdc6f --- /dev/null +++ b/src/modules/MouseWithoutBorders/App/Core/Receiver.cs @@ -0,0 +1,429 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Drawing; +using System.Globalization; +using System.IO; +using System.Threading.Tasks; +using System.Windows.Forms; + +using MouseWithoutBorders.Class; + +[module: SuppressMessage("Microsoft.Reliability", "CA2002:DoNotLockOnObjectsWithWeakIdentity", Scope = "member", Target = "MouseWithoutBorders.Common.#PreProcess(MouseWithoutBorders.DATA)", Justification = "Dotnet port with style preservation")] + +// +// Back-end thread for the socket. +// +// +// 2008 created by Truong Do (ductdo). +// 2009-... modified by Truong Do (TruongDo). +// 2023- Included in PowerToys. +// +namespace MouseWithoutBorders.Core; + +internal static class Receiver +{ + private static readonly uint QUEUE_SIZE = 50; + private static readonly int[] RecentProcessedPackageIDs = new int[QUEUE_SIZE]; + private static int recentProcessedPackageIndex; +#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter + internal static long processedPackageCount; + internal static long skippedPackageCount; +#pragma warning restore SA1307 + + private static long JustGotAKey { get; set; } + + private static bool PreProcess(DATA package) + { + if (package.Type == PackageType.Invalid) + { + if ((Common.InvalidPackageCount % 100) == 0) + { + Common.ShowToolTip("Invalid packages received!", 1000, ToolTipIcon.Warning, false); + } + + Common.InvalidPackageCount++; + Logger.Log("Invalid packages received!"); + return false; + } + else if (package.Type == 0) + { + Logger.Log("Got an unknown package!"); + return false; + } + else if (package.Type is not PackageType.ClipboardText and not PackageType.ClipboardImage + + // BEGIN: These package types are sent by TcpSend which is single direction. + and not PackageType.Handshake and not PackageType.HandshakeAck) + { + // END + lock (RecentProcessedPackageIDs) + { + for (int i = 0; i < QUEUE_SIZE; i++) + { + if (RecentProcessedPackageIDs[i] == package.Id) + { + skippedPackageCount++; + return false; + } + } + + processedPackageCount++; + recentProcessedPackageIndex = (int)((recentProcessedPackageIndex + 1) % QUEUE_SIZE); + RecentProcessedPackageIDs[recentProcessedPackageIndex] = package.Id; + } + } + + return true; + } + + private static System.Drawing.Point lastXY; + + internal static void ProcessPackage(DATA package, TcpSk tcp) + { + if (!PreProcess(package)) + { + return; + } + + switch (package.Type) + { + case PackageType.Keyboard: + Common.PackageReceived.Keyboard++; + if (package.Des == Common.MachineID || package.Des == ID.ALL) + { + JustGotAKey = Common.GetTick(); + + // NOTE(@yuyoyuppe): disabled to drop elevation requirement + bool nonElevated = Common.RunWithNoAdminRight && false; + if (nonElevated && Setting.Values.OneWayControlMode) + { + if ((package.Kd.dwFlags & (int)Common.LLKHF.UP) == (int)Common.LLKHF.UP) + { + Common.ShowOneWayModeMessage(); + } + + return; + } + + InputSimulation.SendKey(package.Kd); + } + + break; + + case PackageType.Mouse: + Common.PackageReceived.Mouse++; + + if (package.Des == Common.MachineID || package.Des == ID.ALL) + { + if (Common.desMachineID != Common.MachineID) + { + Common.NewDesMachineID = Common.DesMachineID = Common.MachineID; + } + + // NOTE(@yuyoyuppe): disabled to drop elevation requirement + bool nonElevated = Common.RunWithNoAdminRight && false; + if (nonElevated && Setting.Values.OneWayControlMode && package.Md.dwFlags != Common.WM_MOUSEMOVE) + { + if (!Common.IsDropping) + { + if (package.Md.dwFlags is Common.WM_LBUTTONDOWN or Common.WM_RBUTTONDOWN) + { + Common.ShowOneWayModeMessage(); + } + } + else if (package.Md.dwFlags is Common.WM_LBUTTONUP or Common.WM_RBUTTONUP) + { + Common.IsDropping = false; + } + + return; + } + + if (Math.Abs(package.Md.X) >= Common.MOVE_MOUSE_RELATIVE && Math.Abs(package.Md.Y) >= Common.MOVE_MOUSE_RELATIVE) + { + if (package.Md.dwFlags == Common.WM_MOUSEMOVE) + { + InputSimulation.MoveMouseRelative( + package.Md.X < 0 ? package.Md.X + Common.MOVE_MOUSE_RELATIVE : package.Md.X - Common.MOVE_MOUSE_RELATIVE, + package.Md.Y < 0 ? package.Md.Y + Common.MOVE_MOUSE_RELATIVE : package.Md.Y - Common.MOVE_MOUSE_RELATIVE); + _ = NativeMethods.GetCursorPos(ref lastXY); + + Point p = Common.MoveToMyNeighbourIfNeeded(lastXY.X, lastXY.Y, Common.MachineID); + + if (!p.IsEmpty) + { + Common.HasSwitchedMachineSinceLastCopy = true; + + Logger.LogDebug(string.Format( + CultureInfo.CurrentCulture, + "***** Controlled Machine: newDesMachineIdEx set = [{0}]. Mouse is now at ({1},{2})", + Common.newDesMachineIdEx, + lastXY.X, + lastXY.Y)); + + Common.SendNextMachine(package.Src, Common.newDesMachineIdEx, p); + } + } + else + { + _ = NativeMethods.GetCursorPos(ref lastXY); + package.Md.X = lastXY.X * 65535 / Common.screenWidth; + package.Md.Y = lastXY.Y * 65535 / Common.screenHeight; + _ = InputSimulation.SendMouse(package.Md); + } + } + else + { + _ = InputSimulation.SendMouse(package.Md); + _ = NativeMethods.GetCursorPos(ref lastXY); + } + + Common.LastX = lastXY.X; + Common.LastY = lastXY.Y; + CustomCursor.ShowFakeMouseCursor(Common.LastX, Common.LastY); + } + + Common.DragDropStep01(package.Md.dwFlags); + Common.DragDropStep09(package.Md.dwFlags); + break; + + case PackageType.NextMachine: + Logger.LogDebug("PackageType.NextMachine received!"); + + if (Common.IsSwitchingByMouseEnabled()) + { + Common.PrepareToSwitchToMachine((ID)package.Md.WheelDelta, new Point(package.Md.X, package.Md.Y)); + } + + break; + + case PackageType.ExplorerDragDrop: + Common.PackageReceived.ExplorerDragDrop++; + Common.DragDropStep03(package); + break; + + case PackageType.Heartbeat: + case PackageType.Heartbeat_ex: + Common.PackageReceived.Heartbeat++; + + Common.GeneratedKey = Common.GeneratedKey || package.Type == PackageType.Heartbeat_ex; + + if (Common.GeneratedKey) + { + Setting.Values.MyKey = Common.MyKey; + Common.SendPackage(ID.ALL, PackageType.Heartbeat_ex_l2); + } + + string desMachine = Common.AddToMachinePool(package); + + if (Setting.Values.FirstRun && !string.IsNullOrEmpty(desMachine)) + { + Common.UpdateSetupMachineMatrix(desMachine); + Common.UpdateClientSockets("UpdateSetupMachineMatrix"); + } + + break; + + case PackageType.Heartbeat_ex_l2: + Common.GeneratedKey = true; + Setting.Values.MyKey = Common.MyKey; + Common.SendPackage(ID.ALL, PackageType.Heartbeat_ex_l3); + + break; + + case PackageType.Heartbeat_ex_l3: + Common.GeneratedKey = true; + Setting.Values.MyKey = Common.MyKey; + + break; + + case PackageType.Awake: + Common.PackageReceived.Heartbeat++; + _ = Common.AddToMachinePool(package); + Common.HumanBeingDetected(); + break; + + case PackageType.Hello: + Common.PackageReceived.Hello++; + Common.SendHeartBeat(); + string newMachine = Common.AddToMachinePool(package); + if (Setting.Values.MachineMatrixString == null) + { + string tip = newMachine + " saying Hello!"; + tip += "\r\n Right Click to setup your machine Matrix"; + Common.ShowToolTip(tip); + } + + break; + + case PackageType.Hi: + Common.PackageReceived.Hello++; + break; + + case PackageType.ByeBye: + Common.PackageReceived.ByeBye++; + Common.ProcessByeByeMessage(package); + break; + + case PackageType.Clipboard: + Common.PackageReceived.Clipboard++; + if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop) + { + Common.clipboardCopiedTime = Common.GetTick(); + GetNameOfMachineWithClipboardData(package); + SignalBigClipboardData(); + } + + break; + + case PackageType.MachineSwitched: + if (Common.GetTick() - Common.clipboardCopiedTime < Common.BIG_CLIPBOARD_DATA_TIMEOUT && (package.Des == Common.MachineID)) + { + Common.clipboardCopiedTime = 0; + Common.GetRemoteClipboard("PackageType.MachineSwitched"); + } + + break; + + case PackageType.ClipboardCapture: + Common.PackageReceived.Clipboard++; + if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop) + { + if (package.Des == Common.MachineID || package.Des == ID.ALL) + { + GetNameOfMachineWithClipboardData(package); + Common.GetRemoteClipboard("mspaint," + Common.LastMachineWithClipboardData); + } + } + + break; + + case PackageType.CaptureScreenCommand: + Common.PackageReceived.Clipboard++; + if (package.Des == Common.MachineID || package.Des == ID.ALL) + { + Common.SendImage(package.Src, Common.CaptureScreen()); + } + + break; + + case PackageType.ClipboardAsk: + Common.PackageReceived.ClipboardAsk++; + + if (package.Des == Common.MachineID) + { + _ = Task.Run(() => + { + try + { + System.Threading.Thread thread = Thread.CurrentThread; + thread.Name = $"{nameof(PackageType.ClipboardAsk)}.{thread.ManagedThreadId}"; + Thread.UpdateThreads(thread); + + string remoteMachine = package.MachineName; + System.Net.Sockets.TcpClient client = Common.ConnectToRemoteClipboardSocket(remoteMachine); + bool clientPushData = true; + + if (Common.ShakeHand(ref remoteMachine, client.Client, out Stream enStream, out Stream deStream, ref clientPushData, ref package.PostAction)) + { + SocketStuff.SendClipboardData(client.Client, enStream); + } + } + catch (Exception e) + { + Logger.Log(e); + } + }); + } + + break; + + case PackageType.ClipboardDragDrop: + Common.PackageReceived.ClipboardDragDrop++; + Common.DragDropStep08(package); + break; + + case PackageType.ClipboardDragDropOperation: + Common.PackageReceived.ClipboardDragDrop++; + Common.DragDropStep08_2(package); + break; + + case PackageType.ClipboardDragDropEnd: + Common.PackageReceived.ClipboardDragDropEnd++; + Common.DragDropStep12(); + break; + + case PackageType.ClipboardText: + case PackageType.ClipboardImage: + Common.clipboardCopiedTime = 0; + if (package.Type == PackageType.ClipboardImage) + { + Common.PackageReceived.ClipboardImage++; + } + else + { + Common.PackageReceived.ClipboardText++; + } + + if (tcp != null) + { + Common.ReceiveClipboardDataUsingTCP( + package, + package.Type == PackageType.ClipboardImage, + tcp); + } + + break; + + case PackageType.HideMouse: + Common.HasSwitchedMachineSinceLastCopy = true; + Common.HideMouseCursor(true); + Common.MainFormDotEx(false); + Common.ReleaseAllKeys(); + break; + + default: + if ((package.Type & PackageType.Matrix) == PackageType.Matrix) + { + Common.PackageReceived.Matrix++; + Common.UpdateMachineMatrix(package); + break; + } + else + { + // We should never get to this point! + Logger.Log("Invalid package received!"); + return; + } + } + } + + internal static void GetNameOfMachineWithClipboardData(DATA package) + { + Common.LastIDWithClipboardData = package.Src; + List matchingMachines = Common.MachinePool.TryFindMachineByID(Common.LastIDWithClipboardData); + if (matchingMachines.Count >= 1) + { + Common.LastMachineWithClipboardData = matchingMachines[0].Name.Trim(); + } + + /* + lastMachineWithClipboardData = + Common.GetString(BitConverter.GetBytes(package.machineNameHead)); + lastMachineWithClipboardData += + Common.GetString(BitConverter.GetBytes(package.machineNameTail)); + lastMachineWithClipboardData = lastMachineWithClipboardData.Trim(); + * */ + } + + private static void SignalBigClipboardData() + { + Logger.LogDebug("SignalBigClipboardData"); + Common.SetToggleIcon(new int[Common.TOGGLE_ICONS_SIZE] { Common.ICON_BIG_CLIPBOARD, -1, Common.ICON_BIG_CLIPBOARD, -1 }); + } +} diff --git a/src/modules/MouseWithoutBorders/App/Core/Thread.cs b/src/modules/MouseWithoutBorders/App/Core/Thread.cs new file mode 100644 index 000000000000..1ce276e9034f --- /dev/null +++ b/src/modules/MouseWithoutBorders/App/Core/Thread.cs @@ -0,0 +1,105 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.Threading; + +// +// Logging. +// +// +// 2008 created by Truong Do (ductdo). +// 2009-... modified by Truong Do (TruongDo). +// 2023- Included in PowerToys. +// +namespace MouseWithoutBorders.Core; + +internal sealed class Thread +{ + private static readonly Lock ThreadsLock = new(); + private static List threads; + + private readonly System.Threading.Thread thread; + + internal Thread(ThreadStart callback, string name) + { + UpdateThreads(thread = new System.Threading.Thread(callback) { Name = name }); + } + + internal Thread(ParameterizedThreadStart callback, string name) + { + UpdateThreads(thread = new System.Threading.Thread(callback) { Name = name }); + } + + internal static void UpdateThreads(System.Threading.Thread thread) + { + lock (ThreadsLock) + { + bool found = false; + List toBeRemovedThreads = new(); + threads ??= new List(); + + foreach (System.Threading.Thread t in threads) + { + if (!t.IsAlive) + { + toBeRemovedThreads.Add(t); + } + else if (t.ManagedThreadId == thread.ManagedThreadId) + { + found = true; + } + } + + foreach (System.Threading.Thread t in toBeRemovedThreads) + { + _ = threads.Remove(t); + } + + if (!found) + { + threads.Add(thread); + } + } + } + + internal static string DumpThreadsStack() + { + string stack = "\r\nMANAGED THREADS: " + threads.Count.ToString(CultureInfo.InvariantCulture) + "\r\n"; + stack += Logger.GetStackTrace(new StackTrace()); + return stack; + } + + internal void SetApartmentState(ApartmentState apartmentState) + { + thread.SetApartmentState(apartmentState); + } + + internal void Start() + { + thread.Start(); + } + + internal void Start(object parameter) + { + thread.Start(parameter); + } + + internal static void Sleep(int millisecondsTimeout) + { + System.Threading.Thread.Sleep(millisecondsTimeout); + } + + internal static System.Threading.Thread CurrentThread => System.Threading.Thread.CurrentThread; + + internal ThreadPriority Priority + { + get => thread.Priority; + set => thread.Priority = value; + } + + internal System.Threading.ThreadState ThreadState => thread.ThreadState; +} diff --git a/src/modules/MouseWithoutBorders/MouseWithoutBorders.UnitTests/Core/Logger.PrivateDump.expected.txt b/src/modules/MouseWithoutBorders/MouseWithoutBorders.UnitTests/Core/Logger.PrivateDump.expected.txt index 1a20c67b31d6..dddef136c481 100644 --- a/src/modules/MouseWithoutBorders/MouseWithoutBorders.UnitTests/Core/Logger.PrivateDump.expected.txt +++ b/src/modules/MouseWithoutBorders/MouseWithoutBorders.UnitTests/Core/Logger.PrivateDump.expected.txt @@ -4,20 +4,28 @@ [Other Logs] =============== = MouseWithoutBorders.Common -lastClipboardEventTime = 0 -clipboardCopiedTime = 0 Comma = System.Char[] --System.Char[] = System.Char[]: N/A Star = System.Char[] --System.Char[] = System.Char[]: N/A NullSeparator = System.Char[] --System.Char[] = System.Char[]: N/A +lastClipboardEventTime = 0 +clipboardCopiedTime = 0 k__BackingField = NONE k__BackingField = 0 k__BackingField = False lastClipboardObject = k__BackingField = False -ClipboardThreadOldLock = O +ClipboardThreadOldLock = Lock +--_owningThreadId = 0 +--_state = 0 +--_recursionCount = 0 +--_spinCount = 22 +--_waiterStartTimeMs = 0 +--s_contentionCount = 0 +--s_maxSpinCount = 22 +--s_minSpinCountForAdaptiveSpin = -100 screenWidth = 0 screenHeight = 0 lastX = 0 @@ -43,7 +51,15 @@ socketMutexBalance = 0 k__BackingField = False k__BackingField = 0 k__BackingField = 0 -InputSimulationLock = O +InputSimulationLock = Lock +--_owningThreadId = 0 +--_state = 0 +--_recursionCount = 0 +--_spinCount = 22 +--_waiterStartTimeMs = 0 +--s_contentionCount = 0 +--s_maxSpinCount = 22 +--s_minSpinCountForAdaptiveSpin = -100 lastSendNextMachine = 0 lastInputEventCount = 0 lastRealInputEventCount = 0 @@ -85,15 +101,7 @@ LegalKeyDictionary = Concurrent.ConcurrentDictionary`2[System.String,System.Byte ------[5] = 0 ------[6] = 0 ------[7] = 0 -------[8] = 0 -------[9] = 0 -------[10] = 0 -------[11] = 0 -------[12] = 0 -------[13] = 0 -------[14] = 0 -------[15] = 0 ---_budget = 2 +--_budget = ???????????? --_growLockArray = True --_comparerIsDefaultForClasses = False KeybdPackage = MouseWithoutBorders.DATA @@ -155,7 +163,15 @@ ReopenSocketDueToReadError = False --MaxValue = 31/12/9999 23:59:59 --UnixEpoch = 01/01/1970 00:00:00 lastReleaseAllKeysCall = 0 -McMatrixLock = O +McMatrixLock = Lock +--_owningThreadId = 0 +--_state = 0 +--_recursionCount = 0 +--_spinCount = 22 +--_waiterStartTimeMs = 0 +--s_contentionCount = 0 +--s_maxSpinCount = 22 +--s_minSpinCountForAdaptiveSpin = -100 desMachineID = NONE DesMachineName = newDesMachineID = NONE @@ -207,66 +223,6 @@ PackageReceived = MouseWithoutBorders.PackageMonitor --ExplorerDragDrop = 0 --Nil = 0 PackageID = 0 -QUEUE_SIZE = 50 -RecentProcessedPackageIDs = 32[] ---[0] = 0 ---[1] = 0 ---[2] = 0 ---[3] = 0 ---[4] = 0 ---[5] = 0 ---[6] = 0 ---[7] = 0 ---[8] = 0 ---[9] = 0 ---[10] = 0 ---[11] = 0 ---[12] = 0 ---[13] = 0 ---[14] = 0 ---[15] = 0 ---[16] = 0 ---[17] = 0 ---[18] = 0 ---[19] = 0 ---[20] = 0 ---[21] = 0 ---[22] = 0 ---[23] = 0 ---[24] = 0 ---[25] = 0 ---[26] = 0 ---[27] = 0 ---[28] = 0 ---[29] = 0 ---[30] = 0 ---[31] = 0 ---[32] = 0 ---[33] = 0 ---[34] = 0 ---[35] = 0 ---[36] = 0 ---[37] = 0 ---[38] = 0 ---[39] = 0 ---[40] = 0 ---[41] = 0 ---[42] = 0 ---[43] = 0 ---[44] = 0 ---[45] = 0 ---[46] = 0 ---[47] = 0 ---[48] = 0 ---[49] = 0 -recentProcessedPackageIndex = 0 -processedPackageCount = 0 -skippedPackageCount = 0 -k__BackingField = 0 -lastXY = {X=0,Y=0} ---x = 0 ---y = 0 ---Empty = {X=0,Y=0} shownErrMessage = False lastStartServiceTime = ???????????? --_dateData = ???????????? @@ -334,9 +290,17 @@ WM_KEYDOWN = 256 WM_KEYUP = 257 WM_SYSKEYDOWN = 260 WM_SYSKEYUP = 261 -[Logger Logs] +[Logger] =============== -AllLogsLock = O +AllLogsLock = Lock +--_owningThreadId = 0 +--_state = 0 +--_recursionCount = 0 +--_spinCount = 22 +--_waiterStartTimeMs = 0 +--s_contentionCount = 0 +--s_maxSpinCount = 22 +--s_minSpinCountForAdaptiveSpin = -100 LogCounter = Concurrent.ConcurrentDictionary`2[System.String,32] --_tables = Concurrent.ConcurrentDictionary`2+Tables[System.String,32] ----_comparer = Generic.NonRandomizedStringEqualityComparer+OrdinalComparer @@ -354,15 +318,7 @@ LogCounter = Concurrent.ConcurrentDictionary`2[System.String,32] ------[5] = 0 ------[6] = 0 ------[7] = 0 -------[8] = 0 -------[9] = 0 -------[10] = 0 -------[11] = 0 -------[12] = 0 -------[13] = 0 -------[14] = 0 -------[15] = 0 ---_budget = 2 +--_budget = ???????????? --_growLockArray = True --_comparerIsDefaultForClasses = False allLogsIndex = 0 @@ -402,3 +358,65 @@ MAX_LOG = 10000 MaxLogExceptionPerHour = 1000 HeaderSENT = Be{0},Ke{1},Mo{2},He{3},Mx{4},Tx{5},Im{6},By{7},Cl{8},Dr{9},De{10},Ed{11},Ie{12},Ni{13} HeaderRECEIVED = Be{0},Ke{1},Mo{2},He{3},Mx{4},Tx{5},Im{6},By{7},Cl{8},Dr{9},De{10},Ed{11},In{12},Ni{13},Pc{14}/{15} +[Receiver] +=============== +QUEUE_SIZE = 50 +RecentProcessedPackageIDs = 32[] +--[0] = 0 +--[1] = 0 +--[2] = 0 +--[3] = 0 +--[4] = 0 +--[5] = 0 +--[6] = 0 +--[7] = 0 +--[8] = 0 +--[9] = 0 +--[10] = 0 +--[11] = 0 +--[12] = 0 +--[13] = 0 +--[14] = 0 +--[15] = 0 +--[16] = 0 +--[17] = 0 +--[18] = 0 +--[19] = 0 +--[20] = 0 +--[21] = 0 +--[22] = 0 +--[23] = 0 +--[24] = 0 +--[25] = 0 +--[26] = 0 +--[27] = 0 +--[28] = 0 +--[29] = 0 +--[30] = 0 +--[31] = 0 +--[32] = 0 +--[33] = 0 +--[34] = 0 +--[35] = 0 +--[36] = 0 +--[37] = 0 +--[38] = 0 +--[39] = 0 +--[40] = 0 +--[41] = 0 +--[42] = 0 +--[43] = 0 +--[44] = 0 +--[45] = 0 +--[46] = 0 +--[47] = 0 +--[48] = 0 +--[49] = 0 +recentProcessedPackageIndex = 0 +processedPackageCount = 0 +skippedPackageCount = 0 +k__BackingField = 0 +lastXY = {X=0,Y=0} +--x = 0 +--y = 0 +--Empty = {X=0,Y=0} diff --git a/src/modules/MouseWithoutBorders/MouseWithoutBorders.UnitTests/Core/LoggerTests.cs b/src/modules/MouseWithoutBorders/MouseWithoutBorders.UnitTests/Core/LoggerTests.cs index be960b9a9b92..a3d3a173f185 100644 --- a/src/modules/MouseWithoutBorders/MouseWithoutBorders.UnitTests/Core/LoggerTests.cs +++ b/src/modules/MouseWithoutBorders/MouseWithoutBorders.UnitTests/Core/LoggerTests.cs @@ -62,6 +62,7 @@ static string NormalizeLog(string log) "lastJump = ", "lastStartServiceTime = ", "InitialIV = ", + "--_budget = ", }; for (var i = 0; i < lines.Length; i++) { @@ -89,6 +90,10 @@ static string NormalizeLog(string log) "------[13] = 0", "------[14] = 0", "------[15] = 0", + "------[16] = 0", + "------[17] = 0", + "------[18] = 0", + "------[19] = 0", }; lines = lines.Where(line => !removeLines.Contains(line)).ToArray(); @@ -113,8 +118,10 @@ static string NormalizeLog(string log) var sb = new StringBuilder(1000000); _ = Logger.PrivateDump(sb, Logger.AllLogs, "[Program logs]\r\n===============\r\n", 0, settingsDumpObjectsLevel, false); _ = Logger.PrivateDump(sb, new Common(), "[Other Logs]\r\n===============\r\n", 0, settingsDumpObjectsLevel, false); - sb.AppendLine("[Logger Logs]\r\n==============="); + sb.AppendLine("[Logger]\r\n==============="); Logger.DumpType(sb, typeof(Logger), 0, settingsDumpObjectsLevel); + sb.AppendLine("[Receiver]\r\n==============="); + Logger.DumpType(sb, typeof(Receiver), 0, settingsDumpObjectsLevel); var actual = sb.ToString(); expected = NormalizeLog(expected); @@ -146,8 +153,6 @@ static string NormalizeLog(string log) message.AppendLine(CultureInfo.InvariantCulture, $"[{j}]: {expectedLines[j]}:"); } - var x = new ConcurrentDictionary(-1, 16); - Assert.Fail(message.ToString()); } } diff --git a/src/modules/Workspaces/WindowProperties/WorkspacesWindowPropertyUtils.h b/src/modules/Workspaces/WindowProperties/WorkspacesWindowPropertyUtils.h index 1c1ddeb6f47f..2cd1d5488dca 100644 --- a/src/modules/Workspaces/WindowProperties/WorkspacesWindowPropertyUtils.h +++ b/src/modules/Workspaces/WindowProperties/WorkspacesWindowPropertyUtils.h @@ -7,10 +7,70 @@ namespace WorkspacesWindowProperties namespace Properties { const wchar_t LaunchedByWorkspacesID[] = L"PowerToys_LaunchedByWorkspaces"; + const wchar_t WorkspacesAppID[] = L"PowerToys_WorkspacesAppId"; } inline void StampWorkspacesLaunchedProperty(HWND window) { ::SetPropW(window, Properties::LaunchedByWorkspacesID, reinterpret_cast(1)); } + + inline void StampWorkspacesGuidProperty(HWND window, const std::wstring& appId) + { + GUID guid; + HRESULT hr = CLSIDFromString(appId.c_str(), static_cast (&guid)); + if (hr != S_OK) + { + return; + } + + const size_t workspacesAppIDLength = wcslen(Properties::WorkspacesAppID); + wchar_t* workspacesAppIDPart = new wchar_t[workspacesAppIDLength + 2]; + std::memcpy(&workspacesAppIDPart[0], &Properties::WorkspacesAppID, workspacesAppIDLength * sizeof(wchar_t)); + workspacesAppIDPart[workspacesAppIDLength + 1] = 0; + + // the size of the HANDLE type can vary on different systems: 4 or 8 bytes. As we can set only a HANDLE as a property, we need more properties (2 or 4) to be able to store a GUID (16 bytes) + const int numberOfProperties = sizeof(GUID) / sizeof(HANDLE); + + uint64_t parts[numberOfProperties]; + std::memcpy(&parts[0], &guid, sizeof(GUID)); + for (unsigned char partIndex = 0; partIndex < numberOfProperties; partIndex++) + { + workspacesAppIDPart[workspacesAppIDLength] = '0' + partIndex; + ::SetPropW(window, workspacesAppIDPart, reinterpret_cast(parts[partIndex])); + } + } + + inline const std::wstring GetGuidFromHwnd(HWND window) + { + const size_t workspacesAppIDLength = wcslen(Properties::WorkspacesAppID); + wchar_t* workspacesAppIDPart = new wchar_t[workspacesAppIDLength + 2]; + std::memcpy(&workspacesAppIDPart[0], &Properties::WorkspacesAppID, workspacesAppIDLength * sizeof(wchar_t)); + workspacesAppIDPart[workspacesAppIDLength + 1] = 0; + + // the size of the HANDLE type can vary on different systems: 4 or 8 bytes. As we can set only a HANDLE as a property, we need more properties (2 or 4) to be able to store a GUID (16 bytes) + const int numberOfProperties = sizeof(GUID) / sizeof(HANDLE); + + uint64_t parts[numberOfProperties]; + for (unsigned char partIndex = 0; partIndex < numberOfProperties; partIndex++) + { + workspacesAppIDPart[workspacesAppIDLength] = '0' + partIndex; + HANDLE rawData = GetPropW(window, workspacesAppIDPart); + if (rawData) + { + parts[partIndex] = reinterpret_cast(rawData); + } + else + { + return L""; + } + } + + GUID guid; + std::memcpy(&guid, &parts[0], sizeof(GUID)); + WCHAR* guidString; + StringFromCLSID(guid, &guidString); + + return guidString; + } } diff --git a/src/modules/Workspaces/WorkspacesEditor/MainWindow.xaml.cs b/src/modules/Workspaces/WorkspacesEditor/MainWindow.xaml.cs index 8f9944cc9034..f5fc7bcac609 100644 --- a/src/modules/Workspaces/WorkspacesEditor/MainWindow.xaml.cs +++ b/src/modules/Workspaces/WorkspacesEditor/MainWindow.xaml.cs @@ -3,10 +3,11 @@ // See the LICENSE file in the project root for more information. using System; +using System.Drawing; +using System.Linq; using System.Threading; using System.Windows; using System.Windows.Interop; - using ManagedCommon; using Microsoft.PowerToys.Telemetry; using WorkspacesEditor.Utils; @@ -30,9 +31,9 @@ public MainWindow(MainViewModel mainViewModel) MainViewModel = mainViewModel; mainViewModel.SetMainWindow(this); - if (Properties.Settings.Default.Height == -1) + if (Properties.Settings.Default.Height == -1 || !IsEditorInsideVisibleArea()) { - // This is the very first time the window is created. Place it on the screen center + // This is the very first time the window is created or it would be placed outside the visible area (monitor rearrangement). Place it on the screen center WindowInteropHelper windowInteropHelper = new WindowInteropHelper(this); System.Windows.Forms.Screen screen = System.Windows.Forms.Screen.FromHandle(windowInteropHelper.Handle); double dpi = MonitorHelper.GetScreenDpiFromScreen(screen); @@ -88,6 +89,20 @@ public MainWindow(MainViewModel mainViewModel) cancellationToken.Token); } + private bool IsEditorInsideVisibleArea() + { + System.Windows.Forms.Screen[] allScreens = MonitorHelper.GetDpiUnawareScreens(); + Rectangle commonBounds = allScreens[0].Bounds; + for (int screenIndex = 1; screenIndex < allScreens.Length; screenIndex++) + { + Rectangle rectangle = allScreens[screenIndex].Bounds; + commonBounds = Rectangle.Union(rectangle, commonBounds); + } + + Rectangle editorBounds = new Rectangle((int)Properties.Settings.Default.Left, (int)Properties.Settings.Default.Top, (int)Properties.Settings.Default.Width, (int)Properties.Settings.Default.Height); + return editorBounds.IntersectsWith(commonBounds); + } + private void SavePosition() { if (WindowState == WindowState.Maximized) diff --git a/src/modules/Workspaces/WorkspacesEditor/Models/Project.cs b/src/modules/Workspaces/WorkspacesEditor/Models/Project.cs index 0c44440d394e..860f78c9d81d 100644 --- a/src/modules/Workspaces/WorkspacesEditor/Models/Project.cs +++ b/src/modules/Workspaces/WorkspacesEditor/Models/Project.cs @@ -342,12 +342,22 @@ private Rectangle GetCommonBounds() return new Rectangle((int)minX, (int)minY, (int)(maxX - minX), (int)(maxY - minY)); } - public void UpdateAfterLaunchAndEdit(Project other) + public void UpdateAfterLaunchAndEdit(Project projectBeforeLaunch) { - Id = other.Id; - Name = other.Name; + Id = projectBeforeLaunch.Id; + Name = projectBeforeLaunch.Name; IsRevertEnabled = true; - MoveExistingWindows = other.MoveExistingWindows; + MoveExistingWindows = projectBeforeLaunch.MoveExistingWindows; + foreach (Application app in Applications) + { + var sameAppBefore = projectBeforeLaunch.Applications.Where(x => x.Id.Equals(app.Id, StringComparison.OrdinalIgnoreCase)); + if (sameAppBefore.Any()) + { + var appBefore = sameAppBefore.FirstOrDefault(); + app.CommandLineArguments = appBefore.CommandLineArguments; + app.IsElevated = appBefore.IsElevated; + } + } } internal void CloseExpanders() diff --git a/src/modules/Workspaces/WorkspacesEditor/ViewModels/MainViewModel.cs b/src/modules/Workspaces/WorkspacesEditor/ViewModels/MainViewModel.cs index ccee84c9c516..b0974e12411c 100644 --- a/src/modules/Workspaces/WorkspacesEditor/ViewModels/MainViewModel.cs +++ b/src/modules/Workspaces/WorkspacesEditor/ViewModels/MainViewModel.cs @@ -40,6 +40,7 @@ public class MainViewModel : INotifyPropertyChanged, IDisposable private Timer lastUpdatedTimer; private WorkspacesSettings settings; private PwaHelper _pwaHelper; + private bool _isExistingProjectLaunched; public ObservableCollection Workspaces { get; set; } = new ObservableCollection(); @@ -256,12 +257,12 @@ public async void SnapWorkspace() { CancelSnapshot(); - await Task.Run(() => RunSnapshotTool()); + await Task.Run(() => RunSnapshotTool(_isExistingProjectLaunched)); Project project = _workspacesEditorIO.ParseTempProject(); if (project != null) { - if (editedProject != null) + if (_isExistingProjectLaunched) { project.UpdateAfterLaunchAndEdit(projectBeforeLaunch); project.EditorWindowTitle = Properties.Resources.EditWorkspace; @@ -431,15 +432,12 @@ private void LastUpdatedTimerElapsed(object sender, ElapsedEventArgs e) } } - private void RunSnapshotTool(string filename = null) + private void RunSnapshotTool(bool isExistingProjectLaunched) { Process process = new Process(); process.StartInfo = new ProcessStartInfo(@".\PowerToys.WorkspacesSnapshotTool.exe"); process.StartInfo.CreateNoWindow = true; - if (!string.IsNullOrEmpty(filename)) - { - process.StartInfo.Arguments = filename; - } + process.StartInfo.Arguments = isExistingProjectLaunched ? $"{(int)InvokePoint.LaunchAndEdit}" : string.Empty; try { @@ -484,6 +482,7 @@ internal void CloseAllPopups() internal void EnterSnapshotMode(bool isExistingProjectLaunched) { + _isExistingProjectLaunched = isExistingProjectLaunched; _mainWindow.WindowState = System.Windows.WindowState.Minimized; _overlayWindows.Clear(); foreach (var screen in MonitorHelper.GetDpiUnawareScreens()) diff --git a/src/modules/Workspaces/WorkspacesLib/AppUtils.cpp b/src/modules/Workspaces/WorkspacesLib/AppUtils.cpp index 9805dd3fe852..19b33214b7f2 100644 --- a/src/modules/Workspaces/WorkspacesLib/AppUtils.cpp +++ b/src/modules/Workspaces/WorkspacesLib/AppUtils.cpp @@ -397,6 +397,5 @@ namespace Utils { return installPath.ends_with(NonLocalizable::ChromeFilename); } - } } \ No newline at end of file diff --git a/src/modules/Workspaces/WorkspacesLib/utils.h b/src/modules/Workspaces/WorkspacesLib/utils.h index 971900d8ec0c..da836ccabc10 100644 --- a/src/modules/Workspaces/WorkspacesLib/utils.h +++ b/src/modules/Workspaces/WorkspacesLib/utils.h @@ -40,17 +40,6 @@ CommandLineArgs split(std::wstring s, const std::wstring& delimiter) { cmdArgs.isRestarted = true; } - else if (!cmdArgs.workspaceId.empty()) - { - try - { - auto invokePoint = static_cast(std::stoi(token)); - cmdArgs.invokePoint = invokePoint; - } - catch (std::exception) - { - } - } else { auto guid = GuidFromString(token); @@ -58,6 +47,17 @@ CommandLineArgs split(std::wstring s, const std::wstring& delimiter) { cmdArgs.workspaceId = token; } + else + { + try + { + auto invokePoint = static_cast(std::stoi(token)); + cmdArgs.invokePoint = invokePoint; + } + catch (std::exception) + { + } + } } } diff --git a/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.cpp b/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.cpp index ddbf0f3cf780..79f19219b3e9 100644 --- a/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.cpp +++ b/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -10,6 +11,9 @@ #include #include +#include + +#include "Generated Files/resource.h" #pragma comment(lib, "ntdll.lib") @@ -38,7 +42,7 @@ namespace SnapshotUtils return false; } - std::vector GetApps(const std::function getMonitorNumberFromWindowHandle, const std::function getMonitorRect) + std::vector GetApps(bool isGuidNeeded, const std::function getMonitorNumberFromWindowHandle, const std::function getMonitorRect) { Utils::PwaHelper pwaHelper{}; std::vector apps{}; @@ -73,10 +77,12 @@ namespace SnapshotUtils // Notify the user that running as admin is required to process elevated windows. if (!is_process_elevated() && IsProcessElevated(pid)) { - notifications::WarnIfElevationIsRequired(GET_RESOURCE_STRING(IDS_PROJECTS), - GET_RESOURCE_STRING(IDS_SYSTEM_FOREGROUND_ELEVATED), - GET_RESOURCE_STRING(IDS_SYSTEM_FOREGROUND_ELEVATED_LEARN_MORE), - GET_RESOURCE_STRING(IDS_SYSTEM_FOREGROUND_ELEVATED_DIALOG_DONT_SHOW_AGAIN)); + auto notificationUtil = std::make_unique(); + + notificationUtil->WarnIfElevationIsRequired(GET_RESOURCE_STRING(IDS_PROJECTS), + GET_RESOURCE_STRING(IDS_SYSTEM_FOREGROUND_ELEVATED), + GET_RESOURCE_STRING(IDS_SYSTEM_FOREGROUND_ELEVATED_LEARN_MORE), + GET_RESOURCE_STRING(IDS_SYSTEM_FOREGROUND_ELEVATED_DIALOG_DONT_SHOW_AGAIN)); } continue; @@ -157,7 +163,10 @@ namespace SnapshotUtils rect.bottom = monitorRect.top + monitorRect.height; } + std::wstring guid = isGuidNeeded ? WorkspacesWindowProperties::GetGuidFromHwnd(window) : L""; + WorkspacesData::WorkspacesProject::Application app{ + .id = guid, .name = appData.name, .title = title, .path = appData.installPath, diff --git a/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.h b/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.h index df95bbadf39c..ad69e1e7e4b5 100644 --- a/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.h +++ b/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.h @@ -4,5 +4,5 @@ namespace SnapshotUtils { - std::vector GetApps(const std::function getMonitorNumberFromWindowHandle, const std::function getMonitorRect); + std::vector GetApps(bool isGuidNeeded, const std::function getMonitorNumberFromWindowHandle, const std::function getMonitorRect); }; diff --git a/src/modules/Workspaces/WorkspacesSnapshotTool/main.cpp b/src/modules/Workspaces/WorkspacesSnapshotTool/main.cpp index 8a99ea6ef580..44456be307d4 100644 --- a/src/modules/Workspaces/WorkspacesSnapshotTool/main.cpp +++ b/src/modules/Workspaces/WorkspacesSnapshotTool/main.cpp @@ -13,6 +13,7 @@ #include #include #include +#include const std::wstring moduleName = L"Workspaces\\WorkspacesSnapshotTool"; const std::wstring internalPath = L""; @@ -46,13 +47,17 @@ int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, LPSTR cmdLine, int cm return -1; } + std::wstring cmdLineStr{ GetCommandLineW() }; + auto cmdArgs = split(cmdLineStr, L" "); + // create new project time_t creationTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); WorkspacesData::WorkspacesProject project{ .id = CreateGuidString(), .creationTime = creationTime }; Logger::trace(L"Creating workspace {}:{}", project.name, project.id); project.monitors = MonitorUtils::IdentifyMonitors(); - project.apps = SnapshotUtils::GetApps([&](HWND window) -> unsigned int { + bool isGuidNeeded = cmdArgs.invokePoint == InvokePoint::LaunchAndEdit; + project.apps = SnapshotUtils::GetApps(isGuidNeeded, [&](HWND window) -> unsigned int { auto windowMonitor = MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY); unsigned int monitorNumber = 0; for (const auto& monitor : project.monitors) diff --git a/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.cpp b/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.cpp index 06d4fba7801d..272602288970 100644 --- a/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.cpp +++ b/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.cpp @@ -460,6 +460,7 @@ bool WindowArranger::moveWindow(HWND window, const WorkspacesData::WorkspacesPro if (PlacementHelper::SizeWindowToRect(window, currentMonitor, launchMinimized, launchMaximized, rect)) { WorkspacesWindowProperties::StampWorkspacesLaunchedProperty(window); + WorkspacesWindowProperties::StampWorkspacesGuidProperty(window, app.id); Logger::trace(L"Placed {} to ({},{}) [{}x{}]", app.name, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); return true; } diff --git a/src/modules/Workspaces/workspaces-common/GuidUtils.h b/src/modules/Workspaces/workspaces-common/GuidUtils.h index acab157938f7..f7b1cff768d2 100644 --- a/src/modules/Workspaces/workspaces-common/GuidUtils.h +++ b/src/modules/Workspaces/workspaces-common/GuidUtils.h @@ -1,3 +1,5 @@ +#pragma once + #include inline std::optional GuidFromString(const std::wstring& str) noexcept diff --git a/src/modules/ZoomIt/ZoomIt/AudioSampleGenerator.cpp b/src/modules/ZoomIt/ZoomIt/AudioSampleGenerator.cpp new file mode 100644 index 000000000000..21e9883bb738 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/AudioSampleGenerator.cpp @@ -0,0 +1,168 @@ +#include "pch.h" +#include "AudioSampleGenerator.h" +#include "CaptureFrameWait.h" + +extern TCHAR g_MicrophoneDeviceId[]; + +namespace winrt +{ + using namespace Windows::Foundation; + using namespace Windows::Storage; + using namespace Windows::Storage::Streams; + using namespace Windows::Media; + using namespace Windows::Media::Audio; + using namespace Windows::Media::Capture; + using namespace Windows::Media::Core; + using namespace Windows::Media::Render; + using namespace Windows::Media::MediaProperties; + using namespace Windows::Media::Devices; + using namespace Windows::Devices::Enumeration; +} + +AudioSampleGenerator::AudioSampleGenerator() +{ + m_audioEvent.create(wil::EventOptions::ManualReset); + m_endEvent.create(wil::EventOptions::ManualReset); + m_asyncInitialized.create(wil::EventOptions::ManualReset); +} + +AudioSampleGenerator::~AudioSampleGenerator() +{ + Stop(); + if (m_started.load()) + { + m_audioGraph.Close(); + } +} + +winrt::IAsyncAction AudioSampleGenerator::InitializeAsync() +{ + auto expected = false; + if (m_initialized.compare_exchange_strong(expected, true)) + { + // Initialize the audio graph + auto audioGraphSettings = winrt::AudioGraphSettings(winrt::AudioRenderCategory::Media); + auto audioGraphResult = co_await winrt::AudioGraph::CreateAsync(audioGraphSettings); + if (audioGraphResult.Status() != winrt::AudioGraphCreationStatus::Success) + { + throw winrt::hresult_error(E_FAIL, L"Failed to initialize AudioGraph!"); + } + m_audioGraph = audioGraphResult.Graph(); + + // Initialize the selected microphone + auto defaultMicrophoneId = winrt::MediaDevice::GetDefaultAudioCaptureId(winrt::AudioDeviceRole::Default); + auto microphoneId = (g_MicrophoneDeviceId[0] == 0) ? defaultMicrophoneId : winrt::to_hstring(g_MicrophoneDeviceId); + auto microphone = co_await winrt::DeviceInformation::CreateFromIdAsync(microphoneId); + + // Initialize audio input and output nodes + auto inputNodeResult = co_await m_audioGraph.CreateDeviceInputNodeAsync(winrt::MediaCategory::Media, m_audioGraph.EncodingProperties(), microphone); + if (inputNodeResult.Status() != winrt::AudioDeviceNodeCreationStatus::Success && microphoneId != defaultMicrophoneId) + { + // If the selected microphone failed, try again with the default + microphone = co_await winrt::DeviceInformation::CreateFromIdAsync(defaultMicrophoneId); + inputNodeResult = co_await m_audioGraph.CreateDeviceInputNodeAsync(winrt::MediaCategory::Media, m_audioGraph.EncodingProperties(), microphone); + } + if (inputNodeResult.Status() != winrt::AudioDeviceNodeCreationStatus::Success) + { + throw winrt::hresult_error(E_FAIL, L"Failed to initialize input audio node!"); + } + m_audioInputNode = inputNodeResult.DeviceInputNode(); + m_audioOutputNode = m_audioGraph.CreateFrameOutputNode(); + + // Hookup audio nodes + m_audioInputNode.AddOutgoingConnection(m_audioOutputNode); + m_audioGraph.QuantumStarted({ this, &AudioSampleGenerator::OnAudioQuantumStarted }); + + m_asyncInitialized.SetEvent(); + } +} + +winrt::AudioEncodingProperties AudioSampleGenerator::GetEncodingProperties() +{ + CheckInitialized(); + return m_audioOutputNode.EncodingProperties(); +} + +std::optional AudioSampleGenerator::TryGetNextSample() +{ + CheckInitialized(); + CheckStarted(); + + { + auto lock = m_lock.lock_exclusive(); + if (m_samples.empty() && m_endEvent.is_signaled()) + { + return std::nullopt; + } + else if (!m_samples.empty()) + { + std::optional result(m_samples.front()); + m_samples.pop_front(); + return result; + } + } + + m_audioEvent.ResetEvent(); + std::vector events = { m_endEvent.get(), m_audioEvent.get() }; + auto waitResult = WaitForMultipleObjectsEx(static_cast(events.size()), events.data(), false, INFINITE, false); + auto eventIndex = -1; + switch (waitResult) + { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + eventIndex = waitResult - WAIT_OBJECT_0; + break; + } + WINRT_VERIFY(eventIndex >= 0); + + auto signaledEvent = events[eventIndex]; + if (signaledEvent == m_endEvent.get()) + { + return std::nullopt; + } + else + { + auto lock = m_lock.lock_exclusive(); + std::optional result(m_samples.front()); + m_samples.pop_front(); + return result; + } +} + +void AudioSampleGenerator::Start() +{ + CheckInitialized(); + auto expected = false; + if (m_started.compare_exchange_strong(expected, true)) + { + m_audioGraph.Start(); + } +} + +void AudioSampleGenerator::Stop() +{ + CheckInitialized(); + if (m_started.load()) + { + m_asyncInitialized.wait(); + m_audioGraph.Stop(); + m_endEvent.SetEvent(); + } +} + +void AudioSampleGenerator::OnAudioQuantumStarted(winrt::AudioGraph const& sender, winrt::IInspectable const& args) +{ + { + auto lock = m_lock.lock_exclusive(); + + auto frame = m_audioOutputNode.GetFrame(); + std::optional timestamp = frame.RelativeTime(); + auto audioBuffer = frame.LockBuffer(winrt::AudioBufferAccessMode::Read); + + auto sampleBuffer = winrt::Buffer::CreateCopyFromMemoryBuffer(audioBuffer); + sampleBuffer.Length(audioBuffer.Length()); + auto sample = winrt::MediaStreamSample::CreateFromBuffer(sampleBuffer, timestamp.value()); + m_samples.push_back(sample); + } + m_audioEvent.SetEvent(); +} diff --git a/src/modules/ZoomIt/ZoomIt/AudioSampleGenerator.h b/src/modules/ZoomIt/ZoomIt/AudioSampleGenerator.h new file mode 100644 index 000000000000..8e279f3b5895 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/AudioSampleGenerator.h @@ -0,0 +1,48 @@ +#pragma once + +class AudioSampleGenerator +{ +public: + AudioSampleGenerator(); + ~AudioSampleGenerator(); + + winrt::Windows::Foundation::IAsyncAction InitializeAsync(); + winrt::Windows::Media::MediaProperties::AudioEncodingProperties GetEncodingProperties(); + + std::optional TryGetNextSample(); + void Start(); + void Stop(); + +private: + void OnAudioQuantumStarted( + winrt::Windows::Media::Audio::AudioGraph const& sender, + winrt::Windows::Foundation::IInspectable const& args); + + void CheckInitialized() + { + if (!m_initialized.load()) + { + throw winrt::hresult_error(E_FAIL, L"Must initialize audio sample generator before use!"); + } + } + + void CheckStarted() + { + if (!m_started.load()) + { + throw winrt::hresult_error(E_FAIL, L"Must start audio sample generator before calling this method!"); + } + } + +private: + winrt::Windows::Media::Audio::AudioGraph m_audioGraph{ nullptr }; + winrt::Windows::Media::Audio::AudioDeviceInputNode m_audioInputNode{ nullptr }; + winrt::Windows::Media::Audio::AudioFrameOutputNode m_audioOutputNode{ nullptr }; + wil::srwlock m_lock; + wil::unique_event m_audioEvent; + wil::unique_event m_endEvent; + wil::unique_event m_asyncInitialized; + std::deque m_samples; + std::atomic m_initialized = false; + std::atomic m_started = false; +}; \ No newline at end of file diff --git a/src/modules/ZoomIt/ZoomIt/CaptureFrameWait.cpp b/src/modules/ZoomIt/ZoomIt/CaptureFrameWait.cpp new file mode 100644 index 000000000000..d4d3fa17502d --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/CaptureFrameWait.cpp @@ -0,0 +1,147 @@ +//============================================================================== +// +// Zoomit +// Sysinternals - www.sysinternals.com +// +// Video capture code derived from https://github.com/robmikh/capturevideosample +// +//============================================================================== +#include "pch.h" +#include "CaptureFrameWait.h" + +namespace winrt +{ + using namespace Windows::Foundation; + using namespace Windows::Graphics; + using namespace Windows::Graphics::Capture; + using namespace Windows::Graphics::DirectX; + using namespace Windows::Graphics::DirectX::Direct3D11; + using namespace Windows::Storage; + using namespace Windows::UI::Composition; +} + +namespace util +{ + using namespace robmikh::common::uwp; +} + +//---------------------------------------------------------------------------- +// +// CaptureFrameWait::CaptureFrameWait +// +//---------------------------------------------------------------------------- +CaptureFrameWait::CaptureFrameWait( + winrt::IDirect3DDevice const& device, + winrt::GraphicsCaptureItem const& item, + winrt::SizeInt32 const& size) +{ + m_device = device; + m_item = item; + + m_nextFrameEvent = wil::shared_event(wil::EventOptions::ManualReset); + m_endEvent = wil::shared_event(wil::EventOptions::ManualReset); + m_closedEvent = wil::shared_event(wil::EventOptions::ManualReset); + + m_framePool = winrt::Direct3D11CaptureFramePool::CreateFreeThreaded( + m_device, + winrt::DirectXPixelFormat::B8G8R8A8UIntNormalized, + 1, + size); + m_session = m_framePool.CreateCaptureSession(m_item); + + m_framePool.FrameArrived({ this, &CaptureFrameWait::OnFrameArrived }); + m_session.StartCapture(); +} + +//---------------------------------------------------------------------------- +// +// CaptureFrameWait::~CaptureFrameWait +// +//---------------------------------------------------------------------------- +CaptureFrameWait::~CaptureFrameWait() +{ + StopCapture(); + // We might end the capture before we ever get another frame. + m_closedEvent.wait(200); +} + +//---------------------------------------------------------------------------- +// +// CaptureFrameWait::TryGetNextFrame +// +// Fetches next available frame +// +//---------------------------------------------------------------------------- +std::optional CaptureFrameWait::TryGetNextFrame() +{ + if (m_currentFrame != nullptr) + { + m_currentFrame.Close(); + } + m_nextFrameEvent.ResetEvent(); + + std::vector events = { m_endEvent.get(), m_nextFrameEvent.get() }; + auto waitResult = WaitForMultipleObjectsEx(static_cast(events.size()), events.data(), false, INFINITE, false); + auto eventIndex = -1; + switch (waitResult) + { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + eventIndex = waitResult - WAIT_OBJECT_0; + break; + } + WINRT_VERIFY(eventIndex >= 0); + + auto signaledEvent = events[eventIndex]; + if (signaledEvent == m_endEvent.get()) + { + return std::nullopt; + } + + return std::optional( + { + m_currentFrame.Surface(), + m_currentFrame.ContentSize(), + m_currentFrame.SystemRelativeTime(), + }); +} + + +//---------------------------------------------------------------------------- +// +// CaptureFrameWait::StopCapture +// +// Stops frame capture and notified any frame waiters +// +//---------------------------------------------------------------------------- +void CaptureFrameWait::StopCapture() +{ + auto lock = m_lock.lock_exclusive(); + m_endEvent.SetEvent(); + m_framePool.Close(); + m_session.Close(); +} + +//---------------------------------------------------------------------------- +// +// CaptureFrameWait::OnFrameArrived +// +// Callback for new frames +// +//---------------------------------------------------------------------------- +void CaptureFrameWait::OnFrameArrived( + winrt::Direct3D11CaptureFramePool const& sender, + winrt::IInspectable const&) +{ + auto lock = m_lock.lock_exclusive(); + if (m_endEvent.is_signaled()) + { + m_closedEvent.SetEvent(); + return; + } + auto frame = sender.TryGetNextFrame(); + if( frame ) { + m_currentFrame = frame; + m_nextFrameEvent.SetEvent(); + } +} diff --git a/src/modules/ZoomIt/ZoomIt/CaptureFrameWait.h b/src/modules/ZoomIt/ZoomIt/CaptureFrameWait.h new file mode 100644 index 000000000000..560acde3ba63 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/CaptureFrameWait.h @@ -0,0 +1,142 @@ +//============================================================================== +// +// Zoomit +// Sysinternals - www.sysinternals.com +// +// Video capture code derived from https://github.com/robmikh/capturevideosample +// +//============================================================================== +#pragma once + +// Must come before C++/WinRT +#include + +// WinRT +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// WIL +#include + +// DirectX +#include +#include +#include +#include + +// STL +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// robmikh.common +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace winrt +{ + using namespace Windows::Foundation; + using namespace Windows::Foundation::Metadata; + using namespace Windows::Graphics; + using namespace Windows::Graphics::Capture; + using namespace Windows::Graphics::DirectX; + using namespace Windows::Graphics::DirectX::Direct3D11; + using namespace Windows::Storage; + using namespace Windows::UI::Composition; + using namespace Windows::Media::Core; + using namespace Windows::Media::Transcoding; + using namespace Windows::Media::MediaProperties; +} + +namespace util +{ + using namespace robmikh::common::uwp; +} + +struct CaptureFrame +{ + winrt::Direct3D11::IDirect3DSurface FrameTexture; + winrt::SizeInt32 ContentSize; + winrt::TimeSpan SystemRelativeTime; +}; + +class CaptureFrameWait +{ +public: + CaptureFrameWait( + winrt::Direct3D11::IDirect3DDevice const& device, + winrt::GraphicsCaptureItem const& item, + winrt::SizeInt32 const& size ); + ~CaptureFrameWait(); + + std::optional TryGetNextFrame(); + void StopCapture(); + void EnableCursorCapture( bool enable = true ) + { + if( winrt::ApiInformation::IsPropertyPresent( winrt::name_of(), L"IsCursorCaptureEnabled" ) ) + { + m_session.IsCursorCaptureEnabled( enable ); + } + } + void ShowCaptureBorder( bool show = true ) + { + if( winrt::ApiInformation::IsPropertyPresent( winrt::name_of(), L"IsBorderRequired" ) ) + { + m_session.IsBorderRequired( show ); + } + } + +private: + void OnFrameArrived( + winrt::Direct3D11CaptureFramePool const& sender, + winrt::IInspectable const& args ); + +private: + winrt::Direct3D11::IDirect3DDevice m_device{ nullptr }; + winrt::GraphicsCaptureItem m_item{ nullptr }; + winrt::Direct3D11CaptureFramePool m_framePool{ nullptr }; + winrt::GraphicsCaptureSession m_session{ nullptr }; + wil::shared_event m_nextFrameEvent; + wil::shared_event m_endEvent; + wil::shared_event m_closedEvent; + wil::srwlock m_lock; + + winrt::Direct3D11CaptureFrame m_currentFrame{ nullptr }; +}; \ No newline at end of file diff --git a/src/modules/ZoomIt/ZoomIt/DemoType.cpp b/src/modules/ZoomIt/ZoomIt/DemoType.cpp new file mode 100644 index 000000000000..40284a795bb1 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/DemoType.cpp @@ -0,0 +1,1447 @@ +//============================================================================ +// +// Zoomit +// Copyright (C) Mark Russinovich +// Sysinternals - www.sysinternals.com +// +// DemoType allows the presenter to synthesize keystrokes from a script +// +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +//============================================================================ + +#include "pch.h" +#include "DemoType.h" + +#define MAX_INDENT_DEPTH 100 + +#define INDENT_SEEK_FLAG L"x" + +#define END_CONTROL_LEN 5 +// Longest accepted control: [pause:000] +#define MAX_CONTROL_LEN 11 + +#define THIRD_TYPING_SPEED static_cast((MIN_TYPING_SPEED - MAX_TYPING_SPEED) / 3) +#define TYPING_VARIANCE ((float) 1.0) + +#define NOTEPAD_REFRESH 1 // ms +#define DEMOTYPE_REFRESH 50 // ms +#define CLIPBOARD_REFRESH 100 // ms +#define DEMOTYPE_TIMEOUT 1000 // ms + +#define INACTIVE_STATE 0 +#define START_STATE 1 +#define INIT_STATE 2 +#define ACTIVE_STATE 3 +#define BLOCK_STATE 4 +#define KILL_STATE 5 + +// Each injection is tracked so that the hook +// procedure can identify injections and allow them +// to pass through while blocking accidental keystrokes. +// +// Each injection is identified by either a virtual +// key code or a unicode character passed as a scan code +// which is wrapped into a VK_PACKET by SendInput when +// the KEYEVENTF_UNICODE flag is specified. +// +// VK_PACKET allows us to synthesize keystrokes which are +// not mapped to virtual-key codes (e.g. foreign characters). +struct Injection +{ + DWORD vkCode; + DWORD scanCode; + + Injection( DWORD vkCode, DWORD scanCode ) + : vkCode(vkCode), scanCode(scanCode) {} +}; + +bool g_UserDriven = false; +bool g_Notepad = false; +bool g_Clipboard = false; +TCHAR g_LastFilePath[MAX_PATH] = {0}; +HHOOK g_hHook = nullptr; +size_t g_TextLen = 0; +wchar_t* g_ClipboardCache = nullptr; +std::wstring g_Text = L""; +std::vector g_TextSegments; +std::wstring g_BaselineIndentation = L""; +std::atomic g_Index = 0; +std::condition_variable g_EpochReady; +std::mutex g_EpochMutex; +std::deque g_Injections; +std::mutex g_InjectionsMutex; +std::atomic g_Active = false; +std::atomic g_End = false; +std::atomic g_Kill = false; +std::atomic g_HookState = INACTIVE_STATE; +std::atomic g_EmitterState = INACTIVE_STATE; +DWORD g_LastClipboardSeq = 0; +DWORD g_SpeedSlider = static_cast(( + (MIN_TYPING_SPEED - MAX_TYPING_SPEED) / 2) + MAX_TYPING_SPEED); + +//---------------------------------------------------------------------------- +// +// IsWindowNotepad +// +//---------------------------------------------------------------------------- +bool IsWindowNotepad( const HWND hwnd ) +{ + const int CLASS_NAME_LEN = 256; + WCHAR className[CLASS_NAME_LEN]; + if( GetClassName( hwnd, className, CLASS_NAME_LEN ) > 0 ) + { + if( wcscmp( className, L"Notepad" ) == 0 ) + { + return true; + } + } + return false; +} + +//---------------------------------------------------------------------------- +// +// IsInjected +// +//---------------------------------------------------------------------------- +bool IsInjected( const DWORD vkCode, const DWORD scanCode ) +{ + bool injected = false; + bool locked = false; + if( g_EmitterState == ACTIVE_STATE ) + { + g_InjectionsMutex.lock(); + locked = true; + } + + if( !g_Injections.empty() ) + { + if( (g_Injections.front().vkCode != NULL && g_Injections.front().vkCode == vkCode) + || (g_Injections.front().vkCode == NULL && g_Injections.front().scanCode == scanCode) ) + { + injected = true; + } + } + + if( locked ) + { + g_InjectionsMutex.unlock(); + } + return injected; +} + +//---------------------------------------------------------------------------- +// +// IsAutoFormatTrigger +// +//---------------------------------------------------------------------------- +bool IsAutoFormatTrigger( wchar_t lastCh, wchar_t ch ) +{ + // Will trigger auto-indentation in smart editors + // '\t' check also handles possible auto-completion + if( ch == L'\n' || ch == L'\t' || (ch == L' ' && lastCh == L'\n') ) + { + return true; + } + + // Will trigger auto-close character(s) in smart editors + if( ch == L'{' || ch == L'[' || ch == L'(' || (ch == L'*' && lastCh == L'/') ) + { + return true; + } + + return false; +} + +//---------------------------------------------------------------------------- +// +// PopInjection +// +// See comments above `Injection` struct definition +// +//---------------------------------------------------------------------------- +void PopInjection() +{ + bool locked = false; + if( g_EmitterState == ACTIVE_STATE ) + { + g_InjectionsMutex.lock(); + locked = true; + } + + g_Injections.pop_front(); + + if( locked ) + { + g_InjectionsMutex.unlock(); + } +} + +//---------------------------------------------------------------------------- +// +// PushInjection +// +// See comments above `Injection` struct definition +// +//---------------------------------------------------------------------------- +void PushInjection( const WORD vK, const wchar_t ch ) +{ + bool locked = false; + if( g_EmitterState == ACTIVE_STATE ) + { + g_InjectionsMutex.lock(); + locked = true; + } + + g_Injections.push_back( Injection( static_cast(vK), static_cast(ch) ) ); + + if( locked ) + { + g_InjectionsMutex.unlock(); + } +} + +//---------------------------------------------------------------------------- +// +// IsNotPrintable +// +//---------------------------------------------------------------------------- +bool IsNotPrintable( wchar_t ch ) +{ + return ch != L'\n' && ch != L'\t' && !iswprint( ch ); +} + +//---------------------------------------------------------------------------- +// +// SendKeyInput +// +//---------------------------------------------------------------------------- +void SendKeyInput( const WORD vK, const wchar_t ch, const bool keyup = false ) +{ + INPUT input = {0}; + input.type = INPUT_KEYBOARD; + + // Send unicode character via VK_PACKET + if( vK == NULL ) + { + input.ki.wScan = ch; + input.ki.dwFlags = KEYEVENTF_UNICODE; + } + // Send virtual-key code + else + { + input.ki.wVk = vK; + + if( vK == VK_RCONTROL || vK == VK_RMENU || vK == VK_LEFT + || vK == VK_RIGHT || vK == VK_UP || vK == VK_DOWN ) + { + input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; + } + } + + if( keyup ) + { + input.ki.dwFlags |= KEYEVENTF_KEYUP; + } + + SendInput( 1, &input, sizeof( INPUT ) ); + + // Add latency between keydown/up to accomodate notepad input handling + if( !keyup && g_Notepad ) + { + std::this_thread::sleep_for( std::chrono::milliseconds( NOTEPAD_REFRESH ) ); + } +} + +//---------------------------------------------------------------------------- +// +// SendUnicodeKeyDown +// +//---------------------------------------------------------------------------- +void SendUnicodeKeyDown( const wchar_t ch ) +{ + PushInjection( NULL, ch ); + SendKeyInput ( NULL, ch ); +} + +//---------------------------------------------------------------------------- +// +// SendUnicodeKeyUp +// +//---------------------------------------------------------------------------- +void SendUnicodeKeyUp( const wchar_t ch ) +{ + PushInjection( NULL, ch ); + SendKeyInput ( NULL, ch, true ); +} + +//---------------------------------------------------------------------------- +// +// SendVirtualKeyDown +// +//---------------------------------------------------------------------------- +void SendVirtualKeyDown( const WORD vK ) +{ + PushInjection( vK, NULL ); + SendKeyInput ( vK, NULL ); +} + +//---------------------------------------------------------------------------- +// +// SendVirtualKeyUp +// +//---------------------------------------------------------------------------- +void SendVirtualKeyUp( const WORD vK ) +{ + PushInjection( vK, NULL ); + SendKeyInput ( vK, NULL, true ); +} + +//---------------------------------------------------------------------------- +// +// GetRandomNumber +// +//---------------------------------------------------------------------------- +unsigned int GetRandomNumber( unsigned int lower, unsigned int upper ) +{ + return lower + std::rand() % (upper - lower + 1); +} + +//---------------------------------------------------------------------------- +// +// BlockModifierKeys +// +//---------------------------------------------------------------------------- +int BlockModifierKeys() +{ + int blockDepth = 0; + const std::vector MODIFIERS = { VK_LSHIFT, VK_RSHIFT, + VK_LCONTROL, VK_RCONTROL, VK_LMENU, VK_RMENU }; + + if( (GetKeyState( VK_CAPITAL ) & 0x0001) != 0 ) + { + SendVirtualKeyDown( VK_CAPITAL ); + SendVirtualKeyUp ( VK_CAPITAL ); + } + for( auto modifier : MODIFIERS ) + { + if( (GetKeyState( modifier ) & 0x8000) != 0 ) + { + blockDepth++; + SendVirtualKeyUp( modifier ); + } + } + + return blockDepth; +} + +//---------------------------------------------------------------------------- +// +// GetClipboardSequence +// +//---------------------------------------------------------------------------- +DWORD GetClipboardSequence() +{ + DWORD sequence; + if( !OpenClipboard( nullptr ) ) + { + CloseClipboard(); + return 0; + } + sequence = GetClipboardSequenceNumber(); + CloseClipboard(); + return sequence; +} + +//---------------------------------------------------------------------------- +// +// GetClipboard +// +//---------------------------------------------------------------------------- +wchar_t* GetClipboard() +{ + // Confirm clipboard accessibility and data format + if( !OpenClipboard( nullptr ) && !IsClipboardFormatAvailable( CF_UNICODETEXT ) ) + { + CloseClipboard(); + return nullptr; + } + HANDLE hData = GetClipboardData( CF_UNICODETEXT ); + if( hData == nullptr ) + { + CloseClipboard(); + return nullptr; + } + + // Confirm clipboard size doesn't exceed MAX_INPUT_SIZE + size_t size = GlobalSize( hData ); + if( size <= 0 || size > MAX_INPUT_SIZE ) + { + GlobalUnlock( hData ); + CloseClipboard(); + return nullptr; + } + + const wchar_t* pData = static_cast(GlobalLock( hData )); + if( pData == nullptr ) + { + GlobalUnlock( hData ); + CloseClipboard(); + return nullptr; + } + + wchar_t* data = new wchar_t[size / sizeof(wchar_t)]; + wcscpy( data, pData ); + GlobalUnlock( hData ); + CloseClipboard(); + return data; +} + +//---------------------------------------------------------------------------- +// +// SetClipboard +// +//---------------------------------------------------------------------------- +bool SetClipboard( const wchar_t* data ) +{ + if( data == nullptr ) + { + return false; + } + if( !OpenClipboard( nullptr ) ) + { + CloseClipboard(); + return false; + } + EmptyClipboard(); + + size_t size = (wcslen( data ) + 1) * sizeof( wchar_t ); + HGLOBAL hData = GlobalAlloc( GMEM_MOVEABLE, size ); + if( hData == nullptr ) + { + CloseClipboard(); + return false; + } + + wchar_t* pData = static_cast(GlobalLock( hData )); + if( pData == nullptr ) + { + GlobalUnlock( hData ); + GlobalFree( hData ); + CloseClipboard(); + return false; + } + + wcscpy( pData, data ); + GlobalUnlock( hData ); + SetClipboardData( CF_UNICODETEXT, hData ); + CloseClipboard(); + return true; +} + +//---------------------------------------------------------------------------- +// +// GetBaselineIndentation +// +//---------------------------------------------------------------------------- +void GetBaselineIndentation() +{ + size_t len = 0; + size_t lastLen = 0; + bool resetCursor = true; + wchar_t* seekBuffer = nullptr; + static const WORD VK_C = static_cast(LOBYTE( VkKeyScan( L'c' ) )); + + // VS fakes newline indentation until the user adds input + SendVirtualKeyDown( VK_SPACE ); + SendVirtualKeyUp ( VK_SPACE ); + SendVirtualKeyDown( VK_BACK ); + SendVirtualKeyUp ( VK_BACK ); + + for( int i = 0; i < MAX_INDENT_DEPTH; i++ ) + { + SendVirtualKeyDown( VK_LSHIFT ); + SendVirtualKeyDown( VK_LEFT ); + SendVirtualKeyUp ( VK_LEFT ); + SendVirtualKeyUp ( VK_LSHIFT ); + + SendVirtualKeyDown( VK_LCONTROL ); + SendVirtualKeyDown( VK_C ); + SendVirtualKeyUp ( VK_C ); + SendVirtualKeyUp ( VK_LCONTROL ); + + std::this_thread::sleep_for( std::chrono::milliseconds( CLIPBOARD_REFRESH ) ); + + len = 0; + delete[] seekBuffer; + seekBuffer = GetClipboard(); + if( seekBuffer == nullptr ) + { + resetCursor = false; + break; + } + len = wcslen( seekBuffer ); + + if( g_LastClipboardSeq == GetClipboardSequence() ) + { + resetCursor = false; + break; + } + else if( seekBuffer[0] == L'\n' || seekBuffer[0] == L'\r' ) + { + break; + } + else if( len == lastLen ) + { + if( len == 0 ) + { + resetCursor = false; + } + break; + } + lastLen = len; + } + + if( resetCursor ) + { + SendVirtualKeyDown( VK_RIGHT ); + SendVirtualKeyUp ( VK_RIGHT ); + } + + // Extract line indentation + g_BaselineIndentation.clear(); + for( size_t i = 0; i < len; i++ ) + { + if( iswprint( seekBuffer[i] ) && seekBuffer[i] != L' ' ) + { + break; + } + else if( seekBuffer[i] == L'\t' || seekBuffer[i] == L' ' ) + { + g_BaselineIndentation.push_back( seekBuffer[i] ); + } + } + + delete[] seekBuffer; +} + +//---------------------------------------------------------------------------- +// +// InjectByClipboard +// +// Editors handle paste operations slowly so we use this method sparingly +// +//---------------------------------------------------------------------------- +wchar_t InjectByClipboard( wchar_t lastCh, wchar_t ch, const std::wstring& override = L"" ) +{ + int i = 0; + bool trim = false; + bool chunk = false; + std::wstring injection(1, ch); + static const WORD VK_V = static_cast(LOBYTE( VkKeyScan( L'v' ) )); + + if( override == L"" ) + { + if( ch == L'\n' && g_BaselineIndentation != L"" && g_BaselineIndentation != L"x" ) + { + injection.append( g_BaselineIndentation ); + } + + // VS absorbs pasted line indentation so we inject it as a chunk of indents and the first printable ch + if( lastCh == L'\n' && (ch == L'\t' || ch == L' ') ) + { + chunk = true; + for( i = 1; g_Index + i < g_TextLen; i++ ) + { + injection.push_back( g_Text[g_Index + i] ); + if( g_Text[g_Index + i] != L' ' && iswprint( g_Text[g_Index + i] ) ) + { + if( g_Text[g_Index + i] == L'[' ) + { + trim = true; + } + break; + } + } + } + } + + std::this_thread::sleep_for( std::chrono::milliseconds( CLIPBOARD_REFRESH ) ); + if( !SetClipboard( override == L"" ? injection.c_str() : override.c_str() ) ) + { + std::this_thread::sleep_for( std::chrono::milliseconds( CLIPBOARD_REFRESH ) ); + SetClipboard( override == L"" ? injection.c_str() : override.c_str() ); + } + std::this_thread::sleep_for( std::chrono::milliseconds( CLIPBOARD_REFRESH ) ); + + SendVirtualKeyDown( VK_LCONTROL ); + SendVirtualKeyDown( VK_V ); + SendVirtualKeyUp ( VK_V ); + SendVirtualKeyUp ( VK_LCONTROL ); + + std::this_thread::sleep_for( std::chrono::milliseconds( CLIPBOARD_REFRESH ) ); + + // Trim the last character from our chunk if it was [ + // Because it might be the start of a control keyword + if( trim ) + { + SendVirtualKeyDown( VK_BACK ); + SendVirtualKeyUp ( VK_BACK ); + + g_Index += static_cast(i) - 1; + return g_Text[g_Index]; + } + else if( chunk ) + { + g_Index += i; + return g_Text[g_Index]; + } + return NULL; +} + +//---------------------------------------------------------------------------- +// +// HandleControlKeyword +// +//---------------------------------------------------------------------------- +bool HandleControlKeyword() +{ + size_t controlClose = g_Text.find( L']', g_Index ); + size_t controlLen = controlClose - g_Index + 1; + + if( controlLen <= MAX_CONTROL_LEN ) + { + std::wstring control = g_Text.substr( g_Index, controlLen ); + + if( control == L"[end]" ) + { + g_End = true; + g_Index += controlLen; + g_TextSegments.push_back( g_Index ); + + // In standard mode, [end] is interpreted as an immediate kill signal + if( !g_UserDriven ) + { + g_EmitterState = KILL_STATE; + } + + return true; + } + else if( control.substr( 0, 7 ) == L"[pause:" ) + { + g_Index += controlLen; + + if( g_UserDriven ) + { + return true; + } + + std::wistringstream iss(control.substr( 7, control.length() - 2 )); + unsigned int time; + + if( iss >> time ) + { + if( time > 0 ) + { + // Pause but poll for termination + for( int i = 0; i < static_cast(1000 / DEMOTYPE_REFRESH * time); i++ ) + { + if( g_EmitterState == KILL_STATE ) + { + break; + } + std::this_thread::sleep_for( std::chrono::milliseconds( 50 ) ); + } + return true; + } + } + } + else if( control == L"[paste]" ) + { + size_t endControlOpen = g_Text.find( L"[/paste]", controlClose ); + if( endControlOpen != std::wstring::npos ) + { + size_t endControlClose = g_Text.find( L']', endControlOpen ); + size_t endControlLen = endControlClose - g_Index + 1; + + std::wstring pasteData = g_Text.substr( controlClose + 1, endControlOpen - controlClose - 1 ); + InjectByClipboard( NULL, NULL, pasteData ); + + g_Index += endControlLen; + return true; + } + } + else + { + if( control == L"[enter]" ) + { + SendVirtualKeyDown( VK_RETURN ); + SendVirtualKeyUp ( VK_RETURN ); + } + else if( control == L"[up]" ) + { + SendVirtualKeyDown( VK_UP ); + SendVirtualKeyUp ( VK_UP ); + } + else if( control == L"[down]" ) + { + SendVirtualKeyDown( VK_DOWN ); + SendVirtualKeyUp ( VK_DOWN ); + } + else if( control == L"[left]" ) + { + SendVirtualKeyDown( VK_LEFT ); + SendVirtualKeyUp ( VK_LEFT ); + } + else if( control == L"[right]" ) + { + SendVirtualKeyDown( VK_RIGHT ); + SendVirtualKeyUp ( VK_RIGHT ); + } + else + { + return false; + } + g_Index += controlLen; + return true; + } + } + return false; +} + +//---------------------------------------------------------------------------- +// +// HandleInjection +// +//---------------------------------------------------------------------------- +void HandleInjection( bool init = false ) +{ + static wchar_t lastCh = NULL; + + if( init ) + { + if( g_Index == 0 ) + { + g_TextSegments.clear(); + } + + lastCh = NULL; + GetBaselineIndentation(); + return; + } + + wchar_t ch = g_Text[g_Index]; + + if( ch == L'[' ) + { + if( HandleControlKeyword() ) + { + return; + } + } + + if( IsAutoFormatTrigger( lastCh, ch ) ) + { + wchar_t newCh = InjectByClipboard( lastCh, ch ); + if( newCh != NULL ) + { + ch = newCh; + } + } + else + { + SendUnicodeKeyDown( ch ); + SendUnicodeKeyUp ( ch ); + } + lastCh = ch; + g_Index++; +} + +//---------------------------------------------------------------------------- +// +// DemoTypeEmitter +// +//---------------------------------------------------------------------------- +void DemoTypeEmitter() +{ + const unsigned int speed = static_cast((MIN_TYPING_SPEED + MAX_TYPING_SPEED) - g_SpeedSlider); + const unsigned int variance = static_cast(speed * TYPING_VARIANCE); + + // Initialize the injection handler + HandleInjection( true ); + + while( g_EmitterState == ACTIVE_STATE && g_Index < g_TextLen ) + { + HandleInjection(); + + std::this_thread::sleep_for( std::chrono::milliseconds( + GetRandomNumber( max( speed - variance, 1 ), max( speed + variance, 1 ) ) ) ); + } + if( g_Index >= g_TextLen ) + { + g_Index = 0; + + // Synthesize [end] at end of script if no [end] is present + if( !g_End ) + { + g_End = true; + g_TextSegments.push_back( g_Index ); + } + } + + g_EmitterState = INACTIVE_STATE; + g_Kill = true; + { + std::lock_guard epochLock(g_EpochMutex); + } + g_EpochReady.notify_one(); +} + +//---------------------------------------------------------------------------- +// +// DemoTypeHookProc +// +//---------------------------------------------------------------------------- +LRESULT CALLBACK DemoTypeHookProc( int nCode, WPARAM wParam, LPARAM lParam ) +{ + static HWND hWndFocus = nullptr; + static int injectionRatio = 1; + static int blockDepth = 0; + + if( g_HookState == KILL_STATE ) + { + PostQuitMessage( 0 ); + return 1; + } + else if( g_HookState == START_STATE ) + { + g_HookState = INIT_STATE; + if( g_UserDriven ) + { + injectionRatio = min( 3, max( 1, static_cast(g_SpeedSlider / THIRD_TYPING_SPEED) + 1 ) ); + } + + hWndFocus = GetForegroundWindow(); + g_Notepad = IsWindowNotepad( hWndFocus ); + blockDepth = BlockModifierKeys(); + } + + if( nCode == HC_ACTION ) + { + KBDLLHOOKSTRUCT* pKbdStruct = reinterpret_cast(lParam); + + bool injected = IsInjected( pKbdStruct->vkCode, pKbdStruct->scanCode ); + + // Block non-injected input until we've negated all modifiers + if( g_HookState == INIT_STATE ) + { + if( g_Injections.empty() ) + { + g_HookState = ACTIVE_STATE; + { + std::lock_guard epochLock(g_EpochMutex); + } + g_EpochReady.notify_one(); + + if( g_UserDriven ) + { + // Set baseline indentation to a blocking flag + // Otherwise indentation seeking will trigger user-driven injection events + g_BaselineIndentation = INDENT_SEEK_FLAG; + + // Initialize the injection handler + HandleInjection( true ); + } + return 1; + } + } + else if( g_HookState == BLOCK_STATE ) + { + return 1; + } + + // Handle two possible kill signals: user inputted escape or focus change + if( (pKbdStruct->vkCode == VK_ESCAPE && !injected) || hWndFocus != GetForegroundWindow() ) + { + // Notify the controller that the hook is going to BLOCK_STATE and requesting kill + g_HookState = BLOCK_STATE; + g_Kill = true; + { + std::lock_guard epochLock(g_EpochMutex); + } + g_EpochReady.notify_one(); + + // In user-driven mode, we can kill the hook without controller approval + // In standard mode, we need to stay alive until the emitter is terminated + if( g_UserDriven ) + { + PostQuitMessage( 0 ); + } + + // Only pass through if the kill signal was user input after a focus change + if( hWndFocus != GetForegroundWindow() && injected ) + { + return 1; + } + } + else if( injected ) + { + PopInjection(); + } + else + { + switch( wParam ) + { + case WM_KEYUP: + // In user-driven mode, [end] needs to be acknowledged by the user with a space before proceeding to kill + if( pKbdStruct->vkCode == VK_SPACE && g_UserDriven && g_End ) + { + // Notify the controller that the hook is going to BLOCK_STATE and requesting kill + g_HookState = BLOCK_STATE; + g_Kill = true; + { + std::lock_guard epochLock(g_EpochMutex); + } + g_EpochReady.notify_one(); + + PostQuitMessage( 0 ); + } + else if( g_UserDriven ) + { + // Block up to the number of DEMOTYPE_HOTKEY keys + if( blockDepth > 0 ) + { + blockDepth--; + return 1; + } + else if( g_BaselineIndentation == INDENT_SEEK_FLAG ) + { + return 1; + } + + // Inject n keys per 1 input keys where n is injectionRatio + for( int i = 0; i < injectionRatio && g_Index < g_TextLen && !g_End; i++ ) + { + HandleInjection(); + } + if( g_Index >= g_TextLen ) + { + g_Index = 0; + + // Synthesize [end] at end of script if no [end] is present + if( !g_End ) + { + g_End = true; + g_TextSegments.push_back( g_Index ); + } + } + } + [[fallthrough]]; + case WM_KEYDOWN: + case WM_SYSKEYUP: + case WM_SYSKEYDOWN: + return 1; + } + } + } + return CallNextHookEx( g_hHook, nCode, wParam, lParam ); +} + +//---------------------------------------------------------------------------- +// +// StartDemoTypeHook +// +//---------------------------------------------------------------------------- +void StartDemoTypeHook() +{ + g_hHook = SetWindowsHookEx( WH_KEYBOARD_LL, DemoTypeHookProc, GetModuleHandle( nullptr ), 0 ); + if( g_hHook == nullptr ) + { + g_HookState = INACTIVE_STATE; + return; + } + + // Jump start the hook with an inert message to prevent a stall + KBDLLHOOKSTRUCT KbdStruct{}; + DemoTypeHookProc( HC_ACTION, 0, reinterpret_cast(&KbdStruct) ); + + MSG msg; + while( GetMessage( &msg, nullptr, 0, 0 ) ) + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + + UnhookWindowsHookEx( g_hHook ); + g_hHook = nullptr; + + // Clean up any trailing shift modifier from our injections + if( (GetKeyState( VK_LSHIFT ) & 0x8000) != 0 ) + { + SendVirtualKeyUp( VK_LSHIFT ); + } + + g_HookState = INACTIVE_STATE; +} + +//---------------------------------------------------------------------------- +// +// KillDemoTypeHook +// +//---------------------------------------------------------------------------- +void KillDemoTypeHook() +{ + if( g_HookState != INACTIVE_STATE ) + { + g_HookState = KILL_STATE; + SendVirtualKeyUp( VK_ESCAPE ); + } +} + +//---------------------------------------------------------------------------- +// +// DemoTypeController +// +//---------------------------------------------------------------------------- +void DemoTypeController() +{ + std::chrono::milliseconds timeout(DEMOTYPE_TIMEOUT); + + g_Injections.clear(); + g_End = false; + g_Kill = false; + g_Active = true; + g_HookState = START_STATE; + + std::thread( StartDemoTypeHook ).detach(); + + // Spool up the emitter + if( !g_UserDriven ) + { + std::unique_lock epochLock(g_EpochMutex); + if( g_EpochReady.wait_for( epochLock, timeout, + [] { return g_HookState == ACTIVE_STATE; } ) ) + { + g_EmitterState = ACTIVE_STATE; + std::thread( DemoTypeEmitter ).detach(); + } + else + { + KillDemoTypeHook(); + g_Active = false; + return; + } + } + + // Wait for kill request + { + std::unique_lock epochLock(g_EpochMutex); + g_EpochReady.wait( epochLock, [] { return g_Kill == true; } ); + } + + // Send kill messages + if( !g_UserDriven ) + { + if( g_EmitterState != INACTIVE_STATE ) + { + g_EmitterState = KILL_STATE; + g_HookState = BLOCK_STATE; + + std::unique_lock epochLock(g_EpochMutex); + g_EpochReady.wait_for( epochLock, timeout, [] { return g_EmitterState == INACTIVE_STATE; } ); + } + } + KillDemoTypeHook(); + + if( g_ClipboardCache != nullptr ) + { + SetClipboard( g_ClipboardCache ); + g_LastClipboardSeq = GetClipboardSequence(); + } + + // Upon kill, hop to the next text segment if kill wasn't triggered by an [end] + if( g_Index != 0 && !g_End ) + { + size_t nextEnd = g_Text.find( L"[end]", g_Index ); + if( nextEnd == std::wstring::npos ) + { + g_Index = 0; + } + else + { + g_Index = nextEnd + END_CONTROL_LEN; + g_TextSegments.push_back( g_Index ); + if( g_Index >= g_TextLen ) + { + g_Index = 0; + } + } + } + + g_Active = false; +} + +//---------------------------------------------------------------------------- +// +// TrimNewlineAroundControl +// +//---------------------------------------------------------------------------- +void TrimNewlineAroundControl( const std::wstring control, const bool trimLeft, const bool trimRight ) +{ + const size_t controlLen = control.length(); + + // Seek first occurrence of `control` in `g_Text` + size_t nextControl = g_Text.find( control ); + + // Loop through each occurrence of `control` in `g_Text` + while( nextControl != std::wstring::npos ) + { + // Erase the character to the left of `control` if it is a newline + if( trimLeft && nextControl > 0 && g_Text[nextControl - 1] == L'\n' ) + { + g_Text.erase( nextControl - 1, 1 ); + // Decrement `nextControl` to account for `g_Text` shrinking to left of `nextControl` + nextControl--; + } + + // Erase the character to the right of `control` if it is a newline + if( trimRight && (nextControl + controlLen) < g_Text.length() && g_Text[nextControl + controlLen] == L'\n' ) + { + g_Text.erase( nextControl + controlLen, 1 ); + } + + // Seek next occurrence of `control` in `g_Text` + nextControl = g_Text.find( control, nextControl + controlLen); + + // Shrink `g_Text` to new size on last pass + if( nextControl == std::wstring::npos ) + { + g_Text.shrink_to_fit(); + } + } +} + +//---------------------------------------------------------------------------- +// +// CleanDemoTypeText +// +//---------------------------------------------------------------------------- +bool CleanDemoTypeText() +{ + // Remove all unsupported characters from our text buffer + g_Text.erase( std::remove_if( g_Text.begin(), g_Text.end(), IsNotPrintable ), g_Text.end() ); + g_Text.shrink_to_fit(); + + // Remove the first character if it is a newline + if( g_Text.length() > 0 && g_Text[0] == L'\n' ) + { + g_Text.erase( 0, 1 ); + g_Text.shrink_to_fit(); + } + + // Trim a newline character to the left and right of each [end] control + TrimNewlineAroundControl( L"[end]", true, true ); + + // Trim a newline character to the right of each [paste] control + TrimNewlineAroundControl( L"[paste]", false, true ); + + // Trim a newline character to the left of each [/paste] control + TrimNewlineAroundControl( L"[/paste]", true, false ); + + // Remove any dangling whitespace after the last [end] + size_t lastEnd = g_Text.rfind( L"[end]" ); + if( lastEnd != std::wstring::npos ) + { + for( size_t i = lastEnd + END_CONTROL_LEN; i < g_Text.length(); i++ ) + { + if( iswprint( g_Text[i] ) && g_Text[i] != L' ' ) + { + break; + } + else if( i >= g_Text.length() - 1 ) + { + g_Text.erase( lastEnd + END_CONTROL_LEN ); + g_Text.shrink_to_fit(); + } + } + } + + g_TextLen = g_Text.length(); + if( g_TextLen > 0 ) + { + return true; + } + else + { + return false; + } +} + +//---------------------------------------------------------------------------- +// +// ResetDemoTypeClipboard +// +//---------------------------------------------------------------------------- +void ResetDemoTypeClipboard() +{ + if( g_Clipboard ) + { + g_Text.clear(); + g_Clipboard = false; + } +} + +//---------------------------------------------------------------------------- +// +// GetDemoTypeClipboard +// +//---------------------------------------------------------------------------- +bool GetDemoTypeClipboard() +{ + const int safetyPrefixLen = 7; + const wchar_t safetyPrefix[] = L"[start]"; + + // Check if we can reuse the clipboard cache + DWORD sequenceNum = GetClipboardSequence(); + if( g_LastClipboardSeq == sequenceNum && g_Clipboard ) + { + return true; + } + g_LastClipboardSeq = sequenceNum; + + delete[] g_ClipboardCache; + g_ClipboardCache = GetClipboard(); + + // Confirm clipboard data begins with the safety prefix + if( g_ClipboardCache == nullptr || g_ClipboardCache[0] != g_ClipboardCache[0] || g_ClipboardCache[safetyPrefixLen] == '\0' ) + { + ResetDemoTypeClipboard(); + return false; + } + for( int i = 1; i < safetyPrefixLen; i++ ) + { + if( g_ClipboardCache[i] != safetyPrefix[i] || g_ClipboardCache[i] == '\0' ) + { + ResetDemoTypeClipboard(); + return false; + } + } + + g_Text.assign( g_ClipboardCache + safetyPrefixLen ); + g_Clipboard = true; + g_Index = 0; + return CleanDemoTypeText(); +} + +//---------------------------------------------------------------------------- +// +// GetDemoTypeFile +// +// Supported encoding: UTF-8, UTF-8 with BOM, UTF-16LE, UTF-16BE +// +//---------------------------------------------------------------------------- +int GetDemoTypeFile( const TCHAR* filePath ) +{ + std::ifstream file(filePath, std::ios::binary); + if( !file.is_open() ) + { + return ERROR_LOADING_FILE; + } + + // Confirm file size doesn't exceed MAX_INPUT_SIZE + file.seekg( 0, std::ios::end ); + std::streampos size = file.tellg(); + file.seekg( 0, std::ios::beg ); + if( size <= 0 || size > MAX_INPUT_SIZE ) + { + return FILE_SIZE_OVERFLOW; + } + + // Grab the potential Byte Order Mark + // Which identifies the encoding pattern + char byteOrderMark[3]; + file.read( byteOrderMark, 3 ); + file.seekg( 0, std::ios::beg ); + + // UTF-16 is a variable-length character encoding pattern + // - code points are encoded with one or two 16-bit code units + // - 16-bit code units are composed of byte pairs subject to endianness + // - Little-endian Byte Order Mark {0xFF, 0xFE, ...} + // - Big-endian Byte Order Mark {0xFE, 0xFF, ...} + + // UTF-8 is a variable-length character encoding pattern + // - code points are encoded with one to four 8-bit code units + // - optional Byte Order Mark {0xEF, 0xBB, 0xBF, ...} + + // UTF-16LE + if( byteOrderMark[0] == static_cast(0xFF) + && byteOrderMark[1] == static_cast(0xFE) ) + { + // Truncate the Byte Order Mark + file.seekg( 2 ); + + char bytePair[2]; + wchar_t codeUnit; + while( file.read( bytePair, 2 ) ) + { + // Squash each little-endian byte pair into a 2-byte code unit + // if bytePair[0] = 0xff + // if bytePair[1] = 0x00 + // codeUnit = 0x00ff + codeUnit = (static_cast(bytePair[1]) << 8) + | static_cast(bytePair[0]); + + g_Text += codeUnit; + } + } + // UTF-16BE + else if( byteOrderMark[0] == static_cast(0xFE) + && byteOrderMark[1] == static_cast(0xFF) ) + { + // Truncate the Byte Order Mark + file.seekg( 2 ); + + char bytePair[2]; + wchar_t codeUnit; + while( file.read( bytePair, 2 ) ) + { + // Squash each big-endian byte pair into a 2-byte code unit + // if bytePair[0] = 0xff + // if bytePair[1] = 0x00 + // codeUnit = 0xff00 + codeUnit = (static_cast(bytePair[0]) << 8) + | static_cast(bytePair[1]); + + g_Text += codeUnit; + } + } + // UTF-8 + else + { + // If UTF-8 with BOM, truncate the Byte Order Mark + if( byteOrderMark[0] == static_cast(0xEF) + && byteOrderMark[1] == static_cast(0xBB) + && byteOrderMark[2] == static_cast(0xBF) ) + { + file.seekg( 3 ); + } + + std::stringstream buffer; + buffer << file.rdbuf(); + std::string narrowText = buffer.str(); + + // Determine the size our wide string will need to be to accomodate the conversion + int wideSize = MultiByteToWideChar( CP_UTF8, 0, narrowText.c_str(), -1, nullptr, 0 ); + if( wideSize <= 0 ) + { + return ERROR_LOADING_FILE; + } + + g_Text.resize( wideSize ); + + // Map the multi-byte capable char string onto the wide char string + if( MultiByteToWideChar( CP_UTF8, 0, narrowText.c_str(), -1, &g_Text[0], wideSize ) <= 0 ) + { + return ERROR_LOADING_FILE; + } + } + + g_Index = 0; + return CleanDemoTypeText() ? 0 : UNKNOWN_FILE_DATA; +} + +//---------------------------------------------------------------------------- +// +// ResetDemoTypeIndex +// +//---------------------------------------------------------------------------- +void ResetDemoTypeIndex() +{ + size_t newIndex = 0; + + if( !g_TextSegments.empty() && g_Index <= g_TextSegments.back() ) + { + g_TextSegments.pop_back(); + } + if( !g_TextSegments.empty() ) + { + newIndex = g_TextSegments.back(); + } + + g_Index = newIndex; +} + +//---------------------------------------------------------------------------- +// +// StartDemoType +// +//---------------------------------------------------------------------------- +int StartDemoType( const TCHAR* filePath, const DWORD speedSlider, const BOOLEAN userDriven ) +{ + static FILETIME lastFileWrite = {0}; + + if( g_Active ) + { + return -1; + } + + if( !GetDemoTypeClipboard() ) + { + if( _tcslen( filePath ) == 0 ) + { + return NO_FILE_SPECIFIED; + } + + if( _tcscmp( g_LastFilePath, filePath ) != 0 ) + { + _tcscpy( g_LastFilePath, filePath ); + // Trigger (re)capture of lastFileWrite + g_Text = L"x"; + g_Index = 0; + lastFileWrite = {0}; + } + + // Check if the file has been updated since last read + if( !g_Text.empty() ) + { + HANDLE hFile = CreateFile( filePath, GENERIC_READ, FILE_SHARE_READ, + nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr ); + if( hFile == INVALID_HANDLE_VALUE ) + { + CloseHandle( hFile ); + return ERROR_LOADING_FILE; + } + + FILETIME latestFileWrite; + if( GetFileTime( hFile, nullptr, nullptr, &latestFileWrite ) ) + { + if( CompareFileTime( &latestFileWrite, &lastFileWrite ) == 1 ) + { + g_Text.clear(); + lastFileWrite = latestFileWrite; + } + } + CloseHandle( hFile ); + } + + if( g_Text.empty() ) + { + switch( GetDemoTypeFile( filePath ) ) + { + case ERROR_LOADING_FILE: + return ERROR_LOADING_FILE; + + case FILE_SIZE_OVERFLOW: + return FILE_SIZE_OVERFLOW; + + case UNKNOWN_FILE_DATA: + return UNKNOWN_FILE_DATA; + } + } + } + + g_UserDriven = userDriven; + g_SpeedSlider = speedSlider; + std::thread( DemoTypeController ).detach(); + return 0; +} \ No newline at end of file diff --git a/src/modules/ZoomIt/ZoomIt/DemoType.h b/src/modules/ZoomIt/ZoomIt/DemoType.h new file mode 100644 index 000000000000..dbfdd3500515 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/DemoType.h @@ -0,0 +1,26 @@ +//============================================================================ +// +// Zoomit +// Copyright (C) Mark Russinovich +// Sysinternals - www.sysinternals.com +// +// DemoType allows the presenter to synthesize keystrokes from a script +// +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +//============================================================================ + +#pragma once + +#define MAX_INPUT_SIZE 1048576 // 1 MiB + +#define MAX_TYPING_SPEED 10 // ms +#define MIN_TYPING_SPEED 100 // ms + +#define ERROR_LOADING_FILE 1 +#define NO_FILE_SPECIFIED 2 +#define FILE_SIZE_OVERFLOW 3 +#define UNKNOWN_FILE_DATA 4 + +void ResetDemoTypeIndex(); +int StartDemoType( const TCHAR* filePath, const DWORD speedSlider, const BOOLEAN userDriven ); \ No newline at end of file diff --git a/src/modules/ZoomIt/ZoomIt/PowerToys/branding.h b/src/modules/ZoomIt/ZoomIt/PowerToys/branding.h new file mode 100644 index 000000000000..b5df0fe64bae --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/PowerToys/branding.h @@ -0,0 +1,3 @@ +#pragma once + +#define ZOOMIT_PRODUCT_NAME "PowerToys Sysinternals ZoomIt" diff --git a/src/modules/ZoomIt/ZoomIt/Registry.h b/src/modules/ZoomIt/ZoomIt/Registry.h new file mode 100644 index 000000000000..1a2f8f2fc883 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/Registry.h @@ -0,0 +1,324 @@ +//============================================================================ +// +// Process Explorer +// Copyright (C) 1999-2005 Mark Russinovich +// Sysinternals - www.sysinternals.com +// +// Registry.h +// +//============================================================================ +#pragma once + +typedef enum { + SETTING_TYPE_DWORD, + SETTING_TYPE_BOOLEAN, + SETTING_TYPE_DOUBLE, + SETTING_TYPE_WORD, + SETTING_TYPE_STRING, + SETTING_TYPE_DWORD_ARRAY, + SETTING_TYPE_WORD_ARRAY, + SETTING_TYPE_BINARY +} REG_SETTING_TYPE; + +typedef struct { + PCTSTR ValueName; + REG_SETTING_TYPE Type; + DWORD Size; // Optional + PVOID Setting; + double DefaultSetting; +} REG_SETTING, *PREG_SETTING; + + +class ClassRegistry { + +private: + PTCHAR m_KeyName; + HKEY hKey; + +public: + ClassRegistry( PCTSTR KeyName ) + { + m_KeyName = _tcsdup( KeyName ); + hKey = NULL; + } + + ~ClassRegistry() + { + free( m_KeyName ); + } + + void ReadRegSettings( PREG_SETTING Settings ) + { + PREG_SETTING curSetting; + + hKey = NULL; + RegOpenKeyEx(HKEY_CURRENT_USER, + m_KeyName, 0, KEY_READ, &hKey ); + curSetting = Settings; + while( curSetting->ValueName ) { + + switch( curSetting->Type ) { + case SETTING_TYPE_DWORD: + ReadValue( curSetting->ValueName, static_cast(curSetting->Setting), + static_cast(curSetting->DefaultSetting)); + break; + case SETTING_TYPE_BOOLEAN: + ReadValue( curSetting->ValueName, static_cast(curSetting->Setting), + static_cast(curSetting->DefaultSetting)); + break; + case SETTING_TYPE_DOUBLE: + ReadValue( curSetting->ValueName, static_cast(curSetting->Setting), + curSetting->DefaultSetting ); + break; + case SETTING_TYPE_WORD: + ReadValue( curSetting->ValueName, static_cast(curSetting->Setting), + static_cast(curSetting->DefaultSetting)); + break; + case SETTING_TYPE_STRING: + ReadValue( curSetting->ValueName, static_cast(curSetting->Setting), + curSetting->Size, reinterpret_cast(static_cast(curSetting->DefaultSetting))); + break; + case SETTING_TYPE_DWORD_ARRAY: + ReadValueArray( curSetting->ValueName, curSetting->Size/sizeof DWORD, + static_cast(curSetting->Setting)); + break; + case SETTING_TYPE_WORD_ARRAY: + ReadValueArray( curSetting->ValueName, curSetting->Size/sizeof(short), + static_cast(curSetting->Setting)); + break; + case SETTING_TYPE_BINARY: + ReadValueBinary( curSetting->ValueName, static_cast(curSetting->Setting), + curSetting->Size ); + break; + } + curSetting++; + } + if( hKey ) { + + RegCloseKey( hKey ); + } + } + void WriteRegSettings( PREG_SETTING Settings ) + { + PREG_SETTING curSetting; + + if( !RegCreateKeyEx(HKEY_CURRENT_USER, + m_KeyName, NULL, NULL, 0, KEY_WRITE, NULL, &hKey, NULL )) { + + curSetting = Settings; + while( curSetting->ValueName ) { + + switch( curSetting->Type ) { + case SETTING_TYPE_DWORD: + WriteValue( curSetting->ValueName, *static_cast(curSetting->Setting)); + break; + case SETTING_TYPE_BOOLEAN: + WriteValue( curSetting->ValueName, *static_cast(curSetting->Setting)); + break; + case SETTING_TYPE_DOUBLE: + WriteValue( curSetting->ValueName, *static_cast(curSetting->Setting)); + break; + case SETTING_TYPE_WORD: + WriteValue( curSetting->ValueName, *static_cast(curSetting->Setting)); + break; + case SETTING_TYPE_STRING: + WriteValue( curSetting->ValueName, static_cast(curSetting->Setting)); + break; + case SETTING_TYPE_DWORD_ARRAY: + WriteValueArray( curSetting->ValueName, curSetting->Size/sizeof DWORD, + static_cast(curSetting->Setting)); + break; + case SETTING_TYPE_WORD_ARRAY: + WriteValueArray( curSetting->ValueName, curSetting->Size/sizeof(short), + static_cast(curSetting->Setting)); + break; + case SETTING_TYPE_BINARY: + WriteValueBinary( curSetting->ValueName, static_cast(curSetting->Setting), + curSetting->Size ); + break; + } + curSetting++; + } + RegCloseKey( hKey ); + } + } + +private: + // Reads + void ReadValue( PCTSTR ValueName, PDWORD Value, DWORD Default = 0 ) + { + DWORD length = sizeof(DWORD); + if( RegQueryValueEx( hKey, ValueName, NULL, NULL, reinterpret_cast(Value), + &length )) { + + *Value = Default; + } + } + void ReadValue( PCTSTR ValueName, PBOOLEAN Value, BOOLEAN Default = FALSE ) + { + DWORD length = sizeof(DWORD); + DWORD val = static_cast(*Value); + if( RegQueryValueEx( hKey, ValueName, NULL, NULL, reinterpret_cast(&val), + &length )) { + + *Value = Default; + + } else { + + *Value = static_cast(val); + } + } + void ReadValue( PCTSTR ValueName, short *Value, short Default = 0 ) + { + DWORD length = sizeof(DWORD); + DWORD val = static_cast(*Value); + if( RegQueryValueEx( hKey, ValueName, NULL, NULL, reinterpret_cast(&val), + &length )) { + + *Value = Default; + + } else { + + *Value = static_cast(val); + } + } + void ReadValue( PCTSTR ValueName, double *Value, double Default = 0.0 ) + { + DWORD length = sizeof(double); + if( RegQueryValueEx( hKey, ValueName, NULL, NULL, reinterpret_cast(Value), + &length )) { + + *Value = Default; + + } + } + void ReadValue( PCTSTR ValueName, PTCHAR Value, DWORD Length, PCTSTR Default ) + { + if( RegQueryValueEx( hKey, ValueName, NULL, NULL, reinterpret_cast(Value), + &Length ) && Default ) { + + _tcscpy_s( Value, Length, Default ); + } + } + void ReadValueBinary( PCTSTR ValueName, PBYTE Value, DWORD Length ) + { + RegQueryValueEx( hKey, ValueName, NULL, NULL, Value, + &Length ); + } + void ReadValueArray( PCTSTR ValueName, DWORD Number, PDWORD Entries ) + { + HKEY hSubKey; + TCHAR subVal[16]; + DWORD length; + + if( !RegOpenKeyEx(hKey, + ValueName, 0, KEY_READ, &hSubKey )) { + + for( DWORD i = 0; i < Number; i++ ) { + + length = sizeof(DWORD); + _stprintf_s( subVal, _countof(subVal), _T("%d"), i ); + RegQueryValueEx( hSubKey, subVal, NULL, NULL, reinterpret_cast(&Entries[i]), &length); + } + RegCloseKey( hSubKey ); + } + } + void ReadValueArray( PCTSTR ValueName, DWORD Number, PWORD Entries ) + { + HKEY hSubKey; + TCHAR subVal[16]; + DWORD length; + DWORD val; + + if( !RegOpenKeyEx(hKey, + ValueName, 0, KEY_READ, &hSubKey )) { + + for( DWORD i = 0; i < Number; i++ ) { + + length = sizeof(DWORD); + _stprintf_s( subVal, _countof(subVal), _T("%d"), i ); + if( !RegQueryValueEx( hSubKey, subVal, NULL, NULL, reinterpret_cast(&val), &length)) { + + Entries[i] = static_cast(val); + + } + } + RegCloseKey( hSubKey ); + } + } + + // Writes + void WriteValue( PCTSTR ValueName, DWORD Value ) + { + RegSetValueEx( hKey, ValueName, 0, REG_DWORD, reinterpret_cast(&Value), + sizeof(DWORD)); + } + void WriteValue( PCTSTR ValueName, short Value ) + { + DWORD val = static_cast(Value); + RegSetValueEx( hKey, ValueName, 0, REG_DWORD, reinterpret_cast(&val), + sizeof(DWORD)); + } + void WriteValue( PCTSTR ValueName, BOOLEAN Value ) + { + DWORD val = static_cast(Value); + RegSetValueEx( hKey, ValueName, 0, REG_DWORD, reinterpret_cast(&val), + sizeof(DWORD)); + } + void WriteValue( PCTSTR ValueName, double Value ) + { + RegSetValueEx( hKey, ValueName, 0, REG_BINARY, reinterpret_cast(&Value), + sizeof(double)); + } + void WriteValue( PCTSTR ValueName, PTCHAR Value ) + { + RegSetValueEx( hKey, ValueName, 0, REG_SZ, reinterpret_cast(Value), + static_cast(_tcslen( Value )) * sizeof(TCHAR)); + } + void WriteValueBinary( PCTSTR ValueName, PBYTE Value, DWORD Length ) + { + RegSetValueEx( hKey, ValueName, 0, REG_BINARY, Value, + Length ); + } + void WriteValueArray( PCTSTR ValueName, DWORD Number, PDWORD Entries ) + { + HKEY hSubKey; + TCHAR subVal[16]; + + if( !RegCreateKeyEx(hKey, + ValueName, NULL, NULL, 0, KEY_WRITE, NULL, &hSubKey, NULL )) { + + for( DWORD i = 0; i < Number; i++ ) { + + _stprintf_s( subVal, _countof(subVal), _T("%d"), i ); + if( Entries[i] ) + RegSetValueEx( hSubKey, subVal, 0, REG_DWORD, reinterpret_cast(&Entries[i]), sizeof(DWORD)); + else + RegDeleteValue( hSubKey, subVal ); + } + RegCloseKey( hSubKey ); + } + } + void WriteValueArray( PCTSTR ValueName, DWORD Number, PWORD Entries ) + { + HKEY hSubKey; + TCHAR subVal[16]; + DWORD val; + + if( !RegCreateKeyEx(hKey, + ValueName, NULL, NULL, 0, KEY_WRITE, NULL, &hSubKey, NULL )) { + + for( DWORD i = 0; i < Number; i++ ) { + + _stprintf_s( subVal, _countof(subVal), _T("%d"), i ); + val = static_cast(Entries[i]); + if( Entries[i] ) + RegSetValueEx( hSubKey, subVal, 0, REG_DWORD, reinterpret_cast(&val), sizeof(DWORD)); + else + RegDeleteValue( hSubKey, subVal ); + } + RegCloseKey( hSubKey ); + } + } + +}; diff --git a/src/modules/ZoomIt/ZoomIt/SelectRectangle.cpp b/src/modules/ZoomIt/ZoomIt/SelectRectangle.cpp new file mode 100644 index 000000000000..cfab73996c96 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/SelectRectangle.cpp @@ -0,0 +1,269 @@ +//============================================================================== +// +// Zoomit +// Sysinternals - www.sysinternals.com +// +// Class to select a recording rectangle and show it while recording +// +//============================================================================== +#include "pch.h" +#include "SelectRectangle.h" +#include "Utility.h" +#include "WindowsVersions.h" + +//---------------------------------------------------------------------------- +// +// SelectRectangle::Start +// +//---------------------------------------------------------------------------- +bool SelectRectangle::Start( HWND ownerWindow, bool fullMonitor ) +{ + WNDCLASSW windowClass{}; + windowClass.lpfnWndProc = []( HWND window, UINT message, WPARAM wordParam, LPARAM longParam ) -> LRESULT + { + if( message == WM_NCCREATE ) + { + auto createStruct = reinterpret_cast(longParam); + SetWindowLongPtrW( window, GWLP_USERDATA, reinterpret_cast(createStruct->lpCreateParams) ); + return TRUE; + } + + auto self = reinterpret_cast(GetWindowLongPtrW( window, GWLP_USERDATA )); + return self->WindowProc( window, message, wordParam, longParam ); + }; + windowClass.hInstance = GetModuleHandle( nullptr ); + windowClass.hCursor = LoadCursorW( nullptr, IDC_CROSS ); + windowClass.hbrBackground = static_cast(GetStockObject( BLACK_BRUSH )); + windowClass.lpszClassName = m_className; + if( RegisterClassW( &windowClass ) == 0 ) + { + THROW_LAST_ERROR_IF( GetLastError() != ERROR_CLASS_ALREADY_EXISTS ); + + WNDCLASSW existingClass{}; + THROW_IF_WIN32_BOOL_FALSE( GetClassInfoW( GetModuleHandle( nullptr ), m_className, &existingClass ) ); + THROW_LAST_ERROR_IF( existingClass.lpfnWndProc != windowClass.lpfnWndProc ); + } + + m_cancel = false; + auto rect = GetMonitorRectFromCursor(); + m_window = wil::unique_hwnd( CreateWindowExW( WS_EX_LAYERED | WS_EX_TOOLWINDOW | WS_EX_TOPMOST, m_className, nullptr, WS_POPUP, + rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, ownerWindow, + nullptr, nullptr, this ) ); + THROW_LAST_ERROR_IF_NULL( m_window.get() ); + + if( fullMonitor ) + { + m_selectedRect = rect; + ShowSelected(); + } + else + { + SetLayeredWindowAttributes( m_window.get(), 0, Alpha(), LWA_ALPHA ); + } + + ShowWindow( m_window.get(), SW_SHOW ); + SetForegroundWindow( m_window.get() ); + + if( !fullMonitor ) + { + GetClipCursor( &m_oldClipRect ); + ClipCursor( &rect ); + m_setClip = true; + } + + MSG message; + while( GetMessageW( &message, nullptr, 0, 0 ) != 0 ) + { + TranslateMessage( &message ); + DispatchMessageW( &message ); + if( m_cancel ) + { + return false; + } + if( m_selected ) + { + break; + } + } + return true; +} + +//---------------------------------------------------------------------------- +// +// SelectRectangle::Stop +// +//---------------------------------------------------------------------------- +void SelectRectangle::Stop() +{ + if( m_setClip ) + { + ClipCursor( &m_oldClipRect ); + m_setClip = false; + } + m_window.reset(); + m_selected = false; + m_selectedRect = {}; + m_cancel = true; +} + +//---------------------------------------------------------------------------- +// +// SelectRectangle::ShowSelected +// +//---------------------------------------------------------------------------- +void SelectRectangle::ShowSelected() +{ + m_selected = true; + + // Set the alpha to match the Windows graphics capture API yellow border + // and set the window to be transparent and disabled, so it will be skipped + // for hit testing and as a candidate for the next foreground window. + SetLayeredWindowAttributes( m_window.get(), 0, 191, LWA_ALPHA ); + SetWindowLong( m_window.get(), GWL_EXSTYLE, GetWindowLong( m_window.get(), GWL_EXSTYLE ) | WS_EX_TRANSPARENT ); + EnableWindow( m_window.get(), FALSE ); + + POINT point{ m_selectedRect.left, m_selectedRect.top }; + auto rect = m_selectedRect; + OffsetRect( &rect, -rect.left, -rect.top ); + int width = ScaleForDpi( 2, m_dpi ); + + // Draw the selection border outside the selected rectangle on builds lower + // than Windows 11 22H2 because the graphics capture API does not skip + // windows if layered, meaning this yellow border will be captured. + if( GetWindowsBuild( nullptr ) < BUILD_WINDOWS_11_22H2 ) + { + InflateRect( &rect, width, width ); + OffsetRect( &rect, -rect.left, -rect.top ); + point.x -= width; + point.y -= width; + } + + // Resize the window to the selection rectangle and translate the position. + RECT windowRect; + GetWindowRect( m_window.get(), &windowRect ); + point.x += windowRect.left; + point.y += windowRect.top; + MoveWindow( m_window.get(), point.x, point.y, rect.right, rect.bottom, true ); + + // Use a region to keep everything but the border transparent. + wil::unique_hrgn region{CreateRectRgnIndirect( &rect )}; + InflateRect( &rect, -width, -width ); + wil::unique_hrgn insideRegion{CreateRectRgnIndirect( &rect )}; + CombineRgn( region.get(), region.get(), insideRegion.get(), RGN_XOR ); + SetWindowRgn( m_window.get(), region.release(), true ); +} + +//---------------------------------------------------------------------------- +// +// SelectRectangle::UpdateOwner +// +//---------------------------------------------------------------------------- +void SelectRectangle::UpdateOwner( HWND window ) +{ + if( m_window != nullptr ) + { + SetWindowLongPtr( m_window.get(), GWLP_HWNDPARENT, reinterpret_cast(window) ); + SetWindowPos( m_window.get(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE ); + } +} + +//---------------------------------------------------------------------------- +// +// SelectRectangle::WindowProc +// +//---------------------------------------------------------------------------- +LRESULT SelectRectangle::WindowProc( HWND window, UINT message, WPARAM wordParam, LPARAM longParam ) +{ + switch( message ) + { + case WM_CREATE: + m_dpi = GetDpiForWindowHelper( window ); + SetWindowDisplayAffinity( window, WDA_EXCLUDEFROMCAPTURE ); + return 0; + + case WM_DESTROY: + Stop(); + return 0; + + case WM_LBUTTONDOWN: + { + SetCapture( window ); + + m_startPoint = { GET_X_LPARAM( longParam ), GET_Y_LPARAM( longParam ) }; + [[fallthrough]]; + } + case WM_MOUSEMOVE: + if( GetCapture() == window ) + { + RECT rect; + GetClientRect( window, &rect ); + POINT point{ GET_X_LPARAM( longParam ), GET_Y_LPARAM( longParam ) }; + m_selectedRect = ForceRectInBounds( RectFromPointsMinSize( m_startPoint, point, MinSize() ), rect ); + + // Use a region to carve out the selected rectangle. + wil::unique_hrgn region{CreateRectRgnIndirect( &m_selectedRect )}; + wil::unique_hrgn clientRegion{CreateRectRgnIndirect( &rect )}; + CombineRgn( region.get(), region.get(), clientRegion.get(), RGN_XOR ); + SetWindowRgn( window, region.release(), true ); + } + return 0; + + case WM_KEYDOWN: + if( wordParam == VK_ESCAPE ) + { + Stop(); + } + return 0; + + case WM_KILLFOCUS: + if( !m_selected ) + { + Stop(); + } + return 0; + + case WM_LBUTTONUP: + { + if( m_setClip ) + { + ClipCursor( &m_oldClipRect ); + m_setClip = false; + } + ReleaseCapture(); + + ShowSelected(); + return 0; + } + case WM_NCHITTEST: + if( m_selected ) + { + return HTTRANSPARENT; + } + break; + + case WM_PAINT: + if( m_selected ) + { + PAINTSTRUCT paint; + auto deviceContext = BeginPaint( window, &paint ); + + RECT rect; + GetClientRect( window, &rect ); + + // Draw a border matching the Windows graphics capture API border. + // The outer frame is yellow and two logical pixels wide, while the + // inner is black and 1 logical pixel wide. + wil::unique_hbrush brush{CreateSolidBrush( RGB( 255, 222, 0 ) )}; + FillRect( deviceContext, &rect, brush.get() ); + int width = ScaleForDpi( 1, m_dpi ); + InflateRect( &rect, -width, -width ); + FillRect( deviceContext, &rect, static_cast(GetStockObject( BLACK_BRUSH )) ); + + EndPaint( window, &paint ); + return 0; + } + break; + } + + return DefWindowProcW( window, message, wordParam, longParam ); +} diff --git a/src/modules/ZoomIt/ZoomIt/SelectRectangle.h b/src/modules/ZoomIt/ZoomIt/SelectRectangle.h new file mode 100644 index 000000000000..aa31b6c53041 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/SelectRectangle.h @@ -0,0 +1,44 @@ +//============================================================================== +// +// Zoomit +// Sysinternals - www.sysinternals.com +// +// Class to select a recording rectangle and show it while recording +// +//============================================================================== +#pragma once + +#include "pch.h" + +class SelectRectangle +{ +public: + ~SelectRectangle() { Stop(); }; + + void Alpha( BYTE alpha ) { m_alpha = alpha; } + BYTE Alpha() const { return m_alpha; } + void MinSize( int minSize ) { m_minSize = minSize; } + int MinSize() const { return m_minSize; } + RECT SelectedRect() const { return m_selectedRect; } + + bool Start( HWND ownerWindow = nullptr, bool fullMonitor = false ); + void Stop(); + void UpdateOwner( HWND window ); + +private: + BYTE m_alpha = 176; + int m_minSize = 34; + RECT m_selectedRect{}; + + bool m_cancel = false; + const wchar_t* m_className = L"ZoomitSelectRectangle"; + UINT m_dpi{}; + RECT m_oldClipRect{}; + bool m_selected{ false }; + bool m_setClip{ false }; + POINT m_startPoint{}; + wil::unique_hwnd m_window; + + void ShowSelected(); + LRESULT WindowProc( HWND window, UINT message, WPARAM wordParam, LPARAM longParam ); +}; diff --git a/src/modules/ZoomIt/ZoomIt/Utility.cpp b/src/modules/ZoomIt/ZoomIt/Utility.cpp new file mode 100644 index 000000000000..ccc72ad752e3 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/Utility.cpp @@ -0,0 +1,153 @@ +//============================================================================== +// +// Zoomit +// Sysinternals - www.sysinternals.com +// +// Utility functions +// +//============================================================================== +#include "pch.h" +#include "Utility.h" + +//---------------------------------------------------------------------------- +// +// ForceRectInBounds +// +//---------------------------------------------------------------------------- +RECT ForceRectInBounds( RECT rect, const RECT& bounds ) +{ + if( rect.left < bounds.left ) + { + rect.right += bounds.left - rect.left; + rect.left = bounds.left; + } + if( rect.top < bounds.top ) + { + rect.bottom += bounds.top - rect.top; + rect.top = bounds.top; + } + if( rect.right > bounds.right ) + { + rect.left -= rect.right - bounds.right; + rect.right = bounds.right; + } + if( rect.bottom > bounds.bottom ) + { + rect.top -= rect.bottom - bounds.bottom; + rect.bottom = bounds.bottom; + } + return rect; +} + +//---------------------------------------------------------------------------- +// +// GetDpiForWindow +// +//---------------------------------------------------------------------------- +UINT GetDpiForWindowHelper( HWND window ) +{ + auto function = reinterpret_cast(GetProcAddress( GetModuleHandleW( L"user32.dll" ), "GetDpiForWindow" )); + if( function ) + { + return function( window ); + } + + wil::unique_hdc hdc{GetDC( nullptr )}; + return static_cast(GetDeviceCaps( hdc.get(), LOGPIXELSX )); +} + +//---------------------------------------------------------------------------- +// +// GetMonitorRectFromCursor +// +//---------------------------------------------------------------------------- +RECT GetMonitorRectFromCursor() +{ + POINT point; + GetCursorPos( &point ); + MONITORINFO monitorInfo{}; + monitorInfo.cbSize = sizeof( monitorInfo ); + GetMonitorInfoW( MonitorFromPoint( point, MONITOR_DEFAULTTONEAREST ), &monitorInfo ); + return monitorInfo.rcMonitor; +} + +//---------------------------------------------------------------------------- +// +// RectFromPointsMinSize +// +//---------------------------------------------------------------------------- +#ifdef _MSC_VER + // avoid making RectFromPointsMinSize constexpr since that leads to link errors + #pragma warning(push) + #pragma warning(disable: 26497) +#endif + +RECT RectFromPointsMinSize( POINT a, POINT b, LONG minSize ) +{ + RECT rect; + if( a.x <= b.x ) + { + rect.left = a.x; + rect.right = b.x + 1; + if( (rect.right - rect.left) < minSize ) + { + rect.right = rect.left + minSize; + } + } + else + { + rect.left = b.x; + rect.right = a.x + 1; + if( (rect.right - rect.left) < minSize ) + { + rect.left = rect.right - minSize; + } + } + if( a.y <= b.y ) + { + rect.top = a.y; + rect.bottom = b.y + 1; + if( (rect.bottom - rect.top) < minSize ) + { + rect.bottom = rect.top + minSize; + } + } + else + { + rect.top = b.y; + rect.bottom = a.y + 1; + if( (rect.bottom - rect.top) < minSize ) + { + rect.top = rect.bottom - minSize; + } + } + return rect; +} +#ifdef _MSC_VER + #pragma warning(pop) +#endif +//---------------------------------------------------------------------------- +// +// ScaleForDpi +// +//---------------------------------------------------------------------------- +int ScaleForDpi( int value, UINT dpi ) +{ + return MulDiv( value, static_cast(dpi), USER_DEFAULT_SCREEN_DPI ); +} + +//---------------------------------------------------------------------------- +// +// ScalePointInRects +// +//---------------------------------------------------------------------------- +POINT ScalePointInRects( POINT point, const RECT& source, const RECT& target ) +{ + const SIZE sourceSize{ source.right - source.left, source.bottom - source.top }; + const POINT sourceCenter{ source.left + sourceSize.cx / 2, source.top + sourceSize.cy / 2 }; + const SIZE targetSize{ target.right - target.left, target.bottom - target.top }; + const POINT targetCenter{ target.left + targetSize.cx / 2, target.top + targetSize.cy / 2 }; + + return { targetCenter.x + MulDiv( point.x - sourceCenter.x, targetSize.cx, sourceSize.cx ), + targetCenter.y + MulDiv( point.y - sourceCenter.y, targetSize.cy, sourceSize.cy ) }; +} diff --git a/src/modules/ZoomIt/ZoomIt/Utility.h b/src/modules/ZoomIt/ZoomIt/Utility.h new file mode 100644 index 000000000000..a78ecdf14e20 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/Utility.h @@ -0,0 +1,18 @@ +//============================================================================== +// +// Zoomit +// Sysinternals - www.sysinternals.com +// +// Utility functions +// +//============================================================================== +#pragma once + +#include "pch.h" + +RECT ForceRectInBounds( RECT rect, const RECT& bounds ); +UINT GetDpiForWindowHelper( HWND window ); +RECT GetMonitorRectFromCursor(); +RECT RectFromPointsMinSize( POINT a, POINT b, LONG minSize ); +int ScaleForDpi( int value, UINT dpi ); +POINT ScalePointInRects( POINT point, const RECT& source, const RECT& target ); diff --git a/src/modules/ZoomIt/ZoomIt/VersionHelper.cpp b/src/modules/ZoomIt/ZoomIt/VersionHelper.cpp new file mode 100644 index 000000000000..bbd758e4603e --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/VersionHelper.cpp @@ -0,0 +1,129 @@ + + +//-------------------------------------------------------------------- +// +// GetLanguageVersionString +// +// Gets version information for a particular code page. +// +//-------------------------------------------------------------------- +#include +#include "pch.h" +#include "VersionHelper.h" + +PTCHAR GetLanguageVersionString(P_VERSION_INFO VersionInfo, + LANGID LanguageId, WORD Charset, + LPCTSTR VersionString) +{ + TCHAR szQueryStr[0x100]; + PTCHAR pszVerRetVal; + UINT cbReturn; + BOOL fFound = FALSE; + + // Format the string + _stprintf_s(szQueryStr, ARRAYSIZE(szQueryStr), _T("\\StringFileInfo\\%04X%04X\\%s"), + LanguageId, Charset, + VersionString); + + fFound = VerQueryValue(VersionInfo, szQueryStr, + reinterpret_cast(&pszVerRetVal), &cbReturn); + + if (!fFound) { + return NULL; + } + else { + return pszVerRetVal; + } +} + +// +// explicitly use wide char version +// this is used when show banner in remote session before display eula from console which requires unicode for French +// it's needed for multibyte app +// +PWCHAR GetLanguageVersionStringW(P_VERSION_INFO VersionInfo, + LANGID LanguageId, WORD Charset, + LPCWSTR VersionString) +{ + WCHAR szQueryStr[0x100]; + PWCHAR pszVerRetVal; + UINT cbReturn; + BOOL fFound = FALSE; + + // Format the string + swprintf_s(szQueryStr, ARRAYSIZE(szQueryStr), L"\\StringFileInfo\\%04X%04X\\%s", + LanguageId, Charset, + VersionString); + + fFound = VerQueryValueW(VersionInfo, szQueryStr, + reinterpret_cast(&pszVerRetVal), &cbReturn); + + if (!fFound) { + return NULL; + } + else { + return pszVerRetVal; + } +} + +//-------------------------------------------------------------------- +// +// GetVersionString +// +// Gets a version string. +// +//-------------------------------------------------------------------- +PTCHAR GetVersionString(P_VERSION_INFO VersionInfo, + LPCTSTR VersionString) +{ + PTCHAR pszVerRetVal; + P_VERSION_TRANSLATION pTranslation; + VERSION_TRANSLATION translation; + unsigned int length; + + // + // Get the language id + // + translation.langID = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT); + pTranslation = &translation; + VerQueryValue(VersionInfo, + _T("\\VarFileInfo\\Translation"), + reinterpret_cast(&pTranslation), + &length); + + pszVerRetVal = GetLanguageVersionString(VersionInfo, + pTranslation->langID, + pTranslation->charset, + VersionString); + return pszVerRetVal; +} + +// +// explicitly use wide char version +// this is used when show banner in remote session before display eula from console which requires unicode for French +// it's needed for multibyte app +// +PWCHAR GetVersionStringW(P_VERSION_INFO VersionInfo, + LPCWSTR VersionString) +{ + PWCHAR pszVerRetVal; + P_VERSION_TRANSLATION pTranslation; + VERSION_TRANSLATION translation; + unsigned int length; + + // + // Get the language id + // + translation.langID = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT); + pTranslation = &translation; + VerQueryValueW(VersionInfo, + L"\\VarFileInfo\\Translation", + reinterpret_cast(&pTranslation), + &length); + + pszVerRetVal = GetLanguageVersionStringW(VersionInfo, + pTranslation->langID, + pTranslation->charset, + VersionString); + return pszVerRetVal; +} diff --git a/src/modules/ZoomIt/ZoomIt/VersionHelper.h b/src/modules/ZoomIt/ZoomIt/VersionHelper.h new file mode 100644 index 000000000000..fb92a8759457 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/VersionHelper.h @@ -0,0 +1,48 @@ +//============================================================================ +// +// VersionHelper.h +// +// Functions to retrieve version information +// +//============================================================================ + +#pragma once + +#include +#include +#include "winver.h" + +// +// File version information +// +typedef struct { + WORD wLength; + WORD wValueLength; + WORD wType; + WCHAR szKey[16]; + WORD Padding1; + VS_FIXEDFILEINFO Value; +} VERSION_INFO, *P_VERSION_INFO; + +// +// Version translation +// +typedef struct { + WORD langID; // language ID + WORD charset; // character set (code page) +} VERSION_TRANSLATION, *P_VERSION_TRANSLATION; + +PTCHAR GetVersionString(P_VERSION_INFO VersionInfo, LPCTSTR VersionString); + +PTCHAR GetLanguageVersionString(P_VERSION_INFO VersionInfo, + LANGID LanguageId, + WORD Charset, + LPCTSTR VersionString); + +PWCHAR GetLanguageVersionStringW(P_VERSION_INFO VersionInfo, + LANGID LanguageId, WORD Charset, + LPCWSTR VersionString); + +PWCHAR GetVersionStringW(P_VERSION_INFO VersionInfo, + LPCWSTR VersionString); + diff --git a/src/modules/ZoomIt/ZoomIt/VideoRecordingSession.cpp b/src/modules/ZoomIt/ZoomIt/VideoRecordingSession.cpp new file mode 100644 index 000000000000..086c8bfb2a2c --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/VideoRecordingSession.cpp @@ -0,0 +1,391 @@ +//============================================================================== +// +// Zoomit +// Sysinternals - www.sysinternals.com +// +// Video capture code derived from https://github.com/robmikh/capturevideosample +// +//============================================================================== +#include "pch.h" +#include "VideoRecordingSession.h" +#include "CaptureFrameWait.h" + +extern DWORD g_RecordScaling; + +namespace winrt +{ + using namespace Windows::Foundation; + using namespace Windows::Graphics; + using namespace Windows::Graphics::Capture; + using namespace Windows::Graphics::DirectX; + using namespace Windows::Graphics::DirectX::Direct3D11; + using namespace Windows::Storage; + using namespace Windows::UI::Composition; + using namespace Windows::Media::Core; + using namespace Windows::Media::Transcoding; + using namespace Windows::Media::MediaProperties; +} + +namespace util +{ + using namespace robmikh::common::uwp; +} + +const float CLEAR_COLOR[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + +int32_t EnsureEven(int32_t value) +{ + if (value % 2 == 0) + { + return value; + } + else + { + return value + 1; + } +} + +//---------------------------------------------------------------------------- +// +// VideoRecordingSession::VideoRecordingSession +// +//---------------------------------------------------------------------------- +VideoRecordingSession::VideoRecordingSession( + winrt::IDirect3DDevice const& device, + winrt::GraphicsCaptureItem const& item, + RECT const cropRect, + uint32_t frameRate, + bool captureAudio, + winrt::Streams::IRandomAccessStream const& stream) +{ + m_device = device; + m_d3dDevice = GetDXGIInterfaceFromObject(m_device); + m_d3dDevice->GetImmediateContext(m_d3dContext.put()); + m_item = item; + auto itemSize = item.Size(); + auto inputWidth = EnsureEven(itemSize.Width); + auto inputHeight = EnsureEven(itemSize.Height); + m_frameWait = std::make_shared(m_device, m_item, winrt::SizeInt32{ inputWidth, inputHeight }); + auto weakPointer{ std::weak_ptr{ m_frameWait } }; + m_itemClosed = item.Closed(winrt::auto_revoke, [weakPointer](auto&, auto&) + { + auto sharedPointer{ weakPointer.lock() }; + + if (sharedPointer) + { + sharedPointer->StopCapture(); + } + }); + + // Get crop dimension + if( (cropRect.right - cropRect.left) != 0 ) + { + m_rcCrop = cropRect; + m_frameWait->ShowCaptureBorder( false ); + } + else + { + m_rcCrop.left = 0; + m_rcCrop.top = 0; + m_rcCrop.right = inputWidth; + m_rcCrop.bottom = inputHeight; + } + + // Ensure the video is not too small and try to maintain the aspect ratio + constexpr int c_minimumSize = 34; + auto scaledWidth = MulDiv(m_rcCrop.right - m_rcCrop.left, g_RecordScaling, 100); + auto scaledHeight = MulDiv(m_rcCrop.bottom - m_rcCrop.top, g_RecordScaling, 100); + auto outputWidth = scaledWidth; + auto outputHeight = scaledHeight; + if (outputWidth < c_minimumSize) + { + outputWidth = c_minimumSize; + outputHeight = MulDiv(outputHeight, outputWidth, scaledWidth); + } + if (outputHeight < c_minimumSize) + { + outputHeight = c_minimumSize; + outputWidth = MulDiv(outputWidth, outputHeight, scaledHeight); + } + if (outputWidth > inputWidth) + { + outputWidth = inputWidth; + outputHeight = c_minimumSize, MulDiv(outputHeight, scaledWidth, outputWidth); + } + if (outputHeight > inputHeight) + { + outputHeight = inputHeight; + outputWidth = c_minimumSize, MulDiv(outputWidth, scaledHeight, outputHeight); + } + outputWidth = EnsureEven(outputWidth); + outputHeight = EnsureEven(outputHeight); + + // Describe out output: H264 video with an MP4 container + m_encodingProfile = winrt::MediaEncodingProfile(); + m_encodingProfile.Container().Subtype(L"MPEG4"); + auto video = m_encodingProfile.Video(); + video.Subtype(L"H264"); + video.Width(outputWidth); + video.Height(outputHeight); + video.Bitrate(static_cast(outputWidth * outputHeight * frameRate * 2 * 0.07)); + video.FrameRate().Numerator(frameRate); + video.FrameRate().Denominator(1); + video.PixelAspectRatio().Numerator(1); + video.PixelAspectRatio().Denominator(1); + m_encodingProfile.Video(video); + + // if audio capture, set up audio profile + if (captureAudio) + { + auto audio = m_encodingProfile.Audio(); + audio = winrt::AudioEncodingProperties::CreateAac(48000, 1, 16); + m_encodingProfile.Audio(audio); + } + + // Describe our input: uncompressed BGRA8 buffers + auto properties = winrt::VideoEncodingProperties::CreateUncompressed( + winrt::MediaEncodingSubtypes::Bgra8(), + static_cast(m_rcCrop.right - m_rcCrop.left), + static_cast(m_rcCrop.bottom - m_rcCrop.top)); + m_videoDescriptor = winrt::VideoStreamDescriptor(properties); + + m_stream = stream; + + m_previewSwapChain = util::CreateDXGISwapChain( + m_d3dDevice, + static_cast(m_rcCrop.right - m_rcCrop.left), + static_cast(m_rcCrop.bottom - m_rcCrop.top), + DXGI_FORMAT_B8G8R8A8_UNORM, + 2); + winrt::com_ptr backBuffer; + winrt::check_hresult(m_previewSwapChain->GetBuffer(0, winrt::guid_of(), backBuffer.put_void())); + winrt::check_hresult(m_d3dDevice->CreateRenderTargetView(backBuffer.get(), nullptr, m_renderTargetView.put())); + + if( captureAudio ) { + + m_audioGenerator = std::make_unique(); + } + else { + + m_audioGenerator = nullptr; + } +} + + +//---------------------------------------------------------------------------- +// +// VideoRecordingSession::~VideoRecordingSession +// +//---------------------------------------------------------------------------- +VideoRecordingSession::~VideoRecordingSession() +{ + Close(); +} + + +//---------------------------------------------------------------------------- +// +// VideoRecordingSession::StartAsync +// +//---------------------------------------------------------------------------- +winrt::IAsyncAction VideoRecordingSession::StartAsync() +{ + auto expected = false; + if (m_isRecording.compare_exchange_strong(expected, true)) + { + + // Create our MediaStreamSource + if(m_audioGenerator) { + + co_await m_audioGenerator->InitializeAsync(); + m_streamSource = winrt::MediaStreamSource(m_videoDescriptor, winrt::AudioStreamDescriptor(m_audioGenerator->GetEncodingProperties())); + } + else { + + m_streamSource = winrt::MediaStreamSource(m_videoDescriptor); + } + m_streamSource.BufferTime(std::chrono::seconds(0)); + m_streamSource.Starting({ this, &VideoRecordingSession::OnMediaStreamSourceStarting }); + m_streamSource.SampleRequested({ this, &VideoRecordingSession::OnMediaStreamSourceSampleRequested }); + + // Create our transcoder + m_transcoder = winrt::MediaTranscoder(); + m_transcoder.HardwareAccelerationEnabled(true); + + auto self = shared_from_this(); + + // Start encoding + auto transcode = co_await m_transcoder.PrepareMediaStreamSourceTranscodeAsync(m_streamSource, m_stream, m_encodingProfile); + co_await transcode.TranscodeAsync(); + } + co_return; +} + + +//---------------------------------------------------------------------------- +// +// VideoRecordingSession::Close +// +//---------------------------------------------------------------------------- +void VideoRecordingSession::Close() +{ + auto expected = false; + if (m_closed.compare_exchange_strong(expected, true)) + { + expected = true; + if (!m_isRecording.compare_exchange_strong(expected, false)) + { + CloseInternal(); + } + else + { + m_frameWait->StopCapture(); + } + } +} + +//---------------------------------------------------------------------------- +// +// VideoRecordingSession::CloseInternal +// +//---------------------------------------------------------------------------- +void VideoRecordingSession::CloseInternal() +{ + if(m_audioGenerator) { + m_audioGenerator->Stop(); + } + m_frameWait->StopCapture(); + m_itemClosed.revoke(); +} + + +//---------------------------------------------------------------------------- +// +// VideoRecordingSession::OnMediaStreamSourceStarting +// +//---------------------------------------------------------------------------- +void VideoRecordingSession::OnMediaStreamSourceStarting( + winrt::MediaStreamSource const&, + winrt::MediaStreamSourceStartingEventArgs const& args) +{ + auto frame = m_frameWait->TryGetNextFrame(); + if (frame) { + args.Request().SetActualStartPosition(frame->SystemRelativeTime); + if (m_audioGenerator) { + + m_audioGenerator->Start(); + } + } +} + +//---------------------------------------------------------------------------- +// +// VideoRecordingSession::Create +// +//---------------------------------------------------------------------------- +std::shared_ptr VideoRecordingSession::Create( + winrt::IDirect3DDevice const& device, + winrt::GraphicsCaptureItem const& item, + RECT const& crop, + uint32_t frameRate, + bool captureAudio, + winrt::Streams::IRandomAccessStream const& stream) +{ + return std::shared_ptr(new VideoRecordingSession(device, item, crop, frameRate, captureAudio, stream)); +} + +//---------------------------------------------------------------------------- +// +// VideoRecordingSession::OnMediaStreamSourceSampleRequested +// +//---------------------------------------------------------------------------- +void VideoRecordingSession::OnMediaStreamSourceSampleRequested( + winrt::MediaStreamSource const&, + winrt::MediaStreamSourceSampleRequestedEventArgs const& args) +{ + auto request = args.Request(); + auto streamDescriptor = request.StreamDescriptor(); + if (auto videoStreamDescriptor = streamDescriptor.try_as()) + { + if (auto frame = m_frameWait->TryGetNextFrame()) + { + try + { + auto timeStamp = frame->SystemRelativeTime; + auto contentSize = frame->ContentSize; + auto frameTexture = GetDXGIInterfaceFromObject(frame->FrameTexture); + D3D11_TEXTURE2D_DESC desc = {}; + frameTexture->GetDesc(&desc); + + winrt::com_ptr backBuffer; + winrt::check_hresult(m_previewSwapChain->GetBuffer(0, winrt::guid_of(), backBuffer.put_void())); + + // Use the smaller of the crop size or content size. The content + // size can change while recording, for example by resizing the + // window. This ensures that only valid content is copied. + auto width = min(m_rcCrop.right - m_rcCrop.left, contentSize.Width); + auto height = min(m_rcCrop.bottom - m_rcCrop.top, contentSize.Height); + + // Set the content region to copy and clamp the coordinates to the + // texture surface. + D3D11_BOX region = {}; + region.left = std::clamp(m_rcCrop.left, static_cast(0), static_cast(desc.Width)); + region.right = std::clamp(m_rcCrop.left + width, static_cast(0), static_cast(desc.Width)); + region.top = std::clamp(m_rcCrop.top, static_cast(0), static_cast(desc.Height)); + region.bottom = std::clamp(m_rcCrop.top + height, static_cast(0), static_cast(desc.Height)); + region.back = 1; + + m_d3dContext->ClearRenderTargetView(m_renderTargetView.get(), CLEAR_COLOR); + m_d3dContext->CopySubresourceRegion( + backBuffer.get(), + 0, + 0, 0, 0, + frameTexture.get(), + 0, + ®ion); + + desc = {}; + backBuffer->GetDesc(&desc); + + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + winrt::com_ptr sampleTexture; + winrt::check_hresult(m_d3dDevice->CreateTexture2D(&desc, nullptr, sampleTexture.put())); + m_d3dContext->CopyResource(sampleTexture.get(), backBuffer.get()); + auto dxgiSurface = sampleTexture.as(); + auto sampleSurface = CreateDirect3DSurface(dxgiSurface.get()); + + DXGI_PRESENT_PARAMETERS presentParameters{}; + winrt::check_hresult(m_previewSwapChain->Present1(0, 0, &presentParameters)); + + auto sample = winrt::MediaStreamSample::CreateFromDirect3D11Surface(sampleSurface, timeStamp); + request.Sample(sample); + } + catch (winrt::hresult_error const& error) + { + OutputDebugStringW(error.message().c_str()); + request.Sample(nullptr); + CloseInternal(); + return; + } + } + else + { + request.Sample(nullptr); + CloseInternal(); + } + } + else if (auto audioStreamDescriptor = streamDescriptor.try_as()) + { + if (auto sample = m_audioGenerator->TryGetNextSample()) + { + request.Sample(sample.value()); + } + else + { + request.Sample(nullptr); + } + } +} diff --git a/src/modules/ZoomIt/ZoomIt/VideoRecordingSession.h b/src/modules/ZoomIt/ZoomIt/VideoRecordingSession.h new file mode 100644 index 000000000000..960ac36444a6 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/VideoRecordingSession.h @@ -0,0 +1,71 @@ +//============================================================================== +// +// Zoomit +// Sysinternals - www.sysinternals.com +// +// Video capture code derived from https://github.com/robmikh/capturevideosample +// +//============================================================================== +#pragma once + +#include "CaptureFrameWait.h" +#include "AudioSampleGenerator.h" +#include + +class VideoRecordingSession : public std::enable_shared_from_this +{ +public: + [[nodiscard]] static std::shared_ptr Create( + winrt::Direct3D11::IDirect3DDevice const& device, + winrt::GraphicsCaptureItem const& item, + RECT const& cropRect, + uint32_t frameRate, + bool captureAudio, + winrt::Streams::IRandomAccessStream const& stream); + ~VideoRecordingSession(); + + winrt::IAsyncAction StartAsync(); + void EnableCursorCapture(bool enable = true) { m_frameWait->EnableCursorCapture(enable); } + void Close(); + +private: + VideoRecordingSession( + winrt::Direct3D11::IDirect3DDevice const& device, + winrt::Capture::GraphicsCaptureItem const& item, + RECT const cropRect, + uint32_t frameRate, + bool captureAudio, + winrt::Streams::IRandomAccessStream const& stream); + void CloseInternal(); + + void OnMediaStreamSourceStarting( + winrt::MediaStreamSource const& sender, + winrt::MediaStreamSourceStartingEventArgs const& args); + void OnMediaStreamSourceSampleRequested( + winrt::MediaStreamSource const& sender, + winrt::MediaStreamSourceSampleRequestedEventArgs const& args); + +private: + winrt::Direct3D11::IDirect3DDevice m_device{ nullptr }; + winrt::com_ptr m_d3dDevice; + winrt::com_ptr m_d3dContext; + RECT m_rcCrop; + + winrt::GraphicsCaptureItem m_item{ nullptr }; + winrt::GraphicsCaptureItem::Closed_revoker m_itemClosed; + std::shared_ptr m_frameWait; + + winrt::Streams::IRandomAccessStream m_stream{ nullptr }; + winrt::MediaEncodingProfile m_encodingProfile{ nullptr }; + winrt::VideoStreamDescriptor m_videoDescriptor{ nullptr }; + winrt::MediaStreamSource m_streamSource{ nullptr }; + winrt::MediaTranscoder m_transcoder{ nullptr }; + + std::unique_ptr m_audioGenerator; + + winrt::com_ptr m_previewSwapChain; + winrt::com_ptr m_renderTargetView; + + std::atomic m_isRecording = false; + std::atomic m_closed = false; +}; \ No newline at end of file diff --git a/src/modules/ZoomIt/ZoomIt/ZoomIt.h b/src/modules/ZoomIt/ZoomIt/ZoomIt.h new file mode 100644 index 000000000000..5abbc2103996 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/ZoomIt.h @@ -0,0 +1,223 @@ +//============================================================================ +// +// Zoomit +// Copyright (C) Mark Russinovich +// Sysinternals - www.sysinternals.com +// +// Screen zoom and annotation tool. +// +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +//============================================================================ +#pragma once + +// Ignore getversion deprecation warning +#pragma warning( disable: 4996 ) + +typedef HRESULT (__stdcall * type_pEnableThemeDialogTexture)( + HWND hwnd, + DWORD dwFlags + ); +type_pEnableThemeDialogTexture pEnableThemeDialogTexture; + +// For testing anti-aliased bitmap stretching +#define SCALE_GDIPLUS 0 +#define SCALE_HALFTONE 0 + +// sent in mouse message when coming from tablet pen +#define MI_WP_SIGNATURE 0xFF515700 + +#define ZOOM_LEVEL_MIN 1 +#define ZOOM_LEVEL_INIT 2 +#define ZOOM_LEVEL_STEP_IN ((float) 1.1) +#define ZOOM_LEVEL_STEP_OUT ((float) 0.8) +#define ZOOM_LEVEL_MAX 32 +#define ZOOM_LEVEL_STEP_TIME 20 + +#define LIVEZOOM_MOVE_REGIONS 8 + +#define WIN7_VERSION 0x106 +#define WIN10_VERSION 0x206 + +// Time that we'll cache live zoom window to avoid flicker +// of live zooming on Vista/ws2k8 +#define LIVEZOOM_WINDOW_TIMEOUT 2*3600*1000 + +#define MAX_UNDO_HISTORY 32 + +#define PEN_WIDTH 5 +#define MIN_PEN_WIDTH 2 +#define MAX_PEN_WIDTH 40 +#define MAX_LIVE_PEN_WIDTH 600 + +#define APPNAME L"ZoomIt" +#define WM_USER_TRAY_ACTIVATE WM_USER+100 +#define WM_USER_TYPING_OFF WM_USER+101 +#define WM_USER_GET_ZOOM_LEVEL WM_USER+102 +#define WM_USER_GET_SOURCE_RECT WM_USER+103 +#define WM_USER_SET_ZOOM WM_USER+104 +#define WM_USER_STOP_RECORDING WM_USER+105 +#define WM_USER_SAVE_CURSOR WM_USER+106 +#define WM_USER_RESTORE_CURSOR WM_USER+107 +#define WM_USER_MAGNIFY_CURSOR WM_USER+108 +#define WM_USER_EXIT_MODE WM_USER+109 +#define WM_USER_RELOAD_SETTINGS WM_USER+110 + +typedef struct _TYPED_KEY { + RECT rc; + struct _TYPED_KEY *Next; +} TYPED_KEY, *P_TYPED_KEY; + +typedef struct _DRAW_UNDO { + HDC hDc; + HBITMAP hBitmap; + struct _DRAW_UNDO *Next; +} DRAW_UNDO, *P_DRAW_UNDO; + +typedef struct { + TCHAR TabTitle[64]; + HWND hPage; +} OPTION_TABS, *P_OPTIONS_TABS; + +#define COLOR_RED RGB(255, 0, 0) +#define COLOR_GREEN RGB(0, 255, 0) +#define COLOR_BLUE RGB(0, 0, 255) +#define COLOR_ORANGE RGB(255,128,0) +#define COLOR_YELLOW RGB(255, 255, 0 ) +#define COLOR_PINK RGB(255,128,255) +#define COLOR_BLUR RGB(112,112,112) + +#define DRAW_RECTANGLE 1 +#define DRAW_ELLIPSE 2 +#define DRAW_LINE 3 +#define DRAW_ARROW 4 + +#define SHALLOW_ZOOM 1 +#define SHALLOW_DESTROY 2 +#define LIVE_DRAW_ZOOM 3 + +#define PEN_COLOR_HIGHLIGHT(Pencolor) (Pencolor >> 24) != 0xFF + + +typedef BOOL (__stdcall *type_pGetMonitorInfo)( + HMONITOR hMonitor, // handle to display monitor + LPMONITORINFO lpmi // display monitor information +); + +typedef HMONITOR (__stdcall *type_MonitorFromPoint)( + POINT pt, // point + DWORD dwFlags // determine return value +); + +typedef HRESULT (__stdcall *type_pSHAutoComplete)( + HWND hwndEdit, + DWORD dwFlags +); + +// DPI awareness +typedef BOOL (__stdcall *type_pSetProcessDPIAware)(void); + +// Live zoom +typedef BOOL (__stdcall *type_pMagSetWindowSource)(HWND hwnd, + RECT rect +); +typedef BOOL (__stdcall *type_pMagSetWindowTransform)(HWND hwnd, + PMAGTRANSFORM pTransform +); +typedef BOOL(__stdcall* type_pMagSetFullscreenTransform)( + float magLevel, + int xOffset, + int yOffset +); +typedef BOOL(__stdcall* type_pMagSetInputTransform)( + BOOL fEnabled, + const LPRECT pRectSource, + const LPRECT pRectDest +); +typedef BOOL (__stdcall *type_pMagShowSystemCursor)( + BOOL fShowCursor +); +typedef BOOL(__stdcall *type_pMagSetWindowFilterList)( + HWND hwnd, + DWORD dwFilterMode, + int count, + HWND* pHWND +); +typedef BOOL (__stdcall *type_pMagInitialize)(VOID); + +typedef BOOL(__stdcall *type_pGetPointerType)( + _In_ UINT32 pointerId, + _Out_ POINTER_INPUT_TYPE *pointerType + ); + +typedef BOOL(__stdcall *type_pGetPointerPenInfo)( + _In_ UINT32 pointerId, + _Out_ POINTER_PEN_INFO *penInfo + ); + +typedef HRESULT (__stdcall *type_pDwmIsCompositionEnabled)( + BOOL *pfEnabled +); + +// opacity +typedef BOOL (__stdcall *type_pSetLayeredWindowAttributes)( + HWND hwnd, // handle to the layered window + COLORREF crKey, // specifies the color key + BYTE bAlpha, // value for the blend function + DWORD dwFlags // action +); + +// Presentation mode check +typedef HRESULT (__stdcall *type_pSHQueryUserNotificationState)( + QUERY_USER_NOTIFICATION_STATE *pQueryUserNotificationState +); + +typedef BOOL (__stdcall *type_pSystemParametersInfoForDpi)( + UINT uiAction, + UINT uiParam, + PVOID pvParam, + UINT fWinIni, + UINT dpi +); + +typedef UINT (__stdcall *type_pGetDpiForWindow)( + HWND hwnd +); + +class ComputerGraphicsInit +{ + ULONG_PTR m_Token; +public: + ComputerGraphicsInit() + { + Gdiplus::GdiplusStartupOutput startupOut; + Gdiplus::GdiplusStartupInput startupIn; + Gdiplus::GdiplusStartup( &m_Token, &startupIn, &startupOut ); + } + ~ComputerGraphicsInit() + { + Gdiplus::GdiplusShutdown( m_Token ); + } +}; + +// Direct3D +typedef HRESULT (__stdcall *type_pCreateDirect3D11DeviceFromDXGIDevice)( + IDXGIDevice *dxgiDevice, + IInspectable **graphicsDevice +); +typedef HRESULT (__stdcall *type_pCreateDirect3D11SurfaceFromDXGISurface)( + IDXGISurface *dxgiSurface, + IInspectable **graphicsSurface +); +typedef HRESULT (__stdcall *type_pD3D11CreateDevice)( + IDXGIAdapter *pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + const D3D_FEATURE_LEVEL *pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + ID3D11Device **ppDevice, + D3D_FEATURE_LEVEL *pFeatureLevel, + ID3D11DeviceContext **ppImmediateContext +); diff --git a/src/modules/ZoomIt/ZoomIt/ZoomIt.idc b/src/modules/ZoomIt/ZoomIt/ZoomIt.idc new file mode 100644 index 000000000000..5bb02ecab73d --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/ZoomIt.idc @@ -0,0 +1 @@ + diff --git a/src/modules/ZoomIt/ZoomIt/ZoomIt.rc b/src/modules/ZoomIt/ZoomIt/ZoomIt.rc new file mode 100644 index 000000000000..c57e0ce94b42 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/ZoomIt.rc @@ -0,0 +1,484 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +// version.h and branding.h are different in the Sysinternals repository, +// keep the includes as such, here. +// From $(MSBuildThisFileDirectory)..\..\..\common\version +#include "version.h" +// From $(MSBuildThisFileDirectory)PowerToys +#include "branding.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "#include ""binres.rc""\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Cursor +// + +NULLCURSOR CURSOR "cursor1.cur" + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +APPICON ICON "appicon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION FILE_VERSION + PRODUCTVERSION PRODUCT_VERSION + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", COMPANY_NAME + VALUE "FileDescription", FILE_DESCRIPTION + VALUE "FileVersion", FILE_VERSION_STRING + VALUE "InternalName", INTERNAL_NAME + VALUE "LegalCopyright", COPYRIGHT_NOTE + VALUE "OriginalFilename", ORIGINAL_FILENAME + VALUE "ProductName", ZOOMIT_PRODUCT_NAME + VALUE "ProductVersion", PRODUCT_VERSION_STRING + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +OPTIONS DIALOGEX 0, 0, 279, 325 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CLIPSIBLINGS | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "ZoomIt - Sysinternals: www.sysinternals.com" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + DEFPUSHBUTTON "OK",IDOK,166,306,50,14 + PUSHBUTTON "Cancel",IDCANCEL,223,306,50,14 + LTEXT "ZoomIt v9.0",IDC_VERSION,42,7,73,10 + LTEXT "Copyright � 2006-2024 Mark Russinovich",IDC_COPYRIGHT,42,17,166,8 + CONTROL "Sysinternals - www.sysinternals.com",IDC_LINK, + "SysLink",WS_TABSTOP,42,26,150,9 + ICON "APPICON",IDC_STATIC,12,9,20,20 + CONTROL "Show tray icon",IDC_SHOW_TRAY_ICON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,295,105,10 + CONTROL "",IDC_TAB,"SysTabControl32",TCS_MULTILINE | WS_TABSTOP,8,46,265,245 + CONTROL "Run ZoomIt when Windows starts",IDC_AUTOSTART,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,309,122,10 +END + +ADVANCED_BREAK DIALOGEX 0, 0, 209, 219 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Advanced Break Options" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "Play Sound on Expiration:",IDC_CHECK_SOUND_FILE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,11,98,10,WS_EX_RIGHT + EDITTEXT IDC_SOUND_FILE,61,38,125,12,ES_AUTOHSCROLL | ES_READONLY + PUSHBUTTON "&...",IDC_SOUND_BROWSE,187,38,13,11 + COMBOBOX IDC_OPACITY,62,58,38,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "",IDC_TIMER_POS1,"Button",BS_AUTORADIOBUTTON,63,78,10,10 + CONTROL "",IDC_TIMER_POS2,"Button",BS_AUTORADIOBUTTON,79,78,10,10 + CONTROL "",IDC_TIMER_POS3,"Button",BS_AUTORADIOBUTTON,97,78,10,10 + CONTROL "",IDC_TIMER_POS4,"Button",BS_AUTORADIOBUTTON,63,93,10,10 + CONTROL "",IDC_TIMER_POS5,"Button",BS_AUTORADIOBUTTON,79,93,10,10 + CONTROL "",IDC_TIMER_POS6,"Button",BS_AUTORADIOBUTTON,97,93,10,10 + CONTROL "",IDC_TIMER_POS7,"Button",BS_AUTORADIOBUTTON,63,108,10,10 + CONTROL "",IDC_TIMER_POS8,"Button",BS_AUTORADIOBUTTON,79,108,10,10 + CONTROL "",IDC_TIMER_POS9,"Button",BS_AUTORADIOBUTTON,97,108,10,10 + CONTROL "Show background bitmap:",IDC_CHECK_BACKGROUND_FILE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,122,99,10,WS_EX_RIGHT + CONTROL "Use faded desktop as background",IDC_STATIC_DESKTOP_BACKGROUND, + "Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,46,135,125,10 + CONTROL "Use image file as background",IDC_STATIC_BACKGROUND_FILE, + "Button",BS_AUTORADIOBUTTON | WS_TABSTOP,46,149,109,10 + EDITTEXT IDC_BACKGROUND_FILE,62,164,125,12,ES_AUTOHSCROLL | ES_READONLY + PUSHBUTTON "&...",IDC_BACKGROUND_BROWSE,188,164,13,11 + CONTROL "Scale to screen:",IDC_CHECK_BACKGROUND_STRETCH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,58,180,67,10,WS_EX_RIGHT + DEFPUSHBUTTON "OK",IDOK,97,201,50,14 + PUSHBUTTON "Cancel",IDCANCEL,150,201,50,14 + LTEXT "Alarm Sound File:",IDC_STATIC_SOUND_FILE,61,26,56,8 + LTEXT "Timer Opacity:",IDC_STATIC,8,59,48,8 + LTEXT "Timer Position:",IDC_STATIC,8,77,48,8 + CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME | SS_SUNKEN,7,196,193,1,WS_EX_CLIENTEDGE +END + +ZOOM DIALOGEX 0, 0, 260, 158 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | WS_SYSMENU +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_HOTKEY,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,59,57,80,12 + LTEXT "After toggling ZoomIt you can zoom in with the mouse wheel or up and down arrow keys. Exit zoom mode with Escape or by pressing the right mouse button.",IDC_STATIC,7,6,246,26 + LTEXT "Zoom Toggle:",IDC_STATIC,7,59,51,8 + CONTROL "",IDC_ZOOM_SLIDER,"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,53,104,150,15,WS_EX_TRANSPARENT + LTEXT "Specify the initial level of magnification when zooming in:",IDC_STATIC,7,91,215,10 + LTEXT "1.25",IDC_STATIC,52,122,16,8 + LTEXT "1.5",IDC_STATIC,82,122,12,8 + LTEXT "1.75",IDC_STATIC,108,122,16,8 + LTEXT "2.0",IDC_STATIC,138,122,12,8 + LTEXT "3.0",IDC_STATIC,164,122,12,8 + LTEXT "4.0",IDC_STATIC,190,122,12,8 + CONTROL "Animate zoom in and zoom out:",IDC_ANIMATE_ZOOM,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,7,74,116,10 + LTEXT "Copy a zoomed screen with Ctrl+C or save it by typing Ctrl+S. Crop the copy or save region by entering Ctrl+Shift instead of Ctrl.",IDC_STATIC,7,34,246,17 +END + +DRAW DIALOGEX 0, 0, 260, 228 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "Once zoomed, toggle drawing mode by pressing the left mouse button. Undo with Ctrl+Z and all drawing by pressing E. Center the cursor with the space bar. Exit drawing mode by pressing the right mouse button.",IDC_STATIC,7,7,246,24 + LTEXT "Pen Control ",IDC_PEN_CONTROL,7,38,40,8 + LTEXT "Change the pen width by pressing left Ctrl and using the mouse wheel or the up and down arrow keys.",IDC_STATIC,19,48,233,16 + LTEXT "Colors",IDC_COLORS,7,70,21,8 + LTEXT "Change the pen color by pressing R (red), G (green), B (blue),\nO (orange), Y (yellow) or P (pink).",IDC_STATIC,19,80,233,16 + LTEXT "Highlight and Blur",IDC_HIGHLIGHT_AND_BLUR,7,102,58,8 + LTEXT "Hold Shift while pressing a color key for a translucent highlighter color. Press X for blur or Shift+X for a stronger blur.",IDC_STATIC,19,113,233,16 + LTEXT "Shapes",IDC_SHAPES,7,134,23,8 + LTEXT "Draw a line by holding down the Shift key, a rectangle with the Ctrl key, an ellipse with the Tab key and an arrow with Shift+Ctrl.",IDC_STATIC,19,144,233,16 + LTEXT "Screen",IDC_SCREEN,7,166,22,8 + LTEXT "Clear the screen for a sketch pad by pressing W (white) or K (black). Copy a zoomed screen with Ctrl+C or save it by typing Ctrl+S. Crop the copy or save region by entering Ctrl+Shift instead of Ctrl.",IDC_STATIC,19,176,233,24 + CONTROL "",IDC_DRAW_HOTKEY,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,73,207,80,12 + LTEXT "Draw w/out Zoom:",IDC_STATIC,7,210,63,11 +END + +TYPE DIALOGEX 0, 0, 260, 104 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "Once in drawing mode, type 't' to enter typing mode or shift+'t' to enter typing mode with right-aligned input. Exit typing mode by pressing escape or the left mouse button. Use the mouse wheel or up and down arrow keys to change the font size.",IDC_STATIC,7,7,246,32 + LTEXT "The text color is the current drawing color.",IDC_STATIC,7,47,211,9 + PUSHBUTTON "&Font",IDC_FONT,112,69,41,14 + GROUPBOX "Text Font",IDC_TEXT_FONT,8,61,99,28 +END + +BREAK DIALOGEX 0, 0, 260, 123 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_BREAK_HOTKEY,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,52,67,80,12 + EDITTEXT IDC_TIMER,31,86,31,13,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_SPIN_TIMER,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,45,86,11,12 + LTEXT "minutes",IDC_STATIC,67,88,25,8 + PUSHBUTTON "&Advanced",IDC_ADVANCED_BREAK,212,102,41,14 + LTEXT "Enter timer mode by using the ZoomIt tray icon's Break menu item. Increase and decrease time with the arrow keys. If you Alt-Tab away from the timer window, reactivate it by left-clicking on the ZoomIt tray icon. Exit timer mode with Escape. ",IDC_STATIC,7,7,246,33 + LTEXT "Start Timer:",IDC_STATIC,7,70,39,8 + LTEXT "Timer:",IDC_STATIC,7,88,20,8 + LTEXT "Change the break timer color using the same keys that the drawing color. The break timer font is the same as text font.",IDC_STATIC,7,45,219,20 + CONTROL "Show Time Elapsed After Expiration:",IDC_CHECK_SHOW_EXPIRED, + "Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,8,104,132,10 +END + +1543 DIALOGEX 100, 50, 216, 131 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "ZoomIt Font" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + LTEXT "&Font:",1088,6,0,40,9 + COMBOBOX 1136,6,10,94,64,CBS_SIMPLE | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | CBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP + LTEXT "Font St&yle:",1089,108,0,44,9 + COMBOBOX 1137,108,10,64,64,CBS_SIMPLE | CBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP + LTEXT "&Size:",1090,179,0,30,9 + COMBOBOX 1138,179,10,32,64,CBS_SIMPLE | CBS_OWNERDRAWFIXED | CBS_SORT | CBS_HASSTRINGS | CBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "OK",IDOK,166,94,45,14,WS_GROUP + PUSHBUTTON "Cancel",IDCANCEL,166,111,45,14,WS_GROUP + GROUPBOX "Sample",1073,7,75,143,51,WS_GROUP + CTEXT "AaBbYyZz",1092,16,88,127,31,SS_NOPREFIX | NOT WS_VISIBLE +END + +LIVEZOOM DIALOGEX 0, 0, 260, 134 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_LIVE_HOTKEY,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,69,108,80,12 + LTEXT "LiveZoom mode is supported on Windows 7 and higher where window updates show while zoomed. ",IDC_STATIC,7,7,246,18 + LTEXT "LiveZoom Toggle:",IDC_STATIC,7,110,62,8 + LTEXT "To enter and exit LiveZoom, enter the hotkey specified below.",IDC_STATIC,7,94,218,13 + LTEXT "Note that in LiveZoom you must use Ctrl+Up and Ctrl+Down to control the zoom level. To enter drawing mode, use the standard zoom-without-draw hotkey and then escape to go back to LiveZoom.",IDC_STATIC,7,30,246,27 + LTEXT "Use LiveDraw to draw and annotate the live desktop. To activate LiveDraw, enter the hotkey with the Shift key in the opposite mode. You can remove LiveDraw annotations by activating LiveDraw and enter the escape key",IDC_STATIC,7,62,246,32 +END + +RECORD DIALOGEX 0, 0, 260, 169 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_RECORD_HOTKEY,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,61,96,80,12 + LTEXT "Record Toggle:",IDC_STATIC,7,98,54,8 + LTEXT "Record video of the unzoomed live screen or a static zoomed session by entering the recording hot key and finish the recording by entering it again. ",IDC_STATIC,7,7,246,28 + LTEXT "Note: Recording is only available on Windows 10 (version 1903) and higher.",IDC_STATIC,7,77,246,19 + LTEXT "Scaling:",IDC_STATIC,30,115,26,8 + COMBOBOX IDC_RECORD_SCALING,61,114,26,30,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | CBS_OEMCONVERT | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Frame Rate:",IDC_STATIC,119,115,44,8,NOT WS_VISIBLE + COMBOBOX IDC_RECORD_FRAME_RATE,166,114,42,30,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | CBS_OEMCONVERT | CBS_SORT | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP + LTEXT "To crop the portion of the screen that will be recorded, enter the hotkey with the Shift key in the opposite mode. ",IDC_STATIC,7,32,246,19 + LTEXT "To record a specific window, enter the hotkey with the Alt key in the opposite mode.",IDC_STATIC,7,55,246,19 + CONTROL "&Capture audio input:",IDC_CAPTURE_AUDIO,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,7,137,83,10 + COMBOBOX IDC_MICROPHONE,81,152,172,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Microphone:",IDC_STATIC,32,154,47,8 +END + +SNIP DIALOGEX 0, 0, 260, 68 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | WS_SYSMENU +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_SNIP_HOTKEY,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,55,32,80,12 + LTEXT "Snip Toggle:",IDC_STATIC,7,33,45,8 + LTEXT "Copy a region of the screen to the clipboard or enter the hotkey with the Shift key in the opposite mode to save it to a file. ",IDC_STATIC,7,7,246,19 +END + +DEMOTYPE DIALOGEX 0, 0, 259, 249 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | WS_SYSMENU +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_DEMOTYPE_HOTKEY,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,74,154,80,12 + LTEXT "DemoType toggle:",IDC_STATIC,7,157,63,8 + PUSHBUTTON "&...",IDC_DEMOTYPE_BROWSE,231,137,16,13 + CONTROL "",IDC_DEMOTYPE_SPEED_SLIDER,"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,52,202,150,11,WS_EX_TRANSPARENT + CONTROL "Drive input with typing:",IDC_DEMOTYPE_USER_DRIVEN,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,7,173,88,10 + LTEXT "DemoType typing speed:",IDC_STATIC,7,189,215,10 + LTEXT "Slow",IDC_DEMOTYPE_STATIC1,51,213,18,8 + LTEXT "Fast",IDC_DEMOTYPE_STATIC2,186,213,17,8 + EDITTEXT IDC_DEMOTYPE_FILE,44,137,187,12,ES_AUTOHSCROLL | ES_READONLY + LTEXT "Input file:",IDC_STATIC,7,139,32,8 + LTEXT "When you reach the end of the file, ZoomIt will reload the file and start at the beginning. Enter the hotkey with the Shift key in the opposite mode to step back to the last [end].",IDC_STATIC,7,108,248,24 + LTEXT "DemoType has ZoomIt type text specified in the input file when you enter the DemoType toggle. Simply separate snippets with the [end] keyword, or you can insert text from the clipboard if it is prefixed with the [start].",IDC_STATIC,7,7,248,24 + LTEXT " - Insert pauses with the [pause:n] keyword where 'n' is seconds. ",IDC_STATIC,19,34,212,11 + LTEXT "You can have ZoomIt send text automatically, or select the option to drive input with typing. ZoomIt will block keyboard input while sending output.",IDC_STATIC,7,68,248,16 + LTEXT "When driving input, hit the space bar to unblock keyboard input at the end of a snippet. In auto mode, control will be returned upon completion.",IDC_STATIC,7,88,248,16 + LTEXT "- Send text via the clipboard with [paste] and [/paste]. ",IDC_STATIC,23,45,178,8 + LTEXT "- Send keystrokes with [enter], [up], [down], [left], and [right].",IDC_STATIC,23,56,211,8 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + "OPTIONS", DIALOG + BEGIN + RIGHTMARGIN, 273 + BOTTOMMARGIN, 320 + END + + "ADVANCED_BREAK", DIALOG + BEGIN + RIGHTMARGIN, 207 + BOTTOMMARGIN, 215 + END + + "ZOOM", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 253 + TOPMARGIN, 7 + BOTTOMMARGIN, 151 + END + + "DRAW", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 253 + TOPMARGIN, 7 + BOTTOMMARGIN, 221 + END + + "TYPE", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 253 + TOPMARGIN, 7 + BOTTOMMARGIN, 97 + END + + "BREAK", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 253 + TOPMARGIN, 7 + BOTTOMMARGIN, 116 + END + + 1543, DIALOG + BEGIN + RIGHTMARGIN, 211 + BOTTOMMARGIN, 127 + END + + "LIVEZOOM", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 253 + TOPMARGIN, 7 + BOTTOMMARGIN, 127 + END + + "RECORD", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 253 + TOPMARGIN, 7 + BOTTOMMARGIN, 164 + END + + "SNIP", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 253 + TOPMARGIN, 7 + BOTTOMMARGIN, 61 + END + + "DEMOTYPE", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 255 + TOPMARGIN, 7 + BOTTOMMARGIN, 205 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +ACCELERATORS ACCELERATORS +BEGIN + "C", IDC_COPY, VIRTKEY, CONTROL, NOINVERT + "S", IDC_SAVE, VIRTKEY, CONTROL, NOINVERT + "C", IDC_COPY_CROP, VIRTKEY, SHIFT, CONTROL, NOINVERT + "S", IDC_SAVE_CROP, VIRTKEY, SHIFT, CONTROL, NOINVERT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// AFX_DIALOG_LAYOUT +// + +OPTIONS AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +LIVEZOOM AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +DRAW AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +RECORD AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +TYPE AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +ZOOM AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +SNIP AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +BREAK AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +DEMOTYPE AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "binres.rc" +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/src/modules/ZoomIt/ZoomIt/ZoomIt.vcxproj b/src/modules/ZoomIt/ZoomIt/ZoomIt.vcxproj new file mode 100644 index 000000000000..d054d2b4bdf7 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/ZoomIt.vcxproj @@ -0,0 +1,370 @@ + + + + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {0A84F764-3A88-44CD-AA96-41BDBD48627B} + ZoomIt + true + true + true + PowerToys.$(MSBuildProjectName) + + + false + + + + + false + $(ProjectDir)$(Configuration)\InterPlatform\ + + + false + $(ProjectDir)$(Configuration)\InterPlatform\ + RCZOOMIT + + + false + RCZOOMIT + + + false + $(ProjectDir)$(Configuration)\InterPlatform\ + + + false + $(ProjectDir)$(Configuration)\InterPlatform\ + RCZOOMIT + + + false + RCZOOMIT + + + + 4100;4091;4245 + ..\..\..\;$(MSBuildThisFileDirectory)..\..\..\common\sysinternals;%(AdditionalIncludeDirectories); + Create + pch.h + stdcpplatest + stdc17 + + + + + MaxSpeed + __ZOOMIT_POWERTOYS__;_UNICODE;UNICODE;WINVER=0x602;NDEBUG;_WIN32_WINNT=0x602;_WIN32_WINDOWS=0x501;WIN32;_WINDOWS;MSVC6=1;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + MultiThreaded + true + + + NDEBUG;_M_IX86;%(PreprocessorDefinitions) + 0x0409 + $(MSBuildThisFileDirectory)..\..\..\common\version;$(MSBuildThisFileDirectory)PowerToys;$(InterPlatformDir) + + + Shlwapi.lib;comctl32.lib;odbc32.lib;odbccp32.lib;version.lib;Winmm.lib;gdiplus.lib;Msimg32.lib;%(AdditionalDependencies) + true + Windows + true + true + MachineX86 + + + + + MaxSpeed + __ZOOMIT_POWERTOYS__;_UNICODE;UNICODE;WINVER=0x602;NDEBUG;_WIN32_WINNT=0x602;_WIN32_WINDOWS=0x501;WIN32;_WINDOWS;MSVC6=1;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + MultiThreaded + true + + + NDEBUG;_M_X64;%(PreprocessorDefinitions) + 0x0409 + $(MSBuildThisFileDirectory)..\..\..\common\version;$(MSBuildThisFileDirectory)PowerToys; + + + Shlwapi.lib;comctl32.lib;odbc32.lib;odbccp32.lib;version.lib;Winmm.lib;gdiplus.lib;Msimg32.lib;%(AdditionalDependencies) + true + Windows + true + + true + MachineX64 + + + + + MaxSpeed + __ZOOMIT_POWERTOYS__;_UNICODE;UNICODE;WINVER=0x602;NDEBUG;_WIN32_WINNT=0x602;_WIN32_WINDOWS=0x501;WIN32;_WINDOWS;MSVC6=1;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + MultiThreaded + true + + + NDEBUG;_M_ARM64;%(PreprocessorDefinitions) + 0x0409 + $(MSBuildThisFileDirectory)..\..\..\common\version;$(MSBuildThisFileDirectory)PowerToys; + + + Shlwapi.lib;comctl32.lib;odbc32.lib;odbccp32.lib;version.lib;Winmm.lib;gdiplus.lib;Msimg32.lib;%(AdditionalDependencies) + true + Windows + + + true + + + + + Disabled + __ZOOMIT_POWERTOYS__;_UNICODE;UNICODE;WINVER=0x0602;_DEBUG;_WIN32_WINNT=0x602.MSVC6;_WIN32_WINDOWS=0x600;WIN32;_WINDOWS;_WIN32_WINNT=0x602;MSVC6=1;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + _DEBUG;_M_IX86;%(PreprocessorDefinitions) + 0x0409 + $(MSBuildThisFileDirectory)..\..\..\common\version;$(MSBuildThisFileDirectory)PowerToys;$(InterPlatformDir) + + + Shlwapi.lib;comctl32.lib;odbc32.lib;odbccp32.lib;version.lib;Winmm.lib;gdiplus.lib;Msimg32.lib;%(AdditionalDependencies) + true + Windows + false + + MachineX86 + + + + + Disabled + __ZOOMIT_POWERTOYS__;_UNICODE;UNICODE;WINVER=0x0602;_DEBUG;_WIN32_WINNT=0x602.MSVC6;_WIN32_WINDOWS=0x600;WIN32;_WINDOWS;_WIN32_WINNT=0x602;MSVC6=1;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + _DEBUG;_M_X64;%(PreprocessorDefinitions) + 0x0409 + $(MSBuildThisFileDirectory)..\..\..\common\version;$(MSBuildThisFileDirectory)PowerToys; + + + Shlwapi.lib;comctl32.lib;odbc32.lib;odbccp32.lib;version.lib;version.lib;Winmm.lib;gdiplus.lib;Msimg32.lib;%(AdditionalDependencies) + true + true + Windows + false + + MachineX64 + + + + + Disabled + __ZOOMIT_POWERTOYS__;_UNICODE;UNICODE;WINVER=0x0602;_DEBUG;_WIN32_WINNT=0x602.MSVC6;_WIN32_WINDOWS=0x600;WIN32;_WINDOWS;_WIN32_WINNT=0x602;MSVC6=1;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + _DEBUG;_M_ARM64;%(PreprocessorDefinitions) + 0x0409 + $(MSBuildThisFileDirectory)..\..\..\common\version;$(MSBuildThisFileDirectory)PowerToys; + + + Shlwapi.lib;comctl32.lib;odbc32.lib;odbccp32.lib;version.lib;Winmm.lib;gdiplus.lib;Msimg32.lib;%(AdditionalDependencies) + true + true + Windows + + + + + + + false + false + false + false + false + false + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + Use + Use + Use + Use + Use + Use + + + Use + Use + Use + Use + Use + Use + + + Use + Use + Use + Use + Use + Use + + + Use + Use + Use + Use + Use + Use + + + Use + Use + Use + Use + Use + Use + + + Use + Use + Use + Use + Use + Use + + + + + + + + + + + + + + + + + + + + + + + + Use + Use + Use + Use + Use + Use + + + Use + Use + Use + Use + Use + Use + + + + + + + + + true + true + true + true + true + true + + + + + + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} + + + {6955446d-23f7-4023-9bb3-8657f904af99} + + + {8f021b46-362b-485c-bfba-ccf83e820cbd} + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + \ No newline at end of file diff --git a/src/modules/ZoomIt/ZoomIt/ZoomIt.vcxproj.filters b/src/modules/ZoomIt/ZoomIt/ZoomIt.vcxproj.filters new file mode 100644 index 000000000000..1754412d2daa --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/ZoomIt.vcxproj.filters @@ -0,0 +1,130 @@ + + + + + {73afce48-6609-48fb-86f2-db7b72a1c1ec} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {db948f16-61f7-47ab-96c8-57914076a38a} + h;hpp;hxx;hm;inl + + + {e1fa606f-a2e6-40c8-8779-8ca1813d9f01} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + Resource Files + + + + + Resource Files + + + Resource Files + + + Header Files + + + + + + Resource Files + + + Resource Files + + + + + + \ No newline at end of file diff --git a/src/modules/ZoomIt/ZoomIt/ZoomItSettings.h b/src/modules/ZoomIt/ZoomIt/ZoomItSettings.h new file mode 100644 index 000000000000..d53136cf0a54 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/ZoomItSettings.h @@ -0,0 +1,83 @@ +#pragma once +#include "zoomit.h" +#include "Registry.h" +#include "DemoType.h" + +DWORD g_ToggleKey = (HOTKEYF_CONTROL << 8)| '1'; +DWORD g_LiveZoomToggleKey = ((HOTKEYF_CONTROL) << 8)| '4'; +DWORD g_DrawToggleKey = ((HOTKEYF_CONTROL) << 8)| '2'; +DWORD g_BreakToggleKey = ((HOTKEYF_CONTROL) << 8)| '3'; +DWORD g_DemoTypeToggleKey = ((HOTKEYF_CONTROL) << 8) | '7'; +DWORD g_RecordToggleKey = ((HOTKEYF_CONTROL) << 8) | '5'; +DWORD g_SnipToggleKey = ((HOTKEYF_CONTROL) << 8) | '6'; + +DWORD g_ShowExpiredTime = 1; +DWORD g_SliderZoomLevel = 3; +BOOLEAN g_AnimateZoom = TRUE; +DWORD g_PenColor = COLOR_RED; +DWORD g_BreakPenColor = COLOR_RED; +DWORD g_RootPenWidth = PEN_WIDTH; +int g_FontScale = 10; +DWORD g_BreakTimeout = 10; +DWORD g_BreakOpacity = 100; +DWORD g_BreakTimerPosition = 4; +BOOLEAN g_BreakPlaySoundFile = FALSE; +TCHAR g_BreakSoundFile[MAX_PATH] = {0}; +BOOLEAN g_BreakShowDesktop = TRUE; +BOOLEAN g_BreakShowBackgroundFile = FALSE; +BOOLEAN g_BreakBackgroundStretch = FALSE; +TCHAR g_BreakBackgroundFile[MAX_PATH] = {0}; +BOOLEAN g_OptionsShown = FALSE; +BOOLEAN g_ShowTrayIcon = TRUE; +BOOLEAN g_SnapToGrid = TRUE; +BOOLEAN g_TelescopeZoomOut = TRUE; +BOOLEAN g_BreakOnSecondary = FALSE; +LOGFONT g_LogFont; +BOOLEAN g_DemoTypeUserDriven = false; +TCHAR g_DemoTypeFile[MAX_PATH] = {0}; +DWORD g_DemoTypeSpeedSlider = static_cast(((MIN_TYPING_SPEED - MAX_TYPING_SPEED) / 2) + MAX_TYPING_SPEED); +DWORD g_RecordFrameRate = 30; +// Divide by 100 to get actual scaling +DWORD g_RecordScaling = 100; +BOOLEAN g_CaptureAudio = FALSE; +TCHAR g_MicrophoneDeviceId[MAX_PATH] = {0}; + +REG_SETTING RegSettings[] = { + { L"ToggleKey", SETTING_TYPE_DWORD, 0, &g_ToggleKey, static_cast(g_ToggleKey) }, + { L"LiveZoomToggleKey", SETTING_TYPE_DWORD, 0, &g_LiveZoomToggleKey, static_cast(g_LiveZoomToggleKey) }, + { L"DrawToggleKey", SETTING_TYPE_DWORD, 0, &g_DrawToggleKey, static_cast(g_DrawToggleKey) }, + { L"RecordToggleKey", SETTING_TYPE_DWORD, 0, &g_RecordToggleKey, static_cast(g_RecordToggleKey) }, + { L"SnipToggleKey", SETTING_TYPE_DWORD, 0, &g_SnipToggleKey, static_cast(g_SnipToggleKey) }, + { L"PenColor", SETTING_TYPE_DWORD, 0, &g_PenColor, static_cast(g_PenColor) }, + { L"PenWidth", SETTING_TYPE_DWORD, 0, &g_RootPenWidth, static_cast(g_RootPenWidth) }, + { L"OptionsShown", SETTING_TYPE_BOOLEAN, 0, &g_OptionsShown, static_cast(g_OptionsShown) }, + { L"BreakPenColor", SETTING_TYPE_DWORD, 0, &g_BreakPenColor, static_cast(g_BreakPenColor) }, + { L"BreakTimerKey", SETTING_TYPE_DWORD, 0, &g_BreakToggleKey, static_cast(g_BreakToggleKey) }, + { L"DemoTypeToggleKey", SETTING_TYPE_DWORD, 0, &g_DemoTypeToggleKey, static_cast(g_DemoTypeToggleKey) }, + { L"DemoTypeFile", SETTING_TYPE_STRING, sizeof( g_DemoTypeFile ), g_DemoTypeFile, static_cast(0) }, + { L"DemoTypeSpeedSlider", SETTING_TYPE_DWORD, 0, &g_DemoTypeSpeedSlider, static_cast(g_DemoTypeSpeedSlider) }, + { L"DemoTypeUserDrivenMode", SETTING_TYPE_BOOLEAN, 0, &g_DemoTypeUserDriven, static_cast(g_DemoTypeUserDriven) }, + { L"BreakTimeout", SETTING_TYPE_DWORD, 0, &g_BreakTimeout, static_cast(g_BreakTimeout) }, + { L"BreakOpacity", SETTING_TYPE_DWORD, 0, &g_BreakOpacity, static_cast(g_BreakOpacity) }, + { L"BreakPlaySoundFile", SETTING_TYPE_BOOLEAN, 0, &g_BreakPlaySoundFile, static_cast(0) }, + { L"BreakSoundFile", SETTING_TYPE_STRING, sizeof(g_BreakSoundFile), g_BreakSoundFile, static_cast(0) }, + { L"BreakShowBackgroundFile", SETTING_TYPE_BOOLEAN, 0, &g_BreakShowBackgroundFile, static_cast(g_BreakShowBackgroundFile) }, + { L"BreakBackgroundStretch", SETTING_TYPE_BOOLEAN, 0, &g_BreakBackgroundStretch,static_cast(g_BreakBackgroundStretch) }, + { L"BreakBackgroundFile", SETTING_TYPE_STRING, sizeof(g_BreakBackgroundFile), g_BreakBackgroundFile, static_cast(0) }, + { L"BreakTimerPosition", SETTING_TYPE_DWORD, 0, &g_BreakTimerPosition, static_cast(g_BreakTimerPosition) }, + { L"BreakShowDesktop", SETTING_TYPE_BOOLEAN, 0, &g_BreakShowDesktop, static_cast(g_BreakShowDesktop) }, + { L"BreakOnSecondary", SETTING_TYPE_BOOLEAN, 0, &g_BreakOnSecondary,static_cast(g_BreakOnSecondary) }, + { L"FontScale", SETTING_TYPE_DWORD, 0, &g_FontScale, static_cast(g_FontScale) }, + { L"ShowExpiredTime", SETTING_TYPE_BOOLEAN, 0, &g_ShowExpiredTime, static_cast(g_ShowExpiredTime) }, + { L"ShowTrayIcon", SETTING_TYPE_BOOLEAN, 0, &g_ShowTrayIcon, static_cast(g_ShowTrayIcon) }, + { L"AnimnateZoom", SETTING_TYPE_BOOLEAN, 0, &g_AnimateZoom, static_cast(g_AnimateZoom) }, + { L"TelescopeZoomOut", SETTING_TYPE_BOOLEAN, 0, &g_TelescopeZoomOut, static_cast(g_TelescopeZoomOut) }, + { L"SnapToGrid", SETTING_TYPE_BOOLEAN, 0, &g_SnapToGrid, static_cast(g_SnapToGrid) }, + { L"ZoominSliderLevel", SETTING_TYPE_DWORD, 0, &g_SliderZoomLevel, static_cast(g_SliderZoomLevel) }, + { L"Font", SETTING_TYPE_BINARY, sizeof g_LogFont, &g_LogFont, static_cast(0) }, + { L"RecordFrameRate", SETTING_TYPE_DWORD, 0, &g_RecordFrameRate, static_cast(g_RecordFrameRate) }, + { L"RecordScaling", SETTING_TYPE_DWORD, 0, &g_RecordScaling, static_cast(g_RecordScaling) }, + { L"CaptureAudio", SETTING_TYPE_BOOLEAN, 0, &g_CaptureAudio, static_cast(g_CaptureAudio) }, + { L"MicrophoneDeviceId", SETTING_TYPE_STRING, sizeof(g_MicrophoneDeviceId), g_MicrophoneDeviceId, static_cast(0) }, + { NULL, SETTING_TYPE_DWORD, 0, NULL, static_cast(0) } +}; diff --git a/src/modules/ZoomIt/ZoomIt/Zoomit.cpp b/src/modules/ZoomIt/ZoomIt/Zoomit.cpp new file mode 100644 index 000000000000..c8ac0ebcde4e --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/Zoomit.cpp @@ -0,0 +1,7674 @@ +//============================================================================ +// +// Zoomit +// Copyright (C) Mark Russinovich +// Sysinternals - www.sysinternals.com +// +// Screen zoom and annotation tool. +// +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +//============================================================================ +#include "pch.h" + +#include "zoomit.h" +#include "Utility.h" +#include "WindowsVersions.h" +#include "ZoomItSettings.h" + +#ifdef __ZOOMIT_POWERTOYS__ +#include +#include +#include + +#include "../ZoomItModuleInterface/trace.h" +#include +#include +#include +#include +#include +#endif // __ZOOMIT_POWERTOYS__ + +namespace winrt +{ + using namespace Windows::Foundation; + using namespace Windows::Graphics; + using namespace Windows::Graphics::Capture; + using namespace Windows::Graphics::Imaging; + using namespace Windows::Storage; + using namespace Windows::UI::Composition; + using namespace Windows::Storage::Pickers; + using namespace Windows::System; + using namespace Windows::Devices::Enumeration; +} + +namespace util +{ + using namespace robmikh::common::uwp; + using namespace robmikh::common::desktop; +} + +// This workaround keeps live zoom enabled after zooming out at level 1 (not zoomed) and disables +// live zoom when recording is stopped. +#define WINDOWS_CURSOR_RECORDING_WORKAROUND 1 + +HINSTANCE g_hInstance; + +COLORREF g_CustomColors[16]; + +#define ZOOM_HOTKEY 0 +#define DRAW_HOTKEY 1 +#define BREAK_HOTKEY 2 +#define LIVE_HOTKEY 3 +#define LIVE_DRAW_HOTKEY 4 +#define RECORD_HOTKEY 5 +#define RECORD_CROP_HOTKEY 6 +#define RECORD_WINDOW_HOTKEY 7 +#define SNIP_HOTKEY 8 +#define SNIP_SAVE_HOTKEY 9 +#define DEMOTYPE_HOTKEY 10 +#define DEMOTYPE_RESET_HOTKEY 11 + +#define ZOOM_PAGE 0 +#define LIVE_PAGE 1 +#define DRAW_PAGE 2 +#define TYPE_PAGE 3 +#define DEMOTYPE_PAGE 4 +#define BREAK_PAGE 5 +#define RECORD_PAGE 6 +#define SNIP_PAGE 7 + +OPTION_TABS g_OptionsTabs[] = { + { _T("Zoom"), NULL }, + { _T("LiveZoom"), NULL }, + { _T("Draw"), NULL }, + { _T("Type"), NULL }, + { _T("DemoType"), NULL }, + { _T("Break"), NULL }, + { _T("Record"), NULL }, + { _T("Snip"), NULL } +}; + +float g_ZoomLevels[] = { + 1.25, + 1.50, + 1.75, + 2.00, + 3.00, + 4.00 +}; + +DWORD g_FramerateOptions[] = { + 30, + 60 +}; + +// +// For typing mode +// +typedef enum { + TypeModeOff = 0, + TypeModeLeftJustify, + TypeModeRightJustify +} TypeModeState; + +const DWORD CURSOR_ARM_LENGTH = 4; + +const float NORMAL_BLUR_RADIUS = 20; +const float STRONG_BLUR_RADIUS = 40; + +DWORD g_ToggleMod; +DWORD g_LiveZoomToggleMod; +DWORD g_DrawToggleMod; +DWORD g_BreakToggleMod; +DWORD g_DemoTypeToggleMod; +DWORD g_RecordToggleMod; +DWORD g_SnipToggleMod; + +BOOLEAN g_ZoomOnLiveZoom = FALSE; +DWORD g_PenWidth = PEN_WIDTH; +float g_BlurRadius = NORMAL_BLUR_RADIUS; +HWND hWndOptions = NULL; +BOOLEAN g_DrawPointer = FALSE; +BOOLEAN g_PenDown = FALSE; +BOOLEAN g_PenInverted = FALSE; +DWORD g_OsVersion; +HWND g_hWndLiveZoom = NULL; +HWND g_hWndLiveZoomMag = NULL; +HWND g_hWndMain; +int g_AlphaBlend = 0x80; +BOOL g_fullScreenWorkaround = FALSE; +bool g_bSaveInProgress = false; +std::wstring g_TextBuffer; +// This is useful in the context of right-justified text only. +std::list g_TextBufferPreviousLines; +#if WINDOWS_CURSOR_RECORDING_WORKAROUND +bool g_LiveZoomLevelOne = false; +#endif + +// True if ZoomIt was started by PowerToys instead of standalone. +BOOLEAN g_StartedByPowerToys = FALSE; +BOOLEAN g_running = TRUE; + +// Screen recording globals +#define DEFAULT_RECORDING_FILE L"Recording.mp4" +BOOL g_RecordToggle = FALSE; +BOOL g_RecordCropping = FALSE; +SelectRectangle g_SelectRectangle; +std::wstring g_RecordingSaveLocation; +winrt::IDirect3DDevice g_RecordDevice{ nullptr }; +std::shared_ptr g_RecordingSession = nullptr; + +type_pGetMonitorInfo pGetMonitorInfo; +type_MonitorFromPoint pMonitorFromPoint; +type_pSHAutoComplete pSHAutoComplete; +type_pSetLayeredWindowAttributes pSetLayeredWindowAttributes; +type_pSetProcessDPIAware pSetProcessDPIAware; +type_pMagSetWindowSource pMagSetWindowSource; +type_pMagSetWindowTransform pMagSetWindowTransform; +type_pMagSetFullscreenTransform pMagSetFullscreenTransform; +type_pMagSetInputTransform pMagSetInputTransform; +type_pMagShowSystemCursor pMagShowSystemCursor; +type_pMagSetWindowFilterList pMagSetWindowFilterList; +type_pMagInitialize pMagInitialize; +type_pDwmIsCompositionEnabled pDwmIsCompositionEnabled; +type_pGetPointerType pGetPointerType; +type_pGetPointerPenInfo pGetPointerPenInfo; +type_pSystemParametersInfoForDpi pSystemParametersInfoForDpi; +type_pGetDpiForWindow pGetDpiForWindow; + +type_pSHQueryUserNotificationState pSHQueryUserNotificationState; + +type_pCreateDirect3D11DeviceFromDXGIDevice pCreateDirect3D11DeviceFromDXGIDevice; +type_pCreateDirect3D11SurfaceFromDXGISurface pCreateDirect3D11SurfaceFromDXGISurface; +type_pD3D11CreateDevice pD3D11CreateDevice; + +ClassRegistry reg( _T("Software\\Sysinternals\\") APPNAME ); + +ComputerGraphicsInit g_GraphicsInit; + + +//---------------------------------------------------------------------------- +// +// Saves specified filePath to clipboard. +// +//---------------------------------------------------------------------------- +bool SaveToClipboard( const WCHAR* filePath, HWND hwnd ) +{ + if( filePath == NULL || hwnd == NULL || wcslen( filePath ) == 0 ) + { + return false; + } + + size_t size = sizeof(DROPFILES) + sizeof(WCHAR) * ( _tcslen( filePath ) + 1 ) + sizeof(WCHAR); + + HDROP hDrop = static_cast(GlobalAlloc( GHND, size )); + if (hDrop == NULL) + { + return false; + } + + DROPFILES* dFiles = static_cast(GlobalLock( hDrop )); + if (dFiles == NULL) + { + GlobalFree( hDrop ); + return false; + } + + dFiles->pFiles = sizeof(DROPFILES); + dFiles->fWide = TRUE; + + wcscpy( reinterpret_cast(& dFiles[1]), filePath); + GlobalUnlock( hDrop ); + + if( OpenClipboard( hwnd ) ) + { + EmptyClipboard(); + SetClipboardData( CF_HDROP, hDrop ); + CloseClipboard(); + } + + GlobalFree( hDrop ); + + return true; +} + +//---------------------------------------------------------------------- +// +// OutputDebug +// +//---------------------------------------------------------------------- +void OutputDebug(const TCHAR* format, ...) +{ +#if _DEBUG + TCHAR msg[1024]; + va_list va; + +#ifdef _MSC_VER +// For some reason, ARM64 Debug builds causes an analyzer error on va_start: "error C26492: Don't use const_cast to cast away const or volatile (type.3)." +#pragma warning(push) +#pragma warning(disable : 26492) +#endif + va_start(va, format); +#ifdef _MSC_VER +#pragma warning(pop) +#endif + _vstprintf_s(msg, format, va); + va_end(va); + + OutputDebugString(msg); +#endif +} + +//---------------------------------------------------------------------------- +// +// InitializeFonts +// +// Return a bold equivalent of either a DPI aware font face for GUI text or +// just the stock object for DEFAULT_GUI_FONT. +// +//---------------------------------------------------------------------------- +void InitializeFonts( HWND hwnd, HFONT *bold ) +{ + LOGFONT logFont; + bool haveLogFont = false; + + if( *bold ) + { + DeleteObject( *bold ); + *bold = nullptr; + } + + if( pSystemParametersInfoForDpi && pGetDpiForWindow ) + { + NONCLIENTMETRICSW metrics{}; + metrics.cbSize = sizeof( metrics ); + + if( pSystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, sizeof( metrics ), &metrics, 0, pGetDpiForWindow( hwnd ) ) ) + { + CopyMemory( &logFont, &metrics.lfMessageFont, sizeof( logFont ) ); + haveLogFont = true; + } + } + + if( !haveLogFont ) + { + auto normal = static_cast(GetStockObject( DEFAULT_GUI_FONT )); + GetObject( normal, sizeof( logFont ), &logFont ); + haveLogFont = true; // for correctness + } + + logFont.lfWeight = FW_BOLD; + *bold = CreateFontIndirect( &logFont ); +} + +//---------------------------------------------------------------------------- +// +// EnsureForeground +// +//---------------------------------------------------------------------------- +void EnsureForeground() +{ + if( !IsWindowVisible( g_hWndMain ) ) + SetForegroundWindow( g_hWndMain ); +} + +//---------------------------------------------------------------------------- +// +// RestoreForeground +// +//---------------------------------------------------------------------------- +void RestoreForeground() +{ + // If the main window is not visible, move foreground to the next window + if( !IsWindowVisible( g_hWndMain ) ) { + + // Activate the next window by unhiding and hiding the main window + MoveWindow( g_hWndMain, 0, 0, 0, 0, FALSE ); + ShowWindow( g_hWndMain, SW_SHOWNA ); + ShowWindow( g_hWndMain, SW_HIDE ); + + OutputDebug(L"RESTORE FOREGROUND\n"); + } +} + +//---------------------------------------------------------------------------- +// +// ErrorDialog +// +//---------------------------------------------------------------------------- +VOID ErrorDialog( HWND hParent, PCTSTR message, DWORD _Error ) +{ + LPTSTR lpMsgBuf; + TCHAR errmsg[1024]; + + FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, _Error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + reinterpret_cast(&lpMsgBuf), 0, NULL ); + _stprintf( errmsg, L"%s: %s", message, lpMsgBuf ); +#ifdef __ZOOMIT_POWERTOYS__ + if( g_StartedByPowerToys ) + { + Logger::error( errmsg ); + } +#endif // __ZOOMIT_POWERTOYS__ + MessageBox( hParent, errmsg, APPNAME, MB_OK|MB_ICONERROR); +} + +//---------------------------------------------------------------------------- +// +// ErrorDialogString +// +//---------------------------------------------------------------------------- +VOID ErrorDialogString( HWND hParent, PCTSTR Message, const wchar_t *_Error ) +{ + TCHAR errmsg[1024]; + + _stprintf_s( errmsg, _countof( errmsg ), L"%s: %s", Message, _Error ); + if( hParent == g_hWndMain ) + { + EnsureForeground(); + } +#ifdef __ZOOMIT_POWERTOYS__ + if( g_StartedByPowerToys ) + { + Logger::error( errmsg ); + } +#endif // __ZOOMIT_POWERTOYS__ + MessageBox(hParent, errmsg, APPNAME, MB_OK | MB_ICONERROR); + if( hParent == g_hWndMain ) + { + RestoreForeground(); + } +} + + +//-------------------------------------------------------------------- +// +// SetAutostartFilePath +// +// Sets the file path for later autostart config. +// +//-------------------------------------------------------------------- +void SetAutostartFilePath() +{ + HKEY hZoomit; + DWORD error; + TCHAR imageFile[MAX_PATH] = { 0 }; + + error = RegCreateKeyEx( HKEY_CURRENT_USER, _T( "Software\\Sysinternals\\Zoomit" ), 0, + 0, 0, KEY_SET_VALUE, NULL, &hZoomit, NULL ); + if( error == ERROR_SUCCESS ) { + + GetModuleFileName( NULL, imageFile + 1, _countof( imageFile ) - 2 ); + imageFile[0] = '"'; + *(_tcschr( imageFile, 0 )) = '"'; + error = RegSetValueEx( hZoomit, L"FilePath", 0, REG_SZ, (BYTE *) imageFile, + static_cast(_tcslen( imageFile ) + 1)* sizeof( TCHAR )); + RegCloseKey( hZoomit ); + } +} + +//-------------------------------------------------------------------- +// +// ConfigureAutostart +// +// Enables or disables Zoomit autostart for the current image file. +// +//-------------------------------------------------------------------- +bool ConfigureAutostart( HWND hParent, bool Enable ) +{ + HKEY hRunKey, hZoomit; + DWORD error, length, type; + TCHAR imageFile[MAX_PATH]; + + error = RegOpenKeyEx( HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", + 0, KEY_SET_VALUE, &hRunKey ); + if( error == ERROR_SUCCESS ) { + + if( Enable ) { + + error = RegOpenKeyEx( HKEY_CURRENT_USER, _T("Software\\Sysinternals\\Zoomit"), 0, + KEY_QUERY_VALUE, &hZoomit ); + if( error == ERROR_SUCCESS ) { + + length = sizeof(imageFile); +#ifdef _WIN64 + // Unconditionally reset filepath in case this was already set by 32 bit version + SetAutostartFilePath(); +#endif + error = RegQueryValueEx( hZoomit, _T( "Filepath" ), 0, &type, (BYTE *) imageFile, &length ); + RegCloseKey( hZoomit ); + if( error == ERROR_SUCCESS ) { + + error = RegSetValueEx( hRunKey, APPNAME, 0, REG_SZ, (BYTE *) imageFile, + static_cast(_tcslen(imageFile)+1) * sizeof(TCHAR)); + } + } + } else { + + error = RegDeleteValue( hRunKey, APPNAME ); + if( error == ERROR_FILE_NOT_FOUND ) error = ERROR_SUCCESS; + } + RegCloseKey( hRunKey ); + } + if( error != ERROR_SUCCESS ) { + + ErrorDialog( hParent, L"Error configuring auto start", error ); + } + return error == ERROR_SUCCESS; +} + + +//-------------------------------------------------------------------- +// +// IsAutostartConfigured +// +// Is this version of zoomit configured to autostart. +// +//-------------------------------------------------------------------- +bool IsAutostartConfigured() +{ + HKEY hRunKey; + TCHAR imageFile[MAX_PATH]; + DWORD error, imageFileLength, type; + + error = RegOpenKeyEx( HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", + 0, KEY_QUERY_VALUE, &hRunKey ); + if( error == ERROR_SUCCESS ) { + + imageFileLength = sizeof(imageFile); + error = RegQueryValueEx( hRunKey, _T("Zoomit"), 0, &type, (BYTE *) imageFile, &imageFileLength ); + RegCloseKey( hRunKey ); + } + return error == ERROR_SUCCESS; +} + + +#ifndef _WIN64 + +//-------------------------------------------------------------------- +// +// RunningOnWin64 +// +// Returns true if this is the 32-bit version of the executable +// and we're on 64-bit Windows +// +//-------------------------------------------------------------------- +typedef BOOL (__stdcall *P_IS_WOW64PROCESS)( + HANDLE hProcess, + PBOOL Wow64Process + ); +BOOL +RunningOnWin64( + VOID + ) +{ + P_IS_WOW64PROCESS pIsWow64Process; + BOOL isWow64 = FALSE; + + pIsWow64Process = (P_IS_WOW64PROCESS) GetProcAddress(GetModuleHandle(_T("kernel32.dll")), + "IsWow64Process"); + if( pIsWow64Process ) { + + pIsWow64Process( GetCurrentProcess(), &isWow64 ); + } + return isWow64; +} + + +//-------------------------------------------------------------------- +// +// ExtractImageResource +// +// Extracts the specified file that is located in a resource for +// this executable. +// +//-------------------------------------------------------------------- +BOOLEAN ExtractImageResource( PTCHAR ResourceName, PTCHAR TargetFile ) +{ + HRSRC hResource; + HGLOBAL hImageResource; + DWORD dwImageSize; + LPVOID lpvImage; + FILE *hFile; + + // Locate the resource + hResource = FindResource( NULL, ResourceName, _T("BINRES") ); + if( !hResource ) + return FALSE; + + hImageResource = LoadResource( NULL, hResource ); + dwImageSize = SizeofResource( NULL, hResource ); + lpvImage = LockResource( hImageResource ); + + // Now copy it out + _tfopen_s( &hFile, TargetFile, _T("wb") ); + if( hFile == NULL ) return FALSE; + + fwrite( lpvImage, 1, dwImageSize, hFile ); + fclose( hFile ); + return TRUE; +} + + + +//-------------------------------------------------------------------- +// +// Run64bitVersion +// +// Returns true if this is the 32-bit version of the executable +// and we're on 64-bit Windows +// +//-------------------------------------------------------------------- +DWORD +Run64bitVersion( + void + ) +{ + TCHAR szPath[MAX_PATH]; + TCHAR originalPath[MAX_PATH]; + TCHAR tmpPath[MAX_PATH]; + SHELLEXECUTEINFO info = { 0 }; + + if ( GetModuleFileName( NULL, szPath, sizeof(szPath)/sizeof(TCHAR)) == 0 ) { + + return -1; + } + _tcscpy_s( originalPath, _countof(originalPath), szPath ); + + *_tcsrchr( originalPath, '.') = 0; + _tcscat_s( originalPath, _countof(szPath), _T("64.exe")); + + // + // Extract the 64-bit version + // + ExpandEnvironmentStrings( L"%TEMP%", tmpPath, sizeof tmpPath / sizeof ( TCHAR)); + _tcscat_s( tmpPath, _countof(tmpPath), _tcsrchr( originalPath, '\\')); + _tcscpy_s( szPath, _countof(szPath), tmpPath ); + if( !ExtractImageResource( _T("RCZOOMIT64"), szPath )) { + + if( GetFileAttributes( szPath ) == INVALID_FILE_ATTRIBUTES ) { + + ErrorDialog( NULL,_T("Error launching 64-bit version"), GetLastError()); + return -1; + } + } + + info.cbSize = sizeof(info); + info.fMask = SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS; + info.lpFile = szPath; + info.lpParameters = GetCommandLine(); + info.nShow = SW_SHOWNORMAL; + if( !ShellExecuteEx( &info ) ) { + + ErrorDialog( NULL,_T("Error launching 64-bit version"), GetLastError()); + DeleteFile( szPath ); + return -1; + } + WaitForSingleObject( info.hProcess, INFINITE ); + + DWORD result; + GetExitCodeProcess( info.hProcess, &result ); + CloseHandle( info.hProcess ); + DeleteFile( szPath ); + return result; +} +#endif + + +//---------------------------------------------------------------------------- +// +// IsPresentationMode +// +//---------------------------------------------------------------------------- +BOOLEAN IsPresentationMode() +{ + QUERY_USER_NOTIFICATION_STATE pUserState; + + pSHQueryUserNotificationState( &pUserState ); + return pUserState == QUNS_PRESENTATION_MODE; +} + +//---------------------------------------------------------------------------- +// +// EnableDisableSecondaryDisplay +// +// Creates a second display on the secondary monitor for displaying the +// break timer. +// +//---------------------------------------------------------------------------- +LONG EnableDisableSecondaryDisplay( HWND hWnd, BOOLEAN Enable, + PDEVMODE OriginalDevMode ) +{ + LONG result; + DEVMODE devMode{}; + + if( Enable ) { + + // + // Prepare the position of Display 2 to be right to the right of Display 1 + // + devMode.dmSize = sizeof(devMode); + devMode.dmDriverExtra = 0; + EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode); + *OriginalDevMode = devMode; + + // + // Enable display 2 in the registry + // + devMode.dmPosition.x = devMode.dmPelsWidth; + devMode.dmFields = DM_POSITION | + DM_DISPLAYORIENTATION | + DM_BITSPERPEL | + DM_PELSWIDTH | + DM_PELSHEIGHT | + DM_DISPLAYFLAGS | + DM_DISPLAYFREQUENCY; + result = ChangeDisplaySettingsEx( L"\\\\.\\DISPLAY2", + &devMode, + NULL, + CDS_NORESET | CDS_UPDATEREGISTRY, + NULL); + + } else { + + OriginalDevMode->dmFields = DM_POSITION | + DM_DISPLAYORIENTATION | + DM_BITSPERPEL | + DM_PELSWIDTH | + DM_PELSHEIGHT | + DM_DISPLAYFLAGS | + DM_DISPLAYFREQUENCY; + result = ChangeDisplaySettingsEx( L"\\\\.\\DISPLAY2", + OriginalDevMode, + NULL, + CDS_NORESET | CDS_UPDATEREGISTRY, + NULL); + } + + // + // Update the hardware + // + if( result == DISP_CHANGE_SUCCESSFUL ) { + + if( !ChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL)) { + + result = GetLastError(); + } + + // + // If enabling, move zoomit to the second monitor + // + if( Enable && result == DISP_CHANGE_SUCCESSFUL ) { + + SetWindowPos(FindWindowW(L"ZoomitClass", NULL), + NULL, + devMode.dmPosition.x, + 0, + 0, + 0, + SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); + SetCursorPos( devMode.dmPosition.x+1, devMode.dmPosition.y+1 ); + } + } + return result; +} + +//---------------------------------------------------------------------------- +// +// GetLineBounds +// +// Gets the rectangle bounding a line, taking into account pen width +// +//---------------------------------------------------------------------------- +Gdiplus::Rect GetLineBounds( POINT p1, POINT p2, int penWidth ) +{ + Gdiplus::Rect rect( min(p1.x, p2.x), min(p1.y, p2.y), + abs(p1.x - p2.x), abs( p1.y - p2.y)); + rect.Inflate( penWidth, penWidth ); + return rect; +} + +//---------------------------------------------------------------------------- +// +// InvalidateGdiplusRect +// +// Invalidate portion of window specified by Gdiplus::Rect +// +//---------------------------------------------------------------------------- +void InvalidateGdiplusRect(HWND hWnd, Gdiplus::Rect BoundsRect) +{ + RECT lineBoundsGdi; + lineBoundsGdi.left = BoundsRect.X; + lineBoundsGdi.top = BoundsRect.Y; + lineBoundsGdi.right = BoundsRect.X + BoundsRect.Width; + lineBoundsGdi.bottom = BoundsRect.Y + BoundsRect.Height; + InvalidateRect(hWnd, &lineBoundsGdi, FALSE); +} + + + +//---------------------------------------------------------------------------- +// +// CreateGdiplusBitmap +// +// Creates a gdiplus bitmap of the specified region of the HDC. +// +//---------------------------------------------------------------------------- +Gdiplus::Bitmap *CreateGdiplusBitmap( HDC hDc, int x, int y, int Width, int Height ) +{ + HBITMAP hBitmap = CreateCompatibleBitmap(hDc, Width, Height); + + // Create a device context for the new bitmap + HDC hdcNewBitmap = CreateCompatibleDC(hDc); + SelectObject(hdcNewBitmap, hBitmap); + + // Copy from the oldest undo bitmap to the new bitmap using the lineBounds as the source rectangle + BitBlt(hdcNewBitmap, 0, 0, Width, Height, hDc, x, y, SRCCOPY); + Gdiplus::Bitmap *blurBitmap = new Gdiplus::Bitmap(hBitmap, NULL); + DeleteDC(hdcNewBitmap); + DeleteObject(hBitmap); + return blurBitmap; +} + + +//---------------------------------------------------------------------------- +// +// CreateBitmapMemoryDIB +// +// Creates a memory DC and DIB for the specified region of the screen. +// +//---------------------------------------------------------------------------- +BYTE* CreateBitmapMemoryDIB(HDC hdcScreenCompat, HDC hBitmapDc, Gdiplus::Rect* lineBounds, + HDC* hdcMem, HBITMAP* hDIBOrig, HBITMAP* hPreviousBitmap) +{ + // Create a memory DIB for the relevant region of the original bitmap + BITMAPINFO bmiOrig = { 0 }; + bmiOrig.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmiOrig.bmiHeader.biWidth = lineBounds->Width; + bmiOrig.bmiHeader.biHeight = -lineBounds->Height; // Top-down DIB + bmiOrig.bmiHeader.biPlanes = 1; + bmiOrig.bmiHeader.biBitCount = 32; // 32 bits per pixel + bmiOrig.bmiHeader.biCompression = BI_RGB; + + VOID* pDIBBitsOrig; + *hDIBOrig = CreateDIBSection(hdcScreenCompat, &bmiOrig, DIB_RGB_COLORS, &pDIBBitsOrig, NULL, 0); + + if( *hDIBOrig == NULL ) { + + OutputDebug(L"NULL DIB: %d\n", GetLastError()); + OutputDebug(L"lineBounds: %d %d %d %d\n", lineBounds->X, lineBounds->Y, lineBounds->Width, lineBounds->Height); + return NULL; + } + + *hdcMem = CreateCompatibleDC(hdcScreenCompat); + *hPreviousBitmap = static_cast(SelectObject(*hdcMem, *hDIBOrig)); + + // Copy the relevant part of hdcScreenCompat to the DIB + BitBlt(*hdcMem, 0, 0, lineBounds->Width, lineBounds->Height, hBitmapDc, lineBounds->X, lineBounds->Y, SRCCOPY); + + // Pointer to the DIB bits + return static_cast(pDIBBitsOrig); +} + +//---------------------------------------------------------------------------- +// +// LockGdiPlusBitmap +// +// Locks the Gdi+ bitmap so that we can access its pixels in memory. +// +//---------------------------------------------------------------------------- +#ifdef _MSC_VER + // Analyzers want us to use a scoped object instead of new. But given all the operations done in Bitmaps it seems better to leave it as a heap object. + #pragma warning(push) + #pragma warning(disable : 26402) +#endif + +Gdiplus::BitmapData* LockGdiPlusBitmap(Gdiplus::Bitmap* Bitmap) +{ + Gdiplus::BitmapData *lineData = new Gdiplus::BitmapData(); + Bitmap->GetPixelFormat(); + Gdiplus::Rect lineBitmapBounds(0, 0, Bitmap->GetWidth(), Bitmap->GetHeight()); + Bitmap->LockBits(&lineBitmapBounds, Gdiplus::ImageLockModeRead, + Bitmap->GetPixelFormat(), lineData); + return lineData; +} +#ifdef _MSC_VER + #pragma warning(pop) +#endif + + +//---------------------------------------------------------------------------- +// +// BlurScreen +// +// Blur the portion of the screen by copying a blurred bitmap with the +// specified shape. +// +//---------------------------------------------------------------------------- +void BlurScreen(HDC hdcScreenCompat, Gdiplus::Rect* lineBounds, + Gdiplus::Bitmap *BlurBitmap, BYTE* pPixels) +{ + HDC hdcDIB; + HBITMAP hDibOrigBitmap, hDibBitmap; + BYTE* pDestPixels = CreateBitmapMemoryDIB(hdcScreenCompat, hdcScreenCompat, lineBounds, + &hdcDIB, &hDibBitmap, &hDibOrigBitmap); + + // Iterate through the pixels + for (int y = 0; y < lineBounds->Height; ++y) { + for (int x = 0; x < lineBounds->Width; ++x) { + int index = (y * lineBounds->Width * 4) + (x * 4); // Assuming 4 bytes per pixel + // BYTE b = pPixels[index + 0]; // Blue channel + // BYTE g = pPixels[index + 1]; // Green channel + // BYTE r = pPixels[index + 2]; // Red channel + BYTE a = pPixels[index + 3]; // Alpha channel + + // Check if this is a drawn pixel + if (a != 0) { + // get the blur pixel + Gdiplus::Color pixel; + BlurBitmap->GetPixel(x, y, &pixel); + + COLORREF newPixel = pixel.GetValue() & 0xFFFFFF; + pDestPixels[index + 0] = GetRValue(newPixel); + pDestPixels[index + 1] = GetGValue(newPixel); + pDestPixels[index + 2] = GetBValue(newPixel); + } + } + } + + // Copy the updated DIB back to hdcScreenCompat + BitBlt(hdcScreenCompat, lineBounds->X, lineBounds->Y, lineBounds->Width, lineBounds->Height, hdcDIB, 0, 0, SRCCOPY); + + // Clean up + SelectObject(hdcDIB, hDibOrigBitmap); + DeleteObject(hDibBitmap); + DeleteDC(hdcDIB); +} + + + +//---------------------------------------------------------------------------- +// +// BitmapBlur +// +// Blurs the bitmap. +// +//---------------------------------------------------------------------------- +void BitmapBlur(Gdiplus::Bitmap* hBitmap) +{ + // Git bitmap size + Gdiplus::Size bitmapSize; + bitmapSize.Width = hBitmap->GetWidth(); + bitmapSize.Height = hBitmap->GetHeight(); + + // Blur the new bitmap + Gdiplus::Blur blurObject; + Gdiplus::BlurParams blurParams; + blurParams.radius = g_BlurRadius; + blurParams.expandEdge = FALSE; + blurObject.SetParameters(&blurParams); + + // Apply blur to image + RECT linesRect; + linesRect.left = 0; + linesRect.top = 0; + linesRect.right = bitmapSize.Width; + linesRect.bottom = bitmapSize.Height; + hBitmap->ApplyEffect(&blurObject, &linesRect); +} + + +//---------------------------------------------------------------------------- +// +// DrawBlurredShape +// +// Blur a shaped region of the screen. +// +//---------------------------------------------------------------------------- +void DrawBlurredShape( DWORD Shape, Gdiplus::Pen *pen, HDC hdcScreenCompat, Gdiplus::Graphics *dstGraphics, + int x1, int y1, int x2, int y2) +{ + // Create a new bitmap that's the size of the area covered by the line + 2 * g_PenWidth + Gdiplus::Rect lineBounds( min( x1, x2 ), min( y1, y2 ), abs( x2 - x1 ), abs( y2 - y1 ) ); + + // Expand for line drawing + if (Shape == DRAW_LINE) + lineBounds.Inflate( static_cast(g_PenWidth / 2), static_cast(g_PenWidth / 2) ); + + Gdiplus::Bitmap* lineBitmap = new Gdiplus::Bitmap(lineBounds.Width, lineBounds.Height, PixelFormat32bppARGB); + Gdiplus::Graphics lineGraphics(lineBitmap); + static const auto blackBrush = Gdiplus::SolidBrush(Gdiplus::Color::Black); + switch (Shape) { + case DRAW_RECTANGLE: + lineGraphics.FillRectangle(&blackBrush, 0, 0, lineBounds.Width, lineBounds.Height); + break; + case DRAW_ELLIPSE: + lineGraphics.FillEllipse(&blackBrush, 0, 0, lineBounds.Width, lineBounds.Height); + break; + case DRAW_LINE: + OutputDebug(L"BLUR_LINE: %d %d\n", lineBounds.Width, lineBounds.Height); + lineGraphics.DrawLine( pen, x1 - lineBounds.X, y1 - lineBounds.Y, x2 - lineBounds.X, y2 - lineBounds.Y ); + break; + } + + Gdiplus::BitmapData* lineData = LockGdiPlusBitmap(lineBitmap); + BYTE* pPixels = static_cast(lineData->Scan0); + + // Create a GDI bitmap that's the size of the lineBounds rectangle + Gdiplus::Bitmap* blurBitmap = CreateGdiplusBitmap(hdcScreenCompat, + lineBounds.X, lineBounds.Y, lineBounds.Width, lineBounds.Height); + + // Blur it + BitmapBlur(blurBitmap); + BlurScreen(hdcScreenCompat, &lineBounds, blurBitmap, pPixels); + + // Unlock the bits + lineBitmap->UnlockBits(lineData); + delete lineBitmap; + delete blurBitmap; +} + +//---------------------------------------------------------------------------- +// +// CreateDrawingBitmap +// +// Create a bitmap to draw on. +// +//---------------------------------------------------------------------------- +Gdiplus::Bitmap* CreateDrawingBitmap(Gdiplus::Rect lineBounds ) +{ + Gdiplus::Bitmap* lineBitmap = new Gdiplus::Bitmap(lineBounds.Width, lineBounds.Height, PixelFormat32bppARGB); + Gdiplus::Graphics lineGraphics(lineBitmap); + return lineBitmap; +} + + +//---------------------------------------------------------------------------- +// +// DrawBitmapLine +// +// Creates a bitmap and draws a line on it. +// +//---------------------------------------------------------------------------- +Gdiplus::Bitmap* DrawBitmapLine(Gdiplus::Rect lineBounds, POINT p1, POINT p2, Gdiplus::Pen *pen) +{ + Gdiplus::Bitmap* lineBitmap = new Gdiplus::Bitmap(lineBounds.Width, lineBounds.Height, PixelFormat32bppARGB); + Gdiplus::Graphics lineGraphics(lineBitmap); + + // Draw the line on the temporary bitmap + lineGraphics.DrawLine(pen, static_cast(p1.x - lineBounds.X), static_cast(p1.y - lineBounds.Y), + static_cast(p2.x - lineBounds.X), static_cast(p2.y - lineBounds.Y)); + + return lineBitmap; +} + + +//---------------------------------------------------------------------------- +// +// ColorFromColorRef +// +// Returns a color object from the colorRef that includes the alpha channel +// +//---------------------------------------------------------------------------- +Gdiplus::Color ColorFromColorRef(DWORD colorRef) { + BYTE a = (colorRef >> 24) & 0xFF; // Extract the alpha channel value + BYTE b = (colorRef >> 16) & 0xFF; // Extract the red channel value + BYTE g = (colorRef >> 8) & 0xFF; // Extract the green channel value + BYTE r = colorRef & 0xFF; // Extract the blue channel value + OutputDebug( L"ColorFromColorRef: %d %d %d %d\n", a, r, g, b ); + return Gdiplus::Color(a, r, g, b); +} + +//---------------------------------------------------------------------------- +// +// AdjustHighlighterColor +// +// Lighten the color. +// +//---------------------------------------------------------------------------- +void AdjustHighlighterColor(BYTE* red, BYTE* green, BYTE* blue) { + + // Adjust the color to be more visible + *red = min( 0xFF, *red ? *red + 0x40 : *red + 0x80 ); + *green = min( 0xFF, *green ? *green + 0x40 : *green + 0x80); + *blue = min( 0xFF, *blue ? *blue + 0x40 : *blue + 0x80); +} + +//---------------------------------------------------------------------------- +// +// BlendColors +// +// Blends two colors together using the alpha channel of the second color. +// The highlighter is the second color. +// +//---------------------------------------------------------------------------- +COLORREF BlendColors(COLORREF color1, const Gdiplus::Color& color2) { + + BYTE redResult, greenResult, blueResult; + + // Extract the channels from the COLORREF + BYTE red1 = GetRValue(color1); + BYTE green1 = GetGValue(color1); + BYTE blue1 = GetBValue(color1); + + // Get the channels and alpha from the Gdiplus::Color + BYTE blue2 = color2.GetRed(); + BYTE green2 = color2.GetGreen(); + BYTE red2 = color2.GetBlue(); + float alpha2 = color2.GetAlpha() / 255.0f; // Normalize to [0, 1] + //alpha2 /= 2; // Use half the alpha for higher contrast + + // Don't blend grey's as much + // int minValue = min(red1, min(green1, blue1)); + // int maxValue = max(red1, max(green1, blue1)); + if(TRUE) { // red1 > 0x10 && red1 < 0xC0 && (maxValue - minValue < 0x40)) { + + // This does a standard bright highlight + alpha2 = 0; + AdjustHighlighterColor( &red2, &green2, &blue2 ); + redResult = red2 & red1; + greenResult = green2 & green1; + blueResult = blue2 & blue1; + } + else { + + // Blend each channel + redResult = static_cast(red2 * alpha2 + red1 * (1 - alpha2)); + greenResult = static_cast(green2 * alpha2 + green1 * (1 - alpha2)); + blueResult = static_cast(blue2 * alpha2 + blue1 * (1 - alpha2)); + } + // Combine the result channels back into a COLORREF + return RGB(redResult, greenResult, blueResult); +} + + + +//---------------------------------------------------------------------------- +// +// DrawHighlightedShape +// +// Draws the shape with the highlighter color. +// +//---------------------------------------------------------------------------- +void DrawHighlightedShape( DWORD Shape, HDC hdcScreenCompat, Gdiplus::Brush *pBrush, + Gdiplus::Pen *pPen, int x1, int y1, int x2, int y2) +{ + // Create a new bitmap that's the size of the area covered by the line + 2 * g_PenWidth + Gdiplus::Rect lineBounds(min(x1, x2), min(y1, y2), abs(x2 - x1), abs(y2 - y1)); + + // Expand for line drawing + if (Shape == DRAW_LINE) + lineBounds.Inflate(static_cast(g_PenWidth / 2), static_cast(g_PenWidth / 2)); + + Gdiplus::Bitmap* lineBitmap = CreateDrawingBitmap(lineBounds); + Gdiplus::Graphics lineGraphics(lineBitmap); + switch (Shape) { + case DRAW_RECTANGLE: + lineGraphics.FillRectangle(pBrush, 0, 0, lineBounds.Width, lineBounds.Height); + break; + case DRAW_ELLIPSE: + lineGraphics.FillEllipse( pBrush, 0, 0, lineBounds.Width, lineBounds.Height); + break; + case DRAW_LINE: + lineGraphics.DrawLine(pPen, x1 - lineBounds.X, y1 - lineBounds.Y, x2 - lineBounds.X, y2 - lineBounds.Y); + break; + } + + Gdiplus::BitmapData* lineData = LockGdiPlusBitmap(lineBitmap); + BYTE* pPixels = static_cast(lineData->Scan0); + + // Create a DIB section for efficient pixel manipulation + BITMAPINFO bmi = { 0 }; + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = lineBounds.Width; + bmi.bmiHeader.biHeight = -lineBounds.Height; // Top-down DIB + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; // 32 bits per pixel + bmi.bmiHeader.biCompression = BI_RGB; + + VOID* pDIBBits; + HBITMAP hDIB = CreateDIBSection(hdcScreenCompat, &bmi, DIB_RGB_COLORS, &pDIBBits, NULL, 0); + + HDC hdcDIB = CreateCompatibleDC(hdcScreenCompat); + SelectObject(hdcDIB, hDIB); + + // Copy the relevant part of hdcScreenCompat to the DIB + BitBlt(hdcDIB, 0, 0, lineBounds.Width, lineBounds.Height, hdcScreenCompat, lineBounds.X, lineBounds.Y, SRCCOPY); + + // Pointer to the DIB bits + BYTE* pDestPixels = static_cast(pDIBBits); + + // Pointer to screen bits + HDC hdcDIBOrig; + HBITMAP hDibOrigBitmap, hDibBitmap; + BYTE* pDestPixels2 = CreateBitmapMemoryDIB(hdcScreenCompat, hdcScreenCompat, &lineBounds, + &hdcDIBOrig, &hDibBitmap, &hDibOrigBitmap); + + for (int y = 0; y < lineBounds.Height; ++y) { + for (int x = 0; x < lineBounds.Width; ++x) { + int index = (y * lineBounds.Width * 4) + (x * 4); // Assuming 4 bytes per pixel + // BYTE b = pPixels[index + 0]; // Blue channel + // BYTE g = pPixels[index + 1]; // Green channel + // BYTE r = pPixels[index + 2]; // Red channel + BYTE a = pPixels[index + 3]; // Alpha channel + + // Check if this is a drawn pixel + if (a != 0) { + // Assuming pDestPixels is a valid pointer to the destination bitmap's pixel data + BYTE destB = pDestPixels2[index + 0]; // Blue channel + BYTE destG = pDestPixels2[index + 1]; // Green channel + BYTE destR = pDestPixels2[index + 2]; // Red channel + + // Create a COLORREF value from the destination pixel data + COLORREF currentPixel = RGB(destR, destG, destB); + // Blend the colors + COLORREF newPixel = BlendColors(currentPixel, g_PenColor); + // Update the destination pixel data with the new color + pDestPixels[index + 0] = GetBValue(newPixel); + pDestPixels[index + 1] = GetGValue(newPixel); + pDestPixels[index + 2] = GetRValue(newPixel); + } + } + } + + // Copy the updated DIB back to hdcScreenCompat + BitBlt(hdcScreenCompat, lineBounds.X, lineBounds.Y, lineBounds.Width, lineBounds.Height, hdcDIB, 0, 0, SRCCOPY); + + // Clean up + DeleteObject(hDIB); + DeleteDC(hdcDIB); + + SelectObject(hdcDIBOrig, hDibOrigBitmap); + DeleteObject(hDibBitmap); + DeleteDC(hdcDIBOrig); + + // Invalidate the updated rectangle + // InvalidateGdiplusRect(hWnd, lineBounds); +} + +//---------------------------------------------------------------------------- +// +// CreateFadedDesktopBackground +// +// Creates a snapshot of the desktop that's faded and alpha blended with +// black. +// +//---------------------------------------------------------------------------- +HBITMAP CreateFadedDesktopBackground( HDC hdc, LPRECT rcScreen, LPRECT rcCrop ) +{ + // create bitmap + int width = rcScreen->right - rcScreen->left; + int height = rcScreen->bottom - rcScreen->top; + HDC hdcScreen = hdc; + HDC hdcMem = CreateCompatibleDC( hdcScreen ); + HBITMAP hBitmap = CreateCompatibleBitmap( hdcScreen, width, height ); + HBITMAP hOld = static_cast(SelectObject( hdcMem, hBitmap )); + HBRUSH hBrush = CreateSolidBrush(RGB(0, 0, 0)); + + // start with black background + FillRect( hdcMem, rcScreen, hBrush ); + if(rcCrop != NULL && rcCrop->left != -1 ) { + + // copy screen contents that are not cropped + BitBlt(hdcMem, rcCrop->left, rcCrop->top, rcCrop->right - rcCrop->left, + rcCrop->bottom - rcCrop->top, hdcScreen, rcCrop->left, rcCrop->top, SRCCOPY); + } + + // blend screen contents into it + BLENDFUNCTION blend = { 0 }; + blend.BlendOp = AC_SRC_OVER; + blend.BlendFlags = 0; + blend.SourceConstantAlpha = 0x4F; + blend.AlphaFormat = 0; + AlphaBlend( hdcMem,0, 0, width, height, + hdcScreen, rcScreen->left, rcScreen->top, + width, height, blend ); + + SelectObject( hdcMem, hOld ); + DeleteDC( hdcMem ); + DeleteObject(hBrush); + ReleaseDC( NULL, hdcScreen ); + + return hBitmap; +} + +//---------------------------------------------------------------------------- +// +// AdjustToMoveBoundary +// +// Shifts to accomodate move boundary. +// +//---------------------------------------------------------------------------- +void AdjustToMoveBoundary( float zoomLevel, int *coordinate, int cursor, int size, int max ) +{ + int diff = static_cast (static_cast(size)/ static_cast(LIVEZOOM_MOVE_REGIONS)); + if( cursor - *coordinate < diff ) + *coordinate = max( 0, cursor - diff ); + else if( (*coordinate + size) - cursor < diff ) + *coordinate = min( cursor + diff - size, max - size ); +} + +//---------------------------------------------------------------------------- +// +// GetZoomedTopLeftCoordinates +// +// Gets the left top coordinate of the zoomed area of the screen +// +//---------------------------------------------------------------------------- +void GetZoomedTopLeftCoordinates( float zoomLevel, POINT *cursorPos, int *x, int width, int *y, int height ) +{ + // smoother and more natural zoom in + float scaledWidth = width/zoomLevel; + float scaledHeight = height/zoomLevel; + *x = max( 0, min( (int) (width - scaledWidth), (int) (cursorPos->x - (int) (((float) cursorPos->x/ (float) width)*scaledWidth)))); + AdjustToMoveBoundary( zoomLevel, x, cursorPos->x, static_cast(scaledWidth), width ); + *y = max( 0, min( (int) (height - scaledHeight), (int) (cursorPos->y - (int) (((float) cursorPos->y/ (float) height)*scaledHeight)))); + AdjustToMoveBoundary( zoomLevel, y, cursorPos->y, static_cast(scaledHeight), height ); +} + + +//---------------------------------------------------------------------------- +// +// ScaleImage +// +// Use gdi+ for anti-aliased bitmap stretching. +// +//---------------------------------------------------------------------------- +void ScaleImage( HDC hdcDst, float xDst, float yDst, float wDst, float hDst, + HBITMAP bmSrc, float xSrc, float ySrc, float wSrc, float hSrc ) +{ + Gdiplus::Graphics dstGraphics( hdcDst ); + { + Gdiplus::Bitmap srcBitmap( bmSrc, NULL ); + + dstGraphics.SetInterpolationMode( Gdiplus::InterpolationModeLowQuality ); + dstGraphics.SetPixelOffsetMode( Gdiplus::PixelOffsetModeHalf ); + + dstGraphics.DrawImage( &srcBitmap, Gdiplus::RectF(xDst,yDst,wDst,hDst), xSrc, ySrc, wSrc, hSrc, Gdiplus::UnitPixel ); + } +} + + +//---------------------------------------------------------------------------- +// +// GetEncoderClsid +// +//---------------------------------------------------------------------------- +int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) +{ + UINT num = 0; // number of image encoders + UINT size = 0; // size of the image encoder array in bytes +using namespace Gdiplus; + + ImageCodecInfo* pImageCodecInfo = NULL; + + GetImageEncodersSize(&num, &size); + if(size == 0) + return -1; // Failure + + pImageCodecInfo = static_cast(malloc(size)); + if(pImageCodecInfo == NULL) + return -1; // Failure + + GetImageEncoders(num, size, pImageCodecInfo); + + for(UINT j = 0; j < num; ++j) + { + if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 ) + { + *pClsid = pImageCodecInfo[j].Clsid; + free(pImageCodecInfo); + return j; // Success + } + } + + free(pImageCodecInfo); + return -1; // Failure +} + +//---------------------------------------------------------------------- +// +// ConvertToUnicode +// +//---------------------------------------------------------------------- +void +ConvertToUnicode( + PCHAR aString, + PWCHAR wString, + DWORD wStringLength + ) +{ + size_t len; + + len = MultiByteToWideChar( CP_ACP, 0, aString, static_cast(strlen(aString)), + wString, wStringLength ); + wString[len] = 0; +} + + +//---------------------------------------------------------------------------- +// +// LoadImageFile +// +// Use gdi+ to load an image. +// +//---------------------------------------------------------------------------- +HBITMAP LoadImageFile( PTCHAR Filename ) +{ + HBITMAP hBmp; + + Gdiplus::Bitmap *bitmap; + + bitmap = Gdiplus::Bitmap::FromFile(Filename); + if( bitmap->GetHBITMAP( NULL, &hBmp )) { + + return NULL; + } + delete bitmap; + return hBmp; +} + + +//---------------------------------------------------------------------------- +// +// SavePng +// +// Use gdi+ to save a PNG. +// +//---------------------------------------------------------------------------- +DWORD SavePng( PTCHAR Filename, HBITMAP hBitmap ) +{ + Gdiplus::Bitmap bitmap( hBitmap, NULL ); + CLSID pngClsid; + GetEncoderClsid(L"image/png", &pngClsid); + if( bitmap.Save( Filename, &pngClsid, NULL )) { + + return GetLastError(); + } + return ERROR_SUCCESS; +} + + +//---------------------------------------------------------------------------- +// +// EnableDisableTrayIcon +// +//---------------------------------------------------------------------------- +void EnableDisableTrayIcon( HWND hWnd, BOOLEAN Enable ) +{ + NOTIFYICONDATA tNotifyIconData; + + memset( &tNotifyIconData, 0, sizeof(tNotifyIconData)); + tNotifyIconData.cbSize = sizeof(NOTIFYICONDATA); + tNotifyIconData.hWnd = hWnd; + tNotifyIconData.uID = 1; + tNotifyIconData.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; + tNotifyIconData.uCallbackMessage = WM_USER_TRAY_ACTIVATE; + tNotifyIconData.hIcon = LoadIcon( g_hInstance, L"APPICON" ); + lstrcpyn(tNotifyIconData.szTip, APPNAME, sizeof(APPNAME)); + Shell_NotifyIcon(Enable ? NIM_ADD : NIM_DELETE, &tNotifyIconData); +} + +//---------------------------------------------------------------------------- +// +// EnableDisableOpacity +// +//---------------------------------------------------------------------------- +void EnableDisableOpacity( HWND hWnd, BOOLEAN Enable ) +{ + DWORD exStyle; + + if( pSetLayeredWindowAttributes && g_BreakOpacity != 100 ) { + + if( Enable ) { + + exStyle = GetWindowLong(hWnd, GWL_EXSTYLE); + SetWindowLong(hWnd, GWL_EXSTYLE, (exStyle | WS_EX_LAYERED)); + + pSetLayeredWindowAttributes(hWnd, 0, static_cast ((255 * g_BreakOpacity) / 100), LWA_ALPHA); + RedrawWindow(hWnd, 0, 0, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); + + } else { + + exStyle = GetWindowLong(hWnd, GWL_EXSTYLE); + SetWindowLong(hWnd, GWL_EXSTYLE, (exStyle & ~WS_EX_LAYERED)); + } + } +} + +//---------------------------------------------------------------------------- +// +// EnableDisableScreenSaver +// +//---------------------------------------------------------------------------- +void EnableDisableScreenSaver( BOOLEAN Enable ) +{ + SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,Enable,0,0); + SystemParametersInfo(SPI_SETPOWEROFFACTIVE,Enable,0,0); + SystemParametersInfo(SPI_SETLOWPOWERACTIVE,Enable,0,0); +} + +//---------------------------------------------------------------------------- +// +// EnableDisableStickyKeys +// +//---------------------------------------------------------------------------- +void EnableDisableStickyKeys( BOOLEAN Enable ) +{ + static STICKYKEYS prevStickyKeyValue = {0}; + STICKYKEYS newStickyKeyValue = {0}; + + // Need to do this on Vista tablet to stop sticky key popup when you + // hold down the shift key and draw with the pen. + if( Enable ) { + + if( prevStickyKeyValue.cbSize == sizeof(STICKYKEYS)) { + + SystemParametersInfo(SPI_SETSTICKYKEYS, + sizeof(STICKYKEYS), &prevStickyKeyValue, SPIF_SENDCHANGE); + } + + } else { + + prevStickyKeyValue.cbSize = sizeof(STICKYKEYS); + if (SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof(STICKYKEYS), + &prevStickyKeyValue, 0)) { + + newStickyKeyValue.cbSize = sizeof(STICKYKEYS); + newStickyKeyValue.dwFlags = 0; + if( !SystemParametersInfo(SPI_SETSTICKYKEYS, + sizeof(STICKYKEYS), &newStickyKeyValue, SPIF_SENDCHANGE)) { + + // DWORD error = GetLastError(); + + } + } + } +} + + +//---------------------------------------------------------------------------- +// +// GetKeyMod +// +//---------------------------------------------------------------------------- +constexpr DWORD GetKeyMod( DWORD Key ) +{ + DWORD keyMod = 0; + if( (Key >> 8) & HOTKEYF_ALT ) keyMod |= MOD_ALT; + if( (Key >> 8) & HOTKEYF_CONTROL) keyMod |= MOD_CONTROL; + if( (Key >> 8) & HOTKEYF_SHIFT) keyMod |= MOD_SHIFT; + if( (Key >> 8) & HOTKEYF_EXT) keyMod |= MOD_WIN; + return keyMod; +} + + +//---------------------------------------------------------------------------- +// +// AdvancedBreakProc +// +//---------------------------------------------------------------------------- +INT_PTR CALLBACK AdvancedBreakProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) +{ + TCHAR opacity[10]; + static TCHAR newSoundFile[MAX_PATH]; + static TCHAR newBackgroundFile[MAX_PATH]; + TCHAR filePath[MAX_PATH], initDir[MAX_PATH]; + DWORD i; + OPENFILENAME openFileName; + + switch ( message ) { + case WM_INITDIALOG: + if( pSHAutoComplete ) { + pSHAutoComplete( GetDlgItem( hDlg, IDC_SOUND_FILE), SHACF_FILESYSTEM ); + pSHAutoComplete( GetDlgItem( hDlg, IDC_BACKGROUND_FILE), SHACF_FILESYSTEM ); + } + CheckDlgButton( hDlg, IDC_CHECK_BACKGROUND_FILE, + g_BreakShowBackgroundFile ? BST_CHECKED: BST_UNCHECKED ); + CheckDlgButton( hDlg, IDC_CHECK_SOUND_FILE, + g_BreakPlaySoundFile ? BST_CHECKED: BST_UNCHECKED ); + CheckDlgButton( hDlg, IDC_CHECK_SHOW_EXPIRED, + g_ShowExpiredTime ? BST_CHECKED : BST_UNCHECKED ); + CheckDlgButton( hDlg, IDC_CHECK_BACKGROUND_STRETCH, + g_BreakBackgroundStretch ? BST_CHECKED : BST_UNCHECKED ); +#if 0 + CheckDlgButton( hDlg, IDC_CHECK_SECONDARYDISPLAY, + g_BreakOnSecondary ? BST_CHECKED : BST_UNCHECKED ); +#endif + if( pSetLayeredWindowAttributes == NULL ) { + + EnableWindow( GetDlgItem( hDlg, IDC_OPACITY ), FALSE ); + } + + // sound file + if( !g_BreakPlaySoundFile ) { + + EnableWindow( GetDlgItem( hDlg, IDC_STATIC_SOUND_FILE ), FALSE ); + EnableWindow( GetDlgItem( hDlg, IDC_SOUND_FILE ), FALSE ); + EnableWindow( GetDlgItem( hDlg, IDC_SOUND_BROWSE ), FALSE ); + } + _tcscpy( newSoundFile, g_BreakSoundFile ); + _tcscpy( filePath, g_BreakSoundFile ); + if( _tcsrchr( filePath, '\\' )) _tcscpy( filePath, _tcsrchr( g_BreakSoundFile, '\\' )+1); + if( _tcsrchr( filePath, '.' )) *_tcsrchr( filePath, '.' ) = 0; + SetDlgItemText( hDlg, IDC_SOUND_FILE, filePath ); + + // background file + if( !g_BreakShowBackgroundFile ) { + + EnableWindow( GetDlgItem( hDlg, IDC_STATIC_DESKTOP_BACKGROUND ), FALSE ); + EnableWindow( GetDlgItem( hDlg, IDC_STATIC_DESKTOP_BACKGROUND ), FALSE ); + EnableWindow( GetDlgItem( hDlg, IDC_STATIC_BACKGROUND_FILE ), FALSE ); + EnableWindow( GetDlgItem( hDlg, IDC_BACKGROUND_FILE ), FALSE ); + EnableWindow( GetDlgItem( hDlg, IDC_BACKGROUND_BROWSE ), FALSE ); + EnableWindow( GetDlgItem( hDlg, IDC_CHECK_BACKGROUND_STRETCH ), FALSE ); + } + CheckDlgButton( hDlg, + g_BreakShowDesktop ? IDC_STATIC_DESKTOP_BACKGROUND : IDC_STATIC_BACKGROUND_FILE, BST_CHECKED ); + _tcscpy( newBackgroundFile, g_BreakBackgroundFile ); + SetDlgItemText( hDlg, IDC_BACKGROUND_FILE, g_BreakBackgroundFile ); + + CheckDlgButton( hDlg, IDC_TIMER_POS1 + g_BreakTimerPosition, BST_CHECKED ); + + for( i = 10; i <= 100; i += 10) { + + _stprintf( opacity, L"%d%%", i ); + SendMessage( GetDlgItem( hDlg, IDC_OPACITY ), CB_ADDSTRING, 0, + reinterpret_cast(opacity)); + } + SendMessage( GetDlgItem( hDlg, IDC_OPACITY ), CB_SETCURSEL, + g_BreakOpacity / 10 - 1, 0 ); + return TRUE; + + case WM_COMMAND: + switch ( HIWORD( wParam )) { + case BN_CLICKED: + if( LOWORD( wParam ) == IDC_CHECK_SOUND_FILE ) { + + EnableWindow( GetDlgItem( hDlg, IDC_STATIC_SOUND_FILE ), + IsDlgButtonChecked( hDlg, IDC_CHECK_SOUND_FILE) == BST_CHECKED ); + EnableWindow( GetDlgItem( hDlg, IDC_SOUND_FILE ), + IsDlgButtonChecked( hDlg, IDC_CHECK_SOUND_FILE) == BST_CHECKED ); + EnableWindow( GetDlgItem( hDlg, IDC_SOUND_BROWSE ), + IsDlgButtonChecked( hDlg, IDC_CHECK_SOUND_FILE) == BST_CHECKED ); + } + if( LOWORD( wParam ) == IDC_CHECK_BACKGROUND_FILE ) { + + EnableWindow( GetDlgItem( hDlg, IDC_CHECK_BACKGROUND_STRETCH ), + IsDlgButtonChecked( hDlg, IDC_CHECK_BACKGROUND_FILE) == BST_CHECKED ); + EnableWindow( GetDlgItem( hDlg, IDC_STATIC_DESKTOP_BACKGROUND ), + IsDlgButtonChecked( hDlg, IDC_CHECK_BACKGROUND_FILE) == BST_CHECKED ); + EnableWindow( GetDlgItem( hDlg, IDC_STATIC_BACKGROUND_FILE ), + IsDlgButtonChecked( hDlg, IDC_CHECK_BACKGROUND_FILE) == BST_CHECKED ); + EnableWindow( GetDlgItem( hDlg, IDC_BACKGROUND_FILE ), + IsDlgButtonChecked( hDlg, IDC_CHECK_BACKGROUND_FILE) == BST_CHECKED ); + EnableWindow( GetDlgItem( hDlg, IDC_BACKGROUND_BROWSE ), + IsDlgButtonChecked( hDlg, IDC_CHECK_BACKGROUND_FILE) == BST_CHECKED ); + } + break; + } + switch ( LOWORD( wParam )) { + case IDC_SOUND_BROWSE: + memset( &openFileName, 0, sizeof(openFileName )); + openFileName.lStructSize = OPENFILENAME_SIZE_VERSION_400; + openFileName.hwndOwner = hDlg; + openFileName.hInstance = static_cast(g_hInstance); + openFileName.nMaxFile = sizeof(filePath)/sizeof(filePath[0]); + openFileName.Flags = OFN_LONGNAMES; + openFileName.lpstrTitle = L"Specify sound file..."; + openFileName.lpstrDefExt = L"*.wav"; + openFileName.nFilterIndex = 1; + openFileName.lpstrFilter = L"Sounds\0*.wav\0All Files\0*.*\0"; + + GetDlgItemText( hDlg, IDC_SOUND_FILE, filePath, sizeof(filePath )); + if( _tcsrchr( filePath, '\\' )) { + + _tcscpy( initDir, filePath ); + _tcscpy( filePath, _tcsrchr( initDir, '\\' )+1); + *(_tcsrchr( initDir, '\\' )+1) = 0; + } else { + + _tcscpy( filePath, L"%WINDIR%\\Media" ); + ExpandEnvironmentStrings( filePath, initDir, sizeof(initDir)/sizeof(initDir[0])); + GetDlgItemText( hDlg, IDC_SOUND_FILE, filePath, sizeof(filePath )); + } + openFileName.lpstrInitialDir = initDir; + openFileName.lpstrFile = filePath; + if( GetOpenFileName( &openFileName )) { + + _tcscpy( newSoundFile, filePath ); + if(_tcsrchr( filePath, '\\' )) _tcscpy( filePath, _tcsrchr( newSoundFile, '\\' )+1); + if(_tcsrchr( filePath, '.' )) *_tcsrchr( filePath, '.' ) = 0; + SetDlgItemText( hDlg, IDC_SOUND_FILE, filePath ); + } + break; + + case IDC_BACKGROUND_BROWSE: + memset( &openFileName, 0, sizeof(openFileName )); + openFileName.lStructSize = OPENFILENAME_SIZE_VERSION_400; + openFileName.hwndOwner = hDlg; + openFileName.hInstance = static_cast(g_hInstance); + openFileName.nMaxFile = sizeof(filePath)/sizeof(filePath[0]); + openFileName.Flags = OFN_LONGNAMES; + openFileName.lpstrTitle = L"Specify background file..."; + openFileName.lpstrDefExt = L"*.bmp"; + openFileName.nFilterIndex = 5; + openFileName.lpstrFilter = L"Bitmap Files (*.bmp;*.dib)\0*.bmp;*.dib\0" + "PNG (*.png)\0*.png\0" + "JPEG (*.jpg;*.jpeg;*.jpe;*.jfif)\0*.jpg;*.jpeg;*.jpe;*.jfif\0" + "GIF (*.gif)\0*.gif\0" + "All Picture Files\0.bmp;*.dib;*.png;*.jpg;*.jpeg;*.jpe;*.jfif;*.gif)\0" + "All Files\0*.*\0\0"; + + GetDlgItemText( hDlg, IDC_BACKGROUND_FILE, filePath, sizeof(filePath )); + if(_tcsrchr( filePath, '\\' )) { + + _tcscpy( initDir, filePath ); + _tcscpy( filePath, _tcsrchr( initDir, '\\' )+1); + *(_tcsrchr( initDir, '\\' )+1) = 0; + } else { + + _tcscpy( filePath, L"%USERPROFILE%\\Pictures" ); + ExpandEnvironmentStrings( filePath, initDir, sizeof(initDir)/sizeof(initDir[0])); + GetDlgItemText( hDlg, IDC_BACKGROUND_FILE, filePath, sizeof(filePath )); + } + openFileName.lpstrInitialDir = initDir; + openFileName.lpstrFile = filePath; + if( GetOpenFileName( &openFileName )) { + + _tcscpy( newBackgroundFile, filePath ); + SetDlgItemText( hDlg, IDC_BACKGROUND_FILE, filePath ); + } + break; + + case IDOK: + + // sound file has to be valid + g_BreakPlaySoundFile = IsDlgButtonChecked( hDlg, IDC_CHECK_SOUND_FILE ) == BST_CHECKED; + g_BreakShowBackgroundFile = IsDlgButtonChecked( hDlg, IDC_CHECK_BACKGROUND_FILE ) == BST_CHECKED; + g_BreakBackgroundStretch = IsDlgButtonChecked( hDlg, IDC_CHECK_BACKGROUND_STRETCH ) == BST_CHECKED; +#if 0 + g_BreakOnSecondary = IsDlgButtonChecked( hDlg, IDC_CHECK_SECONDARYDISPLAY ) == BST_CHECKED; +#endif + if( g_BreakPlaySoundFile && GetFileAttributes( newSoundFile ) == -1 ) { + + MessageBox( hDlg, L"The specified sound file is inaccessible", + L"Advanced Break Options Error", MB_ICONERROR ); + break; + } + _tcscpy( g_BreakSoundFile, newSoundFile ); + + // Background file + g_BreakShowDesktop = IsDlgButtonChecked( hDlg, IDC_STATIC_DESKTOP_BACKGROUND ) == BST_CHECKED; + + if( !g_BreakShowDesktop && g_BreakShowBackgroundFile && GetFileAttributes( newBackgroundFile ) == -1 ) { + + MessageBox( hDlg, L"The specified background file is inaccessible", + L"Advanced Break Options Error", MB_ICONERROR ); + break; + } + _tcscpy( g_BreakBackgroundFile, newBackgroundFile ); + + for( i = 0; i < 10; i++ ) { + + if( IsDlgButtonChecked( hDlg, IDC_TIMER_POS1+i) == BST_CHECKED ) { + + g_BreakTimerPosition = i; + break; + } + } + GetDlgItemText( hDlg, IDC_OPACITY, opacity, sizeof(opacity)/sizeof(opacity[0])); + _stscanf( opacity, L"%d%%", &g_BreakOpacity ); + reg.WriteRegSettings( RegSettings ); + EndDialog(hDlg, 0); + break; + + case IDCANCEL: + EndDialog( hDlg, 0 ); + return TRUE; + } + break; + + default: + break; + } + return FALSE; +} + + +//---------------------------------------------------------------------------- +// +// OptionsTabProc +// +//---------------------------------------------------------------------------- +INT_PTR CALLBACK OptionsTabProc( HWND hDlg, UINT message, + WPARAM wParam, LPARAM lParam ) +{ + HDC hDC; + LOGFONT lf; + CHOOSEFONT chooseFont; + HFONT hFont; + PAINTSTRUCT ps; + HWND hTextPreview; + HDC hDc; + RECT previewRc; + TCHAR filePath[MAX_PATH] = {0}; + OPENFILENAME openFileName; + + switch ( message ) { + case WM_INITDIALOG: + return TRUE; + case WM_COMMAND: + switch ( LOWORD( wParam )) { + case IDC_ADVANCED_BREAK: + DialogBox( g_hInstance, L"ADVANCED_BREAK", hDlg, AdvancedBreakProc ); + break; + case IDC_FONT: + hDC = GetDC (hDlg ); + lf = g_LogFont; + lf.lfHeight = -21; + chooseFont.hDC = CreateCompatibleDC (hDC); + ReleaseDC (hDlg, hDC); + chooseFont.lStructSize = sizeof (CHOOSEFONT); + chooseFont.hwndOwner = hDlg; + chooseFont.lpLogFont = &lf; + chooseFont.Flags = CF_SCREENFONTS|CF_ENABLETEMPLATE| + CF_INITTOLOGFONTSTRUCT|CF_LIMITSIZE; + chooseFont.rgbColors = RGB (0, 0, 0); + chooseFont.lCustData = 0; + chooseFont.nSizeMin = 16; + chooseFont.nSizeMax = 16; + chooseFont.hInstance = g_hInstance; + chooseFont.lpszStyle = static_cast(NULL); + chooseFont.nFontType = SCREEN_FONTTYPE; + chooseFont.lpfnHook = reinterpret_cast(static_cast(NULL)); + chooseFont.lpTemplateName = static_cast(MAKEINTRESOURCE (FORMATDLGORD31)); + if( ChooseFont( &chooseFont ) ) { + g_LogFont = lf; + InvalidateRect( hDlg, NULL, TRUE ); + } + break; + case IDC_DEMOTYPE_BROWSE: + memset( &openFileName, 0, sizeof( openFileName ) ); + openFileName.lStructSize = OPENFILENAME_SIZE_VERSION_400; + openFileName.hwndOwner = hDlg; + openFileName.hInstance = static_cast(g_hInstance); + openFileName.nMaxFile = sizeof( filePath ) / sizeof( filePath[0] ); + openFileName.Flags = OFN_LONGNAMES; + openFileName.lpstrTitle = L"Specify DemoType file..."; + openFileName.nFilterIndex = 1; + openFileName.lpstrFilter = L"All Files\0*.*\0\0"; + openFileName.lpstrFile = filePath; + + if( GetOpenFileName( &openFileName ) ) + { + if( GetFileAttributes( filePath ) == -1 ) + { + MessageBox( hDlg, L"The specified file is inaccessible", APPNAME, MB_ICONERROR ); + } + else + { + SetDlgItemText( g_OptionsTabs[DEMOTYPE_PAGE].hPage, IDC_DEMOTYPE_FILE, filePath ); + _tcscpy( g_DemoTypeFile, filePath ); + } + } + break; + } + break; + + case WM_PAINT: + if( (hTextPreview = GetDlgItem( hDlg, IDC_TEXT_FONT ))) { + + // 16-pt preview + LOGFONT _lf = g_LogFont; + _lf.lfHeight = -21; + hFont = CreateFontIndirect( &_lf); + hDc = BeginPaint(hDlg, &ps); + SelectObject( hDc, hFont ); + + GetWindowRect( hTextPreview, &previewRc ); + MapWindowPoints( NULL, hDlg, reinterpret_cast(&previewRc), 2); + + previewRc.top += 6; + DrawText( hDc, L"Sample", static_cast(_tcslen(L"Sample")), &previewRc, + DT_CENTER|DT_VCENTER|DT_SINGLELINE ); + + EndPaint( hDlg, &ps ); + DeleteObject( hFont ); + } + break; + default: + break; + } + return FALSE; +} + + +//---------------------------------------------------------------------------- +// +// OptionsAddTabs +// +//---------------------------------------------------------------------------- +VOID OptionsAddTabs( HWND hOptionsDlg, HWND hTabCtrl ) +{ + int i; + TCITEM tcItem; + RECT rc, pageRc; + + GetWindowRect( hTabCtrl, &rc ); + for( i = 0; i < sizeof( g_OptionsTabs )/sizeof(g_OptionsTabs[0]); i++ ) { + + tcItem.mask = TCIF_TEXT; + tcItem.pszText = g_OptionsTabs[i].TabTitle; + TabCtrl_InsertItem( hTabCtrl, i, &tcItem ); + g_OptionsTabs[i].hPage = CreateDialog( g_hInstance, g_OptionsTabs[i].TabTitle, + hOptionsDlg, OptionsTabProc ); + } + TabCtrl_AdjustRect( hTabCtrl, FALSE, &rc ); + for( i = 0; i < sizeof( g_OptionsTabs )/sizeof(g_OptionsTabs[0]); i++ ) { + + pageRc = rc; + MapWindowPoints( NULL, g_OptionsTabs[i].hPage, reinterpret_cast(&pageRc), 2); + + SetWindowPos( g_OptionsTabs[i].hPage, + HWND_TOP, + pageRc.left, pageRc.top, + pageRc.right - pageRc.left, pageRc.bottom - pageRc.top, + SWP_NOACTIVATE|(i == 0 ? SWP_SHOWWINDOW : SWP_HIDEWINDOW)); + + if( pEnableThemeDialogTexture ) { + + pEnableThemeDialogTexture( g_OptionsTabs[i].hPage, ETDT_ENABLETAB ); + } + } +} + +//---------------------------------------------------------------------------- +// +// UnregisterAllHotkeys +// +//---------------------------------------------------------------------------- +void UnregisterAllHotkeys( HWND hWnd ) +{ + UnregisterHotKey( hWnd, ZOOM_HOTKEY); + UnregisterHotKey( hWnd, LIVE_HOTKEY); + UnregisterHotKey( hWnd, LIVE_DRAW_HOTKEY); + UnregisterHotKey( hWnd, DRAW_HOTKEY); + UnregisterHotKey( hWnd, BREAK_HOTKEY); + UnregisterHotKey( hWnd, RECORD_HOTKEY); + UnregisterHotKey( hWnd, RECORD_CROP_HOTKEY ); + UnregisterHotKey( hWnd, RECORD_WINDOW_HOTKEY ); + UnregisterHotKey( hWnd, SNIP_HOTKEY ); + UnregisterHotKey( hWnd, SNIP_SAVE_HOTKEY); + UnregisterHotKey( hWnd, DEMOTYPE_HOTKEY ); + UnregisterHotKey( hWnd, DEMOTYPE_RESET_HOTKEY ); +} + +//---------------------------------------------------------------------------- +// +// RegisterAllHotkeys +// +//---------------------------------------------------------------------------- +void RegisterAllHotkeys(HWND hWnd) +{ + if (g_ToggleKey) RegisterHotKey(hWnd, ZOOM_HOTKEY, g_ToggleMod, g_ToggleKey & 0xFF); + if (g_LiveZoomToggleKey) { + RegisterHotKey(hWnd, LIVE_HOTKEY, g_LiveZoomToggleMod, g_LiveZoomToggleKey & 0xFF); + RegisterHotKey(hWnd, LIVE_DRAW_HOTKEY, (g_LiveZoomToggleMod ^ MOD_SHIFT), g_LiveZoomToggleKey & 0xFF); + } + if (g_DrawToggleKey) RegisterHotKey(hWnd, DRAW_HOTKEY, g_DrawToggleMod, g_DrawToggleKey & 0xFF); + if (g_BreakToggleKey) RegisterHotKey(hWnd, BREAK_HOTKEY, g_BreakToggleMod, g_BreakToggleKey & 0xFF); + if (g_DemoTypeToggleKey) { + RegisterHotKey(hWnd, DEMOTYPE_HOTKEY, g_DemoTypeToggleMod, g_DemoTypeToggleKey & 0xFF); + RegisterHotKey(hWnd, DEMOTYPE_RESET_HOTKEY, (g_DemoTypeToggleMod ^ MOD_SHIFT), g_DemoTypeToggleKey & 0xFF); + } + if (g_SnipToggleKey) { + RegisterHotKey(hWnd, SNIP_HOTKEY, g_SnipToggleMod, g_SnipToggleKey & 0xFF); + RegisterHotKey(hWnd, SNIP_SAVE_HOTKEY, (g_SnipToggleMod ^ MOD_SHIFT), g_SnipToggleKey & 0xFF); + } + if (g_RecordToggleKey) { + RegisterHotKey(hWnd, RECORD_HOTKEY, g_RecordToggleMod | MOD_NOREPEAT, g_RecordToggleKey & 0xFF); + RegisterHotKey(hWnd, RECORD_CROP_HOTKEY, (g_RecordToggleMod ^ MOD_SHIFT) | MOD_NOREPEAT, g_RecordToggleKey & 0xFF); + RegisterHotKey(hWnd, RECORD_WINDOW_HOTKEY, (g_RecordToggleMod ^ MOD_ALT) | MOD_NOREPEAT, g_RecordToggleKey & 0xFF); + } +} + + + +//---------------------------------------------------------------------------- +// +// UpdateDrawTabHeaderFont +// +//---------------------------------------------------------------------------- +void UpdateDrawTabHeaderFont() +{ + static HFONT headerFont = nullptr; + TCHAR text[64]; + + if( headerFont != nullptr ) + { + DeleteObject( headerFont ); + headerFont = nullptr; + } + + constexpr int headers[] = { IDC_PEN_CONTROL, IDC_COLORS, IDC_HIGHLIGHT_AND_BLUR, IDC_SHAPES, IDC_SCREEN }; + for( int i = 0; i < _countof( headers ); i++ ) + { + // Change the header font to bold + HWND hHeader = GetDlgItem( g_OptionsTabs[DRAW_PAGE].hPage, headers[i] ); + if( headerFont == nullptr ) + { + HFONT hFont = reinterpret_cast(SendMessage( hHeader, WM_GETFONT, 0, 0 )); + LOGFONT lf = {}; + GetObject( hFont, sizeof( LOGFONT ), &lf ); + lf.lfWeight = FW_BOLD; + headerFont = CreateFontIndirect( &lf ); + } + SendMessage( hHeader, WM_SETFONT, reinterpret_cast(headerFont), 0 ); + + // Resize the control to fit the text + GetWindowText( hHeader, text, sizeof( text ) / sizeof( text[0] ) ); + RECT rc; + GetWindowRect( hHeader, &rc ); + MapWindowPoints( NULL, g_OptionsTabs[DRAW_PAGE].hPage, reinterpret_cast(&rc), 2 ); + HDC hDC = GetDC( hHeader ); + SelectFont( hDC, headerFont ); + DrawText( hDC, text, static_cast(_tcslen( text )), &rc, DT_CALCRECT | DT_SINGLELINE | DT_LEFT | DT_VCENTER ); + ReleaseDC( hHeader, hDC ); + SetWindowPos( hHeader, nullptr, 0, 0, rc.right - rc.left + ScaleForDpi( 4, GetDpiForWindowHelper( hHeader ) ), rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER ); + } +} + +//---------------------------------------------------------------------------- +// +// OptionsProc +// +//---------------------------------------------------------------------------- +INT_PTR CALLBACK OptionsProc( HWND hDlg, UINT message, + WPARAM wParam, LPARAM lParam ) +{ + static HFONT hFontBold = nullptr; + PNMLINK notify = nullptr; + static int curTabSel = 0; + static HWND hTabCtrl; + static HWND hOpacity; + static HWND hToggleKey; + TCHAR text[32]; + DWORD newToggleKey, newTimeout, newToggleMod, newBreakToggleKey, newDemoTypeToggleKey, newRecordToggleKey, newSnipToggleKey; + DWORD newDrawToggleKey, newDrawToggleMod, newBreakToggleMod, newDemoTypeToggleMod, newRecordToggleMod, newSnipToggleMod; + DWORD newLiveZoomToggleKey, newLiveZoomToggleMod; + static std::vector> microphones; + + switch ( message ) { + case WM_INITDIALOG: + { + if( hWndOptions ) { + + BringWindowToTop( hWndOptions ); + SetFocus( hWndOptions ); + SetForegroundWindow( hWndOptions ); + EndDialog( hDlg, 0 ); + return FALSE; + } + hWndOptions = hDlg; + + SetForegroundWindow( hDlg ); + SetActiveWindow( hDlg ); + SetWindowPos( hDlg, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE|SWP_SHOWWINDOW ); +#if 1 + // set version info + TCHAR filePath[MAX_PATH]; + const TCHAR* verString; + + GetModuleFileName(NULL, filePath, _countof(filePath)); + DWORD zero = 0; + DWORD infoSize = GetFileVersionInfoSize(filePath, &zero); + void* versionInfo = malloc(infoSize); + GetFileVersionInfo(filePath, 0, infoSize, versionInfo); + + verString = GetVersionString(static_cast(versionInfo), _T("FileVersion")); + SetDlgItemText(hDlg, IDC_VERSION, (std::wstring(L"ZoomIt v") + verString).c_str()); + + verString = GetVersionString(static_cast(versionInfo), _T("LegalCopyright")); + SetDlgItemText(hDlg, IDC_COPYRIGHT, verString); + + free(versionInfo); +#endif + // Add tabs + hTabCtrl = GetDlgItem( hDlg, IDC_TAB ); + OptionsAddTabs( hDlg, hTabCtrl ); + + InitializeFonts( hDlg, &hFontBold ); + UpdateDrawTabHeaderFont(); + + // Configure options + SendMessage( GetDlgItem( g_OptionsTabs[ZOOM_PAGE].hPage, IDC_HOTKEY), HKM_SETRULES, + static_cast(HKCOMB_NONE), // invalid key combinations + MAKELPARAM(HOTKEYF_ALT, 0)); // add ALT to invalid entries + + if( g_ToggleKey ) SendMessage( GetDlgItem( g_OptionsTabs[ZOOM_PAGE].hPage, IDC_HOTKEY), HKM_SETHOTKEY, g_ToggleKey, 0 ); + if( pMagInitialize ) { + + if( g_LiveZoomToggleKey ) SendMessage( GetDlgItem( g_OptionsTabs[LIVE_PAGE].hPage, IDC_LIVE_HOTKEY), HKM_SETHOTKEY, g_LiveZoomToggleKey, 0 ); + + } else { + + EnableWindow( GetDlgItem( g_OptionsTabs[LIVE_PAGE].hPage, IDC_LIVE_HOTKEY), FALSE ); + EnableWindow( GetDlgItem( g_OptionsTabs[LIVE_PAGE].hPage, IDC_ZOOM_LEVEL), FALSE ); + EnableWindow( GetDlgItem( g_OptionsTabs[LIVE_PAGE].hPage, IDC_ZOOM_SPIN), FALSE ); + } + if( g_DrawToggleKey ) SendMessage( GetDlgItem( g_OptionsTabs[DRAW_PAGE].hPage, IDC_DRAW_HOTKEY), HKM_SETHOTKEY, g_DrawToggleKey, 0 ); + if( g_BreakToggleKey ) SendMessage( GetDlgItem( g_OptionsTabs[BREAK_PAGE].hPage, IDC_BREAK_HOTKEY), HKM_SETHOTKEY, g_BreakToggleKey, 0 ); + if( g_DemoTypeToggleKey ) SendMessage( GetDlgItem( g_OptionsTabs[DEMOTYPE_PAGE].hPage, IDC_DEMOTYPE_HOTKEY ), HKM_SETHOTKEY, g_DemoTypeToggleKey, 0 ); + if( g_RecordToggleKey ) SendMessage( GetDlgItem( g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_HOTKEY), HKM_SETHOTKEY, g_RecordToggleKey, 0 ); + if( g_SnipToggleKey) SendMessage( GetDlgItem( g_OptionsTabs[SNIP_PAGE].hPage, IDC_SNIP_HOTKEY), HKM_SETHOTKEY, g_SnipToggleKey, 0 ); + CheckDlgButton( hDlg, IDC_SHOW_TRAY_ICON, + g_ShowTrayIcon ? BST_CHECKED: BST_UNCHECKED ); + CheckDlgButton( hDlg, IDC_AUTOSTART, + IsAutostartConfigured() ? BST_CHECKED: BST_UNCHECKED ); + CheckDlgButton( g_OptionsTabs[ZOOM_PAGE].hPage, IDC_ANIMATE_ZOOM, + g_AnimateZoom ? BST_CHECKED: BST_UNCHECKED ); + + SendMessage( GetDlgItem(g_OptionsTabs[ZOOM_PAGE].hPage, IDC_ZOOM_SLIDER), TBM_SETRANGE, false, MAKELONG(0,_countof(g_ZoomLevels)-1) ); + SendMessage( GetDlgItem(g_OptionsTabs[ZOOM_PAGE].hPage, IDC_ZOOM_SLIDER), TBM_SETPOS, true, g_SliderZoomLevel ); + + _stprintf( text, L"%d", g_PenWidth ); + SetDlgItemText( g_OptionsTabs[DRAW_PAGE].hPage, IDC_PEN_WIDTH, text ); + SendMessage( GetDlgItem( g_OptionsTabs[DRAW_PAGE].hPage, IDC_PEN_WIDTH ), EM_LIMITTEXT, 1, 0 ); + SendMessage (GetDlgItem( g_OptionsTabs[DRAW_PAGE].hPage, IDC_SPIN), UDM_SETRANGE, 0L, + MAKELPARAM (19, 1)); + + _stprintf( text, L"%d", g_BreakTimeout ); + SetDlgItemText( g_OptionsTabs[BREAK_PAGE].hPage, IDC_TIMER, text ); + SendMessage( GetDlgItem( g_OptionsTabs[BREAK_PAGE].hPage, IDC_TIMER ), EM_LIMITTEXT, 2, 0 ); + SendMessage (GetDlgItem( g_OptionsTabs[BREAK_PAGE].hPage, IDC_SPIN_TIMER), UDM_SETRANGE, 0L, + MAKELPARAM (99, 1)); + CheckDlgButton( g_OptionsTabs[BREAK_PAGE].hPage, IDC_CHECK_SHOW_EXPIRED, + g_ShowExpiredTime ? BST_CHECKED : BST_UNCHECKED ); + + CheckDlgButton( g_OptionsTabs[RECORD_PAGE].hPage, IDC_CAPTURE_AUDIO, + g_CaptureAudio ? BST_CHECKED: BST_UNCHECKED ); + + for (int i = 0; i < _countof(g_FramerateOptions); i++) { + + _stprintf(text, L"%d", g_FramerateOptions[i]); + SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_FRAME_RATE), static_cast(CB_ADDSTRING), + static_cast(0), reinterpret_cast(text)); + if (g_RecordFrameRate == g_FramerateOptions[i]) { + + SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_FRAME_RATE), CB_SETCURSEL, static_cast(i), static_cast(0)); + } + } + for(unsigned int i = 1; i < 11; i++) { + + _stprintf(text, L"%2.1f", (static_cast(i)) / 10 ); + SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_SCALING), static_cast(CB_ADDSTRING), + static_cast(0), reinterpret_cast(text)); + if (g_RecordScaling == i*10 ) { + + SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_SCALING), CB_SETCURSEL, static_cast(i)-1, static_cast(0)); + } + } + + // Get the current set of microphones + microphones.clear(); + concurrency::create_task([]{ + auto devices = winrt::DeviceInformation::FindAllAsync( winrt::DeviceClass::AudioCapture ).get(); + for( auto device : devices ) + { + microphones.emplace_back( device.Id().c_str(), device.Name().c_str() ); + } + }).get(); + + // Add the microphone devices to the combo box and set the current selection + SendMessage( GetDlgItem( g_OptionsTabs[RECORD_PAGE].hPage, IDC_MICROPHONE ), static_cast(CB_ADDSTRING), static_cast(0), reinterpret_cast(L"Default")); + size_t selection = 0; + for( size_t i = 0; i < microphones.size(); i++ ) + { + SendMessage( GetDlgItem( g_OptionsTabs[RECORD_PAGE].hPage, IDC_MICROPHONE ), static_cast(CB_ADDSTRING), static_cast(0), reinterpret_cast(microphones[i].second.c_str()) ); + if( selection == 0 && wcscmp( microphones[i].first.c_str(), g_MicrophoneDeviceId ) == 0 ) + { + selection = i + 1; + } + } + SendMessage( GetDlgItem( g_OptionsTabs[RECORD_PAGE].hPage, IDC_MICROPHONE ), CB_SETCURSEL, static_cast(selection), static_cast(0) ); + + if( GetFileAttributes( g_DemoTypeFile ) == -1 ) + { + memset( g_DemoTypeFile, 0, sizeof( g_DemoTypeFile ) ); + } + else + { + SetDlgItemText( g_OptionsTabs[DEMOTYPE_PAGE].hPage, IDC_DEMOTYPE_FILE, g_DemoTypeFile ); + } + SendMessage( GetDlgItem( g_OptionsTabs[DEMOTYPE_PAGE].hPage, IDC_DEMOTYPE_SPEED_SLIDER ), TBM_SETRANGE, false, MAKELONG( MAX_TYPING_SPEED, MIN_TYPING_SPEED ) ); + SendMessage( GetDlgItem( g_OptionsTabs[DEMOTYPE_PAGE].hPage, IDC_DEMOTYPE_SPEED_SLIDER ), TBM_SETPOS, true, g_DemoTypeSpeedSlider ); + CheckDlgButton( g_OptionsTabs[DEMOTYPE_PAGE].hPage, IDC_DEMOTYPE_USER_DRIVEN, g_DemoTypeUserDriven ? BST_CHECKED: BST_UNCHECKED ); + + UnregisterAllHotkeys(GetParent( hDlg )); + PostMessage( hDlg, WM_USER, 0, 0 ); + return TRUE; + } + + case WM_USER+100: + BringWindowToTop( hDlg ); + SetFocus( hDlg ); + SetForegroundWindow( hDlg ); + return TRUE; + + case WM_DPICHANGED: + InitializeFonts( hDlg, &hFontBold ); + UpdateDrawTabHeaderFont(); + break; + + case WM_CTLCOLORSTATIC: + if( reinterpret_cast(lParam) == GetDlgItem( hDlg, IDC_TITLE ) || + reinterpret_cast(lParam) == GetDlgItem(hDlg, IDC_DRAWING) || + reinterpret_cast(lParam) == GetDlgItem(hDlg, IDC_ZOOM) || + reinterpret_cast(lParam) == GetDlgItem(hDlg, IDC_BREAK) || + reinterpret_cast(lParam) == GetDlgItem( hDlg, IDC_TYPE )) { + + HDC hdc = reinterpret_cast(wParam); + SetBkMode( hdc, TRANSPARENT ); + SelectObject( hdc, hFontBold ); + return PtrToLong(GetSysColorBrush( COLOR_BTNFACE )); + } + break; + + case WM_NOTIFY: + notify = reinterpret_cast(lParam); + if( notify->hdr.idFrom == IDC_LINK ) + { + switch( notify->hdr.code ) + { + case NM_CLICK: + case NM_RETURN: + ShellExecute( hDlg, _T("open"), notify->item.szUrl, NULL, NULL, SW_SHOWNORMAL ); + break; + } + } + else switch( notify->hdr.code ) + { + case TCN_SELCHANGE: + ShowWindow( g_OptionsTabs[curTabSel].hPage, SW_HIDE ); + curTabSel = TabCtrl_GetCurSel(hTabCtrl); + ShowWindow( g_OptionsTabs[curTabSel].hPage, SW_SHOW ); + break; + } + break; + + case WM_COMMAND: + switch ( LOWORD( wParam )) { + case IDOK: + { + if( !ConfigureAutostart( hDlg, IsDlgButtonChecked( hDlg, IDC_AUTOSTART) == BST_CHECKED )) { + + break; + } + g_ShowTrayIcon = IsDlgButtonChecked( hDlg, IDC_SHOW_TRAY_ICON ) == BST_CHECKED; + g_AnimateZoom = IsDlgButtonChecked( g_OptionsTabs[ZOOM_PAGE].hPage, IDC_ANIMATE_ZOOM ) == BST_CHECKED; + g_DemoTypeUserDriven = IsDlgButtonChecked( g_OptionsTabs[DEMOTYPE_PAGE].hPage, IDC_DEMOTYPE_USER_DRIVEN ) == BST_CHECKED; + + newToggleKey = static_cast(SendMessage( GetDlgItem( g_OptionsTabs[ZOOM_PAGE].hPage, IDC_HOTKEY), HKM_GETHOTKEY, 0, 0 )); + newLiveZoomToggleKey = static_cast(SendMessage( GetDlgItem( g_OptionsTabs[LIVE_PAGE].hPage, IDC_LIVE_HOTKEY), HKM_GETHOTKEY, 0, 0 )); + newDrawToggleKey = static_cast(SendMessage( GetDlgItem( g_OptionsTabs[DRAW_PAGE].hPage, IDC_DRAW_HOTKEY), HKM_GETHOTKEY, 0, 0 )); + newBreakToggleKey = static_cast(SendMessage( GetDlgItem( g_OptionsTabs[BREAK_PAGE].hPage, IDC_BREAK_HOTKEY), HKM_GETHOTKEY, 0, 0 )); + newDemoTypeToggleKey = static_cast(SendMessage( GetDlgItem( g_OptionsTabs[DEMOTYPE_PAGE].hPage, IDC_DEMOTYPE_HOTKEY ), HKM_GETHOTKEY, 0, 0 )); + newRecordToggleKey = static_cast(SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_HOTKEY), HKM_GETHOTKEY, 0, 0)); + newSnipToggleKey = static_cast(SendMessage( GetDlgItem( g_OptionsTabs[SNIP_PAGE].hPage, IDC_SNIP_HOTKEY), HKM_GETHOTKEY, 0, 0 )); + + newToggleMod = GetKeyMod( newToggleKey ); + newLiveZoomToggleMod = GetKeyMod( newLiveZoomToggleKey ); + newDrawToggleMod = GetKeyMod( newDrawToggleKey ); + newBreakToggleMod = GetKeyMod( newBreakToggleKey ); + newDemoTypeToggleMod = GetKeyMod( newDemoTypeToggleKey ); + newRecordToggleMod = GetKeyMod(newRecordToggleKey); + newSnipToggleMod = GetKeyMod( newSnipToggleKey ); + + g_SliderZoomLevel = static_cast(SendMessage( GetDlgItem(g_OptionsTabs[ZOOM_PAGE].hPage, IDC_ZOOM_SLIDER), TBM_GETPOS, 0, 0 )); + g_DemoTypeSpeedSlider = static_cast(SendMessage( GetDlgItem( g_OptionsTabs[DEMOTYPE_PAGE].hPage, IDC_DEMOTYPE_SPEED_SLIDER ), TBM_GETPOS, 0, 0 )); + + g_ShowExpiredTime = IsDlgButtonChecked( g_OptionsTabs[BREAK_PAGE].hPage, IDC_CHECK_SHOW_EXPIRED ) == BST_CHECKED; + g_CaptureAudio = IsDlgButtonChecked(g_OptionsTabs[RECORD_PAGE].hPage, IDC_CAPTURE_AUDIO) == BST_CHECKED; + GetDlgItemText( g_OptionsTabs[BREAK_PAGE].hPage, IDC_TIMER, text, 3 ); + text[2] = 0; + newTimeout = _tstoi( text ); + + g_RecordFrameRate = g_FramerateOptions[SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_FRAME_RATE), static_cast(CB_GETCURSEL), static_cast(0), static_cast(0))]; + g_RecordScaling = static_cast(SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_SCALING), static_cast(CB_GETCURSEL), static_cast(0), static_cast(0)) * 10 + 10); + + // Get the selected microphone + int index = static_cast(SendMessage( GetDlgItem( g_OptionsTabs[RECORD_PAGE].hPage, IDC_MICROPHONE ), static_cast(CB_GETCURSEL), static_cast(0), static_cast(0) )); + _tcscpy( g_MicrophoneDeviceId, index == 0 ? L"" : microphones[static_cast(index) - 1].first.c_str() ); + + if( newToggleKey && !RegisterHotKey( GetParent( hDlg ), ZOOM_HOTKEY, newToggleMod, newToggleKey & 0xFF )) { + + MessageBox( hDlg, L"The specified zoom toggle hotkey is already in use.\nSelect a different zoom toggle hotkey.", + APPNAME, MB_ICONERROR ); + UnregisterAllHotkeys(GetParent( hDlg )); + break; + + } else if(newLiveZoomToggleKey && + (!RegisterHotKey( GetParent( hDlg ), LIVE_HOTKEY, newLiveZoomToggleMod, newLiveZoomToggleKey & 0xFF ) || + !RegisterHotKey(GetParent(hDlg), LIVE_DRAW_HOTKEY, (newLiveZoomToggleMod ^ MOD_SHIFT), newLiveZoomToggleKey & 0xFF))) { + + MessageBox( hDlg, L"The specified live-zoom toggle hotkey is already in use.\nSelect a different zoom toggle hotkey.", + APPNAME, MB_ICONERROR ); + UnregisterAllHotkeys(GetParent( hDlg )); + break; + + } else if( newDrawToggleKey && !RegisterHotKey( GetParent( hDlg ), DRAW_HOTKEY, newDrawToggleMod, newDrawToggleKey & 0xFF )) { + + MessageBox( hDlg, L"The specified draw w/out zoom hotkey is already in use.\nSelect a different draw w/out zoom hotkey.", + APPNAME, MB_ICONERROR ); + UnregisterAllHotkeys(GetParent( hDlg )); + break; + + } else if( newBreakToggleKey && !RegisterHotKey( GetParent( hDlg ), BREAK_HOTKEY, newBreakToggleMod, newBreakToggleKey & 0xFF )) { + + MessageBox( hDlg, L"The specified break timer hotkey is already in use.\nSelect a different break timer hotkey.", + APPNAME, MB_ICONERROR ); + UnregisterAllHotkeys(GetParent( hDlg )); + break; + + } else if( newDemoTypeToggleKey && + (!RegisterHotKey( GetParent( hDlg ), DEMOTYPE_HOTKEY, newDemoTypeToggleMod, newDemoTypeToggleKey & 0xFF ) || + !RegisterHotKey(GetParent(hDlg), DEMOTYPE_RESET_HOTKEY, (newDemoTypeToggleMod ^ MOD_SHIFT), newDemoTypeToggleKey & 0xFF))) { + + MessageBox( hDlg, L"The specified live-type hotkey is already in use.\nSelect a different live-type hotkey.", + APPNAME, MB_ICONERROR ); + UnregisterAllHotkeys( GetParent( hDlg ) ); + break; + + } + else if (newSnipToggleKey && + (!RegisterHotKey(GetParent(hDlg), SNIP_HOTKEY, newSnipToggleMod, newSnipToggleKey & 0xFF) || + !RegisterHotKey(GetParent(hDlg), SNIP_SAVE_HOTKEY, (newSnipToggleMod ^ MOD_SHIFT), newSnipToggleKey & 0xFF))) { + + MessageBox(hDlg, L"The specified snip hotkey is already in use.\nSelect a different snip hotkey.", + APPNAME, MB_ICONERROR); + UnregisterAllHotkeys(GetParent(hDlg)); + break; + + } + else if( newRecordToggleKey && + (!RegisterHotKey(GetParent(hDlg), RECORD_HOTKEY, newRecordToggleMod | MOD_NOREPEAT, newRecordToggleKey & 0xFF) || + !RegisterHotKey(GetParent(hDlg), RECORD_CROP_HOTKEY, (newRecordToggleMod ^ MOD_SHIFT) | MOD_NOREPEAT, newRecordToggleKey & 0xFF) || + !RegisterHotKey(GetParent(hDlg), RECORD_WINDOW_HOTKEY, (newRecordToggleMod ^ MOD_ALT) | MOD_NOREPEAT, newRecordToggleKey & 0xFF))) { + + MessageBox(hDlg, L"The specified record hotkey is already in use.\nSelect a different record hotkey.", + APPNAME, MB_ICONERROR); + UnregisterAllHotkeys(GetParent(hDlg)); + break; + + } else { + + g_BreakTimeout = newTimeout; + g_ToggleKey = newToggleKey; + g_LiveZoomToggleKey = newLiveZoomToggleKey; + g_ToggleMod = newToggleMod; + g_DrawToggleKey = newDrawToggleKey; + g_DrawToggleMod = newDrawToggleMod; + g_BreakToggleKey = newBreakToggleKey; + g_BreakToggleMod = newBreakToggleMod; + g_DemoTypeToggleKey = newDemoTypeToggleKey; + g_DemoTypeToggleMod = newDemoTypeToggleMod; + g_RecordToggleKey = newRecordToggleKey; + g_RecordToggleMod = newRecordToggleMod; + g_SnipToggleKey = newSnipToggleKey; + g_SnipToggleMod = newSnipToggleMod; + reg.WriteRegSettings( RegSettings ); + EnableDisableTrayIcon( GetParent( hDlg ), g_ShowTrayIcon ); + + hWndOptions = NULL; + EndDialog( hDlg, 0 ); + return TRUE; + } + break; + } + + case IDCANCEL: + RegisterAllHotkeys(GetParent(hDlg)); + hWndOptions = NULL; + EndDialog( hDlg, 0 ); + return TRUE; + } + break; + + case WM_CLOSE: + hWndOptions = NULL; + RegisterAllHotkeys(GetParent(hDlg)); + EndDialog( hDlg, 0 ); + return TRUE; + + default: + break; + } + return FALSE; +} + +//---------------------------------------------------------------------------- +// +// DeleteDrawUndoList +// +//---------------------------------------------------------------------------- +void DeleteDrawUndoList( P_DRAW_UNDO *DrawUndoList ) +{ + P_DRAW_UNDO nextUndo; + + nextUndo = *DrawUndoList; + while( nextUndo ) { + + *DrawUndoList = nextUndo->Next; + DeleteObject( nextUndo->hBitmap ); + DeleteDC( nextUndo->hDc ); + free( nextUndo ); + nextUndo = *DrawUndoList; + } + *DrawUndoList = NULL; +} + +//---------------------------------------------------------------------------- +// +// PopDrawUndo +// +//---------------------------------------------------------------------------- +BOOLEAN PopDrawUndo( HDC hDc, P_DRAW_UNDO *DrawUndoList, + int width, int height ) +{ + P_DRAW_UNDO nextUndo; + + nextUndo = *DrawUndoList; + if( nextUndo ) { + + BitBlt( hDc, 0, 0, width, height, + nextUndo->hDc, 0, 0, SRCCOPY|CAPTUREBLT ); + *DrawUndoList = nextUndo->Next; + DeleteObject( nextUndo->hBitmap ); + DeleteDC( nextUndo->hDc ); + free( nextUndo ); + return TRUE; + + } else { + + Beep( 700, 200 ); + return FALSE; + } +} + + +//---------------------------------------------------------------------------- +// +// DeleteOldestUndo +// +//---------------------------------------------------------------------------- +void DeleteOldestUndo( P_DRAW_UNDO *DrawUndoList ) +{ + P_DRAW_UNDO nextUndo, freeUndo = NULL, prevUndo = NULL; + + nextUndo = *DrawUndoList; + freeUndo = nextUndo; + do { + + prevUndo = freeUndo; + freeUndo = nextUndo; + nextUndo = nextUndo->Next; + + } while( nextUndo ); + + if( freeUndo ) { + + DeleteObject( freeUndo->hBitmap ); + DeleteDC( freeUndo->hDc ); + free( freeUndo ); + if( prevUndo != *DrawUndoList ) prevUndo->Next = NULL; + else *DrawUndoList = NULL; + } +} + +//---------------------------------------------------------------------------- +// +// GetOldestUndo +// +//---------------------------------------------------------------------------- +P_DRAW_UNDO GetOldestUndo(P_DRAW_UNDO DrawUndoList) +{ + P_DRAW_UNDO nextUndo, oldestUndo = NULL; + + nextUndo = DrawUndoList; + oldestUndo = nextUndo; + do { + + oldestUndo = nextUndo; + nextUndo = nextUndo->Next; + + } while( nextUndo ); + return oldestUndo; +} + + +//---------------------------------------------------------------------------- +// +// PushDrawUndo +// +//---------------------------------------------------------------------------- +void PushDrawUndo( HDC hDc, P_DRAW_UNDO *DrawUndoList, int width, int height ) +{ + P_DRAW_UNDO nextUndo, newUndo; + int i = 0; + HBITMAP hUndoBitmap; + + OutputDebug(L"PushDrawUndo\n"); + + // Don't store more than 8 undo's (XP gets really upset when we + // exhaust heap with them) + nextUndo = *DrawUndoList; + do { + + i++; + if( i == MAX_UNDO_HISTORY ) { + + DeleteOldestUndo( DrawUndoList ); + break; + } + if( nextUndo ) nextUndo = nextUndo->Next; + + } while( nextUndo ); + + hUndoBitmap = CreateCompatibleBitmap( hDc, width, height ); + if( !hUndoBitmap && *DrawUndoList ) { + + // delete the oldest and try again + DeleteOldestUndo( DrawUndoList ); + hUndoBitmap = CreateCompatibleBitmap( hDc, width, height ); + } + if( hUndoBitmap ) { + + newUndo = static_cast(malloc( sizeof( DRAW_UNDO ))); + if (newUndo != NULL) + { + newUndo->hDc = CreateCompatibleDC(hDc); + newUndo->hBitmap = hUndoBitmap; + SelectObject(newUndo->hDc, newUndo->hBitmap); + BitBlt(newUndo->hDc, 0, 0, width, height, hDc, 0, 0, SRCCOPY | CAPTUREBLT); + newUndo->Next = *DrawUndoList; + *DrawUndoList = newUndo; + } + } +} + +//---------------------------------------------------------------------------- +// +// DeleteTypedText +// +//---------------------------------------------------------------------------- +void DeleteTypedText( P_TYPED_KEY *TypedKeyList ) +{ + P_TYPED_KEY nextKey; + + while( *TypedKeyList ) { + + nextKey = (*TypedKeyList)->Next; + free( *TypedKeyList ); + *TypedKeyList = nextKey; + } +} + +//---------------------------------------------------------------------------- +// +// BlankScreenArea +// +//---------------------------------------------------------------------------- +void BlankScreenArea( HDC hDc, PRECT Rc, int BlankMode ) +{ + if( BlankMode == 'K' ) { + + HBRUSH hBrush = CreateSolidBrush( RGB( 0, 0, 0 )); + FillRect( hDc, Rc, hBrush ); + DeleteObject( static_cast(hBrush) ); + + } else { + + FillRect( hDc, Rc, GetSysColorBrush( COLOR_WINDOW )); + } +} + +//---------------------------------------------------------------------------- +// +// ClearTypingCursor +// +//---------------------------------------------------------------------------- +void ClearTypingCursor( HDC hdcScreenCompat, HDC hdcScreenCursorCompat, RECT rc, + int BlankMode ) +{ + if( false ) { // BlankMode ) { + + BlankScreenArea( hdcScreenCompat, &rc, BlankMode ); + + } else { + + BitBlt(hdcScreenCompat, rc.left, rc.top, rc.right - rc.left, + rc.bottom - rc.top, hdcScreenCursorCompat,0, 0, SRCCOPY|CAPTUREBLT ); + } +} + +//---------------------------------------------------------------------------- +// +// DrawTypingCursor +// +//---------------------------------------------------------------------------- +void DrawTypingCursor( HWND hWnd, POINT *textPt, HDC hdcScreenCompat, + HDC hdcScreenCursorCompat, RECT *rc, bool centerUnderSystemCursor = false ) +{ + // Draw the typing cursor + rc->left = textPt->x; + rc->top = textPt->y; + TCHAR vKey = '|'; + DrawText( hdcScreenCompat, static_cast(&vKey), 1, rc, DT_CALCRECT ); + + // LiveDraw uses a layered window which means mouse messages pass through + // to lower windows unless the system cursor is above a painted area. + // Centering the typing cursor directly under the system cursor allows + // us to capture the mouse wheel input required to change font size. + if( centerUnderSystemCursor ) + { + const LONG halfWidth = static_cast( (rc->right - rc->left) / 2 ); + const LONG halfHeight = static_cast( (rc->bottom - rc->top) / 2 ); + + rc->left -= halfWidth; + rc->right -= halfWidth; + rc->top -= halfHeight; + rc->bottom -= halfHeight; + + textPt->x = rc->left; + textPt->y = rc->top; + } + + BitBlt(hdcScreenCursorCompat, 0, 0, rc->right -rc->left, rc->bottom - rc->top, + hdcScreenCompat, rc->left, rc->top, SRCCOPY|CAPTUREBLT ); + + DrawText( hdcScreenCompat, static_cast(&vKey), 1, rc, DT_LEFT ); + InvalidateRect( hWnd, NULL, TRUE ); +} + +//---------------------------------------------------------------------------- +// +// BoundMouse +// +//---------------------------------------------------------------------------- +RECT BoundMouse( float zoomLevel, MONITORINFO *monInfo, int width, int height, + POINT *cursorPos ) +{ + RECT rc; + int x, y; + + GetZoomedTopLeftCoordinates( zoomLevel, cursorPos, &x, width, &y, height ); + rc.left = monInfo->rcMonitor.left + x; + rc.right = rc.left + static_cast(width/zoomLevel); + rc.top = monInfo->rcMonitor.top + y; + rc.bottom = rc.top + static_cast(height/zoomLevel); + + OutputDebug( L"x: %d y: %d width: %d height: %d zoomLevel: %g\n", + cursorPos->x, cursorPos->y, width, height, zoomLevel); + OutputDebug( L"left: %d top: %d right: %d bottom: %d\n", + rc.left, rc.top, rc.right, rc.bottom); + OutputDebug( L"mon.left: %d mon.top: %d mon.right: %d mon.bottom: %d\n", + monInfo->rcMonitor.left, monInfo->rcMonitor.top, monInfo->rcMonitor.right, monInfo->rcMonitor.bottom); + + ClipCursor( &rc ); + return rc; +} + +//---------------------------------------------------------------------------- +// +// DrawArrow +// +//---------------------------------------------------------------------------- +void DrawArrow( HDC hdc, int x1, int y1, int x2, int y2, double length, double width, + bool UseGdiplus ) +{ + // get normalized dx/dy + double dx = static_cast(x2) - x1; + double dy = static_cast(y2) - y1; + double bodyLen = sqrt( dx*dx + dy*dy ); + if ( bodyLen ) { + dx /= bodyLen; + dy /= bodyLen; + } else { + dx = 1; + dy = 0; + } + + // get midpoint of base + int xMid = x2 - static_cast(length*dx+0.5); + int yMid = y2 - static_cast(length*dy+0.5); + + // get left wing + int xLeft = xMid - static_cast(dy*width+0.5); + int yLeft = yMid + static_cast(dx*width+0.5); + + // get right wing + int xRight = xMid + static_cast(dy*width+0.5); + int yRight = yMid - static_cast(dx*width+0.5); + + // Bring in midpoint to make a nicer arrow + xMid = x2 - static_cast(length/2*dx+0.5); + yMid = y2 - static_cast(length/2*dy+0.5); + if (UseGdiplus) { + + Gdiplus::Graphics dstGraphics(hdc); + + if( ( GetWindowLong( g_hWndMain, GWL_EXSTYLE ) & WS_EX_LAYERED ) == 0 ) + { + dstGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); + } + Gdiplus::Color color = ColorFromColorRef(g_PenColor); + Gdiplus::Pen pen(color, static_cast(g_PenWidth)); + pen.SetLineCap(Gdiplus::LineCapRound, Gdiplus::LineCapRound, Gdiplus::DashCapRound); +#if 0 + Gdiplus::PointF pts[] = { + {(Gdiplus::REAL)x1, (Gdiplus::REAL)y1}, + {(Gdiplus::REAL)xMid, (Gdiplus::REAL)yMid}, + {(Gdiplus::REAL)xLeft, (Gdiplus::REAL)yLeft}, + {(Gdiplus::REAL)x2, (Gdiplus::REAL)y2}, + {(Gdiplus::REAL)xRight, (Gdiplus::REAL)yRight}, + {(Gdiplus::REAL)xMid, (Gdiplus::REAL)yMid} + }; + dstGraphics.DrawPolygon(&pen, pts, _countof(pts)); +#else + Gdiplus::GraphicsPath path; + path.StartFigure(); + path.AddLine(static_cast(x1), static_cast(y1), static_cast(x2), static_cast(y2)); + path.AddLine(static_cast(x2), static_cast(y2), static_cast(xMid), static_cast(yMid)); + path.AddLine(static_cast(xMid), static_cast(yMid), static_cast(xLeft), static_cast(yLeft)); + path.AddLine(static_cast(xLeft), static_cast(yLeft), static_cast(x2), static_cast(y2)); + path.AddLine(static_cast(x2), static_cast(y2), static_cast(xRight), static_cast(yRight)); + path.AddLine(static_cast(xRight), static_cast(yRight), static_cast(xMid), static_cast(yMid)); + pen.SetLineJoin(Gdiplus::LineJoinRound); + dstGraphics.DrawPath(&pen, &path); +#endif + } + else { + POINT pts[] = { + x1, y1, + xMid, yMid, + xLeft, yLeft, + x2, y2, + xRight, yRight, + xMid, yMid + }; + + // draw arrow head filled with current color + HBRUSH hBrush = CreateSolidBrush(g_PenColor); + HBRUSH hOldBrush = SelectBrush(hdc, hBrush); + Polygon(hdc, pts, sizeof(pts) / sizeof(pts[0])); + + DeleteObject(hBrush); + SelectObject(hdc, hOldBrush); + } +} + + + +//---------------------------------------------------------------------------- +// +// DrawShape +// +//---------------------------------------------------------------------------- +VOID DrawShape( DWORD Shape, HDC hDc, RECT *Rect, bool UseGdiPlus = false ) +{ + bool isBlur = false; + + Gdiplus::Graphics dstGraphics(hDc); + + if( ( GetWindowLong( g_hWndMain, GWL_EXSTYLE ) & WS_EX_LAYERED ) == 0 ) + { + dstGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); + } + Gdiplus::Color color = ColorFromColorRef(g_PenColor); + Gdiplus::Pen pen(color, static_cast(g_PenWidth)); + pen.SetLineCap(Gdiplus::LineCapRound, Gdiplus::LineCapRound, Gdiplus::DashCapRound); + + // Check for highlighting or blur + Gdiplus::Brush *pBrush = NULL; + if (PEN_COLOR_HIGHLIGHT(g_PenColor)) { + // Use half the alpha for higher contrast + DWORD newColor = g_PenColor & 0xFFFFFF | ((g_AlphaBlend / 2) << 24); + pBrush = new Gdiplus::SolidBrush(ColorFromColorRef(newColor)); + if(UseGdiPlus && Shape != DRAW_LINE && Shape != DRAW_ARROW) + InflateRect(Rect, g_PenWidth/2, g_PenWidth/2); + } + else if ((g_PenColor & 0xFFFFFF) == COLOR_BLUR) { + if (UseGdiPlus && Shape != DRAW_LINE && Shape != DRAW_ARROW) + InflateRect(Rect, g_PenWidth / 2, g_PenWidth / 2); + isBlur = true; + } + + switch (Shape) { + case DRAW_RECTANGLE: + if (UseGdiPlus) + if(pBrush) + DrawHighlightedShape(DRAW_RECTANGLE, hDc, pBrush, NULL, + static_cast(Rect->left - 1), static_cast(Rect->top - 1), + static_cast(Rect->right), static_cast(Rect->bottom)); + else if (isBlur) + DrawBlurredShape( DRAW_RECTANGLE, &pen, hDc, &dstGraphics, + static_cast(Rect->left - 1), static_cast(Rect->top - 1), + static_cast(Rect->right), static_cast(Rect->bottom) ); + else + dstGraphics.DrawRectangle(&pen, + Gdiplus::Rect::Rect(Rect->left - 1, Rect->top - 1, + Rect->right - Rect->left, Rect->bottom - Rect->top)); + else + Rectangle(hDc, Rect->left, Rect->top, + Rect->right, Rect->bottom); + break; + case DRAW_ELLIPSE: + if (UseGdiPlus) + if (pBrush) + DrawHighlightedShape(DRAW_ELLIPSE, hDc, pBrush, NULL, + static_cast(Rect->left - 1), static_cast(Rect->top - 1), + static_cast(Rect->right), static_cast(Rect->bottom)); + else if (isBlur) + DrawBlurredShape( DRAW_ELLIPSE, &pen, hDc, &dstGraphics, + static_cast(Rect->left - 1), static_cast(Rect->top - 1), + static_cast(Rect->right), static_cast(Rect->bottom)); + else + dstGraphics.DrawEllipse(&pen, + Gdiplus::Rect::Rect(Rect->left - 1, Rect->top - 1, + Rect->right - Rect->left, Rect->bottom - Rect->top)); + else + Ellipse(hDc, Rect->left, Rect->top, + Rect->right, Rect->bottom); + break; + case DRAW_LINE: + if (UseGdiPlus) + if (pBrush) + DrawHighlightedShape(DRAW_LINE, hDc, NULL, &pen, + static_cast(Rect->left), static_cast(Rect->top), + static_cast(Rect->right), static_cast(Rect->bottom)); + else if (isBlur) + DrawBlurredShape(DRAW_LINE, &pen, hDc, &dstGraphics, + static_cast(Rect->left), static_cast(Rect->top), + static_cast(Rect->right), static_cast(Rect->bottom)); + else + dstGraphics.DrawLine(&pen, + static_cast(Rect->left - 1), static_cast(Rect->top - 1), + static_cast(Rect->right), static_cast(Rect->bottom)); + else { + MoveToEx(hDc, Rect->left, Rect->top, NULL); + LineTo(hDc, Rect->right + 1, Rect->bottom + 1); + } + break; + case DRAW_ARROW: + DrawArrow(hDc, Rect->right + 1, Rect->bottom + 1, + Rect->left, Rect->top, + static_cast(g_PenWidth) * 2.5, static_cast(g_PenWidth) * 1.5, UseGdiPlus); + break; + } + if( pBrush ) delete pBrush; +} + +//---------------------------------------------------------------------------- +// +// SendPenMessage +// +// Inserts the pen message marker. +// +//---------------------------------------------------------------------------- +VOID SendPenMessage(HWND hWnd, UINT Message, LPARAM lParam) +{ + WPARAM wParam = 0; + // + // Get key states + // + if(GetKeyState(VK_LCONTROL) < 0 ) { + + wParam |= MK_CONTROL; + } + if( GetKeyState( VK_LSHIFT) < 0 || GetKeyState( VK_RSHIFT) < 0 ) { + + wParam |= MK_SHIFT; + } + SetMessageExtraInfo(static_cast(MI_WP_SIGNATURE)); + SendMessage(hWnd, Message, wParam, lParam); +} + + +//---------------------------------------------------------------------------- +// +// ScalePenPosition +// +// Maps pen input to mouse input coordinates based on zoom level. Returns +// 0 if pen is active but we didn't send this message to ourselves (pen +// signature will be missing). +// +//---------------------------------------------------------------------------- +LPARAM ScalePenPosition( float zoomLevel, MONITORINFO *monInfo, RECT boundRc, + UINT message, LPARAM lParam ) +{ + RECT rc; + WORD x, y; + LPARAM extraInfo; + + extraInfo = GetMessageExtraInfo(); + if( g_PenDown ) { + + // ignore messages we didn't tag as pen + if (extraInfo == MI_WP_SIGNATURE) { + + OutputDebug( L"Tablet Pen message\n"); + + // tablet input: don't bound the cursor + ClipCursor(NULL); + + x = LOWORD(lParam); + y = HIWORD(lParam); + + x = static_cast((x - static_cast(monInfo->rcMonitor.left))/ zoomLevel) + static_cast(boundRc.left - monInfo->rcMonitor.left); + y = static_cast((y - static_cast(monInfo->rcMonitor.top)) / zoomLevel) + static_cast(boundRc.top - monInfo->rcMonitor.top); + + lParam = MAKELPARAM(x, y); + } + else { + + OutputDebug(L"Ignore pen message we didn't send\n"); + lParam = 0; + } + + } else { + + if( !GetClipCursor( &rc )) { + + ClipCursor( &boundRc ); + } + OutputDebug( L"Mouse message\n"); + } + return lParam; +} + + +//---------------------------------------------------------------------------- +// +// DrawHighlightedCursor +// +//---------------------------------------------------------------------------- +BOOLEAN DrawHighlightedCursor( float ZoomLevel, int Width, int Height ) +{ + DWORD zoomWidth = static_cast (static_cast(Width)/ZoomLevel); + DWORD zoomHeight = static_cast (static_cast(Height)/ZoomLevel); + if( g_PenWidth < 5 && zoomWidth > g_PenWidth * 100 && zoomHeight > g_PenWidth * 100 ) { + + return TRUE; + + } else { + + return FALSE; + } +} + +//---------------------------------------------------------------------------- +// +// InvalidateCursorMoveArea +// +//---------------------------------------------------------------------------- +void InvalidateCursorMoveArea( HWND hWnd, float zoomLevel, int width, int height, + POINT currentPt, POINT prevPt, POINT cursorPos ) +{ + int x, y; + RECT rc; + int invWidth = g_PenWidth; + + if( DrawHighlightedCursor( zoomLevel, width, height ) ) { + + invWidth = g_PenWidth * 3 + 1; + } + GetZoomedTopLeftCoordinates( zoomLevel, &cursorPos, &x, width, &y, height ); + rc.left = static_cast(max( 0, (int) ((min( prevPt.x, currentPt.x)-invWidth - x) * zoomLevel))); + rc.right = static_cast((max( prevPt.x, currentPt.x)+invWidth - x) * zoomLevel); + rc.top = static_cast(max( 0, (int) ((min( prevPt.y, currentPt.y)-invWidth - y) * zoomLevel))); + rc.bottom = static_cast((max( prevPt.y, currentPt.y)+invWidth -y) * zoomLevel); + InvalidateRect( hWnd, &rc, FALSE ); + + OutputDebug( L"INVALIDATE: (%d, %d) - (%d, %d)\n", rc.left, rc.top, rc.right, rc.bottom); +} + + +//---------------------------------------------------------------------------- +// +// SavCursorArea +// +//---------------------------------------------------------------------------- +void SaveCursorArea( HDC hDcTarget, HDC hDcSource, POINT pt ) +{ + OutputDebug( L"SaveCursorArea\n"); + int penWidth = g_PenWidth + 2; + BitBlt( hDcTarget, 0, 0, penWidth +CURSOR_ARM_LENGTH*2, penWidth +CURSOR_ARM_LENGTH*2, + hDcSource, static_cast (pt.x- penWidth /2)-CURSOR_ARM_LENGTH, + static_cast(pt.y- penWidth /2)-CURSOR_ARM_LENGTH, SRCCOPY|CAPTUREBLT ); +} + +//---------------------------------------------------------------------------- +// +// RestoreCursorArea +// +//---------------------------------------------------------------------------- +void RestoreCursorArea( HDC hDcTarget, HDC hDcSource, POINT pt ) +{ + OutputDebug( L"RestoreCursorArea\n"); + int penWidth = g_PenWidth + 2; + BitBlt( hDcTarget, static_cast(pt.x- penWidth /2)-CURSOR_ARM_LENGTH, + static_cast(pt.y- penWidth /2)-CURSOR_ARM_LENGTH, penWidth +CURSOR_ARM_LENGTH*2, + penWidth + CURSOR_ARM_LENGTH*2, hDcSource, 0, 0, SRCCOPY|CAPTUREBLT ); +} + + +//---------------------------------------------------------------------------- +// +// DrawCursor +// +//---------------------------------------------------------------------------- +void DrawCursor( HDC hDcTarget, POINT pt, float ZoomLevel, int Width, int Height ) +{ + RECT rc; + + if( g_DrawPointer ) { + + Gdiplus::Graphics dstGraphics(hDcTarget); + if( ( GetWindowLong( g_hWndMain, GWL_EXSTYLE ) & WS_EX_LAYERED ) == 0 ) + { + dstGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); + } + Gdiplus::Color color = ColorFromColorRef(g_PenColor); + Gdiplus::Pen pen(color, static_cast(g_PenWidth)); + + rc.left = pt.x - CURSOR_ARM_LENGTH; + rc.right = pt.x + CURSOR_ARM_LENGTH; + rc.top = pt.y - CURSOR_ARM_LENGTH; + rc.bottom = pt.y + CURSOR_ARM_LENGTH; + + Gdiplus::GraphicsPath path; + path.StartFigure(); + path.AddLine(static_cast(rc.left) - 1, static_cast(rc.top) - 1, static_cast(rc.right), static_cast(rc.bottom)); + path.AddLine(static_cast(rc.left) - 2, static_cast(rc.top) - 1, rc.left + (rc.right - rc.left) / 2, rc.top - 1); + path.AddLine(static_cast(rc.left) - 1, static_cast(rc.top) - 2, rc.left - 1, rc.top + (rc.bottom - rc.top) / 2); + path.AddLine(static_cast(rc.left) - 1, static_cast(rc.top) - 2, rc.left - 1, rc.top + (rc.bottom - rc.top) / 2); + path.AddLine(static_cast(rc.left + (rc.right - rc.left) / 2), rc.top - 1, rc.left - 1, rc.top + (rc.bottom - rc.top) / 2); + pen.SetLineJoin(Gdiplus::LineJoinRound); + dstGraphics.DrawPath(&pen, &path); + OutputDebug(L"DrawPointer: %d %d %d %d\n", rc.left, rc.top, rc.right, rc.bottom); + + } else if( DrawHighlightedCursor( ZoomLevel, Width, Height )) { + + OutputDebug(L"DrawHighlightedCursor: %d %d %d %d\n", pt.x, pt.y, g_PenWidth, g_PenWidth); + Gdiplus::Graphics dstGraphics(hDcTarget); + if( ( GetWindowLong( g_hWndMain, GWL_EXSTYLE ) & WS_EX_LAYERED ) == 0 ) + { + dstGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); + } + Gdiplus::Color color = ColorFromColorRef(g_PenColor); + Gdiplus::Pen pen(color, static_cast(g_PenWidth)); + Gdiplus::GraphicsPath path; + path.StartFigure(); + pen.SetLineJoin(Gdiplus::LineJoinRound); + path.AddLine(static_cast(pt.x - CURSOR_ARM_LENGTH), pt.y, pt.x + CURSOR_ARM_LENGTH, pt.y); + path.CloseFigure(); + path.StartFigure(); + pen.SetLineJoin(Gdiplus::LineJoinRound); + path.AddLine(static_cast(pt.x), pt.y - CURSOR_ARM_LENGTH, pt.x, pt.y + CURSOR_ARM_LENGTH); + path.CloseFigure(); + dstGraphics.DrawPath(&pen, &path); + + } else { + + Gdiplus::Graphics dstGraphics(hDcTarget); + { + if( ( GetWindowLong( g_hWndMain, GWL_EXSTYLE ) & WS_EX_LAYERED ) == 0 ) + { + dstGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); + } + Gdiplus::Color color = ColorFromColorRef(g_PenColor); + + Gdiplus::SolidBrush solidBrush(color); + + dstGraphics.FillEllipse(&solidBrush, static_cast(pt.x-g_PenWidth/2), static_cast(pt.y-g_PenWidth/2), + static_cast(g_PenWidth), static_cast(g_PenWidth)); + } + } +} + +//---------------------------------------------------------------------------- +// +// ResizePen +// +//---------------------------------------------------------------------------- +void ResizePen( HWND hWnd, HDC hdcScreenCompat, HDC hdcScreenCursorCompat, POINT prevPt, + BOOLEAN g_Tracing, BOOLEAN *g_Drawing, float g_LiveZoomLevel, + BOOLEAN isUser, int newWidth ) +{ + if( !g_Tracing ) { + + RestoreCursorArea( hdcScreenCompat, hdcScreenCursorCompat, prevPt ); + } + + OutputDebug( L"RESIZE_PEN-PRE: penWidth: %d ", g_PenWidth ); + int prevWidth = g_PenWidth; + if( g_ZoomOnLiveZoom ) + { + if( isUser ) + { + // Amplify user delta proportional to LiveZoomLevel + newWidth = g_PenWidth + static_cast ((newWidth - static_cast(g_PenWidth))*g_LiveZoomLevel); + } + + g_PenWidth = min( max( newWidth, MIN_PEN_WIDTH ), + min( static_cast(MAX_PEN_WIDTH * g_LiveZoomLevel), MAX_LIVE_PEN_WIDTH ) ); + g_RootPenWidth = static_cast(g_PenWidth / g_LiveZoomLevel); + } + else + { + g_PenWidth = min( max( newWidth, MIN_PEN_WIDTH ), MAX_PEN_WIDTH ); + g_RootPenWidth = g_PenWidth; + } + + if(prevWidth == static_cast(g_PenWidth) ) { + // No change + return; + } + + OutputDebug( L"newWidth: %d\nRESIZE_PEN-POST: penWidth: %d\n", newWidth, g_PenWidth ); + reg.WriteRegSettings( RegSettings ); + SaveCursorArea( hdcScreenCursorCompat, hdcScreenCompat, prevPt ); + *g_Drawing = FALSE; + EnableDisableStickyKeys( TRUE ); + SendMessage( hWnd, WM_LBUTTONDOWN, -1, MAKELPARAM(prevPt.x, prevPt.y) ); +} + +//---------------------------------------------------------------------------- +// +// IsPenInverted +// +//---------------------------------------------------------------------------- +bool IsPenInverted( WPARAM wParam ) +{ + POINTER_INPUT_TYPE pointerType; + POINTER_PEN_INFO penInfo; + return + pGetPointerType( GET_POINTERID_WPARAM( wParam ), &pointerType ) && ( pointerType == PT_PEN ) && + pGetPointerPenInfo( GET_POINTERID_WPARAM( wParam ), &penInfo ) && ( penInfo.penFlags & PEN_FLAG_INVERTED ); +} + + +//---------------------------------------------------------------------------- +// +// CaptureScreenshotAsync +// +// Captures the specified screen using the capture APIs +// +//---------------------------------------------------------------------------- +std::future> CaptureScreenshotAsync(winrt::IDirect3DDevice const& device, winrt::GraphicsCaptureItem const& item, winrt::DirectXPixelFormat const& pixelFormat) +{ + auto d3dDevice = GetDXGIInterfaceFromObject(device); + winrt::com_ptr d3dContext; + d3dDevice->GetImmediateContext(d3dContext.put()); + + // Creating our frame pool with CreateFreeThreaded means that we + // will be called back from the frame pool's internal worker thread + // instead of the thread we are currently on. It also disables the + // DispatcherQueue requirement. + auto framePool = winrt::Direct3D11CaptureFramePool::CreateFreeThreaded( + device, + pixelFormat, + 1, + item.Size()); + auto session = framePool.CreateCaptureSession(item); + + wil::shared_event captureEvent(wil::EventOptions::ManualReset); + winrt::Direct3D11CaptureFrame frame{ nullptr }; + framePool.FrameArrived([&frame, captureEvent](auto& framePool, auto&) + { + frame = framePool.TryGetNextFrame(); + + // Complete the operation + captureEvent.SetEvent(); + }); + + session.IsCursorCaptureEnabled( false ); + session.StartCapture(); + co_await winrt::resume_on_signal(captureEvent.get()); + + // End the capture + session.Close(); + framePool.Close(); + + auto texture = GetDXGIInterfaceFromObject(frame.Surface()); + auto result = util::CopyD3DTexture(d3dDevice, texture, true); + + co_return result; +} + +//---------------------------------------------------------------------------- +// +// CaptureScreenshot +// +// Captures the specified screen using the capture APIs +// +//---------------------------------------------------------------------------- +winrt::com_ptrCaptureScreenshot(winrt::DirectXPixelFormat const& pixelFormat) +{ + auto d3dDevice = util::CreateD3D11Device(); + auto dxgiDevice = d3dDevice.as(); + auto device = CreateDirect3DDevice(dxgiDevice.get()); + + // Get the active MONITOR capture device + HMONITOR hMon = NULL; + POINT cursorPos = { 0, 0 }; + if (pMonitorFromPoint) { + + GetCursorPos(&cursorPos); + hMon = pMonitorFromPoint(cursorPos, MONITOR_DEFAULTTONEAREST); + } + + auto item = util::CreateCaptureItemForMonitor(hMon); + + auto capture = CaptureScreenshotAsync(device, item, pixelFormat); + capture.wait(); + + return capture.get(); +} + + +//---------------------------------------------------------------------------- +// +// CopyD3DTexture +// +//---------------------------------------------------------------------------- +inline auto CopyD3DTexture(winrt::com_ptr const& device, + winrt::com_ptr const& texture, bool asStagingTexture) +{ + winrt::com_ptr context; + device->GetImmediateContext(context.put()); + + D3D11_TEXTURE2D_DESC desc = {}; + texture->GetDesc(&desc); + // Clear flags that we don't need + desc.Usage = asStagingTexture ? D3D11_USAGE_STAGING : D3D11_USAGE_DEFAULT; + desc.BindFlags = asStagingTexture ? 0 : D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = asStagingTexture ? D3D11_CPU_ACCESS_READ : 0; + desc.MiscFlags = 0; + + // Create and fill the texture copy + winrt::com_ptr textureCopy; + winrt::check_hresult(device->CreateTexture2D(&desc, nullptr, textureCopy.put())); + context->CopyResource(textureCopy.get(), texture.get()); + + return textureCopy; +} + + +//---------------------------------------------------------------------------- +// +// PrepareStagingTexture +// +//---------------------------------------------------------------------------- +inline auto PrepareStagingTexture(winrt::com_ptr const& device, + winrt::com_ptr const& texture) +{ + // If our texture is already set up for staging, then use it. + // Otherwise, create a staging texture. + D3D11_TEXTURE2D_DESC desc = {}; + texture->GetDesc(&desc); + if (desc.Usage == D3D11_USAGE_STAGING && desc.CPUAccessFlags & D3D11_CPU_ACCESS_READ) + { + return texture; + } + + return CopyD3DTexture(device, texture, true); +} + +//---------------------------------------------------------------------------- +// +// GetBytesPerPixel +// +//---------------------------------------------------------------------------- +inline size_t +GetBytesPerPixel(DXGI_FORMAT pixelFormat) +{ + switch (pixelFormat) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32A32_SINT: + return 16; + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: + return 12; + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_SINT: + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R32G8X24_TYPELESS: + return 8; + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + case DXGI_FORMAT_R11G11B10_FLOAT: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_UNKNOWN: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R16G16_SINT: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R32_SINT: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8X8_UNORM: + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + return 4; + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R8G8_SINT: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R16_SINT: + case DXGI_FORMAT_B5G6R5_UNORM: + case DXGI_FORMAT_B5G5R5A1_UNORM: + case DXGI_FORMAT_B4G4R4A4_UNORM: + return 2; + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SNORM: + case DXGI_FORMAT_R8_SINT: + case DXGI_FORMAT_A8_UNORM: + return 1; + default: + throw winrt::hresult_invalid_argument(L"Invalid pixel format!"); + } +} + +//---------------------------------------------------------------------------- +// +// CopyBytesFromTexture +// +//---------------------------------------------------------------------------- +inline auto CopyBytesFromTexture(winrt::com_ptr const& texture, uint32_t subresource = 0) +{ + winrt::com_ptr device; + texture->GetDevice(device.put()); + winrt::com_ptr context; + device->GetImmediateContext(context.put()); + + auto stagingTexture = PrepareStagingTexture(device, texture); + + D3D11_TEXTURE2D_DESC desc = {}; + stagingTexture->GetDesc(&desc); + auto bytesPerPixel = GetBytesPerPixel(desc.Format); + + // Copy the bits + D3D11_MAPPED_SUBRESOURCE mapped = {}; + winrt::check_hresult(context->Map(stagingTexture.get(), subresource, D3D11_MAP_READ, 0, &mapped)); + + auto bytesStride = static_cast(desc.Width) * bytesPerPixel; + std::vector bytes(bytesStride * static_cast(desc.Height), 0); + auto source = static_cast(mapped.pData); + auto dest = bytes.data(); + for (auto i = 0; i < static_cast(desc.Height); i++) + { + memcpy(dest, source, bytesStride); + + source += mapped.RowPitch; + dest += bytesStride; + } + context->Unmap(stagingTexture.get(), 0); + + return bytes; +} + + +//---------------------------------------------------------------------------- +// +// StopRecording +// +//---------------------------------------------------------------------------- +void StopRecording() +{ + if( g_RecordToggle == TRUE ) { + + g_SelectRectangle.Stop(); + + if ( g_RecordingSession != nullptr ) { + + g_RecordingSession->Close(); + g_RecordingSession = nullptr; + } + + g_RecordToggle = FALSE; +#if WINDOWS_CURSOR_RECORDING_WORKAROUND + + if( g_hWndLiveZoom != NULL && g_LiveZoomLevelOne ) { + + if( IsWindowVisible( g_hWndLiveZoom ) ) { + + ShowWindow( g_hWndLiveZoom, SW_HIDE ); + DestroyWindow( g_hWndLiveZoom ); + g_LiveZoomLevelOne = false; + } + } +#endif + } +} + + +//---------------------------------------------------------------------------- +// +// GetUniqueRecordingFilename +// +// Gets a unique file name for recording saves, using the " (N)" suffix +// approach so that the user can hit OK without worrying about overwriting +// if they are making multiple recordings in one session or don't want to +// always see an overwrite dialog or stop to clean up files. +// +//---------------------------------------------------------------------------- +auto GetUniqueRecordingFilename() +{ + std::filesystem::path path{ g_RecordingSaveLocation }; + + // Chop off index if it's there + auto base = std::regex_replace( path.stem().wstring(), std::wregex( L" [(][0-9]+[)]$" ), L"" ); + path.replace_filename( base + path.extension().wstring() ); + + for( int index = 1; std::filesystem::exists( path ); index++ ) + { + + // File exists, so increment number to avoid collision + path.replace_filename( base + L" (" + std::to_wstring(index) + L')' + path.extension().wstring() ); + } + return path.stem().wstring() + path.extension().wstring(); +} + +//---------------------------------------------------------------------------- +// +// StartRecordingAsync +// +// Starts the screen recording. +// +//---------------------------------------------------------------------------- +winrt::fire_and_forget StartRecordingAsync( HWND hWnd, LPRECT rcCrop, HWND hWndRecord ) try +{ + auto tempFolderPath = std::filesystem::temp_directory_path().wstring(); + auto tempFolder = co_await winrt::StorageFolder::GetFolderFromPathAsync( tempFolderPath ); + auto appFolder = co_await tempFolder.CreateFolderAsync( L"ZoomIt", winrt::CreationCollisionOption::OpenIfExists ); + auto file = co_await appFolder.CreateFileAsync( L"zoomit.mp4", winrt::CreationCollisionOption::ReplaceExisting ); + + // Get the device + auto d3dDevice = util::CreateD3D11Device(); + auto dxgiDevice = d3dDevice.as(); + g_RecordDevice = CreateDirect3DDevice( dxgiDevice.get() ); + + // Get the active MONITOR capture device + HMONITOR hMon = NULL; + POINT cursorPos = { 0, 0 }; + if( pMonitorFromPoint ) { + + GetCursorPos( &cursorPos ); + hMon = pMonitorFromPoint( cursorPos, MONITOR_DEFAULTTONEAREST ); + } + + winrt::Windows::Graphics::Capture::GraphicsCaptureItem item{ nullptr }; + if( hWndRecord ) + item = util::CreateCaptureItemForWindow( hWndRecord ); + else + item = util::CreateCaptureItemForMonitor( hMon ); + + auto stream = co_await file.OpenAsync( winrt::FileAccessMode::ReadWrite ); + g_RecordingSession = VideoRecordingSession::Create( + g_RecordDevice, + item, + *rcCrop, + g_RecordFrameRate, + g_CaptureAudio, + stream ); + + if( g_hWndLiveZoom != NULL ) + g_RecordingSession->EnableCursorCapture( false ); + + co_await g_RecordingSession->StartAsync(); + + // g_RecordingSession isn't null if we're aborting a recording + if( g_RecordingSession == nullptr ) { + + g_bSaveInProgress = true; + + SendMessage( g_hWndMain, WM_USER_SAVE_CURSOR, 0, 0 ); + + winrt::StorageFile destFile = nullptr; + HRESULT hr = S_OK; + try { + auto saveDialog = wil::CoCreateInstance( CLSID_FileSaveDialog ); + FILEOPENDIALOGOPTIONS options; + if( SUCCEEDED( saveDialog->GetOptions( &options ) ) ) + saveDialog->SetOptions( options | FOS_FORCEFILESYSTEM ); + wil::com_ptr videosItem; + if( SUCCEEDED ( SHGetKnownFolderItem( FOLDERID_Videos, KF_FLAG_DEFAULT, nullptr, IID_IShellItem, (void**) videosItem.put() ) ) ) + saveDialog->SetDefaultFolder( videosItem.get() ); + saveDialog->SetDefaultExtension( L".mp4" ); + COMDLG_FILTERSPEC fileTypes[] = { + { L"MP4 Video", L"*.mp4" } + }; + saveDialog->SetFileTypes( _countof( fileTypes ), fileTypes ); + + if( g_RecordingSaveLocation.size() == 0) { + + wil::com_ptr shellItem; + wil::unique_cotaskmem_string folderPath; + if (SUCCEEDED(saveDialog->GetFolder(shellItem.put())) && SUCCEEDED(shellItem->GetDisplayName(SIGDN_FILESYSPATH, folderPath.put()))) + g_RecordingSaveLocation = folderPath.get(); + g_RecordingSaveLocation = std::filesystem::path{ g_RecordingSaveLocation } /= DEFAULT_RECORDING_FILE; + } + auto suggestedName = GetUniqueRecordingFilename(); + saveDialog->SetFileName( suggestedName.c_str() ); + + THROW_IF_FAILED( saveDialog->Show( hWnd ) ); + wil::com_ptr shellItem; + THROW_IF_FAILED(saveDialog->GetResult(shellItem.put())); + wil::unique_cotaskmem_string filePath; + THROW_IF_FAILED(shellItem->GetDisplayName(SIGDN_FILESYSPATH, filePath.put())); + auto path = std::filesystem::path( filePath.get() ); + + winrt::StorageFolder folder{ co_await winrt::StorageFolder::GetFolderFromPathAsync( path.parent_path().c_str() ) }; + destFile = co_await folder.CreateFileAsync( path.filename().c_str(), winrt::CreationCollisionOption::ReplaceExisting ); + } + catch( const wil::ResultException& error ) { + + hr = error.GetErrorCode(); + } + if( destFile == nullptr ) { + + co_await file.DeleteAsync(); + } + else { + + co_await file.MoveAndReplaceAsync( destFile ); + g_RecordingSaveLocation = file.Path(); + SaveToClipboard(g_RecordingSaveLocation.c_str(), hWnd); + } + g_bSaveInProgress = false; + + SendMessage( g_hWndMain, WM_USER_RESTORE_CURSOR, 0, 0 ); + if( hWnd == g_hWndMain ) + RestoreForeground(); + + if( FAILED( hr ) ) + throw winrt::hresult_error( hr ); + } + else { + + co_await file.DeleteAsync(); + g_RecordingSession = nullptr; + } +} catch( const winrt::hresult_error& error ) { + + PostMessage( g_hWndMain, WM_USER_STOP_RECORDING, 0, 0 ); + + // Suppress the error from canceling the save dialog + if( error.code() == HRESULT_FROM_WIN32( ERROR_CANCELLED )) + co_return; + + if (g_RecordToggle == FALSE) { + + MessageBox(g_hWndMain, L"Recording cancelled before started", APPNAME, MB_OK | MB_ICONERROR | MB_SYSTEMMODAL); + } + else { + + ErrorDialogString(g_hWndMain, L"Error starting recording", error.message().c_str()); + } +} + +//---------------------------------------------------------------------------- +// +// UpdateMonitorInfo +// +//---------------------------------------------------------------------------- +void UpdateMonitorInfo( POINT point, MONITORINFO* monInfo ) +{ + HMONITOR hMon{}; + if( pMonitorFromPoint != nullptr ) + { + hMon = pMonitorFromPoint( point, MONITOR_DEFAULTTONEAREST ); + } + if( hMon != nullptr ) + { + monInfo->cbSize = sizeof *monInfo; + pGetMonitorInfo( hMon, monInfo ); + } + else + { + *monInfo = {}; + HDC hdcScreen = CreateDC( L"DISPLAY", nullptr, nullptr, nullptr ); + if( hdcScreen != nullptr ) + { + monInfo->rcMonitor.right = GetDeviceCaps( hdcScreen, HORZRES ); + monInfo->rcMonitor.bottom = GetDeviceCaps( hdcScreen, VERTRES ); + DeleteDC( hdcScreen ); + } + } +} + +#ifdef __ZOOMIT_POWERTOYS__ +HRESULT OpenPowerToysSettingsApp() +{ + std::wstring path = get_module_folderpath(g_hInstance); + path += L"\\PowerToys.exe"; + + std::wstring openSettings = L"--open-settings=ZoomIt"; + + std::wstring full_command_path = path + L" " + openSettings; + + STARTUPINFO startupInfo; + ZeroMemory(&startupInfo, sizeof(STARTUPINFO)); + startupInfo.cb = sizeof(STARTUPINFO); + startupInfo.wShowWindow = SW_SHOWNORMAL; + + PROCESS_INFORMATION processInformation; + + CreateProcess( + path.c_str(), + full_command_path.data(), + NULL, + NULL, + TRUE, + 0, + NULL, + NULL, + &startupInfo, + &processInformation); + + if (!CloseHandle(processInformation.hProcess)) + { + return HRESULT_FROM_WIN32(GetLastError()); + } + if (!CloseHandle(processInformation.hThread)) + { + return HRESULT_FROM_WIN32(GetLastError()); + } + return S_OK; +} +#endif // __ZOOMIT_POWERTOYS__ + +//---------------------------------------------------------------------------- +// +// ShowMainWindow +// +//---------------------------------------------------------------------------- +void ShowMainWindow(HWND hWnd, const MONITORINFO& monInfo, int width, int height) +{ + // Show the window first + SetWindowPos(hWnd, HWND_TOPMOST, monInfo.rcMonitor.left, monInfo.rcMonitor.top, + width, height, SWP_SHOWWINDOW | SWP_NOCOPYBITS); + + // Now invalidate and update the window + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + + SetForegroundWindow(hWnd); + SetActiveWindow(hWnd); +} + +//---------------------------------------------------------------------------- +// +// MainWndProc +// +//---------------------------------------------------------------------------- +LRESULT APIENTRY MainWndProc( + HWND hWnd, + UINT message, + WPARAM wParam, + LPARAM lParam) +{ + static int width, height; + static HDC hdcScreen, hdcScreenCompat, hdcScreenCursorCompat, hdcScreenSaveCompat; + static HBITMAP hbmpCompat, hbmpDrawingCompat, hbmpCursorCompat; + static RECT cropRc{}; + static BITMAP bmp; + static BOOLEAN g_TimerActive = FALSE; + static BOOLEAN g_Zoomed = FALSE; + static TypeModeState g_TypeMode = TypeModeOff; + static BOOLEAN g_HaveTyped = FALSE; + static DEVMODE secondaryDevMode; + static RECT g_LiveZoomSourceRect; + static float g_LiveZoomLevel; + static float zoomLevel; + static float zoomTelescopeStep; + static float zoomTelescopeTarget; + static POINT cursorPos; + static POINT savedCursorPos; + static RECT cursorRc; + static RECT boundRc; + static POINT prevPt; + static POINT textStartPt; + static POINT textPt; + static P_DRAW_UNDO drawUndoList = NULL; + static P_TYPED_KEY typedKeyList = NULL; + static BOOLEAN g_HaveDrawn = FALSE; + static DWORD g_DrawingShape = 0; + static DWORD prevPenWidth = g_PenWidth; + static POINT g_RectangleAnchor; + static RECT g_rcRectangle; + static BOOLEAN g_Tracing = FALSE; + static int g_BlankedScreen = 0; + static int g_StraightDirection = 0; + static BOOLEAN g_Drawing = FALSE; + static HWND g_ActiveWindow = NULL; + static int breakTimeout; + static HBITMAP g_hBackgroundBmp = NULL; + static HDC g_hDcBackgroundFile; + static HPEN hDrawingPen; + static HFONT hTimerFont; + static HFONT hNegativeTimerFont; + static HFONT hTypingFont; + static MONITORINFO monInfo; + static MONITORINFO lastMonInfo; + static HWND hTargetWindow = NULL; + static RECT rcTargetWindow; + static BOOLEAN forcePenResize = TRUE; + static BOOLEAN activeBreakShowDesktop = g_BreakShowDesktop; + static BOOLEAN activeBreakShowBackgroundFile = g_BreakShowBackgroundFile; + static TCHAR activeBreakBackgroundFile[MAX_PATH] = {0}; + static UINT wmTaskbarCreated; +#if 0 + TITLEBARINFO titleBarInfo; + WINDOWINFO targetWindowInfo; +#endif + bool isCaptureSupported = false; + RECT rc, rc1; + PAINTSTRUCT ps; + TCHAR timerText[16]; + TCHAR negativeTimerText[16]; + BOOLEAN penInverted; + BOOLEAN zoomIn; + HDC hDc; + HWND hWndRecord; + int x, y, delta; + HMENU hPopupMenu; + OPENFILENAME openFileName; + static TCHAR filePath[MAX_PATH] = {L"zoomit"}; + NOTIFYICONDATA tNotifyIconData; + + const auto drawAllRightJustifiedLines = [&rc]( long lineHeight, bool doPop = false ) { + rc.top = textPt.y - static_cast(g_TextBufferPreviousLines.size()) * lineHeight; + + for( const auto& line : g_TextBufferPreviousLines ) + { + DrawText( hdcScreenCompat, line.c_str(), static_cast(line.length()), &rc, DT_CALCRECT ); + const auto textWidth = rc.right - rc.left; + rc.left = textPt.x - textWidth; + rc.right = textPt.x; + DrawText( hdcScreenCompat, line.c_str(), static_cast(line.length()), &rc, DT_LEFT ); + rc.top += lineHeight; + } + if( !g_TextBuffer.empty() ) + { + if( doPop ) + { + g_TextBuffer.pop_back(); + } + DrawText( hdcScreenCompat, g_TextBuffer.c_str(), static_cast(g_TextBuffer.length()), &rc, DT_CALCRECT ); + rc.left = textPt.x - (rc.right - rc.left); + rc.right = textPt.x; + DrawText( hdcScreenCompat, g_TextBuffer.c_str(), static_cast(g_TextBuffer.length()), &rc, DT_LEFT ); + } + }; + + switch (message) { + case WM_CREATE: + + // get default font + GetObject( GetStockObject(DEFAULT_GUI_FONT), sizeof g_LogFont, &g_LogFont ); + g_LogFont.lfWeight = FW_NORMAL; + hDc = CreateCompatibleDC( NULL ); + g_LogFont.lfHeight = -MulDiv(8, GetDeviceCaps(hDc, LOGPIXELSY), 72); + DeleteDC( hDc ); + + reg.ReadRegSettings( RegSettings ); + + // to support migrating from + if ((g_PenColor >> 24) == 0) { + g_PenColor |= 0xFF << 24; + } + + g_PenWidth = g_RootPenWidth; + + g_ToggleMod = GetKeyMod( g_ToggleKey ); + g_LiveZoomToggleMod = GetKeyMod( g_LiveZoomToggleKey ); + g_DrawToggleMod = GetKeyMod( g_DrawToggleKey ); + g_BreakToggleMod = GetKeyMod( g_BreakToggleKey ); + g_DemoTypeToggleMod = GetKeyMod( g_DemoTypeToggleKey ); + g_SnipToggleMod = GetKeyMod( g_SnipToggleKey ); + g_RecordToggleMod = GetKeyMod( g_RecordToggleKey ); + + if( !g_OptionsShown && !g_StartedByPowerToys ) { + // First run should show options when running as standalone. If not running as standalone, + // options screen won't show and we should register keys instead. + SendMessage( hWnd, WM_COMMAND, IDC_OPTIONS, 0 ); + g_OptionsShown = TRUE; + reg.WriteRegSettings( RegSettings ); + } else { + BOOL showOptions = FALSE; + + if( g_ToggleKey && !RegisterHotKey( hWnd, ZOOM_HOTKEY, g_ToggleMod, g_ToggleKey & 0xFF)) { + + MessageBox( hWnd, L"The specified zoom toggle hotkey is already in use.\nSelect a different zoom toggle hotkey.", + APPNAME, MB_ICONERROR ); + showOptions = TRUE; + + } else if( g_LiveZoomToggleKey && + (!RegisterHotKey( hWnd, LIVE_HOTKEY, g_LiveZoomToggleMod, g_LiveZoomToggleKey & 0xFF) || + !RegisterHotKey(hWnd, LIVE_DRAW_HOTKEY, (g_LiveZoomToggleMod ^ MOD_SHIFT), g_LiveZoomToggleKey & 0xFF))) { + + MessageBox( hWnd, L"The specified live-zoom toggle hotkey is already in use.\nSelect a different zoom toggle hotkey.", + APPNAME, MB_ICONERROR ); + showOptions = TRUE; + + } else if( g_DrawToggleKey && !RegisterHotKey( hWnd, DRAW_HOTKEY, g_DrawToggleMod, g_DrawToggleKey & 0xFF )) { + + MessageBox( hWnd, L"The specified draw w/out zoom hotkey is already in use.\nSelect a different draw w/out zoom hotkey.", + APPNAME, MB_ICONERROR ); + showOptions = TRUE; + + } + else if (g_BreakToggleKey && !RegisterHotKey(hWnd, BREAK_HOTKEY, g_BreakToggleMod, g_BreakToggleKey & 0xFF)) { + + MessageBox(hWnd, L"The specified break timer hotkey is already in use.\nSelect a different break timer hotkey.", + APPNAME, MB_ICONERROR); + showOptions = TRUE; + + } + else if( g_DemoTypeToggleKey && + (!RegisterHotKey( hWnd, DEMOTYPE_HOTKEY, g_DemoTypeToggleMod, g_DemoTypeToggleKey & 0xFF ) || + !RegisterHotKey(hWnd, DEMOTYPE_RESET_HOTKEY, (g_DemoTypeToggleMod ^ MOD_SHIFT), g_DemoTypeToggleKey & 0xFF))) { + + MessageBox( hWnd, L"The specified live-type hotkey is already in use.\nSelect a different live-type hotkey.", + APPNAME, MB_ICONERROR ); + showOptions = TRUE; + + } + else if (g_SnipToggleKey && + (!RegisterHotKey(hWnd, SNIP_HOTKEY, g_SnipToggleMod, g_SnipToggleKey & 0xFF) || + !RegisterHotKey(hWnd, SNIP_SAVE_HOTKEY, (g_SnipToggleMod ^ MOD_SHIFT), g_SnipToggleKey & 0xFF))) { + + MessageBox(hWnd, L"The specified snip hotkey is already in use.\nSelect a different snip hotkey.", + APPNAME, MB_ICONERROR); + showOptions = TRUE; + + } + else if (g_RecordToggleKey && + (!RegisterHotKey(hWnd, RECORD_HOTKEY, g_RecordToggleMod | MOD_NOREPEAT, g_RecordToggleKey & 0xFF) || + !RegisterHotKey(hWnd, RECORD_CROP_HOTKEY, (g_RecordToggleMod ^ MOD_SHIFT) | MOD_NOREPEAT, g_RecordToggleKey & 0xFF) || + !RegisterHotKey(hWnd, RECORD_WINDOW_HOTKEY, (g_RecordToggleMod ^ MOD_ALT) | MOD_NOREPEAT, g_RecordToggleKey & 0xFF))) { + + MessageBox(hWnd, L"The specified record hotkey is already in use.\nSelect a different record hotkey.", + APPNAME, MB_ICONERROR); + showOptions = TRUE; + } + if( showOptions ) { + + SendMessage( hWnd, WM_COMMAND, IDC_OPTIONS, 0 ); + } + } + SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL ); + wmTaskbarCreated = RegisterWindowMessage(_T("TaskbarCreated")); + return TRUE; + + case WM_CLOSE: + // Do not allow users to close the main window, for example with Alt-F4. + return 0; + + case WM_HOTKEY: + if( g_RecordCropping == TRUE ) + { + if( wParam != RECORD_CROP_HOTKEY ) + { + // Cancel cropping on any hotkey. + g_SelectRectangle.Stop(); + g_RecordCropping = FALSE; + + // Cropping is handled by a blocking call in WM_HOTKEY, so post + // this message to the window for processing after the previous + // WM_HOTKEY message completes processing. + PostMessage( hWnd, message, wParam, lParam ); + } + return 0; + } + + // + // Magic value that comes from tray context menu + // + if (lParam == 1) { + + // + // Sleep to let context menu dismiss + // + Sleep(250); + } + switch( wParam ) { + case LIVE_DRAW_HOTKEY: + { + OutputDebug(L"LIVE_DRAW_HOTKEY\n"); + LONG_PTR exStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE); + + if ((exStyle & WS_EX_LAYERED)) { + OutputDebug(L"LiveDraw reactivate\n"); + + // Just focus on the window and re-enter drawing mode + SetFocus(hWnd); + SetForegroundWindow(hWnd); + SendMessage(hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(cursorPos.x, cursorPos.y)); + SendMessage(hWnd, WM_MOUSEMOVE, 0, MAKELPARAM(cursorPos.x, cursorPos.y)); + if( IsWindowVisible( g_hWndLiveZoom ) ) + { + SendMessage( g_hWndLiveZoom, WM_USER_MAGNIFY_CURSOR, FALSE, 0 ); + } + break; + } + else { + OutputDebug(L"LiveDraw create\n"); + + exStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE); + SetWindowLongPtr(hWnd, GWL_EXSTYLE, exStyle | WS_EX_LAYERED); + SetLayeredWindowAttributes(hWnd, COLORREF(RGB(0, 0, 0)), 0, LWA_COLORKEY); + pMagSetWindowFilterList( g_hWndLiveZoomMag, MW_FILTERMODE_EXCLUDE, 0, nullptr ); + } + [[fallthrough]]; + } + case DRAW_HOTKEY: + // + // Enter drawing mode without zoom + // +#ifdef __ZOOMIT_POWERTOYS__ + if( g_StartedByPowerToys ) + { + Trace::ZoomItActivateDraw(); + } +#endif // __ZOOMIT_POWERTOYS__ + + if( !g_Zoomed ) { + OutputDebug(L"LiveDraw: %d (%d)\n", wParam, (wParam == LIVE_DRAW_HOTKEY)); + +#if WINDOWS_CURSOR_RECORDING_WORKAROUND + if( IsWindowVisible( g_hWndLiveZoom ) && !g_LiveZoomLevelOne ) { +#else + if( IsWindowVisible( g_hWndLiveZoom )) { +#endif + + OutputDebug(L" In Live zoom\n"); + SendMessage(hWnd, WM_HOTKEY, ZOOM_HOTKEY, wParam == LIVE_DRAW_HOTKEY ? LIVE_DRAW_ZOOM : 0); + + } else { + OutputDebug(L" Not in Live zoom\n"); + SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, wParam == LIVE_DRAW_HOTKEY ? LIVE_DRAW_ZOOM : 0 ); + zoomLevel = zoomTelescopeTarget = 1; + SendMessage( hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM( cursorPos.x, cursorPos.y )); + } + if(wParam == LIVE_DRAW_HOTKEY) { + + SetLayeredWindowAttributes(hWnd, COLORREF(RGB(0, 0, 0)), 0, LWA_COLORKEY); + SendMessage(hWnd, WM_KEYDOWN, 'K', LIVE_DRAW_ZOOM); + SetTimer(hWnd, 3, 10, NULL); + SendMessage(hWnd, WM_MOUSEMOVE, 0, MAKELPARAM(cursorPos.x, cursorPos.y)); + ShowMainWindow(hWnd, monInfo, width, height); + if( ( g_PenColor & 0xFFFFFF ) == COLOR_BLUR ) + { + // Blur is not supported in LiveDraw + g_PenColor = COLOR_RED; + } + // Highlight is not supported in LiveDraw + g_PenColor |= 0xFF << 24; + } + } + break; + + case SNIP_SAVE_HOTKEY: + case SNIP_HOTKEY: + { + // Block liveZoom liveDraw snip due to mirroring bug + if( IsWindowVisible( g_hWndLiveZoom ) + && ( GetWindowLongPtr( hWnd, GWL_EXSTYLE ) & WS_EX_LAYERED ) ) + { + break; + } + + bool zoomed = true; +#ifdef __ZOOMIT_POWERTOYS__ + if( g_StartedByPowerToys ) + { + Trace::ZoomItActivateSnip(); + } +#endif // __ZOOMIT_POWERTOYS__ + + // First, static zoom + if( !g_Zoomed ) + { + zoomed = false; + if( IsWindowVisible( g_hWndLiveZoom ) && !g_LiveZoomLevelOne ) + { + SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, SHALLOW_ZOOM ); + } + else + { + SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, LIVE_DRAW_ZOOM); + } + zoomLevel = zoomTelescopeTarget = 1; + } + else if( g_Drawing ) + { + // Exit drawing mode to hide the drawing cursor + SendMessage( hWnd, WM_USER_EXIT_MODE, 0, 0 ); + + // Exit again if still in drawing mode, which happens from type mode + if( g_Drawing ) + { + SendMessage( hWnd, WM_USER_EXIT_MODE, 0, 0 ); + } + } + ShowMainWindow(hWnd, monInfo, width, height); + + // Now copy crop or copy+save + if( LOWORD( wParam ) == SNIP_SAVE_HOTKEY ) + { + SendMessage( hWnd, WM_COMMAND, IDC_SAVE_CROP, ( zoomed ? 0 : SHALLOW_ZOOM ) ); + } + else + { + SendMessage( hWnd, WM_COMMAND, IDC_COPY_CROP, ( zoomed ? 0 : SHALLOW_ZOOM ) ); + } + + // Now if we weren't zoomed, unzoom + if( !zoomed ) + { + if( g_ZoomOnLiveZoom ) + { + // hiding the cursor allows for a cleaner transition back to the magnified cursor + ShowCursor( false ); + SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, 0 ); + ShowCursor( true ); + } + else + { + SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, SHALLOW_ZOOM ); + } + } + + // exit zoom + if( g_Zoomed ) + { + // If from liveDraw, extra care is needed to destruct + if( GetWindowLong( hWnd, GWL_EXSTYLE ) & WS_EX_LAYERED ) + { + OutputDebug( L"Exiting liveDraw after snip\n" ); + SendMessage( hWnd, WM_KEYDOWN, VK_ESCAPE, 0 ); + } + else + { + // Set wparam to 1 to exit without animation + OutputDebug(L"Exiting zoom after snip\n" ); + SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, SHALLOW_DESTROY ); + } + } + break; + } + + case BREAK_HOTKEY: + // + // Go to break timer + // +#if WINDOWS_CURSOR_RECORDING_WORKAROUND + if( !g_Zoomed && ( !IsWindowVisible( g_hWndLiveZoom ) || g_LiveZoomLevelOne ) ) { +#else + if( !g_Zoomed && !IsWindowVisible( g_hWndLiveZoom )) { +#endif + + SendMessage( hWnd, WM_COMMAND, IDC_BREAK, 0 ); + } + break; + + case DEMOTYPE_RESET_HOTKEY: + ResetDemoTypeIndex(); + break; + + case DEMOTYPE_HOTKEY: + { + // + // Live type + // + switch( StartDemoType( g_DemoTypeFile, g_DemoTypeSpeedSlider, g_DemoTypeUserDriven ) ) + { + case ERROR_LOADING_FILE: + ErrorDialog( hWnd, L"Error loading DemoType file", GetLastError() ); + break; + + case NO_FILE_SPECIFIED: + MessageBox( hWnd, L"No DemoType file specified", APPNAME, MB_OK ); + break; + + case FILE_SIZE_OVERFLOW: + { + std::wstring msg = L"Unsupported DemoType file size (" + + std::to_wstring( MAX_INPUT_SIZE ) + L" byte limit)"; + MessageBox( hWnd, msg.c_str(), APPNAME, MB_OK ); + break; + } + + case UNKNOWN_FILE_DATA: + MessageBox( hWnd, L"Unrecognized DemoType file content", APPNAME, MB_OK ); + break; + default: +#ifdef __ZOOMIT_POWERTOYS__ + if( g_StartedByPowerToys ) + { + Trace::ZoomItActivateDemoType(); + } +#endif // __ZOOMIT_POWERTOYS__ + break; + } + break; + } + + case LIVE_HOTKEY: + // + // Live zoom + // + OutputDebug(L"*** LIVE_HOTKEY\n"); + + // If LiveZoom and LiveDraw are active then exit both + if( g_Zoomed && IsWindowVisible( g_hWndLiveZoom ) && ( GetWindowLongPtr( hWnd, GWL_EXSTYLE ) & WS_EX_LAYERED ) ) + { + SendMessage( hWnd, WM_KEYDOWN, VK_ESCAPE, 0 ); + PostMessage(hWnd, WM_HOTKEY, LIVE_HOTKEY, 0); + break; + } + + if( !g_Zoomed && !g_TimerActive && ( !g_fullScreenWorkaround || !g_RecordToggle ) ) { +#ifdef __ZOOMIT_POWERTOYS__ + if( g_StartedByPowerToys ) + { + Trace::ZoomItActivateLiveZoom(); + } +#endif // __ZOOMIT_POWERTOYS__ + + if( g_hWndLiveZoom == NULL ) { + OutputDebug(L"Create LIVEZOOM\n"); + g_hWndLiveZoom = CreateWindowEx( WS_EX_TOOLWINDOW | WS_EX_LAYERED | WS_EX_TRANSPARENT, + L"MagnifierClass", L"ZoomIt Live Zoom", + WS_POPUP | WS_CLIPSIBLINGS, + 0, 0, 0, 0, NULL, NULL, g_hInstance, static_cast(GetForegroundWindow()) ); + pSetLayeredWindowAttributes( hWnd, 0, 0, LWA_ALPHA ); + EnableWindow( g_hWndLiveZoom, FALSE ); + pMagSetWindowFilterList( g_hWndLiveZoomMag, MW_FILTERMODE_EXCLUDE, 1, &hWnd ); + + } else { +#if WINDOWS_CURSOR_RECORDING_WORKAROUND + if( g_LiveZoomLevelOne ) { + OutputDebug(L"liveZoom level one\n"); + SendMessage( g_hWndLiveZoom, WM_USER_SET_ZOOM, static_cast(g_LiveZoomLevel), 0 ); + } + else { +#endif + + if( IsWindowVisible( g_hWndLiveZoom )) { +#if WINDOWS_CURSOR_RECORDING_WORKAROUND + + if( g_RecordToggle ) + g_LiveZoomLevel = g_ZoomLevels[g_SliderZoomLevel]; +#endif + // Unzoom + SendMessage( g_hWndLiveZoom, WM_KEYDOWN, VK_ESCAPE, 0 ); + + } else { + + OutputDebug(L"Show liveZoom\n"); + ShowWindow( g_hWndLiveZoom, SW_SHOW ); + } +#if WINDOWS_CURSOR_RECORDING_WORKAROUND + } +#endif + } + + if ( g_RecordToggle ) + { + g_SelectRectangle.UpdateOwner( g_hWndLiveZoom ); + } + } + break; + + case RECORD_HOTKEY: + case RECORD_CROP_HOTKEY: + case RECORD_WINDOW_HOTKEY: + + // + // Recording + // This gets entered twice per recording: + // 1. When the hotkey is pressed to start recording + // 2. When the hotkey is pressed to stop recording + // + if( g_fullScreenWorkaround && g_hWndLiveZoom != NULL && IsWindowVisible( g_hWndLiveZoom ) != FALSE ) + { + break; + } + + if( g_RecordCropping == TRUE ) + { + break; + } + + // Start screen recording + try + { + isCaptureSupported = winrt::GraphicsCaptureSession::IsSupported(); + } + catch( const winrt::hresult_error& ) {} + if( !isCaptureSupported ) + { + MessageBox( hWnd, L"Screen recording requires Windows 10, May 2019 Update or higher.", APPNAME, MB_OK ); + break; + } + + // If shift, then we're cropping + hWndRecord = 0; + if( wParam == RECORD_CROP_HOTKEY ) + { + if( g_RecordToggle == TRUE ) + { + // Already recording + break; + } + + g_RecordCropping = TRUE; + + POINT savedPoint{}; + RECT savedClip = {}; + + // Handle the cursor for live zoom and static zoom modes. + if( ( g_hWndLiveZoom != nullptr ) || ( g_Zoomed == TRUE ) ) + { + GetCursorPos( &savedPoint ); + UpdateMonitorInfo( savedPoint, &monInfo ); + } + if( g_hWndLiveZoom != nullptr ) + { + // Hide the magnified cursor. + SendMessage( g_hWndLiveZoom, WM_USER_MAGNIFY_CURSOR, FALSE, 0 ); + + // Show the system cursor where the magnified was. + g_LiveZoomSourceRect = *reinterpret_cast( SendMessage( g_hWndLiveZoom, WM_USER_GET_SOURCE_RECT, 0, 0 ) ); + savedPoint = ScalePointInRects( savedPoint, g_LiveZoomSourceRect, monInfo.rcMonitor ); + SetCursorPos( savedPoint.x, savedPoint.y ); + if ( pMagShowSystemCursor != nullptr ) + { + pMagShowSystemCursor( TRUE ); + } + } + else if( ( g_Zoomed == TRUE ) && ( g_Drawing == TRUE ) ) + { + // Unclip the cursor. + GetClipCursor( &savedClip ); + ClipCursor( nullptr ); + + // Scale the cursor position to the zoomed and move it. + auto point = ScalePointInRects( savedPoint, boundRc, monInfo.rcMonitor ); + SetCursorPos( point.x, point.y ); + } + + if( g_Zoomed == FALSE ) + { + SetWindowPos( hWnd, HWND_TOPMOST, monInfo.rcMonitor.left, monInfo.rcMonitor.top, width, height, SWP_SHOWWINDOW ); + } + + // This call blocks with a message loop while cropping. + auto canceled = !g_SelectRectangle.Start( ( g_hWndLiveZoom != nullptr ) ? g_hWndLiveZoom : hWnd ); + g_RecordCropping = FALSE; + + // Restore the cursor if applicable. + if( g_hWndLiveZoom != nullptr ) + { + // Hide the system cursor. + if ( pMagShowSystemCursor != nullptr ) + { + pMagShowSystemCursor( FALSE ); + } + + // Show the magnified cursor where the system cursor was. + GetCursorPos( &savedPoint ); + savedPoint = ScalePointInRects( savedPoint, monInfo.rcMonitor, g_LiveZoomSourceRect ); + SetCursorPos( savedPoint.x, savedPoint.y ); + SendMessage( g_hWndLiveZoom, WM_USER_MAGNIFY_CURSOR, TRUE, 0 ); + } + else if( g_Zoomed == TRUE ) + { + SetCursorPos( savedPoint.x, savedPoint.y ); + + if ( g_Drawing == TRUE ) + { + ClipCursor( &savedClip ); + } + } + + SetForegroundWindow( hWnd ); + if( g_Zoomed == FALSE ) + { + SetActiveWindow( hWnd ); + ShowWindow( hWnd, SW_HIDE ); + } + + if( canceled ) + { + break; + } + + g_SelectRectangle.UpdateOwner( ( g_hWndLiveZoom != nullptr ) ? g_hWndLiveZoom : hWnd ); + cropRc = g_SelectRectangle.SelectedRect(); + } + else + { + cropRc = {}; + + // if we're recording a window, get the window + if (wParam == RECORD_WINDOW_HOTKEY) + { + GetCursorPos(&cursorPos); + hWndRecord = WindowFromPoint(cursorPos); + while( GetParent(hWndRecord) != NULL) + { + hWndRecord = GetParent(hWndRecord); + } + if( hWndRecord == GetDesktopWindow()) { + + hWndRecord = NULL; + } + } + } + + if( g_RecordToggle == FALSE ) + { + g_RecordToggle = TRUE; +#ifdef __ZOOMIT_POWERTOYS__ + if( g_StartedByPowerToys ) + { + Trace::ZoomItActivateRecord(); + } +#endif // __ZOOMIT_POWERTOYS__ + + StartRecordingAsync( hWnd, &cropRc, hWndRecord ); + } + else + { + StopRecording(); + } + break; + + case ZOOM_HOTKEY: + // + // Zoom + // + // Don't react to hotkey while options are open or we're + // saving the screen or live zoom is active + // + if( hWndOptions ) { + + break; + } + + OutputDebug( L"ZOOM HOTKEY: %d\n", lParam); + if( g_TimerActive ) { + + // + // Finished with break timer + // + if( g_BreakOnSecondary ) + { + EnableDisableSecondaryDisplay( hWnd, FALSE, &secondaryDevMode ); + } + + if( lParam != SHALLOW_DESTROY ) + { + ShowWindow( hWnd, SW_HIDE ); + if( g_hBackgroundBmp ) + { + DeleteObject( g_hBackgroundBmp ); + DeleteDC( g_hDcBackgroundFile ); + g_hBackgroundBmp = NULL; + } + } + + SetFocus( GetDesktopWindow() ); + KillTimer( hWnd, 0 ); + g_TimerActive = FALSE; + + DeleteObject( hTimerFont ); + DeleteObject( hNegativeTimerFont ); + DeleteDC( hdcScreen ); + DeleteDC( hdcScreenCompat ); + DeleteDC( hdcScreenSaveCompat ); + DeleteDC( hdcScreenCursorCompat ); + DeleteObject( hbmpCompat ); + EnableDisableScreenSaver( TRUE ); + EnableDisableOpacity( hWnd, FALSE ); + + } else { + + SendMessage( hWnd, WM_USER_TYPING_OFF, 0, 0 ); + if( !g_Zoomed ) { + + g_Zoomed = TRUE; + g_DrawingShape = FALSE; + OutputDebug( L"Zoom on\n"); + +#ifdef __ZOOMIT_POWERTOYS__ + if( g_StartedByPowerToys ) + { + Trace::ZoomItActivateZoom(); + } +#endif // __ZOOMIT_POWERTOYS__ + + // Hide the cursor before capturing if in live zoom + if( g_hWndLiveZoom != nullptr ) + { + OutputDebug(L"Hide cursor\n"); + SendMessage( g_hWndLiveZoom, WM_USER_MAGNIFY_CURSOR, FALSE, 0 ); + SendMessage( g_hWndLiveZoom, WM_TIMER, 0, 0 ); + SendMessage( g_hWndLiveZoom, WM_USER_MAGNIFY_CURSOR, FALSE, 0 ); + } + + // Get screen DCs + hdcScreen = CreateDC(L"DISPLAY", static_cast(NULL), + static_cast(NULL), static_cast(NULL)); + hdcScreenCompat = CreateCompatibleDC(hdcScreen); + hdcScreenSaveCompat = CreateCompatibleDC(hdcScreen); + hdcScreenCursorCompat = CreateCompatibleDC(hdcScreen); + + // Determine what monitor we're on + GetCursorPos(&cursorPos); + UpdateMonitorInfo( cursorPos, &monInfo ); + width = monInfo.rcMonitor.right - monInfo.rcMonitor.left; + height = monInfo.rcMonitor.bottom - monInfo.rcMonitor.top; + OutputDebug( L"ZOOM x: %d y: %d width: %d height: %d zoomLevel: %g\n", + cursorPos.x, cursorPos.y, width, height, zoomLevel ); + + // Create display bitmap + bmp.bmBitsPixel = static_cast(GetDeviceCaps(hdcScreen, BITSPIXEL)); + bmp.bmPlanes = static_cast(GetDeviceCaps(hdcScreen, PLANES)); + bmp.bmWidth = width; + bmp.bmHeight = height; + bmp.bmWidthBytes = ((bmp.bmWidth + 15) &~15)/8; + hbmpCompat = CreateBitmap(bmp.bmWidth, bmp.bmHeight, + bmp.bmPlanes, bmp.bmBitsPixel, static_cast(NULL)); + SelectObject(hdcScreenCompat, hbmpCompat); + + // Create saved bitmap + hbmpDrawingCompat = CreateBitmap(bmp.bmWidth, bmp.bmHeight, + bmp.bmPlanes, bmp.bmBitsPixel, static_cast(NULL)); + SelectObject(hdcScreenSaveCompat, hbmpDrawingCompat); + + // Create cursor save bitmap + // (have to accomodate large fonts and LiveZoom pen scaling) + hbmpCursorCompat = CreateBitmap( MAX_LIVE_PEN_WIDTH+CURSOR_ARM_LENGTH*2, + MAX_LIVE_PEN_WIDTH+CURSOR_ARM_LENGTH*2, bmp.bmPlanes, + bmp.bmBitsPixel, static_cast(NULL)); + SelectObject(hdcScreenCursorCompat, hbmpCursorCompat); + + // Create typing font + g_LogFont.lfHeight = height / 15; + if (g_LogFont.lfHeight < 20) + g_LogFont.lfQuality = NONANTIALIASED_QUALITY; + else + g_LogFont.lfQuality = ANTIALIASED_QUALITY; + hTypingFont = CreateFontIndirect(&g_LogFont); + SelectObject(hdcScreenCompat, hTypingFont); + SetTextColor(hdcScreenCompat, g_PenColor & 0xFFFFFF); + SetBkMode(hdcScreenCompat, TRANSPARENT); + + // Use the screen DC unless recording, because it contains the yellow border + HDC hdcSource = hdcScreen; + if( g_RecordToggle ) try { + + auto capture = CaptureScreenshot( winrt::DirectXPixelFormat::B8G8R8A8UIntNormalized ); + auto bytes = CopyBytesFromTexture( capture ); + + D3D11_TEXTURE2D_DESC desc; + capture->GetDesc( &desc ); + BITMAPINFO bitmapInfo = {}; + bitmapInfo.bmiHeader.biSize = sizeof bitmapInfo.bmiHeader; + bitmapInfo.bmiHeader.biWidth = desc.Width; + bitmapInfo.bmiHeader.biHeight = -static_cast(desc.Height); + bitmapInfo.bmiHeader.biPlanes = 1; + bitmapInfo.bmiHeader.biBitCount = 32; + bitmapInfo.bmiHeader.biCompression = BI_RGB; + void *bits; + auto dib = CreateDIBSection( NULL, &bitmapInfo, DIB_RGB_COLORS, &bits, nullptr, 0 ); + if( dib ) { + + CopyMemory( bits, bytes.data(), bytes.size() ); + auto hdcCapture = CreateCompatibleDC( hdcScreen ); + SelectObject( hdcCapture, dib ); + hdcSource = hdcCapture; + } + + } catch( const winrt::hresult_error& ) {} // on any failure, fall back to the screen DC + + bool captured = hdcSource != hdcScreen; + + // paint the initial bitmap + BitBlt( hdcScreenCompat, 0, 0, bmp.bmWidth, bmp.bmHeight, hdcSource, + captured ? 0 : monInfo.rcMonitor.left, captured ? 0 : monInfo.rcMonitor.top, SRCCOPY|CAPTUREBLT ); + BitBlt( hdcScreenSaveCompat, 0, 0, bmp.bmWidth, bmp.bmHeight, hdcSource, + captured ? 0 : monInfo.rcMonitor.left, captured ? 0 : monInfo.rcMonitor.top, SRCCOPY|CAPTUREBLT ); + + if( captured ) + { + OutputDebug(L"Captured screen\n"); + auto bitmap = GetCurrentObject( hdcSource, OBJ_BITMAP ); + DeleteObject( bitmap ); + DeleteDC( hdcSource ); + } + + // Create drawing pen + hDrawingPen = CreatePen(PS_SOLID, g_PenWidth, g_PenColor & 0xFFFFFF); + + g_BlankedScreen = FALSE; + g_HaveTyped = FALSE; + g_Drawing = FALSE; + g_TypeMode = TypeModeOff; + g_HaveDrawn = FALSE; + EnableDisableStickyKeys( TRUE ); + + // Go full screen + g_ActiveWindow = GetForegroundWindow(); + OutputDebug( L"active window: %x\n", PtrToLong(g_ActiveWindow) ); + + if( lParam != LIVE_DRAW_ZOOM) { + + OutputDebug(L"Calling ShowMainWindow\n"); + ShowMainWindow(hWnd, monInfo, width, height); + } + + // Start telescoping zoom. Lparam is non-zero if this + // was a real hotkey and not the message we send ourself to enter + // unzoomed drawing mode. + + // + // Are we switching from live zoom to standard zoom? + // +#if WINDOWS_CURSOR_RECORDING_WORKAROUND + if( IsWindowVisible( g_hWndLiveZoom ) && !g_LiveZoomLevelOne ) { +#else + if( IsWindowVisible( g_hWndLiveZoom )) { +#endif + + // Enter drawing mode + OutputDebug(L"Enter liveZoom draw\n"); + g_LiveZoomSourceRect = *reinterpret_cast(SendMessage( g_hWndLiveZoom, WM_USER_GET_SOURCE_RECT, 0, 0 )); + g_LiveZoomLevel = *reinterpret_cast(SendMessage(g_hWndLiveZoom, WM_USER_GET_ZOOM_LEVEL, 0, 0)); + + // Set live zoom level to 1 in preparation of us being full screen static + zoomLevel = 1.0; + zoomTelescopeTarget = 1.0; + if (lParam != LIVE_DRAW_ZOOM) { + + g_ZoomOnLiveZoom = TRUE; + } + + UpdateWindow( hWnd ); // overwrites where cursor erased + if( lParam != SHALLOW_ZOOM ) + { + // Put the drawing cursor where the magnified cursor was + OutputDebug(L"Setting cursor\n"); + + if (lParam != LIVE_DRAW_ZOOM) + { + cursorPos = ScalePointInRects( cursorPos, g_LiveZoomSourceRect, monInfo.rcMonitor ); + SetCursorPos( cursorPos.x, cursorPos.y ); + UpdateWindow( hWnd ); // overwrites where cursor erased + SendMessage( hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM( cursorPos.x, cursorPos.y )); + } + } + else + { + InvalidateRect( hWnd, NULL, FALSE ); + } + UpdateWindow( hWnd ); + if( g_RecordToggle ) + { + g_SelectRectangle.UpdateOwner( hWnd ); + } + if( lParam != LIVE_DRAW_ZOOM ) { + + OutputDebug(L"Calling ShowMainWindow 2\n"); + + ShowWindow( g_hWndLiveZoom, SW_HIDE ); + } + + } else if( lParam != 0 && lParam != LIVE_DRAW_ZOOM ) { + + zoomTelescopeStep = ZOOM_LEVEL_STEP_IN; + zoomTelescopeTarget = g_ZoomLevels[g_SliderZoomLevel]; + if( g_AnimateZoom ) + zoomLevel = static_cast(1.0) * zoomTelescopeStep; + else + zoomLevel = zoomTelescopeTarget; + SetTimer( hWnd, 1, ZOOM_LEVEL_STEP_TIME, NULL ); + } + + } else { + + OutputDebug( L"Zoom off: don't animate=%d\n", lParam ); + // turn off liveDraw + SetLayeredWindowAttributes(hWnd, 0, 255, LWA_ALPHA); + + if( lParam != SHALLOW_DESTROY && !g_ZoomOnLiveZoom && g_AnimateZoom && + g_TelescopeZoomOut && zoomTelescopeTarget != 1 ) { + + // Start telescoping zoom. + zoomTelescopeStep = ZOOM_LEVEL_STEP_OUT; + zoomTelescopeTarget = 1.0; + SetTimer( hWnd, 2, ZOOM_LEVEL_STEP_TIME, NULL ); + + } else { + + // Simulate timer expiration + zoomTelescopeStep = 0; + zoomTelescopeTarget = zoomLevel = 1.0; + SendMessage( hWnd, WM_TIMER, 2, lParam ); + } + } + } + break; + } + return TRUE; + + case WM_POINTERUPDATE: { + penInverted = IsPenInverted(wParam); + OutputDebug( L"WM_POINTERUPDATE: contact: %d button down: %d X: %d Y: %d\n", + IS_POINTER_INCONTACT_WPARAM(wParam), + penInverted, + GET_X_LPARAM(lParam), + GET_Y_LPARAM(lParam)); + if( penInverted != g_PenInverted) { + + g_PenInverted = penInverted; + if (g_PenInverted) { + if (PopDrawUndo(hdcScreenCompat, &drawUndoList, width, height)) { + + SaveCursorArea(hdcScreenCursorCompat, hdcScreenCompat, prevPt); + InvalidateRect(hWnd, NULL, FALSE); + } + } + } else if( g_PenDown && !penInverted) { + + SendPenMessage(hWnd, WM_MOUSEMOVE, lParam); + } + } + return TRUE; + + case WM_POINTERUP: + OutputDebug(L"WM_POINTERUP\n"); + penInverted = IsPenInverted(wParam); + if (!penInverted) { + + SendPenMessage(hWnd, WM_LBUTTONUP, lParam); + SendPenMessage(hWnd, WM_RBUTTONDOWN, lParam); + g_PenDown = FALSE; + } + break; + + case WM_POINTERDOWN: + OutputDebug(L"WM_POINTERDOWN\n"); + penInverted = IsPenInverted(wParam); + if (!penInverted) { + + g_PenDown = TRUE; + + // Enter drawing mode + SendPenMessage(hWnd, WM_LBUTTONDOWN, lParam); + SendPenMessage(hWnd, WM_MOUSEMOVE, lParam); + SendPenMessage(hWnd, WM_LBUTTONUP, lParam); + SendPenMessage(hWnd, WM_MOUSEMOVE, lParam); + PopDrawUndo(hdcScreenCompat, &drawUndoList, width, height); + + // Enter tracing mode + SendPenMessage(hWnd, WM_LBUTTONDOWN, lParam); + } + break; + + case WM_KILLFOCUS: + if( ( g_RecordCropping == FALSE ) && g_Zoomed && !g_bSaveInProgress ) { + + // Turn off zoom if not in liveDraw + DWORD layeringFlag; + GetLayeredWindowAttributes(hWnd, NULL, NULL, &layeringFlag); + if( !(layeringFlag & LWA_COLORKEY)) { + + PostMessage(hWnd, WM_HOTKEY, ZOOM_HOTKEY, 0); + } + } + break; + + case WM_MOUSEWHEEL: + + // + // Zoom or modify break timer + // + if( GET_WHEEL_DELTA_WPARAM(wParam) < 0 ) + wParam -= (WHEEL_DELTA-1) << 16; + else + wParam += (WHEEL_DELTA-1) << 16; + delta = GET_WHEEL_DELTA_WPARAM(wParam)/WHEEL_DELTA; + OutputDebug( L"mousewheel: wParam: %d delta: %d\n", + GET_WHEEL_DELTA_WPARAM(wParam), delta ); + if( g_Zoomed ) { + + if( g_TypeMode == TypeModeOff ) { + + if( g_Drawing && (LOWORD( wParam ) & MK_CONTROL) ) { + + ResizePen( hWnd, hdcScreenCompat, hdcScreenCursorCompat, prevPt, + g_Tracing, &g_Drawing, g_LiveZoomLevel, TRUE, g_PenWidth + delta ); + + // Perform static zoom unless in liveDraw + } else if( !( GetWindowLongPtr( hWnd, GWL_EXSTYLE ) & WS_EX_LAYERED ) ) { + + if( delta > 0 ) zoomIn = TRUE; + else { + zoomIn = FALSE; + delta = -delta; + } + while( delta-- ) { + + if( zoomIn ) { + + if( zoomTelescopeTarget < ZOOM_LEVEL_MAX ) { + + if( zoomTelescopeTarget < 2 ) { + + zoomTelescopeTarget = 2; + + } else { + + // Start telescoping zoom + zoomTelescopeTarget = zoomTelescopeTarget * 2; + } + zoomTelescopeStep = ZOOM_LEVEL_STEP_IN; + if( g_AnimateZoom ) + zoomLevel *= zoomTelescopeStep; + else + zoomLevel = zoomTelescopeTarget; + + if( zoomLevel > zoomTelescopeTarget ) + zoomLevel = zoomTelescopeTarget; + else + SetTimer( hWnd, 1, ZOOM_LEVEL_STEP_TIME, NULL ); + } + + } else if( zoomTelescopeTarget > ZOOM_LEVEL_MIN ) { + + // Let them more gradually zoom out from 2x to 1x + if( zoomTelescopeTarget <= 2 ) { + + zoomTelescopeTarget *= .75; + if( zoomTelescopeTarget < ZOOM_LEVEL_MIN ) + zoomTelescopeTarget = ZOOM_LEVEL_MIN; + + } else { + + zoomTelescopeTarget = zoomTelescopeTarget/2; + } + zoomTelescopeStep = ZOOM_LEVEL_STEP_OUT; + if( g_AnimateZoom ) + zoomLevel *= zoomTelescopeStep; + else + zoomLevel = zoomTelescopeTarget; + + if( zoomLevel < zoomTelescopeTarget ) + { + zoomLevel = zoomTelescopeTarget; + // Force update on final step out + InvalidateRect( hWnd, NULL, FALSE ); + } + else + { + SetTimer( hWnd, 1, ZOOM_LEVEL_STEP_TIME, NULL ); + } + } + } + if( zoomLevel != zoomTelescopeTarget ) { + + if( g_Drawing ) { + + if( !g_Tracing ) { + + RestoreCursorArea( hdcScreenCompat, hdcScreenCursorCompat, prevPt ); + } + //SetCursorPos( monInfo.rcMonitor.left + cursorPos.x, + // monInfo.rcMonitor.top + cursorPos.y ); + } + InvalidateRect( hWnd, NULL, FALSE ); + } + } + } else { + + // Resize the text font + if( (delta > 0 && g_FontScale > -20) || (delta < 0 && g_FontScale < 50 )) { + + ClearTypingCursor(hdcScreenCompat, hdcScreenCursorCompat, cursorRc, g_BlankedScreen); + + g_FontScale -= delta; + if( g_FontScale == 0 ) g_FontScale = 1; + // Set lParam to 0 as part of message to keyup hander + DeleteObject(hTypingFont); + g_LogFont.lfHeight = max((int)(height / zoomLevel) / g_FontScale, 12); + if (g_LogFont.lfHeight < 20) + g_LogFont.lfQuality = NONANTIALIASED_QUALITY; + else + g_LogFont.lfQuality = ANTIALIASED_QUALITY; + hTypingFont = CreateFontIndirect(&g_LogFont); + SelectObject(hdcScreenCompat, hTypingFont); + + DrawTypingCursor( hWnd, &textPt, hdcScreenCompat, hdcScreenCursorCompat, &cursorRc ); + } + } + } else if( g_TimerActive && (breakTimeout > 0 || delta )) { + + if( delta ) { + + if( breakTimeout < 0 ) breakTimeout = 0; + if( breakTimeout % 60 ) { + breakTimeout += (60 - breakTimeout % 60); + delta--; + } + breakTimeout += delta * 60; + + } else { + + if( breakTimeout % 60 ) { + breakTimeout -= breakTimeout % 60; + delta--; + } + breakTimeout -= delta * 60; + } + if( breakTimeout < 0 ) breakTimeout = 0; + KillTimer( hWnd, 0 ); + SetTimer( hWnd, 0, 1000, NULL ); + InvalidateRect( hWnd, NULL, TRUE ); + } + + if( zoomLevel != 1 && g_Drawing ) { + + // Constrain the mouse to the visible region + boundRc = BoundMouse( zoomTelescopeTarget, &monInfo, width, height, &cursorPos ); + + } else { + + ClipCursor( NULL ); + } + return TRUE; + + case WM_IME_CHAR: + case WM_CHAR: + + if( (g_TypeMode != TypeModeOff) && iswprint(static_cast(wParam)) || (static_cast(wParam) == L'&')) { + g_HaveTyped = TRUE; + + TCHAR vKey = static_cast(wParam); + + g_HaveDrawn = TRUE; + + // Clear typing cursor + rc.left = textPt.x; + rc.top = textPt.y; + ClearTypingCursor( hdcScreenCompat, hdcScreenCursorCompat, cursorRc, g_BlankedScreen ); + if (g_TypeMode == TypeModeRightJustify) { + + if( !g_TextBuffer.empty() || !g_TextBufferPreviousLines.empty() ) { + + PopDrawUndo(hdcScreenCompat, &drawUndoList, width, height); //*** + } + PushDrawUndo(hdcScreenCompat, &drawUndoList, width, height); + + // Restore previous lines. + wParam = 'X'; + DrawText(hdcScreenCompat, reinterpret_cast(&wParam), 1, &rc, DT_CALCRECT); + const auto lineHeight = rc.bottom - rc.top; + + rc.top -= static_cast< LONG >( g_TextBufferPreviousLines.size() ) * lineHeight; + + // Draw the current character on the current line. + g_TextBuffer += vKey; + drawAllRightJustifiedLines( lineHeight ); + } + else { + DrawText( hdcScreenCompat, &vKey, 1, &rc, DT_CALCRECT|DT_NOPREFIX); + DrawText( hdcScreenCompat, &vKey, 1, &rc, DT_LEFT|DT_NOPREFIX); + textPt.x += rc.right - rc.left; + } + InvalidateRect( hWnd, NULL, TRUE ); + + // Save the key for undo + P_TYPED_KEY newKey = static_cast(malloc( sizeof(TYPED_KEY) )); + newKey->rc = rc; + newKey->Next = typedKeyList; + typedKeyList = newKey; + + // Draw the typing cursor + DrawTypingCursor( hWnd, &textPt, hdcScreenCompat, hdcScreenCursorCompat, &cursorRc ); + return FALSE; + } + break; + + case WM_KEYUP: + if( wParam == 'T' && (g_TypeMode == TypeModeOff)) { + + // lParam is 0 when we're resizing the font and so don't have a cursor that + // we need to restore + if( !g_Drawing && lParam == 0 ) { + + OutputDebug(L"Entering typing mode and resetting cursor position\n"); + SendMessage( hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM( cursorPos.x, cursorPos.y)); + } + + // Do they want to right-justify text? + OutputDebug(L"Keyup Shift: %x\n", GetAsyncKeyState(VK_SHIFT)); + if(GetAsyncKeyState(VK_SHIFT) != 0 ) { + + g_TypeMode = TypeModeRightJustify; + g_TextBuffer.clear(); + + // Also empty all previous lines + g_TextBufferPreviousLines = {}; + } + else { + + g_TypeMode = TypeModeLeftJustify; + } + textStartPt = cursorPos; + textPt = prevPt; + + g_HaveTyped = FALSE; + + // Get a font of a decent size + DeleteObject( hTypingFont ); + g_LogFont.lfHeight = max( (int) (height / zoomLevel)/g_FontScale, 12 ); + if (g_LogFont.lfHeight < 20) + g_LogFont.lfQuality = NONANTIALIASED_QUALITY; + else + g_LogFont.lfQuality = ANTIALIASED_QUALITY; + hTypingFont = CreateFontIndirect( &g_LogFont ); + SelectObject( hdcScreenCompat, hTypingFont ); + + // If lparam == 0 that means that we sent the message as part of a font resize + if( g_Drawing && lParam != 0) { + + RestoreCursorArea( hdcScreenCompat, hdcScreenCursorCompat, prevPt ); + PushDrawUndo( hdcScreenCompat, &drawUndoList, width, height ); + + } else if( !g_Drawing ) { + + textPt = cursorPos; + } + + // Draw the typing cursor + DrawTypingCursor( hWnd, &textPt, hdcScreenCompat, hdcScreenCursorCompat, &cursorRc, true ); + prevPt = textPt; + } + break; + + case WM_KEYDOWN: + + if( (g_TypeMode != TypeModeOff) && g_HaveTyped && static_cast(wParam) != VK_UP && static_cast(wParam) != VK_DOWN && + (isprint( static_cast(wParam)) || + wParam == VK_RETURN || wParam == VK_DELETE || wParam == VK_BACK )) { + + if( wParam == VK_RETURN ) { + + // Clear the typing cursor + ClearTypingCursor( hdcScreenCompat, hdcScreenCursorCompat, cursorRc, g_BlankedScreen ); + + if( g_TypeMode == TypeModeRightJustify ) + { + g_TextBufferPreviousLines.push_back( g_TextBuffer ); + g_TextBuffer.clear(); + } + else + { + // Insert a fake return key in the list to undo. + P_TYPED_KEY newKey = static_cast(malloc(sizeof(TYPED_KEY))); + newKey->rc.left = textPt.x; + newKey->rc.top = textPt.y; + newKey->rc.right = newKey->rc.left; + newKey->rc.bottom = newKey->rc.top; + newKey->Next = typedKeyList; + typedKeyList = newKey; + } + + wParam = 'X'; + DrawText( hdcScreenCompat, reinterpret_cast(&wParam), 1, &rc, DT_CALCRECT ); + textPt.x = prevPt.x; // + g_PenWidth; + textPt.y += rc.bottom - rc.top; + + // Draw the typing cursor + DrawTypingCursor( hWnd, &textPt, hdcScreenCompat, hdcScreenCursorCompat, &cursorRc ); + } else if( wParam == VK_DELETE || wParam == VK_BACK ) { + + P_TYPED_KEY deletedKey = typedKeyList; + if( deletedKey ) { + + // Clear the typing cursor + ClearTypingCursor( hdcScreenCompat, hdcScreenCursorCompat, cursorRc, g_BlankedScreen ); + + if( g_TypeMode == TypeModeRightJustify ) { + + if( !g_TextBuffer.empty() || !g_TextBufferPreviousLines.empty() ) { + + PopDrawUndo( hdcScreenCompat, &drawUndoList, width, height ); + } + PushDrawUndo( hdcScreenCompat, &drawUndoList, width, height ); + + rc.left = textPt.x; + rc.top = textPt.y; + + // Restore the previous lines. + wParam = 'X'; + DrawText( hdcScreenCompat, reinterpret_cast(&wParam), 1, &rc, DT_CALCRECT ); + const auto lineHeight = rc.bottom - rc.top; + + const bool lineWasEmpty = g_TextBuffer.empty(); + drawAllRightJustifiedLines( lineHeight, true ); + if( lineWasEmpty && !g_TextBufferPreviousLines.empty() ) + { + g_TextBuffer = g_TextBufferPreviousLines.back(); + g_TextBufferPreviousLines.pop_back(); + textPt.y -= lineHeight; + } + } + else { + RECT rect = deletedKey->rc; + if (g_BlankedScreen) { + + BlankScreenArea(hdcScreenCompat, &rect, g_BlankedScreen); + } + else { + + BitBlt(hdcScreenCompat, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, hdcScreenSaveCompat, rect.left, rect.top, SRCCOPY | CAPTUREBLT ); + } + InvalidateRect( hWnd, NULL, FALSE ); + + textPt.x = rect.left; + textPt.y = rect.top; + + typedKeyList = deletedKey->Next; + free(deletedKey); + + // Refresh cursor if we deleted the last key + if( typedKeyList == NULL ) { + + SendMessage( hWnd, WM_MOUSEMOVE, 0, MAKELPARAM( prevPt.x, prevPt.y ) ); + } + } + DrawTypingCursor( hWnd, &textPt, hdcScreenCompat, hdcScreenCursorCompat, &cursorRc ); + } + } + break; + } + switch (wParam) { + case 'R': + case 'B': + case 'Y': + case 'O': + case 'G': + case 'X': + case 'P': + if( (g_Zoomed || g_TimerActive) && (g_TypeMode == TypeModeOff)) { + + PDWORD penColor; + if( g_TimerActive ) + penColor = &g_BreakPenColor; + else + penColor = &g_PenColor; + + if( wParam == 'R' ) *penColor = COLOR_RED; + else if( wParam == 'G' ) *penColor = COLOR_GREEN; + else if( wParam == 'B' ) *penColor = COLOR_BLUE; + else if( wParam == 'Y' ) *penColor = COLOR_YELLOW; + else if( wParam == 'O' ) *penColor = COLOR_ORANGE; + else if( wParam == 'P' ) *penColor = COLOR_PINK; + else if( wParam == 'X' ) + { + if( GetWindowLong( hWnd, GWL_EXSTYLE ) & WS_EX_LAYERED ) + { + // Blur is not supported in LiveDraw + break; + } + *penColor = COLOR_BLUR; + } + + bool shift = GetKeyState( VK_SHIFT ) & 0x8000; + if( shift && ( GetWindowLong( hWnd, GWL_EXSTYLE ) & WS_EX_LAYERED ) ) + { + // Highlight is not supported in LiveDraw + break; + } + + reg.WriteRegSettings( RegSettings ); + DeleteObject( hDrawingPen ); + SetTextColor( hdcScreenCompat, *penColor ); + + // Highlight and blur level + if( shift && *penColor != COLOR_BLUR ) + { + *penColor |= (g_AlphaBlend << 24); + } + else + { + if( *penColor == COLOR_BLUR ) + { + g_BlurRadius = shift ? STRONG_BLUR_RADIUS : NORMAL_BLUR_RADIUS; + } + *penColor |= (0xFF << 24); + } + hDrawingPen = CreatePen(PS_SOLID, g_PenWidth, *penColor & 0xFFFFFF); + + SelectObject( hdcScreenCompat, hDrawingPen ); + if( g_Drawing ) { + + SendMessage( hWnd, WM_MOUSEMOVE, 0, MAKELPARAM( prevPt.x, prevPt.y )); + + } else if( g_TimerActive ) { + + InvalidateRect( hWnd, NULL, FALSE ); + + } else if( g_TypeMode != TypeModeOff ) { + + ClearTypingCursor( hdcScreenCompat, hdcScreenCursorCompat, cursorRc, g_BlankedScreen ); + DrawTypingCursor( hWnd, &textPt, hdcScreenCompat, hdcScreenCursorCompat, &cursorRc ); + InvalidateRect( hWnd, NULL, FALSE ); + } + } + break; + + case 'Z': + if( (GetKeyState( VK_CONTROL ) & 0x8000 ) && g_HaveDrawn && !g_Tracing ) { + + if( PopDrawUndo( hdcScreenCompat, &drawUndoList, width, height )) { + + if( g_Drawing ) { + + SaveCursorArea( hdcScreenCursorCompat, hdcScreenCompat, prevPt ); + SendMessage( hWnd, WM_MOUSEMOVE, 0, MAKELPARAM( prevPt.x, prevPt.y )); + } + else { + + SaveCursorArea(hdcScreenCursorCompat, hdcScreenCompat, prevPt); + } + InvalidateRect( hWnd, NULL, FALSE ); + } + } + break; + + case VK_SPACE: + if( g_Drawing && !g_Tracing ) { + + SetCursorPos( boundRc.left + (boundRc.right - boundRc.left)/2, + boundRc.top + (boundRc.bottom - boundRc.top)/2 ); + SendMessage( hWnd, WM_MOUSEMOVE, 0, + MAKELPARAM( (boundRc.right - boundRc.left)/2, + (boundRc.bottom - boundRc.top)/2 )); + } + break; + + case 'W': + case 'K': + // Block user-driven sketch pad in liveDraw + if( lParam != LIVE_DRAW_ZOOM + && ( GetWindowLongPtr( hWnd, GWL_EXSTYLE ) & WS_EX_LAYERED ) ) + { + break; + } + + // Don't allow screen blanking while we've got the typing cursor active + // because we don't really handle going from white to black. + if( g_Zoomed && (g_TypeMode == TypeModeOff)) { + + if( !g_Drawing ) { + + SendMessage( hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM( cursorPos.x, cursorPos.y)); + } + // Restore area where cursor was previously + RestoreCursorArea( hdcScreenCompat, hdcScreenCursorCompat, prevPt ); + PushDrawUndo( hdcScreenCompat, &drawUndoList, width, height ); + g_BlankedScreen = static_cast(wParam); + rc.top = rc.left = 0; + rc.bottom = height; + rc.right = width; + BlankScreenArea( hdcScreenCompat, &rc, g_BlankedScreen ); + InvalidateRect( hWnd, NULL, FALSE ); + + // Save area that's going to be occupied by new cursor position + SaveCursorArea( hdcScreenCursorCompat, hdcScreenCompat, prevPt ); + SendMessage( hWnd, WM_MOUSEMOVE, 0, MAKELPARAM( prevPt.x, prevPt.y )); + } + break; + + case 'E': + // Don't allow erase while we have the typing cursor active + if( g_HaveDrawn && (g_TypeMode == TypeModeOff)) { + + DeleteDrawUndoList( &drawUndoList ); + g_HaveDrawn = FALSE; + OutputDebug(L"Erase\n"); + if(GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_LAYERED) { + SendMessage(hWnd, WM_KEYDOWN, 'K', 0); + } + else { + BitBlt(hdcScreenCompat, 0, 0, bmp.bmWidth, + bmp.bmHeight, hdcScreenSaveCompat, 0, 0, SRCCOPY | CAPTUREBLT); + + if (g_Drawing) { + + OutputDebug(L"Erase: draw cursor\n"); + SaveCursorArea(hdcScreenCursorCompat, hdcScreenCompat, prevPt); + DrawCursor(hdcScreenCompat, prevPt, zoomLevel, width, height); + g_HaveDrawn = TRUE; + } + } + InvalidateRect( hWnd, NULL, FALSE ); + g_BlankedScreen = FALSE; + } + break; + + case VK_UP: + SendMessage( hWnd, WM_MOUSEWHEEL, + MAKEWPARAM( GetAsyncKeyState( VK_LCONTROL ) != 0 || GetAsyncKeyState( VK_RCONTROL ) != 0 ? + MK_CONTROL: 0, WHEEL_DELTA), 0 ); + return TRUE; + + case VK_DOWN: + SendMessage( hWnd, WM_MOUSEWHEEL, + MAKEWPARAM( GetAsyncKeyState( VK_LCONTROL ) != 0 || GetAsyncKeyState( VK_RCONTROL ) != 0 ? + MK_CONTROL: 0, -WHEEL_DELTA), 0 ); + return TRUE; + + case VK_LEFT: + case VK_RIGHT: + if( wParam == VK_RIGHT ) delta = 10; + else delta = -10; + if( g_TimerActive && (breakTimeout > 0 || delta )) { + + if( breakTimeout < 0 ) breakTimeout = 0; + breakTimeout += delta; + breakTimeout -= (breakTimeout % 10); + if( breakTimeout < 0 ) breakTimeout = 0; + KillTimer( hWnd, 0 ); + SetTimer( hWnd, 0, 1000, NULL ); + InvalidateRect( hWnd, NULL, TRUE ); + } + break; + + case VK_ESCAPE: + if( g_TypeMode != TypeModeOff) { + + // Turn off + SendMessage( hWnd, WM_USER_TYPING_OFF, 0, 0 ); + + } else { + + forcePenResize = TRUE; + PostMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, 0 ); + + // In case we were in liveDraw + if( GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_LAYERED) { + + KillTimer(hWnd, 3); + LONG_PTR exStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE); + SetWindowLongPtr(hWnd, GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED); + pMagSetWindowFilterList( g_hWndLiveZoomMag, MW_FILTERMODE_EXCLUDE, 1, &hWnd ); + SendMessage( g_hWndLiveZoom, WM_USER_MAGNIFY_CURSOR, TRUE, 0 ); + } + } + break; + } + return TRUE; + + case WM_RBUTTONDOWN: + SendMessage( hWnd, WM_USER_EXIT_MODE, 0, 0 ); + break; + + case WM_MOUSEMOVE: + OutputDebug(L"MOUSEMOVE: zoomed: %d drawing: %d tracing: %d\n", + g_Zoomed, g_Drawing, g_Tracing); + + OutputDebug(L"Window visible: %d Topmost: %d\n", IsWindowVisible(hWnd), GetWindowLong(hWnd, GWL_EXSTYLE)& WS_EX_TOPMOST); + + if( g_Zoomed && (g_TypeMode == TypeModeOff) && !g_bSaveInProgress ) { + + if( g_Drawing ) { + + POINT currentPt; + + // Are we in pen mode on a tablet? + lParam = ScalePenPosition( zoomLevel, &monInfo, boundRc, message, lParam); + currentPt.x = LOWORD(lParam); + currentPt.y = HIWORD(lParam); + + if(lParam == 0) { + + // Drop it + OutputDebug(L"Mousemove: Dropping\n"); + break; + + } else if(g_DrawingShape) { + + SetROP2(hdcScreenCompat, R2_NOTXORPEN); + + // If a previous target rectangle exists, erase + // it by drawing another rectangle on top. + if( g_rcRectangle.top != g_rcRectangle.bottom || + g_rcRectangle.left != g_rcRectangle.right ) + { + if( prevPenWidth != g_PenWidth ) + { + auto penWidth = g_PenWidth; + g_PenWidth = prevPenWidth; + + auto prevPen = CreatePen( PS_SOLID, g_PenWidth, g_PenColor & 0xFFFFFF ); + SelectObject( hdcScreenCompat, prevPen ); + + DrawShape( g_DrawingShape, hdcScreenCompat, &g_rcRectangle ); + + g_PenWidth = penWidth; + SelectObject( hdcScreenCompat, hDrawingPen ); + DeleteObject( prevPen ); + } + else + { + DrawShape( g_DrawingShape, hdcScreenCompat, &g_rcRectangle ); + } + } + + // Save the coordinates of the target rectangle. + // Avoid invalid rectangles by ensuring that the + // value of the left coordinate is greater than + // that of the right, and that the value of the + // bottom coordinate is greater than that of + // the top. + if( g_DrawingShape == DRAW_LINE || + g_DrawingShape == DRAW_ARROW ) { + + g_rcRectangle.right = static_cast(LOWORD(lParam)); + g_rcRectangle.bottom = static_cast(HIWORD(lParam)); + + } else { + + if ((g_RectangleAnchor.x < currentPt.x) && + (g_RectangleAnchor.y > currentPt.y)) { + + SetRect(&g_rcRectangle, g_RectangleAnchor.x, currentPt.y, + currentPt.x, g_RectangleAnchor.y); + + } else if ((g_RectangleAnchor.x > currentPt.x) && + (g_RectangleAnchor.y > currentPt.y )) { + + SetRect(&g_rcRectangle, currentPt.x, + currentPt.y, g_RectangleAnchor.x,g_RectangleAnchor.y); + + } else if ((g_RectangleAnchor.x > currentPt.x) && + (g_RectangleAnchor.y < currentPt.y )) { + + SetRect(&g_rcRectangle, currentPt.x, g_RectangleAnchor.y, + g_RectangleAnchor.x, currentPt.y ); + } else { + + SetRect(&g_rcRectangle, g_RectangleAnchor.x, g_RectangleAnchor.y, + currentPt.x, currentPt.y ); + } + } + + if (g_rcRectangle.left != g_rcRectangle.right || + g_rcRectangle.top != g_rcRectangle.bottom) { + + // Draw the new target rectangle. + DrawShape(g_DrawingShape, hdcScreenCompat, &g_rcRectangle); + OutputDebug(L"SHAPE: (%d, %d) - (%d, %d)\n", g_rcRectangle.left, g_rcRectangle.top, + g_rcRectangle.right, g_rcRectangle.bottom); + } + + prevPenWidth = g_PenWidth; + SetROP2( hdcScreenCompat, R2_NOP ); + } + else if (g_Tracing) { + + OutputDebug(L"Mousemove: Tracing\n"); + + g_HaveDrawn = TRUE; + Gdiplus::Graphics dstGraphics(hdcScreenCompat); + if( ( GetWindowLong( g_hWndMain, GWL_EXSTYLE ) & WS_EX_LAYERED ) == 0 ) + { + dstGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); + } + Gdiplus::Color color = ColorFromColorRef(g_PenColor); + Gdiplus::Pen pen(color, static_cast(g_PenWidth)); + pen.SetLineCap(Gdiplus::LineCapRound, Gdiplus::LineCapRound, Gdiplus::DashCapRound); + + // If highlighting, use a double layer approach + OutputDebug(L"PenColor: %x\n", g_PenColor); + OutputDebug(L"Blur color: %x\n", COLOR_BLUR); + if( (g_PenColor & 0xFFFFFF) == COLOR_BLUR) { + + OutputDebug(L"BLUR\n"); + + // Restore area where cursor was previously + RestoreCursorArea(hdcScreenCompat, hdcScreenCursorCompat, prevPt); + + // Create a new bitmap that's the size of the area covered by the line + 2 * g_PenWidth + Gdiplus::Rect lineBounds = GetLineBounds( prevPt, currentPt, g_PenWidth ); + Gdiplus::Bitmap* lineBitmap = DrawBitmapLine(lineBounds, prevPt, currentPt, &pen); + Gdiplus::BitmapData* lineData = LockGdiPlusBitmap(lineBitmap); + BYTE* pPixels = static_cast(lineData->Scan0); + + // Copy the contents of the screen bitmap to the temporary bitmap + GetOldestUndo(drawUndoList); + + // Create a GDI bitmap that's the size of the lineBounds rectangle + Gdiplus::Bitmap *blurBitmap = CreateGdiplusBitmap( hdcScreenCompat, // oldestUndo->hDc, + lineBounds.X, lineBounds.Y, lineBounds.Width, lineBounds.Height); + + // Blur it + BitmapBlur(blurBitmap); + BlurScreen(hdcScreenCompat, &lineBounds, blurBitmap, pPixels); + + // Unlock the bits + lineBitmap->UnlockBits(lineData); + delete lineBitmap; + delete blurBitmap; + + // Invalidate the updated rectangle + InvalidateGdiplusRect( hWnd, lineBounds ); + + // Save area that's going to be occupied by new cursor position + SaveCursorArea(hdcScreenCursorCompat, hdcScreenCompat, currentPt); + + // Draw new cursor + DrawCursor(hdcScreenCompat, currentPt, zoomLevel, width, height); + } + else if(PEN_COLOR_HIGHLIGHT(g_PenColor)) { + + // This is a highlighting pen color + Gdiplus::Rect lineBounds = GetLineBounds(prevPt, currentPt, g_PenWidth); + Gdiplus::Bitmap* lineBitmap = DrawBitmapLine(lineBounds, prevPt, currentPt, &pen); + Gdiplus::BitmapData* lineData = LockGdiPlusBitmap(lineBitmap); + BYTE* pPixels = static_cast(lineData->Scan0); + + // Create a DIB section for efficient pixel manipulation + BITMAPINFO bmi = { 0 }; + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = lineBounds.Width; + bmi.bmiHeader.biHeight = -lineBounds.Height; // Top-down DIB + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; // 32 bits per pixel + bmi.bmiHeader.biCompression = BI_RGB; + + VOID* pDIBBits; + HBITMAP hDIB = CreateDIBSection(hdcScreenCompat, &bmi, DIB_RGB_COLORS, &pDIBBits, NULL, 0); + + HDC hdcDIB = CreateCompatibleDC(hdcScreenCompat); + SelectObject(hdcDIB, hDIB); + + // Copy the relevant part of hdcScreenCompat to the DIB + BitBlt(hdcDIB, 0, 0, lineBounds.Width, lineBounds.Height, hdcScreenCompat, lineBounds.X, lineBounds.Y, SRCCOPY); + + // Pointer to the DIB bits + BYTE* pDestPixels = static_cast(pDIBBits); + + // Pointer to screen bits + HDC hdcDIBOrig; + HBITMAP hDibOrigBitmap, hDibBitmap; + P_DRAW_UNDO oldestUndo = GetOldestUndo(drawUndoList); + BYTE* pDestPixels2 = CreateBitmapMemoryDIB(hdcScreenCompat, oldestUndo->hDc, &lineBounds, + &hdcDIBOrig, &hDibBitmap, &hDibOrigBitmap); + + for (int local_y = 0; local_y < lineBounds.Height; ++local_y) { + for (int local_x = 0; local_x < lineBounds.Width; ++local_x) { + int index = (local_y * lineBounds.Width * 4) + (local_x * 4); // Assuming 4 bytes per pixel + // BYTE b = pPixels[index + 0]; // Blue channel + // BYTE g = pPixels[index + 1]; // Green channel + // BYTE r = pPixels[index + 2]; // Red channel + BYTE a = pPixels[index + 3]; // Alpha channel + + // Check if this is a drawn pixel + if (a != 0) { + // Assuming pDestPixels is a valid pointer to the destination bitmap's pixel data + BYTE destB = pDestPixels2[index + 0]; // Blue channel + BYTE destG = pDestPixels2[index + 1]; // Green channel + BYTE destR = pDestPixels2[index + 2]; // Red channel + + // Create a COLORREF value from the destination pixel data + COLORREF currentPixel = RGB(destR, destG, destB); + // Blend the colors + COLORREF newPixel = BlendColors(currentPixel, g_PenColor); + // Update the destination pixel data with the new color + pDestPixels[index + 0] = GetBValue(newPixel); + pDestPixels[index + 1] = GetGValue(newPixel); + pDestPixels[index + 2] = GetRValue(newPixel); + } + } + } + + // Copy the updated DIB back to hdcScreenCompat + BitBlt(hdcScreenCompat, lineBounds.X, lineBounds.Y, lineBounds.Width, lineBounds.Height, hdcDIB, 0, 0, SRCCOPY); + + // Clean up + DeleteObject(hDIB); + DeleteDC(hdcDIB); + + SelectObject(hdcDIBOrig, hDibOrigBitmap); + DeleteObject(hDibBitmap); + DeleteDC(hdcDIBOrig); + + // Invalidate the updated rectangle + InvalidateGdiplusRect(hWnd, lineBounds); + } + else { + + // Normal tracing + dstGraphics.DrawLine(&pen, static_cast(prevPt.x), static_cast(prevPt.y), + static_cast(currentPt.x), static_cast(currentPt.y)); + } + + } else { + + OutputDebug(L"Mousemove: Moving cursor\n"); + + // Restore area where cursor was previously + RestoreCursorArea( hdcScreenCompat, hdcScreenCursorCompat, prevPt ); + + // Save area that's going to be occupied by new cursor position + SaveCursorArea( hdcScreenCursorCompat, hdcScreenCompat, currentPt ); + + // Draw new cursor + DrawCursor( hdcScreenCompat, currentPt, zoomLevel, width, height ); + } + + if( g_DrawingShape ) { + + InvalidateRect( hWnd, NULL, FALSE ); + + } else { + + // Invalidate area just modified + InvalidateCursorMoveArea( hWnd, zoomLevel, width, height, currentPt, prevPt, cursorPos ); + } + prevPt = currentPt; + + // In liveDraw we an miss the mouse up + if( GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_LAYERED) { + + if((GetAsyncKeyState(VK_LBUTTON) & 0x8000) == 0) { + + OutputDebug(L"LIVE_DRAW missed mouse up. Sending synthetic.\n"); + SendMessage(hWnd, WM_LBUTTONUP, wParam, lParam); + } + } + + } else { + + cursorPos.x = LOWORD( lParam ); + cursorPos.y = HIWORD( lParam ); + InvalidateRect( hWnd, NULL, FALSE ); + } + } else if( g_Zoomed && (g_TypeMode != TypeModeOff) && !g_HaveTyped ) { + + ClearTypingCursor( hdcScreenCompat, hdcScreenCursorCompat, cursorRc, g_BlankedScreen ); + textPt.x = prevPt.x = LOWORD( lParam ); + textPt.y = prevPt.y = HIWORD( lParam ); + + // Draw the typing cursor + DrawTypingCursor( hWnd, &textPt, hdcScreenCompat, hdcScreenCursorCompat, &cursorRc, true ); + prevPt = textPt; + InvalidateRect( hWnd, NULL, FALSE ); + } +#if 0 + { + static int index = 0; + OutputDebug( L"%d: foreground: %x focus: %x (hwnd: %x)\n", + index++, (DWORD) PtrToUlong(GetForegroundWindow()), PtrToUlong(GetFocus()), PtrToUlong(hWnd)); + } +#endif + return TRUE; + + case WM_LBUTTONDOWN: + g_StraightDirection = 0; + + if( g_Zoomed && (g_TypeMode == TypeModeOff) && zoomTelescopeTarget == zoomLevel ) { + + OutputDebug(L"LBUTTONDOWN: drawing\n"); + + // Save current bitmap to undo history + if( g_HaveDrawn ) { + + RestoreCursorArea( hdcScreenCompat, hdcScreenCursorCompat, prevPt ); + } + + // don't push undo if we sent this to ourselves for a pen resize + if( wParam != -1 ) { + + PushDrawUndo( hdcScreenCompat, &drawUndoList, width, height ); + + } else { + + wParam = 0; + } + + // Are we in pen mode on a tablet? + lParam = ScalePenPosition( zoomLevel, &monInfo, boundRc, + message, lParam); + + if (lParam == 0) { + + // Drop it + break; + + } else if( g_Drawing ) { + + // is the user drawing a rectangle? + if( wParam & MK_CONTROL || + wParam & MK_SHIFT || + GetKeyState( VK_TAB ) < 0 ) { + + // Restore area where cursor was previously + RestoreCursorArea( hdcScreenCompat, hdcScreenCursorCompat, prevPt ); + + if( wParam & MK_SHIFT && wParam & MK_CONTROL ) + g_DrawingShape = DRAW_ARROW; + else if( wParam & MK_CONTROL ) + g_DrawingShape = DRAW_RECTANGLE; + else if( wParam & MK_SHIFT ) + g_DrawingShape = DRAW_LINE; + else + g_DrawingShape = DRAW_ELLIPSE; + g_RectangleAnchor.x = LOWORD(lParam); + g_RectangleAnchor.y = HIWORD(lParam); + SetRect(&g_rcRectangle, g_RectangleAnchor.x, g_RectangleAnchor.y, + g_RectangleAnchor.x, g_RectangleAnchor.y); + + } else { + + Gdiplus::Graphics dstGraphics(hdcScreenCompat); + if( ( GetWindowLong( g_hWndMain, GWL_EXSTYLE ) & WS_EX_LAYERED ) == 0 ) + { + dstGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); + } + Gdiplus::Color color = ColorFromColorRef(g_PenColor); + Gdiplus::Pen pen(color, static_cast(g_PenWidth)); + Gdiplus::GraphicsPath path; + pen.SetLineJoin(Gdiplus::LineJoinRound); + path.AddLine(static_cast(prevPt.x), prevPt.y, prevPt.x, prevPt.y); + dstGraphics.DrawPath(&pen, &path); + } + g_Tracing = TRUE; + SetROP2( hdcScreenCompat, R2_COPYPEN ); + prevPt.x = LOWORD(lParam); + prevPt.y = HIWORD(lParam); + g_HaveDrawn = TRUE; + + } else { + + OutputDebug(L"Tracing on\n"); + + // Turn on drawing + if( !g_HaveDrawn ) { + + // refresh drawing bitmap with original screen image + BitBlt(hdcScreenCompat, 0, 0, bmp.bmWidth, + bmp.bmHeight, hdcScreenSaveCompat, 0, 0, SRCCOPY|CAPTUREBLT ); + g_HaveDrawn = TRUE; + } + DeleteObject( hDrawingPen ); + hDrawingPen = CreatePen(PS_SOLID, g_PenWidth, g_PenColor & 0xFFFFFF); + SelectObject( hdcScreenCompat, hDrawingPen ); + + // is the user drawing a rectangle? + if( wParam & MK_CONTROL && g_Drawing ) { + + // Restore area where cursor was previously + RestoreCursorArea( hdcScreenCompat, hdcScreenCursorCompat, prevPt ); + + // Configure rectangle drawing + g_DrawingShape = TRUE; + g_RectangleAnchor.x = LOWORD(lParam); + g_RectangleAnchor.y = HIWORD(lParam); + SetRect(&g_rcRectangle, g_RectangleAnchor.x, g_RectangleAnchor.y, + g_RectangleAnchor.x, g_RectangleAnchor.y); + OutputDebug( L"RECTANGLE: %d, %d\n", prevPt.x, prevPt.y ); + + } else { + + prevPt.x = LOWORD( lParam ); + prevPt.y = HIWORD( lParam ); + SaveCursorArea( hdcScreenCursorCompat, hdcScreenCompat, prevPt ); + + Gdiplus::Graphics dstGraphics(hdcScreenCursorCompat); + if( ( GetWindowLong( g_hWndMain, GWL_EXSTYLE ) & WS_EX_LAYERED ) == 0 ) + { + dstGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); + } + Gdiplus::Color color = ColorFromColorRef(g_PenColor); + Gdiplus::Pen pen(color, static_cast(g_PenWidth)); + Gdiplus::GraphicsPath path; + pen.SetLineJoin(Gdiplus::LineJoinRound); + path.AddLine(static_cast(prevPt.x), prevPt.y, prevPt.x, prevPt.y); + dstGraphics.DrawPath(&pen, &path); + } + InvalidateRect( hWnd, NULL, FALSE ); + + // If we're in live zoom, make the drawing pen larger to compensate + if( g_ZoomOnLiveZoom && forcePenResize ) + { + forcePenResize = FALSE; + + ResizePen( hWnd, hdcScreenCompat, hdcScreenCursorCompat, prevPt, g_Tracing, + &g_Drawing, g_LiveZoomLevel, FALSE, min( static_cast(g_LiveZoomLevel * g_RootPenWidth), + static_cast(g_LiveZoomLevel * MAX_PEN_WIDTH) ) ); + OutputDebug( L"LIVEZOOM_DRAW: zoomLevel: %d rootPenWidth: %d penWidth: %d\n", + static_cast(g_LiveZoomLevel), g_RootPenWidth, g_PenWidth ); + } + else if( !g_ZoomOnLiveZoom && forcePenResize ) + { + forcePenResize = FALSE; + // Scale pen down to root for regular drawing mode + ResizePen( hWnd, hdcScreenCompat, hdcScreenCursorCompat, prevPt, g_Tracing, + &g_Drawing, g_LiveZoomLevel, FALSE, g_RootPenWidth ); + } + g_Drawing = TRUE; + + EnableDisableStickyKeys( FALSE ); + OutputDebug( L"LBUTTONDOWN: %d, %d\n", prevPt.x, prevPt.y ); + + // Constrain the mouse to the visible region + boundRc = BoundMouse( zoomLevel, &monInfo, width, height, &cursorPos ); + } + } else if( g_TypeMode != TypeModeOff ) { + + if( !g_HaveTyped ) { + + g_HaveTyped = TRUE; + + } else { + + SendMessage( hWnd, WM_USER_TYPING_OFF, 0, 0 ); + } + } + return TRUE; + + case WM_LBUTTONUP: + OutputDebug(L"LBUTTONUP: zoomed: %d drawing: %d tracing: %d\n", + g_Zoomed, g_Drawing, g_Tracing); + + if( g_Zoomed && g_Drawing && g_Tracing ) { + + // Are we in pen mode on a tablet? + lParam = ScalePenPosition( zoomLevel, &monInfo, boundRc, + message, lParam); + OutputDebug(L"LBUTTONUP: %d, %d\n", LOWORD(lParam), HIWORD(lParam)); + if (lParam == 0) { + + // Drop it + break; + } + + POINT adjustPos; + adjustPos.x = LOWORD(lParam); + adjustPos.y = HIWORD(lParam); + if( g_StraightDirection == -1 ) { + + adjustPos.x = prevPt.x; + + } else { + + adjustPos.y = prevPt.y; + } + lParam = MAKELPARAM( adjustPos.x, adjustPos.y ); + + if( !g_DrawingShape ) { + + Gdiplus::Graphics dstGraphics(hdcScreenCompat); + if( ( GetWindowLong( g_hWndMain, GWL_EXSTYLE ) & WS_EX_LAYERED ) == 0 ) + { + dstGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); + } + Gdiplus::Color color = ColorFromColorRef(g_PenColor); + Gdiplus::Pen pen(color, static_cast(g_PenWidth)); + Gdiplus::GraphicsPath path; + pen.SetLineJoin(Gdiplus::LineJoinRound); + path.AddLine(prevPt.x, prevPt.y, LOWORD(lParam), HIWORD(lParam)); + dstGraphics.DrawPath(&pen, &path); + + prevPt.x = LOWORD( lParam ); + prevPt.y = HIWORD( lParam ); + + if ((g_PenColor & 0xFFFFFF) == COLOR_BLUR) { + + RestoreCursorArea(hdcScreenCompat, hdcScreenCursorCompat, prevPt); + } + SaveCursorArea( hdcScreenCursorCompat, hdcScreenCompat, prevPt ); + DrawCursor( hdcScreenCompat, prevPt, zoomLevel, width, height ); + + } else if (g_rcRectangle.top != g_rcRectangle.bottom || + g_rcRectangle.left != g_rcRectangle.right ) { + + // erase previous + SetROP2(hdcScreenCompat, R2_NOTXORPEN); + DrawShape( g_DrawingShape, hdcScreenCompat, &g_rcRectangle ); + + // Draw the final shape + HBRUSH hBrush = static_cast(GetStockObject( NULL_BRUSH )); + HBRUSH oldHbrush = static_cast(SelectObject( hdcScreenCompat, hBrush )); + SetROP2( hdcScreenCompat, R2_COPYPEN ); + + // smooth line + if( g_SnapToGrid ) { + + if( g_DrawingShape == DRAW_LINE || + g_DrawingShape == DRAW_ARROW ) { + + if( abs(g_rcRectangle.bottom - g_rcRectangle.top) < + abs(g_rcRectangle.right - g_rcRectangle.left)/10 ) { + + g_rcRectangle.bottom = g_rcRectangle.top-1; + } + if( abs(g_rcRectangle.right - g_rcRectangle.left) < + abs(g_rcRectangle.bottom - g_rcRectangle.top)/10 ) { + + g_rcRectangle.right = g_rcRectangle.left-1; + } + } + } + // Draw final one using Gdi+ + DrawShape( g_DrawingShape, hdcScreenCompat, &g_rcRectangle, true ); + + InvalidateRect( hWnd, NULL, FALSE ); + DeleteObject( hBrush ); + SelectObject( hdcScreenCompat, oldHbrush ); + + prevPt.x = LOWORD( lParam ); + prevPt.y = HIWORD( lParam ); + SaveCursorArea( hdcScreenCursorCompat, hdcScreenCompat, prevPt ); + } + g_Tracing = FALSE; + g_DrawingShape = FALSE; + OutputDebug( L"LBUTTONUP:" ); + } + return TRUE; + + case WM_GETMINMAXINFO: + + reinterpret_cast(lParam)->ptMaxSize.x = width; + reinterpret_cast(lParam)->ptMaxSize.y = height; + reinterpret_cast(lParam)->ptMaxPosition.x = 0; + reinterpret_cast(lParam)->ptMaxPosition.y = 0; + return TRUE; + + case WM_USER_TYPING_OFF: { + + if( g_TypeMode != TypeModeOff ) { + + g_TypeMode = TypeModeOff; + ClearTypingCursor( hdcScreenCompat, hdcScreenCursorCompat, cursorRc, g_BlankedScreen ); + InvalidateRect( hWnd, NULL, FALSE ); + DeleteTypedText( &typedKeyList ); + + // 1 means don't reset the cursor. We get that for font resizing + // Only move the cursor if we're drawing, because otherwise the screen moves to center + // on the new cursor position + if( wParam != 1 && g_Drawing ) { + + prevPt.x = cursorRc.left; + prevPt.y = cursorRc.top; + SetCursorPos( monInfo.rcMonitor.left + prevPt.x, + monInfo.rcMonitor.top + prevPt.y ); + + SaveCursorArea( hdcScreenCursorCompat, hdcScreenCompat, prevPt ); + SendMessage( hWnd, WM_MOUSEMOVE, 0, MAKELPARAM( prevPt.x, prevPt.y )); + + } else if( !g_Drawing) { + + // FIX: would be nice to reset cursor so screen doesn't move + prevPt = textStartPt; + SaveCursorArea( hdcScreenCursorCompat, hdcScreenCompat, prevPt ); + SetCursorPos( prevPt.x, prevPt.y ); + SendMessage( hWnd, WM_MOUSEMOVE, 0, MAKELPARAM( prevPt.x, prevPt.y )); + } + } + } + return TRUE; + + case WM_USER_TRAY_ACTIVATE: + + switch( lParam ) { + case WM_RBUTTONUP: + case WM_LBUTTONUP: + case WM_CONTEXTMENU: + { + // Set the foreground window so the menu can be closed by clicking elsewhere when + // opened via right click, and so keyboard navigation works when opened with the menu + // key or Shift-F10. + SetForegroundWindow( hWndOptions ? hWndOptions : hWnd ); + + // Pop up context menu + POINT pt; + GetCursorPos( &pt ); + hPopupMenu = CreatePopupMenu(); + if(!g_StartedByPowerToys) { + // Exiting will happen through disabling in PowerToys, not the context menu. + InsertMenu( hPopupMenu, 0, MF_BYPOSITION, IDCANCEL, L"E&xit" ); + InsertMenu( hPopupMenu, 0, MF_BYPOSITION|MF_SEPARATOR, 0, NULL ); + } + InsertMenu( hPopupMenu, 0, MF_BYPOSITION | ( g_RecordToggle ? MF_CHECKED : 0 ), IDC_RECORD, L"&Record" ); + InsertMenu( hPopupMenu, 0, MF_BYPOSITION, IDC_ZOOM, L"&Zoom" ); + InsertMenu( hPopupMenu, 0, MF_BYPOSITION, IDC_DRAW, L"&Draw" ); + InsertMenu( hPopupMenu, 0, MF_BYPOSITION, IDC_BREAK, L"&Break Timer" ); + if(!g_StartedByPowerToys) { + // When started by PowerToys, options are configured through the PowerToys Settings. + InsertMenu( hPopupMenu, 0, MF_BYPOSITION|MF_SEPARATOR, 0, NULL ); + InsertMenu( hPopupMenu, 0, MF_BYPOSITION, IDC_OPTIONS, L"&Options" ); + } + TrackPopupMenu( hPopupMenu, 0, pt.x , pt.y, 0, hWnd, NULL ); + DestroyMenu( hPopupMenu ); + break; + } + case WM_LBUTTONDBLCLK: + if( !g_TimerActive ) { + + SendMessage( hWnd, WM_COMMAND, IDC_OPTIONS, 0 ); + + } else { + + SetForegroundWindow( hWnd ); + } + break; + } + break; + + case WM_USER_STOP_RECORDING: + StopRecording(); + break; + + case WM_USER_SAVE_CURSOR: + if( g_Zoomed == TRUE ) + { + GetCursorPos( &savedCursorPos ); + if( g_Drawing == TRUE ) + { + ClipCursor( NULL ); + } + } + break; + + case WM_USER_RESTORE_CURSOR: + if( g_Zoomed == TRUE ) + { + if( g_Drawing == TRUE ) + { + boundRc = BoundMouse( zoomLevel, &monInfo, width, height, &cursorPos ); + } + SetCursorPos( savedCursorPos.x, savedCursorPos.y ); + } + break; + + case WM_USER_EXIT_MODE: + if( g_Zoomed ) + { + // Turn off + if( g_TypeMode != TypeModeOff ) + { + SendMessage( hWnd, WM_USER_TYPING_OFF, 0, 0 ); + } + else if( !g_Drawing ) + { + // Turn off + PostMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, 0 ); + } + else + { + if( !g_Tracing ) + { + RestoreCursorArea( hdcScreenCompat, hdcScreenCursorCompat, prevPt ); + + // Ensure the cursor area is painted before returning + InvalidateRect( hWnd, NULL, FALSE ); + UpdateWindow( hWnd ); + + // Make the magnified cursor visible again if LiveDraw is on in LiveZoom + if( GetWindowLong( hWnd, GWL_EXSTYLE ) & WS_EX_LAYERED ) + { + if( IsWindowVisible( g_hWndLiveZoom ) ) + { + SendMessage( g_hWndLiveZoom, WM_USER_MAGNIFY_CURSOR, TRUE, 0 ); + } + } + } + if( zoomLevel != 1 ) + { + // Restore the cursor position to prevent moving the view in static zoom + SetCursorPos( monInfo.rcMonitor.left + cursorPos.x, monInfo.rcMonitor.top + cursorPos.y ); + } + g_Drawing = FALSE; + g_Tracing = FALSE; + EnableDisableStickyKeys( TRUE ); + SendMessage( hWnd, WM_USER_TYPING_OFF, 0, 0 ); + + // Unclip cursor + ClipCursor( NULL ); + } + } + else if( g_TimerActive ) + { + // Turn off + PostMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, 0 ); + } + break; + + case WM_USER_RELOAD_SETTINGS: + { + // Reload the settings. This message is called from PowerToys after a setting is changed by the user. + reg.ReadRegSettings(RegSettings); + + // Apply tray icon setting + EnableDisableTrayIcon(hWnd, g_ShowTrayIcon); + + // Apply hotkey settings + UnregisterAllHotkeys(hWnd); + g_ToggleMod = GetKeyMod(g_ToggleKey); + g_LiveZoomToggleMod = GetKeyMod(g_LiveZoomToggleKey); + g_DrawToggleMod = GetKeyMod(g_DrawToggleKey); + g_BreakToggleMod = GetKeyMod(g_BreakToggleKey); + g_DemoTypeToggleMod = GetKeyMod(g_DemoTypeToggleKey); + g_SnipToggleMod = GetKeyMod(g_SnipToggleKey); + g_RecordToggleMod = GetKeyMod(g_RecordToggleKey); + BOOL showOptions = FALSE; + if (g_ToggleKey) + { + if (!RegisterHotKey(hWnd, ZOOM_HOTKEY, g_ToggleMod, g_ToggleKey & 0xFF)) + { + MessageBox(hWnd, L"The specified zoom toggle hotkey is already in use.\nSelect a different zoom toggle hotkey.", APPNAME, MB_ICONERROR); + showOptions = TRUE; + } + } + if (g_LiveZoomToggleKey) + { + if (!RegisterHotKey(hWnd, LIVE_HOTKEY, g_LiveZoomToggleMod, g_LiveZoomToggleKey & 0xFF) || + !RegisterHotKey(hWnd, LIVE_DRAW_HOTKEY, g_LiveZoomToggleMod ^ MOD_SHIFT, g_LiveZoomToggleKey & 0xFF)) + { + MessageBox(hWnd, L"The specified live-zoom toggle hotkey is already in use.\nSelect a different zoom toggle hotkey.", APPNAME, MB_ICONERROR); + showOptions = TRUE; + } + } + if (g_DrawToggleKey) + { + if (!RegisterHotKey(hWnd, DRAW_HOTKEY, g_DrawToggleMod, g_DrawToggleKey & 0xFF)) + { + MessageBox(hWnd, L"The specified draw w/out zoom hotkey is already in use.\nSelect a different draw w/out zoom hotkey.", APPNAME, MB_ICONERROR); + showOptions = TRUE; + } + } + if (g_BreakToggleKey) + { + if (!RegisterHotKey(hWnd, BREAK_HOTKEY, g_BreakToggleMod, g_BreakToggleKey & 0xFF)) + { + MessageBox(hWnd, L"The specified break timer hotkey is already in use.\nSelect a different break timer hotkey.", APPNAME, MB_ICONERROR); + showOptions = TRUE; + } + } + if (g_DemoTypeToggleKey) + { + if (!RegisterHotKey(hWnd, DEMOTYPE_HOTKEY, g_DemoTypeToggleMod, g_DemoTypeToggleKey & 0xFF) || + !RegisterHotKey(hWnd, DEMOTYPE_RESET_HOTKEY, (g_DemoTypeToggleMod ^ MOD_SHIFT), g_DemoTypeToggleKey & 0xFF)) + { + MessageBox(hWnd, L"The specified live-type hotkey is already in use.\nSelect a different live-type hotkey.", APPNAME, MB_ICONERROR); + showOptions = TRUE; + } + } + if (g_SnipToggleKey) + { + if (!RegisterHotKey(hWnd, SNIP_HOTKEY, g_SnipToggleMod, g_SnipToggleKey & 0xFF) || + !RegisterHotKey(hWnd, SNIP_SAVE_HOTKEY, (g_SnipToggleMod ^ MOD_SHIFT), g_SnipToggleKey & 0xFF)) + { + MessageBox(hWnd, L"The specified snip hotkey is already in use.\nSelect a different snip hotkey.", APPNAME, MB_ICONERROR); + showOptions = TRUE; + } + } + if (g_RecordToggleKey) + { + if (!RegisterHotKey(hWnd, RECORD_HOTKEY, g_RecordToggleMod | MOD_NOREPEAT, g_RecordToggleKey & 0xFF) || + !RegisterHotKey(hWnd, RECORD_CROP_HOTKEY, (g_RecordToggleMod ^ MOD_SHIFT) | MOD_NOREPEAT, g_RecordToggleKey & 0xFF) || + !RegisterHotKey(hWnd, RECORD_WINDOW_HOTKEY, (g_RecordToggleMod ^ MOD_ALT) | MOD_NOREPEAT, g_RecordToggleKey & 0xFF)) + { + MessageBox(hWnd, L"The specified record hotkey is already in use.\nSelect a different record hotkey.", APPNAME, MB_ICONERROR); + showOptions = TRUE; + } + } + if (showOptions) + { + // To open the PowerToys settings in the ZoomIt page. + SendMessage(hWnd, WM_COMMAND, IDC_OPTIONS, 0); + } + break; + } + case WM_COMMAND: + + switch(LOWORD( wParam )) { + + case IDC_SAVE_CROP: + case IDC_SAVE: + { + POINT local_savedCursorPos{}; + if( lParam != SHALLOW_ZOOM ) + { + GetCursorPos(&local_savedCursorPos); + } + + HBITMAP hInterimSaveBitmap; + HDC hInterimSaveDc; + HBITMAP hSaveBitmap; + HDC hSaveDc; + int copyX, copyY; + int copyWidth, copyHeight; + + if ( LOWORD( wParam ) == IDC_SAVE_CROP ) + { + g_RecordCropping = TRUE; + SelectRectangle selectRectangle; + if( !selectRectangle.Start( hWnd ) ) + { + g_RecordCropping = FALSE; + if( lParam != SHALLOW_ZOOM ) + { + SetCursorPos(local_savedCursorPos.x, local_savedCursorPos.y); + } + break; + } + auto copyRc = selectRectangle.SelectedRect(); + selectRectangle.Stop(); + g_RecordCropping = FALSE; + copyX = copyRc.left; + copyY = copyRc.top; + copyWidth = copyRc.right - copyRc.left; + copyHeight = copyRc.bottom - copyRc.top; + } + else + { + copyX = 0; + copyY = 0; + copyWidth = width; + copyHeight = height; + } + OutputDebug( L"***x: %d, y: %d, width: %d, height: %d\n", copyX, copyY, copyWidth, copyHeight ); + + RECT oldClipRect{}; + GetClipCursor( &oldClipRect ); + ClipCursor( NULL ); + + // Capture the screen before displaying the save dialog + hInterimSaveDc = CreateCompatibleDC( hdcScreen ); + hInterimSaveBitmap = CreateCompatibleBitmap( hdcScreen, copyWidth, copyHeight ); + SelectObject( hInterimSaveDc, hInterimSaveBitmap ); + + hSaveDc = CreateCompatibleDC( hdcScreen ); +#if SCALE_HALFTONE + SetStretchBltMode( hInterimSaveDc, HALFTONE ); + SetStretchBltMode( hSaveDc, HALFTONE ); +#else + SetStretchBltMode( hInterimSaveDc, COLORONCOLOR ); + SetStretchBltMode( hSaveDc, COLORONCOLOR ); +#endif + StretchBlt( hInterimSaveDc, + 0, 0, + copyWidth, copyHeight, + hdcScreen, + monInfo.rcMonitor.left + copyX, + monInfo.rcMonitor.top + copyY, + copyWidth, copyHeight, + SRCCOPY|CAPTUREBLT ); + + g_bSaveInProgress = true; + memset( &openFileName, 0, sizeof(openFileName )); + openFileName.lStructSize = OPENFILENAME_SIZE_VERSION_400; + openFileName.hwndOwner = hWnd; + openFileName.hInstance = static_cast(g_hInstance); + openFileName.nMaxFile = sizeof(filePath)/sizeof(filePath[0]); + openFileName.Flags = OFN_LONGNAMES|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT; + openFileName.lpstrTitle = L"Save zoomed screen..."; + openFileName.lpstrDefExt = NULL; // "*.png"; + openFileName.nFilterIndex = 1; + openFileName.lpstrFilter = L"Zoomed PNG\0*.png\0" + //"Zoomed BMP\0*.bmp\0" + "Actual size PNG\0*.png\0\0"; + //"Actual size BMP\0*.bmp\0\0"; + openFileName.lpstrFile = filePath; + if( GetSaveFileName( &openFileName ) ) + { + TCHAR targetFilePath[MAX_PATH]; + _tcscpy( targetFilePath, filePath ); + if( !_tcsrchr( targetFilePath, '.' ) ) + { + _tcscat( targetFilePath, L".png" ); + } + + // Save image at screen size + if( openFileName.nFilterIndex == 1 ) + { + SavePng( targetFilePath, hInterimSaveBitmap ); + } + // Save image scaled down to actual size + else + { + int saveWidth = static_cast( copyWidth / zoomLevel ); + int saveHeight = static_cast( copyHeight / zoomLevel ); + + hSaveBitmap = CreateCompatibleBitmap( hdcScreen, saveWidth, saveHeight ); + SelectObject( hSaveDc, hSaveBitmap ); + + StretchBlt( hSaveDc, + 0, 0, + saveWidth, saveHeight, + hInterimSaveDc, + 0, + 0, + copyWidth, copyHeight, + SRCCOPY | CAPTUREBLT ); + + SavePng( targetFilePath, hSaveBitmap ); + } + } + g_bSaveInProgress = false; + + DeleteDC( hInterimSaveDc ); + DeleteDC( hSaveDc ); + + if( lParam != SHALLOW_ZOOM ) + { + SetCursorPos(local_savedCursorPos.x, local_savedCursorPos.y); + } + ClipCursor( &oldClipRect ); + break; + } + + case IDC_COPY_CROP: + case IDC_COPY: { + HBITMAP hSaveBitmap; + HDC hSaveDc; + int copyX, copyY; + int copyWidth, copyHeight; + + if( LOWORD( wParam ) == IDC_COPY_CROP ) + { + g_RecordCropping = TRUE; + POINT local_savedCursorPos{}; + if( lParam != SHALLOW_ZOOM ) + { + GetCursorPos(&local_savedCursorPos); + } + SelectRectangle selectRectangle; + if( !selectRectangle.Start( hWnd ) ) + { + g_RecordCropping = FALSE; + break; + } + auto copyRc = selectRectangle.SelectedRect(); + selectRectangle.Stop(); + if( lParam != SHALLOW_ZOOM ) + { + SetCursorPos(local_savedCursorPos.x, local_savedCursorPos.y); + } + g_RecordCropping = FALSE; + + copyX = copyRc.left; + copyY = copyRc.top; + copyWidth = copyRc.right - copyRc.left; + copyHeight = copyRc.bottom - copyRc.top; + } + else + { + copyX = 0; + copyY = 0; + copyWidth = width; + copyHeight = height; + } + OutputDebug( L"***x: %d, y: %d, width: %d, height: %d\n", copyX, copyY, copyWidth, copyHeight ); + + hSaveBitmap = CreateCompatibleBitmap( hdcScreen, copyWidth, copyHeight ); + hSaveDc = CreateCompatibleDC( hdcScreen ); + SelectObject( hSaveDc, hSaveBitmap ); +#if SCALE_HALFTONE + SetStretchBltMode( hSaveDc, HALFTONE ); +#else + SetStretchBltMode( hSaveDc, COLORONCOLOR ); +#endif + StretchBlt( hSaveDc, + 0, 0, + copyWidth, copyHeight, + hdcScreen, + monInfo.rcMonitor.left + copyX, + monInfo.rcMonitor.top + copyY, + copyWidth, copyHeight, + SRCCOPY|CAPTUREBLT ); + + if( OpenClipboard( hWnd )) { + + EmptyClipboard(); + SetClipboardData( CF_BITMAP, hSaveBitmap ); + CloseClipboard(); + } + + DeleteDC( hSaveDc ); + } + break; + + case IDC_DRAW: + PostMessage( hWnd, WM_HOTKEY, DRAW_HOTKEY, 1 ); + break; + + case IDC_ZOOM: + PostMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, 1 ); + break; + + case IDC_RECORD: + PostMessage( hWnd, WM_HOTKEY, RECORD_HOTKEY, 1 ); + break; + + case IDC_OPTIONS: + // Don't show win32 forms options if started by PowerToys. + // Show the PowerToys Settings application instead. + + if( g_StartedByPowerToys ) + { +#ifdef __ZOOMIT_POWERTOYS__ + OpenPowerToysSettingsApp(); +#endif // __ZOOMIT_POWERTOYS__ + } + else + { + DialogBox( g_hInstance, L"OPTIONS", hWnd, OptionsProc ); + } + break; + + case IDC_BREAK: + { + // Manage handles, clean visual transitions, and Options delta + if( g_TimerActive ) + { + if( activeBreakShowBackgroundFile != g_BreakShowBackgroundFile || + activeBreakShowDesktop != g_BreakShowDesktop ) + { + if( g_BreakShowBackgroundFile && !g_BreakShowDesktop ) + { + SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, SHALLOW_DESTROY ); + } + else + { + SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, 0 ); + } + } + else + { + SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, SHALLOW_DESTROY ); + g_TimerActive = TRUE; + } + } + + hdcScreen = CreateDC( L"DISPLAY", static_cast(NULL), static_cast(NULL), static_cast(NULL) ); + + // toggle second monitor + // FIX: we should save whether or not we've switched to a second monitor + // rather than just assume that the setting hasn't changed since the break timer + // became active + if( g_BreakOnSecondary ) + { + EnableDisableSecondaryDisplay( hWnd, TRUE, &secondaryDevMode ); + } + + // Determine what monitor we're on + GetCursorPos( &cursorPos ); + UpdateMonitorInfo( cursorPos, &monInfo ); + width = monInfo.rcMonitor.right - monInfo.rcMonitor.left; + height = monInfo.rcMonitor.bottom - monInfo.rcMonitor.top; + + // Trigger desktop recapture as necessary when switching monitors + if( g_TimerActive && g_BreakShowDesktop && lastMonInfo.rcMonitor != monInfo.rcMonitor ) + { + lastMonInfo = monInfo; + SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, 0 ); + PostMessage( hWnd, WM_COMMAND, IDC_BREAK, 0 ); + break; + } + lastMonInfo = monInfo; + + // If the background is a file that hasn't been collected, grab it now + if( g_BreakShowBackgroundFile && !g_BreakShowDesktop && + ( !g_TimerActive || wcscmp( activeBreakBackgroundFile, g_BreakBackgroundFile ) ) ) + { + _tcscpy( activeBreakBackgroundFile, g_BreakBackgroundFile ); + + DeleteObject( g_hBackgroundBmp ); + DeleteDC( g_hDcBackgroundFile ); + + g_hBackgroundBmp = NULL; + g_hBackgroundBmp = LoadImageFile( g_BreakBackgroundFile ); + if( g_hBackgroundBmp == NULL ) + { + // Clean up hanging handles + SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, 0 ); + ErrorDialog( hWnd, L"Error loading background bitmap", GetLastError() ); + break; + } + g_hDcBackgroundFile = CreateCompatibleDC( hdcScreen ); + SelectObject( g_hDcBackgroundFile, g_hBackgroundBmp ); + } + // If the background is a desktop that hasn't been collected, grab it now + else if( g_BreakShowBackgroundFile && g_BreakShowDesktop && !g_TimerActive ) + { + g_hBackgroundBmp = CreateFadedDesktopBackground( GetDC(NULL), & monInfo.rcMonitor, NULL ); + g_hDcBackgroundFile = CreateCompatibleDC( hdcScreen ); + SelectObject( g_hDcBackgroundFile, g_hBackgroundBmp ); + } + + // Track Options.Break delta + activeBreakShowBackgroundFile = g_BreakShowBackgroundFile; + activeBreakShowDesktop = g_BreakShowDesktop; + + g_TimerActive = TRUE; +#ifdef __ZOOMIT_POWERTOYS__ + if( g_StartedByPowerToys ) + { + Trace::ZoomItActivateBreak(); + } +#endif // __ZOOMIT_POWERTOYS__ + + breakTimeout = g_BreakTimeout * 60 + 1; + + // Create font + g_LogFont.lfHeight = height / 5; + hTimerFont = CreateFontIndirect( &g_LogFont ); + g_LogFont.lfHeight = height / 8; + hNegativeTimerFont = CreateFontIndirect( &g_LogFont ); + + // Create backing bitmap + hdcScreenCompat = CreateCompatibleDC(hdcScreen); + bmp.bmBitsPixel = static_cast(GetDeviceCaps(hdcScreen, BITSPIXEL)); + bmp.bmPlanes = static_cast(GetDeviceCaps(hdcScreen, PLANES)); + bmp.bmWidth = width; + bmp.bmHeight = height; + bmp.bmWidthBytes = ((bmp.bmWidth + 15) &~15)/8; + hbmpCompat = CreateBitmap(bmp.bmWidth, bmp.bmHeight, + bmp.bmPlanes, bmp.bmBitsPixel, static_cast(NULL)); + SelectObject(hdcScreenCompat, hbmpCompat); + + SetTextColor( hdcScreenCompat, g_BreakPenColor ); + SetBkMode( hdcScreenCompat, TRANSPARENT ); + SelectObject( hdcScreenCompat, hTimerFont ); + + EnableDisableOpacity( hWnd, TRUE ); + EnableDisableScreenSaver( FALSE ); + + SendMessage( hWnd, WM_TIMER, 0, 0 ); + SetTimer( hWnd, 0, 1000, NULL ); + + BringWindowToTop( hWnd ); + SetForegroundWindow( hWnd ); + SetActiveWindow( hWnd ); + SetWindowPos( hWnd, HWND_NOTOPMOST, monInfo.rcMonitor.left, monInfo.rcMonitor.top, + width, height, SWP_SHOWWINDOW ); + } + break; + + case IDCANCEL: + + memset( &tNotifyIconData, 0, sizeof(tNotifyIconData)); + tNotifyIconData.cbSize = sizeof(NOTIFYICONDATA); + tNotifyIconData.hWnd = hWnd; + tNotifyIconData.uID = 1; + Shell_NotifyIcon(NIM_DELETE, &tNotifyIconData); + reg.WriteRegSettings( RegSettings ); + + if( hWndOptions ) + { + DestroyWindow( hWndOptions ); + } + DestroyWindow( hWnd ); + break; + } + break; + + case WM_TIMER: + switch( wParam ) { + case 0: + // + // Break timer + // + breakTimeout -= 1; + InvalidateRect( hWnd, NULL, FALSE ); + if( breakTimeout == 0 && g_BreakPlaySoundFile ) { + + PlaySound( g_BreakSoundFile, NULL, SND_FILENAME|SND_ASYNC ); + } + break; + + case 2: + case 1: + // + // Telescoping zoom timer + // + if( zoomTelescopeStep ) { + + zoomLevel *= zoomTelescopeStep; + if( (zoomTelescopeStep > 1 && zoomLevel >= zoomTelescopeTarget ) || + (zoomTelescopeStep < 1 && zoomLevel <= zoomTelescopeTarget )) { + + zoomLevel = zoomTelescopeTarget; + KillTimer( hWnd, wParam ); + OutputDebug( L"SETCURSOR mon_left: %x mon_top: %x x: %d y: %d\n", + monInfo.rcMonitor.left, monInfo.rcMonitor.top, cursorPos.x, cursorPos.y ); + SetCursorPos( monInfo.rcMonitor.left + cursorPos.x, + monInfo.rcMonitor.top + cursorPos.y ); + } + + } else { + + // Case where we didn't zoom at all + KillTimer( hWnd, wParam ); + } + if( wParam == 2 && zoomLevel == 1 ) { + + g_Zoomed = FALSE; + if( g_ZoomOnLiveZoom ) + { + GetCursorPos( &cursorPos ); + cursorPos = ScalePointInRects( cursorPos, monInfo.rcMonitor, g_LiveZoomSourceRect ); + SetCursorPos( cursorPos.x, cursorPos.y ); + SendMessage(hWnd, WM_HOTKEY, LIVE_HOTKEY, 0); + } + else if( lParam != SHALLOW_ZOOM ) + { + // Figure out where final unzoomed cursor should be + if (g_Drawing) { + cursorPos = prevPt; + } + OutputDebug(L"FINAL MOUSE: x: %d y: %d\n", cursorPos.x, cursorPos.y ); + GetZoomedTopLeftCoordinates(zoomLevel, &cursorPos, &x, width, &y, height); + cursorPos.x = monInfo.rcMonitor.left + x + static_cast((cursorPos.x - x) * zoomLevel); + cursorPos.y = monInfo.rcMonitor.top + y + static_cast((cursorPos.y - y) * zoomLevel); + SetCursorPos(cursorPos.x, cursorPos.y); + } + if( hTargetWindow ) { + + SetWindowPos( hTargetWindow, HWND_BOTTOM, rcTargetWindow.left, rcTargetWindow.top, + rcTargetWindow.right - rcTargetWindow.left, + rcTargetWindow.bottom - rcTargetWindow.top, 0 ); + hTargetWindow = NULL; + } + DeleteDrawUndoList( &drawUndoList ); + + // Restore live zoom if we came from that mode + if( g_ZoomOnLiveZoom ) { + + SendMessage( g_hWndLiveZoom, WM_USER_SET_ZOOM, static_cast(g_LiveZoomLevel), reinterpret_cast(&g_LiveZoomSourceRect) ); + g_ZoomOnLiveZoom = FALSE; + forcePenResize = TRUE; + } + + SetForegroundWindow( g_ActiveWindow ); + ClipCursor( NULL ); + g_HaveDrawn = FALSE; + g_TypeMode = TypeModeOff; + g_HaveTyped = FALSE; + g_Drawing = FALSE; + EnableDisableStickyKeys( TRUE ); + DeleteObject( hTypingFont ); + DeleteDC( hdcScreen ); + DeleteDC( hdcScreenCompat ); + DeleteDC( hdcScreenCursorCompat ); + DeleteDC( hdcScreenSaveCompat ); + DeleteObject( hbmpCompat ); + DeleteObject( hbmpCursorCompat ); + DeleteObject( hbmpDrawingCompat ); + DeleteObject( hDrawingPen ); + + SetFocus( g_ActiveWindow ); + ShowWindow( hWnd, SW_HIDE ); + } + InvalidateRect( hWnd, NULL, FALSE ); + break; + + case 3: + POINT mousePos; + GetCursorPos(&mousePos); + if (mousePos.x != cursorPos.x || mousePos.y != cursorPos.y) + { + MONITORINFO monitorInfo = { sizeof(MONITORINFO) }; + UpdateMonitorInfo(mousePos, &monitorInfo); + + mousePos.x -= monitorInfo.rcMonitor.left; + mousePos.y -= monitorInfo.rcMonitor.top; + + OutputDebug(L"RETRACKING MOUSE: x: %d y: %d\n", mousePos.x, mousePos.y); + SendMessage(hWnd, WM_MOUSEMOVE, 0, MAKELPARAM(mousePos.x, mousePos.y)); + } + break; + } + break; + + case WM_PAINT: + + hDc = BeginPaint(hWnd, &ps); + + if( ( ( g_RecordCropping == FALSE ) || ( zoomLevel == 1 ) ) && g_Zoomed ) { + + OutputDebug( L"PAINT x: %d y: %d width: %d height: %d zoomLevel: %g\n", + cursorPos.x, cursorPos.y, width, height, zoomLevel ); + GetZoomedTopLeftCoordinates( zoomLevel, &cursorPos, &x, width, &y, height ); +#if SCALE_GDIPLUS + if ( zoomLevel >= zoomTelescopeTarget ) { + // do a high-quality render + extern void ScaleImage( HDC hdcDst, float xDst, float yDst, float wDst, float hDst, + HBITMAP bmSrc, float xSrc, float ySrc, float wSrc, float hSrc ); + + ScaleImage( ps.hdc, + 0, 0, + (float)bmp.bmWidth, (float)bmp.bmHeight, + hbmpCompat, + (float)x, (float)y, + width/zoomLevel, height/zoomLevel ); + } else { + // do a fast, less accurate render + SetStretchBltMode( hDc, HALFTONE ); + StretchBlt( ps.hdc, + 0, 0, + bmp.bmWidth, bmp.bmHeight, + hdcScreenCompat, + x, y, + (int) (width/zoomLevel), (int) (height/zoomLevel), + SRCCOPY); + } +#else +#if SCALE_HALFTONE + SetStretchBltMode( hDc, zoomLevel == zoomTelescopeTarget ? HALFTONE : COLORONCOLOR ); +#else + SetStretchBltMode( hDc, COLORONCOLOR ); +#endif + StretchBlt( ps.hdc, + 0, 0, + bmp.bmWidth, bmp.bmHeight, + hdcScreenCompat, + x, y, + static_cast(width/zoomLevel), static_cast(height/zoomLevel), + SRCCOPY|CAPTUREBLT ); +#endif + } else if( g_TimerActive ) { + + // Fill bitmap with white + rc.top = rc.left = 0; + rc.bottom = height; + rc.right = width; + FillRect( hdcScreenCompat, &rc, GetSysColorBrush( COLOR_WINDOW )); + + // If there's a background bitmap, draw it in the center + if( g_hBackgroundBmp ) { + + BITMAP local_bmp; + GetObject(g_hBackgroundBmp, sizeof(local_bmp), &local_bmp); + SetStretchBltMode( hdcScreenCompat, HALFTONE ); + if( g_BreakBackgroundStretch ) { + StretchBlt( hdcScreenCompat, 0, 0, width, height, + g_hDcBackgroundFile, 0, 0, local_bmp.bmWidth, local_bmp.bmHeight, SRCCOPY|CAPTUREBLT ); + } else { + BitBlt( hdcScreenCompat, width/2 - local_bmp.bmWidth/2, height/2 - local_bmp.bmHeight/2, + local_bmp.bmWidth, local_bmp.bmHeight, g_hDcBackgroundFile, 0, 0, SRCCOPY|CAPTUREBLT ); + } + } + + // Draw time + if( breakTimeout > 0 ) { + + _stprintf( timerText, L"% 2d:%02d", breakTimeout/60, breakTimeout % 60 ); + + } else { + + _tcscpy( timerText, L"0:00" ); + } + rc.left = rc.top = 0; + DrawText( hdcScreenCompat, timerText, -1, &rc, + DT_NOCLIP|DT_LEFT|DT_NOPREFIX|DT_CALCRECT ); + + rc1.left = rc1.right = rc1.bottom = rc1.top = 0; + if( g_ShowExpiredTime && breakTimeout < 0 ) { + + _stprintf( negativeTimerText, L"(-% 2d:%02d)", + -breakTimeout/60, -breakTimeout % 60 ); + HFONT prevFont = static_cast(SelectObject( hdcScreenCompat, hNegativeTimerFont )); + DrawText( hdcScreenCompat, negativeTimerText, -1, &rc1, + DT_NOCLIP|DT_LEFT|DT_NOPREFIX|DT_CALCRECT ); + SelectObject( hdcScreenCompat, prevFont ); + } + + // Position time vertically + switch( g_BreakTimerPosition ) { + case 0: + case 1: + case 2: + rc.top = 50; + break; + case 3: + case 4: + case 5: + rc.top = (height - (rc.bottom - rc.top))/2; + break; + case 6: + case 7: + case 8: + rc.top = height - rc.bottom - 50 - rc1.bottom; + break; + } + + // Position time horizontally + switch( g_BreakTimerPosition ) { + case 0: + case 3: + case 6: + rc.left = 50; + break; + case 1: + case 4: + case 7: + rc.left = (width - (rc.right - rc.left))/2; + break; + case 2: + case 5: + case 8: + rc.left = width - rc.right - 50; + break; + } + rc.bottom += rc.top; + rc.right += rc.left; + + DrawText( hdcScreenCompat, timerText, -1, &rc, DT_NOCLIP|DT_LEFT|DT_NOPREFIX ); + + if( g_ShowExpiredTime && breakTimeout < 0 ) { + + rc1.top = rc.bottom + 10; + rc1.left = rc.left + ((rc.right - rc.left)-(rc1.right-rc1.left))/2; + HFONT prevFont = static_cast(SelectObject( hdcScreenCompat, hNegativeTimerFont )); + DrawText( hdcScreenCompat, negativeTimerText, -1, &rc1, + DT_NOCLIP|DT_LEFT|DT_NOPREFIX ); + SelectObject( hdcScreenCompat, prevFont ); + } + + // Copy to screen + BitBlt( ps.hdc, 0, 0, width, height, hdcScreenCompat, 0, 0, SRCCOPY|CAPTUREBLT ); + } + EndPaint(hWnd, &ps); + return TRUE; + + case WM_DESTROY: + + PostQuitMessage( 0 ); + break; + + default: + if( message == wmTaskbarCreated ) + { + if( g_ShowTrayIcon ) + { + EnableDisableTrayIcon( hWnd, TRUE ); + } + return TRUE; + } + return DefWindowProc(hWnd, message, wParam, lParam ); + } + return 0; +} + + +//---------------------------------------------------------------------------- +// +// LiveZoomWndProc +// +//---------------------------------------------------------------------------- +LRESULT CALLBACK LiveZoomWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + RECT rc; + POINT cursorPos; + static int width, height; + static MONITORINFO monInfo; + HDC hdcScreen; +#if 0 + int delta; + BOOLEAN zoomIn; +#endif + static POINT lastCursorPos; + POINT adjustedCursorPos, zoomCenterPos; + int moveWidth, moveHeight; + int sourceRectHeight, sourceRectWidth; + DWORD curTickCount; + RECT sourceRect{}; + static RECT lastSourceRect; + static float zoomLevel; + static float zoomTelescopeStep; + static float zoomTelescopeTarget; + static DWORD prevZoomStepTickCount = 0; + static BOOL dwmEnabled = FALSE; + static BOOLEAN startedInPresentationMode = FALSE; + MAGTRANSFORM matrix; + + switch (message) { + case WM_CREATE: + + // Initialize + pMagInitialize(); + if (pDwmIsCompositionEnabled) pDwmIsCompositionEnabled(&dwmEnabled); + + // Create the zoom window + if( !g_fullScreenWorkaround ) { + + g_hWndLiveZoomMag = CreateWindowEx( 0, + WC_MAGNIFIER, + TEXT("MagnifierWindow"), + WS_CHILD | MS_SHOWMAGNIFIEDCURSOR | WS_VISIBLE, + 0, 0, 0, 0, hWnd, NULL, g_hInstance, NULL ); + } + + ShowWindow( hWnd, SW_SHOW ); + InvalidateRect( g_hWndLiveZoomMag, NULL, TRUE ); + + if( !g_fullScreenWorkaround ) + SetForegroundWindow(static_cast(reinterpret_cast(lParam)->lpCreateParams)); + + // If we're not on Win7+, then set a timer to go off two hours from + // now + if( g_OsVersion < WIN7_VERSION ) { + + startedInPresentationMode = IsPresentationMode(); + // if we're not in presentation mode, kill ourselves after a timeout + if( !startedInPresentationMode ) { + + SetTimer( hWnd, 1, LIVEZOOM_WINDOW_TIMEOUT, NULL ); + } + } + break; + + case WM_SHOWWINDOW: + if( wParam == TRUE ) { + + // Determine what monitor we're on + lastCursorPos.x = -1; + hdcScreen = GetDC( NULL ); + GetCursorPos( &cursorPos ); + UpdateMonitorInfo( cursorPos, &monInfo ); + width = monInfo.rcMonitor.right - monInfo.rcMonitor.left; + height = monInfo.rcMonitor.bottom - monInfo.rcMonitor.top; + lastSourceRect.left = lastSourceRect.right = 0; + lastSourceRect.right = width; + lastSourceRect.bottom = height; + + // Set window size + if( !g_fullScreenWorkaround ) { + + SetWindowPos( hWnd, NULL, monInfo.rcMonitor.left, monInfo.rcMonitor.top, + monInfo.rcMonitor.right - monInfo.rcMonitor.left, + monInfo.rcMonitor.bottom - monInfo.rcMonitor.top, + SWP_NOACTIVATE | SWP_NOZORDER ); + UpdateWindow(hWnd); + } + + // Are we coming back from a static zoom that + // was started while we were live zoomed? + if( g_ZoomOnLiveZoom ) { + + // Force a zoom to 2x without telescope + prevZoomStepTickCount = 0; + zoomLevel = static_cast(1.9); + zoomTelescopeTarget = 2.0; + zoomTelescopeStep = 2.0; + + } else { + + zoomTelescopeStep = ZOOM_LEVEL_STEP_IN; + zoomTelescopeTarget = g_ZoomLevels[g_SliderZoomLevel]; + + prevZoomStepTickCount = 0; + if( dwmEnabled ) { + + zoomLevel = static_cast(1); + + } else { + + zoomLevel = static_cast(1.9); + } + } + RegisterHotKey( hWnd, 0, MOD_CONTROL, VK_UP ); + RegisterHotKey( hWnd, 1, MOD_CONTROL, VK_DOWN ); + + // Hide hardware cursor + if( !g_fullScreenWorkaround ) + if( pMagShowSystemCursor ) pMagShowSystemCursor( FALSE ); + + if( g_RecordToggle ) + g_RecordingSession->EnableCursorCapture( false ); + + GetCursorPos( &lastCursorPos ); + SetCursorPos( lastCursorPos.x, lastCursorPos.y ); + + SendMessage( hWnd, WM_TIMER, 0, 0); + SetTimer( hWnd, 0, ZOOM_LEVEL_STEP_TIME, NULL ); + + } else { + + KillTimer( hWnd, 0 ); + + if( g_RecordToggle ) + g_RecordingSession->EnableCursorCapture(); + + if( !g_fullScreenWorkaround ) + if( pMagShowSystemCursor ) pMagShowSystemCursor( TRUE ); + + // Reset the timer to expire two hours from now + if( g_OsVersion < WIN7_VERSION && !IsPresentationMode()) { + + KillTimer( hWnd, 1 ); + SetTimer( hWnd, 1, LIVEZOOM_WINDOW_TIMEOUT, NULL ); + } else { + + DestroyWindow( hWnd ); + } + UnregisterHotKey( hWnd, 0 ); + UnregisterHotKey( hWnd, 1 ); + } + break; + + case WM_TIMER: + switch( wParam ) { + case 0: { + // if we're cropping, do not move + if( g_RecordCropping == TRUE ) + { + // Still redraw to keep the contents live + InvalidateRect( g_hWndLiveZoomMag, nullptr, TRUE ); + break; + } + + GetCursorPos(&cursorPos); + + // Reclaim topmost status, to prevent unmagnified menus from remaining in view. + memset(&matrix, 0, sizeof(matrix)); + if( !g_fullScreenWorkaround ) { + + pSetLayeredWindowAttributes( hWnd, 0, 255, LWA_ALPHA ); + SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); + + OutputDebug(L"LIVEZOOM RECLAIM\n"); + } + + sourceRectWidth = lastSourceRect.right - lastSourceRect.left; + sourceRectHeight = lastSourceRect.bottom - lastSourceRect.top; + moveWidth = sourceRectWidth/LIVEZOOM_MOVE_REGIONS; + moveHeight = sourceRectHeight/LIVEZOOM_MOVE_REGIONS; + curTickCount = GetTickCount(); + if( zoomLevel != zoomTelescopeTarget && + (prevZoomStepTickCount == 0 || (curTickCount - prevZoomStepTickCount > ZOOM_LEVEL_STEP_TIME)) ) { + + prevZoomStepTickCount = curTickCount; + if( (zoomTelescopeStep > 1 && zoomLevel*zoomTelescopeStep >= zoomTelescopeTarget ) || + (zoomTelescopeStep < 1 && zoomLevel*zoomTelescopeStep <= zoomTelescopeTarget )) { + + zoomLevel = zoomTelescopeTarget; + + } else { + + zoomLevel *= zoomTelescopeStep; + } + // Time to exit zoom mode? + if( zoomTelescopeTarget == 1 && zoomLevel == 1 ) { + +#if WINDOWS_CURSOR_RECORDING_WORKAROUND + if( g_RecordToggle ) + g_LiveZoomLevelOne = true; + else +#endif + ShowWindow( hWnd, SW_HIDE ); + + } else { + + matrix.v[0][0] = zoomLevel; + matrix.v[0][2] = (static_cast(-lastSourceRect.left) * zoomLevel); + matrix.v[1][1] = zoomLevel; + matrix.v[1][2] = (static_cast(-lastSourceRect.top) * zoomLevel ); + matrix.v[2][2] = 1.0f; + } + + // + // Pre-adjust for monitor boundary + // + adjustedCursorPos.x = cursorPos.x - monInfo.rcMonitor.left; + adjustedCursorPos.y = cursorPos.y - monInfo.rcMonitor.top; + GetZoomedTopLeftCoordinates( zoomLevel, &adjustedCursorPos, reinterpret_cast(&zoomCenterPos.x), width, + reinterpret_cast(&zoomCenterPos.y), height ); + + // + // Add back monitor boundary + // + zoomCenterPos.x += monInfo.rcMonitor.left + static_cast(width/zoomLevel/2); + zoomCenterPos.y += monInfo.rcMonitor.top + static_cast(height/zoomLevel/2); + + } else { + + int xOffset = cursorPos.x - lastSourceRect.left; + int yOffset = cursorPos.y - lastSourceRect.top; + zoomCenterPos.x = 0; + zoomCenterPos.y = 0; + if( xOffset < moveWidth ) + zoomCenterPos.x = lastSourceRect.left + sourceRectWidth/2 - (moveWidth - xOffset); + else if( xOffset > moveWidth * (LIVEZOOM_MOVE_REGIONS-1) ) + zoomCenterPos.x = lastSourceRect.left + sourceRectWidth/2 + (xOffset - moveWidth*(LIVEZOOM_MOVE_REGIONS-1)); + if( yOffset < moveHeight ) + zoomCenterPos.y = lastSourceRect.top + sourceRectHeight/2 - (moveHeight - yOffset); + else if( yOffset > moveHeight * (LIVEZOOM_MOVE_REGIONS-1) ) + zoomCenterPos.y = lastSourceRect.top + sourceRectHeight/2 + (yOffset - moveHeight*(LIVEZOOM_MOVE_REGIONS-1)); + } + if( matrix.v[0][0] || zoomCenterPos.x || zoomCenterPos.y ) { + + if( zoomCenterPos.y == 0 ) + zoomCenterPos.y = lastSourceRect.top + sourceRectHeight/2; + if( zoomCenterPos.x == 0 ) + zoomCenterPos.x = lastSourceRect.left + sourceRectWidth/2; + + int zoomWidth = static_cast(width / zoomLevel); + int zoomHeight = static_cast(height/ zoomLevel); + sourceRect.left = zoomCenterPos.x - zoomWidth / 2; + sourceRect.top = zoomCenterPos.y - zoomHeight / 2; + + // Don't scroll outside desktop area. + if (sourceRect.left < monInfo.rcMonitor.left) + sourceRect.left = monInfo.rcMonitor.left; + else if (sourceRect.left > monInfo.rcMonitor.right - zoomWidth ) + sourceRect.left = monInfo.rcMonitor.right - zoomWidth; + sourceRect.right = sourceRect.left + zoomWidth; + if (sourceRect.top < monInfo.rcMonitor.top) + sourceRect.top = monInfo.rcMonitor.top; + else if (sourceRect.top > monInfo.rcMonitor.bottom - zoomHeight) + sourceRect.top = monInfo.rcMonitor.bottom - zoomHeight; + sourceRect.bottom = sourceRect.top + zoomHeight; + + if( g_ZoomOnLiveZoom ) { + + matrix.v[0][0] = static_cast(1.0); + matrix.v[0][2] = (static_cast(-monInfo.rcMonitor.left)); + + matrix.v[1][1] = static_cast(1.0); + matrix.v[1][2] = (static_cast(-monInfo.rcMonitor.top)); + + matrix.v[2][2] = 1.0f; + + } else if( lastSourceRect.left != sourceRect.left || + lastSourceRect.top != sourceRect.top ) { + + matrix.v[0][0] = zoomLevel; + matrix.v[0][2] = (static_cast(-sourceRect.left) * zoomLevel); + + matrix.v[1][1] = zoomLevel; + matrix.v[1][2] = (static_cast(-sourceRect.top) * zoomLevel); + + matrix.v[2][2] = 1.0f; + } + lastSourceRect = sourceRect; + } + lastCursorPos = cursorPos; + + // Update source and zoom if necessary + if( matrix.v[0][0] ) { + + OutputDebug(L"LIVEZOOM update\n"); + if( g_fullScreenWorkaround ) { + + pMagSetFullscreenTransform(zoomLevel, sourceRect.left, sourceRect.top); + pMagSetInputTransform(TRUE, &sourceRect, &monInfo.rcMonitor); + } + else { + + pMagSetWindowTransform(g_hWndLiveZoomMag, &matrix); + } + } + + if( !g_fullScreenWorkaround ) { + + // Force redraw to refresh screen contents + InvalidateRect(g_hWndLiveZoomMag, NULL, TRUE); + } + + // are we done zooming? + if( zoomLevel == 1 ) { + +#if WINDOWS_CURSOR_RECORDING_WORKAROUND + if( g_RecordToggle ) { + + g_LiveZoomLevelOne = true; + } + else { + +#endif + if( g_OsVersion < WIN7_VERSION ) { + + ShowWindow( hWnd, SW_HIDE ); + + } else { + + DestroyWindow( hWnd ); + } + } +#if WINDOWS_CURSOR_RECORDING_WORKAROUND + } +#endif + } + break; + case 1: { + + if( !IsWindowVisible( hWnd )) { + + // This is the cached window timeout. If not in presentation mode, + // time to exit + if( !IsPresentationMode()) { + + DestroyWindow( hWnd ); + } + } + } + break; + } + break; + + case WM_SETTINGCHANGE: + if( g_OsVersion < WIN7_VERSION ) { + + if( startedInPresentationMode && !IsPresentationMode()) { + + // Existing presentation mode + DestroyWindow( hWnd ); + + } else if( !startedInPresentationMode && IsPresentationMode()) { + + // Kill the timer if one was configured, because now + // we're going to go away when they exit presentation mode + KillTimer( hWnd, 1 ); + } + } + break; + + case WM_HOTKEY: { + float newZoomLevel = zoomLevel; + switch( wParam ) { + case 0: + // zoom in + if( newZoomLevel < ZOOM_LEVEL_MAX ) + newZoomLevel *= 2; + zoomTelescopeStep = ZOOM_LEVEL_STEP_IN; + break; + + case 1: + if( newZoomLevel > 2 ) + newZoomLevel /= 2; + else { + + newZoomLevel *= .75; + if( newZoomLevel < ZOOM_LEVEL_MIN ) + newZoomLevel = ZOOM_LEVEL_MIN; + } + zoomTelescopeStep = ZOOM_LEVEL_STEP_OUT; + break; + } + zoomTelescopeTarget = newZoomLevel; + if( !dwmEnabled ) { + + zoomLevel = newZoomLevel; + } + } + break; + + // NOTE: keyboard and mouse input actually don't get sent to us at all when in live zoom mode + case WM_KEYDOWN: + switch( wParam ) { + case VK_ESCAPE: + zoomTelescopeStep = ZOOM_LEVEL_STEP_OUT; + zoomTelescopeTarget = 1.0; + if( !dwmEnabled ) { + + zoomLevel = static_cast(1.1); + } + break; + + case VK_UP: + SendMessage( hWnd, WM_MOUSEWHEEL, + MAKEWPARAM( GetAsyncKeyState( VK_LCONTROL ) != 0 ? MK_CONTROL: 0, WHEEL_DELTA), 0 ); + return TRUE; + + case VK_DOWN: + SendMessage( hWnd, WM_MOUSEWHEEL, + MAKEWPARAM( GetAsyncKeyState( VK_LCONTROL ) != 0 ? MK_CONTROL: 0, -WHEEL_DELTA), 0 ); + return TRUE; + } + break; + case WM_DESTROY: + g_hWndLiveZoom = NULL; + break; + + case WM_SIZE: + GetClientRect(hWnd, &rc); + SetWindowPos(g_hWndLiveZoomMag, NULL, + rc.left, rc.top, rc.right, rc.bottom, 0 ); + break; + + case WM_USER_GET_ZOOM_LEVEL: + return reinterpret_cast(&zoomLevel); + + case WM_USER_GET_SOURCE_RECT: + return reinterpret_cast(&lastSourceRect); + + case WM_USER_MAGNIFY_CURSOR: + { + auto style = GetWindowLong( g_hWndLiveZoomMag, GWL_STYLE ); + if( wParam == TRUE ) + { + style |= MS_SHOWMAGNIFIEDCURSOR; + } + else + { + style &= ~MS_SHOWMAGNIFIEDCURSOR; + } + SetWindowLong( g_hWndLiveZoomMag, GWL_STYLE, style ); + InvalidateRect( g_hWndLiveZoomMag, nullptr, TRUE ); + RedrawWindow( hWnd, nullptr, nullptr, RDW_ALLCHILDREN | RDW_UPDATENOW ); + } + break; + + case WM_USER_SET_ZOOM: + { + if( g_RecordToggle ) + { + g_SelectRectangle.UpdateOwner( hWnd ); + } + + if( lParam != NULL ) { + + lastSourceRect = *reinterpret_cast(lParam); + } +#if WINDOWS_CURSOR_RECORDING_WORKAROUND + if( g_LiveZoomLevelOne ) { + + g_LiveZoomLevelOne = FALSE; + + zoomTelescopeTarget = static_cast(wParam); + zoomTelescopeStep = ZOOM_LEVEL_STEP_IN; + prevZoomStepTickCount = 0; + zoomLevel = 1.0; + + break; + } +#endif + zoomLevel = static_cast(wParam); + zoomTelescopeTarget = zoomLevel; + matrix.v[0][0] = zoomLevel; + matrix.v[0][2] = (static_cast(-lastSourceRect.left) * static_cast(wParam)); + + matrix.v[1][1] = zoomLevel; + matrix.v[1][2] = (static_cast(-lastSourceRect.top) * static_cast(wParam)); + + matrix.v[2][2] = 1.0f; + + if( g_fullScreenWorkaround ) { + + pMagSetFullscreenTransform(zoomLevel, lastSourceRect.left, lastSourceRect.top); + pMagSetInputTransform(TRUE, &lastSourceRect, &monInfo.rcMonitor); + } + else { + + pMagSetWindowTransform(g_hWndLiveZoomMag, &matrix); + } + } + break; + + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + return 0; +} + + +//---------------------------------------------------------------------------- +// +// Wrapper functions for explicit linking to d3d11.dll +// +//---------------------------------------------------------------------------- + +HRESULT __stdcall WrapCreateDirect3D11DeviceFromDXGIDevice( + IDXGIDevice *dxgiDevice, + IInspectable **graphicsDevice) +{ + if( pCreateDirect3D11DeviceFromDXGIDevice == nullptr ) + return E_NOINTERFACE; + + return pCreateDirect3D11DeviceFromDXGIDevice( dxgiDevice, graphicsDevice ); +} + +HRESULT __stdcall WrapCreateDirect3D11SurfaceFromDXGISurface( + IDXGISurface *dxgiSurface, + IInspectable **graphicsSurface) +{ + if( pCreateDirect3D11SurfaceFromDXGISurface == nullptr ) + return E_NOINTERFACE; + + return pCreateDirect3D11SurfaceFromDXGISurface( dxgiSurface, graphicsSurface ); +} + +HRESULT __stdcall WrapD3D11CreateDevice( + IDXGIAdapter *pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + const D3D_FEATURE_LEVEL *pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + ID3D11Device **ppDevice, + D3D_FEATURE_LEVEL *pFeatureLevel, + ID3D11DeviceContext **ppImmediateContext) +{ + if( pD3D11CreateDevice == nullptr ) + return E_NOINTERFACE; + + return pD3D11CreateDevice( pAdapter, DriverType, Software, Flags, pFeatureLevels, + FeatureLevels, SDKVersion, ppDevice, pFeatureLevel, ppImmediateContext ); +} + + +//---------------------------------------------------------------------------- +// +// InitInstance +// +//---------------------------------------------------------------------------- +HWND InitInstance( HINSTANCE hInstance, int nCmdShow ) +{ + WNDCLASS wcZoomIt; + HWND hWndMain; + + g_hInstance = hInstance; + + // If magnification, set default hotkey for live zoom + if( pMagInitialize ) { + + // register live zoom host window + wcZoomIt.style = CS_HREDRAW | CS_VREDRAW; + wcZoomIt.lpfnWndProc = LiveZoomWndProc; + wcZoomIt.cbClsExtra = 0; + wcZoomIt.cbWndExtra = 0; + wcZoomIt.hInstance = hInstance; + wcZoomIt.hIcon = 0; + wcZoomIt.hCursor = LoadCursor(NULL, IDC_ARROW); + wcZoomIt.hbrBackground = NULL; + wcZoomIt.lpszMenuName = NULL; + wcZoomIt.lpszClassName = L"MagnifierClass"; + RegisterClass(&wcZoomIt); + + } else { + + g_LiveZoomToggleKey = 0; + } + + wcZoomIt.style = 0; + wcZoomIt.lpfnWndProc = (WNDPROC)MainWndProc; + wcZoomIt.cbClsExtra = 0; + wcZoomIt.cbWndExtra = 0; + wcZoomIt.hInstance = hInstance; wcZoomIt.hIcon = NULL; + wcZoomIt.hCursor = LoadCursor( hInstance, L"NULLCURSOR" ); + wcZoomIt.hbrBackground = NULL; + wcZoomIt.lpszMenuName = NULL; + wcZoomIt.lpszClassName = L"ZoomitClass"; + if ( ! RegisterClass(&wcZoomIt) ) + return FALSE; + + hWndMain = CreateWindowEx( WS_EX_TOOLWINDOW, L"ZoomitClass", + L"Zoomit Zoom Window", + WS_POPUP, + 0, 0, + 0, 0, + NULL, + NULL, + hInstance, + NULL); + + // If window could not be created, return "failure" + if (!hWndMain ) + return NULL; + + // Make the window visible; update its client area; and return "success" + ShowWindow(hWndMain, SW_HIDE); + + // Add tray icon + EnableDisableTrayIcon( hWndMain, g_ShowTrayIcon ); + return hWndMain; + +} + +//---------------------------------------------------------------------------- +// +// WinMain +// +//---------------------------------------------------------------------------- +int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, + _In_ PWSTR lpCmdLine, _In_ int nCmdShow ) +{ + MSG msg; + HACCEL hAccel; + + if( !ShowEula( APPNAME, NULL, NULL )) return 1; + +#ifdef __ZOOMIT_POWERTOYS__ + Shared::Trace::ETWTrace* trace = nullptr; + std::wstring pid = std::wstring(lpCmdLine); // The PowerToys pid is the argument to the process. + auto mainThreadId = GetCurrentThreadId(); + if (!pid.empty()) + { + g_StartedByPowerToys = TRUE; + + if (powertoys_gpo::getConfiguredZoomItEnabledValue() == powertoys_gpo::gpo_rule_configured_disabled) + { + Logger::warn(L"Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); + return 1; + } + + trace = new Shared::Trace::ETWTrace(); + Trace::RegisterProvider(); + trace->UpdateState(true); + Trace::ZoomItStarted(); + + // Initialize logger + LoggerHelpers::init_logger(L"ZoomIt", L"", LogSettings::zoomItLoggerName); + + ProcessWaiter::OnProcessTerminate(pid, [mainThreadId](int err) { + if (err != ERROR_SUCCESS) + { + Logger::error(L"Failed to wait for parent process exit. {}", get_last_error_or_default(err)); + } + else + { + Logger::trace(L"PowerToys runner exited."); + } + + Logger::trace(L"Exiting ZoomIt"); + PostThreadMessage(mainThreadId, WM_QUIT, 0, 0); + }); + } +#endif // __ZOOMIT_POWERTOYS__ + + +#ifndef _WIN64 + + if(!g_StartedByPowerToys) + { + // Launch 64-bit version if necessary + SetAutostartFilePath(); + if( RunningOnWin64()) { + + // Record where we are if we're the 32-bit version + return Run64bitVersion(); + } + } +#endif + + // Single instance per desktop + + if( !CreateEvent( NULL, FALSE, FALSE, _T("Local\\ZoomitActive"))) { + + CreateEvent( NULL, FALSE, FALSE, _T("ZoomitActive")); + } + if( GetLastError() == ERROR_ALREADY_EXISTS ) { + if (g_StartedByPowerToys) + { + MessageBox(NULL, L"We've detected another instance of ZoomIt is already running.\nCan't start a new ZoomIt instance from PowerToys.", + APPNAME, MB_ICONERROR | MB_SETFOREGROUND); + return 1; + } + + // Tell the other instance to show the options dialog + g_hWndMain = FindWindow( L"ZoomitClass", NULL ); + if( g_hWndMain != NULL ) { + + PostMessage( g_hWndMain, WM_COMMAND, IDC_OPTIONS, 0 ); + int count = 0; + while( count++ < 5 ) { + + HWND local_hWndOptions = FindWindow( NULL, L"ZoomIt - Sysinternals: www.sysinternals.com" ); + if( local_hWndOptions ) { + + SetForegroundWindow( local_hWndOptions ); + SetWindowPos( local_hWndOptions, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE|SWP_SHOWWINDOW ); + break; + } + Sleep( 100 ); + } + } + return 0; + } + + g_OsVersion = GetVersion() & 0xFFFF; + + // load accelerators + hAccel = LoadAccelerators( hInstance, TEXT("ACCELERATORS")); + + if (FAILED(CoInitialize(0))) + { + return 0; + } + + pEnableThemeDialogTexture = (type_pEnableThemeDialogTexture) GetProcAddress( GetModuleHandle( L"uxtheme.dll" ), + "EnableThemeDialogTexture" ); + pMonitorFromPoint = (type_MonitorFromPoint) GetProcAddress( LoadLibrarySafe( L"User32.dll", DLL_LOAD_LOCATION_SYSTEM), + "MonitorFromPoint" ); + pGetMonitorInfo = (type_pGetMonitorInfo) GetProcAddress( LoadLibrarySafe( L"User32.dll", DLL_LOAD_LOCATION_SYSTEM), + "GetMonitorInfoA" ); + pSHAutoComplete = (type_pSHAutoComplete) GetProcAddress( LoadLibrarySafe(L"Shlwapi.dll", DLL_LOAD_LOCATION_SYSTEM), + "SHAutoComplete" ); + pSetLayeredWindowAttributes = (type_pSetLayeredWindowAttributes) GetProcAddress( LoadLibrarySafe(L"user32.dll", DLL_LOAD_LOCATION_SYSTEM), + "SetLayeredWindowAttributes" ); + pMagSetWindowSource = (type_pMagSetWindowSource) GetProcAddress( LoadLibrarySafe(L"magnification.dll", DLL_LOAD_LOCATION_SYSTEM), + "MagSetWindowSource" ); + pGetPointerType = (type_pGetPointerType)GetProcAddress(LoadLibrarySafe(L"user32.dll", DLL_LOAD_LOCATION_SYSTEM), + "GetPointerType" ); + pGetPointerPenInfo = (type_pGetPointerPenInfo)GetProcAddress(LoadLibrarySafe(L"user32.dll", DLL_LOAD_LOCATION_SYSTEM), + "GetPointerPenInfo" ); + pMagInitialize = (type_pMagInitialize)GetProcAddress(LoadLibrarySafe(L"magnification.dll", DLL_LOAD_LOCATION_SYSTEM), + "MagInitialize"); + pMagSetWindowTransform = (type_pMagSetWindowTransform) GetProcAddress( LoadLibrarySafe(L"magnification.dll", DLL_LOAD_LOCATION_SYSTEM), + "MagSetWindowTransform" ); + pMagSetFullscreenTransform = (type_pMagSetFullscreenTransform)GetProcAddress(LoadLibrarySafe(L"magnification.dll", DLL_LOAD_LOCATION_SYSTEM), + "MagSetFullscreenTransform"); + pMagSetInputTransform = (type_pMagSetInputTransform)GetProcAddress(LoadLibrarySafe(L"magnification.dll", DLL_LOAD_LOCATION_SYSTEM), + "MagSetInputTransform"); + pMagShowSystemCursor = (type_pMagShowSystemCursor)GetProcAddress(LoadLibrarySafe(L"magnification.dll", DLL_LOAD_LOCATION_SYSTEM), + "MagShowSystemCursor"); + pMagSetWindowFilterList = (type_pMagSetWindowFilterList)GetProcAddress( LoadLibrarySafe( L"magnification.dll", DLL_LOAD_LOCATION_SYSTEM ), + "MagSetWindowFilterList" ); + pSHQueryUserNotificationState = (type_pSHQueryUserNotificationState) GetProcAddress( LoadLibrarySafe(L"shell32.dll", DLL_LOAD_LOCATION_SYSTEM), + "SHQueryUserNotificationState" ); + pDwmIsCompositionEnabled = (type_pDwmIsCompositionEnabled) GetProcAddress( LoadLibrarySafe(L"dwmapi.dll", DLL_LOAD_LOCATION_SYSTEM), + "DwmIsCompositionEnabled" ); + pSetProcessDPIAware = (type_pSetProcessDPIAware) GetProcAddress( LoadLibrarySafe(L"User32.dll", DLL_LOAD_LOCATION_SYSTEM), + "SetProcessDPIAware"); + pSystemParametersInfoForDpi = (type_pSystemParametersInfoForDpi)GetProcAddress(LoadLibrarySafe(L"User32.dll", DLL_LOAD_LOCATION_SYSTEM), + "SystemParametersInfoForDpi"); + pGetDpiForWindow = (type_pGetDpiForWindow)GetProcAddress(LoadLibrarySafe(L"User32.dll", DLL_LOAD_LOCATION_SYSTEM), + "GetDpiForWindow" ); + pCreateDirect3D11DeviceFromDXGIDevice = (type_pCreateDirect3D11DeviceFromDXGIDevice) GetProcAddress( LoadLibrarySafe(L"d3d11.dll", DLL_LOAD_LOCATION_SYSTEM), + "CreateDirect3D11DeviceFromDXGIDevice" ); + pCreateDirect3D11SurfaceFromDXGISurface = (type_pCreateDirect3D11SurfaceFromDXGISurface) GetProcAddress( LoadLibrarySafe(L"d3d11.dll", DLL_LOAD_LOCATION_SYSTEM), + "CreateDirect3D11SurfaceFromDXGISurface" ); + pD3D11CreateDevice = (type_pD3D11CreateDevice) GetProcAddress( LoadLibrarySafe(L"d3d11.dll", DLL_LOAD_LOCATION_SYSTEM), + "D3D11CreateDevice" ); + + // Windows Server 2022 (and including Windows 11) introduced a bug where the cursor disappears + // in live zoom. Use the full-screen magnifier as a workaround on those versions only. It is + // currently impractical as a replacement; it requires calling MagSetInputTransform for all + // input to be transformed. Otherwise, some hit-testing is misdirected. MagSetInputTransform + // fails without token UI access, which is impractical; it requires copying the executable + // under either %ProgramFiles% or %SystemRoot%, which requires elevation. + // + // TODO: Update the Windows 11 21H2 revision check when the final number is known. Also add a + // check for the Windows Server 2022 revision if that bug (https://task.ms/38611091) is + // fixed. + DWORD windowsRevision, windowsBuild = GetWindowsBuild( &windowsRevision ); + if( ( windowsBuild == BUILD_WINDOWS_SERVER_2022 ) || + ( ( windowsBuild == BUILD_WINDOWS_11_21H2 ) && ( windowsRevision < 829 ) ) ) { + + if( pMagSetFullscreenTransform && pMagSetInputTransform ) + g_fullScreenWorkaround = TRUE; + } + +#if 1 + // Calling this causes Windows to mess with our query of monitor height and width + if( pSetProcessDPIAware ) { + + pSetProcessDPIAware(); + } +#endif + /* Perform initializations that apply to a specific instance */ + g_hWndMain = InitInstance(hInstance, nCmdShow); + if (!g_hWndMain ) + return FALSE; + +#ifdef __ZOOMIT_POWERTOYS__ + HANDLE m_reload_settings_event_handle = NULL; + HANDLE m_exit_event_handle = NULL; + std::thread m_event_triggers_thread; + + if( g_StartedByPowerToys ) { + // Start a thread to listen to PowerToys Events. + m_reload_settings_event_handle = CreateEventW(nullptr, false, false, CommonSharedConstants::ZOOMIT_REFRESH_SETTINGS_EVENT); + m_exit_event_handle = CreateEventW(nullptr, false, false, CommonSharedConstants::ZOOMIT_EXIT_EVENT); + if (!m_reload_settings_event_handle || !m_exit_event_handle) + { + Logger::warn(L"Failed to create events. {}", get_last_error_or_default(GetLastError())); + return 1; + } + m_event_triggers_thread = std::thread([&]() { + MSG msg; + HANDLE event_handles[2] = {m_reload_settings_event_handle, m_exit_event_handle}; + while (g_running) + { + DWORD dwEvt = MsgWaitForMultipleObjects(2, event_handles, false, INFINITE, QS_ALLINPUT); + if (!g_running) + { + break; + } + switch (dwEvt) + { + case WAIT_OBJECT_0: + { + // Reload Settings Event + Logger::trace(L"Received a reload settings event."); + PostMessage(g_hWndMain, WM_USER_RELOAD_SETTINGS, 0, 0); + break; + } + case WAIT_OBJECT_0 + 1: + { + // Exit Event + Logger::trace(L"Received an exit event."); + PostMessage(g_hWndMain, WM_QUIT, 0, 0); + break; + } + case WAIT_OBJECT_0 + 2: + if (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + break; + default: + break; + } + } + }); + } +#endif // __ZOOMIT_POWERTOYS__ + + /* Acquire and dispatch messages until a WM_QUIT message is received. */ + while (GetMessage(&msg, NULL, 0, 0 )) { + if( !TranslateAccelerator( g_hWndMain, hAccel, &msg )) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + int retCode = (int) msg.wParam; + + g_running = FALSE; + +#ifdef __ZOOMIT_POWERTOYS__ + if(g_StartedByPowerToys) + { + if (trace!=nullptr) { + trace->Flush(); + delete trace; + } + Trace::UnregisterProvider(); + // Needed to unblock MsgWaitForMultipleObjects one last time + SetEvent(m_reload_settings_event_handle); + CloseHandle(m_reload_settings_event_handle); + CloseHandle(m_exit_event_handle); + m_event_triggers_thread.join(); + } +#endif // __ZOOMIT_POWERTOYS__ + + return retCode; +} diff --git a/src/modules/ZoomIt/ZoomIt/Zoomit.exe.manifest b/src/modules/ZoomIt/ZoomIt/Zoomit.exe.manifest new file mode 100644 index 000000000000..17abe5f21295 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/Zoomit.exe.manifest @@ -0,0 +1,36 @@ + + + + Sysinternals Zoomit + + + + + + + + + + + + + + + per monitor + PerMonitorV2 + + + diff --git a/src/modules/ZoomIt/ZoomIt/appicon.ico b/src/modules/ZoomIt/ZoomIt/appicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..41feb27525e69906aeea47e43edc28b2a7a24af4 GIT binary patch literal 83812 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 ZGpUSKuQX_nR4xPH;l1C_z15Y@{vQ&SU&#Of literal 0 HcmV?d00001 diff --git a/src/modules/ZoomIt/ZoomIt/binres.rc b/src/modules/ZoomIt/ZoomIt/binres.rc new file mode 100644 index 000000000000..9585c75bc414 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/binres.rc @@ -0,0 +1,18 @@ +// +// This file allows for CPU architecture dependencies + +#ifdef _M_IX86 + +// +// x86 +// + +// To prevent Visual Studio dependency tracking logic from assuming that the x64 .res depend on the .exe that contain them, trick it with the macros +// The .rc's included below will be touched every time any of the .exe's mentioned in them is rebuilt thus guaranteeing the Win32 .rc will be recompiled too +#include "Dependency-x64.rc" + +RCZOOMIT64 BINRES MOVEABLE PURE RCZOOMIT_x64_path + +#endif + +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "ZoomIt.exe.manifest" diff --git a/src/modules/ZoomIt/ZoomIt/cursor1.cur b/src/modules/ZoomIt/ZoomIt/cursor1.cur new file mode 100644 index 0000000000000000000000000000000000000000..048f06b4aefde54e0ff825ccb5a5db4d7001d513 GIT binary patch literal 326 zcmZQzU}9ioP*7k10|Q0|1~DK@1BexX*a3(cfe;L!6oi8y|NsAw;0zE8=!O9W0CiJ? AlK=n! literal 0 HcmV?d00001 diff --git a/src/modules/ZoomIt/ZoomIt/drawingc.cur b/src/modules/ZoomIt/ZoomIt/drawingc.cur new file mode 100644 index 0000000000000000000000000000000000000000..b5db12d01445e741394889540988cc8915d06702 GIT binary patch literal 326 zcmZQzU}9ioP*7lC5CB30Mg|5k1_lNVAO;FCH~=vt5P|`ef^ZPz|Ns9H9Ap-w15h&_ v3{=bfNB#i=Lj#ls3gA-@lEVRjZomZp?En8Kfd4QakcVMHYQgfDwtz(d@=SP5 literal 0 HcmV?d00001 diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/black.bmp b/src/modules/ZoomIt/ZoomIt/icon1.ico similarity index 54% rename from src/modules/videoconference/VideoConferenceModule/Assets/VCM/black.bmp rename to src/modules/ZoomIt/ZoomIt/icon1.ico index 18d40779cedd9cf94146441fb2f6aeb19c617d9d..8ba93283ac13fe5c13eb12169e2ed5f4e0cfe74c 100644 GIT binary patch literal 766 zcmeH_u@Qh!2t)Hd2e7iHbPPvhG{$iYe9_k4LIX)S(s4+GidbYEleFR+47kIg8I_Xk e8A(Wzc^k^8s=^)g)#~;HDX%O)K79dx;8mP?#g-NT literal 822 lcmZ?rHDhJ~12Z700mK4O%*Y@C7H5FULpY=4Xb6mk003!i0b>9F diff --git a/src/modules/ZoomIt/ZoomIt/makefile b/src/modules/ZoomIt/ZoomIt/makefile new file mode 100644 index 000000000000..fcde8dfc9373 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/makefile @@ -0,0 +1,58 @@ + # Microsoft Developer Studio Generated NMAKE File, Based on procmon.dsp +!IF "$(CFG)" == "" +CFG=release +!MESSAGE No configuration specified. Defaulting to procmon - Release. +!ENDIF + +!IF "$(CFG)" != "release" && "$(CFG)" != "debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE CFG="release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "release" +!MESSAGE "debug" +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + + +!IF "$(CFG)" == "release" + +ALL : SUBMODULEUPDATE ZOOMITX64 ZOOMIT64A ZOOMIT32 + +ZOOMITX64: + msbuild.exe -m ZoomIt.sln /p:Configuration=Release /p:Platform=x64 + +ZOOMIT64A: + msbuild.exe -m ZoomIt.sln /p:Configuration=Release /p:Platform=ARM64 + +ZOOMIT32: + msbuild.exe -m ZoomIt.sln /p:Configuration=Release /p:Platform=Win32 + +!ELSEIF "$(CFG)" == "debug" + +ALL : SUBMODULEUPDATE ZOOMITX64 ZOOMIT64A ZOOMIT32 + +ZOOMITX64: + msbuild.exe -m ZoomIt.sln /p:Configuration=Debug /p:Platform=x64 + +ZOOMIT64A: + msbuild.exe -m ZoomIt.sln /p:Configuration=Debug /p:Platform=ARM64 + +ZOOMIT32: + msbuild.exe -m ZoomIt.sln /p:Configuration=Debug /p:Platform=Win32 + +!ENDIF + +SUBMODULEUPDATE: + if not exist modules\Build\.git call modules\update.cmd diff --git a/src/modules/videoconference/VideoConferenceShared/packages.config b/src/modules/ZoomIt/ZoomIt/packages.config similarity index 76% rename from src/modules/videoconference/VideoConferenceShared/packages.config rename to src/modules/ZoomIt/ZoomIt/packages.config index ff4b05964868..691158d1b2a7 100644 --- a/src/modules/videoconference/VideoConferenceShared/packages.config +++ b/src/modules/ZoomIt/ZoomIt/packages.config @@ -2,4 +2,5 @@ + \ No newline at end of file diff --git a/src/modules/ZoomIt/ZoomIt/pch.cpp b/src/modules/ZoomIt/ZoomIt/pch.cpp new file mode 100644 index 000000000000..17305716aacd --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" \ No newline at end of file diff --git a/src/modules/ZoomIt/ZoomIt/pch.h b/src/modules/ZoomIt/ZoomIt/pch.h new file mode 100644 index 000000000000..2afdc4e5423b --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/pch.h @@ -0,0 +1,97 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Eula/eula.h" +#include "registry.h" +#include "resource.h" +#include "dll.h" +#define GDIPVER 0x0110 +#include + +// Must come before C++/WinRT +#include + +#include + +// WinRT +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// Direct3D wrappers to avoid implicitly linking to d3d11.dll; must come before declaration +#define CreateDirect3D11DeviceFromDXGIDevice WrapCreateDirect3D11DeviceFromDXGIDevice +#define CreateDirect3D11SurfaceFromDXGISurface WrapCreateDirect3D11SurfaceFromDXGISurface +#define D3D11CreateDevice WrapD3D11CreateDevice + +#include "VideoRecordingSession.h" +#include "SelectRectangle.h" +#include "DemoType.h" +#include "versionhelper.h" + +// WIL +#include +#include + +// DirectX +#include +#include +#include + + +// STL +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// robmikh.common +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/src/modules/ZoomIt/ZoomIt/resource.h b/src/modules/ZoomIt/ZoomIt/resource.h new file mode 100644 index 000000000000..c4c0cfad8747 --- /dev/null +++ b/src/modules/ZoomIt/ZoomIt/resource.h @@ -0,0 +1,115 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by ZoomIt.rc +// +////////////////////////////// +// Non-localizable + +#define FILE_DESCRIPTION "Sysinternals Screen Magnifier" +#define INTERNAL_NAME "ZoomIt" +#define ORIGINAL_FILENAME "PowerToys.ZoomIt.exe" + +// Non-localizable +////////////////////////////// +#define IDC_AUDIO 117 +#define IDC_LINK 1000 +#define IDC_ALT 1001 +#define IDC_CTRL 1002 +#define IDC_TOGGLE 1003 +#define IDC_OPTIONS 1004 +#define IDC_COLOR_PICK 1005 +#define IDC_COLOR 1006 +#define IDC_DRAW 1007 +#define IDC_TITLE 1008 +#define IDC_VERSION 1008 +#define IDC_ZOOM 1009 +#define IDC_DRAWING 1010 +#define IDC_BREAK 1011 +#define IDC_HOTKEY 1014 +#define IDC_DRAW_HOTKEY 1015 +#define IDC_HOTKEY2 1015 +#define IDC_LIVE_HOTKEY 1015 +#define IDC_BREAK_HOTKEY 1016 +#define IDC_SOUND_FILE 1017 +#define IDC_BACKGROUND_FILE 1018 +#define IDC_SPIN 1022 +#define IDC_SPIN_TIMER 1023 +#define IDC_SOUND_BROWSE 1025 +#define IDC_OPACITY 1026 +#define IDC_CHECK1 1027 +#define IDC_ADVANCED_BREAK 1027 +#define IDC_CHECK_SOUND_FILE 1027 +#define IDC_CHECK_BACKGROUND_FILE 1028 +#define IDC_BACKGROUND_BROWSE 1029 +#define IDC_TIMER_POS1 1030 +#define IDC_TIMER_POS2 1031 +#define IDC_TIMER_POS3 1032 +#define IDC_TIMER_POS4 1033 +#define IDC_TIMER_POS5 1034 +#define IDC_TIMER_POS6 1035 +#define IDC_TIMER_POS7 1036 +#define IDC_TIMER_POS8 1037 +#define IDC_TIMER_POS9 1038 +#define IDC_STATIC_SOUND_FILE 1039 +#define IDC_EDIT1 1040 +#define IDC_STATIC_BACKGROUND_FILE 1040 +#define IDC_TYPE 1041 +#define IDC_CHECK2 1042 +#define IDC_CHECK_SHOW_EXPIRED 1042 +#define IDC_TRAY_ICON 1042 +#define IDC_HIDE_TRAY_ICON 1042 +#define IDC_SHOW_TRAY_ICON 1042 +#define IDC_AUTOSTART 1043 +#define IDC_CHECK_BACKGROUND_STRETCH 1046 +#define IDC_STATIC_DESKTOP_BACKGROUND 1047 +#define IDC_STATIC_DESKTOP_BACKGROUND 1047 +#define IDC_TAB 1050 +#define IDC_FONT 1051 +#define IDC_ZOOM_SPIN_TIMER 1052 +#define IDC_ZOOM_SPIN 1052 +#define IDC_ZOOM_LEVEL 1053 +#define IDC_TEXT_FONT 1054 +#define IDC_ZOOM_SLIDER 1056 +#define IDC_ANIMATE_ZOOM 1057 +#define IDC_COMBO1 1058 +#define IDC_RECORD_FRAME_RATE 1058 +#define IDC_SPIN1 1059 +#define IDC_RECORD_FRAME_RATE2 1059 +#define IDC_RECORD_SCALING 1059 +#define IDC_SNIP_HOTKEY 1060 +#define IDC_CAPTURE_AUDIO 1061 +#define IDC_MICROPHONE 1062 +#define IDC_PEN_CONTROL 1063 +#define IDC_COLORS 1064 +#define IDC_HIGHLIGHT_AND_BLUR 1065 +#define IDC_SHAPES 1066 +#define IDC_SCREEN 1067 +#define IDC_DEMOTYPE_TEXT 1068 +#define IDC_DEMOTYPE_BROWSE 1069 +#define IDC_DEMOTYPE_FILE 1070 +#define IDC_DEMOTYPE_SPEED_SLIDER 1071 +#define IDC_DEMOTYPE_USER_DRIVEN 1072 +#define IDC_DEMOTYPE_STATIC1 1073 +#define IDC_DEMOTYPE_SLIDER2 1074 +#define IDC_DEMOTYPE_STATIC2 1074 +#define IDC_COPYRIGHT 1075 +#define IDC_PEN_WIDTH 1105 +#define IDC_TIMER 1106 +#define IDC_SAVE 40002 +#define IDC_COPY 40004 +#define IDC_RECORD 40006 +#define IDC_RECORD_HOTKEY 40007 +#define IDC_COPY_CROP 40008 +#define IDC_SAVE_CROP 40009 +#define IDC_DEMOTYPE_HOTKEY 40011 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 118 +#define _APS_NEXT_COMMAND_VALUE 40013 +#define _APS_NEXT_CONTROL_VALUE 1076 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/src/modules/videoconference/VideoConferenceModule/VideoConferenceModule.rc b/src/modules/ZoomIt/ZoomItModuleInterface/ZoomItModuleInterface.rc similarity index 100% rename from src/modules/videoconference/VideoConferenceModule/VideoConferenceModule.rc rename to src/modules/ZoomIt/ZoomItModuleInterface/ZoomItModuleInterface.rc diff --git a/src/modules/ZoomIt/ZoomItModuleInterface/ZoomItModuleInterface.vcxproj b/src/modules/ZoomIt/ZoomItModuleInterface/ZoomItModuleInterface.vcxproj new file mode 100644 index 000000000000..c922d389693a --- /dev/null +++ b/src/modules/ZoomIt/ZoomItModuleInterface/ZoomItModuleInterface.vcxproj @@ -0,0 +1,113 @@ + + + + + 17.0 + Win32Proj + {e4585179-2ac1-4d5f-a3ff-cfc5392f694c} + ZoomItModuleInterface + ZoomItModuleInterface + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + ..\..\..\..\$(Platform)\$(Configuration)\ + PowerToys.ZoomItModuleInterface + + + + ..\;$(SolutionDir)src\common\Telemetry;$(SolutionDir)src;%(AdditionalIncludeDirectories) + + + $(OutDir)$(TargetName)$(TargetExt) + %(AdditionalDependencies) + + + + + true + _DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + + + Windows + true + false + + + + + true + true + true + NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + false + + + + + + + + + + + + + + + + + Create + + + + + + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} + + + {6955446d-23f7-4023-9bb3-8657f904af99} + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/src/modules/ZoomIt/ZoomItModuleInterface/ZoomItModuleInterface.vcxproj.filters b/src/modules/ZoomIt/ZoomItModuleInterface/ZoomItModuleInterface.vcxproj.filters new file mode 100644 index 000000000000..176397300361 --- /dev/null +++ b/src/modules/ZoomIt/ZoomItModuleInterface/ZoomItModuleInterface.vcxproj.filters @@ -0,0 +1,47 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Resource Files + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/src/modules/ZoomIt/ZoomItModuleInterface/dllmain.cpp b/src/modules/ZoomIt/ZoomItModuleInterface/dllmain.cpp new file mode 100644 index 000000000000..eea809a0a2b5 --- /dev/null +++ b/src/modules/ZoomIt/ZoomItModuleInterface/dllmain.cpp @@ -0,0 +1,233 @@ +#include "pch.h" + +#include +#include + +#include "trace.h" +#include +#include +#include +#include + +#include +#include + +namespace NonLocalizable +{ + const wchar_t ModulePath[] = L"PowerToys.ZoomIt.exe"; + const inline wchar_t ModuleKey[] = L"ZoomIt"; +} + +BOOL APIENTRY DllMain( HMODULE /*hModule*/, + DWORD ul_reason_for_call, + LPVOID /*lpReserved*/ + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + Trace::RegisterProvider(); + break; + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + break; + case DLL_PROCESS_DETACH: + Trace::UnregisterProvider(); + break; + } + return TRUE; + +} + +class ZoomItModuleInterface : public PowertoyModuleIface +{ +public: + // Return the localized display name of the powertoy + virtual PCWSTR get_name() override + { + return app_name.c_str(); + } + + // Return the non localized key of the powertoy, this will be cached by the runner + virtual const wchar_t* get_key() override + { + return app_key.c_str(); + } + + // Return the configured status for the gpo policy for the module + virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override + { + return powertoys_gpo::getConfiguredZoomItEnabledValue(); + } + + // Return JSON with the configuration options. + // These are the settings shown on the settings page along with their current values. + virtual bool get_config(wchar_t* buffer, int* buffer_size) override + { + HINSTANCE hinstance = reinterpret_cast(&__ImageBase); + + // TODO: Read settings from Registry. + + // Create a Settings object. + PowerToysSettings::Settings settings(hinstance, get_name()); + + return settings.serialize_to_buffer(buffer, buffer_size); + } + + // Passes JSON with the configuration settings for the powertoy. + // This is called when the user hits Save on the settings page. + virtual void set_config(const wchar_t*) override + { + try + { + // Parse the input JSON string. + // TODO: Save settings to registry. + } + catch (std::exception&) + { + // Improper JSON. + } + } + + // Enable the powertoy + virtual void enable() + { + Logger::info("ZoomIt enabling"); + Enable(); + } + + // Disable the powertoy + virtual void disable() + { + Logger::info("ZoomIt disabling"); + Disable(true); + } + + // Returns if the powertoy is enabled + virtual bool is_enabled() override + { + return m_enabled; + } + + // Destroy the powertoy and free memory + virtual void destroy() override + { + Disable(false); + delete this; + } + + ZoomItModuleInterface() + { + app_name = L"ZoomIt"; + app_key = NonLocalizable::ModuleKey; + LoggerHelpers::init_logger(app_key, L"ModuleInterface", LogSettings::zoomItLoggerName); + m_reload_settings_event_handle = CreateDefaultEvent(CommonSharedConstants::ZOOMIT_REFRESH_SETTINGS_EVENT); + m_exit_event_handle = CreateDefaultEvent(CommonSharedConstants::ZOOMIT_EXIT_EVENT); + } + +private: + bool is_enabled_by_default() const override + { + return false; + } + + void Enable() + { + m_enabled = true; + + // Log telemetry + Trace::EnableZoomIt(true); + + // Pass the PID. + unsigned long powertoys_pid = GetCurrentProcessId(); + std::wstring executable_args = L""; + executable_args.append(std::to_wstring(powertoys_pid)); + + ResetEvent(m_reload_settings_event_handle); + ResetEvent(m_exit_event_handle); + + SHELLEXECUTEINFOW sei{ sizeof(sei) }; + sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI }; + sei.lpFile = NonLocalizable::ModulePath; + sei.nShow = SW_SHOWNORMAL; + sei.lpParameters = executable_args.data(); + if (ShellExecuteExW(&sei) == false) + { + Logger::error(L"Failed to start zoomIt"); + auto message = get_last_error_message(GetLastError()); + if (message.has_value()) + { + Logger::error(message.value()); + } + } + else + { + m_hProcess = sei.hProcess; + } + + } + + void Disable(bool const traceEvent) + { + m_enabled = false; + + // Log telemetry + if (traceEvent) + { + Trace::EnableZoomIt(false); + } + + // Tell the ZoomIt process to exit. + SetEvent(m_exit_event_handle); + + ResetEvent(m_reload_settings_event_handle); + + // Wait for 1.5 seconds for the process to end correctly and stop etw tracer + WaitForSingleObject(m_hProcess, 1500); + + // If process is still running, terminate it + if (m_hProcess) + { + TerminateProcess(m_hProcess, 0); + m_hProcess = nullptr; + } + + } + + bool is_process_running() + { + return WaitForSingleObject(m_hProcess, 0) == WAIT_TIMEOUT; + } + + virtual void call_custom_action(const wchar_t* action) override + { + try + { + PowerToysSettings::CustomActionObject action_object = + PowerToysSettings::CustomActionObject::from_json_string(action); + + if (action_object.get_name() == L"refresh_settings") + { + SetEvent(m_reload_settings_event_handle); + } + } + catch (std::exception&) + { + Logger::error(L"Failed to parse action. {}", action); + } + } + + std::wstring app_name; + std::wstring app_key; //contains the non localized key of the powertoy + + bool m_enabled = false; + HANDLE m_hProcess = nullptr; + + HANDLE m_reload_settings_event_handle = NULL; + HANDLE m_exit_event_handle = NULL; +}; + +extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create() +{ + return new ZoomItModuleInterface(); +} diff --git a/tools/WebcamReportTool/packages.config b/src/modules/ZoomIt/ZoomItModuleInterface/packages.config similarity index 59% rename from tools/WebcamReportTool/packages.config rename to src/modules/ZoomIt/ZoomItModuleInterface/packages.config index ff4b05964868..09bfc449e21c 100644 --- a/tools/WebcamReportTool/packages.config +++ b/src/modules/ZoomIt/ZoomItModuleInterface/packages.config @@ -1,5 +1,4 @@  - \ No newline at end of file diff --git a/src/modules/videoconference/VideoConferenceModule/pch.cpp b/src/modules/ZoomIt/ZoomItModuleInterface/pch.cpp similarity index 100% rename from src/modules/videoconference/VideoConferenceModule/pch.cpp rename to src/modules/ZoomIt/ZoomItModuleInterface/pch.cpp diff --git a/src/modules/ZoomIt/ZoomItModuleInterface/pch.h b/src/modules/ZoomIt/ZoomItModuleInterface/pch.h new file mode 100644 index 000000000000..93ddcefad54c --- /dev/null +++ b/src/modules/ZoomIt/ZoomItModuleInterface/pch.h @@ -0,0 +1,9 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#include +#include +#include +#include +#include +#include diff --git a/src/modules/ZoomIt/ZoomItModuleInterface/resource.h b/src/modules/ZoomIt/ZoomItModuleInterface/resource.h new file mode 100644 index 000000000000..cf73380cafea --- /dev/null +++ b/src/modules/ZoomIt/ZoomItModuleInterface/resource.h @@ -0,0 +1,13 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by ZoomItModuleInterface.rc + +////////////////////////////// +// Non-localizable + +#define FILE_DESCRIPTION "PowerToys ZoomItModuleInterface" +#define INTERNAL_NAME "PowerToys.ZoomItModuleInterface" +#define ORIGINAL_FILENAME "PowerToys.ZoomItModuleInterface.dll" + +// Non-localizable +////////////////////////////// diff --git a/src/modules/ZoomIt/ZoomItModuleInterface/trace.cpp b/src/modules/ZoomIt/ZoomItModuleInterface/trace.cpp new file mode 100644 index 000000000000..575c9d3338e3 --- /dev/null +++ b/src/modules/ZoomIt/ZoomItModuleInterface/trace.cpp @@ -0,0 +1,93 @@ +#include "pch.h" +#include "trace.h" +#include + +TRACELOGGING_DEFINE_PROVIDER( + g_hProvider, + "Microsoft.PowerToys", + // {38e8889b-9731-53f5-e901-e8a7c1753074} + (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), + TraceLoggingOptionProjectTelemetry()); + +// Log if the user has ZoomIt enabled or disabled +void Trace::EnableZoomIt(const bool enabled) noexcept +{ + TraceLoggingWriteWrapper( + g_hProvider, + "ZoomIt_EnableZoomIt", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), + TraceLoggingBoolean(enabled, "Enabled")); +} + +void Trace::ZoomItStarted() noexcept +{ + TraceLoggingWriteWrapper( + g_hProvider, + "ZoomIt_Started", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); +} + +void Trace::ZoomItActivateBreak() noexcept +{ + TraceLoggingWriteWrapper( + g_hProvider, + "ZoomIt_ActivateBreak", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); +} + +void Trace::ZoomItActivateDraw() noexcept +{ + TraceLoggingWriteWrapper( + g_hProvider, + "ZoomIt_ActivateDraw", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); +} + +void Trace::ZoomItActivateZoom() noexcept +{ + TraceLoggingWriteWrapper( + g_hProvider, + "ZoomIt_ActivateZoom", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); +} + +void Trace::ZoomItActivateLiveZoom() noexcept +{ + TraceLoggingWriteWrapper( + g_hProvider, + "ZoomIt_ActivateLiveZoom", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); +} + +void Trace::ZoomItActivateDemoType() noexcept +{ + TraceLoggingWriteWrapper( + g_hProvider, + "ZoomIt_ActivateDemoType", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); +} + +void Trace::ZoomItActivateRecord() noexcept +{ + TraceLoggingWriteWrapper( + g_hProvider, + "ZoomIt_ActivateRecord", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); +} + +void Trace::ZoomItActivateSnip() noexcept +{ + TraceLoggingWriteWrapper( + g_hProvider, + "ZoomIt_ActivateSnip", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); +} diff --git a/src/modules/ZoomIt/ZoomItModuleInterface/trace.h b/src/modules/ZoomIt/ZoomItModuleInterface/trace.h new file mode 100644 index 000000000000..fafd579a0e65 --- /dev/null +++ b/src/modules/ZoomIt/ZoomItModuleInterface/trace.h @@ -0,0 +1,17 @@ +#pragma once + +#include +class Trace : public telemetry::TraceBase +{ +public: + // Log if the user has ZoomIt enabled or disabled + static void EnableZoomIt(const bool enabled) noexcept; + static void ZoomItStarted() noexcept; + static void ZoomItActivateBreak() noexcept; + static void ZoomItActivateDraw() noexcept; + static void ZoomItActivateZoom() noexcept; + static void ZoomItActivateLiveZoom() noexcept; + static void ZoomItActivateDemoType() noexcept; + static void ZoomItActivateRecord() noexcept; + static void ZoomItActivateSnip() noexcept; +}; diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/PropertySheet.props b/src/modules/ZoomIt/ZoomItSettingsInterop/PropertySheet.props new file mode 100644 index 000000000000..e34141b019cc --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/PropertySheet.props @@ -0,0 +1,16 @@ + + + + + + + + \ No newline at end of file diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.cpp b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.cpp new file mode 100644 index 000000000000..3a197714b782 --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.cpp @@ -0,0 +1,274 @@ +#include "pch.h" +#include "ZoomItSettings.h" +#include "ZoomItSettings.g.cpp" +#include "../ZoomIt/ZoomItSettings.h" +#include +#include +#include +#pragma comment(lib, "Crypt32.lib") // For the CryptStringToBinaryW and CryptBinaryToStringW functions + +namespace winrt::PowerToys::ZoomItSettingsInterop::implementation +{ + ClassRegistry reg(_T("Software\\Sysinternals\\") APPNAME); + + const unsigned int SPECIAL_SEMANTICS_SHORTCUT = 1; + const unsigned int SPECIAL_SEMANTICS_COLOR = 2; + const unsigned int SPECIAL_SEMANTICS_LOG_FONT = 3; + + std::vector base64_decode(const std::wstring& base64_string) + { + DWORD binary_len = 0; + // Get the required buffer size for the binary data + if (!CryptStringToBinaryW(base64_string.c_str(), 0, CRYPT_STRING_BASE64, nullptr, &binary_len, nullptr, nullptr)) + { + throw std::runtime_error("Error in CryptStringToBinaryW (getting size)"); + } + + std::vector binary_data(binary_len); + + // Decode the Base64 string into binary data + if (!CryptStringToBinaryW(base64_string.c_str(), 0, CRYPT_STRING_BASE64, binary_data.data(), &binary_len, nullptr, nullptr)) + { + throw std::runtime_error("Error in CryptStringToBinaryW (decoding)"); + } + + return binary_data; + } + + std::wstring base64_encode(const unsigned char* data, size_t length) + { + DWORD base64_len = 0; + // Get the required buffer size for Base64 string + if (!CryptBinaryToStringW(data, static_cast(length), CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, nullptr, &base64_len)) + { + throw std::runtime_error("Error in CryptBinaryToStringW (getting size)"); + } + + std::wstring base64_string(base64_len, '\0'); + + // Encode the binary data to Base64 + if (!CryptBinaryToStringW(data, static_cast(length), CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, &base64_string[0], &base64_len)) + { + throw std::runtime_error("Error in CryptBinaryToStringW (encoding)"); + } + + // Resize the wstring to remove any trailing null character. + if (!base64_string.empty() && base64_string.back() == L'\0') + { + base64_string.pop_back(); + } + + return base64_string; + } + + std::map settings_with_special_semantics = { + { L"ToggleKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"LiveZoomToggleKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"DrawToggleKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"RecordToggleKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"SnipToggleKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"BreakTimerKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"DemoTypeToggleKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"PenColor", SPECIAL_SEMANTICS_COLOR }, + { L"BreakPenColor", SPECIAL_SEMANTICS_COLOR }, + { L"Font", SPECIAL_SEMANTICS_LOG_FONT }, + }; + + hstring ZoomItSettings::LoadSettingsJson() + { + PowerToysSettings::PowerToyValues _settings(L"ZoomIt",L"ZoomIt"); + reg.ReadRegSettings(RegSettings); + PREG_SETTING curSetting = RegSettings; + while (curSetting->ValueName) + { + switch (curSetting->Type) + { + case SETTING_TYPE_DWORD: + { + auto special_semantics = settings_with_special_semantics.find(curSetting->ValueName); + DWORD value = *static_cast(curSetting->Setting); + if (special_semantics == settings_with_special_semantics.end()) + { + _settings.add_property(curSetting->ValueName, value); + } + else + { + if (special_semantics->second == SPECIAL_SEMANTICS_SHORTCUT) + { + auto hotkey = PowerToysSettings::HotkeyObject::from_settings( + value & (HOTKEYF_EXT << 8), //WIN + value & (HOTKEYF_CONTROL << 8), + value & (HOTKEYF_ALT << 8), + value & (HOTKEYF_SHIFT << 8), + value & 0xFF); + _settings.add_property(curSetting->ValueName, hotkey.get_json()); + } + else if (special_semantics->second == SPECIAL_SEMANTICS_COLOR) + { + // PowerToys settings likes colors as #FFFFFF strings. + hstring s = winrt::to_hstring(std::format("#{:02x}{:02x}{:02x}", value & 0xFF, (value >> 8) & 0xFF, (value >> 16) & 0xFF)); + _settings.add_property(curSetting->ValueName, s); + } + } + break; + } + case SETTING_TYPE_BOOLEAN: + _settings.add_property(curSetting->ValueName, *static_cast(curSetting->Setting)); + break; + case SETTING_TYPE_DOUBLE: + assert(false); // ZoomIt doesn't use this type of setting. + break; + case SETTING_TYPE_WORD: + assert(false); // ZoomIt doesn't use this type of setting. + break; + case SETTING_TYPE_STRING: + _settings.add_property(curSetting->ValueName, static_cast(curSetting->Setting)); + break; + case SETTING_TYPE_DWORD_ARRAY: + assert(false); // ZoomIt doesn't use this type of setting. + break; + case SETTING_TYPE_WORD_ARRAY: + assert(false); // ZoomIt doesn't use this type of setting. + break; + case SETTING_TYPE_BINARY: + auto special_semantics = settings_with_special_semantics.find(curSetting->ValueName); + if (special_semantics != settings_with_special_semantics.end() && special_semantics->second == SPECIAL_SEMANTICS_LOG_FONT) + { + // This is the font setting. It's a special case where the default value needs to be calculated if it's still 0. + if (g_LogFont.lfFaceName[0] == L'\0') + { + GetObject(GetStockObject(DEFAULT_GUI_FONT), sizeof g_LogFont, &g_LogFont); + g_LogFont.lfWeight = FW_NORMAL; + auto hDc = CreateCompatibleDC(NULL); + g_LogFont.lfHeight = -MulDiv(8, GetDeviceCaps(hDc, LOGPIXELSY), 72); + DeleteDC(hDc); + } + } + + // Base64 encoding is likely the best way to serialize a byte array into JSON. + auto encodedFont = base64_encode(static_cast(curSetting->Setting), curSetting->Size); + _settings.add_property(curSetting->ValueName, encodedFont); + break; + } + curSetting++; + } + + return _settings.get_raw_json().Stringify(); + } + + void ZoomItSettings::SaveSettingsJson(hstring json) + { + reg.ReadRegSettings(RegSettings); + + // Parse the input JSON string. + PowerToysSettings::PowerToyValues valuesFromSettings = + PowerToysSettings::PowerToyValues::from_json_string(json, L"ZoomIt"); + + PREG_SETTING curSetting = RegSettings; + while (curSetting->ValueName) + { + switch (curSetting->Type) + { + case SETTING_TYPE_DWORD: + { + auto special_semantics = settings_with_special_semantics.find(curSetting->ValueName); + if (special_semantics == settings_with_special_semantics.end()) + { + auto possibleValue = valuesFromSettings.get_uint_value(curSetting->ValueName); + if (possibleValue.has_value()) + { + *static_cast(curSetting->Setting) = possibleValue.value(); + } + } + else + { + if (special_semantics->second == SPECIAL_SEMANTICS_SHORTCUT) + { + auto possibleValue = valuesFromSettings.get_json(curSetting->ValueName); + if (possibleValue.has_value()) + { + auto hotkey = PowerToysSettings::HotkeyObject::from_json(possibleValue.value()); + unsigned int value = 0; + value |= hotkey.get_code(); + if (hotkey.ctrl_pressed()) + { + value |= (HOTKEYF_CONTROL << 8); + } + if (hotkey.alt_pressed()) + { + value |= (HOTKEYF_ALT << 8); + } + if (hotkey.shift_pressed()) + { + value |= (HOTKEYF_SHIFT << 8); + } + if (hotkey.win_pressed()) + { + value |= (HOTKEYF_EXT << 8); + } + *static_cast(curSetting->Setting) = value; + } + } + else if (special_semantics->second == SPECIAL_SEMANTICS_COLOR) + { + auto possibleValue = valuesFromSettings.get_string_value(curSetting->ValueName); + if (possibleValue.has_value()) + { + uint8_t r, g, b; + if (checkValidRGB(possibleValue.value(), &r, &g, &b)) + { + *static_cast(curSetting->Setting) = RGB(r, g, b); + } + + } + } + } + break; + } + case SETTING_TYPE_BOOLEAN: + { + auto possibleValue = valuesFromSettings.get_bool_value(curSetting->ValueName); + if (possibleValue.has_value()) + { + *static_cast(curSetting->Setting) = static_cast(possibleValue.value()); + } + break; + } + case SETTING_TYPE_DOUBLE: + assert(false); // ZoomIt doesn't use this type of setting. + break; + case SETTING_TYPE_WORD: + assert(false); // ZoomIt doesn't use this type of setting. + break; + case SETTING_TYPE_STRING: + { + auto possibleValue = valuesFromSettings.get_string_value(curSetting->ValueName); + if (possibleValue.has_value()) + { + const TCHAR* value = possibleValue.value().c_str(); + _tcscpy_s(static_cast(curSetting->Setting), curSetting->Size / sizeof(TCHAR), value); + } + break; + } + case SETTING_TYPE_DWORD_ARRAY: + assert(false); // ZoomIt doesn't use this type of setting. + break; + case SETTING_TYPE_WORD_ARRAY: + assert(false); // ZoomIt doesn't use this type of setting. + break; + case SETTING_TYPE_BINARY: + auto possibleValue = valuesFromSettings.get_string_value(curSetting->ValueName); + if (possibleValue.has_value()) + { + // Base64 encoding is likely the best way to serialize a byte array into JSON. + auto decodedValue = base64_decode(possibleValue.value()); + assert(curSetting->Size == decodedValue.size()); // Should right now only be used for LOGFONT, so let's hard check it to avoid any insecure overflows. + memcpy(static_cast(curSetting->Setting), decodedValue.data(), decodedValue.size()); + } + break; + } + curSetting++; + } + reg.WriteRegSettings(RegSettings); + } +} diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.h b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.h new file mode 100644 index 000000000000..9ea60451c002 --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.h @@ -0,0 +1,20 @@ +#pragma once + +#include "ZoomItSettings.g.h" + +namespace winrt::PowerToys::ZoomItSettingsInterop::implementation +{ + struct ZoomItSettings : ZoomItSettingsT + { + ZoomItSettings() = default; + static hstring LoadSettingsJson(); + static void SaveSettingsJson(hstring json); + }; +} + +namespace winrt::PowerToys::ZoomItSettingsInterop::factory_implementation +{ + struct ZoomItSettings : ZoomItSettingsT + { + }; +} diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.idl b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.idl new file mode 100644 index 000000000000..bd4d1915db20 --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.idl @@ -0,0 +1,10 @@ +namespace PowerToys +{ + namespace ZoomItSettingsInterop + { + [default_interface] static runtimeclass ZoomItSettings { + static String LoadSettingsJson(); + static void SaveSettingsJson(String json); + } + } +} diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.def b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.def new file mode 100644 index 000000000000..24e7c1235c39 --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.def @@ -0,0 +1,3 @@ +EXPORTS +DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE +DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE diff --git a/tools/WebcamReportTool/WebcamReportTool.rc b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.rc similarity index 95% rename from tools/WebcamReportTool/WebcamReportTool.rc rename to src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.rc index 21e9822dda9a..5fa3c8b90d58 100644 --- a/tools/WebcamReportTool/WebcamReportTool.rc +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.rc @@ -1,6 +1,6 @@ #include #include "resource.h" -#include "../../../src/common/version/version.h" +#include "../../../common/version/version.h" #define APSTUDIO_READONLY_SYMBOLS #include "winres.h" diff --git a/src/modules/videoconference/VideoConferenceShared/VideoConferenceShared.vcxproj b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.vcxproj similarity index 50% rename from src/modules/videoconference/VideoConferenceShared/VideoConferenceShared.vcxproj rename to src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.vcxproj index a888f9087712..21998a40dae8 100644 --- a/src/modules/videoconference/VideoConferenceShared/VideoConferenceShared.vcxproj +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.vcxproj @@ -1,49 +1,36 @@ - + - - - Debug - Win32 - - - Debug - x64 - - - Debug - ARM64 - - - Release - Win32 - - - Release - x64 - - - Release - ARM64 - - - - - mfplat.lib;Mfsensorgroup.lib;Mf.lib;Shlwapi.lib;Strmiids.lib;%(AdditionalDependencies); - - - 16.0 - Win32Proj - {459e0768-7ebd-4c41-bba1-6db3b3815e0a} - VideoConferenceShared + true + true + true + true + {ca7d8106-30B9-4aec-9d05-b69b31b8c461} + ZoomItSettingsInterop + PowerToys.ZoomItSettingsInterop + en-US + 14.0 + false + false + Windows Store + 10.0 - - StaticLibrary - true + + DynamicLibrary v143 Unicode + false + + + true + true + + + false + true + false @@ -53,87 +40,83 @@ + + + - - ..\..\..\..\$(Platform)\$(Configuration)\ - - - ..\..\..\..\x86\$(Configuration)\ - - true + PowerToys.ZoomItSettingsInterop + ..\..\..\..\$(Platform)\$(Configuration)\ - NotUsing - - - - + $(IntDir)pch.pch Level4 - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDebug - true - $(SolutionDir)\src\; + %(AdditionalOptions) /bigobj + _WINRT_DLL;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions) + ../../..;%(AdditionalIncludeDirectories) + $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) Console - true + false + ZoomItSettingsInterop.def + Shell32.lib;gdi32.lib;%(AdditionalDependencies) - - true - + + + + _DEBUG;%(PreprocessorDefinitions) + - Level4 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - true - $(SolutionDir)\src\;%(AdditionalIncludeDirectories) - ProgramDatabase + NDEBUG;%(PreprocessorDefinitions) - Console true true - true - - true - - - - - - - - + + + ZoomItSettings.idl + + - - - - - - - - - - + + Create + + + ZoomItSettings.idl + + + + + + + + + + + + + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} + + + {6955446d-23f7-4023-9bb3-8657f904af99} + + + + + diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.vcxproj.filters b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.vcxproj.filters new file mode 100644 index 000000000000..056f948c9572 --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.vcxproj.filters @@ -0,0 +1,35 @@ + + + + + {de682ddf-17ab-471d-9761-82b42e6baa70} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + {c02d42a3-682e-499a-8b28-638a0802d43f} + + + + + + + + + + + + + + + + + + + + + + + Resources + + + \ No newline at end of file diff --git a/src/modules/videoconference/VideoConferenceModule/packages.config b/src/modules/ZoomIt/ZoomItSettingsInterop/packages.config similarity index 100% rename from src/modules/videoconference/VideoConferenceModule/packages.config rename to src/modules/ZoomIt/ZoomItSettingsInterop/packages.config diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/pch.cpp b/src/modules/ZoomIt/ZoomItSettingsInterop/pch.cpp new file mode 100644 index 000000000000..bcb5590be1b3 --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/pch.h b/src/modules/ZoomIt/ZoomItSettingsInterop/pch.h new file mode 100644 index 000000000000..ea0275969f54 --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/pch.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include +#include +#include + +#define GDIPVER 0x0110 +#include +// DirectX +#include +#include +#include + +// Must come before C++/WinRT +#include + +#include + +#include +#include diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/resource.h b/src/modules/ZoomIt/ZoomItSettingsInterop/resource.h new file mode 100644 index 000000000000..73711ef9a9a7 --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/resource.h @@ -0,0 +1,13 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by ZoomItSettingsInterop.rc + +////////////////////////////// +// Non-localizable + +#define FILE_DESCRIPTION "PowerToys ZoomItSettingsInterop" +#define INTERNAL_NAME "PowerToys.ZoomItSettingsInterop" +#define ORIGINAL_FILENAME "PowerToys.ZoomItSettingsInterop.dll" + +// Non-localizable +////////////////////////////// diff --git a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.cpp b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.cpp index 491a0bdf4272..8287ee1cced8 100644 --- a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.cpp +++ b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.cpp @@ -9,7 +9,6 @@ #include #include -#include #include #include @@ -36,7 +35,8 @@ AlwaysOnTop::AlwaysOnTop(bool useLLKH, DWORD mainThreadId) : SettingsObserver({SettingId::FrameEnabled, SettingId::Hotkey, SettingId::ExcludeApps}), m_hinstance(reinterpret_cast(&__ImageBase)), m_useCentralizedLLKH(useLLKH), - m_mainThreadId(mainThreadId) + m_mainThreadId(mainThreadId), + m_notificationUtil(std::make_unique()) { s_instance = this; DPIAware::EnableDPIAwarenessForThisProcess(); @@ -64,6 +64,7 @@ AlwaysOnTop::AlwaysOnTop(bool useLLKH, DWORD mainThreadId) : AlwaysOnTop::~AlwaysOnTop() { m_running = false; + m_notificationUtil.reset(); if (m_hPinEvent) { @@ -509,7 +510,10 @@ void AlwaysOnTop::HandleWinHookEvent(WinHookEvent* data) noexcept { if (!is_process_elevated() && IsProcessOfWindowElevated(data->hwnd)) { - notifications::WarnIfElevationIsRequired(GET_RESOURCE_STRING(IDS_ALWAYSONTOP), GET_RESOURCE_STRING(IDS_SYSTEM_FOREGROUND_ELEVATED), GET_RESOURCE_STRING(IDS_SYSTEM_FOREGROUND_ELEVATED_LEARN_MORE), GET_RESOURCE_STRING(IDS_SYSTEM_FOREGROUND_ELEVATED_DIALOG_DONT_SHOW_AGAIN)); + m_notificationUtil->WarnIfElevationIsRequired(GET_RESOURCE_STRING(IDS_ALWAYSONTOP), + GET_RESOURCE_STRING(IDS_SYSTEM_FOREGROUND_ELEVATED), + GET_RESOURCE_STRING(IDS_SYSTEM_FOREGROUND_ELEVATED_LEARN_MORE), + GET_RESOURCE_STRING(IDS_SYSTEM_FOREGROUND_ELEVATED_DIALOG_DONT_SHOW_AGAIN)); } RefreshBorders(); } diff --git a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.h b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.h index da14d508b2c1..0505c837a282 100644 --- a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.h +++ b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.h @@ -9,6 +9,7 @@ #include #include +#include class AlwaysOnTop : public SettingsObserver { @@ -53,6 +54,7 @@ class AlwaysOnTop : public SettingsObserver std::thread m_thread; const bool m_useCentralizedLLKH; bool m_running = true; + std::unique_ptr m_notificationUtil; LRESULT WndProc(HWND, UINT, WPARAM, LPARAM) noexcept; void HandleWinHookEvent(WinHookEvent* data) noexcept; diff --git a/src/modules/fancyzones/FancyZonesLib/FancyZones.cpp b/src/modules/fancyzones/FancyZonesLib/FancyZones.cpp index d0839f2844d8..1956c57a97fb 100644 --- a/src/modules/fancyzones/FancyZonesLib/FancyZones.cpp +++ b/src/modules/fancyzones/FancyZonesLib/FancyZones.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -185,6 +186,8 @@ struct FancyZones : public winrt::implements m_notificationUtil; + // If non-recoverable error occurs, trigger disabling of entire FancyZones. static std::function disableModuleCallback; @@ -266,6 +269,8 @@ FancyZones::Run() noexcept } }); + m_notificationUtil = std::make_unique(); + SyncVirtualDesktops(); // id format of applied-layouts and app-zone-history was changed in 0.60 @@ -288,6 +293,8 @@ FancyZones::Destroy() noexcept m_window = nullptr; } + m_notificationUtil.reset(); + CoUninitialize(); } @@ -302,7 +309,7 @@ FancyZones::VirtualDesktopChanged() noexcept void FancyZones::MoveSizeStart(HWND window, HMONITOR monitor) { - m_windowMouseSnapper = WindowMouseSnap::Create(window, m_workAreaConfiguration.GetAllWorkAreas()); + m_windowMouseSnapper = WindowMouseSnap::Create(window, m_workAreaConfiguration.GetAllWorkAreas(), m_notificationUtil.get()); if (m_windowMouseSnapper) { if (FancyZonesSettings::settings().spanZonesAcrossMonitors) diff --git a/src/modules/fancyzones/FancyZonesLib/WindowMouseSnap.cpp b/src/modules/fancyzones/FancyZonesLib/WindowMouseSnap.cpp index e127371347fb..eb2a431313e5 100644 --- a/src/modules/fancyzones/FancyZonesLib/WindowMouseSnap.cpp +++ b/src/modules/fancyzones/FancyZonesLib/WindowMouseSnap.cpp @@ -11,7 +11,7 @@ #include #include -#include +#include WindowMouseSnap::WindowMouseSnap(HWND window, const std::unordered_map>& activeWorkAreas) : m_window(window), @@ -27,7 +27,7 @@ WindowMouseSnap::~WindowMouseSnap() ResetWindowTransparency(); } -std::unique_ptr WindowMouseSnap::Create(HWND window, const std::unordered_map>& activeWorkAreas) +std::unique_ptr WindowMouseSnap::Create(HWND window, const std::unordered_map>& activeWorkAreas, notifications::NotificationUtil* notificationUtil) { if (FancyZonesWindowUtils::IsCursorTypeIndicatingSizeEvent() || !FancyZonesWindowProcessing::IsProcessableManually(window)) { @@ -36,8 +36,15 @@ std::unique_ptr WindowMouseSnap::Create(HWND window, const std: if (!is_process_elevated() && IsProcessOfWindowElevated(window)) { - // Notifies user if unable to drag elevated window - notifications::WarnIfElevationIsRequired(GET_RESOURCE_STRING(IDS_FANCYZONES), GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED), GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_LEARN_MORE), GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_DIALOG_DONT_SHOW_AGAIN)); + if (notificationUtil != nullptr) + { + // Notifies user if unable to drag elevated window + notificationUtil->WarnIfElevationIsRequired(GET_RESOURCE_STRING(IDS_FANCYZONES), + GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED), + GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_LEARN_MORE), + GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_DIALOG_DONT_SHOW_AGAIN)); + } + return nullptr; } diff --git a/src/modules/fancyzones/FancyZonesLib/WindowMouseSnap.h b/src/modules/fancyzones/FancyZonesLib/WindowMouseSnap.h index cf8f2615ac2a..e7e5365b19d9 100644 --- a/src/modules/fancyzones/FancyZonesLib/WindowMouseSnap.h +++ b/src/modules/fancyzones/FancyZonesLib/WindowMouseSnap.h @@ -1,6 +1,7 @@ #pragma once #include +#include class WorkArea; @@ -9,7 +10,7 @@ class WindowMouseSnap WindowMouseSnap(HWND window, const std::unordered_map>& activeWorkAreas); public: - static std::unique_ptr Create(HWND window, const std::unordered_map>& activeWorkAreas); + static std::unique_ptr Create(HWND window, const std::unordered_map>& activeWorkAreas, notifications::NotificationUtil* notificationUtil); ~WindowMouseSnap(); bool MoveSizeStart(HMONITOR monitor, bool isSnapping); diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/InputParser.cs b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/InputParser.cs index e8bf4a577ad1..614627c1ff5d 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/InputParser.cs +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/InputParser.cs @@ -146,7 +146,7 @@ public IComputeRequest ParseInput(Query query) // This is only for single chars if (content.Length > 1) { - throw new ArgumentException($"Invalid Query: {query.RawUserQuery} (To many characters.)"); + throw new ArgumentException($"Invalid Query: {query.RawUserQuery} (Too many characters.)"); } else if (content.Length == 0) { diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest/ExtendedCalculatorParserTests.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest/ExtendedCalculatorParserTests.cs index b13072021b24..594773c36bc8 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest/ExtendedCalculatorParserTests.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest/ExtendedCalculatorParserTests.cs @@ -279,5 +279,67 @@ public void Interpret_TestScientificNotation_WhenCalled(string input, string sou Assert.IsNotNull(result); Assert.AreEqual(expectedResult, result.Result); } + + [DataTestMethod] + [DataRow("sin(90)", "sin((pi / 180) * (90))")] + [DataRow("arcsin(0.5)", "(180 / pi) * (arcsin(0.5))")] + [DataRow("sin(sin(30))", "sin((pi / 180) * (sin((pi / 180) * (30))))")] + [DataRow("cos(tan(45))", "cos((pi / 180) * (tan((pi / 180) * (45))))")] + [DataRow("arctan(sin(30))", "(180 / pi) * (arctan(sin((pi / 180) * (30))))")] + [DataRow("sin(cos(tan(30)))", "sin((pi / 180) * (cos((pi / 180) * (tan((pi / 180) * (30))))))")] + [DataRow("sin(arcsin(0.5))", "sin((pi / 180) * ((180 / pi) * (arcsin(0.5))))")] + [DataRow("sin(30) + cos(60)", "sin((pi / 180) * (30)) + cos((pi / 180) * (60))")] + [DataRow("sin(30 + 15)", "sin((pi / 180) * (30 + 15))")] + [DataRow("sin(45) * cos(45) - tan(30)", "sin((pi / 180) * (45)) * cos((pi / 180) * (45)) - tan((pi / 180) * (30))")] + [DataRow("arcsin(arccos(0.5))", "(180 / pi) * (arcsin((180 / pi) * (arccos(0.5))))")] + [DataRow("sin(sin(sin(30)))", "sin((pi / 180) * (sin((pi / 180) * (sin((pi / 180) * (30))))))")] + [DataRow("log(10)", "log(10)")] + [DataRow("sin(30) + pi", "sin((pi / 180) * (30)) + pi")] + [DataRow("sin(-30)", "sin((pi / 180) * (-30))")] + [DataRow("sin((30))", "sin((pi / 180) * ((30)))")] + [DataRow("arcsin(1) * 2", "(180 / pi) * (arcsin(1)) * 2")] + [DataRow("cos(1/2)", "cos((pi / 180) * (1/2))")] + [DataRow("sin ( 90 )", "sin ((pi / 180) * ( 90 ))")] + [DataRow("cos(arcsin(sin(45)))", "cos((pi / 180) * ((180 / pi) * (arcsin(sin((pi / 180) * (45))))))")] + public void UpdateTrigFunctions_Degrees(string input, string expectedResult) + { + // Call UpdateTrigFunctions in degrees mode + string result = CalculateHelper.UpdateTrigFunctions(input, CalculateEngine.TrigMode.Degrees); + + // Assert + Assert.IsNotNull(result); + Assert.AreEqual(expectedResult, result); + } + + [DataTestMethod] + [DataRow("sin(90)", "sin((pi / 200) * (90))")] + [DataRow("arcsin(0.5)", "(200 / pi) * (arcsin(0.5))")] + [DataRow("sin(sin(30))", "sin((pi / 200) * (sin((pi / 200) * (30))))")] + [DataRow("cos(tan(45))", "cos((pi / 200) * (tan((pi / 200) * (45))))")] + [DataRow("arctan(sin(30))", "(200 / pi) * (arctan(sin((pi / 200) * (30))))")] + [DataRow("sin(cos(tan(30)))", "sin((pi / 200) * (cos((pi / 200) * (tan((pi / 200) * (30))))))")] + [DataRow("sin(arcsin(0.5))", "sin((pi / 200) * ((200 / pi) * (arcsin(0.5))))")] + [DataRow("sin(30) + cos(60)", "sin((pi / 200) * (30)) + cos((pi / 200) * (60))")] + [DataRow("sin(30 + 15)", "sin((pi / 200) * (30 + 15))")] + [DataRow("sin(45) * cos(45) - tan(30)", "sin((pi / 200) * (45)) * cos((pi / 200) * (45)) - tan((pi / 200) * (30))")] + [DataRow("arcsin(arccos(0.5))", "(200 / pi) * (arcsin((200 / pi) * (arccos(0.5))))")] + [DataRow("sin(sin(sin(30)))", "sin((pi / 200) * (sin((pi / 200) * (sin((pi / 200) * (30))))))")] + [DataRow("log(10)", "log(10)")] + [DataRow("sin(30) + pi", "sin((pi / 200) * (30)) + pi")] + [DataRow("sin(-30)", "sin((pi / 200) * (-30))")] + [DataRow("sin((30))", "sin((pi / 200) * ((30)))")] + [DataRow("arcsin(1) * 2", "(200 / pi) * (arcsin(1)) * 2")] + [DataRow("cos(1/2)", "cos((pi / 200) * (1/2))")] + [DataRow("sin ( 90 )", "sin ((pi / 200) * ( 90 ))")] + [DataRow("cos(arcsin(sin(45)))", "cos((pi / 200) * ((200 / pi) * (arcsin(sin((pi / 200) * (45))))))")] + public void UpdateTrigFunctions_Gradians(string input, string expectedResult) + { + // Call UpdateTrigFunctions in gradians mode + string result = CalculateHelper.UpdateTrigFunctions(input, CalculateEngine.TrigMode.Gradians); + + // Assert + Assert.IsNotNull(result); + Assert.AreEqual(expectedResult, result); + } } } diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/CalculateEngine.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/CalculateEngine.cs index 815a52d8b0b5..9248e3ca89b0 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/CalculateEngine.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/CalculateEngine.cs @@ -23,6 +23,13 @@ public class CalculateEngine public const int RoundingDigits = 10; + public enum TrigMode + { + Radians, + Degrees, + Gradians, + } + /// /// Interpret /// @@ -52,6 +59,9 @@ public CalculateResult Interpret(string input, CultureInfo cultureInfo, out stri input = CalculateHelper.FixHumanMultiplicationExpressions(input); + // Modify trig functions depending on angle unit setting + input = CalculateHelper.UpdateTrigFunctions(input, Main.GetTrigMode()); + var result = _magesEngine.Interpret(input); // This could happen for some incorrect queries, like pi(2) diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/CalculateHelper.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/CalculateHelper.cs index 436591e3b333..95705a34ca13 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/CalculateHelper.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/CalculateHelper.cs @@ -25,6 +25,11 @@ public static class CalculateHelper @")+$", RegexOptions.Compiled); + private const string DegToRad = "(pi / 180) * "; + private const string GradToRad = "(pi / 200) * "; + private const string RadToDeg = "(180 / pi) * "; + private const string RadToGrad = "(200 / pi) * "; + public static bool InputValid(string input) { if (string.IsNullOrWhiteSpace(input)) @@ -204,5 +209,86 @@ private static string CheckConstantThenConstant(string input) return output; } + + // Gets the index of the closing bracket of a function + private static int FindClosingBracketIndex(string input, int start) + { + int bracketCount = 0; // Set count to zero + for (int i = start; i < input.Length; i++) + { + if (input[i] == '(') + { + bracketCount++; + } + else if (input[i] == ')') + { + bracketCount--; + if (bracketCount == 0) + { + return i; + } + } + } + + return -1; // Unmatched brackets + } + + private static string ModifyTrigFunction(string input, string function, string modification) + { + // Get the RegEx pattern to match, depending on whether the function is inverse or normal + string pattern = function.StartsWith("arc", StringComparison.Ordinal) ? string.Empty : @"(? Resources.wox_plugin_calculator_plugin_name; @@ -67,6 +69,20 @@ public class Main : IPlugin, IPluginI18n, IDisposable, ISettingProvider DisplayDescription = Resources.wox_plugin_calculator_replace_input_description, Value = true, }, + new PluginAdditionalOption + { + Key = TrigMode, + DisplayLabel = Resources.wox_plugin_calculator_trig_unit_mode, + DisplayDescription = Resources.wox_plugin_calculator_trig_unit_mode_description, + PluginOptionType = PluginAdditionalOption.AdditionalOptionType.Combobox, + ComboBoxValue = (int)CalculateEngine.TrigMode.Radians, + ComboBoxItems = + [ + new KeyValuePair(Resources.wox_plugin_calculator_trig_unit_radians, "0"), + new KeyValuePair(Resources.wox_plugin_calculator_trig_unit_degrees, "1"), + new KeyValuePair(Resources.wox_plugin_calculator_trig_unit_gradians, "2"), + ], + }, }; public List Query(Query query) @@ -183,6 +199,7 @@ public void UpdateSettings(PowerLauncherPluginSettings settings) var inputUseEnglishFormat = false; var outputUseEnglishFormat = false; var replaceInput = true; + var trigMode = CalculateEngine.TrigMode.Radians; if (settings != null && settings.AdditionalOptions != null) { @@ -194,11 +211,20 @@ public void UpdateSettings(PowerLauncherPluginSettings settings) var optionReplaceInput = settings.AdditionalOptions.FirstOrDefault(x => x.Key == ReplaceInput); replaceInput = optionReplaceInput?.Value ?? replaceInput; + + var optionTrigMode = settings.AdditionalOptions.FirstOrDefault(x => x.Key == TrigMode); + trigMode = (CalculateEngine.TrigMode)int.Parse(optionTrigMode.ComboBoxValue.ToString(CultureInfo.InvariantCulture), CultureInfo.InvariantCulture); } _inputUseEnglishFormat = inputUseEnglishFormat; _outputUseEnglishFormat = outputUseEnglishFormat; _replaceInput = replaceInput; + _trigMode = trigMode; + } + + public static CalculateEngine.TrigMode GetTrigMode() + { + return _trigMode; } public void Dispose() diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.Designer.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.Designer.cs index b48a3f417ec3..861993dbdd33 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.Designer.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.Designer.cs @@ -203,5 +203,50 @@ public static string wox_plugin_calculator_replace_input_description { return ResourceManager.GetString("wox_plugin_calculator_replace_input_description", resourceCulture); } } + + /// + /// Looks up a localized string similar to Degrees. + /// + public static string wox_plugin_calculator_trig_unit_degrees { + get { + return ResourceManager.GetString("wox_plugin_calculator_trig_unit_degrees", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Gradians. + /// + public static string wox_plugin_calculator_trig_unit_gradians { + get { + return ResourceManager.GetString("wox_plugin_calculator_trig_unit_gradians", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Trigonometry Unit. + /// + public static string wox_plugin_calculator_trig_unit_mode { + get { + return ResourceManager.GetString("wox_plugin_calculator_trig_unit_mode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Specifies the angle unit to use for trigonometry operations.. + /// + public static string wox_plugin_calculator_trig_unit_mode_description { + get { + return ResourceManager.GetString("wox_plugin_calculator_trig_unit_mode_description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Radians. + /// + public static string wox_plugin_calculator_trig_unit_radians { + get { + return ResourceManager.GetString("wox_plugin_calculator_trig_unit_radians", resourceCulture); + } + } } } diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.resx b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.resx index 727603ab04d6..3c56eedf4b5d 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.resx +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.resx @@ -167,4 +167,24 @@ When using direct activation, appending '=' to the expression will replace the input with the calculated result (e.g. '=5*3-2=' will change the query to '=13'). + + Trigonometry Unit + Title text for trig unit mode. + + + Specifies the angle unit to use for trigonometry operations + Description text for trig mode setting. + + + Radians + Text for angle unit. + + + Degrees + Text to use for angle unit. + + + Gradians + Text for angle unit. + \ No newline at end of file diff --git a/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherShowEvent.cs b/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherShowEvent.cs index de9d8a9f98ff..8882c5f0ecae 100644 --- a/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherShowEvent.cs +++ b/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherShowEvent.cs @@ -12,6 +12,13 @@ namespace Microsoft.PowerLauncher.Telemetry [EventData] public class LauncherShowEvent : EventBase, IEvent { + public LauncherShowEvent(string hotkey) + { + Hotkey = hotkey; + } + + public string Hotkey { get; private set; } + public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage; } } diff --git a/src/modules/launcher/PowerLauncher/App.xaml b/src/modules/launcher/PowerLauncher/App.xaml index 052ea24ea097..23871bda7fe7 100644 --- a/src/modules/launcher/PowerLauncher/App.xaml +++ b/src/modules/launcher/PowerLauncher/App.xaml @@ -8,6 +8,7 @@ + diff --git a/src/modules/launcher/PowerLauncher/Helper/AnimationFactorToValueConverter.cs b/src/modules/launcher/PowerLauncher/Helper/AnimationFactorToValueConverter.cs deleted file mode 100644 index 3987f1c3bf7b..000000000000 --- a/src/modules/launcher/PowerLauncher/Helper/AnimationFactorToValueConverter.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// https://github.com/dotnet/wpf/blob/main/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Controls/AnimationFactorToValueConverter.cs -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Data; - -#pragma warning disable IDE0130 // Namespace does not match folder structure -namespace Fluent.Controls -#pragma warning restore IDE0130 // Namespace does not match folder structure -{ - internal sealed class AnimationFactorToValueConverter : IMultiValueConverter - { - public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) - { - if (values[0] is not double completeValue) - { - return 0.0; - } - - if (values[1] is not double factor) - { - return 0.0; - } - - if (parameter is "negative") - { - factor = -factor; - } - - return factor * completeValue; - } - - public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/src/modules/launcher/PowerLauncher/Helper/FallbackBrushConverter.cs b/src/modules/launcher/PowerLauncher/Helper/FallbackBrushConverter.cs deleted file mode 100644 index a9e3b06a80c1..000000000000 --- a/src/modules/launcher/PowerLauncher/Helper/FallbackBrushConverter.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// Copied from https://github.com/dotnet/wpf/blob/main/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Controls/FallbackBrushConverter.cs -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using System.Windows.Data; - -using System.Windows.Media; - -#pragma warning disable IDE0130 // Namespace does not match folder structure -namespace Fluent.Controls -#pragma warning restore IDE0130 // Namespace does not match folder structure -{ - internal sealed class FallbackBrushConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - if (value is SolidColorBrush brush) - { - return brush; - } - - if (value is Color color) - { - return new SolidColorBrush(color); - } - - // We draw red to visibly see an invalid bind in the UI. - return Brushes.Red; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/src/modules/launcher/PowerLauncher/Helper/ThemeManager.cs b/src/modules/launcher/PowerLauncher/Helper/ThemeManager.cs index 4f7ff85b47cf..66a71b5b0af0 100644 --- a/src/modules/launcher/PowerLauncher/Helper/ThemeManager.cs +++ b/src/modules/launcher/PowerLauncher/Helper/ThemeManager.cs @@ -36,37 +36,20 @@ private void OnUserPreferenceChanged(object sender, UserPreferenceChangedEventAr { if (e.Category == UserPreferenceCategory.General) { - // When switching from high contrast to dark mode we have to use UserPreferenceCategory.General otherwise it will crash when loading fluent.xaml UpdateTheme(); } - else if (e.Category == UserPreferenceCategory.Color) - { - // https://github.com/dotnet/wpf/issues/10043 When switching to high contrast we have to use UserPreferenceCategory.Color or it will crash due to fluent.xaml being already loaded. - if (_currentTheme is ManagedCommon.Theme.Dark or ManagedCommon.Theme.Light) - { - UpdateTheme(); - } - } } private void SetSystemTheme(ManagedCommon.Theme theme) { _mainWindow.Background = OSVersionHelper.IsWindows11() is false ? SystemColors.WindowBrush : null; - _mainWindow.Resources.MergedDictionaries.Clear(); - _mainWindow.Resources.MergedDictionaries.Add(new ResourceDictionary - { - Source = new Uri("Styles/Styles.xaml", UriKind.Relative), - }); + // Need to disable WPF0001 since setting Application.Current.ThemeMode is experimental + // https://learn.microsoft.com/en-us/dotnet/desktop/wpf/whats-new/net90#set-in-code +#pragma warning disable WPF0001 + Application.Current.ThemeMode = theme is ManagedCommon.Theme.Light ? ThemeMode.Light : ThemeMode.Dark; if (theme is ManagedCommon.Theme.Dark or ManagedCommon.Theme.Light) { - string themeString = theme == ManagedCommon.Theme.Light ? "pack://application:,,,/PresentationFramework.Fluent;component/Themes/Fluent.Light.xaml" - : "pack://application:,,,/PresentationFramework.Fluent;component/Themes/Fluent.Dark.xaml"; - ResourceDictionary fluentThemeDictionary = new() - { - Source = new Uri(themeString, UriKind.Absolute), - }; - _mainWindow.Resources.MergedDictionaries.Add(fluentThemeDictionary); if (!OSVersionHelper.IsWindows11()) { // Apply background only on Windows 10 @@ -79,10 +62,6 @@ private void SetSystemTheme(ManagedCommon.Theme theme) } else { - _mainWindow.Resources.MergedDictionaries.Add(new ResourceDictionary - { - Source = new Uri("Styles/FluentHC.xaml", UriKind.Relative), - }); string styleThemeString = theme switch { ManagedCommon.Theme.Light => "Themes/Light.xaml", @@ -92,10 +71,15 @@ private void SetSystemTheme(ManagedCommon.Theme theme) ManagedCommon.Theme.HighContrastWhite => "Themes/HighContrastWhite.xaml", _ => "Themes/HighContrastBlack.xaml", }; + _mainWindow.Resources.MergedDictionaries.Clear(); _mainWindow.Resources.MergedDictionaries.Add(new ResourceDictionary { Source = new Uri(styleThemeString, UriKind.Relative), }); + ResourceDictionary test = new ResourceDictionary + { + Source = new Uri(styleThemeString, UriKind.Relative), + }; if (OSVersionHelper.IsWindows11()) { // Apply background only on Windows 11 to keep the same style as WPFUI diff --git a/src/modules/launcher/PowerLauncher/Styles/FluentHC.xaml b/src/modules/launcher/PowerLauncher/Styles/FluentHC.xaml deleted file mode 100644 index 91fc2b6d1fa5..000000000000 --- a/src/modules/launcher/PowerLauncher/Styles/FluentHC.xaml +++ /dev/null @@ -1,6710 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 11,5,11,6 - 1 - 8,0,0,0 - 14 - 22 - 22 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 12 - 20 - - 1 - 8,6,0,0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 12 - 14 - 20 - 28 - 40 - 68 - - - - - - - - 1,1,1,1 - 0,0,0,1 - 10,0,0,0 - 0,0,10,0 - 0,0,4,0 - 0,0,0,0 - 24 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 9,6,9,8 - 320 - 1 - - - - - - - - - - - - - - + 16 + + + + IsReadOnly="True"> + + + + + + + + + + + + + + + + diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.xaml.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.xaml.cs index 1687a24293d3..06e435c9f0e4 100644 --- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.xaml.cs +++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.xaml.cs @@ -8,6 +8,7 @@ using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.Windows.ApplicationModel.Resources; +using Windows.ApplicationModel.DataTransfer; namespace RegistryPreviewUILib { diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryValue.xaml.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryValue.xaml.cs index 3e0d16c9328f..1bf403c3fab1 100644 --- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryValue.xaml.cs +++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryValue.xaml.cs @@ -3,6 +3,10 @@ // See the LICENSE file in the project root for more information. using System; +using System.Windows.Input; +using CommunityToolkit.Mvvm.Input; +using Microsoft.UI.Xaml; +using Windows.ApplicationModel.DataTransfer; namespace RegistryPreviewUILib { @@ -17,12 +21,16 @@ public class RegistryValue private static Uri uriDeleteValue = new Uri("ms-appx:///Assets/RegistryPreview/deleted-value32.png"); private static Uri uriErrorValue = new Uri("ms-appx:///Assets/RegistryPreview/error32.png"); + public string Key { get; set; } + public string Name { get; set; } public string Type { get; set; } public string Value { get; set; } + public string ValueOneLine => Value.Replace('\r', ' '); + public string ToolTipText { get; set; } public Uri ImageUri @@ -46,12 +54,49 @@ public Uri ImageUri } } - public RegistryValue(string name, string type, string value) + public RegistryValue(string name, string type, string value, string key) { this.Name = name; this.Type = type; this.Value = value; this.ToolTipText = string.Empty; + this.Key = key; + } + + // Commands + public ICommand CopyToClipboardEntry_Click => new RelayCommand(CopyToClipboardEntry); + + public ICommand CopyToClipboardWithPath_Click => new RelayCommand(CopyToClipboardEntryWithPath); + + public ICommand CopyToClipboardName_Click => new RelayCommand(CopyToClipboardName); + + public ICommand CopyToClipboardType_Click => new RelayCommand(CopyToClipboardType); + + public ICommand CopyToClipboardData_Click => new RelayCommand(CopyToClipboardData); + + private void CopyToClipboardEntry() + { + ClipboardHelper.CopyToClipboardAction($"{Name}\r\n{Type}\r\n{Value}"); + } + + private void CopyToClipboardEntryWithPath() + { + ClipboardHelper.CopyToClipboardAction($"{Key}\r\n{Name}\r\n{Type}\r\n{Value}"); + } + + private void CopyToClipboardName() + { + ClipboardHelper.CopyToClipboardAction(Name); + } + + private void CopyToClipboardType() + { + ClipboardHelper.CopyToClipboardAction(Type); + } + + private void CopyToClipboardData() + { + ClipboardHelper.CopyToClipboardAction(Value); } } } diff --git a/src/modules/registrypreview/RegistryPreviewUILib/Strings/en-US/Resources.resw b/src/modules/registrypreview/RegistryPreviewUILib/Strings/en-US/Resources.resw index 580d108d9a7b..9401908d216e 100644 --- a/src/modules/registrypreview/RegistryPreviewUILib/Strings/en-US/Resources.resw +++ b/src/modules/registrypreview/RegistryPreviewUILib/Strings/en-US/Resources.resw @@ -257,4 +257,28 @@ (zero-length binary value) + + Copy path + Like "Copy item" + + + Copy name + Like "Copy item" + + + Copy type + Like "Copy item" + + + Copy data + Like "Copy item" + + + Copy value + Like "Copy item" + + + Copy value with key path + Like "Copy item" + \ No newline at end of file diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-NotInUse Dark.png b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-NotInUse Dark.png deleted file mode 100644 index 08446a20784f5ea25073748d15d5fa2a4cfc9e00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13104 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 - - - - - - - - - - - - - Camera not in use - - - Microphone off - - diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-NotInUse Light.png b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-NotInUse Light.png deleted file mode 100644 index 285ea495b86078735bd6e8a8ac531ddd22912f40..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12931 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 a0YP5=e>%aHp3Vc>fMlhV-oqqJ{`zlUYgK6g diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-NotInUse Light.svg b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-NotInUse Light.svg deleted file mode 100644 index a30e909ff116..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-NotInUse Light.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - Camera not in use - - - Microphone off - - diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-Off Dark.png b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-Off Dark.png deleted file mode 100644 index 32d7559e73a1fb996776ead24f6ff9633bfd0bfe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11546 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 - - - - - - - - - - - - - Camera off - - - Microphone off - - diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-Off Light.png b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-Off Light.png deleted file mode 100644 index 7f0477ff8984cae4a39a3beebc574400f89e0bec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11488 zcmeHtcTiJZv~PqDQK|}vB27dJu?;S$R+wr^izIikE{rP6@AMeb-IXTHbd!4n{Ugh^&?={pED9ISeAP@+plA@dz z1VVBNT$fzB2>#191oeRvtGS|r?hTU zzX{8T$?Y919qjPD_paheLtkjkhB*ft`;{B{=}=kciL6ql)N$+lq854kisiR9EE0Qc zOy6^Ve13C9=RtXxvSC_-Lu*HA`j4Zk-e(!tv$cw%)>v)}SXoAOs#q>`c6!yPat3tr zxi0wjY*L8BF^i}E^^efV^_43GNx`AaV2}Lw3Iger4g8PWCH!RIg$c*2x0LT4xOjPm zC4mb%Nvh4U)(IUj1m~x*eOV)~`%n|3{#!2 zg6v8VL!-a{$cCl0}u;ktYYUw=-PGU zgDd32uG>sw{6gi}h>tIaG`Un81@}yq*=Rot{R9Mkre$RGt=w+Jc4w|V_+Z4uM-^q& zqjvOD0DL#wfg_s9)yyn&{`17xYd$9U;01r~O+m{&@v^zX$|)@$AD_e3@8+$x+p{ea zyPbjq*G7O4#xb8iyHzqtB2^sg&nm`@fiu-`3JnV@cfd**2b}E(A0Q?wY!*5bj!&lX z4#;<4A}^jr@;6a#2V+(RU%$%h!TriJ&JOGGb=m4^MM0$0Kd~F79ngWJ?LTOE#7)5` zK^G~X8XCz4Q@l@TPLdo24@eL&Yra&dkK*9qq_`La^m$z#IGk6s^YVcjQBR*f9h{u} zW>-}Gvv*1u-+8iG&w}b&>dPD&AJ4x`!=b2U5EcX;(uNW2k<#w!>Z)1EFQ8cGt3NGW z=uRofRES7qVuL^)PPHcyWw3`cifi2xv458kun;af)%*FLc8y-es?FX~pZ7-fqFIz8 zc+ySlicozL4aY zUs|daaK4*nULn5v4Mh<5Jq>3f6AV18KRqi;Zgr%1 zd%K0+eKEyDiyc^(qK3)!OJ5^W*=unNNtEl3b^Eb|Eg^HZtp1%;Qp}N>9?0PAJ4=(M z0fxhN6MAlp69>M!e*bxTG^hH%n(6LX4b^vc{yzLoKl7e;_KoqwwXr)PO&K0jUaf0a zE@ZLaFV2*^dso_j@&YR8aUeNqtqYpT<+GgM;ZsHzF-8|3VlpcyA4nb#FR!kvD+*e> z^;q`gXZWr17Y#&yM>8RoA@43+3L)O9!Gd3F2Ectz!`*%8E^X;ue;eUT@-TbO9V~M& zHA|6h!84nc!MxyuI-kRpiV25-3CDT_@|_s(T6o-`yUB-I;ySXobG`v%3Ykupia31Y=C0rQ{M1KFxIzh9G6tb>(L zSB#HqBuj>xeU1^=-Q2x*gW{*x^m6@ojJJ5o%arQ0roxBu*GS1IaAdD2I!=JaP~H+z zfu*T~X9$*UPE@LE=cwt%|8u*QWT?#R#Uj`5JUyp}X^n$$vN}34)1t{L*=xapmo6 zppEMk0+O%XmbtHWr^&!?i8`z~;Qz4Ta}6Eqba{Ds8AKhD$4tM_H+V-7l{3fWlsbguYsnI;o}iM_9H#&rpHwl~1=z~Y_%RuGGIZ~7yF ziL%Pd)#}C6j<)DvLCa1>uL*h+&qtM0-ge{WzjQBD%67Zy3cLn_A#-mJW*a1pDO}77 z1=1mDRS0WE#gxyP=Bp(vENp;AB0NrjFUnUQiU7VlK zO%R!eLxo>brTNpi_L~b{D@qqHu=AupgX=_h6i4P52~^&*7l|41)-g%yUcV6kawuPy zLC88%idnrg`b|tsj6t=_*M*)m$MNL11eX&FHO?eC%a%+iytLvebZI#UzU z7D=iihJ{k|~8xFEL70l)Kub9x9uBVJ>aUVf~%0i)vW( zeJfiZNVfM*JLi75qwk%KO%Po7nrYOn+alMd6sRu-fzSQG{o7X0rZ<`lHKS)%cX$Se z6`c7KyRu!>lh|$t=zP39cMnLWuj8bC1$mE~J8EG0^Yo@@8GfEGpbt@r&Cbr|Fm@l( zwG6Rw{xetP+CK6J`MtQ0$HNQpn!d24Hn^SCINvqG9QGJ;Hh~hfwIzznzUvzD0+{BF zNS@-_2g`_qwXsY>s5>biSsm)lkS(`pkBUF+ju((sh+rNHrQ^{G-5k<`s~*)A*Y1Q8 zw2D9N!FPJr&u5p^3Oipmv_!=Y@goc z7ZmLO;wg@23T+wF(L^v3&ni15JOAL%2sWm45OfH6OGo87kCdEq`kb4U)f&-sJEV!X zSTw!l@+bFT`e#2@W1D99e?HS<3u(GtDVpvy{#p`CFL2`0HgmuoiDBBWlTjEs-zmha zh+&vdoPemMECZOjo9pLqeD?YUi)lJNqm0nZNT`oRY*=UXA(r`xTl>#g|n zO}y>#t4f}bu)1zHV>?EN%GyAu zahGZ*u`51U)uqJiGJH!IW~wczIRn^>VVsh{b6`&-roBbRXbOF$znS0HuH7D)V#$rF z%oBG_%};765-&Y_60B11)lV1O71xP;^;1a}( z4Z}ivvNq#>S9e}C!{hDfYGxJ=1^tK_E@(Yl>dq)q=^!|AeAf4Q=Tk52HoKb;S(V-3 z5;+Iv_0ICpq3s{FESgwR+Z!tOlcprK%)%nL!8%2_qW}m}-VC~FzuB=!y`YuJa=-3v zngO`6-xQr*T`?ZB%o2Ex^_#yBRE~leD+ndms!<1NW?I{=wtNi1tSvj^GnzuEZ;i8fFWtrl z;LmP`c`SCP9G@T77lWiOzphSt0|~rS@7dur3(D5Dp~#Gp(@`19qWm&W6KCDH<{~`U zZagvKUK!yFWsI!+Io1)-{I zz@r9f-hjO^=y!;T`M~UPbU_9I31YKw|lA`q^=3 z{(fubEP`cx#x*+A`13=-(jF4>>q|AOMFXfF*sV%2G1JC>q(MMCUUv*A0Qqb@R$iZG zYLeEKw^UDWZi$HO5pE@g+to8Vz@Tt-e0cLKFBjY|fl>O}*OHNpsM7P$pp=PW&S>+5 zNNV<&9u5R#k+VGLHvEEy(|ujm&shr0UUKg4?!gsz6h1DI!;fBrs=*BD8T+yzSELBG zX18{y;c}Z;O_c$izE5eM;7vs~`Ws7B^X{K>@AnZI{b2Ipgqc3VCEtC|$t%gAy%v_f z(lPl|LiDM704(Qr--foxNzaEr+7CBA*Vlue5p!*D(5AjWqyC{)gx-(x9 z=)H2@=bM@j^Q2Vib^KJ>NJ{M&iIo;m#Gk;zlYoSV=w&rXXrxcKn!JApl2RZDu9nGT z(sYJyPQ|i7H>JQzRzo%Ej}^12qj|(kTT}tmwMpXxk;`Ee#i%jmPRL_Wg#o%OMR} zJBuUdPM*NnQ|;ulmi1k+lhvnXuKD;tdoiBdW*{5CpLqh?tlgd4_T1a);IjkHn46pX0a{X}L_yO0d?{k2MZb`G zT+&r6Krut3*{Li1O-+&THdG}1GTiQU@G9E4=wkg$;&n3IAEO>$7l|)93-2)|A+$TK z?Seu3D?Y4hvAcm;yJKsqX>*^7AzVhW_pdzd52A+UDzNws_9FL|G_n3C>x5#Vld31` z7nU-ZozuVX&WZ!7?$H>7F{4wfQubVw46SBT&a-(D^Cxzwn1YJoOrRBiqLGO7Vp#Wi zR9MdjA?9+ZSM%n-vyCpSeU@6`Nm9!m_V8f9uXjNcvFC4}5*?)Qm{OpX<(oR9%Do3@ z%vC+lX#6uzAA_MN$U!%_nss96_%L7g%(pe|D=*e%xdSF2}xIWnpz=RZF(@kF#{YH+c~ zb-e6r{B1LX4b_J=2=juhVy|%br^Dj(qKJCouMR}1JU*qu-Pmq?_Oxp=KqA@mghGCN z?tS8&9!s9MoGw1Sy^GR6e~;ffC2KJ%MwG_*3|{AKU9oGZ2lm*$fU-Io!LKi@~7gw<6?3r6J+jCMk<8CEqs z+t4&*XRo*OwLPg!!~9|NJ1n!iw&}TDeQLYvaUram$V8>#UPD$fPsUm$wSBq4RZcIE zE%Z$tjwG-iR@N_>p$2*xkW{4>QdWs1_uI`oi~JqgqElSj)IJ!alsTf%??bH9DBMusYSz^p83=) zeU>A#DKO567qV>KcvJkA5Qn7v!ad)oMxcF^t52_%@0V{qQ8}Mfu(wHk~l;1MMNPmzr8Bv3FSR!>>p1Eu7dn_J*=|8{>rHzTd9W_KA|Lfz8X|iA%}?j&lN{ zdKL#tOq*&Z2q_S#UyaqJ_Xl6e$k3AIRa86!@k{hX!!^-wQre)7kF{an$UwJ=xIx-DnCBgWh)UkUUm8UeT-1Z)FLXDa%Ej8zZg-Z+rS5_iUp z;vr;xp!P3wnSV;jBvFPgtgADIpRMTacMA4UETJ+(`0wCHuhnm5FMM&%>oH8Zg4zj` z+Z_vRKf-}X@!|sQC3W=Sl+Qj3ew!tjZ3X~LI);V?@bjIxItPzKtVa@)ci{Uv;!$DW z2G0>_Siz(`9mm%-3Pgoy6^+khfo?`vkxjcEpZNxvT?jI#+LIm~kðIdE|FMn@+r zoW+fA%LfD)KRw@q_E+WN%hwb~8t9(liMcNQN6BG&$;rnDy-{~)0&tU`Yg=SfM{7kI zTKr~V=FUZd9P`AN7g5z8eMw%C@LzaJO%Tle=S?f?zAy5&j*fBcgtGiNE&xZ*B;#-7 zy4W2)_H!LskejPWEpu7|*0~e*=Jkt$!sr4_>pwplyuE7sso)W!cYRtNSj`sN+RdCF zv>a(MWVjx8?<=Ia*LcQt%Z87&E;m0QPWU7L=gZ+>nD0ux8)KSZa+FN%fckw)v(j9t z^#I7*g8claJbFcg^z}#b1RK zWusn8kC3-BPPF_Q{Q69518kZHxYNjDNXe^O=oN1%X6c=_JJ{mQnpG$-9OL^iP26!x zijqM{(V-HJR`gsMyoUwlDR}D z)BQftPntvXU})s<$j@chk3z@OWAChS``6c7lQv;|YG#QCa?%6sj$}Le_K2Je`d z!JGqAX&DaHG5d@|nOCPme#dTSYgRG?uSv+=z}!kHxZiP@y}OjmQqKjgx`ia=vSh_r zi*qzpF)!5SIc|y%GWL+plBP&5hJeMQ15gOR_Bp^D^#S0TpO?3cah;r+Dtb#!zcTvW zyk;@g$E*T3OJAS+KG>*-l)`1} zuXc&@_3PrLeJcF-GFkF+b92#!cEacw9=)GfOG0IEyi(9bRmb0))O=W`vv8tV@HyBb zU9{nw>f=k0hb|knyJ{d(H}oj5!NVrWHlU3seUC}y&8QRDO~yO8}kSI(j1{c zatLHh04%lNA$nSv_HqP^Oc8n$W5|a&GMhxi^1+J$qU%u)BLH_HpM2D)%Y{b28{RZ7 zzP%RHw7hCwm2ZrUQ!Wa=2=WV@?CrOYZ@*=`Dt`(^`Fz`Q_J{n?p%B zkblm#M@LD7z1iR2mvEVTw}IY-p=9qHRgmdUtWwfYqgQOZ0wDN3+wa+}7qS`&^$FFf zB+)CW{uol&)(>JVqV*%w0Kk{?gzbixvXdMh)YgODCUd?WaaRdo$OH3naKb9*XJ
%D{nN0CdEKMipNnq0ZHwpHez2b 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 BQeyxB diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-Off Light.svg b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-Off Light.svg deleted file mode 100644 index 25eecdd72f2f..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-Off Light.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - Camera off - - - Microphone off - - diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-On Dark.png b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-On Dark.png deleted file mode 100644 index ac33d985c89d570a400abf579264ff21a0262cca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5664 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 b4Q03nLh&CGYW|s%2d?U4u;>z$WB9)T2z+bK diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-On Dark.svg b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-On Dark.svg deleted file mode 100644 index ea31e3d78db8..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-On Dark.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - Camera on - - Microphone off - - - diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-On Light.png b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-On Light.png deleted file mode 100644 index a43b3cf364b2def9ecad99c1351cb6ddee759cfe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5678 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 N)#2K(k5EMTe*k6bX?g$v diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-On Light.svg b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-On Light.svg deleted file mode 100644 index e3c0352bccb2..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/Off-On Light.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - Camera on - - Microphone off - - - diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-NotInUse Dark.png b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-NotInUse Dark.png deleted file mode 100644 index ff34ff3eb5cd58b11ae59659e5aca4b41121ac4a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6016 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 - - - - - - - - - - - - - Camera not in use - - Microphone on - - - diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-NotInUse Light.png b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-NotInUse Light.png deleted file mode 100644 index b4e5edaea5cb02f6e0b50386a9768e275389db29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6321 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 diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-NotInUse Light.svg b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-NotInUse Light.svg deleted file mode 100644 index d9d340c03418..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-NotInUse Light.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - Camera not in use - - Microphone on - - - diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-Off Dark.png b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-Off Dark.png deleted file mode 100644 index 8492439759f691898f6c098431c84f9e317965d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5808 zcmd5=cT|(xmJb(8P*4I~Q4xXAdy^JQAS84lNS6|Nm7?@+AR+;g-lQlc6r~sGpb-!R zr1xH>7lF{>g?rzdS#PbG|7Oo>(wiC_Q-$0Qj&00535Bz%jAuU1tIXT#tjx{Lt*xz3PELsGp_iJ8;+;ebIy=!h zIXSkrwymwLL}DTb(V(=nv?ouVG&eUhK#8WIcXxM_larB1B$NTFtgO7Xwe{}ZJ4Hps z^Yimdi-{`Gs7@SudwV-7DoQ~?0fk0iD#oEu=+3>py@-eiI2>MBSU5a9j6*}AXk2J$ zXlZGwmX;P63?@Q}&gkgq?Cs%KQ%Sg#>QrFaByN`A|xbadU_fHfvm2srlh1~XJ@ait;x&F zfBEtS27?htQAS3_(9rPlewGB99(Ds;;hZyH2?rqp2~1JZLhJ7 zH1GNeILUW9Gga=ZSGbUTiRfup<5Rgp{gCuKXOu7Psu`&jmQo(`$8=WyR;MBe9E>Y*^r23Y){2Z~Hs|o~i znE=%{WRp3mz+A^cWZAxGPSs6&g(Y$sv+-7s@e~uoWib`3%ke@;2>Yg~&$kaImR&P% z$7^@Su>4P#`EYRYtPCrge!6S>V25j-qfeV1h9}jE`S)n8;MFIw6G}1?Ca$XweQRTF zlBNXmXp@DjhwtDqzR;Gv8}cYk1>0x2CpsttK+Rd z*(QDq^m9}AlY%iSQT)NNw-VDT-U>7f_3$&o@~%h-AG-C5WbBZu0Vn^GN%_hwM$P88 z#M8es+%})q+!f6%^)4&pVEfS&(H*JN#E2;6~@H-iZ ziDlnoUZuL3@OkLMdsk;`Bl{tE?+vYaHX3*m{>MG3MeS&GKbuotmKBKNhQeAdzLcP# zw9_(esA2$0FG`vs1+_~3VxR=$&zT&qCBF7LzX1vot|yVnX*8_~)8D5}&~Ir8^IfHG z()sxI)R_#+e?Fya55|u$nOSmy*RPjZBbl;<>n-rKh1wD4pnNIE3xx!$yq&;TZ;E_M zPptRrh1WRope@-UovBq3n=XyUs`%Pa0dVb%AvuUZ!3rPo!g{J5_QkJ&Q$0M4-gs}v zi2JAunC;Kq4?~`pcP1D6JM+3z&gO}y)QLWN-svB>88tUxrXh!E$bJK)U%mH=sDbX0lahaX3yi+M|Tmw03`{)mSl1vVqE z=%l^Xfil|e>TFGQj0FWw@LjkA2Yy>5`q0-Q{}u4pZAF?#VD+wSY>C9yq3UGKT4Ft$ zKW(uIv*h<%QYS58Y|ZW4Upruv%zuDTe0D6+WA9m?U!LZQf*V45RU2H-cAT z5&_~rI$R~9uZ@`^$sn*VOmsvh`sN6_Y<{#{SPE;XYpm?AZ-`s2PvsA-$y|KXzM z_bs$1>misX*DaWV35Iq}jRGo~H>G}SFj3U=?zcX{r8w|8{%PWgsMBYR1aa0az59SA zj6O$UGQ9N^y6@(Xbs&q6LI}ribCe2fPxe1l1Jm>xHP!rLbJlg7O=kVM^!WMtV9BCs z0wHu}*9^mUg{z!A99j)6RSP#eq8SE1lCubXGI)E#UAHxpB9$_5x-!i`ew7Kv?x)0Y z8@LZPs?sj?HO%n&)S1Fl&)6sF;o{iiWucypWn@Tq0q^3Waf2J~MYP7#avPe8y#xms z83@v!O(w?C(O8K4n&ycd>I!k|!B-?Ro$~l3-`x8AD!PnmheJ53t-xC1#v=ncjL(lS z7g@oE>tGt+p=r&z<(~JMRI@?)TNfq3l=5-1`{C29C8D+t{%*Q!olyn!DZ}T}Jr%>H zCe`u|PalMTM$!HV?eVS~!)$b0lylD4)*3`Hl{@g1)e9&+wHAZhXwZ=i&TxF;_R8y7Xh;M%$Chj5uJL!!&0ODwl&>+MdJUTL1GRvR|S_3529 z`Zj9-3j2(r`+@E8Ufti^Q=N+E8Mj@pd#>v<`Lpe=ZMPWt>+X?T*I(P82h?xFhOw+E6)wz>J!myN7$c*V zIGCCC$GkjUzT9z=A2&(xxtX=E{ThQ9FTTx+SWejvfsY1H`NF@~(%*BiJXczrvSsLP zxk8&-{)u*O5^ z9^d(Qk_cdmNv?gVo>g@mcmN{%)0TnL$5TJ#=9@$GUCl1wS$#Tn$|A4Yw24o{(t1*r zmArB^tz(ly+?@=uWqcSXrxiOKV{sqU>SP^${3IT&Z(Z4ejebY`Y_debd#H$tifo#U z&x!6n9Q6FUnX?$+IBG#<){CjHYPiOPC8TtJy}of}V>t9Tc<-8V^~%|C*&;k?r@}!2 zbWIYOLh|?y)xXrqfa9j!#BNuf|B45bZ~X>_z31$GQFzD#A2CsfiEmJ@jISB-`>cy* zk_QrJ7MvEo>?iwfJ9w;2S{nQ;VEG$^M8M1w@2489_>r#xC90M8dO`(CAGFlkmj?me zX+X2Q!Ztta2Y2ArRptSznDOdGC+?bn3~G)5F|I&%ZbaT>VJVWeqdkdFJG4ZESx5Ys z02x+|k>W;GoZauG06|imsMsd5xyL0zMRnjlcm7CVgwFMwy?76POGXCj;u<(8(Ko?PGy#zB{zNg=x1N=RnRrJxKVZlwr(rB*qC~% zZnk9I-93BKVg10jv21XyCKOoi=k1V4O$xe`sSc(&kr}b0b}!BLZ!c7&RV@pR3TGur zvm%&iE@-_^DEP58qZ&2W}147BIr-&sbp_%8oi5!jtB-wRZdn@gpa+>ZjZs+Y^z@6tG((i^}5w z*~Y0wH*crHi7y3HJ4ti$#(uEV2PhMez3>N0vxM=!nwBEUOFfj@JKQeG*NuVujH=Y? z>2jdH)fJAh0RQEWM1#W3QAZz#e-CGq(Me9~z%WxBPqDcp5#;Ge!sXxxDPqWLk)c9h zsqVA7T=VmXn|oRG%wRRCXFO8mdiC6}x=8~6`y}8u<`+3+ikIt8Ry1Rgr0$M}X2scY zk1+^>qFv;x?QuA!ix5Q&chfa%?-VmV2l4;f;hmioi0fKnQz#M zXNxp;RI6!49Xjs+Jo`|WuO>hOv3#3AM?Na(yz=1*W-7yid#EdV#;E!kciyJ7Dp(3u zsV-hi5E{HGU6x;Ct>lf-uQ(g)u>wJ+sjgPlj`;3wY^a0_$XFIb7xFK}TTD@28a+Q) zVaC_Ae^u&qXcp%~xI>YO8NLydx3?tcT4p!H;|;q*Uvvh~#aeq`?HyhLW($8_A485OpKmC&HgQcakFJg3F$nLesC%?*aDAtk=oH0ML1lSzE?jAVP z<{Jxe}e)TrrRGrX+^3(*>AnrCXYq8_?YldXMkb&6J9Ud50d4vvJo+*4!^9Xaw zmuHGd_{d@JH@QJOn?x$J!}ea@1uZy!{yVuz?1?!x>+ijcqsN-K!*D!$I6FR};T+;8 zvdD-a@Ez@FSoYIa7jJRZ1RNpmdRMz!V1EhjM=5NW+q`=3x7XjYaWBIL=SlUpj5vuh zFHpZ}BVvdrx?mG*$@8A>vG~9MmwTYr%)z_QCO1FxjG&z+!a|YBXiMwCj+Khc*~{R) zf*(FHt8-ZF$Zs0i>sZuux`@|Pc|h4n2$kCK2wz&X`Ee5c(>OlhWNcMr?f_xIxaam@ z>*I6R^k=5BM*?y`$zi8+_UQ~fmO?9le=38{lI(1sNJ0>g#gqttbBGq%+b)y9y(58 zN3J_d&NGuu`JG!zxGv`SMd*^iZ9^Yod+uG7Kbl3UIWuUdWNMVsHC4_p*4{L+^_jo% z5=ha@4T6*}coKpGMHw5wGQ-&ZBq2u(#HE&eyxcN$MAK^R1)7Mn<@xW_l#Gqdd(?EjEd_f zF?a0I0zrJS<8SCL^Hp7#&SjSF!ws`3z5r6Eza^7Q*&n5jx7WG)y>81DCdaXSXC@WEI)WrLf7T!`KTcc`Iwmc2c?H2lUzPs zyqi+X;|QhXlG{QoONs89_ZyPw;0k~jRZQ&)mufBkfCE3^4D}*NROGIGWg#L-?p=w! zOlB=9)q;Q-R8evQWJH5y|3^Fjzg?L8mzOxP|GM}AeDOKIO>zSW)eHM}Mr>qtL+HC% znz>m)EM8a<3xJS-kT9=+5U+rswtxggSQsMwh+9AaA|PN|o!9nn0*=m>cGlkiy#Q#D z(v2v<@gEFsc8*rAZf1@y|CAx}2x<$8LWG4NkA(jwx!E;(@6uFdggU$kW*YPl5D>ll diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-Off Dark.svg b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-Off Dark.svg deleted file mode 100644 index 67080eabdd91..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-Off Dark.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - Camera off - - Microphone on - - - diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-Off Light.png b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-Off Light.png deleted file mode 100644 index b011e944bb27d7f43deada6c475d81bd17998da8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10232 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 - - - - - - - - - - - - - Camera off - - Microphone on - - - diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-On Dark.png b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-On Dark.png deleted file mode 100644 index 6f1955d2d2ea98d7b1d2c8f48d485b0713f2c6fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4975 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 bQc%@YQv8?5yOQ|_KjXZBG|?~Cy-NHqs-GnS diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-On Dark.svg b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-On Dark.svg deleted file mode 100644 index e539e785a6f3..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-On Dark.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - Camera on - - Microphone on - - - diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-On Light.png b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-On Light.png deleted file mode 100644 index b9fb04c6a6e3dd4311bea4bf3b4db0fc3a4fc653..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4976 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 Z)YH`YNs{|;Ul+iDE+8#UUz%VD{{ho^266xZ diff --git a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-On Light.svg b/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-On Light.svg deleted file mode 100644 index ff4a5c2e3114..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/Assets/VCM/On-On Light.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - Camera on - - Microphone on - - - diff --git a/src/modules/videoconference/VideoConferenceModule/AudioDeviceNotificationClient.cpp b/src/modules/videoconference/VideoConferenceModule/AudioDeviceNotificationClient.cpp deleted file mode 100644 index 125290718415..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/AudioDeviceNotificationClient.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "pch.h" - -#include "AudioDeviceNotificationClient.h" - -AudioDeviceNotificationClient::AudioDeviceNotificationClient() -{ - (void)CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&_deviceEnumerator)); - if (!_deviceEnumerator) - { - return; - } - - if (FAILED(_deviceEnumerator->RegisterEndpointNotificationCallback(this))) - { - _deviceEnumerator->Release(); - _deviceEnumerator = nullptr; - } -} - -AudioDeviceNotificationClient::~AudioDeviceNotificationClient() -{ - if (!_deviceEnumerator) - { - return; - } - - _deviceEnumerator->UnregisterEndpointNotificationCallback(this); - _deviceEnumerator->Release(); -} - -ULONG AudioDeviceNotificationClient::AddRef() -{ - return 1; -} - -ULONG AudioDeviceNotificationClient::Release() -{ - return 1; -} - -HRESULT AudioDeviceNotificationClient::QueryInterface(REFIID, void**) -{ - return S_OK; -} - -HRESULT AudioDeviceNotificationClient::OnPropertyValueChanged(LPCWSTR, const PROPERTYKEY) -{ - _deviceConfigurationChanged = true; - return S_OK; -} - -HRESULT AudioDeviceNotificationClient::OnDeviceAdded(LPCWSTR) -{ - _deviceConfigurationChanged = true; - return S_OK; -} - -HRESULT AudioDeviceNotificationClient::OnDeviceRemoved(LPCWSTR) -{ - _deviceConfigurationChanged = true; - return S_OK; -} - -HRESULT AudioDeviceNotificationClient::OnDeviceStateChanged(LPCWSTR, DWORD) -{ - _deviceConfigurationChanged = true; - return S_OK; -} - -HRESULT AudioDeviceNotificationClient::OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR) -{ - if (role == eConsole && (flow == eCapture || flow == eAll)) - { - _deviceConfigurationChanged = true; - } - - return S_OK; -} diff --git a/src/modules/videoconference/VideoConferenceModule/AudioDeviceNotificationClient.h b/src/modules/videoconference/VideoConferenceModule/AudioDeviceNotificationClient.h deleted file mode 100644 index 3fe3f5fd1db2..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/AudioDeviceNotificationClient.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include - -struct AudioDeviceNotificationClient : IMMNotificationClient -{ - AudioDeviceNotificationClient(); - ~AudioDeviceNotificationClient(); - - bool PullPendingNotifications() - { - const bool result = _deviceConfigurationChanged; - _deviceConfigurationChanged = false; - return result; - } - -private: - ULONG AddRef() override; - ULONG Release() override; - HRESULT QueryInterface(REFIID, void**) override; - HRESULT OnPropertyValueChanged(LPCWSTR, const PROPERTYKEY) override; - HRESULT OnDeviceAdded(LPCWSTR) override; - HRESULT OnDeviceRemoved(LPCWSTR) override; - HRESULT OnDeviceStateChanged(LPCWSTR, DWORD) override; - HRESULT OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR) override; - - IMMDeviceEnumerator* _deviceEnumerator = nullptr; - - bool _deviceConfigurationChanged = false; -}; diff --git a/src/modules/videoconference/VideoConferenceModule/README.md b/src/modules/videoconference/VideoConferenceModule/README.md deleted file mode 100644 index d53920685ab0..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Video Conference Mute - -# Introduction -The Video Conference Mute module allows muting microphone and/or web camera video stream during video calls or other activity. - -# Usage -If you'd like to mute your web camera, please select "PowerToys VideoConference Mute" device in your web camera-using app, then restart it. - -During a video call, you can use default shortcuts to mute microphone, web camera or both. You'll see a toolbar indicating corresponding mute statuses. - -# Options -You can tweak the toolbar position on the screen as well as set web camera overlay image during muting. - -# Backlog diff --git a/src/modules/videoconference/VideoConferenceModule/Toolbar.cpp b/src/modules/videoconference/VideoConferenceModule/Toolbar.cpp deleted file mode 100644 index 0dabd58d9c9c..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/Toolbar.cpp +++ /dev/null @@ -1,390 +0,0 @@ -#include "pch.h" -#include "Toolbar.h" - -#include - -#include -#include - -#include "Logging.h" -#include "VideoConferenceModule.h" - -Toolbar* toolbar = nullptr; - -const int REFRESH_RATE = 100; -const int OVERLAY_SHOW_TIME = 500; -const int BORDER_OFFSET = 12; -const int TOP_RIGHT_BORDER_OFFSET = 40; -std::wstring cached_position = L""; - -Toolbar::Toolbar() -{ - toolbar = this; - darkImages.camOnMicOn = Gdiplus::Image::FromFile(L"Assets/VCM/On-On Dark.png"); - darkImages.camOffMicOn = Gdiplus::Image::FromFile(L"Assets/VCM/On-Off Dark.png"); - darkImages.camOnMicOff = Gdiplus::Image::FromFile(L"Assets/VCM/Off-On Dark.png"); - darkImages.camOffMicOff = Gdiplus::Image::FromFile(L"Assets/VCM/Off-Off Dark.png"); - darkImages.camUnusedMicOn = Gdiplus::Image::FromFile(L"Assets/VCM/On-NotInUse Dark.png"); - darkImages.camUnusedMicOff = Gdiplus::Image::FromFile(L"Assets/VCM/Off-NotInUse Dark.png"); - - lightImages.camOnMicOn = Gdiplus::Image::FromFile(L"Assets/VCM/On-On Light.png"); - lightImages.camOffMicOn = Gdiplus::Image::FromFile(L"Assets/VCM/On-Off Light.png"); - lightImages.camOnMicOff = Gdiplus::Image::FromFile(L"Assets/VCM/Off-On Light.png"); - lightImages.camOffMicOff = Gdiplus::Image::FromFile(L"Assets/VCM/Off-Off Light.png"); - lightImages.camUnusedMicOn = Gdiplus::Image::FromFile(L"Assets/VCM/On-NotInUse Light.png"); - lightImages.camUnusedMicOff = Gdiplus::Image::FromFile(L"Assets/VCM/Off-NotInUse Light.png"); -} - -void Toolbar::scheduleModuleSettingsUpdate() -{ - moduleSettingsUpdateScheduled = true; -} - -void Toolbar::scheduleGeneralSettingsUpdate() -{ - generalSettingsUpdateScheduled = true; -} - -inline POINT calculateToolbarPositioning(Box const& screenSize, std::wstring& position, const int desiredWidth, const int desiredHeight) -{ - POINT p; - p.x = p.y = 0; - - if (position == L"Top left corner") - { - p.x = screenSize.left() + BORDER_OFFSET; - p.y = screenSize.top() + BORDER_OFFSET; - } - else if (position == L"Top center") - { - p.x = screenSize.middle().x - desiredWidth / 2; - p.y = screenSize.top() + BORDER_OFFSET; - } - else if (position == L"Bottom left corner") - { - p.x = screenSize.left() + BORDER_OFFSET; - p.y = screenSize.bottom() - desiredHeight - BORDER_OFFSET; - } - else if (position == L"Bottom center") - { - p.x = screenSize.middle().x - desiredWidth / 2; - p.y = screenSize.bottom() - desiredHeight - BORDER_OFFSET; - } - else if (position == L"Bottom right corner") - { - p.x = screenSize.right() - desiredWidth - BORDER_OFFSET; - p.y = screenSize.bottom() - desiredHeight - BORDER_OFFSET; - } - else //"Top right corner" or non-present - { - p.x = screenSize.right() - desiredWidth - BORDER_OFFSET; - p.y = screenSize.top() + TOP_RIGHT_BORDER_OFFSET; - } - return p; -} - -LRESULT Toolbar::WindowProcessMessages(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -{ - switch (msg) - { - case WM_DESTROY: - return 0; - case WM_LBUTTONDOWN: - { - int x = GET_X_LPARAM(lparam); - int y = GET_Y_LPARAM(lparam); - UINT dpi = DPIAware::DEFAULT_DPI; - DPIAware::GetScreenDPIForWindow(hwnd, dpi); - - if (x < 322 * static_cast(dpi) / static_cast(DPIAware::DEFAULT_DPI) / 2) - { - VideoConferenceModule::reverseMicrophoneMute(); - } - else - { - VideoConferenceModule::reverseVirtualCameraMuteState(); - } - - return DefWindowProcW(hwnd, msg, wparam, lparam); - } - case WM_DPICHANGED: - { - UINT dpi = LOWORD(wparam); - RECT* prcNewWindow = reinterpret_cast(lparam); - - POINT suggestedPosition; - suggestedPosition.x = prcNewWindow->left; - suggestedPosition.y = prcNewWindow->top; - - int desiredWidth = prcNewWindow->right - prcNewWindow->left; - int desiredHeight = prcNewWindow->bottom - prcNewWindow->top; - - HMONITOR hMonitor = MonitorFromPoint(suggestedPosition, MONITOR_DEFAULTTONEAREST); - - MonitorInfo info{ hMonitor }; - - suggestedPosition = calculateToolbarPositioning(info.GetScreenSize(false), cached_position, desiredWidth, desiredHeight); - - SetWindowPos(hwnd, - NULL, - suggestedPosition.x, - suggestedPosition.y, - desiredWidth, - desiredHeight, - SWP_NOZORDER | SWP_NOACTIVATE); - return DefWindowProcW(hwnd, msg, wparam, lparam); - } - case WM_CREATE: - case WM_PAINT: - { - PAINTSTRUCT ps; - HDC hdc; - UINT dpi = DPIAware::DEFAULT_DPI; - - DPIAware::GetScreenDPIForWindow(hwnd, dpi); - - hdc = BeginPaint(hwnd, &ps); - - Gdiplus::Graphics graphic(hdc); - - ToolbarImages* themeImages = &toolbar->darkImages; - - if (toolbar->theme == L"light" || (toolbar->theme == L"system" && !WindowsColors::is_dark_mode())) - { - themeImages = &toolbar->lightImages; - } - else - { - themeImages = &toolbar->darkImages; - } - Gdiplus::Image* toolbarImage = nullptr; - if (!toolbar->cameraInUse) - { - if (toolbar->microphoneMuted) - { - toolbarImage = themeImages->camUnusedMicOff; - } - else - { - toolbarImage = themeImages->camUnusedMicOn; - } - } - else if (toolbar->microphoneMuted) - { - if (toolbar->cameraMuted) - { - toolbarImage = themeImages->camOffMicOff; - } - else - { - toolbarImage = themeImages->camOnMicOff; - } - } - else - { - if (toolbar->cameraMuted) - { - toolbarImage = themeImages->camOffMicOn; - } - else - { - toolbarImage = themeImages->camOnMicOn; - } - } - // Images are scaled by 4 to support higher dpi values. - graphic.DrawImage(toolbarImage, 0, 0, toolbarImage->GetWidth() / 4 * dpi / DPIAware::DEFAULT_DPI, toolbarImage->GetHeight() / 4 * dpi / DPIAware::DEFAULT_DPI); - - EndPaint(hwnd, &ps); - break; - } - case WM_TIMER: - { - if (toolbar->audioConfChangesNotifier.PullPendingNotifications()) - { - instance->onMicrophoneConfigurationChanged(); - } - toolbar->microphoneMuted = instance->getMicrophoneMuteState(); - - if (toolbar->generalSettingsUpdateScheduled) - { - instance->onGeneralSettingsChanged(); - toolbar->generalSettingsUpdateScheduled = false; - } - if (toolbar->moduleSettingsUpdateScheduled) - { - instance->onModuleSettingsChanged(); - toolbar->moduleSettingsUpdateScheduled = false; - } - - toolbar->cameraInUse = VideoConferenceModule::getVirtualCameraInUse(); - - InvalidateRect(hwnd, NULL, NULL); - - using namespace std::chrono; - const auto nowMillis = duration_cast(system_clock::now().time_since_epoch()).count(); - const bool showOverlayTimeout = nowMillis - toolbar->lastTimeCamOrMicMuteStateChanged > OVERLAY_SHOW_TIME; - - static bool previousShow = false; - bool show = toolbar->ToolbarHide == L"Never"; - - const bool cameraJustStoppedInUse = toolbar->previouscameraInUse && !toolbar->cameraInUse; - bool shouldUnmuteAll = cameraJustStoppedInUse; - - if (toolbar->ToolbarHide == L"When both camera and microphone are muted") - { - // We shouldn't unmute devices, since we'd like to only show the toolbar only - // when something is unmuted -> the use case is to keep everything muted by default and track it - shouldUnmuteAll = false; - show = (!toolbar->cameraMuted && toolbar->cameraInUse) || !toolbar->microphoneMuted; - } - else if (toolbar->ToolbarHide == L"When both camera and microphone are unmuted") - show = (toolbar->cameraMuted && toolbar->cameraInUse) || toolbar->microphoneMuted; - - if (shouldUnmuteAll && !toolbar->moduleSettingsUpdateScheduled) - VideoConferenceModule::unmuteAll(); - - show = show || !showOverlayTimeout; - ShowWindow(hwnd, show ? SW_SHOW : SW_HIDE); - - if (previousShow != show) - { - previousShow = show; - LOG(show ? "Toolbar visibility changed to shown" : "Toolbar visibility changed to hidden"); - } - - KillTimer(hwnd, toolbar->nTimerId); - toolbar->previouscameraInUse = toolbar->cameraInUse; - break; - } - default: - return DefWindowProcW(hwnd, msg, wparam, lparam); - } - - toolbar->nTimerId = SetTimer(hwnd, 101, REFRESH_RATE, nullptr); - - return DefWindowProcW(hwnd, msg, wparam, lparam); -} - -void Toolbar::show(std::wstring position, std::wstring monitorString) -{ - cached_position = position; - for (auto& hwnd : hwnds) - { - PostMessageW(hwnd, WM_CLOSE, 0, 0); - } - hwnds.clear(); - - // Images are scaled by 4 to support higher dpi values. - int overlayWidth = darkImages.camOffMicOff->GetWidth() / 4; - int overlayHeight = darkImages.camOffMicOff->GetHeight() / 4; - - // Register the window class - LPCWSTR CLASS_NAME = L"MuteNotificationWindowClass"; - WNDCLASS wc{}; - wc.hInstance = GetModuleHandleW(nullptr); - wc.lpszClassName = CLASS_NAME; - wc.hCursor = LoadCursor(nullptr, IDC_ARROW); - wc.hbrBackground = reinterpret_cast(COLOR_WINDOW); - wc.lpfnWndProc = WindowProcessMessages; - RegisterClassW(&wc); - - // Create the window - DWORD dwExtStyle = 0; - DWORD dwStyle = WS_POPUPWINDOW; - - std::vector monitorInfos; - - if (monitorString == L"All monitors") - { - monitorInfos = MonitorInfo::GetMonitors(false); - } - else //"Main monitor" or non-present - { - monitorInfos.push_back(MonitorInfo::GetPrimaryMonitor()); - } - - for (auto& monitorInfo : monitorInfos) - { - const auto screenSize = monitorInfo.GetScreenSize(false); - UINT dpi = DPIAware::DEFAULT_DPI; - DPIAware::GetScreenDPIForMonitor(monitorInfo.GetHandle(), dpi); - - int scaledOverlayWidth = overlayWidth * dpi / DPIAware::DEFAULT_DPI; - int scaledOverlayHeight = overlayHeight * dpi / DPIAware::DEFAULT_DPI; - - POINT p = calculateToolbarPositioning(screenSize, position, scaledOverlayWidth, scaledOverlayHeight); - - HWND hwnd; - hwnd = CreateWindowExW( - WS_EX_TOOLWINDOW | WS_EX_LAYERED, - CLASS_NAME, - CLASS_NAME, - WS_POPUP, - static_cast(p.x), - static_cast(p.y), - scaledOverlayWidth, - scaledOverlayHeight, - nullptr, - nullptr, - GetModuleHandleW(nullptr), - nullptr); - - auto transparentColorKey = RGB(0, 0, 255); - HBRUSH brush = CreateSolidBrush(transparentColorKey); - SetClassLongPtr(hwnd, GCLP_HBRBACKGROUND, reinterpret_cast(brush)); - - SetLayeredWindowAttributes(hwnd, transparentColorKey, 0, LWA_COLORKEY); - - SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - - hwnds.push_back(hwnd); - } -} - -void Toolbar::hide() -{ - for (auto& hwnd : hwnds) - { - PostMessage(hwnd, WM_CLOSE, 0, 0); - } - hwnds.clear(); -} - -bool Toolbar::getCameraMute() -{ - return cameraMuted; -} - -void Toolbar::setCameraMute(bool mute) -{ - if (mute != cameraMuted) - { - lastTimeCamOrMicMuteStateChanged = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - } - cameraMuted = mute; -} - -bool Toolbar::getMicrophoneMute() -{ - return microphoneMuted; -} - -void Toolbar::setMicrophoneMute(bool mute) -{ - if (mute != microphoneMuted) - { - lastTimeCamOrMicMuteStateChanged = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - } - - microphoneMuted = mute; -} - -void Toolbar::setToolbarHide(std::wstring hide) -{ - ToolbarHide = hide; -} - -void Toolbar::setTheme(std::wstring theme) -{ - Toolbar::theme = theme; -} diff --git a/src/modules/videoconference/VideoConferenceModule/Toolbar.h b/src/modules/videoconference/VideoConferenceModule/Toolbar.h deleted file mode 100644 index 04b1c28a233d..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/Toolbar.h +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -#include "AudioDeviceNotificationClient.h" - -struct ToolbarImages -{ - Gdiplus::Image* camOnMicOn = nullptr; - Gdiplus::Image* camOffMicOn = nullptr; - Gdiplus::Image* camOnMicOff = nullptr; - Gdiplus::Image* camOffMicOff = nullptr; - Gdiplus::Image* camUnusedMicOn = nullptr; - Gdiplus::Image* camUnusedMicOff = nullptr; -}; - -class Toolbar -{ -public: - Toolbar(); - - void scheduleModuleSettingsUpdate(); - void scheduleGeneralSettingsUpdate(); - - void show(std::wstring position, std::wstring monitorString); - void hide(); - - bool getCameraMute(); - void setCameraMute(bool mute); - bool getMicrophoneMute(); - void setMicrophoneMute(bool mute); - - void setTheme(std::wstring theme); - void setToolbarHide(std::wstring hide); - -private: - static LRESULT CALLBACK WindowProcessMessages(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); - - // Window callback can't be non-static so this members can't as well - std::vector hwnds; - - ToolbarImages darkImages; - ToolbarImages lightImages; - AudioDeviceNotificationClient audioConfChangesNotifier; - - bool cameraMuted = false; - bool cameraInUse = false; - bool previouscameraInUse = false; - bool microphoneMuted = false; - - std::wstring theme = L"system"; - - std::wstring ToolbarHide = L"When both camera and microphone are unmuted"; - - uint64_t lastTimeCamOrMicMuteStateChanged{}; - - std::atomic_bool moduleSettingsUpdateScheduled = false; - std::atomic_bool generalSettingsUpdateScheduled = false; - UINT_PTR nTimerId{}; -}; diff --git a/src/modules/videoconference/VideoConferenceModule/VideoConference.filters b/src/modules/videoconference/VideoConferenceModule/VideoConference.filters deleted file mode 100644 index e19316f1bdb9..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/VideoConference.filters +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - - {2c7c97f7-0d87-4230-a4b2-baf2cfc35d58} - - - {aa4b6713-589d-42ef-804d-3a045833f83f} - - - - - - - - - \ No newline at end of file diff --git a/src/modules/videoconference/VideoConferenceModule/VideoConference.vcxproj b/src/modules/videoconference/VideoConferenceModule/VideoConference.vcxproj deleted file mode 100644 index e04332202145..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/VideoConference.vcxproj +++ /dev/null @@ -1,189 +0,0 @@ - - - - - 15.0 - {5ABA70DE-3A3F-41F6-A1F5-D1F74F54F9BB} - Win32Proj - overlaywindow - VideoConferenceModule - ..\..\..\..\$(Platform)\$(Configuration)\ - PowerToys.VideoConferenceModule - - - - DynamicLibrary - true - v143 - Unicode - Spectre - - - DynamicLibrary - false - v143 - true - Unicode - Spectre - - - - - - - - - - - false - - - true - - - - Level3 - MaxSpeed - true - true - true - NDEBUG;OVERLAYWINDOW_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - ..\..\..\;..\..\;..\VideoConferenceShared\;%(AdditionalIncludeDirectories) - stdcpplatest - - - Windows - true - true - true - $(OutDir)$(TargetName)$(TargetExt) - shlwapi.lib;gdiplus.lib;dwmapi.lib;uxtheme.lib;shcore.lib;Wtsapi32.lib;%(AdditionalDependencies) - - - - - Level3 - Disabled - true - _DEBUG;OVERLAYWINDOW_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreadedDebug - ..\..\..\common\inc;..\..\..\common\Telemetry;..\..\..\;..\..\;..\VideoConferenceShared\;%(AdditionalIncludeDirectories) - stdcpplatest - - - Windows - true - $(OutDir)$(TargetName)$(TargetExt) - shlwapi.lib;gdiplus.lib;dwmapi.lib;uxtheme.lib;shcore.lib;Wtsapi32.lib;dxguid.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - Create - - - - - - {459e0768-7ebd-4c41-bba1-6db3b3815e0a} - - - - - true - PreserveNewest - - - true - PreserveNewest - - - true - PreserveNewest - - - true - PreserveNewest - - - true - PreserveNewest - - - true - PreserveNewest - - - true - PreserveNewest - - - true - PreserveNewest - - - true - PreserveNewest - - - true - PreserveNewest - - - true - PreserveNewest - - - true - PreserveNewest - - - true - PreserveNewest - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - {caba8dfb-823b-4bf2-93ac-3f31984150d9} - - - {6955446d-23f7-4023-9bb3-8657f904af99} - - - {98537082-0fdb-40de-abd8-0dc5a4269bab} - - - - - - - - - \ No newline at end of file diff --git a/src/modules/videoconference/VideoConferenceModule/VideoConference.vcxproj.filters b/src/modules/videoconference/VideoConferenceModule/VideoConference.vcxproj.filters deleted file mode 100644 index fea3b28290b5..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/VideoConference.vcxproj.filters +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - {efd98846-4568-41d4-a425-451c246802cd} - - - {e79f8c1a-b78b-4ba5-b923-f7db79eba776} - - - - - - - - Assets\VCM - - - Assets\VCM - - - Assets\VCM - - - Assets\VCM - - - Assets\VCM - - - Assets\VCM - - - Assets\VCM - - - Assets\VCM - - - Assets\VCM - - - Assets\VCM - - - Assets\VCM - - - Assets\VCM - - - Assets\VCM - - - - - - - - - \ No newline at end of file diff --git a/src/modules/videoconference/VideoConferenceModule/VideoConferenceModule.cpp b/src/modules/videoconference/VideoConferenceModule/VideoConferenceModule.cpp deleted file mode 100644 index aab538e88389..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/VideoConferenceModule.cpp +++ /dev/null @@ -1,733 +0,0 @@ -#include "pch.h" - -#include "VideoConferenceModule.h" - -#include - -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include - -#include "logging.h" -#include "trace.h" - -extern "C" IMAGE_DOS_HEADER __ImageBase; - -VideoConferenceModule* instance = nullptr; - -VideoConferenceSettings VideoConferenceModule::settings; -Toolbar VideoConferenceModule::toolbar; -bool VideoConferenceModule::pushToTalkPressed = false; - -HHOOK VideoConferenceModule::hook_handle; - -IAudioEndpointVolume* endpointVolume = NULL; - -bool VideoConferenceModule::isKeyPressed(unsigned int keyCode) -{ - return (GetKeyState(keyCode) & 0x8000); -} - -namespace fs = std::filesystem; - -bool VideoConferenceModule::isHotkeyPressed(DWORD code, PowerToysSettings::HotkeyObject& hotkey) -{ - return code == hotkey.get_code() && - isKeyPressed(VK_SHIFT) == hotkey.shift_pressed() && - isKeyPressed(VK_CONTROL) == hotkey.ctrl_pressed() && - isKeyPressed(VK_LWIN) == hotkey.win_pressed() && - (isKeyPressed(VK_LMENU)) == hotkey.alt_pressed(); -} - -void VideoConferenceModule::reverseMicrophoneMute() -{ - // All controlled mic should same state with _microphoneTrackedInUI - // Avoid manually change in Control Panel make controlled mic has different state - bool muted = !getMicrophoneMuteState(); - for (auto& controlledMic : instance->_controlledMicrophones) - { - controlledMic->set_muted(muted); - } - if (muted) - { - Trace::MicrophoneMuted(); - } - instance->_mic_muted_state_during_disconnect = !instance->_mic_muted_state_during_disconnect; - - toolbar.setMicrophoneMute(muted); -} - -bool VideoConferenceModule::getMicrophoneMuteState() -{ - return instance->_microphoneTrackedInUI ? instance->_microphoneTrackedInUI->muted() : instance->_mic_muted_state_during_disconnect; -} - -void VideoConferenceModule::reverseVirtualCameraMuteState() -{ - bool muted = false; - if (!instance->_settingsUpdateChannel.has_value()) - { - return; - } - - instance->_settingsUpdateChannel->access([&muted](auto settingsMemory) { - auto settings = reinterpret_cast(settingsMemory._data); - settings->useOverlayImage = !settings->useOverlayImage; - muted = settings->useOverlayImage; - }); - - if (muted) - { - Trace::CameraMuted(); - } - toolbar.setCameraMute(muted); -} - -bool VideoConferenceModule::getVirtualCameraMuteState() -{ - bool disabled = false; - if (!instance->_settingsUpdateChannel.has_value()) - { - return disabled; - } - instance->_settingsUpdateChannel->access([&disabled](auto settingsMemory) { - auto settings = reinterpret_cast(settingsMemory._data); - disabled = settings->useOverlayImage; - }); - return disabled; -} - -bool VideoConferenceModule::getVirtualCameraInUse() -{ - if (!instance->_settingsUpdateChannel.has_value()) - { - return false; - } - bool inUse = false; - instance->_settingsUpdateChannel->access([&inUse](auto settingsMemory) { - auto settings = reinterpret_cast(settingsMemory._data); - inUse = settings->cameraInUse; - }); - return inUse; -} - -LRESULT CALLBACK VideoConferenceModule::LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) -{ - if (nCode == HC_ACTION) - { - KBDLLHOOKSTRUCT* kbd = reinterpret_cast(lParam); - switch (wParam) - { - case WM_KEYDOWN: - - if (isHotkeyPressed(kbd->vkCode, settings.cameraAndMicrophoneMuteHotkey)) - { - const bool cameraInUse = getVirtualCameraInUse(); - const bool microphoneIsMuted = getMicrophoneMuteState(); - const bool cameraIsMuted = cameraInUse && getVirtualCameraMuteState(); - if (cameraInUse) - { - // we're likely on a video call, so we must mute the unmuted cam/mic or reverse the mute state - // of everything, if cam and mic mute states are the same - if (microphoneIsMuted == cameraIsMuted) - { - reverseMicrophoneMute(); - reverseVirtualCameraMuteState(); - } - else if (cameraIsMuted) - { - reverseMicrophoneMute(); - } - else if (microphoneIsMuted) - { - reverseVirtualCameraMuteState(); - } - } - else - { - // if the camera is not in use, we just mute/unmute the mic - reverseMicrophoneMute(); - } - return 1; - } - else if (isHotkeyPressed(kbd->vkCode, settings.microphoneMuteHotkey)) - { - reverseMicrophoneMute(); - return 1; - } - else if (isHotkeyPressed(kbd->vkCode, settings.microphonePushToTalkHotkey)) - { - if (!pushToTalkPressed) - { - if (settings.pushToReverseEnabled || getMicrophoneMuteState()) - { - reverseMicrophoneMute(); - } - pushToTalkPressed = true; - } - return 1; - } - else if (isHotkeyPressed(kbd->vkCode, settings.cameraMuteHotkey)) - { - reverseVirtualCameraMuteState(); - return 1; - } - break; - case WM_KEYUP: - if (pushToTalkPressed && (kbd->vkCode == settings.microphonePushToTalkHotkey.get_code())) - { - reverseMicrophoneMute(); - pushToTalkPressed = false; - return 1; - } - } - } - - return CallNextHookEx(hook_handle, nCode, wParam, lParam); -} - -void VideoConferenceModule::onGeneralSettingsChanged() -{ - auto settings = PTSettingsHelper::load_general_settings(); - bool enabled = false; - try - { - if (json::has(settings, L"enabled")) - { - for (const auto& mod : settings.GetNamedObject(L"enabled")) - { - const auto value = mod.Value(); - if (value.ValueType() != json::JsonValueType::Boolean) - { - continue; - } - if (mod.Key() == get_key()) - { - enabled = value.GetBoolean(); - break; - } - } - } - } - catch (...) - { - LOG("Couldn't get enabled state"); - } - if (enabled) - { - enable(); - } - else - { - disable(); - } -} - -void VideoConferenceModule::onModuleSettingsChanged() -{ - try - { - PowerToysSettings::PowerToyValues values = PowerToysSettings::PowerToyValues::load_from_settings_file(get_key()); - //Trace::SettingsChanged(pressTime.value, overlayOpacity.value, theme.value); - - if (_enabled) - { - if (const auto val = values.get_json(L"mute_camera_and_microphone_hotkey")) - { - settings.cameraAndMicrophoneMuteHotkey = PowerToysSettings::HotkeyObject::from_json(*val); - } - if (const auto val = values.get_json(L"mute_microphone_hotkey")) - { - settings.microphoneMuteHotkey = PowerToysSettings::HotkeyObject::from_json(*val); - } - if (const auto val = values.get_json(L"push_to_talk_microphone_hotkey")) - { - settings.microphonePushToTalkHotkey = PowerToysSettings::HotkeyObject::from_json(*val); - } - if (const auto val = values.get_bool_value(L"push_to_reverse_enabled")) - { - settings.pushToReverseEnabled = *val; - } - if (const auto val = values.get_json(L"mute_camera_hotkey")) - { - settings.cameraMuteHotkey = PowerToysSettings::HotkeyObject::from_json(*val); - } - if (const auto val = values.get_string_value(L"toolbar_position")) - { - settings.toolbarPositionString = val.value(); - } - if (const auto val = values.get_string_value(L"toolbar_monitor")) - { - settings.toolbarMonitorString = val.value(); - } - if (const auto val = values.get_string_value(L"selected_camera"); val && val != settings.selectedCamera) - { - settings.selectedCamera = val.value(); - sendSourceCameraNameUpdate(); - } - if (const auto val = values.get_string_value(L"camera_overlay_image_path"); val && val != settings.imageOverlayPath) - { - settings.imageOverlayPath = val.value(); - sendOverlayImageUpdate(); - } - if (const auto val = values.get_string_value(L"toolbar_hide")) - { - toolbar.setToolbarHide(val.value()); - } - if (const auto val = values.get_string_value(L"startup_action")) - { - settings.startupAction = val.value(); - } - - const auto selectedMic = values.get_string_value(L"selected_mic"); - if (selectedMic && selectedMic != settings.selectedMicrophone) - { - settings.selectedMicrophone = *selectedMic; - updateControlledMicrophones(settings.selectedMicrophone); - } - - toolbar.show(settings.toolbarPositionString, settings.toolbarMonitorString); - } - } - catch (...) - { - LOG("onModuleSettingsChanged encountered an exception"); - } -} - -void VideoConferenceModule::onMicrophoneConfigurationChanged() -{ - if (!_controllingAllMics) - { - // Don't care if we don't control all the mics - return; - } - - const bool mutedStateForNewMics = getMicrophoneMuteState(); - std::unordered_set currentlyTrackedMicsIds; - for (const auto& controlledMic : _controlledMicrophones) - { - currentlyTrackedMicsIds.emplace(controlledMic->id()); - } - - auto allMics = MicrophoneDevice::getAllActive(); - for (auto& newMic : allMics) - { - if (currentlyTrackedMicsIds.contains(newMic->id())) - { - continue; - } - - if (mutedStateForNewMics) - { - newMic->set_muted(true); - } - - _controlledMicrophones.emplace_back(std::move(newMic)); - } - // Restore invalidated pointer - _microphoneTrackedInUI = controlledDefaultMic(); - if (_microphoneTrackedInUI) - { - _microphoneTrackedInUI->set_mute_changed_callback([](const bool muted) { - toolbar.setMicrophoneMute(muted); - }); - } -} - -VideoConferenceModule::VideoConferenceModule() -{ - init_settings(); - _settingsUpdateChannel = - SerializedSharedMemory::create(CameraSettingsUpdateChannel::endpoint(), sizeof(CameraSettingsUpdateChannel), false); - if (_settingsUpdateChannel) - { - _settingsUpdateChannel->access([](auto memory) { - -// Suppress warning 26403 - Reset or explicitly delete an owner pointer 'variable' (r.3) -// the video conference class should be only instantiated once and it is using placement new -// the access to the data can be done through memory._data -#pragma warning(push) -#pragma warning(disable : 26403) - auto updatesChannel = new (memory._data) CameraSettingsUpdateChannel{}; -#pragma warning(pop) - }); - } - sendSourceCameraNameUpdate(); - sendOverlayImageUpdate(); -} - -inline VideoConferenceModule::~VideoConferenceModule() -{ - toolbar.hide(); -} - -const wchar_t* VideoConferenceModule::get_name() -{ - return L"Video Conference"; -} - -const wchar_t* VideoConferenceModule::get_key() -{ - return L"Video Conference"; -} - -// Return the configured status for the gpo policy for the module -powertoys_gpo::gpo_rule_configured_t VideoConferenceModule::gpo_policy_enabled_configuration() -{ - return powertoys_gpo::getConfiguredVideoConferenceMuteEnabledValue(); -} - -bool VideoConferenceModule::get_config(wchar_t* buffer, int* buffer_size) -{ - return true; -} - -void VideoConferenceModule::set_config(const wchar_t* config) -{ - try - { - PowerToysSettings::PowerToyValues values = PowerToysSettings::PowerToyValues::from_json_string(config, get_key()); - values.save_to_settings_file(); - } - catch (...) - { - LOG("VideoConferenceModule::set_config: exception during saving new settings values"); - } -} - -void VideoConferenceModule::init_settings() -{ - try - { - PowerToysSettings::PowerToyValues powerToysSettings = PowerToysSettings::PowerToyValues::load_from_settings_file(L"Video Conference"); - - if (const auto val = powerToysSettings.get_json(L"mute_camera_and_microphone_hotkey")) - { - settings.cameraAndMicrophoneMuteHotkey = PowerToysSettings::HotkeyObject::from_json(*val); - } - if (const auto val = powerToysSettings.get_json(L"mute_microphone_hotkey")) - { - settings.microphoneMuteHotkey = PowerToysSettings::HotkeyObject::from_json(*val); - } - if (const auto val = powerToysSettings.get_json(L"push_to_talk_microphone_hotkey")) - { - settings.microphonePushToTalkHotkey = PowerToysSettings::HotkeyObject::from_json(*val); - } - if (const auto val = powerToysSettings.get_bool_value(L"push_to_reverse_enabled")) - { - settings.pushToReverseEnabled = *val; - } - if (const auto val = powerToysSettings.get_json(L"mute_camera_hotkey")) - { - settings.cameraMuteHotkey = PowerToysSettings::HotkeyObject::from_json(*val); - } - if (const auto val = powerToysSettings.get_string_value(L"toolbar_position")) - { - settings.toolbarPositionString = val.value(); - } - if (const auto val = powerToysSettings.get_string_value(L"toolbar_monitor")) - { - settings.toolbarMonitorString = val.value(); - } - if (const auto val = powerToysSettings.get_string_value(L"selected_camera")) - { - settings.selectedCamera = val.value(); - } - if (const auto val = powerToysSettings.get_string_value(L"camera_overlay_image_path")) - { - settings.imageOverlayPath = val.value(); - } - if (const auto val = powerToysSettings.get_string_value(L"toolbar_hide")) - { - toolbar.setToolbarHide(val.value()); - } - if (const auto val = powerToysSettings.get_string_value(L"startup_action")) - { - settings.startupAction = val.value(); - } - if (const auto val = powerToysSettings.get_string_value(L"selected_mic"); val && *val != settings.selectedMicrophone) - { - settings.selectedMicrophone = *val; - updateControlledMicrophones(settings.selectedMicrophone); - } - } - catch (std::exception&) - { - // Error while loading from the settings file. Just let default values stay as they are. - } - - try - { - auto loaded = PTSettingsHelper::load_general_settings(); - std::wstring settings_theme{ static_cast(loaded.GetNamedString(L"theme", L"system")) }; - if (settings_theme != L"dark" && settings_theme != L"light") - { - settings_theme = L"system"; - } - toolbar.setTheme(settings_theme); - } - catch (...) - { - } -} - -void VideoConferenceModule::updateControlledMicrophones(const std::wstring_view new_mic) -{ - for (auto& controlledMic : _controlledMicrophones) - { - controlledMic->set_muted(false); - } - _controlledMicrophones.clear(); - _microphoneTrackedInUI = nullptr; - auto allMics = MicrophoneDevice::getAllActive(); - if (new_mic == L"[All]") - { - _controllingAllMics = true; - _controlledMicrophones = std::move(allMics); - _microphoneTrackedInUI = controlledDefaultMic(); - } - else - { - _controllingAllMics = false; - for (auto& controlledMic : allMics) - { - if (controlledMic->name() == new_mic) - { - _controlledMicrophones.emplace_back(std::move(controlledMic)); - _microphoneTrackedInUI = _controlledMicrophones[0].get(); - break; - } - } - } - - if (_microphoneTrackedInUI) - { - _microphoneTrackedInUI->set_mute_changed_callback([](const bool muted) { - toolbar.setMicrophoneMute(muted); - }); - toolbar.setMicrophoneMute(_microphoneTrackedInUI->muted()); - } - - if (settings.startupAction == L"Unmute") - { - for (auto& controlledMic : _controlledMicrophones) - { - controlledMic->set_muted(false); - } - } - else if (settings.startupAction == L"Mute") - { - for (auto& controlledMic : _controlledMicrophones) - { - controlledMic->set_muted(true); - } - } -} - -MicrophoneDevice* VideoConferenceModule::controlledDefaultMic() -{ - if (auto defaultMic = MicrophoneDevice::getDefault()) - { - for (auto& controlledMic : _controlledMicrophones) - { - if (controlledMic->id() == defaultMic->id()) - { - return controlledMic.get(); - } - } - } - - return nullptr; -} - -void toggleProxyCamRegistration(const bool enable) -{ - if (!is_process_elevated()) - { - return; - } - - auto vcmRoot = fs::path{ get_module_folderpath() }; -#if defined(_M_ARM64) - std::array proxyFilters = { vcmRoot / "PowerToys.VideoConferenceProxyFilter_ARM64.dll", vcmRoot / "PowerToys.VideoConferenceProxyFilter_x86.dll" }; -#else - std::array proxyFilters = { vcmRoot / "PowerToys.VideoConferenceProxyFilter_x64.dll", vcmRoot / "PowerToys.VideoConferenceProxyFilter_x86.dll" }; -#endif - for (const auto filter : proxyFilters) - { - std::wstring params{ L"/s " }; - if (!enable) - { - params += L"/u "; - } - params += '"'; - params += filter; - params += '"'; - SHELLEXECUTEINFOW sei{ sizeof(sei) }; - sei.fMask = { SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC }; - sei.lpFile = L"regsvr32"; - sei.lpParameters = params.c_str(); - sei.nShow = SW_SHOWNORMAL; - ShellExecuteExW(&sei); - } -} - -void VideoConferenceModule::enable() -{ - if (!_enabled) - { - _generalSettingsWatcher = std::make_unique( - PTSettingsHelper::get_powertoys_general_save_file_location(), [this] { - toolbar.scheduleGeneralSettingsUpdate(); - }); - _moduleSettingsWatcher = std::make_unique( - PTSettingsHelper::get_module_save_file_location(get_key()), [this] { - toolbar.scheduleModuleSettingsUpdate(); - }); - - toggleProxyCamRegistration(true); - toolbar.setMicrophoneMute(getMicrophoneMuteState()); - toolbar.setCameraMute(getVirtualCameraMuteState()); - - toolbar.show(settings.toolbarPositionString, settings.toolbarMonitorString); - - _enabled = true; - -#if defined(DISABLE_LOWLEVEL_HOOKS_WHEN_DEBUGGED) - if (IsDebuggerPresent()) - { - return; - } -#endif - hook_handle = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), NULL); - } - Trace::EnableVideoConference(true); -} - -void VideoConferenceModule::unmuteAll() -{ - if (getVirtualCameraMuteState()) - { - reverseVirtualCameraMuteState(); - } - - if (getMicrophoneMuteState()) - { - reverseMicrophoneMute(); - } -} - -void VideoConferenceModule::muteAll() -{ - if (!getVirtualCameraMuteState()) - { - reverseVirtualCameraMuteState(); - } - - if (!getMicrophoneMuteState()) - { - reverseMicrophoneMute(); - } -} - -void VideoConferenceModule::disable() -{ - if (_enabled) - { - _generalSettingsWatcher.reset(); - _moduleSettingsWatcher.reset(); - toggleProxyCamRegistration(false); - if (hook_handle) - { - bool success = UnhookWindowsHookEx(hook_handle); - if (success) - { - hook_handle = nullptr; - } - } - - if (getVirtualCameraMuteState()) - { - reverseVirtualCameraMuteState(); - } - - toolbar.hide(); - - _enabled = false; - } - Trace::EnableVideoConference(false); -} - -bool VideoConferenceModule::is_enabled() -{ - return _enabled; -} - -void VideoConferenceModule::destroy() -{ - delete this; - instance = nullptr; -} - -bool VideoConferenceModule::is_enabled_by_default() const -{ - return false; -} - -void VideoConferenceModule::sendSourceCameraNameUpdate() -{ - if (!_settingsUpdateChannel.has_value() || settings.selectedCamera.empty()) - { - return; - } - _settingsUpdateChannel->access([](auto memory) { - auto updatesChannel = reinterpret_cast(memory._data); - updatesChannel->sourceCameraName.emplace(); - std::copy(begin(settings.selectedCamera), end(settings.selectedCamera), begin(*updatesChannel->sourceCameraName)); - if (settings.startupAction == L"Unmute") - { - updatesChannel->useOverlayImage = false; - } - else if (settings.startupAction == L"Mute") - { - updatesChannel->useOverlayImage = true; - } - }); -} - -void VideoConferenceModule::sendOverlayImageUpdate() -{ - if (!_settingsUpdateChannel.has_value()) - { - return; - } - _imageOverlayChannel.reset(); - - wchar_t powertoysDirectory[MAX_PATH + 1]; - - DWORD length = GetModuleFileNameW(nullptr, powertoysDirectory, MAX_PATH); - PathRemoveFileSpecW(powertoysDirectory); - - std::wstring blankImagePath(powertoysDirectory); - blankImagePath += L"\\Assets\\VCM\\black.bmp"; - - _imageOverlayChannel = SerializedSharedMemory::create_readonly(CameraOverlayImageChannel::endpoint(), - settings.imageOverlayPath != L"" ? settings.imageOverlayPath : blankImagePath); - - const auto imageSize = static_cast(_imageOverlayChannel->size()); - _settingsUpdateChannel->access([imageSize](auto memory) { - auto updatesChannel = reinterpret_cast(memory._data); - updatesChannel->overlayImageSize.emplace(imageSize); - updatesChannel->newOverlayImagePosted = true; - }); -} diff --git a/src/modules/videoconference/VideoConferenceModule/VideoConferenceModule.h b/src/modules/videoconference/VideoConferenceModule/VideoConferenceModule.h deleted file mode 100644 index f3b835867a84..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/VideoConferenceModule.h +++ /dev/null @@ -1,102 +0,0 @@ -#pragma once - -#include - -#include -#include - -#include - -#include -#include - -#include "Toolbar.h" - -#include - -extern class VideoConferenceModule* instance; - -struct VideoConferenceSettings -{ - PowerToysSettings::HotkeyObject cameraAndMicrophoneMuteHotkey = PowerToysSettings::HotkeyObject::from_settings(true, false, false, true, 81); - PowerToysSettings::HotkeyObject microphoneMuteHotkey = PowerToysSettings::HotkeyObject::from_settings(true, false, false, true, 65); - PowerToysSettings::HotkeyObject microphonePushToTalkHotkey = PowerToysSettings::HotkeyObject::from_settings(true, false, false, true, 73); - PowerToysSettings::HotkeyObject cameraMuteHotkey = PowerToysSettings::HotkeyObject::from_settings(true, false, false, true, 79); - - std::wstring toolbarPositionString; - std::wstring toolbarMonitorString; - - std::wstring selectedCamera; - std::wstring imageOverlayPath; - std::wstring selectedMicrophone; - - std::wstring startupAction; - - bool pushToReverseEnabled = false; -}; - -class VideoConferenceModule : public PowertoyModuleIface -{ -public: - VideoConferenceModule(); - ~VideoConferenceModule(); - virtual const wchar_t* get_name() override; - - virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override; - - virtual bool get_config(wchar_t* buffer, int* buffer_size) override; - - virtual void set_config(const wchar_t* config) override; - - virtual void enable() override; - virtual void disable() override; - virtual bool is_enabled() override; - virtual void destroy() override; - virtual bool is_enabled_by_default() const override; - - virtual const wchar_t * get_key() override; - - void sendSourceCameraNameUpdate(); - void sendOverlayImageUpdate(); - - static void unmuteAll(); - static void muteAll(); - static void reverseMicrophoneMute(); - static bool getMicrophoneMuteState(); - static void reverseVirtualCameraMuteState(); - static bool getVirtualCameraMuteState(); - static bool getVirtualCameraInUse(); - - void onGeneralSettingsChanged(); - void onModuleSettingsChanged(); - void onMicrophoneConfigurationChanged(); - -private: - - void init_settings(); - void updateControlledMicrophones(const std::wstring_view new_mic); - MicrophoneDevice* controlledDefaultMic(); - - // all callback methods and used by callback have to be static - static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam); - static bool isKeyPressed(unsigned int keyCode); - static bool isHotkeyPressed(DWORD code, PowerToysSettings::HotkeyObject& hotkey); - - static HHOOK hook_handle; - bool _enabled = false; - - bool _mic_muted_state_during_disconnect = false; - bool _controllingAllMics = false; - std::vector> _controlledMicrophones; - MicrophoneDevice* _microphoneTrackedInUI = nullptr; - - std::optional _imageOverlayChannel; - std::optional _settingsUpdateChannel; - - std::unique_ptr _generalSettingsWatcher; - std::unique_ptr _moduleSettingsWatcher; - - static VideoConferenceSettings settings; - static Toolbar toolbar; - static bool pushToTalkPressed; -}; diff --git a/src/modules/videoconference/VideoConferenceModule/dllmain.cpp b/src/modules/videoconference/VideoConferenceModule/dllmain.cpp deleted file mode 100644 index c3d012cd6c5f..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/dllmain.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// dllmain.cpp : Defines the entry point for the DLL application. -#include "pch.h" -#include -#include "trace.h" -#include "VideoConferenceModule.h" - -BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) -{ - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - Trace::RegisterProvider(); - break; - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - break; - case DLL_PROCESS_DETACH: - Trace::UnregisterProvider(); - break; - } - return TRUE; -} - -extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create() -{ - if (!instance) - { - instance = new VideoConferenceModule(); - return instance; - } - else - { - return nullptr; - } -} diff --git a/src/modules/videoconference/VideoConferenceModule/framework.h b/src/modules/videoconference/VideoConferenceModule/framework.h deleted file mode 100644 index 54b83e94fd33..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/framework.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -// Windows Header Files -#include diff --git a/src/modules/videoconference/VideoConferenceModule/pch.h b/src/modules/videoconference/VideoConferenceModule/pch.h deleted file mode 100644 index 7c614d9a5c65..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/pch.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once -#define WIN32_LEAN_AND_MEAN -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include diff --git a/src/modules/videoconference/VideoConferenceModule/resource.h b/src/modules/videoconference/VideoConferenceModule/resource.h deleted file mode 100644 index 6073efd0c352..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/resource.h +++ /dev/null @@ -1,13 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by VideoConferenceModule.rc - -////////////////////////////// -// Non-localizable - -#define FILE_DESCRIPTION "PowerToys VideoConferenceMute Module" -#define INTERNAL_NAME "PowerToys.VideoConferenceModule" -#define ORIGINAL_FILENAME "PowerToys.VideoConferenceModule.dll" - -// Non-localizable -////////////////////////////// diff --git a/src/modules/videoconference/VideoConferenceModule/trace.cpp b/src/modules/videoconference/VideoConferenceModule/trace.cpp deleted file mode 100644 index 043c6b30e74b..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/trace.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "pch.h" - -#include "trace.h" - -#include - -TRACELOGGING_DEFINE_PROVIDER( - g_hProvider, - "Microsoft.PowerToys", - // {38e8889b-9731-53f5-e901-e8a7c1753074} - (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), - TraceLoggingOptionProjectTelemetry()); - -// Log if the user has VCM enabled or disabled -void Trace::EnableVideoConference(const bool enabled) noexcept -{ - TraceLoggingWriteWrapper( - g_hProvider, - "VideoConference_EnableVideoConference", - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), - TraceLoggingBoolean(enabled, "Enabled")); -} - -void Trace::SettingsChanged(const struct VideoConferenceSettings& settings) noexcept -{ - bool CustomOverlayImage = (settings.imageOverlayPath.length() > 0); - - TraceLoggingWriteWrapper( - g_hProvider, - "VideoConference_SettingsChanged", - TraceLoggingWideString(settings.toolbarPositionString.c_str(), "ToolbarPosition"), - TraceLoggingWideString(settings.toolbarMonitorString.c_str(), "ToolbarMonitorSelection"), - TraceLoggingBool(CustomOverlayImage, "CustomImageOverlayUsed"), - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); -} - -void Trace::MicrophoneMuted() noexcept -{ - TraceLoggingWriteWrapper( - g_hProvider, - "VideoConference_MicrophoneMuted", - TraceLoggingBoolean(true, "MicrophoneMuted"), - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); -} - -void Trace::CameraMuted() noexcept -{ - TraceLoggingWriteWrapper( - g_hProvider, - "VideoConference_CameraMuted", - TraceLoggingBoolean(true, "CameraMuted"), - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); -} diff --git a/src/modules/videoconference/VideoConferenceModule/trace.h b/src/modules/videoconference/VideoConferenceModule/trace.h deleted file mode 100644 index 0a9f193e6951..000000000000 --- a/src/modules/videoconference/VideoConferenceModule/trace.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "VideoConferenceModule.h" - -#include - -class Trace : public telemetry::TraceBase -{ -public: - static void EnableVideoConference(const bool enabled) noexcept; - static void SettingsChanged(const struct VideoConferenceSettings &settings) noexcept; - static void MicrophoneMuted() noexcept; - static void CameraMuted() noexcept; -}; diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/DirectShowUtils.cpp b/src/modules/videoconference/VideoConferenceProxyFilter/DirectShowUtils.cpp deleted file mode 100644 index ef2d3f76ea5e..000000000000 --- a/src/modules/videoconference/VideoConferenceProxyFilter/DirectShowUtils.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include "DirectShowUtils.h" - -#include - -unique_media_type_ptr CopyMediaType(const AM_MEDIA_TYPE* source) -{ - unique_media_type_ptr target{ static_cast(CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE))) }; - *target = *source; - if (source->cbFormat) - { - target->pbFormat = static_cast(CoTaskMemAlloc(source->cbFormat)); - std::copy(source->pbFormat, source->pbFormat + source->cbFormat, target->pbFormat); - } - - if (target->pUnk) - { - target->pUnk->AddRef(); - } - - return target; -} - -wil::com_ptr_nothrow GetPinAllocator(wil::com_ptr_nothrow& inputPin) -{ - if (!inputPin) - { - return nullptr; - } - wil::com_ptr_nothrow allocator; - if (auto memInput = inputPin.try_query(); memInput) - { - memInput->GetAllocator(&allocator); - return allocator; - } - - return nullptr; -} - -void MyFreeMediaType(AM_MEDIA_TYPE& mt) -{ - if (mt.cbFormat != 0) - { - CoTaskMemFree(mt.pbFormat); - mt.cbFormat = 0; - mt.pbFormat = nullptr; - } - - if (mt.pUnk != nullptr) - { - mt.pUnk->Release(); - mt.pUnk = nullptr; - } -} - -void MyDeleteMediaType(AM_MEDIA_TYPE* pmt) -{ - if (!pmt) - { - return; - } - - MyFreeMediaType(*pmt); - CoTaskMemFree(const_cast(pmt)); -} - -HRESULT MediaTypeEnumerator::Next(ULONG cObjects, AM_MEDIA_TYPE** outObjects, ULONG* pcFetched) -{ - if (!outObjects) - { - return E_POINTER; - } - - ULONG fetched = 0; - ULONG toFetch = cObjects; - while (toFetch-- && _pos < _objects.size()) - { - auto copy = CopyMediaType(_objects[_pos++].get()); - outObjects[fetched++] = copy.release(); - } - - if (pcFetched) - { - *pcFetched = fetched; - } - - return fetched == cObjects ? S_OK : S_FALSE; -} - -HRESULT MediaTypeEnumerator::Skip(ULONG cObjects) -{ - _pos += cObjects; - return _pos < _objects.size() ? S_OK : S_FALSE; -} - -HRESULT MediaTypeEnumerator::Reset() -{ - _pos = 0; - return S_OK; -} - -HRESULT MediaTypeEnumerator::Clone(IEnumMediaTypes** ppEnum) -{ - auto cloned = winrt::make_self(); - cloned->_objects.resize(_objects.size()); - for (size_t i = 0; i < _objects.size(); ++i) - { - cloned->_objects[i] = CopyMediaType(_objects[i].get()); - } - - cloned->_pos = _pos; - cloned.as().copy_to(ppEnum); - return S_OK; -} \ No newline at end of file diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/DirectShowUtils.h b/src/modules/videoconference/VideoConferenceProxyFilter/DirectShowUtils.h deleted file mode 100644 index d8c35a54b62b..000000000000 --- a/src/modules/videoconference/VideoConferenceProxyFilter/DirectShowUtils.h +++ /dev/null @@ -1,87 +0,0 @@ -#pragma once -#include - -#define WIN32_LEAN_AND_MEAN -#include -#include - -#include -#include - -#include - -#include "Logging.h" - -void MyDeleteMediaType(AM_MEDIA_TYPE* pmt); - -using unique_media_type_ptr = - wistd::unique_ptr>; - -unique_media_type_ptr CopyMediaType(const AM_MEDIA_TYPE* source); - -template -struct ObjectEnumerator : public winrt::implements, EnumeratorInterface> -{ - std::vector> _objects; - ULONG _pos = 0; - - HRESULT STDMETHODCALLTYPE Next(ULONG cObjects, ObjectInterface** outObjects, ULONG* pcFetched) override - { - if (!outObjects) - { - return E_POINTER; - } - - ULONG fetched = 0; - ULONG toFetch = cObjects; - while (toFetch-- && _pos < _objects.size()) - { - _objects[_pos++].copy_to(&outObjects[fetched++]); - } - - if (pcFetched) - { - *pcFetched = fetched; - } - - return fetched == cObjects ? S_OK : S_FALSE; - } - - HRESULT STDMETHODCALLTYPE Skip(ULONG cObjects) override - { - _pos += cObjects; - return _pos < _objects.size() ? S_OK : S_FALSE; - } - - HRESULT STDMETHODCALLTYPE Reset() override - { - _pos = 0; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE Clone(EnumeratorInterface** ppEnum) override - { - auto cloned = winrt::make_self(); - cloned->_objects = _objects; - cloned->_pos = _pos; - cloned.as().copy_to(ppEnum); - return S_OK; - } - - virtual ~ObjectEnumerator() = default; -}; - -struct MediaTypeEnumerator : public winrt::implements -{ - std::vector _objects; - ULONG _pos = 0; - - HRESULT STDMETHODCALLTYPE Next(ULONG cObjects, AM_MEDIA_TYPE** outObjects, ULONG* pcFetched) override; - HRESULT STDMETHODCALLTYPE Skip(ULONG cObjects) override; - HRESULT STDMETHODCALLTYPE Reset() override; - HRESULT STDMETHODCALLTYPE Clone(IEnumMediaTypes** ppEnum) override; - - virtual ~MediaTypeEnumerator() = default; -}; - -wil::com_ptr_nothrow GetPinAllocator(wil::com_ptr_nothrow& inputPin); diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/ImageLoading.cpp b/src/modules/videoconference/VideoConferenceProxyFilter/ImageLoading.cpp deleted file mode 100644 index 48878011540e..000000000000 --- a/src/modules/videoconference/VideoConferenceProxyFilter/ImageLoading.cpp +++ /dev/null @@ -1,424 +0,0 @@ -#include - -#include -#include -#include - -#pragma warning(push) -#pragma warning(disable : 4005) -#include -#pragma warning(pop) - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include - -#include "Logging.h" - -IWICImagingFactory* _GetWIC() noexcept -{ - static IWICImagingFactory* s_Factory = nullptr; - - if (s_Factory) - { - return s_Factory; - } - - OK_OR_BAIL(CoCreateInstance( - CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWICImagingFactory), (LPVOID*)&s_Factory)); - - return s_Factory; -} - -bool ReencodeJPGImage(BYTE* imageBuf, const DWORD imageSize, DWORD& reencodedSize) -{ - auto pWIC = _GetWIC(); - wil::com_ptr_nothrow imageStream = SHCreateMemStream(imageBuf, imageSize); - if (!imageStream) - { - return false; - } - - // Decode jpg into bitmap - wil::com_ptr_nothrow bitmapDecoder; - OK_OR_BAIL(pWIC->CreateDecoderFromStream(imageStream.get(), nullptr, WICDecodeMetadataCacheOnLoad, &bitmapDecoder)); - wil::com_ptr_nothrow decodedFrame; - OK_OR_BAIL(bitmapDecoder->GetFrame(0, &decodedFrame)); - wil::com_ptr_nothrow bitmap; - bitmap.attach(decodedFrame.detach()); - UINT width = 0, height = 0; - OK_OR_BAIL(bitmap->GetSize(&width, &height)); - - // Initialize jpg encoder - wil::com_ptr_nothrow encoder; - OK_OR_BAIL(pWIC->CreateEncoder(GUID_ContainerFormatJpeg, nullptr, &encoder)); - - wil::com_ptr_nothrow outputStream; - OK_OR_BAIL(CreateStreamOnHGlobal(nullptr, true, &outputStream)); - OK_OR_BAIL(encoder->Initialize(outputStream.get(), WICBitmapEncoderNoCache)); - wil::com_ptr_nothrow encodedFrame; - wil::com_ptr_nothrow encoderOptions; - OK_OR_BAIL(encoder->CreateNewFrame(&encodedFrame, &encoderOptions)); - - ULONG nProperties = 0; - OK_OR_BAIL(encoderOptions->CountProperties(&nProperties)); - for (ULONG propIdx = 0; propIdx < nProperties; ++propIdx) - { - PROPBAG2 propBag{}; - ULONG _; - OK_OR_BAIL(encoderOptions->GetPropertyInfo(propIdx, 1, &propBag, &_)); - if (propBag.pstrName == std::wstring_view{ L"ImageQuality" }) - { - wil::unique_variant variant; - variant.vt = VT_R4; - variant.fltVal = 0.1f; - OK_OR_BAIL(encoderOptions->Write(1, &propBag, &variant)); - LOG("Successfully set jpg compression quality"); - // skip the rest of the properties - propIdx = nProperties; - } - CoTaskMemFree(propBag.pstrName); - } - - OK_OR_BAIL(encodedFrame->Initialize(encoderOptions.get())); - WICPixelFormatGUID intermediateFormat = GUID_WICPixelFormat24bppRGB; - - OK_OR_BAIL(encodedFrame->SetPixelFormat(&intermediateFormat)); - OK_OR_BAIL(encodedFrame->SetSize(width, height)); - - // Commit the image encoding - OK_OR_BAIL(encodedFrame->WriteSource(bitmap.get(), nullptr)); - OK_OR_BAIL(encodedFrame->Commit()); - OK_OR_BAIL(encoder->Commit()); - - STATSTG intermediateStreamStat{}; - OK_OR_BAIL(outputStream->Stat(&intermediateStreamStat, STATFLAG_NONAME)); - const ULONGLONG jpgStreamSize = intermediateStreamStat.cbSize.QuadPart; - HGLOBAL streamMemoryHandle{}; - OK_OR_BAIL(GetHGlobalFromStream(outputStream.get(), &streamMemoryHandle)); - - auto jpgStreamMemory = static_cast(GlobalLock(streamMemoryHandle)); - std::copy(jpgStreamMemory, jpgStreamMemory + jpgStreamSize, imageBuf); - auto unlockJpgStreamMemory = wil::scope_exit([jpgStreamMemory] { GlobalUnlock(jpgStreamMemory); }); - reencodedSize = static_cast(jpgStreamSize); - return true; -} - -wil::com_ptr_nothrow LoadAsRGB24BitmapWithSize(IWICImagingFactory* pWIC, - wil::com_ptr_nothrow image, - const UINT targetWidth, - const UINT targetHeight) -{ - wil::com_ptr_nothrow bitmap; - // Initialize image bitmap decoder from filename and get the image frame - wil::com_ptr_nothrow bitmapDecoder; - OK_OR_BAIL(pWIC->CreateDecoderFromStream(image.get(), nullptr, WICDecodeMetadataCacheOnLoad, &bitmapDecoder)); - - wil::com_ptr_nothrow decodedFrame; - OK_OR_BAIL(bitmapDecoder->GetFrame(0, &decodedFrame)); - - UINT imageWidth = 0, imageHeight = 0; - OK_OR_BAIL(decodedFrame->GetSize(&imageWidth, &imageHeight)); - - // Scale the image if required - if (targetWidth != imageWidth || targetHeight != imageHeight) - { - wil::com_ptr_nothrow scaler; - OK_OR_BAIL(pWIC->CreateBitmapScaler(&scaler)); - OK_OR_BAIL( - scaler->Initialize(decodedFrame.get(), targetWidth, targetHeight, WICBitmapInterpolationModeHighQualityCubic)); - bitmap.attach(scaler.detach()); - } - else - { - bitmap.attach(decodedFrame.detach()); - } - WICPixelFormatGUID pixelFormat{}; - OK_OR_BAIL(bitmap->GetPixelFormat(&pixelFormat)); - - const auto targetPixelFormat = GUID_WICPixelFormat24bppBGR; - if (pixelFormat != targetPixelFormat) - { - wil::com_ptr_nothrow convertedBitmap; - if (SUCCEEDED(WICConvertBitmapSource(targetPixelFormat, bitmap.get(), &convertedBitmap))) - { - return convertedBitmap; - } - } - - return bitmap; -} - -wil::com_ptr_nothrow EncodeBitmapToContainer(IWICImagingFactory* pWIC, - wil::com_ptr_nothrow bitmap, - const GUID& containerGUID, - const UINT width, - const UINT height, - const float quality) -{ - wil::com_ptr_nothrow encoder; - pWIC->CreateEncoder(containerGUID, nullptr, &encoder); - - if (!encoder) - { - return nullptr; - } - - // Prepare the encoder output memory stream and encoding params - wil::com_ptr_nothrow encodedBitmap; - OK_OR_BAIL(CreateStreamOnHGlobal(nullptr, true, &encodedBitmap)); - OK_OR_BAIL(encoder->Initialize(encodedBitmap.get(), WICBitmapEncoderNoCache)); - wil::com_ptr_nothrow encodedFrame; - - wil::com_ptr_nothrow encoderOptions; - OK_OR_BAIL(encoder->CreateNewFrame(&encodedFrame, &encoderOptions)); - - ULONG nProperties = 0; - OK_OR_BAIL(encoderOptions->CountProperties(&nProperties)); - for (ULONG propIdx = 0; propIdx < nProperties; ++propIdx) - { - PROPBAG2 propBag{}; - ULONG _; - OK_OR_BAIL(encoderOptions->GetPropertyInfo(propIdx, 1, &propBag, &_)); - if (propBag.pstrName == std::wstring_view{ L"ImageQuality" }) - { - wil::unique_variant variant; - variant.vt = VT_R4; - variant.fltVal = quality; - OK_OR_BAIL(encoderOptions->Write(1, &propBag, &variant)); - LOG("Successfully set jpg compression quality"); - // skip the rest of the properties - propIdx = nProperties; - } - CoTaskMemFree(propBag.pstrName); - } - - OK_OR_BAIL(encodedFrame->Initialize(encoderOptions.get())); - - WICPixelFormatGUID intermediateFormat = GUID_WICPixelFormat24bppRGB; - OK_OR_BAIL(encodedFrame->SetPixelFormat(&intermediateFormat)); - OK_OR_BAIL(encodedFrame->SetSize(width, height)); - - // Commit the image encoding - OK_OR_BAIL(encodedFrame->WriteSource(bitmap.get(), nullptr)); - OK_OR_BAIL(encodedFrame->Commit()); - OK_OR_BAIL(encoder->Commit()); - return encodedBitmap; -} - -IMFSample* ConvertIMFVideoSample(const MFT_REGISTER_TYPE_INFO& inputType, - IMFMediaType* outputMediaType, - const wil::com_ptr_nothrow& inputSample, - const UINT width, - const UINT height) -{ - IMFActivate** ppVDActivate = nullptr; - UINT32 count = 0; - - MFT_REGISTER_TYPE_INFO outputType = { MFMediaType_Video, {} }; - outputMediaType->GetGUID(MF_MT_SUBTYPE, &outputType.guidSubtype); - - const std::array transformerCategories = { - MFT_CATEGORY_VIDEO_PROCESSOR, MFT_CATEGORY_VIDEO_DECODER, MFT_CATEGORY_VIDEO_ENCODER - }; - - for (const auto& transformerCategory : transformerCategories) - { - OK_OR_BAIL(MFTEnumEx(transformerCategory, MFT_ENUM_FLAG_SYNCMFT, &inputType, &outputType, &ppVDActivate, &count)); - if (count != 0) - { - break; - } - } - - wil::com_ptr_nothrow videoTransformer; - - bool videoDecoderActivated = false; - for (UINT32 i = 0; i < count; ++i) - { - if (!videoDecoderActivated && !FAILED(ppVDActivate[i]->ActivateObject(IID_PPV_ARGS(&videoTransformer)))) - { - videoDecoderActivated = true; - } - ppVDActivate[i]->Release(); - } - - if (count) - { - CoTaskMemFree(ppVDActivate); - } - - if (!videoDecoderActivated) - { - LOG("No converter available for the selected format"); - return nullptr; - } - - auto shutdownVideoDecoder = wil::scope_exit([&videoTransformer] { MFShutdownObject(videoTransformer.get()); }); - // Set input/output types for the decoder - wil::com_ptr_nothrow intermediateFrameMediaType; - OK_OR_BAIL(MFCreateMediaType(&intermediateFrameMediaType)); - intermediateFrameMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); - intermediateFrameMediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB24); - intermediateFrameMediaType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive); - intermediateFrameMediaType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE); - OK_OR_BAIL(MFSetAttributeSize(intermediateFrameMediaType.get(), MF_MT_FRAME_SIZE, width, height)); - OK_OR_BAIL(MFSetAttributeRatio(intermediateFrameMediaType.get(), MF_MT_PIXEL_ASPECT_RATIO, width, height)); - OK_OR_BAIL(videoTransformer->SetInputType(0, intermediateFrameMediaType.get(), 0)); - OK_OR_BAIL(videoTransformer->SetOutputType(0, outputMediaType, 0)); - - // Process the input sample - OK_OR_BAIL(videoTransformer->ProcessInput(0, inputSample.get(), 0)); - - // Check whether we need to allocate output sample and buffer ourselves - MFT_OUTPUT_STREAM_INFO outputStreamInfo{}; - OK_OR_BAIL(videoTransformer->GetOutputStreamInfo(0, &outputStreamInfo)); - const bool onlyProvidesSamples = outputStreamInfo.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES; - const bool canProvideSamples = outputStreamInfo.dwFlags & MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES; - const bool mustAllocateSample = - (!onlyProvidesSamples && !canProvideSamples) || - (!onlyProvidesSamples && (outputStreamInfo.dwFlags & MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER)); - - MFT_OUTPUT_DATA_BUFFER outputSamples{}; - IMFSample* outputSample = nullptr; - - // If so, do the allocation - if (mustAllocateSample) - { - OK_OR_BAIL(MFCreateSample(&outputSample)); - OK_OR_BAIL(outputSample->SetSampleDuration(333333)); - OK_OR_BAIL(outputSample->SetSampleTime(1)); - OK_OR_BAIL(outputSample->SetUINT32(MF_MT_VIDEO_ROTATION, MFVideoRotationFormat::MFVideoRotationFormat_0)); - IMFMediaBuffer* outputMediaBuffer = nullptr; - OK_OR_BAIL( - MFCreateAlignedMemoryBuffer(outputStreamInfo.cbSize, outputStreamInfo.cbAlignment - 1, &outputMediaBuffer)); - OK_OR_BAIL(outputMediaBuffer->SetCurrentLength(outputStreamInfo.cbSize)); - OK_OR_BAIL(outputSample->AddBuffer(outputMediaBuffer)); - outputSamples.pSample = outputSample; - } - - // Finally, produce the output sample - DWORD processStatus = 0; - if (failed(videoTransformer->ProcessOutput(0, 1, &outputSamples, &processStatus))) - { - LOG("Failed to convert image frame"); - } - if (outputSamples.pEvents) - { - outputSamples.pEvents->Release(); - } - - return outputSamples.pSample; -} - -wil::com_ptr_nothrow LoadImageAsSample(wil::com_ptr_nothrow imageStream, - IMFMediaType* sampleMediaType, - const float quality) noexcept -{ - UINT targetWidth = 0; - UINT targetHeight = 0; - OK_OR_BAIL(MFGetAttributeSize(sampleMediaType, MF_MT_FRAME_SIZE, &targetWidth, &targetHeight)); - MFT_REGISTER_TYPE_INFO outputType = { MFMediaType_Video, {} }; - OK_OR_BAIL(sampleMediaType->GetGUID(MF_MT_SUBTYPE, &outputType.guidSubtype)); - - IWICImagingFactory* pWIC = _GetWIC(); - if (!pWIC) - { - LOG("Failed to create IWICImagingFactory"); - return nullptr; - } - - if (!imageStream) - { - return nullptr; - } - - const auto srcImageBitmap = LoadAsRGB24BitmapWithSize(pWIC, imageStream, targetWidth, targetHeight); - if (!srcImageBitmap) - { - return nullptr; - } - - // First, let's create a sample containing RGB24 bitmap - IMFSample* outputSample = nullptr; - OK_OR_BAIL(MFCreateSample(&outputSample)); - OK_OR_BAIL(outputSample->SetUINT32(MF_MT_VIDEO_ROTATION, MFVideoRotationFormat::MFVideoRotationFormat_0)); - OK_OR_BAIL(outputSample->SetSampleDuration(333333)); - OK_OR_BAIL(outputSample->SetSampleTime(1)); - IMFMediaBuffer* outputMediaBuffer = nullptr; - const DWORD nPixelBytes = targetWidth * targetHeight * 3; - OK_OR_BAIL(MFCreateAlignedMemoryBuffer(nPixelBytes, MF_64_BYTE_ALIGNMENT, &outputMediaBuffer)); - - const UINT stride = 3 * targetWidth; - - DWORD max_length = 0, current_length = 0; - BYTE* sampleBufferMemory = nullptr; - OK_OR_BAIL(outputMediaBuffer->Lock(&sampleBufferMemory, &max_length, ¤t_length)); - OK_OR_BAIL(srcImageBitmap->CopyPixels(nullptr, stride, nPixelBytes, sampleBufferMemory)); - OK_OR_BAIL(outputMediaBuffer->Unlock()); - - OK_OR_BAIL(outputMediaBuffer->SetCurrentLength(nPixelBytes)); - OK_OR_BAIL(outputSample->AddBuffer(outputMediaBuffer)); - - if (outputType.guidSubtype == MFVideoFormat_RGB24) - { - return outputSample; - } - - // Special case for mjpg, since we need to use jpg container for it instead of supplying raw pixels - if (outputType.guidSubtype == MFVideoFormat_MJPG) - { - // Use an intermediate jpg container sample which will be transcoded to the target format - wil::com_ptr_nothrow jpgStream = - EncodeBitmapToContainer(pWIC, srcImageBitmap, GUID_ContainerFormatJpeg, targetWidth, targetHeight, quality); - - // Obtain stream size and lock its memory pointer - STATSTG intermediateStreamStat{}; - OK_OR_BAIL(jpgStream->Stat(&intermediateStreamStat, STATFLAG_NONAME)); - const ULONGLONG jpgStreamSize = intermediateStreamStat.cbSize.QuadPart; - HGLOBAL streamMemoryHandle{}; - OK_OR_BAIL(GetHGlobalFromStream(jpgStream.get(), &streamMemoryHandle)); - - auto jpgStreamMemory = static_cast(GlobalLock(streamMemoryHandle)); - auto unlockJpgStreamMemory = wil::scope_exit([jpgStreamMemory] { GlobalUnlock(jpgStreamMemory); }); - - // Create a sample from the input image buffer - wil::com_ptr_nothrow jpgSample; - OK_OR_BAIL(MFCreateSample(&jpgSample)); - OK_OR_BAIL(jpgSample->SetUINT32(MF_MT_VIDEO_ROTATION, MFVideoRotationFormat::MFVideoRotationFormat_0)); - IMFMediaBuffer* inputMediaBuffer = nullptr; - OK_OR_BAIL(MFCreateAlignedMemoryBuffer(static_cast(jpgStreamSize), MF_64_BYTE_ALIGNMENT, &inputMediaBuffer)); - BYTE* inputBuf = nullptr; - OK_OR_BAIL(inputMediaBuffer->Lock(&inputBuf, &max_length, ¤t_length)); - if (max_length < jpgStreamSize) - { - return nullptr; - } - - std::copy(jpgStreamMemory, jpgStreamMemory + jpgStreamSize, inputBuf); - unlockJpgStreamMemory.reset(); - OK_OR_BAIL(inputMediaBuffer->Unlock()); - OK_OR_BAIL(inputMediaBuffer->SetCurrentLength(static_cast(jpgStreamSize))); - OK_OR_BAIL(jpgSample->AddBuffer(inputMediaBuffer)); - - return jpgSample; - } - - // Now we are ready to convert it to the requested media type - MFT_REGISTER_TYPE_INFO intermediateType = { MFMediaType_Video, MFVideoFormat_RGB24 }; - - // But if no conversion is needed, just return the input sample - - return ConvertIMFVideoSample(intermediateType, sampleMediaType, outputSample, targetWidth, targetHeight); -} \ No newline at end of file diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/Resources.resx b/src/modules/videoconference/VideoConferenceProxyFilter/Resources.resx deleted file mode 100644 index 4770a524fe27..000000000000 --- a/src/modules/videoconference/VideoConferenceProxyFilter/Resources.resx +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - VideoCaptureProxyFilter - do not loc, product name - - diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/VideoCaptureDevice.cpp b/src/modules/videoconference/VideoConferenceProxyFilter/VideoCaptureDevice.cpp deleted file mode 100644 index 7b97891c5b39..000000000000 --- a/src/modules/videoconference/VideoConferenceProxyFilter/VideoCaptureDevice.cpp +++ /dev/null @@ -1,636 +0,0 @@ -#include "Logging.h" -#include "VideoCaptureDevice.h" - -#include -#include - -struct VideoCaptureReceiverFilter : winrt::implements -{ - FILTER_STATE _state = State_Stopped; - IFilterGraph* _graph = nullptr; - wil::com_ptr_nothrow _videoReceiverPin; - - ULONG STDMETHODCALLTYPE GetMiscFlags() override { return AM_FILTER_MISC_FLAGS_IS_RENDERER; } - - HRESULT STDMETHODCALLTYPE GetClassID(CLSID*) override { return E_NOTIMPL; } - - HRESULT STDMETHODCALLTYPE Stop() override - { - _state = State_Stopped; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE Pause() override - { - _state = State_Paused; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE Run(REFERENCE_TIME) override - { - _state = State_Running; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE GetState(DWORD, FILTER_STATE* outState) override - { - *outState = _state; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE GetSyncSource(IReferenceClock** outRefClock) override - { - *outRefClock = nullptr; - return NOERROR; - } - - HRESULT STDMETHODCALLTYPE SetSyncSource(IReferenceClock*) override { return S_OK; } - - HRESULT STDMETHODCALLTYPE EnumPins(IEnumPins** ppEnum) override - { - auto enumerator = winrt::make_self>(); - enumerator->_objects.emplace_back(_videoReceiverPin); - *ppEnum = enumerator.detach(); - - return S_OK; - } - - HRESULT STDMETHODCALLTYPE FindPin(LPCWSTR, IPin**) override { return E_NOTIMPL; } - - HRESULT STDMETHODCALLTYPE JoinFilterGraph(IFilterGraph* pGraph, LPCWSTR) override - { - _graph = pGraph; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE QueryFilterInfo(FILTER_INFO* pInfo) override - { - std::copy(std::begin(NAME), std::end(NAME), pInfo->achName); - if (_graph) - { - pInfo->pGraph = _graph; - _graph->AddRef(); - } - return S_OK; - } - - HRESULT STDMETHODCALLTYPE QueryVendorInfo(LPWSTR* pVendorInfo) override - { - auto info = static_cast(CoTaskMemAlloc(sizeof(VENDOR))); - std::copy(std::begin(VENDOR), std::end(VENDOR), info); - *pVendorInfo = info; - return S_OK; - } - - virtual ~VideoCaptureReceiverFilter() = default; - - constexpr static inline wchar_t NAME[] = L"PowerToysVCMCaptureFilter"; - constexpr static inline wchar_t VENDOR[] = L"Microsoft Corporation"; -}; - -struct VideoCaptureReceiverPin : winrt::implements -{ - VideoCaptureReceiverFilter* _owningFilter = nullptr; - unique_media_type_ptr _expectedMediaType; - wil::com_ptr_nothrow _captureInputPin; - unique_media_type_ptr _inputCaptureMediaType; - std::atomic_bool _flushing = false; - VideoCaptureDevice::callback_t _frameCallback; - - wil::com_ptr_nothrow _allocator; - - VideoCaptureReceiverPin(unique_media_type_ptr mediaType, VideoCaptureReceiverFilter* filter) : - _expectedMediaType{ std::move(mediaType) }, _owningFilter{ filter } - { - } - - HRESULT STDMETHODCALLTYPE Connect(IPin*, const AM_MEDIA_TYPE* pmt) override - { - if (_owningFilter->_state == State_Running) - { - return VFW_E_NOT_STOPPED; - } - - if (_captureInputPin) - { - return VFW_E_ALREADY_CONNECTED; - } - - if (!pmt || pmt->majortype == GUID_NULL) - { - return S_OK; - } - - if (pmt->majortype != _expectedMediaType->majortype || pmt->subtype != _expectedMediaType->subtype) - { - return S_FALSE; - } - - return S_OK; - } - - HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin* pConnector, const AM_MEDIA_TYPE* pmt) override - { - if (!pConnector || !pmt) - { - return E_POINTER; - } - - if (_captureInputPin) - { - return VFW_E_ALREADY_CONNECTED; - } - - if (_owningFilter->_state != State_Stopped) - { - return VFW_E_NOT_STOPPED; - } - - if (QueryAccept(pmt) != S_OK) - { - return VFW_E_TYPE_NOT_ACCEPTED; - } - - _captureInputPin = pConnector; - _inputCaptureMediaType = CopyMediaType(pmt); - - return S_OK; - } - - HRESULT STDMETHODCALLTYPE Disconnect() override - { - _allocator.reset(); - _captureInputPin.reset(); - _inputCaptureMediaType.reset(); - return S_OK; - } - - HRESULT STDMETHODCALLTYPE ConnectedTo(IPin** pPin) override - { - if (!_captureInputPin) - { - return VFW_E_NOT_CONNECTED; - } - - return _captureInputPin.try_copy_to(pPin) ? S_OK : E_FAIL; - } - - HRESULT STDMETHODCALLTYPE ConnectionMediaType(AM_MEDIA_TYPE* pmt) override - { - if (!pmt) - { - return E_POINTER; - } - - if (!_inputCaptureMediaType) - { - return VFW_E_NOT_CONNECTED; - } - - *pmt = *CopyMediaType(_inputCaptureMediaType.get()).release(); - return S_OK; - } - - HRESULT STDMETHODCALLTYPE QueryPinInfo(PIN_INFO* pInfo) override - { - if (!pInfo) - { - return E_POINTER; - } - - pInfo->pFilter = _owningFilter; - if (_owningFilter) - { - _owningFilter->AddRef(); - } - - pInfo->dir = PINDIR_INPUT; - std::copy(std::begin(NAME), std::end(NAME), pInfo->achName); - return S_OK; - } - - HRESULT STDMETHODCALLTYPE QueryDirection(PIN_DIRECTION* pPinDir) override - { - if (!pPinDir) - { - return E_POINTER; - } - - *pPinDir = PINDIR_INPUT; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE QueryId(LPWSTR* lpId) override - { - if (!lpId) - { - return E_POINTER; - } - - *lpId = static_cast(CoTaskMemAlloc(sizeof(NAME))); - - std::copy(std::begin(NAME), std::end(NAME), *lpId); - return S_OK; - } - - HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE* pmt) override - { - if (!pmt) - { - return E_POINTER; - } - - if (pmt->majortype != _expectedMediaType->majortype || pmt->subtype != _expectedMediaType->subtype) - { - return S_FALSE; - } - - if (_captureInputPin) - { -// disable warning 26492 - Don't use const_cast to cast away const -// reset needs 'pmt' to be non-const, we can't easily change the query accept prototype -// because of the inheritance. -#pragma warning(suppress : 26492) - _inputCaptureMediaType.reset(const_cast(pmt)); - } - - return S_OK; - } - - HRESULT STDMETHODCALLTYPE EnumMediaTypes(IEnumMediaTypes** ppEnum) override - { - if (!ppEnum) - { - return E_POINTER; - } - - auto enumerator = winrt::make_self(); - enumerator->_objects.emplace_back(CopyMediaType(_expectedMediaType.get())); - *ppEnum = enumerator.detach(); - - return S_OK; - } - - HRESULT STDMETHODCALLTYPE QueryInternalConnections(IPin**, ULONG*) override { return E_NOTIMPL; } - - HRESULT STDMETHODCALLTYPE EndOfStream() override { return S_OK; } - - HRESULT STDMETHODCALLTYPE BeginFlush() override - { - _flushing = true; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE EndFlush() override - { - _flushing = false; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME, REFERENCE_TIME, double) override { return S_OK; } - - HRESULT STDMETHODCALLTYPE GetAllocator(IMemAllocator** allocator) override - { - VERBOSE_LOG; - if (!_allocator) - { - return VFW_E_NO_ALLOCATOR; - } - - return _allocator.try_copy_to(allocator) ? S_OK : E_FAIL; - } - - HRESULT STDMETHODCALLTYPE NotifyAllocator(IMemAllocator* allocator, BOOL readOnly) override - { - VERBOSE_LOG; - LOG(readOnly ? "Allocator READONLY: true" : "Allocator READONLY: false"); - _allocator = allocator; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE GetAllocatorRequirements(ALLOCATOR_PROPERTIES*) override { return E_NOTIMPL; } - - HRESULT STDMETHODCALLTYPE Receive(IMediaSample* pSample) override - { - if (_flushing) - { - return S_FALSE; - } - - if (!pSample) - { - return E_POINTER; - } - - if (pSample && _frameCallback) - { - _frameCallback(pSample); - } - - return S_OK; - } - - HRESULT STDMETHODCALLTYPE ReceiveMultiple(IMediaSample** pSamples, long nSamples, long* nSamplesProcessed) override - { - if (!pSamples && nSamples) - { - return E_POINTER; - } - - if (_flushing) - { - return S_FALSE; - } - - for (long i = 0; i < nSamples; i++) - { - Receive(pSamples[i]); - } - - *nSamplesProcessed = nSamples; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE ReceiveCanBlock() override { return S_FALSE; } - - virtual ~VideoCaptureReceiverPin() = default; - - constexpr static inline wchar_t NAME[] = L"PowerToysVCMCapturePin"; -}; - -constexpr long MINIMAL_FPS_ALLOWED = 29; - -const char* GetMediaSubTypeString(const GUID& guid) -{ - if (guid == MEDIASUBTYPE_RGB24) - { - return "MEDIASUBTYPE_RGB24"; - } - - if (guid == MEDIASUBTYPE_YUY2) - { - return "MEDIASUBTYPE_YUY2"; - } - - if (guid == MEDIASUBTYPE_MJPG) - { - return "MEDIASUBTYPE_MJPG"; - } - - if (guid == MEDIASUBTYPE_NV12) - { - return "MEDIASUBTYPE_NV12"; - } - - return "MEDIASUBTYPE_UNKNOWN"; -} - -std::optional SelectBestMediaType(wil::com_ptr_nothrow& pin) -{ - VERBOSE_LOG; - wil::com_ptr_nothrow mediaTypeEnum; - if (pin->EnumMediaTypes(&mediaTypeEnum); !mediaTypeEnum) - { - return std::nullopt; - } - - ULONG _ = 0; - VideoStreamFormat bestFormat; - unique_media_type_ptr mt; - while (mediaTypeEnum->Next(1, wil::out_param(mt), &_) == S_OK) - { - if (mt->majortype != MEDIATYPE_Video) - { - continue; - } - - auto format = reinterpret_cast(mt->pbFormat); - if (!format || !format->AvgTimePerFrame) - { - LOG("VideoInfoHeader not found"); - continue; - } - - const auto formatAvgFPS = 10000000LL / format->AvgTimePerFrame; - if (format->AvgTimePerFrame > bestFormat.avgFrameTime || formatAvgFPS < MINIMAL_FPS_ALLOWED) - { - continue; - } - - if (format->bmiHeader.biWidth < bestFormat.width || format->bmiHeader.biHeight < bestFormat.height) - { - continue; - } - - if (mt->subtype != MEDIASUBTYPE_YUY2 && mt->subtype != MEDIASUBTYPE_MJPG && mt->subtype != MEDIASUBTYPE_RGB24) - { - OLECHAR* guidString; - StringFromCLSID(mt->subtype, &guidString); - LOG("Skipping mediatype due to unsupported subtype: "); - LOG(guidString); - ::CoTaskMemFree(guidString); - continue; - } - - bestFormat.avgFrameTime = format->AvgTimePerFrame; - bestFormat.width = format->bmiHeader.biWidth; - bestFormat.height = format->bmiHeader.biHeight; - bestFormat.mediaType = std::move(mt); - } - - if (!bestFormat.mediaType) - { - LOG(L"Couldn't select a suitable media format"); - return std::nullopt; - } - - char selectedFormat[512]{}; - sprintf_s(selectedFormat, "Selected media format: %s %ldx%ld %lld fps", GetMediaSubTypeString(bestFormat.mediaType->subtype), bestFormat.width, bestFormat.height, 10000000LL / bestFormat.avgFrameTime); - LOG(selectedFormat); - - return std::move(bestFormat); -} - -std::vector VideoCaptureDevice::ListAll() -{ - std::vector devices; - auto enumeratorFactory = wil::CoCreateInstanceNoThrow(CLSID_SystemDeviceEnum); - if (!enumeratorFactory) - { - LOG("Couldn't create devenum factory"); - return devices; - } - - wil::com_ptr_nothrow enumMoniker; - enumeratorFactory->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &enumMoniker, CDEF_DEVMON_PNP_DEVICE); - if (!enumMoniker) - { - LOG("Couldn't create class enumerator"); - return devices; - } - - ULONG _ = 0; - wil::com_ptr_nothrow moniker; - while (enumMoniker->Next(1, &moniker, &_) == S_OK) - { - LOG("Inspecting moniker"); - VideoCaptureDeviceInfo deviceInfo; - - wil::com_ptr_nothrow propertyData; - moniker->BindToStorage(nullptr, nullptr, IID_IPropertyBag, reinterpret_cast(&propertyData)); - if (!propertyData) - { - LOG("BindToStorage failed"); - continue; - } - - wil::unique_variant propVal; - propVal.vt = VT_BSTR; - - if (FAILED(propertyData->Read(L"FriendlyName", &propVal, nullptr))) - { - LOG("Couldn't obtain FriendlyName property"); - continue; - } - - deviceInfo.friendlyName = { propVal.bstrVal, SysStringLen(propVal.bstrVal) }; - LOG(deviceInfo.friendlyName); - - propVal.reset(); - propVal.vt = VT_BSTR; - - if (FAILED(propertyData->Read(L"DevicePath", &propVal, nullptr))) - { - LOG("Couldn't obtain DevicePath property"); - continue; - } - deviceInfo.devicePath = { propVal.bstrVal, SysStringLen(propVal.bstrVal) }; - - wil::com_ptr_nothrow filter; - moniker->BindToObject(nullptr, nullptr, IID_IBaseFilter, reinterpret_cast(&filter)); - if (!filter) - { - LOG("Couldn't BindToObject"); - continue; - } - - wil::com_ptr_nothrow pinsEnum; - if (FAILED(filter->EnumPins(&pinsEnum))) - { - LOG("BindToObject EnumPins"); - continue; - } - - wil::com_ptr_nothrow pin; - while (pinsEnum->Next(1, &pin, &_) == S_OK) - { - LOG("Inspecting pin"); - // Skip pins which do not belong to capture category - GUID category{}; - DWORD __; - if (auto props = pin.try_copy(); - !props || - FAILED(props->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, nullptr, 0, &category, sizeof(GUID), &__)) || - category != PIN_CATEGORY_CAPTURE) - { - continue; - } - - // Skip non-output pins - if (PIN_DIRECTION direction = {}; FAILED(pin->QueryDirection(&direction)) || direction != PINDIR_OUTPUT) - { - continue; - } - - LOG("Found a pin of suitable category and direction, selecting format"); - auto bestFormat = SelectBestMediaType(pin); - if (!bestFormat) - { - continue; - } - - deviceInfo.captureOutputPin = std::move(pin); - deviceInfo.bestFormat = std::move(bestFormat.value()); - deviceInfo.captureOutputFilter = std::move(filter); - devices.emplace_back(std::move(deviceInfo)); - } - } - - return devices; -} - -std::optional VideoCaptureDevice::Create(VideoCaptureDeviceInfo&& vdi, callback_t callback) -{ - VERBOSE_LOG; - VideoCaptureDevice result; - - result._graph = wil::CoCreateInstanceNoThrow(CLSID_FilterGraph); - result._builder = wil::CoCreateInstanceNoThrow(CLSID_CaptureGraphBuilder2); - if (!result._graph || !result._builder) - { - return std::nullopt; - } - - if (FAILED(result._builder->SetFiltergraph(result._graph.get()))) - { - return std::nullopt; - } - - result._control = result._graph.try_query(); - if (!result._control) - { - return std::nullopt; - } - - auto pinConfig = vdi.captureOutputPin.try_query(); - if (!pinConfig) - { - return std::nullopt; - } - - if (FAILED(pinConfig->SetFormat(vdi.bestFormat.mediaType.get()))) - { - return std::nullopt; - } - - auto captureInputFilter = winrt::make_self(); - auto receiverPin = winrt::make_self(std::move(vdi.bestFormat.mediaType), captureInputFilter.get()); - receiverPin->_frameCallback = std::move(callback); - captureInputFilter->_videoReceiverPin.attach(receiverPin.get()); - auto detachReceiverPin = wil::scope_exit([&receiverPin]() { receiverPin.detach(); }); - - if (FAILED(result._graph->AddFilter(captureInputFilter.get(), nullptr))) - { - return std::nullopt; - } - - if (FAILED(result._graph->AddFilter(vdi.captureOutputFilter.get(), nullptr))) - { - return std::nullopt; - } - - if (FAILED(result._graph->ConnectDirect(vdi.captureOutputPin.get(), captureInputFilter->_videoReceiverPin.get(), nullptr))) - { - return std::nullopt; - } - - result._allocator = receiverPin->_allocator; - return std::make_optional(std::move(result)); -} - -bool VideoCaptureDevice::StartCapture() -{ - VERBOSE_LOG; - return SUCCEEDED(_control->Run()); -} - -bool VideoCaptureDevice::StopCapture() -{ - VERBOSE_LOG; - return SUCCEEDED(_control->Stop()); -} - -VideoCaptureDevice::~VideoCaptureDevice() -{ - StopCapture(); -} diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/VideoCaptureDevice.h b/src/modules/videoconference/VideoConferenceProxyFilter/VideoCaptureDevice.h deleted file mode 100644 index 3af63691a6a0..000000000000 --- a/src/modules/videoconference/VideoConferenceProxyFilter/VideoCaptureDevice.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once -#include -#define WIN32_LEAN_AND_MEAN - -#include -#include - -#include - -#include -#include -#include -#include - -#include "DirectShowUtils.h" - -struct VideoStreamFormat -{ - long width = 0; - long height = 0; - REFERENCE_TIME avgFrameTime = std::numeric_limits::max(); - unique_media_type_ptr mediaType; - - VideoStreamFormat() = default; - - VideoStreamFormat(const VideoStreamFormat&) = delete; - VideoStreamFormat& operator=(const VideoStreamFormat&) = delete; - - VideoStreamFormat(VideoStreamFormat&&) = default; - VideoStreamFormat& operator=(VideoStreamFormat&&) = default; -}; - -struct VideoCaptureDeviceInfo -{ - std::wstring friendlyName; - std::wstring devicePath; - wil::com_ptr_nothrow captureOutputPin; - wil::com_ptr_nothrow captureOutputFilter; - VideoStreamFormat bestFormat; -}; - -class VideoCaptureDevice final -{ -public: - wil::com_ptr_nothrow _allocator; - - using callback_t = std::function; - - static std::vector ListAll(); - static std::optional Create(VideoCaptureDeviceInfo&& vdi, callback_t callback); - - bool StartCapture(); - bool StopCapture(); - - ~VideoCaptureDevice(); - -private: - wil::com_ptr_nothrow _graph; - wil::com_ptr_nothrow _builder; - wil::com_ptr_nothrow _control; - callback_t _callback; -}; diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/VideoCaptureProxyFilter.cpp b/src/modules/videoconference/VideoConferenceProxyFilter/VideoCaptureProxyFilter.cpp deleted file mode 100644 index 2a860a72fadd..000000000000 --- a/src/modules/videoconference/VideoConferenceProxyFilter/VideoCaptureProxyFilter.cpp +++ /dev/null @@ -1,937 +0,0 @@ -#include "VideoCaptureProxyFilter.h" - -#include "VideoCaptureDevice.h" -#include -#include -#include -#include - -constexpr static inline wchar_t FILTER_NAME[] = L"PowerToysVCMProxyFilter"; -constexpr static inline wchar_t PIN_NAME[] = L"PowerToysVCMProxyPIN"; -constexpr static inline wchar_t VENDOR[] = L"Microsoft Corporation"; - -namespace -{ - constexpr float initialJpgQuality = 0.5f; - constexpr std::array overlayColor = { 0, 0, 0 }; - // clang-format off - unsigned char bmpPixelData[58] = { - 0x42, 0x4D, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, - 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x00, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, overlayColor[0], overlayColor[1], overlayColor[2], 0x00 - }; - // clang-format on -} - -wil::com_ptr_nothrow VideoCaptureProxyPin::FindAllocator() -{ - auto allocator = GetPinAllocator(_connectedInputPin); - if (!allocator && _owningFilter->_captureDevice) - { - allocator = _owningFilter->_captureDevice->_allocator; - } - - return allocator; -} - -wil::com_ptr_nothrow LoadImageAsSample(wil::com_ptr_nothrow imageStream, - IMFMediaType* sampleMediaType, - const float quality) noexcept; -bool ReencodeJPGImage(BYTE* imageBuf, const DWORD imageSize, DWORD& reencodedSize); - -HRESULT VideoCaptureProxyPin::Connect(IPin* pReceivePin, const AM_MEDIA_TYPE*) -{ - if (!pReceivePin) - { - LOG("VideoCaptureProxyPin::Connect FAILED pReceivePin"); - return E_POINTER; - } - - if (_owningFilter->_state == State_Running) - { - LOG("VideoCaptureProxyPin::Connect FAILED _owningFilter->_state"); - return VFW_E_NOT_STOPPED; - } - - if (_connectedInputPin) - { - LOG("VideoCaptureProxyPin::Connect FAILED _connectedInputPin"); - return VFW_E_ALREADY_CONNECTED; - } - - if (FAILED(pReceivePin->ReceiveConnection(this, _mediaFormat.get()))) - { - LOG("VideoCaptureProxyPin::Connect FAILED pReceivePin->ReceiveConnection"); - return E_POINTER; - } - - _connectedInputPin = pReceivePin; - - auto memInput = _connectedInputPin.try_query(); - if (!memInput) - { - LOG("VideoCaptureProxyPin::Connect FAILED _connectedInputPin.try_query"); - return VFW_E_NO_TRANSPORT; - } - - auto allocator = FindAllocator(); - if (allocator == nullptr) - { - LOG("VideoCaptureProxyPin::Connect FAILED FindAllocator"); - return VFW_E_NO_TRANSPORT; - } - - if (FAILED(memInput->NotifyAllocator(allocator.get(), false))) - { - LOG("VideoCaptureProxyPin::Connect FAILED memInput->NotifyAllocator"); - return VFW_E_NO_TRANSPORT; - } - - return S_OK; -} - -HRESULT VideoCaptureProxyPin::ReceiveConnection(IPin*, const AM_MEDIA_TYPE*) -{ - return S_OK; -} - -HRESULT VideoCaptureProxyPin::Disconnect(void) -{ - if (!_connectedInputPin) - { - LOG("VideoCaptureProxyPin::Disconnect FAILED _connectedInputPin"); - return S_FALSE; - } - - _connectedInputPin.reset(); - return S_OK; -} - -HRESULT VideoCaptureProxyPin::ConnectedTo(IPin** pPin) -{ - if (!_connectedInputPin) - { - *pPin = nullptr; - return VFW_E_NOT_CONNECTED; - } - - return _connectedInputPin.try_copy_to(pPin) ? S_OK : E_FAIL; -} - -HRESULT VideoCaptureProxyPin::ConnectionMediaType(AM_MEDIA_TYPE* pmt) -{ - if (!_connectedInputPin) - { - LOG("VideoCaptureProxyPin::ConnectionMediaType FAILED _connectedInputPin"); - return VFW_E_NOT_CONNECTED; - } - - *pmt = *CopyMediaType(_mediaFormat.get()).release(); - return S_OK; -} - -HRESULT VideoCaptureProxyPin::QueryPinInfo(PIN_INFO* pInfo) -{ - if (!pInfo) - { - LOG("VideoCaptureProxyPin::QueryPinInfo FAILED pInfo"); - return E_POINTER; - } - - pInfo->pFilter = _owningFilter; - if (_owningFilter) - { - _owningFilter->AddRef(); - } - - if (_mediaFormat->majortype == MEDIATYPE_Video) - { - std::copy(std::begin(PIN_NAME), std::end(PIN_NAME), pInfo->achName); - } - - pInfo->dir = PINDIR_OUTPUT; - return S_OK; -} - -HRESULT VideoCaptureProxyPin::QueryDirection(PIN_DIRECTION* pPinDir) -{ - if (!pPinDir) - { - LOG("VideoCaptureProxyPin::QueryDirection FAILED pPinDir"); - return E_POINTER; - } - - *pPinDir = PINDIR_OUTPUT; - return S_OK; -} - -HRESULT VideoCaptureProxyPin::QueryId(LPWSTR* Id) -{ - if (!Id) - { - LOG("VideoCaptureProxyPin::QueryId FAILED Id"); - return E_POINTER; - } - - *Id = static_cast(CoTaskMemAlloc(sizeof(PIN_NAME))); - std::copy(std::begin(PIN_NAME), std::end(PIN_NAME), *Id); - return S_OK; -} - -HRESULT VideoCaptureProxyPin::QueryAccept(const AM_MEDIA_TYPE*) -{ - return S_OK; -} - -HRESULT VideoCaptureProxyPin::EnumMediaTypes(IEnumMediaTypes** ppEnum) -{ - if (!ppEnum) - { - LOG("VideoCaptureProxyPin::EnumMediaTypes FAILED ppEnum"); - return E_POINTER; - } - - *ppEnum = nullptr; - - auto enumerator = winrt::make_self(); - enumerator->_objects.emplace_back(CopyMediaType(_mediaFormat.get())); - *ppEnum = enumerator.detach(); - - return S_OK; -} - -HRESULT VideoCaptureProxyPin::QueryInternalConnections(IPin** pins, ULONG*) -{ - if (pins) - { - *pins = nullptr; - } - return E_NOTIMPL; -} - -HRESULT VideoCaptureProxyPin::EndOfStream(void) -{ - return S_OK; -} - -HRESULT VideoCaptureProxyPin::BeginFlush(void) -{ - _flushing = true; - return S_OK; -} - -HRESULT VideoCaptureProxyPin::EndFlush(void) -{ - _flushing = false; - return S_OK; -} - -HRESULT VideoCaptureProxyPin::NewSegment(REFERENCE_TIME, REFERENCE_TIME, double) -{ - return S_OK; -} - -HRESULT VideoCaptureProxyPin::SetFormat(AM_MEDIA_TYPE* pmt) -{ - if (pmt == nullptr) - { - return S_OK; - } - - _mediaFormat = CopyMediaType(pmt); - return S_OK; -} - -HRESULT VideoCaptureProxyPin::GetFormat(AM_MEDIA_TYPE** ppmt) -{ - if (!ppmt) - { - LOG("VideoCaptureProxyPin::GetFormat FAILED ppmt"); - return E_POINTER; - } - *ppmt = CopyMediaType(_mediaFormat.get()).release(); - return S_OK; -} - -HRESULT VideoCaptureProxyPin::GetNumberOfCapabilities(int* piCount, int* piSize) -{ - if (!piCount || !piSize) - { - LOG("VideoCaptureProxyPin::GetNumberOfCapabilities FAILED piCount || piSize"); - return E_POINTER; - } - - *piCount = 1; - *piSize = sizeof(VIDEO_STREAM_CONFIG_CAPS); - return S_OK; -} - -HRESULT VideoCaptureProxyPin::GetStreamCaps(int iIndex, AM_MEDIA_TYPE** ppmt, BYTE* pSCC) -{ - if (!ppmt || !pSCC) - { - LOG("VideoCaptureProxyPin::GetStreamCaps FAILED ppmt || pSCC"); - return E_POINTER; - } - - if (iIndex != 0) - { - LOG("VideoCaptureProxyPin::GetStreamCaps FAILED iIndex"); - return S_FALSE; - } - - VIDEOINFOHEADER* vih = reinterpret_cast(_mediaFormat->pbFormat); - - VIDEO_STREAM_CONFIG_CAPS caps{}; - caps.guid = FORMAT_VideoInfo; - caps.MinFrameInterval = vih->AvgTimePerFrame; - caps.MaxFrameInterval = vih->AvgTimePerFrame; - caps.MinOutputSize.cx = vih->bmiHeader.biWidth; - caps.MinOutputSize.cy = vih->bmiHeader.biHeight; - caps.MaxOutputSize = caps.MinOutputSize; - caps.InputSize = caps.MinOutputSize; - caps.MinCroppingSize = caps.MinOutputSize; - caps.MaxCroppingSize = caps.MinOutputSize; - caps.CropGranularityX = vih->bmiHeader.biWidth; - caps.CropGranularityY = vih->bmiHeader.biHeight; - caps.MinBitsPerSecond = vih->dwBitRate; - caps.MaxBitsPerSecond = caps.MinBitsPerSecond; - - *ppmt = CopyMediaType(_mediaFormat.get()).release(); - - const auto caps_begin = reinterpret_cast(&caps); - std::copy(caps_begin, caps_begin + sizeof(caps), pSCC); - return S_OK; -} - -HRESULT VideoCaptureProxyPin::Set(REFGUID, DWORD, LPVOID, DWORD, LPVOID, DWORD) -{ - return E_NOTIMPL; -} - -HRESULT VideoCaptureProxyPin::Get( - REFGUID guidPropSet, - DWORD dwPropID, - LPVOID, - DWORD, - LPVOID pPropData, - DWORD cbPropData, - DWORD* pcbReturned) -{ - if (guidPropSet != AMPROPSETID_Pin) - { - LOG("VideoCaptureProxyPin::Get FAILED guidPropSet"); - return E_PROP_SET_UNSUPPORTED; - } - - if (dwPropID != AMPROPERTY_PIN_CATEGORY) - { - LOG("VideoCaptureProxyPin::Get FAILED dwPropID"); - return E_PROP_ID_UNSUPPORTED; - } - - if (!pPropData) - { - LOG("VideoCaptureProxyPin::Get FAILED pPropData || pcbReturned"); - return E_POINTER; - } - - if (pcbReturned) - { - *pcbReturned = sizeof(GUID); - } - - if (cbPropData < sizeof(GUID)) - { - LOG("VideoCaptureProxyPin::Get FAILED cbPropData"); - return E_UNEXPECTED; - } - - *static_cast(pPropData) = PIN_CATEGORY_CAPTURE; - - LOG("VideoCaptureProxyPin::Get SUCCESS"); - return S_OK; -} - -HRESULT VideoCaptureProxyPin::QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD* pTypeSupport) -{ - if (guidPropSet != AMPROPSETID_Pin) - { - LOG("VideoCaptureProxyPin::QuerySupported FAILED guidPropSet"); - return E_PROP_SET_UNSUPPORTED; - } - - if (dwPropID != AMPROPERTY_PIN_CATEGORY) - { - LOG("VideoCaptureProxyPin::QuerySupported FAILED dwPropID"); - return E_PROP_ID_UNSUPPORTED; - } - - if (pTypeSupport) - { - *pTypeSupport = KSPROPERTY_SUPPORT_GET; - } - - return S_OK; -} - -long GetImageSize(wil::com_ptr_nothrow& image) -{ - if (!image) - { - return 0; - } - - DWORD imageSize = 0; - wil::com_ptr_nothrow imageBuf; - - OK_OR_BAIL(image->GetBufferByIndex(0, &imageBuf)); - OK_OR_BAIL(imageBuf->GetCurrentLength(&imageSize)); - return imageSize; -} - -void ReencodeFrame(IMediaSample* frame) -{ - BYTE* frameData = nullptr; - frame->GetPointer(&frameData); - if (!frameData) - { - LOG("VideoCaptureProxyPin::ReencodeFrame FAILED frameData"); - return; - } - const DWORD frameSize = frame->GetSize(); - DWORD reencodedSize = 0; - if (!ReencodeJPGImage(frameData, frameSize, reencodedSize)) - { - LOG("VideoCaptureProxyPin::ReencodeJPGImage FAILED"); - return; - } - frame->SetActualDataLength(reencodedSize); -} - -bool OverwriteFrame(IMediaSample* frame, wil::com_ptr_nothrow& image) -{ - if (!image) - { - return false; - } - - BYTE* frameData = nullptr; - frame->GetPointer(&frameData); - if (!frameData) - { - LOG("VideoCaptureProxyPin::OverwriteFrame FAILED frameData"); - return false; - } - - wil::com_ptr_nothrow imageBuf; - const DWORD frameSize = frame->GetSize(); - - image->GetBufferByIndex(0, &imageBuf); - if (!imageBuf) - { - LOG("VideoCaptureProxyPin::OverwriteFrame FAILED imageBuf"); - return false; - } - - BYTE* imageData = nullptr; - DWORD _ = 0, imageSize = 0; - imageBuf->Lock(&imageData, &_, &imageSize); - if (!imageData) - { - LOG("VideoCaptureProxyPin::OverwriteFrame FAILED imageData"); - return false; - } - - if (imageSize > frameSize && failed(frame->SetActualDataLength(imageSize))) - { - char buf[512]{}; - sprintf_s(buf, "VideoCaptureProxyPin::OverwriteFrame FAILED overlay image size %lu is larger than frame size %lu", imageSize, frameSize); - LOG(buf); - imageBuf->Unlock(); - return false; - } - - std::copy(imageData, imageData + imageSize, frameData); - imageBuf->Unlock(); - frame->SetActualDataLength(imageSize); - - return true; -} - -//#define DEBUG_FRAME_DATA -//#define DEBUG_OVERWRITE_FRAME -//#define DEBUG_REENCODE_JPG_DATA - -#if defined(DEBUG_OVERWRITE_FRAME) -void DebugOverwriteFrame(IMediaSample* frame, std::string_view filepath) -{ - std::ifstream file{ filepath.data(), std::ios::binary }; - std::streampos fileSize = 0; - fileSize = file.tellg(); - file.seekg(0, std::ios::end); - fileSize = file.tellg() - fileSize; - - BYTE* frameData = nullptr; - if (!frame) - { - LOG("null frame provided"); - return; - } - frame->GetPointer(&frameData); - const DWORD frameSize = frame->GetSize(); - - if (fileSize > frameSize || !frameData) - { - LOG("frame can't be filled with data"); - return; - } - file.read((char*)frameData, fileSize); - frame->SetActualDataLength((long)fileSize); - LOG("DebugOverwriteFrame success"); -} - -#endif - -#if defined(DEBUG_FRAME_DATA) -#include - -namespace fs = std::filesystem; - -void DumpSample(IMediaSample* frame, const std::string_view filename) -{ - BYTE* data = nullptr; - frame->GetPointer(&data); - if (!data) - { - LOG("Couldn't get sample pointer"); - return; - } - const long nBytes = frame->GetActualDataLength(); - std::ofstream file{ fs::temp_directory_path() / filename, std::ios::binary }; - file.write((const char*)data, nBytes); -} -#endif - -VideoCaptureProxyFilter::VideoCaptureProxyFilter() : - _worker_thread{ - std::thread{ - [this]() { - using namespace std::chrono_literals; - const auto uninitializedSleepInterval = 15ms; - std::vector lowerJpgQualityModes = { 0.1f, 0.25f }; - while (!_shutdown_request) - { - std::unique_lock lock{ _worker_mutex }; - _worker_cv.wait(lock, [this] { return _pending_frame != nullptr || _shutdown_request; }); - - if (!_outPin || !_outPin->_connectedInputPin) - { - lock.unlock(); - std::this_thread::sleep_for(uninitializedSleepInterval); - continue; - } - - auto input = _outPin->_connectedInputPin.try_query(); - if (!input) - { - continue; - } - - IMediaSample* sample = _pending_frame; - if (!sample) - { - continue; - } -#if defined(DEBUG_FRAME_DATA) - static bool realFrameSaved = false; - if (!realFrameSaved) - { - DumpSample(sample, "PowerToysVCMRealFrame.binary"); - realFrameSaved = true; - } -#endif - auto newSettings = SyncCurrentSettings(); - if (newSettings.webcamDisabled) - { -#if !defined(DEBUG_OVERWRITE_FRAME) - bool overwritten = OverwriteFrame(_pending_frame, _overlayImage ? _overlayImage : _blankImage); - while (!overwritten && _overlayImage) - { - _overlayImage.reset(); - newSettings = SyncCurrentSettings(); - if (!lowerJpgQualityModes.empty() && newSettings.overlayImage) - { - const float quality = lowerJpgQualityModes.back(); - lowerJpgQualityModes.pop_back(); - char buf[512]{}; - sprintf_s(buf, "Reload overlay image with quality %f", quality); - LOG(buf); - _overlayImage = LoadImageAsSample(newSettings.overlayImage, _targetMediaType.get(), quality); - overwritten = OverwriteFrame(_pending_frame, _overlayImage); - } - else - { - LOG("Couldn't overwrite frame with image with all available quality modes."); - } - } -#if defined(DEBUG_FRAME_DATA) - static bool overlayFrameSaved = false; - if (!overlayFrameSaved && _overlayImage && overwritten) - { - DumpSample(sample, "PowerToysVCMOverlayImageFrame.binary"); - overlayFrameSaved = true; - } -#endif - if (!overwritten && !_overlayImage) - { - OverwriteFrame(_pending_frame, _blankImage); - } -#else - DebugOverwriteFrame(_pending_frame, "R:\\frame.data"); -#endif - } -#if defined(DEBUG_REENCODE_JPG_DATA) - else - { - GUID subtype{}; - _targetMediaType->GetGUID(MF_MT_SUBTYPE, &subtype); - if (subtype == MFVideoFormat_MJPG) - { - ReencodeFrame(_pending_frame); - } - } -#endif - - _pending_frame = nullptr; - input->Receive(sample); - sample->Release(); - } - } } - } -{ -} - -HRESULT VideoCaptureProxyFilter::Stop(void) -{ - if (_state != State_Stopped && _captureDevice) - { - _captureDevice->StopCapture(); - } - - _state = State_Stopped; - return S_OK; -} - -HRESULT VideoCaptureProxyFilter::Pause(void) -{ - if (_state == State_Stopped) - { - std::unique_lock lock{ _worker_mutex }; - - if (!_outPin) - { - LOG("VideoCaptureProxyPin::Pause FAILED _outPin"); - return VFW_E_NO_TRANSPORT; - } - - auto allocator = _outPin->FindAllocator(); - if (!allocator) - { - LOG("VideoCaptureProxyPin::Pause FAILED allocator"); - return VFW_E_NO_TRANSPORT; - } - - allocator->Commit(); - } - - _state = State_Paused; - return S_OK; -} - -HRESULT VideoCaptureProxyFilter::Run(REFERENCE_TIME) -{ - _state = State_Running; - if (_captureDevice) - { - _captureDevice->StartCapture(); - } - - return S_OK; -} - -HRESULT VideoCaptureProxyFilter::GetState(DWORD, FILTER_STATE* State) -{ - *State = _state; - return S_OK; -} - -HRESULT VideoCaptureProxyFilter::SetSyncSource(IReferenceClock* pClock) -{ - _clock = pClock; - return S_OK; -} - -HRESULT VideoCaptureProxyFilter::GetSyncSource(IReferenceClock** pClock) -{ - if (!pClock) - { - return E_POINTER; - } - *pClock = nullptr; - return _clock.try_copy_to(pClock) ? S_OK : E_FAIL; -} - -GUID MapDShowSubtypeToMFT(const GUID& dshowSubtype) -{ - if (dshowSubtype == MEDIASUBTYPE_YUY2) - { - return MFVideoFormat_YUY2; - } - else if (dshowSubtype == MEDIASUBTYPE_MJPG) - { - return MFVideoFormat_MJPG; - } - else if (dshowSubtype == MEDIASUBTYPE_RGB24) - { - return MFVideoFormat_RGB24; - } - else - { - LOG("MapDShowSubtypeToMFT: Unsupported media type format provided!"); - return MFVideoFormat_MJPG; - } -} - -HRESULT VideoCaptureProxyFilter::EnumPins(IEnumPins** ppEnum) -{ - if (!ppEnum) - { - LOG("VideoCaptureProxyFilter::EnumPins null arg provided"); - return E_POINTER; - } - *ppEnum = nullptr; - auto enumerator = winrt::make_self>(); - auto detached_enumerator = enumerator.detach(); - *ppEnum = detached_enumerator; - - std::unique_lock lock{ _worker_mutex }; - - // We cannot initialize capture device and outpin during VideoCaptureProxyFilter ctor - // since that results in a deadlock -> initializing now. - if (!_outPin) - { - LOG("VideoCaptureProxyFilter::EnumPins started pin initialization"); - const auto newSettings = SyncCurrentSettings(); - std::vector webcams; - webcams = VideoCaptureDevice::ListAll(); - if (webcams.empty()) - { - LOG("VideoCaptureProxyFilter::EnumPins no physical webcams found"); - return E_FAIL; - } - - std::optional selectedCamIdx; - for (size_t i = 0; i < size(webcams); ++i) - { - if (newSettings.newCameraName == webcams[i].friendlyName) - { - selectedCamIdx = i; - LOG("VideoCaptureProxyFilter::EnumPins webcam selected using settings"); - break; - } - } - - if (!selectedCamIdx) - { - for (size_t i = 0; i < size(webcams); ++i) - { - if (newSettings.newCameraName != CAMERA_NAME) - { - LOG("VideoCaptureProxyFilter::EnumPins webcam selected using first fit"); - selectedCamIdx = i; - break; - } - } - } - - if (!selectedCamIdx) - { - LOG("VideoCaptureProxyFilter::EnumPins FAILED webcam couldn't be selected"); - return E_FAIL; - } - - auto& webcam = webcams[*selectedCamIdx]; - auto pin = winrt::make_self(); - pin->_mediaFormat = CopyMediaType(webcam.bestFormat.mediaType.get()); - pin->_owningFilter = this; - _outPin.attach(pin.detach()); - - auto frameCallback = [this](IMediaSample* sample) { - std::unique_lock lock{ _worker_mutex }; - sample->AddRef(); - _pending_frame = sample; - _worker_cv.notify_one(); - }; - - _targetMediaType.reset(); - MFCreateMediaType(&_targetMediaType); - _targetMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); - _targetMediaType->SetGUID(MF_MT_SUBTYPE, MapDShowSubtypeToMFT(webcam.bestFormat.mediaType->subtype)); - _targetMediaType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive); - _targetMediaType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE); - MFSetAttributeSize( - _targetMediaType.get(), MF_MT_FRAME_SIZE, webcam.bestFormat.width, webcam.bestFormat.height); - MFSetAttributeRatio(_targetMediaType.get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1); - - _captureDevice = VideoCaptureDevice::Create(std::move(webcam), std::move(frameCallback)); - if (_captureDevice) - { - if (!_blankImage) - { - wil::com_ptr_nothrow blackBMPImage = SHCreateMemStream(bmpPixelData, sizeof(bmpPixelData)); - _blankImage = LoadImageAsSample(blackBMPImage, _targetMediaType.get(), initialJpgQuality); - } - - _overlayImage = LoadImageAsSample(newSettings.overlayImage, _targetMediaType.get(), initialJpgQuality); - LOG("VideoCaptureProxyFilter::EnumPins capture device created successfully"); - } - else - { - LOG("VideoCaptureProxyFilter::EnumPins FAILED couldn't create capture device"); - } - } - - detached_enumerator->_objects.emplace_back(_outPin); - - return S_OK; -} - -HRESULT VideoCaptureProxyFilter::FindPin(LPCWSTR, IPin** pin) -{ - if (pin) - { - *pin = nullptr; - } - return E_NOTIMPL; -} - -HRESULT VideoCaptureProxyFilter::QueryFilterInfo(FILTER_INFO* pInfo) -{ - if (!pInfo) - { - LOG("VideoCaptureProxyPin::QueryFilterInfo FAILED pInfo"); - return E_POINTER; - } - - VERBOSE_LOG; - std::copy(std::begin(FILTER_NAME), std::end(FILTER_NAME), pInfo->achName); - - pInfo->pGraph = _graph; - if (_graph) - { - _graph->AddRef(); - } - - return S_OK; -} - -HRESULT VideoCaptureProxyFilter::JoinFilterGraph(IFilterGraph* pGraph, LPCWSTR) -{ - _graph = pGraph; - return S_OK; -} - -HRESULT VideoCaptureProxyFilter::QueryVendorInfo(LPWSTR* pVendorInfo) -{ - auto info = static_cast(CoTaskMemAlloc(sizeof(VENDOR))); - std::copy(std::begin(VENDOR), std::end(VENDOR), info); - *pVendorInfo = info; - return S_OK; -} - -HRESULT VideoCaptureProxyFilter::GetClassID(CLSID*) -{ - return E_NOTIMPL; -} - -ULONG VideoCaptureProxyFilter::GetMiscFlags(void) -{ - return AM_FILTER_MISC_FLAGS_IS_SOURCE; -} - -VideoCaptureProxyFilter::~VideoCaptureProxyFilter() -{ - VERBOSE_LOG; - _shutdown_request = true; - - _worker_cv.notify_one(); - _worker_thread.join(); - if (_settingsUpdateChannel) - { - _settingsUpdateChannel->access([](auto settingsMemory) { - auto settings = reinterpret_cast(settingsMemory._data); - settings->cameraInUse = false; - }); - } -} - -VideoCaptureProxyFilter::SyncedSettings VideoCaptureProxyFilter::SyncCurrentSettings() -{ - SyncedSettings result; - if (!_settingsUpdateChannel.has_value()) - { - _settingsUpdateChannel = SerializedSharedMemory::open(CameraSettingsUpdateChannel::endpoint(), sizeof(CameraSettingsUpdateChannel), false); - } - - if (!_settingsUpdateChannel) - { - return result; - } - - _settingsUpdateChannel->access([this, &result](auto settingsMemory) { - auto settings = reinterpret_cast(settingsMemory._data); - bool cameraNameUpdated = false; - result.webcamDisabled = settings->useOverlayImage; - - settings->cameraInUse = true; - - if (settings->sourceCameraName.has_value()) - { - std::wstring_view newCameraNameView{ settings->sourceCameraName->data() }; - if (!_currentSourceCameraName.has_value() || *_currentSourceCameraName != newCameraNameView) - { - cameraNameUpdated = true; - result.newCameraName = newCameraNameView; - } - } - - if (!settings->overlayImageSize.has_value()) - { - return; - } - - if (settings->newOverlayImagePosted || !_overlayImage) - { - auto imageChannel = - SerializedSharedMemory::open(CameraOverlayImageChannel::endpoint(), *settings->overlayImageSize, true); - if (!imageChannel) - { - return; - } - - imageChannel->access([this, settings, &result](auto imageMemory) { - result.overlayImage = SHCreateMemStream(imageMemory._data, static_cast(imageMemory._size)); - if (!result.overlayImage) - { - return; - } - - settings->newOverlayImagePosted = false; - }); - } - }); - return result; -} diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/VideoCaptureProxyFilter.h b/src/modules/videoconference/VideoConferenceProxyFilter/VideoCaptureProxyFilter.h deleted file mode 100644 index 58f49f032af0..000000000000 --- a/src/modules/videoconference/VideoConferenceProxyFilter/VideoCaptureProxyFilter.h +++ /dev/null @@ -1,120 +0,0 @@ -#pragma once - -#include - -#define WIN32_LEAN_AND_MEAN -#include -#include - -#include -#include -#include - -#include -#include - -#include "VideoCaptureDevice.h" - -#include -#include - -struct VideoCaptureProxyPin; -struct IMFSample; -struct IMFMediaType; - -inline const wchar_t CAMERA_NAME[] = L"PowerToys VideoConference Mute"; - -struct VideoCaptureProxyFilter : winrt::implements -{ - // BLOCK START: member accessed concurrently - wil::com_ptr_nothrow _outPin; - IMediaSample* _pending_frame = nullptr; - std::atomic_bool _shutdown_request = false; - std::optional _settingsUpdateChannel; - std::optional _currentSourceCameraName; - wil::com_ptr_nothrow _blankImage; - wil::com_ptr_nothrow _overlayImage; - wil::com_ptr_nothrow _targetMediaType; - // BLOCK END: member accessed concurrently - - std::mutex _worker_mutex; - std::condition_variable _worker_cv; - - FILTER_STATE _state = State_Stopped; - wil::com_ptr_nothrow _clock; - IFilterGraph* _graph = nullptr; - std::optional _captureDevice; - - std::thread _worker_thread; - - VideoCaptureProxyFilter(); - ~VideoCaptureProxyFilter(); - - struct SyncedSettings - { - bool webcamDisabled = false; - std::wstring newCameraName; - wil::com_ptr_nothrow overlayImage; - }; - - SyncedSettings SyncCurrentSettings(); - - HRESULT STDMETHODCALLTYPE Stop(void) override; - HRESULT STDMETHODCALLTYPE Pause(void) override; - HRESULT STDMETHODCALLTYPE Run(REFERENCE_TIME tStart) override; - HRESULT STDMETHODCALLTYPE GetState(DWORD dwMilliSecsTimeout, FILTER_STATE* State) override; - HRESULT STDMETHODCALLTYPE SetSyncSource(IReferenceClock* pClock) override; - HRESULT STDMETHODCALLTYPE GetSyncSource(IReferenceClock** pClock) override; - HRESULT STDMETHODCALLTYPE EnumPins(IEnumPins** ppEnum) override; - HRESULT STDMETHODCALLTYPE FindPin(LPCWSTR Id, IPin** ppPin) override; - HRESULT STDMETHODCALLTYPE QueryFilterInfo(FILTER_INFO* pInfo) override; - HRESULT STDMETHODCALLTYPE JoinFilterGraph(IFilterGraph* pGraph, LPCWSTR pName) override; - HRESULT STDMETHODCALLTYPE QueryVendorInfo(LPWSTR* pVendorInfo) override; - - HRESULT STDMETHODCALLTYPE GetClassID(CLSID* pClassID) override; - ULONG STDMETHODCALLTYPE GetMiscFlags(void) override; -}; -struct VideoCaptureProxyPin : winrt::implements -{ - VideoCaptureProxyFilter* _owningFilter = nullptr; - wil::com_ptr_nothrow _connectedInputPin; - unique_media_type_ptr _mediaFormat; - std::atomic_bool _flushing = false; - - HRESULT STDMETHODCALLTYPE Connect(IPin* pReceivePin, const AM_MEDIA_TYPE* pmt) override; - HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin* pConnector, const AM_MEDIA_TYPE* pmt) override; - HRESULT STDMETHODCALLTYPE Disconnect(void) override; - HRESULT STDMETHODCALLTYPE ConnectedTo(IPin** pPin) override; - HRESULT STDMETHODCALLTYPE ConnectionMediaType(AM_MEDIA_TYPE* pmt) override; - HRESULT STDMETHODCALLTYPE QueryPinInfo(PIN_INFO* pInfo) override; - HRESULT STDMETHODCALLTYPE QueryDirection(PIN_DIRECTION* pPinDir) override; - HRESULT STDMETHODCALLTYPE QueryId(LPWSTR* Id) override; - HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE* pmt) override; - HRESULT STDMETHODCALLTYPE EnumMediaTypes(IEnumMediaTypes** ppEnum) override; - HRESULT STDMETHODCALLTYPE QueryInternalConnections(IPin** apPin, ULONG* nPin) override; - HRESULT STDMETHODCALLTYPE EndOfStream(void) override; - HRESULT STDMETHODCALLTYPE BeginFlush(void) override; - HRESULT STDMETHODCALLTYPE EndFlush(void) override; - HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) override; - - HRESULT STDMETHODCALLTYPE SetFormat(AM_MEDIA_TYPE* pmt) override; - HRESULT STDMETHODCALLTYPE GetFormat(AM_MEDIA_TYPE** ppmt) override; - HRESULT STDMETHODCALLTYPE GetNumberOfCapabilities(int* piCount, int* piSize) override; - HRESULT STDMETHODCALLTYPE GetStreamCaps(int iIndex, AM_MEDIA_TYPE** ppmt, BYTE* pSCC) override; - HRESULT STDMETHODCALLTYPE Set(REFGUID guidPropSet, - DWORD dwPropID, - LPVOID pInstanceData, - DWORD cbInstanceData, - LPVOID pPropData, - DWORD cbPropData) override; - HRESULT STDMETHODCALLTYPE Get(REFGUID guidPropSet, - DWORD dwPropID, - LPVOID pInstanceData, - DWORD cbInstanceData, - LPVOID pPropData, - DWORD cbPropData, - DWORD* pcbReturned) override; - HRESULT STDMETHODCALLTYPE QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD* pTypeSupport) override; - - wil::com_ptr_nothrow FindAllocator(); -}; diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilter.rc b/src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilter.rc deleted file mode 100644 index 1a2f62db5eaf..000000000000 --- a/src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilter.rc +++ /dev/null @@ -1,47 +0,0 @@ -#ifdef _WIN64 - #include "resource.h" -#else - #include "resource.x86.h" -#endif - -#include - -#include "../../../common/version/version.h" - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -1 VERSIONINFO -FILEVERSION FILE_VERSION -PRODUCTVERSION PRODUCT_VERSION -FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -#ifdef _DEBUG -FILEFLAGS VS_FF_DEBUG -#else -FILEFLAGS 0x0L -#endif -FILEOS VOS_NT_WINDOWS32 -FILETYPE VFT_DLL -FILESUBTYPE VFT2_UNKNOWN -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" // US English (0x0409), Unicode (0x04B0) charset - BEGIN - VALUE "CompanyName", COMPANY_NAME - VALUE "FileDescription", FILE_DESCRIPTION - VALUE "FileVersion", FILE_VERSION_STRING - VALUE "InternalName", INTERNAL_NAME - VALUE "LegalCopyright", COPYRIGHT_NOTE - VALUE "OriginalFilename", ORIGINAL_FILENAME - VALUE "ProductName", PRODUCT_NAME - VALUE "ProductVersion", PRODUCT_VERSION_STRING - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 // US English (0x0409), Unicode (1200) charset - END -END diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilter.vcxproj b/src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilter.vcxproj deleted file mode 100644 index fd8525072f32..000000000000 --- a/src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilter.vcxproj +++ /dev/null @@ -1,157 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Debug - ARM64 - - - Release - Win32 - - - Release - x64 - - - Release - ARM64 - - - - 16.0 - {AC2857B4-103D-4D6D-9740-926EBF785042} - Win32Proj - VideoConferenceProxyFilter - VideoConferenceProxyFilter - - - - DynamicLibrary - - - v143 - - - v143 - - - v143 - - - v143 - - - - $(SolutionDir)\src\;$(ProjectDir)..\..\..\ - Level4 - - - - - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - - - true - - - - - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(SolutionDir)\src\; - - - Console - - - true - - - call "$(ProjectDir)build_vcm_x86.cmd" - - - - ..\..\..\..\$(Platform)\$(Configuration)\ - PowerToys.VideoConferenceProxyFilter_$(Platform) - - - ..\..\..\..\x86\$(Configuration)\ - PowerToys.VideoConferenceProxyFilter_x86 - - - - - - - - - - ..\VideoConferenceShared\;%(AdditionalIncludeDirectories) - _LIB;NOMINMAX;%(PreprocessorDefinitions) - NotUsing - MultiThreaded - MultiThreadedDebug - - - $(OutDir)VideoConferenceShared.lib;Windowscodecs.lib;Wtsapi32.lib;mfplat.lib;WindowsApp.lib;Mfsensorgroup.lib;Mf.lib;Shlwapi.lib;Strmiids.lib;%(AdditionalDependencies); - module.def - - - _WIN64;_UNICODE;UNICODE;%(PreprocessorDefinitions) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {459e0768-7ebd-4c41-bba1-6db3b3815e0a} - - - {cc6e41ac-8174-4e8a-8d22-85dd7f4851df} - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilterx86.sln b/src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilterx86.sln deleted file mode 100644 index e4f5a921765f..000000000000 --- a/src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilterx86.sln +++ /dev/null @@ -1,51 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30907.101 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VideoConferenceProxyFilter", "VideoConferenceProxyFilter.vcxproj", "{AC2857B4-103D-4D6D-9740-926EBF785042}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VideoConferenceShared", "..\VideoConferenceShared\VideoConferenceShared.vcxproj", "{459E0768-7EBD-4C41-BBA1-6DB3B3815E0A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Version", "..\..\..\common\version\version.vcxproj", "{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {AC2857B4-103D-4D6D-9740-926EBF785042}.Debug|Win32.ActiveCfg = Debug|Win32 - {AC2857B4-103D-4D6D-9740-926EBF785042}.Debug|Win32.Build.0 = Debug|Win32 - {AC2857B4-103D-4D6D-9740-926EBF785042}.Debug|x64.ActiveCfg = Debug|x64 - {AC2857B4-103D-4D6D-9740-926EBF785042}.Debug|x64.Build.0 = Debug|x64 - {AC2857B4-103D-4D6D-9740-926EBF785042}.Release|Win32.ActiveCfg = Release|Win32 - {AC2857B4-103D-4D6D-9740-926EBF785042}.Release|Win32.Build.0 = Release|Win32 - {AC2857B4-103D-4D6D-9740-926EBF785042}.Release|x64.ActiveCfg = Release|x64 - {AC2857B4-103D-4D6D-9740-926EBF785042}.Release|x64.Build.0 = Release|x64 - {459E0768-7EBD-4C41-BBA1-6DB3B3815E0A}.Debug|Win32.ActiveCfg = Debug|Win32 - {459E0768-7EBD-4C41-BBA1-6DB3B3815E0A}.Debug|Win32.Build.0 = Debug|Win32 - {459E0768-7EBD-4C41-BBA1-6DB3B3815E0A}.Debug|x64.ActiveCfg = Debug|x64 - {459E0768-7EBD-4C41-BBA1-6DB3B3815E0A}.Debug|x64.Build.0 = Debug|x64 - {459E0768-7EBD-4C41-BBA1-6DB3B3815E0A}.Release|Win32.ActiveCfg = Release|Win32 - {459E0768-7EBD-4C41-BBA1-6DB3B3815E0A}.Release|Win32.Build.0 = Release|Win32 - {459E0768-7EBD-4C41-BBA1-6DB3B3815E0A}.Release|x64.ActiveCfg = Release|x64 - {459E0768-7EBD-4C41-BBA1-6DB3B3815E0A}.Release|x64.Build.0 = Release|x64 - {CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Debug|Win32.ActiveCfg = Debug|Win32 - {CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Debug|Win32.Build.0 = Debug|Win32 - {CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Debug|x64.ActiveCfg = Debug|x64 - {CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Debug|x64.Build.0 = Debug|x64 - {CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Release|Win32.ActiveCfg = Release|Win32 - {CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Release|Win32.Build.0 = Release|Win32 - {CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Release|x64.ActiveCfg = Release|x64 - {CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {0E41348C-22CB-45A4-8A16-8D7BEA070BB2} - EndGlobalSection -EndGlobal diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/build_vcm_x86.cmd b/src/modules/videoconference/VideoConferenceProxyFilter/build_vcm_x86.cmd deleted file mode 100644 index 9b8507862344..000000000000 --- a/src/modules/videoconference/VideoConferenceProxyFilter/build_vcm_x86.cmd +++ /dev/null @@ -1,3 +0,0 @@ -msbuild VideoConferenceProxyFilterx86.sln -p:Configuration="Release" -p:Platform="Win32" - -exit 0 \ No newline at end of file diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/dllmain.cpp b/src/modules/videoconference/VideoConferenceProxyFilter/dllmain.cpp deleted file mode 100644 index 61133572c82b..000000000000 --- a/src/modules/videoconference/VideoConferenceProxyFilter/dllmain.cpp +++ /dev/null @@ -1,242 +0,0 @@ -#include "VideoCaptureProxyFilter.h" - -#include - -#include -#include - -namespace -{ -#if defined(_WIN64) - class __declspec(uuid("{31AD75E9-8C3A-49C8-B9ED-5880D6B4A764}")) GUID_DECL_POWERTOYS_VCM; -#elif defined(_WIN32) - class __declspec(uuid("{31AD75E9-8C3A-49C8-B9ED-5880D6B4A732}")) GUID_DECL_POWERTOYS_VCM; -#endif - const GUID CLSID_POWERTOYS_VCM = __uuidof(GUID_DECL_POWERTOYS_VCM); - - const REGPINTYPES MEDIA_TYPES = { &MEDIATYPE_Video, &MEDIASUBTYPE_MJPG }; - - const wchar_t FILTER_NAME[] = L"Output"; - const REGFILTERPINS PINS_REGISTRATION = { - (wchar_t*)FILTER_NAME, - false, - true, - false, - false, - &CLSID_NULL, - nullptr, - 1, - &MEDIA_TYPES - }; - - HINSTANCE DLLInstance{}; -} - -struct __declspec(uuid("9DCAF869-9C13-4BDF-BD0D-3592C5579DD6")) VideoCaptureProxyFilterFactory : winrt::implements -{ - HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown*, REFIID riid, void** ppvObject) noexcept override - { - try - { - return winrt::make()->QueryInterface(riid, ppvObject); - } - catch (...) - { - return winrt::to_hresult(); - } - } - - HRESULT STDMETHODCALLTYPE LockServer(BOOL fLock) noexcept override - { - if (fLock) - { - ++winrt::get_module_lock(); - } - else - { - --winrt::get_module_lock(); - } - - return S_OK; - } -}; - -HRESULT STDMETHODCALLTYPE DllCanUnloadNow() -{ - if (winrt::get_module_lock()) - { - return S_FALSE; - } - - winrt::clear_factory_cache(); - return S_OK; -} - -HRESULT STDMETHODCALLTYPE DllGetClassObject(GUID const& clsid, GUID const& iid, void** result) -{ - if (!result) - { - return E_POINTER; - } - - if (iid != IID_IClassFactory && iid != IID_IUnknown) - { - return E_NOINTERFACE; - } - - if (clsid != CLSID_POWERTOYS_VCM) - { - return E_INVALIDARG; - } - - try - { - *result = nullptr; - - auto factory = winrt::make(); - factory->AddRef(); - *result = static_cast(factory.get()); - return S_OK; - } - catch (...) - { - return winrt::to_hresult(); - } -} - -std::wstring RegistryPath() -{ - std::wstring registryPath; - registryPath.resize(CHARS_IN_GUID, L'\0'); - - StringFromGUID2(CLSID_POWERTOYS_VCM, registryPath.data(), CHARS_IN_GUID); - registryPath.resize(registryPath.size() - 1); - registryPath = L"CLSID\\" + registryPath; - return registryPath; -} - -bool RegisterServer() -{ - std::wstring dllPath; - dllPath.resize(MAX_PATH, L'\0'); - if (auto length = GetModuleFileNameW(DLLInstance, dllPath.data(), MAX_PATH); length != 0) - { - dllPath.resize(length); - } - else - { - return false; - } - - wil::unique_hkey key; - wil::unique_hkey subkey; - const auto registryPath = RegistryPath(); - if (RegCreateKeyW(HKEY_CLASSES_ROOT, registryPath.c_str(), &key)) - { - return false; - } - - if (RegSetValueW(key.get(), nullptr, REG_SZ, CAMERA_NAME, sizeof(CAMERA_NAME))) - { - return false; - } - - if (RegCreateKeyW(key.get(), L"InprocServer32", &subkey)) - { - return false; - } - - if (RegSetValueW(subkey.get(), nullptr, REG_SZ, dllPath.c_str(), static_cast((dllPath.length() + 1) * sizeof(wchar_t)))) - { - return false; - } - const wchar_t THREADING_MODEL[] = L"Both"; - RegSetValueExW(subkey.get(), L"ThreadingModel", 0, REG_SZ, (const BYTE*)THREADING_MODEL, sizeof(THREADING_MODEL)); - - return true; -} - -bool UnregisterServer() -{ - const auto registryPath = RegistryPath(); - return !RegDeleteTreeW(HKEY_CLASSES_ROOT, registryPath.c_str()); -} - -bool RegisterFilter() -{ - auto filterMapper = wil::CoCreateInstanceNoThrow(CLSID_FilterMapper2); - if (!filterMapper) - { - return false; - } - - REGFILTER2 regFilter{ .dwVersion = 1, .dwMerit = MERIT_DO_NOT_USE, .cPins = 1, .rgPins = &PINS_REGISTRATION }; - - wil::com_ptr_nothrow moniker; - - return SUCCEEDED(filterMapper->RegisterFilter( - CLSID_POWERTOYS_VCM, CAMERA_NAME, &moniker, &CLSID_VideoInputDeviceCategory, nullptr, ®Filter)); -} - -bool UnregisterFilter() -{ - auto filterMapper = wil::CoCreateInstanceNoThrow(CLSID_FilterMapper2); - if (!filterMapper) - { - return false; - } - - return SUCCEEDED(filterMapper->UnregisterFilter(&CLSID_VideoInputDeviceCategory, nullptr, CLSID_POWERTOYS_VCM)); -} - -HRESULT STDMETHODCALLTYPE DllRegisterServer() -{ - if (!RegisterServer()) - { - UnregisterServer(); - return E_FAIL; - } - - auto COMContext = wil::CoInitializeEx(COINIT_APARTMENTTHREADED); - - if (!RegisterFilter()) - { - UnregisterFilter(); - UnregisterServer(); - return E_FAIL; - } - - return S_OK; -} - -HRESULT STDMETHODCALLTYPE DllUnregisterServer() -{ - auto COMContext = wil::CoInitializeEx(COINIT_APARTMENTTHREADED); - - UnregisterFilter(); - UnregisterServer(); - - return S_OK; -} - -HRESULT STDMETHODCALLTYPE DllInstall(BOOL install, LPCWSTR) -{ - if (install) - { - return DllRegisterServer(); - } - else - { - return DllUnregisterServer(); - } -} - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID) -{ - if (fdwReason == DLL_PROCESS_ATTACH) - { - DLLInstance = hinstDLL; - } - - return true; -} diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/module.def b/src/modules/videoconference/VideoConferenceProxyFilter/module.def deleted file mode 100644 index c4fcbcc6619b..000000000000 --- a/src/modules/videoconference/VideoConferenceProxyFilter/module.def +++ /dev/null @@ -1,7 +0,0 @@ -EXPORTS - DllMain PRIVATE - DllGetClassObject PRIVATE - DllCanUnloadNow PRIVATE - DllRegisterServer PRIVATE - DllUnregisterServer PRIVATE - DllInstall PRIVATE diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/packages.config b/src/modules/videoconference/VideoConferenceProxyFilter/packages.config deleted file mode 100644 index 6199e2345ccd..000000000000 --- a/src/modules/videoconference/VideoConferenceProxyFilter/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/resource.h b/src/modules/videoconference/VideoConferenceProxyFilter/resource.h deleted file mode 100644 index fbba96964503..000000000000 --- a/src/modules/videoconference/VideoConferenceProxyFilter/resource.h +++ /dev/null @@ -1,11 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by VideoConferenceProxyFilter.rc - -////////////////////////////// -// Non-localizable - -#define FILE_DESCRIPTION "PowerToys VideoConferenceProxyFilter" -#define INTERNAL_NAME "PowerToys.VideoConferenceProxyFilter" -#define ORIGINAL_FILENAME "PowerToys.VideoConferenceProxyFilter_x64.dll" - diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/resource.x86.h b/src/modules/videoconference/VideoConferenceProxyFilter/resource.x86.h deleted file mode 100644 index fe511d09292e..000000000000 --- a/src/modules/videoconference/VideoConferenceProxyFilter/resource.x86.h +++ /dev/null @@ -1,11 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by VideoConferenceProxyFilter.rc - -////////////////////////////// -// Non-localizable - -#define FILE_DESCRIPTION "PowerToys VideoConferenceProxyFilter" -#define INTERNAL_NAME "PowerToys.VideoConferenceProxyFilter" -#define ORIGINAL_FILENAME "PowerToys.VideoConferenceProxyFilter_x86.dll" - diff --git a/src/modules/videoconference/VideoConferenceShared/CameraStateUpdateChannels.cpp b/src/modules/videoconference/VideoConferenceShared/CameraStateUpdateChannels.cpp deleted file mode 100644 index 534428531bd3..000000000000 --- a/src/modules/videoconference/VideoConferenceShared/CameraStateUpdateChannels.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "CameraStateUpdateChannels.h" - -#include "naming.h" - -std::wstring_view CameraOverlayImageChannel::endpoint() -{ - static const std::wstring endpoint = ObtainStableGlobalNameForKernelObject(L"PowerToysVideoConferenceCameraOverlayImageChannelSharedMemory", true); - return endpoint; -} - -std::wstring_view CameraSettingsUpdateChannel::endpoint() -{ - static const std::wstring endpoint = ObtainStableGlobalNameForKernelObject(L"PowerToysVideoConferenceSettingsChannelSharedMemory", true); - return endpoint; -} diff --git a/src/modules/videoconference/VideoConferenceShared/CameraStateUpdateChannels.h b/src/modules/videoconference/VideoConferenceShared/CameraStateUpdateChannels.h deleted file mode 100644 index 02ec542f7ae6..000000000000 --- a/src/modules/videoconference/VideoConferenceShared/CameraStateUpdateChannels.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include -#include - -struct alignas(16) CameraSettingsUpdateChannel -{ - bool useOverlayImage = false; - bool cameraInUse = false; - - std::optional overlayImageSize; - std::optional> sourceCameraName; - - bool newOverlayImagePosted = false; - - static std::wstring_view endpoint(); -}; - -namespace CameraOverlayImageChannel -{ - std::wstring_view endpoint(); -} diff --git a/src/modules/videoconference/VideoConferenceShared/DLLProviderHelpers.h b/src/modules/videoconference/VideoConferenceShared/DLLProviderHelpers.h deleted file mode 100644 index 73c29cf08bc7..000000000000 --- a/src/modules/videoconference/VideoConferenceShared/DLLProviderHelpers.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#define WIN32_LEAN_AND_MEAN -#include - -#include -#include -#include - -#define DECLARE_DLL_FUNCTION(NAME) \ - std::function NAME = (std::add_pointer_t)GetProcAddress(_library_handle, #NAME); - -#define DECLARE_DLL_PROVIDER_BEGIN(DLL_NAME) \ - class DLL_NAME##APIProvider final \ - { \ - HMODULE _library_handle; \ - DLL_NAME##APIProvider(HMODULE h) : _library_handle{ h } {} \ - \ - public: \ - ~DLL_NAME##APIProvider() { FreeLibrary(_library_handle); } \ - static std::optional create() \ - { \ - HMODULE h = LoadLibraryA(#DLL_NAME ".dll"); \ - std::optional result; \ - if (!h) \ - return result; \ - result.emplace(DLL_NAME##APIProvider{ h }); \ - return result; \ - } - -#define DECLARE_DLL_PROVIDER_END \ - } \ - ; diff --git a/src/modules/videoconference/VideoConferenceShared/Logging.cpp b/src/modules/videoconference/VideoConferenceShared/Logging.cpp deleted file mode 100644 index faeab04bb52b..000000000000 --- a/src/modules/videoconference/VideoConferenceShared/Logging.cpp +++ /dev/null @@ -1,202 +0,0 @@ -#include "Logging.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -#pragma warning(disable : 4127) - -static std::mutex logMutex; -constexpr inline size_t maxLogSizeMegabytes = 10; -constexpr inline bool alwaysLogVerbose = true; - -void LogToFile(std::wstring what, const bool verbose) -{ - std::error_code _; - const auto tempPath = std::filesystem::temp_directory_path(_); - if (verbose) - { - const bool verboseIndicatorFilePresent = std::filesystem::exists(tempPath / L"PowerToysVideoConferenceVerbose.flag", _); - if (!alwaysLogVerbose && !verboseIndicatorFilePresent) - { - return; - } - } - time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - std::tm tm; - localtime_s(&tm, &now); - char prefix[64]; - const auto pid = GetCurrentProcessId(); - const auto iter = prefix + sprintf_s(prefix, "[%ld]", pid); - std::strftime(iter, sizeof(prefix) - (prefix - iter), "[%d.%m %H:%M:%S] ", &tm); - - std::lock_guard lock{ logMutex }; - std::wstring logFilePath = tempPath; -#if defined(_WIN64) - logFilePath += L"\\PowerToysVideoConference_x64.log"; -#elif defined(_WIN32) - logFilePath += L"\\PowerToysVideoConference_x86.log"; -#endif - size_t logSizeMBs = 0; - try - { - logSizeMBs = static_cast(std::filesystem::file_size(logFilePath) >> 20); - } - catch (...) - { - } - if (logSizeMBs > maxLogSizeMegabytes) - { - std::error_code __; - // Truncate the log file to zero - std::filesystem::resize_file(logFilePath, 0, __); - } - std::wofstream myfile; - myfile.open(logFilePath, std::fstream::app); - - static const auto newLaunch = [&] { - myfile << prefix << "\n\n<<>"; - return 0; - }(); - - myfile << prefix << what << "\n"; - myfile.close(); -} - -void LogToFile(std::string what, const bool verbose) -{ - std::wstring native{ begin(what), end(what) }; - LogToFile(std::move(native), verbose); -} - -std::string toMediaTypeString(GUID subtype) -{ - if (subtype == MFVideoFormat_YUY2) - return "MFVideoFormat_YUY2"; - else if (subtype == MFVideoFormat_RGB32) - return "MFVideoFormat_RGB32"; - else if (subtype == MFVideoFormat_RGB24) - return "MFVideoFormat_RGB24"; - else if (subtype == MFVideoFormat_ARGB32) - return "MFVideoFormat_ARGB32"; - else if (subtype == MFVideoFormat_RGB555) - return "MFVideoFormat_RGB555"; - else if (subtype == MFVideoFormat_RGB565) - return "MFVideoFormat_RGB565"; - else if (subtype == MFVideoFormat_RGB8) - return "MFVideoFormat_RGB8"; - else if (subtype == MFVideoFormat_L8) - return "MFVideoFormat_L8"; - else if (subtype == MFVideoFormat_L16) - return "MFVideoFormat_L16"; - else if (subtype == MFVideoFormat_D16) - return "MFVideoFormat_D16"; - else if (subtype == MFVideoFormat_AYUV) - return "MFVideoFormat_AYUV"; - else if (subtype == MFVideoFormat_YVYU) - return "MFVideoFormat_YVYU"; - else if (subtype == MFVideoFormat_YVU9) - return "MFVideoFormat_YVU9"; - else if (subtype == MFVideoFormat_UYVY) - return "MFVideoFormat_UYVY"; - else if (subtype == MFVideoFormat_NV11) - return "MFVideoFormat_NV11"; - else if (subtype == MFVideoFormat_NV12) - return "MFVideoFormat_NV12"; - else if (subtype == MFVideoFormat_YV12) - return "MFVideoFormat_YV12"; - else if (subtype == MFVideoFormat_I420) - return "MFVideoFormat_I420"; - else if (subtype == MFVideoFormat_IYUV) - return "MFVideoFormat_IYUV"; - else if (subtype == MFVideoFormat_Y210) - return "MFVideoFormat_Y210"; - else if (subtype == MFVideoFormat_Y216) - return "MFVideoFormat_Y216"; - else if (subtype == MFVideoFormat_Y410) - return "MFVideoFormat_Y410"; - else if (subtype == MFVideoFormat_Y416) - return "MFVideoFormat_Y416"; - else if (subtype == MFVideoFormat_Y41P) - return "MFVideoFormat_Y41P"; - else if (subtype == MFVideoFormat_Y41T) - return "MFVideoFormat_Y41T"; - else if (subtype == MFVideoFormat_Y42T) - return "MFVideoFormat_Y42T"; - else if (subtype == MFVideoFormat_P210) - return "MFVideoFormat_P210"; - else if (subtype == MFVideoFormat_P216) - return "MFVideoFormat_P216"; - else if (subtype == MFVideoFormat_P010) - return "MFVideoFormat_P010"; - else if (subtype == MFVideoFormat_P016) - return "MFVideoFormat_P016"; - else if (subtype == MFVideoFormat_v210) - return "MFVideoFormat_v210"; - else if (subtype == MFVideoFormat_v216) - return "MFVideoFormat_v216"; - else if (subtype == MFVideoFormat_v410) - return "MFVideoFormat_v410"; - else if (subtype == MFVideoFormat_MP43) - return "MFVideoFormat_MP43"; - else if (subtype == MFVideoFormat_MP4S) - return "MFVideoFormat_MP4S"; - else if (subtype == MFVideoFormat_M4S2) - return "MFVideoFormat_M4S2"; - else if (subtype == MFVideoFormat_MP4V) - return "MFVideoFormat_MP4V"; - else if (subtype == MFVideoFormat_WMV1) - return "MFVideoFormat_WMV1"; - else if (subtype == MFVideoFormat_WMV2) - return "MFVideoFormat_WMV2"; - else if (subtype == MFVideoFormat_WMV3) - return "MFVideoFormat_WMV3"; - else if (subtype == MFVideoFormat_WVC1) - return "MFVideoFormat_WVC1"; - else if (subtype == MFVideoFormat_MSS1) - return "MFVideoFormat_MSS1"; - else if (subtype == MFVideoFormat_MSS2) - return "MFVideoFormat_MSS2"; - else if (subtype == MFVideoFormat_MPG1) - return "MFVideoFormat_MPG1"; - else if (subtype == MFVideoFormat_DVSL) - return "MFVideoFormat_DVSL"; - else if (subtype == MFVideoFormat_DVSD) - return "MFVideoFormat_DVSD"; - else if (subtype == MFVideoFormat_DVHD) - return "MFVideoFormat_DVHD"; - else if (subtype == MFVideoFormat_DV25) - return "MFVideoFormat_DV25"; - else if (subtype == MFVideoFormat_DV50) - return "MFVideoFormat_DV50"; - else if (subtype == MFVideoFormat_DVH1) - return "MFVideoFormat_DVH1"; - else if (subtype == MFVideoFormat_DVC) - return "MFVideoFormat_DVC"; - else if (subtype == MFVideoFormat_H264) - return "MFVideoFormat_H264"; - else if (subtype == MFVideoFormat_H265) - return "MFVideoFormat_H265"; - else if (subtype == MFVideoFormat_MJPG) - return "MFVideoFormat_MJPG"; - else if (subtype == MFVideoFormat_420O) - return "MFVideoFormat_420O"; - else if (subtype == MFVideoFormat_HEVC) - return "MFVideoFormat_HEVC"; - else if (subtype == MFVideoFormat_HEVC_ES) - return "MFVideoFormat_HEVC_ES"; - else if (subtype == MFVideoFormat_VP80) - return "MFVideoFormat_VP80"; - else if (subtype == MFVideoFormat_VP90) - return "MFVideoFormat_VP90"; - else if (subtype == MFVideoFormat_ORAW) - return "MFVideoFormat_ORAW"; - else - return "Other VideoFormat"; -} \ No newline at end of file diff --git a/src/modules/videoconference/VideoConferenceShared/Logging.h b/src/modules/videoconference/VideoConferenceShared/Logging.h deleted file mode 100644 index e58575922923..000000000000 --- a/src/modules/videoconference/VideoConferenceShared/Logging.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include - -void LogToFile(std::string what, const bool verbose = false); -void LogToFile(std::wstring what, const bool verbose = false); -std::string toMediaTypeString(GUID subtype); - -#define RETURN_IF_FAILED_WITH_LOGGING(val) \ - hr = (val); \ - if (FAILED(hr)) \ - { \ - LogToFile(std::string(__FUNCTION__ "() ") + #val + ": " + std::system_category().message(hr)); \ - return hr; \ - } - -#define RETURN_NULLPTR_IF_FAILED_WITH_LOGGING(val) \ - hr = val; \ - if (FAILED(hr)) \ - { \ - LogToFile(std::string(__FUNCTION__ "() ") + #val + ": " + std::system_category().message(hr)); \ - return nullptr; \ - } - -#define VERBOSE_LOG \ - std::string functionNameTMPVAR = __FUNCTION__; \ - LogToFile(std::string(functionNameTMPVAR + " enter"), true); \ - auto verboseLogOnScopeEnd = wil::scope_exit([&] { \ - LogToFile(std::string(functionNameTMPVAR + " exit"), true); \ - }); - -#if defined(PowerToysInterop) -#undef LOG -#define LOG(...) -#else -#define LOG(str) LogToFile(str, false); -#endif - -constexpr inline bool failed(HRESULT hr) -{ - return hr != S_OK; -} - -constexpr inline bool failed(bool val) -{ - return val == false; -} - -template -inline bool failed(wil::com_ptr_nothrow& ptr) -{ - return ptr == nullptr; -} - -#define OK_OR_BAIL(expr) \ - if (failed(expr)) \ - return {}; diff --git a/src/modules/videoconference/VideoConferenceShared/MediaFoundationAPIProvider.h b/src/modules/videoconference/VideoConferenceShared/MediaFoundationAPIProvider.h deleted file mode 100644 index e3d6fcec09ea..000000000000 --- a/src/modules/videoconference/VideoConferenceShared/MediaFoundationAPIProvider.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include -#include - -#include "DLLProviderHelpers.h" - -DECLARE_DLL_PROVIDER_BEGIN(mfplat) -DECLARE_DLL_FUNCTION(MFCreateAttributes) -DECLARE_DLL_PROVIDER_END - -DECLARE_DLL_PROVIDER_BEGIN(mf) -DECLARE_DLL_FUNCTION(MFEnumDeviceSources) -DECLARE_DLL_PROVIDER_END diff --git a/src/modules/videoconference/VideoConferenceShared/MicrophoneDevice.cpp b/src/modules/videoconference/VideoConferenceShared/MicrophoneDevice.cpp deleted file mode 100644 index f8e6f00a80e3..000000000000 --- a/src/modules/videoconference/VideoConferenceShared/MicrophoneDevice.cpp +++ /dev/null @@ -1,154 +0,0 @@ -#include "pch.h" -#include "MicrophoneDevice.h" - -#include "Logging.h" - -#include - -MicrophoneDevice::MicrophoneDevice(wil::com_ptr_nothrow device, wil::com_ptr_nothrow endpoint) : - _device{ std::move(device) }, - _endpoint{ std::move(endpoint) } -{ - if (!_device || !_endpoint) - { - throw std::logic_error("MicrophoneDevice was initialized with null objects"); - } - _device->GetId(&_id); - wil::com_ptr_nothrow props; - _device->OpenPropertyStore( - STGM_READ, &props); - if (props) - { - props->GetValue(PKEY_Device_FriendlyName, &_friendly_name); - } - else - { - LOG("MicrophoneDevice::MicrophoneDevice couldn't open property store"); - } -} - -MicrophoneDevice::~MicrophoneDevice() -{ - if (_notifier) - { - _endpoint->UnregisterControlChangeNotify(_notifier.get()); - } -} - -bool MicrophoneDevice::active() const noexcept -{ - DWORD state = 0; - _device->GetState(&state); - return state == DEVICE_STATE_ACTIVE; -} - -void MicrophoneDevice::set_muted(const bool muted) noexcept -{ - _endpoint->SetMute(muted, nullptr); -} - -bool MicrophoneDevice::muted() const noexcept -{ - BOOL muted = FALSE; - _endpoint->GetMute(&muted); - return muted; -} - -std::wstring_view MicrophoneDevice::id() const noexcept -{ - return _id ? _id.get() : FALLBACK_ID; -} - -std::wstring_view MicrophoneDevice::name() const noexcept -{ - return _friendly_name.pwszVal ? _friendly_name.pwszVal : FALLBACK_NAME; -} - -void MicrophoneDevice::set_mute_changed_callback(mute_changed_cb_t callback) noexcept -{ - if (_notifier) - { - _endpoint->UnregisterControlChangeNotify(_notifier.get()); - } - _mute_changed_callback = std::move(callback); - _notifier = winrt::make(this); - - _endpoint->RegisterControlChangeNotify(_notifier.get()); -} - -std::unique_ptr MicrophoneDevice::getDefault() -{ - auto deviceEnumerator = wil::CoCreateInstanceNoThrow(); - if (!deviceEnumerator) - { - LOG("MicrophoneDevice::getDefault MMDeviceEnumerator returned null"); - return nullptr; - } - wil::com_ptr_nothrow captureDevice; - deviceEnumerator->GetDefaultAudioEndpoint(eCapture, eCommunications, &captureDevice); - if (!captureDevice) - { - LOG("MicrophoneDevice::getDefault captureDevice is null"); - return nullptr; - } - wil::com_ptr_nothrow microphoneEndpoint; - captureDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, nullptr, reinterpret_cast(µphoneEndpoint)); - if (!microphoneEndpoint) - { - LOG("MicrophoneDevice::getDefault captureDevice is null"); - return nullptr; - } - return std::make_unique(std::move(captureDevice), std::move(microphoneEndpoint)); -} - -std::vector> MicrophoneDevice::getAllActive() -{ - std::vector> microphoneDevices; - auto deviceEnumerator = wil::CoCreateInstanceNoThrow(); - if (!deviceEnumerator) - { - LOG("MicrophoneDevice::getAllActive MMDeviceEnumerator returned null"); - return microphoneDevices; - } - - wil::com_ptr_nothrow captureDevices; - deviceEnumerator->EnumAudioEndpoints(eCapture, DEVICE_STATE_ACTIVE, &captureDevices); - if (!captureDevices) - { - LOG("MicrophoneDevice::getAllActive EnumAudioEndpoints returned null"); - return microphoneDevices; - } - UINT nDevices = 0; - captureDevices->GetCount(&nDevices); - microphoneDevices.reserve(nDevices); - for (UINT i = 0; i < nDevices; ++i) - { - wil::com_ptr_nothrow device; - captureDevices->Item(i, &device); - if (!device) - { - continue; - } - wil::com_ptr_nothrow microphoneEndpoint; - device->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, nullptr, reinterpret_cast(µphoneEndpoint)); - if (!microphoneEndpoint) - { - continue; - } - microphoneDevices.push_back(std::make_unique(std::move(device), std::move(microphoneEndpoint))); - } - return microphoneDevices; -} - -MicrophoneDevice::VolumeNotifier::VolumeNotifier(MicrophoneDevice* subscribedDevice) : - _subscribedDevice{ subscribedDevice } -{ -} - -HRESULT __stdcall MicrophoneDevice::VolumeNotifier::OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA data) -{ - if (_subscribedDevice && _subscribedDevice->_mute_changed_callback) - _subscribedDevice->_mute_changed_callback(data->bMuted); - - return S_OK; -} diff --git a/src/modules/videoconference/VideoConferenceShared/MicrophoneDevice.h b/src/modules/videoconference/VideoConferenceShared/MicrophoneDevice.h deleted file mode 100644 index 6a40fb5d54d2..000000000000 --- a/src/modules/videoconference/VideoConferenceShared/MicrophoneDevice.h +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once -#define NOMINMAX - -#include -#include - -#include -#include - -#include -#include - -#include - -#include -#include -#include - -#include -#include - -class MicrophoneDevice -{ -public: - using mute_changed_cb_t = std::function; - -private: - friend struct VolumeNotifier; - - struct VolumeNotifier : winrt::implements - { - MicrophoneDevice* _subscribedDevice = nullptr; - VolumeNotifier(MicrophoneDevice* subscribedDevice); - - virtual HRESULT __stdcall OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA data) override; - }; - - wil::unique_cotaskmem_string _id; - wil::unique_prop_variant _friendly_name; - mute_changed_cb_t _mute_changed_callback; - winrt::com_ptr _notifier; - wil::com_ptr_nothrow _endpoint; - wil::com_ptr_nothrow _device; - - constexpr static inline std::wstring_view FALLBACK_NAME = L"Unknown device"; - constexpr static inline std::wstring_view FALLBACK_ID = L"UNKNOWN_ID"; - -public: - MicrophoneDevice(MicrophoneDevice&&) noexcept = delete; - MicrophoneDevice(const MicrophoneDevice&) noexcept = delete; - MicrophoneDevice(wil::com_ptr_nothrow device, wil::com_ptr_nothrow endpoint); - ~MicrophoneDevice(); - - bool active() const noexcept; - void set_muted(const bool muted) noexcept; - bool muted() const noexcept; - - std::wstring_view id() const noexcept; - std::wstring_view name() const noexcept; - void set_mute_changed_callback(mute_changed_cb_t callback) noexcept; - - static std::unique_ptr getDefault(); - static std::vector> getAllActive(); -}; diff --git a/src/modules/videoconference/VideoConferenceShared/SerializedSharedMemory.cpp b/src/modules/videoconference/VideoConferenceShared/SerializedSharedMemory.cpp deleted file mode 100644 index a7620e77419f..000000000000 --- a/src/modules/videoconference/VideoConferenceShared/SerializedSharedMemory.cpp +++ /dev/null @@ -1,190 +0,0 @@ -#include "SerializedSharedMemory.h" -#ifdef _M_ARM64 -#define _mm_pause() __yield(); -#endif -inline char* SerializedSharedMemory::lock_flag_addr() noexcept -{ - return reinterpret_cast(_memory._data + _memory._size); -} - -inline void SerializedSharedMemory::lock() noexcept -{ - if (_read_only) - { - return; - } - while (LOCKED == _InterlockedCompareExchange8(lock_flag_addr(), LOCKED, !LOCKED)) - { - while (*lock_flag_addr() == LOCKED) - { - _mm_pause(); - } - } -} - -inline void SerializedSharedMemory::unlock() noexcept -{ - if (_read_only) - { - return; - } - _InterlockedExchange8(lock_flag_addr(), !LOCKED); -} - -SerializedSharedMemory::SerializedSharedMemory(std::array handles, - memory_t memory, - const bool readonly) noexcept - : - _handles{ std::move(handles) }, _memory{ std::move(memory) }, _read_only(readonly) -{ -} - -SerializedSharedMemory::~SerializedSharedMemory() noexcept -{ - if (_memory._data) - { - UnmapViewOfFile(_memory._data); - } -} - -SerializedSharedMemory::SerializedSharedMemory(SerializedSharedMemory&& rhs) noexcept -{ - *this = std::move(rhs); -} - -SerializedSharedMemory& SerializedSharedMemory::operator=(SerializedSharedMemory&& rhs) noexcept -{ - _handles = {}; - _handles.swap(rhs._handles); - _memory = std::move(rhs._memory); - rhs._memory = {}; - _read_only = rhs._read_only; - rhs._read_only = true; - - return *this; -} - -std::optional SerializedSharedMemory::create(const std::wstring_view object_name, - const size_t size, - const bool read_only, - SECURITY_ATTRIBUTES* maybe_attributes) noexcept -{ - SECURITY_DESCRIPTOR sd; - SECURITY_ATTRIBUTES sa = { sizeof SECURITY_ATTRIBUTES }; - if (!maybe_attributes) - { - sa.lpSecurityDescriptor = &sd; - sa.bInheritHandle = false; - if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION) || - !SetSecurityDescriptorDacl(&sd, true, nullptr, false)) - { - return std::nullopt; - } - } - - // We need an extra byte for locking if it's not readonly - const ULARGE_INTEGER UISize{ .QuadPart = static_cast(size) + !read_only }; - - wil::unique_handle hMapFile{ CreateFileMappingW(INVALID_HANDLE_VALUE, - maybe_attributes ? maybe_attributes : &sa, - read_only ? PAGE_READONLY : PAGE_READWRITE, - UISize.HighPart, - UISize.LowPart, - object_name.data()) }; - if (!hMapFile) - { - return std::nullopt; - } - auto shmem = static_cast( - MapViewOfFile(hMapFile.get(), read_only ? FILE_MAP_READ : FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, static_cast(UISize.QuadPart))); - if (!shmem) - { - return std::nullopt; - } - std::array handles = { std::move(hMapFile), {} }; - return SerializedSharedMemory{ std::move(handles), memory_t{ shmem, size }, read_only }; -} - -std::optional SerializedSharedMemory::open(const std::wstring_view object_name, - const size_t size, - const bool read_only) noexcept -{ - wil::unique_handle hMapFile{ OpenFileMappingW(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, object_name.data()) }; - if (!hMapFile) - { - return std::nullopt; - } - - auto shmem = static_cast( - MapViewOfFile(hMapFile.get(), read_only ? FILE_MAP_READ : FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, size + !read_only)); - - if (!shmem) - { - return std::nullopt; - } - std::array handles = { std::move(hMapFile), {} }; - return SerializedSharedMemory{ std::move(handles), memory_t{ shmem, size }, read_only }; -} - -std::optional SerializedSharedMemory::create_readonly( - const std::wstring_view object_name, - const std::wstring_view file_path, - SECURITY_ATTRIBUTES* maybe_attributes) noexcept -{ - SECURITY_DESCRIPTOR sd; - SECURITY_ATTRIBUTES sa = { sizeof SECURITY_ATTRIBUTES }; - if (!maybe_attributes) - { - sa.lpSecurityDescriptor = &sd; - sa.bInheritHandle = false; - if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION) || - !SetSecurityDescriptorDacl(&sd, true, nullptr, false)) - { - return std::nullopt; - } - } - wil::unique_handle hFile{ CreateFileW(file_path.data(), - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - maybe_attributes ? maybe_attributes : &sa, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - nullptr) }; - - if (!hFile) - { - return std::nullopt; - } - - LARGE_INTEGER fileSize; - if (!GetFileSizeEx(hFile.get(), &fileSize)) - { - return std::nullopt; - } - wil::unique_handle hMapFile{ CreateFileMappingW(hFile.get(), - maybe_attributes ? maybe_attributes : &sa, - PAGE_READONLY, - fileSize.HighPart, - fileSize.LowPart, - object_name.data()) }; - if (!hMapFile) - { - return std::nullopt; - } - - auto shmem = static_cast(MapViewOfFile(nullptr, FILE_MAP_READ, 0, 0, static_cast(fileSize.QuadPart))); - if (shmem) - { - return std::nullopt; - } - std::array handles = { std::move(hMapFile), std::move(hFile) }; - - return SerializedSharedMemory{ std::move(handles), memory_t{ shmem, static_cast(fileSize.QuadPart) }, true }; -} - -void SerializedSharedMemory::access(std::function access_routine) noexcept -{ - lock(); - access_routine(_memory); - unlock(); -} \ No newline at end of file diff --git a/src/modules/videoconference/VideoConferenceShared/SerializedSharedMemory.h b/src/modules/videoconference/VideoConferenceShared/SerializedSharedMemory.h deleted file mode 100644 index 15f10527467b..000000000000 --- a/src/modules/videoconference/VideoConferenceShared/SerializedSharedMemory.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif - -#include -#include -#include -#include -#include -#include - -// Wrapper class allowing sharing readonly/writable memory with a serialized access via atomic locking. -// Note that it doesn't protect against a 3rd party concurrently modifying physical file contents. -class SerializedSharedMemory -{ -public: - struct memory_t - { - uint8_t * _data = nullptr; - size_t _size = 0; - }; - - static std::optional create(const std::wstring_view object_name, - const size_t size, - const bool read_only, - SECURITY_ATTRIBUTES* maybe_attributes = nullptr) noexcept; - static std::optional create_readonly( - const std::wstring_view object_name, - const std::wstring_view file_path, - SECURITY_ATTRIBUTES* maybe_attributes = nullptr) noexcept; - static std::optional open(const std::wstring_view object_name, - const size_t size, - const bool read_only) noexcept; - - void access(std::function access_routine) noexcept; - inline size_t size() const noexcept { return _memory._size; } - - ~SerializedSharedMemory() noexcept; - SerializedSharedMemory(SerializedSharedMemory&&) noexcept; - SerializedSharedMemory& operator=(SerializedSharedMemory&&) noexcept; - -private: - std::array _handles; - memory_t _memory; - bool _read_only = true; - constexpr static inline int64_t LOCKED = 1; - - char* lock_flag_addr() noexcept; - void lock() noexcept; - void unlock() noexcept; - - SerializedSharedMemory(std::array handles, memory_t memory, const bool readonly) noexcept; -}; \ No newline at end of file diff --git a/src/modules/videoconference/VideoConferenceShared/VideoCaptureDeviceList.cpp b/src/modules/videoconference/VideoConferenceShared/VideoCaptureDeviceList.cpp deleted file mode 100644 index ba710a0453dc..000000000000 --- a/src/modules/videoconference/VideoConferenceShared/VideoCaptureDeviceList.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include "pch.h" -#include "VideoCaptureDeviceList.h" -#include "Logging.h" -#include "MediaFoundationAPIProvider.h" -#include -#include - -#include -#include - -void VideoCaptureDeviceList::Clear() -{ - for (UINT32 i = 0; i < m_numberDevices; i++) - { - CoTaskMemFree(m_deviceFriendlyNames[i]); - if (m_ppDevices[i]) - { - m_ppDevices[i]->Release(); - } - } - CoTaskMemFree(m_ppDevices); - m_ppDevices = nullptr; - if (m_deviceFriendlyNames) - { - delete[] m_deviceFriendlyNames; - } - - m_deviceFriendlyNames = nullptr; - m_numberDevices = 0; -} - -HRESULT VideoCaptureDeviceList::EnumerateDevices() -{ - HRESULT hr = S_OK; - wil::com_ptr pAttributes; - Clear(); - auto mfplatAPI = mfplatAPIProvider::create(); - auto mfAPI = mfAPIProvider::create(); - if (!mfplatAPI || !mfAPI) - { - return ERROR_FILE_NOT_FOUND; - } - - // Initialize an attribute store. We will use this to - // specify the enumeration parameters. - - hr = mfplatAPI->MFCreateAttributes(&pAttributes, 1); - - // Ask for source type = video capture devices - if (SUCCEEDED(hr)) - { - hr = pAttributes->SetGUID( - MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, - MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID); - } - else - { - LOG("VideoCaptureDeviceList::EnumerateDevices(): Couldn't MFCreateAttributes"); - } - // Enumerate devices. - if (SUCCEEDED(hr)) - { - hr = mfAPI->MFEnumDeviceSources(pAttributes.get(), &m_ppDevices, &m_numberDevices); - } - else - { - LOG("VideoCaptureDeviceList::EnumerateDevices(): Couldn't SetGUID"); - } - - if (FAILED(hr)) - { - LOG("VideoCaptureDeviceList::EnumerateDevices(): MFEnumDeviceSources failed"); - return hr; - } - - m_deviceFriendlyNames = new (std::nothrow) wchar_t*[m_numberDevices]; - for (UINT32 i = 0; i < m_numberDevices; i++) - { - UINT32 nameLength = 0; - m_ppDevices[i]->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &m_deviceFriendlyNames[i], &nameLength); - } - - return hr; -} - -HRESULT VideoCaptureDeviceList::GetDevice(UINT32 index, IMFActivate** ppActivate) -{ - if (index >= Count()) - { - return E_INVALIDARG; - } - - *ppActivate = m_ppDevices[index]; - (*ppActivate)->AddRef(); - - return S_OK; -} - -std::wstring_view VideoCaptureDeviceList::GetDeviceName(UINT32 index) -{ - if (index >= Count()) - { - return {}; - } - - return m_deviceFriendlyNames[index]; -} diff --git a/src/modules/videoconference/VideoConferenceShared/VideoCaptureDeviceList.h b/src/modules/videoconference/VideoConferenceShared/VideoCaptureDeviceList.h deleted file mode 100644 index eb0bf4afd4b3..000000000000 --- a/src/modules/videoconference/VideoConferenceShared/VideoCaptureDeviceList.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#include -#include - -class VideoCaptureDeviceList -{ - UINT32 m_numberDevices; - // TODO: use wil - IMFActivate** m_ppDevices = nullptr; - wchar_t** m_deviceFriendlyNames = nullptr; - -public: - VideoCaptureDeviceList() : - m_ppDevices(NULL), m_numberDevices(0) - { - } - ~VideoCaptureDeviceList() - { - Clear(); - } - - UINT32 Count() const { return m_numberDevices; } - - void Clear(); - HRESULT EnumerateDevices(); - HRESULT GetDevice(UINT32 index, IMFActivate** ppActivate); - std::wstring_view GetDeviceName(UINT32 index); -}; diff --git a/src/modules/videoconference/VideoConferenceShared/naming.cpp b/src/modules/videoconference/VideoConferenceShared/naming.cpp deleted file mode 100644 index b93088cd003f..000000000000 --- a/src/modules/videoconference/VideoConferenceShared/naming.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "naming.h" - -#include "username.h" - -std::wstring ObtainStableGlobalNameForKernelObject(const std::wstring_view name, const bool restricted) -{ - static const std::optional username = ObtainActiveUserName(); - std::wstring result = L"Global\\"; - if (restricted) - { - result += L"Restricted\\"; - } - if (username) - { - result += *username; - } - result += name; - return result; -} diff --git a/src/modules/videoconference/VideoConferenceShared/naming.h b/src/modules/videoconference/VideoConferenceShared/naming.h deleted file mode 100644 index 8d127b06231a..000000000000 --- a/src/modules/videoconference/VideoConferenceShared/naming.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once -#include -#include - -std::wstring ObtainStableGlobalNameForKernelObject(const std::wstring_view name, const bool restricted); \ No newline at end of file diff --git a/src/modules/videoconference/VideoConferenceShared/pch.h b/src/modules/videoconference/VideoConferenceShared/pch.h deleted file mode 100644 index 128bb3589fa9..000000000000 --- a/src/modules/videoconference/VideoConferenceShared/pch.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -// Dummy file to allow compiling VideoCaptureDeviceList.h and MicrophoneDevice.h in this project, since it's also used in PowerToys.Interop.vcxproj, which has a pch. diff --git a/src/modules/videoconference/VideoConferenceShared/username.cpp b/src/modules/videoconference/VideoConferenceShared/username.cpp deleted file mode 100644 index d8b99e8dd57b..000000000000 --- a/src/modules/videoconference/VideoConferenceShared/username.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "username.h" - -#include -#include - -std::optional ObtainActiveUserName() -{ - const DWORD sessionId = WTSGetActiveConsoleSessionId(); - WCHAR* pUserName; - DWORD _ = 0; - - if (!WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSUserName, &pUserName, &_)) - { - return std::nullopt; - } - WTSGetActiveConsoleSessionId(); - std::wstring result{ pUserName }; - WTSFreeMemory(pUserName); - return result; -} diff --git a/src/modules/videoconference/VideoConferenceShared/username.h b/src/modules/videoconference/VideoConferenceShared/username.h deleted file mode 100644 index dcbefec38bbe..000000000000 --- a/src/modules/videoconference/VideoConferenceShared/username.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include -#include -#include - -std::optional ObtainActiveUserName(); - -std::wstring ObtainStableGlobalNameForKernelObject(const std::wstring_view name, const bool restricted); \ No newline at end of file diff --git a/src/modules/videoconference/make_cab.ddf b/src/modules/videoconference/make_cab.ddf deleted file mode 100644 index 0c75024114b2..000000000000 --- a/src/modules/videoconference/make_cab.ddf +++ /dev/null @@ -1,20 +0,0 @@ -; Disable default limits -.option EXPLICIT -.set CabinetFileCountThreshold=0 -.set FolderFileCountThreshold=0 -.set FolderSizeThreshold=0 -.set MaxCabinetSize=0 -.set MaxDiskFileCount=0 -.set MaxDiskSize=0 - -.set GenerateInf=ON -.set Compress=OFF -.set Cabinet=ON -.set CabinetNameTemplate=driver.cab -.set DestinationDir=cab_output -.set DiskDirectoryTemplate=driver - -VideoConferenceCustomMediaSource.dll -videoconferencevirtualdriver.cat -VideoConferenceVirtualDriver.dll -VideoConferenceVirtualDriver.inf \ No newline at end of file diff --git a/src/runner/main.cpp b/src/runner/main.cpp index f73801655a4c..e9ea4e59d977 100644 --- a/src/runner/main.cpp +++ b/src/runner/main.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include "UpdateUtils.h" #include "ActionRunnerUtils.h" @@ -132,6 +133,15 @@ int runner(bool isProcessElevated, bool openSettings, std::string settingsWindow } }.detach(); chdir_current_executable(); + + // We deprecated a utility called Video Conference Mute, which registered itself as a video input device. + // When running elevated, we try to clean up the device registration from previous installations. + // This is done here too because a user-scope installer won't be able to remove the driver registration due to lack of permissions. + if (isProcessElevated) + { + clean_video_conference(); + } + // Load PowerToys DLLs std::vector knownModules = { @@ -164,13 +174,8 @@ int runner(bool isProcessElevated, bool openSettings, std::string settingsWindow L"PowerToys.CmdNotFoundModuleInterface.dll", L"PowerToys.WorkspacesModuleInterface.dll", L"PowerToys.CmdPalModuleInterface.dll", + L"PowerToys.ZoomItModuleInterface.dll", }; - const auto VCM_PATH = L"PowerToys.VideoConferenceModule.dll"; - if (const auto mf = LoadLibraryA("mf.dll")) - { - FreeLibrary(mf); - knownModules.emplace_back(VCM_PATH); - } for (auto moduleSubdir : knownModules) { diff --git a/src/runner/settings_window.cpp b/src/runner/settings_window.cpp index d1f8fa4f6725..265d3e3dc097 100644 --- a/src/runner/settings_window.cpp +++ b/src/runner/settings_window.cpp @@ -674,8 +674,6 @@ std::string ESettingsWindowNames_to_string(ESettingsWindowNames value) return "FileExplorer"; case ESettingsWindowNames::ShortcutGuide: return "ShortcutGuide"; - case ESettingsWindowNames::VideoConference: - return "VideoConference"; case ESettingsWindowNames::Hosts: return "Hosts"; case ESettingsWindowNames::MeasureTool: @@ -698,6 +696,8 @@ std::string ESettingsWindowNames_to_string(ESettingsWindowNames value) return "NewPlus"; case ESettingsWindowNames::CmdPal: return "CmdPal"; + case ESettingsWindowNames::ZoomIt: + return "ZoomIt"; default: { Logger::error(L"Can't convert ESettingsWindowNames value={} to string", static_cast(value)); @@ -753,10 +753,6 @@ ESettingsWindowNames ESettingsWindowNames_from_string(std::string value) { return ESettingsWindowNames::ShortcutGuide; } - else if (value == "VideoConference") - { - return ESettingsWindowNames::VideoConference; - } else if (value == "Hosts") { return ESettingsWindowNames::Hosts; @@ -801,6 +797,10 @@ ESettingsWindowNames ESettingsWindowNames_from_string(std::string value) { return ESettingsWindowNames::CmdPal; } + else if (value == "ZoomIt") + { + return ESettingsWindowNames::ZoomIt; + } else { Logger::error(L"Can't convert string value={} to ESettingsWindowNames", winrt::to_hstring(value)); diff --git a/src/runner/settings_window.h b/src/runner/settings_window.h index de905a00f760..e6e6e07e4c54 100644 --- a/src/runner/settings_window.h +++ b/src/runner/settings_window.h @@ -16,7 +16,6 @@ enum class ESettingsWindowNames PowerRename, FileExplorer, ShortcutGuide, - VideoConference, Hosts, MeasureTool, PowerOCR, @@ -27,6 +26,7 @@ enum class ESettingsWindowNames AdvancedPaste, NewPlus, CmdPal, + ZoomIt, }; std::string ESettingsWindowNames_to_string(ESettingsWindowNames value); diff --git a/src/settings-ui/Settings.UI.Library/EnabledModules.cs b/src/settings-ui/Settings.UI.Library/EnabledModules.cs index 49ebbb2d2aed..0e0556d44276 100644 --- a/src/settings-ui/Settings.UI.Library/EnabledModules.cs +++ b/src/settings-ui/Settings.UI.Library/EnabledModules.cs @@ -88,22 +88,6 @@ public bool ShortcutGuide } } - private bool videoConference; // defaulting to off https://github.com/microsoft/PowerToys/issues/14507 - - [JsonPropertyName("Video Conference")] - public bool VideoConference - { - get => this.videoConference; - set - { - if (this.videoConference != value) - { - LogTelemetryEvent(value); - this.videoConference = value; - } - } - } - private bool powerRename = true; public bool PowerRename @@ -512,6 +496,23 @@ public bool CmdPal } } + private bool zoomIt; + + [JsonPropertyName("ZoomIt")] + public bool ZoomIt + { + get => zoomIt; + set + { + if (zoomIt != value) + { + LogTelemetryEvent(value); + zoomIt = value; + NotifyChange(); + } + } + } + private void NotifyChange() { notifyEnabledChangedAction?.Invoke(); diff --git a/src/settings-ui/Settings.UI.Library/Settings.UI.Library.csproj b/src/settings-ui/Settings.UI.Library/Settings.UI.Library.csproj index a967dd28a770..c3832b11c508 100644 --- a/src/settings-ui/Settings.UI.Library/Settings.UI.Library.csproj +++ b/src/settings-ui/Settings.UI.Library/Settings.UI.Library.csproj @@ -19,6 +19,7 @@ + diff --git a/src/settings-ui/Settings.UI.Library/SndVideoConferenceSettings.cs b/src/settings-ui/Settings.UI.Library/SndVideoConferenceSettings.cs deleted file mode 100644 index b16c79de7910..000000000000 --- a/src/settings-ui/Settings.UI.Library/SndVideoConferenceSettings.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace Microsoft.PowerToys.Settings.UI.Library -{ - public class SndVideoConferenceSettings - { - [JsonPropertyName("Video Conference")] - public VideoConferenceSettings VideoConference { get; set; } - - public SndVideoConferenceSettings(VideoConferenceSettings settings) - { - VideoConference = settings; - } - - public string ToJsonString() - { - return JsonSerializer.Serialize(this); - } - } -} diff --git a/src/settings-ui/Settings.UI.Library/VideoConferenceConfigProperties.cs b/src/settings-ui/Settings.UI.Library/VideoConferenceConfigProperties.cs deleted file mode 100644 index 9c7b33f80411..000000000000 --- a/src/settings-ui/Settings.UI.Library/VideoConferenceConfigProperties.cs +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json; -using System.Text.Json.Serialization; - -using Settings.UI.Library.Attributes; - -namespace Microsoft.PowerToys.Settings.UI.Library -{ - public class VideoConferenceConfigProperties - { - [CmdConfigureIgnoreAttribute] - public HotkeySettings DefaultMuteCameraAndMicrophoneHotkey => new HotkeySettings() - { - Win = true, - Ctrl = false, - Alt = false, - Shift = true, - Key = "Q", - Code = 81, - }; - - [CmdConfigureIgnoreAttribute] - public HotkeySettings DefaultMuteMicrophoneHotkey => new HotkeySettings() - { - Win = true, - Ctrl = false, - Alt = false, - Shift = true, - Key = "A", - Code = 65, - }; - - [CmdConfigureIgnoreAttribute] - public HotkeySettings DefaultPushToTalkMicrophoneHotkey => new HotkeySettings() - { - Win = true, - Ctrl = false, - Alt = false, - Shift = true, - Key = "I", - Code = 73, - }; - - [CmdConfigureIgnoreAttribute] - public HotkeySettings DefaultMuteCameraHotkey => new HotkeySettings() - { - Win = true, - Ctrl = false, - Alt = false, - Shift = true, - Key = "O", - Code = 79, - }; - - public VideoConferenceConfigProperties() - { - MuteCameraAndMicrophoneHotkey = new KeyboardKeysProperty(DefaultMuteCameraAndMicrophoneHotkey); - MuteMicrophoneHotkey = new KeyboardKeysProperty(DefaultMuteMicrophoneHotkey); - PushToTalkMicrophoneHotkey = new KeyboardKeysProperty(DefaultPushToTalkMicrophoneHotkey); - MuteCameraHotkey = new KeyboardKeysProperty(DefaultMuteCameraHotkey); - - PushToReverseEnabled = new BoolProperty(false); - } - - [JsonPropertyName("mute_camera_and_microphone_hotkey")] - public KeyboardKeysProperty MuteCameraAndMicrophoneHotkey { get; set; } - - [JsonPropertyName("mute_microphone_hotkey")] - public KeyboardKeysProperty MuteMicrophoneHotkey { get; set; } - - [JsonPropertyName("push_to_talk_microphone_hotkey")] - public KeyboardKeysProperty PushToTalkMicrophoneHotkey { get; set; } - - [JsonPropertyName("push_to_reverse_enabled")] - public BoolProperty PushToReverseEnabled { get; set; } - - [JsonPropertyName("mute_camera_hotkey")] - public KeyboardKeysProperty MuteCameraHotkey { get; set; } - - [JsonPropertyName("selected_camera")] - public StringProperty SelectedCamera { get; set; } = string.Empty; - - [JsonPropertyName("selected_mic")] - public StringProperty SelectedMicrophone { get; set; } = string.Empty; - - [JsonPropertyName("toolbar_position")] - public StringProperty ToolbarPosition { get; set; } = "Top right corner"; - - [JsonPropertyName("toolbar_monitor")] - public StringProperty ToolbarMonitor { get; set; } = "Main monitor"; - - [JsonPropertyName("camera_overlay_image_path")] - public StringProperty CameraOverlayImagePath { get; set; } = string.Empty; - - [JsonPropertyName("theme")] - public StringProperty Theme { get; set; } - - [JsonPropertyName("toolbar_hide")] - public StringProperty ToolbarHide { get; set; } = "When both camera and microphone are unmuted"; - - [JsonPropertyName("startup_action")] - public StringProperty StartupAction { get; set; } = "Nothing"; - - // converts the current to a json string. - public string ToJsonString() - { - return JsonSerializer.Serialize(this); - } - } -} diff --git a/src/settings-ui/Settings.UI.Library/VideoConferenceSettingsIPCMessage.cs b/src/settings-ui/Settings.UI.Library/VideoConferenceSettingsIPCMessage.cs deleted file mode 100644 index 1fdc7f489e33..000000000000 --- a/src/settings-ui/Settings.UI.Library/VideoConferenceSettingsIPCMessage.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace Microsoft.PowerToys.Settings.UI.Library -{ - public class VideoConferenceSettingsIPCMessage - { - [JsonPropertyName("powertoys")] - public SndVideoConferenceSettings Powertoys { get; set; } - - public VideoConferenceSettingsIPCMessage() - { - } - - public VideoConferenceSettingsIPCMessage(SndVideoConferenceSettings settings) - { - this.Powertoys = settings; - } - - public string ToJsonString() - { - return JsonSerializer.Serialize(this); - } - } -} diff --git a/src/settings-ui/Settings.UI.Library/ZoomItProperties.cs b/src/settings-ui/Settings.UI.Library/ZoomItProperties.cs new file mode 100644 index 000000000000..3cd756267368 --- /dev/null +++ b/src/settings-ui/Settings.UI.Library/ZoomItProperties.cs @@ -0,0 +1,107 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Text.Json.Serialization; +using Settings.UI.Library.Attributes; + +namespace Microsoft.PowerToys.Settings.UI.Library +{ + public class ZoomItProperties + { + public ZoomItProperties() + { + } + + [CmdConfigureIgnore] + public static HotkeySettings DefaultToggleKey => new HotkeySettings(false, true, false, false, '1'); // Ctrl+1 + + [CmdConfigureIgnore] + public static HotkeySettings DefaultLiveZoomToggleKey => new HotkeySettings(false, true, false, false, '4'); // Ctrl+4 + + [CmdConfigureIgnore] + public static HotkeySettings DefaultDrawToggleKey => new HotkeySettings(false, true, false, false, '2'); // Ctrl+2 + + [CmdConfigureIgnore] + public static HotkeySettings DefaultRecordToggleKey => new HotkeySettings(false, true, false, false, '5'); // Ctrl+5 + + [CmdConfigureIgnore] + public static HotkeySettings DefaultSnipToggleKey => new HotkeySettings(false, true, false, false, '6'); // Ctrl+6 + + [CmdConfigureIgnore] + public static HotkeySettings DefaultBreakTimerKey => new HotkeySettings(false, true, false, false, '3'); // Ctrl+3 + + [CmdConfigureIgnore] + public static HotkeySettings DefaultDemoTypeToggleKey => new HotkeySettings(false, true, false, false, '7'); // Ctrl+7 + + public KeyboardKeysProperty ToggleKey { get; set; } + + public KeyboardKeysProperty LiveZoomToggleKey { get; set; } + + public KeyboardKeysProperty DrawToggleKey { get; set; } + + public KeyboardKeysProperty RecordToggleKey { get; set; } + + public KeyboardKeysProperty SnipToggleKey { get; set; } + + public StringProperty PenColor { get; set; } + + public IntProperty PenWidth { get; set; } + + public StringProperty BreakPenColor { get; set; } + + public KeyboardKeysProperty BreakTimerKey { get; set; } + + public StringProperty Font { get; set; } + + public KeyboardKeysProperty DemoTypeToggleKey { get; set; } + + public StringProperty DemoTypeFile { get; set; } + + public IntProperty DemoTypeSpeedSlider { get; set; } + + public BoolProperty DemoTypeUserDrivenMode { get; set; } + + public IntProperty BreakTimeout { get; set; } + + public IntProperty BreakOpacity { get; set; } + + public BoolProperty BreakPlaySoundFile { get; set; } + + public StringProperty BreakSoundFile { get; set; } + + public BoolProperty BreakShowBackgroundFile { get; set; } + + public BoolProperty BreakBackgroundStretch { get; set; } + + public StringProperty BreakBackgroundFile { get; set; } + + public IntProperty BreakTimerPosition { get; set; } + + public BoolProperty BreakShowDesktop { get; set; } + + public BoolProperty BreakOnSecondary { get; set; } + + public IntProperty FontScale { get; set; } + + public BoolProperty ShowExpiredTime { get; set; } + + public BoolProperty ShowTrayIcon { get; set; } + + public BoolProperty AnimnateZoom { get; set; } + + public BoolProperty TelescopeZoomOut { get; set; } + + public BoolProperty SnapToGrid { get; set; } + + public IntProperty ZoominSliderLevel { get; set; } + + public IntProperty RecordFrameRate { get; set; } + + public IntProperty RecordScaling { get; set; } + + public BoolProperty CaptureAudio { get; set; } + + public StringProperty MicrophoneDeviceId { get; set; } + } +} diff --git a/src/settings-ui/Settings.UI.Library/VideoConferenceSettings.cs b/src/settings-ui/Settings.UI.Library/ZoomItSettings.cs similarity index 57% rename from src/settings-ui/Settings.UI.Library/VideoConferenceSettings.cs rename to src/settings-ui/Settings.UI.Library/ZoomItSettings.cs index c33bcdaaa6d4..db3b07f36365 100644 --- a/src/settings-ui/Settings.UI.Library/VideoConferenceSettings.cs +++ b/src/settings-ui/Settings.UI.Library/ZoomItSettings.cs @@ -1,32 +1,32 @@ -// Copyright (c) Microsoft Corporation +// Copyright (c) Microsoft Corporation // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Text.Json.Serialization; - using Microsoft.PowerToys.Settings.UI.Library.Interfaces; namespace Microsoft.PowerToys.Settings.UI.Library { - public class VideoConferenceSettings : BasePTModuleSettings, ISettingsConfig + public class ZoomItSettings : BasePTModuleSettings, ISettingsConfig { - public const string ModuleName = "Video Conference"; + public const string ModuleName = "ZoomIt"; + + [JsonPropertyName("properties")] + public ZoomItProperties Properties { get; set; } - public VideoConferenceSettings() + public ZoomItSettings() { - Version = "1"; Name = ModuleName; - Properties = new VideoConferenceConfigProperties(); + Properties = new ZoomItProperties(); + Version = "1.0"; } - [JsonPropertyName("properties")] - public VideoConferenceConfigProperties Properties { get; set; } - public string GetModuleName() { return Name; } + // This can be utilized in the future if the settings.json file is to be modified/deleted. public bool UpgradeSettingsConfiguration() { return false; diff --git a/src/settings-ui/Settings.UI/Assets/Settings/Icons/VideoConferenceMute.png b/src/settings-ui/Settings.UI/Assets/Settings/Icons/VideoConferenceMute.png deleted file mode 100644 index 22a39baf64ce97fb1b44d21c8d4e6a6db118af18..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1155 zcmV-}1bq96P)<(^q zt|FpLoj&9EAHVtPJ%GIrIFQlN(Gv`MhoYwgqrhRnoQx1`5mhjTBuUt?eqF=IXnQ<@ zh@hf~3MzuAqM-&VBmxr}QII;C#7vzriz(BlQ?NNUZ`wHL>8GCL(yMPgET1ntWR#P_ zSQ)^`-N0pDkY*^b*0O2idRDDiMwH7T&f!G77nio;Q1>;5I!DdHxLRf=+gL4SlJOn< zXZkdbIN>x({bd&ZG57F`uD;=z{SH3t(yf~}0}!rDMU+~5WLXhUr(UnqSOHNK;jG1q zAPp~#JQ9aE@ggEGDCfzgA|#UM+KC^zNapZb{{K8Wum`D$s7_RUEMf{4r{_#mitJ&;`wBB{@_xMfWt&D@0=6<1|}8RpmAG^T6Jd^4FkuO@WxB*2O#!-v1!4q3 z(n8i$o{c9E=p361w3-)pD(WfKMfpf)Ga{CX#5n0iM|$VDPD1KEXj6bOCWsL27+a_d z>U}0GC&Cno{qePoV#j!ZcHE0x5EP2OxswzlrekETO(u|XPEZZ?;02fYUX6Pg7y|@B z5+3{79G4YDdr}Fxc8^m#uDL)+JaHS@EEnkzhu^0|5P+Z<(ljMa60Eg>N|S~s6`J8( zR~$%Euh&SDGJt=kjqKR*5-@ez%$di#IPM|HM11W35|2E>hU*NRqGvEIG=buhkxqQiKrE=wOmCi2; zi|cC>GB%oGR7qXJ@TAH7f7iXJR>xcDx?Z5B=S#NjyjM@9($|MNA=Q-rfq}jE+IL?R z{lK~O15r6a;RyqK10>|0Yzx}7Vf`zWO5e`qN_kgfECYiB^bPcTa(JSh?;Y)W+R|ft zScdWSwQE-YnJ<+n7E7e{1mII(AA=qsYSz@WxV|lDWc$_^#zsfh3=R%oP$(4(E=?sg z1bQ~7RSU$rg#nYz~v0RRqL VC2A3^L%RR~002ovPDHLkV1nXQA+`Vj diff --git a/src/settings-ui/Settings.UI/Assets/Settings/Icons/ZoomIt.png b/src/settings-ui/Settings.UI/Assets/Settings/Icons/ZoomIt.png new file mode 100644 index 0000000000000000000000000000000000000000..f3c8aff3dedd15d63470179ceb827b68df75e473 GIT binary patch literal 1837 zcmV+|2h#Y7P)EX>4Tx04R}tkv&MmKpe$iQ>8_#4t9{@kfA!+MMWH?ibb$c+6t{Ym|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfc5qU3krMxx6k5c1aNLh~_a1le0HIlBs@XFKsG4P@ z6LB$@Uljwd=tl^H2qGdeQ%`0Vv+x{W_we!cF2=LG&;2e3JS*_Mt`=0!Tp@O!O;X2JxB(Q`eQV=1djtZ)<5TjKi#YCF+;~xHq<4=)GCRYWF z91EyHh2;3b|KNAGW^roLO$x<<-WS{c7y|;kK&xTf-^aGyIsyF8z?IhV*P6iWC+Urj z7Ci!nwtSMtN+!XwRcmTtEp2oCQFCi;X6t39$@-_+s;!sh)}|P~%xaaZzjJF@ zre=vF=G(-&P?Wa|h#)XQfqO69`#jI-4+8ELxNw~#+WP%>&VD=R^L)?q`3psW_FiS5{X2RQjQ&2{GfDMDK3{Q^@a5qawv?jq#-P6Ag2FCot>RDG&YO@ znbJi3BZ;o-3AD+=xY|MF{7HuD4-;!SfN4mi1mS%Q>(Vu3l&v6rVKGz59n)i@drBnY z$k8LGfO|#>H7$7+=tKDa_=(J>9hhbeDZ!Lr3I`bdn5M)u!7w4}dz!1|>xgE0CS6b0 z_4wgw%{0w~glKf~f=iEFr|`^vto_H4!ofi4+gvMtfJpXy42u>U2 zOJ9w-L@=Fulv{(6@&Y6q+oou|Y~seTX%50^R#0Z55S-Jo&@&2oQ>bP%U7w zVj@t({dkUkj&}Af4B@5Yq3wj-bEn$ov}PE_=*Z!4kmJpnFf-%GKCGb=NZ$tZjaB5@ z9h0s)Xu_b|jrq*$;LJif_A=g|KS6G+Mzz@!a=W^_=BGc$AiId?SE z-&~DUbBV5h2bly0z@~sEAcRVE?Q^6B&R_{1AS={OR_UV&xjvtdV?P{=1JcKUT3cJm z&(9x!u62io9n^~VF|+4Q?+OrLS0O|i#^YO1st<7e@JDDR%aL)F*WTVvJVSy)e!m~T z-+yD5Va2(;vNyqLE>pELqr`?whj|LV`0FMSwaK zBH5k^K*hzy_Tf?#mf~41PBBI z;}%?^yC?&+wRKb6l~erG01eiBinUTQdcMK+T_NX6 z)*+_}bKB(xto3hViVXbDB}`dFx~}(5`BMV5jtU;`X(H!R70VP0^+gpJN^)ngpuK^j z^V^U}E;^r}Q%Q&9K)sq_7#n~`fTZOUP+gQ-mlt@WKW@uw`9O8{G|0A+r+)7$EN?V4 z>u56*QsQoF^3DC_>oQNr$5si1V~}yB-ptnW-tA0xwN7TSfbUZ_tG$)10X_wC08DjZ zSkJn@UD_P|#D>z8aL_c_J`iEE5Ii53(yS`1^zEnlmI1|qX~3OQvJ`Lu5h-Z`&Svc*1kkn##Uj|N zD7`VNJU{2us3cxSIRMt8C7T`u5Cp~!5hFz;63+F bMm_A`i<%8zX5#Lb00000NkvXXu0mjf-TrA- literal 0 HcmV?d00001 diff --git a/src/settings-ui/Settings.UI/Assets/Settings/Modules/OOBE/VideoConferenceMute.png b/src/settings-ui/Settings.UI/Assets/Settings/Modules/OOBE/VideoConferenceMute.png deleted file mode 100644 index 722ee5ca1d3a214b07253bd4f2f1f02fd70515c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56878 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 JPDHLkV1in#Dck@6 diff --git a/src/settings-ui/Settings.UI/Assets/Settings/Modules/OOBE/ZoomIt.gif b/src/settings-ui/Settings.UI/Assets/Settings/Modules/OOBE/ZoomIt.gif new file mode 100644 index 0000000000000000000000000000000000000000..74c024ae8177208aa10d85a6eb818273dcd40fba GIT binary patch literal 1089718 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 z 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

G|v)>Gt{ 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

9J9^mqdn!HqhF)RKe%YKL;yh65I#d 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ș{1M!l z)|&q$ew945lT4)qN+(}<&U9Q}q_^B2stMnZlTS5B%UdO#O=q$&liCTg-AGx@;l`rl z`?gE9D59dOO>i}ANoVZajm;45r%2C}FPEk<{a`(d(v~3W%|S#)cQu9!kS|)D{Npuw z_nA07x18b*MRdt9>B9=4R0iswi{{_$Ut|As9n$UKpn&rP?S`zV?)=5|F`f-2cbKp%>~ravSQNAMioM0xGIX2 z#8y>1Qt%m&@;CJ7w1o7KqJMlSZZ!*rH*nQQ^<1YS7h$^;Ucc3aD|1X3rH3wg>VPLy zA7i}_Y;!=Etx+FT2&DI#g`ze2LEPwfWGCG=2C9ae@9^WjT1VEqm$xuBW{)176V1)i zJ`0lDzo#E{99(K`=#G>c=Z-G1=kkHkk+PB|l3ZTWgw zkkW3AjW_~d<^6a@m-DvCBIigqcRkCbyj^=;o?ear;S79W*Lz_A&$Ch>@kv+?0q5A41d{!|o@s$bTx6(xDI=*1qOf%vw5)a04d{u6~q z{OGXI#9eBQ`@XvHLwwX41z_=gMTjuCtFEZBKdNO=#W1auhOCE=pXoB{DJ#D6;%1S> zT+x1D1MnYo%LF1E!-H4PwNq`a-xyPvsq_bJeUiQnM=@dXF2b0cIJ_Sbl54scjrQI- zYQcLK{qyMJv#RswP2Q>5#2oV zBEdx~Y~p}Um9Z~Wvz^V$s3lH1zmf5Maa*p|=!8^t`rpjn6+o;--rgtk)T*;cDR$43 znf1YZKg>kV&cx%6uPM-t2J^owB9O)p_T(OCgMA^CJ$K!I8|mL@sg5}D7QCA`((yfL zRpI_z$NirT1j{LSgznOdf6BIY=N=(~bzQE_9|o8g)MhF;@3G9D|CP$JfrlXKrIi{P4qp^)^7zvPO&sqU_l zV-JN{PinJIqz{AL)SpC_GG5dyFEA#xJz1wlrrhR;1{xM&p_GNkGj5UFPR(USzfe0z zZczYR{|)1%$juGTb(TiHQ1P?>96q*yKyA9qIWPz3iu$=q_LuOj6hx8O{yo{`st@H-gi$(1ZF4_N7ka zaEVstnUfriw85q5>Q}-^nd;uG@Smbr7M~Gn)Eb=&S!vbN*~_v`1d8(uewi=d@BmJ_ z%~L(7cMIkE85Ul?7(Osv))r%Y?gc)dX>txx-d8Xwwu{w)Cb}TYc8@)OVHJ(9 zQ@1xDQat~-Emhe9Q11}d2Xsg)nqTkut2d6@ehc#r5Wkap#}nOTY@=i}{kkVgPo-T{ zA0=l|&igcb_y$8{BwYyP(RTtJlf*&UMv1!{{51|4K5!qV3L!xk3-4&{&X$p_AIP$Q-BtbIm>R`kckfPTFv=o93b#>P@NeQSV@ee9jFJyRo_v5;vLxIY3o)z=ug!oF9??k`E7Y@FsPGub!wHa~QwL$c2!z)M$6)*sNM@3-VP=xi9 zI}#J0-|n;54V3{$bFMZY)$pZC?Nrl~92$)-N)J6#_JAX-%j+D3twq1icx3~qw~daE z$KW53zmyfylS#v8;V`x8-vr1JG+u3U_DeeGp6Q^|)iKVG53X_0$wmoTtD&Z4$Szz!RdHnA z=HLriwoL?3xp_=R*QM+L#J&TlSUz##u;)X7xO9a8x4Z%WUb@3IjGAAlH>&b*94n}S zvjL)=mzO04>NCmMrrALk)pYXHJHdrl||HDy~1$6Zqy*Gd*S`rA{R|XPi|xaJL_9 zK6xOQ>uR;;Vj{M3Lz(z;m(njj-J2>e#~|0NM$^81u96JBeV2luGWwbDnsnkGvXKUF ze^j$Rr`$(EN%4EXw3~EWQ7HJTfW#RCKz0(;Lg|p)73U5>$OtI}4fj)L6400bXc)+J zWW`$v{I;ILFC8>12mGfJ*HvfI0Uo}uTCkhIMSYjqFTpb`QhwY+lUp}=mXd>P7G>>C z9@`{6T|x!w)eI`UkdWPC%kR0MAYyqIm3L7r8e^pAM;O;>tP{Z>ES^5>iyB&ZOt#00 zYs;htvnTUu?#&5qet)yHB|kpyB8A?c`;I1I7Y@H+4%WQ3I3)l+HS%BUz%Qk_2^N#K z`JyL%+MleyNRKgVqJ6p4JIV|VAk>9thh3Q|{i1%s>~h+}kC_LW{~53L%(?Z?t==a% z%zqI!%c{|XqW^Kq-|iu#Ff|*_Quw3Qobjn2S9V0W{bhE2omB+zP1`HTQd&%bnX5D|5umvGHaVMwuaX> zY5>K$z{BScV%ODPKPc{%2;Ns(&Ks7iltA!^C2XmU#)0><#M|mJ8=GUmde8kU)RG!$ zv3{z}aWM-%8*swy(MpyKx;$nCX^{2StKaOc@FVcOJi;L=N~{@+tFL^q!K{w>UR9!1^E&^k1O9I5~KY_-ykM-T3n4RT21GUrFk+Jge)h`3D@H z;}RAt<;MlI5MR3qhBS5kC;8)d_*uqJ=PwRq1z)fKvpN{A+utSxy#9cM z`Kis}{;dIpmbcX=hb5!=3oEcg8=o;LKk6PosvKB;i|vYpH6sF|(vw$m(wfeh zC2Z59Tu6&@*lBd{OWduhmg&PL<3F#cmLA9r+rNqN#6NgxRf4o4sji^ad`R>&BQjjl z>*zNYr{g?M5j*vcCD|V}P}Mx*wGBZ#e3w3PJ>FclcVWC%T1((^>=Wuq98hHr^R9Yb z2JJ$Szup^D;&ROGWWnVZ`TkDBkW;_DpHGoJ^7Yt-LJmhP3eWZ8N9hmN6!3*98a;DCtMPAV4EJi%2c~J%T9bU08o)&lx%C09iE`oG8v2X1kKSKPSaY%~jLFe?ZqkTH&n~VVMo{(t?<&L3_&v1=68dzk#{pW4$ED_#t-k#lj(&a9s+sF$?LuBTVeZ%;VU z;;q-x^V8Thqq)_Hy&Pw%!|(0ae(xefaFx->8j2J5zmx=jXL14M^c~{a*YCR91g6)M zK|8vve|21=h)3w-LnDksZd#k~AlzF}oUN&rT`(SDJiA+VyF9_Z<=0KvIqli6l;N8) ziO_Mv$o6Ny`ZIHTd-tj9f=D(_89T@OOKc1DgVe>*^5H!MWv0o$0d%tbIjpK~CivSR zrN4{0MwvPL-lFVMK#wh|+ zxtA29forx~zPzdXtSn6FRw*#)?|NNBP9eu!+bm-9 ziGGoiy9l4X=`!l9=6}d4agga2)M`Orp$bPt{)A*3ag~+*PV3191&gSZIk|C+eYL&D z{coVrJgbhouaWWmag>JhG&Id~7-@Fc2HqqbtRKs>sQ!2L`bYCHJ)B9z74k`0_x<&j zXS1f?`RgV`=Wu4}flHTAxZ3(sAAQ2}T20$7%YKfUN0FlQTKb(llbtSuO8aJ;g^jZ- zrEjR0res-lg#*%ICKDUdtH#z^;i1l&I@!|JQ}KuhrNYN0^5dXA70wr({$^{HFz$Gw zl+J4{7EM2DzNDG2ZKx7DDa1tcwe^+ky$EX%rKruT$f(|#Ct8Q>Uoau+v-x$G$0jA- zHcf-4-Q^8aB+w0t94f1_f51gw)wNMX9dxUVv1Op5;^h)*wcYaL<#Fk};#;bm&2?k> z>oe_k{| zZZ@40Sasyz6t{*3O;`l0>z-=hqyK46;-=toA-T z$AAr_>{_{LMbP!c9;TC)aurpV7BR`w)h4O|XQ_3$qRDKTR=nSOeC@`w!R+Gf=%J6f zen179b;Me)>CH#!-=%GZ?zqRcn`L|2?MCWn0OXJD1=_d$?vkdocHc!jdH?OPYwDdH z3&wU0QR`>F-X-_WPEth@;2$_($^GZccmvIEgK`m@-2+-?tI8%QNAkuc+0T}N)8~WZ zlEwpLYdRm$BqyeD%3VcuY}@py4!+JA_Vue?W$@rbr}>^^B{hHsnh{R-!|gHi;jIX$ z`a`P`yTASLrbpntqAp6daua{V?=LmFfvusNFU++{UT;e1c=lUQ&P@5}`uE!<`vHaC z?59Vp4^g$3a8Ib3V<@1v3(ZNx*TV!s~PRA zW^!S6l3Ic&`l5X)lEIff;MnV1(43>z3egV=Hx7GVlO?6<;$d&Q`Q&{^Lv8mf_8~#o zMQ=flrf28n!d9M@ECQNTsGge!H#p5Jx&PBA2y7XG$ybT?}W?Z>MNV5g#kcQtoFNT+wmWljJBz@r07SvQK=I0+?Y>KQelOmtP&WySNu}FckXx z16dT2Zey+It)rvs((S_;k_#TSM|jq{_Plk+1-O*`m*>}aze@*LowDa!-XP{7G1s<= zAt?n|bXEFx4X=(QuGgUuF`-(#jencuqapzeERXP7Wm3-_Xae*?BI0zH!kah57A@ zVF2@6mcAx3=7+?IGpn_{U3Aq3EiNhW=(9i%_5ugN;s@ENS}K*jykwBSXZmj-N9VDZ zr_>0!T(MjNQ6gx`Ox%F!Z)V3Wu3whNFb1<+2!jRFW;G_1+4pF~Hub_?Lh&(qAO2F9 zhTZxPzp9)T)$;7!r=q3*t%IDcs&3`aS;}l8jfWT?4MLdT+=Yl7pJkje^e}c&Niaq1d=n$~xj*iknIct)o;SGo-E2nLx{&G4kQ&oYTdS)VslQJ*rGgrR zb~x`YkA}r0!YF9U5pEmW#?2AsO-}X)VY`y0@ zxtQZ}{LYa{ru50H07c{Jsn1#23WrW65}vv|q{*i{Mz`e$X7s2;o$7EhXH4mEr(WH= zlQ;~pJi9B*o}@zgLs&Hh@LtTJ`Kg`f)a{3V79;fEluJn0u6)hUKXmw;xW(M&Lz6ao zfpr#*p&k>Aets7!h4UH5J1e_x>K=`b6KKc94Cf<1dV;-m`@MD2cHJ(nbU4KBo`3uj zUNH4^g>AOsH{WWJ>i#N0=j%9)V`lDFe9U2|82}j{3Ph!KKn{F@iBu})m_r#%JTUch zn9n&E#m2RZawgF-^x5DcwxqCjA5;M^HhtvRZ}WCz-r5M8>zVGIs+4EfsA zS_%mJYEQ2MD2<(Y1cT^^8z$PQMQCc0Guh_?aK3EiWd6e%OQBSu^vft6YrTCMy^nUu zGZW8U)5&6ya&+V<(9bCi^hw|H*;s5>F2tIX$Y(>-1zMtDxJi(3$ALs5Px`JkqLISV zz48fm0{Mm;3w)pGBv~A$?9z(%6DBjH)2T4q#OG%9>+{*enOGFs(=j<(<_qF><}h;Q zV6vqU>Bobyfqu+p@Mi1MKjY`24cU4)ccyTyX6(GR8CQAR?a%Yv-sLhI{wLIvPPcK`Ytu5Qb(^373BkVJb zpxvhp=}CHfZ0JgdkU~ugb+2CIIlaAE4BShjK5fgT_Sebhd&4B*(6dx|bvosiq3pak z>KJI}5GYlDX&~LOkb@%>Uj}%(QVzJnHsLLLE_mw%>C^(r!>(!elei$N9kBzNR{$v= zaZ|+^2h(34u7@}h6Wc&I5se7x{sK=}%e!*WqOdH|gn9EZPDjt+aVFiVxk34u07mpt z(Qm2T0)A{eF#J>3QmsJpC${(iUCMvJ;MfxE9U|g_p-L%}oJ z^53G9bQ8fI;v-lJ6?Ig&JQ)N`kU;t|)XHLlB8m+vc;O>#NKY;@Vi3@2qVh!`nMoa9 zd;4D|b*=u=Ig=b-q03hT@ZClUxmLL1B2^CFMQk3D$(c!|>#GJwiwiwaKdQ51lC%C% z#2QbIt*x3*-%RJhiQ4jbb7eDa=^7r`O8~;AIQxqqzQY;?C_P^_wh+T5LQh~zXt@+H zKL0SsMHHAKg(RiWzo?1PIwx6TM2W@iq{tflBO^cEG4r^5S@C#F!`fKl1u0EWP&Tn$ z^U*3~zD#=7$1!3S-OdANU}L^q#=eoZ2{nn%%tD|5iuQGgp(QQ90VIm6=FULenuM-- zkh_OqUwC?)MoK_5A`@%8s|&^h?)=9Boo+CWkKGz#8~m$-0~sV7%j%((bn_xozkW&{ zX!BD-i55?BI*3ls-6qe3Yz}NXeO6e(k_Zz&9=?Nzk&^9G;GrNv{iE&YRsaVZ=H@tb zKISI7?k!h{>At@0kWr*&y{T(LIgMmLkVo&=hwLVpzo5!Rj+!I%?T`s?Y7A6FCIG}k zu6^eh1Py8_Rp4C1{!fZ*Bxu9_O<01rkb>>P4L_`%zrH_)2x@ zl6)|hPg0|6%l)Jxdn6EzM5*>H#55Ic2~eu9BT=Ox2dJ<$Vo-}8_AWq7cFHaaklYX{ zt|FpGj5`X@{{TwG+K2u>)B1<)IsQ1Wm!V|BK;5Sz$`lbIJ{DyJSh)h%5ChkIss)9s zz2()gnCR3$r8C@Vysg=HL#CB?C=9tjsbVpbE&rn?CtOddxx5^5ZUB8?SJ1P%5=m{W zQU%6M*ElU}tb^!!yzb|s0IVn}O=s+IdLV;Iv(&HGNv9$(vw6jErJq@lWMAM-cO6sa zw(Gk%4;wMlBW`~`JB!aW7%NLM?wBe7;U@tJ8qj9P@Yza^2D?n|6Ft^Op#dJAsrhMo zT_l4pS8@UFBOcPxsKe*^Ew7}Iw53PDreg)eT}x?c6|eZzKw@X$N`kSaa4o9Naof(R!t5#$`8rh0v-U`MUdSH($CNxrmA(1&p>kzl z3Q@{LxPOYF^o4k&Q;>U!D%B)`$Vr!Ch9+Fb8lI!dPyr^%02!|{HciZe;GNi?byg0= zF_A-F4i>10x_e&HhzzVheFo>Sh#E2d(Je&xKSu<@_R?cv3+0n~`{iAlz%z6iHt0PC zs6vdEnWQ2n1t?XaLj7RD1@>`boiE20(ZRdg@zh7NZr}6Om=w05ChoN9ik3m26uzZAr%{bU2i`+G?E2AQ|R73kJf~lmHud)r;dtIG`#%=OvDjjFpr1)mNQOQV=({E^^MY2>8Jgi1uMym=h>)mY>xfE z+&#zNdd+_WKNckELjq(er)G~gY~)B-bny*$U>5}U7LSd{=*ylWl2*=8H-lR7zWHsu+3n7-@``PXP;7g1nSi`Z${9E z#MP7%ZMjv+c!NN@rcJbD8+GpJW(2lh;%Kn_G%Wn7@mC2KjVqvv*>LYOsE3vZ=@mvn z1RLtUsGl=%5si_<*S5!|43}FOs5Xd)Eu;g4Yw09?C+d~W3H{U0xn8@2oQ&lb2jJYe zI1W*2QGi*YN~y1VxN;sV$J`I%`G1j6e3w>M4^Sf4{SW1(?&$H*?hyfcMA7nM{y6++ z9_g`M>m~S>fL(pLvU~!3QdiM6TzJCMrRYJC*UtD`UcU0zyc#hsNw&9su=epKVksRs zy;X&gsZ;ENm_&OfRIayPSw$<^1I#GV3M&$DqYZFzmNZTKn;u-{A2!+|HfmwF z*OEY?JWPc(i0Ns&JvwZ24r?29p4wER)=g3~ipRCssn`pr6@i3@)EwQ|xb4eYccX_y z`U`4z>*CLDv%JfYU(B-k*m60Lp>AO0=P|A3rQYD?plV<|g4a<^2goDqkWumO386;> z4VN41yV} zMhVgC<&p~vk7^|lYl4J^vsNQ6NI!|3F{@*qizy-@x(6F4XoY9$R#%^?#4x1iuqegI zDHTVQW^HE~b4o;-KC_5nMnC$e{p`fz-gE3&$uT!I`B;+} z#NWB>uWaxV9&y6Cbsv11hly7zh>lh^w&<@~2Yq;4ex<+mA`f)KWTYjv+kgEhJBi(2-m=r7b8ZHUvS)m-g(*SBPF<}LwJG{Q79xW5 zhq9zr#!w2XlQSE{0Yh7*d@m-3Z#1EmS13H-2r0u zRI7hP0W+v=0ld0Jl<(JgK)8!pkwBdA80tM?b9+S1Ct}R=8-~C>_lTxt;-s2Vqox|2 z4eP_uNosT4p!1jIwzB*tKEax@q~!sMWq=XaNi{Y}9;q!YIwz5|^byuRfPQT7!>7`2 zDg(#z8#!J_0>qw*&60dbB*OQ8iENLb1dP93N;$4AH^+mg{n^{Ic;F&?%(L5grY=56 zSBa=y-0@ngZL!LID|Su27KEhyXwu1(Kul*TT)tzBm{))Tr1{wW-$uaZPj=rY!_HHim=2exYb%#Av|#nF=3`!CR!Ts; zC7+?jji$j!WX)_X`00B|48<>Erk5mI*HV-KDw>7&QU`IH{@9_@{NCT*@4xOLSd%kG zni-wY0(?r8o6h?uZ*CnKBC6yM=lH5xr(lXOBKO0u_%zrAhOoH z;!|h(iq$Pc^1d`isJurTM0@aIDNK3Ar!10$I!FhE#^k54%eh ziQ`PS1VcfX7V4Y1oPH@|xw>BGw6*4SS1(ojprgmXtCgvl2js0(h1HizDvecp30;0F zTiPG$4@mXues5XOXAusIjNvHpxu0lfmK1%f2ys()Pc5A_d;nLsr2lg$-g;B8C>o%Q zy4^5e{-7-iyZ7%%WZLTd-{_lPUY%%n!e^M|9i33PR`ROln)iF(xfa(j`Uq|4^3L`+ zk9|Q(o*0wLk!Ve|{g8%7iK3@XzJ!LgQc*V2GAo*I&_`}~mO^oqr;62GZI*jN9LD$1 z%x6$_DrOfm$6!9=Snb{$MZpsq3=Z>w#p@Bt3lvIZwzpoQNhuJOXaz(tUsM~!QkJ>a z_qBuOh)O8?m9=4oJX`40Nzw1n^QoWGk3KZc<*mCStmdd7Y4b+vFsDCVZl=<3tO{kr z?@i__IUew6hR-X5wfBd$+r*w96%c*Oh{?$_K{Hh2Nyiw!%)FCsa3<>iJps^MJ{i`;$O~ zNudFWFw7X;>2IAvy8mFISxTjKaF$HIN>=aMedJ%@ zxNo&q7yYeF63^(>>7{QtU4(u_lB7AFb>2K<3VbvPju9(XsL+&TpPbG3`$lFdCR2vZ z58iE*AgybNV6BYpfAIJIGc&T?(Y9$z1pmiHXH3BLYXBs1~9RGSqJTxW2WPv6`^AcsT@Z$iXWjOQRs>rH0j&X;h7{? zh^_4ZxB21utFxX;`rX((!lfhnw=ca}!@y(>d%066eTs#o*}OWW^d$RDPO2)IQwWlF z9Gu*V)aR5+n!Pr=TDSLkWCg;jF&d7~nwPoo!-O=br<4~He1o=4HDW=CJViS%B9|4X za1b^Ve73S5vGO*4+}?U~T;?ntzB2j2Tklqgr8*ggLq6P&+k(B08z>E2V>+u^PEr2J z7DfaQA@$MGe!3fN8mmH3=mtCfM)dms#Pb0Zr1FXev37Cm8$Z*K5I7K|9W5FH5 zdzD{%EP@{{dgGZ($QfZW`UY$%DJT;soKEseryou`H)9K%t+^u5w_^<^O`ath3P=j$ z66bDg@D-DFL5eJaOLUAt;m>a{lwLplWID7Kg&BnIi2xe*3vGS=j;rNyU5lQ$)2PhmrgUe*o=ImXCu5#oi*5-uFenT1n^+=pksY^MZbP}v`mJV)yE6>?XLRbIW7q`3!Tby?GQ?lJDyk_qWEII31Fdox2LP%23m@X z6t+?LO7c&Mq7Q@2>o4|6FZEYKzi+p*6I`dHauU|3JZAcyO|E2tt^8k(R_higVw8jk7JB~WHDHHJG zy<2g-zjFBspa}{UGAcC=vi)v7#Y#<4ey-NgloggoA)a*G+TyD z50wLz=^fTMYiaDazAq^F2V}c}E8dS3K2@AHaE0n-^m=RgbnlQZxpxQ~;{N1QceO&} z_HTxiBq_`>62yq(sz+VVmucvckBI+X=1;0tzd2#%O<;+%|7jP}(p~#j212a7W;nf) z81H?Q5o2au!g7qU@-_a5*0cbO6V%CF3(dZINxi`4q_RSf+o<6`pNppN#-sb=!*bnP z^Y^N4KA$?dcXvP2vjz=7p6mr1rO_gmGl$jY7a@7;bQSe(EChpF-u8V^`h`WJz5$i$ zS4QwiVYwAA8bO{+l5VOFSyku4ytyL=RH5Lvb?9Bw>sKFmAoCqf7?7j7bCH!G%i=7T zyQkhIU-S5{L~3_EB1yOSRdVu|i(4!+a+Qnvyr{N7dHAKx0_VA*87bGys&2b!GpVmS znSW9`}vL8wO5zy>7?c6vg77<(*vkl&Mh>k^3cqW-GHAYje%kJ5LF|IYRN)7U3n1&i|SvX=*iDEZ(LkJCcG5$1>aWK!!_tiKW3t{v=xpw(w96Sk#vvZm zthu^lslViZ>t`fRLMW3UOM*DX?DX`p)6XtvXl}|xWSLp7fvhG$+YBIyM0hPRu02bN z$A#w%Ktl(PM_1}Oh=Zjj#lXFkbi8T_8n%B;#)(G`C7wQXGvoTrW7Cz8m2aRhdbRS{LSmh)f)MA{vUgH-PiR0$B&*RqeqVzjM3>pVw8-O zmQX+hqyffZ4nx&JW>T>El=M3!AHoE3J54tV-81{9Tx6T=|MvpxL8a z9TOW75yp{so%SkSQF&tNz?aXZ)p;`8XMsMiX|8MF2ID*%2IwybnD{CxpDK&JQe_bb zG;_;4K0$7Gtr3rz{B*qO{h+hXQ7ArQzzr;J@{B1LmbN8aY4U%OJp zcl(5`dT!tE+?UsBpRXZxX+U3)-y8L+XH!L8So2LU%=B;3;7AM_l&iG{65j#8w6yrN zUEP)^EFDd2BNh(&6u;_}1>T8$nJ0YR+C}YmhO{Hqpal3b&uiAEI9}A>Db?YHSk_A- z$nj3>qgvUsov|YMMru>C)3%XLG7WD-n)SCxhfJQrQk=GmLkKQhvK4SJu zw0u+ihELhG1R83jxy-wclz|(21)5bVPWWRE?x}B$uER>R8$OlXik-b(^joE;y#Cx< z>DEP%4ThX!LbjLz8KV3rI%T8gRCFgnkNR7cDPCUvDpvqa#~MJ6^){7Fpci7<)pO$S zUM9q!y6soq@G9^2p-S_(cbk_7NR1#o^DFZnNmHIIY_ivE!UB13RG<2zF8?;GCK&0E zs;P^kY7>BKWMMVTC7m^uS+L%ggasCVN8PLS-=Yh~O0rtI=~z#!KX>t-x9neO`a*P- zc2V8n{^ba=!x2`a!iSK#v8$4nS5k%5u&B)IBO!L@u0$#`uIP8574_J^gfJ|XPuuDN z?x4^8jhcKNW*JAdE4tgugsd{27^=7n!U7^Vt4yuV3PAwV+A z{XErzc(1~-I}X5Phu^M{j^Vq{un$$PJa_ujZdO1>4c59DY3$SY>T;ZQJGrG{_Ls`> z#oOO1dfL2YHyb^lkm@>H`YImT8Qn3eM)x^Zuw~OSkeK*^!*9_W8vd&a8jk%(u-uIb z9(D2Y`O~!z6=H4tyz7WD%1}_9!XZ*Jng-`@6MEeJJkt<(*k`G6zq*T|znI}<#JpwI z`D{8b`1ioy#x5)An2Q@(n+eR*jt>qY z<_i02t!{f}JP0;v6g(I>xpY}d_c&tOPOGwx6Wxz8Z8*t)@1IOJhAwN~*>USzpE2JA zzf*XSW^dq!eypfV$K(U+#WC;Yk5|H-}v>yEdb(MBcJQCG-^k7kXzyd!| zl-Q@yk_SJG)+sVVDD(z&>VB-~RY@A&xy=TWtS6AxE`1j;$1{&^^2I183O8mMdL>X5 zvyc-t0iTYCACqo0^}=~m-c`X38iY%VdiI^cbhHDD*E zeJ{ZGzFCGBRJ-HiV_E)|CZo!pqB8cx6(#?v*I71Za}O>wd>a@&?R!Z@zepQLHT)6% zs&(#s#vJZZ-E_>$LAAzLl>z!UT1?GZW(l%S&<{+uoZg8dB}hLDMs_R9+*e(8i7)SNUmtFV&9nlZG5*v=A0nMk zP1*2wxyyDhXf0*6K38j7AU|1pQ1#@y--7zZXW~wEks8Z6+Dq{((6(EJcm>Q!lpul0g%=nS0iZ4z>}A?+Supjvm}?f@lVnQ*Pa$$ zc#2zURBx#aO1)dv1~jAv#2)rVC#_aoSUjw%i_#b|@Lp~IyLelA)=Hqx>4Qqk;Tk-7 z&A9z7#buP?_y#Zgggaol6S*KJu;$yZ)zRN5Yd!CMUeh|c?h$g)^w`34%?-2}t77`; z(X2~f{yYQzjdIKx7d~vewX*7*)69N3GCuTj#N}PJc9-7ra%6%m%5`4%@4Jh~woblr z8Od65eDZz}dGX|KHR;<>8fuemfzIJV%J%&uEqUb23Aq_=AM+ND*=mO3sSjT29IPsnH_r7gwy z&39hfjXZ42y8keANBn*Eo3=L}pjEq1ksp<1o*yG3p&SSMeos1ohw`9Z(X9>DWtF>w z52ym45(eKB2ki`#-!=v8Za=l-3Ed`;wxt4=4}KvPjtyIUUU=`i({X+Wl(F+J=dJyy z?2OK2z?nBl|M|Z5-TC%~WkJR6nQzPb>#New4QM?J|F(WT=o0_(Wp1!*{nj#%dHa0( zC+O$TPM7zDp8Yrgexb_sr0X;tea_yaeO`O?_eX!_nuqIG)!f~(&&w_k*JMxpQfB{z zc6|2jcq?(_`$hk`A@i?EI!*G=ei=XA6srDp@9+CWp>qtxb@}d;bjNU2 zIxOO?PIZry(J%kRpSac4A^sKB+#f)T-)B0$sXbe(Jh8o9F_edGRD1CIdenb<4}QMU z*_&TZxMA^qOK>&N<)euI_lko*5tqLeUjEwtbSb8KC;4pW)rVi3&URj~IGDJ6AoO&p z?fns<2|u;Nq$F1?mz$k!}0#BbDvqm{g2~yMvT;0Q=vk7{}0FOm9(I1 zXO%9(ouKp^vpGeQ5l?u$4_9(5k~ytoCiQ=FyrVw(p)M5B>;FH;`~OLfx8mxr(-Cz= zaU71f=a+BP-4}6ZF5Un6>kQ|T@io7gM+X1-#m=9)<{!6o^*{gkw?)?i5gvoWqd9(7U}HgoC2OETxgSdZJj0NVSjy#rq;f%+*B=xNl{+drid}$szAg%?1+hl z?%?y3Y(}2S{V;aPGeO75o{7YDe6~ebDT*bTk&upkL$$rcJfRR) zc6}@FS$%=K9`_ba%NMVpl$&!2dv)o=?qpDk2N1dUNnztb9Z|3YnOZ3I-lx7xX5xnF zC$^>R#t+E1gWzF{E&vY~Itc8^g#vJT6wG5c#2L*tlJRt1Df`g~Q3^_6Pjz6%__0Fg zLFzCpMn9*jHEzeW+}dM?^sMGYG}|7)=fS-Hxh*QW?_d&a9S6+q$qmt^q+5xFgHR&t z@)oQiwou$2NY5=;tZCauwtR*pP0%43+9>e3;(>p&pP-Hz*ND5v55w}?DeyYtgzF4L zR4@;Aq195L_0_lpozCehBMR)Q-Tymb<%lR@Xd=NIpG9m3jiTDIM0|VK@c25@DFh5Tl!J)AITXd{OjwI%8}Chw)`W zj-&-|aKa#BtYC_i4zPwj5!9V(M*xi!sVsuKBw~tC_}6k9Ur)rZ(de@k~7qZ zg4qvmh!5i$tm6~u#ip@fAm-i>2hzS8~5-TY&Eei9x zpaMPS)+6Gw-w^#i!*5qsfF~7^65tP5@oXiDW#g>G6z#`ZyGNh~c%n=?7uAVIN{>PT zc})%58e%ozK z!!4Qz0}pCZzciWQy#h8-!zTRvJ1MDuD+Suc zJ3H_xn%@q2-IZ#2gnsmn3H<{4^p*;+vl*Y1H}-(WFIh_~QAC7Xji+JdQm1v4qKuAi zpBd7Y;jGsRgI94}VrP9>Dvw>8h|MDgVshR6$=H_}-8U z+%s+C^?Xh=>1E&qZ);4EWe^M#KRv$L5yK7Ns6+JJ`6wIJE~#X ztqBva2NCN)RzR{%TDublBoinvGir&!H#<%O|Fi(OWF8pCq@$ND)aC&AgNL4O!^i3j zRc%<$j4MyEorszyM8=R_8rD?EQB@*>WS(|QwWU*xAzzrNl1dz$`fVn?2B=klQH=pn zAM}hu0T?X!^CR$4mYx(!dK55V)?I10W-S&$)Pym-)4J0gD-j4A&-1O)`xYY=4|obS z&Cid%-G;qXkW)C2{d>Jy>myzK007k=u-k8zowI$Z3u^X0hBjc6k{LMFtdyjO%aF}Yr2*8jtu~d| z+}|)Uk>(ALQv4FAPLzefYfS_j5ouVZK;kP=G9pC%SSDI+*r@ug(cYg%dB3T;ESm<| z&cCM0#tG*4z7C9$>`Btqkpqt3@GyLa?3aW`LRg{*6RlZ3di_vVM~rNGVMt}4Th{6* zzP0VuE)dC3M`mK^A4r^Pwl)o-Na>hj0rmv&o&;+8CWh0ic)Zv2aoO`bxI=Dgl3t!O z?oyQVgjnv11E`qXZ62?>lhkyx)YY(*Bsxq~UQ-((H|x_#$~53ndfOuVqiN4at6;Mh z>>BChFwoE*94+0cgHqFa^n|eKQtwP;J%3oAS-Tpm1~`;`KN*8 z&N(#DgkJIJPK5`n!ksH+AkTq+OGehTO=TN+yI-qiSVL(WFuu*lW8zEFN(1eKpL51p zCUD@)cS9NbGIf;x;|vgD-?aYmJ;ahBQ>j@HP10#@;})OFi<0N9ylwJAaIBMfV_MmN z<%R!WZbNt)5LA`8OO&UbJgU~{w@cDOlqZ^`%exWfP$U&DQ1aXW; zf74Brmr1^II!bz2uOU$xC~mJr!pb6W(~=BDqmWKFu_G>y1M+a&ye@$Fnzzh0pq`j! zmQi#4Z#IF8OW`*d!p+6Of4MmLZ^-{E{wo}mm5JaEUPf4>CUV5BGh`jQ>Zb~LBAflD z^2bMWW!s)0A$}C)=-hQB&B8} zg?BNduQ6?QL+!(AOvpq)i@}BHHN~&fEaJfR@7YlQdV9csDLXfhcyuoa%=P_O+ukO@ zmK`kmus&k=?*-o7+D@SK=>6pC++L>BIxh8n{j=4YpZ{9Se+uzar!XtT`Jta=0lq<1 z_joS5X1Dm^9i<9Of8hwp%UTRKYXJ+2JtcCbY_o{+fXw%ziQW*m4Gghb1zL*rZ z)CoAXnj$`Rd@h^YGS2JT^`03L+3fK9h=?a1Kt%*<4bgl%1i(S(w0z6z0^8am{Bn49 z;!vL23_4lRMvFKm5t2q6OS7VO&!*d1{u0jeym-3I-uqkk`{Z~uWrR-d#cZE6;4R#a zPw<#h%Y}aptFw=l2=zV_-{WS*BhSErCBhiO+{i?IAg@;6UJNf%(bc}DnC8eX-YUr+ z-1luAeX-kYhi||Go0OlUAd-=3j>pku1OKCfLxb%C6xGKh<8X%cCy&qFl889j5Bx*- zx-ncX(Y7RKqb8_T$)HGC`^QRq`0J{C8Tjs7a`IlHRlQ`-S%a-FmHx<{n$wSjhiqk& z`12=~>CGf34g-9}S${eHy9n;C}3$CyKDkP}v_@nSX8+zlS=hhqjZ|%aLuIbNVG;Es%wf1OsDva(&6?tKC%|BoI z%EZpj_39{ndf|61?dnUvYX7*`=c-+hLwcMYG_v`d2*)7yseEek?+5$SGm{UnEA}md z+DN?xMeD28QUlDZdu$@7}n|e{1!0w+q#C zQ+ngB-L}5qxqlct)rq9}&oSqIeI^S&{4e>Pg$e)30l_b0GbZgk>dJ>@W|dNh-=BM5 z{wp+`cxjLR5ysB!jFZ0@EFpGnaUCkMG9BhSP!o59@PCa zVSgWgXYyZP31!QE<}DE@Imv<~ZxiM9Jb#3ak|a=H{LRUZm0o0K#(-RSwJbjEk%v>j7;`mH;t)H6ew#}5GX;6 zs63rXcTTDmv8@?(kF|o^m%1j@cZu~u(1_)Q)!$sHg5RrhZ+spRX0EB~=+uBID;Z}u zdfzjxH#cMs?k{gm-!r<*BwbkqA?3YtaqN150Zrw)_3*U+t_mAuJ5RV!b z1{&2lPX`n$YA@A?7Y2IRFLTaBLCamm-AUp4)ecW09Sh2tVo>!i0$FTf&B9%M0l`0; z?uQzYNm5)j`88yrf9IV$o+6O!EbKRx8Sc+39Pg_I>+pO^8}M z4b9Fk{5XmdsHZRJ*Eu}OcsW-*ZwA#Pu)i zWDS+Le|f<3dA7&qq|p%kA;DZJm?-KnDcBYDfq7aVH=82L z<*B8^AID&hU;}(_uEV zdcd~<{91aG69VFR)v#&4v>Awrn+swQr}=K7Ozomy^nZxethuP6B*{@uuzxua;;Vaw9t$wG6Uzk*nAZ^8F4ny zqWGC_dK0Hk?|o3gb!PWIe(<2)|9$c)pgO-5VtcRJ^GKrh%&AmOCpZWx%`u?kLvn9^ z`0%8ADCAPah)meyFRMCnJV)s$8^h)yK0o-<>%rOK-jq6ln2L5$P72J4Hf-dNp`EvF z(DVp}LH`43z@zyI(u$-_W?Llpir zMz0yUPY{`8>AnN1uBY@0kNg?Ex)5=H{d(NOE%xL~i+ENIGH^&-&{Z?D3~m3BuIl1x zZ!ODD%nU7&Mh-AW<$vv^njRA2WpIcN#r?ELfudAPd3|m1$1qh-=yX-Cst_apK!X*gswIYz>C|YSgh63w_#KT2E3Me zBVM^|(?xcA=WzsBQIO4M5Z}jS({>5qu1LlujNyt=tc{{1lMc}dg!0|`p7h?_=)KXu zaihzXi%{(dqmxM#vIv4CDU^c|27b_8xGg+N{bcZRYu~b%J26V$w?i%e!N!vwAEi{? zCoxvBDHdSGsw8V}ozJ)wMeGo_D}GpN4$p1vTr2}|Ij;XsCuKwZ)$z|S8Lu8f?*F(& z5Ge8S(sOZZSe99A0o(v26m?t}t1`@Y)Aa7fDF5v#|o_YA^+N2Gq zJ>HmWl(kjVc!p`llc*#GwAY(1@m)((0VX6DAM!Mn@7x;b*dCx#j~coU2*pyv z?4f-G*Q61F%i`XS$Hk;ca%?=1L`bfL`Y3Rp_)!w{{l8S2mjrn%#?S+FYwl(-gn)tx zzh~#g@P7lj5D3YN*Pi`*EXiq4AAW#mAqC>EcA@mGKp!4@91moXfm#IMF|J$#0#I;4L3ajR zM&mbz2A)QxuHS=u+Y4t95gIcf)xB6Ds$GT%LDtjf!l=&)l{7L!Z=*Bgx3^5s5aJe) zH`FLGD_$f`7w&;SE}g~~O?R^<3#+q$POR`ZYbS?iU}gl6BQ@i8n&=*TJVWB82tzHi zdtYdqE)cy3DrL&bdtV)w)ShwAHiN?wn1XNcJZErOoXU4_jaXP`R^Uul*>_$i0ucNw z`+SXIvxWt;AqMLrC!@K-S z)7Nf>rJm-$E~3j&>Z1`OBlD-~WNU*gZSXwq5pK&IKAM#t98_c!Syt;HM+6v_$H4B| z+s&eqObJERJZbH}#a`@#-e1cp!W6{;v|n0XwTc#2=7LtSQ5gZoxriVs6J0XA)WXB( z`uj1lKVXFpk|YOtj#aOKTrF9cFX`PuIR65^4};!585`Yv{+?BS1 zgM<<)2$^~1=CA0WI;pg@6nU+$(OJe~U%7L@U(}wp&a4bfCNL<|236MtbN%@r z{Gc&B+M{avdQLID>WhaeeqF}J9VZQtUy-`y_u6O`&)c$9cQ!;B=nj&gKw7!t4OIE9 z)1Bo^bWZA>T?wj2Y$x>*pceE@Z2nDlUPZ+9(tqszs|zAl$n}ibGRZt%h2TiI%LJXr zxGX`~&*!wq=^C{&9)5)x!qe+V{-E_OLn_W*Df@Cy#A!%m^qS5@iDYG=c5ftH;g7Y< ztSGG}QID2(XD3g+Uorcefy-L0fn;6%`3il){}k|&K+d>AaKeqp0}pIHrJ(vvTrN*| z9(d#sEwQekR1A@XfA1D(O8`)Rv@Gi*TE3ds=;xoHeL<>_wJYPcYKWgTVn|mRgwy)Z0@fDN*OvTkEv<%JNrw`(B7VChAHPn zK3^j4+20f>VU+%%_i?9`Z~h4b;E{e|BfDXszJcP+M4%16w&l9E!5Pg-=?WhEiu!(Y z4Wf<>1~y3xJ`feCB0$XcUHad5>xU@@cje37M`jqev!yW6A9UO+fNCsZ9a{# zP0n>9PWk2k7AuQOBnCBYrbkNVhJXf;0k)f^!3*J#M>N)-)`;303&ur?T&`7p}P|}8FSM3m%s&{ zwxwA^A4PvjYKL+3U40hN6JJg8g<5b)o(WZc6s>mMoxCw3a4O`wqk`j{u$S0o@2PFy z9!r(gw5-$c@$kl&qoe>;8Jp)DBD5*KI=k4L-|4%;_jJ~LuSkra4h+`;IEOsCG;^W1 zPh9#;14Ch0$6IvAJjhU-t*2MFOu6Ef)MOy9^DIDL}jn za*hcD*<*%pdU<4=KH>*BV;`;55eah6hxl-Ur^Ta}Gd&(k+nj}fjx>aR0rZozAk@Qi zC1zojOTt1%jw`}vI?a&CP9=8WE=hGw!;kgoJ2j#} z7qhWCxh+k|lS2NX8J^QzpzEeb9t5ck7tDpsDvoF66L%y58aM+^(N?^+ zK9l3sYw=0P0CO%7rSWTJeQOum9{hsTnVTBFDJaL%_Bbsja*Z4!kOYNhvWg_DP^FK*`XlO zQ{NR*tW;+4`~!Qu#Vn``E5|`L?n4nYn~U$-h|_YQ(-48LXr|7gWDrVxW$Z--~tuw@Fozz6RMujhdZ-N>nE5M87^)tFDX(lF{j7 zbCA7oDh_pl`X3MkbDmPE%~UMrt6`X07vwrsJv% z=>E!h12l*Nf2&N`O{eh=5RBd@e;%gs(HY!l+^P+D&dgK*`^0+$(;!i6+$98FVMYG< zkq{27y(7r`yQ)pj3e>+Oil0?@X!XLC0hx>ACeQG65UwQ7fZr<{y%cvld%}rhJ2PoK z*Jj?oH^{!fSVKmKn=v4j`{x7IzGLsne6iU621ER`-K31M{bqG9aY^ zf(B-8(3@Ot0o6YWkMQ6528&{VQT)}N{5!f)54bETE@u%@yry(L-}5cKy+BGqOx6Px&FZ1{_(f9{Aj;9xQ2N4a)0d3Va#J%MQXG&b9(I)yYn}=#gd1{CzLmSE;<%g?uu3Y5}4G+((I%|CCVn#}Kwd=&> zZ;-&BGg{Wyw%2ZFO8&fsbqVhZ{Q6~-yIPAqSM$B`6Qb3|C%${8h78HmEehnB?~UW| z#vdm0-p27uDi5l8BrTWu-~S~Ns+S`1_x#itBf#ii;FU=6>CMO1?1N&hg`__}Q??Rp zLhF8Y{Qb-Rl98e={q^0^J*)33C3>TGK58OH=Yle@g2GCI>gQQRZnR)4S?w*&hj#F;?|r4>dzp)r>&n8Mrn>2e6#;Ywswj9p z%=o|J@9*V9VP%ng)&V?r6|%49@?X=02v)F5ic*kA9@)%$b4Nxs-#k)2}!b5IgJ891e^OBvL+;ceR9Rw^l)v7C6i z_3ejBnV()d8HQ%3uUnjoWD)gjMAbQlaQ9azGREYh)5J1u-L}wr0X0m`0T%(dr4v}h zG<`uS<&qGlI^28a(sx~{07u>WEcsY$PhCX>0RR=p1Jk*WiUe_J-17!|)k|wu)O-4F z>F-!GgV$38vZv4VoV{7#+>`D%6PaTii%;hih-Er|tCNnyuJbz$MC#~YJUO%hX0g%~ z;g&j5kP`cIf2k!l$ss{Jh9>J{W7^dR<1#^dQ?(Q^Km0nR(jP}mk)OnZivnMM^5~Q6 zae$WCJ>FJ;Uh@3A3qeG&BH4BHjY+WNrb&!KgBI2(4 zJ$)2GicW#+#BcMSlGGm#;x*id*XNC(&C@CZ^-iP147*&zU76pN-pgMwO%F*IJ+%HQ z|3g{<^7PjN@FFsncDv)p?|4gDL*)7W8XiOb9q`jo=9F&LP5KYjXT>BQy=-}t#pZQM z-+hHl>m2DnGKur))Y$p=S72iL$$OU8s`~dsXvYONsU>!kYc;o(84~Yg{`>eqvdnp* zS)mRQHy3&TWB-AmS(0YLYL{4AypoiOwdvVH+;^cLDO8y%l-0Z8;f|X>RdJs76eC#L zAXq!iEbw>g^H6vtHVe&03~W;n$=+nW9-QKuqlZ8vF4c(!^yrG2_2sh9@v~PEC|iS! z#fkKD*-gm|Fu{m4l!W39CkJO=*SLIUj=C|Czj$)JfD3l(stt%^i~@!9wuSXql%N)+ zK>6TQSrAdx6r@Ctn+zJW*@IxDiHpaJ1F6=rB#Ay4RF9_HbOZkk?nARe1qut09vn|* z<0f?N+>O1$&Ye0nLKI9RKrPca)7NbUp=e2yiv$dxlf%%}(YZVFfdJ0|R{bF_GsiXG zk=N9%^j^;Bn8X?`47*8HxE7=O=@8?&s75ym9HROd&XoR}vj2epDy4?h3gY{adl1VY zi`YlWSFoSksdFxW!j(6~2591+W`<Y^9^9cO|(R&uQET zYkaX0tXFs|Ka8UmFMrP-X$aymUGvJ13KqRHMxYpwZ1rX=am!jZGTqjzCix05^z#@+ zW6KH`-_%rBur+D#xA2Xeng)NBNs*-A02cHo$a&q}pUvl@r?*Z~Sql>T7xFZx8PQ;n zLlU%ZoudEid}vd6f(i-AiQ|nw;^C74G1&(oVC$BWeaB5{Z+*96j(5PEb~YU!pnS~N z+$JwAN6|`+hzNVADq&qPd4EDVxCR|cI9GYWY*gIQ4QN<7EVH>B3aHED(c0g-A))Y$ zt*~>Aez0X@suwXNViI&r?xJ3Hl=kA4#SNh=i>xjIlg6+CGzw^&L*jMxaJ>`^3i|yK zJ{x#JXD$#V+Anlo$nlh{>(^}Uv7a(bdyuqA-t>|&FTDH6?C#P z7CZtsavraG6WL)k2$3R}T3vp-ohKG*C^+CI$5jRP_Wukwo7%RK_BviK+DL%-G*f)_ zcD!aHLg0n`c2aS>#{9d8yKRiEbRK3T}73CgIqLuX?7Nu<->$l9JaB7l$0F z5wX~6Fz#ze{jfK#`FW;9doi@QRM|@QWZt7cZ(NH`rguCDc6PRE_*Hu5Hj!1xe&tLN zF9?!KR~mgv#?KOf>yEtvljGi*ScScLthf5Z{Pm~OE-uN^#E0QV;Zh{<3k#a6lkwn!9 z1C!tX-V?i5tE(za-vda>2|tzXOZB9$KaYut=9Z5N5(5f~AHgehv1|Ol<5r&Jo{j60 zhn{$uyfHNuqHuwX^+Su6F|gYEvdZsjfNv%4fyZrcrGMFAp|{Eyy7Gu29X_dEm1QYy zCmPhnWOi*ssLcMUugb#6F+EcR$;aw)+ap_LBuVnt zhC&2wmZ$#g{NVNllfmfD)YZtvak=Qr7*gfcq?-=8*)n)>r_Piz@G}){F1-GE7u$~MjL1EEyH;60+|*S0EuZ%wi7cA6E;5N(^}gYd ze%y~FF$FV=r}U*FyDt|Xfi*n)#l=@S{mi(}VKRsZ>&yF&{ixIKSPb8J2G|dtHTBH- zMM0*4i#$U?0{T8oPiGdK{WnmE4u={=H3iRU40C_q=}J#)XxN70>20=b_m^t*PfPYLo!-5offLMEUjvf8VH9tmS&nV zHJyC24l}8qYnheqLkJW}he=V2P1)G3MVm>o`Y#(HcgM|7RUdFZOkmS<~k8$RZ)WUGS$Y0U^72lB1S=)W|%-2uwx{ZmyjDaCPKWz~orS@9z)MF%Ff@Evw* zB%O04_K1*rDvgPSL4E8oH@8K;ca}6>$-n%6SmEsLjHBs95ghv3hR$ysv?EclX6Zig z16arBP7c(mGWB(a-PhqEX3A%#R$`b7(a-V#mt zsaDfDHoz1Mdk|!kgr!qtt>iBfQap?+PCF7s*N9j`N_L`VUk23=p2Crw9bv}jPG&y$ zG+%vd?EO(v=^!;sqx4>cUPKICV3CMql2xSW?_f|fnqhV+NgqyWRZv=r&c!T|Twxvi zaI6nOtYEl5={FY(5BQo6nmkGi^{H3c21qObIFCH}z{l8aFtWSn@DBhjC6=9*Z5P;d zkJVvHCn;h{3^PD=9#9_!c29%eBM3T$5Pddak9~nH1vRs$<X_i3G!-|?3<%H!a-d- z@J!T2Um<^Yin6!v(L*yk2QbnB8vZ-bYEH8;D6AMARv7Mwr7=8`J4he9yH z@g;yEJcaUuYU}&FgNt8ok0_r8DgX+F(!uKR%-jY2)&w(fI>gWoD7QeA+Xi$lq}_tU zd?p*Nu0b2PUgTylrD2cv|4bg5Jofq4Cb|!>iV$ILKpJL$61cWD1dE zp-)OIQUn%YPlopN&6dexEZe_4%ObGH-$=TSbfA!r#|0M;x3Fdv9|^bp)XlwAp)|4& zLbbM_0{(|EWJP>^%2^%@kY@s&FvG-*6#a-Ic2zSm-3;)BuH{Iv8EYXfje*RaU%6-3Wp*-V4(dnaI~ZF%wlGoi=(ej55Dh>y z=K=0OQWAprdiSA+C{S9N;W*zDZ4_j(zV>o6C2OZ`zFYu_133|1y`woMIYGVD1P-#v zapoz)^)F^7Q_R(0TBt2sTa>J^(S!WrbA%T4>rd}j{pT?@m z5)tN|TP%|E{b|%+Msi)ig6c@feL%H=1h>dj9G1GZ z27S@J7Mf4$ZZ4HCm+R`(#l|$RKLGRS(dCvGJ6SNK8sPLBrfb_|7LQY2GobP|QDQsX z3Nq1L-ki>^hDeIzouJpFe+07I$Z`7>?8_A z0&Dfx+bH9HT>8^hCcyCgQ^2FEv81~{0jk(S%{0s8Zh61S6aQkWvk`(P?cmREpOkYe zHJXM!aon=Lk%A=%pwpRI5dg6Wr0yGr;<5JQYe4mF*3CVZ?j(3@5A(;0>XfFAb(B$3 zkki9FVGCZ#4PkuZUD6ksgR2LE941p%mU%)MV4*-_LM=cdkbH6vYHCd5{Qgx-dn;>R zuVE>@UiL9QDaM7;3o_}Z2*f9J|5Ys2nSOr_mUI15ktmAfu@C~DDhdAc_LQZby4taa zR;9-`KVKed72PNM(a|OyouEL1FOUs8WN5laRv`rMM%Nm(EF1!*mluDQrZo6qY5jq!7z*1j=Q5mX&L#G!_{-h7GWJcZ z{=8Y8M%U!^IHjExo z7t%QoWD{1(*8^&f4iS(lova`>`wO6s0h>QZjAVECA55swvnPjPA2)fQG8e#{{U1#=@p%|QyOMt zQOgOdBuAY2y*-*N>v?SAn_{x$7@Oy+c$ofKXy$fH`qbO;F6gYVnVLJ&v+nb0xhXGKr)A?eEXdm zNCyiMHdzs*e^d3b+YS#Ael0;ny$X#W!b?d+34Iw@Z>o6j8?=*n`I2sN+yrqQp0XlF zzx}+Va^dnni9wb9FJEm+rR@O^TjMPq0GOw1pmeG$7g^M&>ZJN*|546&Ge{CFa-wBP zEL7yAMN6%L7QaK?wn@2yUo|mL64z5YrSwJ4sHOS>-R!CUY#ASkC(u zFrq!M$}&IL{pX|t$n+I#BM9Wz+;w%I8npYGL05$j(d4Z<9l^RRyICsw6C>j#|-7^&_9!VOD)Q};f-0AZyWg~EPlcM zFN)6mk?F^ezT>y%W%OPIS4+M)cQ<7XSbEtc ztd)sb0bLgOp7{=W_0=i&$wiZc6^N0ero$=YlAB~23sR&g6ja#AKo306{uFr1OHcA~ zxx7vET-7YyRWod%oW^o$%<(PmJ=Dkkr8Vm?EqUVCFE(&*$+{&39=(b2w|I8;Zga_v z2Iry+S&@xc$5jS96?-W8#LW@Bi?V^mEwYp0^|0f0jkOG!;rq@mWv7PVaX~{K7JZ;( zfW(E1RqpY)%}Q~lzZXH(;ik1dE_&N*P?(~AZ>6kyU&s4$d;tO@BW(=%G3;f8z!X|d z>bx(vzRupf>UHARc4Uot5RGYT1ZZPMy2S%tGaYWa}N`W;dNAEvH?8sWuf< zu#VtOz=)3pli~}cWF?6oa0#}cOBfYIB@Id2*(B}7Z^vo5%Nh+ht1+`~@@d+;f02Cg znL8X}lJSmDtH-S5@`(8EMbaw?Tx;BAbbs2gmtJ%)C(7H;9{G?M6}?Py+uOwaKpy>@ zH!MHj|4qsy8c{}f#@4a3F)u%_Ntux6eTGT;qV7s6Y}F~mE@oqra4a8{t4?&7!T30@ zlZMBRPmYaN_$xjmfRy4AmVgq;hYXIMza_J@*G&Cg@;DUv@F_|WPZ4KtM@>h0WBH z8*f3wWAMj^E(ZjNnWTR1^WXnWEKuWhT0^q<-v;&BxTZ~~kVLh$FaG;_$~+Dfb!y=i zbU3Fjz!dA)qdEZ}bBYV~N%BXJRENJ?7p5?uyB}6{C)$rBx#{Jh z>xabex$C@4vsfqRFVvWhqf_R*tkoRr#Qyj`+dDSvB;oTlh^WeLG=EnwNCOt3LS(A| z5+1I}{n=3t@}WJeQ_QToq^O8|C8J*9%Uy+zw6tB&9@22pN1goeLJ-@qXd7RL*OaN# zcJh5Dt^<-#(GXL-?YHY;P{Y1oA0`?etu$x0F-XbnkOpHWnhH5I|W`%bqg5CwPyFWwNz?)`>`PC8;!H9>zI11e&pJ+0m2!gx!Gzazb z_M88Drp_q4SMXU>Jm=3|DT6ITB1if_DBCfKbgKhX1yBpYKn>>!$SXOIeba~w4g=t> zqTMB-YXC3tt$cvGVlKp3mV7?c>U!+_Cu#W$&-(t&URRqDHK~!Emv<+#3BO&#J;*g@ z4vvoooYpxm*A`$>dg0q%Cojo^$EjnCL80g_7~E#tHrE1S0Js3;=LBOaC-%CK6; ztVAmAdY>u0P8eCxRbGa8MO$To%K65}JU9RaznC((GFZ>EP!tSz^wj!Y57I6RP09Cn zc%c8@HD#UVEAoApRR>*FkL7x>amI3j;s#;*=j4SZo2WH@)t*|#N@WO}eL~laADUj} z$ImhzSUz1OKBeY@)W~@G7|D*D#*nn1nDHVsI!?d0#?ruUrSBcwedo6mq6XE}Humld zdF%h`fOfS_g&4e->qQZwc5N`yb-Yn)n*!-@A3?sDTt}4`C=Fm_PxO@Agcvtcjbw%h zUKS#s4um%XXAl@^F8kHqG#XUH^RY2ax!4&Zmmga3MPt^$i5tCzbux|8_(^wl+Zk@; zqQ-GC+5^RhnttirAmdd%;FKS9BW~4&(BcyYJd6jPZJ)^j-Wls;JR;n-! zWAXHJahwncRuiYVH&G%k>{no4+Af8;r_@8U!7nw;Q_I!wm562LyTq5DxDFRis@T?*6(&-8D_138^_L5w{Zx`KL9KZ!n=gJNXr77}DRPdby zy;^XgPdfj8Ymi~gy(rzinYx~xjBORcLO!I>e+P~_x}wq{T6i#xb1jpae0Sd+57)f? z;yBM6`tK{aNHJfNHBy6YP-{EcY`^*gRA((|do$I)VXlp|%J+L;(|oW6(-xbyigpoU=kwXILWb zU-2nx5cdI@A{{>S>QfoPbQ5|-QKHN*K3sQ#QV zmRPn6(e0II6(OV+?l2D%FG*W+-4So&vTbj7%e}Kr%7v%z;@sCV&zhK~BX>CLmv=3& zcksdh!_UBek>RMSI2pn@W7+vZUt6+cp6ohj%z<;kxZBR)^PbVrEHKZDGu4!didp=t z92NFd1q!LVaQGiRnuvBgtbM@GC4K%so%2g?A6j5I2G_+dK4HQ}qFoLmx%meBhsp!T zvaR;j3E_2$%Hzbsj&?EIayjY-vDo*OS$@eV)ZvZf}+EdBRD^teb{+9EiQ3 z(?{u*eF0qBx|%&mn0b+2m)s{RVPPX&b;k}N8xewE4cr!IyD^NO2|U61bPqHe}fg^lb!#oE-=jr$K=XP2iNgM;OrtB{k^r z2az@BC+QbUW>Qg7d=V99yOY- z-v~t(Jdxeg4}3>pKUg!CGZMe&lT(Qqe4=jes^^gQp|M7t&>@{5I(D@n^>3Cz%Dxm; zh$5Blg$tvH0@SvzNUzSeiYVWt?SEVAlFbL>*xH`UYo5{XjzrV3{O5us!DDd_b*Uqq zA^w1v?u4VzTs0L^D_-fKbv8Fe)fX03zAvf%t$zcK2+Do@3VT2pKM~*H!0~~UWzlv< z5N?F#__^qbDe~zdFCA&fvxhl4;eK&ZYLzLPl*MI-?AP;d#rmv63vJ6Dy>)k^JpI>6 zMuQ;SZpf*3%b~7X&fA{&U#}18%+&rJK1I1CXcTT&;48bsE#B#R`)EB22(xvSt^T&3 zX;j_P7uiT9er#O1ga9R2Ufku|(!jpb^b5E#sh$d`$dxP*x+!&vhYUl}Cc+hX5E{4c zGAp^d=~gOX6kxI8REwE>!zgm?5mAhyAJWkQ+=IIBf|Vw|6$A^2dtolNd*p#HN1o2F zzD{$pKs!~2>6>XgnMK8!tvluY2AZvENbm{DX;ZV>M>zV7S19O(b}bqHYR934Um~vl z?=A%@iHAlLajIF?LhzSQla;Cyu6PJTm3W{3;NqCugYlTjlkN=x7n=_^#$25txJpZJ*m=9AEU|%h1%9(I+v^xJQLW z45hQij`EF;3L{)~3%a%{K%FhBGE;x`pHs4*>WRVX`8(FB~o(EFB{)1 z8g%Ey)(GK;v(o`ILPZQ)$9=!5wjQCq&hdOA!S-ZUh$!vol_@Eac8|WQ;N+Bt<^JyY z*nP!HsJ@DSdgtUs>E}Q6O9kb9LB69B8<3iw>?D(vbwHSa308 zQ1mhfKEF>>5iv0~l0cr&$I0Zf3nX_$E(NzckQ4dK*iGeUzDE*mjY78kbXaxNws$1u z6yiSCh;P}j(9(|Q0I=G^+Aa;0v>>&F5YnC_#EwG!bbdD<--_>i9-(8+ASy7TKC_qN zaE3l`Xr+`^Wu&exs2YA2qL?V{zv zIi3gj&bco&Pnn@lZN1LlUxhaiAl9A7p!k=j#!@is6Nk@5YOjNE_{;U;(|#Y0*>sY; z?!2*!pdoj?eGKW`b?HhjQZ(=2#rHaij|-k5*AYVJci@jp`%6oo4^n1Zl|~=7u4-SE zSc_Fn==fqFsTfLcbzeogj$YyyYN!GW`d4fz!<#7Yq4d>AaN*<_tw$~KdN*VjmZa8l z9Qxc;|5Oe>fC#mup_wmU?dg&hD|lsGhUUhRmM8oQDRu5kb;)w&_$pbZqv|48eM7Xn zTU4Pq87PcA|winFJ zJo%@r5+1Mohaz6r{T>R0-O-NxDozi!ncp`CNw|={DFh4;Hswp zaN2LI^S!PwjnASdp{^m?kFKTDDCgn~QzMpbYbYm?0FGu+bL$+ZJR&X3$X$D5asYX{ z|3-gn%)S6Ak>{Q_LEVU!*CuyB?jmb*u`m7E-pZ>=``dFQQc439Ba#Bl5AisMf;PRY zskWk1KwpUR`i4YiXc;YOpjq|^V>6;cwyN(yVEv|P8s7di*1jC%-X<=+!I4)4;FvG; zvU>JMLu@GmVDqh@;@_gH`H3lvL?pfP9=RMCTm%n6a&tGws38p}53`{E zTb=0|Y4odobhu4Hi)fa_Uebx#PSgSC8_i5t?ooHco9~w1i0~Indo_qxhX3s!VyM8$ z0!PgND{JQQXMAvTAQSXz)uA!#pizvsT?^FX^}Q=8sWl3>d%f@fSTIFc8VR6&dCRAM zEcj^|NeQk>t@H$S3+L9GFCVGF5v*Iw%Ykn-WimTH@QBKM&Lg*Q7b8c_3DfuOo>spNYs+R?r(z8zqYVWB*Ct!jRp7ZuQ=5u4&3=-%iurGEKH} zuDX1Bg~4&UCJ@IKX4zM@*h6_|yDuqSja@1GA-XjNaW@yNV+4ntaPNKI@aj+lc zj?DTNpK+NezbW{kW}z8P0pb>Ecg93jsApA+?fQ$(_UHZSYvH1dnq{ZElpYEeR^k=C z$Dj2eM6utZjI%~+m$%Zct#sYnr`ngFm@fuv6oIi{T^(t$FaV3r-VR>)>Fc9dz3uwN za;WQUtgaF5%S+CfKx8~~=kV!)iOhlVPsg_T9OMi)Sf_t!%*Yz#q(9>*TU^zUW^=$9 zh_T_ie-8VVG%)Tk^X0>v|30YC3c?n;mpo7};OQ(e<04d)MX7(0W|92)!=FUnHe1+k zIJ|tUCUgT*oNT|bt+kzS14Er5bPSK%7ecq=$kWrtMkkxRbK&hm0`J`LFcELvkN2_0sd_29| zB!#Zn`glo9d~v%nk&}u`@3BM{*O`h(Ehi{Mx?B|Lcy~=}2GZz(u*wOW>aRJIH}s}m zuh>?G=D6B!r~99^Di9}p4na0bWLjH5*t69kjqN+J7f#k*w2GI#d;Zpsj(aCziiS7r z?B1nk>F{fQqrtYh_l=A_#?|zqHwt9a2NL4ah>d_{jlD*zts8b$s0#sq%M#@m(6KL7HM28E%9tIF1vuV^r>*3 zr6(VmGV*yUrc!0*-U!=ggh3^)T8D*ZwEo>OS$EN|Wa%W-9DQ6+=yqi1+R_t#9r=?o zt7t4Y|6{i43*Af%+YKGGFlQP%?lphSlRnRUnS7++Jbce@%J*u#8qP{5s3Y;^320qt z`rpp4fpH$pHhm6V&BX-`1z`QkgHSWaTHLeMAm2O zAve<|fgR_;^t+o;bSR@sO+B)MnXHB$U4|Ihn8{mdE6?aDCM`dpi23{;z;Tz-BK8RlBrS`=kdFByv6 zcyKkAPzHd0KNw#RBBmu>z(h&@T5_$9K+{Vid7lg}dEX+3dsjxZ)+4*ZgS5pwd|128H-|i@vuI$v*(RiIj&j-zEKFKy zGDf~>zenN{%wfAKGCE;FC6Yy27m0h9A@W8iW0&+)1AlXM437VS>L^c=e8T0wVz@+$h z6^~o&lGf~u2p@@y%d|qn$Y~B7l|(4&Jf#&?4p4&rsVf$zy%X zt#2NCHWcu*s;yqQ=}nM0XnLNkH+c!9F{C+kKK7XA%DBrJ)wue+B)2T6?d(pRfpP|#E~b(on2@@!KR+J{x2j^&UKQ=EmDgqtN(3X&Q{KT%OfA9D!buFv@BS_hs zf8o@uh|W$63FA2?YxTu3X{9whp}UI;P_h=kBU5U%BQh85UH=g-gpwBI=2- zh+oASgp&C=Q!qc@3GR5+2IupcwpKGFVNh=;jj?Su8 z_$GA%+rL$FNF#0g{1zKyH1TBL^1@g3%@XnC+*k0mFrLP=R4V~$n~Q1Yb>H-rA|hF< zA8-}*s@>8gO?sV2R5eRZG)C<$0iu$@w97bmf=La1Sc;Sx(9qX*buvJ%eROrYX|b-U z&*rKJawWo|G^HZL-C$9?-7xp}F^(PuvxR;Dv&Q4+B;yXlJ0|bhRX+5ZK#%<0imCi7 z74LVhAXiVW=?aZ4ih9dy!3os-3N1XdHD4`=${5X>?=FL7DWyDxxSb&6GMvb_+k`D` zLT;$@tj62*XAT*1Msl=CFLwU0bd;-^a$%9NO?qH>1}B%i;k0kv2BKai1S>p3Xen<_ z##D^cb$6sNdI=MsBbqw1yFoFm`DIuBnlt`bAWNXxz}faURGvyL!C@v;t|BY1atL7A zYx5?5*KU2knCIVRFXZ6wpHlHY5-MIcxi0wxWYoxoSBMB}*|`Ca)|NXfW*s#%p2+zy zF}we41xk^s%KlWuIqma55`2PoDbQfGvU*}6q3^luV(qu8lzbfE@jH(xxh}9R-bs%+ z%tB)>n3-*e`>3u7tU0EnOYhp=Dco$avBe*|d_J;dkUV!arqut$JNpq-fREhU!mhfe zYd-e-Z!4d6zJ#wbwmo|AhVX<|(`CqA zzu+52Zdj$f3?>#hh6R6Y{-C`KGp$Vs&ssKR1vi3McdkS(NzBVHj^%d_P7JvE$Le2N zJ!kT+PEk}|wN9{@%f2kN>hA3^{WRJn%xyE76ym2VHp-Pdm-G!D#6(={0NpletMoj` zCjBMd!Kax|BWI|2o~r=Lot-={ZqLWvs}a+EeZ%eDDGAw@!FL_o!WS6JujjH)#b1jn zk!&QtAs+t>q8z&3xA5o9p)u>kog~p<5GtQc+NE?jsao>(J=IeD4+6v+PVfGpzMVhG z-Q!4!9d^qWWNV*TixQ*bIskI>B9N5bYwL@@mYx>;HrG1ln(v;TOs{hlVrJ2VQ$D~D zc#4x)-DcX@*Yjwd)q4EDP9^VfX51C>grR7g>!0#cZD{AsO{aoO%#A1Beb-;?zjF2R z9Ie@85=HZ-TZohb*V~SrIF` z5bf-M)J^&Lc_~ezBGBn=M(NuzL(J5t0i*n*3ps40cXgV0BH#m<`F_cpENQz`H-}LG zI2s8GiNR*ej-X-_n31#?bQM+1ZH!D0rN$1fU)J784tn&|NOCx;>)mr*jO}#FoM`H5 zoKyO-YhmLfxyMfaXmkFjf9g!)2gbyyW|1^csD594TIt?(kQ>C03Qyw_o`+NJbg@#X z9&?WU49Qq;<_10@WafR{M8an>%x7cu^APUAde?(N$^S~jryCPK+d|6HsFHp(mGwON zWrDB8kg@c6v3CjW?xT;CO&+VmJ*hyo#dey=XJh>N8SF%dpDQ+Y`Fr7LXPF}XwCcZ$DG zmtN*b=JWKD8G(VC)`&RjGEZ)grtQBapIRm~@biDFGU|4;NS;)fuHjwXB=#M{${$_> z{1U)k7hSTO_H&HFKORswA`~!(Up#uk)@P8{lpjV$&xxS0t!8?PjEk@CGq53V|w za(qiWU(6+)(jFI0&E9**$4a@-HT~!*#i$7!?LuFnRNt3|1;%Th&oKd27i`vHlu3ln zloDB5Q_^4wMz-&CBm9M@=_(F!A|CPekynO6>|zr*4J|dFow4YSJcPD5Dnc~!Rk$0m z`Nh-RX47K`idvy=xomC?8GMbBlADc>itvN7+yi(%ia0K0+SIyZIW}LI#g2HV?(LHn zu7TcX+gmR?O)w(Hu!YA#;Ru#PM<3Kt`n&WpJ9fLY6MB-j-7A{z0z2F;Q{0}I7@?`+ zU?{z~W_0fJ=F+F1KA+WG&8A~OeWGST1Bf2EQsHyBX&(_((;vGdxyn?tH_AK zPr@)YRF@H`{s`O!v5JV(-sC{NMJ_}!H=><&6r?;4CI>#9d*hCl@~PK#4wrmN&nJG> zNXpXs$I+80mdZvAwU%Jd7OrkIU;`ow7LLdHJ%R#3Vux``_ATIwSSP<_&>TUeyN769 z9DfPF#RBL(dFpDRHQG$6rY~8ZUUt1xrnz?Gu($r)Kkl9^Xq)`9Lw8NB&PFY8TXIQ@ZXo)Tn@pvAX zxFW+4EiLs_ANurFWr{pwY@ zy6B4#;fIzaJD$ToAO>-KA#uoyF6i>%i}~bT>ZOoo^6UggLBt@DytU=(`%}IX!@y{s zrD8%v;0bI@DMq%I08JrVLoEi%gxJUXC+Uw;N3pqi2GK%G|Go=m1SaS2ph^>d+tx}BWL zp|$VmaFJDq%RMKmn9$@AJwKk?J}#(|V(A0$`-58dBW7o~nfqynALxL|9XX}^-Nil& zOVxqQmq}>s({>}eW^ll`M>;*EfX8~*)3~kAMFYTwSXW`LDc*0@NjmR(2%r!gni^#6 z20Mu!KiCTbESV0EG^c#uDh5G8O$aCF0G#>BBST-=w=c3v56Q&mC+b~|J}#MyJVGDbxdE9Ik*q>nWP-&XF;rQO2!I5mQ2yy)N1lG$!+a(b z*#e?C_Xib=c~hYsQMoa#`Qw}>KSV^`67E09^KlArc&8-}5GpE9P?q37T+DxF zS^7}L7K^UhyiW*VV2c4~YMMdwOcX~?c+!*JLtqC09gH-S@~H^2e9~t5w?bBFBWYE6 zdXK=Y@!8hOp&o6hUa=~opq2+z+g?4OHWKSD@`+@9r4_m4eSj3t3u?G{)*=h~gBe50 zxqL6c7Znj&45`K*XMpM8*o zk+KBM%xu;dRFdP_Pe=FV=-dhVx_3JW zwayeDDEZ`*`ze7eu`Pni#wevN>3$!RB#1_1Oitg!C~9*hnV*5~=;L=F#}l%|1h>d= zTbcrkreJ^xjd?C^hB;bVteqB)V2d1Kb#^6YNgzd)W<(tvvv2h_<;N4=u!45+`UYzW zDqg=jaTPb7%UXL-qttY>4uxZmQ1h)iVkyO1(@gWz7p{SXcIa~FOn@GS1RWtDH3KBG zjldZM*dz8;GtuA*+>Mv#qf)TPE>vOCmZaZ!61EA7f!jr81#O5sxzROd8E7e-sJxlz zc15X5DF)xHT$fewN~1;gMj_Zp)CBw@}m>B zF85N{x!#1@uf1C54815#h7(ID^%{KfyF)$z=YIr+Up6vGXCu`k#>kfY{EIif1t(jv zKwX4CTwCCQV_uJ4fJ-*g{ro_XNGq~BZe_>yd7)ahUQleKGH#R$`oN{+jglk0G% zC;XYX&5=5*Wguv&aRsOZS|WA0z1%AFnS0UnLmKLG6H+UJ8vN9nMQf-M8Lc8qEE7;7 zhxXAO5gWD-ZX^a$Dr66jc9x>s%+H?Yz@%_Anx%zfOkr33csDX&1^aONC2(X(^3X7_Z2RgUpF1hijaH1@a0Z zJvKhWu6K8oZpsC!1cjdn`O`&ULxfI>>pQ;HH$_s8N)SyFz1_GWai3Lu%-0dGP4s0z;tZUQXHX@6 zkWtw*71w%+stwK3k_)Cq3X6xJDZpDYLEWywN8QV}ZpE0&ey$vSk8JfYvc05>NmH?0j@s__EGH^r8;>=6C3Cg2D^o7byXz zEVj~lvaE_MP8NYZ`>)h50&CIGX3}T!;}fiw084-SQ?T?i=kWG*5qRm(%`eH)Ch#LC zdD3Z1r)f^daF|%$6yJ|Eyh2sjj+ka~NZJ@!3c(pP(_Dq#rrMjspX+;`=K zL^>}d99=YaHG_Ij_J{EFgO=K6B1MKOZyjIXQL<0N2kV&$E_uGBADO(bXhzwv0T?I~ zv;OSV52ubpCDbkcO)_bId&Mp42LB4xv~bLw(2xu^8Kaf^NYN;tJ-L>sHC_F0!g=^v z+gyWF9`X=z)Fb3h^_%4GUrQ{o1g?Zt_9~Y0`cCGj0dbGY$vG{jTy(qMb-BGTf(3DsgymoiFvg^p4_9GND+J;S zL%Xx#SWs+q<*Ox1xwjsIwio}Q(RD<9y!Rpl<5A0Y%90uk@Rc&_@nk*I10j+Y z}W&DQZh8-fJI$n{WWh(A*;?HHMNKlWOo*L`%%QX3zF7< z5NjzG{V79&JjGt6e%aoR|FW|JHB`$WCT&UR&d#c~$va@or=rZbC97)M3Tb?i<}`j*dBv)RzM>D#wMjXO zswwTa&6UX@=xo{3;U4Rg8rhL=wYq7Ttt`!(eBsR(z6F=0GbqxR0=yN2%u1MU>hS9L{NT)Of7f)N0q$J zXmA`TD;BmtWUJXEU6QCoI7my@m2&K+QT8XUn@5+@Q&d!bi4gMvY2_+xNn75T##I9gLS z+5oxn)(7P0j-`8XsFYztMo+yte1sQs6>RVYnND_rzAt{LBrS`(;fkCJgD zS`k|^S9NiF+;XW(%&<%pUd?e<cEK8ZN zJ}iEVZMc3N>wJ8)5*7-I>^qF9*B&8c-;M_#Mnx$Tf0Pw_vS~2UC!+HE{IrBWQeq)! z5RN*p8?JT zD@n&pG&G9RV9+6!s~86<^avG#XwhJeg$wja87?whPQrFjblLxD5Yj0FY{Gf~X-qBV zCLwZM_yq9)P*$IrzNhXECs#LZueXpjp|Va9ljxDfEbyH5kdAq#MmHfO1hCfJ6c&n( z+yhIA!?~7;JI&NfCf3Qi8xTS68%MA9OXUi}?mL!>nAB&DOG=gZ0brr4(|1X}Uzvs^k|n65Bty%y6Zmm=TB& z1Txw>D@!|-sCdhM!h^pXmGSx#Dvu{Dz4GYFNmdZQSda;w-hX%1?)0abTmuuD+y2wr+PJEmGYR|h19}e`|-%lm_rEe*FC8w<@_LH6U z=9WEt8ka8~Hia1}Ptqm7PGuR-bCnVvN&RP5N=bj5xExB9ztPHCbKtd0#-qW0R`dyL zaA=&bqqsf0K3{?*igZ2@cDI;^VM+1Q!kJOg6ZGfrI=*f= zuP6=?T-JY>-U!uRhW~TU_bpA5yxwuQ_M1V;b4g{dhjCg;L#+2xw20>+zVUW3VeKB`ebG);s@B+DrycEn;#G^7iCURN(R@8uJOe|1qKvYxDTJe#y^a2}} z#sih#5?IZWyb5EyhI>KkQQDqs^yzvHV-ZLtl?Hl$pnR6rkB23(LHaXA;}xsh?LQqZMnfz+&n&e|h=o$$cQc#V@ zNapzfbSPp~R{IsrZ7x#4F?^?j{z50NL<&!o#1OB3QgJ4j(!6YdLu)0VVUxTp;n|Tz zg&K_^Ps~@0?T00CAk}Rb)~lphRERnO%$y00DWI1*Lm$dinNcx&%EY-msk3cXCcYKx zu`Y`5VzItfZ#L0&_~_G3mp=#}ae;}gQ5e|rQh=#v96_g&B6(C+ zb3q7Mqe?U|#Ivaf&COIydHN57R63AQxNd%#oBSfvae5;4(Jujjgoh3K)-~RcUa=_r z-5)&R3&iq((R@r$Z1(Nv;-m_6<2C^3WK~9ts)(sItd#7dh#jF&+mez0wqpZj(GFxt zp@=5T95t#-3%&)s_`cSZ541DOH651nag!+;f|hnO)%Ep$JC;ihfqzG21vCZzjRx+@ z2HLYhG~U&Q(lTQj2ghjZ1^8*GU4tkw9kd|7SM74;(!=kE^yBM$z zDy)Okl76S9l?v;c2|Iv6Zud~xA`;hmuyYG7R9I^p1y)VHB3$EE5@2i!EOV-*jnR@> z2s6R7UgwKNBJ{qJ3b8Dp2L+PN!R0$4&RPpH`_QoS1d;+B6LQ0R=W$-}m2>l-)VO@OW)hTwz%nj;qcsm|ehldzX925%#3ja^Wa6BJb zD7@jf->UIwni2cg3u0jfz;2q>_1m%nHs}b!zg}0ej_=oT81xtK`-= zUA_&9Ba5*_5*GRGaVr1k*QGN9cF&59^q=eJ!I(4R}q zZA6*tqe|B|0dGv}StOxe%{#R{8OqSt1GgAh#3urz3N!jc!XK@$Zpl zz;$d`AxzLN;I*7y=&~=e6)+4mZ1LZQ$XWQ4yR-)0_@q`6pkxBbCb=ny0+p{Yf8%5G zmhU`UDPA#JWjq7)=0TG&H_x`*YG77*a47dy8vK1671!I({&XI|!z$TOGCNKW52oW` z&NtZ9DOdsnlE54BUL5h-8Hr;+yztlyU*X+9M|>nleLY75j36F9gAw@ABhwI*GKc^@ zipPw+QL(q*bP@2Nbw02TW@{@UGJ`Q{@C0zFCv^fEGB<|_m>%)m7|q=o&GDQ#tUBsH zJ(1HfQ8EpFPy=vffJ3H73kOEyc90Q1p2k!VnKFi-ohaEDIn5diE+#dQref0t6TbE+ z~AUQ9z2%(Ta0-DVVNnKCrqO zArlbnH3HywPc$2izV4V1u)%vdz&&j6>8+8zj*WYZ&iIZ69vI#>v!ET0i?Bu}^TU@d4^fjo5L8W0vZ1M!jx z%+l%{+WUzPyT-nAuSrbF6ZB68XytRik%3C*j6@=2emybmLhkx0ZZ`hyo(E;Jrg*a1 z9(9NcG6&Q%MeS`JfeoNZuK}yt+D8fK5#dqmwu=499wnc@<=sC8(E9C!h_6jNgB2?Cl1`s5Q$~} zfgP%gt)4y8^hwE*3jAs>b{}>3r|rW74`Tg-wd!v7T=aom3+c^eL|fAUwav5jQ4l)X zf`w>pBSZ>8qzA~dX(`$j^2d3;5yT>&1I-a(1CKL}b+>pHB43sx<&}BXk0{fVMn=0nI|s6#eW<60dI7U^CJ9 z$L_Zu550jOGeM{?@jKrHH~~lNRdRMMy?Mx6_zVB>+EmQyjSe5K`wxjKUB>(q6`fNs zl$Moy^IGqivE(AU6S*Rddn=i-eDn#UAxT@0pdPYo1b}D*Ea_x%&0r>^1dVO5PJ|$1*;<7#s>C!x9yapSaPlrI{UF; zKi;YX<9+Qh%f;<6R`=Z|(>*Ko@5pxpa)K>yn#y2#ui=9$Tb&O2e3p8Ov61?+;W4L+ z|B#WN?F<5}{)J=XkG+SCaUvfXy1#iFI0riUZ#CfSO&f}Kd&YZ(-OtyhuUI*5{7cj! zG3368R$Hs<{krj5gZ&<=;cBv}y7EcQ7NND0OFTPhEnBZKozK7F&FuP${L>vS_D{c7 z{gdofp6xfK!GE#!Y6}XP{NxB8pkhn;o~-6JywkZ*Gw37s_-4JaN<yFSfAeWwU++FIO~OOceq*1o!#-w6Ft^?R{@G~Piv2D zr99TSfg@yH?OnPX{Puy9O7l;<-Vb*cl#&Gxn2od> z>6YB_&BWscrkTG5BEV;vTZfN+KeC0KR<%>o4ZCcLsvXtWt^a8(`{SG0)|taUYrels zdZf>|{_hNYgXt@?b^L|h)6Ic7$GZDW7#v|1CD< zNWO&y@o8TfdGC3}$VN7Hrm>g~2M>}b%UxU;=v`xt{pC6%Rl8EZr2In0JgR~CyQC-0 zY40so))-{^`a}vXMNNYo8~=9>SNDJiSCzl7x?EBzlK1q*M>-aPLpt_btisXh;`5G!=VEx3|Iw@0{(YD)95!w4 zD%|FcW=>>@YKoX5UGI%$_?+*%9B_eVQ14=R4Og{jUJR*NFUQ}28v9M;W=n_e6Jnlv zkC{L2m}~83203kvDx5Iv(!Nd3PGXhAb`oyq8)(h4r^8;E+FlCC_B8ttWj===q|46f z+>yWGu~+Wr+y*!QjG>vWY5`r}>Kge>oO>JO;QuJQ?|-WQH-6yG{%#J;a z;~Xm^tB}#LN7S(*5og%sn30i9TF1&rbq*4uPztG#%BnY|Qr7o;zTdy#`wyJk`Qi1v z-JaL;dR*82-m#WxAVY=w$#iS`)|r)cP9v>Oa%<6~MZxI(mVX=FL*LKCpz`ILQ+gdc z19`Vt5j{DCgY=@X+nt-s+^33r3f;!9y;dA)=&M%KeJ<^p$mniB#%)@oy8QE=N^-?z z^&cI4-{*Dlep<}x{R&jXzFuhwUuzjrth#5)jv@XwmI+UAI#uLLJq6M6HY(PQ`7 zu!^^tCr$N|LH^FW=fMSk&fcBQOwju|aLr}W@M}e+sN?4vP@7c5Ae>Sy*JPKyEx<}^pdb0*-2B}-CKCdEupQgL_yXo40ci&Gy`Yv~r z9=rOlQsnoKFU!{wu?g!@*LRh3Z~ph-59ZtHxlicJA%}b4--$`+Y8G*i`Sxkg>oDtc zHg}qqA_)AEe(|$FV~& zKZ3$ey^aznu`tws=gIH$Sb=X4p|0l0#qPbg*q<$)L=+CSRhSar*P|1hWgM1Cdp-CdcEb0qR8Y) z#c!9-MWS}CU?*uNBDD9Lm8c%sb!D#wtvSxFT~h)1FZonqSFw!UzWvZNGg?D6$WzZo zP4YkYAK7I?3=e{1+J$J0eVszShY5Z@A~$76QR3Jf^G{`Ab}P>-p{~-W*zBn2V~V+S zi$bC8%bMr;)CG?S>dw0xK#SVN#FchgsW!e&CI{eE$k zqO9s3C!x`^J=YLit@Wp4YxGCR&1T0KS*=`Kug2r$N6OEg zCAl#kn?aQce<#o)EznYfl zBV#Ei3T=C6{y!yqU&v5?+#ryfMZ0Y$DlD{b&g3rJ_ClPPQ-UGdOSXaF`N9jowJpJk zW7|7|?e+z6=RIYv zj6FO1`!)8zhWBk1Cl_j|s(!|soNHeO8rcIDju7xyQ7pD(5y?49G_^k9ON zNMzn5B3Rjj1rH`sW%h|&)*b^wO{6r9BtM=Ik3p#~q>SVHeuxZ@AqAzVEQchvNA2-c zEjTL2XWw7^na8kBQ&e7LQh@YVk7p)dqVkjX1CX4aBY36gg1n?aMP<)XyWr@es{KHW zwda^?Q*_DQq#*SW&*xrWqOU*N55i`6jt3~kluxj+ux8JR^T9C{@ArcZpB;I=h-r$c z`j!-8`qlI0l`k+Vlo_+i9OWghB zgY!gAuh~JROKo|{5rN8HbI*e>byOWhgj##eziPVFbvHROBE;+6yDyizA00%JGQ1W( zDaH3rBwvVa_Ike&9RKkB!G(lpULSro#XtI%d@<>(*T=mt@lOs8E~av_Uu2aNSiDzB zG-dB4cu2ya%pob$+Iv~3IpL|s)u`MM?@v-+6P_JEjG||FuP7*A9(A}HUEJ*b`A99~ z@^hcV=(15w)#U5tm&u1QHJm=Hc;&>YysNPd%06p$A&IZ54r5!a zeb!x@6KC#Tjk^=#v*GnM@$I9-I7WugW`OdQxrwWnI-7mIoe#P4?)~AVo@YMaW16qL z$Gw-Rt^3{6)ODr)d3pTfqtdSA>#^rJ&N+VNtKOoYNK!1iz57(>@pgiq=8D2m@bm7d zAII;?PhoC4UZ$i~UvJj=cjCW^;rhd!JG!XFn5Ul8*XOpDY00hnaw?Og(l}Swb&tAWBJ2*YRyGkTK(v} z@5wK?xwe{lzQu{}c=K)e<3U%Z*7KVmru*|LO!zeORXtO+g1L-)3|cYg+hKAGy>OFFOlP?}5+f2h?;16uiym)f7OT1Akcq8m@w{B$X@EwL0LzZ4))EVx7-; z3%vzX{Rq5a&ftI4!Tt&j<3Jsg&B4J}gU5Bv%-Gr>c*tDX{7(hDpffk^Y{IKQBB*)e ze%s-Bb%(6InHa?6|3P<`rh8Yy&$?Xs znPIq?YY;QCV&dSuBFNe$SecQQ|9mx9mUoL~5gN zf7v7>bea+H{LI6Dt;DQjAsc)fZ`LDoR5Y(@?n*RlFFY(VYi#{{E-xi=4yuRgyN7$G zsG|1qh0O2u*Q7Ruqtb}zz(37caBJq2MQFCLN9648l=s89g0DZ{3470=7DPFgxA>C@ z2O$l8D1KovQiePAM0FrvfT+py_-C@ltC(tdzb0K2NRBs&g!nM5DtP#=3qvd z>~?rDV^Gkmfn_Bf%T+jv=~*eXQ}(ydXeEItUxb&IaI?P^4As1Lzr6Y~y91;?mM&q&paVlZb104eq>Ru{zp2V4TcV}z0i+~1H)z-x)bfsEnXan zfZ#;M_HgXLoo~EGYa=oS3sZsY{`bo$liNAR93%gJb~EE7@)#~6-_sI*YW#b?xy{H> zo$7JmGZ+Xgg!a7nw?KD_*k-I0o>;iI_sw+Y1-_7I;3IfO`;a-vZ@l|>@5ghg2CDf> zHDL*_W8ODj+g2@eKs6WcfVvkp8Waw9V?Px_Kh)+Qp65{>isD}QsP;HvH#dX=S;5Dt zfp|USJ*oe3@DTr-Brw04T61#r$$X}8w%;>!NJiYT;l7GZb0^`i9?psjTq|t9Yf8Wp zw5W&GfD>j}FpnCLt`;_ekKin! z3@l!4xGir!|IYpJ0r&(_AnC&%RK0Jqva#)XIydel{7@jnn?#kGN^R7y!#zJc9bGy< z3EeQB0dRry&X($*pTMImx(*IK_#1rfRb zNjz(00QRHVz~KcSr!mq(T9VA|yJL6NcORubo63~bkJLonP>fGK!_Lp=qQnM>?-mw% zdV0bXgj~uLUUC1Xh$6`R-;;uLn^hdb9Can0A)vPj?EWjmk9)KgSMb}KT2E5Lq{Cnj z6H&Iw#zPmYHoW1+%GZkpzNVio$l`HhLh-2BNO)y0b?FhqQnlh5kbT-UtqmxNyv^-<@_gx&va5dAN*SIV^SiGgy7| zr=$4)S}8FnyNoRg6{|Mh^WC6BEix%$ADkBcJPth}>v1yS#%Qx$i9(eeq85IoXGrDR zHgBIlBPzP#(-_49Y`lUhjp)A}E_R(S5=s@$BI1RvI#Caf{yse^Eu1T?Tp`}8xOGX} zztkepQljZjpz)7_mu3-L(j&1X1+y9)oZ;m5GBIDe*GUy#Lv=kj;Rv-^9gx>9$O(u& zb~PJstxI8LTTSA4^hvf(rcWtKwtlc5DjQmZ1aFBCVMuKT8A&YQX}$MG4%~Gc_hy?v zg^R{wuee7unG|b%x+3AMAl!8Ef70c>TnB1ETj7Zh7OR%ZhAd(2sN7cnts0m}WVaiK zjFdh58oD|Z_6YD~_uHUU@9Q8LX=8Z0@W3DaT>Po(zy~EKo+AXFKy}<#|lJGP641C2VWU z?;+((ZST4^1#Ce>v+vmPHQ-~D@*&ja0YvgHNOo(B(=re!(u=|Fe)+=d7mMP}YQUAG z4m>fgnx0K)v*EpJ?qSN#ac3b1+09o__XFFzO1+sp#@AoyZq^Faq*^Mka>)IqTPrH& zvH07~xi2Ut$gn~QoQcG(S&0bOjU!|3R3|48s*;5m-IZl*T;f#T;UI5q=Q<6~Q_!1B z5&QqFl*h5pYME)4qw1cXO?a?#8w(NrO&>Z%&h?%IitUaWzv<$GCoQ2Q_jWVHdbO6k zuD`0}Q8}LorGP{uSc11s-!WqvZpsNf)C@nS_PDpGT{0n+m(in^o1+;y$Ryr5D8lh4 zl4v@CD9N8ct#t`e=?Vxk_vvAvpR#?p`2s?Z7 zC-FpPjNS0UgSUTpSR9v*cK30=HPoYro(vUPT_sV}y_co#9&j2F3ZSBd4C70zl8-%m z{94~@z-Dx4Khp}PWbo06JB9f_jEQG9HDZ#pbI~Cn9_CLvFB*JYu^=9clsi5N^fHHi za7rC`5Co|w-)WY9ktSlg1xR%d{Ouas^F?xdM*28X!FUlwMesn-m#fSnCx{pm=6UKe zh;bdpqI*OuAnG%q$4REIV#p8UDLw)q+i0K*oogOp*2;u-UsvpM5m&Jk|LV#G;hgel{HosD;AoaRYfj*N7@t{`AR zkTTnnIzpt}u}b-63F?ZojqetYFI0}m0I|_aQzV2z!o`*FCB{Kzoq%R#{%A(F+#=|1 zX0|K|n9hXz68Hqqkgcp8#qIPj(Dpy z?g!T9307ih$|k2`lv8>j9+;2~COjO2)T9XC{GDFUoS2mLab^1G`2)u0BEa*5X&G#Ue8 zne%B5^JX9+XeW`#^30K+{Ezhu*EqOCv5qT&(O%AKuc^u)isL91a*v~kbtW6l1Rh6( zyOCXNsgQCe@7+r|%81CCVRpVYz6DG8VeimHIn}s-AT#zVkQ+i+<8ond+UbeW3N zO@S;@Zn-*FD=%2DT&@OmX8FwEw!pN!m7Sog-cET5P40Td zBPO(Ek?3#DS3`tOjVjn=pb5P}IJA{%DnzuCx>)c2r5hCgOy!~tn4D^f^Src26^gpiN>v((5HTN0&8|+cVgwLD#PaZ4NExh=>lz zM{~$!sgw+#7W^3n^rpjvRdb8NFq2DiZkJDTi@8>HIHAIu&dSSF2`2TY){&?;?3~JP z2B0FtOiWTad$EQ3;n4G|8n51zPWx#SEG%8H4ag>U;9C%&>C%rbGjTPm=FX0xzfu$!BT#pmGH*u+I(7@d8M|t^R9wbnD)wm3I<|3 z=xl2t;F`@TQOi&N=mj>bS=0b1h|vY~|R0)m|{}A6br`RwnST zDWR$Gtfxd^0Uv9Ta|ACpUt14c7r2RUPdF;nyc{BJVjY1v?>*vYfB6mLPew`{s&kD} zyl1G)<<}`Az(}1|uT%&w?W5ip6TKBEq6uglh$5vgl?6`1vOZfCT?S6QDsX^=<@F)- zg0$c2+)kJVig@0jt*V|6MLqs^Tb&6Cw!LF;7AU*zQEb>58Fg=rReU3go3_q+jH_X2zgaWxsEN&5hc%qon~>>zzr5cw*6`cOL4}JM360N^t`^mg9D* z5Vl+DjfI2^d-pArraOCChj@PNhy1P_H(NAg)?Y;ZYJF{M{$`w2Is@+Nf3cee(qsZf z)Dot4o05zWdW+R2naz$&5cC$dZ0eFD8<=Ghqki(QE#4%U-_3X%hyx4<1fBU9arcK6 z*ntj#e!K5BCL(pzBY=07CwfPARYEowMyp)Z(3XSwQD>%svZmT{ge^s4&5O+l&t6me zPAP_K?K$fL`R64Q>$x`DrxjIdfI*f4YqjL?KS1oFEK%CCSxY=1Z3g-+bXq_u79~@? z3@#=%X9wiVGHz0jOzM7Z(bPnNlthYo2w6m!mgPH4jl}{8k0FJ~&F?7&x2;VaDU zPg z@C;fFG^7q8nyX%=a}^U|`K14uq+Sg0gL)+h;r8nDmnVOizOhohLgKoPgr&3R1&Q-g zUvlG~mi+RHI8dI_Y_aA_VcSDk2I z=UjhepXM+C31D8%Vy>ENqTPS51)jDS?-rm|2Ynr9|8FqFon(j&BQl|}^!38U)nMdu zAN*-f>xye%C$Hgyw z(S#1IA>o#V42nk2KXWyG-0|-5b;ZetE_VC-io@10=FXz z?p9Ub|MrL@9ppfSCOEXPY-^mJ>iU|7gXt0 zKlJ6QwS%WBAU;f}4;}L3tgYKf(NoWYYzs~*2}Uo3ORfP&JHUxF_y9>uP=r@<21aH= z{C7Uos9{=7K0-qc%tnBgnZNeif3YQ0c9=5!mJ&{eiu$aA{=W<=l@7aKbL<&IAE$38 ziH=I)xM(w$RG@jzrQP7LyDqH|<7KdHR{$ z`N%)GGSfV;spD;u2dggXlctD{;&t?@%L*rN7}IrFB*vAf)W98F@Hei~suaoTgp; z_suz~wO+XCmE}zNANYX08uZa-yDga89qTt*Tv#H`BRa34A3onn#-F#EC-e+yfz@uT z##SH5gMuXE!cAk();qqUL2_h1fvy|2fpjWT!kUJdp*kDzJT3o8hB|e@Ad=-I08~iZ z3+%brK1vE*%Fv*|9CTAUjT*9q4*zBjq$HM6t~p*iIV=^u-?nu#uJf|0xX>wr!1X69 zIt)wD(mD&O?zNFI%RL@9P z8qTC%Gvga22zx~1R3suj`U0~AOEW(SdS6>gmp1qq`%|jKYAJwwE;Q9odv7_w4{qCk z>$}y|Bn!dQpj;);?4+X@|oNtXo(nB^tx;<9yty|j|S;vZ1m*lF17 zo7R6TxUSo&MzT&gY`j{{aD2u5#E(~Bqm`s2z?5$3N6jf5$MVQOt#z65d^Q|6`Iqf@ z5-$hxpfo31%*FK90i4pY^yO=Ik}m5~uFjTmW*6&l(Cd!798|7~-$Sf37oW7Qln@J- zh8J89VBd5uc7}Bencmy=291T(h+z5E)EvMUEEg| zQupX_dl%{c21DSE!jS1iLdQ1C@!l*;;rbEzzjrc8B%m0#rBFcyp;Y{0mhSIGg#vqT zR?zFrXg|==noI*1P1x@rTDdCt)!+0AZ*YNodiP@cCa1nS*-||6aU0^rK^-jJQ9aQx z)4VFN9cKfq5^50gJrf1{@6&H3&@hWu>}(Lt=rymb32&Jm+~Wp4e{JnqQYTgr$!+Xk%!xxI#XOw zQA^=?F#@+}>>?YRRXRlw_ICNfIPZ4;jDe)@Y9*?DZaJ|wJ^Psa)eY#~pU*0?D$Sh5 z{e+dN5V@-!12FC7-9aR#Aj@rKS*|K`5VrWL&QwELTY|e_R#HAqt|h{Y%LPHbFqDV4 z@jJ4(R?jj+1g1N)$4w~Fb0coM`EP8~gWe5{q_O9VByWWW8qH6^k^<$$oid@<1qk@) zf=u;<=U&@U3-H5jASw`tC`VepPW<_Re`?dYoHW3{h2-|5*9WT#^BUD@>1$%F)r@ZO zCz($-n>7wv82q!UZ9#B4AwSWGu?XWrGPkL&JT6RFhBtwpj?YAi$($6C<&EcY;{w9X z3>}lP15XT1Ev{r}RU3RyQ1E4c4}mQN&Himm(?kXFa+|>}?KqZW+mZmoa9BxX4XO2I zfQ^ybCxPdva=Bzgi($HfOQyBf^0GkKE}5U?1PZpeqaYYlD7^2)9oWyGzjibU)pXM8 z5D8ZhnzoyRpX<>nx=ZD$A8P%WZWoiEPs)W#A%iO?1Y_{YVsi`tX< z{r^7uocWtSTJaOV%d7>8R50!NPobt9lj#tR0@Y;73k@*6GtFuJ_p-lK3!W{TR-K|- zeN&eq`EUG4FMADHZqU{%8$eI~vrPQbb@$^cK|=Kbr-fpjP}{7-k&Ee0zPIpgrTkYT z-I-45c&5eO6)r1eX$|P}?g%L_^L9AQioxXMGTJS2X<0mxYzCi(CFR zsvfO|+*~ImuZtZPybhM6Z~d1@nao*55ejE znyX*&-JEf>02gXC)yO~|VH3`@GUwH}9~Fp~_Ma+$;F2kQzXt?Q;27z#cVVPKrY^r* zuSsE#-FSH9Nc<;6l`8{?=BaMJxKPagMrwtg*)+t>!s^l}w@S#I(mk>W!O- zitDc~>^1+U=LKcml|@-Zx(gxxm(?wc&6>d2Wgau}Q@p-MlZ@jti(Z8a;A4yWo%iaf zQXj<2(?k>7N!;;XEBmQNVGm5>hEuChD=d>_64VdEtzAM<8)0B%$zky(E5MwEvISEt%YRd#^ofi_tl$iWwfh~aAqe?jf*iprWqB`I^Q zlc!IYh_&o;V)|DeAnt?2BFa8gUG0{Z-L)n7341B?v2<~{YNd-pRw&0NYTn2qICvEt z$;!MIu6^^ChGg$R5^12sL;tVI|Koa0x7_70G2F2wJk8%i)%lc(v!`n_5)JQrRC? zon@5fR%$@kD(>H0e|O=2VY=us->u0yGPgGApP#4gHos;RkHE~&kDW9F?Lw5Dbh3g( zeh;Pgw|L zWGYD*8B2K-@I?1d=@izPqK%zDJa0Zykf_6e3d?&}(i=~4sxJc3bop_=R@Df^+FSaQ zL;j1DB6Gud0V6wPu+%(HNO161{^_I^6L5f>aP%i*N*kwaE+NnLkS1|-i(s>J_$(1%_$r_O4cHKqh zHFoz%g9KDzww|n0@^mTKq3hjc(HlP5A2hTj6c>H*;qmC0Piag1&aA~`QJN2!Kd{*dz%45J{F#EL$4=N_-5?WF`mxI(bA z{{A}gVX`^&#cYNPhkG<88pibz`UkCm$#m z@J{GRA{2N6nKoxsJMxeZTU-8cUSkJnQch{;$T8kE?$Z)yzT}3Usi9eqfZY~t;;C{M zdcaA~Gwi(_I88R|vLqb5jS*$Q_7_hS2z4u-)X? z`xvS7(d8NnPhYB8VLv^-F_o@u(vdht79s&ZKWA7+rL}p9PaA>foR6onk5vsMW=cjm zX<#`_7qJFL%>q6;mONEq@h>EQg^w z+d!q{Iei&m-Bf1MJYZuExG<|KHI@cewI5^hOAtpjZ#?lfq-k*Qh?hS!Oq`0) zGw)0tS*(IYXd@oW^ZcQ}@p;~anCk>_uql?;R2*z)ljiZSFE$loY}mG5$1i10VILID zGE3)G9#tyDluprEr0A?Z{cC#4q=5H^2gU5~L;pUonK?CuL{VViRLnv6k+eVMHuyzy z`$L%f`2Q$Ubt2V%v9*hvT?W7WyFmH5Fv%riroKoWi;_B~t)9Y!m|_5FEYaMS>&il1 zjt%s?C(TBGDvq|0p~iIA2*irt-Hld+I97iL17Jg<_GRrCb+q|0fE`0JKVn+Q5C9Oc ztE3i4urJ#FR&Pxn3fJ&wg^>*nA&LFN>WeOs#l{^|S?Zb8Bdf_9&MsD|Vc9ohV7@i3 z#R*cv|GG;?(%f3bavAxR#HP!EJt^j#$q5xrp%%uxqCJDI+)GdoEa--z!c-W*_@@as zF5}QV4R1q5GfD#I2{HSqm2IdKhMGjpS@Z*$5N=I6sXdSsPhQM#Zh4jbmyif7=mHi5 zw17tpuc3vic?%`Qo|Z1_=e*xYLFvUR4C867BAn4`N&TSEx*4LQk?Tz0kq zx*U+hcH7{Jnr$bA%1Jrn)U-da0yf?0J3=#=1xnq)VSA{A8c0Or$@RS^hPoAK>T$bb z$A8cJ`ift?1E6Za7bJ_v+Osw9l4}iV0WEd0##BKkpyOXaMj>3r z18CNwBb7BF{HwGgRgrquJ_H6m8A=f}-M?b=Z9s{Z%lpiwL)Ey0+((bVZKfE{ELeSsV_cyTyUgTNrGFSD0s_ZNMc+ zH&-C!k12(g#ZzB_P*0#`#~~t-5Ot0!@ioBRGB`ic`+g(BSDePRmHHFwt#rV(%g8w? zm_}So7d$?dvPG8l5RbTZFL91?#Glg^M+CXsV0`k@?Y3&f%gsSchHl=s^8+mJk|d-T z$z$U*SC)p8IaQF@v|cBuCwTkxzjg$ymi>!r6Mc5G6n?JU-&Jsw4cHGU*%TmMX=A&4 zwq1CaQ;bfrUQC;RC?7JFK3v0gMXCGCAg8jk71C9SkfMRf#5EFRP<6%E{UWjeF zhZFm_EgEKmENs#OS07j1Qa!O%f4Y#&Po$pavgOW#deGm<)W9<}0HQV2Bg@)#_PVZ` zoXj;Y$ufHN3L$?-)o+z%1YS~~%XQ|~9ruEHVCp}us^yx` zliCnKSzsoW)~kOcgQVCSLf3l=V*7w{2yWrfC)+*t5_<+2&$}yH0J1$mH^f`;a}7S7 zBB9J&(V8W}np6{n#Q5N8#%6oUBUpRq9Qi#!@82s#0dJT5i^qG=H=gW#QjU^Jz5@NO zYp+M(QG_&Y=KMxI|7@h0HU{E}%CJXL z*=CpUhN(U?&0#FjW}f~&H57=&??W9gwa z;5C)`QUQ5U3_y3*PWm#!qX%T9l%KNt;cwknwHl}Ky<Pt9q!(ZzATy{tvK49?< zzhi(3k?!Au&IO|oh_g@IOm%kY6iJ}M#a(e-8>%iAq~o!nYfd#WPh0lMauf%N&W=X5 z(Xg~t2USZL2a27LCn(%CRxY^+EEE}_BfUSOUa)NkvCq)yD`m9@mpc@UMEt)WU z`th3Mw*6G$&%)#du0|A4{py;DO@1+segcrT7ApFmtj6bA?!6NDk?0my@Dk!;Lf7x; zmK5<@+a#ddtfExdDQ3@#_>WhTB*4Mw_p8!*I--3*lUKCW?fZBL`w7N=Je$E+)rSSo zvzgHt>pw2$X*qMw&tAv{q{xHiDdQT>s0}c8VUBPp zS=jKbjz{-Z9)XLgX}XiO$#DO%>S6ffyRitU-6H;{4dCeKE?JkDwr1E7i{x?{ch*6q z&F=*|%~I8|nUgb(>(Pnu_BfysTj0(3$yJx}*@o&_ozBhrXm^Y9j3!>zPh%R^Kn4%9p!=$ySxbqvJ1 zt$m+W1SWR?0CrT7qkF-&>Gq41H0M^Ue1K>=q}5x^=JAPJMS7UdJ7-WHK%r?caufyLc*ajUd%L1eBA61Sw(M0@_5wvv6XZ0}XDb&nXDambnJ z8=D<$$<3MqXHj_z!1}AE8z}ns8HpiqrsLH9-Jf5N-N2}*2M%RAD-4@SY6n)53NiC1 zsL;z2sx08M9Qv`)$=wiblx>!_2XR!FUW4<#>bSET0)jeWUt~CvMhTkl z&8SDD_v|~sXWL@Mqk~yN9v`>JtQ(c7TJ3>u5=W#?kHR&t*KswINkr#Qe!0cO#<9C_ zJ=G5>Jm+mLH##T~^Y$LsD(rv5`X9wYN}@LiU+UkF=#qAj(OOkz<7BEt_!XCCTT#L? zQsL{d|DIgzo!+VO8*Dh)cEqsxk*<5p*gNV{Wy|&{#XK>sQZB(ulE0p~N5$Gp|1D7$ zzrK(Vv~JOmk^4s5|5SwEmk46s0?}x$w%*D{jCnrE#+Cc8*@Zd=!?5jm!XX3@C!^B+OP*L2$?2D0^H^n6N#{ z#Qec~Lf`?@3j1;Y&r9Qt{TO=%#Jm#-?jrrem8f6XaU(<56#dprD~SnJ-wG?rvM|Kz zig*-y8ojkOEH<~nlEXmU$w!D8Bo%&fCY8!(Qaoj=Em|K>AY3I0(T3+YF)V;* zd>ytyf0ZSH&TJI2)!t$dR91;+J{gzOr@ZhsQ0pbZD+FqZ?V)18sG!MCwtGCm`^Vdq zmWFNCrBVMdK^~PQCSE9vA)nUzZjR#&o_F+2sX0`nVM4{L?DZsGz`7f6)p@=V*=^up~4Mg3LU%>XfmWft7J` z<^)gc(^4El~lSP%cdRuz#g1ynmpQ^urI^HGC2L9$;u&08}TD^_6R-!%!At%|ka6#Ok= z>`aQ9VgkiWW`F-ma9kz%CMrwJ$*MVCqCgrh9mEU>(i8&%+@3`hafw0>A4I_eit43KEL_cG_8Ts1wth4^*Z8fIeOV8K#cW8x)yR`af#&F5-c!g;Eg zR;ouU(BG$YtM(cAJ568_w3dpm^7biRZJeA+E#Z=9j=gW^5c=4A%?laf0O;jURCFv* zBDGdPbCpBm%A5+Cz4}w*UxV<)vJG&KPSs8X5u`Xt=hE2yctBceCJrre%54`nV+3Vh z5z@qxcAu5UGJ*QJb*G`QVWit@kmt;2zf6A+#%8;Bb(ExShs?|6MhR;Q+j^p=?0C*1 zP|l=Jiux2w=}w50q}wS@M@(9-y45xN)LQVFhjuppY*%vuAQ9T@pl!U=cO}gdsxf)} zt>dR-sSd%a3AX3%n7RS;4RfH7D-MOI(nck>J64C{{9?YV^w{Kal=x*Y>jnSzqx-^< zvB$><4B|3>`Ov14F`3L$>XfDbC=a2&OO`7nmlyT(oOQLh#&Zo?Tojt7=G(SnTY09m zqajEm^0FO1JgbXyAmjqy+S%FZzg@erbv!vmEcbh~rmilBK$+Ti$D*_iRPHPvyJ9jd zd(TyHZgL8ujFgUkOor>P)?8JBW!buHfz=79*t7I_v6YVV5>$=7lc^B< zO>WKZ9kMYMqOyaG)R-j8B>?oJiz&PeRF+M^Q;-auC31kvGsvW|gvO>JlCA4c^o+= z%EYJr`Wtp|hVO9uL`&~f#c6hM=vjGJbX~!*tFU**{k3_a*mCx;lD0vmI6Kk7UCplu zKhDzE&SY{VALIBEXk$c|Ttdr?iVq1E&Qul*F(GKA_bG>HL;X$Uv&zI4_*IVVP^7Yq z)jq39e_o@V$SA5W0@NNw%?MR42_F2Fv`bl}?*uy9evc9?L&iM_N!Aiyu?a;#AOU$Z zpp74~&Tg^4TN=k8&{WrRcuyxYNz4UUH}IW-W)y_Kg^T)Fc1g6rDG=+oS)7jZU)nDJKw=NdUzhhi8but;vi+ zk?Z#xMq!nAOZBmFz}_Jtv@5VPBM}L4?jJ(J8Z2N*ix!^lEla$|$U^o5HPpa?jEw-6 zu&S1KN)4X9o^AGM(ZV>(hA<@_I7LVrX~s2p;tw(aqNWzagYS*p} zcAdFmmr9A1S2?b?2#{I``AF-3F}s)6ka7fB6t_c1hUH9NuPSno7}^VKjK$KFwf#)U znveE5w7Y1XhOo(HSDc)nf?T& zw5S0u>;_UMQ0%X(36!6=KAbl`I;3SgW&(w)kCK#$+a{Dd^;+L!&zMgA9?2m*sO~o; zz_Sqwoi!Bu3h%b9k`0xGLh=J;wi7N+E#Nn&*IoA-jlS33?!*zDTK|frMJCdy@cx z2tmn8N?2K@l{Z|nn3=&8a}{tZT3qn8gy9!0AIw;Sqr4K5@Y;%0_RF8<3Q%*!0;@

@~r1yLX9QV_l5Wg{wA6_J|gl)nIKOOghBmH|7K*W$GsEZRS zmY1yd6LMM<-F*=yOgP$S=KMtnfGu>(kj9E2RUV*Zv0M#|9@vt~S~aJz0;iOK=<)#yRKBd~N=*!dP8P5@d1R9O`0Qtxd^I@L1pJwPig4)l zSCKL)meXeY?&z=yX@~Tgwt08O#nX>oY%n-D^UA4N^OJX6ygOY+n1bm5PTuya3=L@J z0hN0;b;0?mf;cBJfr{#R!M`PwCqIbZH$M%N4JQ{u*oZ>G%gZhnFj! zwx6qxUVX-$RjMHidh<7okN&Czq|iUi7Uz`&Im`!^<9d9prEi{?nBbM5MA7Zs$|U3) z%4w#;GBR#k02{Y)i5l`#iC*Rpy^lX(_?@uV<3tywf;9N82|*%GVhA9+$&#Uyh1e=) zZ=MwqYF9gIcZ>7igmBZ+wf$QJUUNrHbzk2E(4jMb-GMnWbcPfC)U3wlFa6E9`ssC} zoQ^Fnnc4Sm8>j}07E0b0N|ordHyS-JS+MKg3vnxELjZx--qNdd&2NeZfddjPi<7gK zosW?FPL*9olcvBoyp9N>wEVq0REF-XSKJ$e1nC_H6Dh%yW=nYVh@yHn_sk}r{;#7C z8W;S6YH+#2XVe2J=;Frk*3aR-6whgje$ow!`y?VH1U z*xkdM?XN98rGZ*u1no)6`4eBmTZ3c2Sa1$MFA7|)LP{zxJBNIm^3AT}J+vxcHJ7ZR zsJb-j_X9;y<8zV3x-aPx$F!_s&|CQ9=8youDdI^ut zh1rfy+PkMivO9u$*-r&GCBWfSc~XG<)d0gYr;W-#ou2eCo_6tIC>Ur}e@b>Wy(eQ7 z*K*uydN*i5v@`9F$PK}54gz>>a$WhehZ&j*@?kaHwk3 zwg_m#+3#Mc8&BzVc84Yxc#JRz5*#uhQL&2_%9{Z3nm0k0>@K~jP-`g;kpR|SsH$@K zFlob*#Rw5Msrm`6&C#m8h39q4&NIOLmAlM;HCcSK+)ozX8-yOQQQ`r$zyWy%Kn#JC zY+Dp<|Y0woTV9l}XZT2Q$m$yl0JD`C#ZV}8k6 z$6`a{>Fwv60QiuMp2d)$n=r8fuge1z*sQ|t$QWjSYKq`p>b<#?6{=r=$+um|IxKtg z204>vne#vuUIl>8&^$)ywnHoxdd}KfsL$yv+a1hJKVLdjvLGGY`hVEFudk-QKYZ|k z^n?;Z?+LxvNG}P!3kZmU5Rj^f0Z~B_lhCW7g93(*3K%*nDxrg@G!YS{2nvV@hs;@%&wD@nc};NSeYVy?S@6TS3gfv7J`Wanh1X{V6@4Cz)UGjm zDpsXV5!oUr(E1qBtbYAipixrux{!_cZ_DF-JWlWK{k9JG>Rq(h@p%?OnTo^wyTJ8# zZ55jPZUhtQ;9zy(o028oQ9hPtB>3IqN{!Y6lf4$oO8~P$ugyzDCy`9Eg1k@MLUMFc~s z8TFrMgV8Y-K^;!(vuS*JKx7-qDD8zAZF60Zq(fwfhtjV6_Pu)Bk-Zmx9vl%@@g+PA zsMc7Ypv}r0848?n%ZopUeYmuOaVCgO5M)a>RO#Vb`xsOor%r<_fz+=G2zxD4{jMA` zk8PMxS$AkZ^I~htX`r0?H&Fm^KcuE#n_b;1k+1)6F(pzs$8c(Pwq!Z(;!0tIePe(6 zflbDh@9%7^=L4mX7YI{TDK=Hs8-w+YFwg_?~qR?ULS4${2l8{xq-{xTDNv6>lKOD)w$$bF9Xz(uylI8uRYT4 zG~E7UHpUs*uf1d;8w;z#p5|3!Vt4w6?p=5q!YRF_$~*4W8wM9kvk00@)9-0_`GND2 z1|EOkuGNdviRnm@3s9(#I4HF4j;*>{gh!er`E%|Lx$~>XZiUX|?ch^WC(PVtXTIeVDWrrddSi=W=-zu&g+&S7qZef|h@ zfcSi{eU4iL2M!=e9e3m1@Ab*@v=lrWXlwI0=x+OIl3++i#QsHHch(%dghMIKe^`|5 zj}pX83=3?3<=>$c*gg`mV>U+&x7DT#$Z=|xES(%9lv%8S>YYNLk_CUX^4iI=hkqdY0@l~aq)=wg13$Ae;F z?F^)3f239!8sqj>?`4k4bLhM7HAFbvuWpn!G0y`xg27=bbdMiK2eX-2wZ9#nOPBR zq!h!9fDhLP-L*GIvkXFF>1Tu#q@4xRnr;dZgs2!O2Q#Ed@dE`w-Y2LWmnSSSW@$_H`MA*1GH+crRX`=zU5GdvZu zB^4Fi(+eoE@kqVYc{s{ouxy8s%>|H;?9zHw{4pHSRaKWUe})F*WaC|8?p9XAc+<7i6yFOY-v@!*@oncCb_$F~#{00!VW`o*5g zs}c8C)h$hsa)ysbWtwSmX!`}%gEXo2d_xU#U;oKI>=s)v=7>nR)^Jt+o~GW!yiSm6 zW|026hG|&2;C*g8rtod_#TAaptJR@*2HxyFw)7f&cz0ljG&mz1Jtt=DQ$|K&{@nke z60P;5?d^fQoz5k$xV_p*^bUvGAyGDnfT#iC2T&rP7R@De5L2#mRJ*FMubAKY2D!zR zXtl7OST`-}464x%DBqj5Y92EQQ4iR?MYj;sAr#lY71#*j7D=6c?jJ9u+IU zbI$vk^j8*bIb?HJ``i)zgoBUKO}XjdpF&wI!CK>p2^zCcA-^-7|Lxx&kQes6lAQkC z6AcWTbX;}T{82r(K#`=fZ%9qR4ph|lW0ug7SNMx`iot2M4Xf=f&paki;oS1xT? z5|N(kbx_kjt)QlQN+IG|x$&1f+R${92TjvOk_O(Ke@F9vecAp{x#zu?@&25py9*|1 z_qg?F9r!~&C0Pf*Tc;DWjadN-d9RPKua#%f?up#~vz)qGL;RF?l4_rF=i;neQ|slN zjihYpSUR>2XN6T9XrCQjyY<$)0Skfputs+83Zc$bLIk{bwCyNnXJ5%D{X11vaB)IL zF<;lAfob#o-{eTLSd3kw;DFr}Tk7Nz8#fm{hgm^iu#kWk;>?IVsl7(;o0Fx-?2?3m z@-m8IY-=ZB~Pq$?L-6%23O{ zm~+}z0B2^v1V2hr*)ZKkt8Q3G)x^phyqVoq$RE0P*jOVhAj6q%a7eF4%9OMbu;K}a zP-{t=N7!(R6m`TuLoJZw1JjRXN1zMEc3bwO+Zid#3yquV)RmrdP*c=nn+C~u$?gHw zylG=X%C$Vdzu#?`z+2DcGJdBNTXh;#bxB?`Smture1L1}n7^i)(*3!rQbRqvHLFM6 z^;?XVM4DEXW3|xvEV>B$_I;~^Jz61`S8uxO(S+Uf{>d4%p!R}o+4}F7QVHu6h~G{6 z)h865Sti`gOUUhx< zxei6XB^tl$3|r2@Q4E;wEJ?| zs?3}|O4Tnt-T3)$0)u?W8!0Dqc{ut^YY{E|#yVK$b;fKvE>Pg3p|;Qa&Dk!S z)ojPIWstmT+VP@lnly@%ZR$$N4Z?%81_F3*%2+(@5e6pw`sy#oC4wmLFZihBWB?AQ zV?EH?H+Gjm-VH3PL5JwV%;0gw0C8u6MNvsEUuDpG-;`h)n$P!MvTy>ek0*hVD7j9A zs^Kja?S{2(?u@GoAP{G^sKs|gnoNujxspL`)zb83EtW`apvWhYB9A8aMCde1HHzBI z{rS8(KX*7zr_)iw(hB{{Msb8ZcAkmR(!+eo4V>VVRDx#}?y{f4dWPbHP?{ zDipF3lFdSkUfBm7k_&Pi(5eCUj>q34)jB5<_20a>{MVTO$3H&2J|C(<&AU&Q8o-~n zuEif>z{@jN=kQzD+JigGVsGJN$#Nd=h?s9! z6>e`@vdt1zxI1=0AU3J_wblSOzL85)2dG_ql%>2WC)d1B%?UzT$p1k)af|)3drGs) zGy3Hy-(SZmL~c~NU9;hC_DOm914Xzw@SV9`5d8VL{WaDE6Fz}K%%2ICYmaxd0jaWZ zPZ%;j*RktdnMNX#xTX@WetVsby2igbd72lr-OVjSoiF9s$ZjkUOq1znfeoaBp2Ltgv%* z*5U#M**brv$~r3uCu?7FXL&v)2cn+Fli%HfV+Q>wdV@hECiPNY&Bf z#ouL}`#ohUZBxr48V>pTF5AHUtx)sNpCt=8_8)A&L@Ce$nABPtgq>3t@iasl#YR`O^^3s#0#g&X*}n;G|uf2UMvQ-0q(C-xJd zDPAJN(BfZEd!)6)03~|OjM_Y=zqPI6c3ZvnRy~*CAIddHtbfE9eD<*=pkzz$#S(Px zcz*r_=EB&@*nBPIen|e@JAM+M=VHh#=is*trx)91&<`_B9Rta}DQs+3_gR;5uqyp;XntgoMm(xpfDxOm@G2}vb;&cL$8t1t&BUZ z_4HWqY?gCvw~lskAs>&0D}&}h(Rv>n3%#sCCVjfFv9xQBAEUInc;-5kS+ z6pcyOs1m}~?4dIQQy5HUdP zPZ7P2c1)?9C98wi(JS$o3pZ|W-m4p!B3FS~B>eQ_RYx!T!^atiy$+4E@2xaB2-_}; zt~9fwiW51wc`PmgKzM<^MxC_a_FI3QQg6g8}T3nfGfe1ttO7Afed{9`j9ELawqc&VH@ugGo(U z6 z2Vd)jtbln8on+OTxmxhgt+Jr3mt<(w3U{$8#24W10jqrW1+I!=9ZYh{y(&`=>XRM)y~3x9=8|`V?nQpLu@>L%*B+PW*F0x|3PINNOQ*<6_At@i zbenYr{mYjyIiRl=^%*_cXgXy=g#y?Af#i~UDv$t&=5Y_Axy&#`$4=8G4Xy(Mn#On!XApB9uoNBn2k z7gvM7Hn3WJxbgd3lVj&``LDSTceIZ<6&QNS94~k=lbR_X)gdlRT%MLTHR?_4x3Ev9 zm0B;fr44#(ow%Q(n!);ak)ja|5Z&2!Kfl>MD9g9g@e!18x?MkRoNew|?Q9y&ZV?aG zkN&9;?GlN^D*Z?uZP!4>%fog~C~&s2gP^6N(rB5C_3Y-_Tp$!gCAMzpZgC2hOqdLzlaEqLVk6fZT;G=Tk;mx#Q?B4dERR6W zZ4dm{l25l`uQ=ioVLPq^BUll!N_b56$zEu@AJr~nHPjb>c480`Lmv*SH1Y&WDr{ST z+OCF?Jv*#5@;AeriF@U3uwWe+mA=ysRPRNPp3&Jgc5;0fzf`%yBeR-5Kk zhnm$>l|N6hnp%l|O&?vzJb0`K+o4$+H1#fo*Z>VL1Gw;%m>O02u%W^bTVRJ~*{f>( z8z;hW$r@@&5O*ulQ-KFE+4mwIg389@$<+H>U&J0RL07UQAFNIv)r;RcKDJc|TfvA< zX(>+Dff>!ZC{EGof?0zHi7`!5@NKCZFK<+-0y_G%0uK-v)K|d0c$*C z5u>Qx`Yja`UFA@4mrE%_C7KcuK{(e7o;oXA5#e=-H-6EFZ@AZu4hBssSj%YFWIjGkY@w~%+rA3yd4alf_P=%kW#d=28F}3_ zf)guhP~0~F>3;9j=+3h#%#DU`N?9a$3>_@QeLzhOYfaX42_N_^NU@@IhN&>5}`1X+*>n1{pF4UB{pQgBHfvK?g$PM~0nanw)L}kgY^`0$G2A z?rW_knY7I3vS9{QP=G1=sQlPl)z$qQj^SDX(IQMLp#Er1B|CRrU;(atN$|jt72A9H zey}XWWyhPyThXeM$3$0g{|9U9PaF7@5#*AFzsXYvLUV{b=MZS^wGDFq+MI*cAS5=g zh_qfR^d3P~QFL1Sq@QsZA0NHg^Yih*kRS64w1}MV5&5X#{y~|F*s|Q6ngK3W{Ke^J zGIS@HQ4H@m#`LoyJQ}^`-(4wi6vBI`n|8(eFKPB-ySjQogSQ&VsmL3uVb=~I zg@qT#mpI`TfgcbuD#RZ`OnJGIT8_tH3FY zP&@kB6sM$M7q~$ltk$V3lFq&Efw;I5Ccuj=dQUMDEW+K^ zDs4hdxF~Ksk9L2*7ElH~86gYotg=%hJYsQCYR&!l2SLOtb}J5i0Kipe9cH$KN(vYt zG6$Ny!rCLbF5rvO@o1{i9i*q{8KT5{q(Eq!z?DE~l|>2?rb8ma$1%v*+S4~r*pFPA za_F_aCLa)thmPX~6TS<&cQ>TJx!kQSLp%h|ZhNy(RUa{(6how7_tM=b0;cubpt~T!Z>N5s0-@bHRAt$@V>cpZ#Vake< zxY0?j0573X7o%zQi{2spsi#<#AhTY0-=}j9GR6MPyElhc9v46sK7-hPYPz@cM*>J{(nKNOxHK*;1vus^{u!awjxSG&o2?yP_OjrkHlTu^qbecpou4< z#GJCTO&Iv<08ClAMOBM@-#LKy@F$erd|3s|%p%nbO_0NBiMdj^Ly}Ef(^_-{bwp&i zjVJQI$54{RH~ELag{H`0i8bllm}3SiqDvcl1)sR3Coc8Y zw``CF>AL)`S0k;f_)@sdh{;%a{cr=( z5sqT}a1q&Ch8iF!*A-|Pq=ltQ+mvE-P1_@+0)|>`ZwG3>&i|WZAJt8t^Cz(pEG3tv zK9D#?9RGf&iqihv;AG#N&&vx5_U=h|>0?lPDCUP6F4&e?{Cl9mxy$e-d?ug8#!Bu%1?1ESC4{Z`uhJYNQ` zzVPSgR1i{oqadZodP)%S#`3KIxY!O&4H3cUN(E=3<5Ya3unXS$ea@OHK5T2FRFpD*vO2a1Fcv~5?4{=04tH0g zoNCe(gy$|N{jL2mo1V?D>|HbW{1z+WhO(~`_R_aIdQ}Uag>mibgmk@U9r`HE6bUAa z>ZmDl?8I3sIcnB*Q*NshxFiFn5YO_rH+}G+puKEwR?h*i!y^XMGU?d99RDRV?-ZY$ zk)vu?q%!$RpGYaK4U=kGTa+n(HNwqCBGET5Q?Fh$UEGj)L>NNvU%-O-^wkeI#9LO= z?vPI&_EOU--;o57Rt)9~{UD>C&I+Mr44^aCbYMaDX-ml`{33>JY8J>v+sWJtvOwy5 zOzYrbqnu36vsUD&v0$#&FT95HJJd1xRE0p8d{K})LUT0MlE?XDkJ1}nqi#>JkTP`A zZT&uSw7m>VZpu!vHaC&ydeFc8SK9Qg+#vx+l7MCVsjY8JPW_d2c5 zT&qEA8Hss{SC6}H?PG~F`Csm}`y4yjsy1O2dHhR`@HgbKZpMHVv&0HzIGRSaEw)fs zC~&nhXc?3&ZRm2*DW01s;!%{y3#f0YZ5iOzm;X|XRPIJua$9ZXz9@KDM@ZtCw0Y2v zPCySy8IA;@hlTty7J$4mEH<`EoS3xNvN~s#gjnh5rSjLJB#O%A*D*Mku8nY@S4dCa ziOd*|WY0*J0>#QlUSR46QeYAH zvfaiGfVl3y1WI&axeH12*c$-VB&}byFR%J?%~{Dl15jGs9C>DIkN@$s?Zsn8{8ot-{l}89sfoAg zK+zdIM2!yAINfpYZBL5CM{>1Z_b#_l)o1BNn2mh1Wr5fL9UhNLIpnnCkEVSRzi3sX zU@C8`vbHWhN*RwS)d?YcHH&LG2K>KRV2et$(V>Gv`_(t zZ@!P~lobK0d_)E-HYl2Ij2cgwWS9;&BsJpsE7~tCqvuhJkYfceDy!{DtAMXqB6!j+m zk5?U`Arrk;xr4}os1O#$;zAJM%}o*oaZ;+|QlOS^fs1z! zAJ+vxY^3@x4xuoM%rKGjE)eBp>=a4z^A4G-YQh83UuExdZYr+m9W-Pl3B3gQPy7+R z-)?FtwMHA|I+YGlQ(~qll;I;;D4=xSL4zSyRqRpsfO-5Z^_y0`YIz#OXs-L-F82VD zvC}VPB{ZP`;uKQ5jNlHZK8UHYd}JVtRO4bMOK)l8j*-tPB(*Gvb;A1YTG{KkQjmb= zb?>AsNJKh~Dm2q6J2f75n;m*jt9xYXH8vnQK2ghGLo8mqts53dcUf?^5Sf*X*5FY) zE<^{=ZNueRh*(ClrvCipk7*E|6P0F%g`7f<@G0SXBi!B+GDzLQIVhSV#E0F|!lHpB zr+RA@b`-f|N=gd)^0HiNIG}$mik(~YQe4JS$Nu|?)9|h|n;qg5>M=+OHwq3kb6UQV zPnmzh&V>7EDGA>)=#Nl2HvJy6CLK<*(n(O0Ji{%69eDI%Hp3F?O>(f_zyxb}=cYTB zIS4Rfn=nPaPYfCqZ8w%|w1|^%H_s~mcGp6EhtiB7RNdkul(oEuHo}`GQ^;2pD&|T! z%~ShXe0^nj%t$KY8oP*rQZrZZFIz3wC>Snl2Kw~{dZ#y?7VpYN_f^<1ffC%{$wi?UoEL_-_*IiT}O;D;}%*`baG%!O+c5_;r5w_(mB z`-$CqE(1)s$plBaWi_y}PexR2F#Ff9tudoUxAk2lBlKM(J<9`(%pa>zZacU4Fnr4KxiMXgG zXfY{n!BuX%lKTW}t!v78VoV{ZdzYiuk|VYS=|Mi0c!)g-tBH1Y|c z$)8kuFB070yAcYz*$Ha+!M=(IxsHLy9&-E5$W-JZ%W1GEfR54|zRD<0qAProcB7lZ zvq0mzkjgc`!|i>Uq_zZfA;KN<2^Uhh`p8_K^1+j2L@Z4`;DE(FNy}L1<$gp1f148V zwt_wR8Fa6bdlkLv?fxcv(38SarmI zinOl=ieE?6tMNJeB}kn#`v?KgE^ISuv*a8WcyPBi7D3kl3UDb+pq3vGc0^QMSK=OIgbA&-{%J`O{gF~mTdqVhbh8dne5pS(dNImL8~ zDiqX~25HA68CnR{Xo2%;Y};DF=7uc!pW*&W0l`sP;1G;I6Mu6SCoJlf+@~Ozm!xyd zRoR7Fx;G*2irva|2W?Fj#)QN#K4OLO{8o#){p=4)$HUl`E3= z0FwlS$6|~e9^iAF0cM`?s#O}&dxG->3C@YFG0o*lU*c%}L>~T+8^6pE+#BSkQd`;! zlszV{T@YetN>J39=*rr&jN%0U*?g(?y7QgGANeX+_vi-a5OSS^%KllH;@o z(Am}dLu?~gUyNfi1XNQ#=`QodplD4$GKwfA(+VmldY*Jp=)=IgDG$6n_<%}x#C3$s zb77~J_JWn@Kx-)SA%kt3BARIk zt2->jy&c{L8sh#=$9({jPJ&$$1}X@mz1u)z#R$oD?(~`BdDqG$dfhvMK<8;6gMb>F zBt+vxR|BA%^0lJ@(0OmCi}C`I{sO_Gcc;JTX3^X2|8$)~B2p%9SfQY$c!bAS_WO^T zwG`OQY6}g~PD5lqKvYk_9D8M>0El`90*CEBquQPDr+f7tD9jc90M%*x0Fmj)Uk~W6 zCm}MQAPT>NDcUJFrPrz@|P!W?7 z=zQehVfxb7kSaXa?!anXJG?Sk(UkWc317RE zt|DrPFmIC48rI!~21&(SGhXFhd|_|xU76Yo@y3Jl1kx)@1>I>7Dhb{|SBY-7j~uX{ zr*ZYr5T#4dS#N9AZbk(KNJxg3YF(S$>AbVgtucsA-3Btou};P-m33itF0OJw=~2Q#(A-<`gr%?Gr?fJ4|~ zCt0OuB0X)@#_G_Aw-`=gqow$WTeq7x?>A4yQ2ACsA!Jr8gJBsB>bhu^>HlAhx0X0B zU;6JvFqQF$&EtZ`5&zvm)O`DX4MDx3yu zBr@B!EdAf6op5zG$g)Y*a*^~=IKJECOOoidho_b?S&X#n_?B+QK8$0M2X|)#HyV}_BEKtY}@7ic2jtL2Otq2Dsg|&k; zT!D@lNCbJxuxe8D+oaOBDO)e=3OCsc1aI-VE|@8Tz5}~TLmA<1c%uY9j}A$>rK*3J zwB??%yD?+;ZPLDJO6ujLXw#Hrd2nUOK}B`a8wgf5<`IP-EU$`lgaExeQrG$AQpcZJj0>rL5Xwy1g) z55efTXD%y*p8ax=NuDsCPQNJa5fdo8S$=>_Kq#ko+UM{l?+xY^JfIS&9k;5#lQ1%MD*-IBZz}R zAXloW(`uBDFCNO&K@>G1UYElqoL;F<*2M2DWOcLOfef^|uD${w5 z3yT`%U^^1EljHs;w@|eb7Pz{6k)FNSsK;;dQd6;{QcT5tv>etDJvTg#sGWe9lA*9p zR5)7fX@QXIryCQ4uTR;vKP{hLc7}RwO&fa)JoT7V^ad*7s~oi;VkPh@(p>SGWj47Q zOG7Q$x?3-Mv!T<2^2KUyNTV^owA*TI(`2ONR0w;OVhSs#h5h@qpi@NMwf4Y=+C z$cNx_EK1NF1wHN3&0;Ice^vEU1W_#_zC>6#t-Zcim7)d7EL51Z(D4F!Mv!0yB>sQyRagD%FS`VG4ub;$ z+h%!=q70{)yam4^ackt`M$JEt374%`@AzK1Y#GXI4)J^|-7ZV>+8Sxz80P$TFrdXh zaBBG3HF!&(yL6a8%h~Cb+BA)_ zR`=L;!ENGJhP?{h(1f`Eo`K2}zuO(18LM16a{rJv#I95F5M4ABW2q?v2*!5&W7@jc z2~u`gKC6CLMV8vPDo5jWgAW0~9|Nb*9IkQN-}i2a=Xf6HdAReZ|10bk=U4ZulX;x~ zRqZ@Z*x~VK9dG;DFf-+?JdMt%)HYrM0yGblG*xGs6r>++Ua>uHx}$Yk27G$T71X}h zp6qg(bx%D?(|p49BI|(bC$Qn4M+FDJN3%<5^L~%n*0$8<&w{g^&3i*G5==ZEJX{S3e54o`^h{_%G3^${+2Ntfax{ay6c!($Z$EROH5 zXzrvQ32(!&q2R=SBKM;GpDo;1JAyq zdQ~Ih=L=J&A8Ps;T;{WE^h$AXi(LCHs5U}DCEu3(!+UnJQdx9UQl+yx>+$8g&zjZ+ zBd5zmg4>Bb-uEVJl(o>o;d6V0XExze?aMmbOSi!1v!qPDY_fBWJigCWUQ;-ebXWcT zD)X@|uars5>UMxT(WCgXvPHc3?gP6IjhB~}c6s#)1$zJ9khO(s-cfIR<}4_qhORz= z6nc$su&8U^k3*ZPJ6@m}HX;`JJf;gmUr!c9zr6Ftv0Y|jQKTO zqzeDylm?+5fmGFk02gwx{{fyvS>MrUWDXTHex10VRbg>lPU1AmLAQCv=bU;W?%I7w zcACi)L*w~v67#@BPII7Z;(?lGx`OyQnT;BiNGIj%0;(w^&1GEj%Q|Jwjas5(E>1GT zdnjWt|FH;z7uVXA@Ee@vF_@nyowjFvW?L<df#MKcSL)x)*I}t#0jJ`BdSyQs;LfW_;*JMb_j=k$%UF z7d?@GvnmTy9`AK2-4Y*>=SY_%>Gh3oHt6sO?oT!~*o?W%^IC>|?|_TmrQq>X ztZJiLt%qKN+3rT+#slNe$kH};@`e9I=kJ^U?VtV%`s$^7T9B(_Zhq8H>y~_9+2C}4 zp-XnAT}As?T8!~m-}MLY{+@w^yf0=oTBo+%q3^|#Tf4Lj-;HS$W;nc^^Hi;|w*t%khH_aHYW6Q=P(+mr9sOF<5az;WoB#zI*Yv|txlb}{=!l!`O$~n=Btq9i6cC^L=CHkOL=je z<(qKHYHuRqrm0T;<S<}KyI}vNnXWuPyjp(0*K0g&VeVBPxPPS$)#dT3eU=|9O>|-j`&UDK}P&8onvt`t~~En$_8q`E`S;nHR=RXW8pg z-Mu-92h>R;*}n~Fpl9}wtPuKb$nV&idkj8R<;I%XtiysY-{7=99kDzsoSoz=JBv4} zn7^1oeh!_i%wB$x)QJ%~h8dZpZ5*VXEo!PQl%Fyj6rx)m*Zc8JSm_OcHQlB-=ZKIK zcOEB6$*0#7oGmgVPQ3V}^<}MK06T^Gae5{9w4MEprs*59jjwT<0!?jOwm8O7pm7%~ z&Iw{TZsVr5WX^rAGDvEw2x#{_CFmvGJF^jR_Q$E_XPQlK%Ps^3IJ&U* z8J@lqi4VeW{CVFnE7bk`+tykN+YddM=}{rZ>di+}%J?S=a7Br3))bKi^|Q1si)42}OJ$%-AZ_1nv@k6%;288;s4 z_v6l&_%Ei?SJo3g&Q%JVw%Ge$3%D!wv)AkI=8X^6-u@6fXnFf{EBw~^_lqBAAH6kg zid(#X2mt}Gzd&FJfCW$k01N?VfxiI&7z@CHOV}~!%tRQ!ith-cvOg6i>rggAVNwHHR&0W5xdukbD0P4hbk5@Z8-lx{rS#!hJGQ zydURR&6laj8gO{p6ZhlUG`i8raPwly*6Wkc%{*nVh-roOrX=WFXTC6>>rLdY8V$t+ z<$|viC!BscYr(BHv(wMZn!{VUJA2AWkya(wms2xq>nl!A>=p;u%eegHjhkV!CE8x^%~f?P#r`C74eX#0F^dUC8_d8~@)T-g-=EQ$aZN-{m@3us813xz zqfd}HQbbRn`0n^Y(z~z(iOYu{Ev5wbMe|8RaJP)-hM_ZVz~y&x<(n7Y29ipjw$IebsbCg$&wkvCvvHmxw7F)6n0P~Vt@dZ$|iFM(5w?qYcQ4OgSgq#@t@ON5jHr(-*jTDm)99*jYlGf7XR)qrLMM7z4zU#fu1FS4poPD(k2rI=@F8xpsAit<-x-8tj%?C9)lx>wM0BB zdPKgQK}BlxfMnUKB^$ofOz(BQ-zIR?rs1M5!2u)$fJUdumDBdZH4xJL-1;A5EfL~M zS-;MEQnH6>c~a_sLIw>I?G(L!|E1Z;KI)r-OWN%SR&HvTbA~xU5!6bXY}j$ z{jMEXuvc+#yZX`sNn{m&W>ELiEs<7R9Eb*{+$9~u)y7Y+7os1^I?0$H76177HG>uV z9qv34g?O)U>4)>er9W-2R#tn_w($RoHfq?r=GC8Te61);r1lbNCi{A-hID)LU!sjd zUwnTou6`%L(q>#^RsF=(H{@C#v!#ST+o$#z#_K9)#!r6%?)LVZ5BP-b<*S)QjzEe*N?vV{D#rj-se1q4@{bCb|`VH zxT2x|zCUNVBZz=FSK#8tQur}|-!Gw&JLOL`z*Y@OS_@q{7im>U&bV?*^h|>=Y8h3I zfhpl9)A?@iB*|_K$TM~l!If}j*{D3ORspCzEGdZv7&Le2wv^o4Nj2k=fwNB74Pb9G z_)|xyu1+23%}Qs~qaBE0XKId0Gf;9K=r0>f*N52D`WdWDyPsx&%yuj?F6a9geT16- z9$W_fH!bWM@q-f<#Y7oNtZ=7#_nGbGCY6s2$fGGxEj0>M&4A+zaeeRy<1=PylzX;d z@0P$^FZ-Bd=s-j`%Mumf)@qq4u@)^Ls>UHOx&+Y|85#>~cNcG*fv8==Ld1`tHskgM zCpGw=Pz9hNB9~@((YeS-5l|62s#d3X)G1Q#Y_OIcfA#vnLunEPRo)BM>7nope(RV1 z5OG)NkzJ?%nNaM@@KviTzsk$TH6T`iM2rqcX6L=;8+Xe5|6+<+w4=BrUqxafPxig+ zn^yhw7N-V_TTxlWRZhY3Fpy+7J_$xpR$lX{m)ppf&0N~kJ6d^rG6yYP-VkPdYmCN4 zPZYFOuQd~`=9pjU&Fog+u3NRUQHVg@*~xO((55rdMp&-1eJ^j=HPQ9+IFQ;Vn?AVM zsn4g$iHLUq$kQWxYJx+dr@V|vlrh|W*rCgJ0881(%XoKK3zVS+@D}%40tIw1WdwYb=a6%9?%}gD-*O6w;^M*{ znLLHDV4d!kp_^)vm`{cB`az>FBWI6AEy9N6yLS@*b05J;&yxIq4>i}6ErERUsPTqh zd{wS(FXTIwQ@A|M(niBE*pt9OMxh4g^W4G)v4ZVp zLmTERLz{<9C6V*zeW}$E9s4oC=Zs05*gS%l`sqWt)Vx*;gCkz0>1)hR4MdF#BiY5O zcu?bWeM*MRC(xB-h}E2k=-dvkci7qMEPQI-pCzct(K1gGBT0!!;kr;06}6bg?yO@Z zNjljn^?l6hs@h~~4`BJqQS;(aOAj`jbu@K`)J0YReJ5#s`FbP|?mgg%=9wh|pTLmw z#t^qFyKvooo~|VRvq4*>mF&(+vlLhq&bEpOfckFn`R$*ml&(g z{#OYUzKY=#Ou&O>*w-h+54)74e9qk@0fiD9{(E}U>}q%H3mslDO9fKEaX;7!&^_<^ z&XHFvhtUOiI(e|K8_Pa*FRm8+;?Q!Q^q6RnCE+L!mh>Z2$DEDTpHa~E^_w`ww3YWC zehl|dk=A_f!_?zsIa!ibd>>=FE5Jre`;QNAOW9Il&bj1Mm8u9tKkpUkh>`z8(tXAy z`TlPMmo4tS2Z#e_IC7_es5o<$niZ~6vqCeo&2ld^H8m~VW(!wgSt0H+!%=BjjXFTKu7w5(GIgj&rKmPaY`9<5*#kKYKvim)~h7I+0$Y~z`g(gs7y_B>x z1DC-xy}8SB$Fo8kf2q$Qp2=jiTJ$9-ucF zXvPLPk>d>JLGfhq6y@;Ou+zI(Afrv?Q>UoAEu(F?KxaW@hM`oZ08s6wc9U@X0{VLL{K;i$P5{)1sgFIWYD5H| zV>#yZNnRiWSN9%7o!Y7I39@I2*g~K`7CwxK_>7f2B^1cIkmGU)#+R&&UFJ=6D9~0p zyQ53?@h{@^YxPcN>h1`L#xNsYd6b&V_NOKzY!SOo??pobsf20GRG#Yjd$P{%!h zx9{aM9`XorsMMorsIjipl==)p0K#=Z9;k%fw+P-l5B6b!zO`6PO=ZqC?V6)V#*l$` zw;N4bhIE(oNL*w}Sr#EqD=PoC&bcV*Mp*r?fB$RW|9{cSqX zNzOQk3?HWii~r0y7OnZVgqpIRmV8-PUU-i}a^G_+Ec6~A_YFt$94+sH=bncZd-kH# zGmOrgsP4iWSe7O675J(`O*HmSugsJ^(i*#)V5isIX z-B}kX7bK#zS1Md5X$DSga49RfZn>D9B5%G3)cFCTaV6V6Wp7FDw!Zd50CxbXTZQ%T9^ykzOryLTK!q*XlLO zkk#862CT5`JZ>pCz!D2jQDnvh0IS|#O$fwhSBRgnw-fEimm4@8w#nnGGm7>S5hDL$HykJ9^f`}DxRCv-+K=5GT**$nH#aQDdz)P=|wT7=? z35p;lO!52jSYe=dPzo@f50_D^eIy>kSIwyG1{blCvG-+IGa!{fs#2EL(PCX=3?z$v z@Ee^p8)dW;b)Fp&mb9TBxGWzMNc)>|35wynT`=mspzOtluP z7Tqumzo8Isb`$6FOC{)~MiBCY#h*jU164N@R~qjmmOTI~^g8VE%sD)EUmn0{*k@!{ zqzVhpxom|E`~q`#lxgpoxtVW6{oO&m7JPH@ zepG&<*(qKrF~O{DI&Esuzw?PvIj(|A@i;QWI5HHv`h-}nVXaInyFjU#Y0mIOl$-MQ z-t_WR5&n@seu_PLdS6rrab@Gmzm@82cuM?>mIJjQ(`<=^CE3!5P$=@|Wn>=A?#|&$ z$*(Vk=u}nSwvz8#5o50ux+{{z_OHV}=uKx2yP zn58B|qc!kHfm6=z|4!IlsM0#x78G^j-u6NuaKWn1i!*1LkKCyg_1-2IZ0ntTb2FiG zxD8<$pm}tm+Y_MO6{tD%#DVl}XHCp49OPWz>y|IS^d_ykt-`wRfl(Qs17n5`ZCTa? zqjEY;&$sg0N>ALkQnQW3-F8p7UAnVYHo1LwUG{sj7dVKW{H`Ppczx#d5+5EL z01OolnDb8T=nYiAa*0TKuRDlqb;y&idDDI6WyinX7QB2YXWfF=sEe@*+6G=c_-$ui z>OCEU(A{OK&TgEur)`5kwv9@W&Xed_qUDch6YQGyY*s+p|c!Z zxP>BOAmL1ipTJA2N&YFW#r8Llv$KA&v}vCbk{=Zs_j6dpSgI=YzQ(miWopdM210TI#>|Tk}fA zX;l&(6cKG4#)hXe!SlVpQN!!w@+ zBOn*Mk_gNmqH_A^XSuOI$~#H<&k_=0Dk6}@!JwHXw+M>GHY$N7;=~@oeC|jpAX4+y zVQORHh^It8KF&!M_XF5GeBd%*Us~SL#qHrR>=QuBzQ}cRl-(70%i};HFsQo=9L9xw zPa2cA3k|*QbIajMe6l7mDfLzLGeUq;oaqEPORdgvQf)!kNKSiXry4(5^R~0TQ^KJjkp-5PT)^5Ca0PRSEn1od2 z`4K+c(BXx_1j>kQV-#T4+&g8kCz_#cZYlQSZ##G&^E8bqUO*NX#l}c{uwT=F;vZr> zZXo+LJ(dh~VQUpcWMeC!HQ0+ygPjVk2BX`q5h;PHX_Ys}2dnRUrC#b{l;}zVQL0hi z0i{w8UqR%5IRHYklTJEC=;=q2{uft3mhIIvP#-oj51w zd2oxM=nYCDUd*8}_Ey4E0}_AcsfpZT5;RrF6sLb*&QwC+@*j(yeB^l`)K#cx_t@yF z$e4s3VnclRcr}?msL#g{^|$*1p!=?h+aLI!_6fIu=BLq4tADbn*1FcQ5JZ`m%6gx} zo*@OiRrP$7eCkF3e%P60d|)EJ!Pvl=51!P9?SChpE(!yRa@uT%)7mlp-#{WJxaaP! z_bZ^EgQJ*_`E4IHLMDLWYrs0{XbfeE#(ZD-a3-1^aR*&9AblgL3$#xVdc@|M2u1fZ zL3X`$1%xEM^d3Dh-Yveim#M-k{VD!q$+orAn-_2(i4Cr*H(O2CZa6wHCyC56ent@N zV2DYMbIblwq-w~pQ*78-3d~A`{G4Ua5U@!RKkBf(Z;ordN$$zSd`mmnwogco3)a^E z?)TqnSNHi5U|GeHH!3hu3IWh;I{OM(*bT|VNJzZ*c2kj-{vnaWgx>k#5JG)d+4F8} z=3SBCoeK(nhi_|S{fozy6ip>a6yht%9W6J_`q#cYQy@tc*r&lWym{MpeIL@-02Wg` zwgp5^)f_oln>1`=AON^0;$wl6~Vt zd;A}Rw1VL+Oi3QeDo0oPhA6Z}hV2vkU5#2&sl6M*fe6KH;Pg$llJu~g)N&UrmO>0n zy3r7loy7sgV#I5NSgR34>}$#_I{=>ae^JPpO8af!>bWN$K+jH!r}0lbLO~c#cM3x4 zm{7LS>Ry#ivEs~US3T-Ux9TPvGGtU78~Ex2rr|cn#_QmHCvys<)kS6P?1k}+d<`=f z0SDi#c$=iy9onOoAEIYVAa`<+D3AOin*%NB3vEV4D(2-4ULhuz*|D#y6Z6V_!`P7x z7XNwC!Odf8RIWVx8l~D8_htIm zm2ozGqlz~VR{OBiwevodUI~e;Ss@xf_y&1ibTFoYMU6wW#xDJT?b0exq+L=AJb&sq zpB1jK!#Ca!$f}z8mkN?ocQ@_rVc-gr0!?P!4wY9A!zVoaYYxOrF?k>Sn@O#I8+|_R z*0gXw75lWwS~E?{%vIsfyYYLBaI=KP{)OoGb7LCji2`E1eAxep$w@A#sCtBaol&3? zO^z}eJ5wjPb}^nr%?|2ZKU{Ni`#1Em6(x_|tdfm+uMku|G1w{l@S9;J=}<%4;601V z#a=bDrS*DAW3a;TmFyORn(V{R0bM6a-Jtu31m*(IU{P*K&asIFfN5Vq@SvLL?N+GX zZ4#=`RjRl_aSwUHKrI%%by(TfdmbR|76~`3Ixe*|$vxgF4=wlTN7UUgio%8n@93_G zXIASwZF_c+l-8rNtfl@(JO0!^T;nhO-LQ&8fXC+PCbl5aS7||^P%Uy8FuxZY1-Cl> z2=|}6z&RA75u38gC^Fx=MCRT8w~r=e4fE1h3?YqVsKyq~*i`ytlWO6PR>dvYRLB1? z+9}as+d_ks*Q+B}A2lq%wBH#3jRR8>KJ7_O`ym%{v}D1()Q$W(`-SSGty-8?w%U7U zVEN()&B)$h>7B=;rJ!YmCx}JeRJ(dURLy0gL==3FHQ0TA829m7YKY2S%~+C`exZL4 zPQfeXKomVg`}9)x;j1qo6Fd!nV!hH=7k!wjBdf!wvuJa+|^=}RXi zqhB_wlG1xKH7;oQ zhUD;B@4cD24a68(H;q+-a{0TPD+(5rJP|@ylE9hVKQiN7mC{$jF z4>WK*zRrCDOVy=gf3)DNsLR)ye)gPtB{TGp7+`%NUCvC+<}6j*Os4z5^QylyS++gD z9+Il{WXd*rWviJrPTNTN%W@ep2awtL^9GhaB+#ix>yL%SZo*^nXr)C%C4HT^csK2> zfNYPD66*OSFj0tT1jVKzO)GLYnyAi^&CN>tY43xxZI(oLf5 zqZ@A=o3y4Q92auukZzhStChAEZD6C#1?6$>tigD()E@pq-Pf9Hk-OE z%IRTJs^}o87f!V=E*j*p5Z&DIHc{p-DfFEfYE`a{*N&s@^L>D!(7k7Rm7BKJLa zgKjmus%HHi=EwmkHzzUaz3~Ki1Q&!pZLni!yy2;-Y?-54F&;xRrPAHKl6F_~Om!{2 zq4fs&j~%A)bHiYDbVP0p<#WjranNM+$4F6X2E=C`v_qnF=&E1v&Vv~PYVYbn7UIC% zi#~__D^KmvKVM(LNx*TVF&I@}V^zqayl{VG!Yi3&UU?*!t}7Fj6E+`h{(0XsgMYQ4 zJ8aRPp7e~}M=A=rt%e#k80CarpGK~RiMwem@{93|Ohs1WHKPhV%EI%N>Oxy4HAXu^ zvzCee&Gxj}40P^D)zeehaQE?Ej1FIJyr^a%HzFv-EOKwJ1fn6Xav(Da@a>Vs;=`TU zAZ5p5sf4>fFTPyFN8j^uaC0Cb$^ z-56{<^5G??FqX1dVAeu4`iRcZqaM-y*YerTT$DiTRWM*W+BE>=%Wo0^A-)+kQQb|IQzl z>9$<1dTVz0%em&~4VsM_70F6JePI?G3Fr$nvqYBwyb&;hkdjK1(naIc9W9AUrU^x# zvj>sYWQGl&rit!6mi|cOU9O^`_SjFQgyLP!7eMMQ90u|qx#`jA_nEUKcdfBUE9M?*D>&toTQ+ z%wIN#&{Wm5KPH%@ObG4P)!tq=l(^AT0@N4a)M_@?g$m#2(!V8W&kDXND-<^`L0(3L z72@F2h+K7EkqL+7WhH*3BbE?yO{X9x!y=Y9+a#yj<6b6tHBD*!5WbVs^1AyHK+`3=;!c z!W=~v2Al9Rceqzkvr4On*nj=!1A^o0^~e2(%H7ikv*vVCGBLDe_eF(%uCW2y|ih_H|b>%o$5-Qop($+o2u~IPBn>o`avDPE}*`;&onYUgqErR%2laC+N&G`B1lM zpbZ*Qwow`dERMvK^>0X+BZ006yX^PSP;sygnI_plLveszfev5!&a76B?=yBbWC&w1 zHW#y@k!Z)pdN;=&a1~c2bDHWZp7|Nyb`f(kj0JWj7dQz(-eQjW>(G!2>yD?_EQnyq z5ynMgMhrs#_&lW1^nRV2WBn01y?L4s5sJU!^p%+DJ?y4Vr2Att6KNT~EQTw(2-*$~ z#Ac?{+coCMqQh?#QS0r37-32 z5#LvfTFC4%DK&!U{*%ZQb*GE<=_KHqbKNSrc;{EqkeSnRLpQDn6-l5law)2-=&K-8NYrQtR&edg&7CT|jYz`og8LDi-0hKLz;qiDVU1TR{V zFrEiRwlolX>+O5M-YwvWZuijzq7n)gMgsj}ORAFqR!p$^eN#!Vtax+=4hu5l(yU3M z50sbe3p*B2^>LG0m&nb?28D>@^(#l>S1$Xq84tH%&gug@^faQbcV02Fi+SvD zL<6ayZZi*|(v(u{p*Yr~p-P~wIKx-$e%WWHSPz{8lJ6OXgi#>gCOria+`Zj7ou?tf z2hB1Mnpzw*udf44u%JM)+lx)_z!v!68~B~gBB3FZ;SpF6i-y?R(@_Cq7pDQmmNmQB z=zQ-?UjapHRDrV%GoGdowIgF!z&2sD59eg(h93oPHp+UzVu!)OtJJv$ssV<+OH^S- zYAN*Xu2RbIljXzK_m&CIFXMt+B0KV8~?hODhrP6c-RO3*f$!613M^$_a<0F^4O0Ig{ zE>|Tvc;)l0kOiqCFRJ2ZmQX<;Cd)>hEpd?$v-ypt{;rVqakGB2<*_O;6x3s3_`B;N zvFTy}pnaa^%^rGi){`Zs(3Va$B+=cNxG)Jb$z+LCa?SPm48OSC`vi=pW2PIE)+7Fe zWq)T^w%rY!Whx(bbUKUrCdB`*W@wkXUcJkI5vmWxKmpUN7T+wjk?bQI%5DC|7q@ zkX(T76&(>u1zK_GgBXL<>H0e+En8H;-UJ$9J|k?y`>0xmJ%Z*~Q=~|y6<9aOsP|O| z>Y)LWH}yfg{#XhpzOmQ@kTC*?Qj&I?m*Jj+q&*4d<=;klKeh>b?3vSX&im#sP>D`O ziz}yv$Aj1+bkV(3?Rl#Cv<%Nl6rKbhlb0pUJa<|FP5o{M&jK%Q!RW>>{l0O7#cH>b zl^eYCwbks(@G#ag?USZt9og&}9u~m?83fR@mZDUg#And_g#Js=A3RmtKU(B6RScR~HWv;VU&<(lZC)ge`) zU3NWlFNS_&tARxZ&}WGc*4oyG87`b6t5y2p6nU-tcx!%h_WsMOBj74{yMRmZuF#!( zW}ArySg(My>E5qCf!`_DP?32z-_U&G`HAM8U$dcm(iu*i1$zM~h}_4;YY5ldbM7um z++jWqrYtf-Le^uWb?1R@81Gy+%VR9Y_StE*dFp?&T@PNPZ3WbKXXM)L0oKFd|D_MeDI7StiY&GAa`UDK-c{KH7+}MAct^`E#=JHmMBWE4pdn z#$Nax9R|OelqOD4743m~l!&+a&_K*1_k56%KulLmMmB(Ekyl!9pQbxa)uGIov%p~+ zG6w`8t)!^WSmo=rjPHN@E(TPcPU+fji&IvXb!{!xA?`B|j>WI=`CB{pbQCJue?*1P zbe#6Noz2vo1Q-o7Wc|0xrNVH}h!89Ym!k?v0RsfD@Iiw^aqC2Q&Cx|)fwaq%KScBZddXi&ye z#c9BQH!4YK7!SPRGj`tXZ0ejnK!-%X*QJ4KjC9<{r1}NPxhaPvWZ!r;AJqRrf#h7j z6|};8vgzj>iJ`x+?aVU@(4A?)r0-W zr<>a2jRaJbh}cFitltPXqRNeJQZFJDI4@dA!(d^Q-^6EZ865R!m+=7j9Ex;FN0mr5 z$I<=eT;J*&6+oY(W~WhvwFyov;Y7EqZEJhQbbJf)`&5uwd?FibVv#@->xC%)g&oC! zjqL%|ta|eRh*-_Nm|=z>|7uP8ja?Pt55WCZjn^L7Q`5bCEDW=1EaEReG3+;%U_1lU z-4s%}mAz)mA9I_vz2e-0H0Cnos0m1^-vI7T`@S=K<-RpsAyHA{E4nANFOPr)J##a& zR0Y-{?hM)@TO$)eQ+eNJTH2x^o-^~h_^u1UF@2uw;$=J>aB2oHwP+bjWT3J?K!>jF zz^#ZVN!iLVHxJc<@a%$^TW4u4=GZU7L!o7#hvj4n8pF>VUm@?lWkEfBPAMuKY`l3i zB=D1x+<*OOy7(`*BkTL?tXiWJI+(ZBODw2aWmi+FLuw>|`EGKUIOAxD-#o+fVgwC` z&D7$F(i#5gYxx;+iTbB+p@tJrK%PWX*9-!t^&XaIG6Ci_G)1+Fjn*sFoCY7V-&ZWu zTkMEV{5XP|+5wgCJk}hU*s<+i(hW^~@Q55-e%nE>#D56+qZblEg6u(O9QA~Rpdk?z zwgZJAoy~>xGi9hD2-)vm6$k#wZ_?%{&?WuR?q}CyxuE7?Gt)0cj?tbnxtSs8m8YSL zzoxInq#rYohdQqSszrTn>Lo%?a-Y|3@JCM0fVZ->dyCuV9=8-v<1+Ix^1?m*)Xt#i zf`)f>L@K-kU~3QAeM>zb1u{yABF<3@@`n50XS5~(28>g4-T__YAW@jEcm(78Bvpk3 zFvftDz=o+z>pd}g|K3q;;;qE8V!gs>13^?J64jK$U^!LEMm@D*xp!*E5BY+=8FCG;g0+n7^&K7kjt>n9 zIVj|h9Myfo=U$#BkJ>$2$L|r{o^H1A7$V#m z;??Jh;m+?nN$O9A$iG!cE%q#upW?}$5-cJddf7Ozs76RM3IVPnF4NOa;t4*wr{7Gr zNbY33b{&Zf8h0PDiDvb}geW(7@={Q_*KlNA{~3^%@}#e}2jh}I?AQ0;0HK@mNnnuo zZ+q)t>`x`P(7ofMQ*kmW=k{p1ti@a7j@Mv^A}_mxa`T?!e$isg`0<|uQqTXd`)FIt z?LluhLL+WCPFW<5-u&^#(@HDb&ul zmULMod!kD6smG;*6cwaD-SaNZ$+K?>4~P$n#CK&~ee(xIG$%#n*a5B(WGoWcT)Z>} zZ-ly4{f2>BcK)KJJPsbf#1_xJ$9uw!zQ6cFRoAg3TBKhkz`qFNVX#U`qiR8;pJ+~F zo74oob6-n3o5Fx7ESR6r!yEaQ%N)~Rl=!@!cda~@{%LK&-cMdlzQjt?m^F$`n{oTK8ygJ??o~Cz=JBZ zG1m*qH~Usw!KG(%u0@l9*7-aSqo)w{DH?qs@M*+_;elLEqZPR=F!H_CBK-B`hH2~} z$9Js~qOE2`s{Z=}Ua$8)27}n1(l<$8s=Rq>i*ngEYf&n_M7;)XTg{ z@$;MJbpxP!>S~Saa5CJY+7Gdn0+0}4l#U@EtYY8bj<-+UR+|#FeAo}td8ZvYUdUK> zxA+G#n_*6gk|4z6BtiuEZ>MiT=uVk`GuyRP*D1*-W0jWLJ8Bfu+Y1BUe^4PW3{2`P zswSaTq?5QjQQecr!}hIy$hSJ{d-t093fsS zNYS32RT*^_;Az zEbx*;g?ADfAS)GAwoB=@#Y#Fvo&C{d@54Z3tpngEc;cEXYn^OJb=Ptx-PNC&yt+Sy zhsa+gHR&752cvP)>DcU~^^&A3ZR>%xM#KOb1vIysFA1ZIV8m8S{Agqi*_I z?DC?fF5|PZ+8_EZaQ&%qif};tE@j7#Q%flo-{#=4-{nr_*?^O@pb)FV(hawAUOI5&`Do}~9RAs$ZeX+5 z+Qzd#6Z#-gtslYYORDaE!n>6UyMz^kiZgF`@7%ZQiv?vBRQ}K9ErpyDv*ZESu*)xt zGd30)`r~l^tL?7bH7@IAdWibkLd?8q8q9V?x69=Ev+9CnpI|1WqdWJT6eRHI##2Oh zhP{Ai)uZoelscg>JSA_7DR1+lt!MLDiuRU79NfQD`*>`$)EsX3#CWV+v-;^E0)nTY zu|hXGp^_E76KL@vJiXgJNWHWEiFTJ7Q5f5Rma z6Px_tmiViEGGu*MXm9rQ0t3pF}9v8?Kxm*v6k^4kxx@HB#|kmtHB`Q#TS23b7YkIR*an z(rO{Ta+o6B@2#Y)r5x!0L7f1t5mV6z3Jeq@Mz8dj1*Sy#Xhh8phDuHu^bbhMzWw1h zrzK9Lmio>DsEuyAZT`?U{$oxgp+#aeuw>ML!820`?sH?P?->2GfKxju=tVe)j; zh%09Aj<1OnD3aLU*Zyi!sW$ zUWzj^Q}VyOw|wo2T^lv$@~9 z;T1VDqa!lsD6;*%BQ^d{RtK(iMsfwUNMtlqtWIxNKf*DnfA|$}Pl?`^mN~gsc1q2{ zt8N^k#zboyTD>(ns%PY}-|Vy+2OjZoCRl3#XTm8E8|XFfS{#ozJYP{0fKw|Pgtq(pc;biVh34)MW@}2oKcYxNYDp=X(Cmfk29dqt_&Zrejj`eld2K*tmrr@Jv)Jx0#|G96FSR`~mKC4V4iCjoSMq za#kqnT-wL;u{Qc3D}A>@LweB{v=zZE>-(^$H&3NnOqM0=J#$~(qLJhtWP6CaN;XcTzgI^KucuGb?FVRrpT=l|G}->cWtS1FNb$Fark`mYe;tVgHtSlv zBSZJ1bUx0?zr7f!cj9iwi6(_q$C|RV=#vu@*jqw5=@u?0QdwmW&u)4toN(l4k3!aX z$&NN3=;=X)Y4q7cv>%-e&xW@(W6c;tyy)(xQvBqCP9a@Rhw_B-Fap{9kE`5|Ls5Vh z;vlv70Or~=zqpsfZ{tVW5gx|QI6-%qPC+4(f-CxMRy+@iLi2C(6 zTcpWXrGiBwH*FN+Pkn9VF_%Te|5)ed2qs3>a`DSBguEqd(hR31PVahA?Y0ft z%SJ72ftD8aTM-_Pkzf8U=!#a&&-y|_5D|b*Lf&=;JDhW~5eJzCe9~#4I>G%9t{jcu z#_CZf1GYioAr=mZJzu_9IIwSi{dsJ)1YarjCCVczT1N6_MD4ZFPq9@Qw|J5l4t=;? zwcx`U4;&dRPRQ*R#~V_B#$3Dw*zHg6!EN~`t2g@&x|>SQB9AHr=}xHfRt}w=Q9^q7 z>MI``5HJjWRQr+pIC{+|jEyK|K__IUC$uvjJTe`h_w6|_*z>br`sCiYn{@NI-FOXO z-ndwpUIAAnh|pLr*@%_4!HFlDJFLx})j>_=%jKhfS)LGiPwtyoimx3?{{9W-tzVG#_czxW6LEL4sA`U*Rs$UP02Me=fUBooNI;5 zgQjKX*Sp?pmr@kIleOkW+AqMa9iX27rjWzU#`?W$FS#TY2LOI4lm1d7w_|rFR&_(b}0su)73wipbKS9&Y<{Dky5F{GSYpqhKCck^#~m;wJw9OVt1 ze`K&RN+Ta=7l4V-`Z)KafXr0ol+;M8nrC+rCey4WnPfWgIsAdqgRo)G+5P>w>ptgR z4ip|Ep9HF=56wIjd#59=0tT9C!J->M;Yv?dQ#0%c6}H*)Pu~H;RHQ^hme2rvYi5qq z#Nv&mGUZpdKUJa+cZwyQ`;OG#_kxmqz-&zIfkYKq8roPc(+}|faiZao?v5p3@UU)N za9ZrWTXElbru{+@n=Nl3mbT|ypSCGLa)lBUt1*4%YBOMCQ`{=_EnxIJHu*2N?A&0@ zvN|3Vr;+J#r*fdR?vm(7>#wUI$&~r(oQv)UXl&Efo!vE@?NUAOrRL#Of1kH!gynYw3Q%+U|twJ@p3MIUl=ouJ@G8{0GuIzAmX~ zM+WfXrrH|sA1&hY#p@PJY!#BSi9MYOQ+$W5Jok87VtLZVMx;2N}> z{xZPOjD;2HHst-3eQ?q94qZz@fQvgv$21JI%y&vky-ZaKhx2h3#GTL9k+OoPatk&& zQ`}ya9}8Mt7mZk0%*p*yDBFUjJ9>HZZm^@E&Z4zYA{0^qDGV=jjmNx7QaeYdUMwYInJbO1Vlf7sSX6k9T6ooRL5m1s5< zHtg?On-(;1vbmc#t#bOeXe#{Vhj!`Df$3lgQAxg5TuhxY8THie{HrUU`rTW&0x_ZI zZmAz%()Srvu+;Gx(qUzfJ~}=2oC25fz0?od_N&rIKVdeV zPZT)MC@#`yM`x8Fo^BQ_eBD7>`(Uqj7;Rt8x2&&XRY@bbV$PrF&mpW4*Otwc@g44@ zOHy2W&tZF|ARA$XO(ANcaCdZ3^XHIrsZ3QhFU8ZpYivpm54b8>T`IB+#`=Y31JJ{| z#;E{#DcOtDmjH3y*rd}FoPw{E?uvcCbZK$sq*3~r4Tj@k z=6#uST%=9K*Zw^M-|rVV_a9D_;WnU>?6B((JWes$`VO_Q$Wf zc9FF5?9y?XxB&xmDNb*ZKJZvg1La*B27&~u?9>|+SC3&$T{IJgcbdq;n#U(OE7e@& z`vI(m?m@L(mIi@V6-%^nB(H8LOx-e)I1m^ud#8dYUdBo+$4ILkZnW+GW)hCSGt20G zqJ);N6b)MC9BP+jb`1S{1o8P61B=kq`TB`NzwwzDUz0u0bbP?Zc3LHZH%uoFTKN#t zI+?|0ftOV1jW5~WfrB|VjgNYlpr7Yt)w>b`@_T7Sy$Xf3@pBI{*Q3A0THA;aZf*PrOE zF${q@hMpOnQOgo4X`CHSe-a;<>ucz51F{rTnR$YGzYyhQUv6Mzzc&GV4mD0y5^df>eZdOzLI z@AbxCal5xFRU>xu4AhwYQgnbtW^UD4i~AW(HwvHeI^T~u3Hnj8;oqlXz7{FWUwS@0 zbZ6(0#|HWdAwyy?Gj>Q#%hpil^C54*KFz8yxgz^=w#?fHRvqo4MMzu!Gus)g))7FS|qpO>mK&lD^HU@mVb>afzS0a@N5a0Ph- z617PwC|e@xQ1Er1-ZhBvrf0KrMxGPc$isvUa1VIl9Q!QOCnr0!*k;;5W3@HHc;&^N zDg(3VT`~uYgH<|6Rz{9|A16z!kNdf>*6mmyee?O3mQ6~x*8>_NlX6K>VU*4o=KI|e z>rjg^Zetr?Z~z}$@+ei0Su;<8xrX5tCn#B-*)&!2gnjOgN(DisIG8zRWHh3oAjk}< zXTRwgZu9Y88%xqWe&37G_Qh+*sqSX6mcpm9F$n8>W(|i#G4O&}5?!;@NkK*M9T)2a1mN9 z9N>D`n*?EWkgggw&rbsraBz`Qa8b)Ruf5x+Zgjrpc<++#>vVSweglYkdIX-iIdbty zYL;%N*uEpJPyUiB+#>s^>EB$t)xei8a2rB@3*sL=xhD11!+)#d zTV`XtN=@qgXl^>gWl#5>yA#p&6a!8~R+0kSv;qIy^$=k8hWxBc2Vo?o;IZoAvq|lN)=4|)E|p`)!1_DL%K+(Y9SU+#>3_?@a3D1yg@%?jHV~Gk; zoL(+k@zy2BJ&YO<#t-pwr!JH!l5!5DCjL~+N^F{Zn|V7Tq9bA7-vvI={Ih4@T31K3 z(jT-*Qj||pE%+U?)D=O1d=B?3|NW5p-t9dXLuhY{z(xUnVw9cY1tzJUX~E0bQQZ=cbVck6Q<@OWklH*;_r(tj8&0Oh1E`&TE z@C0Zgw_8)}>u$B@&;CKj^uF%?V8*$6!)zP&ydsg}_|=Thkg{5kyA>bc?~|`5wJ+%F z4J;mZ4k6D(KGTYMD<0LH&dtl`v78sX#_CYmu?aR-iPIbW&Q!Yay7KeoslpvEN{ZMO z&)GsoViv2YS|`u%UvD<~zpXUsy4n9;@gd~86$Qft;+rpV!G%Zalz&*pQrG7F|n%T;FB3enuQGCnxW=*5?~2WWfI?d-M$i}AE(WM$LUDvZI&@;K^-GuEF%Qik8;CBTZreCZcAT)tF$ zhx@fp|GG9kd@~WN5~FQppFcBFt8!9aDNo%Z^UMPE(E5sE1u$%}_u#5BzgmW?)eair zplMWTSwVygDbzjl@RdXA#4Z$VS#jXneaZ*Lfvg~nv6HsIe!aN6j*z#ao2XS~7P1(i zy$w*%1PVtPiY?3k71aC6^3DJS8Aqw`v|Cj~@|Q1V3X=qLVnc-CUo4y)v7cR6S;~)2 zW7SilgdRsQGU$J3n$U2XhFoxb`^rz^u(_j+=7|Q2_3^iQpj*k$hTw+|H|~6pqQRFl z9VM8#mpbb5p4;9=zrf5Y0Q@B32CBO-CpD>rVfu(p&+vWQt-8A);>? zdCJ8o6066HP}fiw?{*<%Ft$GK19F|!KiCliR9 z44A}wL`Js3z&TM}GT+H7bZ1sY2*?;Q?4NI}m;l@8Im@HchBNQNgN3VaK+qWg$Zc~>;4Jk{oi z^+#ZZ-Lw{%j>{J&D_O{|7EBP%hm5!@fA8yC*KPj_-E=##_vug?7FRnRbkJ5K3MZo# z%qUTo+1CJ*&6ng|(D0fiN&GI8yOQi^H~F{Vr;xqU-jE%FqwljMsr?V@Z3U{^4EtgQ zwQ8C7{hs+SR@s5EmLjWl_zMX0(hI{|25x`u*1Vh`P?-wbr zhUnoNyNRkHRSfjhvF#NC%$*U}@pLAvvU=c}H>~Bz$+f=Q9CQil^mmDGYz8RH4jdwW z)@2Pe63^$*#1{p?r&*4--MlljQOyE4e*v&g#lN8v=pqBf=hNs|4_}f&*!v@mROBTF z=q%>|Z{h2SW`_7rC8gLc$raAQx=G0C@E{@Dd@^LM$PLoIGmiuGt{gt~FM z$r*;mL-OxviqJhn1uHv@7FDAplV-c#OlFe~WC!p5rxOEo{;sPl>q;`#c%-C#>L#hR%~&2o?!8rgJQ2_GE{)D5$C1 ztgpMk`+k3yO=WRf8*SQ(Guxw&K`aAHni%oVAz{ujO~d`NUQbkP7n6rhL`;h1VT?Dv zo0VwkoglnAen;JA8R`V^N%k)Ks-ibv9!JWJ|6r@dU4S)yzZ;>hU*n}294svR;}CBs zPffhqCXt$`yY`gaWU5@PeUBy$83d}da8|mPh`_(w$|^%CcbTdVIyM*qtqlAJ&DRSn zKevcj^cbrAEYAM$&w$&>}&ixx}rkN+^C@`ofyx*qw~~G2(Jdr709W zBSHJNX787jXKomwMh#KiZ##OtLRqlHPXau77vzrx)7CmJkl;TV;>J< zb#yu&9OXYEmpUlc%qaP~rc)J@p0spg(;kkdN)Q@gj?GsWIg+tyuv7tCyS(li`%XtZ zv20nC0^Hv}oIaxyXzE0Isv5GYtAfq3oFSn3-@%)lDd;L)_s~17AIF2H-yKLUyVs~( zdDuK+jp2fYTB|Hy8IqO}0X)Z5oG`Y3qb&m+q^hiBDM8L%Vxae$O*kROOFd=h++J}h z>N2(x__4~)TmCPbA=@ip{QK&^Av`orMsHa)9GGw!dw2namP!NTcA^@7Q;C7IK<`$Z3sx@YfAf_Eo* z)abdTV}Td#1{zk0B>NRRj~viPc{>K|-rsG2Lo?w_(j7h>?%#k*{cDH<`C5dc11x;m z&Ae_z!U0Y z1U}(NLGZncW&)g_&A5#f*}$U6+A6QCgca#8$KB>Ee zn|$aXM-E2bW=!8X(3ZkzCkhMSJBVo%ls4Vnv7(3sQk75fM;YnWVx4Iz3{+MF{}D*d zFq%JI6!OHF1OX*iu)DuChCb=z&I<_t6p+Z`3PT^+_bc-G zE4THPI}h~YkFXx3xP7}460E;sHn-E`yli=VT#i5$DVQSa>b8A!fTu!oLSl`RNjmPe z_I+_CsVCQ_DH=mPkcU=n9x7IBhY%icId!%{+idTCq(H(ijiG+{(VL;QEvu5Z1+19H zK)aCTYJt77cCy)oUa|w^G;8eRX2CxK+zHp8^t&LR1gjE&xFs`h;?3Gj+AfpYO7}kS zSg<+@j&|;6)YYHVbHXd6n7biYSAk1~A!nu92RpF+OV??P-$GNQYn`3q+d-Z~g_gd4 zjgqz)6~S}OvqN2@Gkc_(X2drEX5&Fz!5(%YB@36)CB7#h!VfBNu_z2sq4|-zrIN@c z2CSK5Sj7m{`2worpanusSX=-J|8~v&RB}<=k~~6J%7m0iS=Qyvn6j}p$#++DMo?P~ z2q~SFy+5rUtB;bWlTtc)-!)1b?5kY1W*q$X85PLcH2qsh8?MX~M(rC(L8|`?&95-dJ?;?jpNLeMtWLCj$uay= zmzn4JJqon+=OZZ-e=h!L!K;PjafI{BX@H8Tyye$^+q?JgnEIUW*V*dH6g?=g3q<)c zOQCwN2|_MX>LV21qLU&q>5@(VhzCu~VvmFgHD>)36ZTX=A3nbZ5*I?La*4oL;|XL9 zLVdUNalB*0@MC2k)1cO=j;pTd7ro@>wT9n0rOoganKLs%5{lx0=H4R=KKv$zt!-?(v z4ph#A)afwz8`vya+LIevqqbvWmQ1>BgFyv(2wmn?gSP3@SnFWCuV(|Kt95*@TTfGP zU@;xSZ(I1o6|95$BHWFP2wUt z^Hf}k-hMoRW?c998h>NO`%N;!qazQMd z6r+b;0PQM)u?GuG|({hF4LNc+U(^;wfZpt+R+Owh}-+-GZB==iL<{!Qwte+dx zzT&9bkH_NNY!H5Vg1{Iuz&P2~17b5S{EcIcL!X32A?=l)uo`7~MMBY3&S<^fGB9GFEEk9UuQZgIrAmSnlAulEel=b_fiILSM7m)SjA4ETzX&MRgMGK?GW8Et zT+#9*W*E_Gnv-_tO0v5snYS5+)@@|cw6PatF zdwEzd=&-NgsRk`XaE|e44=f7LcgcefWL{I3?Qgf2XEM|km@HV9Z=3bM;CuZ_U*+Cy zD4C}U7BtVhhK#$t++Q-CFUG&cI@1o)YaBGnj8x`f>idVK7Q*F$qk~Oamp5+PFAEv* zds}y?o_o*ec_hq{81chGmc66J@-0-T=++zVqS{2JW2|!BcaY3ZG`OzCR8ir8_9 zPT4(**xiXXtDQq7Ox%0L>x@y*#UYb2cbnkj{s^4_;Jy<#D9```a9>EUWv0EdR61!` zN_4UZvp4F{qwN(EMl_PpX+Wg17St!#eQ*qcXuZ@yM##~2={XXN$^xHH1uDd0m8Gu} zz#0}xa1SOxdN9w??#@u5Tk{}9zrZH!c(C$2C{Vhd3zX}pWUDy^3x_l21G%drzPrIf zCxwqyM>2YJ14UGS{mC)SDi!vxp!s+3!X5OoP{rEa%I%dKwrR&%<5Ig@qSx8Q$1MjT zT4vFasBOuhUt~?in=0ao{Axo{NQ2lk0~~6Wf5Wp~(aQ#aF#dhhp zdmW&P35KEEc}}KT7*29f;1ny_wuEt-Cg#4#u5e5&Z$A5^<1G@RqqmGYutO4VoQSd2 zJ%@7{S;h(8Pi_zqg!^KZYfCL**7}K`ju0kwe*Nd_+nrZzuYo@jE zwar5+!V9@lQj~`nZcu*%SDe&(6PbIE69j;!6hv1EvBeFRjK>Cw`g^>P0hOA z{R%mq5i+g2-NS%K4vNvaOvbad#9MYZtl;A}JtAF=i70pA|Y7X9J|mDvxvo;L=GuQ%-OYmg(w6WwZ34TCQ5IHBjgQ>5V+NY zQ&|_KJ5p;kgB=Txt2@gvp;;2%)#1Z#YeK$G_IfK-)@@Y>WyYVlI9Bw*?ZTFY=BJ~@ zOTLEt+7Fk5ULM-knD)^mWw4w$H><7TlU{M!QkBqyY!P6lpgvV}kPsPPxos8(0?JHt z9ao$Z!H7Q`Q6|gl-*@TaP=0E($fsg|QYqAQ?L}_+(T6eFgF?7wLh0~jD_=X!BJO`z z8l(-`(_ouZXJSSQ-3>+*%0@(j=`_*Lwy|)V!9vdylc5@2fd@PYph|AgYtFGdx#^P( zUWhMO0i~2`#s-FQ@O9GWaENdQ6J*8}vt}pdS7FlT06BEwH3FvMXJSWElzL?P<jN`balWmR1gH zPx-iAvI|u>SwQLt?WANdRIz1$JKFpsDQJKMdvj9_36Luo1RTJEi$^?2z+S`0O`5#kkZ^N|Q z?pQ1fxMx`CiWJ)Y;Qyrtts~CoGcOE;I>hpSJll#V7em_!Lar==;x-^{1YCwi{P|#~ z)nFZ>26d$XEXV+UX=qTkbwX%VR*i5D2Xu&o|Ep%czXqqtupzF1DBndGEyW4_MONkD zo}X}gwJ7mh5{siUVVTZ49Kl+)=^InpB)P00TR1p{M=bA`8z(_h*G>m|S_jZ!I=2g5 zN~O#2UI+1tgEf&2A^UD+(o&+Ty(eWpkrA<6fIS;bUCZ=46*b8c>XQ^&RxS9QMO(wd zpZ8YgYu3~?s6=sq$M0b2e(_5H;Xo4Jf(f)n3dJf@>jsV62|}J^P}%})oQ|q)4Zw#% zYAL9iyV=!0Mf$PeePl>Af#$K1Fhqtb3hXs_LVnFB18xPr-U%LtVGy_oZ z1XOj=`hf*)451QR4w`)9TvzHtbDIG8Jr5ne82{jt+MFl_`Fzz4JN)UW*4?V@>!i zch&?5sNw=Bk0*L+=j2^1e94h)!L5?RR5vsNlj*SQtoC*S=3D{1nbp?8YU5$A4gD4? zTDn#Q?;h#A){ci~_`}<=@M;R!zY<*K0`Fp9J0~mLjuhrIj_;#;*3ZIg1saU8ka|44 z4SRiLsjYYl9>B*Y>2SOQ=nx&+LWY-Vb$&0n)=Y;({)lx7ob=>I39DakLw5dHYHOpw zJ6Z4^7ThotdKgPI5Kwg`LGoGf?)T{%ObH$t(IEIFJJp%9?0{9TSrHS5-alKyRa=nua-#87Z%*GILJc%%- zP*UlI)3Zc`!+xkQypkY9VuJLLB)|LSg@XWB0Z1|fS}zbaO`r(36g*voY5!3$z{+NC z*Bc|#^~>Zxj$~x!h`!~T-LHgEkw>)io3kKSJIVghnE!PalCWTVCNMbI_a598H3%Tl zp>13^M!V1UaocYfcqi#zJwd2;N9=OD_N-G;GSaAv2}eF|C%$TzwCrqVH{%6RzkXTZ zlgRocITH#vkqvdpm3%0DJGnfhoeWFI9{mJB*E#^J4nbm>LKTeU?(qF;uZVA1BGU{V zex)AI>tvu|f1QTr>wJJU9(>y#enPk_q)UYBcRQ7%$VDaJ9Opq8qjZc@8+6T}IN%=mdX;eL7%^|hY=HD2nV6E}&_7xO zYhF+P!y>Z0V(O9594}+sO`+>_1juZ^up_);4s>+|xw8ul;B?V%o4up=C$GjH8-uv= zYe4W|8q%n_6MjYORy(W1KK))4cI?nm$lwP6`bKyxW2~m|Zh*mxK;8dbdWKaEIj1zB z<7b{g;$M%;*>~O4U=Wu#88A2=7aJ9;193&BW7CaO<)_ZpJ?3%8 z;2Xd|_GHW6RQ%rL^`d-B7V!Jp{8Egq3GLB|7Sary4)!VkC!Le8RLh5k1Lz?264~FGo~7@J&$!uIV>P?MGyrr@d@Ko zoNO2a&wp3pJ!E(@G9-s|RhQ=h|IWPn;*(Y_;o5bLSj>rp(<&GW%~A{4~!DF$Q~n0LOE@ zK_;Uy)A1<-NhZdwT(S6-HL@+e*A?jYZ%vPEkX8{sJc+3rq~>oSBaW}`JHGbkoRKQ? zT;AJ{y=Kd6PkHOA$2T3Hac*j8J@f>)J_NawKhdn@AKpAy{bRlMAI@YJK+yw_zFiY+ zE>mS3>Uf5!dcSaAf#8l;>HnwLGuIUN;z3;vUhaxj?D1u*kk?E$Y-__)XUxyOv`&wM@{ z4@?8?GiC$PgZh5^^wvwhZtAL^x=F37l&KXwl~lH+u7Qb{25Jfvo;|-IrZh+qEb8u+ z^o!U=8e+s6%xQwj!}*a_uPv^i9-YadR!262``vaNIH`}QEkr&1;s{<8?BMVsDQHkfli@szm;(2M?= zYhWC(S!<0_L@raG=>dZcFnwF!l*BMj`VEJ!ZpG*?zFPg^2f`cAb1LS zW9NpRoX5rE259A+uX9yDW#pju)UTUoUQFq}an3hNI{W>{s`pg; z>*l%)b4>=o;A$f2BBth@5)Gy78~&@d=SRSckN0e={9Ww@J=2)GTfOhhS6Mhsn{5k*X z!HgJEKbAL;YBS6jykICXm1jc?F1n!aiO<-2zVawjDAf4%;?{{nG<~eMTMcsjQMs`6 zzJW-OCYM4v1KdC=aoM%f!2k1_W~Srg8mydD7;J7sSVq!eM(365mV z653h_XSVA6r4w!LL6LKxU-l@SY^`4^g*bQlmAfeXN!)bECcf8GG2egfWv52*!tULh zn%?~4!linxo2%}5!ut(J+R?e9@(L#V`IiWqFRG|OUa!rq?<*IP`mL%?w>B4x6onm& zl+2^Pw40)Fe_f@2MwW^nZDt)Ns}QpumHWJQI-nK5(y9G0{2$W9r~hP7!DwVvSn<^U zL&~=`cN%zsFzs)6(d{{5_F|@2zfMK9_t1quTa=jgCfytu*!-fC876x~ zYxTCRut}5Xtf;=>b3}KK39!&mgHQi`>-zdI%jkOEhH&FF;A8jf7_p8c}e79C`Q z&qH($vS_v{9uMi8pCs9fE`NgGDDM8z@3w_q+c6rw)R%JWmGMsZ!gu@tZf=C1*4gST z%fFQ$u-VtT)YE6kGQ9I$R5|!X*u^8YvlTP$;e`veCz>V#5ziT=KP5Egka6rt-M_}N zck7L3PvL%NFL^!PcIowCF>bn; z@NOKFT8bT-R*?8wVm)x0VQA$2Z2k^2!!SCsa(0$fD*dOywmy)^{F-a`XPi~lq2N1M z>`(u5Sg*3#ujZ4!xWhUolcRD`b&ENDgzGQy2Xk}^RG;E-2 z&i;!K=D?E7Q`uW`1DXzTx9^gN6d`*PTXO2M8Q+Vqh=2S3>QKVppQ{)8yW=lhGAA=L zFTOiz5^5#>Wv(c}$j4~L?^<)~8yRNC+N-NC3$|seIck(nrE==_Tz^mZN#!8hi*K*_ zTv?SQN9v>rcKY+VfLkBkAcjshu~-}tRa!!UH|xuu<%U$#4SB2`hrKuZ^3cdEm8B@aKBkr3$zyAC=@$UJ{9In2{kN8?tH z;xD}<;4LWT5BX%IK2Z=6u%i6>{S$W_+yfTOzXe;-g&5V%M#xuVPL?LnO?Ei~?>}Jw zbYOKY14C8gPTthKnP*b97PkDhUBTsa(uFjMmX}VGx4#w}P-*fmnnAx@d?U8_`z2R^ z7a_K{Gzu-Mj#lwJcL35D55J5x<*2Wzs^0LO!13m0WkqLgPB85JjphiG?vA0M?Cnbr zp1e1$PjWGnMN=I1>i0iQb2rx82?+;XedB%C8I+S%eR4b8ytGv<#M3owGFC+z#d9`( z|6?cfOQwqM^K$WIHLr&CxpmvaVE2UIhIN-vO6IDY#G(j^lGVTu4$mDOQ)iA|d9=K) zDMxGc7wxTi`MpiD-kEr2LDeN+`HExQ*`s(<@dpB=l2ZZuPkww+J2ytrxD zF7`u{t4`_{QabJ z?2akE$1hvUy6vv_!1}T4>F;As{Qd32f_O7C`BJn&%kN`P9{l6S&hhSRQjLo`obEr@>V2y#JT4~akN@JB_wC-6xVX6V0N(3$ z?>qP3$0eNm6TpG^^bf1XCl>ROOEsUnkHh0n)&B|HaP+x1+Y+Dh|09?GUqmk5|DTY{ zoyX54H=?C}v!?@-n=Z?IbXMP)snv^UvsQTGQGKtv<9LeR358Go3%?g`yiU0;XNnd0 zzr>`_{|jPLugIp99}fmZ{a<48kgUSN5P82F&661Aqn&}1H(OkD6+<7!MkTdAy=-=B z^YvtJ+w-f0%-;t-?u3rj$nz#aXAN_Nr6o@=GPZ2n=ew*+ql2O=H?0fw!zOn9(OoZl zBWFA7qr5aHZjo0_RhD|cEHvS2FJ*1gqP?ic-oy8OKHat4-*A9S=+w~x!a5B5ED`7u;T;W}=yf^s>C3ShGRGNwCEl=^ zbM?Ze0iT#0RZ5x9yyCoA9_D?29%Ae3*IK~AaX9$DFS!60hA7HNK_g6ytl zqULVgSQFypwO%zFDPJq$jqrNbdbK$F<47CA0_kfDv(&laAR9Z9IIdJ%M-$e+8wSYn z<@M#PC&XEGlwH;?nO}<1k@p7(7nGDb$|plTCpDOBJhYo$E_RSsCY|C$_qu0czZz2$ zucg!0cTO#|t?Io!s?`}P0#%d*Z@X_azZ*m|Mp3Soo#Dd{p* zbfhg=_L@7A_ElLn71=D9$rO1Iz4fwvi%&n*7!_KKQ+%Ghy{wb;0v^vLqj z9@|@T8aoe*2;7dx57`Hryzon?Pcg1_ng)!iZ1Fl9(qvn){hSZ5$Yg|hui4KPnt4?0 zneg!!We774H&e9c6ALI-d&Ua6ZZ_u^y7t=n-wtcK<@m47jyqp}e`0o(Y-Jv}#mbcF z&nUmO;CsDX)Phx>DQf<<8F2fdqR~F-kD76}K3q{{Q-xnV`1bJGkNH2DXT;UH#igN| zX!hRlx=;MGU+ZQ%UH#kK7u6YdCE7yfJD_8K*uJ`ZbVpSNlp$b=A^_k_3UC>S z8v0Ng_bbL6M16(^HQYh(L2`(jW)56@Eo)OPsZ7um?Y4mE$gNcgEj! z{9Dgy6PeawxgLSbGjH#7To_bMs!U^7@E)en^ulaI?z`f?mH8TICO;2|ON5S(4duXT zGzobLtQ63!0B{;7UWo_E-6mwo)=~Bs`SHh(A-8+$u4Tv{od~ft?7mFzIV!e%l(#__ zjwdUJOhd!4xA^g7$0E6*i4j0UJF0yEo1#mwfd?{CvQb%~7ESe8{=IiJi*Pd8h!%}Q z&Ql&}Px=s^-%w5jmNZP{Vxmf(SD93)jx3|DK^=`B+8n$#|K;p)SD;vh>Etg1SXGQ> z05S$x<$9X|i;V2~@4uY$y{MoLR7sX+Lpp^B-APK4iE^b6lZEd*sI{@3l% zj~rEnl;&veF$f?1nvUUAc;%*FRSeEKqn14d$~6B?>QYfpuNH)lXK%+^3THFyPVZ!z zv2Y;+BdzEcTVe_1OzB#tV6<$FEZ|4`p(E3I@Q5?EOEUcMXAMB}TH4{_rSGj~$8h^~ zZh#fJj_x@B{FC=gdQ_Q8C>LIzMOmSeMl^l9A(`C)aV`RPXgsoU;bFd@@j zDrSS6@1v3#1DW<0|4$8f;j4>l#st_g?WOCxpd&d8vl}8!gTfy2G!fTb8>=5O66a4F zg__xTz>nk220yB0giSjg(+O=9T0&iL3(Z3W(rL0-stCPNZU0Pzz0B#ua)Ve0ZdxIJTAEg#L=&(4so+&G((MUDXo>0P3CaAc;u>4;j? zh4Bc}&;(u#G6x@(D=*?&w+w16o%L3&Rcoe=|FDJ>8_KAg_wfzU^nYxK4&p}cLGIu@OglSp+Q$C` zTE8>``FS^%vwZvlW@NUqFHsB4mi>MN9=m9#+FA=WsG~r7hqsD#{*-BG_MX2qFJg9t z1&|KR=P$#JS(QzQ_>S=Baf{T8BaPwcs|*-_=}RB`v)C=U0i?-4->Y9ubnk62(; z-r|tz!)b18PPI_6xw#i{{oMq?X)Gu%rbWBWoZk^3($D#>`hDSDm;uON#)2vmP00Ea zt(@-QI4o90ex>R}Ma1%trTlHEF28Sb;}ak`G9G#2vI2zl)rge_sGn;n5ba__7*7Zm z7}s&$O*DrVzifQ6=NB*{yyY9C;iI9*5S01j6klJ@r6zx4B(ZZsCfo&bTnU(G^%H=H z2XD^HUi)jp?vytR=Ti4E2j^PeyxDJ06>_|>{NwsX;OCRyGy)^-?p7=Uw6Fe|8W{F@ zARk|KPJ6kyD)h^H-I{0FGyjGyT0fq+wY3+$f=s@A`qB*CAJM(vPK~Ct_G#4ob0GHJ%X3fnrr3+!W`@opsiYIm%#1TlEQl)ISxGwT>I=i6 zoH$P})XpuSH5oEUPhB#Gx^e_TGeBb!P|?QRkPHZA!*~KG*XXbiuHY{z@#%F<3y7RG z1?$uc^c4`kbH_5K%H$mZ=E)JXdAvRCOr}4kZvtb+d=M5&^nge(Q=vUzS=pQ~f0}ol?YcyQ1+oAF^XdP7MCvDI`_+&F+JQkE z28A_lA-m}n3&)L#z{h#Qx^0K;#=W)rt;wm-Q|*WA@!-!3z|=@!$TWbjJNlAgLv+!| z2>;g<;V4pGXlb7O&*GKE5}K!!r6=Gd9VUOrk}m+MawT-7vTHXoQU>$uFevGte0{87 zDGcgL2HbN3S~J4gw^3sG5Qacuz$}c!OiS4Ehw$31qkAQ+`G6(Pb?e`cmmAfLhL z9J7&(JOl70+n;F>DMJr_o5Sho+XV>l4FD2IfI3{kTnfU)E9|?O)Iq*v;tcFkHi{L14}j(qf*pOajF62XD@z z#`y`qZwE9CR?Vm(5B@6uhd)^sm08UM|8Y9KCT?hq1DY~D|0+XW7B3S!(vND!$?Qa- zZIpfUvqglC=ZzKXuIG6Fk_9X$1oKLXQRAh;9gcucdP^LnFTMOAkswpO z`~v2Q)NxT#JHQ3r%hRHfy(wuKDb=}osi%c5)fD{NHxz+B?r4^bu6 zU9$D7w8!0QFMH7M_3&59;9a0SR&C7ucw-|#iw@wi0I^v3ElB0`hRa;4vqq`z&*78z z1Tk9o)S^$-``@(>tSv|wY#N)CWxOm2H`G{`@irw&6*S`8a=PG_nLU2r|k~n_5?RN*J(%!sbHYB&RG%iwc-odrzW1FbIdgO46ylh&T z1&Ztosb|=?kj}^y)Rwzg>AmbYV}?xqfGR$=uc$)v(Qn;aT36Areb=dG9Zr&kl0BJr zMf+D>E+lmoE}i?g?AvI2g(oTX*QiW9?UH*l^=%nuX&h+D0bZ!FH*e0T84d$B$KpmN)T50w2%Qp{FY2Aj zGeBh-WEW(YV5CN4U*mF`7uqVtQ`|ge-;ZM_KHSh>`i;|E(uwZ~I{NC|X#g5?v@p|_ zBGI69u*{f5txJh+%d@b24R<%r>>E&O&=bg-`*3ARykl{kp}pN*;t5@5>$=M_m=9Ba_L%EL3$uakKI7J2a?HMQ4eWa=ngj_-S}{19jFw%&_KI6% z+gZK4*XqElR8Z;xUt58jNH$PHdpCoA>tX#sK*Mqf-)AUeE!w zA*DeDnvm{pXkopRR5^XYnN0vwcIdCJu)JaZHxkg^RV^EQSIZgXN`J(M8KH*u#F2q% zf64Xf#$T7B)m{QR3gtRIG}Ou9OI`N$1c(GH_qBJg$sb8e^O9dE@xOLA?4u+7l`G^v z>ArCR%2n0rQvj|6p&^#5BoIPuFcr+M4W*Vvx`0d!9hRq9A_u_oMId_tV2EG~Krl!f zaRW~Wli|^NN$h5RG@7SdRPPw*#iPY`=jy> z$Mh>&+~IHR$R?z9xK+ST=V{(Ww5?M?G%SK;7b7q!g6{-yJe6h5kXu^OiU-t<*`eus zV$RX~JW*-sA9a6Mg^SdMc(Nv(3uKG|z~53qu$N_fI{2eAG+D&hFYU2`h@Q%*y9c9l zF3VmKeLW~trkN>6oGa9AQ)(c}V(YUno_l4zMgt-1!S;CNpM?ermlbt*h4o+XcwxqcNh%XsxmuY!d0J;sLsLeSwjo$xk94}FWbA|H<=O&e*kL#Ntm#} zO-RHfOW5ah?Z3_A2inY?Y2XkN;GDGeT-nwOA zVHUbihYqj>KqBan3_A3~Uua0yo0xk2%$4Kz^RnF%oUWwhV$R%)gOC8E@05?>*jz`A zQHn30uw)5+cmt&(g~FK&>}yq@`;8LU()39krI({$Kk;7qbCWp7SDDZDnRb5Sh~!g1 zy&Jk+;;XWODtZt6{NAwqh^rrUp^0=z)4-K09kQ0RGody_et5w6p-?{MZ4O_F#6w~Z zx;cHmUtddwNm{upgC*ken4VW5S0EuQFpKwQXkSl*NS0Z(Y0930(E6LX3-e%DiRuAb zi-4q+=i@m1oeOp$D*6ZKELf@`EJ!k&Z(hDhKL7DZK-X(oDe_^^6OAy7FJcuRfxOdJ zo3mH%^>3U2zc_j(r3mn$nDI891@RDhEt}~6bws$CJLk&N`)>7meU%w+% zhSjXcx}o=g5hVU^zW#d&ks-P;0}0KpEy$8C;JeWL6j47?e+TWv4@|X?pkahB8F8j6 z8P^BNL(?SaYvp^U#L;$7$QcrBfFlAZweP1xOK3uvt6P{yLWyLs`j4)-d&Ax<<%Eui z%k`J!e4SrrC)AtV2x38gcsbhgtniruCt6CtMQEX;ribrhq4q?L10=6n0pZp-_pe@> z>DW5-f!9q&y*@>gBPMNSvNhCq*vHXM> zVv=*nUs2?_sBkS;$Wt2oQ9D}gGN3)R!UYu(mf?OoS$)Qfu?A;bTG=L*`u`{PYcx^Q;iQN8lyC3v( zu{U5qhuu1KlrEgl`)}+W8LHo1{boGQl>q57gxXycu4jQ=9Z&q*f%cP@gdzV8;o&rX zC^6_RJp%wf1r@LG-H02=MKr+t{rXVhmKK^0sVOg{3v!nf*!X;@3!% z@T9^V!&+t_(?X`8Hya9G?b@6t@J53y?=gY664E1FU*YIkYQU(^ZqSpDeG#tYlGNdTxCnV}q_VQ|?eCbu6D0T<#>H7d+u6tCLqGea$tQxraRz|HdNuUEhr` zj7-SrWdmOH>vi-YI>UuQdau<{EZ1XZb((J8r{&w1u;E$mdg$w`JCTEg>Cze7+!6)L zs@ESYv@hLR-Bq|gW%`MK3}@?Zts`==i9qBYK!k!(+KmZWktF36dPsfRz_3# zyOOPl`U?P{n_L*JfoUt8O;r`exp0H^WH$1-bH(x}zd|F6h$LssJxxuN)wQdRA zO+lXel2*YtJ|cu!EAvgYQB&P!|2la~zin2n!AB>!2`1%99E4!J*zFT}{|1XhZTNa+ zxlht^c6F%dZ#8KPE5I<)v+DA*=R3YT>n6Tv%}l5QnY^inHcC>O7r4Pv77wiYwEcK~ zChFND`?=oU= zu9@$D8ZIY5zO0GjPHU9)Nc&@H{HtyJTAAnhKOel~X${IZ)%K98n7D~Tz54lozjEZr z;s(R-alG5zIcggdBb9;lmOlS=TUl~F@L^b%-`;Lmv zmvyHIjM=>F&l1n0DWsdaf>{R! zlO__2JlMf7-HH68b%tY#&CAF}M#cW)P?lSGV#HelL<>aCmK_iX2RGU*^)1NxIytAU z7b@!iB-gpF(c}(Sy!*AVTucfCh?IUjKISP2R4}HBRInTj!=w(W+iu8Bva+$Q6vca7 zN>C&oq=orzg$z$LIo$k$jV^`kGcG@Y?SzUh{K$Ns50F{o)%ZRFw21K6Eu=B_WdbW*yXx%!!5q;|eTTViNW_4-c_zUMc?PE0lr;c%0X|Uo`&6(o2$xsQZQQP;eaehy8euu4nks*mHW1;joH{z7lKdj2R#w{Ur zCP~Ny3y_l?lo4?+GFjsu-J2P7unVI}P3$`I_U3*=@j6{C5lsjbVcDveW~lJ-)R1Zk z)uC^!RKA}DgzgFniFoQ{E&qlCsLk&0EaP5CG z9-oRlB_7B0pl1jHS=u~J(mvvae^xadRHK%wPf;KCoqCn`d9yjFBfsTHgQcQoB~$4*@uNkI8XLDlP~vBoZcAoLx;k@c zVGVIVVY`24n#qafSr&l>&}d0!EAi}T_+J?KWui;C5zg)89)XEk3lC!C^x{M+1{Tnd zCLJ5fHXs9}{RgNiU5$_97{VO%W^Y1F1*L&SxnOEW!?NH*1fx~y-Rw0j5s6k<)mKr{ z3XrcIp7+jX!mQOr&zhWK1}Ha+qv)b2l_#Ujmr^qE!)hG$7PU8}4-2;JHpND!5_)q} zS)`_8i6m{`b>NdHNSCqdUuO>dG?n?J6DIFX!PI7L5G{oTXA%mO zno864Ov(_Q2dJOQ1%tTMETHCVa8^ni^F;ropW>5|w6okNg<;bBwI=~X)(^nx!HVom z?rM_6oyuJuU-)$CrCRM0`%Ha^H~i=0sw-UfP2k^MRcGJZ=EfQMtow!WqO8_k~XYb0gfpo@Hp zeMvY|%VfoTbU-7QuV9 zZx+c3aN&sq2V`=#_qQubv1ugb6d9z4Bgkk4w14tkrgD{SMTa;2_N$O;#aO0k2iQCC zhBue37sA35SVSohH4Bo!lS{$mcw=rW(iIMs>um}^^8Q5$m>l1Akab6Y{wtQT#9~D~~ zYUvV12Uj*LCHTX6jg@o8H)(91T&!GS4bXYiq2sWYVp7ee3J0$rw=(;|)EVFcTv`5b zsg!PK;~0k~U^{ZzjwCR7HaB+`K(u4(BubQlkb9-g0qJC?a+!iUpa~eV-=N#pC1=DF z9x%#rSqB9Tuy^1&zBNO&{&%?+@Gz-tcRXi%KihEzMCB_UnQ2F9!;bcYNe0YD9f#Mq zN}6Atb6wQzSb{6zfx2Q=+C+XpX>BAmH=v(wYR8rsDl->HOeNaNSfCtXdr!TY!&8)E zy8S?$=AWthYXE!BMUK@PZ0qQ#W2q-UW9w)1f8wsQKwRI&Q$h~$Ouy^bNVgt6IT<8YRxn5tgeAB_hj^je&(6X{m zR`4UWbHi#bt#i@siSo|t3bLO}H2=V!z@e}-t%W$NC{Ht(#309DXB}!F+}777vAt(@ zzzMM2MzHIO3S*)-Vm?PJlG)DVYVlnEQyX|@H|RYxVk!XMS>ha?zgoL-&3Z=Z&t4_P zSeA=&pWPZ1IR^Hmb7*{UKUM?VqHM3$4xCV)4Y{JaF6Dwz*-FwkslnRrAxcj(n;SV% z9dg$P+BH`wTP8>iN*D2HO|LT#QoEWHDJFzSsX{;U^3s|8GsRy*SZ)TF^(-x{@WAnP zxFTL6wE^w?5O93E($n4R6Mv_F<(84J`bMc&f}8qz^`1!kFe6q*ds&J)xv z=}cDCW_FAxII4Vy4H=S#m)F`p?oYALEJbNNl3hmrC$d27l06B#^N>{-q27qCI1yCG7k;~qlsC{IK zV+zLreq-)612jSi4yBv`v5QJ%*=d1u#J;@HP6d{P3LZBWMlp=pQ-SLovj#PuHc(7i zk`E{EVolvu_=rE61tIn8_p`X%#C*30kjPoRTotgbEDoOs+7(Mrvog1!GcV-pqW&;1 z&^ZT?!}HCxX1_Z^RXUE`ivXehHi6Z^Kf+OTjw*hrVfRN*`% zKY;`a@6`1uR9wt{U})eCCd~l4`1u-ikXrDIg6&t&yv&PME+`2Z`?y^#;yrkF2i&_v*N=Yq=_cYNB#C^LiX9GcM)n=VXpTxQh4^ zz&M)ySE@Zh>XxQ}Nn?g&-ORVk>TWomJ>Ma%Wgw9wG@Z8t=+A&Uk%iC25LaH;R4YLx zB}j|R##fRA+#I)9pi(JZ!D>2l(iC1)>iQb+=p7vV`7P-Sn2@5KvIMqV$HdA;4FoySMWA%t|V$zNNKYTO#&lo5g?}@Zeyv&tUn)_I{o2 zGU3Xftkca(Ciyub0+5j%YwCFI?l(-i1{KYoak=%**zAjPWab6_J_VJ99`CNcS&%~v z+u4tEm)sSecO!EWy1SIsp>gf_9^k{x3%Bboc#}cqoItc6Pz!^Qx4Bm!TOi;_tNGuF z_ssF-J>0vXSrra&e(bf@&@pm7#@(HUF-?rUE+-U9pR$F){lP~aIaf2IXTl)d$Z@y6Sk^8HG z`{o1wZyGus3e0^DxY7rB*9!Rlm-*WUy;6tHzGboC1v{b~QFfPm-2RQ=vX?-)_=e;I zYgJjhtZ=~~yYZ|}lthlWLOT>%uSy1Jt>?lX?(ti{i}AMzYAmU|s!zhtz1={oAh0KC z?XPA~ieFu}6uxk*#D~7FYF7Ez-!KWnG+Grd%^ijklswce>FlMduS>;j%YE~{VqmL` z5hCM%pC-_k&7$GIWfI6Pwr?mk$Z{(>=V4G!tl+4MaJ-?T5ZrvQW-xnu>ErLvaw47W z#mzY%UzQ@yp>gq>r$6)>Gp+3)-y2oJ?7&9W|BI#wUT5$Vp@n(*g&xD>+8;@pu~Z*a z>trO`bS6+sEZh^7ZKYZj<#LW8E(`7~yUk$M7k9r6G?oo#etHd9z_YBRB8AI~mb}N> zs|W{fe2b;uzB$b&cXzaZ1>0L+jHqIXZ=qGaCGVgeAOaa0+-~_I0p=eH?JD1AIg7O? zY$XHjU(r9zd`3G*HWaVi?hpXLJ>c%2up@TaoomaQ>rB=6024v>sUNTiQ?6vwdb*US zX!k$+OupW{^(!$GhX?f*Z`+RtZ}b4v$nC|ILLv_w#lT*i22?k~M=ikrHCG^i!xRPM z;{0=8mzY1RK02;T$qRO4&7L8RcCz+1L|x{7eS`Xb9Ox&GzW}ZX?zvaMIL{dDO^OXT5%44a%vgRb_{vBrNL7z zn1QE6Fme6t-6Z2=#si#Pt$V=LYgGU>12%(feT2kuSafuyw4akmW@6{k*x}+|hhstJ zRtN7`jntG$hGE;a`qH!g@!5fP*^LJw0p#qNbL}l>CzOpEt&M5e8 zxf*x}U)CL)9gElfuL=knhF@}$G_u+5vG+cXLM-q{3MZMOlKrqe=$2n8@X#&Qb}^r% z!P$C#g6*lL-M{@do@Hln`TcN+S;+=nIx3GaYu|kNmD}x1DHYonV()%ntD{ZgKwS z&>GGhgvu(J?e|j;VP_X_@83*XtTB0tQ#6ed$1>lQ-#ER65#0)8-Ir0_iWpiyiOoi7 zn0yt4j(JTYvm)0(EL@|NOcjB=Xa~Jo&?w_@{YCB14iqWB7@tYOl&B&>_ zoVtdNywIi~bz*hO+H(bh!@1HVD!TF|F*v;XZx5a=Ynl2o`fC!?>qt@BPuU!mI4;2f zaa_SiKa8LFMkZ%Z4nE%mL-DXyv>h%WXcmUJ$XF~X4I;cIlaMK98{d7*V)z(#(1S5u z7m1#dIhCpSPr{9H?3HRn5=|&{ON8qSWrxfBCxhs%9DnejjAaAKP5(*apiG$KXC9kL zn+h6497>|jgZy2sR}z70-TmuY+s?%cfo`lhzg=j39zc2j72)2{`H{DGdBfPX&IbEPkFG9&z4Wh!cFXGiSh?YTk{j6Ew|hL+DXd$ zkrlBI!&HG;ihe(EvyT9*{(HowXEbHM*lt?({Qgj?O+WeRKAXu{7u6O4P+Cj9 zg`to+hF`3*&9rWGiJlGSgq&*%S(i25qQ)t@$ZS@ne`J{ngXZ@sdQ6BAVJ5$1&2!;D zfyjWrjA7%~DKwOM(k5Ot`~)-o8OphZS-`K3NghV*e5V*3@5|Hf-dh#sPxaB8`oW@Y zi6t^mb}VRrfQY`vmNC%GRmK+VSr3V-=rcZ!q^DqExM#w&hFcbVLEYiA7Ncww3*2LA za_9%y`fku)#n*}FtO4Q4MlB3B(#d*NTC{b^YTqs=`Ks@Oom)LaeTu%jMJQxjyXL8{ z!s<)5-=F>W_;gxD?}5x^lYZZ$YPv8D}1mKnZ&bDgu`{PqfCAI_y-9c}# zi??pM@y4=Fq1I=-{vX;uKdAYZ==A>-?1e)@c6by+mv5No;k*Ggo000%Lb{Q@M1suI zr*(^4A{|B?n5XvhSe9c9X_m69{yg7so6ut$r&b0XLeBB}9Lds{8#b;Yv*k+>eim~S zg!H>RYo?yo21a9u76$xC$hi5e9Y@~oKCg3ANA}{%@XygQfd-F^mrDcC@J(9VY$%v& z%n*)K&T^16P2|8@X1_>8Rg)3u?L$H|zGKIgL@@2C_EW_CN`6ZJq)u&zuWZ*gl6pp# z?Bbfgb)5(}+$WR9X8R%EDqI<^e2j2pFn!`^a_9TV(&tucsxWK$jwwEj(n_Wf^NZT^ zTMB}!*XU6H1>DlbH-c#ExiX{(diZG_<@j}G0?7qiLHP`3jM8#vfi;Sx?^+xqi2XmI zd&FNRgt%VO&UnYSz%i|^jMCKO$ykL=9g7rr6*iaxg+6yR3b>6z^RI!lxzs}%zuisb zxmXeYMGEljn55_rrlKd$JXMV8ClZE`9nb!#2 z$#j`-*bzgAnsG$n5@$PJN8|W8+af&Ih7rxI;~uV?GL6=bVyRsywkBg&n}?`!#rF%(-; zZf=Ud_LKW`xcyXFNw2r=9Px^8!yNq1gFMvu8pv#gDKCsGmrNyLUZ33cww`*uOB7A< zRU6`cZOZAg4nIreb=$C_Sll*0<_nwTqczJF-3M^EOPT!qgNFMh?ma*f9 zDCl`|S0D4v1Zzfk<9V3jNGSQ+jLzUacVzWvMcXH zFsxlKA;QP|dnN9UoHv@niaNaa1(6UMHcfpy>1KWH(vc&_bm}w=x3rX|-Z7?Ep0&{U zLw~}CWT>Ore4@6uYzyPPpY40&Ga;-~!m}+zpXaXdAbbp=A-u9mMq^+GM5?W|I$aR; zFm{a32u<9Rx6C`(^V9!GbmCs}yIr~O>Xhzs?TCIVcBe=0Kr) zJ>1JBkixx3{Uy`YJL{f)#ZT9jFe3BN|}x@bqJQhOLN0ssBJK3qAN?= z!ZjAKjbo&6(XX99$L){Ex8|kA;*)F_flkNev*jXI4s!jiEzTT9icc_NPmI-_rXNY! zSH98p0$L_Uo_HmXZ1h}-Wh?Am2h>hib^u_$AE%do1brOXRf{;6GN2j&DGzUvS{Rk8 z*#uaM>vq7|#Lr~3UvO~eNV?Rkl~LH~jI;YVXS-M2?@=D_K+=0U&n}W*vHQ=;dei&T zAm)6kehSdw2Lt^TZIRT6O z{H{vr!Qd+N>eKL$r)#ZB5C|KOp~%1s58tOfcnJR52-#D4A7=u|E}e-6ziwaTp0^JwCsf-Syg+R3%ERYr8fJIO7r@rZ(lv#$FUk8!nBXWk znJA%A#^8Ey_BI2cq6tOLT8N`lS7qg;QJu^9l@J8yJd8{0t9mW)Iivfd+R z2{h2BbK~382Mxpk<;lkS&B0*Ca07Rmkyyz6g1hN`d!e?dgUb`jV#aA-1tKb5MDBbM@ix<6!a7Q#Tuw2MOEU zCulBIFER*=?j}@Mll})lNndXheFM-c5mHGn9hk$30RBzZj zIx=`vYUHOBb{$~JX@xrb95aQ(W1hj!yy6odCl#Ju9)OVU;u9~OMXEOTz7+g233o`9 zPtpPgn=eAf+6w? zSuZwTM<;xzmC@)+o8fJYdY8WYoek1l1c+GquATvFqA1H+101fqS|c@O7G>2mHJvm+ zqFc5AmZd({Eh5%_V5MbjrJ2Fme=d4{ufR-t`Q}TRO(_kUAG;r7FA?6+sS@cFiqTjf z1Vx2`n_s>?Y)aA5b@}#E$20`Up)RpK53%PDnURJw)fb3PT5%!SavdU{7?C1_uxvqOKIuV1y2sLzF zLYiDiHNsIJ-YJauo;t77weIBo)~f!{eN^$jc+A~_PaW&;puSKxvJHMTSVKcEL}jnE zo*K23okddP_@j5b=~=P7WJPC7!eRnb$#vJIitgv+`>`?~%Iv4Oc6Xq0U0d8Z=q|k7 zE=~;s{h2Z_P`N|=Ug7zDsY4f{()1moitl8FE1wtWYaC22AF9`+pK(%BPXeeZQ}y^F zV~O??>_Q6CvHe9na(@z8^x@(0*GEr>CD9T4&A5+j+|4rBt%)=p2jTBZdSNhYgdbeD zuc_&0yX=#hitu5^<{(-ZxVy6HTJ&Ct|I^y;$W!X2r=LI$Lmd(fRnDh*w7TdWKSsk) z3D)J+U+6VKP|7!J&cAFB*SmB>2qbcW<}}c^CkpnX-6YBVofx3>V~_7r?81+w5~FN~ zDfe3WLvETMAJK*QtmwTw&{NMZPn|D4b^c=UZ}4@-K7GMN5R#@6w#BmLoewK#+e&Db ze5&3$K&^pk7x21J(CHB_{Ah!4C_K98d3n+8$f7pexp#8AD_gR*(cVRJ{UV?JRNt?Q z;r%|oLyG97{hHE5f9Jwh&mtbNH8S?ohDZHS_{gAzv|kxTl}}Murs`O;@Iw^U*Fs}j zadg-$nk3`f$R_b97oG?h*x`<(XTCRElN+)nE58Og?Ej9l?|tFbDkW@TJ~*03TqoB* z=Un+)w?a1lOs<*rwH}nbUZ8&$+wzo16=0D>?P*!RmLY zegU73W4^S8n!AN31O|+)i3*3X0ExX=)0(PZC>ma4k>DV6G0;Q|v|M+;_{&Xwm3knB zv&kA}ytxuILsnmWe0l9#+NO~Z!GG!`)(7SX{maryy#FkY2ZEI|fRB4(ymp_(Uu~3R zN9otixS-Z&ke8wMQ??A!yluSMyKjtKY6BI zegeYta~**+o$u~;v3|K@p!?X&)>WN_Rh@a_$dBCr7O7hJ|8ZYe;d^9l{^#h4RCzb&km_Qo4$2t3K~f*g zc(LvD7Mp~3IkSA@j6TRrSLFG43}r{r?(dEGb1}r(L;p2E(Mi^h?Slv^RGAC0UOMTf zC7G z*L7>xubQ|bL799DMVm)`E!uiLad}Xw=ToSPkE(#G*#xp|5u&p^@(2j8E3GNjq0t?= zM+L-I*IfQ=um8Wvi)&1h2_LE%e8^!LEK~2V^Zsh5I3fl}vb5Q->%-ejA@fb6^OqYL z?}K-P-8X{KE->tr!1TUi!(=;eK^1;|TR)I)Fmr&kfHuQR0&Q{P*3O~*Avl3-Kl_i(Ch9V+~QPAqja3_kzgn^ce? zVR9s``MWQsG876w>{ax6Yfau0pon@&4g(- zdAR|8&(hf>u0+p7Ilc&;Se!I8uyq#$2@S##*quq(=@ImukrKf2&A?#4ViaBY!}KAs zyZeho$Jq{`8+Q?Plzv7xG;`?@ycv8uBG;=!zaUiy5vE;uHUzn%@3u_THenabc-CxRJUO*+F33tYum(Gr?p;+a7`J* znc7p>F+O#cvEp?BboYb&CuSap2nz@No87mbc*j*3K5ez|RK`8W>73Pa@;gsvYHvXb zQnu_tylV;{gySAs^t{%}iw4!|fg#Cn)rF#%b$7eA_IeOvZ+;HFa2P zr69Y#Y`>w+@)C(&U#sg$VNDME;&i#F`tAIXh9ME1cQLw`IPl=bogj3oD^>IG90GC-P&*;)Ht&4 z4pke6>z%uRENkK@59bRZN&|xuSE9ozlyqRed(xUUUrVo4OoD2CK-xTXmrak#=cp#5!oxBR| z%+#CG!y3j=54-A<8~H@{vvvUYhVf8?#yaH)KvPsNQNM0`@z%PS!}hWx%;A)sXTo#0 z+s(0YA!NhWv%Nn0b+m@q7qbn{+-ChFOq|ikv7!J^@Ag=hXIEAKaVqbbpTUFoXJ2?7 zzI6R<{$aBQ?D*j;3HiYIbHX!rOo-B5PXMHCtMFE~s$T~)`{JJUiU&PW;>J8XvovB& zRPXN?`i1C>Ld6yzPp?Piyvn4 z7SbIwXXp@NO5XzNS)D+xq<;Tj3-q117Zq~^Dt}JqFrU{`Px-Q7$ZvOrX z(aNNQs>eWbF+#;L774ZApcmuPc4BeT1rx1qQLN>?Wn%2Aa6EMs9p2V(by)4#YyUyb zOyt_UwX z|B zMGR8Uei9RneLytN)9vHCx^1tJ`S)pUSP}WfU>O6|ba<~L{Nm%P_y5cp=)ArDWfQ20SVSymK0F>4C!bUbM4upAv|c5{Bps9Q4fCbB zd}gXb_^WR$c9lFWma1T}KgV{OKss$ebJOwvVN%ib>2DTVIC_3ZY?O|=!u?YuDXmft zO;?AIXR_3sSHVlU#SBH9S$l>1yA==g@;NgCjiCm5ZN5<7ChO-5u@)Z@*#wX#!_i43 z5H_N;RA!cp+ul%(-y9-*d!h?5qvl8hj&*wX6$I|sF5IybR;PGPoM-13tmheO7``$G z+dKFmML=@D^?OKdpr0+T9HlecASJu}{Q+*D#U;fWVwzu+%XRv5Q({VcWz&PEoBd1Z z<5w?6{|y5gq`tsK`8DNNUo-+-I$oL^#VU5j`sh6>9p=4hAsDU0@MVW9CI0ZZyo@fZ zJ7oy7hVkpc&+)^6|Yq(Tkj zGeytO!e!vob;;icnBb6zk&wa0lv8r;y!>3}^{%N~s^{U0>%ESrR-gMa{oV1u*I{Xo zdUjg;Wy7oCZiWA-#gRckq@zKZB&MMbeP~AZaGjz#-V!l*jr^mpmsavm5=x(Yw$NhE zbDuK{J~UPu+9Xb)FMsfknuZ^>{`uDDetY2epOqdvf-m@8OldV?w(n$ke;R*ZVE=bD zq3m#6@!O8j3Qd|1M6HP;bFGvcwgObNASAY8T{+j{N|j=dFhd<*?Q+Umu}U@#&reEx zA%7+(yRGY}Z;;K%`z;%^h7dD^&I!0U@w>74QNw6?>m*3=>Jm5}ILbeLQ4R1gqLFbFKe=b4po$^6b^maWT>^_C z*7mg<$t8P3w%ao0cOLOLJDv!1KI5(Lbm-ajzEjt{x=fxNoYS2kkNG9EZ|hv%?s;m@ zN2T3v{P{5H1w~wAQ3|7G?{0eY+NS_e@6s}aE*+?Kn6CZ$<4~RSvtr zTV9o^!sI58aktcGmuRXHf6ne?E4=A93eKON!DHW842Xe=tAq)b9*o-b&Ie39Gz^d~1Q zwn|!`Rea~|>=jF7{P!sWa)DB!%Az(ZO}Fw#-MRcB*H>Ck_p>U_fM0ce z>@hHu;|ttuFW()`R`NUiI_U7e5CKyJ_v9sHdlE}7e@SpKF2BAAgA@Kt>M5;|{q{?h zzrNHq05jZLp+Xa-JSVz{VN6+1ftPmYoEvoBJLXPh)BF(2L?jb4ed!gB^m$m<`?<_w zD)jD|9N4=>k6(D+bD_ZiKxrlm=IhfE=Q^VvWwW2*@gp05wAhiJ=aonnAU#sLMnB95 zFto*C;S>>E#*CuYmUW;!+8(vA9ihpSN%_~uq?sP@_y?5KKgFi(2?M{fFkJ=xHn0L(Nc0iBV zYz1&8^D$43nq~fK2mTd3@fAEw->C#ZBo12`?$>qeC;ZM~{f-j+4)WdGQXxq){DdBc<>FpDVox_XsXGBuQP*eD4rRG8Sb`;`& z4-PJAt3B2}GftA_5bX1T8pU&R3+*MO4}x2zhpL9$y)Q>kt}p~tq3)o2IvKhZzi8en zMsxK)&g7s3p3o5KQ(@Wa$&J!I&=$po{=%k)b&rx3sU#C4IRT2$uXpB5*5?Tnj+pfQ zx!DEQ#1~&fLxX&3Z@5Cgl<~YJ0nU=ImuiY{dLJqV^Tk+`?!sSLpOTL%YM4(H>nrIe zv^<(qb?>TSid6Pp zfc`yz(xf0CX!#=Di~o--NMu1W8JJYU8(sJ_ICtGQe9H(oel^pQ(wWRMS3-DMgJ%;K2QE~^HGC&tpR{S zKfakOZxBwlyyt#1MGEZ@#4evxP)IV|E_Iu(H=ly>uHnNvrz)mR55GnbdIOC1#GEb1 zm@ESggIbV6#>r{7BmXG-F7v?U+IF+D$8aJ@R;R(JoN;@W>_((?+)+P&T|=&i-w7T9 z$W($`sr=&I+wh3`I$8CPH=xe3jGk)ycgeupCS}*6K+{oHaE*=FO55C)*XZt{A>tZ5!75wk=2|GFOe%jG3a^p(QkQxIZo56@nY+9AH zz(sl zS&RPmn-*Ou)7yVPv}0d!2_qk+Gi#p{G=9p#)&r;amuh=nVv~D|0HT0 zfiFsXdzQj?U0o?I!bMT>VtL}DJo)(D33JYzFWPTCDTHJ@a5Ozm<_=0N1U zvB!oNJ^9G7tS3`LY9`?_pWh8d{S3O}4&73mb~iUxE&ry5hHN``B|?8bVrRGEW-HnK zUF5yh~tGqc`tp1>3dmf zEs&W|nqly?Lg@Tlkg;6OQqX7Ip)uFj!#-;NC^28NAv?(ui(ypS^V7N^ta=e8F$>-% zKwis&d#9pDm5%&ls&!z_++hcbhTcy;`_P{y!(~iuddO4Fd{}dsC_S4v>ih0C@I24( z!4JbCATrR+_ap}9DaI^)srYw7Ly7v`Tg5b%Y^wJmaiIx$uz#VP1qogx{NlNMmubT> zKYfL`zP0RTZW$2f2qyNy?!43>Pr z?RvP@^zG88uIPREA$uMsy3#_H??ReBdT;cY=yw4d9{Q>EJ+e`q)3$zzz>u;K;+20r*7CiAC>{dWHYKu*K5DKb zeep+N9?-&Nr@udaFM1|+zlR|?rVWSa@Lh21Ew7A({9_TY42k$ykrWhSP`D?hDht>D zQa?EyWPV75Fs=Z`8Qv%yZzR-u&n8i{O2KiA9ek!SwKbU8DMWO|CiZJuXYi zsBna{U@VCCKg||MDg%iED55C8J;fJPQ(j~&srfQxNw;CTue>UCyN|wOGzidU6kOYn zooC3{yVp%O%$4{*J0BQYN;0=jVpO_l=K4F_d_>oWk@t_})G`rgWrca$^9H)wAt=cK z{r3UDiK^edXQ33m(LVwg>@~KlqgqYz@Lrnm zT|ngTw~MrhBFxKqfn{BI$==z2`q;)BUAqdQGvZb52DRU%%0J09g>j}`S0kz!a+lg> zADCeFuq}Mirg#{~%k4q6wqYt{IJeSJc4nwT&NfvMn*Xmq3g*kmDJ(itI`c;N4-5$aA2RqGF~76J0^-R) zpa}bWLKL{F0pL5mGvimdQnK&O`UaSh@tgpkRG78D_Iio-BvZ+Z zAiJ^@9wKI(*OfH_D3;GvTodf6Du@K-`28KoEO6@^|l%R1NW-ROF{MR*FbHv+da|}Kvxo*<}aOT@;NTnLN&>l zo*cEzlUzk3fUkEqg=6Mf16R1e|EkVCqP&&t3}?yKOsER-8l zUNT+09&xBj7ZS%n>^fUzBZ=!WSn&t8FuNy{dk=dE~>i^h0`Mw8Go#Mp&h?!!(_}< zNsB~_{Z}e_hcP)?QoZpVx~%m;&N1vRjXUU~y8FCW+yh$GeOJ!bnU>$Vj@yowzs1=b zhL?6A6}{#c=U=9EZi{Nxyg$cs%}+6joVV5{PN?0?Ja?_3v@x=vCCXXr%Aab~>07Zk zEfEnQy;~_C!)8`GX+|~IQx;kGJG)&Fd!3qO?YE}|2UuUlln*Pe9Vy!y)@s6k_X)go zdSP5+$3P`jR^<-wm8*6!eQ<|-pC5}LGEwl+3z%$iL28A%MieQ%a~;I-Q>{X**>*w} zYKNGp6HI)6y_B|j=_)R$(XkMr05v` zqe(08=x><`O83z9mvM||N|*Q$pK|^BEodBHr(e_Z_5)!e2-bnF0IIeT`+lStqoJDg#ePAdZqomu(eeFF?K@|A^EC9HPpvb#W+r7G%yX+$ zdi0*_JT|Jm4<9IFJ5*N4O!#fpN(dRH>7#a}RtBq9(;~Nc)UNR?4zJ|2Bo!IZQ0p(9 zw(mYhHXgj7=s~t&c2Tv58H#9HR#RnV|73V~p;>?F69MSnq-e(}INLYS84@{$x<5~@ zl--(`5usyA-sRnSaH63rsnE$%cGv2-ti9q!MWMkVlhr}=cJECP)@zeJ)aNjL_)3wo z$MjM-jaT-7cPXs`p%z3_dLtiT_pn#q-)j!6T7_R&*-7am2T5E1;13aB_db_5&&d$5 zWZV=B*(fhvmiOU*yzh^-qG}~PE*ps(U4PXq8)X(h-DfpfBw8Fipo_S^bEjx?ZV)A} zlLAz!?U;}c{FusqKun7F{~w`trRm|eMeEO7Dh>lbu4c;x93$LETPpkkL?-`f_R)W8 z8-$%4x-W_He*CD|y6tQ{!T!F-bKWTjOL8!vR_#A>n3={~ol;vbE98G#%w89!(oXNBAvjM=$!R z{CKO4^m`qS^ue=aB`HeX-=E!nMbHsAY+>u-S7{=?p`q;>Ma?2ApkI0KND~Eq?K3hs zea~6$8J;4?M2Hq9R#j#t!wfNVFefs%G{TLe$6%tGFJfw=#5VH82%kla8*zdUjX zG$kkiOcaznvy3VZwHO^20o3+~Tfe?4LbN`ipaOrgu%X@~!`!Wl1 z3>p&auwy(OhneaCO&3(yYrq}{Wo6lTl8)8cX!Iya62zh8;Y!_-JsrZNJy)1S@tm^8 z_dH2XF-K197NI~;L3$5gjJ2E4U*bZ|piHRtdKQ5mWK~TYcDW3?>iXamJ^d`bVBt)8C{{LQ^pf9eiE)sT zbPt-mp!^oI900T;`$sj&HD$T#O<{r?Fif0qvM4#$qQBZ;2x?8n%3Lqy7P&pX@-H=7 zJslt1^x72`wZyS?(AhrH%~pRqnRD*qh_8<&K?urmQP;LGKX#)mYk z&P(kfZcTS2(~_X*3?8v+=%}G#Wfpg9^oD|XfY zO3n$y2@zh28frL;{7h1{dbtprKTR`8?hU%tniuE&k5C~e|H1BdQrraGm|Zp|28WGu zWMKKlqfzsyw(dxmq?g>?a8Sl#7DVHWnAJ0che)#X#uIza`z8uOCNtt*&GS1oYSsBW2=wG_$yRq_174k78N zHISbKaM{tzd5$4NbJEu;YG@&TELCeE^8YA1_kX4y2mZ6G%`kJnW$t&)B`uc>!(5wN zu4%4O{DAu%B+x=iefjFoT%wR$?IMXI8j-IdvF^p9zaN-^6RnlPntU*CjU8{!HBM0eS zOo&Y)KuUb_T8MjlaYSgf+#K8F{#~K7(S`kq17|l23+{n1EGtw8TIA*PRiU6fsz?}d z(f3*`+o|u~p+uW(r9cx^uWEjgs&O!BrPQ~S5%VO!R9Ym3oQ)*{q=Fv4;WOKT8uL^H zmV7skjX7S5NwG0|J(qJr=ifq1sDB@K&%5>|8_L@>$c>O#|ZMy zPVVazUS`8HW1)ja0Z*+_eQcg<3)W7GZTCt@O-|VP0nep@5fo4&9XEmWQ(yJl&z(BPSy<~VTCaQuX(w~AD`X=(rM@`O9RHhyvGY4=z z95Sd`QgbhUf*#%JL+vA~IWf(SSZ7g*utvVZs$Sv0&$8k$5I0TV-IB~krr^+m_^gCX zElnVfY^%>cw3x)}?wyQ$A){S^7$+kpi0Jd(Q1l+qB^I{QEB@(9^$-~`RenG(0h&Wb zY_Q=SJOiw)wm_ADKkJk^oj~XT*Uo0$=#l1|pYF(@h$)^c6SDvd|b-WFSQ;8{re9^&cszz>* zQl_Am5pjxu`oqFz?g&AWYI&++0}e2maykb?_4KB(=6&brB+74z?F1MMOcrS+NQFp@ z03Z*(3q3F}zg2MgoGEy;!Q7Ar&W*jb`^&FNI$lbXCnGg841`$%l(!F(44h4Zn5fAl}&$W1zyk(!9e+Cq=^0`X^HPHU5!#*@JO1(MNH{i%@VjBoPHX3KSy+D55BTh zpIULbi3#;*&|pE_dchr_FQ4FN(|gui%|UYATEBVKShx!j;2tY5M`B>l^t`1B;^M&- zoUU4IzywJ^jSP+R?LmDKYN7W;k_C@0)^AoKDp>yEa{zaefQw0!f>T>K4y3^X77Yqv z{A;#(+;nWx3DbLZgZ64@>aDciPqFZnL!uf@Ko2JL7Va|Pwb%roU@lIkAPCFL7UEf_ z?8)GZO!z~r`RNz3pYC2w=7~HAKI*b#$FUmDcOSwxZN<&|cDmnWO`BGDwZD{iTG~A+l2~ zjjQm>35Bf?IH+PU84`LoRiKF`_`TQgwQO5P>Hx2f`6?eMV|AjiOlss^*iDwMc>Z0F z`E&ORW#JTH9J?#ywQL^~Vxc4I#0R(jI25RaNM|s#Xrl5+3ZBmyI$pHs(VyQ%>korK zHf%O41Nv~V&{&X0ET{^nr2N8nkPWY5K!edvVxoDxs~#t`Kog%}2S=oxJlal%M{dL0 zV*gi4Ek+lAF0G5%hPSif$?}4o%dXyq9UqvZvY2S%%l#-jG&9enUyMtKIo$AoNi1O+YU6P$qg6}NKZ!=J&ZG>8i` zN#eo1fI?6%2Ht^#=Q+bOir|B~)5AsZPR3~MHoR(i^y2h%8%HFyeWIWSUdx7-_k*HX zu!lwCt&EwWc6cji>TwaAULyealF!{2X(G!FwU3@QpH7ML&dlT;$ulj?nX#hLYTapG z^E8W(>Psfw;x#2XvyscQtsIf%eK_HTzsH=YQ&U~^uFwWOz9(0Zr=ALDDCzN;B(q=# zef-7V_&!#L-|ho@qQNly^x*bvaulnD0l!5~^ihIT#PX`F^Iy`ZQ;Ws`pQmy$U{L{M zT!-**sOGWd4p5n=|K|gC%PCa=!D%i?C;==%{@j)^MqmxoER^edhkth1LJcq1q^gm{HKt&1q2PEpAOZ)M~lWNh%rqc zzb)%4l7r=YT?|dW5h@L4K2aT1Ed1v8nPW2$$NNB&#er+aU{6icRt`17AxXJKXd?DS z1sNKFb0`fllr9sMq+n!h$oVXb?-N3|r#a%V0>;*d<)(&WzHNYfpF7FMFT-ZVU9~h}2EJi)8a&eZ8VV^4+h^w>wk2e{lFzdCaNWF*_mVi ziJTQ)Gpv&fVDg;v~s3};mNx2b_Zw}j$7420m}Xm=@EiAv){M!AV)GZ67vSauXOO=yO@9L8MEso zGAO)roq6`7^Xz&g4Sb_q>UfaEA#pKY-ZfMJ-pYV?FyJ(Ecr7bC5)C#dO5U1JkO%^L z&$P()faiKBDf<&GE1%atu?;ExpW?0iI@3B_LH_8tS|WT1@u4bKfJ++~9Rl1byjX>X zooB3dh5H4>%cce?7yf;7s!0KNe5L`WP>KyKr$Q69YQA}pB%!J$;26})MC2QZ)jT!@hE71)c5@SA8> zW9%mikB~%ik5~meNbe}w8}2l$^d^^mYsA4RQBT`kVaXgrpEqU}SI)ZBZCv@c&anc0 z+XebCcS?jeY-b_ubs@YpTc8mb`W$xS3%rGq8}dl$xpn=fU@G=4j6Cq!{W>g@Bhm@n zu|knr@TA=rYJ7VG-?Me4j|2Kjyw%wJ_~v6?$De!0{=n{@aFh5maO_XD`k&tV-`2(Slj$p%Af!o%t;T&P7CTtwwolOqc_@CI`f5W3zp8!)$!zHS+vNWM*2-~@F<*$ne)$7c$Qz12*MmaIoD7drc{8lPtM zEEIrr>S+8nJ)0xyXU1_GneR~=l%RhC+L^b6sS+#vFaoYGvyi+Nw3 z9C+|Oe)?_j`RFMPhu^vu!`81gA(~<~F=N#{#8C~)UG->G%>0AM{gcwV%CZ4ISy0{j zy8rREq&rCm?2rsHX7N33Oq`TP)g+8bnE*IPcTMk=8Gn==L7J52=<0%Hqw)sFxZvnC z_r{W_y(oJ{J+Ga65+{uua#nK`x}B|6!j4%4tj)VY6s=zGcz(JOx?_Ha)UR_}@ypjA zuMLBMUk{OLjeojcamQSKP!h1M{URWmRh~n9sr_^LiDO7o(}iDup^&Acf=I$AahuC; zjh|#Y8IMda){m$+N14n-{e2kOA{(0C>vRcxj}mxlE%>{el;gjWRr}Ow6KsIo369&= z?|Zw~#mjaNd9q1*6ZW{zF6~W~dR~XZdIpwz)vH_mecsx?k$wK&RV8fdZT_Yg%_`^9 z%;J`!f?oSd+RltrP(HVF(BZ1$%=6_<>t~LpbFx`|E4uuWf6gdToxc3za+l>*Lb%_!t|Nei#R{CXs>w3n^x)*knv~7Y7+LV&s}OQ zahF=sQ>r=>2lFUvp6w~Q>#&KbyHyz}nRx_n8y1^;w@&a?4z|SYBT>IqCgn8pn%_)u zl!nLhlzX_vCz`6C(Km_9H0tWa-t#zQT2hU*`Z zcc6wZCfnK{xhuSS1;)4fD;8&V$l8?k)FwP;T{nO}I>KHGdrv1%)O(2nv^xe)&yE)ms z1R?bJZI$G-C9b?lm#&t))2dgvSqqT5+VN-375gHj zXB6g=Z_N2So$$MV*ET^VNF~@*(8y@cR;0M*kN4H>+yh28aA3ZKMwyqs%12BhRg$|y zzMH;i9}Sw%?un|=|M_d7*m2im;aA)5uc!2bDABZrsEv0dm4njjo1wu*nqD*cy}SI8 z3H+gNM~Kpn2YcpQM2zcyrcE@So&8R7T#Ni}o_v_{CNXrQB+|S32m1K0@YDIamtCS9 z``Z86UA`niM@!`2?*IIZ0bGuX>bW+Nq4mSffGj^13TzdC7~A(Wy=s0nd4qe)PtyKy z{H*KG_jfzBi*B9Te{-+F?{(LT(5aB`D}Ax2G(L1L92c%x`o8zWeOtCX9%3Uk4L{@c z@YPJG@ApWjrxCqJ^mE!$63+&eO!@AW?mk5HN2M#A8G3awxw~LlJNfDRw|D0C@9@>V zZt+uh2JzaO2_Zy-&vMQ8-M_d*-tD+TBus1n*lwFw!GuGP9Ow5CI&;aQA;~G~4!GKj zseb2nCpql?lb+}F8_x()q7w6;MNVst__hqYk z(Or_8F4Hu@gsd895U^1B?yYot<+H}S(J|XPR)x-3lYgWu3sLSJ?z&H}*d<(S6a1ik ztZKeqBHG*NP2_o{t>6ucPuk%Nn7?(hkL(|vG6zmb7~PVczIt!rTK1-D#n+^#UH{t3 zQ}x^(|GcbjyY&5hcJUdqMadKSt6~9{YwK{)UNzFedX3pd`m6!dpey>{J05=CJl6l~ zwd~Hl-$TWBY>vvxZ*9nE6vB=(pzLWnl32<%hz#hmZMxIX(MNo@r^B0F3++c4;bL)2Rb9V<7R( zK*wTB_{n>;QUlJ_O zFLt;l54^DWxbVpA%}iY~6Z&Z0yaV(4qr&&cB7gt8a-);2z)cyq5Bz$iCH=i#M(Xsb zz;D$b(?42pQ(3uz-y1b9Y`SEmEw%*i-a2*R(+O_c(pcb+yDb+!M`xU0{uubP|Ko-K zE^yDYp(po-H7@QHXQZ!docuL)>f*OrZu*A($=?et7k6)GT-ZK!^3Us!7k@tFUf|@O z++Wk+X8fATxcI&0VF`pxxYxr+<|Q zu#$|jl1jIdF0zuTv65}Kk{hs+pSDt1wmPtFrMPc}Mp!G!TPy2YtC(A>I$NvpM$b{! z8tK-WMb=t1*4pjXIs?|a)7E;+*81Dl2luTp2pa==8$(?iBXb*LXPZL-HYQOvhtqAa zMK(ujY)sp2%m!@Cr)?~jZH{i+Snk{45O^zjytOXg#vG4##@hzq?V|AZ>39OS2=7pX zcWlQy4d9)p@h;1F*KPcn3mOu50UIZtLl6>lI*oJj&KP-PWhb*0;viuie&v zz&2po_QbMn;I{3_eOnU3E=b-kSl2GZ+%DAFE-b(2|v_19nl< zcG1grXSeNQ_U&R3_Hpv|@w)a2=Jtus_B>D1xhVVObo-Pd`_vlyw08UR1NQ0D_7|4z zFK*js?AwzO1d2R?s!PZ;CuBJjvI7V?QH0!dLS7LezlKoIPAD886ipL~mkF1)377W? zG=xKmyhEw3!xeLfGG~YK0Eeql4i)JRl|>F!H4fL>9jXT$YNj1(xyut_S%!6qw%7L^ zjw2lFi=ITt3Z2)PbS;zg*i?BrRvf%oi{*4zHHatEbKT{DuSOU zJGB|lVyb4lMr2`e06CiY!vXvg5ZHa(*`1v2y#YE(gPBBtX5?LndCrTi&QAMN&RCEs zJ=2cq%yY$JV_gQ)?tIqd9m z7MMuSoIvQZ14i&9o|dLel0nfLpYa%1ztEN^nQ6A36zp!{@ZSua-dt-`D}vb@pR*a&L*Uanyfzdi=!o&p})=i_CgQ409R zU(IUFr_)h$09M#+ zZ<>qxvpEeg9uiGl-E)(uomI#3k5lUOC9=GT?kng8!`)#cAzH?s+w_P#&_(n>-hyiR zjA_!m8F=KtZAa}VPj#Ass$4834d$tjo5vIbliVIZQ87Ah=DGf9j<0PV9Ss16l}d8v zy~tqeTD78YkDNd2cCRh24I9q2&f8sBOdF&~R(fK}XM`QgygolVexmPT=CjprrE>=P z+84la6(7Cs*iY(0Q*?o4*!PIQ|UNm-@6RG?VJmC4P-O)x8aX3$>nn|0vgDpytpc zNgTh{Ati}DM>#TohtCb!-lA@_}ur4O2 zXxPwG65-U_xi&^q`7hK-#xAs1|GhTY;l&pRDZPM2>DrW-lM}7pr(LwqXzjH-x1sP6?K0DWse;T|0Kr*7y?(JvL zNi_FHRe$=g&5eayhvf!NzsajClpC9@(sh*5@?&62s9-@UE;1;Se8{KgK+Jc&C)a%6 zDXfMG{a9TaYepF19% z1r$EC*PfEKjg_->rSexO3&U~4UzmZbusYgez&N~~uNmwA-E8Gh*VA(I)rHjT1 z=nQbE&W5kjZG=rfm3@BtavdZ#hSJ@u?mAzKdKit5UqAzew1eWtb^1KHh;yUC9c#y4 zuD1^hX?b}1E(RH_Cj;Q-pLBQEQSqwZUssBZ#M`SC`ut2X=S45<8aGM5H(RftWo0H_ zJeus1`wV?8zS|>T<@03oo%7dDtX?`_o_1jQN{|)^TVQfZ!*b7blWyZ`N^N;~?)A0s zqb;B4nU3#1EqNvS2x?UF7c5P7*v$U=XmhaFgzj8#Bj}c9ylvU|gr2bZ;Nw%Eh-KyM zaEFfI)!k`B&1;DOaRJa1wRbe?R{bfXC6&Cm0A--u02=Iz9nr+aFQ!uf3p6Uw45CFibb-a_(jaY%8*v8lo2`j%?^^bNb06{bI zTaon&fE;-hrBD+j^fP4`{Q)CZK>#WAGP2}r$)^=gJ4W~TC}*p>QJ1d}jJtylo?UMc z)!_J~F}%BB^UWl10O5us6XG75Dfh!L&qR2rID^(8xZfsb`(3$zPFfV~)tFbr`5mSInzs36Inu zEx|y|Z3%3K>PY%qb`Azt0u~=|zM3*ol3_Otc$+|&w?Wrl9e1#>dyuGcXQBK@c=+ur^K57U-A36? z38CpKQS%B3miH%?8vjKLF))ow@Z@Ks!mc5MdD&|3*dXOaW}b#^o87U|IoR2Q8j~te z{f$@vc{a{M+l!TMzBPAWR@LB_lC>1CVm!jFD@hFvIk4KTgzyQa3ZFm&;18@tD?e-i z)j0g3+J7=lm3Ggj^vfkij(RrzMGMn6)Q`wdnU5XcRs4h$!2YFNa-|PK&Dc}C5z9>3kz8P?Oc zd~V)YlY7M))p|HsTr^j4^A*!pWgM5Ku>YT(p5OYB{ukD?cd7-01iV-p-FNX^=h@pQ zqA#fc{D)8!-lKIJd13y-2!wvkr#w4t0a2)N07YQtGrUvQJ5#+WNTh(~sYa>-NKCuC z2+gjXNoX!rOH>jrMuQJF6g*AzS>h_roH3GngE;lUqGJYp#6NX`oq16!>9Nr!eCq2k zRnNy-F43;bay;&B&mHNr_%rh#V`-))bmc)Wp?1q*a|X40^N0x!fSRol2-rK6`pXcn z_=C*r3iAgyFrOF<)JMdpsK_+u4U4#9#$-tmceQ)!m=WDq)_KL22o|NRviSh!;-x1F zNjvtU0EO}azI02UXNuI4=j(q}q%vZuBKyO4Z`{ObA3MS?>R2UMsBlS0ZNm_e2y4ui zpTQjNvXWdv=Q*Q+1#4ahOiN1y{h06A3}*IFTnQ&fqo#TTJzjT#RT2OR)6*tfRW!#_ z)j`TPGfsS$Q1}~hgT1HC;?}(^)}720qg!QFNk*l8`rB09scURmX{}Of;1$gR2)T~W zqw>(%Mop{2WjI^RfKsoPU88s+@ka_dx@k6iO5@ZYJN+fhmxa^urlOvDGiEmD@_ckW z|CIoAc@3Hj+VDVLseEu#!<02o9qDGPsQZAuQ1rA**~Dk-OnpKl-xM39$E51??tHLa z8xkoBwpm|e=1h9meJy`%qt&3a2XK-IMC-PmE_t8b|aOXSb(f1@8famjGe<} z%jo)t!~NMAifsNr zaR60;3u+t@RUg0s9JG&qluH)&PvW`HG)9i|Fg^+OVL&o8{=G{4LWpapl=R(?4kuN$ z71U749>CSR=i%xJHIkG<7!2&pG zCv%Z+D-8d7MNP0^?`{}vjfurSv0atQc&wp+&`?6-S-KM&9_4LvwgTqQ;m5oupW#Ox zjt4-vJhxoPQNcYCEj}Q{o_q`&o$8*;WdiXuO7Tw~IsrMrNY5L~p1KdjJke1@LuzA> zuG$J4_~gHD$hQzBxuXTzq~hn-(il=%o^j{TYewqf$;R}oa29Mp172-%PS{P~DStzg;=qqES_idYlTex3Tazw&KS<5ln3E z0YCqRYNg;9?-`f&%F0M z;xV8|y&`0mP_#QL!`cPtk|33m2?)uuXUf1s9RB}NRrbaHL~SfPTVhGda~=>tgqh}h zut1g@(%D;iM|R_q5J82o58_M8vpN=i#w_(Gv=v#mu*^w~Yrn20Oa21V=Ej(B6_dN6=Za%V+di7Ehay1f( zUj&$Nl6*X5R~xR~wvBQHWP3JV)VO<6qQdEZP)VnoZgvSua+3t4WTL_J^_NmUcR}P$ z>K`aXBQ{_1JK!V4h)V~W(IB0%r$3Peqi7CEr)uWIvOvGHuSbL?o=a~?x%P6jSR<_3 zf+#9f$%{6_Zm*v+*pnzI5tjpq4qVCavli8&6;6<2RJO68>ezy zM(yQQwVnxJEurE1kWx2AS`DbNmalNn%}}8vcZf>IZWoho$hLj;^&dJ?i?}>hCCgopGHgVihSGKI zu)x!Y7wZ9+h7FG%LPi=U!LCVTk+c>_U=cC|A4H<0z7$wHT-(> zlvWY8)#;O8)ve^JMjAwoQCv*`1_+pc{1B$e0G*FTWQk=?Dd{Dls?K>FN~2T|2c=dX z81Hu)YL)4HgQEmt&StG?6AOhO_bgD#mnYH=f8&};+3%I*Q$qVx zuK0j;zDEw~>*U=(^+p1z`I05qP9N#mQ&KuYH9}b{hzzMWPGX-8iaG!fX&Thmm}Z#@ zo`?+Ya{1If#V@OfK05HzZgbZmb@Gxf3MHL=_Tpp>gILZDH6sfW@hpKMawt_ys0s%% zFL%>Rq5nYeFhCUrVtwwM`RLyoRMnBVNUB%=#f>}6C4+o8A^{k%6SE4y1C|6U%HsOUe(3B` zQgZRl$kMpX8vseehl@I3U(_|DKH7fjVN3PXi)LWS(%Y}+&_5)BpWu}%JsESMhrey< zn7RX8X##Vs=uDtsB%A-kVX7+j&fj?bw3oIllbHOu5?N_mws&d(TZD&@v4dc3kfs9J`9l8>GDYkSsZR8)omRFd0=K^ zS(869r4*5rID*$0b4Q|Yb4`y{^B*24XJk^YXd#LqYCOT&4&5Hf@ zfEoUxWTy~313DjZG<#U6igXDZEX~%wD-@w5S#?WlM5=2V>>m4Y_!i2|F;Y{a)2T=a zp9?0D!JV%<`>1hmt$`5<`r=7P0HQEt+|-8^lx=j&3y zb`L>|-_dv$h!>bmOM(?6-NG?r^J!MZ)26qSA-Wd?%F&B)n1w`V7wIGoVR>3qt{19i zAoP<&b7Md6>YZl6?pcV`-<*1b7kQi3`w39;fmt zAXxp!QImF>$A{)Ono1U5EgJ{GMsGko1kf)SV*LX;uE1kIAXy^^om5V|T$RmPJtY?Z zjD!w7Pk&R2hUN3XA`GO`T-Njt+0oDP$j61KSoUi@LKF!SiW_S(kXY#qM24DK%&Tk` zzB%~j8RF7}E{8vYHsxbm(;v_mr=}9~o4+wN-M1HPd|Z1x%FN=DPvjxn6&B31SOsun z<;HOB%@ePja6qD{Y(X(Nl7~L?;>YYaB+mLTTcD4rnkl{2w_O)Y13p6 znG+Q0C}-I(_*ecb3aYn(E;z_3J=kUBLKNLeC!u5yLUhfam-Yi#;vg6Q*ZSqHl%1<) z1e?&XIQFq-TbGpAtS8MVQ#A6{BWM+8Yi1-BVDPDf^eJ}4NPCWFF3iep*t{JN&E?_C zIQYV_N&o{I9%fK3E+k+F&&5Fcc|y?lpg7Dn(%%e+x1`J#h4_{DTk zLYn+Oo|hSi#Nl9O&Rzo~SaK{hg~owBJq@!YSdsyczaFXEDDeUhzk6*FFiz7PSKKdA z@n&g9@u@3bv|4_kI611#%SZF5@UnPV_J|6e1j*-e;DhY5KLB3__~29=#GG%$NV7w* z3P7M24!8t9dI-w9f3}>nHHL8jt08)6uoM=^;$&I8LAow2z=xw*#XNk-(m}?~LGT%| zmLw3x2FY3a+X`?H&C;w96E=RwUh z|L|`@blkHR8>$8y=+B(zaqKN*!459xHI@}$8zaz!M2sQ#s{Vc<#THNe_uP5-Oc+`~ z_aLJ4kz<)Ef(K*gkRa~vqV>=de4;8jh2o%NWu&>Rna5rOS+<2AiseQ^hf-Dn<$10$ z%7@$skOUjm;taJocEli+aLuMU-eTRP#NW0ky@x{@PrEELAO9baf8a8jwThcYHO0dT_&O3s49Lvj;+Ji zGbiek&h=+UGv07-PkGvX6Ol6^KR}~2JWhwMJWtB~@2OlDY4`J6k*kHruAq(vq!v`qyu9fh^wi3<<=GUC&d5x6EZzme`><7P$uc}=V zS!e}G@hoMK+N4JTr}Se=SDVGmnfgf!>Sb&J@#uBV>=l@f1XhquW zqlE)m`IqJVdiUy~!QgGmgxFQ&lj<*z$~we?%E7!lf{0GMxX+feo!r^1!4R0_Q6K6h zSL&Ro!odW!+-j#5?6W0lcT_Uv;M-=S^q<*wh1mvC)^v_yX%v6H zb5?#}+TZ4Nb!2=dycIyP_?xXL;Uf98K4V%?r^bLAqgbHtrlPQdM2dZ{DVhTh--_{L-E!q$r9445@zf3Cf|`_H{L*`@{D7#o3vYtnAae5%KAKbnUQ--l zdUrVJiIQl_Eivc4k&!O~YocmP*2=L;BYVp?P2UpiG~RJCS(GP%bT@aQt6>7(=ry_a z^FF_$-j75CI3glZf=bEkOug;Z(1}Qe^bzUn6Fb>L{R@L4p_tlXC0D3v#E`<#HcNwx zDpJk7%0nCQVCvi%@?(4{qDZm$W!&ZvpG%IiI`*r|wNBV2KO*1y7334WQfx+PPl2Y!To?sli6#i2onmvoa zM+}nOiCym=5>7b>*c+?Pfi(84Bqlc2^!pPIQkphZkCa%WQ&t(zFRV$okB_MQBSURM z8=_XWFS+TshXgb{$PMDIYZY;U1t>ALi5!2nBl#Qk0+b}KBl9_q8>~-7cqaTb~k$L#HPSg z7(z^3s)i0@aO_MIjVcaOOZ0mwMW3?xB@_jql|Qvv6ePhc!0n@41Bt|edsK?;qs8V} zyhSO8&JxJIdmw61WP?_ycCpQLHe31#F>b^sVy)x0Saf=#Z7s?CoegiZb<3SLul|d2 z8Lq4>w}ggAYZ7X|{DvNhU(FQ}b;8^n#|z=Mhs)8;ha!bWxPi!X`PHtf%K zXi*^M+eT%{VcVuDX(!A6SA-CNT=yFj@<9d*y2dI=)Zns<&vjg;I0GT}$*Oda8o2Jg zjec*?t<9Zx$VeJ*^h=M?AXr_UAgm5IxWT#K9DW#4f`FP?B})!hRb?_5pp1!F~qxVK$8I;HmvVo#mdM_seTj<;UQR-|BlzeOt7*8KoGwl54 z%mzHWZ3fX!tb^71Q#Wj-MkFrsz0(zJ)rHjP?biJfSw4OIzH!SSW0Dz=(G(&P#oG3P z4BeC>fS+paUrK0e{1L-a7VgX&)%+{ED&|af#kUJ*Jdu{*nfmE(@So%sQ;+QBj=&~Bdlszcnd0!+t(@k#uE=bLA zwIF09)$tWMyS(e3ddMpKN2av)b%}M;XdK>NB=dOTf^0`>P~YYc_zm%CU$>1N>yU!2rBDY8`QFiAcM-8lO2$>ffsp`D|6X`5hcJ>dd$O|Uy za8)OxlIk>WGNZ)coy0Y;0A(zI*BrIP>B_)WwQ#Vm6iT^cZ}u?8O_`DRtv3RhQ!tfX zkyj|tSD_3OI^Y8kTxGn1jm{V^iAG_@&r1 z^-2JS4baDBIuhD9C$cS>R6Q&(x@a_FnaT^?Ut&=T(=7S4jB@f#+x&GQR++q;^J^gk zKHoCM`dc~{5PfrIitqS!{|9#zesJ%%Y)UBh&1wQW zK>VB+-KWqTOu~pj4XmHfk%cFK zoEQZe(+uqp%ahvn{GxfX0tLVRbZx3<8L7#vRIXeRfIZH5!Nx>l;1w(&PaJcrPM}~N4$~7f;SP;+)*OIYR!{uFA z0k-AKxX5mL6*|C<^owqe6i_q_oaQP zmgLEUt2qG-RF=;GZING*!>>ll^y!^E{|;<3L*zFSD(Krau45FV3MTE>SIG!JpjQW5z{# zrNJ@*0GBo10Yy>7Hn@&I;Z$LiVRjW$m%Jmcm(q@GI@`@E-#}?nxFUOGMRXQR+s=mo z6w#z)5Hq!1+aaZ$7gUHmu96G^D=3hA#B! zl|kF5OBYC&F6_x%cn5w)7W`SM^y+JF3}2Pn_=7LzC^^m}b<9ELEnb&hqmT_g`_;K0 zWmynkoid;ArCcb6u5)`*{)-NF#59QPAWg97pW68`yk8Xtij816!lDKv4 z^sQqs@$ry+5i5m1*zg9K0&YHI-buIyZQxhf%XMb9C2k43k$`IBlJb?qPdGqt9D0v$ zW?}rv>j{u`ZzeV`(*h%0x|ZWH4p_xWzVmV4hIbkB+`|}DC$O-AlNmr(4S+$0Ce7yJ zD4@R;KUom>C91v?e@dy`DN~9{FVJUP{$cPvYtzycYrxS6?`T0)T`WK{y;-MrSRob= zwI;k1M^vVD-gczaRKCEHYc{Qn@9Q5J$tx9?R}Qd2|}~p^gtJ6Sc&@5=ps?EaHO~RUY!q(?f&$+ARTK!#%!R z*Q#jF`3ey|(^k+`Q%cr^)N!rWn_>JK(x3o_;BxDw2bmQ(U%%ag%*6?le)jm*1jvY0 z&+$Xak(cv8*#Bsyl|x|LydaZ2;JFFglFtwBd{Wdxnh1TFMe$|2_G+}+} z`*h@QV1r-3xM>a^4XDSKav!-+4(;+E`_nJ*=U@;LY@G+(wGOtSgPnL+vD(j+e^Wd~ z3tRd#10s%ow*j9FrMPt2D3TC?L?&?+@_$&m55J`P_kZ9ZdkXF?xc5%YED;q4YHF^^ zym5~-(X6bj02glDT3I;LTxe!iR^Up_%9WXS14m_B8)n@WKR(~b??2#h-se2d`+8s3 z>q*Ad@BsNYQ>-By&_J^cj(vVvtl;m3+gtGLHxCU2eC9b03v{Y$hMK88HY;8jlIsjB zy{z>!W{C<}CzobnN2JdH=SM=Wj27&L<58pkF%A0{uYb#S=CC3Wy=s7n;5EgEaYZzC z>%;sT{5mtqIxXdpkms#IK-l^#=*W-m%&zEI_|uHvp^yx!4=D|wwWpwnN2ukK;zl6Bu~b-6 zKiFgo=Jf&Ln4#@Kg38YH@3T|CVu-5XTkEbseE~5g;^FdHH6sROKDC~F4~4oXt7MZXGC=gMY+6{jieJRMsuG zaL@i|&uJ;>o?wYe!vg7%-C3&IM^+?s^reQ0tUn%g2Fhk0glcQwS3y^qk|dB}XjI5c ziNSQ5wPLN(R@7~lMpWM8b&t|EHBxngc|$>l=7QCz6Czkb{9oVwDh;)icp=R*Sg>Up zm^_5d<*KJOJ1+RW-)~so%sht8V+7`k9N^i5(%Aqb^vz#DYwjVPWr)KTK+W&GrqlV_ zyP!~-YSk&2X*UXSFgdpYa#h?_tLO%;NJXe$NG1b z8z3H=ojCfmQG-V8~x_OesQ!H(=nW?M^4cKlMC=$X3O_7jA3^5w(N)V zk_nbwT4F_>txBD;f1%hHUh`QY$hB21>jF33@72$tg=FHJY%{~2W5-X8KK<_x>PzQP zMFcnVzcvkf8?LD4?v;)1Ov4tS4BWl>*P^yCgSMsU!yq9N9D~+djxiwi@Y>7lpIUf$ zuq)(b(c;_Za(6dxZ!Tq#e16IMXpfdTT=oL_aGFDHDnw&;mq$RdotJVpTc^)1uy!(c zjWsdGGc5sd$z5l+uQ6BDi=~~7&U|~D^ujKsWg$HluQ__JKoq%sIypHsD%H(I{(`pkmE{D% z;CNju=@7-~NhZNvF+6JO;@7;U(WKUyDH+6yaiP4`-)_Rbt6}@j4M2a0@+P5k zEdp{LQFO#a75VSChOE&WrLT^ZcZ20_b%^GpH1@G{(52=f1=x$^C1O(ktRP$*QHd=& zIv#&9{=dFY@*;L>Uf<)ov4VGFfBuW!woOUF5lbUv-#RDsSl{@^*sI# zhLX!VIA=S)466yj$eUub-#TLoG^xwB)5CkMmQSkIqmIA5kI*h$okkcNUtjez zIsJVdwBLFFFoZJYFs(`RW`j2h^dH_qRBy^m7_k?54FeMiBY~95PZg zx5Q_W6Cwwx7Vul*b{`9zfMWLY<69q#8eB;U67r{kg^|2ek{^H2xYV<4`$cg>AdCGpt>phQ-KOg8B!5XdmoDUK8bEM_V zRm%3;DaL(6DysMGJcJ(5?^`gh2@&@YHXi!ULjSYKaMs~*Qs7ddeLQE4`+yroHnkfh zsp=i4Qt_yRKJ}QZiX}rRW#?YAK)K?yjH^xpm9Icf_%vM#o27beP$paJTcKHv6*1_7 zlgadW9=1vPA;F8sFS%P$3070AZGY=$6epv%FZci4->L-ri+Zu?^pbRuj+AvZ8k8G3 z>#jY;q=vprpG7E5KXjGFIGkOFnMzLQKQc^6!$qQv%lX-ch~Euf`hMGH1`l?2mprI2 z`5_O(s|2LYx>!|b1yWx256*{_xL1;66{G4G>`^dL690V`W0iTl%vJUlT?yaXK|v{NeB=jX zHw3iV7?ul(#zYT%Eo}awl;Vdn_GuZcvLN8^>(zej9>#Y4;X1jCB2<6umCn?X4%v4X zU!d?%Pt)o*jM2}@6})3B^VWS+N5e0v3W*AK2RwDA#M|RxA=p9O-@A~34SUXn8@TR%B)vtxmxMM1 zdNlOnQM%hsu>J>^nm3o z)y@H27{1d?jCDP0ykZz?2MEz%_g9Aq#WsdnUb@U6XN0TCk-f>L%$M)!?&ZP+tq2bf zTH7C$l~TL@7l}oF88$sY*@hE=)6pyE*30eYWB>hHfgEBPq_iyWoUY6JTpf_{ zK}+)xz@DP*xd7_%Z_%`95lEie=j=Z%GE}PIC_I>oyR+@)bvikiEa_G{iF6->c&&N; z+Qy@u)-BJ3*88|uav&x+h_e&R?*c1QO&`6i07%FM%+f%najT5W{z4)6H7+2r&drva z8|+=5p`K94v|Cn8^_a2JXaxFvbU$b^h1)G)qoCGoAokKTv49tbbmj$D@NOuD4A((y zeSoRo$|tLLI(C@UMVhVgp2=)8umfuc8aQ?Az={r?h@1Y+Z>$!56PPesqne+4!05h? zBG+5H$(Z%#jDbHSWa?U`+1-s>$G|K2;PnUYo~8F_9a^U^?i_;o@H3RYf8wkvqO

+%$12uQ8k<~@nlQo)ViYE9Zc+I9gSz>S6z!rZ)|2qY2HoI6>pPV_QjOdM zO+_za44i-SV?K+c&3Eg6ui z+w!^g2(r!u5p#upmT+}-VDvBCfU6|XRXZ+ z@K-I&syI!qphB0BOEUAq3A+>exaYq%6 z1E2=^8_1CCz(YR{28UFu--$-R<+F`$wE>gf-W=b5#w^ppbx6=5(fo7fwK_7_$*i{l zpIERwVtxcDB|_sdyP7o>>&5;{s>B6YQ!gP|^HhS=@kkQ}`Ml%1Vf^3_>$_w0MLp&U zqMX1xc7k=bttt47N1xA?v}=>!%<%)WH=>nDYhFWWq2UZczhFx5vHr!FH&Z)Wf^6$x zSBxE%Jd(8oCA8%;(lAZ-wYQ)3I4W@VXqYYo>J-C%C&)%+De5#$-yj9e^+~*I#mmjI z!I7CGoJOGOT864ih8~UilZf?taejsF>g|HH{BeG7)T8y?nLZ{S6Kt0@YQ4$V9dtiFp=a>oUW~)q9eK=R&5uruZ z&CSnEP%OFV9Iu^a@Ot86dWK$zK*|azR)qCTfcj!ZxMetRHB4KTEPas=D{#~eR_>1i zznxMY+pl`crNV(eAvZ^QDyV{&mMHEFNRAycCpej{lK;OV?Eh~HuFQIMkVtcE+j`-f zI``rj`Q?UdSvl#|JFK@1g);1##kv30s@Oq{>T-el){Yb_f$nI7eY6NH_uSE}-Idbf zA;;PO8|SD3cY3;hzf*y%=mx}Zdr8W;IBFHW>In3*cO#rvu}Eb}+cIU`1X8h)l=xMd zSS^YNP=Ge~NMc(e%y}uUsCVIb3qm?rV z4JBZ+q6yy;?t4Jk0j|Wds=#uIPyWr23=w!dBJ7-_^@WKlurHors>is5*wgYhuzgvooDbsx^#{D^!7_^JkBpbY z$?r5?hcQj(N5gdv=Dc~Fe)5R}H^X|H`@y-vseQ->aKL||Ui>3}3J+~=4{2Wn+6H>g zb0Tta*GF&I8*bv)w04L@p^`pBNz_VFXw}miN&*+#@W~F@x$J77QH!Q|fRsrj zS!H_&{~e%Gv(LG;Qf->?^F<^BGf{b9kb%@I{QLHtgr0HikdTYC;Y#4Y^W$@eOL&dc zJsJa14SluFUW<+D1gCtuldj&h;~d+|_9{B{>51go2K!OnPmU%4$*YZ^Pco1r+n(h@ zfFzAc=*+ej)76xk+(@P1yr?S`uPq+B9Jouo!##iScwpg}cH%R+pyyGce?eYPWd89M zMz1N+z8=`?^_X^q3Mwb!+oe7Iq&2n|~xzH$y zRk@-bDXwx$n5>h{z#vm2O_SmA;qkgE|F_@$p~opt)KX&h2K>`_1ZYTm7cR4msJ;^L znMrynccQ;^$2)-VT}|$p@ygxL*(Vj7-><5d#9C=N^#VJlbU@Sba631a9t91!u28;L{s2~){MzTF+|9DFF0>bGThwDH#+wHxWPmkq{r{dY;pThOGUM^L` zQSi$jw%^?j!#{#nd8P)g^|}u`#!zucg^PR!Z?Dh!N2V_EDIHLY=K`t5j|jMgX)k=| zI+~My^(3T9hR^!2Gt+v@@zVL$@Uu}a9bS~17}2wtBP~%KQu7_yF_fO^wQW+OvCP$l zCYg2q6-XQS&Eh|yv}m8vE4*y~+j1d>8Bot`#$(EFl!*2%lLL}6A#vUz|sDJP+2eO}= z!0oIM>B2Q4QEI2ecz}Y01>8eI{Zq7=tMnHO>EagCV!fS>8P*)K951){CPJy4RnZYc znFH!OA4q=$V- zAM(kB&-dfsRg$+l8`Omrzxpt3f&Sk+zKFj5vo>h}feQcF5|PvFqf4e;pS$MXM2TbH zqP}ZGlnj9%Mqe8p&a-Y)?20!tIS=$Yybl7q!6qxFjswjvV=pqKKROPj(SQ0Y*uL1G z)yRiG4ySON!wqy?(@O{5yHR)trRUm0rgiSl@cP2IuH^v!`)>Y>bFM#9RYa2JF}2po z4|W!ObOuXb8A@?}3;4s|tAwL)obQL?;;uIZTp|_^n{Xt;<~L|3 zFU5MI()Ln$m=&K|p11$0W z_cyZ{y~dYfu$G!KY&c&?AF2P20pu7-zwa9SH(!pSgYi~_d8;maY63%;`=V61iTVi9 z0S#AYArHxeK%0TztjvFX|K#TC^VE4Q73>S@bfYg*J(kNv040F_&UW&rZ3ZTN;{5j) z6gJ9aT5#i#T>L!a${E@~=Q`wOg-rGJxP~9-3=GN#`E`}fmny!SIbHT46RQU?@jn=y zaQxYxYuS1*8a3IB%S6<$Jv-kc^l<8?HuAmN`wJgNxb~UUCp@#?*;f#=4$jc94VVA+ z(8WKdu-C=Q!bn#F;FPwVlxVy6*LN%>_DgP#|_oQp)#9Sv->706Dap%Peee&k@O;bM!kJ0^8*aBDcQ5oCiN%n2#{d*?yrziEpt zUz+z)94AL4IXiLhvxqq0Y|G8Dt=%aBW@ z!KP^Pw9f?VqP6hyzNh_lf6F3(7vE__NfSw9TwkZ0GUu1u+WuR`L<^5S9$R8*Si?nJ zxr|KTD2BQ!StU&AZMZ2ol_CEm8y?HST(C6>8!Y&i(mYv{JY$vYyW-j$t2bM-E&u72 ztekp@Mn!k8v!ah)UA%Hu69rkOS{ChPP%irLq)6O)cHpP!l0#DOqxG$z1}I7<>6PDH zUhlGN5xL6bT_Z;Ore}<|aLe5014`NSfZN8qV&Y0{cIQW7+zKp8xm*+H zNZH6~%~jEFje#7+ys&%vj&^%92WxGYy2v_~=hO(pzS8AKdfdQ9@f;k|al~+^lSkiF zRk{B2vcVGHX%2r+>t2;2XT9@i`o$-A&dXb+wd_y?>4zIt^%f?!8}Cz;lTef@D#8DU z&@UdK#@0rl;6$6WL8VYmu)%1w95qZ%# zN^WuDfUdNK2Td}2Gjd@pOU9e9%mMsyhsjw>lmTJc;T+~2#L`7-i#(lBUlzNmpWl`= z_#ZdRTJ$Wo;oN}*pkyEm@ut*@Qci@(_|ceIa+x13H0Ag4m_?CO`VT1CMctWjRdA2t zJq3>~nEdV}PrdUVje24AHV%VJnL69-?2BbG8oJdlf`g?;i?T9GHc+?1(BTfz(} zZ?T3|w%2X{>(agJ01Y`m3h?%&vj^N-q;J^P&9zs~^cQ%8H`A_O?PSS6>b%v1GU`_N z4y`o&yHuAg*V5V2Xv&~@kctsby|H_wKQ#Or)ePsEligXK&-1fOJDiY~<8SS(GQ zarpApAp0Dfwu1LhbJsba^q2T{#{%xDS&i><@UoK{<3Z*{wCuz*OzzZ{Yu3X6uHa#l z?Uk@^YW`_`F?EYtYwDjj>$WeaI^&D&&;IMQH|JdYk){3eeU@4^PnEyvZ2mV;&(Tm^ zL_Qk(!a+15kBu;2IdJ53}LlQ-WpK9wd z@BM>mDpz@l%=I9?GWq{tuVuqP9RF( zTR|qLS0JoZmck_eV@Si9=v1u_xqpL$l+H42(rQ-0k=&rE&lO!~HYWdRf>-nH#1_Rx z15a41sLH*+B~yxX)&I1zKlf_{`SCaxqU|>P-M$5vlsbr5KuMK(zf+#6UWM)Ezm(LO zVfD>1;Q8G(?)}6(W6z1$=CFy!tT&RaJ|hM-!-Sds8N8y=r(6-d@osqB^)^*$Q|Rh} zuD?>%g3Ll_Zg`Eq?z42MAKo8kHIb;iR)=_^7PtA0mpijO;S zdv(-s#_X#4MFy&BYjjYGg{E%PV8hoOCCR1b4>G~^q>sqs3oPC_qrFaNSaXnPxtDhM zHbTs9??wCZz>c`rT5D+#Wp2mQH~F)|4A&^DnbHdEUiJ=Gu#Z0d9*neqQA#9ym*%={krltwEFW$>clBFm=?{lV zrp7LvHGyP!CSKi#j<0Sx04UW>c7~Ee0)mPZ+V*RY1o|mtcG}5}(0E}8y9P&D2dNB0 z4Qf6jtnykUAS1Rl4p9uxUb;obhG~VP&?7IgYR4fSw$nR~4MeE@9Nkkk_Muo}7HZtj z&!D-NmDw#w@L33?WjU>4R%6gn@5F=H)a8`d4;Hn9+%weHPU!c2jnk98{NGywm32NN~<(!fY4D zq?!rY<}_fXK4DNzZq6@++X{uvKR&xa&LqC+4Z2Bi`qMm`6XNq&y?}ad}Rt@&nVpv3xFG3@89%`0S61Rt+J)5F^-F>yH{jHPG@koG3`>5S;%;K{LY#Equ30(h#(81Y zqSW82Ydg>J88dfm3)!kt+Wb6~chX!gV?pzQO84V1CPa;ED}ts}Hs`#~v^sp(_JT$B zJ{MdcEG+eEPzw!IMk;;RmT)Irb|sGsUDhGQy#ZA&) zcucpGx|B(CJZuvC2x$?Q$NSuiw2#vR{`*EH(C--l%^Gvo+2&9U(FMo ztDSop`_Ei%ODb;&oH&2H(GjP7#EaPL=$_W`7rOQo*Ww|}TUec7@`pRM^t$FUpQSv0 z){{-O)!VygL~F~rMB{Mgds7OBJUNW+>0!v6T~-#+h?pavv-@)3iyhY{o6R|nQt58J z-j9xY9tItJ9pHa>d+>c=V0=)&0TKD=&>oEg)`>TITFfI?ZuA;^@c1XDvJ9t)ikmb9 zZrF<+bD&S??HRs0$z26Yc$AM8pYkRK7r`{L2lTYxR3Z)F*>~*k-$4_VPCe3^3cK<- zV_|~B@YFbJt=}Fj#P&(@rN|0;VSawXtOE3K!AHnhLc~NDK9d<{&zAp8Ix+XCDt+|h z`>dfEtl@moCk0l`cP$RDOVF4rbNQ1&U-p;qkFCpK*Z~H7h9Tc*q{<4De6PE)5GMeW z2`Vk&n=5BolP!M*iLo&+giyyy0%n^lElOkV;EERy4d&s|^xUhQ&P07(%kN!&so`-? zCTVw(?DY|#SeRf)am+J~I~Vjn6n*L}$J82)Nn9>8xwLmNI1AL)0anuXx%)}W zvHs|=k=BH%e4#UBKZj_w{41OT8zf_%`o<^h4Gw`>o6=00mdukhV8rO59TSJI#_W;s_!@CjOKfBTR`?OA2e;zORP*eXAB=05~DUyB#T!v@cc;1gh)IG7xmLum2^`aOUku*hFPuGb>#1opKf5Q?imYh{A+%GapIoT!!@w?W93jIb(!{5O1 zE#YK~zmqJj0OK~CmiC>;ZChR1zo39HKbgp$r&wNxR4h=CsGEF6SJTXl;auVI{YR!$ zXe7fDOa96VU@jtiswj{Lv0Rq>*Z2yj8JdJM`ttCo2hFIq z^MR4$_0MmO{%GRnONG%74k?fk9kENxZ{4<+ZfHOqVrlHVWrn>#yMy`%kk=u1IZfhJ zdR7=Z3C32NEe7j2-EFgodHwn&UB>EKsMNc|^ULaV25f;Z+n4}q^YDD}z0d#KRf_Y^ zMzO$a(kH54GtDI|Ki9Vru!+G0Y%tLF?TXBKng#~$_Y%=*3K9>QtcW&WbKCi~;XNlTA#0AhxLT_B($TXs(* z9DR?29cS3B31yp;RO^@U+t(mtLfNrMu_%d8Y4*FO;rJlguyoWaq5EO~RaH$xp8{Q| zltq}q=gWLwsdHQ@lkR{iCT$Pb%X{DXP{J|$BD7stN~zZ`F6`u4p=9%YqL`4D$n$5= zXZvCbOzNU7A`dO_5#EfAnQLyog?|G(F0dJtG#8P@6_fe)d#AXtlw^;#a-G9c3q7e! zkpf-!*-ET0K;mA+6yc4lKccaHR3hoxj-9cK)>ju7%N3SVHT|TaZf5oH2`;-K{-F@8 zBgK(+lwa*J;VN*|^5#$HZIDAu`nE zhcdOo`$NZtegL{8cQtMHJ~Fl@Qr5tV7kGwb(R|HolKO_#8dTGW+Rx>td0Q#6R7#17 z-T>#)fc0kWKey+dn}ybX5nUiT znxUys9Qvs~oZ|{j6~&TE5z=l7! z-r%SGMDo4C_w+AUa_~CR0|LZ2@wf-yz^dNNU==*fmBzlm%xA#Umci)cqD!A=j&mR7 zZCW7e%X%dZ>WR`R(Y5hH@B&Q+8y`0Br~t1+Z032z=Imxzc(VIh42{$BFqk*a8l6iVgeT zZ|wZ&MDxOMS5ZvWNdl<2hv&?+#DCH3>P#`N@{Xf%7Z@^fqXx%D{X~&ksi1(DXIrWc z@O#Jnd;{8!LC9uDUSAL2cLi{ioPPyM=LdT%@2h+*RYZ!nUiSP#P&fdJ8z9O{Tut}x zgzx|-pY{fPh&g>Q*y^|2>w1=4pD^V}z*x$$pgN5bZ`$dqWpE_}n<*gJ&{czp*xqTn z7wBB3Gjf=LswB8AaAoGr&qh&k%`~qAKk-)-YR_^J;x$sq@Y&9gT3)Ftc0M-F<$pY^ zzc9#nD65@~fKfKAtE3I@EJHj9Mjq9~&##ehKJ8Wd68m%X*`$m(Gtx8#YPDx;@a(EO zUqTL-M=WKQXTP_$k)WJ=vf-9tIT=hqR@eVP$o0@PvOA%oOv8vvBOJlx37K%!(mH%4 zK@G2S3DoOp7l>p*4nLo>!8z|-h|}$h(eHCQIv%dtlXmB$k>#TdD!Wg7V{KC_;iZbO zMxoSK{kv~Iz{3;I{5#tMA3Q?YdbiGpHB!Q*R(}kS7aK`hL;Tfsc&1MoITrB@oLWhYzDMWo$vM)Mo8_Q#u>V0T^f=!;9-OA!0808|Wt?SIx$N@( zQx?xPK54i{S0m?FwB)>B>R}w>P`6|EuYwR4XVKF)fw}VzpVya@iy{taX5UW$C) z`)YVPpez>fJ5%81ldr;A!uIlD7L=nj;Yzwhjm)eQAU4K(<-qL%k28S7dr$TnWy--N4|QspO+<9? zG%JfEr|gB{bqiK>I#mLqX)smQIAEO4hjnJz{tc4hHS)JTAV!-oJ*HmB&>%{$oolLi zX^|4*q@X1@MAovjpW%tV6|$qJwqybl)I)3MA`?QXBgc@zbKw;pBM*zCK)&R0>L8NT!Ik%ide?<3iG~+Y}0^XmvewfGOM0faJxU23$NZ;WFEHw{=8A z_VOFcL9aQW2DFd~Mk(1VI8h3;YkPm4?k@__G0{!i-rD%`%8_MmH@X#+!B!8Iv=j$N zW8_sejM9W05ix>B$wG*_ZJ9%pP5Wxj^U{1*z-py`>!W_3Am4u=ZyukTiLiv`t7n&X z-1hL+_AWM(f}DnT>ls+t2lLYfRxbOl>^*pqFsLKlO0o9oB{2uH@@4ecAzwF>REPcI zJcL_62cZWt%#ycw<&&@M61)1hxyjv-YLDqLrc0HPbfv1?u{qmMy;((1r~~z&4_>dO zW@V|Ldvuol(di!oOJYbzDEK@J;s zxmSvObt22B$S7Mj%qd$DD>FlU2^Y^YWUF)!VRwIL3{icq0|HzV5+kR=K{Z!Es68sv z?pCz!suG7+?38SnHjfmEvQczz^s;&3KM0FqNGt@r94H+{nE#QM#yU^oA0A$eO06&} z-R6^Bb@bU8Sn**2wV1|IDAe}ej!=phF40*s8O~)z?z>8ds47N>vIEJWck2S;SmfN5 z;sW!WlBBl0%!(V$FQ6Q(N+9Zuu`AEq!GCAV$khf)Y>!NHEz2QSqt*6@}&u*OqH5dzpR9R>1~x`Bqo)0 zjhH!RxAFZd9{pN_P({Dge27wN>fi%$2#|-j$yuYY5Y%@8+af$RDs?~o@EeKnuC9co zj5x%@r}zoG#|wBohAHc-6H~t4PBk~X?i*3~jziH|Twjc^TjY{mrLXmH!skW)3xf_0 zbVr!pptIA2j4|4O&`0uQSw6Ry{1)#Yd`o*o8|(gTTpW!E>* z-qD>9ioy427Y?)poH%s+>Zz596Gk%}Uq`PF%CP2r|Nn|lua}tqgFNMa;^OwloCAN8 z$qZ~+$wnmDSgusUNbOh!Up&REt~Zlq1qN;CMIy3=*)jZj%z@`i>dv-XQeOF6Kew-%l z^*YOsVUGifk`a~Vh_i_BJnZpxSm^gy)wASrhelz>d(px>2xXD1aVc;#2mJ->496Yh z=wz7sh5O=8%QTvZs~W1VFp=BxsWEoZnQASK&H5pQ;gKBbYQ5zu$(0reQS#sl5Pt^; zC4?HN%M5ODA_p9i=KgMhL2J$y5}H(Ynx;b6Sf;sT3ERoOUaEF%#N1xzKCPg@ z<-TCBb$hx+?bDd@7;QwmsD|w-wp^#Tpmsu8OPZJr5BA`oo*zH2DYQe~Urm@rk0Rjxr1{+mdn8o@rK?cn!)BFw4~HRkw>;TLV`-~>6k@yBPi->0Vfq7mA)7=N zL2KeN+u2Fx->a>0GyYbxDMW1PHpSO2EJLX!c@OG8)OD?WNMsM(Ue6`&B=7BQ$<8B9 zm#w7mp8@kZTuu43EkV0PuhRGDU`)+AvEu z?%O)FTreBREbVSD-=nkJtE5sq%bxyDz2D6#E1XU&n{0tbZ7~0w9Y;C&`=4~(SCBdu zqt(0-&iDh&k`BL~F;Zg%H5R!E5NmUO4ihN(6Sj^Bqf=C+gjfPv3M{+y%rMkP1LM8L zlsrqy>~cwIoj8j0w6eq9zxtPDqBo-av3rk-n-rCJc?3wBb* zhupVm>2+zm$c0__1)YP>UFkkjNAa$6MEeO}sM^*^r-wXQbY?=oT@qTI40A-BzTT!-^g^pX7Y1*D)^cs`uK$ngr6_9+t(8XfF5o>&S#W9!yv$$1* z@a?asJ2Rdf+~%M(99ESR8zkBvS#uOFoo7;sR+Isd5|NpKxpMD&2BwLSb3FCf(_@W8)5S&EjpOF={~#Yb#EzNxpC#plLbD4l zzx1`cyRo*9N>Ogcu66QC3qn#^lKXrL{xLV;l<%Cg)ol@~W#WD88U!#kb_JspBV-xr zx$N28Z=|kaB{}IqvT|QMx8rMunh_Cqi>cdjQxomG4a86hOH%K}pQ>>2^YPr<0?W+2 zHbT<-=b5Yx&Aey7Al_Y+jNDCNBl)uuMk=hlAou$Lc29C^Oo;b1U&Se5 z9rI}Y0Tu(eVM(8LqbuvLLC#~~0h4!DxH6QZ(=j#Mf=8KnaAQCZ1Y9ZLusQi;`2;g6X(B8*#hGnao+NJiXBPp&5B^<0Ms}K zi*bv5#Xxg~VrmZjmI<<-+Lyy)T+)g8kAZIaU#^ooP$QzsCql8#O_yleNQv_tM&;qq z@MZ%{+Tnppbcr1LoDfXqK+`yg0q((Py^@O@R1FRm%+;8NS=Vq-EgCVG@1tr-FxnJ3 zTS~>j3|hfEwhrF0^-ZVohop_Jy>m4@lD_LrGSi!%maaj?^lNTNm{veF^rzv`blXBl z5L<_GE%5Lyi}(|=7~WLc?GmprIm~#D49r4R5u%A2CfzSN6-RTy; zC!|f2t)7kAV4s4c>2TEs!><+4OTAh`yb}!XVAurm;)vh_JZHgojM$mIDMZT7BkI>B zyEv$b6?4yWR4xZ1{)9d%pRNOi!d-E?B~$}_!J95fdP(`JFbnQJiEk#nmX0jz zO?g7bjx$h#6L1fAu(==rB7l@~&?;>AMFu)Yzu*J;L5l;g4TR3Z4W24pqdB=qY!MJDzK3z^G-stdu& zN7J7zC2y?ihACh~beTPl;J7JxC*w@Z=8;`2><3zeR=yNz&uFwB;=wtfS`sipL0TE3SJKW%84&wbY))5Kwb_>rTIl2U1)|mjU z;idqui_Xj~*LcdHxqMgc|fKC(W$o`HU)<5Rlin$*wwp}`F1hllJ>-c5s65YSG2 zs?GjvP7J&f5FJ+GrB;b>exjjJVF6*u-Eo2?k0Z-gsrA+|f-W{Fzh|GL#ax(po*hK_t*XFW4Y2AH;q6U3lq>vj=PwR>{^p*o(!z>RPru=9O|9 zbPp6-g+qU+G589$5~N-kwko#tQA{!dVL{X%ae2!-FO}laxg=nm8FJ0vMg6wsa{w~jCkT7Z z%^YP_m2LJ!06Gmo=^T&xo$K|EZ=Fei*s{?1ePwbyRR*Syrj{R&n_t{1%8L2a?DOXnU*k_ z3LlyVS@0AgNb?T>$BmT3+q_RL9N+`pVQen3`l%3VJzDsw@$%~0966;!b-fJ zC!>88U}@!v#%2%}Jsk|Xri=F<UGdqg!0Lp zgoSUQTaAiC7w$p9Y$dS!nt4-g>gWsx0wq;`Pw1}A;TX^x_yRFhB{~jY2fY&9Jt1%Sv&WbCHo-L zrLG;yDWjSho@>y2jY^ZML7X5#IytH~M%0&P{@P{`_XnB*Dy}TN9zjJmw*f@u9D4{J zx}=DiJZu}Es&uhJ!}b{7l>kZRhV2~^jg^L#ZNi|=KAHwu_J4o;W6mXKa1M%21nn6_ zRpQ!%d=S>#E&bIf9tr91(P&s<`BYj>@2HhN4V1hd+7)6v$bnl6)6o@p-6=>TD_KHpN!On84*$R#Jc{n3!Gq~w+o+b& zJ_R8jWXGGR<=rTlJX2?%_ISg`Bok5tXd1V;FiwI|0WQWq4$s#KSHz++AK5)sD&q>u zsq@p-GIXXx_5{@2C&VEVW?$0T!S7&^Jg__S#8<}#=#tdFjj~*E;3OTr2#6NRMB5sp z`^^%ZJ-}Igp&y@=CzC|TF2aFsK2n53={$TQ;)u=F166?1tzgia9g@dKCO#D7&NGR% z$fI7!HnUD=uD#dI$5%)*^xaP*I*^GS$WGG2<$ANIbvRFmY{j7-#?R>dkrV^aB`@YX z*O5of{~vYd{?GLP|9?BOInA8UGv^#~Zq9Q^V-9m(p_b%@D1_*MZ4PtFoI)X|kWM4X zDa|oNA(fn(Q&g%6MbSQcfB%c`<+7jl(=OYd&+UGH+-}!vZc-=;nvZ@F%6Er!GfXC! z-f;_msn>ZKk=n zr5ZXPkuDZWfHhx(H&${T&U4aaxT*{Hwas%P;Wd#kqb-n2-}{a~)45~t)`;0vmv`mK zyoyXnX60zB;QU0u!g-hfxrA%R`HnMnDLntvRjau#+_U8@v>w0(X29WMVhzPmI89(} z&21t1%}_FbWn|LcS&?VTjv;2D>ycR#O#UVUEUX>u%I4)NaX&>YM7S)Re*nL#lWI9H zb8u}zL-&L6clbRf{OUD$&N#&Hj0e#G^~s%1C0(n#EBMbov@N)#9R<(D^7<3V>I})= zD4FRuW|ky0m*{y33#+E{hy1yYt7u=N6;UE*UiYA3WDDsX;3V1do*0QU6-XTCo2zVZZ-7^h!)_q>qUccWo9szHCF#+igB}a98N1U7&;0go4E|m%U}3Es zo)VGrjDH{}1gS%ZQ0Q;(G2jm)XPek>BO*9oPCOVL90HW3MzB2<49HT($&&VTNDM>t zWZl%ie)+u2`bsum*zse|2`IP-(t|7RCGnLe!%tbQjlY?~$O|yWxqqagetMdi)#DbL z*7{5ke*98tB%EUwYVu$Oc@kd8Ub&WGNytNU$;FHV_;}9J+knZt?74ZB+rTQ-SyLj9A`?)sw4RG;c$sPhc09nRmRv+fuw%~%TCB1_riFvfh9j0yBBgsU}?@Dm5{ zd#H8SlTbWC>CRS(e%=M?9;g}_nr^jaa9bpJ9Nae{VvW+3fNe{LvLQ)%XUDJG_N`y<_8sy8I}C!?P;U3=Sma-J9G! zeror*{>xf-I`reV$?NTs+`M2Eq+u;Fec`w5;XjuZw;$j4@T=UZ$=#9Oly!Lx4c5B? zUj*WMfm#2-DhcolIdGfHuqz~j-$kWC8?Zm>XC>+5qhxqB9j1hlX>JA)3D5^g>!pWx z8!tc`#&k)jgDcj5AdhyWN+EcX8k`~}y(q^2c(rgmOO*qESP4h^z{q;ZL1YUMUB3X2;?s@8bVTN%n26V-Q7VTTPk!sK5vOD{jp~BJ5D)@ z9rA9(>BkJE(ylA&+!zN8Fp!ESq2r{45550!m#!iG)0md(!D`3!ZrbJ&Bu_WIwr*I{ zSlzqPmrHlCRZbPSb2@Zi8SeuX(erswxA)ZN!CPGuFC*0xh2iefXU|SGkSP#2+HYEF zWa=(U%lE!h?8pkQOM$$0+oQMtM>ee#8R~~Qf+Yy$N zEq~?uCon`{jQl}m#3-z#(d({#Y;%jc;0*;U9UpC{6n>uv-t|sL>}t~@WUOn0&R(oe z`7OG5eE;Pv2dzAqX`#}LS?nD|qH!zA!^f&P~Lzj zk-e@p)_ZYtK*DeP;ef=?UL^|!Kb5@u$bZrkFGRb6{7{WepeA%UjxgQ>Nm{qzmEX-= zd|nq^L(t|A<-w;Z_HBJvlnMwcuowKOqBV%gb8fzmDGu67L7g36d?D~dW%HHUF{2o? z?z1fSK?TVjk-mK%!IlA&g0js{q``?TS4mTyEElzNdWOok!=}hIwb~GNkKEWO|G+aE zA<~=E9LIN|x{62=b2xUzyTGkGY&yz8Dt1F;=y2bkALucm!Y4gYPAKKRVuR5S4W8Ep zNENw6+D3{3Ez&j6D0(v|T)e8;i$s(hF zYTJHk%^s5b`bJ7)06}ofJxETyG`v6cJZays)tx=*4XuLFT7IcGEhE&exAjn!{I8#U;LKh(3CNi}*RD#dgjb>T^BJ z5g)o|lYS_6x(f3C@-!I@J2p6Ek$rOa*f%nNKj1&j=N7y6`yQlC z@6X~O>RA*dRFi+IDmDHzzL9sX^S({c_5MQHGo5@fv8GFS-M!6*sE|tu&#YV)nPb;R zep%=9*WtosD1z^HAL>_klNjrh+Nr~{F8V*DG}g?pJJzWR;Xm$3nl2yq+xAT}JC>E06ZGC45$YJRmHz98y!4(4m4J{#yIv+-Re!2S9uLvTFOxmR zHq)IUg`XKND>?Zaf2Ye;(`Sl&xzP6pKlBci_oA}8_1WH<90>V??8!~$rIvHQ^5Xk1 zI_;K(*vp}}bdSQ`-4pZa`0G`h^!YE+GiYxr$sLF zX0!bjidSq+fx0K*M)&Kx4|1QXWUZ_(Ij7FA2A))rHc2Afn2&f|$DUiV$s5uu5Nt4T zD*d$AYx=7G&zkbgR>nf0CrApXd)-y~zn$q4wEJ6Df-$Mb;Qb4++@G%kyt=Yw^hMi~ zWtufP3F<;k(o-Tob(8tz7N=EwJHkz-N(H|8@fvoN<^D9HAM;*1hM0E#WFgvk=;+7o zPm*``@*+%rZUm}s9dXNz-l^a)&$=0Y?K#!RL(?Pl=-{)Qv81AC)%#_a=6yNq4O9EXKF-bv#m|mEnHU z+Q@Sh`WsYbLNU@Ke z`UlYV4ImjjN_=bb5=>%@FFWQ;6DnrlSrG_&*1_;-7IX={)*xZ4_RKK+0O9&@t>oQZFxVfoQs8%rn))0kj5w3 zVezxc| z?m3}~;(S*BPJr*>C-#em5t=iZ+FLzYMPF_wB%Fe1{dp9Y7z0?jTY8Uva3)`=zea{&QGLb!=9qbIMdg{|(?5hwdrKNmlUk;?%EHxeJz;sU*aKG>3eS?t$jcGr(8;V5>KF8Z3f%BpLw3dry9t~ z*KYHQ|A37?`tn=*)U!7_O*&Q^S$$IN2REHo%*qbLjf}Ph}hNX^Vi${UvigplMGFP51t1%e`CR($^46t?Amy%J(v zuWY(!&hLE1L2@xAITrj@hLbOrjDR5Nk0KI#|1*Up}gKRXNrER?~v{|rs2 zhIZTLShFs>jb%NHAiIDo20AO2T5}IJM4wq}o6k)5oqTMhXK(KyU?OE?r_BjxUjA!o zrGlNfVt0=FH96ORQp?_TzhBM5hA?GM*tWFPK3Z!xpwesa9e$MG-a28@*<9(-l zT~7B$ogU0NJ=}15wC}_az&FX^o3-(eE$}VQ_$U7O)^PmOtN6BTe0v$b<37H#3*R-0 ze>R8j-oQWK$1??-d*qyZwVnGcoco=f2mGA}!<}DTbsoxg9xihpx$pe4%XxIvd2G)4 z)rRxyedlojmkBwSNo|)m7A{lHE^qx^-i5oozv?ob?ed|_W#+!iY?sU2sLTAE%fg1s z$9)%;fa{{1>yozXvW4r4v+JtA>!)znwX3e{*{+|yLd` zwt(BFoZC;1w%eA4+qSdYj=$TlaJS!A-FCCx_R8G;+;{ui<+eZSb};AmZ^MnV@5UoY z0LT-7Is}j<0qjD61Q57FU*2m3KCX^~I}kr0@INC6j1dIq2}0ip!UqI|pu32?J5tA8 z)Y4td#a%qWT_VC=@|wF;j=OZZyUYW3*=O!@WA5_v?h4=B6%X7|f*wlp9%vm8WlIkg z7Z23{548vn^=lp)IUbtj9)})yXg%}L9`n$d_t5?3arnSPPtbEm&Pc!LHB!s-Pob?* z>}!s`L9w6buZ^;rMH!6X>)UN_4nE6S?PZGj_nX~u-75j^(Sa%mFFQf6JruBP@6Gq{ z6njnx80P|ZEcZH=I^|GF)r>?Mob~#m0&zR=B5)tX47+up$c&e3(JMlLw+Gi|j7s&z zfDQS|&(C7b1?*5xZ%0Q{@GS3B-`+ZF2)GY;iQ~%AUsdcM+w=DiG=dPA%lg)Dy?YCD zMX;2xXFe)JKr5b9Ul*`G15njOH$#?3`Ps)+sR!xYI@aODp}SD&o($u5oUM1L zptC-|q|rVvdL5ubqT<<8&LpbpkPv8z@A^<>a6*OeXGP(kRj)S76dLbnn&sXmJXNHN zA8!Ik@5*%#<;o0A$2XBtHt(;vjAjzZ<2~{+JRloXsyEkLjisy*;C1v;Rc`;GELHgW zH`NEXavl#IFMpD2a<;f&rnp=cD838eI;t_1ATt`sWQfAS0lKHJ*XMxl?iBwuJ>KsH z&-_AGou<0Rr@CXn+HBaFXMBnO&#PUZI`coxHj3ghmbI$~GD$wsaF(jOTYRhWZW595 zEQi`rPQma9x$qZ4Jk>uiVuhA zQoCgBO3;8Rgc$!ejRsP|FsDfT?6-aM&ECBSE2C0=s&09-Zt%WvSV0NBSd;536M z#{|B+b}|k3aat7!KSUpbfaX0HOr24N~R4>GZ)vNKI!%>#g4^oPNz8NohlumD3So633BQ5M_2YdhDEjGBf3ST z=n{d?vi$WU7bQPYb+HtoA5y(LXHLK)tODgrD#`@ zxvc09FbVl-irp^nLPQEiioC)AMCkav%%Q5bRnOt5&P1+t`?wMcD8xz@S*JKm&)XrW z@uqTIpE*AAt>+NfEON>6C{Q)g`!nY#@UQzVqsm46I_0&J4lE_GTR`H_g5diAl1vC$ z0i`F0x~EE`x)LECjMLzo{L%z~N+rnnJlK#1lVAb#a49}T$8UOnP#^#rn5#ux5Jy}N z_TBt?(fnG^DKraY{5?hOyNSdQ#WF1w(hB(LZsk1q64-Qht$evuhyJF#Jc);zl>FAU z64c&M`#Ub<}RgivL*fvz5Ta`L*-kC_1HqQyC9H04|~|fAcRdG0~e_);VATts>`Lr$O{e zh3yco{2aUxK$7DLGT=;qbS_z)zPS{yBg`2aN)&10d?7TKOwtGr2}aYpc*Bo zAt2Tipod9GX#ktVXFN^&R`t zpc(KSx?#FNRir70TZOkz0W_sT|9u1cR)q=HEe#|>2sBVQj@`W}UBA_%6h(~qLD9L6w2cpYfR$HYfSU6XyIlNoyEM>=d&TyZ<{WHXaeSQ^o2(k3TwQ|FbPT5kUv{iiD`kw!5 z@LN}0&^1S)Kfi*ndxssg;`L5`vwKJ8TjKw89w1S%G4e`C@AM7P$jHay#Fc7#Ot#^CK9g^yJo#yVKsx>0@{a?BRiTd||R}hMt3trNWuh7JOHkAOgimJ?f zmlWLsI-D3YfzxHRynCgs4wXKMq+RN?yn`);Z89^c-VE9?_*$4U}!&Mn9vQleZtAN0h%A}kN+X>!S`?ZOi0^0M{6)TtB6H08)jW)gTg zru65TMO$eTdeCPyJ%^cMf0;EzTmEP*XC2ROumNXCWr98g*;Lye6_%Ffm=@;Op^9tDmy#%g)XoO~87s1>LE zp*i?DKbz{x<&m)TwScNtpxk=CRY=l4o1k z4V%Y~)hqe6?Aiov1nNk_+2}vqeCK7c9;Ycho!i?;~$F?_lQNWwA+j|rW%g-Wy<4! zk=z>3_QehSiLIJwb|f1Z&v>ozi<9n+RLYz=Y}XPB;*aa}AuX00Ao;zN5Ny^9y7E@G z)}ESYQ-pZ8Dn4P&zr*07?ZL~ZKdhxMYu)=bTEz08rXNnc9#K-0-DURr%gM3MOUtji z{kj$Kg^|N8%!{v}ITww3y9NDP*s@)JoC-nZW~uX=tI;xTkUEZ(^*@u{rS@3$r?0He z2;cZ`_VHZTO{+gOUv-`nbqnIg(hP9#ZM{sU*?rc=1oe*;(TEps&%Q{l^GG=;Qn7<; z*CyNY%bknos}EY23+TM@;n z&P>;mE;^RHjku6+G#Mw9xc&B;@E}*J7xS;MrchT<+>T$pkYFo}kL+=fiyA*Yq*}?$ z=RaJ_$g35MeP^nXqFK5P3=>ps41wAEpB}7<+Q{S6c*Nr5^XnF)Hr?PMPBF75?KEkH zmos*X&eb1}@Rs!OEWa_`eC5gKjpMZs9XGNbUUMo=vUtX#@XyH11bdgSHcXsl4eEV) zyj~}Js$KB-t$L@B1C)atMd~L`t%f+lf4E0QH0Q|2$O3+O+%~qq#ks>=G*0p8XBIMW zT!f~S9^`TNemhv%*=R0u%f+bNxym+B%)_WC@af&zg1}Ecu`<13f-l$?f$ze%#xQH) zhWt8MUc)DDhc?!ZeG*#jjn`Hgd;ALc?+xXoKA(?YG2J^7*~y9#8s}>e=Yg z!I`U6SF^9X%Wh`j1)>7-c<}J&*WXOFcSfc3V?!j;Sse7QL4_ncA=9t-4dWN*k||)p z_@Z$4nB!l&T4Ih0ZFgxY_9H>ZFgTAiI8izw=5xB8>~pQA^f@1OL4$~}(3)0bS#!v1^o?AHn# znJxysnA!KWM=&?SeI`n*4;D&~ZnF-Rwc2HUmQxVaK)>XnE{g&*#)UC_l{}!fPT_a;H_Ws9p%6BNyZ|UfRNOP~}t=+{sd@ zYGfX<9~O)jEymf)(YL8OE^B@PWr%iUbc14$t<)SXP34Kwa0p>Czu>-#+7ZWLeAs0E z9P23BiQQuFvz}$+r&4iwTGGC0Q9N(IR@?BdV1x=)?094#g{MVQdPOJ(P}n1R1bJV= zc`;A!)*XZ5c4xP+W@I3VtT+E8pI-TiHyoFu5x@E9Nx%emm)D1k<2qeRqxCGhJRJvd zR4GJ{K>9jZH)T_}SKKuxRcr2`4$FCAhEDOar`hS2+#SZ78OjV}9P}c&Sv@(5pf3to z9PRrgxZJZm%ZQ&pQ4fB;cJmfW@UwVCs%- zwzBKHYGz%>Qa-c4R3ia3XRBkJ*aGmHi+cdcB^1n~OkZh+d3&?F0MRhSgoY;{HLx(j z)SuLsU!XbY5vurTNHTA?Va20yvxn~+jG?lSqeiUy)|>BsKAvGgL+oaot|!#A%&`YQ zSaq2Ak1v9M=&L&UYTha0jC_vA{eW+nY!c3MTe$CNlFP-l8C? zm>wY-D@7GiRjzT3Padm3eJCv^Crw<_wA#!&%;#|!aQG0v6)VM@iN5bEpw8nisxhLr zLL};E=w*F*-IbcA39#ih5ecx<$uYMvG?^rXK~Wl$2NuBUQ;p0MxG^|PAy*T6(p2U0 z-89qQOj!gzEf8QpbX_30tr0iKi_ZbI`hp@fy;R+PC6Tt>!I|xi9DhW$aQt+i!aq9A zxe_h;f(rbGU%+Gd3f3jfGI@rJ~VxXl8B;A&LbkNw9-#^@98THi5VC5jEp*30A zlap``4}JiY%Kj3sPNyhUSN*4WU7KdKdGWhP;nsHxYvI%?C#&; zZFZU_w=7@YB16_b$V~d8Lu~BMUUNa%8+D!A!r+Yb>8@9fr@Ui)FT3TGaaxfx@qGAm zjp!Ft%~Ga73==3kN0tnIWBB%UWQzRsZC(q~bD=Ui6dymEIiUwXlYB9_{#vN2Vfc}& z>>9yh^#F4M2s3Uj`b5;tgzuxPp$jJwBM^B;@3dB5@#LNhv>u}n#K%}f#ikREx{fJ@AWi;o%mBXVvm=u#&t1xt(ZAI zlZft%*C(35;dK6%V#|+_@F+cR-ste@(>f7P;`N%Ho^XcnI+0lnCgt22SeFL2!95fc z3G^etKK>F;yO^!Wbgi67TS1DC4QX0n!4oBxjvDZgNT3-HHlOAVB+Hcb0uAZ~y@N32 zB&a%5M=^TZn#jEcr5~zK2k#|r)|<>> z`TZizjM?JPYR$E=&{FKx508aDM#4)Cl;8PW>v*m0H(l&=|wjf5Jje0K3|GaGAPZV^rIfaGXC-z zv8)B&qG=Bl2cc5VIBr~T`4I&VLIuEljCeVxK>!a>63u~HaAPH2qJ0<{Wm^1$cy)8S z)TT;mn`qmrS^nv)H@fPSnNj+`Hp{<3iHQku8pr6+(vp9S5??mRKTxB7)6|TfWY2_l zu>ur#;8Cm${S3uPbm-t|N^w*8n1j#)0T#pnUr!7lyyr`nY$(ocDj^!WI zM7;h`_!)Hb!$fh@>2e!1{1)WY?1yr{VUYDWLNije$Ie-I1n5VH&GEP{wcQYJxT@x^ z9I)sqp{lesoegYKmx~1ASl4|yLB-e8ko^C-sMp1%Z|a7K80SRE4FA+RZy$V%ze+LH3JFwX8eHUEiz4Q7?OsA|$=kphNkIwC z2IUM1GclAkg0CHQ;U7ZqJ_%~iJmsw~d0bU{DN189DiRpz@|UPfjW(#s*WQZ*(mV{m z#l)$5n!eH(uaUa(bwpcyQd^Ru6m{81cSN#RMYOjiSMt^+TJtIS*(Qq-J#lfYH44JO z3K_3a`a{d09U@-_KtDLggkB97x*HY>ozbN`)yWR)O)Uq`4(C@BpsIwpqBF7wHWejr z!B-hxA)%3dUw|*0MK)prIVX@t)26&%t8L)A`b$z#8Ni8S#cwZNdls$X=K;j`m4X2h z_#XU0)D!KCT9cc?ye|xw7qey;Q+a?AVpW~ zGgENy(X+^UGR4V?-oIlfN72wkbOay0wY@4iy&2u=u3Eoc>YoNQCcvca-~n{+v1S9? z53UAmkA#u(b_TD#o`F8HMXm|oBCX;{hmhzHPs9;NTX8uw@>GekW}lJ~U4^Tx_oGAn zlF#y9R1&v1^lgQaZ6mg}-d^?9EaNn@{xqm24Sbpc@kI5>T)D2xu2(+>GMHl`y1W~bEm($%st6hLP0=3dKpcz?XXHy{X`MJ;MxZ=AG z3zbExJY>L!gnoOF4%_vRqmb&6>)H$*wd^M*>rdWHC|d{03ifDnZTH6!YB*GX`QzsZ z_}x>SeePDMftuXPZqNi(1J|@bHfV?+6C&aqA*U2_#O$evnTyScQm;|OaV7+10l}fD z`)N7f?&+vyTvOL*%FtIxc#%H!&U`l7=rF3!jxus<-+(yVG?CG>v{?Oq5A?hXqEr^~ z&3@$mlrH4uh4NY8Td3NoT#wby65S5<_1}yhyAcD7O1%Zd(Nf_Xhb- z`Dvm3f{z%Go?!FmO^>~Pf)Wt|s2ea>Li|ji?sjbVo5enZ)8;IF1!I)T2e~8S7}ONr zK>Mj;VHpq-2wJ&6Y`YKAT=t2t0`8lL9R!D$U3p?a17ihxYCiR?%Q?5&i7#DI@Z{(p z>uA6AE#n6P(<+g`?mOR-oy4SVJ@^K7{QxPfE9CP^~wIB zJkThR*~@&?$ZowviMc%r57lwl$`_EM~vpR#2e$WIb+452XVEL8r(jE-w z4&(^T-cS*(lAQnz-)&ZP2nZrUx$#WVX;n`ID-8wnap5ieHc{X2d0XEh=IiW;0Q3wU z3e<(^>f%BP(DUDl?lfA#)|AI|AVHN^9-?76Bv!;TaK^J-^UDn<>Lz8(k z#`%g!d{HDQ5#_GP?pQfi;;<^Y>5RENDEN@{deSI2c0vS0hhA^9To{MBA{NAnAYkC| z`3|sOq>4Su{Ddvoj|q+ES>^U7LKzS|(>%_i+e!>;&q;;^GMCb@Z+#=6!K7F1p2(at z$bauV_s3qiFd%22@uo+@60JT2^FX~_y)KQOy#{FQ7Ap`lkgb-gPfQIsKa97W1Y*Sm ztlCqte$xDnYgbIjwy|f5}Sq%^(-%Vr4RasV&%R2tsAJ$QC$Hpai-I@H8f*D=T>F z!FLWF#=)A%Qwcqh@UedlqdRYf&{#a`&bckh@wpFHJHS>2{RU`!-GjofO#T~@yq8et z(AGa=c%b&<1AFDl&6X`ULXUpL=BU!UBsjoCV4X%>Kv?I0ueNW|_HPc!QXro?jUsJFl+=6lX(!$PPeVg?Bs- zJC0Pq;!%+0H-k8MLi$f(RW|5~?&(L7nlt}|t5r|*audcRyPV*V3aYH69O~*Z?qTaR z9qIOn$zQ|ZP4JEPi2U}U`&*&PTub0Jxj!Ji@mH))Mf%0^5C(54dwXWVvG~!(L&SG~ zY3$=LrQX^cbtcF^nYRnFGpp-(jRP-2@cLDP_&PsEeNAnrUNWacGf=(g}_*YnDp_V^c6$U~k-3v`%AWR6#xyIpdqrlgTY z;^=N~8oz{U94_PHXYog=f&prxgZz>jb}^&cRU*r&0(9wsu1K4o{rN^5>_5A(mj7N$ zxph(lW)acP5s2Z~4ycUkiBpN>uz*(UZvidq23wrQotnE_7`m^w#R(U&;MKRGJVgE z1Xp(`n_>%VGD?zmign-I5aopJ^BB)77lt+jyJ!Ht8trZi0 zdO2M&x_?#b{M9*~p=bGvcSOxV;%%5UI*b^M z|Dx!7rokqiGKpIeS5Pl-JA9Iwu_|m~zZZ7`RYv`Ag27C|I5$imv02-&UUvK zPlcq2s7alcK~A3yBJQ2xM`H_~-W92Tl_Gh*Oga7a8Mb-w`UR%4y0pK5&2qZDz*k4; zFI>Xrh0a$e2~r;(qEsX!fWOyn&j+1~)V8Y~x8eQ%9kD94-Uw09ybymkC`-|HIaKGH zz}N55?8)|(?4JU5UsJ{E)>WiCKXn#&AA0^<{ifZ1*31zFb)%g+oQMYoQF z6!;oAj&7Ngg@M0|YW*_>T}gIo^hFEywN$x@#C3y?%(lPE5=dhXd_4iZp`*Jl+dBl7rLo)Vcp4n_ znE-d8o=ovpJ(}JXuoN*;iq6Jf;<_^j6x0W5R}N|OqrG)?l?LV4E1_ly0FRq3Ph{AY zuuJRqdR-GoA*Sl`XG9>n8Zd>3mahSyK&xGW+!2%wG}~Gn?7p0wXYlY2#5@G3C4sR` z3Q-ot?+QpMDBVrn4mqML3gvFFs7d=h;uF&=eCC>|qA3l^_h!lm%3j>x7jPkwIpN?& z#GWx-BTb_SCls$IDi{&6jPE#2(p^G<{xqqotK0+BdqfGqp%)z4(I>2qi<=FE3?RBf zPVI6*J`&>umrNx@1Xx6Xo7l^$9qL!wXQbP=@k%ey0%zz-FaxQdgea=I$PybKVWBR~ zShq)mMQC>ZOT@XM5VPxfFaxpt>xy|jNE!W7Cm9#1OKrWVje&uh)Kx|O)d5r@lcF}R zB*{U2*+|Cqo{LhHwD?@^3L`w}|8-3fxG6Pr|@?%VOag01rN+M{34tLTyYx4n%x~;9g0WP<^6) z@<9LPBQ{#ZejVUj@LuJ5Ef36t@+xQ|kKcr0BUTc7hBB0wWx4XbPVt$Nh|p;#_I6a9 zg9|-4fR>Gq*`}pl?hy{E1ZmO(oq+dlT>P{pe8_{0?BOfESRpyiJ_{6-^$@tnbME=w z474;O>s!!ik#y009u*8-LPDd5|JBb;*#$OK?0~N#q!1`*KNKL4{8aSoTM{e@qqRHt zUar<(PiDu3pg#ZPbvxRju-52~JEtedle8G`l~8x=oqe-BsYiT0IqYS16l}Z#CA5&Y zv~_b!@PAi|6?eVeCE^!BTY{^P1JIAFsX(<|EiM^GLxrPHv)m^mUr^A*{D}A~dHy*L)Hbq}`Y7^JYd1MnO`FVT&kew~Me_PEe!MKlQBSR@I@P~L`6NdAzwFB6 zk_>ua*H79uHW8YF!u92cH6T*D(QnFVg<>;y0hCFy0O)4);cFvD8JasCkccSl(8%61 zvm-gQ6oL1U<$@@07d_4SaI%H-+Dt^LbH>p|VVtj@dBqU{qNsTqXNNkID_d zLTdh{4an=72V6<~A=}nw*GT^@GFia`ODoBbbZl!SqH0cjK7bz~DGh#QwHTS9Y|)g7 z+38S8%~~g@f%AVolEJ+K+6@wdn3fcG8a;P=?~ZkR9?aI?s}F8FpO|4jXy*e_Njj^} zUmMBiA8%^2uAzR!U~vAiQmT0Pt{kp~lIDs64fMW+9@e#iIW?$Aw`Km}e}AP-V#B`4 zI{_~WR2mNI$o572^)L&1aVx0#TyLE2$5i}Y=XBI`yv5xfZ*b?TKb9z!&X(h6p!kS# zXYvVxlOIB^@*Y}mPd^Qt{N3W7si??_K7_&aNW>_dO;Q1gMRCuPXyZ!i_hrO`vjRS0 z$*D56l~6sFnh=qh<{k-ZT*0Ji2=qWTF*a}_6DTVnGVJ)POfsfz=>6YekZurKYE#-f z_(#TGTSPklr-<9JLl8R@uw{sb?Gsw2Q}&`OhNK~8A;1VzK!cQkyvAYhUQH|_4Ie^z z$gj<81kBJL{}Sc*C&@-g3)q|{%M*dR=7&d1HT4M(O$vY}xD;1rYRCAK5E`Tdm*zW^ z;(!8Mw1F&kL3YF=I)7@|?J0H|5ZWTdBc#`QnrglavTXws;~9_%som35;Sklt*~asK zO=2`2{v>JxY5-DL3Wtj$)olYBF;a#`Wc`^`tu}52xKD>g(P43qgebuN<^!$UbtUw_ zFiephd{>Do%A{S2z9||4w2rrl4rvpuBqwrb1{y$to8MyJcwgE`=1&9l6!>k544;rB z=v9pW(a0eH#PxJ+Bh4T-ywBqqH7BHFqHAJ^`noi8V7qkOA2OClfVCF0YA8 zNv%drDGVyI-U^C)@)T)7Pm;;x68ss32#qajImCa{o&NGipPmR8FLwb&&;4?Cva zmI8zGKbf$0ads^0B}*_VHjK{4eoguzWZUCK@uwB4I?5hPKf#m;mPeAWdFE5vsJ_ew z>kcs+B1Lwo@lD|kOLl9GG*gueE;e)d)|UsGkRmyOFTu)@rc~FxPBsHc8&2iu8OZ7A z*KW5{tk*Lm9c53J6og2n+To~bC`!_JzK{*f3zzn(VT^w_43--J3fnEpN5T9;2H8pIdOIM+2e9%u<^P~V4HGmhKkfD?YfgIzFy1C<) zC#Ut1PH+Mffu;kE#;aCBtj&+|I$`or7xN{hsQ4jQzo0ip7|MgG*PtN|}Z;KmTC?&o?K`Aj@~jvL3=u zq@F(XzwOl9f|SaG?~@IsQqC;h_w!2Wm`xAa%}Q#cVi>)#7b_I9M&|TY3O;8}Cm6e< zsLDJBzejF}&5@HDU7}f#$sn@Ul_Ktd`N1aBwU;8Vk*lyv_WnaoBDpCtK|e~+A4p_h z?Hn~0Xaks4Dl^Kn`n=s#C{9$j6i+Q{0@UofiWv5D?##gdz;iz#pg?C)S%!3zOeTiZ zz#h+W$5R!D39@3VRac|qF4B2I)lz^cJ7k7zo)fKq?{~5hi;|0VyME&MZGx^y-d)bKke?x zow+m5jfcy{3W2tyX;mXfe@2Q`$b)wspue5w?9DVhDp!aio5ui1(e0wTbnFs(MeYy%vcfdk+YDgB{E%&VD;D!U3!%r1R_Q(DsJNqz)*y>H_aNCkCfHQB z9LDF1Z+*o-5_ME-hKo-?^4Lx)tx``FQB+HQ;RqZ!_~$c`4`g8s`PMvdSGE2LqLRs3 z(1m$7VGPg$kp`*ukzgo?E>b+kp~ydNMnu(d_l}mK8?2Wp`P^0v0%FL%2bzK#4*3l8 zL+y5xSA9k^MaMane*>&k-JK$(#;FyN@; z1`8pdJms9M`Ee?ZdvB9x!8jW<;|%W7J|&1{yD*;S!~&vflnNt&c#P3i)7EAE%<)d? zw$GJ{Z6DL8((de~qh8i;?(}OrA)f4kGZbiq52N+>V77x6mdjpwhMk_;E-~bR~d!&di_uO;rs9iWm7c~J6rHwks5NcokLVK z#DWK8hyxi${&&fNiYW;k_7n2iO&4VX?%>RT!-R9H&Gs~tq5{jH$`nyFMVYJFC3NfT zg5+-vKH5#=JiX%bXw%Kn-gMhmUZx;r{c4L)l&Aq?_|awDW=OxnP-&ya10>gSPMpA- z7A38d6*RI%lrowU9?-5s-RTtPE{TER@;nbl>^PJ-4bp9E5;|_BPOBWBLl?||WE~ZF z1bZ+VscC4X7+e~bk++rnXl}yuvdJB27F5ceJG404TRJ_nk22H{fB9&!x{MZ!2x3_vm7<@HY+qH)wsQ}=qLCyDv6;c`Ws{~96atUI~CV!cg$&9Gg*&P9IrX7N??VA;R6S9zPRDZU6 z66@8S>I#QAacK>*5f6l{f77UwZ@@_<``^?xj#cT`gUAO96lwje5Q1>AdNYGw(zaBp*EXj)okXjWEMfH-sD z9%johKQ%>H zE5(Z=wrGg=r2^S^H(R^{`yo8lxnzOC_O&RYm}$VORKWaVUA7(j73wrTBt04Y`$(+w ztDu?NI*Q4yLPsV#p)p-cJl5Js@TQ+`&(UW53FeH4iIGHrYR=ab33*bD|J~od);3D$tlN8MB2?RzYTvLz*wj zFvG9>Dj(*B#q>N5zQwV zMFC`N5QB+u9X>E@LwxzLrl9sI!xAEw9hmlGX;c+0kGWgbH;IL}-Lwk@sGz^dMKMW} zsd09h!sY!pgYoqAXRB{-`W@OMC^YFr&CW^2KJ9(`6;sTJ9(%8~Bz<`QLwob~*l90H zG7;5YIoELLIX2QG{8w0rz4X|u!cBM&Hr4iv|gOV{hMyUO@s5_Q$xN~pj8FEis7QW zzC8Z&qOoos-6(%&?ma+|{<*q%F=g-Mdux=5Q|r{1_A}$G)AIauU`+j*kn7Q#vJaZxn4QTUUIDF&0+qGuRE5!00u z;r~S~UR#Cw_)(`wI@V@s<e4ERH9gSTxE37NBI^mvKcr}MBQg(9*uwujkB^85k zE)JtrdMEj>go<_X8VIgr8Zp`E1RO${-u3QSmp6Ed#qJ8!=bb_v^eBFl*uE+G^xc(4 zv(Q3gpl-Cs2@ZGrO4v8OxyxqQe6izQ^;wv>M2)wPoHHe`hJ^E#f2zgdhDG^xV;?fd zQA%dMGg*I_k8%YX)tv?r8SB$BrPk=D-IP2?i945~9Mne;o3b00XbXP-$=g%K{9aJ4 z*K$2VNvk`;bT~hx&CJGO=Q!_e{+;QMJDUVwW(rJhbSUSa#Wz-=?Z`vu*vtSo>vG0k z`@?01<#-)~;rv61Ka(D3nhZbL=DjU4Pq`@jZa%q2%&k%OvG)M4&sMd2%V(b6a3ZcR z;`9p*zevH>QAqHjT#-3?QK?tpK_J8h3%t5NJOT1$(&y0@%`uX)_Se29_Ms9%PoI+4^gAWWZ|(s{z};vTI5MnC3Zdvi zlzwZYF`sE0;=Ud?f)AWAo`MDkU_z<}i#8&TYc$hsQNi5lN*4Isw@mr0da=|z!NVgd znYZ+{OLhJHD?jG?2dr{%=hI$i;FWv2$Fuc<*J)&=(&0icq>C>hi&p#g>k!mx?RO%f+ij_sMk( zBnr4V2hA18uUzB83R>SC<3erhDO2u7vV0kP+6m{<%K^AuEat&Ib_Sg7%G11eZn;VC z8wrI|Dc(&sPSpjjgkb*rx=YqI8p#rSxm2jB*G;u7)$)nj(83!>rNMem9RpYJ`ZLkC zPAuXpDbu2LjxF-tZHYQJ&Mm5gPF=~FES%dwt%`%${G60Uw|kU3`}EI#K`TIZ}Kqvsjq< zL<{{?-lKd2nti09hDh?=3Hwe1SJ#lD3?$0%4%S7vSt^2F^39xVb>2Xzps`G*sE3zs z+rJG~|4owO;=~A)2tr)1{la;sM8H7RvA^w3G3V)G0#EhjkQIoy@|mXqWspHppf?NU zV7jYmW?lFF=!=4Yqt`mN^$m_kkLe8)K`IM3#H~4+l5NB^cSt{uNvhLUT^N?D>4I*Of&OC$chjo$M~S$I%x)*LP-iTOU(Xm|AT;YTJ^1lAWeh zL+$?@^|etcCS{aP}+#tOvRgXWWrem zIqVi4*-ce1jUCnQ91yWeO-~&QZ$x^b@ulT6gf^?_Jgvx;U3DSMgolYCULlK?`dpR7 zu#RNH9$CFp%gINbCs__6TOoqG-9T3eL?+ySury`##YEvb+oEbmaV<#s*h5B^t9lgc}Vf z++eHG8d)8Xq*hyv=Aay2@F=Mcaiq%u-WDsMD>stvaL4Kxva;La`qSJuwL9tm?T+SQ z2Aqxj^cOE!(iC+c23(iUHA&$7lx%%LN7N!l6I@LyrkC#c|9NpU2GIef#BqTHw2@BY z+Zj$xU(?l6bvfBiL6dY(QXaGo)~-K7{h%_)GnZU+>&K5(P$+9RIcWXTNc=fezC_qS zwG?N|LfcL>(>;NS9mb)MK6?*K#5;@Y&SG5EpVnRf*Q}8$2FuE z>0({A|J&sXciu>!vi^k|*;;gsfefXr@l|~uq<7CIOA%_bAvSZ2#BZOnL$Vm+Z=& zXokh`I!n_m4C>u@U%FTrRpyYSZ`-YshV!z1?u$imh#j1$yi|CL+;NZC&ByVNl3R3q zlFr5-VF@PwWk)I5%JGK9R!>PHB0|<)$z?ehV(=-i_?+DNoUfQJY-2*FPm7FG*gm7L zOpT4q+6691p?DIcgZ}UHng9N73NxMOc*TkhrGQIIL#b=4dzDuvAL&5C#6N8>U)V@e zt2z~Vn^y=i0o~>2{4z`_oY?FAONe?KNMf%tzx)jS6de|Fim9=%C};T1L8q~t+KUo> zmqrBjd3_(S;4`Hllk5ReeRX>)uJ^OK(J$LUzOFLzrSo)JI{y_9CA_kxXWM*;u5priAB9lK@3L1l=_?*tH0XD|9EHW>z$T?<&uVRlN*v&j5>oBc?`rnld97Lq#J6 z{%4~WSXCsblBnV*B1(xTxz#J*sT{~ouGU^SW|G@aQi}Ouw;bZN6UfS~=vCQZN=Z=6 zC`{=>I&CpST3%K>a4I4Y*WB3)R%aS7jGOc-<#OWFxU*P6<^((l;yrz%CmyK%JN(8O|-*bhE%) zy#-Woq1}L8HxW6Wa-gv?s25P&bCAI&YXOcD@fu=<{%iS6SP3^21sGe&jree1+L&Y{w;E zl0=L4||&Fv}}GCvm?Pd#~>DedXvJXLnLEF(M+dsvb|Fm{lfUyz)b+w)WX zs&UxEG6`)C58TW8u`o2X)vL-~B-6r>FGO|<#g2PHRqX^3-c%SGiF2bl!zy}pKKXmk zNGp-uzY)EZy(N9n?rwDH+1iSzh4C>-QgszR1UmC~u~(Wasv5!k{}y@uqlUfY_z%fz zKL#fAcs5C6nhFkD9kTw$%BTeUb~b^#*^8|uJGT;~C#2vTL|hCCflt=hB0l>b-q3yR z#zwW#{9yM6$xz+Pd)@Y^vaP9|ttn!aPOvqT)80?(mlF>)g8&vg>6f||NKv+$RFYz# zie)|HN;@c!z5Ha$byt)9yDAq$Pk{Cc*(^rkT3o-$3Rw$5mX8|!6-{_d8I&IhJrcJI#wIYxEU;9}u2d{{GB+WomErK~;GJ4t#Q8{v(SXveLRk z%jQb)?}(P~16H2evN6tH&7P|Ry{Ji1L)?rNs9(7oqNvf=v+kos6RnwfieG$#hYnz^ zYpRX`Rl0{EnOgemO*S(qi=`*-MVkF+Q4Q|G_W^2XWU#$bY7HjMLK)QkSl<3SKeVGj z{C6F?OHopj1#v3g=NI|_c`SVCs#IIQ1)VJ4eMD)BhytM$=m1Dwzwc++Ypw1_F}$OO zjljrEPfwRHDl3RjR_qWQQL^&#P4pdpfggE1iVstao!9kWKTlg41JS&0EEOu}%%NV@o;sbTno@ zBYQExzXzbeWvE5~^tIo|Us5rolQq^!3i`Z@8xV=fn4#iVVRJ+&dY^y~&#k8CZfnnr z>uh`Yhw*vEVP%9jC58|`yKLe|EVDv%Fxop7qDSEfHl0qR)=A5k=D7i$TPq|dM zr7;<@Pmtj>O&km%KX;-I%wMSpy0)jdrK?gzJ_OJ*iu`MBM~p4YP1FtAPQIKs&Phts z0NKMnN7QyZPzM-#wbPqh3|{(U4UyKh0P@gnmA7Rn$X>_^;SRgWfbTeimP}%=WlVzYTu%AEb~e$y z9jW+%_bl43 z5QYae5rI>M*whC*dbmENm~HnM*COcwk_M+y`C%{ys(fd=cL=Faa(YP%mhbeBZpaiI zwG)2(a$=lc`9e8ITjP>hkFVpmdL3UAuG3n>I7K%~V^ohcvx*+^|J>kDNMA#?@jril zGn#Eo4}fhGV}CoNM2~BRh&~P1z7id^a>72#=~IRGjdb#fsowXPT9VQvi9JR7pFDn! zNN^ZCE!u*$2rb&e^GQV$G0(ncL5St{ zXU{KXf46tb@Nq45`%bn;AfPV~PHvum)EU{Qb#+{=8v>7#JRiUh5P5Z7PM~YCF6y24 zYNA;;xQe{B^kl2kWqP|;jk%NYD-&LW5ULk0A3!#YvgKoH9$o~# zy;Qt}a5NXbD~cSuza8$jJ%zsW{6ZY9aMcVILehuSKPw`BTvyegY~Hmi84r&WeNjU@ zXY%OPxCKqeXr(Xg8#z2VG~D86nA*>^0svXwn!;=RZ`xI|L7Sw&$|Y6eFroOA;F2 z$?_p?Mz(miDlRI!s~PVe&Bdz(eteRBRCesIts9bn4U zWz;5HC;<%%$yyOif-gWf>WAb%)jR6>q^GQSOH&*p{Mat(z}4>(F}&**CeoP@HhM&j zI$q~VHkf@=_wUDizOwvgn1=C5|H3|HE|1V~ues(=^AMxuzw@#1=_5?(1hu0c zDKD*0_|wfz72k!;2H^hMAFCn4<^HDBiNI=!a97r~xzB;Vrd4cUdFRZz3w}2`MP8mB zs?_Mmg$Q4VYLMu$?w9l@Wq+-AL?okzP@X>bfP#!bz6f@mrwsyHh+H#>vo%g&wtnxG zs}xy6-^$-2p_JCwer}zsJ*)Mv7dx2`ddI|%FXu9w5knPRy5B)kv?iVB!x^GK*??9s zRu!6!*BM7cCQ^=nQ2VhYR|U5BwLII(k~;-dow;SYyz5pOLoWNIWCaQ1i4-b|yM6(tQM+t#wrU}J^f$+fuVj||P5AifnNk(ayL69YY1M&GF+PGSmN-_D zvO8!CjH20P$TvshfchbQsvMqtqojPg;L!ufA9+p@sitYA@pkno+Bw$|iQ(M`TVkM| z_hKx0b%*a(5%<3SH zM1kQ-0?kzEJ^3pGmyM`%=~LAi_=r{M`YUHL5O8^m=!GoFnuv+3rnJdb#_|A$JcT_E z^m}ypNuE)}_F+=J)V<^bDW3x4$%3I==RRz{-eA2QQpvLN^Gv&KrgrT|e*W^KG{_a% zvtPRS?PA5|DGQ!uQ|;f>hcos@_RuzMy*pBRAZte!WJxWK2YQC|{x%yh!Zj}8qN?0@Pb`yXE3EAv`PS5oMFGy49^&9@9=5I#I7 zf6;VOBj)F%vbBjJv<0G|xTCeCMw%h5ZlK*l?PXnbtw3-ZH8s??1XZ*$y<05H#K3gL1Kqf#l(l-7f(BQ; znlPy6_UP(>YnLTne7fTNqOray$#Bm}mAgwUQTdc(4GQT7U8xR^8b!1Hoz{!#2A_u` zWJ0Tdr&c5wv*33wcj5=LG&HU7SFRYJ&&8;mp(CGNbH8_`%QAjZQ^#u#mz%n(AQP*B zb>})YR-;{yN$&~}Z1Kb|I5P3-)@P~7#mA+{nJ7tiA3FyAHzae7v7(6Iw zuvqEj&qnyoo}V8+3JZQ$f28o)b&U4IDpz7UMlTTvw+yAeBFr=mvL(`p3o;8+f zawA~w8r*s1Ye~MmXwm=-Roh)l?i%pqvKBO>dlaFrSZg7v$(ZTDN?G<+nhWWMBbaS zrm0-K)f~c-2sbXZmd~D z7~RIWyy+CEGco6~UF)SZ%A5CU6@Gpo)qZQP=SjHHFC8%?c0Flv?)GIUoIu-u!R<%f!yzaNqJimANgk^;z&ti*-c@DN7y*)n%3 z-U<>jGUZvLFx&lZw@0+-Os%HEE4EnLf6@6AM9pnI?0d@*Xz(d#c4<+{iY+49y`#2+ zWh+#ycQ=A$xBc!M`b^pfo4RVV_0FPKCx-UZM9J2*v-^>oRJ@zzsAT^V4&szf#*WUG zX!EM1OS2)-!}fW`EVOM^7}#KvXRA62FpOZHyYmg4Gt8|``j;*)jAz=LF4jSGovem{ z84`E6)}WxKxQvWY!gjd&iOD{w%b&EqiCW{vZFTYcK8K*WyZ?-=hKel0`JewhAg=0!D zXhNK_2(nO2Yt%ztrkR<0NC_8vp;|Qa9_VeRniJxxCoaVq2ee(KG{CX zLk=f`1#<6BLDUXN0URxpBHukPRO^zOd-5>%0v;K#S67xIhG^NiV&R{ciec*fen1zFZadYj+iW$7>Ya9V?+n6+>_qF-{|?1$D3Me3guU~aav-wcKv>E z64-Q=Tck<>oA|7OzQr`4vyOG1g?(Fv4xqi&vcH3MqVmHcHj=d&WzPEloW9quYmAc8 zO>tGO{G{pv1)c=45dyDS;_FPj`wq|SF(cIZnu~D zArt7s)W5ch1?1=cY8lP@%{>ikN&#M%sFStA`OhW(u0wl99SP%<``7T~(>^rjWp?=M z;lu&xnGIm}`&#ve4{8d`JcSd_?jw9VuU`lje{*H@j_;2La7l%NT|4KXL z9^?v&R}kX%cY^uzf!*7^K6?bweK%K~fLO{o!La|V)_q6jp2r5YHbY!c3;3+mu7q&D z(@4rffDRCwwK!J8n=C!+ue$59*<-@Kl>B?Ac3TSQ@OJirZ<92@Si&GmwnYVBOqCjQ zW!;t9Gv?iJifL9D{u<_0g*r3&AwTO#r1zi;EJ(QiYMSAPqgWEPYRYowWsudOo)4T3 zeyFchxFPW!4DyiFRYDv;oA>%3vdHNp>Yg)8edVLc!Q5n3xq!=4#&#bLpN3XVEzEooSa!t%eUxdXI!8r%ZtVih8&kVl(2i|Asy=_Q;56F)b-DAx)264X+B zj1Cc6x;sUKErH5ZQIuKESkFzZ^&@COewcDMLz>nicAf|eAibR>DXNRY2{*OI$M+ZW zB|90rOqsG0RcdFd#kz1(japGwJgBwYb&FqxAU)}~L%s~=<4+$!RQ`GNh#rv}Mf`+5F=SPPksHc7f0PhF z96shTmxUOi08W{@?aAk1nhmUC34l1pI)*GX*}~5Y#S|@Ka;R|?Bgd6wtr8^2 zM{P(LJQ4S;Q*)w=F4H*VEm&Wl=pL4FmpmJaM?U1*s-IL3^?={DgBdP@Pq6k)Bay`- zR_<)n%ePGlOQ0pb3~}|hdl*zaJC=xSz2?y>LHVPJh-mh>(c$6yxjLY}rq7}O;*9d?uHdK8_NB%nPOJbN^SWzW=KldimtM*w(S$ z+@y)k>MF^49620^q~eQnR>bk`uQENsy&OzFiS(zx3&SX$h_D=A4Sg*fe=n+b<7L|D z;2@EUhGAbiQt7{xKUeQKbAH33 zS_LBU_{Ya^e%UvoqR5BbrYVQDj-AkRq}-f~RBv|sr!ML~x2!6Zs!tF3&mS%K*R-`g zV#Uc8o1?#^;w59KzB^%K=fO0QIx%-XY}6}QcyhX7uxVPgvwApnk<=DNK1&z|gaJ^( zM|PjHX{_O{$ewo{1S?Us`h5A#70?C;YgB6!ABJkCSe5H0TYqT%BMmaLQ#9orh}WJt zLsii+mfNA;j;&T3x?<|jM8-GSbc)I}cO2fy?*aIX2ej?%uWv&8;BmIyUq6LnTV4>3 zBX^N|D^C078ERt(-xZwHV#s%dtK?t{5No>ZhIh&sESUN2)LmzHXO_ zJz`WViEotjIz#t(cN+SWFW0eY_oy0d9qw@{T>6*Yzw%y02OYxC7P51r)4wP(!%(&K z@PM_@@*9xnC*i$RD2OH2M#p@gwv&F3F)j`d7|Sx7v2%2LU)VO|tP}7q*Pi6WywscZ z!6-0Q&64`qqFO>aA5A!Ut8a8A5}6@EBi+B30KFh`C?~~qbxkaWA0QyFfG1PUoarbQ zLur^H-NkX!UXCR#8M?PMT%tO}fGzUzlC?Nw30*?db9Xf({_xE02ot2dc5K0tK?%2;;EwvKsVM=uhRRW456<)+p{=Lb)l`1>d#(!% zxXcVl?1fSWc-EVW#6@Rof_S{e*_SQE{j45|D$*|UJ%Pg&-|1h2XMFas@RH3pVm4To zDQUZ^Md4!v)yGkxYZIZ8)x&fAgB}M0Vwu`1RR$-FIGR9;FL6C{jIuQyCF>9tM2E}G zZkRg%yA&TTJ1dn7@>TqBDvls-S9@57X=b|U{3s&*J`+JDU3eMme(kXKqwKMt37@y9 z(zkc+`<4Tn;f;zB@J11s{uHN&wPy4A}L`Q>}@bLO!}WZ{R~IX>e$#ZKKm(A zTE!QS5QAT$UP}D(0;7#ceye7YBHOk^Ax6fAcD(2k_lc4|ahSO~_FMlnGqU|V%xcjl zEjw|@_TVL>eCy`<(B}xWhnYl^&#dU(Mv9ie5_(ecxX5J@u7g^B+S#%ADCoSU=CmmG zGw0Nrt)MFtp0oVtd)obC4%jTmT7S9nrIwba9h#M?=*y^OjormW=g{!T$+rRV2i$~) zmtmsJiiTk~UTU0^f9Q-yIvvTkP)lBv;D7PdUwzGoUCfUN@}{0 z_Fb(`$K;X4yUseq)bm&=my?%8#E#*FA*V|u5^S9nKvoYw_@t^r1Pe1#HWl^Ce0%Y0 zj(JQCZ@bEMA7Ax6pXval$8gNPN*@0{X{s~|PVY6CE4tkH1E~AkTmE>%K#92_V|4nX z%(zHs-E7CBwh)v0l#H`y%j(3;-_iuenx}KV9o+jU;OoiH_3MoF9AplsqkEm19-t?s zD~uqC@sHA0Mc5ed;m$=&FXvFc(bA-v>_bve-21Szl2`Uf40k0y?wLD8ThdRU8hP@v z<*O+ZbHIU`d2(t((w({tS2=88g9mZx(tXgiW$<_}nzHymXZrqo)PxQ{3{3cU$V!C4 zaVvL{gS$_bLPm*bB3>@PivK9evHXk84Fpy=-Tfoxa^od<-sjYI>4jihabJ#c{oO*h z-*MBmpwGmjlus1jFlGW@)xB*;DFFX_@@7=vWmEhu4M54+FJ1@2NhzZRaiWABe8lhC z7lkK1F5r-+i!!Dp7-tTfwB4L^|5THwn#2%V<~g4Bc%|muq(dC;g?n^nkqi zX@b}>DpX%wZ4T&aJbNh^dd)yBQ0W6Er;4&JfBiNKVaQON|4!}&-C6Rhi3sk{{7W%NRw1>>9}e> z36nbY;K)h-q^NCzx#S~`Axs?FjYGRHE)Xy5VUl8vbDnRW@YqkSet7?=lZ3fe@8$Oi_BcC_P7Q(XK>mPFA;h zm~}H`t$64qI=qVrqdkPS(c#l{lmcUA-`GEI50`RI#LdCnx3X9S18Mnixm^Ug%8_C& znuqLkYX@!O6pgq)AMV9~y1iA8b^pro(JzFI*3dSBG{f> zmYbr$SroOpB67nZt?O7zR5E-+M4J8bO%UH!Vq~D^FKPNK+(pcY9$uX_dZhxGN3hNh>77i~H?R#sn)6X@_W`A^2E z4TsC!k}4jJ-Kjf=N2?!>^CC>4I>ZzC&+Xd$OSozrET(2j_cRf`*Ne}^W( zxLmcpY`s`dE$nAoz+x!g2QLxNsN3iM8z?w=)dql(kgP@Hu$khnbs& zIa3i^rAIoP?SkslNi~Coc2mbRFIIe3yy=?IO$+O9@HRZLg53!&kvZ7m7W*Mp4h*S~Iq6G}A($T7^zP6sw1Nv`)wRpjk+nx`tID z#jD=0uV?r6dt_lLc6SJuJ*}g#@+J3y*r_5Xjf{$tP|eDf{Beudc~S_KqQyx;A1Z`B zU3PZ+TymCnnWrgLt&)#K)YzsvnT|{k zxZrMPN*5uq|FJjj>>rREKgC9V7=S+8#2s-kw;bz(+6*k#xP9#HYi`kBN9+57kS+uG zsc!L?Rtqa+MM;}(Cy-?DWSmo#Ws>^4u&Qdi$s7&4?m<;vlGLlS1&;{M&krUOU~`8q zAkVx|w&^L9*YX@EL#+zqpf>|~#R%V*mW9K`v-0Ah1-hZuJI|4A+O~+D(|e=IrV| z+96sB)ow%ov2E2tZ#o+83jg6|h{d7sE`Eo#Z-c3X8iTQ; zm=YUt$w?n49fZrBRe3GY{0&9?+)v|_sbCj5J7dCIR4ZG}HW8OBmCgle8}gvh z#-RT(K@%YT=nra6(4CoG*B|tuTr95)d#5@S3CcvV3zRh5{Jac}?|kEtWHi?DTcw;; zv~EBY%Q&b&dXrv_ib)45?nr`dH9OduG3shEPHDY^R}^pZ$@xsndJQFlEXY;Z1df9k zuJiSxW=K-2#+jA--pQ3vl2OtJxOo9L0}>NcF3c|>L)F6(53cw@_tOA}PXpvPzB#^{ z{9mjz2InLB0y9mu1GsN!_IV29Wg86T@Opj1vS_8ZmxffIrbjdzfSSe1C_cy(b4$0? z3`p(@;V&YzpYqNmh}_Vqc!z3V%^DLw4K|}Ls@AOF3!=Dp6ebx3@ZT<0#)WWXAQ@AJ z7Bghxv+P{)ac-x|Rd(63bZYSebXlUkac3C0EAic>t>aC=Lkig?nMU<@SctfpcR-yJ z3}gm1#aOe^yWDp}I+bE;x<)QCLsv@=v{t%J=OKcWsw-@t@-V}mS^?^6${}x`Sg=K5 zHf&N<>@-7qj+TBvJz44L_5{X@1ThZ@i<*xnYbrgu-qpH%;Wc{dS3C(C!PaivA*KOq zB$0x39`s3%tyUtwVA07_@h=&A1=6YO1MhiI-?f*AJ%as-=oRyRhDVgscyJe6%Pu7xL&ZVO92t-RRya zx|k)j^!bB$H3gmkJs=%`PQFZ|Id}jTbAqUyW{|$(zE5zgoT-exv@im}R^nm)uPFv` z_{0;}0m)l^aN&{+x1qd%O8n8#G;o6z%JEPB$2%C(O^7+Dm-3M%NhnVQ%4YPEQQtL_ zjR3lVw~&u?bQx)8>?$p9K3QRd1`Swm#gCxv6)xfGaT4m}$V6G#aZK~TLb`hC3!uKI z%$Qgw_3N}B}E?Y@LOl~odXF05(3qSqHzo}qD{Siuiueg=^lI=nBMbPs+7f&UE z#Pb1!;7B?y)pDb%c4$>S;$dc{^9CO2!u1GWFx77SD;-Th* zsMVg>5G1swXzMADpM+&7?0^-V`9S^ks#-1ORv%SciP#N*bfR{R1=0jI9G=aE%s3eP z$1O-vL{X|3agaQrqBYvy{BHWq1L^Ek$BL!en2TnYkBq_n%=#L4M~R~5xS5yV?$+B_ z+>oa&W?y(OBY(Numf(zk%W(16TT55gSI3JJYUz;Aj*M#60?L5$AW`h|Cdv9^h8jnpWs^@vtIqCx z`*Iq8y)y#-`LxkMCkLAQ2i&|JcN$v4l##7$pFb4`4KQ{N$6QkL!h9qPG~;lvdzi)lzT7BvQ5T16+Bt|-9?*Za#5jfB`;Xq9) z>$U`M5~9KuZ=mb%b)+o_4fh+OLVcWn`E4CY?G32JS$_K# zbSnj(qk+KYr%5_W^wA&`8o);c_D)v*g^bc0BJ3bdpp#h*4Dp2a;0TZzKY!U1O2uN1 z0GHjKrbicn(fo^k?}PrUmmb>qAAL*AU-e`I#$W?=#1q;lvgcGytPBelMHeq7#=f39 z^`js8QU)Q^gX>Rfu->a1(M-&#;(IKapLi@||+rR{Aq8+HU#>45 z7@se>7bkWW2mA4};M@P25q6iz5gSKp1O;@ zAQslghI5T!WxZgb`qyqldT}sEbp>EV1|{%g((cB;4$IV`$?q>bq}3~4OSj9_@oi58 z90~}PyQR3F9#{FJ^1Vgy&lmZ7iM!Gl^8$Opb!_;jxNFm=5w*Qw?+u`lyuRJ2wtSdh z%p`PfOGqproAh4mg2Hb0!WwZ6ahb4IYQtIGhDI9f+-SqaQCJ%r)+EAcVEJ93 z1QOQR7;DY}5uhsE`f18u}|a??*KWFPjpgZ;j24A`I)F;CNa{*EX_?-dyzcjtprxyLV_?>u95yOjoO zq2Dg*bI&k_p|u<1KC~+TZD`@&LB521<6ZM=$AtcJO=Uy>9X(N2-t;ROAz1{8<8pp7 z(sSqiBkBy93gH6Og#=_MGT%;xIx93km1 zk?N#D7c272nZi{!iNGqU&~wG&2XW#Qw(IWx>Xm0X$`oK-c%y(1lZW4MxX{4VZEL1M z<9e@|V9L$dfIu1~^$)Ct*x87NOOL_i;N8pTAwIp=?Ea8+H>wBv1OOXP@e4F)D~{Qk z*~FJZYC&MRxI>0(X1}TdzX(8lq<9<=Qqp_xgkIMwyD6dtTWRda2{QF=K34+JG~=2b zcndC@d|0ao%(FTo=oLR)-+#gUh;>E(1@Qrr{s3vA->O3FPKuE^0Z4%Yjp703IBzC< zufhG6H7l6N%Ss#SAypZf{3|;5ML9m3~(P;EQ!E;7pK-%#%xx_q#X?ts8Ioe*DQL zq94ERde=RRv?|wlQ#%dxqf4~^ImT7STH1_ZQAv=PUa=4TwxPdJ&qu41-xIvs6>W%G zSNvge7e=e;gK!weK;$}Sqo*1Rj>dT&Oc!XUlj*v756n6qn0J7VP{&R4M`SAdpIy}! zQL=TJJhy*+_VxJVKqAPPO0SAnyJD-kH}Y<^@zcdCFpC?b(UYTwCTOfJaQ=N>Mvcd$ z^wVlwLj(F@EeBuVAM`Z*o;4MC45_Kj6Ovd#AtGaizw^3G^$3Ucy2y!F>|MAZH|k5znHOOHxlb)}rlvA-UN5^UUk=2p4~Nm8Qfi-?s;O>>@-|)W z0QBZ-a=+$bN)8Kl}pZ6%(i@}_ImlE-p#Kl@a%}tle_g@ zMnTk`LVZc0-alOZg4$?3{s3G5Pp~kN{R*`Ib+-^ziB^K-yn^nx{*Prj@xVMG&hWU2 z-feF6ZUEr$|OSLB!B_#9&#v|(+M zE;zAnWqUhZ)`i1#=W0XyQ!noxJWhCeU03q;)Tf1YgT>nf(?vhk|7KSFt}S(b)wc@5 z{3)~8Texf;y5iNTh4`QQ>#djx8)LWjH&$y-&^4n{z>snsR`SDuynSf84l9#<< zE6clQ##KHfYek@&)zUFQL-YqyC$?O+Kz*^;gQTiA|Is8qXwA^&w+i|5IUR|zRj|gJ z?$h^;JI`kYVe~6D5HC)IJ3ESXV@nD8gKepcx78oyC<$;IH2w8=53!z-U-34WlD>`8 zUb4N)N*9(1x|?eUdlVn!)DUiJkGEmg12OX@I#1gystjcmF24@BYhfUwRx_$`MB@K& zb=PlAzJJ{KS;6ShqsQnJkj}w~kwKrF!WK|z2>CEUW^QoBPv_)z2XmHCVtFHkX&&R$k zOUfNkicAvz@v5-sPKRoV#LCLd9^AG|3ctXgsQ%-#@2+`gI@@*8UC{%{MOW8(bOrxw z+&g)tvzm&z`R0LEqey2TYB^Co!LXVv+wV7 zK1ZHdw448s)%vD(twZ45=#beT^?(n`!N*oN8&Oh1eb40Y&G!A8_=JA&x0hETdEt{q zi9}Z6I6@9a5=mXMfbH{GUX>2|)VZ@QE&F?Pv7-JkF@CSq?C_MP@F!l_N#qG5%@wz5 zL4rc0lK0O{qD4>sy(&2DOh;2hb-kWf@NJ+o`Ob|b$q;S0aXTZ={WjxK5G6-z(2QxMZlFmdc?VwB`t!*_P$B?m==}d~!n| zqJ`%yh#=R?an};o7w1!P>ZC+@Ui?yZ=^ebJ5YAoTbcR z>&upgr+Twb#Wk<@_nyok2RiuAjCUf0yqca^JNydXdS^{p{yZ$-g?+o~H&rzmb4|L^BP^kTxGcNnZMQ7JcJ{>L%N(E7RyWe`2 zF3y>}R`dOj^}k)Rupfq|2A2rYd97Bg;X{5l?5sM^@X6e_iRjdN#KDpiu_*;f4`@BwsQfLayKOb{%O8L;g$ZCZ%$ABgBHrCPQ8$y%OtB`ntQ5m5{f^oD1C!WOTTuB{*F`n?2P~JyA&3t z6#tC#<~+d@wd6!k`~?d7Bc|B1+wt|{VvH!)U69H)z$LmNv~m@=Lu);UOM8JX1)~*5 zZ~5}7sC;}E3yZ9T7L7yX+XDB27?rqOmki?)DbUqJv*x&uDF?-3C%cp7kAA|kQ_G%6 z3ZyQX3L4Gg8)>!sJcovVp{_UB1%2pmg=xcGjLiGj*V#{v^=P+fQQS>}1#iCZR@Pz$ zfK|P?q7)5>a~Y@1LK?;XDp^Y(&0Vh_{*Oanc4Sy|$X8!MKuFLMmE^4P& z^`Tb5hxxV48{TSKMp{MTy zj{4kv!(vMeXQv+%Y&;rXn5;;jHgwI&J7`!T?eI!gx#kf(n%H#DTB<%C%g^#?Ry`Nx z5P0NPG3n8Ax;e@z?wWhew#O~wt*A38NA7j3o~>y4XxH3p9!(0Kw;j$!yVo9hwAy&K zxi?39c3ktk6YkmWzZLEM;K;Kp-SbYUe2nkYYhJxAo*gmgV*KA6c@0i_-o4Zu6ZrX> z_sF(q=k=|avwx4gsjOaIMETfY?(06|3SQmW=VC)8|M<{tyn2e8W6!By_nis%x>vmw z8)5p#myzz(+bACw<#gTed5c$H`?u00M@vh{uJ-g2?D zBl(1icOG2}HN|a-S-$M0v!Y$Lk zQ7##N&l?pIZ#$(#d))F{Y!6Rt5BwYLGv)WEV0{FlZQ zE_dgq#D*#Qzj_jW`ChGh1i|e7W69F~lG}lCitU^?m(qJI`vWI)g-&!awEznA!X(VaYX(H`q)&u&d{- z-AWXI`j0F=m78E;kB_uc(2mc%ck9h=Wx?+SI}0{Bu8#@w$X5f_>4`~i`FE0Lubt0) zcykE@@#ZPvcvPrK7*mwmXZboRQ|Fw84hxpoU7D|r#tI6!+SnKrzQR~uM$&HQX!yR$ ziOV}^6YFAu7*UemU2)j2)ZLP{D5fy>4w_IZd#WmM3U{(OY>|OwkEf5%oSGxcAA{JU zMcI8wlR)7b>`&#iQoD!z-8_Hazfs0oc=aF^WY0CP@rs_j=B40n+%4UL=xUz)&MY_* z9fSlI7`*fd5tJ@!zKP-%rQ(GT0jCW}o(QsI+WquP9NkI+$Vi}^ z5AdJ=VEZ8KeH!J4KQPVRKpY{&3doY)qkeP1r=kcN6p&FJ(O?It)&(d)0M#%cy+{i^ zP39OhK#&S}*#2nwb=}xdt~8w>9!q1&(M?G_eEgO`3upi^DWCYzaMtd6aQK1svQkyN!V{NY#`NRVhe!z`d2 z!6X>f+_z-v)b?~k6Y&4~UWF^nt&>fYvjIpJqE+iqY7)8fPlkOmwBbJIlqL$fM6h8h z>N_L@>gd+}EI1W_WDH{DtSp)gO=k#~c5Njp2&RMRs!yb_T@o4#LRQpQVga5b;2HrE zN(W^FSLjb zhZ&wY>*`_$3lwu$pQF;mRx*-cKpA%^7)k$>hfm^F(|^%Q5H?i@ zkT?WrMlxyzNor8B^g}LTIB4pglhF=fQWN!MoL~bdyW^%9VfeL$A*%`?wwGI?3tzKh zsEx&U9RomtkAIi|=x{M{${Dx8naMPYFdb;NLuWn4A8s(VW^9UaHb|klJQK*!CQ)7q zb;($G>rxJrw7)3G^o_NTlABQlL4^CE&;!2MEg%{@<(%enc8IgY2WWw{jr#t0lKvt#7r@~JzEBF* zL%Hh}km9YMdkRhSMFGx$$;jpf=_P<_qIc3sAYIG_qmtvHOn<3g=;;?XWy-RYmeTPD zly^1O#%vHwxMOcbCys@nnHmELkwCgF&WbSNf~x%daXcUM!4zrwIAAj(K#>EH+B2 z2h}nQtZA7g=-Ry^&*_G{#mpK-EAJALfzkxcpirT})dlXa^7I8zjViz_SuR-UPg!>K zc~wO8%o|+(_Iz1k6(GE~?8vg>phOh&SrkLzD|cSGt`cuLt+WQLm?8)|DJw75J+++h z0!nxRI){3_-$SKQG@Lwp$9?PM^bA8O&;_en0OK(cYrKFn$K; z9`HOv)9dU9UpJSaxp6Nk23`O|{7NEQ!H9KQOMxZtgnc{^6L_%-%e@B}5rbfsXJ{=0 zao~$-J{wnQ5?6b(rw?{zCvlbM&F}=XkeuWQ!#iGz!OJT-Z3uvnt#*>F_#2K;iMy~bsK=7B@Jm212Dg4{MpdMiX@`^6dgmx8Nnm$|W81r~G{jETXlj8s)!?II*7 zM8QVAQi6-K%uf6S2AV3iVvZ(B?f?v5;OnAXMJ526Fw#VBSeI4kk1Ya=X&}-C568G| zj1j8d0Hk0~r7OJXV`sNy2_`>-&B`8$61G6Xn~eq`?{#0JZ8oi*t&D(qnjO|3nBqHE z@H^QL1(LRpYo{JE$s#z}9!0N;#dnSqP_T8n1AZ$eY|3Gssmn`Z&+Yud>mVFtA@9ZN zw%(mXX(?5i{U@W6FcJ7u?(B_FZ0sub?VXDwl|tvni3Rp99gj`xh{kmwlSmr*JWbe< zID7{nwF)$A9ildav|N~NPqrIqGgLGF&G@>fCPr@%i1Z<7ca7CF&Y6&XwJ7f$mNo<| zOao8;0|o`@L$)K(|03qaw$p?;U^0ZR4k#h){w=3y!X`))2dMt;j|reUV@R1MV7!h4 z^oOg6Cx=`Y+C|sFf(kODT6@=g{4xF_IOn}1bB8y~(&!jPeW_|fuV;OJ?{M(pS&fUK^jx(;t@B-xRl@+{j9iTv+x>o(v z-G`bNKz^iy(KHb3^_sXn13ujq(})17Bo7DLSi~A`FMPL4o&5B~e)B=N;Ui~KX~3{6 zj9ECP<57%xOp&^&xmByk3=pSejs>bqcfS@JVAZ z*%5V~MN|x_xszp0(6Gq78^m1mj?uKwv%u)35#zTLx*uKK-Qc=lEtD&Ye7 z7IP4*`)A@qcmi)6pyR?#8Kn1UgH??f{!pEdT%G=An;!lX}8)Dw(+X%JjYW zC{fT^mLGP#t#gf-Vij_vz}9@lseg-y5gQXv;o9fT-aHnPdjYpRNAEKF`R=KR>;1OC zC;c7%eNKH3KU4HR+jV>N`IQ09Q)Q`pSHTU2mS5QiXo#@!=Aow_?ao7=3Jr_zuxz?q+EWv!f#<> z^R;?X>e2&on>X(m#*=+fjHvHJHNTwSz3nynk)<=5agrJ-dF0fs<+mALzrj}c%Yn-D zf0X8A^sLgOA3ZzSU#c4TeA$vyckow`Koorg_<~#JxQ0=#*LdBI;h| z)>;N)y_w;0Qgb=jeqBqjf-_RIJeaam8y1iWPGtKpNvB}S+a>Xb!J4)C-I4~Ba+abn zpBokr5s4b_woSgUq%y5uO{;n-2ypAaOa8WNw7F@S z!NGTMR6q%5ZbX!(EGCiOR2f}a_c}|i#MiQ~&Y%5>e9j&lm;UbF*o?JWcUo$=IL@YA zr9_#;X}-IE@$qMyssP3A=(+Za$EY@%z?Gc6Cx`)w{VAbdj%KG~x+E_*nkVIoQJAS=Q{&n*C*So8iWERa2p5P-Vnk0#6h+@C5QJAW|9C{$V#yc#9Mhs}}ty@AE-qtEN6J&tyI5PJT#xiVN9 zEmleGd8~T3>*VpDyW^+KRlh&E@JO}&&bxpAcE>F3k-rP^+@mjxiW8o|n)co)AC#LP zzUfT)3L=Y!eIq`HY-{WL)!N}0K*{kn{;s46<+lT7tan53iZjw2o-|8=wo#IXhxMNq zY}qzVG*GsG1DPDpl{PiL0=aa~nI*O~#SE_p80NzI0+00w#bs_PXZ2Usk6Z@%meT+DlT6bt8kf_d1$ROnQEWFN zQ^0PP(`Oa9&b`mXotx%g0J0S}VFhB-aLW*EjeLP61>@ed`+}Bh0F!~3!zI3l!5+I7 zX311uLasYDXiLdi!sq6j)FLW%g7((fBHiEc;N^*XYBJmethMGKKF>)T z1R7n+u!4s}n-Sfy_htS-T|_g{rW^OYbJ*n&!k*`C>kJ&4Z=kE()>>+q;P4&1t#ArnWi>h|DHvV z;I{&&;!*Y_&AxL;K`ni!HZDpU_%tI}a2mEOtUvU0RB*hKO|*EAC!T|%G5^1VvIF{B zZsh7ZfAKP)^^4~zdp?+tv0RPW?+>$ykwg(@l2h$q*!y96SLgLb)w5UYbJZ_ui4b-y zzT_DdHW@9j`eH$nVp`4Eq|oMtb!#>4V5pJf7sWCecY)0@Hls8PHnMC{XmJ+t0)AbH z#z;RX`#GC>vJK=75W8uM?R&ka)&?;}0L7H}a&OLSh*oMg@C5CdP9pmT9*y~3r@+`e zutm+wB{}+QRfg}bIrQYRK-3C?otv9C?xvBgd-CS`VzZu#)6=YxkL#G=JHqBX_s!7m zhBGE$P|LqP8;yV12M;D>E~M;O#Rq5UT$Dre2VenC?w?jZTk2aM#R5gw_b6DXYt+sj zt2$R<`e_&*B2QOeBYex3XR_gyKGqsG-E6`>yQ9y>Eh;xvvW#$8N2X|rjo){B% zf1Rif{Kltm6tIWQXh_n!#wC|ea#V)m%#%sdRO1IkuRsIBsVe7eBIRynH4J^JK3Wj@J{Ppzb)>A$!KJHh|8%!O5 zz_y$1=aFd*F%qZ~#qn{Mu*&i=+s!ajv2sP*+hAkdXsbgm=3W+1aOv64zV0`fu|!Kj zQf;l{rSRLFk5HCjQOx|_>O$AiMny@ESi8TeNcc$_tE%j%%t$;&@7-bbeTgTrcP!gh zk`Ua@6_Q3t@odtEO#hoX{rg%r4oyXhrI*%fwm}B)r|%8;07_EJr8wqt+^W(y!_yTJ?3F;()gv* zk3-Y(mqA0s+<4q4UjL0HSS>_um#$p6$PK+ zkcVll?S7@#n`+sYp5{r6!j4I_gZ;%U>&=sMFICr9@v^IFY%&e+GnlrSdcf$jeqkH= z-i+(6X5{y0_OIsWESU0!HSBCZg@~J^eM706sxa&SwL{8#Z@)xn>Qo({G@kStN_4G) z(pmn6h0`oZ5WCn45k zxhPs7T5R?d@Q5|()=QJuTj6cr9V79wK2z7fm$P4)Hw|jA4?+siUoH+K7vPdwJe5*duUOb3)1wNU~N~=m^THj)m2f3X)zFqE88(yqDEr zB+o{~%-;g*y^!VSmvNP0o|C0aZl#D=1-o4ij-LY>qevWuoWwnVF$1(!e(JuZxYa6~ z%N3I^Au6OxhN3#@+v&o}C=dwh5pX%pa4MB!Db;r(&CKmQ;tIdw2_p&YgHOQW!L(Qj zC6EaY_`?=9KgxLn1vWx~3o2?}80EUeHObO~*>&NRMa=(Kd{!9-fs#T)MMl-NCh5jI7WN?N(yzy$C-1$5;-48mR<*CN;r7c<%8H9UcH-C%&u52Bs;)O;3zKQiKb zh}SX@ke3HSFh1e2eF5opJ|9;Y+ZG>)2>WhHlxlzxfl1gp7|?z z&!MNbz5#!1fk`eg_5xfPF2Hw(0{qjlmgP4xb+GU0Ad_Bn;zp_dAfyz=eVM|h!2njd z<#X1{uv?r8Fif{s6n^F*k_xAwJ*?uA?9bT2JO}ugz2O1BvvPt3PJ+(_<3*he`F%xA zIfuwVK6|1p^4c$6m~S-)pHwhk;OuuwItp)nweakEYM7Gl_g}m+hnc@Di%#l7&8fC- z1?)I>>?drt{!6Ky{fdsLE6bvyKYdO;EK{jJQRX`rEEdvTbvF{3Hx!%qu2tR|?a* z$v#9W+PaleTlUADj6cvC`;Gj;jglF%1X`;!d>@u3qa0x&Tq>h_na?IMG{u|N3=+G> zZx5HZ%*ytzM-`PW6-mW%m=4P;B%X9%VO=X?b}oBZ2n|M6bMXmz$~4mW)v{ZFdV9BZ z5cs@^!eUCHTNxe^QS;+U1P$llkR@waDr=6gzEO80os}aDmsc+bFF7b-UQlm{xp}_& z-q*xhdqga*N-akzotaeaV%{z9`!~t_=Xb5VgiSPo#dxIv>dOGm3T6bf{x3T0TCTIg z40{&1uDnty64O0PQDmP9n5I!t9n)2>h3wK$>#LuzbmNXD-B(x@v+y2%L7HGkTWmV#@ zTw~@2UyAoeowu%WL_4#!B=1jqE2y-l`2hinfhqSM(ySh~Ai%;YFWcocpLUP>J zzuY+fu;>shE75CvAa@3{+_^C=8@VRogqN^Y?PPI)8J$MmUQm2sC82VOUuUuN!@gpJ zSdP8yRqsCgHqT;7W#b(fmn=rqyh2vuJ17e0=26PAkYSv)E@S5>UOZnn(vtXN(f0nR z2ra(VE`v~ikn*Li{!U{7JH79hrTaCKZp*=a-?_-vBggCm-Y6E1ArwbEb8o_eo~a7| zYGM9iagcS5X(w1{1E1jKC$)F|#qZNJtqQ}I2tCOVH^Z@+$s12?0|seQxglq>ev4Z74E<@AvKlT= z#pNwj?wqIQrtS<|Eo?9Z%KmP_@wba!me z-wkiEBL+P7Jgd|%VcZAt?g9gm!QCNUF%IIa3z~`yu)`=MfI04Sd18yr?@UW8P^N!t zfcpF7KFw;;w!P?)+Uf*0jj2An8f2)aiVLFSMI^!|6cM>WBanbJ2ulF)Q@lWcsB>bW zP<@d&*BH=gZz2E}BAzT>6kT19SBAw*Bn*KAG^efhw10XQ#wgUh;0V;N%dACQ;k;F& z)K*y3aNeKFv4S%0tQ#HtmcpXi4Vw{HqIP}k7H4LS{ZZ3Tg3rFwS7!e>+<8T_aChq7 z@$`trne;na1u-``zk%FVr>MJ8Aps9d2mKP=L2u_F;b~xH!R3pLY|3y_^9})-?1x?(@j%bdu=|jAczmXhaEG)-vOx zxd>=118m|Vj%k-M)s~>irm`X-u?Q#u#-@i50}~J#2=>|n)V~GxQrx`a3sZMK-C9S} z>kMe6CP&nFjyfE>L9J~Qup}*NRK036!B<;{iiEkDS#^Pv(l}lhoV(frcJ2Z@6ui79 z`O;xe%3M>n==sPyj&V)Z^XQx=-+kkU=O*0N5=u2W8gbBYtiuhrzZuFH|o%NB+U8NAdmo6{XW!&z26S%$Sz9)OHrREyf=XeeOM zXBM06fr_iORm#N!2f-mIwjZwSfu;-CTIN@PGKFx5J&-X@ec2F&Jh5~a-*QFQBGR#M zF2$UEG|q-wU+k*;U%oUG#&+T_K2-Xc3ooVL8hr(%@#*hkCu}7jg*8e!%bwF8Y+=AE ziw|JYaC75``TlnCDXY6?yWiRyGHB#YW3)Sr&FRhJ^+b+fCupq8w3%kxL_iyMG8PyQ z#Ig|jg^TpkJxPrq<2r0Fky9nd@l*Vmxr>4~j17;IP8(5CV@#ZS!QRHgd3Wz^y5{;* z-Kv_I1$Q|pj(@&u?`>umTPRCbthFrY`|b0?(|z6U5*qRmU`|BPd`1`Bk`wrv$L#r^ zk(OGzv+2No!$!`}{!QPT;$b@dKe=0BY$hxtIjX{MzJW$g)Y)$paE=ymSr%)oz__On zT&ML`CQK1Gs{KeZx}WF3rxYIKzSTtwe3)hm<9i(CtFK=N_VuiFH+fv%eZq_dL-PyR z?@~Dt`>=u~$;Re0uw(+=czRCS;aaz>8VBUs7&8 zd;?wMnEfX9L!^Qa0)n(-2v6mu(MqpeGRMwy5oumSG z;$+b57jCP|^0lZC=Q^KX+RO3*%aOah(^&R_Zy@gz#y&AzgK?L;Ighh)l?{smcPuH^ zHze-!v8B80cVXqHR(Dr$-Cly4eIAd)L;dxmE7SQ=gk%cKxx?0m-YA zHPvOUOe!fz^X@_C=yhovyHbr#7wWo)YJ@`wD_<(Ktbo1KMV^3zsIfFUP??{~Kab}q zYL>HkmCfjZ%5O21u)8~3^J;Gq2Zp>Hawq-Z0Bux-N?ies{74Qe_2}?@(cgEBUo_3o zN(3|tE8+5jVy|zuRu5FKVes1ByWRw1!M7CmC;mI`@PDrk|4&{m?D)?w*t%7gRtUYo zm58ab?P@4Q59Ub>U6AFJIu_;@k=HR#=%wQM*d{WCPrYDRkR0p0ryfdL9d^hW5?QCC zo+K(iEs``%8qeAPI`Igu-qd9%r(CQQG}W7eet%|JNm;FG#iBGP(zT!Mf#fH_3_6dL zb`mVOIJ119FD_R>mYhM)Pu1a)ZrQio4-wJuNv4|;+wXM!CfIO@hZ}8WO>)aw z_Wxnj3)uHGxzw*|3e*B&#(!((4JQ)7AhN-d|>izNKGq>+8V@H3V@dpMFZoTU% zf6&|fig~CpSP=AR_GZH1T62*Og%RA6nUk&3Aa*0Nfy+$egK|}ob2O(_q1)(0QS-;6 zDc0LkqZn4?AeNYqmYN3tPb5zle~4PQ5kw{zgyb`o3|6a0bl2&8^(2ZWvg*H@Hdcv* zNJ6eX?l+x&GM|}V?)Z~R$Vi1&x29`ph4Bja^)lsE?D{Cul0B{wuad1fFQcf#Pb;cX zRJ4bRx*QE!N$dTUVLK5qQcCX8qu_`-^8$2wQ%6G5D{8_ab3x7st z%H@D~i-6;Tb<(X>`JW^M?3#kEdL!RCcH}>V+miw+_q4e8`c4I8BxufN1)QyNC11gh zLLVFx4xKq63nRoA5s#hY@aZ#dK9&V)?m@5hFJkx_$-zL&Zs^l(>AH{UqoG-h+TzE7Z#wfA=V+#nCi0%$hKb@`(>`DKTGCC z`XP3^#QY2_vQS-Cw%Zijk&C959Htc5mybH7F&|bnt|(cT@c;`~O*JInu1?_Br^=WT z&k0TxeRCNhPZTJrcPplqv{*(62#18R)j#&b1kloXYgjll_5$rR+3ptNHuxh37bUT4 zxnF;8iPNwk-X(9)nK>3Vn{2dNgGE&$4h`obT5CA}?6|Nw3j0<4ION4o;&!f#faz%t z{RTenxaV9+qYgF-bf0?j2?tX8RSPa*0i(<3tk{?guZG@Eeq>z;Crw-6hLsOdAQrFR zpas=0LPCwY@Z9lrM49iSxeXHXBAKhB>`l*=tJP?{QtWl+f<^3Th73((V&?p!}YFjOZ+v8ReRg;%+;T#MKUTZ zIsQ%P@da729&bFI|L6tmlef{z(5ga^wD^NrzL@D0&?a`RN~N*Ef}!G4n-}LYbTE9E z&Z%bUg-;PBO%kFTRcljSA~KB=fTAlN1!p1#IB})t2&mCq zj~3rvw|w+{yH6M~bFRVjUuXZ1GV(tEqI`qQFRj*FyMtzGyB300VofZ| z{5j}BFdJo##`_qT`GD&{d>YDnD&&XpTHu~jFNf!HN)uKZr;FeTlSgA+k)rqL)AtEcy{J9Bh$W$H=xk$M-fmYO;K)hZ%s50mJu!W zQEn5p&g;WcOZ$+4=GoX!mlqqhdc;@1;A$n zz70#7#b3O&dDtYd2Li#L-yVIPOA|bFd0KL#hs$A=scg`R(gk=}XIhvAoyKX8l~F)F zjpV%iD=Xt_Xu)gLg#5*|+<`ryND~~Qgu!#FH#jE!!%WIEPH-9SNwV_ZB#4R?K1&UW z9`-o4QCwm$#H>_Qt{dOlR@nfJ^+ul7q!SQgh0y)1^_JL7R`n&52qRS_AAt_!``&-| zWPKZHK=HTyFqy%hlvVS3!txVLKF746J5%@f>2z&c$L~I}NEvLRb+gToDAy?9zXZ4( zg$iz)_?~dXE?p^hKfFW*GcnaFw5H*prW-=KQox}9o6-E>E)Hh;>2pck!R)$*d0AnmHVX4p;t3;4A%D0KD7_Nel!^ETmwkfBLkyko zi26xPOn!cSP4%@vbe;%7tK+55pt*8liO_FTxqTUVpw?feA>PNh* z$d_4K1tUvR*!?L)nYtYe#Lwu5{6VXeIQ13@>U z^1oH`wNTDDXnHuh{e@R5mLEx~l!Djv>g+Xq*9R)hj@6IJ zoezT0O5_YX`A1Z;@eW>+QE`$jL$s%)Ti9oWu|V_;2m-A#(pZoSRPP+EhN;1p;W?^N ze2+SR)U2is+HuZ!o&su%dnWT)l*T>~5k69ZU=8w}FX zEQ+WxY3(FaRZbCz9a|jJAEuLTI#dK;Ag((kAI(Y+qlQS8VK_^#z#u5Vhg0qYScm1o z!~#Ir0KlZOu?WP4c|oS|p>e4}8bNR{U_HlfpgcGxi5t4LjOX10D8jo46jm3QfWsZ* z!|3W~MdkxqN^3}hF*MyRA=?>4JSY?!m~IUZ045)^Ur;W;&;yt0&BSd0nA7TakWz7J z4RBPopr1whz!BYxTLD6s~>(fGUn$wO{n-aY*6bg}v4X{W-@Lr#;UHuJZGj{=s6sV?HJ!6uW& zc;!ei-<{S!qNv>IR^>S!Z7RqG#d??|nTpCtS*i)6L%gwMHzkNqR7dlEy0a!o#D$Ba zy^C9?7W_MNfC^Dog{W{^ymP4{!EXvMWOGJk#Uk}wGDnLO?>_n#F zzmNNDKC+D!3@##)pp4}Wz#2c=6E1|a!;ZCFVPrQdBy5Quj#Lf85~IKOufy&VD*J2g zZ-*rt#f<><>cII_5xO!&4>xo_3m{wpv@=LArj|3OrFHi3?>vy@*&y!%n)isH#okou z%1r?*(M_|b|B!99jifa=-6RK8Tm_n7At^OE_Tz(BMjGJ^E5Y^gh2gR@Vao27>D;5{ z4OcUBu=q@7rRsduCq7724y*Se@idj7T0l@m5pALAo#=+%=lH+B@#-$*8M!7m1nAZR zUYKt(JXY?7n{W{vBG!f%=>i;i@Ps1Uy-}d}5jdD*ApSdEzKe8nUQW(s&*aK?wH1oU z;P;+g22+LwdDYD|(Dkxh#V=H!8ezvsVL;w{tQ44tPYgk75PH$*CT@d3Uy_l#4c3TM z^5fK3TM|k=WE=Z*CI{1RV$T(msc#RTzd0nOg###jH0z8v6vh#pwvYjuV6{Vhg@Mwf z13qsKKk{VuyFK)jD9Gt5dv9A-8?-tAs(OKcO1QFZz_njc-nAqcJ zm|Ca0=5kYLznr&r>UXt65Uef$3Kpife~{&hYr-4&Fc&G+@fGjop$e0^Je@9*kmP@L zXjWGPGd&EEkSqUy>cp|z^cbhaNN5$&)O~lz<}Ac|;tB^7)R!c_69f0DqBCwwHBRwH zHR#p!Ozz>VzeHYDBVnqMuo7Oqi*#{;|9l$6Kh8to0Zh$6e$t~1`n2DH3er2w$T>%} zG8q4LENnHGj%L;=4Ys?AFA|5R&^oW236NReNgZqBuuSyRY0_z&=(#_5G@aZwArcTm zOh-Lyt5B!R@y8(`8qf*h9Dt+`!ST>j-7W)L03LetBrkX*s1(fmT!L5rrfXOgUovIPC{mGC_(yW49a}@Jjskp&+Hdjp__z z=8H=jJnuD?*Zei!luq7JqhKS!Yi;-wjT8$tI#}U>)MgYwJPkiONH+-vNUy42m}Av9 z#V=6@$D55`@0_l#dt@gXlmgZWb(bp?kj#1PEp87Uc+)4HoM|I}E0cOtN6Bs-uW2;s z$xS zZ@&8WwbnLmQlyJj6Lo{-T*CymiD1au02lc>ax-JgZFERX8ADpAhn};@G9M&dG})Ln z1}N?kqhcKU4_RHP0cP_#IR^N<3#_MXJmQj=tKj}gVjoN5(4j(*1WM!}cx|}7BbKHd zWn*t4TDTqY@qrcQx68HT)8(gOk8t;IRqDPLlB_&zWQyEA20e2Az!`Y7Lpl`o2{0lr zB%SqmtP3wi#cL;#P34$HyB^%a9~72u0%8%ml0p{%)T34m#zMqL z5=yL~l*Ryqo=uDFIY#})^ZO9cWnqakU?HAY1Knm(p0Mb@fSBe}3BS{fSIJ!l?2`Y| zBr)%6rPeQzYf0?sbHeF!dU4k*MdRz&sqxAyR4D(YOeT-+$Jp*|p~Nl&yCw3nWw=f* zZxKSno#GA~1X-M7OnG?jd{z|AE(-;KKLT>FO_FfyWqzq(15){Z|J`1I2s`O)Zo21T z%jtg$cm8Cgw}8&?XQyH^^lkn-d0;cUEDG85U<+a!J}~(yI(17GpxjCdORMQeWJveI z=Q69)o~>pol`n4Dt!NoVgyGdu8gqN;P-h{9+ah{fI#B;Wz2ucv7j(1`)&|6UCAW z`Fx+p+i(t!JMD&ZvK_MCD@gx z98B~!hy~iv8ADwn0R(%jJF+8RK$DB(-emAivxp{AHK8VwPRcni)d-56DBuupT{h5c z=?9U=ufN_)5EOa%SgSa=jkF@x8hh^CfYlz0WZEONcSM_9$Pm7^aB1~}VeaIIGP`p+ zn)5$LrdxMi8Xn$`Bh^78?-M=^zZ#?7bf)e#B|ep3;uSyq>3h2N#3-vVr^QThU>TMw zJAcSlCTw-4vdr`rVE#`=Kml0$@HT;s5TiFx!T*};WqEb7USEL0QRq}-jVaN z?p&Uo}5_O4YPnmhKDc z^#4gJ5fXKrYP*AVplI6hZ+}}Ce+6aZ1Uj=UlAJBV zfA;v#6q5Vy1qizhXkr7*Bc>BXQ4`&Gmn|%lwb(t?-df=={CbcRi??G{-!$ctMpy4t~McYXi< z%`PjLa2L~6$l4rz|4vfFB-%j2a3AtoOo^fto}3uigL3dINLJTM=Rw{WiPC*sDe|AR zn%n}F*`jGK<%Yew91Yv96)?F$dH5t`S|+TT-D~`Bb&|n&nS&Ct zAbO4-_oG~`nAhMrqaZM8jWNofiCDO4zGJn)#;3cA0}5wa6+5TCTP>R8HQwtgvC^nP zkz{tTgF;4w3_dicqI{``yH?isGhFfobJLz5_AIA(lr#-2!po16Y(xYrvTdBB=TMFEeAUa$4MuD_m^!rU-8?YlPLVZ`h=2|Gwd4ezjhl2zQ5(b(y`IFT`EKOfdWfr(p`tw!;gs1wdQJ zb2R3JTgVG}aup3Y8+|G$zG!jsp=o9D?Ad*QlCKsa^93oEI=Yl36c6HL{uq!>_Y>&+ zLR?zzC~L4zE9(4crp(ZydA@r0S10Y~ID+)A=x~NPG#DV(-Z{te#@tLvrI1^|P^a!< zuhah_>CEGy`oadz%$PCO8S7v$gRvWHwqzMY_9T0fEg}1sBF$LG+SvCRTiMbGMX6@& zgb*d6u@#c7<)@N)z3=_+t5!s&cXOJiN4r=#ZtcAJ9>I9g0`|KK0QJh2yMi1UPm zWLa>NC^#vL&%W608CwqFWYVty$UQnBlt3*<;OjyJh$oi6@cTm4&uEqZwGRm-{X#a3E^g;| zP-LR=5x+ldnir&QRN}=ha%Yd_UH%uqOOcvtgB(k4_aD9I2KOYjd*SEaR&#q2YWT}6 z`q5l@q_cj#f^=86{Nadfe7N`JBU8kYJIY9DfC*~wIk@mCQU4l|k=! zKDz4a!KQR5sBH|X4pj4fIw6;hFE!CS?x)9gnF0kCa%xX`v2zDcS_&r}_(T4%i0adI z9oBt#zpe1pN${OYwY_F%5Rjx~&ROcm@Xk;TD2Iu#HS@cEFBY7c60bSnMZ(bhk1@mQ ziryD{e~ju()sT3ou#10gU_>*>01KfTCAUkz=50(Og=s_CzhCtc(Hg!^M zfaHL;MVy)~QwlA&tfa+bXGpeOg-og|Qq7W_6BFDnn8E*(OU|m`w=|-P)F-}UoPL^t z?!A5pRP=kE>jkQLDfF+#5(y9!sU)Z{4f-mz?a-;8DX04NpRYR)qdBxI37r^AqQ;k4 z!R9s!q&mXZ)R3YH{aoz%3vY(sFQ+crful8rj#lBl zqK!u3`{|mMtlR-=eYI~1V9RzQ-|2^5CvxtLisN=TU_8&r^LmmvCAAYF4*!k-@#_zV zHrm*>{|xoDax|9~d6ElOdQ~mB(BlKU$dIB439dk$G9F-@#Ke7d`8s;M!sNO@NR@_w zv!?FT{tdr6<-TovkCdh!+cSl|eOVg#!>a{K;y>u*?`PucOgIepXboRwP%qrHZ)a5g>Pnftt&uM}S^gs<|DC!>6$Pd$N)Z+3~9bkA8?j*=?;oP@vbqXs#3&<}t(6 zmBp+CQpqmKHIOxC-hA(JcoHTWXDjD(;pETZyDxPOYHm}awqj3J%@LNu(1168HZ0|r zj=xZ5;1cRdCV%I$y>k;>Wdf%K3SGH;!{FWa4yn5?pZw^St2S8h@*BaXJw0n$t@UtQ z#D=|6+UJFe3A+VB!@MLc+T_r}wV%yVU{7%a#^xE~!H;|%r8II0U|Rl9)D>DLB&&H~ z>y0TBo!kh16Yg=Lr=(fPQ<12kT8<^L@A8@uu{he0AF{by^g zYB=1VwC83&->%7BMNoHEX6Iaeajx^mImD}|gZlPLFHXy$dTTO~^L!ydu%RLG=fgXh zt|#{3+vq#zr>g_Cjx0FJ)V8d{m(%&kqPwjkif|ry^mAZDrgA*h0Y6V1+z>(2a(zSkSVs!BgS|j0Jn~X+TvZYIY#^%>`H1A%B_QgD``%C` zNv+~eDE+u>##J~s(K517@5(=8b`{MoPr01T;+fO-jBIm(zj zuNeja_rz02gUiWvte@1`^=ZB0akO+BFH$y1YE0634Hv76m%qv3zWoUZ24av&@_RUq z@IIYFKD{`g4nA4!#Lm9WDr93p`F8H7fS8Ff#YCNLqHtb0a7NI6sE>5n%u~k2UB)~X zqel?5C0@M5VA~|KVxvVq*PYmzfmi|n-OnnjMcka6C=);*uZwYws$TuwJqrQ z9oxn0j=j?VlJ7?lC6~;`*?f@emHd7s{k9+}&jAS{cmy$7nzk!!LGgsv8%+8?(^b5~o8T2Tr*DnS*;0tv1z4WmTPTnyew;7*ah7Z3! zdae@3FApP4PVj-GE%|EqGy2tq?iR`WX3^e+OgXHc@l>GDp^SmsQzRdavOBtTaRN^N zvE8A%Yi`HtR-0#U*OI=!`S$FpEs39ZW3_K=CRZT9e~NatO1MTOMH`lF1Qqpkv*DGGgBPx?5&j4W809aa*ydw_jW%3-6y+)e5F`5rFykaR*NViQ}Gvg`kD9AmZ z6Ja5Lg8~;jT)kwI%d1;ILILWa`kqa(3jH9x@-Ds-o6rBPUU_!S$O5OuBB`G}E3{$O z=p+F%vt6S&l_;}{v7gK)D^Xpy>omau6SIcsiiqfbLBeOAlo^XQfLNii#rE5pADR5O z(v$q&>iYqN8A1N%@xg}q&o+>VrTh3be<2mA_`DQp@Ku@ntZy@HB6fsj9k>Wk*QjG& zIm^J~jOm!0GO;_vJN>l9(l1<_EW$kibmQWf1=C_lB$tZL&iPzZ)F7{5z}Y+udo}(* z?N~eqD!~m~s(Oak@aWYDdXG0)eTuU-@Mo!a ziM^tL`R3wZr(lT_YM4Q-iRzeB`ZY(xxq^r2Brgbug(;jR^zv-d z2t5tG30t6f;}R`aiC}B=3!Et7zF#WW1Z+gSVYNB7R|K>()grA(r9*Ue7^716d z-WY+tQdb7vIUrF|Us3b^Z}bEwH)T5pr^5_u65PJZnA<*iiJ!Srb3y*WQ@}v1=-j7B z@htl<7Q}I*!s0tU0f;kfNm@AThD+(tc{kdqKyLpfSEOpU8CSfRgJZZ&Lz53s<0<2PO9hW{o>EK7I=*!O&Lnc!h@~zDWvXb< zx@w1&Cjr*eB1BxACUmdnPrj76)#%aE&Jy@ug`RiQ~$4~q=Fw$Du7 zSrfcGWw+*tCp85AMB*+Z@Sn=R0f-r#;V#R+s&pm+5|t(=-%xGHf$Zgr3z3g&b2K`u zO>VUmo09EB9eb0v8uPQfE5e^2iHvwCoWd~Mnhk3FPA z1nMkXg201Bk?J>NsErG8BLMxD09`6AfKB!BAY(;1%S%n+gms?G*UPcmE5xO)Gc;)) zoJQ(J6tV!F2dk){Y;iMt*}jYJI4MwXUFF>v8K9)H3CAnxD`a>XoBHd~>DTT6z6;#N z#k5#hs@m!Om;R~7R_ewmtJy&m}?L#_fNF^Kb+uuTzp@pM<(P`Po)!&NVy(@vS2fyUJj&$W6B3)2_ z>}I5K8Ndu4#j-+vitCVi1uJJD4TXXCw1b)*10NNV<;P5W#(BNy=$>Bn@MPC=8#84~ zY1FizT#Cp`Bpp6fAva;cfIq5}Q= z->vAs;j!FgtxQBg|0R@$#;}#9Z*QL3MT5KYg{-#sz7Sn21D5Sw>P$5X0TSC}{K%;H zB2)bztn>V*Ywc)G*rRRO>CRVWOBNz*k%*b7xRE#A5zcklIz37JEMcY{ye(sVmL1zg zoNjKH%@pg1kVAqyONL^k0LNsmXPjkLrCEEUAbKxmo}ToNO5o5ndtXzY*PJ~EuKv;G zE_oqPc33UaqZz*tMp|t4DPi#sOYwg-f1P0hspnLt5btzUtvF5JR#|r}FMsibg_lf} zj0UJ~r`s$~{`4PEj|K?Ch(ikpVOjmxw^>U%xkgd_jWyisvuKT}+!C$KrUK&f{Yz?- zth_g(vhi6K3Dp8zy;U*SaX(ld&)I)UokuIDe3IgQr1jAVW*N8O;2cnn==zTn!36); z+U}I_{&QEcg=;yqO@MaqnxwP<*sRc9QRNg&a2CmtmIs< z?B(mvY7UQL7qJN&&>8*#g{5&LNP{a9U%du?<^xqNaH2EcfZqsJqTP3dPkpfGEKuz% zc$9bJ>DTnpU~Q)qMsUX3mER$hv8T&P0@P}?3j!15-vWl|JX)S#WXu04gR-IpnzYsc z3S}P?9K|Zez8}#cEH~e%Hy&|2O0<_d{Qgzw&UEw>!va(5_)Bhfxc)TrphEvg zGui_4;C0#&d-!{ra__ld7#b)o<9DGtfb^DEmsPZ%h>mu`B7qSb0im3x(!nM*QSZWZ zDlGg^7u6s>w#n$#%eECd5$}-Q z1#&qE6<4G~cV2z3N1_#j6i_S6g-~>;JJiYd$(FnTICV3c#C&~6Ld&y^~KS! z+Ci#?Nne^J()t+T|6%%*QRI|F#0NSK!hDpmqB-DOqs z{W8uoC4m}HdE8@+&^G6=P8D{fnzRbpsrfam#EGmW3wgn;PYxAWu<)=<;2j>C59N*N z_nYMb_xXm0QyQY<=+fQK{L44)@qEct$2VE&%9M5-F-;&Px>l&L!Hg3@H}{kPF1lfSly+QRc0xcmH)(GAs7ahEXU_i&bT+W0hmqH}-RknKzBex{MXVsr_^vPa?SLomXr=$_MvyIa6hW!e-TCadS$;e-}1k?>CXYs;N+c`AyQ zDN;frQoju}ureCIJQmzWK6vDlc!yJDrPn1GYZ!siy3{PgKSLKlPn)TeYreV`Kn4Aq zqUY2zG~a4)>W>ZzIcw45S~#pdcBi2aL$dG4F)V#aD2;x&27!EDE*W(l+atW3j6 zNyJI{9T7{c@`xOu8cRD-m6RGJI{eVy>YT(7SOo!_jUxcXJ2dpK*;*^V5W-CKGeChG zAiZfK^Mi+>pm0DyPLtz}K3Yc;8{Q)2Qb-?6`;Y|-h?w?G9DLZd_Z~I#`Wwz`sz``3 z6cW{DU+b))*Rk$nx+yKk7>!BNAWYaH&p-H-;0zSMH(|QhWXWylb?zmDKh}uPpEEi< zqxmsjAUN(FXY9|XpVF>mJ1SoC{cQ?TVWRAWVlUddpX36%M6QhC0iCWVuk1>f2Q+K4 zoVr*tFL%~Sry-mLzHST*38;ck>CzpPq^+waCSY{bxc)S27WeG#^~f8uA3fdzjrM#D z?QG5E25VPEPdf7#Kd{G<`vH$|pcWN(2UX7G;!fEDPJ;&Gw7g?Arcy0cDcHO1$AHT# zrXq+sDH?nuvAu8GM@cVBFwggu6aEfT-Sdl;CBNqD)`^=>D%(uSIiuj2_$rpzrc0uN zY#OKaK|qyHB(QkqVqIYUvNA_rt9Q{OAL-3?c|Pf+VsGm(B}vy z=N9p)x&{N)&tu>gE!u9j2dQKo$4n)K{gBl&9sj*hZ=a9y?9Q`{eF)P3b%C?BnL83y z?)=Hp9CeU+jqa{@24>4A!Q)cc!yOHQb*rUal7@GsbiZMic4`}r@m;jee2it`fJ^;1 zp5nL@c}ZL$TP$rtv{v51DAA;FDWl-$zl|Xi|3&iUvkpe@D%m*Zt+8Nwvb;t%v-*PU zYLE-2wrwGmJI4Z#ET05GJI8xZZMK`$du905l_3+$e9k2)oK`^i^r+~KOH--I91cM; zfQl?mo;&F~2*~0?G)g(GLf4cMbl(eIHE_QZWYrLHf%}iK_PVvPJ#t=hn9>irK^Av- zkpA7r+k_vS$Mx``j7a|61@2&bAfmshwLL97w}Jn=aFbQq=$~ucw;n2awHwbV*aWu` z*>(Ib&yvuAPq>c8#8qDQ1AkO#8}uEcrBx5-?+WP!?x#lRpDon5s<_h&>mnj;q(ve} zbKcd08MTXiD~lZ_f=d8w3#dy295HS3sd7{Oj|v$!lmIvv`e&8w4EA7#e-;zk1R;I# z(_R9O+$ED}#0r5umf<&Q)+58?feXMACHDvdC)d}q_;A0x$n@zO%v_ZiKt=1;8x1l{AAgizS$nZQ8TUIk6DMe z12GXVixof51M-71h}-9 zEr0=uV*qzh!iYyglDq%>o9Mp?76LdiS2Xvbd8Wmvfv7c>>C?w&&~Qy60#b+KXKBK; z28Pr$nDyf-bZa42EZlh3@ybl36`I@Cx5j=4R^$Df@lD_fi&J*`p&uh&nG`;X;^*foc%UH1fwz3E4aJ#3W1Z_+p^J2iPM zV;7`+O-tiidm5DBQz!EyOfJE?6!&#|Ye0T4l`W2z<;+(7GS?v>iEZ#?V8N_nWZX%y zlTBaPt?5Q{kQk~^=2y|qs@wRtI;tQp-VjM;*;+y@C@cxYZpEx^gl zRlB5WG<~q7*mTH{WeXIz6;9;2IU!5g$K39}Y|)Q@vZE^j;A^zOa*#6>&tJw)ZHI$S z`bnf6*30Av*!;((vn;BVGZPO3KX+Z7O!R`12u4;kuHi}DLzJHXgDCj}wrCcN$1+DU zhvwpyZSy3|mnOCqV=yuE;SLR&KYEpPho#vs#mZ~2MUE(yO1$aCTe!|43=p0(-ccjV zEXxLihk08b+#Fs;@OhuhAG(^)Da;J=f4B$Yjh0sX)wU962H9W{ZVD7nLGzPXu-W;e z$7bk99Ow2j+4`q^gH~i>RnUr1FZss?R!K)ZoXrXB5XbXHK`WOfI6ZPfGPI;;ckxcB zJ(>5J#}4ae0X1O9D^ADZd;>hP*MaQ3YoL@C*{1=#5{hz*;Fg=Kv(Yv$gEMqV2M|w{ zbALI7SjM#HeL~E~l0aW`f7Ap|SC7!$I?eKgOvYQ|t4;uxD{E2jlE67^B2`pT)$#O@n{~qRJM+F zC4az37l&L0fm^~`Abc4{Wq|VQ@Yo`0S2Z4I>CEi(Ryzi8g2Im)3{Zw#f=9^NkQICy zbjQ^VrWSF$^p_=wdSu!SeEq~3j&)_`d2qpYWO4Oc+I>oEOeMj%A4^Q40*C7f{ zrDz7A&X^D#^;wY+pB8{`;E^(q=W=k68DE`o6fQ-us1~Y$*2iNJ0<{pWM;4dw^eb<~ z8N>*R77EW7$lhdBV(DT*z7NUOe3i7I6Qj5_cVnV4M?#R+G*PVFW{0OmHrkj&lo;@C zt5%tFT~jQI+M)N-8EZZLQuUm(K_!CXsqwd z9PkHPtr^^vw6t~XVI_l0*#zTRiV^jLAZkrL>-A>OdjB`-{gzcc{IvzSPaq=6r#ZxY z6lP;xXB*f!zwW8)xPre>H+qy#n~ZpYVaiZS_TCYOo8}c)fSBr z?;#4$dEMwzH2Bb`#Gak+6nYUEsUOlsx#S_}-$xK;> z6? z`ycSG?U#;ffmW1JG^(PqFNlECTWQSd9+2_pICiB0)wH9tdwC5QKzYrYvIij9XCUSI zniH#6uJJyf59>b5sapKo;`hpO{=r|mqm6g52T3=l=r?tm1*W3oM?$&ZbX^k2;N)2C8E6LaeQYyT| zfJi77_1C;<^>=+Ls}`kc-&hvn44K+4!0qD2!mHsYg(KyZ)(QqkhoBHsS7DN;8q{!( z!<=<9KMqZ16*yu!>B8oy^J=SSa17IU^;v~=-!_~ka@jE?pZIYCDsEaQ=Leu+0bQ;2 zEZjRR0^7e*GghZ72@ukb+~i?9Dop2dJ04(@-KT4&e`vFNhcdF`6F41XNXywwihdDy zsouWCY$x{)<=!b?(;LP+P3~f=3<2E>h&h6{5rw=fBck@EMr|f+MFAX5V0WLpDYPPp z)iPSlc1ZyVIbvz9D`E~N9?pF=M^Bq~{=R&@b=_^1FJ(C>&(ta_`hXm#Wmv!+%_3v| zwxmbiZ{c}uNFkq%`;bq+%$gnUOm?J~H}9YBTZdCJ(N+*D;~sO%Oe_s?sSSU40z663 zN}ZncykY9Cii<3(hgunj3SG+{UXiMHY|_$bl~|3lqa^Ah5Gf_El;RuS-t5t_g~X)r#UFh08gi(Fo^0*dD^ z*S15I3B4BrXOvxVS1s~f<=5j&(-(`+`AnmQ=4ikK!bha(a0Y{PVfT?f9ZK#F`_Ky7 zVW~tP-8#?8Z9o~VFtxx_gM*XAl2`?f2|R}kK4&zdYgz1NH3Y5%pJw5nqiKw@*l%tD zi&5}~bdzJkXwe#>ZyWMXD5&Ku;+Vh|dM+8|W6j(swKF&Mm>OJ2Viopc74l>iiac@4 zFV8+oADDdlCeDkOy(obK7Vlv7j$EFv)Eo&SA7*e%26SYH3m%kn;L9A4gR=mm$5KN*>8w#}28`RJqSQ~lmY zTzLj~0Jqk6Mje^I>`;f3iQs}|!D9kfBB4g*52zslQin6CM?m9Eo;R7X^*#Z;Mpwk{Jyi-J))EUd)6t@%%fx_0RVMYPd zv{z!ML=HC|YHtgw04|yJ%ss%0u(NV*pEmIAza2ySrY)63qrJ4;K*874jbi+Q>|M2z zQ(}{C6QIyJ7U9rzH=40_3+6e;$K5u}|5V(m9zD4c(nC4I8ez)Z_b(h~3buGqW#Ci$z9Xfk z)Zw362yQ`f1tW*L@O>%sY>Yp6eWh_~T|cB@FZefcr72s|C>qv{P^o$q6CK|w{l&Jz zGh}Ia_R@bUbJA)mK9l70z^v*=UlR;%(8#4Z0Z+#w?3YrbU@ z2MyH*0}&+}Ny5xfkF;4KOU;J{h%s{Cnwpm^W{_y&$Ccl()uN>98YNL zFU2cI42b`}b>X68Fd2U}A^n4zyihPGiBpHYzK>fmsdOr(^iI|VTjSHe%WF(d-!Z$ zS`>We)?>zf&lI>wrJt4S315|d{a_JnEfuVFz7LNlP5pfT_lb>*R+k43B8;aP120Oe z!XYyW(`mu9sK!_qt!^1W8c)>dNHWhw*g>a9(wC1KXU~nQKt=AQnj<-bxe9q0DOW#F zo6N_FF~@?B|9q6xsiRI+WUEi3PRGFqgd0U7U^P}+(e=P1eZ5n-p{6Q6^cPNMG{ob% z_R?V=#f{olTF;)>2@&%^?jD8js;B}DazG zK&nt{tF2nAeNwtE70n$0dxz2>a{dG4mUVHLE77Beub#Ht(SS(F3c0h zvj>@+b7HE}mGKeiW%;)GE|fU+Y#Yenk*2^CI_Nb(o}A%*8@I z*nt-lo{^2h`A&)~d#~EU?%=5hyqNpT8NwV(9(xX*zPFME0t3!nUwZpOq`um+*js!( z^kjf-b<%6PgW@M?xzrvp_ZI#AN4o+ML81?rj2liWGJ^jipjCUGW+s)$02&y76H8FM z%-C5e3A2dcvgq!`P(*aQrUo!KIzC$jQGk+bmRD=zFW#&S&-gycue)H+CWhTV6)N>z z0l5suf~G(Mdo(V&B&m>u4o$9@G&ZSTR$k+^WUWG+SU#{)t6Vw~Szl7J(bJ$bBODXE&9*mR+?+Y-O%Inxt69*7TSc%#LgD<%hIgeevv zi8(4rX+T3seUi@ecn0c=R*LTGS<75e(?CwrtT0~k8t0=r{l@xlb+MakWrGp+sA4@M z0_A%^o#0Bp*V%&Sm@^j#C0~JtBs=4$ySmVLdw zu#57gJhGlz*1}kmKJtf%o!z$g$FPX$9UHK5UZ7xu&Hp{!2LsR z6vhXt5;x2z1Gn$`l@dhn0$DN~lg=>4dVW7HU-pPk!jz`JdfLOO!!-mJqp~QunQ-xz z82^f*5hrDYT=3(zzNOVC-ncfXr;Ooc_fw}IPAicb`j)U>1 zf^Y+pcN3QGHl&GJnG^XB)%xI3dWZ~NRtK3B;90)qdp#Skv3K-J!jQ=VNwB`L`H!Ac zTDfd?BvaWfq<`tsx@6A=NMe|QmX_Ej?OB;Jd8?I$NY7-{f+KevL1R4o(e=K}=aEk4_~q+6on=*=VmT8=N;oiffqI})=iXxwrmlXd7ZYKkNSRoDl& z`)};E`wNsPrv;TGAEz3Cgb=L zmjXRBqHf!#;TcjQw=6}M_wutnJP@4N$RxCb^C|j2ylg8Kk9@K>Ht^;z;*mU%qnHYL z&3D)1qY5i6isM{yF%edaD7iv8QVsLV7sw$2=Q%VVL{B{+ji7r)z~@!H3tjY|_giaa zE<#P}=%%?g*X`u~!6fSFd|lL$(a6AxFqoK7p>Z;A?p}J@dE3KTZm_cXRECv|4{sn1 za1ivsgGCn!hXYmif<}y)BG&Jte+fl(`2$DWLxTnY7AW><;pmhS&Y@ota8`+-h|@ZJ zi4FwF&qywBwky8U3Cul?B7!&1jHlCpU z;RUa-AsT11J@jfVa0f0y5tP=7#OqU#h!S=R%JN{)_XRax!i3;Q*s>GwXm zQmD@!;L;jXK5ZYCKMc;NMy&NlzlV^LSitw_85VxAZ9gQmQD<{V*&_{^qwJ~94eTC- z3)VE5k~vawLrMu5JU4?M4al+9Wj7?-meI0vN}**eU?~l7hH;K#X?9sSy9+@`7Zt0o zmccH=MJpoAvXK%AY|5|zIWM@U^sRU}w>~>cYS}oLlDis^aYCCq(Kn0y%vhbv%%OqP zSv_@d>Y?Ys299n^=Fy1=t}Ygi3J0}gc@rHU>D?p*h7LH%C<;*=%bcX*GLu#lds2D%U+MHCdU zJ8QN`ERA|gE!x9KPg0eFw^p;rCvaQ|NDGiJ(zoDH1A<)-k~aqp0tdX83ILHSfY@F$ z1|pBA1NeGB|MohNrvuplt!UdU#|En1n^s!>Y49o!aEbuHOo0NakR&hmbmPi2WA+bG zY^SM3%WT$BHNjB_yqgES9h;@mDE4$Rdxmi(@q{z>R@Y%bkD>tV{$-#@0XP$Z4Ij!G zrRA9OK;>}3a6Wf8!E%TCyKNc3)d;|@2Elnhe|r=7=mzLlb(so{nGx%A4~wqYYApZY zPZ=q}_QOTxC`j#9NZ$?iG_Mo<4Gfh8(1%rdK#7-cIAsZje<=gRuDCqx27dieqqU^+0j8l)xcn868wEOdoRcR>p>$4y=MPWge0pEV8aS3lqBsb2N zRVS0rIKY7Nn`io`%HRm=q4NYeF9!j|Hi18d*hVBKqRln4jbEuv@FF0&Jiq!>I8>Voi_jF=9-=N-bQ+hk)pc9+e%pjUY# zG7Xj3PCtMA;y^Y+D!XsPVB{Bdl-M!W^fX?{DXg?ZFzabta~tfVnO+eRZrvsRw^Ja# zBUj+6Yk6B)IWKbf*7#OL}|A*LLs!(k7ay zu{aQu^0>L8sKx|Cu&&LE?-sUJzsK20Y3?i(1EwJ!y0coVUZco2KQ<7PA8jg45cJ&6 zuNWdCZu{{i=eLJ6KO6e~xSG|o-Tm3`KX(PpK*aYaw8_V3m;JHf=W)gDvTW=>PDI1yLiCm0On)3Lbvr+zUD{jX3&$^m6v*_pBu&t95=Z3 zv4*>t#bEx@8b3ap5wn_ zdcjCH))ySx)X`e(=yg0tJSNhCZe%POzS44<%ky$V>j5-Lu4F)@k=Bonb(j?&+3(-L zNiLeaQey!|zYgVhX)bg|I@b)#J{!(C>eZ?NURQQ^{%g=_)$E>E8m%0WrP&h<7k%-y zyAm-Pi3CpLUX*ab^*q`Yj$p6ln6XRc+M{x>TZ;1=J=&vI6!}g|IRBNnQfV+|)ituL z*pI%b7T!Pje8hND>}}+*n^}4%hoL){`zNu&(*`3Bm^RE_|GD4&L*6x>e!U&~cXyk&eX5brhSoq`P%T35@a0$zAO$;+g)@>RX&NB(_Ay>j(cG-)ihvh|Nmv)ghR zw;1h(lFExfiqrM;xzP<@L`}H3B-L%YKrINJ4F62fHKJA*J+ugQsA>Rg4FJN_hC zaGmHeJNR9YNy@{&tb3;{Qz-d;FXH31_kae<@GZq5X+;x7m8LAVaPIrq1y<{E4`i-G zGseBg`rEXPZAS)|#N(gh*g|F~t6Z;3Rp^fS-H8jmmOT>()jCuBDYU$6Q@_R37Kh5@a?{sw`5$YqtCm5S`;OTkM5kZN@vNgbZzYL2-Y z#X0d|7mI~OyKlYmsjHt@-y#~PHI){+15f+@8#a|+{o1>#+3I}4vFCWcdI10U_!97m zii&W{$Bua=J|3>mvm03)8Z{g z=d<7|2KPYho+IY3CE}Q;8T(6nD(`11#*9M0#4e5TRei|%Ew0$}{%NhK$Zy`@oDbfX zUv_JHhjO=oTy@(y15>^`vtKfg)gK-Mqp=8t`gm1z2V4A^}U zytTEHZ?Isq7`mz#>u`4X<(Yj8<%mGL8qKV4Z=Y|c>rPgN?27yMD~3GXv0F90i+zKA zVX-#-C~*z_##`{!h-ogq8jhs!RMQhzLdLz{crL3-EOR~D0N>l2O_;;p6`b(=Bsex< zX7CNf{=ITy_uRcbIG*{_YU+nq z$)Sh41@pTv_jjXI_m=+-U*G-(eN>_u>hy_20b@2K}%8O?-N%DSrIo%|FJsB7w`Ni;Q}ARo|BGmW}tV zRP27Gs}C>TbAEX5ID#9-JZ27{TqCYk+ zG#Fa9a_Ku!Y)b{2oqs~56$eT#3cf`BeYEXT?|xyYZuE)Ve1r2cc3rVk;dO`L7YV^; zmwLr#Q$-=I{Ro9lkhAbo>NUrSkX|=*ZnP+hw59C@628a>X+Y)`LR1|rSj}ZEp~HY{mrg{4)gbHWb?S< zk|7{a^*!T)TH~+Ezfj$umD9Z45dLee#$Rhr?{tnFC_U;t5Is_B{&iE+_8BNgGs2ir zs=+~Ll5tG~yha{W{oK%Pd&AGjqoC8d$Sh78bai#oK>U`nZP#%mm+HurV&Ur{3COiA z)h|sRljdT5&&fUisUbO(k|jKBhQ73H^Nl}fIeKmMtG^@5Si7nv#7<(iGQW@iyZbi_ z#$$k<9Tid z-Y;wAyy9{>61i;)8eYU*gZ0|Jh2sy>v79@$2IY7T&dKbKB8jvhKn6+Wq50 zpLLt*d*&^-#)rMU&>Dwjb_VWz45KE$j1TYU-*paaZgxJ37?v(ch#XaVdK5XP`92|P z;`Dz^x1y)5b^b-qTyVJ+^X}sHe=&2uCu__6wWt4L7oy(Zy1o?u-@ogOWZ}fP zl`Ng(xU~Y8#2cS0t{>mns4Ypnxz+si_~v%|`^5O2=l>nY@AV1aPB?h2!%X<`*5&rC zUmveCZym0d+)n)S^(iy)===NIw~zn+$Gpt~wkH5(yjZ#8j6t&YL{7gG$`7_?8*tn)tUdN)OW zK9QTRdGp>nG(~~WlT2lNnDCr9{Qod^uklPbe*F0DXy!CC%wf#g80L`XJPdPe4zZBt zkW|!2#nr)1m}7IuS{{MG=H-EQxbKB>!z2C3* z>#1iDknIy2tyr@~Hu4C_32KN|x|-^aj|<2RUyfF}v*k|649JVoi%}g<^{~DakbgKf zM*Y>62XQE%;8;Tp=2NPt!@GcUr((4WTO%v06 zBHjg--TohL{=Sik6lb? zumGeV?;`sTm1_`OE4@G74fB)A6XWKJjq&cL{{-a41=p)5*2!F03@9k-us27{o%H>Q zQJs;HoR?}gH0Km552CEBG7d^dlOFSb$0nK{U-pSH4yydy3BmIK9&*b?D$J70`6VtV z19Q0e@>=OQ{>R|k{7f_7^DV(jAS8nx#D5msTmXI~&6~_{i*Wt_aC7q{p7n1*Q=A3g z&*5E5yImnHWd)4?{WCOB;#phU`eDOGI!CzyC3##w*XMK2lh) z%KNSRtooozs2#14jd)qgt!eh1hUS9vYcdws%PzsWusuAGR>J>q^Dhes0Su4Z;%6vM zVy)s75)XRbqLr%YHEVurl0C#Y-{Aep_Q5CrfPM4Ar*${Fu)QBhf%8*^a^TDOx;|-C zQJ@YMAmvKxht1x8{p|!xzC4kv5}c#35a$84V6b|AK6tZ?T<%QyR=^tiHM;=kUa}C^ z-~^KRk{7>U+Cc|MhmoRCJpwHL)e)&(_H#oXWxeuVJegnyTXAqx%k>jWReVg~t5FIi z($<_aUp{GY>V{fueU7g`91Qt4w70Pl=Z;K>$wNd*QOf&Kd=j`mdRdZ;byaNbH;gqwuP*GDd5#FMd(qYc-0G3nDJlV?t|K_0OZcngW1-pV?Og=k-T-F za)an$-Hxwk_tS$ca&JOq3jq0;Px1P{Y)8K&k{f?aLW~}CN*$bc(?M#(>|$9kma=fZ zcdbvQb6zr9;HIOt5n_V{jB2`D?Lqa=r%$FzrHl-kPzrfwn*s=N5+LW0vw~y%M6_M& z#4hq7>O%Ux9n_DtF(k0rpbO&KU9zrR(g*$6<*8ej2DFh1l6nl5e8v2y{VqvTc32mv z*gMmnafDOF^tDn)Bn^<=Bz}f2a~;entpUiJt`^iw77qFt8YAAxawQIs8l2Ik8+17^TL1M5ws?P z{0RZaKy*fl@NNK>AYjYIF8ufT+4jy`0es+CWPe*3eIR4Uy&q7!OZJ8%{n{Q$IY9!~ zRpoT|Gw;KyhY{ygtNu5Lu$i$R9I%ctY2ylP@be%l(Vl*)1LwvzLvT;{fC)x-tHQ+} zB!|EiE;Ss876J@%L11tOktX)AS(tg2!Hj7L>~88WNu?E*rVwzqztxvwe>0~Uhv4?l za@fU-WB`P zW<-`pcm`x?kYig|P_{`)j*^;oBy7}chLS#)PrI$$hEbn!4y z!^jwL4B*|s5i7C*2(JDlOF4!8DiA`Ya}x7Zk80fesb;L(d&7E!yBm=~rm?HH!#q#S z!8Pl<=T1S4P-CGZV7rz3kNXu%MN+#59A8`F^(d|3K0JqCqT)z zJ`O~R6S!yyt=xlQ(af+V&G>-vX!`*xPo>j#hpvcsGee@5HcUJ~g#jqC?C~dxap%#R zAP?0+OJT(&z7*XMB)w8)r)TIiWSetKd%vCUgCw;#~46?)s1o; zAk5)`BMqogJ|N0z|JS%pW!u(w3}<7Q9&dBo2QAHuy;;ifZu_o)trSCAS$n$-;M>%t=%&tPX60t zV*`5_kjj1M(Et9o))XWA9LLyf1ZcSAow4Bg5_LaT?|S~4=OL?Ik<<8Zc))+BAMN`M zuoF?7_-y4Fpj*!)Vk+UqX(}%Pyze$w;wc$eByz3iA4ozTeyX3$@0^tW zq!qtl{uf!MWn^`c((;1=*Mar>)0~_{y^ujzkxuiULjccSam&hh^t5;M^^qqi7aie{ z<5t$&dd{C5*4O^)@|#^`goFKqy8%X29TLE=_uB1VaO}3suw=%hKP^M*>ZGxfV8u6^ zz2c*JN;uPDVTQ5zLT1zR?zDB>f9l-1|Tyr z1nPLtFrPY8Pc!bK{i(>mJU>&g7xp!Wg`061%mv}M!tn7OI6k{QvBO|}w;JdLEcUK7 zANU%~aU_v~_1FM18}`($evX}v9oOOmZP3nCSQiRC``W=XMSbo|;N!(L_TAHu&B|#t zt+eK=S}ku?vuD~+BA*AROq>v47Z`V9+|-E&GMi_qO#(Q#!EeABm5Ly|1V>lwBQ0mL8lrLO{%5M~-ij|cpC4YwZX`?=qnn@PL<^58e)(VDp*0QBCQ z5gim3Z5jXAK4Uj6;~pClvAtz7&;hX3A4r$j_uv87oBHaiiMOr#Yp%dbt>=}+)7CRr zxV{9R2Z|#vd|*pYiOW|hka3@Prq>Ca*B<=t4~?(4n&<9EWvfg^zIuSCZMpTs_uW(5 zr$EMgT8UOTu5Z6~-FMrmBm^LXc9?Btc^KKvD8h!<*y<6x)kwfleMpM5Sxdr`Z$9_q z@SfM)*pj(nk~g#z3S}iuSMiLD(agKPD>shB*ce4#2|abi4BhJ)4xI5bxnU=MP672+ z06dY*?qcBnVy+LL>%G-^K=DS3pQT-sH4D`_?#sf%Zu)Fpjar>9aW(0xKE_{ygLdg#ntwApCp0@Xghllo5Qg*Ag8?!2%|pAVA2c>sAWfyd z2l0gW8O#sY-p1!`ziRu8mex=txD8mnQ^UPK)LM8K3&`UYPqbCo;Vuv5>EDpD9=Oit z!7`p5Y%1WNv+Jn8CTNh8y?o-3RAK&RQ~njF!_ushYns~D1G7S#=E3<~&sxPRPOItI z1HIJMF1gwpHo4t@3v``IZeCO25m&DamE3!A_?OiGg>tJ&NJw~rtN{NHD0je8u8M_g zCf>->W4PGpe<-(Q-3Z(A@0|p%>zBr>{(qGF@}rAr=bV%Uody|I?Qo;S!bPLW%hdV{ zs5I-?oJP~w*!+OtmgjBsfgFs_jWt>!?y=gApJD^Mo19QyjYfgDc|z=twE0? zOV5Rvq4>VK!EB^yO3&W@mohbO`F8v5tRWv3W=4*|cfc(#iBz^*;3=9lg2<)dLOaaX zM%sVN!hcJ*^Hkl2hW~y0EzIy}n*H!sDcPl~m4APJD@#30x_oWYaaW-;z7K-l->?y` z-*UVTZq^Gc_O-sbzMz&ezZ>=vxrb@tp_YW!$vz~=WBZu(!xZxgf)v(3oND7R^^E^h z2@Z7@W3zNp`THgt9@;J{ITvQp_(Y1fH{)plZR!M2+Sj-OnESHEGpgYD`IDitUYE}I zOL@R=qKf>pgE>)YHG2BKE@oZ(rOC*O<%G^3O(^Mz4l1ZP*?50LsjpN+f5|qh6RfUv zA`s3Qc32tTx!k(6VmGQ04U(H$puBCQ-`{l8=sOM+$Ih_Dc{X!|*%iCLr^VHZLkCOV z9rrTZe*11W<;N15`gUY#vH6w8KwZtxqn|jiA*c~;;4tzgU zdft+bYrQ_^WRLF%Klsd5Hm1nOOz!tvILCcmHU%X|oP3ek{^-amzQ%s$MuJdZqv~>p zDXQU`|H(UyepEL3YkvJ->%5kMb49v&SaK}n)wSNREA9RkrvFRyS}Ti8_N)pb1$ikE6^JJ74dz z-}c*lov!ld_=}`+7xF%!tb=N(K2}54_HV13zg^MJ%89oH-lt&-+Gn^)xA$bdMh22k z%iOFl`Bf}8s(Y&5TWt!XqL8uvQPlO^Px^D`^IOgsN%eR!yDjvtIJp#EcNFCYC$EXs zsb10}pUr8XU5=a2V$S{9d~#B&76mZe_ckFqCHl{|xxO!@+uYO{qj)uy(;dqzYh;&lw2!((5M?*<|b)p)GZf< zt~(S6uif&9zl8qHl&cWATY6{MJ?kn^!WBOw8x3-l*RZk`5_Gd0J4xRT%B%E{+zq#p z3z9a}PewS}^YYKGuK7LUXcnJ45<%%WLrsbedAO()q%Vc%wq@_n21q}akUrv@l&hyZ zyfacEOWxsw)^c*6bEJr)woa1l&jB>f4=G%Y)mE6LVbr?g@4G~9h$|D_=*VHu>J&4G z*?buGVVTTPZbGu^vOqF>U2lbpI82vmBs+D0Ed&guzSL^$-WA!<2Eg79&dBMo8z37| zbUdXU)Aa1Teu!rYDosZLwUF=Wh%cMWt9Bky$akYGfJbDcGXnV; zZhW@NC~coU!<`_^h7Zp*x2!&IX`<^_-8{KEuCwiRD;|0<2hbGE~GZR zREsZW-xPRK$!n1TUSLEtB4MN-nIHnHoF0s*PxE;NF65DY zYYT9Feeyz4mUo^GdUgiuC%Gzr6uc>EIiuwA>5D@6Q*0xd;cCcNu+8+k&e7`J(?>3U zI-$JmV1`wZK0z>wVANmK`#NOeeMq77gFv$It*e?$Kz86Zw!WfFeUD{)UvR*@&iOa= z8a3@FFg)R4wpM%P0ol5T9@as}=T-(W6AY-OfF*Ol$nC`S!+TdFRb=A@N3`N=&!wN$ zRY}1D<>i34-d+Ny=vItN0l6905w2)62Qlv=gy7cbUQ6u5vIT)4D|DTr01h>Kyw15M zlr8~EQA1^uq$0?m{FQYN>w-cfIbD!y|JHhzTV5U+V%a5}?+3o0QM{&M4FL_gcsmNI zPaCgYLS9A7O%z|xy`@qg*#EeungCCv*>qjmy~myQol`3AQS@8+s9(gAdvJ-P!iBY! zPBSFoWo(sMrp928LY`0Ff~3!;DmNYf!~=YCyK=OLBkv$=on%6-wP3RM`~_THv<})z zzk;CW0>-R8w0HWOM4i>YhwLxnh3PtX9het^>QMS#@L{ z$Q=HGkjz{>!`p#7kZY=%5#gbGZae!N-Ty9PO!VC0!QoaJe~C=r@-k(ADz29goHZPk z7}t*npAFEru=yZq~&F%5d!5aspL|5p4sHKy%WaoA-; z;b=jo(QoOEkG$BI?zIJSJP|akx-^#O+a^aJjm*8EHZ^$U=Ag;+>mro?e@tgeWI62O zaLH|l^P_Sn9$O*#|ZP{j|7*vyECVfo!h; zTD~sYWNo24sl&dDLyR6Klq>}KDepRI8Me^?s^1Y7J`WFkN|rhCtsoCQ>JVf+qC>a@0UbSGH&oG?O%`7?ly^EN-DxG`Vk(~%fF z6&4?r2gZzEtx7%%6_V&j~b5V1rQv0iI#w{#4V0ONLE#T+3T%6N2x9OI?IqCNwr z-y^rvAo0nwkk1D|pCys_mF&W`IlE+4$s($Xr%nhA`DRAeK zRNQGG_jqTELX$O0fx-K8c3WnczCr~XT-ZjU3N)i>QMQ>6HDUsB1SL}@(2tq1M3xI5 zNqoPZWM-zkzqVKDfLm`RI417=%&@3mGhH^8~b)fS(W#?+bZk3;s!gb@A&>C z2KX!m_cB1!d_H7a0d(7w-4YZuiiOii0ju9QL!R1dBgd4wwU91_x>1R~C$+rGPJdoF zzmjw+q{HgP<4jkg=CDgaDS&%kA$R5SSv!*1g_48j3|-0;FvugV7n~vC6Z3CxB6)Y2io+w0-32>DVOWe&OQ=BKpLfz7VQg`DDQH=_oW~5Sxagqb?L7+ z%)%w$_YA8JJx`W3F8snWu%D?Glp`)~R81*Y@D^6YSCwlcy^_sTr9j4n7Rz=FrEbrxf}$m`5cZ(~ z=bd|_$ENg<<~8loa6bHUm)$Z##ujqPky*l1+X>}B>eD=$x4Y=lU^IvY`q>@*24J2o z%Fl#AIYyw>MK$}Lbk_~N2U#`KY(3DG_II^hSSXPBPi$dvjL{@ZayOS2pm|{wu~L-1 zXk;MwQV)1T^+WdQhkFjDpW?hHJAG=K~M}C5aX)c2LGjTZG^IO z(YD-9{ehy%(v%?0z8rD@g#2ZeqYkPHD-s|mP5rxi!Y&#CVtlY^J5*cA0o(&fb26V0 zqa^SVxb8j(5{yXy7M(##tWT55de>6G#GMpx-!v*4GCYX88dCK*`_py^L{$I1vh zCWK4M)GL;2&4qpoQ4)ZS+U+Y+T+J9s#Dr+Wn(Z8|b0+owSm@PF-LYpHZh(CPky)SX zR6x?^_m}Ddt~g`iDm%D_F}XFU@HX$-OGjDyHcJ|y?}&{9XLE6lKpVPe6iC}*U&8vq zFO)P$@&bY8!!7%lCB7WZAa#}fSiTS8sgp}g0A3o~Ssqc%#`aQhw$D)B@ZIIFr+A`_xMr&jf(OAgpTHPNQG7Jxi5kXga zAr8Mmpv$r5i|w+YM)+F!tDz=u7Klcd8o>tfIdYNz^i9?=5%#8!+Hb&-6$?J4jc`eXtD`u8+*xueg( za8Ojyb>h8$@-JoaZrEcS@_J5rK+@B~8(FGeV|LK+cKbjm{poBTG+Z!obOCfSrNrR8 z=9}^eph?VaNfqhXq4J$i4hqLZ1rwBqK}YAbJY1g3_NeohR!00SVpeF>PUd4 z8wunCoWV*+%|BrCi+D(N@*5eX%yj)5w?U}wd)=z3Hay7uxIy00D5%&g&!?xzjQ~%% zOVZENr`+HJQB0ry^Nvj@4pQTa2s`x^F5oY$kDb-4DTg`acEM&UFF!ca2Q6dByrH|4 zsK}h0|DR*-9=Y6GxQu_r$2>$B{DGCGxX&@K`=82xPRZ+PRjRev88-Y z^J0d*1LUAcvWOwIf@(`}1=AU@3g(+>j00xVt##+=U_%TPh>NlFO> zYDu`;_kzRM)w@ff)j^DD3j>2L+0t*@XAECZu5# z(mx$F#Pqu($w3Bp({4*X)i-S9GfpVs2s`q=1}n9iZ+JMMC-N$aEP}B4QsrijH`n0{ zXKl3BLE6XnbQ_Nf??%1Kb%5Rck3J-V2^9zG&xt7E0k&hToQ7OJwY};u?MI2eA?l^zn`}(3a(-3!(bpQu z)5@}YgrOCG6Bhb(GV{>e(Y;%SVq6A=qv8Ad@B6AboU=TR{5Ce&*;CWhFeDUkTBjHaF)ys z-+fF}b4*sTb++9CvXrlVv+Xq!{@}RHcoE99?(W{7*0H(83CKI}Qr{|@EE(O>uEC+~ zrue@OZJ;|77rTQGQU#1!+P6c`w6}NkWlUT@kkYfgD5M9tHIED&-CHt~oL#;0Vve3@ zfsYwQS;Q@(Z#|Jxx;7#N|CwoD$|@n%vy=9(m@ZmGup5Mk54W0SG<-f5EWVvyeV!SE z^UiVWNj&`b&mXJZa7m36EL9TllCA9`v6s@9p~e${%8tf;%~KC}Oss=w{{69#1+ooH zs8{A;2jm0T3sCFit;)PArQN>`DkChjLD~7pm_%L7SyA*k|J0-;%-zANhgA!|_qwew;Qo?`FJFu?>7BL9S-LYlV9E=l27*@;h_a`6kF~p=yE=W%w4bhVf zO0N6Bg`Ios^RM&eSRx?Tvv=e1#1z9~AT#jgN7fy!hpFHaf4PdqEahloEf?t@Ukg=@ zn2(pT`cBldqed?1x7``p$f}NbxE=*}A}M4}y!g0@uQ|#E+#gkY)<4yZ4m0XQM7n~W zYsLN*x4hZ)oPYB4c<(}nhYkvJ@Sgi&YUw#&%7S~X(%!D1x!Ab8dMS;-6$-AqrJ614 zVmt~)1vC{uH1Y4U9n98x+@n_(U-0C=pa|r`qU1T!&*FNu|B>Zx5egpa$zl7^UdcTR z5R?;tE2=)7&df2@8AC6VFS3s8*{-7J4fR7Co&M2&bt!#PxrA=x9=I=skIO)Wb>h@t zPkGy$?g;Wz@`6V+)m*(nJUw!CSIo_`3*9F8s6Ez4C<}|+^aMeDp}!p~#PaB*f?v6( z@E0qOoILf;*SZ*dKMz>~P0}^_Z{3U{rdYxwqC6C0;Q{Y2o%w78`7L~O`Np-rv7kV* zRheVQOMdW;8?P%(0VfGdMf7!l%St*O2SEiVyBJWE@|Tw0EEP)bYf(=2j$L~cU48fG zxl?DStd5Qy?k8!Kw?tXME}r}Edc0ARYmR>%K&|(&g=lhXfLLh@kQPqDqGT>JFSbwH zjk$4^VI!vVL7@Vud+pJl#cgWNPgqRpWcC749Db9b|NUK<=lk$;aF?`KONjdp_#JcE z4!BhF-zkvBZxW)PG`y412Q|XI4YeSYN{6k>+r+YcoTtm2xx7pRunzh)GxYA-V7|7Q z_D-FR*;}*Uu1QYBMf&%+nF)D%-8a3}+bAFf>o3Z7CldFP383!02Ax!e_gwk8;a|XZ zZWlw((ZGd`WfbO_oiVYN%gfZh#)ne3^70d7mukfN0nYcW*0;m(@j5*YdCz|NR$k_N z($@;7YaI!1M%*=ms4bcwCC=4IME8V!7zTbeL1#(0X#)(9)W0#LaKhjWIjGsjX;NJ= z>ZQ|TYc*n>0E*jYMx_U?vkjJk7}9i=Jff@W->HqA;Uj}wY?Cb2w-#cK1sc`4*n~os z6vRf4vSy*oq22HdFgV|MhG3`L;Vx-9H(ex#* zb!UV|os7t9U967Vul4gXq+|4bI zE5E&P>1*d?t7|p(ae){1C$|K?MnKe03&Dn^>*~kyGYfTAWNGtJ#)rL7uq3b%A%So- zQwOpA1x@C`kOWD4KiV@?~?);*Gzdn=F%bioHxu5J1f@C#<2+AZTh%zGF< z7SD2f1O+JxeaIDpO=czE_4Er=<5;;~q;<5EWz}x!4*tYhwnxvIyk#v?`>@l;+`uJE zF3Mk6OEoyDyMr#1J+>_Csgr$GHf||Btq-bWG+s{72Wrv_y+hbThk8WrW(6*WadO|( z@zxxs%`Ghrp?J`b-gqziCOR&N(JDE1e&;+)n0GC%%7p+H5uWsv0kO?V2;-CENtpd=*2 z%^o$01Owm^@h6Cp1(_y9tI~)(F*Vc!9wr0C3Dv1X6d?GVEH#dE+Ow{+Kb;3|2ZtwDYdjlq%}N3^KI`gjpA6Z9Bp=-iWUdk+G1v zJfP3+mg7o?7ajx@^q0yB*O9i2!b~mtbmNDE2UV(9&ij;B+qmCUH@~vhk`lj!%q|YZ zR3SNUZMwOW_icE0y1odm#uWP*xzyjgQcWyxyGQxrv8Uy^R7jJ|(fGyZnhnhH#=d!o zDW8oEE)9_kZ#lnq`o2YJ+Gc9=f9gVkn>VG_ww zN#xTiPdrXiJJRs})t{Lv*Bj$QWp{(5ypYdc!XoXV2DMK5!YR)~1K zm+jizsMmqz6!t=nNx6Ojss@kBFhbuq$xlJ_A~q!*<^c*l3>XdeRO`dMyAJK%*}roI zq$E;?UHIGl23XWxA1e{R1(yxwE7c5XSIsd0EKnDS`8v#d5?l7N*#;&MF zjBp((Aj=u{-xq8v31jR+y0hj-b`Q;Pu+m*wK5suO967 zl_)#PgQWT7bsI@VEl9}IS@tlf)`KoQiU_Mx{RMAMLY26B)+@l(1O8WtLMb(@u zls3IxobM)-?jSTW0RP2D32pJC9O1LVArp^L(Ns&%Z}E>wKoD;V>#BTsJ#!`gXVi0g?6e~ zHh!LSdlEm^Y~k#B>tC9}JqnLIdEqx8Kfa0k73QWca0;C5++Gr@6|qnpy$2sV5$0J@wgAJ_E3w2|BR*i9n4k_jr&+}Igh72A?&*Kvy3j#3 zXivK)u;~YlOs_jjQO*)C#3)mEzlOl=jhHlU9&&Wv`yS(BS z&Te5unTS>0yvhEGY3F~F5tyFgGrwf+u7ItG0CxqciXVD_53Daz*km-s2CMw>*KmG$ zPOC2N5%KmXHQ{lq(iD4^);cFbAZxCmV?)^){quUd151%Pj8t!_suN<200@~A>*{kgh62_hWGhLa;JgD)jXI zLM%FvuI{x*QtY6+@qt=ImOP?Ve&o)~$i-a>T$9+G;^2qjFRCSC4OD{^X;{ctFvM27 zJ<}^IIFIwoCER}g0*cdI>0Rohyvh)-%RsA5-6Vajv@-NZX~C{R&~W- z`*@w~O9|(~rutV~k~bMZABhVuCZPdaD%ZRKD44RAi1WNEpU%q&+=55-fNfIS#6-L< zpZz7Euo}<8X%EHP-TRuGNnU@b(Q-H1_JS$jQ1VyNWxc1)(l#zt2=8!7sy0XW(D=(k zxNET!&Z&;x+LDnoAlq5qG*AH`)$A*nctHv_R?2P=_-Ia=!rL$BHDL?Z^9#1dF%%=Y z!%EaXpkIph+b9()U5jttP%0LrGs()sBK%_jcc)mEeABPq6OKQ!(u3PKMhjNfI1&Fe zMi9*WPvxo!b>pNdttLjMjtJC4UjNNU`HQV;w9@AN( z&Lk~={}Z_+wqxoAQY=V+Q8p4%|M_F5*y85PsQoMk+X#&fdw{qZwix^7X9(2T8P@Xv zk*#TE?jxi)zh^)Bg$^={XB({d5m&e|boA6DG!V<~l5pY+>WjCuY;+_OQ!A_q6`U4; z-XA4glV0hs%=XP)>P%XXAV*6ye08zIT3qvk!oT&c}J+O~4Zd040DM8fDzQs%^EOxc%K{`pB##qeFI0F#G4WgZd;3 z$peLn(eL|)cE(a3wk)e2F!ZoxEEPuM-%1$(ym+aA$7a0fA0;SC4e`W}>!71ph&b1- zv?Zy8_Se02@tJm3;C^SPQ_oKhLXK=*)=PufiM;=eJ73!{1OH-~7-dWd%?))qcWa%V z3(?;v3rLNX{l5WQ`i5Mfk1-x%6F(7_&GPWcxi?*4&F^Ov*3ktZTg%c*7MBzmJD0*Q zMQnlYeyAmT$;Tvl^7jWlVszk*8iKU-HAm#|G<9tsr~{UbnUwvw`kZxU{G>FE@bKQ} ze*lndob!xjTg=S*DnBE^iqTSQVZ%U997XW24cr&X`y&9w?yP zG?S%21gZ8r4N%6i$sWiYAjCn$&ZD3{R$ct4%WlpS9H+V~uK>Cl@7#yEXdyDj6VcRm zXQD5OV#SRZ34||9IW`b)^r&vk8iT&cL=w1|EkDgKPs?Z7_9Ng(tb<8CSe_9L)@75{ zW4iZ9M)>tLD(qcbXE}->PZ|-C2rzt6Ryp;__%Wr!H=|CwqK+Bw*V%e&>Bq5xyxs%s z(7Kjy-;`565bdVM*P`v&Uj5>VI1z1;z*jS3nNYZQWu=c0AuwOTyUhWN(ZxffUP}5N z=-a``#7xrqa7Bzf@qVu9dqXdQ3~HIX zNaDWfc!;GMcKlkZ@mfuOEFav(L>fntT1JBbRTriEm+sHAG@GWU?=&18;aaX#N$;;r zC$d5~uY$P`Fe|mY!sMIR&s!ToT0M$l5L^SAPWIk&yDX!%dca+BDv9eH1OE#~C&q_z z{7f>RhIHBmy#{qD9~w_ZWPMYtjC9U*_fMJ6j3s8q2wh_7iO=Hn1XDeQd+YYfHf{>) z^VR`2h=--4;B8AI7I~plJt`0OL&irY({Y{^`edJ=%T^n3|3)C#aEtlC52Zyf(L!_S z)Y?N*Q20xO#Ln?6n61&l9bDO8&_iYb!xLfv zS{HiER~wM=DNIA12~ghxsE@$zy}Nm142|zQxMu0Mp(ZqLWJp5v~qjTqB$UP$>Y_o{czO@aA~_@ z6cLK;d#m)>#gCodz0bisR6c>m0>$t;A)r~WmsU_ghxA}WeP>_y;t&D;~rsp3STNnDN*>!Tg-t**>vGCM<4$2g8&CU zf-wc9r!36sesK)%BF1C)Pk;?4c^)sXUn*n0A#?sZw&_nCzq|mPuFl`SuFv`LZsgy^ z)$x^=yZyLLnPZC7Z+0$Ia_{+l&PuIT++a2ABYr^o+&QqV*X3QJ>uftW-XX@Wl9s%{4TZ#vC~SG1T!`Hk z3HqH)Ptz%c)rO@S@@r3THCv4Q;e4_=deJA$S z*=Jrm_R88(lCtB~la5KDRmX&2t^Ub(=WH@5Nv`tu^LH2LZ{vE_2lPjNcTVgSBuoM2 zpO1>0fp}BTLNqkj)*s35UWnf-?Xy+*kmsxuLs4`~<~_*_S)ePc|AQgR>H9H4f@F3) z5gw4SJD#j>*G#N+qw7b}YGla2Sr5Hvc56+1~k{ zBPU!I3_K3|A2z<%Y_jo{pQX6#pA`DH0pa%Zj-a26qa=--%5k60Mww5NpPn#kCgZaq zjT~RB!$WT3UV~Rp$ymRZ^LaXc)dYpW8O{A1S@QBhq~H48`F_8-z2)b_B7P*X<)SRM z&ZV5Jne?(erNk`=w;SR22V~pOTs1l=hxw`go0G1`xA)gDv+BbakdpEagssNizuHGQ za%CMPvf7&+YqI7e7bF7Vp4Ww&QvOurctWQF%2&r{8;`IHZ>-P9Htp#-;OA_0vcvh2 z`_8>ryDF{so9(IB$kR^}7G|pM=evlb!IOnjX4LM^g3~F)03iIox0kiO{_F@v>})`= z++=oW!`+S>G?xLrOcCwF7OII3ujOu@!MjN}mKCJHwbrI=eDp80kTtRFpbJ2yC_gh;N*O6dpKAEpyP>W7U0m`oC`ud?l zFdEBAl&A=xc7Y2&IG?93B)W~$cl2*RTc3vordD=_CFlA47C`)pxdz>?a#4c|ffhy+ z7gls`+&?&&@OT3Qzdqe+FkhDknergSC&8&HI*PBs5Pa%}W^|!}TH6dq&Y#J?5b&0m zJ-|+nAIJ~FN7)7SDL3bE2p>o2j%8a=W^_A5pSMmD8n3W;^X2v;Am;wDz1F%dHU|`3 zu=BPfJ3R_B71#WYf3e;j|LiImfjVls=%UFwYh}4ALLViRA*aZP?nq0&Bh~y6jiV8VhZHg+dMoiv?-c#$bNXLZrW4MJ~+ZYZaV@$!T zp}xwxXR)~meBVR&zbRPUHZ@53cW{%FU8!8+gfDc@ZkQ*`HoK0Jfe)6M`Yg&YWkv}P z5J4&vBIuh=J&%MffZyq+#}7B=8`ZpqcPf7wCh26sQV<><{>ttn?*3QpOjz1b*NKZT z4gv(!yg%1uYa=lhULgWX>lihT`g+<)TGjmHAmHfBgpjnhB(zg&(dnB>*Gr1e{|RF# zpK=^CeRj&_9{9&4YaTGmsbV=MIvj_~V^=KHf>pfvzRk@1Xy$Jt71BnP;WH2Qo*p-~ z8N$v#UqbJlG+K`T-TpvpejXf{Iu&xaFL(H-a=Mo3gXD)VRaP8|+h(LdzxDy-3Y+hW9_jM~sl_k{jxosbfGzUjDMchBkX#vC%h zPa~{nrls2~1+=@V685x0vN_D+hqhvu2 z@*q`HV^as%DbA?VCQw`ZQWT<3{=~R8ESpO0RQ=K4J*GrYa>*QfSX3$w8EHa`1~xX6 zjWx&p5vEo5kEbpnJxlr`EQ8DR+FkTt14HQrX}*|O`Zw{o3qE{>V!$ky5~Xo$sNjz3 zh$B}tc4a$QHjD{;#?+R}j3*nAH*!M7)7A5WL6eTF*Eq|IQI@1&Y@+C5Zh*?A&Lg^k z*D^}dg(8^>!eKrAY-wC-t6imZn7_p#DKkd!p5Eg}y>yIh#oc2nyPhi974=C+EY~d? zIH#HM0h3b*GP+_O@L`OZ%Zs_0Fnnmq^D3wK;`y?K3BBXZ7QNhvwWY!lru&=q-^Gy! zIVyEq1Ij!EddBRirCI4^ng0Wd@MqPW^vRjN8_z{7fz@P*kqU7`h=3!m2RL) zMTv~iMe(lmC&U+OL9Jj8Y|5p#FUOMcbVFB;Xf4A7?kF9ZXRjZ(t~uf_1mU)zXFChVB1}A6lm|&zQ?Ug&+Y#roGtZD>YTG#Een{(>Wt1K;@!mdud~98q+QZZ6rxFSb7Yz+pLvAra z&&@iOvol`&#Rpm9=ab(8wXh0z3;z!QpFm*0%Dw>@jLZxUs6a%B1a=YJ7-Ry?eGbF1 z3SBvj$DXpl!^*|9LfL-uy9zfa2PrW%QpZ^7P$oI$;1!bpkio) zDwO}h+g%u0@Z5a)#Lrb4Uxg74P?JNU3@#+X9`H>tB!f0^g9ApxF^pU%5JIagjeZ=N z)xpz?6@)jqg4UH5TOCQ*`PwS-vI_!fErUM`Tps)DKA0EW<8CmMJz#ia&(rJSz zTtVsRUFMkxu;Bn|(cM94gPIgxfiR1>w8$w$Tr^a|6ifz{Bm@NM4-GL_azhim_aJk9unQ&bz}+{RFLk$mG9sT zrvV>E4WADb9~ByzUn!py;({3z34Y)J4_L|$ct9d(g{sh+m~0RMWe9)ZKpf-(+3^3G zW&t2hn4i!LAwfiu$1GbQS&_4$ixwe+YYoY6=?wnW)>cFj3m}s*+650R0UK08-<04_ zoQY5HLIvL2z+oUE^&9-S#b5*+zjTPfVPwj{MTTe&9$3j%@LD1q5&2n#l)PR2>0Jug zKpcS9t^kW#%tlbc$40b7iTywcEWsY2ViJl17hqg7+65E>7KIsKkzts30NQvQ!4jYW zA!Gt5jKU~z(@0 z9HNo2NEyIF6mA4A;K8I|m&nix4(LE41d~B%LnmOt?u^UcDH{(Efd=}+C`$i952OGR z7y=n(q9_o-Lu$wc{!ab9$rZ%Lm2|`(u@Q&-1L?t(>D5n;q#pmU-Y^nMF>d2_p@K5f zpfu$k%Iw}WehH`f!CeYp8fv3pBHv#vA2{mUg%pOR+(jI~0zo)d4WPh<)E}OJPZbFf zJ;o%pESh-T#rc5;KYAv(z#K@0Q3)hhMzWS6$i&52TMO6#Z7mo7Z2?h`3$W$M&!oX6 zD7q9#X*-+rVgv|1UByh}(C7EOhw!jFgBrd27SXj@`_<>|zmNp#1mPE#Qwx<0Z z2ezcZ5i+Gl=pY07WsL%6Ue>6N{-uH)!d=i#H0U3ejKWi{rOrtu5tRSJVFq4RZev6V z9nq!AA@RTt=s-d#6oRyd4=m01ydvt^rW*ptE5Kz0855(0k>*H3w*82GQNklo0wpK{ zoJsk*>_G1>{F0day&L0K#aRR5WMs;Z-(Dr(kxYka9yVl))Dj$98UK zMPx!x#1tEJ#zfeYbi|5wbqIRupFJ`}<~@^pqMt@Y5q)BZ4j}*6mF)^+@TYrOMHm67 zrxvAr9#I!vl^SER+H-Ea^dTBoZCP2~CHE3KND_g@#g23y482 zV(h1|3@K^OAoT0B%w!4V&uSpvg`7}ba2g$SOT%bGF5u}SJc1%9LL(>w&L+YmBtj!3 zg3u;HoC<9tGy)%pfo;-`HVCOUi~<-K>5)R1l2YZ_IB7IlAr?yM%+$HrI*Wm@jW zrK}-T?k1SVQ(wp-WR)q7bfSCRUnTVGw~&DpNWm4{Ef!n>7EHkvOu^pr?cMS%7ThhM zz7G4@1dkAcFz8A;d<)@8jtyW-qplTs-XEoEgeGzUmx2Ev+*Zy+w15X(0^MH16qJsr zY6G4rVH4m0NKlTdx|eTVNYgyRs~W^D$||DlBB0&sFRGrd8bkmEr|kV|u%gVcGNaBR z=f-#nvM%SQbz1OwLomcaeL(9WN^7d6femmUS!8PrSn29SLo$#;8i)&}yb)L|m3y^7 z4R~KnW|q4C4ojV17N(yR@W5RDgASlpy{ZK=2tqIUmd^cWfVu><@gHv4h?jUq6Yv2p z$Ob_ogf}1qE_8w-3<4g=O(vjLwv6l)(>J z&xIjrd0B0RwH;Qv>mmIBhPW?VWgg{FPUTvaTQUyY#wAX??dM7d5zOtoX2KDeM+w~V z9Uskk;IVp?z#gl|;iiqgqG=qwf=@8tiN%1IAqvGxlUnuGW3oVGUWqrPf*D|DrY?^! zb?Uq3jxR}pAp9^K;=&jZ0Z2?1)jfoP;S#K7LJ8o&r{Pyvg8G1gY$sR?Q2nZW>O>!pNS3vht}cETY{L8|U> zr38_cGDrlaKxG-*uE;NYvg-*fp3>DEykh^#F+Jw{{jWx})&T#|z8)|U{_DPoaB=L< zJbJ@g&_+6N11~%R8c=};D8X_0z#!Oj#PUH22pr{vYh9GENU{Zn`ioR>$O?a~PsE6; zw7?6KY>8gUH%J0Qkc0~4u*MPab-=8Q`h+%=f)k9bFNLku>_!SCl`oZ!kOcG6Lh(B@ z&MQ!}Fdq}uLM$9MsoO#6+I>zOKnA;NTbe%78L1&T!FA##jgayB3mm_lr8|P689Kv(51uUe&DSrv0$-r?ehK}lP@3d#-LR& zpRqG;N--xZC@pI;Un6}yt5tGwG;goBWowOqn+-HU7I1-rAPyWiffP)E)`e9$S5|ta z^F7k9U^p5h?uvZoFQ!zs6{Xg48DuY2+CKMd7AY_b*mYPPA%p}amb^l%9KjFxzz*!d zv!vq$R^SH$%#G-V30q$re6zt^3&FAQCVglgowT2rEKFqr#kn+0lb=kJ1m$pA9Mp6( z;ldUSbqtV_cItpbtVWqW1ctOK6iah1q(PoEDpN0$7VmZyvWOH^Q+RYO22z!Sp->w8 z12@Rw5_z=`%^4g&LNEbh*_8iv={SV2)nK(%EL&4HL~b|{q@&Vx#1`z%zF_l0b`h-lGJo&iE{f)nf&0ToDdK4+UfmI&F8 zELNe$)x>Kwf;V0`itCm=u^0O}Hx9(HFo>b~Qd_pXZ*;50H&{YTE9;w>0l}wV>vohN zb%_5im#%Z)^4$Ml{@E6870{ckj`kEK|82%s95@_vGL}gT1*U9Ls76&RO@B)gNe=cs zb%@8>`F9yOoN11yEthTVfh*e2e%Sl(z~Y$kLSmfE;|_wPSkk+92dj5h86rj+SpXYk!i(Fj(bDa8B-g7^_(?G3yjod-G*+|~+TFChKB1MW97caVSk;26bfh}-s=_D)}C^i*K z#KE<2Aum5VBF2#UkLE;-7+VlwlM5Y7a;n&zPywSw7FOI?`qOr(NeLMkWzPI3k*3TK zX+)vxsWAT?E;=V-Otdjk#tAYAeZGoQqD4)&6J@ekf(O}Ff9sAJY7((#RFD5+v^Zf# z)ik6=TH7wXXJEZLw?}lGUEgy zB9j8|s*RUD6oa9r8mM~VgcCZ6W}oWFfh7(ZQaE8CiDXdWpB5rZs5*3TaRLYD#EtyA169@+x&SUJY7izM>3|ElS&mY?E`o070`nUHQ^SsfykWV2*$AL z(&5GsDPp=ZsuPG1MH?kSdnFAX02_|AIadqphbDOP370s6%Sa=QETWIj%uc`}5pI;^ zrn1YT3Qo`>Yrw%fQ0`hszhfl9p)}2)GA^vAd`oZ8QAu6xsjy_)O^QU032&ivlDTAy z6mV#)qmKM^Y^t`{z~!57M5L$$GddxM&0{hlLcyu1+Ah==a=IfJHo2*U3!zj<0gFtc zN$Q(Sz%X&B7h=E=MdARA;e zGG?q{V2pm#NH~Fr6s|csaG`A-Sb{>2Bk9;&Xr1e_lPJhPU0@-NTog`!PM(DG62@pnt07~;2+ z4_p8?9#WWr2$z{kmENZjQ3Z$ybePukMx?GLBtjdg(}pXsprB?+1U=(w!32-dv1HI; z2^CR63zo14VdN-8acF@>euJg+Y;YhuFhnpSq>yMlVhJqRj&RI^mW7Z*E%=(BTlnR# zW7s7fdD+X@$YwCXBrJ#MK#X=6^PCqzMlu~^#S#FsugusW1snU!LcW0vHv9kuVhNI& zY*I46JSzn&b5(7)fr~N(NP#p=2QQG)0XaYHu3Oh3v9dD555yM>gdN6anQkn0F)vJ zLC9z=*~8xgM>gWTfN&l9P;Fr3!sgtJS^r>x<94SI7){P1FVIp>I^>>oH9a8zYLHVfsA+D~+XF~$1}X%GP9RH2M1lXlv8MpB;0F#whmt~* zh9%tdToQqi#`0qB8&M{ z5EZr#BF5nZtkYLj27*F7Eb jA{jB21YGCJm|hMoRr*#l!$Ei_d{fC%pBFCHz2` zs<~PjIkpgwjm9+c1Z4l1S*rP24F+}8sMi#78?RQgkFLWN=tQ*yP#ErKY+ykO+#(?9 zi06?>!`VwOQpu>XggoZC$R@M4p7uCW7=wUFE^9>-```z4%*{kA|6v-p?IcI3^9L;M z0Ft(~RR+84C1iQQ2d7{Rb~Y)d;cC-Dn4Bmq>0v>O#54a*nO&rIE%*R?a%kT1h(ZcH z0O&u$X%iciGpF`hLKBFPf*+6}b8|zVKZtmT-3XPnoFu2>h(Lte5pxNbz;AVuVTmS0 zDW@b>7ZD8lVbB0=p+~f7UnC-hh%$+yD8mS@YMRlFDuf%S0Aq$a5>nI<;YNnhPdcJO ziB{$mOELA!SYRiE?EcuMsgg?~grTEKOf|5ea~OKY(oivTp%iO^pyzbJg0mpyRnbU< z6nOI&h*@~A`pA(9Gx)G3 zRGC*NqPACj^=~zTB`jB*I3JqO7p8&nPGPEe#b^Je=O!tT7-l#jXw>)v z_wl+>{9<17tO+=6$p)o(#LZX#_}rTegh<69f*Eq*qJ9RANFQNjF2s`#q@CbLHLwAa ziTRy7O05%4s6j`tMmxYrm$=9X8((s%U7h4-mHqJ{?Z%rY)ai#8g8=B5ne_t#v6JC^ z086O>q>&b|Ae%4R6HNHhn17rAz#f-T!!l9=Hl$+S34V_s0L=m&@W5PRQT7Q~umdj8 zfe%yI%?>gVLZiV|DX1WW4oXnhIMYtw6~_4z*uaJ?l#K||>h9e3HqzmGbu#z;YUZTmkW(?mg6oVif-iuU!Z?Iyx0+`S>km*}`sl$B&2o02K#6Fn zYB0!__FfEnA`to`D%lG9a6zH7pX)6-5kxS2_IY98!K3`h5C%W*#UhMD=7!6W)~(%W0AgC81mw--6atg%jcoF5OAc(hs>9z%1Kuuz zf$*c{7D8><4R&A&JlrEz-szh>r#b&x01LLNI{M}VA|jV0=>>MU3V%~_39HM~~ z;(!QFpaf80U}A7ZHm(FN#}7au7+~QLY~X}yKnhfW&sM1vxL^nHWe1#)aCCwfqDiH$ zkmh6uXPU26oR1(lEuw}B^wdd7&_NqaA__|b zL-^+u0c6-Tg$NqYp#Y=>cwpryFBk5B2zCH=?$5~Zuc2~+4v@hxk_n)8LkFBd6kZI= z{_F%cA}pZG^=KsyULi+<;S&FvKuRcry>>tfTx@UBr#xmP6*B_|eqanpVNLc1lgMD9 z1g$0{g-@CXMBDB&2; z2Ck^X3s)f#*Z{-0E-{sD3BZ621fdgh;iQD&638e8WIzWJp^yR$lkPwY62u1%lL)rp z59(|xL5vsZfHYR}xaMvnM}=Pi0~VKn5$z=oKxUxwPqorRB2HjcmP{$UM}r^+wZsP& zrN9`a&r*;f6VTuXnovR3uPT}Y2Z%rn1fdo2=VrQN3yKhR&;c0?!3mB4BvLRiPzF#s zLVsF73J&2VA?Wg&<^=Yj?TiK%=wLU3<0-D@&01gzwsCK~K@^w+R8l}LTc9Ri0i`li zt}Nq6Hpp{k1PlKRp;h!Fk47T~X$l9B&K(ytD2~W9^iLp^2w?JY9~T35G!YHiP7kD0Fla6Q+%KRYhxXpBsrFL7WjRDenVg9Sd|5MYy?FmNR~BFc1z$_Q?5bf`Sojrk;Q(wKxvq5&5001c#I z38a7w;((A?hMg2b7%0Io<5bxUFAB3M9f~HIeBj{@sN7DV49v#|oq!LcY=2hJ5R#!M z(&6erEE@lC;S%s5>Z~;m3_%ol0Z{;zrEDP2c7P2;LEJDirMy8HNZ}CZAnMYV;40>=u<3Q_zN=_myTJG^Kjv)|ws0MyOGhoLCzG?x{;1uR99YDbhU{Jiu zbSg|zQq!OmxG}PDfeQo!O8r9bG;9yf$Y?NWG)mwDmT(NSF%7_gauXi_Q~KmiMk2vtr%5T*-wpH(5g z;TTxq5&WPMUO^b*&l@xcvRuXx*dPw#U=Q}-c2^Q#oFHxjuVdc!S6QG39(N*Az`+0Z z^)ID~7tp{5*rE_+LI<|MJJ(@=|CAiOAsU2%7j!rnjv@Z4jT^4;G*IY9P>NS)2{Xxo z8uy2w$9V!XQSDgegEu;A10%8&ZJ?d>{mW;N8k)Ao>m$o6reN z=TEue6$qgW3fU|-M1FZ-3+Uhywv`-eiUvSAltp=zLpd{a=00E{D^)5M;s9uu;FV#S z2$n#WX?d1y`IeV}J(wh!>?TxpgA61gamgVWMu81_XhRSQkz`;B{)f-jK^y;QamKjp zCVnF$ui%Ef!BWy8iD6+6rfNer4(ECxgX*oZb6KHm)r~Svqm<2lgNrE*HI^ke+WwFf#H7rr%hX}^N5HhD+BP5M3Ar6)R%mQN$ z*&q=-FNYvF7bt;%9&uoDiU`mk5qt%IspA_`lMSRGar%W=vN=K)ZkzwLAsLb(8X%J# zkO3EZHl_568<-f1g&{t^RFfa1+Sn-?N?{MM;0HV>yxMCD;-C|dfs4l@76O3`1W;NBdDj|JldW^P{{dmrBRSbG5H=y@Ux$oQCrPtzb1UUF`f*x(O30XFqRS`#4- z3KLgr;7eJx4Cvs?4>m9}VGn?u75^atX+SYYlMqy4((VEoN`VmApfHI5Lu??;-<830 zfm`89cst<{_@L1@tH#JiOK?C60FRx%AsK=p7ii%X1iObZsf4^6a#@39e*g*S;1D_i z7os>M(`}pO54Q;$GZ(Ifl5Rcspb@lH8&KFbf&mpclYRei014ROA3y=gKa8-O1Q}l8 z5_&Gh#9$9DK^2058~ze)1{@R)Aq{#&3gRFUKw(>X)l+8)u2rEDBwN{fv8{EiQf4?Q zyf70KK@=#CcV-wJ)`=V{!Bq|6)|>U+t79KJdN8?wvt(fBG65Ej;jaHQvY@#We%vr0 zbZ4us6z=yfPTM__m=`+XH@l7|C&*w!5_qkh8>>AOc>xsepb5f>1~MWi(f}1``hDF4 z#DXCcG<)cbxLoyj2|^~&OPO3I9HiQ739=v!_<-F3QQxg27dk-^{D9MeaKmFg{c1ol zU6l|(;r~P^7C^euSJm*yWs$?IJ9I)664#EsVTu2BIPXb<8@@z%Gh>vQKEnl{lqW*F z17iv3pzar9AH1Qtf93HZKk_C28@yp3<}H~r1a>mA#U>B3LZcKU!4O3M5GuY?e;XF~ z;0Nd#c;wMXcLNI!A>5vpfRDiyEa4FRU=R!;6KEkCiWr*ztgL|Tgy{5`*e$2lrFo*yQ1fju^0psV!8;;=>GJy`JU`1&C5>6o) z9$eRZDjI^p{OOh>U(qQN?B8?X^VzgMo z23N9g1Uq{C2r{Hdkn2j~Vsk=;m`1#!ksJRB5?!=TX;`pe(`n;Ce;Lkl3l6_&6!Ky#*$4Jl3X-P ze_(B_>d{-!B`s?3$;C}zPm&$ieG}HH%#Ru|V*L2AgGd}vF467u2e;?t!g6s5;!=b0 zzlsZWoLI64RJ7cRQjkV2=@D5F$Eru(K%*sDyRiJ8%?0#f@t!|z+i(i)WHA34`_4}7F-081rs^nM1zYW^ZnBhh}w-vqC_&h z;E)WywU9+6<>3WmQn|$O;bRYYG5){XW; z4Nk;S$}vdsB%3zLM57IKRvpvH9Yo+D1AL9e;6iUi>>&(sBN@cU5-ikE0vezUS(RLZ z*x=glEjxWsV+40PmjC5-R|W5@?591_f`K9Q5j6k^coD@-$fK*S}gw#pMI zX`E166N&JG)LSK`vy(wb>OlX*9mK+hp-0>VLsuuY#z+n*VwA8%CwQWp3>}M=i31Nh z?BK%|mGDyDwdr8%re2SjK}2K!ykOlzGAza|8js|nO|jt;^vyA;1VRQ8JLo`z4INM9 zn+!Yvmq{`LRi&38P5AH#GHz=4qcFUXQb`;()L>s@qfXRa3MkwJ%ezU9wUo*zFj(V! z^~Hb#5jn9c8!2g^aDsgwURNfAI6$_=Ahd9!X>4wBiq$1-IPu}mYLAGbL)cA<#UZ>L zbBr)`(``51dhfk=-hAJU3^KwXb2nma%y*)7E$Gk$8;PV6%v4vFCEGE%bh1arI-Gf? ze2v-1Tbea2k%l3n1e5=aHzyls+=je>GDsRr;1FNVjlqxt5p-yj4B>(YKKS0r2m=cp zNVJf`31eg;Ofq=a{rlj-AHxeBM5Hh&5`6G7yz_PkFFoDElVbA;Vvy3j_jf<(18?mbPUy9 zCN}AzMJDjD1&9B&?}81?AOtnoh%5-P5*pMX;DC2Q4Pr1DxnKhkUho4L{DXcr`N07GnJ_Z|KQdZ?obI>L{5w!F^)DYCyGO)0f0Ja z0S+7j0~qjTA)z5c8V*5m0bYg8)k*rx?7Ae~KJkqchvbgDjGk04~X16O+Pa|g4*7zA7 zWPu2>Ou-c55LQJrBBhjgL|r`^)-2e7Au_O~MLP=8lZq9iBIQFCV9)|2&;hN46{%nu zdkN#EfJ{lvWD9nHkwb_A7gE(=PhrssL!4~~b1D@LsJXU<5TT+U#j9CM`iQZTRHd+O zEnz{LQn6|jwz*XV9i;FN6=Y$taTRMv<;vKNHewHAup}7x@L1Wx7Pe^Z!V+|6(br0M zx+VY3s3ho+g%jAIq9?8GBUGwVv=-=i3bUjX0IG_dPBodGAOsua)B@|&Kr)$l1ur_= zQ(TPV5p>`J5h|4i+Mcze+yyLQ?<-!%VU(`3t!r&FnutTFl?XDhL3|!`ugH*L58~mh zRH>Q^Sb!oCalpb4a)Y!oEod~PX@MbY+6kz3mZ!l8@F*&ARVk3xl?;Ia4UF726qRXC zOMvSrqT1sgS2YvNB?6^>zz0#L7!;K-L?Gf|h9)fG2e>&wX$QEo`g8{cO`wB=HwxG| zH#Vh*5CezhXU=op^B+H`>1$_eSB>Vjv5la^f$Edzgi+)lJ-`JO-T)v7M_saXwcRKL0eu7=i8DN?GKLZ}2R zuw@+Rzz06;fe&o|K zZmX4bK?+{&fmNq_g|w!%sb3(=-pGIjtai1jU)^e6L!=@tz<0axoo-X7AO)s6LAzyr z?}Mkh)B~5)f*OPa)9j#ebjUUz@IVJNI00XrW{jvGs?Ub>Tiy3gwFgRl@^lA0*7!!a zt53daGq>OcDo_Cj+&ybq<6PFz68Q-XzG{238s@qx!Ob~9wH2ybG;>jWP#BpZIchsfi>*cy+!O|)7gq#evY^keF2 ztc~qGWLxyc-hydPpac4mDLY9%ZFekk0)NJV?c6rDoz1K;8)V_vY*;0!e}4HGgeEkc zTU+S5gZ5b~J?9B$^$D_;XzQR82X{yH%9mdCn4yNHTtPq6gguzFXMKT! zT_jVNH7Qv|S~|d2%w`eN<{K6PgDl_!KVxnKw;d`la2=R}o1+8rXGxsq0w^$W3$axU zF&d%4R5dU%9!O^VCj)6R5uip*K4?iP03l36KPQNWX?TJeNIyQPdN|O5R>&YUH*mOv zO&y3lIFJICWJwmWHLKSUDzb-{HFtBzX=#W&b;uog$OCid12!RUZOAnDl6p9RNk(`k zi=%&Vm{pg>hx%s`1b0vRG)SD5fsa81kAZ(tmsBdSRDH1+p;7;b|G*WY;UE#$c`=BA zJivl{XjCise~Ys*_(EEb$Z1amhZFb@f@B>IA~O4zfzg=6#K!5R0~Ts)vH4l~t`|e|N|NDUc>4=zZ~F1N1X8 z)~EwLU@wm`GWKFGsRti6;9)i5elf`)<%lz!WKH_yjC1I0CxU3Bkxz-HPaakS5yywf za{>d0J@BRivZRcO);ZSn4~)@-^<-u!0EHZxNiSfDXTtv*b66iPxghqT5Smvzo7Wrg z=95m+5b(AgZL=^(wloX@mDWU)qT(@Y`2sd@lY6-^i{Xwnz#wTtmI-5aqcMa(^K)0Z zb-O`=@7I16(Uy7HlJoeHAL3!L#EkL5jF$;-vgBc;(TbQEORm@uHV{apa*o5Ner4ie zA$gNvc~3XPXAja18`^)?P+)RXLx%S zeWfA;Fz}Mf8GxR*ksFC3T?r8qfo5&FAcJ@Umh}I8WT~4+IFki7Z+a=8i6%%Pxlf(vc}yj3$(c2*36?M!lb}Ws z4Pkf`if9{}lRSBoKG|%!S((=4VGHpXCnAa|P&?gMnMwnd3d5CNIin52Ig&z~z1fn3 zBx7iz5K1FRq85zNHhHI}`10F`1O-f_AS)TLJn!FK9dC5sib1?SVoq72&DdMLN0U{OAVUen5 zdD)tUDx^t+oAQC3M9QO|iFka;8)?cUQb_-&iF!^4^K5bos*{SD@CKSP#(+@LlS0~> z+-Z~BhXck*HHhP+qgbdO_NyJLFq-$T4U(t=n`bp@ zqYS|Vq;Y&6nKX-9tg;HC-nW;^ig-Tj zai|#^eZ1j{Mrecx1FKAHrY0Jvtf&8uRN9mUNS|i%qh5Pd5&N4)dutCDm9rYN7aCLa zfp}#CkgwU9qbX6&sCqN&u(Nunho?^m2%0XHnPTfwhZnO;vLt`|wN9Is;HgxbhkTa$ zg`-lI3<6V}gsl$?14c-2S*slr>V7vFrZHtyABL5n)313Jv&}}OH0GluSb?WouT43p z5Bre@3sDOyKkcfx7(1jb8q{$IoPyLYcO!DFiWWdJn5T->x}bpxLmrZS_hC3 zc~5G&5H8Cbq%w!s@qUAwGdLNuBWkO^*|Ud-H1mpR_KJLh2@y8nx@XdU(W^5|YqiB& znK3G`&dI;;8Xwu=rXAy!4w3(k={U9_c(_PYfe(4WYpb`y8>t8=e4X>K9-60kdVG7C ztFD+ZTC;TyLY{eBo-Z4?2OPT-h%j@=v)j06;>){0nU)P=t2ene=1HGPD`TY^nVuU_ zJj||gI**0>wv|1v3Yr8vx!`M-qPpr7( z`XuHw!w6h}a)~0+cf}t$iupQ<&daf^3%##pPL;H6(UaCu48P%5fQ@O3K2A{sd1b$2spcl>cF3>yJwOn zx0Xrv+Oc3e!|j^DoXY>iUVO>)3d)TvykUG!G7OxvB*{*^%04W)vns&>E2((t%LKf= zk8FHET(}2(y-C%zN%O~f`ys9GR2rn_ zjKx8m&R_hSk}A4>OB&7Cz!ZGMoRg?WTOu_}B9Q#O^83x${Gs&Gy#e~qjhw~vxX0?O z&XznXbQvO%Om5Ho#i1O>_B^`xY|nxVz7)93%goUJ3ecMRpXqtcA?<1H_i!g2eGmmA z{`_emebEw_#uH7^9}>7It<&t+&Fk#VptjRN?bAao)V0&jMP0B74b(`@&+f<5nyS)B zUAs_SA`o37QvLtGLLIZejMd(^(3SbiU%k$jywgry)-G+owo8G3JJw>IXq(*CL9I3^ z9nmq_q+jjUAuZANThx2)wGzG8a1E0`jlbrk)Jx6RDBaYb_R>$S(1^{=ehtot8rTjM z*>zpj5emudC)9pT*5yysVyR;9neYLw31EOJ&n?g&DRF&(fB;t zFAdw5{n@K+&Vc>dy=~bvD%y^%*4zx!k1f`Z{o9hu+*D26z)jW>&Dst<)R9cp+Tq*L ztTszy4~0f*~1Ojs-4}?-Pnb_*=U{Is-4xfyV~pB&FSr}-;3GW-Ouy= z#SV?y{>}g0lI^X!4cIMR-wGYy@m<`r4d02)*pyAz48F&vE!e1y-^J_MjcwrC?aknA z+^rqr4;9{?*4ECw;I5s}C+^b9?c)8M#gl#5GrrqX?bN^>+oJ8^VNKi7P2pw@;&ct* zK%LqL{>?P*;Wkd*ydBkP&Eb*#X44>mM-PDUhMhZ+(2&G z$m<(V$ZqL~KIhYJ?aSTix((=uecAr(Eq7T@jmJ_9^`i|?eAXdqCVlPUg-SZ;)_#W}}&hVSw=F86P^uF(e{qgP2>Yh&U)_&;~zwMyz?BE{m zCV$_0-rF8;@ovuV-9F%Y{`1Ce^8+99{Jr19?zH5c;rTuEInVARkMa24^kd%eDL?<$ zGw<-8&p8^hAL?5_^afw_s&4iDt+;Uh^Z`xw$({CSz42r}@o}H=)IRqt zFV{Cu_kG{x84Kz=|LvO$@ODq@g0JIHzxHNL_zNHNv~Ki}-`;-j@qOO)luzh;ul1Pk z>E^BT|NZPyU-?JR`2`>J{B8JUp7fY5`ZM45ouAf_Kkf#9=%sJlSzq(EKk`+-_i+t8AN#8g@^r5IbB^_zfBnbZ?`kgmJRkP( zz2T2e<(q%|@1E+oPTFVx@6?vHlP06Pxmy>^79W6Gz9++Bv{bk zzkdc5CQL}9p~8X)B~GMR5g|m310@Qin9<`#jSoLw^cYek!IK#$mNZ$BF+oJ4mg%?&FTa{-8@~!Ng3gkhQlgyl}&oSe$Xc6=|$-su6K~ zDn%iS6wt@mY?Ki*xfEP0K_kbDuEiTcgtEQ*NCZvC=GfazKH`QN@H`%SYw;{42^8+6 zGQ~8G%QL0S3eG6$3^7VPPx~^>2(>$Krato=5U@QBbLmec`D@J1ER)ocu_beibkH_W z<1EHCljTVRlJzwj5`0P0BtqKKpmrtJuo{3 z^D7Fmaud@YR~41Cz)E#h&s>{>^-EIely){$fyA=7RYO(tzh`5$3^iKyTDCXBy1lPT z-EM6SJV!N^R9R!k-PF&oqLq$3@o4oDM|Z)SHaoPcmF!x3mDHBl&&-7kLMqWEb>Ak3 zg|AuM>XSD`L?1;;Q(>_~*wT0@HuJN6GX?FeaQmI}-eYH^PGHeg&DPr;Tka24k>9ln zL{2Bs?MARf(>)ZLZ(&`Rv~%bC1|4q^h3sK%8P}Bx)TuqO z&OCzh+u;P~nAlARSC9kX?r=w&{;}yQ&kNm@`bE6k0O>;avS6dwN3RGz%w!+jSg_Dm zz7C$xSoSKN*bJzpg3%COFEdgFccq|^P%34`qnOvY7&H=V>Zx))}u^O8O9qoc0SOlcMel^|6F7mzx9`x zohW>n98xw>q)T`zQE>}n(h0YT(KIQLeOv^WGh@ghgnqgECWn{5&a#mbbuia!X$$d+Jl|_M1GN6jI;} z*3ll?%$92MWkHRa8aXP~u!dEO!tbASm%&=mFD_?tLCHx_dvh3_(W4rfL z(<-*4L)<4Ln_ARUvMsfOB^?84r=S0w&Q`a(<*h7xYtr1dvx)IUU-0HMvC3Ijz3Uy^XvK@&;7+ly z$&BvS5_-(Cn)iy5#4mgCvO(wiSHQO&utLH5)dQ#MwF&HKh};W7%Jx@L1tu*}AxdEk z3;4mt?P=K%ywtKT*mxWstZhX`K<94Qu|}0IR#co}7%z5By$o>gG*{2`{`Z-H%vs%z zYA$NVRkly$VMf7wy7lB`XXMRlj2Yy_@w!gL+&LeOFU;ib#@CcRe$&b{Gvyikwph@$ znv%WiYrg)lK@=pINi1nT8?o!9J3-frm^lg(acdVNPKk?5MzUX#|s4RWv zG+o2dE7w{mOmz(lx>Z8)Z9sMD>-y%!>J1oNK^0SEdUdZZCx+*5$mBtk(g1;jqt*+u0DsXRPKmdJy`>dlPis z*;SzX=1b2kDJ73_%yxj{;~iqvK>b-lBwE9^cyLmj>xa$ zQQLyJRiyd|o?Xcme1!jTonJGlIqhP{Jlx}cQno@K?m&m~m4?nG&S$3Rdq&bU`7yYV zRet5x5*f@k_OPyMb!@KO&~uloay1i$ubO{*>e0@#isScKM~R53Jtw!v|NZVmUzyp> z1`f+bZeH1t-Q7RelT_^tQ&>-IWJ#Z1vN<}#Ro}19oK^SMM=p2fgo)fWe7gwgz9S^& zJkOIv{6e*C6ti_89vKoF$BEek;s zEI|`IK@?0u6>L1^TR|6mK^Tld8Js}@96=hqK^)9M9o#`4%r(mEK_Co5Asj*?EI}JA zLL^K=C0s%#M86|!LMV(vDV#zotU@ciLM+TeE!;vb>_RX6LNE+NF&slOEJHIqLo`f7 zHC#hBY(qDELpY2>Ih;c}tV27zLp;nwJ={Y+>_b2NLqH5fK^#OvEJQ;*L_|zPMO;Ki zY(z(VL`eUPL`j@PN~}anyhKdQL`~d8PV7Wa{6tU;MNu3@QY=MNJVjJYMO9oyR%}IA zd_`D{MOmChTC7D|yhU8hMP1xQUhG9*{6%04MqwOAVk|}!oqIe}|KrE)hGEQY?ss!* zm}|>*7>2pcJ(urXqsWM&6uV)rbIGNUxr9=UR8uPVh{`QVrMVT+=R>y--Te0ZcYmI3 zkH2}D00oLb3NPXdalnkYtr@nTh|NQu6!eBju@VzjHjaT zG#fmffMpnAc}* z$Y(Ia7t7$6+I{2c`UiWIO&jk!Z{6qGy_CkNM){zl;5}(!uPsniqnmixPVBiGU zS67dQgF}Khz;^xA-nWz2*Cw;uDZO(Z%3L3%ehPDeaEIUyO`85T%zTC-C<_yn^#};; zB%+;PVSXy3J|j({=p<2;-w`^}riC85UaQPkyhyp%;_8k_XA#-=Ya|R=>us?ZI!&KA)PnihXZn0iOS! zLbV6-jel|J6nSBy>IenNqQ-;+tsx*QJl%s!cY)K*FV8AZB7%XI{2xB|nG*@5+5c2DU_xwtvPF5KWqA5}C%^~;_Q`p+KY4~b-`!VB>-A&NI87 zU-g!nY!6vd}X#}4|4>(PY_4LmTSHpF_9DXqXP67n3pr$6l&!KH^NN4xvH?`$08|@87AN0D z6ob^_!p!37JGjsd+>Ba0K>whTc0C}ZpPM&0}FHpnWCC z2h#csY$ER=@JF;)n~+l+`RZjf?>kW;74s1Wpo(E`-z22D%=Xcr_5Ok1NEaRcbvdWA;pZ1FY%JXIeAs*-rdH`t_ zwUkTvG4=5a=N|OZ_4A7?_BY;>>A(O zZ$k%hz_^BGCv~dZk6A<#0KuZ-I8=b^{GbbxGQlF|k+ zNHtmp{h{nb_}%Y*bnccP9J1Ch7xyRcL*SxqJk|8!=H`Vb*TKP=7wKttf_P~!yWwvX zYp92>Mxr(VUtRJQYo-;FDEd6mR(kTfPSXBKpp#G1@7y4Z_2g`qd{}XS5}Kx_7QGlp z0Ux8ix0ncd^f^GDf#U+nxdf4e6QX%1d2h)XYcn!6lTVdr3_q;=wOP6Nh>rgZ__{sY zI~VE_mn@T%^sFIzFp=uSOL4dh@Q#=zj75#KJe3&>=to4GWKbTq#7V}1iVj?a&8|eQ z&97HKO8sTS5KRVbe)y7>_C-D5t(@9ax3K@?Ka{z5OCInwRgU}Zo+-KWU%Yr;g&*dx zPrCE{Hg4QSFE~hZgYxP_L|70&^?Q(c`ak+LYtkFByuh@9m^2|Z@6+dZWm^;buYS|# zq!B*u93%#QMa-DIfZm?-F!DJrbCK$2|NS6qdSo4tk(B<*@b&czzSsX!%=t}J+bDLn1Eug0yDO;l<$v@`k=w%YYXN9i#P$0#(`{vJ1oj# zJ!1a(`smALt{vIVHmW0chpslsxRsb^yqHv)ampq{sl$E8i>CINZqB1fWz0PM=J9wf zN&6*Wu`k+EmiBNhaM_FIf%RHyC4c=u#gQ^^+EQrq>j*B@mbC9Qbt3%vaFj{nmUS;>J$P;Yp8UKd*j#Aqy$VeojqSWl;IA_yj-`LLd_XkkJ^>h(|rd^1n0! zEHLCbab8XSrCjt(^x?kWcu7&g`t^@`59k0@1d`D{Clrj*6JJppBwo0aK#$J&vh%{| z-o(ziry|v-^#Zca$Pk$|)8AW?l3W&ju}e7ah3yv?oH2CUsS`2>T)*MF-(4DMGch2$ zsR$w-Z0SRpe@{{A2U;7&I^@%)Tf95|39t*Mx-G3c+MUk9mT8VY&eqT80MbSLn{h)f?0(Z-19HRzGRPCu^`l;IE^hQ$Iar1T8&$E_4lyfaIwFYMXc|TNYoNf2# z=Z}BiXHWZPJN)hFI6Xb40g?)Cq=059!xHV1c_2x@76(@fb!r+SW%;|}mFVw>Sh%D| zjbxrWjv2QP!Dd{Sh6bR2^EINyR9<}+Q-!K?S>{0L>P&}kiqfD zK_Lf;doh)Mnq9bPBY~qsG(Y!UP^rSojzn$NfmB;uMX94=M@t3qXh*9#EZF_cAek z^3&rtt4-f@-hSbzbfc#l@WxTZqD4Tj(KPW4>YmDJy?U;a)V(cxlRkqPT-$O^m3RhH zai&6L#Vw3$(MOuUe+yB#nDEBX`bIxUI*cj?np2__0Fk0bKHd?S~QH()N&C&V=!h^6g2p+b!r$>E-LjktzcML(i;lB_ux_ zX48!xs9qU1?38(sbF#1aYG?P9xnKC5mq7>7hBvsO57usV8OR>4=bjX0`s_(z*Z4za*%SJiEuENk?#(-G8dwo5?d<;;xoDsrIf_ z_(k-tS4TJWez<&UsrTa*n(Fn{CYv_di{~y>x%;){yFh?c1{v4?f>pZFum{ zgRe^u{(THm>)RQU{$Jnj6Rj(KUnb1n+jyH7fggUI_50sLuc=w}KlZOry?^-MJWcJ< zo^Iy<9__zNzV*=cb?N&@zb3AzJ>FNjc<|`Yf4`nT`u!{WirvpW5IU!)LiIp|YkN>% zYW_u<&!TN~0~N{HB4Lf7L-7vr4n9=j;iUsy^MEMz08RgQxxszm-hkMr(wq&CWq_#T zpxo6Lj6bKwMfPGdY^u7df0H>%XP=k38RH^<}He?Y**{oLt(_7iZ3$y9+!_zqngqv=M(ik zYyTsv{^L`M`O{8V4xYX8>2~wEmJPQpUC$(-MF$wN;hGxai@HGUAfDG#lZ=0nbXL0L zopO}-ZOqGCKTg(%S!lYYJ$=z|a{Af~_)uv2VLw(&B_ks1n&^w46F0t?-bi}4wS7E< zm?CbfeaP^W8FXy4e3Vm|72dfevpHw{oOSuah_)6y+B9S|>h5X&Q?|9)R>)S8rCI$S zR6_Wt*@>dNJ=Y$FVFd&<_Q4QAfdc`QgMfg5Cg`t#fbfC90aO`}&UHZGjMlAm2*I4( zF}j8*qO1v5D6JJokN0gFj^={v`yDtf;}v>-*TTlTTPLc~(bp2Esj!Y1*r`vQ^1IR9 zr24x(`3^fH_B4|i9!tYXXHw1dD86G@w8^PB@b=lc#jl$4H)WM5kq$E*uPclrxa2Y_ zzK+n_l&SUc#ryl|>0f{H50GGGh=lMKmAW6D%R~9nhax8Br7IXU$G* z(VboWZkx``x9@6+$JUFVIXaSI5^NOKWF*;Sw(eReLyMln|LpBbev;q~*I0)oe^@rl%DcN+KG!@^vEA{N~yY>IVBet@Jo|*LZr;e*e!F`=XnoSs*xwEj`LGmIm zT`uE|g~C#Wmy3d`)yBeq;YL||u4`3c1_&pS5M@)5*u}(qF>#v<@?xm^sV=%G4oa^i zn(%f&k{KfAEm7`~2 zZnia^P4I`Q)%DY)Q(B~8%(~3eRk=#@2mK(qyqs?M;kbyqVOHK=`<|_}H&$WBwVW;- z%y3RUCZ26%Deu^-9a4RGAUKtYtnyF&e0Tozi5qt>lHNd#f2LJ?nO6%31m50$+R@+; zI)kNQ&sdrWsxZ@1C-ZAzmzf$VWXi{QopJIQ>9qt|B+HlFF#e%UGQ1CDz*wZ#VQ8THAE$L;lP?Q-ZciT>q; zGg~|5!iruf_Rx^onZ-G&#F#Jc0pmMCj@^=NdEM^0a+Ywv(_YUU~yGHX(g7@ z5Ut-k!*ZoXmR=v7y>$Nk*(rsEl`G3Pn`D(ZYbt8FieEL^Qm|TK<{AIZ{s{Ro7>{hB zh+Gfe{&6i=ume9UaraEO!R+je)Dwl16U8pdZXiZs-Kcsbq**GK1P~n*e6-tzb4CRZ z>doEdU&H~Bn%)5PFJBbiAOJy5H40geIY=}PNR7=-9L`wQL10SBG_5d@3b$rNqcx?Z zd7!TRODUp~CltqHG#-4Siu-;$Mq8?wiuY27IBjoP-y#hOA%t~D$K9McmxJh2rz!_5 z7!a3JgDR;eO-tvs2EmWI|j~7L2N<~7$;+>3txix;hkE^uPj7>BpHE9qR z)c@(i3Yx=b=<#D?E|(ywf*J&|8Qp@_-_1tI)GHy0co}8>3deoV2_3g4k<{oY!k>)^ z4P@v(ytu-g(0Br%S<1YfoGJsmwUBi(_~k3Am|C!i=8Fm$l|g7(?$&^K6&4z!{87Go zN7?PTfYVTt@9BGK?|z-!xLHB&&aEr*JKHJmm2x#E=wi(v?l9Ss_ln=HIG)NMXjf!_qi3mHeoH@$t#SRw=o{B>sG&Z^Pbn zk5Y1$2hNpmePRmeR$CCrEn5C?bTX?E%7$8 za__6q;ovTas=RiYV8TZ8%IYKuIt2IN8&sZt^y_pfs*4P8^R3r3_BPTun&CF8RYj(% z^abQ4*Grq~&eI&$G&3`&1@*Xmx%qE_c94l)TgK7y#JjleDc6!0))2P%^|{8+Ri({qZC=YgBf{g2;NW(g!k@B|V9o%@ zP~FWs{6u-?xHy}2alkR#r{Gt}Qze;jq^M70Kg57+zLoBOZF{h1y_SOdq9~RI6P6cc+0W`e6TaazG0x_n$_w zT72%sK1zpL9X4dcA?0_C)bnPtWMN4c=Trg#G*sYt^k9J|aaw)y{U>;AsUN`aD3)&8 zw{lSO%}vN?$0tU)Qxw@OJGoFqReki&5uI#sOMx(Gd8%mi+M%u+S4z9td;8xY?#{1I z9#G!w=@-^CKSVR5Gd{@E4~KZ>w290HP$@dCf?W)Uqm75cf42_FCIqX%&Z@T!Enu)M z4k((ofrt^Ekl1iRSraq_MB$q--;tXd5Ag}#&>3}yTEBh$8;W`Ne0&m8rJp)AEmvnM z^0F)aCR44(`|O{g%pU0vq~7Z*({xw|UI8ZF*omlgmOrbaI+^#PX)e1TJAC^3dl4&Ml+7b(n-ZIS{$bP-@`;VTn+X(!#kY!vh{b z$!EFv-hJnTBQRfR2!oR~Xgb*1HdkF(*GQ%)cKN*_KMKRML;S#2$UMM!x<#>{D( z>~wRsQ?E=c4Ng}c$Ab}GJcY8Pr;llrh92E8I}N~5r-THN+rpl3|Ii0|c824}dM1LJ zKo5G#Kd|3vxv}tV=l{i9yj6Rxa6GjoT77K9vBTDOyUU?|MpwXTV&|TC5GOLdr{wc< zXyMdb@&@~WTj-`E(#@7H(JvMC5zEI4MUtQR#K|))E{lGy{C1CIFh46wHnYwxeAbG7 z`GX%TAhBnbwv81sjwX`5%NJfhKikcI<=LdVc;Coy*guAJwX>2U@OFqv={fKZC|cZX zZhhg|W`6O3J-iE~II_u3)m(Re_U&TS3TeHsIK5p)rBXnmPaWR$1ZF=UyRRM5JqYyT z2tDDMUj(W)_6x?OBzbn7C+cXByS?LF^we{))dK59AgJvWHvdRp7-&`0aGfzUWMAJ-EJ4 z-nrNdA(bi0#0d61@n#_rt9%fdfgel581OLmBxy8Jt6spAdLZn?*j0!*rFz@xytgm| zn38aQgt&mn61uAPE>5*`1VhZtv&r+GIGlE{lV#7dQQbHtds_9bcI1Jq{W=Y$HT#88wS@0R7EW{r*|adTt|E4X8K39UZmz4c*=Jn4N>}cn z-i{~<4~Q5(fnDH$tvO0(vkxmS| zkm2^;2O4@T_p7Vt=Q*GiR;W5%VQxeuaVq#9O{-&+Vk;~-E4UK53(Ju={T-Bl^iCFk z)8WSwp6*w9&w~EOiwR_8DSL^)naV;(f3KwUE1W#Jx@mIZ0m^%=q^66C6Jes5Og z^61WaffY(2y4uSZZjGFJ-z;Y{ zMW6)V`3lrn!E@U2%pfU9b%Ek$P5O+NwnOCjNB`Ti)tL&Gm1`2S_>`A57k>o>A3PBq z-ORH?lo)bY%pN_{MpF+K6y7Qq@}J!2E`0$vnd*bUJW;4_GuzB-^W>BGb2bVUrOcc` z^Yd=YZn!DvAROjd#S$H79etS{HU%ALDZD)`ESzu*`aNEt>fEQG3YB3E90%-y1^+!( z@k!9QfqBMprW%E}hr5G6w_>f(ry3JdAGXO8+CdODeL3boB1upisOD&ms=1lxCg{P{zXc<3l-1csxWPx8t zN5kG2v;P?BydM1Lbd0FB{gq)2m8YQV2Qp0?E;9GdIJ;d#D7#4?64sY+2YX?`);oHi zA(nC?#*t@Y{YO<%!lf2DmLhWwE+BTzYX_$kc3W)ii63r4(rnfH)by+6oLHG_aWWs- zDD%h)8&(Gn-dws;ZP1&bBYB3iF9BC%o1T?X<3){zNX=oQe;$i|aVHwMmvW5*v0?$| zj@ZI+U=3NVMIWe%Q-MIjH3_qfQZ`oEfcnWh^4kq<*HY@fRY6eUsL-^tNG>%XjTquD9 z37!H=StSq06f=Ive=~ywAD{*A(S-CLbO-Ue5#vfP%#y-lj&1wKybkE}KtqV+PE2kO z5i6L86|$NTL>;;@)s{(iv?umMkRC$%Cj>(|JvQ(rJ_kLoU5UX~nx|K~DJUATn2Q&y zas7ggXf@*g@#=dZ+eLrgUDxu3@UW)|(V6w3%-|wO_=>^s5L+}huh#wmA#F2?}026Z{BvN-4RwxlI7|a1*8L8bAY6lDYozTyr zf3iOB0G6mgT`hzl3x&=#c1Manh`wGf->V-GpV!@VCpZTZ!xB7$eyCq4n4|^q%Bgk! zP_~4-#K-8bAH?fob{ZSEx=R7tM&?I?S%N7!LTBJY@l)M@o}RfH&#XRjBvtwjG4x@W z`r`zQj165?=fCUs%TjL`Ktcrs6L@zbE(`wI>i)cN=@#vn#)6C`2aL~wgmU_=l!W5Q zkeQ=5E~eG(|A%M4WGtKkT7O76E_>4kT|e-HbD|8v8WgO)sDR;uKLhYO`r2oJ_dS#< zFg~3`0YP8uzC&BxHgLmEjv#DuAcEZ@y*qGmifFSsv}}^9+ubrXN^Edx$;Wv=$Rdm*Ay7;{%oG`47WoMSLD*osun%Kjc2%#ZdJb(WUJpg=%ec)slw;qf>R61 z&8Hm{)2@fXg-*SNW(hpCfIFn9Lt98s$8)5Q07WQ1f*4utp*2_S3YpiVD(~`Z-hR~^ z)KDl0lNB!$ZJUCg<3Q{iIcA%l_q%XvIlyu!!3-a0W4{Q;XW|I^Nh=GQO%_xM2eJ;L zqKf}}s8Z<=s&FHbCsZvUal%OKyg`FK=Ij7Bax`MM}qD5|T z=3$azT(NN*lA~79jj@g!#=g<-E)J%t6U7E$%ReQWGR_)Ml@fhHK|3P5-^^?KgLk!F z7?RP%sTcKRXdFq&xCox$18tjq#U+ar^W=1;ynF%rB%ecVJ`+!JqGO(mV&JO}AaUvsPfdz& z`$eDRTuH%#kvwp#lfrb)A2PK!@fOKS!#rhV^QQk=ubla zBCrmV9T21Xf$OG)$8u&0O8DxKD0gPE@3sXuNA%Y6D)z4;qGbpOuyvB+vPYDz1aRFn zpEE-Xp#j!W{es~v$m_ndo~-ph?o#IcAibw?!9If9g+k?1P=n$()1p%|y%Cev9)!h?A(4o<+;q-mUmKNGZT%*jy4P7ADf9jw4AmBenbgk$?3#NnCa zhayDRz)?P&4xfoUyZ4?{@%QQ#HhCzcVaSCkXu#JGT;lt+#*M`st!9C7kN&KO z1*T(PKt!^Tkd#=m*ZXC|j{{yJtZnu!;g`E|vNr0FwElO`RrRijZ>u{HQ_u_H0Sl(* z7V@M)x}1gT7-et<)CGcB38U^U~O1}Ps{fO1*974fAtuaDIv6#PJQjD@^tkWO^k=A~DP#manMgv0LI$(@!|-K&Lq*)pUP{d4?d?l%Z?IL2v`pM9=~ zNtTF*e1(OAM0z4Yaj(+eL|B~-x5#^>a#};|3>h3XECTH|$t)9JB8xSVh3Z6}l$VRX z-C>@kh>!P+@cZ_@k)@95P6jJ0T(n=lTW)?-l5s2C7`SvgCF6doLLU*?R4Sg^WHWuYI97uZr>J2_IL z#dY>2D%LlDAz-gG(55l{dqPgm?(%vEe<~!ka*GsE7ZL|5^n=WkH*Eg?#(RaLiCI@` zviAQS@lZgu4ENHvY7XaP?Qcpeipi)Mna194_l=I5$u>=ayJXmdIlU@3vC{4MS7c9;Fmk zp)Ogb-5Sr7KJD&<7%7)jD^tsvms^c3GMitfl-wdAuIH8BPrS6c~I|K^!nIS67;QU@TF1TlAp++EJ` z7fNB^0brimCo|?%L=_(AaQ(NNZjE&v7gY6$Ola%~NhSTg-} zG*lttKF7MhzXFhlbZ6=upkF)!Fp4CIIm-~Y|MincJ<8oaUiO`d*AP^UBD4LJdWBif%#yvBtIid7>&&~my;v(Ooqyd6w9--|K`=LJ z$0wH;Ss(@salFPnR54;BwKU*Tnv|YkUW@e2bljqoh&)ooo2YHN>^$)9f+A7VDQf{F zcam3LrIo64sfp3zAK!s=(=BokQpv|^m4)?;e|OP4(tT3K((2t8~m@JDqT|8eg*J7^il`dMokPBU41rhJ&azs;lq! z@`p-8^{?L^$RlA}2O`0P+uLCt`6M=-uXm8Ux$uwrim(|DupgLKFy|tp?}Y^jtz}F_ zj=~N?&1=K(CLHOYmGm!{DOaMH{*vzE~yDy9|)Oc zElkzZ-12orFIn98dnZ+iPwYwiqh_g%g;#&YkAK&_M6BDPzF^KVBzj_QLUyeKG3`WWi2%UBm!|hc} zgS9N2ih&1FInx2UV?IEIm@Sgw6hNLd0L#vz$s}MX=j~dNev%Z4!HnW@n?d7XHb7>a zQ!%bCC3zv8uGFILBpQrmlTr=|4x7>~F%_MNFHI6Xicya*e7TI=>xWpP*)3iH&`6t( zd>Ji;pK0@Dwvw78N;RTccyigLXqn`EF{x2xKkvHyfHuu63iOZW z55!sL3AJBXA=zpj^T+X1)$1l=DwXrKqhq?B6y%QF}%xGW~u&?586 z-HJ7cWbJCjK!>FKf}@s=p4`m-h841x2OIUVA0`)Ri{kbM$d)c(lyZ|Nj##FVj~%P2 z^g+oJXH>$mN~{VdV~3-t9`@HXgt@-zFaWjM{m~ zJ2zp4%e^Yu;EL3NmiR_5yWc|Em#qfw`oD2M`KMouJB=4l*5(q@;_FtxYoT-vXv5D| zrm03%*VVDd$?94N=R36s+b_55^FNrr;4g(Pu<}Vo(yVD7B;3@bss62SSC%@pU*LN= zGK2rW8j|#30Yrld{zq>Uj1EUc=E@DMsTpu61Ekaj)|7%U&bq~Spwtno zvRtINYos-AP%D-8|T~4CZ?EEO+Li%=F}DiM&1mX)_rR?uLA%fDmQ&%91V(u!+1_cQ$G#P z|Kn$qz5B6fZ)54dfD=sQS{re}8T5A)AXidYaX4cjPp1Xz7us^`ySpP5 zx^M`FY6fauSBL2Huu!il8jj!}(~hMHd7;S%RJq?X)3(Z`FVkL68Wh~tB2YxN?X1@- zNn*9w6QaI{oCbZK+L`PNT@wcs03UpC*}x0-G)Namt2@chB>eBBR#THX85Ue#-b}zK zj4YoPR9R%n9WI|vjZvoQ&J+kA4lENK7m(~cccrDAjI9AT!%i#m)K=N zy?%A}ul{~PN2EbI`Fiyx##PBlPS7+kcESFp6F>6@{PQ=4_S;27$1r~IZ15+^z25*> zJc*{(?jEf%4YhpVIEwjH<~65UwjjSEHGt16^e$uKl&PKVEY(ZTn82S4U|9ayLWYxVFJh{VHLej| z`LoX(`|EaX(-`;Fp3uC8(pnB+VqC(_w*tYVn3EvcLk0dvf!%)6gL>VEA}NM=dQ7m= zz5HC?1)ypT)TdUZVv2$!NtFg4GQ&UQ)Le25X+Z9PB6grpwDSB&G}Ril$9giJ(G+Ap z?X7^6AT-y5NA*P?+3h`3cz6QSf1u?DkY!P%`LuM6p5Bm10Es45Qzy@q{Jnd9ckeduy0T_G_p!QW zGMp{JMR2%PFIFkv=dQ3O9$P5Um4D9j$%&=(aPvIB&f==kR z;9oa%4XUCC3R4EfgE#0N{8wdq*Yha1)(dj&j!@*d_claCZz(`ND@bh%F!&kooBKJ^ zdK8JhJlh;ZV+Jf@fu_oWJKw%1oe$7dr;&eIrDO`<(qs_Y=`Q^v{(1&rYv+9_+E0AJ z?@w)N`Lv*g+xZSC8~&F+HKZC$&BoCA;mlMAp_4l_v`r~ufnxMc?8zI2u$sqetTDA6 zib~DEfnR}Cs({7RA?*qt1<9pf3V9Gc1~%tcmiBTgQ52~KiW+HbN%Yct(MPIEb~a?w zzX^({Jxa7yKSNr=Wfp)6*6+p(oy5@Z0h+V9_og|*5gWxpwW79P1%okQ&B6{XF4SG1 zX-9*>!;~QUsRVp3cmiS*+#oOrcRo&$!h?wD&a?&lApq{`hJz88uG3rlAivmwOy%lp zAf1%I`1E5csfy!l#N}J}JCqg5*Cb-~= z7*17b*ztE^JpfXnP2JO`vc3XTxzq>BQf@^WSF|g`qg%|l^rB|D7nmm71>k;>w=N!Z z<88kE7eQYvXxYb{l-5*Vp&7HRwveA2(+Av7;{&$TH;pCVuC;pfQ(v3~OprC@NFF|% zi!t&Ln|NSBA3}yiSwBKCCqo>64HEWTf9c7$V%d37_=Npj5}s}pPu*LqQR7ncpEjwi zm|6)N2cZ?fJ|?H%Cf9_CknmGFKZtfhwQulFT~QWGpcNvpu@3oT`eA%t)IQkQsnRK(pEZFr`Fkj$-Dcfv$DTVSCQtGBh22*bLTqBv@1i&|G5Cq5+aV)ccLce$W^>df2a&HQmz|^b zZ2UDL8t|(Kl(C$vek3>IH9$3^A;&8BK;p8yxqOEj&w3?5xllm!bfQL_26d(YXnZU7{UMv_zicKp-0t5-aeeF#C>f$iXBZ~uOtkD3A6fu-o5)*q z-5&cU_Yt1!g$CX1xcs5)ihjGKK9~{8SWrQ$)qWRCJ$Gn@(s4aI6IO_ z@vwngyd`x1UZzMdPzg25B^v>n!lI5TWv}S{W=as#oes?k6>m5B;CB@BowC21`CQJcO1KtNPWKL^&hpA*4_5|+Sfb>qzD%|4=bIXNt%m?43n(P-vz7saz4usw2dUVVVi-7U+MU@?ZJ*KLJ+r{UkR5{ZhnTm=& zmyO+;tP=Z87uiDT}%Mm`IO67164F4FW!d9zpn6lqYERbU)O0vV7*Vw#{T zWS|eZ?g+C277MyZRmrG|@;?FrAE$?gYimvsO80Whdzi)_UWmj{UPU!RUHU6?pehSg zPEu+1UNxWomtt{CLJJJ}Bf!@b%toNppWHLn($bfTXep83GQewLMn0s0e@PVo+SY6` zMDI~~8$`l=fTDr{CJ0 ztCwn84on;jnH5?SY_Y+;O^5v4AK^uv4l_@iqrUyYGcQ$WJ}tA|qu3{m@T{tIL&f~P zK>Gt#Ns`fW9O$vZOG{>}*mx`FLp3rrK!^NBLJoVHOv%5j;jSSzAlFkWr!07pi)zbFQdpUQ_SG^%#L5WYgH<(PP2Kq=zWTMiC1Mi+IuI=|IX(n zl{XttKgHK6n||2W4=RAieF330%Cm(9oqebhm=Ct|!NcLy zW&^0$Zm%rVALliK+yLmGBxyZJMrF`nMSuFWS127%#r9v;lq~R&r*YZ?(W#nP{~HWH zyc_96ft#RHW3lgQ^o;K@`BpM%gTz8 zctA#p;!n&%xFf@)9ZMgV>OfLuw0$G?Kr6zLXha}#fVO(ImDEqmM!z#I$LOwnax8m( z+9}WU^>ugfs&K87s;AHn!Pbz?(^8Z0)&SzBlOD8IKWE`ObMLzyOPJTDV)JtYr;*z0 z6h!b1H(%{ZcNs3Yh2DUbwR=$NTo76)BP&%XbW5<#A6E#Wb+je!Sp_yQ+Qpf;Xn z!~$Mk-C;VNs2~9ZMm-wg%KO~Jmx_-Bsu4-*{UpBz7_QA9dqT*T_m7$XIUcsRRn3z2 z`VgMDyX-c-B^oBwzxd@$gJkXmqChVkkKXjgQWT2fRoOohy4Q|AgSmAMO^8n z(e4cIr~yc+D1(i}T~^vkw=&Bpmbz-2B-yruQQs-naNt0Oa|%O$5P zTTf@0*ZF8rtxm=T=CGr`m^Hv24Q5bM)M5~anBy?@mmBbgaJ?Rr|8MRF$jX;wdyRVGXR&O3X|t$~ZPCH?vu z#~cgT@oN9O334-%Q_@7KU(1Npaw(Fr%8!w<^1u3+lzY4pzq}GXd)1UQ)lO+%=2UT5 z=OH&Qw{O#VZJrlhjNb3j-W=w%q)^X#01>{p1CzP_L8;1k+C|Go_&|%8Zi_>~MVG%7 zg=$C~-WO-t4$-M8wdi_sOjvfUxC;F{z=^3ngB3J7cDe;-5MB4`R7sXSj#i`wAm1!@HRf-=9B_2(TM)3VLHFW|x~U#Ub6(a-=xN@?DLt{5JEcxpfdyqQ)7!xjc&&^6k~I(hl9=dT zUzZ9`%;q&i9S#oyL&!RW(3S-QX3e`F&V69FEp?r*kb9r?o!wmA!{Gq=^@T=iA$n0BFMfC+t$b8MZ;qVl zZ84`ZM3;@on6i5B-#r4g4N#2pFNo@)A1e9hYpG>bT?$>=W8tLrtD~zWBWh!NpZ+`N zw))cvIXLO>GgZHX4n46g4w3gyGIGd6uZ3l@4tMr!$W=<;IewNYuT)NOP>JmYizT1$ z7c^RzU`(j!e(V2d(|loPPU0ZJ|4KDF1+L-rKdFldG>@ueIz4JXO1>WHP#RXn6OP5K zcj%cgAvXC==;QNcF=>NP{hg=BHD|8z%{qZE7N?*m*KNahKONh|L!6ZTItm0zUFCe| z^)4}tlJhn7y;xM4Ds_eqegK-1&k*drD2UJ&4O{sM@3kzymsY0jKC(>FphnjJoZ8Yk z@|wAMAyxRoK#QJ`gOG7~YFAHY|O)!9P~jZ37ioOMZq$`xe>O4|*V0?;+< zskGKdUPk&u;}^$pYAaI{;Zpw9KYN{&Z&Z4!)jRw5?gS{j8gR0#6EL(lefJ)V(=-K$ zWC||}CMUKc!epV_l&RAlM)L12#KYf+3Jm zzHfAk1tlV@2%(sfKtv;Cc@s$$X^_;5jOhe);6)@sLa!yD1jbz!6 zpd%W=_%DD1{9j?1%Z!xq$1s<0f)n5Y7s~v{ez}336SOs&mO5rBs_BpOTvM+-+Gc&c zA-P;6!+QUQfypAVa`L z4u&wa7z|`wD74vR(htl43T+)Pbh+5W5}3%Erch+BfC17H2q8AgAh4c}kw|sZtQIC= zY!AFB5=(>Ozo8r=7&ZM!Iy!-dfBc}8Q{|&~Gg)PFXyd3!ZKtA|y0Q&J^&drR)kR{! z<4o0u7k=o{^DM%e7W|;Apz{X@mw*CrL3V^RXaZVig~D4A>#Z4)t4!8G*S4A`_?Jg)ov44R3to8{CM7P_%I_ zn=SIuAbO;RwX5mwZebPSu8(??q)R1c7h!w!p=_qM>H}ag%nzZZs`+@cr?smzS$Z+Fq02ALBb7K2-Fg+ z;KecY9gSop85g2x#2v_>6bs(4k(QeA=MZA!dulpnHE04MK6Az*0XfzYg$Y5zxtxXO z_%T~ZM2VSG6D*wIFW#YHMlAxQCL}@|c!6*Uu1=!lEDRG5we>JBM?jY%MbrD zag00vgI51w0bxI4SIt0$H7DHyEF4u3$QhbVFlK52C8>=@n=I28ISmmg9l=ZQ?0G#s z=>>U_L{N9o1zst&Szndv6RwrjGlVOwZ>EYE=C!)sEBanbpX+Ld4zP7SHx78LvH4i+fFCz0r#lO-Q?{ejtav69*)xC2e!UXXNX+g^R5$O%lrAs`Sb9mKyVMTD%< zn$)*HvEiX+}z3(+_2<|V5H1dNRq;RNDBy(!%Y#+ z9GgUBL?v*8M=4WQBm&PwNV0UC>3~V|yuiqPK+P>$tffObn3Mjo){)%B)ExgvGVpFe!4WJ$8V~{{WI`uoLMBwgA>08MWZ4d+ zpZ$>C*Ts`liJc{I0bboxYsiHZT*88tw!9OHJZb;N2 z5Wx;yUzcT?0%8mngbih+gEu6J3VhsBHI?i&+Ir;GU9m~-$3B61Vh}7 z0vmu{@BPS7$Pl?u*1$=U{He<+wo}32-%AWdOwhz5>|9Q)Mn#;!zIaqxr4a&_Mcrgh z1FqXKG(rU8OA5GC`1}AJh(d|2)QKI)IK4+gOqW!NAi`x=VpI|hQA7$h+`~yy3*vxI zyv09U!cgr4DP5HzXopH93vh+pk8sxu{zD_gO9!q4I(&mSWTjSaC0BN3R&oO`_zw%P zgsvS#G+crdu$A@wT@2if(Cv*Dx?`?%Vc?h`D{KJ|xQH=*fH9T8f-RWEq~F|p2(p0P zJmukyd0AtG2o?;{s&3MC6UDPqg9!O|IDU?AwP2&j3K<+^hNLZRQeo8e8AD$5(X^j=1m|6*? zRjoK5VCYN=5P>ArjA*H2T4b7B{tY~qrEYYBGX=(vgx?mN0yl^gDJ;=NMFdIN0A39w z{3Xo%xfQj2fVDXb=tM&!s1vSGBmfE^bfU|+5dqKjL@$2i6hUAMgiCMzgKU6-B;Nd94XyRGR7Y6t!!HE*=IvuMKC;qc6`Ln zaL#&|Ud+UojZ^}{n98lIb7tfgkXJnyP7;l4&3W0w2V|6c83!!eq`# zK?_7kepcZz;SF?U;eJ9IT_)W}p#m0&UkeP4#Q;)ZUJlu5#`D0F=Nx7|spe1!43oqF z3v5AEkOw*-10kHj64cJ^EI|{P>Zz8h6OgKhL7o#tVRZyUA}oOpphn%i5~PY=qBIdk zfI%n3X2{S)C162UbjNx=UI~EWj@(QzSl(Z-1TDe@_S8xWr~ssG2Fy4{b3SLRaRV_L zW1?B7d1U7gWYu2b-UC^ccxKfuGF$MS3utJgS0w+NsiB$)h2yG`W2DBw67-5s;%D{c z>VD!{JoYFkfB}W!NwU1agk;1a-~!cUf*EYbL}G*%f=II!BxTIsKm47gbk-f<0{7L# z&V9vd(2Yf^7LbM8vuLD9eFy_Sf&-#UNRFgLL{ANvK_z5R2liJkhyo@2fqtYx9CRv% zT!mh60VCPog%L)Oe$C4HVBz!=g?rJ`fh>KQ)o}|T=&Mdf@ zhb1_H#%zt-zAfB#4cBZ<54^??OqtMS0v0flt8^?|_UT)8SfGNK2^uO%um)7jMoBhL z&&6k#<&~t;7#>z?e6HpyIhqV?>T_NN|M~v`5qQ83{H1URM+y9ch%6Y|6pSYsOYgPj z65s*PD$_rq0pEH@-Bd2-z8kJ&?#CbygdN0r)RVCuYm~GJ8DxTG2}&?Hp``u5CAh@o zg(E1mNDAEUPW{M_#DES+LD>8XH%w=fm>%qf-G-5?xk9QlR+S{JD>mgMK9wgnLYO~9 zLnkc3w4B`x%%Ja;(oyMCO)&wQ=4{%tSOi!cBCj0zL*%2wWtw6jChAx4}*S-!!eWs9-RLHgDjW_IDsNmR^B9SxwdbbjbJAvT-2f<)uyda zM%?aVN^JH^Odvzowt(n`ZS*{4TWu*-mf%NOf`StJDsKTaXCFo`=5Hv*`d9v<@_IDVE02BY86Fk=c)hjrPqyOgQ>iFw@QXexOFaj$}!8%Lm@P-4I z$b{Tp1=oG^QUMi)^S!@jV$sq9fASQ`0& zW2IuuqHP(mn@EyzpJap}=wk;GS|-r0an!B&Z9ygIT1=A6W9eekRR6O4#BI(L>9~St)4&2I*T+W$=$!XjQSx*X&;q3y8 zf*E|kQ~K@ZU|8T1-M~u3pq9rX<0Wu8#ERCPBwJq|Rr2K83*=7VdUCSSUS}etrPBDt zS(~UH;R*2M6AOUBB^>`K|M-Cv49or0P3~TGAh+$BJjN0T!kB@CH;}>@oWNIb8`I*G z4u}#6qeCu`LAhowA<)ORtOG32LEmWxu2QL&l*kWofpwmdQN5I=yi+|LPQ!H^v7RY(`fwC=$H=~3fkPVS^CgdM~w>7;mPC48|% z7KAp4!p5XBuI&GeNnkEXJ;n#r+0iC%IJyEwm0SBQY_jp-X~0+F*6D3Mc?_M#Q2cGs zVc{VU?(Q-ep-vJb?>0i$KuJRKJsDkL+o2?p0}4GZKK0&W^YZu@M3KxR8hma0^U`Tsj1|%0&Mam7c^8jj$TtK78}vo#?THO2H~C^`8AP#l zqq7ut#JciGR9uWTqC@n86)4HJW>l}ex@UT)BC`qbzrHto2ebl1*KUwOT|K4Ipia!( z_gjELa-{zlC}ctDTyDn3p9s^E{a|FUou$sf*i?3GgK`fGXJCf7R_;x+6jW6{~aPg$Xm9CW^E*v|>*1&U@6hP|a z2?Rne9G*d5)gZXYN$^CKS2-I|`DtVxEv}nsx(JNZ09gPXHHo?44(yMZ`4^@+*fJ~# zdEJMVmtiLaVm44F-;1T3Kt7_wN_~TA?f{_kNxV^tZT1b~VuTK`0W8Ex8F_;%ED`pBmq>)^VN4nb)m3nVE0{qumk4yz0I`$vv1>P8p)&+A`=#|rRHQ(sNrotLP!s%x zW5=QjrkK3p%I8rRssIUc(EvmRhL^yF>rZOjR7>p6)haq9> zL{9X#PS_nHC~^F&A>-c*6)#@M&?r=6j1zHQk&{UB-?2+9SjYeh187yCD`~`d5rh9m z4H{J!>Npfki>!5=M?2sVp>7^w@%nGxB7H zoV57SwI|TO3|SCK6is5VL^WEZNO3|8DAt|*N#>FtSct&}+hkyjp%g4@VTm}9LC3IY z8fhYhtx|yO1?adS&n#_5F@p!T-diX^A}l!$KwkW)!7r^+_#uv9SX<|{WIF#@LLr2# zq6|D3n!rV=&c3-MG#n0+jv)sn@y4ulQc0r(q9&_yGSXfkq7?edn&_KO$oN2^pr*2c zs;v@KX`vIA7$li={PE_LF;Mu&hTURlfrvn&k#H%0gh_;l7TN*|vJ^^)BbSK`t81NT z5^3Uu_HJ9K1t|>C1|5HvA}1F%2xRLmjcO?2kz?qZ=$J-`SZOQl;=o0wSvl3_6)AYA z;liJO;;$2JQuQX6#9Y{`t*lBY1EMY|vIwKmIPwT2W=lHhEvbZ}BNvzwdQGNiGTDL! z9e&73D4*OD$}5#(z=4G=I&so4lKj!e6dfkbB26paz&ha$TvGp?D4I@w*rA2e zxZ(}2G)5`-uDp!3(#oL*E6glzP~k!^sZzKMG7Tl0uCK~2%WN~VzOjT0(cEHK)S_zO z!3kHiu~BDlDv{!Z8fvg=B^h>Vc%cI)3(BAxSis_t?Pf(M8cD!t!NdfI;>p#X5R$>c zM6@AC&MbORf!t1#F)PkY&^Uny6RUc!u@kt6H==c5p<_xJRLD${v;p*nlr8YtNqza(Qy+g|^G0fwI#Tg=tP=)U9| zIOQDUggX_=b5Fqk40O;!t3p)UR3D9W(jG0vwDC?q{ee)Se59cTQ&F9_vsGua5*+A& z2!060rf8Lpe`tdgO~}<$R6rG9aV93hB38wUQi3roD<;jlNJdK5k&jStUe$tGR`i#K zPLN}H-trPJ;y{EQ=l}=UIoE}Hk|zA<#a%>DMA~dr7e{#}7=KtofuJ{)O6{g-2FVWy zOTY$J6pSLc*a8n&kdvXM?*tH&7+&vJc<9$9ab}|e^i7GDKQarf|DST zSp^0%U;!99@eS^r0t;`^!3hSTv02d~4pG5hdrDL)q%7|r-snVVV4#s6XiI@IAqNa= zfC5AYr6)t1jt$%eF?k_`8?fMl3?{dg^vM8o8w*ijI_H)XU4ndPY0-;Z5TiKoqDHR) zmlN~@JNL*=20`+Z?JBW_DJ4ls&mqF^I+G4pu;FpQr8&Cnr?nPxfS35rna1PY=QHPD!}Pg0C=Py8~KQL}i84MfOd*NF0h z{Yj#K0Q%n}W+RjV?g<&>kYpei_zHpq4P8<>0Vw}DL(4b~i*s?b3`3H|!KGB>gOZ8X z2&rWfnB9g2O&CNpV8W?^&dM8XW5Eo`rO6A0bB{nH0v4v=(jCwN7s?UhOlG1DSi}&C zRgoT5c%vBF{9_47K;{eRX19p!Lni1D#vqz7E}Z~H1s6h;7nyaJD_BM=|AgaPN`MEl zjFlp+zyc30ltc|#XGaxn+p}|riEQkXve9DbeB!&h$U;!FR!J1jwhlbhZ z?%@)W2(oaCCWCOPTXtZEOsE&H$Ebu$b+i8!taNQ5!=VE&R4R;1;Gm;6SZzkYfD2%C zrXps*W*M`FqHg-5bbR4W3TQJ<2?6q8M`RGC1gwzR;Q}4K^he9&c`WIyWC@Ru7jl9( zyvlgiVgcQfZZk&_u%5HmgffqWV@Uq=;kpgXnT1nbk; zUEAk`s8~fKmr7}u(D5mk{=iPwDf0(tDiN~)&}u(GW&wqPz>y?GSZQ!+4Gz?=5`X~| zNtK8Ne^9LOJr!9GDHv6s6+&r|&@3hdnAd*523~kWtZF+8dUk-;_G;xZOw&OV*pLW1 zNPz_(*uo{eq12h!h#Q??!#`MHnHT?%%q@DU84=7t2R>w>An`dwO*Q&rT%-Z5Y_0)S z@)Sim6g!q+rNwyy;`WX!9>bg_+oY%rt$Oaw`{=!u&WJ%t!-Zc!rqp-&y$==mrUXcw>` zQN8{0=tw#|GNW{U68R;lSg_iD(SQdhIF?78@Vuq6n1ce9YCc8P&q*f zPCx`USb`VH00kIMko`N*Xel~-lqlH1`0%s!AOa76_R}B*papQ?S_~phfbhEf zNe6VG5|H6F(ufCym2dLaEDz4kp{+&2+B@vZ~+fWpg{1bG@eMn#>m60 ziZp6~2t)x`XsI)7X$w5y1i0)LxeUZ?k;~K%`>?=2yu}+<0r0S9B`&J)%7>#6;;^oQ z@j?pjMi5fO%%uO^On>BO|LUUo*Z|)QW%J7G11O=U7$x+aV`$oi4Zv&9o`f54;SO}f z7XRS~h#(G<&!@U%A9BHCY>@@@!)iFI1jvB*KEzpwf?>Qy_&Ughu*nqXk@i}{#h{QI zf}s=kfDDL$2!0?Vd0+{+fDSBS6}ICWNI`gXUv0TvD+4z2(rGg2Pq zQ3}#v4=&*qguxrWAsYDL{!-vw=ELwv0vS5t4y1qxcwi=NG7)lt(pUx-*q{bZKtD`_ z0RuzZLQ7*P3^4{JZg$OZEJlnf5d%E~G$v(7+Kt^f%V^rl2YjFj=j}D%T>IQVYq03;UzK?m-KC!9(vwxR~ufc!cm z88X2M@S_J8k`nVp3c3#6E`bY5;4v5D=-QI(%+4Q-k_(6cJ847U-0C8KP`R!|It-#f zmLL^iv4g%r6#Q%nnqUbWltG&yLLIb0AJjqdAQyaUBDx1=+64r^DkZI~5vET&*(<7V82Xcwrke?=kviP*~suQlwy#;SmVLIlTr9GU3La z#51%36$Bv-q~Hq7AP)Rs6t-jIV&ZZ5U<-&~LYIID^nx}%01f7XS<+}ki)%4Df(&3` znKY^s{;vm&YcWc42`u3Vlf%;{f*hg&7cyZG{@@PofDZ1!5HbN4jv?08K_tguT*!qD zUV(zl&s*d!7*ydB_y7;+AXDjJ5BwkzKp_{9A=W%Y81~>M8bkYXflX;8kfH$=DB(}z z;12d65jr6loCHMYB^`tz6WD+Yy3_^BBIJrEL3DuIx}{#ca=2PBEV;&btfxCQ;}8Ea zQJxg8SrOtYfr4nb%nAM==FV_bdDRJi0E?)PX?So;&43U5LIzH03myTiWL|@S2WaNNc>|k0ni!xFtNaG*4><7|73sKZFbTIr{pjb4s zxV&Zw5+QTa!7h3Ah-zT^pn?d>AP$HPWqWKi(nL?#AXPpY04MK^1kbz!PP*>s;*Wx4j%0fji;fO@jYns3h-lQyC!%L3A6)1rcJ~bLd zsZUgD9bAJua6#3C%@F9oV+7E~>8FL2+VNtq;b$(0kqTv{XL4JcF8KS`( zGE^o&(|)=_2f+3vxP?}{B^|gS84Q?yHw7KMVRZ~oPjTTA=s*mJ;NSleB048yXpXK! zcff!UqIb2S<4{llYlFvNBwt+-7H#Bqu;2q4^DPp>MHuEQOk|JD>k5+ZTbJ_{{vZvG z2;ZttEtVh+_y82Tt&9?c1(qNXP_K6bNj%ZO37nup$+(Qom<%WZ89vh$uE?a+LkcoM z7@$y3K>_pL@BLf=3@TweU}7C|kPY^7i_m2u&emOnAyQklx_Y!n-|q*&K)w)llJaH= z-lj54gv(062bMt7$|+9j?}$c`HfpGb!tbnpkxOKva-k0@5+o}bY*KarQ;^XvV!_5X%vKBpQ$*8Q8g<+c_HCnVsP|8N6XrWHA-Wpg>xH zT%>>vGC_6F*&BF)5}cR_bF&6E*%E9uQb~&(f}v~=G_ zdbVazEfWrCc3-0lD}fD`zVIN33QKLZ^gdrKU zAs6U?X_kNt3;`CDb1Bjx8AJgOus~tnW+i})5MJSz(K#AYArQ2*FNttYoAtn8R zvDz0M(19Gj;jFjNcP{}{@@0Txc`WSFw*Z(n$pNiJNtFNAdQ@%A2`niqdQ)~qRwmdt z9moM4(%P)kL7>eUoq_WkxIq|jAr6qB1$@Idu5~NGX(f8}AhZt@l=C%y$q-@^-%4N< zwZ>UF`#m8zR+Ive(t#H4U|bnF^UgFOcB6>#g9o^v6!=fHz2O*e0TeDl5f0%H5}^?? zVH9#98Mr|yl;(sL!fWC{6`%{R5JDSp!4^896GWjCK*77aJG{HQyv;kj!#fr>?K3;B zAgY41(;$vB6gZRN6%K(7$N&rU8w}VW5UlvRSyB|L>t|Gg%ruh+%0Lo=fg46pPhsH^ z;vm1VU<|k_S=(II`jgmS79e01y8xAr`b@bpQz+nyC`#U<{hTOZkYO zxnP`Yb?P*f7y6V9wpt}Jqr&|l6Ikq>UJMyTK@sAh45Xl3)ME;6G7&Q26k?8b`Y#wt z;SvlX4$L5>bA@R9O$X${NeYgq=?@ojffs}!8n_`E1i@!S0)^?KUs%En1R)b%q5H}S zo#Qo9^*qd7$S~yOBx2w}JQWv0m5LTy7=X8>$Yl!lpip-bW6SRwggX<4%|YV8Q*+@M zYVS4FX0e0e6gZj)P=E-wfDeHDAJkVQSjQWL0Twa=53UG53Mi5=T4d=hPkG@I#>s;_ z?Y9hj3y*;hZZZ>8As8y}PkJ&JC^E_8!wmltVH9}boJR^cqk$Kq8Kr@yt9w8S;=mPl z_tq(xUVNz~6Tu9;bX0zT2)V!z%=xvY9C;;`B+PFndJ-2N!Own}6?Y&GN}+zkYE=RL zZY|*zG5X&Njyn=z3QnLnOEDEGMJwJa*qj^|ddgAgQlmw|%HseHUi>kgm6t=jzb^q7 zz^c-cffg*`%FW;kmcTJkkuq|7H#Cz7<3JRW0fEdC-x~mmaatI<3*#>7AZYG_<{C9!B@M3@kwyw4rw=6%{g}5+tD#mOI+vWKvb` z&zv(piCB|p;|iQIY|h>;Um+7HArb#5;SxSo8<4{rl7STH;0~>4g}b*BKJ`#1cve^v z7dn9tz<_D=QVIeg6I{XA|3pc7ffNqGV~RyR;y~|tp-tm;dr@$0(m#`w}-p>lXVh7#8;612%}B=NixRRKcb|iv@u^5R;0KV^8_O zrJ!O7D4~lvMbB5#8-n2y0OAZ4QPKSU^Jj1!!i5OeeanT%QZ8-e5dOP}@ghTn+Hl2L zQbLNPVBacc%(!tKxnP;N)TsZ#h0RmZzO6fmbtAcsf7n>^W)P*n zbmYGI<(BMFmJ%@j6+Vgh;)}&8YJf@9374>vJT)$Ks7)BGPJ+aoa1kT1=zlU=NTG8H z6|ZRM^1?;{?3#Mmtw>aSh4=im#8XQ2Zf1XUy- zH}Ns#4KI>l!9xo_keB~kZY(U333l0Gv|TQI)ZhXOKcvA6ffiYYRWNk8@L3E?fMTIV zd2Q#>d2|GmPC6H2xE(pTjKKmAy`dG{5`*y4T1s*i^^tgIjV7H8{KdcpDdeuko)nihpe&J8 z3oLAr2r?$^q*YMd@DvTldI?DEVl-yE~exm+RzQ`(MaRtzohu*5%yl(O1^8-qMsB5X9l z!%P0fknME+y^vcCOQ5j_(#d#pYEM6LoEa{*VKEa9*=n1c3n>tB2ro3pO!Ljc2m?wS zHi-2D7^LumGu<__Os)(m1LJMqwa`)YH&kVEO!E};^hd-jFLl08m z0m?txw21%EP{+7?2Nz33Ed$m8KUv-sjihWd=-8x|g7pM&?P+`Fiey{~PWI{3q zy2{1?lZ#Fe0u4*(K?{n7wWo~dDL=pg5wH-4N1!4Y(EuBjeiED6*k%h$pq36MNCRxq z0BbUM$q&YGh*1cGBJKm3FjkR>G!WqfTd2_cWRnYAfI<>}h(jE@00txwfhiX$%zo&# zm>2(~;0J8L1>h=YyupEj4k%dC>@GquGhBjY$HSi8c9sPc3{iFvi%_WhgG&x5TyL1DdUg@7@Uv>O^Aal zMJY>F%F~l^m_mOj_RCKO;**4E=pX{RP=X@Ca7c*5Ax>#eQJQk0r6ed3UJ#ww0f+xu zOGv{YI^hapf>WHJpadPrKm;GKfHb+hqgnPtgf#F0qp^(TLsuzJP_mMv9R1`V{=mwI z_Ozh^Riz;Kz=n9)APaHWsVPO7R8MO3s(ko}gR(#eR{~X@Np0mJ4nc=5d;ke-@Z>+} z$x4Tk@}d72sz=|JP=?C2m9rd#AwFpcI!JL~IKTnX;*bbY46~S7d<7^PL5DIB;e=>u zK|d=oip3HW7o^C9AJ`y;Bly53dkAP*_dW&^bW=LcA5>m|CW+0Ak`6NdkYLwI8K z!wJG*yu2A=3{ub-DX>Af#0@7dXv54Y{NOxO5Ckre35rV?Vh@6K9T8$87PMdlTmLxY zXwv9{8cZRq^d!VzVd=?;deW-+jL;nmEVL&45}>k`Em3XDh9#sRjfj~hZ)Cs&n*87j zaUet{NCAuDW)T*kKrS2TH`5YF^E@9YK?!>7V;}c;$U!dhkB|I;6A-z`Kt4eUPH+Mz zv29>fGmoI2+=MZ(Ar5rtvKQIF1|X z7FG(Zg&pn?>L z+Q&{V_LGT>Y$O|**vnovl%oR!4hS33LPoZ+jm&~#5zN$_R`!y)T>=iY;Lkz+fCox& zZge;M(N0N0qdTo+QXg8$^ghAiR!A`%u%HA>;KG)>Oouq6feYw7fwe^Xg0UL za&d5i9pG69&t~$W*G=q!8M@om_OS;FE$JucIJY;=R#Ki!1b_eA%NKE-u$Zg12Tk)g zxFl=~O5kQN2mB5!H^b|o3?Lk|FwH}JN`zv-H!#52i%kEA6nOtI>822Ys$T@d67~&c zK^=5$Wjv#SN%n#>cPP_Pb~2D3eQ9BpXLb+!hr2Zm=}60))F1e>s!6l?&K6)J%E7shaIs*g3tr+G54eLj?8)Pnyk)RJN;_7dZkeuY&YOrd}K zApLf%l5FD{$f(57pp_gbV5Oyq>6yBF&KA;1~M;4_4 z91u82YGfXnS1mZO11%tN#}_NQW_~Zwe7OY`I$(RKHx?381F@4v0eBvbb^fNBo}dJzPC1-cYI2Sb!8_O%tdqs zW@409UWFwnxrcf{*D9KKQ0hd1(=;&p(ICafgk;elyn$Z!MuX?2Xis4SzxR9O)oTY9 zc8j-LFtLEq6&#iqdSZ7GHSiBhVPOIDFuK8aIMDwCG_eDh=Yi&j0{_5*BX$yAM|3t& zh7Fh$^#^GGkbD1dLYWtajCV+mw_AghgA}xg1A}IJ28C%fjpYGSCKgTI_#b1TdWrS| z<3)bexOb$NgNyMJ$T)7gXpARtcTwmcMAQ_07KMs9Wz@K5QK&}NRCL)QL`Fv*hGBI2 zQ3Ke*YCcnj6XX=YSC0IcMnIx@1GpGYF);qu6gL%i=%s2YuzSacLTEuX1%?q{$Bg^& z8)XrZE|7`lc#eo@1LIYVDlkpuXakuzHH$G`JNb|axn?pDT}7mMdPW187=~x2MnyN3d2|^Wh2@wZC)WQI$JZN8L6d_71LQ}3+TwxeC68f<7Qkqf zVQ7R)QItg)lNiW{w}gpsSp$h=k1iQaE+B{4G9H;YF*R5kWPyn^5SH0emuW^`yir+& zd3=#`cSCfLV#syYw>H&iI4ux4Gzf`j!4zqPUWS8}I|&0fIhIeclX+*78Ig`wiHL_3 zg>C~hI3SXD)HY9okC|x$NZFfbRv6>ai>#SueaV?M;E^7wfi!q;XkmmVsfb6XkwphI z*~n_wm`3JRafQ2#%h8|Q?F^CPO<+Ky2Wb6l9?r=lKiM`lA$KEsMlA(f?fj}WO&;{liYsUIuKpiUu}M7K-d35^>{ zjlW@^_?C_xY8DaMhuOKJQkk6v8Jp8|pfh@-P7(ug2sG6gluP=bCC7Cd%9Rx=hS@o# z^QnnAnr7Dtn!YifM%bcgnnoB%p04?O%=ixo2AgqdkZk&iU0Q_6$0XYF55$6Iz6Y0T zYJ}&vXp2^oCAoKPV}3dMIiO))W$~un*?6XRlqoc()~TdxlaO8~sf$sTb~e zSQ@5U`XkOYn@V|v>U63^SF7czro}0(`?;rQ`iV#htY>;=;TcU7%BSIZtk)Wah^nE$ znyPy!splx3$cmvh5Tp9)ru#^KP^guLq@Eutto$dT+d4?5M;eqVhmIMpBCE2$I;wa2 zoGlqNrMI%>c}FvAvo~9uC@ZUtH>8Vbq339uCOSm=F|^kBIhr`H zW2#HjxP1KBlDW#C^jiO_TAHsTYK{Tpwfrcw(qy6Msi(x+hua#bhDw}KtFo@?w)i@; z>ZFQpda6GPu`3j(b$PKio2oPwI|sG1M|-q}w5vo)xF%M!iOaaQI;9@Ut=8lpJF2YL z%CC)!xrv*!73njwnv!Cev=a)l^9s7sdAMk%uv)9FUAvDTOR)T!q^b&{Y%{R0i;^q5 zw-+0?YTLJ&dq`BKyEePGt(m$jOR~T5BteV0yX(7(%e)#&k{8yzTKc@o8nHNPxyDPb znOnWno2;RGV&+J5dl$WjYP9?ry&>zL+&eqJ+OV+ddKmh;51XyF+r2c~i{6`Nse8Y( zIvPcrzxuns{hR-|z014p`=$bXw8VM63Y@I;3%%;=y97+W=KHpAO2POGw^=K|i)*|Y zS-$_9r8C=qxEsI@Y+xh2uGHI|`)b1FE4=&pz;7$O3Y)>ATfz{G!pd5_Tf4w9yuvqo z!;CwuHSEI0>%Tb6fBZ|n!m7et2e+>4!sl4MxQf6}tgR)S#eBH0i+R5%3B_1D#W(E1 zUTmv6?7R;k6{4_rzw5#9KVN)qAR3+<$K@!+E^Mk=lt849E^^u@kz#fgGk> zoU6VVsfB#VQESJ9i^qrz#T>lHDXhL;Je-ltnrJ-0U>nBNJIQuy!*e{z4%=%oY_Xo4 z$f@kM9PIzWtc=HJ+`bts$;7+FSc}U^Jjl|E#UBgHuWZOpOvMQt%c&g1X-vt8O2%wl z!IbRB39QJ4Ouu}r!PG3F|J%xa498Kd&CjgDA)Lu4{LRrE!6_Wc!3@XvyUL41=seGY{LjPO%gEY^yX(l=%*!jB(E`oPXq%-aHqH1v zul$?8#azmE8`7cd%0&#)2Q1NTtj^+m()HWYaXi4b%y@Fl&NXezzg*G&tHZ!7)W;mr z_G|ysCyl^Uebg;|$Dh2(7;VkY%*YXK%C|hwXI<9kd&i?|(kji+JnhvMyw2Oar&(Ln z!}`!_EXDh5zUoqW&PoY06Z*Hm5C9Np0( z%*N^4%4eO!(!A50jmmpH*W66n79G}#Jl9Z*&!BA39leJat=P!C&@a5ip54Fo?A43i z+RQA?sU6!bEZlAF(%vl6rA*E^Jj1fg*iaqSbNt$ft;)wr&14Oo#S7EF4ct6NF-w)2-pbgi>4Ym@F;Tf*s8~)!8&fy;p;xrxNBmUu+ zP2w3o;3ux)E6(CAKH=2u;xR7cGhW6tZsY20;y142%Dm$cp5r|Z-r!CSQ%>boZsk{w=4r0x zYtH6v?&fa}=W#CQb57@VZs&K7=XtK@d(P*5?&p6F=z%WigHGs$Zs>=O=!vfAi_Ykc z?&yyW>5(q!lTPWCZt0hf>6xzSo6hN-?&+Tn>Y*;`qfY9jZtACw>Zz{ktIq%Gt?uft z4(qWl>$6VlwQlRTj_bLu>$}eDz3%J34(!1$?88p%#cu4!j_k>)d@B7a0{qFDo4)6gl@B>fq1#j>NkMIev@C(oI4e#&|5AhK%@e@z+6>squ zkMS9=@f*+a9q;iU5Aq=|@*_|3C2#U4kMb$6@+;5sE${L#5A!iE^D|HLHE;7bkMlXN z^E=P;J@4~B5A;DV^g~bdMQ`*+kMv2e^h?k5P4Dzi5A{(m^;1vvRd4_GSC92suk~Bc z^Zx8ozFZXj#_jPagcaQgZulIY;_kHj8 ze-HS9FZhE`_=RuyhmZJ)ulS44_>J%Qj}Q5gFZq*C`IT?^myh|GulbwL`JM0ipAY(> zFZ!cT`lWCBr;qxnullRc`mOK!uMhjNFZ;7k`?YWTw~za|ulu{t`@Qe`zYqMuFZ{z# z{Kaql$B+EUul&o;{LSzD&)?__dvwsx_0r#p)Sva%-*(u4^`RRzXK~tR#FG9}PqB-piXcUg>6uCK&-5Y{rwIlS|6czH#PP4jzkfe)EW{z> zpF@WTB~GMR(c(pn88vR?*wN!hkRe5mBw5nrNt7v7u4LKLaKP!HyUd0xx?n>=HWqApvBw@Ek^u+57OL-}8a{NZz7%}C%muIPlc>I;7{Z|i7Jh2sgcxe* z(k~gM!nJzCm$*5 z>#G-RxRwU5~BM3PK0xkL~)5axl1DdITfl8_tWBaJ0$i1k{3yS4ddoO9O8E7zu=;}TFv z=_C;hnjBkI1Et!QB@~c^A z$}6}0@~2$;Aqzt~A!RsH2#*5^rLeU~X_{kDI?g5zft!vg+4Qe|`4b7ipjvngFji;e1~7?pQYR{L z2thRBZLa`DBjP{=qv?nUacD&7_?8Gh9HJ7Ps8A;Yv4tN%j|I~UU3oHbh&XTo48{8t zC=vlOP{1%jKl@xK_JFRLna+JfBx3&&bw(u_h#?W5dxa~USR7E$fe1F@AL^V|r4_QF zNrdYH5l|o}c6kL0djLg+GQkHkG+_y3;9wa^Aqg=c3q?dQLz5_|L$;+s5Sd`bDWWI^ z9UO3lW1!wDgyx4W4CMz*a?&V-RzM;YrS z=uHlV(1H{s1qVxr!zE7fBsTm21#2Qg8mQ-rQS1Q=EP!4OmN22=G*YU zUyh=e3^sTPSDc~}Y@pZE;D;G43I~7DEC>zO1kyirBBywe!lk6Zhu+xI1}ylZo-mUJ zNu1&pl}JNPS7-*DDvt})qL){G@K92$hXpb)st!7(R63|Y21=7^X-#`tyi^GXh$~}2 zRiW5U#K8sv8Es`xC)WR_*5_$}u_Gv=)B@c;%{3SA?NQ-oQxlb{WQ_3{tEfH&7K5PP0kE9u;ErHnMSlcpFWZ z2I$?*1!7)MXv*^0N`wFcV>Ag-TFubZ}VTVgf_jXO?uncMWfMDu_fqlC&#?Xs^0cK2XGBuW!3;&wQ>?WlkJ?!fLV-yR_N9Qf;r>8tn8xOF{uGQj@R zl@=<5`Q52OgvCTB#-~~O;!guLbUwgdw_YpxX{NceDf*3Q+v~$u?xxtRzVth)X}3K< zFA^{NlMC}jVGb@YhiIm})oj^>rQMylA%}ZvQ*1WqJuPHq@qzgNuvZUEcAd2Y(Xdp#*#Q z>mQvLv;IA|$y|i~yaLA?yJM%VlnO4nN-))J0q5Jwnv{@&vc@1(+sq>f04h`sK(h{kgs;*%7w5tvqd~`(^hUjlzy5|@yDX!%&iq~mT= z8r=8lRcw$o@7%!k3kJdpEK<)1p6ySCglFJG3PC$&Rgt%^>aNm@ZyVVA-Y`1>S0Oq_ z5FkI|=|g`8e>zxrN8fNg<(_n^gp74L@xZBBiy?ivu?;1CC_Bf-k^Zix)s~aZec#|u zD4y@sHN&~?Ste*K0HIotE`wrj=MI#Msxg~hcbRi-d;7&jqlqPu0dZt6zN_t9Q&+xw zPRyuio#ZydGG4s*E8~CR(xp}R!td@Y3+?tN0Oq|7N`nx=#`zOk>V8+~+t*6VmEB6P zY6FW*lO$HI=e0w@Y6Fq_M}u%A5$kpcI@`cAU$j=flb;hmj@_5w+2T9?+>@6#!D6Kt zW>ZnB6wr<~ZxR~3gFk+G-utSK@=B?L8jhi72D0akUrt~e5gG0X6Tc&@TsE_7X54m_ z5p;<@^$V#=1V*ngCx2m7O8{NiY^PO*uCO9Jno+z0vR?(p)Hq)_{>vM*@$tcEzj-NQ7rWr}N zZs<2X!M~B9@G6EuPQHARE{?hZpT;mKj^m>#{_pxwQ~Cbx^)`@9IZQ#TPi&d>1_Dc< zw*!#!CkmQJ{gXubXPs)C00u}OLD@E0latFTKKP!W?d8@b0$j=s8+z-z`GBp2!u^s6 z-iOA#JJ;k$n&(Keem*5xWZCya_tsa=O06{>o;3d4j5Rmk&I)OmT)Opy3s71OKuZPn zawpy=Smm_`BEn=(BJMo@R)YMOKVR>A?nJ=vYTr4Bw!@PMi{yaT{NjbLoXp>Wvg*NF z4M@zt$AzBce^=TcP=X)!QdLl_DS6f6Zir(A8{-#j_bJ3KXMAiZxb^!q8OuqY2qF80 zNIj#C)1%JvE=%dtV=bZHKSJ92X8whQ`hS{f%?SOgIkIoI>+2$Beet00|DW|;ALffEVoIWWA2kl~e@m8(qRN-}V+`D$KW z|Bv-eOF$~5?mqEngu3WbApfi*ded0B&B%!QcRT!RJW4@7swHVG&HG~Zno;wh*Nw|h z3RYXA-aH?ha8|e4%Gv9!&{Cji5HrIW$PLhoxZnTph;5+0rvi{&`SL-}wb%D(pf44q zmN6yAQumE~_p8kdbW_PQYQ5EO{p)O|OAfS^9od)my3fsZ1oc$cJ|?}pP4K(1;686` z>EHc_jr@jJz3-nk)I}dYc!&9AtJ0tQ>BX&0_>j5X&2R67HD|zOtkA2J$=-tsUT34b zDLmqaD0zwjm13I53DFr0Scz_M|i7EX}mi?LEJC087 z`c#_gWg*xq^EWF_SsapaY|~rt08QasCCM$RW83<4&Px%J%Y_W$+YXpg{g(^$`?|f< z5RCn+Bso7z>(}ky9@!sYN?$zkuZ&H!ii!D9YpO=56rVh?EbH{9Zmd8B>AAo+<#-?U zymm_g#L;XiNnmRoWkB}4+hyb`CDxD!8Y158sihcP(uG5FghiXpq(>(FUk5 zC8;peS751N``0U_Y&=`7)brO$RU-?Z&&gux-kOm5kTpC-8SJ=-d<;VQpU>VLDRzlU zfO_(;IK2z)bftWB(c+fE~{z!nF^j=ml@qu;y zFQ};@9`Z!30|)hG0|9b_rApcGSHGczQ65NbfoAm{5ho=I|8`C50|n-j0k-hpSrwlE zL^%lQ<2uJnzZ2a9jcOKw_z+j5^aa|kzj;f6H#M*q_Qi{XN+!2|6d#U>L+Mh>Pi9-{ zs7%06Me8G}e;4yDTiWbM*yZmnicTtEb7%?TrA%N`QEqmE`YSX<Y){x z*$ePkVTW@KkqHV&81AEPKtd!D((9$HB&>%{A6FPmMLS92F@=y*{y14B&-Q;8s&1GDC(r#b~8DFB!Ojv^V6Gh|6~QL1TvQJR5g>Ha+r**P62pObe^;$}5`sdVYY0QBS?3l7 zBzaTWcP#ci?u3wLDo8q# zgU%Ut=r6Y_UeZjV%g?bc5vhxL1d;X4>%dNup?*^L&Hh8W`*fcu*=-AmzYT3N(2CE; zeW<;v`@Ps;Y85yAt#-7@>O6sY4sSXV-n9N*Q^)F(Qb8ieV2XQ9wC*12U7m0G{qh-R z_5nW+Ex|Qe07GXIud+1>vO@+C4;GM+yT8g9gffamvtL};;gfmIp67msnCubCK0rEE zd#c<~N((UXtl1%7f*pDj2^|gOX>>IYcfWU%wHxM*Zl`^C|6zDuWv<}!n}}kcZIRzk znlQc}#U3ctw-5;moTS4GubIOoDIDNPFiWa^Rbl&>Y>{i>mHQYcud{op_lhcVQrilz zdQ@j(vRanqQwj9MkUQr90}G;U_On3Uvn7qoz6F?Q;NLr^Oo-BIDze^l+{*oUQSS;sd=;KR52ZZ*hoIkAWx^47vbM+JA_&o_lfk5-v35v;?bGV?Vk$|z73p;F^g-PvT|xyeh}$eI0`^q zdl+|ubPF7em$*-R`6zK5Z=UFR`g-o{h}ueBUe`PCLEA}y{!yR&T&<#-eZu^auyK_u zzS^Q?ELMKBRJ)Af@`;aNinvGG$4C}Rrq)htR|PVtr4reK4NYsV?sC2lX4_NM8!Fp( z`t&&RfKXk=o`R_-kgiNlm)Bt*k)OuHvcsniVB;{dBp=+E+&4cYm z@RB51|e-#aPewKErSXScxVOfMx{_BqIp`S#2fNFTGK0RTeIKlKy7Cr>~1FjnH`nAcR z;lZ)8-qI8t`+|&-vBHhEheJmn8jV9ECh3nYlh-Qs#N`T4%*BtD@mn7&7yhmwV^>Iy;a_YaxiDAHIm)HQ55(Oai8xzB_7dIq?oIzZyQUhD-$ z-m}=FiYa@4?2#B!bHyIEunD{w?nL=-4@t+vpzMg0zJoR?!=NkTXIU~tJ>A)*QMqs=%e5TXcEwh9jmda-Cm^Mh#fil*P42z<+ zGm}5k4DiQq0ExzCe$NQ84j1rf7)I3+oh---akbRvfoq6be->rNgm7E1zbTDY{Fdsy zDZ3AQ(#baerF-H`JjhuhE4M|j^I36M9;T!V%nj5Rpkd!gAfKlkpOKR`d5{{89@|^p2M1-nDI`i9xRnIrrC=UJn zyG-%|U=JQk4$4vb7QJm_4{d2zQTYkrB;t?N@!dD5Z8Jb0H0&JNu7P%PHvEKMqNT^A z;gYrA_U8m@7pM`0i|eFli}wsOGs{T@8Un){gYw_x@*&tN6uI&2_-(qhwrUt?l~Zw2K%^c;4lbI(?3j z{PvoTX3)-yN2@RGqCP7oT9ge&l7%$|WAE9&ZLvyBE$f9^eTn*j$WqAkPJxI^!qI_? zn==0{T3&Pk=bD|vHAz*WPd-PaXX=CMK*Z2d!=B{wYbU7qpm5XH##@`F0b_PWPwZuN zv8L0A99MVgTU0{4*_~tXK3)Y-Rx0Hd$Vo!~wr(o(X^FFhf)O7i=3yxmXetk8=nYFD zLZgLXXAagyHn~5;{e7o5-3AgvYc{+MOXolnXb`jCe%(5hJ>U1uY(ECPZ6p?1$$@#I zE|5+>B%Tk=;KMTb(7iOsR{%~mDw7ZlB2yvp;$JKgmMKtPU%qOLUW|9#oKcH8O&9UvgB z^TauFC-x%4;TEOoeFeftB46nn^L4(HpBcnoWXOSDzZe_{<&VRTFI@d-p(=_j#@qqN za67MzHz%%NTaT)7(#N@MXjGBSyAzzH-^>2abxOw3j;AFa7lQu1*=2cS7aw63%z>T~ z!o`>(kApgdLY?OzD$wv093(5P$kE0hcHJnE2xD^)4eQ85b*NqmWZD6E3je}WrpAk% zh6W)02SCjjKJ*N4NAx<#tH&#e2rCvMW|wYW!u6ctKz)QD2MK+fiyH20JqJ*zUJhz8 z6~Q{t<3M5Ea`VvIz{^@_>sTdbGp_paA*o`GTB!Lv)GlKIylFz~+u6~*HB>}CO?;M`q-^&@jCLp|dib$|$eh@+a8{mJi zD8-->FUu&Cyk*w!$G5|N&HS!=_leAu%c#W2t^o32wXpH_Qd>yio1oq4J zDb4Xw>46y@JV@?3vZ^#iie&e=5XHtp-d;9Z-w7lWVGT6LvH#Haq`kLrh)_lB)IN-S zmqSKrmd0d4ym=Lyt7O(((Sv`~O+)oA+{Q~yUCl(M(!l4l@8~z#9=Z;`U}mF3-xHvV z*&+IFB1XyoCV_MeawSeXpHaRQECJ1w5F9U5f6bTTN(8UgLTjj+$I`TAHl*&aBXenx z+iEEoavC=M%Ey+<9ki=^Ify=VWZjhVE1YCA*FF`gY)Jr_ER=RVH_w$o_AY3d1D`Ys zqy}iH8a~vI3sOGbGTCC@fywyN1qrD~G~;>)xKf7c@Ec>mo$IiRILX%%Ph^7hmf|CK z{1xJ@L)L8=Vm4Rf8&a?^D@U?x7N8o4FrS4avbnoQCulDR-bN8V>O)WRQCuF(cqO!& zRhXOZuos88#aH_E5si>CVH4+0_i5L~$8{Jf9v?=QD0^w>YZVA|ra+7M6EHuT(+094CWCT3 zZqn**7bwp!9zJ?ga}6z3!BMH|*_WSqjZA}f4*|0itmUt^g8QEbOGd-4QiOFu zPZ1BL?wj>{EZ`*uAyw4*hwbzA02MI_n}KegPS4T`0JQUhkl4b&_q*ATa1nKtSGG=H4C@E(3z+o4HHAbhrNe+?X( zEE0lKh4Awnl!=90o#0L28D(qj9T#?IUW@~gC7|hMLoVlx?^CzW$0-XWp6?*So~_IV zn8@07Y3K4FJmuCA-Eru?6Gl9c&#M{R>u(;l%Pp!&w(wyg!tg8|Ps{*_&;)e$lq>E#6fs>l46)JUF3Trhio)Wzn61yWo> zqR`ngkw4mVt`en>>U*v&;`=Y)daI_C7ylv|d`PS+hD?Q<2E3EsKm!4Ie=5xFxG)GG ze5`4H42Mjmf)9Q9TDf7sjZ>37o5)Q`N;oTBLA@B)0z7ngHJXat+Mzv>prt4qJp9P_ z!~o3H=fuIEGUtV!dO^VB@bEQ!RViB1<8+lihqbvwA!QoqERDpMslN`)eJ>#k>i&U@<8A6;&WL6Mo@YbzIVee4tDab`M0e>iAtD8RZO?Z%v-QKy+)qV! z-xPNnOw2r)?m}kLAphEeB{se^7U@<{5CyFdU)ZFtPW@u81}r$clGpq4-Ott!9aVqk z_ZL=D-xHI^-XF(a(SW_Kxd`(tQQ87o{2^pcR@XU$tY4>e4+&~WRgPGv3^3y1E!vydO19~4KDrGEO;9o3I!KqdopaU_`Sadmi(c3ih3aZ;9oO-@ z81DplC*LME`z|DlYCc3@Y^rQ&dA2D!v5@jk25_~{Lc zAuOy&<*{h7_r(1Qo8p!1qNTFj33-Er*}v~~G4JWG))w8T7Cr`#q-FJPai;{RVh8ud)@_Ho*{#D# z8LA(ya!TJ1AvD7utTrC*OAYEiJOw}!4n@R@^;RRfRmcE!){N)lxEugcj?2J9bnF-1 zl#FFv?ho8~I_X|b8Nr75S}^g$g^&7<_(Qk0l!tHmJ7x-?ijFOKs5(DG*DcL+qurrG znrUz;>pys+=zJbH^HZaxksZ|Toh{NpC6F&{${B>lHz8cRl|QQP{@t5h)t-M_jw$0pI+5&!i{re42+mZwNzVadkyax>2#h?KlWxA zW1Y4Lwd?EuYY>%|wzv#apHCUnt&CyO_0(+(P|E2ar;du53%qPgvf?gSrL8~p$fepd z94&NA-z6mP@aA|<6(wWpm{wLlLQmG@3=RdWAX;p*2`Y_za*=Hr#p*5+#+fF}|+{8oMx_?y0TF*2;J)R#FA1JY9k;bo8XitF=`3m6i-EI9%zoETa`t4au z3v;1rECukU)C1GmA{TRZdGz2RljqIZa+Vb_UV@|~7oL9RmWQ|tFMbZD%2{nLFzU@X zxA2Ve9E36%$AOf`19QzevEm+Jft2;$n~l9}XahTUjQCY5P-qaoWhcOFQq|}~1|l=V zAcT*a8}hT)$}yX7P!pq6wPOAiLku|IEd9UY&)B!lgfA~PgPuj^`-CmlT?v3%Kc z3V!t%iHEyy0y}>d6v{zRK)Cn!ZZS-w3d!$T zs*|4X7Q4So2~LHn_7a&T@aandQev((sVI&3LhE2cI4GKBW?sAY^E! zh!tyzQs;HmJU!2uiMYK0nOZ6vT{7Cwxce@Oe7VRKIHuYs7A>Oq4PD5$5X>6@U5ju& zUQEC#92py)i<7emWH9&SyX)(PUoCERL)NTsko#iG^9&)zwy(ZQJ6cs4#t}w~L0(eT zX=2Z^srpoOy$z!TVQt$4)91@9QtvX|J@)Uc2Ol(}2=a_pPf+jgpvz$DQ4#?<%2g2| zFF)KQ(z&K)H~oB~)u$UXF(ldEJ3fX}>vU}axzkEm9+mbtZlLm}OUx#JA&~b-uABl( z<+}|Uz3UoW88a_E0zgq~p`teU;7wvl6)&%h?VIj`?PY};-h1KYB5cj2+tIOyJe7*p zb51r;GW6n7Bhx>2u`_W%Dk{j`NbEk=X*KZ#P6I#;Lsv+ z2mi+A%ml=({L^sNz8c9>f0XWTh8y4OE8Ir3DoIb$HgdWSNQj~WHB#{GKbt1Yoj26H zh5)EwDg%2HU6l|j(m%Z~86eH0Aehmkhv|Xu)|OH_70PK+7jYd|&74aVC`}l6W3 zw_pWduSq%r?PGC>^*d@c_L|w??eVC}8~loA?F-8o2lh{=tWaZ>kL^U<2viF`A1Aj_ z+!a_SWR)CU*Kx{hIP-`8HlDsssT#L|^pOA^->zHq zT0|EeM;A>F(1)nOmcUXBC9Bc(39d}vHqO-7Jgj}T1rDeh3Dinr^p481GnInOm{KUo zrz%b&0S)>83NZISk~Qx+&c*tqp8Mpx^8=xzD1@d4dAb3Pt>D>b zG*;l9=?l3YeBj?vtl$=6yJwdpmX*}Yw3-B_Ed)N%Axk*Dx5){OxD}o463T5vtzhbxt-;1*|l2{He-=?O4Kq1E+~RpcN-1$=6i@% z1#AimK*GwN$KeYA5zl2*%s>$fxgS`T#qF1rR%Bodb#;PRScS~uV5e&;R5IwcN7$&o znt4W!)~`Gb3aTLTK~@_=%N88}6~lt(x~|?s%}c9NP^!dB7#4GaS0#2OH3M53Iiv%b z(jr^&Zkg-<6PQ^gje#u%lU*0IT> zs~@t>t65{c)mU4)d9_@en2t7kq>`bgDDk+GQed%~ZT%Nm|z$AX+!6bd#Cdd=xZ))J=$^o8vj;)sH*0Ff#I*#5dxRdb9d$5G#`HPjn0?`-f znNdJ5TWCi_GuEDYw;9k6cGBlF6IL;Q#?j05zI_6QDYGfdvq^BOzNQ+ZRtMi4nt1R> z?e*pR>V9+y_OS1!?5L6Jc-thz_(}d@8pK{~tG3a%CNQ`r9Qndc;GNBPiT+qz?^sjbLC27UJ7!19Y}UAIfn}@^y<>O<(mQRbZLbl3{auIY{o-m9j_J$Q&05HDAWVqr z;EJ<1m9dgO68z#hYm(7~Q9F_@9D*`TaqSoBhLC~vyl3{%SR&LIv6CvFn;;CH-@wiI z`c=`k(f=^Bc*bl(x2}*pTwAI%+i5%MT(+EJOYjv?I({W#v;KngHwTYQ6BVcoGCCI| zD|z}7-62_0Egm3>?8{H0$Dt19cp;B(3_3H|#Jc+ZY|FNiKNtQ7$>MB8vrG@8qAoU9C{f)-_|gj_MrZ zIrdxr`f;$`7rT+vv{oPgPHw zhjN>$d&?Aw;eijhz4P!U9NU&kR-;T*eDl|D!|le)`ow~IryL5J5O$1$i-S4tgzLuI zK-WO6-Lf8ow=eGaMo^&uwy$Qd-f_IK+U2`Yty%i`Pj6Yu9~+Jmp;CN<-r^>B03Kvq zYaA^TJ-Za3!2>45Hbt&Kd**Cpu9u0w5Ayp??~OcQg= zg~btgY;BC90XnDsAGc=3=LV5SS~ua)`WBk&0b$RwDB%~{y2ln@tS;r>8F+meeD@~s z>dedX+i${S5c%L&NF^7)Ky6g-64@#H79|5bV1&JyhBC+?mPO}L)|r|SYyr3EAsopW z&9OAYU?mo_*3N47DojgC?p|QB8vJWY06q_MVphR;j9Pgb9o@RahyyP9$4(4Ess0gW z4$$SOq=ALp2#RF4XBB&)X3#Dd60V)rn++`UsLYsiPl`}x!*8mO$OYc3VzEV^dBoEn z!4a$A!Kf;^UWV#8vg6Z&>pDI4m(6{&qNXkAm9h(W9d?K{^(8{lq8Ds0SNQQR&^_f! zIjc~-NSE1!fo?|MxwI#=7kC_L3+wj05&w<>uHMqxYRyw)2a*zGfhS z*TemT;SXZz9=#QPEU4$F{x$osY7Sj}bi4y=ZZzj!!Mf<~mFt^yasL(X+V-1aTar6R z3$CJ}eLnQeig)bIH*7QJoaY{t@nilbleVQ4JJ7>M_iV_{-JA+JdSy@fMvu2bVWw;)IDBER3Ba&vQqWtSB|m`P@VgnszDGp^2fD4+By!I&YmVL8Yfix%Osrfs2Z&p$^p8}cGD5Niif1x#<>l8~8T5czI z4!}!pbWK!fGyKiQnr;<5?3I~(m{_)UuK-0+#{pOIl7HR;;HGbjy~oNqFWPr}xvoT> z<17el6Tjcob-ONU?O8wd8>UzoHkJ&?7?(v%K}F%b8=`I7bekq2?d;lK{qXJCX72Xt zvN;x;u6}r7D_VW{jcqI;KF2RRK4Uw56ymr!SgAxP_6Epl9vtv&at<^(Z*O=Z4&*8U zxx~S;X$P^#$X(tFGKz4obyrt5$vA|4@_T>ebGk;R!eJJ~5?6ohGJ<7~*2JX?fM$@ z7mgOK&-8XkR-R0v(*`X!ch#nI!S8+?jl@&q<=|&Q8UqdcjxZ!YzEBO*@uH?r_~gCL zxDbBw0>k-S$)? zry3Y17ZYd19}ukP`eryHzFq0DePc{Ln?PxhNs7c3J>E%S%GgTIth~x{R!(O@!|fqK z5|Bl7P7pt588799%=K@xdRi6@dpoVjWLNPdwLEhsm(zW0LAsoi{k6aEegNptf-WUZ z4#gmQwZ`;A&bu67n1o}XIr}@u^-UgrMx}d}vef7OY{v9)CS5!*) z_Pz`4^+nRrkM66p*dQ&coakpQ{J8#~MsfHLo_jh%gTUi?6rRbcP-ko_d;1&qP~C2TI;w0=3b0N%BWD%gdwfmzv-bZZImWm680O%8M&8l zO+2IH#T+Rvv5cyx9LcZ0R}GB+{U`5(f4yyb`q!Zo@5IG2X)9^_(cGu@d9TS826U!- zVXld{Z~OiqhT-)0eaYY6R;WhsRz^E~ygx^G$5c-JO`?PHB$dtI_H*ivE{*kBez+;b z>pttL0XqC+FHf5-iRvAWFLkE(G)byCX7FZ9pzF>xYyA!RN18_pgw0o`I2*;o_ngM2 z_9~3}VU-nHm!m40miKTeh_N?Iam$T`a_MQmd`@!Y>(m|3L|Z-#9Py&>&4BFiG*M~D zGE7>>{mO_d%Bt$up4m8Wn9q?Pb3Qb*<#dYv+CG-OzUa!9(RVCgr|L|ahjl3KIt91W z4-D0xFY!sV!Vk?k`*c%rna(pb*HBmk_LcTW!H*!x#m?{aJ*f+^p1N&)U&jfh=u)`h zoYK#8%8)IIk!{CGKV)PXYTK7d(ow+!(vM_&6KU}BF%Yvf$J7^dQ1Vh$4lF<@<57Q@{xW&RNYlH6Hw42^Hp zYVp%cc6Yt%hz((>E#OR$I<6CT2DGr+P2ml0O? zs^6<1wyH19*U~L((9d#go#Cy0Jf(9;+Q<=7+L3*`=7^gGPYA}}Pg)7EKe2pppZ!|l zkDsqkRO-sL+Vglh_)-4M!qHM{(0(`57W*$@!8%$qr1xZ3gu;i&>}MoLO1aQ}V7-%! zB<%Wn{(4Bb*03}#%U{;>QL1eDz4?!^xQ=kqhLUO3j!$Hy!Ni05Cu7l4NX6f8e^e$I zQDYG{USY8LvtMcxww>B;174XHc?KPDsTTdwFTJlp_7aG0nyt1gJQ2EdCjOoDG7;TR z`u1?a@>hWEsr_UPy$y*SrDl6Jw`2>+^;}Q9UFDtsO7YX4CcbR+2>Ijpds16pGDS-A zsFNH-0_DQ-FZP}W^!uC(llB@D0<7TN4txaM`fWcV*M@+}v^0(mN z-s~&VjI)Kw?QH*3T38QvrthZ(SSCNG0gWlzS>0r8O_7##8RXpJq?%06x#;zl@Lgj_ zPH}zSs40p3N_8^Y&r?~}KB(iV6j_!$3y|XEq2JEr=s5FT49bsn%;>c2Ii$5X$}6>y z51!hOnXJkMe-(pYbm>A2++dctI7t3}U4!`rknYdTYIS9ldO*RP`pf6| z;|i-MulqzudEZ2`>s@ei78ts(lICVD6Z%8Xb@8!4Dqt{&}9T-Bovg(IdJ<5_{ukB*X|OeE4sO>yu&CF5)}DRdH`MZ zDFwHR%khnM+bL~IJ1uZ(A8ByymD$4VAhxdWHjXt>{xS}v{^g&x;r53y2MlAo z8laXpqLqrnzAN<~j#xsrDVMwU9yfh?Nof9&o!|MNxwhN>2Mvr}#+jpB^>?=SZ`M0z zo0X9!f4<4FZoQ=5lfcJ>+h=z`N{vs=FW<@@vy>GHcx$@~YHSXI&tuDHLH<(`z6WD2 z*T5g;o9+HjW;p6wErR|<3vz^QY`b{Q-K49exG!5_=^L!;N`BxHqLgl@lVdY7u5gAD zy*hafV#WLP5c4%8d*weTJEnK&E0388w`CdsB+9J_+`d6&|3^D)>5UN!7u(lS6UGrh zjStA@9q9}yd+H<49gOJJkE50$9P$qa_==IE9@N&Bq-;;}pnv>~t07b~g#e^w{etGD z{ia=qw&mw0z(^YfPjzvKMoQ?ujDvSAu8wIl6=(RCM}Co1#E*deg|Wz-;E2rEEsN~- z8;C=f_tL>P&Kc-16bl|)xjvd&IMxL~`7DS8GRG)(JEmB?Bayl;XM+%Krbl@Pt%q8A$-tgIgCV=9!o z`JvmA8F*~6+98^Yq|DHGOavbqCM>Z^4b-$5yDJ^aBXOnK`9EJB&r!lBs8@&350Vm$ zFPwSTuMZ8oQM=wxzuti7O1Qc#Sy!!ZVo)Iw12Ud*mvvLmgTB(x&v5?7Ghbkx42V1_s8oa3G#}T1^@v}r0U0HqWTnPj9LnVsaat#o z)56@w1B5O3N^!^;?RaztUaEaDru`+{0&K@~Q7Pvy+(LZo%sVp6bxo?V+VGJ|d2pOl zQdf<1^%USkeO~pt>vQPNO_)dA2|$E-9#4P>JOA|wb9+_;{3 zl54tlrcg9B_cAzK2aQtFdi+qn3OCe{RHxpQtJ*p)w*~4R%6sP&l0+UJ_ZT$)NFU2@CY)gqeX zuQtT2OQ=Rf+n*ZT#sVNm`PIV@YU>LReNxE`j0~+N>G!D-pJv;vyQpxGN#gAbBY6_H z${r(zVshjCI83v70fwXFlA)(`PPjNs-+G9)7S949Z z^t4|ez$Zm2pIA(CHOj|0G7{221~Gug7an^S z4&^*~goqJn6CUo!U|$u|7ym)UPbKOS;&pCG_~OZO)ywgtVhe8&P9vjc^%{`6rsxZ| z`cP`)IZJ-eQ%*c@)E&^EKX&H0n*9Y_ihzXnUAT6Ek7zkdyY4x6@)IbWDJew8z( zl+xWcaB|Ge(EUMcf1dP8kVSTYec&!ck~ccBxEqmD8c|-oG+@J@x2Fyo@Bp&D7)mZQ z1CZF9M$%uG=~l|l{Uw3Ny>+f$yj~hS|HLi6Qo@~+W9c5Z@7$2gI{j{hhY3$NAg-En zh!va92t7GwS_-IeBTR2B|HbNekTc&1)Bh#jqm6pZJ`yR*p2k_Iw1IK;c z*Li->0ze%KI;3gX;$2hZF)#K`^W!TlBC+tt7JE~=aLsvg{t7y4^RtHLq($jUbeM?f zCDm_lKHu72M0g)h$nDfsw7e~y8y-gWxjDeI$CEBy?5|R69sNrE6y=E_|#9+m0VtjQ{d+?TGDen}baXa_bHZN#|21;Y~8XDr;>SjSI5pbZ6X`woqwf}EG(3B`o5X$Z6=8J4l zkXv&}E7LAAgC@9w*opDW%h_+>`6e8;c=zQBT_tirgNUD{VQ$R0*+*FHxV>}&5f_#T z@V8uqx*2;4v;n&FE(mXED7}n(C1dS*9xHE)%=6Q;RQ3C6xL7uuhv<~YdQ&y?-L6eL z;`UclZxk%aeOY;@?^%6$WJc>#zMjCVi?}P6gat(;~%Au##TL zFh>RK1{4|+Rp`P6(=Boohw%M@uov}>SUw3jP@5;1mhxF(Su*tY{|0k&t68UB07ic- zJgW)_$MA`Pfoi$!eM_GZrO~a131;LRB}2Eq-1ipK7Xp+?R=cu!YTQws;TIMpW6LW^ z$BR@m+jfW|-&3QCg&A(nxt$h`K{fRy`vW;LmdoD8R2F z^X((uB_?J1E#2j<qWJ3)F!EW$@VUP z<-1AigxG0WXT{hb!k23S=m0(`Y4)s$i$3naSe;y(kBu45O1X`NWdO2vyhg>TbhW1% zZQ15Oq(_g9qpOZ_^P@*uS0DWB{++~3 z14tIKuTG5cR?{aMkUQq;*NqobR7;YaorKdIccXS<5AwuphN!GHoN9~MkU&$ybK!95#{bSFh)jp-LQk!q7O+<@0@drz9g7YO_5QNt&QOTJ{ z^2`roS!l}ZpRU5m{|3;ztVQ3vWk9t}FB6doke%DpM1p;o?`~89L}QoACujbfr`zWa zj~};e`uOX}=&~b)b*Ea4Y$6TP4x{4tSu*>7WyLL(`z>_^ygVB%%i8Gv zLd$PX*y%R%QkFnD4j=ETSN2mj&YlZY!wmD2BHFXiS? zOCpuy3rEm_FCHDdQ}Ew^;>nU>i$kJ-5&caAeQ~x#)YZnOCyfXD2U?$;{0xvHewn#xB|bhMp(`{dlTWBXq70OyGqDs;oIrBJLd|6^}i@jz&S z;005{zmv^Y{P>`^k}(4ZhDR+VP^j4sR!-h|E#9>C_)*$x4FjWN`$@~+PL$T-jx%)Y z1lBEra{hI7WVc=uxNhOMU-&(q`}RTpw3$sfOJN-;rZ%OlRFN-cmJ`H1?KrSvT_VYi z86;n;wH>ftXvjjQs7=-=S!0C#sY))5n%4iO=?Slv2d>nf5Iwb>Qz&BG+xsZ*&ri8q z)@eW6*6%j_h_Sf#Ykxjx_(De*M8_m{nhFzjq$F_<)r=zSrR$BHx)mqr7K`yc;qn8P z(H;^H&)nsE_xa$&=@9{kZI*llbeyG)*UN z4$`dj6Y^@K9uvt=##<8J(GIQ5DbP%>?D9cmhKfNo95OYpti}(p*)AHw3@$q4y0TS$ zNOVC`8B5*~m!>~42G7^CYIo{ZT_Y>&}Sw z&1MB{vm#rU#ovc)s}9fgh7=9N1-2lx=Qs+&0h-VFFBJby`f@o;v)Qsp=KNeRud;e; zSuXOh=Ldg*=F>G06#;~@jNxCy>if!s;16=|XR~jY3U{1jb-wY7TA`8l4K}2FR!Ft@ zN6x1@@`Z0P1{c>`xCft>%3V4ows5X(E~mC}@~^U3O)~w1ocQkw{7~dslE&5K#c#@D z##y9Sw_5)#2j7=*CCgX-Bnho!|5!GDvXKoDzm}`?6LV+joO=;cD`EHKm5Ll80X%d_PrWTZijg4!=;rtKJj*d~pCP6Q&=W zQz)EbIth8$Mz<0XR{hQ4t@tf&3(ls3F>dsT;mML4JbLy?12TGj&5$tqj^Dm13ERar> zhe*}Xs1sr9kh2mZ*Wh_F5~r5K+x7|ufAYKq-XIa0z;aiwmTDaVSkb=oNvi)+Ki9_F z$JB)*1J*Fob;V`nYGa~b?||MX~03ud-~@Vqs|uuPDPZZlE96;t4W zNi^&k;O42CVMpz$mK9ZvZHju)qn_ZL^QhoF;#er=Is<@e(iKBjb`|ro;<|@!mv4M2(bd*ja?SAUdeu0u&J(H_X%GKVQ15HL`^=j zk*9HdinqA43e}Y5vzA}9ff-Hlp+yED=KZ%^mpC@O2R$Y?#dOzMb{1YCAs{tdMWdKJ z{LIu<$q}ZvG0jpMT#oR>P6+79Um|^pcI4^0H3;+;kr0#7E*g&t2yWD2F}ivIOLTma60A9p{L^958rYO z;Vr_w_Rv(*Dna9$^4JI*Rd7bEz=^pczJyt~k?c8tXhmK)fnbT8O)PX>0}^!?r9R^t zimk|e8k?JG<=}y5N^hIFNcC^zDgiy9*;fE1{)QvSAbBomK`0oRN&{=QG%vRI zQ-v}rfY>Z|kk$0vvJEYHRLAvdPXapM>PM7*E;b}sIyB+|mDzg!DnN-IwDN$2dv!2q<*BN^2f`shUYO3bIi4V23ed(Uwq#D9 zlVStqtB68X_$i9ME!2-$(273=0*^Y!S}H zSUJbw@^a71i{)sBov17?@t82Gh2kxx)tAG9X@c6B2KuC5x_R`f+0nIDCD5Pms8iB8 zVz);IWoyW_*%AKy0}C7P(soh)l~z{)`X}8hmgfuy5n~oK&M}8d9G#cJPCVA7 z{E%X@SesK;pp8i73{WkAeSGOpecb79sNev3lsCb~@Ij6;%<+?4F-Flu-2a;UDmG6g z%2Hu&EHw0FZNZO6VDVB=h0G2Ukt%MZAGbC;^z-w{fm~J9T}s}Y&r14)J=Ot%W&XY5 zuCu)_Q;4OD2n$-avYD>D?P^}ZQR^HW=h-teZ~el|xT>Wki4P`Mk_$CIDLqxcRfWs~ zlIK}GJB zV$n8LGL3MNxt~jMuk^fy--;x$-Q&~G>E?N4`scd+@$DkYr4OddCbe;ZC~)5I@_=Qm z>)(8vVwfrGv)?zw7=%@l)#%xL>BPn~QCMKR_^O~!ny~YbUPUwN_BUP0pOBRZMK90~ zAv|{OUvyQ}=QD_uKd*Hd<2sPN^v6ai=|Ve0jsf&4an0bxmHWwS1)Y^~cB=(ys@eHL z@gYxd1*92C#~2duNXuOPBayH+ijXXnL%v>+n=Jwk<{ygIFNHr%c?K0kAm;}Bmg0Mg zJ3aGRP;=Z8qi}Ao#cYQ$;Ii6bb*LK;%Yz&l0cf zgio|(LqI#5w(I!qNNgrKTVzEgFLCqR{z-!s4k3TcZ)QtOi&~%z=lyU)ED>KMSHPXR zl6SOVd$(WjXbRurfVlw_pp>P)Ks&x7+F^zwq%Y{Q<^odL5FfOC6CRgON`BoOnW#>I+1=vteIur*I2tOrj8o5Kah9U5cuHTTD^C0_b3+r_ex;pp>AgephO1+6Qm3u5{nICk z3UXb{DvG{rpQqxH> zboT&DebJEPb2#C-50g`;>bmjbX4!&`6tfg&(hChHnPPU2ht-BY?q+26Zh;*sMGdYu z%pJu?#xS@xfd-N~taFRjg&)fiWSr9QxvLy~=ZM`mB`>=A>;G`J%^L5qDt1B<@aK}x zatIzD{8Q+rcCeo@UN>4;hAkiUe*=G16$|bHjDtea+TK=1JC-IpRz3c6Jdl@=Qi}GofEZYz(U19IDV;fV>Y1$PKzx zA8&DCz;};;Ss}n(0f_XcmgC;Wy2)sAwQmh!dIEXbt5+o*CU0hbk*MXdQf65yiR*)0qXERzDCV_NojTiLzveQ0RJV_|Rc z2US-G{Yti8O?J(LyX!f^8p9DIoH%Q|>(tAyi`Ffk-u&rw^m~WjK`rjF6#W=dcQOTj zi-P*c5pu^nOds$dj=g~5?P{4YadwiTA#-8eK#(;mSS=P?^Bj)1yZr&&#zAI)MP?6J z&Ts@80D74e+yVtFUQq9g<{Lvs4d3<_58_Asg(U6 zzd;lypuc_NLACLLVxhMxpaHL-rV1%1#Pl?O+JME#MNDY!D;$ZCCOmNZbZva-D@dul zX<1ZnWB7K3(NRQj@+cH}%TZm~rk!)1Ew6Cq@9gPwshO;!XRuaJU41g2rDkGRVI3`* z^CoF7ccOpI#xIMpzpAZm49TJ(SD2Ox zCYYZ%!9fzDU}%+dhC^Bh6NTnrSC30w6s5I#?0{v35|_LHW#=OdGbR_qLj+fm*jZF7_Ne>`F4H--V?Eh|Q3)4$s;rXUv6$V2TGF zI&z+9-ymEKIpRmCvN(9fVa-mh-F$zqk?3C()&g;7ieH^?`7cLXXei8HvANQ|`D=ao zb?6~wNv+Z$cR?kC3Ws2lWa8AB8h@txH$9Q0P)m`tw-&GjI zgyvJ9=<>r_yp$)A388C^+zx$xzoW{GE4|#;4?SW}o0(I}Rs$z4LQ|q^^^MnjRoy@2 z&?i?KN`^G~)78U(ah^kCkD=bR9HLGWqm_h zV*2Cb!&H1rZDgWkpXB9UCK5e@Y=;KWPYBrmHoot!j1hVw z&6EtRR5JR)5O_r5cyn(El%w;Wika(_h9qrXi%n9fGKAI|_O4G%3!gnab@*%vGtlCB zua5Dn`D=fl%m=bo1)-e3A&VU+q=8UxP6O|V6%5StB0y~a(&~=h^N4l+7kmV8fSG<* z=bOjLw9%(WlcQmm|4n_$$IqX z-Z|+!F6-?)a`|BGnY=*u(gxnS_rw=FRiSvx@B3qh^B(5d0wK#SL?yG7WJ-0eEn*gKCiJlfT0g&7aUo^Jg8HuaZG-1MgGe82YC9sa?+%A!ZZYVPzCyudk~2gfb? z4n34Ghejx2xZd6YMomT;q{>csW( zOT@W~#$j{Y&12P?$j3Bp2WEZf0$QgccD`cOC0Ew#fq4-&+^)gYe`v8ox5ZM@n5_B3 zKe^qeMCR{@X`yuC!*TNe8Qi1dkqKu6$`~L+&K2%!lRS5pI$!l z^7&HwK=d}J$3GPWkdO~U#W^zrL^ zxQKCwkG4uT(@!twBMw|y@1O5kt|c2id5T)p^JN`&Lqb3LtgKF}txgJlA%Fe0oZNi; zsD{k-p#L7+&fp6ETOOtl-My&e*z_~LWBK*N+h!hygB6I)D{c?p^e6w^brCZ8C+iCM zz5eDepTBB@IIBiHC;V@rqj zR0p4;@S0rQn^{s@0`TZOA*bbC!uarBjjxUuM~m$LX{I$F*<#$3B{ zsW_&y^VV3*^;?hmPu{pQ>3H(yy`|!lw;p^MJ9+!@KmJ$-ThJ-CYe=>v_Rg60cs>kT6xX+YsU+^fhg;)u55GJ{#`k}lbc%oU zbEzc$@$WC=@lXE!Lz0<5v@@9nl`AE)`E@491A-O;34=mz&IwONPn0GMNybkk49lJq zNF0&B;G8(Be7Q7nO#Svm;y91>O`6bu?ws_@_-$#@q}kVrq~}Mt0=&Kqv`g}|tz231 zjHAx83gE=^z5sc%x=mZdJGe|?tvHj9f&<51DAY0LR?=hIe-btcnR&szwdS*vh!J@c;S#Q8Jp z4e^s_-d{Q=n7+|+!8LvJ%H{Li^bei4C(}RPdLo$d>CSW4jL-Mpp3nI5;Ok_@*T-DJ z%q=$BEpvNF?n36bF`eg`-zP25XLn}Y+|K@(J#pde&xQEsXMZi7Luc)-TyV?UTfclE z>-UG-&$Iq~d4fK-|LwWkxxYW(UO4yf_t)n=;pW>KI*33loufl#uJQS&5kS)5d|Rc` z276D6m1r9QZ`y5-%z_V!GS^&;tQ%}ZJ#%=QmqpeLKH#ViajVTBJCK6j1yn6RbewkxOuruKWV6> ziNwzf%xjXi`K@IW%Wp@usrz;nTh|fQ>=Mt*5y4joo+bIEY7X9ta}~-{&BAS(?P?AP ze((KNkv0xU)Lx!gIta1r!WX%Sdtsr8Ve)q-Je(>*K-UKcOO^ab+|17?VIdBc6CrS) z#(4~(bFD%EPZi&wJc|uULeB{dD%o!HdxpuQtjYWiqEwM5Bkl5b(h=dN-zrk_ZR}M2 z$3#vhRkcq64(h5#$Q=adP|S+zXFil1c_ZQSnhsHpQ5!+Kxl@JhlUr0(`H=T$aL@f# z;RHWR=eTe6=Qt#8+jM`Kih|HM?MSGvCEb*`$H<+zWB@g) zD@N7O^0XPVT@fQ6329qs@mUxmf|Mgs!^}})5HV%F)=H9ixG^rc_-xq#z9FN?dW-nL zluJem&|>@|qphJ{^Z~qfd65&`QlLv~Gzj(qTSXtq9=rD0Vqywj7C{xXCS;$tx5`nj z%N8u^1*aSE1sW5K@psKPE$)cJju^@di%fozo%;ilG0%kum|80f@j*2Qm$9+tHVQwKTsqY zZmrT0LpoUSU5N4yRLU##5tq~N&dg;I3+q-xe}EAQ8@YH1hhp18WBGz+1Xu9bl)oK! z730syK6iR2M-$GTPCLTuuzAGqZZ9ur-P@VyE>&R5NN8R7p{vTSM-c6oVX@&vE59>E zuKNnuSPoEZ4tLU2xdqEUVlACZgNTOq31>30kNz&&uof#(AdN&RoY+Q_2U>)A(Rsx7 zN{y2+9#uP~BlY_taMW0_GxeXH@;zj}R$Dfc1GZ6^Ab>?n!zXrMZd_TNf+*_NpzHm@ zRW_!;H8(;;`jjJ4$@ImP=Mo}Krq=8XI#6*(e5BEr$j@v!6|EJa89Oql?kn+yn)@B& zWx8GxBRp`9vW)pp)EbtB`I{OO|^(H@}^vA#hO1M8>w8#KG#inA=!S<&Y>mvO472>jfugB z=jX)%@4R@6*JC|2Fe7=0VbqyTb0p5N{N|oLR zz_{*z(4Wi`%nh@zdu@I1y^aFi5*5~>#469iqnTV_MKu(X&0ouefIZ|;#6&MLaOW3# zqyR#7$FQNIxngH0g^rp|1z+Fczq*CK1&EWj0e?|+>D)$F^!V#Bf#wWInJ)h|TbLKa ziZ$pYXynM9a`Yzy4>Lr~biK4*+2=DM0X<2tR6?a`ehJy~TJEQ%4#2eCLF8FXry>TD z;DcVrWN^-ECufWHW<$$Q$%$(wR0G3O!V6y6Unidq*}@LJ$k9v?1~nIG;ULKX*H#+b zpCK+22C7#9v3{j+nK8q|IsDDRQ8ajbEgV?~ZOL5DEC_dK} z_!+o|c%c|fZJLbYi~L7Sv)Dpk-Yv4n#iLoi=V+X7iDn0O z;WbQBAWn=Ft-=DG<^rQBa4Qtqii49FAS6EAGCLukQ%-_Qd9y6TXz-8r(aXx!aUO1= z_kvZsD5-cZLBld4p1#b1gIBr7@C_* z0c!yQl32iK90IZpkH&$tXwVB=DHY1rQp=){E^x-wnU@hK(0ow*ypaA2Vb!9usA-_K zL(S6=Nl&m>M4_aZHTi8azojzd5YDQ9+D$wmfy)GH`eGWd_^!Xe+}-oPO@bc>Lr6|EsGph8r90tI+APgn;NZ_R-DU_nM=GOfGyi%myOyuZ1+fg>MotjfPE5a#ubKo zBs8lsp%paydIsz$2kbcocA>q|-tGhSWM3N-7?hHoXMxKsGvsfg z1XVW#)f5LMQy{7Y+SuvvQ!n7J!=bZ17sJgUp{d!{1rWzG$-J(}r#4(zH6>h6Inbg_ z=!$BM;x=g7zeF8-0Y!uv=?c|$cPz9hWLkswl#)8h{1=kb3L-sR2e zpSBdy*ht$`Atca~VM}KfXe%_7P7A6h#QYP5*%N4l-)N*CwH^R9Cb>hli`p=7O%`mT zpv@RZek!S*BHl6Z(^eO1H&w{sFJZ(D1NCe`W8o*^NV_UWm_GodNCb^UNm=k38K-XE z*omws!>*OeK9(Kw+73n1kRu4!jq>UPE+0?;n)Ax!i#YEDm@~x zBzPGi)}EGWN(DzVVwEoX9U9jf;L;?J=qyXHRC6%OrR0w>-(43!D(5@mQPIiR8Yz*;+*0&OwL{FGC!*EgS4)(E)X48X{1>=SUp_w*kXD!!$ zf@tR>IQ8kO5Qb-x?13Tw2b4JSfD(!S2TG=Qe?8ADK}Xx}9p69)>iTuaJ2u*vx2Oh; z{L~Bh75}Eo$uD_hm&o{kpyW>bc&%>eSfc~YRzSkArmjf1!}Dsu^z7bol^1U<;#uC| zW+Jd>RdPmABWc*xr%%KT3pJO83NFx1osJFCM=PKx>8M)9HADW6`{x8!$C{k($1R4{ z7moBwglf(|F*@})Em#*)EUM5n$og?J)T7txL|5=M`%@6J&fw(IMBm-_Pa>lG=U%r! z(ehzJN(zqMYi5blLZ_m)(fOZWYg_&Le7x0GST_M4u3qhQakWJ-+Qzy1!+~3*(cbcs zhrHY>scB=26f9X#dhV@73D+X}UT29A0%2SlaZT-_;n(?*g3I|?`@2z^kk@v!)+bR{ z>$Y`?bj!R99VbvCvIp!z{$*1?)aV zgNlV!8mB;lkv^wik{AG9+2$56+KX*+O&54 z>*L?l3LVW6=IB(p^#-YiaJlCGYqtIdSyFYH-aTd3N#1Plcp7nIduU~I_7zFHduu?H zMIVqnM}Ags-_-L4G2rwd@MWz)l#w40TdcV1)@*ggYE)FV`?m(#!al)Hr9ac)tL4=p z;viy_I=b!DI&W=|-q9iEqT;t-3_79L#$fohw7eV;^i-sldOWyQ>8#|(AdpT->u8>K zO!<1H-bXEun^N&c>5Y~!N7=vZfR9g)J5Z)y+{atLc7Gw~t==4meb4a46kCW+_Np>& zk7Ze=H9b;|5is3gvIUg}xB1Iu>bo&Pk-MD1&-b|GKSKS#Ttk!>ynkb{=2KH3c367< zYpUr!!&(I!daz0(*0k{Rrq_Q}_m`BhLAwNrj1x1g`FM+2b_+^$03F(Y?c}FJ!!;13 z)?0*ErCx4|E?Px;dwAi{aXYhq4}|{6sX$ZQ!h9PCHY5_Q`gU$6MKoXNd%c^1SOCIz zEdP=RGhAkbN6PpyL0`S|bee>!{TmAI9p18(+i`@M5X$rAwm5Ri`?9-@g9DhqWd&JM zi&0$dBukakw{^7XBxn1hLUNY|)j`Wr#1sYf$I~v}e)|~Vc2gUre_H2$m#|jSJSygW z*r2&@ej>2Y95M4kkq_IjjfrYStstm@$-y@z$yXLs$mnl6vging-;x;G_P#G&p{HoqB5}+k!IHWJRDI_&G7iX7e zqdE>c%s(^0e!nhv>5GZ?cq0X#g&DFOiJlauGjt;McrivoE^!MevmNH5y~`LIr+xJ^ zGW{5ro_1rPJiK4KeZ?^z>OkP{uP3GsaOdTj9aou_Rsqb7Cgld+i%heuE5IC7fD=p70BBd`q> z4{6(X>c)k9$Tm)K{8sFFzMnUoo{0zb&|e%264iKz_3vMBWQYdLDn1EA z{JeGSB2Hb++6Zv!7xTUpt7W2NZLT8ch^XxJ4N(KQ=m^2LP_(;ok{ieE{^n{B)Zju#JSTxI+ox{T7Y>g$JMgZ4(PWKK?3q{52bW%co|l(eQazV3KO($Y7o3 zoVpjnt>ER2^@+WnN?}{sO;HgW_xFakf&Pq;jQKd$;-Tj)N;|Gv(&ECc;`-_l*;c=f z<#hf?c8q1_jfzrNPua~m>skG#>!ZPeo_L$?PX9RG_O(RzR5 zo_>u+cy!c4p(!ay|9!+#m@~}k*n!1`jkNJkx~YdnwKLR9j4`GYf+=QhDKoiX7fn=} z)JWjyg{+1Bod&DV1s-2J8%gB2s|%A-vdJ6hK1xaGP+o~1A^ePq1CihNH$LDAeHqH~ zo1gq0(Vx9>C^XoRKl-M_3;adY4L^Hb=r)>kF#YQ12uu-KPxT}lBGcVFAPD!w)x)60 zbl>H!(xRMvP?Dzka}>25-XdyRA7K$_!0wfm|FBwFQ==Eib-VjmO7+^c<4T(+Pq?Ie z9eOPDKJd0#2l_EB_m5!`N6!hB#V`|d4LILCpsc9pj2)7Y`W33$jOF5eHEFg>c9?ru z50Wl_4m(l%sPN)1CxyrZWE&?ApK@EOzXk5J&yGo)80gC2i5Z3D%7n91cD&XrQo^hW zEHq3#S2#-V#Hon0IxnSkm129cGkZkN9_~JUvMr)5{Ghsxq*kH>_&zQHAkzR19f+!_F2|TQ5v@7H7C$)^v&(L@IlB4vb+T~KdPi|z|M0FYo z6xi^-;B3KR65MkOJ)EQcB-vB&fTK#}**_|QgRN$X zUZA)d%LJd0*VN-5XQV6$VBA%X;$D!SKtJUuV|hKcB@e61267Y#Wx1;?3Iq8r{ zmWAgOqR%RsRGg%W8;pXE6qy~aCh2XLzuh*H-VDPd4s~x0hHDGH3&`B3Q%E_4abepAGMeJEOR~>9)0dIc;dGRI}42TQU!YcZ#K)r?5 zwpV*m<6Sn$lL-k2K%e(%7QCx`#l0V8?0(7B+Tg5*f%Lp~Rk>N`ddW*mrQ-moAM>2x z3?*v%jBi(x+LpRC1rosIo#hIu@J(JuG4%f+x;ETq%uDEO8%< zg*mO4PIq49TWFNl*RbXesokHoz8D2Mao6wUjJ6UZ<~RX5xd*y+$DWr0TG}p8@IPrt zH+|^|#OOmwIEXpfzH|o^wv~UjProU`B3mt{Ek*T8N}cy04s8kl7UDgMv#fMDX|ye4 z+R)m)jepZ?f1CyJWL~qX_ZvE9YJWvDl^-9%gm`W7P>Cylhj2Cu(Cdz1rhbk~q^OPp z@0EcuXdYLn$Y|0njvi(9x7WuNoRjYV=^s-F1_0ShL0$#$*VEw13<%_V+tkmv=u{ub zsInK&^Z@ct>M^bZ_-pC#R3^l*NO*q3;i{3x>`|>J6{Su*LWB&@z?fLCYXwkX6;p_- zI0l1DV!$;ZhbfoUexubWetsBO1r0$b-EEsfR8wFi-9T!mgLN3WG}If}S$&kHqA(3k z0Pv3z6e)1CD2{o5>w!nBhv1;2?rD**xrFR08gfMb-kBQ$`Wg+dE_*RxO#uE1j-g^O zXjs_D;<%Q)75G>eB$mm;O5oqeWG37H7xw@hVlZ_1otoA5BP$Y3Y{n|75k8K zaj_(MfE434y(^an{bpl0rJOEnEb2*ZTqJ@6g5ei9y)7JRz7qZ>8lsrTX^H->^x+U`XHz;80cIwHy4^AR77~PkT<)cpueXbY0t+RyJxw{X^gU1jSRR4Ony&?m7~S%Er|%P2*lx0P$)H)G6LT z#7KS`rx+rCU6*ln3Q@s?Eu>Vy%xq@uz@ZrU1qyRL<8Gw}#EgTtO-cMDq3OELIQJAs z0_dq^3-*)X(p1qEX!vL7mFpmfB7!uVCNRB)3j2gQR3X5kAe+eWSO&O3_&}t_Q7)&F zeiGh9K?X~s770Ud$wScs{6!ep^arKA0jo_1u&3_jXf8*!nufT+M6v+@ScD2^z75w%-C}o&>2=PG}LpE&%$WWmwVFh|NVLn~9`OfeUhbs<-%AWP$X3RKx@- zYM=N0XLuu&TXIXNJ$(sPf-ej-c+IK|fK0;#O7!z+{}z80ZsZVsK;e}qXj*DV;bAO^ zX)}%-;XJ<>JKZUb8ledE1CaHchk4vV8G2YGen7^FHgb;LUqxoNZ%ONE;g0z+Ey{;A zZ=$rDkaQCK`+~frq52v$b8wvu#Xd@D0?(#o1}VE8dVYk__!<)(THVpF0>r z_bAx*jtQlwnYT;DcmiW-b8IvA`wHRL6OdR8d=<&adV`2|2OiQD3M0W=0W#S)U*tZ6 znonujsmr5!UljrPvu+MAxes06$3PxI{ze$Jzt2ARUz{}!&Y~z;LN&p`ldVMujJH6h z3=rcttOF*;6k@CnWv>*+UP0V21TQNv_@ zDgYXpkmJ{OkOzq5T?Pw0!W{>(+bXF|f%jriZv(|X zl5{F?xG=A>```=rOUZqjoo_vWeq{Jg|FBiC%O=y{Wf!`oP%tcZb;(7r4+mEQL_z$T z{EeP9h_W?ifVyHy`b?nWH`OE;&}fK3Aho5U7~}+y&e?(=AtL)Z&olZH-_qa_>5xn^ z|0w5;)U@xi3`%GcQmq_amr)gTkDC7uoWbCi)OJfI3jR9GjvXzc&q`UlL(|BJHrnVC z^8%Xt7_&h~m6yU6W+{RhiJS>&1{q#W=Iw%wPEWnw))FwR0B*q z9zrGXS6IJInqKZDA>?k%Wx)a{CIxl)1JpADm8q(d&hum=ZzIZlA4&CFvH@lB#;Ya-c$nZ zuY#g!i0Mn~(fj<9cmYd&osT$yCMIOp#&B-NVGp9`=q1)ihB=a;45shunkm>r71(Vs zvIRfN0eudEHen`K!M?(vY96l~R(WVRgXT;#{-i1xw8Wwbuv1Fl0+K?KufMXJE z7{3Eo5~#+AdRHB^AC@BAr(R=1y-D!+#9xJR`f09$EZyaeqn>^ViB1Gq8)xq=>SO{| zc5_H9vdn0Ps<(jOE6c}`>#mqV4dRh)19j~g|MPVA>B-t z6$~jFp|9jLGIdcmh~c{|bfql7BY)cSXIpvYRRIYuxJFS^;gqEN;!OF@FD>yI8S{V3 zgo9gKPvkWJ{SQay;?LCo`0?E@HoIZwJ`8iev*}7+wNy?zhu<31ab;sePxr86=O?EuPs#o@`D4|3PHEF( zNy*kc{c{-wS%{}vtu9HdgqXF*YIgfyb{Ca=I`h>oDx+FN1FGQ>f^ZbhO`u*KKmS(p5Gmx+W9FOkV&$9BW z%OpikeY~h_)i*8@`?2N}Tm7P`=X@*UYedS0&ViOfh8MNckMBQ17yHq4ieh`bt~9LO zKpPj?n{bS^i-jQLEx!pbW+ARR;rgGF38fd__G(~mWns+ z=IhrQD@U#C>KVtH|RQ+mIajtek?=ETdymQ`L7m6 zi8>*(ZyUZc=>Z1Gx`+~ z4B#aNfA?dV%6a#zbCq4>T>fOM9+<>isE|un#^ub>CI%{z3}B8uChDz>gJk&An0BZp z7U$MFB-;sMqhgTm`yuw5E~LL7-&)F5|CXW360I`SM046jtms6dcOPpS=~c}nbI(L< zyzp_KsA)zX(^WX1&OfO6FLmo`f>D>4_vJuwiS4g>+k@XwJ@dRgCL>GvuC>Bn>J-AQ7di49H6XPHK!DabNAU|;E_PX0_v2XBrxZzEjD2fN*|+Qx zzPLT%BMa`dwpFLnik2;KQ@b_Xuf4I7?Z)RS|I9@(yH;~IKeTkJ97khLt(*yPk71t( z+-@~lfr>owKy6WQ0p>7^7ktkv#&XW=lDw+NCw5iP$Y` zRso=qky8z6;#rK}il2K=O+hS0SM>)smpL3*{~%o-(<~D-S+lee7Pu(7oDNrUR(P>X zXtinTScO(9r_dz9U9D-V_lToj52qinspmJ`m;n)=UYW%`>BmHg4so?AIMt!W!PaI0 zu=3Fzuzh_67(P2Iz&V35Gz=kTT)uhtDFA9P#Zl}o!5kTMS36GwqaJ0QPw1S6?2rKs z({3nN)Pq$dDf*);0+@9Y5EV{yQ%A2>*18+%$AWiQXV7!q`n6?*4nvhOHoSrZ*Llf; z5|0RER69@adwF9SS=lwDwaZZkRC?IvY2L^$-ubAH84AwqXC2RMS`5Z;QTK1F9QwpR zvH5pE``B~H z3Ox{F^m-Vg>_^kR9%Nymtgg~LaWEfUtlLos)dQFPP&!SSBN+NfTsrIp%H$hJuEonU z-V_a{e{W+vqfeuIuAr3xO~_suZaH4t?Sm*WjxM?HHij=?#jdEmLwv3`DHE?XgO$_# zcSa`(nsi@0u{!GS(MG-p*wTM5SG!TQAfqoCc(*e-ZKn=V!e?8k)M>w`WdQ zek(m`lVb#b<_*?K;@WvVckz?bvV8rO)4=(I)OuExa!SClVp*Z2-aw0qwj$N$!OSDa zkW^Zs@T^2SszbTMmNL`q@+80@^S7jUQ@|p`F#)-G zrK}OjBRaLSM_#5Qm=>RS8l_=+xe_{-Kh_(Az?HTe`m0_&wDm^AWJ+8`M18w;S-g6m z+7+rY&PGP?`3;aiyOMWfSR4H*=yDTVQ;W$vD{dnudpdDA^7WT^1a+X&qJ+V8=VTH@ zm+Gu0mi**)Jd?V({Jgdh-sZ_oLmGU41vQ}o!z1puM&x@I=DhIQZguKYO1n1RuNwgz zEgg&Ku2n3K@h~f_xk4H=7`K`&V3{DUOeLlmQBHd-I0oeA4jrD3X%cuKsF_!@t1SoF&-qxJHyg=<}XZ@~^8n%@qKp4{jaLzgJ3 z^DU5Cl(CO=tdDFdW%U`6oDz!Xx$=JYz-wn|FlTh0J4S_Uz5)o;m@k0(@Oc^Ybtx_H zB(L9n=O|#TE@##Ec`@xd*I@r*i7ah=mq|-aolN`UKZ79slw3Y9fO$~nEK^TS7XFiT zpDUGmu$oP#d=pdW-w7aaCmAJ^*+vsl*C6p;Ky;vJfxBn+$uCd1nbqpO%A6nMXFd>-)we7;Zn?b4z>$Il8vK6Y&F(~19y`6(&_-{;RI@z(|_Mk#7 zO0iOt4-Q*_ZOKJPlB?UrNL7bC;uJ^0-vFCedRmlWN>yJ%RN6f0&{_dUSXgHiV*>eL zLx1HC(Y?AS)|w37$P4qfX;7I_=i60{X}mE?+xT1wN0HC@^(kME4BbCQlek9}n>H6u>-fjZ-DZ>(^fhBGI9$o0q!y?D+A22jZ#sKOBFF~C0dusB~~ znjqg#2)4E0S>m?ZQk`QLX?X;4Dj8~P&#|AxA1eXs0Kloy{3Bu6ETQZgfDn3~7L#kW z1`Zgz=PAjw2N*ghI@_|K230sv_ZjF6TGK+^Rt)`n94!@*>|B^2VtT!j4#;^pGnvUR zX2RR)V56xa1%Iy_nH*!bD(sSFlESVp}Q2?R`;Z7zYBjbyG$lTw3VmHKv_Pi|bsb2duoY6eUzpKZo zA80rQjy`BSrVT%^qFpv~zQn)3YFg{E(CoTX7LDBOHPIyzP);Vf?El!}n@&tLMAzhi zcTS-cf~bazHeM5E#AP5+z@;-_X@Jf>GawBM8|8Qs+Jxie-y64@703V!K5?|V3hxG> zHM)HD>&zfkxg%4I>BSsX|D3x~NM}Tr6w2i%`)67=IKm7Soq}#!P&DP_^4W7aLwD@r zkSKq9T>E!qnh%YvcG210zGN|Pr+>y~M8>yy9{nZHr6I#Dn&>YoyR(E;@X7C&>(*^> zkc4F?v+DJQHwpGYBEV4Qu8F{T)g8&za~|HhXD#yD68I1J~- z2-UaC=RKkcbYg)Pq|C?OE*(r|ixg;yPEd7)oV_*%i=cu7D6J0tIpAD)q2UvUqV{10~J>| zrtwPB8VcMZ*pOpkvpX1Rp{Qw@W|!6IR@R{BXIdm8LB~pZFHCD(SZi}ye)J7#QapJn zzROU_t4LAesFADt9|c*x7OFOr^Iwz-afRce(=m1+Y4w^k`>1 zh!hXp^tvgqpUe!+j_BfHsX#@*DDBeCO~V;iQk-fc>h-2Mwm{_dmpO(FQ^{hen}B<& z2?+g_{j4{KNCgM67-`kHepIkc6p2J_J^CJKz%IHW_yD>^Tvh%O=(-{-f}kSFkcp*+c2~k{d$4<^(wlujr#Yd;8tvFBq?x^V@U#4R zF-H%PVZKz6cb7MHM@LnxRVKP_O;$Pb3ZsJ{7|UWv&eueR%yyH z#p^cW6l?2gvCADXbC->1m@tBabgdTXwmleB;}w z<3?FAQd#3zlKp4aVFAohO>tr0SQO`ekbw{q%P(7ZCjC&+>LWi@nBEzbqsxxt{C7!6 zZ{c*TdEL#(Z=!>LY-$=jZ~oRqTdUz#&37k(ks{>~?%fLWh(e##V4-aP-={;yP+LXZ zewnFAV&GxYQyC=2l!unCluXIMg}-BJnzfGV+TXK^?l;ob9ELRK^*7?O5XVVQekkG; zIFgEQIw>?+H2U!UWs$bfQXBr#lyjP?=6(=Zhk6#vuCdI?mpKFjoD~N*6DXu|)*|E+ zRgoC4Q0Jz3KAxl4XCvkS zb1Q@8hZW&oVaGVk+I!hc;bu5U1b|}2LX~TCZ(3k1bCAEu>dwV(4oTOsjMV=Rz$B;j01> zhYN-$Fhu*OeR(;!P2iJ3xIc$ltR8~4#6#$dpfc7uE4EDflFJhFK8Z1X78l-1Xa+23 z2-pfu;ci7dl5ctLC*XdrD1w?e_L2As7Mu5X)$>IfOH(<@BA}97{%mbgrvT()QTc=m zwOr(c=WN}=yq&$$O%rhQHPDpCCEKEUr|C?eME=#4{QW=V6HPdjM|bn1IpN2m=Oi>D z4ZO2qw4$q0tCkG?{^{P~3hZ#k*)hag9uKA6syNNk2z_+st{~uH&ex)5g%qycDaHL$ zH;+uBDY~tVVvxZ0*x6 z=j}xt1sxCgfDm?EG1VV>WWH>NUvZCoVeZ`ABUPT3eGO+thtdYLod$1N1a&=a3T(Zm z5_;X3y{YMqr@sX_=JF?sSDrr0`@}&#ixqjL6hRr2>yFqHa0FkOW$b?f%g2L&V87+(6Q=kXifZfp?MOK~`0PH5teEch3+kw|v zL5Y`GmtSiba0D3?N0S| zjK6Z&1NNEr)5B`${m}K$L}#F`$CJFchF8pzJ#nF(HG`Mf7fu|C?R}BsC*e+6$*|+R zM`N5mdqq_T#eaG~o=n{0MvD2zs)I?luUDfDHYr_==$d^1?Fi_s!>&aQ zle1Y}yiP&**v8dOS^PHdWrIDY2Cjz(8+ zZ)SdqUf#P_tNGPh>96A))%PjN_D7+2b8M>4AO*5q1u)jjOj4&y9auvRIXLDH#BD1b{7vxrXe2 z%m6%VAEpaFQZB&83No5@t?IFp@Y8@|w;Pa za8Iry-c@Wd*t|uH`bFJvmcz(1<+n6P!Xu}_Ka6KFJ^u>zo@z|-q{pmw5i%XPX}3n_ zekYzZtT-awk@LW#uk zW4h=g)AjT`_wz42FRS1*X#ZG>B-;0KGGsHM)cz0_uVT$0QbKu*E3pbF)sspe`p
2Wbk%FRHS*i4ROb6>A2u0nG(7O!IyzGvW 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�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
8^@*y_m&@#u>D`HJg^%7gyw#s1PK#g#vu8;(wn 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 HIA*p* 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 C@@Xdk literal 0 HcmV?d00001 diff --git a/src/settings-ui/Settings.UI/Assets/Settings/Modules/VideoConference.png b/src/settings-ui/Settings.UI/Assets/Settings/Modules/VideoConference.png deleted file mode 100644 index 028d98889c62c79590220b7e7aeacfd46ced6fac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55499 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 diff --git a/src/settings-ui/Settings.UI/Assets/Settings/Modules/ZoomIt.png b/src/settings-ui/Settings.UI/Assets/Settings/Modules/ZoomIt.png new file mode 100644 index 0000000000000000000000000000000000000000..c4fb8b00f6eec316675c9b952109dd76327dd4b9 GIT binary patch literal 23370 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 Vt+_>11dxAy!ra6LQ;oh9|6eg7(;ff- literal 0 HcmV?d00001 diff --git a/src/settings-ui/Settings.UI/Converters/ZoomItInitialZoomConverter.cs b/src/settings-ui/Settings.UI/Converters/ZoomItInitialZoomConverter.cs new file mode 100644 index 000000000000..2107caa39147 --- /dev/null +++ b/src/settings-ui/Settings.UI/Converters/ZoomItInitialZoomConverter.cs @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.PowerToys.Settings.UI.Library; +using Microsoft.UI.Xaml.Data; + +namespace Microsoft.PowerToys.Settings.UI.Converters +{ + public sealed partial class ZoomItInitialZoomConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, string language) + { + string targetValue = string.Empty; + int zoomLevel = System.Convert.ToInt32((double)value); + + // Should match the zoom values expected by ZoomIt internal logic. + switch (zoomLevel) + { + case 0: targetValue = "1.25"; break; + case 1: targetValue = "1.5"; break; + case 2: targetValue = "1.75"; break; + case 3: targetValue = "2.0"; break; + case 4: targetValue = "3.0"; break; + case 5: targetValue = "4.0"; break; + } + + return targetValue; + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) => throw new NotImplementedException(); + } +} diff --git a/src/settings-ui/Settings.UI/Converters/ZoomItTypeSpeedSliderConverter.cs b/src/settings-ui/Settings.UI/Converters/ZoomItTypeSpeedSliderConverter.cs new file mode 100644 index 000000000000..61208b00b353 --- /dev/null +++ b/src/settings-ui/Settings.UI/Converters/ZoomItTypeSpeedSliderConverter.cs @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.PowerToys.Settings.UI.Helpers; +using Microsoft.PowerToys.Settings.UI.Library; +using Microsoft.UI.Xaml.Data; + +namespace Microsoft.PowerToys.Settings.UI.Converters +{ + public sealed partial class ZoomItTypeSpeedSliderConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, string language) + { + string targetValue = string.Empty; + int zoomLevel = System.Convert.ToInt32((double)value); + string explanation = ResourceLoaderInstance.ResourceLoader.GetString("ZoomIt_DemoType_SpeedSlider_Thumbnail_Explanation"); + + targetValue = $"{zoomLevel} ({explanation})"; + + return targetValue; + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) => throw new NotImplementedException(); + } +} diff --git a/src/settings-ui/Settings.UI/Helpers/CHOOSEFONT.cs b/src/settings-ui/Settings.UI/Helpers/CHOOSEFONT.cs new file mode 100644 index 000000000000..026a9f01a192 --- /dev/null +++ b/src/settings-ui/Settings.UI/Helpers/CHOOSEFONT.cs @@ -0,0 +1,70 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.PowerToys.Settings.UI.Helpers +{ + [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Keep original names from original structure")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1306:Field names should begin with lower-case letter", Justification = "Keep original names from original structure")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "Structure used for win32 interop. We need to access the fields")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1805:Do not initialize unnecessarily", Justification = "Let's have initializations be explicit for these win32 interop types")] + + // Class to select the Dialog options to call ChooseFont. + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public class CHOOSEFONT + { + public int lStructSize = Marshal.SizeOf(typeof(CHOOSEFONT)); + public IntPtr hwndOwner = IntPtr.Zero; + public IntPtr hDC = IntPtr.Zero; + public IntPtr lpLogFont = IntPtr.Zero; + public int iPointSize = 0; + public int Flags = 0; + public int rgbColors = 0; + public IntPtr lCustData = IntPtr.Zero; + public IntPtr lpfnHook = IntPtr.Zero; + public string lpTemplateName = null; + public IntPtr hInstance = IntPtr.Zero; + public string lpszStyle = null; + public short nFontType; + private short __MISSING_ALIGNMENT__; + public int nSizeMin; + public int nSizeMax; + } + + [Flags] + public enum CHOOSE_FONT_FLAGS + { + CF_SCREENFONTS = 0x00000001, + CF_PRINTER_FONTS = 0x00000002, + CF_BOTH = CF_SCREENFONTS | CF_PRINTER_FONTS, + CF_SHOW_HELP = 0x00000004, + CF_ENABLE_HOOK = 0x00000008, + CF_ENABLETEMPLATE = 0x00000010, + CF_ENABLETEMPLATE_HANDLE = 0x00000020, + CF_INITTOLOGFONTSTRUCT = 0x00000040, + CF_USE_STYLE = 0x00000080, + CF_EFFECTS = 0x00000100, + CF_APPLY = 0x00000200, + CF_ANSI_ONLY = 0x00000400, + CF_SCRIPTS_ONLY = CF_ANSI_ONLY, + CF_NO_VECTOR_FONTS = 0x00000800, + CF_NO_OEM_FONTS = CF_NO_VECTOR_FONTS, + CF_NO_SIMULATIONS = 0x00001000, + CF_LIMITSIZE = 0x00002000, + CF_FIXED_PITCH_ONLY = 0x00004000, + CF_WYSIWYG = 0x00008000, + CF_FORCE_FONT_EXIST = 0x00010000, + CF_SCALABLE_ONLY = 0x00020000, + CF_TT_ONLY = 0x00040000, + CF_NO_FACE_SEL = 0x00080000, + CF_NO_STYLE_SEL = 0x00100000, + CF_NO_SIZE_SEL = 0x00200000, + CF_SELECT_SCRIPT = 0x00400000, + CF_NO_SCRIPT_SEL = 0x00800000, + CF_NO_VERT_FONTS = 0x01000000, + CF_INACTIVE_FONTS = 0x02000000, + } +} diff --git a/src/settings-ui/Settings.UI/Helpers/LOGFONT.cs b/src/settings-ui/Settings.UI/Helpers/LOGFONT.cs new file mode 100644 index 000000000000..575f91d117d3 --- /dev/null +++ b/src/settings-ui/Settings.UI/Helpers/LOGFONT.cs @@ -0,0 +1,125 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.PowerToys.Settings.UI.Helpers +{ + [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Keep original names from original structure")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "Structure used for win32 interop. We need to access the fields")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1805:Do not initialize unnecessarily", Justification = "Let's have initializations be explicit for these win32 interop types")] + + // Result from calling ChooseFont. + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public class LOGFONT + { + public int lfHeight = 0; + public int lfWidth = 0; + public int lfEscapement = 0; + public int lfOrientation = 0; + public int lfWeight = 0; + public byte lfItalic = 0; + public byte lfUnderline = 0; + public byte lfStrikeOut = 0; + public byte lfCharSet = 0; + public byte lfOutPrecision = 0; + public byte lfClipPrecision = 0; + public byte lfQuality = 0; + public byte lfPitchAndFamily = 0; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] + public string lfFaceName = string.Empty; + } + + public enum FontWeight : int + { + FW_DONT_CARE = 0, + FW_THIN = 100, + FW_EXTRALIGHT = 200, + FW_LIGHT = 300, + FW_NORMAL = 400, + FW_MEDIUM = 500, + FW_SEMIBOLD = 600, + FW_BOLD = 700, + FW_EXTRABOLD = 800, + FW_HEAVY = 900, + } + + public enum FontCharSet : byte + { + ANSI_CHARSET = 0, + DEFAULT_CHARSET = 1, + SYMBOL_CHARSET = 2, + SHIFT_JIS_CHARSET = 128, + HANGEUL_CHARSET = 129, + HANGUL_CHARSET = HANGEUL_CHARSET, + GB2312_CHARSET = 134, + CHINESE_BIG5_CHARSET = 136, + OEM_CHARSET = 255, + JOHAB_CHARSET = 130, + HEBREW_CHARSET = 177, + ARABIC_CHARSET = 178, + GREEK_CHARSET = 161, + TURKISH_CHARSET = 162, + VIETNAMESE_CHARSET = 163, + THAI_CHARSET = 222, + EAST_EUROPE_CHARSET = 238, + RUSSIAN_CHARSET = 204, + MAC_CHARSET = 77, + BALTIC_CHARSET = 186, + } + + public enum FontPrecision : byte + { + OUT_DEFAULT_PRECIS = 0, + OUT_STRING_PRECIS = 1, + OUT_CHARACTER_PRECIS = 2, + OUT_STROKE_PRECIS = 3, + OUT_TT_PRECIS = 4, + OUT_DEVICE_PRECIS = 5, + OUT_RASTER_PRECIS = 6, + OUT_TT_ONLY_PRECIS = 7, + OUT_OUTLINE_PRECIS = 8, + OUT_SCREEN_OUTLINE_PRECIS = 9, + OUT_PS_ONLY_PRECIS = 10, + } + + public enum FontClipPrecision : byte + { + CLIP_DEFAULT_PRECIS = 0, + CLIP_CHARACTER_PRECIS = 1, + CLIP_STROKE_PRECIS = 2, + CLIP_MASK = 0xf, + CLIP_LH_ANGLES = 1 << 4, + CLIP_TT_ALWAYS = 2 << 4, + CLIP_DFA_DISABLE = 4 << 4, + CLIP_EMBEDDED = 8 << 4, + } + + public enum FontQuality : byte + { + DEFAULT_QUALITY = 0, + DRAFT_QUALITY = 1, + PROOF_QUALITY = 2, + NONANTIALIASED_QUALITY = 3, + ANTIALIASED_QUALITY = 4, + CLEAR_TYPE_QUALITY = 5, + CLEAR_TYPE_NATURAL_QUALITY = 6, + } + + [Flags] + public enum FontPitchAndFamily : byte + { + DEFAULT_PITCH = 0, + FIXED_PITCH = 1, + VARIABLE_PITCH = 2, + FF_DONT_CARE = DEFAULT_PITCH, + FF_ROMAN = 1 << 4, + FF_SWISS = 2 << 4, + FF_MODERN = 3 << 4, + FF_SCRIPT = 4 << 4, + FF_DECORATIVE = 5 << 4, + } +} diff --git a/src/settings-ui/Settings.UI/Helpers/ModuleHelper.cs b/src/settings-ui/Settings.UI/Helpers/ModuleHelper.cs index 0d8945cf550d..f21ca2bfac8e 100644 --- a/src/settings-ui/Settings.UI/Helpers/ModuleHelper.cs +++ b/src/settings-ui/Settings.UI/Helpers/ModuleHelper.cs @@ -73,6 +73,7 @@ public static bool GetIsModuleEnabled(Library.GeneralSettings generalSettingsCon case ModuleType.MeasureTool: return generalSettingsConfig.Enabled.MeasureTool; case ModuleType.ShortcutGuide: return generalSettingsConfig.Enabled.ShortcutGuide; case ModuleType.PowerOCR: return generalSettingsConfig.Enabled.PowerOcr; + case ModuleType.ZoomIt: return generalSettingsConfig.Enabled.ZoomIt; default: return false; } } @@ -108,6 +109,7 @@ internal static void SetIsModuleEnabled(GeneralSettings generalSettingsConfig, M case ModuleType.MeasureTool: generalSettingsConfig.Enabled.MeasureTool = isEnabled; break; case ModuleType.ShortcutGuide: generalSettingsConfig.Enabled.ShortcutGuide = isEnabled; break; case ModuleType.PowerOCR: generalSettingsConfig.Enabled.PowerOcr = isEnabled; break; + case ModuleType.ZoomIt: generalSettingsConfig.Enabled.ZoomIt = isEnabled; break; } } @@ -142,6 +144,7 @@ public static GpoRuleConfigured GetModuleGpoConfiguration(ModuleType moduleType) case ModuleType.MeasureTool: return GPOWrapper.GetConfiguredScreenRulerEnabledValue(); case ModuleType.ShortcutGuide: return GPOWrapper.GetConfiguredShortcutGuideEnabledValue(); case ModuleType.PowerOCR: return GPOWrapper.GetConfiguredTextExtractorEnabledValue(); + case ModuleType.ZoomIt: return GPOWrapper.GetConfiguredZoomItEnabledValue(); default: return GpoRuleConfigured.Unavailable; } } @@ -177,6 +180,7 @@ public static System.Type GetModulePageType(ModuleType moduleType) ModuleType.MeasureTool => typeof(MeasureToolPage), ModuleType.ShortcutGuide => typeof(ShortcutGuidePage), ModuleType.PowerOCR => typeof(PowerOcrPage), + ModuleType.ZoomIt => typeof(ZoomItPage), _ => typeof(DashboardPage), // never called, all values listed above }; } diff --git a/src/settings-ui/Settings.UI/Helpers/NativeMethods.cs b/src/settings-ui/Settings.UI/Helpers/NativeMethods.cs index c895866c1ebc..072f12b00cd3 100644 --- a/src/settings-ui/Settings.UI/Helpers/NativeMethods.cs +++ b/src/settings-ui/Settings.UI/Helpers/NativeMethods.cs @@ -48,6 +48,12 @@ public static class NativeMethods [DllImport("Comdlg32.dll", CharSet = CharSet.Unicode)] internal static extern bool GetOpenFileName([In, Out] OpenFileName openFileName); + [DllImport("comdlg32.dll", CharSet = CharSet.Auto, EntryPoint = "ChooseFont", SetLastError = true)] + internal static extern bool ChooseFont(IntPtr lpChooseFont); + + [DllImport("comdlg32.dll", SetLastError = true)] + internal static extern int CommDlgExtendedError(); + #pragma warning disable CA1401 // P/Invokes should not be visible [DllImport("user32.dll")] public static extern bool ShowWindow(System.IntPtr hWnd, int nCmdShow); diff --git a/src/settings-ui/Settings.UI/OOBE/Enums/PowerToysModules.cs b/src/settings-ui/Settings.UI/OOBE/Enums/PowerToysModules.cs index 9b0440ceea51..fbf689b9ded0 100644 --- a/src/settings-ui/Settings.UI/OOBE/Enums/PowerToysModules.cs +++ b/src/settings-ui/Settings.UI/OOBE/Enums/PowerToysModules.cs @@ -28,12 +28,12 @@ public enum PowerToysModules QuickAccent, ShortcutGuide, TextExtractor, - VideoConference, MeasureTool, Hosts, Workspaces, WhatsNew, RegistryPreview, NewPlus, + ZoomIt, } } diff --git a/src/settings-ui/Settings.UI/PowerToys.Settings.csproj b/src/settings-ui/Settings.UI/PowerToys.Settings.csproj index 3b695d5738f6..9d71b62de7c7 100644 --- a/src/settings-ui/Settings.UI/PowerToys.Settings.csproj +++ b/src/settings-ui/Settings.UI/PowerToys.Settings.csproj @@ -33,7 +33,7 @@ - PowerToys.GPOWrapper + PowerToys.GPOWrapper;PowerToys.ZoomItSettingsInterop $(OutDir) false @@ -91,6 +91,7 @@ + diff --git a/src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs index 6fd49a5cd7da..a9a73eee0824 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs +++ b/src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs @@ -441,7 +441,6 @@ public static Type GetPage(string settingWindow) case "FileExplorer": return typeof(PowerPreviewPage); case "ShortcutGuide": return typeof(ShortcutGuidePage); case "PowerOcr": return typeof(PowerOcrPage); - case "VideoConference": return typeof(VideoConferencePage); case "MeasureTool": return typeof(MeasureToolPage); case "Hosts": return typeof(HostsPage); case "RegistryPreview": return typeof(RegistryPreviewPage); @@ -451,6 +450,7 @@ public static Type GetPage(string settingWindow) case "NewPlus": return typeof(NewPlusPage); case "Workspaces": return typeof(WorkspacesPage); case "CmdPal": return typeof(CmdPalPage); + case "ZoomIt": return typeof(ZoomItPage); default: // Fallback to Dashboard Debug.Assert(false, "Unexpected SettingsWindow argument value"); diff --git a/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeShellPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeShellPage.xaml index 4ff7d4fd0d3a..d3f3d7e2572e 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeShellPage.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeShellPage.xaml @@ -161,14 +161,14 @@ x:Uid="Shell_TextExtractor" Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/TextExtractor.png}" Tag="TextExtractor" /> - + - - - - - - - - - - - - - - - - -

oG1@ByHh)U zU(75k&BI#%%)6o!#^z;W*7}MLQ!4JgI62YUC?_w&YIPrk{s+Zwn1~%*8m2vrd;d7< z`g-HA-Awq{9Fboer81)QAxTsD%uAN|Lk)MKp9=M_WX-i2QlASbm?u8=X$min=<)Hja1rcQzus172h;N=hc?ll!Sii9j>Uh5otn>i}%&Pzu3-$Oc#qiS2^ z6HQmTHtfC4w|Or1<~PCa3ZG6K&=NT-v3BM9-5`ap*Ck7u90ERw1#g&K$BK^k0bqrR zoa!1;^gaFR+^n%k=)S+2{=PD7}A8 zSssNF)dl|qNjE4Q3$uRWM8B`(&clwN4)N*c_DqC~vMy$mq_DtlO>*0R>;!5`$_wmJ zY%#NS1VpmauyYP9eo?9ubGZe5nCRfj;rGT{?>1SEuESCs0nmfFejEy zhOZ#XCuQtHoSh9{Z;u5VX6k!KIh`&a&cW>AQe~ZE540+Z<@lgl*!zD~Io38YS zb>4>qAf3qv%khL@*4#Fiq&V-wxNy{}S*B}}8;IXKXJ^RM@y>H2?KOJ>{pWqzzdg?X zT4p6869<-vX6M=0PI@rdSsIo@2*3U&$!^A&&e^XpC&1&FDlE(nJB&R`9uezjXvy{n z#iwAiRNw-YHhc+Y%A|R>%xCEYl@_@C8WLj)u6r#BNP399ND2#NXzG)HyrKzrLz}2R zFO<*c0z~SuFbA0kkwdu58{e`(I$ou4FJleeyDnM&UEeBN)a@}slP-LN%Ux-~S5>9+ zaPE7Ln%K9rs2beOb&;RPBhwl0l(_34Y`An;T$zYvEO;P>d$mNd*+UJGu84e4*|)IL-I$emgDauBTfy37+5elVe0F;Ot< zZA{XNS-IRO6`mOtrK3}ON!n5Zad)XH>&vLJl393RmQ0rNMcLMjEvmcj3QcE$4NIS) zp|B@j*qH{^%Q;S>zuIOgzr|%M{}G2-QfU~a=i@r61c(@NNdl2Kclp(>szdX1oNy9M zXX^{gG9XH!>BKz^{Q`$TjH6rv`w{6!F6NM}n&YD!zc47j3~pRA`M;Pu54R@UEnkNu zkkCRX(o5)}N)r$f5^6w15JW^oK%|K@ktRYCI#L4Ci?q;tktQm=sThhHPjpX z0(_jEA|bW2m??$?Rwd&ehObGo`jc6>y8sdCPi38zH_Eu;>mv|rsC5q#5_9@wM*Dd&9WuO zsa~($brx7W=;{1e3PZmOv(Cf0-5$9M0VX(evh~W(w^H3&U$&FFU)bh5?sT!d-HFfN zm{8ms4L)UUrStLXbsi#MAZGZ*b!BFi-964+X+PKbM6x>dPa!;GsrIjSqeS<$Nn3FDcso_;-bBO)JSI-l7y+P$Z{Prrsz&MY3lCRwppmn-Lk%wIkVeB5-uMW4Rt$@zYt z>p%VH10{_YDav&RuYOxFDVmT=1f5>Pkkzd6{dZ3MQi^{)!|-^_}%?}?a(1ZtxKJs|1yspC#D9@a-u~CAk*_?D z_Hft1^TXiu1xle1WcvMX5Q1r-fN9iz3%B?qVeu91wf!&jl(g%0+g67aLd-B>R?b3J zEdevy6HC7+j~ITvVUspyZ_K7=yPp5eerJ1@a%zE5kZQp!&5&0qjY*FfMk=*<;olVMnAFRYPVX(IugGA9m78a=_ATKDYB=O-pn$_hlK*m&9 z(%(#BK%|P}#*mb#s&lbw@VrU+a(Rt_%KWVM(J~}xncwPzEboWk7R;97H&0PN=yCnH z{0agk?(ADmt@&ath8whv4D^%l1rm$Sz{Jp;D_z4_<`B^eIk7)1m|}VcV!GLY3R)Wa zY5+Zw6)Ki{Sd)(q6~jb{HTwwgr4x-FQF9K7#2&Q;FS{`1Kzp z*N?^R=}PTk5)PcD4uTSn5~Ysv5;s&!e_JpON}Wt4Zd#Szw3BdlE_L>laPcp738hH5 zMwPlIO1Pz$x;>Jh##g%6O5AEGz4c7OW1!SyRO0sA(%bVAo}WrRwR$zX|+APw{2ma_A;F6`}PA$YNn`H_(MGW1(&m=PrOhotIfmk_~{Fc?w_xE92Q z#BT}vaU;XWo$y*npuB6i>DmWWd1TK*jfnuqc~?Wb^5|#Rb6wX=yj`P1%VSNiN5vsy zYgc1ikZX$9ifWJ#I*FS`Y?OY!B-h*Iny9K&W(U8I3ai=aRCASX;aogIooR(cA3uOi zNkFFj(oIQN%ZQSC#K{kn#c{{bAcytn90+E_Zsbuf2Y{Bj56f(i=F05mI6@WE8vYhl zn$Wy)py7toa6xrMp*@B2Gy-Bh!u2$|tfsM_q$+{AOc$1pJ7tj)X0+uCY5f(xuW< z=2`a%q3Ry(Hhi`X3$wj_ZXcT=p-0daoTrKwkM9xA#PRS`@Xe)T+D^<=EhA@rw>Z^# zN$NtW^hi0yFk`?{SRE0Q?jb^tE?7T@GcnM&s?X}3j!}zRSkxwaqrV7Hs) zCIxeWZI5&iYlefc=)7Yrhgk&=f2!K|TfDY!%;E0hR5zcWj%1&yIlr6`cra1cwtWEY zpUc85iE*^o`I&~yeaG_oF96p0A)v^M)7mx=Kq%6*LKa~Tk zBPolcN;D+^)ns4523Rxl<>H5Tx<+7;7kp~H>*bI!xQ{a~At|-HFh1J@ z%VZjN@61>4Z{nsBhjYM&;shPut|*a9o}wJ=X&UhtzTnbr2goCsKC@Tj@AkOYg4|EpzFxK7LU()Z z03p9dYPosBRd+jS8o0AmFYk(WjySlr`HjA%U#U+V36au;XcrZ5rB-?!NjH*k13 z`Bg%PwpUgP+x_DZ31RVp+_cP{qp-us-AE4iym}f&SvDa*pj5n0qXp_;aw=EqDcsuA*p7?8}{Aq?j&CChYYr(XG0ozJNK5j)4yipaR za$LJ~QWYs9M8%VL@)5gnR!C(-3?6i!Xqnbjg5ug}exV*+t8TF5z{#7|ubpqH&X_w}16-JKbgYa^^z zqiUK}&y}Bkq5Q4?%i$~Kvo3B$=_q-AY46Q)b4HgrvG2Vq-9lVD90;0k5|hRc?qYdw zJf*2Iw|=auo5+-kJ?BlsxQW_?u3g@6wqAH2|0^89zrmp_FMzQuJN0~tE2Nfdh~x>-w4{MGbq=!MLFOP@Yfzr~45(O2BmT2e-+m(m`n#q01lvtEDl z-BeV;0jbXo6;TiD9%q&rhZi>O-3h0m{c|=n~=^ z9SgXf)STI0x;^w`S8ToJq{CZJwGT7ieXh#w*CUmSe^*<(v}lo?h`!T*(eOxyg@2Gs z*OP0735lxZxZcCDh+=P+d$Nd{de+k@rtmbb`)cy}uv;6x834Xi0Iw4s&9jf2aAqQH z;3=SpHqUgOeW_G*g$RXf)=I~l)GZA#x=}qYOvZ6jEufo2g1Hy68@q2}Ws&h;c{XH2 z4q6X~yI}iR7Jf7@;quv!`yS7*UB}^7b~@r&?y3QM((&lzDbz=i(=bxEOiZXw;sGWo%unai8~cl4=AfR@F6YGRkP6|lF|G}=pi;7%$^1rBl}KJ$2^nfV*RH7`HsUYS>bNMw@a~90dX=_ z2W*l_?e32sPi14pU{V2e4XiaC)F6`)Ii0fkG>^YsQC| zpTQRxpWODPU>ctQbZY#Xp7)fC@~}c>1;DhA^IzXN%hEf5=EZKlLQDz9v!r>TlP!TS z=S}*00?%DPRomSBOXKmADd#!ssVGOgrhGiN7>{p5w+vQ?^T_l$WVd^l238MX!P2bs zTx6=pJ(tkQ@e7EG@7YO}VeV`&W>O2QFU(& zke^gz*4fo+b-;pDXnh?KW>$qDS@IBc_8QUN>O!v>`OKN@$5xw8t2LSKu8l1?<8Ny= z@%3~C%SkDyH$Fk7R8=sjWbnlI)G+{)pB3JhSGrA^q=0 z8#!ZFLvJk`uWzhLf3M5sODbTXE#OOHsJ~Lg!@_EIayO^SmTz=x_gToHmd_k3?tZ;D z$MfwQ)06ZW9mUFX7L-WXQ}yTHAFwMQJXyP1=R+D@;haA{Y(+kK@%<>w^;hf9U%IZx z6ipOqU+qr|ri5i1!9h2gMc5!!J=sy8n(gEK&lXIsakGC|Fxe%H|8Bv|*T&JE&`3q< zWE&<+TOewx8Ps zujoDJpzOQ1rs^CnKdR1l^LW?lv-Gt0qVn2{KMgG-dFNVd z-#-c5{rsn)1q)*Q)6f#bE@Styt>MEUfn_4bq`mRu3pY2?8m_%*^>sn=@%{rt`-fo) zI#qVBY}SR%=fI^KeASP?ylV?kJyiR7vVE>AoYBk3MP@;Oa?F%U1Pzi`NyQgZyW3AD z;WKK_EsQ?hcIBf;FG`M9#z&!1D$N@|)H z!l(v<0<&y^--edAsrKP;gZ=zKxkW-gOk~VHEg~VSYbjc^zrGNQQ2OK$i!3d7L`&AL zEk77{1KcnzJJGBcs{Cm!BVJ?NQWR}UnEF5n+QzITV~hjPDJoKfD-S(*=u1qTXVvBGmicSLo-c!hIqJhm{KC?V>)Fh@Kd(m+lq{2rJbST9DiTKM}+&H zTs_+1Y?UQw2P>6Nxj5C&t`|c(hRaaVBN(7A^5)@MX|B?V9%AH0X#y>u-0XTq`K(wU zDuq`}Tvw`}5=SbMD|O$f5i`;NW;|)+l{Rc%mfoxv*d7tD8f2^5Y}7h$Ln3A<$$V+n zjO;=_o_1!OfQso=eQ8}x;lMwhin_Jc&VBm9R>!7k1g`bVfXvsg%(k z9~)nv10b?gLkpJ&xf?1OG8xXGX0nQf86JuCv0e7q?&o%?-X7o&*xVjOM9c0BiDh`~ z3?r$AmJ!+3&7Bw2jJ92>p~YkOmHO&`W@xGTHg2N!<=cdrq1^XL%geXFzp-|y`To{6 z;LG1K zp&rf-a->3hA(IQHmv@#N#p}ckGcV0r`l8@;_DGn85{?uUVqm>-)})9vDNs>dA~{wl zxZr9ow;ob!7;9Nr1gpUi&#IuqK*K$3(MA1=zUKO6`-aTk3cO~1-SKFt4?JAo7(SbW zIe-;3QS#lLoGJ=ZzPX~|l^{dit|W+U*A2^Nj6AsAm{uSE@roVdh0W}^rZ}=&PTUHpKrBcRnHBGe z>0;D6QlgV16e;}Dk8t%4he_|>RLU@_cMko)=eK{8A=T*o{VThCJwrY8Ei>nF!oocD zL;4U81yj%TT{~5EFhsta&aGoN@B3j1L!&n$)+dEMpE6#G`btjhcA{4=Fk;X06e=C}AOCu|x|rkZ(`5 z2b?(yN0SWRJ^x$Lba=>JX@@yV-*)Uz6rFf~uZ>zXGnH@6&;6)EJPu{+g><4ZZ#>p_HCghEU7Q^Wb4MgW?lXJT-XHjCowJ zueyorO{~oMdY;sps>Sy>!eh>*uFoi^Bamzi$FF+VtTY?F@Zzhk?eIDV+QV_y?`+@j zbxi%(S{*n3h-z!qIc~DHY1>aYD@f5eyz_#QqGUtb_}G@Vu+>#Xsz$PK+hsZZD5;SG zKVo5HO!%1u)0q2g{$vBDr>tjNuSnoHgZ*yyidN19F5nh_kaT^8v-!HI0{O1DUIFYnjlO@!>DgT$Beg zt*kUTMmqDrt>l;BE3s{;C`}dGAx0S)aot!By;hVMAN69wcT-j#RqLP1IMdR=Pk;*X`e$_j>tV+7ml`j76Ouoz+>{sGXgxG z1ntU{4{;n?N5#x#oWlzK1`8=^O{jKPP|X^xoGEEd`FWOm^rXdW(%PJIP@CQd?Qdjs z7K>#EdXo=B0r$jFhU;$jC=IdN4#LylTtGP2V>Dn;)^vKJZk_ctG#xa>YoDHlQ`XWk zR5GRPHqncHX;EK#OewZ{7?I%}S(&m^3Z5s@owPy18SJ3(h6XEHih+_rd@LC{-B}f8 z_iqA?I0J~~gToQDpbGRemBz%Xr^_PJwwNF3WR`LPK9S7iCv>f$e&RKrBke(ed)Kqau)#xrEAs$J>Zw*NZGf z4B^raQMXkTlg01G&QG$xK*N7i#qS%7#Io1z^pu4Y{;2S4Rzy1Ed-RI5MYR$?Q1|1c zF>3VVV7I%#BDA*w7B6o9D|!n zL8wfJZ(7l@`dU|{L9!OL0|5iMMvgg(K}*_N(19qFpD@V;^Hf2)4-c*>=GeZBc8a`+ zZ~lf@c#?1E-iH|ymk~AR8{&|cRE(_NrIjbYS%EX8oNKxHD0W%WP=%CkZ0;-aPSYCg z11uq~bzSb671BXsB7{&XM0%dj+T_0TkzjU-1II#?@8uNpP1F^ddu}?p8E_%;V%bRy z4Qz}{xj0*|R=ET^p>cwvG+3_!I+I`^kqNsLNTjb$an*lhqZlr$qGclhy_vT-l}H_4 z`o)M{Ke01bh!$&tNu9WYQ-RyTh^1%6p)x6$Xj6)oQj(N6&NF&tM3=g2CgH$w)#0M( zxo@LlGRDJ(FZE&*7>G<3X&8P9QcpNcs)Z5Lv}EPB`abDP!FOC51dK+#70n~t`vz7xrX;m1 z!UZPj^JE4#P)9zP1$kl&@B5gb;el{LSscZT-UwtAU{V|j_Xs&f_OXbm|MazQ4`I5d z{HcI9y!BX=dOo9zTv8rH*awLf$_#M;&af&nf_bbMRP?9IE+#EzNaPdJ->=eH?lqwY*q5-HIqr8_s8Lyf$VwBi>bns{{XH;ox=}9TXW6t7rv_ zzYx2uju5+fcXKQ<#9FUpbGY(}S~4&9-7q>`%tOcf7J_yC<8(N0UH;h71qQJx4L6kr z@y7Bn65=*{p(Q%R`<5a5$J@ZA>hw?dZ}?ty7hUu9kJp??$)sMMVF~!&a$UzQnRjyx z-oA>u*uY^}qb7V?hW_R?@T@-Pt(f!$KwZKJX{7I)t!HR>o zCwF|pp-&ND_8;g+oyoUbSZ6YTXXKI2Wc*N$*e50Sm#;$=2}kx}fN1OIjQC#eTmcc> zAkpZ=&R{%dgVyc>VIpgmoNaOqF}03jDE$;}$}VPhqs&{kE9jZ7!+VkG;Gu=WEWdDP zG3E~{&^@{Zfl{E%!OUc0`5@;7vx~;A^1Yg{aprF#foIUw`x(y zkP}nEMdN-Hd+XH8_$e3sWB^`z-;dcRs8Rx68wJmfh7a324E9Jbz=Qe543wkcy(RG0 zKIUjMGrJ7NUl7&=QT9+@jpJ1g!^>=()~xSzVdmEGjqgyVQ}FqEm~9~I9Wj~9y%C3Z zS-ZK|mM+3OC&C@Zy)Q`OJ*U~c)bZZXXxSmS{674h+69~>6JRhJR%pe(tqu2K%6P~` z@xD_$2~O;}qj?I>NO6uqG{_HPnI4u?wT2urugBEm z%~XMmq`)t{+GVQ@g!|oLdW1B|RlZEi%4~fR*Vq=v?sJ+<$J!}=kB;Vyk0YK%G5X9B z_#9mE<$nAt?gVBua{ap}#Xj^z1GuyWhcS~mPj)h;^AO&~g1i0gR@kVH7yiC5`fU(S z=Q0!xCIu!!3RT_&a<8bv$=2`#i%XXz;Nd0k6=x_;0e;8VPr%^J0g@9+BU`cR3KoWH zfy||w2^`)2E3P1Eg;NnuAn*=k4+9?uYrQifL)_d$hP@hY}_%vAZ!!7Ic`s^1Mie%$c|{9oRQjghE z&%;u0-ZEc}GC!L#|KPH~?6TmFvXI%b(8Dq;Z#iD0Ji?|tD!4o*yF9L=Jf1RJo_JVJ z;H^l}s7SS`NDr>a%&y4ppvpTc9vxN`@KzRSR1$3}OM@%Rvnwk*DywHJYY!{yd8-;V zs+w)8T7s+Eva32esyb(@o*hu(dmSMdlYYmpEmH%pX-)vK=d!PK{RIy#^}$XE<07$k29QQLvwK7 zYFIvufIEO5O+i%^P1vDfy%yJ;7WXGD9`9N_f3|q@wfdfE^}E{Yf3Gz#r#1LVYskCS(4VbX zzBc@swuq~3QTN(na@yjaw8g(`OZ?eJ;A>~tew=c(>Kwc-jj_7qhH94C9m$;b5*tuf zxfQ8cHlML0(cKcPOm_+(`}hZ3_|3)C2OWMLkb4Nao9%EXdx@uxb!-jb0HY@lJ~uLU zU$1tO)5gOwWCcZiWlaQ>hm4TP0$3o3P!jaE~P0H)c zP8FEdZFck&XVd2?sE4zoX=HorctO6pXBO~8jn2x9(^REZpI1(^0aFzztFMtEuk1x% z>gT=-O#R8y{g!i;Rw4aW+5I-Tm9}&JWrzLt@y+Kn2g;2(p1KWGk7&AAS7PP{y!i)x zH3$7{2mM0^Z@(A_+^h)h9L${^4CNof^9w00(ufxTPoEmf`XNpAe?g;jhvGacloV*k zNKi$FrsSh?B`kQ3%p9vwoTXWzu0T77f-R7sQf7UH)n&zV!&KdpbwN*+M_DmHlN*9T z(i@0Sf3f!fWKRNRz#(S}MmjypTJfMW2wG88od%h98kCZ}J$VXCOi zdNnuqYX0ceBLC>J=IDy;=%uK@xi;8_y*8j0>c37SV@cuHb=PlEj-!3D?h8{@n`#+^6D`*e(-x&!lT zY?)~Yaji(??6|1SxI|4MGH?7PEBr4gBpCn$)B{HTBR_^a6oswu8s}mfiuxaLD?8fm zc%=;_A#~&TjT(u=50Ms?|77_7Px{V-iP_bi7~{u(7{1-#|D7M7`#TExZ}Vf( zbC3Su$G=g?%Rl(>pD1K~qTGVYk2@Z3{C5oBRDOIe-}Gt6_l@bMTU37hr@^*V=)yB9 zKVF-ty8imv)1P~PppfU!e*N6v-B|d|k0}5;RszJLxmlo_+R_i#Wq#szr8mQNzVu_}4QC_gtjDzAf1rOY z05gCQH2fbQU43D1G+gxWkIsE==pS-+qEQSN*hYQ0vE-jA)_;xu|NiKL6~+HV|L0m{ zP3oNghW@Ku7yftXALils8~uxNdCLAq|CtjP1=}1AoV(5*kCC>ia`qD5PEU-hV`TSe z*}*a#SxmP+-FD~X`|2lkOnel(wzcz}>gU<{2<$8GI}jcpeD4kgqVqJqZA|Oes zaVl@81?glMz<4@Q*LqQ%v&YIk+S;%yV*0Godo00B{jMJ#nsGvK#-M|tVmckiEHi?E zFrjHl}_n=QM|~x;(c&RjfL~2?ZbWc^wX%ZN=%sp2D;RUd{a zWgX$)9_iGWUadHZ7vm^$)p^;7L=DvtlftPF111E0I%2ye;Jj_l}tGqwL#OE zcoO>aS<$gw?UD{HKa<*}2NmmW5K|DdsvqeI!!rsfVC!>q0 zR3X~vr6ccd=8#FLQpWI0XN}z~QhcdOnb9kEo89bbswum5_?2hyZq6c8nfjp7sBiXe z?wU!N#?oT#kYmlkmLX3ZUo9b-Xh1 z@8vA-E7sGnS{C5HqBjdiA9M@aE1ExWOueVH*sF#?M|{1{LA-~6oVFjsbGLmXw)diq zC$_MZ0V8?kIIs^0^Lcb}5psyKGlzIxL7b%7(Ok6VksZTrJe!fw}D-WS?oz>G=E?^AZ*MHWRj zYCHei#$xXS%2dwN?_FCTCM-em@`pY*B8nf@Zy){P{%#T;k-q!{#=5<$4yPM+N-I&ZlJd74jrQw_7p>errdc~*S%Ct5 zj0hQa?$jI&??|J+=4hPBGJ>ahzja$R$IMl%KGKYIbACj@l3D1)$Zl(esx%q|+8FAT z79)zZF@uQuAxN}-TGSj3_zVfhAQ1Suf`KxvK*-H4t#sERG7#|DojbxI5D zuLRzEviy0Yu8W$ZK~=9;nUxMmP^YvnRW~-9NCwm??WEPMFVrb*)t8nz{|)Mt_O~Z~ zC7n8@T`R4kPH9^NTZbF+1zrIhqytb;EouX%Clk&U3=d+TLbcu2K1!p*u(&S<&^Jdd? z;Y%ykDaY=;v8)gQpKn5goZ2K@M71xyO8uhHMEinE)SVa$b?*}}Fs)F!LRV#s4zAJx zAqDQ%)>3igAW{!vCsdkfE+CvI9u4Y85QN}37_kk^ib1ALZ5AjY`AwKY;nC-8MPSO7 zL&6k0VY*jGix3Ndz9c?VSGXU`T!848!LUMph&e@;91OB_0T_5x6*2ureH_<);tUkV z5Yn2oj6Nu^lo*~P#D0P6Ub7ZI(>5*^wTKp*>@whAh9|6nkzh2K>!nwsTICI114aFd z#3jh~gB9)lz&KNg~oQD6%(8lF7aZh&M>0AP8;|l)7Ac?%&F$HnnV40Ve;evZ-bAEh)E;+MH0! zrs9W`uqusztvUI}a?9VoaADUZ3DIxs&L8{yYVF^+T&>af==X99%FDB+5w5N(|AzOD zPx3jJ*2*h(-aoCb3bhV`Ol~ZRH800qe!G`N zbCM(pQ|epHWjsgB8gQgc7L+sLv@YxN>t{RkvRKrk`?M3Z)Wnhc&Ol?yD`qabocH)e zpaNH>&GML}+Q>bODprhKz14U-!&^0@f9-&jsqaTC;J-drO#;^zI%5AVo=SpZ7xXVR zum9ow`2V+g{hz)cL)V!&1`y_vrI%bC^tjUv9GE#6CJS{0MijD{P7%wOW9YK>FEB|B z)JJe%>4eX+Xv#Jiif35r46;cL!9i>xwkbx`V{Z%}iBVxQNw6?tuy;L4GWd!L5&eE44s`x^45)i^9jshpgRbij<#bpO6CSou86jOv=K3HxH zDit!+uE&L0tk)AKlE%8VG5k7l2)${POAe-!jAzVluqW^kopyk*M{mi!+8zYoSmvr@ z3PN8p&t&@oXC5{sk`cGH&W&_tQZdj`A>r1vm8Q!-Yu`gKfMDutWDwEgD4Z6VC%aVT zh(A&`NCZbBNy4#&pBMDCRrm&3l$vFFS=7mBMur-eAZ6`vH zSjyEYcOL6l@Y}eghD;-LA38Y$8H%!O&TX(Ms2hBZx*ou{r*p1Pct|+J?<^Y3q&QR$ z=8J}ox6S~C(U8fc$1=5VDAWMlZu%ue`wDG$LC+`EIXOp$IqU6(iSMSW z{`MdB$A>B!FbYryaQ;)p<&591i;CxFIzeR$J_r~(tr1l{lq}kp08~z3+db(x_>f-P zpwGuGH7go6F7{^pMlAG2;Z8=JBA%2nXzr0ve3(?5 zw)mj1Ze-k7^}Fydi3;WMd*FrVN!;OQ?yXASSv~1SIUYVd&im_Gl|+STtkil0fCd97 zWBZ1LMF@+OO*0Zhi0X}|c<_s)h&aSQ019awMT^;##htj?H&mW{quDD185Li+?O^DO zyc8i;(eRW^YceVG4Y#mU?L?_952oMLt5-@&23bR7SF#p(Y^ z$MKK7(0}dd3@3Ky?7f-qx_^!t79zd9Y@Wn;p>}THr}DMKfIW|`Gb3)oTqJr%BpGo+ zz43xBHSzYLnwE5}g?RotpW3%e7O9j^g7@PplrCl_rAwK{awwSG?GXT5LkcID zq!B}CNlZER5`$`a!Qv&hqQ5?787g#J2TJ^lt7AquG1=UI=A~Yq_1?n&NJRY0>X=!v z@%fIW{E-UlroSCI9Ku+Eb3c|JG`YU0Of$OiM=KdG0bqmkoHwy0J zROuFb8SbrJ>*W3o-4@2-N5BDXehm@bf$l72=6+2T>gpKp=b11S9mBb+fAZ3+wrXZ{ zOi$Twt|50{=R6N6!JjQkx@` zPu;W2U&A6gFUVeJ`sZCmk{(&Kl%XCkKR`^ z3#NGQE$Ap%ODq|y_Z1XIaT>Wo(b`7}4pvb&Rf}|CFu&|u863^|2I{tf%i43$ZzI~O z*3;ure0F{F@fL37S9y9&AS>u~=nAvoDSqqOB*S1Zb=9(*WNk4Q%UxorIMfx+-gSEh ze%~?ufW#JmI`W;iRCar6tf$DNbFLqQ7_CzG>15};keygv*IB68jeJLA;g{Oa*Mr0h z@4`B6;(`5R=??MfL66wyYObu8nvW|)qU6m+){}?Cj0mNV6Dr*U6ms=HRZ9M#kdqWv z^)m^@^`9y?YCX|eX7QcBJGrZoQA|2@zxQols@`2g53By}cXIPiPXFlS zOwQ;2?&KK2ZvS_k9LrsM2n8|L4V5T1@g1V>+Y%x$rDP3-#4pv#Zi@r(W%| z8!siJi(pREW55%)RnU5pPtB4jX2H#q=E~O|Pa1Qbe>`C+djIaEwGi>~6lQm5Y5ZDo zo?lW?3$yCXEx!9drhJuO-FQPAbar+Qb(yjcWKLiA`0=0b+y0}I%Sosrc?JCYPA>nr z{YA}RI=Rs{QpevrxvWsH zn>5=F$%7{;M}I=M)w-}_DgKiy8z*FPzg01oEHuZLLw8_g_ZL z-RP#bsqbYUAcLg6W3^nH47=?D8}?l*)+sicNTFr4fV?f zH$1RED&p?V>=Ssj2-YwW<((=YP;J~!@QfGbzk;Gdw`AIl4eq6QLqoxcwInQ9j5SnY zNJkzA{R?!{Qy2TMp&Nz`2Qen&q%GD#Rvo@+^&U56uS>nK8Q)27u>1%+GE{%?rGZv< zzZ<5B!u@Q zl&T|mmF8z4dEV_@w6SH{MJyz6MSN1MrEo>yWTx8t3d_44<}9{!ceL}8JtJ%;YlANp zFz?d{{>RkQx8O>J^@yyh|-1eh1nh!h4 zNjO#G9La6-#%7{rYZ8*xrfaLMG1XzWRVzADWyd%htsL0GqN@*r1H9?PHy_tWr>$Q( zwK6$i{05Y_*e@=-4OO9-{b=!H7Wk;};IaVJzd(?@$y2T{d4`FjSxz6ocZiysNW4^G ze2?3P`Q3AS4Nf8lxmRW!ODnZ+UupHRrq&5N9&U=FN15RvQE|2aZnfrA?wUKyjMw7M zXJEUWWCFjEp$zH(B8Ap1u%A)pm8X9}7yu7RCC#V7xM+&NGWc}u$<7I#WKn5m4{W%UPf&*K%; zk?FwkRN+djH=fPw{;l_j3y~ z--jnRCSF?wbzj=@jZ))ZR?f%0b*TqFvR$P9;hszz5{jGrq}E(Ba8Y*NTZy~8D@V?< zcYiT^m$5$paoL}KQ&vlktOIPo77iH@h%Y@i7Rk{p-7gikh!Gy;UnuH_gO^@>l!r8| z`wMY4eINCGmb3UVlqKXX=OxgbTLc-$}BwCNc&Zh}3KCcH@J)1M+<{ z_I`bpSUg;y_X=L-)B4^THX9Y6`0ak(+a9o{=!8$$UgvJ;-m|cSuR@756ZfvqmbaoQ z?}dsAr_N}s(C6HT%iO;AneoAl%=6H%RnP9b?DqZSQng8J&bMtJ{QWrYA`S%8vb#QMKB=LN78LvEfkU|LoUOHOa(Bv zva<(kJ5#ZB1@LmJG!Ks1mHJ8QiS^(`@R8Xe>H-As6Z_iXwBf%`