From ecf878c1ef7a9424e3497e45de4958c974c1e6dd Mon Sep 17 00:00:00 2001 From: ioa747 <97930522+ioa747@users.noreply.github.com> Date: Fri, 26 Jun 2026 13:39:40 +0300 Subject: [PATCH 01/15] v2.2.2-alpha --- bin/Alt_VersionCheker.au3 | 54 ++++++++++ bin/BackUp/Alt_VersionCheker_old1.au3 | 80 +++++++++++++++ bin/BackUp/Alt_VersionCheker_old2.au3 | 71 +++++++++++++ bin/BackUp/Alt_VersionCheker_old3.au3 | 96 ++++++++++++++++++ bin/BackUp/Alt_VersionCheker_old4.au3 | 139 ++++++++++++++++++++++++++ bin/x64/NetWebView2Lib.dll | Bin 114176 -> 114688 bytes bin/x64/NetWebView2Lib.tlb | Bin 46100 -> 46324 bytes bin/x86/NetWebView2Lib.dll | Bin 114176 -> 114688 bytes bin/x86/NetWebView2Lib.tlb | Bin 46100 -> 46324 bytes src/Core/WebView2Bridge.cs | 26 +++-- src/Core/WebView2Manager.Main.cs | 10 ++ src/Interfaces/IWebViewActions.cs | 3 + src/Properties/AssemblyInfo.cs | 6 +- 13 files changed, 475 insertions(+), 10 deletions(-) create mode 100644 bin/Alt_VersionCheker.au3 create mode 100644 bin/BackUp/Alt_VersionCheker_old1.au3 create mode 100644 bin/BackUp/Alt_VersionCheker_old2.au3 create mode 100644 bin/BackUp/Alt_VersionCheker_old3.au3 create mode 100644 bin/BackUp/Alt_VersionCheker_old4.au3 diff --git a/bin/Alt_VersionCheker.au3 b/bin/Alt_VersionCheker.au3 new file mode 100644 index 0000000..4e1bfe3 --- /dev/null +++ b/bin/Alt_VersionCheker.au3 @@ -0,0 +1,54 @@ + +#include + +_WebView2_CheckInstalledVersion(@ScriptDir) + +Func _WebView2_CheckInstalledVersion($sBasePath, $sMinReq = "128.0.2739.15") + Local $sArch = @AutoItX64 ? "\x64" : "\x86" + Local $sLoaderPath = $sBasePath & $sArch & "\WebView2Loader.dll" ; $sArch depending on the host + Local $sCurrentVersion = "0.0.0.0" ;= _WebView2_GetInstalledVersion($sLoaderPath) + + ; Load the Loader DLL (WebView2Loader.dll) + Local $hLoader = DllOpen($sLoaderPath) + If $hLoader <> -1 Then + + ; === Call the function === + ; The first parameter is 'ptr' (NULL) to search in default paths. + ; The second parameter is 'ptr*' to receive the pointer to the version string. + Local $aRet = DllCall($hLoader, "long", "GetAvailableCoreWebView2BrowserVersionString", _ + "ptr", 0, _ ; browserExecutableFolder: NULL for default + "ptr*", 0) ; versionInfo: output pointer + + ; Check for errors or non-S_OK (0) return value + If @error Or $aRet[0] <> 0 Then + DllClose($hLoader) + Else + + Local $pVersionInfo = $aRet[2] + Local $tString = DllStructCreate("wchar[128]", $pVersionInfo) + Local $sVersion = DllStructGetData($tString, 1) + + ; Free the memory allocated by the DLL using CoTaskMemFree + DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $pVersionInfo) + + DllClose($hLoader) + $sCurrentVersion = $sVersion + EndIf + EndIf + + If $sCurrentVersion = "0.0.0.0" Then + MsgBox(16, "Error", "WebView2 Runtime not found installed.") + Exit + EndIf + + ; Version comparison + If _VersionCompare($sCurrentVersion, $sMinReq) = -1 Then + MsgBox(48, "Update Required", "Version " & $sCurrentVersion & " is out of date." & @CRLF & _ + "At least " & $sMinReq & " is required") + ; ShellExecute("https://developer.microsoft.com/en-us/microsoft-edge/webview2/") + Exit + EndIf + + ConsoleWrite("WebView2 OK: " & $sCurrentVersion & @CRLF) +EndFunc ;==>_WebView2_CheckInstalledVersion + diff --git a/bin/BackUp/Alt_VersionCheker_old1.au3 b/bin/BackUp/Alt_VersionCheker_old1.au3 new file mode 100644 index 0000000..3f14359 --- /dev/null +++ b/bin/BackUp/Alt_VersionCheker_old1.au3 @@ -0,0 +1,80 @@ + +#include + +Local $sArch = @AutoItX64 ? "\x64" : "\x86" + +Local $sLoaderPath = @ScriptDir & $sArch & "\WebView2Loader.dll" ; $sArch depending on the host +ConsoleWrite("$sLoaderPath=" & $sLoaderPath & @CRLF) +Local $sMinReq = "128.0.2739.15" +Local $sCurrentVersion = _WebView2_GetInstalledVersion($sLoaderPath) + + + +If $sCurrentVersion = "0.0.0.0" Then + MsgBox(16, "Error", "WebView2 Runtime not found installed.") + Exit +EndIf + +ConsoleWrite("$sCurrentVersion=" & $sCurrentVersion & @CRLF) + +; Version comparison +If _VersionCompare($sCurrentVersion, $sMinReq) = -1 Then +MsgBox(48, "Update Required", "Version " & $sCurrentVersion & " is out of date." & @CRLF & _ +"At least " & $sMinReq is required) +; Here you can open the download URL +; ShellExecute("https://developer.microsoft.com/en-us/microsoft-edge/webview2/") +Exit +EndIf + +ConsoleWrite("WebView2 OK: " & $sCurrentVersion & @CRLF) + +ConsoleWrite("WebView2Loader.dll v: " & _GetProperty($sLoaderPath) & @CRLF) + +;~ $sLoaderPath=D:\i\Pro\.AutoIT\_Test\100_NetWebView2\NetWebView2Lib\bin\x86\WebView2Loader.dll +;~ $sCurrentVersion=145.0.3800.70 +;~ WebView2 OK: 145.0.3800.70 +;~ WebView2Loader.dll v: 1.0.2739.15 + +Func _WebView2_GetInstalledVersion($sLoaderPath) + ; 1. Load the Loader DLL (WebView2Loader.dll) + Local $hLoader = DllOpen($sLoaderPath) + If $hLoader = -1 Then Return "Error: DLL not found" + + ; 2. Call the function + ; The first parameter is 'ptr' (NULL) to search in default paths. + ; The second parameter is 'ptr*' to receive the pointer to the version string. + Local $aRet = DllCall($hLoader, "long", "GetAvailableCoreWebView2BrowserVersionString", _ + "ptr", 0, _ ; browserExecutableFolder: NULL for default + "ptr*", 0) ; versionInfo: output pointer + + ; Check for errors or non-S_OK (0) return value + If @error Or $aRet[0] <> 0 Then + DllClose($hLoader) + Return "0.0.0.0" + EndIf + + ; 3. Get the pointer to the string from the return array + Local $pVersionInfo = $aRet[2] + + ; 4. Use 'Ptr' and 'wstr' logic to read the string directly + ; AutoIt can read a wide string from a pointer using DllStructCreate + Local $tString = DllStructCreate("wchar[128]", $pVersionInfo) + Local $sVersion = DllStructGetData($tString, 1) + + ; 5. IMPORTANT: Free the memory allocated by the DLL using CoTaskMemFree + DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $pVersionInfo) + + DllClose($hLoader) + Return $sVersion +EndFunc + + +Func _GetProperty($sPath) + Local $sFile = StringTrimLeft($sPath, StringInStr($sPath, "\", 0, -1)) + Local $sDir = StringTrimRight($sPath, (StringLen($sPath) - StringInStr($sPath, "\", 0, -1))) + Local $oShellApp = ObjCreate("shell.application") + Local $oDir = $oShellApp.NameSpace($sDir) + Local $oFile = $oDir.Parsename($sFile) + Local $sFileVersion = $oFile.ExtendedProperty("System.FileVersion") + Return $sFileVersion +EndFunc ;==>_GetProperty \ No newline at end of file diff --git a/bin/BackUp/Alt_VersionCheker_old2.au3 b/bin/BackUp/Alt_VersionCheker_old2.au3 new file mode 100644 index 0000000..3321fbb --- /dev/null +++ b/bin/BackUp/Alt_VersionCheker_old2.au3 @@ -0,0 +1,71 @@ + +#include + +_WebView2_CheckInstalledVersion(@ScriptDir & $sArch & "\WebView2Loader.dll") + + +Func _WebView2_CheckInstalledVersion($sLoaderPath) +Local $sArch = @AutoItX64 ? "\x64" : "\x86" + +Local $sLoaderPath = @ScriptDir & $sArch & "\WebView2Loader.dll" ; $sArch depending on the host +ConsoleWrite("$sLoaderPath=" & $sLoaderPath & @CRLF) +Local $sMinReq = "128.0.2739.15" +Local $sCurrentVersion = _WebView2_GetInstalledVersion($sLoaderPath) + + + +If $sCurrentVersion = "0.0.0.0" Then + MsgBox(16, "Error", "WebView2 Runtime not found installed.") + Exit +EndIf + +ConsoleWrite("$sCurrentVersion=" & $sCurrentVersion & @CRLF) + +; Version comparison +If _VersionCompare($sCurrentVersion, $sMinReq) = -1 Then + MsgBox(48, "Update Required", "Version " & $sCurrentVersion & " is out of date." & @CRLF & _ + "At least " & $sMinReq & " is required") + ; Here you can open the download URL + ; ShellExecute("https://developer.microsoft.com/en-us/microsoft-edge/webview2/") + Exit +EndIf + +ConsoleWrite("WebView2 OK: " & $sCurrentVersion & @CRLF) +EndFunc + + + + +Func _WebView2_GetInstalledVersion($sLoaderPath) + ; 1. Load the Loader DLL (WebView2Loader.dll) + Local $hLoader = DllOpen($sLoaderPath) + If $hLoader = -1 Then Return "Error: DLL not found" + + ; 2. Call the function + ; The first parameter is 'ptr' (NULL) to search in default paths. + ; The second parameter is 'ptr*' to receive the pointer to the version string. + Local $aRet = DllCall($hLoader, "long", "GetAvailableCoreWebView2BrowserVersionString", _ + "ptr", 0, _ ; browserExecutableFolder: NULL for default + "ptr*", 0) ; versionInfo: output pointer + + ; Check for errors or non-S_OK (0) return value + If @error Or $aRet[0] <> 0 Then + DllClose($hLoader) + Return "0.0.0.0" + EndIf + + ; 3. Get the pointer to the string from the return array + Local $pVersionInfo = $aRet[2] + + ; 4. Use 'Ptr' and 'wstr' logic to read the string directly + ; AutoIt can read a wide string from a pointer using DllStructCreate + Local $tString = DllStructCreate("wchar[128]", $pVersionInfo) + Local $sVersion = DllStructGetData($tString, 1) + + ; 5. IMPORTANT: Free the memory allocated by the DLL using CoTaskMemFree + DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $pVersionInfo) + + DllClose($hLoader) + Return $sVersion +EndFunc ;==>_WebView2_GetInstalledVersion + diff --git a/bin/BackUp/Alt_VersionCheker_old3.au3 b/bin/BackUp/Alt_VersionCheker_old3.au3 new file mode 100644 index 0000000..f44d16e --- /dev/null +++ b/bin/BackUp/Alt_VersionCheker_old3.au3 @@ -0,0 +1,96 @@ + +#include + +_WebView2_CheckInstalledVersion(@ScriptDir & $sArch & "\WebView2Loader.dll") + + +Func _WebView2_CheckInstalledVersion($sLoaderPath) +Local $sArch = @AutoItX64 ? "\x64" : "\x86" + +Local $sLoaderPath = @ScriptDir & $sArch & "\WebView2Loader.dll" ; $sArch depending on the host +ConsoleWrite("$sLoaderPath=" & $sLoaderPath & @CRLF) +Local $sMinReq = "128.0.2739.15" +Local $sCurrentVersion = _WebView2_GetInstalledVersion($sLoaderPath) + + + +If $sCurrentVersion = "0.0.0.0" Then + MsgBox(16, "Error", "WebView2 Runtime not found installed.") + Exit +EndIf + +ConsoleWrite("$sCurrentVersion=" & $sCurrentVersion & @CRLF) + +; Version comparison +If _VersionCompare($sCurrentVersion, $sMinReq) = -1 Then + MsgBox(48, "Update Required", "Version " & $sCurrentVersion & " is out of date." & @CRLF & _ + "At least " & $sMinReq & " is required") + ; Here you can open the download URL + ; ShellExecute("https://developer.microsoft.com/en-us/microsoft-edge/webview2/") + Exit +EndIf + +ConsoleWrite("WebView2 OK: " & $sCurrentVersion & @CRLF) +EndFunc + +;~ Local $sArch = @AutoItX64 ? "\x64" : "\x86" + +;~ Local $sLoaderPath = @ScriptDir & $sArch & "\WebView2Loader.dll" ; $sArch depending on the host +;~ ConsoleWrite("$sLoaderPath=" & $sLoaderPath & @CRLF) +;~ Local $sMinReq = "128.0.2739.15" +;~ Local $sCurrentVersion = _WebView2_GetInstalledVersion($sLoaderPath) + + + +;~ If $sCurrentVersion = "0.0.0.0" Then +;~ MsgBox(16, "Error", "WebView2 Runtime not found installed.") +;~ Exit +;~ EndIf + +;~ ConsoleWrite("$sCurrentVersion=" & $sCurrentVersion & @CRLF) + +;~ ; Version comparison +;~ If _VersionCompare($sCurrentVersion, $sMinReq) = -1 Then +;~ MsgBox(48, "Update Required", "Version " & $sCurrentVersion & " is out of date." & @CRLF & _ +;~ "At least " & $sMinReq & " is required") +;~ ; Here you can open the download URL +;~ ; ShellExecute("https://developer.microsoft.com/en-us/microsoft-edge/webview2/") +;~ Exit +;~ EndIf + +;~ ConsoleWrite("WebView2 OK: " & $sCurrentVersion & @CRLF) + + +Func _WebView2_GetInstalledVersion($sLoaderPath) + ; 1. Load the Loader DLL (WebView2Loader.dll) + Local $hLoader = DllOpen($sLoaderPath) + If $hLoader = -1 Then Return "Error: DLL not found" + + ; 2. Call the function + ; The first parameter is 'ptr' (NULL) to search in default paths. + ; The second parameter is 'ptr*' to receive the pointer to the version string. + Local $aRet = DllCall($hLoader, "long", "GetAvailableCoreWebView2BrowserVersionString", _ + "ptr", 0, _ ; browserExecutableFolder: NULL for default + "ptr*", 0) ; versionInfo: output pointer + + ; Check for errors or non-S_OK (0) return value + If @error Or $aRet[0] <> 0 Then + DllClose($hLoader) + Return "0.0.0.0" + EndIf + + ; 3. Get the pointer to the string from the return array + Local $pVersionInfo = $aRet[2] + + ; 4. Use 'Ptr' and 'wstr' logic to read the string directly + ; AutoIt can read a wide string from a pointer using DllStructCreate + Local $tString = DllStructCreate("wchar[128]", $pVersionInfo) + Local $sVersion = DllStructGetData($tString, 1) + + ; 5. IMPORTANT: Free the memory allocated by the DLL using CoTaskMemFree + DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $pVersionInfo) + + DllClose($hLoader) + Return $sVersion +EndFunc ;==>_WebView2_GetInstalledVersion + diff --git a/bin/BackUp/Alt_VersionCheker_old4.au3 b/bin/BackUp/Alt_VersionCheker_old4.au3 new file mode 100644 index 0000000..42f1747 --- /dev/null +++ b/bin/BackUp/Alt_VersionCheker_old4.au3 @@ -0,0 +1,139 @@ + +#include + +_WebView2_CheckInstalledVersion(@ScriptDir) + + +Func _WebView2_CheckInstalledVersion($sBasePath, $sMinReq = "128.0.2739.15") +;~ Local $sArch = @AutoItX64 ? "\x64" : "\x86" +;~ Local $sLoaderPath = $sBasePath & $sArch & "\WebView2Loader.dll" ; $sArch depending on the host +;~ Local $sLoaderPath = @ScriptDir & $sArch & "\WebView2Loader.dll" ; $sArch depending on the host +;~ ConsoleWrite("$sLoaderPath=" & $sLoaderPath & @CRLF) +;~ Local $sMinReq = "128.0.2739.15" + + Local $sArch = @AutoItX64 ? "\x64" : "\x86" + Local $sLoaderPath = $sBasePath & $sArch & "\WebView2Loader.dll" ; $sArch depending on the host + Local $sCurrentVersion = "0.0.0.0" ;= _WebView2_GetInstalledVersion($sLoaderPath) + + ;----------------- + ; 1. Load the Loader DLL (WebView2Loader.dll) + Local $hLoader = DllOpen($sLoaderPath) + If $hLoader <> -1 Then ;Return SetError(1, 0, "!Error: DLL not found") + + ; 2. Call the function + ; The first parameter is 'ptr' (NULL) to search in default paths. + ; The second parameter is 'ptr*' to receive the pointer to the version string. + Local $aRet = DllCall($hLoader, "long", "GetAvailableCoreWebView2BrowserVersionString", _ + "ptr", 0, _ ; browserExecutableFolder: NULL for default + "ptr*", 0) ; versionInfo: output pointer + + ; Check for errors or non-S_OK (0) return value + If @error Or $aRet[0] <> 0 Then + DllClose($hLoader) + $sCurrentVersion = "0.0.0.0" + Else + + + ; 3. Get the pointer to the string from the return array + Local $pVersionInfo = $aRet[2] + + ; 4. Use 'Ptr' and 'wstr' logic to read the string directly + ; AutoIt can read a wide string from a pointer using DllStructCreate + Local $tString = DllStructCreate("wchar[128]", $pVersionInfo) + Local $sVersion = DllStructGetData($tString, 1) + + ; 5. IMPORTANT: Free the memory allocated by the DLL using CoTaskMemFree + DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $pVersionInfo) + + DllClose($hLoader) + $sCurrentVersion = $sVersion + EndIf + EndIf + ;--------------- + + + + If $sCurrentVersion = "0.0.0.0" Then + MsgBox(16, "Error", "WebView2 Runtime not found installed.") + Exit + EndIf + + ConsoleWrite("$sCurrentVersion=" & $sCurrentVersion & @CRLF) + + ; Version comparison + If _VersionCompare($sCurrentVersion, $sMinReq) = -1 Then + MsgBox(48, "Update Required", "Version " & $sCurrentVersion & " is out of date." & @CRLF & _ + "At least " & $sMinReq & " is required") + ; Here you can open the download URL + ; ShellExecute("https://developer.microsoft.com/en-us/microsoft-edge/webview2/") + Exit + EndIf + + ConsoleWrite("WebView2 OK: " & $sCurrentVersion & @CRLF) +EndFunc ;==>_WebView2_CheckInstalledVersion + + +#CS +Local $sArch = @AutoItX64 ? "\x64" : "\x86" + +Local $sLoaderPath = @ScriptDir & $sArch & "\WebView2Loader.dll" ; $sArch depending on the host +ConsoleWrite("$sLoaderPath=" & $sLoaderPath & @CRLF) +Local $sMinReq = "128.0.2739.15" +Local $sCurrentVersion = _WebView2_GetInstalledVersion($sLoaderPath) + + + +If $sCurrentVersion = "0.0.0.0" Then + MsgBox(16, "Error", "WebView2 Runtime not found installed.") + Exit +EndIf + +ConsoleWrite("$sCurrentVersion=" & $sCurrentVersion & @CRLF) + +; Version comparison +If _VersionCompare($sCurrentVersion, $sMinReq) = -1 Then + MsgBox(48, "Update Required", "Version " & $sCurrentVersion & " is out of date." & @CRLF & _ + "At least " & $sMinReq & " is required") + ; Here you can open the download URL + ; ShellExecute("https://developer.microsoft.com/en-us/microsoft-edge/webview2/") + Exit +EndIf + +ConsoleWrite("WebView2 OK: " & $sCurrentVersion & @CRLF) + + +Func _WebView2_GetInstalledVersion($sLoaderPath) + ; 1. Load the Loader DLL (WebView2Loader.dll) + Local $hLoader = DllOpen($sLoaderPath) + If $hLoader = -1 Then Return "Error: DLL not found" + + ; 2. Call the function + ; The first parameter is 'ptr' (NULL) to search in default paths. + ; The second parameter is 'ptr*' to receive the pointer to the version string. + Local $aRet = DllCall($hLoader, "long", "GetAvailableCoreWebView2BrowserVersionString", _ + "ptr", 0, _ ; browserExecutableFolder: NULL for default + "ptr*", 0) ; versionInfo: output pointer + + ; Check for errors or non-S_OK (0) return value + If @error Or $aRet[0] <> 0 Then + DllClose($hLoader) + Return "0.0.0.0" + EndIf + + ; 3. Get the pointer to the string from the return array + Local $pVersionInfo = $aRet[2] + + ; 4. Use 'Ptr' and 'wstr' logic to read the string directly + ; AutoIt can read a wide string from a pointer using DllStructCreate + Local $tString = DllStructCreate("wchar[128]", $pVersionInfo) + Local $sVersion = DllStructGetData($tString, 1) + + ; 5. IMPORTANT: Free the memory allocated by the DLL using CoTaskMemFree + DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $pVersionInfo) + + DllClose($hLoader) + Return $sVersion +EndFunc ;==>_WebView2_GetInstalledVersion + +#CE + diff --git a/bin/x64/NetWebView2Lib.dll b/bin/x64/NetWebView2Lib.dll index 9acc3b55add836bf66c577edcc6969eae192f061..7287b21e6c51001eabd5cc4cffc816b9df55c839 100644 GIT binary patch delta 33878 zcmd_TcYG9O`#$oa?@4ve~@o_nhDF{LWuz`Ec!h-R-IK%riT) zn}$o4h6ay2Z;kT}8uOblUTq>S#z$rdv0n<|sVi@PXZ_A`{(at&qMQ_MQk0t3#|HZ- z!WZOfqK8TMn?IUn)Co+!TUjNzw9QT(>{@L;SOY@*D(B7 zgjqDVptu+*WYfYYWqwPA@{CE|*W&AuYxZqcgvHxps$VLENel3?YUO?&+Faix`GB_G zH%xBTcKSBTZCVe%iSmAJjh`)gI|6F26~a5&ONg`;OAwcs9-6dbF@(P?TUw6##VYba z?M#>JM z=tro|$KVz0cnO#qk&OPaq(&*pr|4bl7XE1vN%gr1OnpG9`9p{W$)mLJ2%8+G7Gd|jv`%}Ir$B|C6iBT9;{cvn*65L95K|MrPNVQ$EQ?I zo=#Lp8!@r%%Lu>7DyrHi2qzbBJ+tHAB>rWYrkRp6wSW|J&S`S^{0fKZ6#NC*&Rk)e zq0LXW$(h=kWLwTG^81?nzPZA0Hrc)<+jlM-%ATX0NVY}JCF2D${@^mU*X~*^FvTY4 zY3V7puzpt8{2Lq~ytk+FrQVXs@IUl(m{)YKH8t6{cF9=_*3a z68$$CNm4~nhAJ>UL?0Ua9x!@al={cehZy_E@uqi?Ff)Sgd^l3Cg(Y1X9d_A>RTxtPj@R40_Y zq$9W`qWe{{>!+9w-2+U?QRtC$PsNmcN?VaWA}+^h(tf>32Phn^$?eFjeVu-l%+m^c zSbg%{v{QSOm?ohR?Yo%~+OZzDgndr)?HaYauTnEm#e6+WTuDBs&FDEddTB>>Af*cK z*F5xV3H57%_Fd1!^j;m=$tO+;P5zE@#3@!?zyb0-De!(?E6Nxpduw-PWXL|~kq~cM zTuLcfU+uGueA!Qn$V`{Zv|*VuWTCb<(>l6;=kx=WctqfJzJKy>l$A!h8#vazz}g}> z(?}oDy9LJ;cgujzIkfLn^R=?9XgN@upB3pdsKeT_F)LkK=@6{xViF5H99?Ki1ppj7 zTTW!#B|?75iI#&kYi>byaYrDvoJYT|bC0oZd52D0nH!uu#Hi&fdM#fyYB{uXx(5`k z%ldHbz1&^SVMf4fdcf;OKuPBS9vte5Yp5%R8!=b~XwqYC;jS3*4>1!drqqaeQ;&Je zi18WO5v2L#e<;heGx-TVFt#MO~Fs$kn zhE<%yrgnsBX?-GOr8cBbTu4=i)>Wqlt-g;vZkmzite)nak*2yMKzpW7hFqzA(H_m64o7UDZLeAFm`o;Ooann}!8yGQ=nnVk(u?p*F zzpf&Ar1pHj+i~_RE1W9d)b*i{|7uGnhrIdUI8iG8QI-GAz zSP`#tsfW6&9i;w}PBp{a)eA_C)_Xfj+|>(7JscXx2zPZ2sY^*cQfgoK_X(>d1)spm z-2E1{_!m_u@^)?Nz&^pa4DhR4V_t=sUduH=DpB5gTpo3X8M?A02|LiL64BLtcpn^9zY z^gY89^$5pO)Y{}&MqTiP_QvoSA1>-wL^yU*h8X5So??O9p2QJFZ4IEHom%FIFbwSQ z5pi;-cHM|%F4En%j@+K6TyQ%wA~A!<|7oQT3l=s{N>Zxg+AE5NAMi0!Q9{9{~dB3y|T!Ka>b?PMSDJ_mO{pb+j!q+aeS_gDNFRAlB|yB zsMH89^=Fi-ZzpH!t-}stf%bTrU6yPAE=!23KrPY-D0Nu0PzyCFEvQpxSsgD>E`88! zUOZ@dwicFcNJzbG$SU+j`q2dcguGKymy~ArTwN@x~ zwOVwoO?z-mvD~D6J*E$^+t`V~#<4?zua4aYbd1XfK0L0{a}!1NsNLMs zM`iMONXc}jaZBJ)M`t4IU()d;tZoL!GvM9LA3v^rF)2VE(terL-K)K@16tbTco#dU zUG2sWXpL^{p!VqG%|0<5&DF+Dc|k^K;ZyGjqbZ@(ZK76Ohq8ieZ%5S}imJ6v9b(a| zuK89*I9Yra9_b!6*e)zc3sCg7v*9@yeBBk#|C47c41VsOhyTg*1sH-b>F=X%)*h^k z%cQz`8L`w0L6)u-9+3am(KrN}9B*sCRW@XG@(l9n>XTdq^8<-tHMu@w!2^lmS43+& zt5)-YTXPs5fyT1)idHuXsNYt`2N<^j9dFYV#lAHT2R6>xK^Y$6 zHk@{Dr_)Zd_SdvXc~rAkmt$#~R~?0AVr_M1mlsi`H1yzuND%6HQG2zzyG1`*wT0C| zTEKMcXj;Q`2L~=jFiUpAH!u#&gIr+W`A@-`OF3KxYj!JC;5u@ z@$sk$!Mo#iZSb7sa*}p^w*M1Zvde`H^ z(qzE}*BcAc* z{aJqrF`r;TrUoNwMMsoYwJ4#R(fTU4y68=@oWq^?eJUO#QWYZor;N3t5urLzlVj+l=BR zcVjYtv}8VP!|bXO<)gj|ruN_fJ-DXsd3j39T0Y(K87WR{ zo0rekPr^<(BYR-|ojzoWF=4TBeBQFV{)F`Zf_%>a=-lI-#epSIrD>bc>-69Uo+FxAvcX`SNA2 z8tk|Yv)gcHcMPW%b)zkLJk17u^z^aEX#d^VYgISKU?sot#?83giEiAkZ(*0B%J@VO zU0WvsylqHM)R)xLjkhG<*m2ZQ_F+Np*$dpNa@VRZ zUzVxumEvt)aB#3Sxb`o&CWbmLOYP{|(m;GrjpDH+ns{rIEVbC%Li1^l=215QTK#i0 zzd(aJ6!-`04GXj+t6&ZjfcF+=&2d{vfQ2YVlRm5s^l*4+FW)xVelJ!Ck7P6qdC0(@ zX4Y)#ig|ck8?df2ys}eGJ!&2crjLT5)GjO!(U0|Cpu(~K;kpPD8)9z>(WgZ35R9yU zr(JNu?XB{2?Tg#9U)RSX9`#P?>M!gmq!~GiG$x;vt`=bfYT{HO z4q36P%$J;=^(ON)-?IF!Vvg@h$cv#zVFRhiDlYh5$QIGNn*&w3yM***#e{1I6RMCc zV!O7oDRkEA5mdR4a|!cP2%qjr4Le)5IMXUDImh~2#BKRy`4M7=Z}AXsF+7=KccQ`G z;>Nxtw|Q?a_7>HN15@r5<-M>;mQ-DD5kH))_WX^37IB|;xhdSax!5WeCbSOs7RR`* zr@5|yjDB3Rv#cM_HU4e@#ot(5mXGXlRPQCd33K6T5pl@tE!xnMDDkiIj3H6t=Y)(Q z7SWa4uqBxWO5e}+7P0Y^=u2-ZAhm$xuIO!Vafqw( zG8Zqn`k(ZPF7pDujnVnUl^E15BfstCFJ8+gY#czt{Cg&i3=i0kT;(%ENE6YG@b~_d z=L<|LZ*h`)KCQH@Fdv7am=Q>bn~b7C28gGN{kj%2+lu4-dN8snVkOuOhRr0%c1ZKO zw^&Zp%I~!)eFkas?v3bGJCNM{L>)o`#1^msuv^$Yg;Rx#jcj|cAKAi1GutL>&);jq z?(QR`3LL2Yc5iZ*TZd7q6!8H&?9+N~4sm|Wp;3u`UFV4mafU5>*)KzU$?V7wipmfY zFCi|+`E~snY%NHDi0w-)%Q4twum({p8Wn0wpJa-w6{{5TECVYByIoOZ14JS$#bU9z z*Quy7K;TXl=u*+l>=S0o#5QKBX0p|Z2btl6Sg_^dVFg)50j@Sqh!tW7vu_NxhuOk3 z-S#-MdvM)Lo=-AsG}u#$lhSyl>&9o<7;mt{%&sz$zR0Y?upMW1&Pek*vtNw@-(vQt z5%(^$R}9Y+%t8&%j}^s9U1}IlvGGmA_yw~k40cXWVph7%q1bQ*M!*KOeRgB@+Lxs3bt`LE$HwLY8xDbnFg9uV- z2p0wsTV=3w%x)DSYZ=ABd}%9Tgb=V)3CE!*nO7IVr|5!|oNfPsDg;^_-?nT*GW8+ddPMnE9~n zb1{Y4Yh1(`QOS(1{ffm|F^w7RVT#39Vmh@VSDhRZ17EXGp2k|{nP zLJ_KLWOg%>E|w;F6SFfYezEkHw=fGqMHkCJxtf`SZ6R_kvoBHnVi_*iF+)nQD0v67 zeyH|h886o}yOH9Y5}SLb#n=HZmObR%%r5&9%aTpZ9%Eac+{EmDX1(RT%wA?TMBc}2 z6(4FNwe{$vjCTL8H^>1>e2(i+%c8rSf2d7t2M4KG#@ zI)?T^)VT8g!0w5IfuHspMtO=#f$tWNL+rp*s*sXN75ZpoRq&_=zhJ89r_rRJiRxlC zpBYM|AJ=`}FfvDRYhJgKK02K6!3x5x1j1eHzblO7SJ?VJYoZt@v;HN{@CYg`#R0~E z5hSn3Cu~lNHcRo*&^f_a%_nn>KIT3+(SJUYis4iVzv!iq4`iCA6{At4ul??wFryajy|E9#T~0AeNu=ZW+{ z5n>g;o6NxHlmK9hPeh1ClvQB(3>=$J@?FJ)gDv9EgtI}T8s*+fq(0{ zu6QVX#(O(U@fPY!#}Or^c8o&ZZ|yP;xJFDx@T|(#fe$2l3SvO zN;~v7j_i={!%S+gio2e=x?R6B-5XWWD^xY~Y>?9;N`_NSb=4Bg+jcpse;q2J>o-Jo zggwXYE6VMNa`!a5Rc;xMsrC&2AUj1&G8Ngz1zY1glCE^CO14|eUdZT3`u|MsXwsGb zPQ86EWONkVS^oRNR$%5^#H9e5w!;GnXJrOKlkT&E?4ld~0PzYSS+CGh?&NoP)MJC|F+f+&_D8!>iebHJwfLtaq6BM+MbNNHk>q<9 zCVS^2!s&ic{oSGR-vRCZxI)I%`{#o7A~$+Bp-ER(Jp}_wv0I#fYo^xI(YcrF`*+9s zKNbAHs>l4_npA+1b3bbRd2VO(p?I;6Uegv-Wuosupu_LKD|C(P0Q>vmpG8zpUush4 z&PQMN#(2NLt$gWfijfnDEi5Vf+p(+Qlv>nXNG{_F3ugA#pAiJiNdw-o-pB ze5{Es_Hu^Vn(Sh)XxHu;+WT@y4`E6m_UHi_qn&GOSmNOBv*R#tT`ro=>F6UfP5w2B|%VW@uZU z7! zwwnE-tF^%W(YSV?*D=2p{V(7GU4I?(Yw9n-7U5A})X(#L)C%izvD;vl=oQv_af;a) zFN#|s&KZp2R)`;TPqfQ|i-Uwb&LS?Ct+G1BA%i_ow#K?ryzFFpMxIOv5I2gx{K3l^ zub~BFMWYzRjJn4HroXu2)(&3(d(^ux>#m;wN(S- z_8&7>Tbr#LT}F?Rhpl*cfnUeW#bBE|7?N)3U{QOm54czlROS&E%eJn!?sBmWw)NJ% zE*1p#I58^!nEC6-_11kZ;~KC7E>@p?(E7BC-C}RGKIdXjXCAj6aj}q)tMo7BDhEeBol#GM98YqcbOpUyP3$@wgwqj+uiKPg^_K zoXh|>TVTafan9vg5fS3XhL>A#QQDqmSSMy4;BK?IG3PP!d%5n$Mfh~GBh6blPCHoZ zP>cB5RYcgZ5I5$L7lMo6_Traz3lQJB*o*ko_d6H6FFmA#InB?;-9Nb4+c=qZum$Mt4(43b$#rd1h?}u7YN`0q zmFBk*0d8z+x3RdC*I&oX$qDXEU|>3Iqe4T(&n{0jEJXa`VvWx7%OStI=&Jb3As1cj z(V_tHhl^dGc-D$L^ZYty-jaCUicdWac0W287sLj8r}Tmw^GJ|x>{Q;bR-APW&okYe zzgltOWzd(4#|n#!eP86x7A0S@cGz%96^a}3M%>X-i|}+Yzk&ca76Invvb~wRRCv4C zf%v6PH@Z6bI#Y+SA#jTuyB-YB>ly{pY0uZi=(L9$*1FBFK5VJL?SF%9KzDbrzTry+ zo*gi3Q^G@pvxBClE){qzz%b^ehPbg%Bn@=gdLwBEYe3SjF581h+QANoF2!A#_M9JJ zCUmeL3P1Oyt8Jq|*}t|6F3$}1P~ljC4UWO~6$ZGm-=dcatIO6kCd7?hQ+Ppyx@yIbftFD8oSxL|lRs9Zv@^d;#TVR|b%^X>=B%6mk?Qii&$?8k5u@^t`8{b3(J3+W zD-}T|Jm0`CoDclBn9^PBtNsC^M?3TTcH~&m)5ZRUzUW|&p)WevQcT1Qm*-uWh&n_0 z$NWA+Z8BX(0i%nV6@TB*tah8ZTUKCbc02Rin>1GBx!AEz?ClbF+qseeH&5E$v9P62h)8A)f+UUIU*=q%bx&M+9AH+#wD z%o@cx%%@&*Gc)HIFKR_^`LyopMXl&9U)EhcEBa3~_m*!OHfmFE`GLWxO}*t;2BS9h zkrxa`P3j{r8jPCMNBZE7EbWh}NquFQ&YWJvUk#fPIze{tuV)b@GeWPC(+$?G#5pf?qTFoI!jgHRljJ)F zTWG5doh*He^uTpsQ{-TS{T8t-bgEo#FkjoU&`P<_V22}DhE~aM4E8zLG?_3!;B~X- zoXA^4tK}qvHAdd*44p1F7<7F09icPiYX-X>Y^F2~)B~&R8$)Nwz6NUmn=Ka^>{;7= zp>yPJgS`nhSAK4=-Z9%lua)*edX{pqd2)=w-U!(h>by?gX3#UB^W{;4B}YCH>X4TV zHWX}u%o(hw*_8QI=t4QqU@c%Za=XEP2yP9nl_w46AJQ7SNCp?{agRs66uMZJ8te_Q z>z#5H)0IL?`giCJ@;8HR!6|2nTri9R&q&%@FOk~~MqBHp@?(S1?rxd9U@+RqWo_3{ma(H6B{o;4V4QCG;{3`S=|r+maYLQg}d!v=ZOU~~eyQC>0_T|C?< zGfH(&IvY011f8C1k+#aknfr7;VDumbV#~(ROl=+-5M^ukV$+3`YC)y>g$yXuJNX zJY+E1u0JZz8H~2;kIA15M%(qrWcGM2-ix;DkITLWbJBkOaY@gg(z%)T>rcp42BZD@ z6Y_|`XusYf-!~X-*IQ(p!Dzd_PyS>u+OF@D-6rTcX}kWU>}xREu0JUq2CH|Xru*d* zgVNQ?etE!Pw3k01Uo#l(-8TPhpHkdWf8upH~OefDXlCG%VlXipA74`elnPpJAr2asT zF&JHfoRIezjIIGbl!pvPm)jpn&l!60C$hGfPRdGy-I-zu{a9|8soRRo7V)XvY_P%J z#10!w^(FSE)1VvFsIX6E@GLzr*gGlglpJHQ|M>I>J1yvY>|Ubv?# zmmBPU|N5{$}pZ`{h*ZtRpNu}7K2aZ9vsmdgS9cET*upb54b{VW* z5<6|M7~B(6m4F3$mc0tGVFpW6#)7?Ouo8|t3x@Wu6sMW~VHh`?KKE4>{e$zB;v+$U z$qV(QYm}v6HyP|rGd^fiHW+NZBzE3l%grB#s!DJT#pxem<7sYw9rJq#rz(Td=byB{ zaT(2Vy#s`~-PQak_Ij3f<~J*5slb=G^)zPM?R2ntBiDF(x@=L%iKnlP0z+{A!w;|+ z>{9$#;iK5OYEG)#-C;gT4%0JUR5w3mp1~;4PiZz71^OxWTFP@qQnme*@dl&H_$&Ji zMwRKJTrwC{CQ!*)L~$zx9im;8W@cxclG+=re4tZF?F~@^7IP6^)LyGHnAy#u23u6C zQp#+7SYrQoe67lO-NyF_tV$)bMxmOwgjto@276g~C@fT|HQ2L0yTihiIwQ_WHy6T{ zM#DJO>#4ACWwXI<_I@fXLV40~B~P33tYNG5em=~myys@KE1wv)Lmn@N*_DfKwn#-@ zPfcnRJ3Ml%kvtSC%?oGYU>Rl5WAd5AYHN&((e0af7o*!Z$sK`+OL5trNnCGDbFux2 zZ-(`7F^bFX6qn<&J(K9X$C~G&`x8G7>+NC`Skx(SfXhY|#do~%YQN7!k9u|7XByEd zuGD3txH1<*1D#fUU zuaDuIVcT6s3f$2t5MNVsRdl^|w~JBFJnCW;x35#&lP((-c)-Od?rDYB|Mr`c&vy!J zb-7aD3ob^1FS-~N_)4d^S6w!Wd)>t-?oAh?xOc(Oem)K{Y2I@gDewaqqri_`i~`#X zrcbt0F55GS2d$@FY=2@%_?Iq5ao=`|`;M5C51?lfTdn6^uKN??!+&-$3cS=Q@K2ZR znZ)DP%PzJ*F$>S*wht4s0d!>{+a#SJzXpZ^9+{C^KO(bC zcO~OEby$5z;5c<0GyRNrwK|O%6_3Xg)Va(W#fC2Hz?K{AZt-F0cy+g%=LB`1VG9qi zhzY8?f=akKjL&})R9~iz;#M}UZqSWX!~}IcvqpjMR)W3M$@ZpUn~ZJQ1T|@;dt3&y zM&a}!+sikS4Ie)HuCh*04>TH{P82awZDrahKJZ&*ov4mp)sbehI+0nU=ozq1OjhT+ z*`}!18@4Yz@ZglHb+TYtsA=GA&lALXQx%=F1NMNKwrr`fiw zlWmn@3*rLb>tt&)Y?&77(X2IYjc}@cnPTd(@pgBky3w!&bAiV@+1@d1Rc!NF>y}gv zX4WVcv28>r+i1hqi!17!*~z%TFh0PQd7+c-HN$q6ZBe(m7nsbfQC!QmWu0uR4BNe2 znX{d2=beUeBG+c%I`^cd%o@e3ob>)qwucPc8czCLC)>-0?Fic!FTD#;a$ds&sIwf_H&oTVRO}k23r(x zUD!PJJTtx8^VQ!B+b}Fb^VJ58vb5W7W!5MT;DDX4`fPBw1%sjejbbiVsQKz`os1ip zHHz18ojzany}MH&vqo{mk8HPevfXLe4*HWVY@>Tz46{a2hryn&t|sPm)pUbl{M|ey ze7^cJGyO#3P)qNjH2R6ep-wUwohufoIsfXgEl>v=jBE?l4fl4~7OL9~Mz$KYVKdpB zdeR#8PNsT+wd(BqIs$9eB?hCwMe1w!ci0xGCk;ln#cKDh9k#`4UxShDdiAz#9k%P$ z%{p`PsqzMO_x29s4eB9-QQ#6a;GquN5;ewPWLv6cJltVhsumfHY|GTwc6Zp8sV5Ca zwmS89DQPUOm}I zuG2g|?&C-I2c*bjd_s%;BsB4d3exx`6OPTN?*UH%N}+qEv1gjL_T%{QGI*-uvrMvn zokO0aks?id>En@CW}c;IZubnpw(iQT3=_rKPt1RFL828$o4A5rMMxEUNGyhVOTan@hB!ui{Wh zTH8YBy9hJm34HqU@-5r~_kb%?{2$h6=I;WPb;WmmXZ57YnW=KE-$iHv--qFUuy)P& zR_(P@U5)?2sPw5*p_%WN2LzZ<>3{&U@Xrmv)+~Djwe?aS;X|c_H;yFq&!yI9Ybl=% zjW)A>Sp@0bk%mtZCE6XI4Tv~Oy(q54*kJ9kGjsi-`jc57svEVc(~)U(b|2;! zG6L}6P}NY1D$#bFj`YxHaEbQ%=>eD@n*Zlr=`H4S-=M!~R7?NQOQeU<9_@}VdIsr5 z==f&>rM*#m>xvseGYkdDs6N!^g!WDit zoQi_A!t<8@BNn4=L4VUWZPWQ&=ivbz$Cob0@hPs;Qu_bFs#nWv;tMS!FYJ*)w1vB% z(00&Er4K%qs#j@#KZd6DA2k7TSn?FHRUKL|U91-Cvc>|*=W%t&h`GQte}~wl4%Etj zoDu%)unFS0dR5u|z$s80u^(J}EAW-Xp#cr_`tNzD87V?giHTES^$F zr~bjRBG0LFQ#|DbX#6Gl+vF+nbWu;~i)@3XmucVd;rJ%8XTdyR#HdExdU^$SbG=Nz zm#&t9rgd5OBlE2Mhheo3e;k_n;RlgtomTx*=%7iZKSGYced3E^#t<*%9M>>dd{Ssv z?BZXgJ)k)eoULS{|A`*;pKP?}pc$v;<&;ArTkvww*`SdlceN$e9b=SyG zmBEJQ{qjGQQkKUc|3+mJ=byw;)1kMBK+|=@XQ&s&@%$!r9@k-!_?Oo6=g6#q!(UaW zqb6^wt2o01(}w|mrU|B^0YRoJ(=}P)z>=&)Xuix!GaXm6252jO9-o$7ah++7Ov%3> z=EzC$3nAZ#2Lk5EmXaGxOXW|c^}taHgo&E`B}Mks(te5bpzqwQl$*8kUqZtl8@b7} z!!$5=tk_|SAKGYIZ`#vmi)oYEqB(yVDkp0%{SsNwzuaU#A^%nC4b-Q?I@}3Cdl$C^)=B9bPWr8+5f25{5JYt3(& zuGc32n(M!&)M>sT*B0J{6cMAe=3jUFeLSqu^Mon9q|x&&(>!g$ZzIztkLaPiWqJs= z#QLKA!5HXM@daKq+=X6mnFa<8_IgVk#zQdBXm9=26MyVLUhLD4qGHW7MPtq0qb7Rq z7RO7b0ZRrf^DdR26yE7Q25oxCd#kL$x1Yw~;%q5?m*@dJRJL0T)Rtb1^tfF9o;T&Z z?_x^Hz~OU!PM9tam*RwJb{{EvnOn;jLSxD$O)`F=_=M^AoC{(UCgfPiks~gM0p`-e zJ8>O;B3OED7RC8*s{_pAwJyI8#cw`d{d=UJW5hb&QOaHAkNDC7wet7K#Erw=fhMxo z2fh=Ou%gd>Cz!v%^Cea0X?@Q6Rw*a!OYywU3hl`61G>|=ZRcsW53T5-Y*K56tP^jU zx|R0!o1>mhDe_yXJd;xDw-4>oGXAi7h+#{`dZkty`A588(x~Ykhqx=fOoz4lKYBXp z*`pJtt4fxN3vxl>Uw)g+ujiTkPnqa}mK-^GgpdCT(=~-%p}ADt-Tx?JrPopDdngwr z-8fw>a#HgAkISn^_4VIjek$Xr=S4{ab5YJ4ImrK_q}!qw`TplczVGQ}@-8d)zld)^ zP4Yh_`g-Ia6|c$g3N7nW55FVGD%FF%p759I>)LgfQbN8gf6>262`_xjKTxGk2vm=Z zuxO88vdMGW>z8unVom+C4}K)R|DW;lE3Nv^6vaA3yZz7c;gl-S92Vpi_>&ATT;qR9 zQurnO{^sRBdxq08Qe{f>|2*(X+j=w;U`^?5w!a?$)& z;x^2&BrHKyDt$X>j(WIjU{_yMY>j^~k4~_1M7#H|c;tWnuSh4A-dCZeX0SqIl&QYn z^@adXaa1h9k2Ak4>Vy2nad80hYvM-8=fy4fIWH-nhUPc<1h8Hu&y|cfF|G#si+Ym~ z_$e#XA;?cb_7s1b$WxjL&5T}7y!i_}QUKRX3%PEB>?uZioQBg_U{{gpNdY50PY1;c z4HZfeYlTehA$-J5;XOofxq%VI7lP_M~DL8Xx8A% zevqq$a~$5T6%D{zu?|=#?vEJ2#gw3!o%U)teG^}ePo=C0)$|>~hz7PcvfRw_Huyv* zY-68otlxpyKzl1&kHA`za0EZVVg*u$9zMZ|@$8cVA5Z%L_8A19lR1DoaXHr~`|DXCnr%&micRBn{%= zLF`!q>z?o`wpMe7YSvf7^MRx}utwNdvb7PK*OD4Jwvl~S!y0eL{Z^{iHV)p#hHY^D zCFwAS9f2Iv?Ffe*Ve2W@pJxBltT_#z;oVe~S`)8Ui$&ey)kah+o;4{dHDeI;_jelv zJ-VIsCD88)uU4y_;^l7DDz&~^-6ej2Oo^&hj9>B`I7QeS5uBgg$Ucqi)5t!J@Tp2( z4WD@XHuy9qZ{vcuv2_RZp7vJYg@_}t?nyqv#UEj78}z?NoQCYIh!Cc=Lba);YVm%u zYT6}aifW%Yf}c9xUFoh zgg(kv&HmM_sfN#!DbSY_+ulkK5XS zZ`*{&TJe$13m9mR0e)^v0qzMe0)A^N0Y=#8IPn&5Uk&uM?*N{SI1W4)cMf<{_%=^! z#}UTUjH(y6%!`u7vz!8XPxv5~OCU$st681{+0)+0@;1gJjHek@Z_eZGrz*xYI04A4;t<#xlk;4qzO_SjAZFqdDQa zl1U@uR>p0NhZ&DB9>)!(K>I0{Pcxo_W=}YN#F7eQ^zx-j$FdyHm;z0_y@=%jjDr|U zp!c*_LUz^%Rk5m?v4L?VV1inYfdwsgXVLa@Lww~ z+oV5Nh|vq0#MD@p;~7(+>5=Lj#H0iyKed|WIgpD|8(Cfrxg>QP%R3-nm3oBb#$*TN5Ze)! zk3*hmJI(Sr$RlhbfW}M>;9?+;vBk5T0(r7+5X&Wy_u8sio&)(?TO-S>As?{q0JhqW z1K+l_vHn~D=Kr;J5lBg67>gJy85wi128kP8Q43r6*wre4Or@o6!B}t*vJ?lmQ~=C z$V%X>$Ohno$Y$Wu$X4Kuk!`@Wks@KO*bo^5yf3l{_)uge@X^Qy;K9gd;Ni$t;46`B z!2d*w#I@pNWDM|&$Rgl(k(Iz-BO8Ds%Gr!Juc%gF*Qhq2ElMP<6$w!>!1SmhU|v)u zuzyqoa9C6`a8y()@S3PLV0Dz}wpPrGiUFeAfs3Omfh(dKfVV_71MiG#1#XIJ13nNX zlGln|Q8B=MQAJL?JsVXCJQh`ywpP3mRSEncssVT^stx#6l;}<;p%~zgQANN@QI$Y* zbOX>ox)~T6-3p9}Zcbk-QleXd7b4n#-E5)gJy85=HeJ)F1wZ=L3Va~CvTuv{B)SOE*+uXlJ40Xn~;%!xI8}OOf%90lGLu~5^D!7eNlyW5)i%MHWW?T`=m5dFH&5W&# zZH!_hM==&LRx&m)HZ!&|I@|b7lyLxKQCW*v7+1t{C1V3)Gh-`b8>1-asPY!^L|hEZ zMU0h<4UElfSj5=C*vcqsSkKtN*jkg$0kv#kY+!6<6pL8T*g$yT z3qPsJ@XYd~xUpOu^%}6+`ZCa?_L&P2P1tQ!>dP#1sC{R!0H(=y+2c<^P~J&?)XrAo5`^GP@Z%>EDf@ z!UFAt`#JcPbc)i8{GYA)6${~+o=^Uj@r3V2EC&8mN_yw01bR!XpwwOZ5DLcLHj=Ll z*2DhiD7}DJxYBwR^{OXw1FjlM#q0ey$Qis8GcXt$RYoCBb?-_*TsudEaZVWkwMk!?D{`>zLMTibv<@XG-dddhv|Q?I^m>G zihFs|>8NW)4Wp#@gi*oM!U=n)5*D&%2Ww7-k|wBsJ@8;5`CDU1GpCS7`d{4$Uy3G8 z8V`rcQEPa(BZkZf$6d*%tYp40l7jcK(?(8eVtj&+f>#*7Eg>Jha*uKc>eY4k8Pk6y zeE!K(FGa5qH_7?G&?dbn+*_u%N$)3WO?zY9TX|)ZGWnprmix&W9!&E;ErD958{9SI zvBR)mUAyf#Y{H1`3Co1wWMUxUG~Qv(&;p7g*iPczU{G)qtDw*v83 z1B4g!9zaighteDRZBD%52ls^!RNHZbg1#~73yqKPgXSUW56#0s`UAjS5bOu^6p!Hd zh6BV7pn{L$0-^5$^b|W~SLk;Eslq|f2Le6ujmco}JwOFK1e(3l3eBU^X@x3SghKV0 z41?-%paPe01Y3cg_!46T^esRIem3aCfS&l0q8<7tfeQR0p^pH1;yZ{@&>sLQqK}A% z=Aev$<|&|pPs?JVd0NIn^NfshLNx`;t|z_`m;lwYKn1_wl?csqG6|aJfr_Za9|!fs zm-v#QISf=p6@JIt6JOR#h2{uQ5z|B(G)HB3XkG*=_?Rvonq#sDG%o=a{N2Z%(7Y@& zpg9igrHC0K6RKBa7F4eS6)_v1M@lgVh!0X_4)m`B6){)jLi2B#2hAG?Mp|XIlK7GM z4}4Do74fNf7jhd=!4EdQ50vr*G)mKhVRE5!octE#YM>&<%kLpi04icKZa_&f1&Bu< z4sUeMnJRPc>&AK)$051LznidZeXKwbk>#GUxb zUq#?M)4;oA2vC!uuxx30@od|=xTtq-#F6@x&MHJ+E5d(RJh=aUBBtUkGB*;#Y47ow1LT(Ve| zkZ%-O9s_#fEeE7gB%Q!LQwz8t8En{A+sLE}gQtDKip-mT{ms zQtpv~51N|sya)bq(;k!L$;fqm)m5F*EZQ5|Ht6}Os_|po{yH%UfWInKHE*v zKHHnV1T{Zmy5QHn$tOnEb}e4Az)`bkjH6=u%);qYr)FhjG*xBDP$e^?sSxY%&Wb6 z&iv_)8z?3#i@ic3^4MvpV~C^XhN_zBdOp@QO`0jgJ=nQGcW!zC#YARjW>Ma&XG|M6 zXT}YqQE5l@Vy|24qcA|F<{_x3+s_QsuMmE<|&4$3O zWNvMWjFs_$*;E9FagBOqH~khTM{&-kHSyA_X6ENK#m31Hr67mPR5Egz%Uqr2<~Ci3 zm0_UlmB;VacG`=*tTKxNWSFLKmy({jlaqGaajF5e}{A!=4u0S6})P+2AO=Pa62 zHE+(c85EGqx~pc)b5!XC=IOrS8NJB4ePWEQnWxW-j9%Ph89Y!xmjPZ?t1^O*NY^X-^^#K3Wn9w{Jqgtqxu&GcFr>-mG$y1mT(_mmh>e4Bm}cz4 zJYLvChH_oD_CQ_Erpu}Aby?7Z<8wG(!4zxmA^WoH`krw85oR;$mMfaN@01akdq%mH zJvk1u1pP#DclMNh15njGeLcve7Ui{%10!sUzvF*U8P%7x%KeFX?lvkO9b71a)Yu5m0{G!K6csRYMf&Gl9DV5t2k!_-B8<9^_)sq%gEflD*w$@qXTqF(=O zQ%3oSdq>V58}P>V{~S2GS}qAXFy}rQ;1QhF0}mGCF;kzc9{87DHE+S}ssp!gm&Z*W zc!Ic>6gf?g?~?JMSM(mP2Ju898=Iclftgs)^zR+A0L_fuEt8tkcVel;<5PHMA%mP^ zny%Z4twKRl{Z84-vlku_!mn{<>6TAmQRxJ6ey1Gbfd^{);(0~gG^|t?$-8BLyxq53;%8->-rX&WP5DzZ(l+K` z3K#5wGOuaD9$6vt4;UFHO;X8Y9Q zg9rA%@TH21ytz*f?OOc~POHYNp5&PIu~x4pKrDC=gCL5cf?`1tp6h$hWOrjZ@B4e+_xbBtK3w~~zU{6v zbIKm2BpdjZ@7}GCxb)Uk(`hrNwxREJMJyzcyRuf_9oAe;nW=$Q3uPX0I9Y!%$9$Vcvn9{ z=@XaIWh8lACXXwB@)$+7&&hW6Pqqh?U2!JlBzZ__j5qM{%KrEaK2iA= z?voU^gkF5IG9V$DM=J{w4AvMKp-vnVq7X?Em|wEY5;1<+G=8x#y6L6)yU{HezdiU; z`v}9)zBSOIM|5n$KnW#QQbp|9gl@`T=%%*n3~I5$(bB4nD^%h;Jj>&he|1Ra@yfjp zp*%qe?P!SY&|0P%HA#}^_nS?Q2;A5T&iBpKX0IcPT~73hYb5G84Ru%hp@B=7>wsS$EV52>n` zjJbzxU!NewT~eOwG%0Mly*iLEVX0p;(60s5ugOYMa!g{1Jv;eCO2)XWlp|6ys6wa| z_XR2N{iRZuJcy?%XOok88hRwajrI;jl&rH7nUcxVl@Te4yh?dAWgO2?zD+R<&TN~$ zmlTBvd~W2#-Jq;gqxRs~arsnd!I?(-nA$DJwQlLsHiy!wL#FarY8daT>`D!B&$e5e zK1faE2HMQ3+UeLdXG=SpQr-Z|=BA*|W{!}I^f2B{8JeDz*4-XREf=F--L}VsZiZc_ z97*?&>!H>1lv>NTwOZ!1O}AN6idP3IhK%jjTrJ=oHQ-$>pl90vF*wu}Bd9Adn4&AN z8=y)5Z!MZPYcks+CbO{k38~Qj0mS6;s$YCRD2J4vRguoMMZV1zim00e^C(4G2?CjytF9 z?$SB5fJ#LMOf6(k=WQCk$54)eiqtjIz1W^Z>C`otmni+aM#c`ZYqb>pZIz$|V=2LX z$`f59t%KXTilLrKL!CyGCKCrHQK5S@ONDV38QsZNH1rE!!M9 zLQC_dn&z68W~4np`7Jw{*C-vkg+z|hoWD|?aYPVhKH%Uyx!X}3G?KbUx{r3yj_e-H z%amErmOE&-bng}1m6}95Tx~C`9^rghT%K~T`(ro~KGtJ2e@pqcM;E`%RCN<{RW=RGEs^+QWn-^OK3DPRy@dNKYkIHbwMt~4 zn4ozSRf>SPZkQIHu8FdL2WMBQda+X0Czrp~w5iWeauD@U!V}t|9UC)_@?sItSJ~Y! zkq0Oj`-S;s!-tLn21=+Nz7+3*lRjd9cFdVg(`&mj<*R~`JV@!=Kb!|E-CK7rdynD-3rRMg5EjtXPmC zTyQ@ZHqBvCVhN?TsykI>dSM_2c3EL0->mE`j1xsV`qonJmnj$A^0=w1m$WMWEcbinR7#%~Dpxhj2=J|?Oadc!q)FKgU zRP40SS8{9zzc!s^u)IpS)Il@3ib0!ITq?@ZTV7Yr79Zh$%9@fi9;v)llER~uUrSOn z>jzD#gFct|BTC?qZLZy@wM?q5Rz_Ewl+TCc@zqL)(rn=P(viSprTIYjp<9424b238 zF|^EOHAN*=uW2g2|D1NveF>Ftbv)=QU4}oxLzFj$|E7)M3N)qmd4T0#%G)EVrB}F; zJF=^9XluubCDq0DemZ5(NVBqa0dVi{vx zs#PfMQ`#L>6=@j~fOljt(^r37l)`P-M8vE&E_~Fjx+QcXaw>j}r5M zH-AmZc%UQSudI5&pwv7N;A$&YX?P$?)1PUh|L%be?t%7ZDr+A+%6*mLqgMseT##zl zQSGOo4FBrIsFLMZ>4~zwdbP$%QCYB6h_AyT(YXrCglQeTCAG=I@CFPXj*8~L^E?8B zr=#c5zwgC8dQ)6~1l=Vg&8R8?0kmYVFR_tlGW_@j=x-$!RTrDT=Yp*t>>8-oL@ z(%sp#%`riL@>RYnUn(}wsw435(RMCJl}E;O=f{;}V|sQ~y9m2B)Mk^w%>uUoEvINA zVs%QVgE%t#B|EbfIJi7U2bXZAM@0yKQyEoJj2+O9icstf-mXY#cLMe6fc|<835?jE zxR33qSGP%JPlcaSGS)DdHcZvQf>RDmg%{x)lW2&gg?<=~Bpt3|+~RtcCEqI_V+VQ>UHs z8{0bFW8CKB)KRC$DOJ1a9r%Bg?CDwjf-+T5AA=-#Coo!DSg_J-py8jQEUS9ZeQIkOl>b9jB)2Gr>PPt}%Esyt_h}Bc ze^y8G>B?8trqU|AmL?aSq;y2i^^~(3Hd^ZaMitV{|J7D?jP;DRaa5N9h{K-Ar+TI` zVn$rpMReu-JBYc69WFH(QM2q(%BC67?PqHx+*3=q>sZ1Z2jA;6hF}KuoEeO@$*7rO z{Hii_dAMsTQZ^I?Jatp5H2u&LZzmY&L3&1t*X=(N|n% zlkI`o!5(THRoU{BQa`)2o7($SIk8HUYK3SUJgHW#uuZG3OT@uaulUcwnn)>~6XQ;& zv8~I9N9Ozk^Vn1~6}DwH!8x?;UF_kfbFLkRV#Kj8$=TUiyKsV?P*sE%ElQj@(^X;T zKMngDajut2wco5A$9OsSeT zR)3kYT~RK~o1`9Ot#C&6LGvGXCsVi%yBW*pP1on2=UzBzcC+9_Ssa?aRNk}ZJ6!{d zRZ8jt)LN_)wTN)2MgKaJYB~Z_+XH89-NANWQOd6YemY-W+;ye*!UF3zR6-R_qNi1V z3(?cy=ajV^Q_RK3$?_e!>RrQJS5{+Z5@V?P9BDVl7=84X8!&B-39Py;G(phZ6q?{F zpLXP9g64anF;{gEnh`3_xM%K>6l5ErBFOrsVpiJNQRYAAa@KgaA@4plk3D1mQo`h8I;SEt7p zNbKwq=P*~BCNB2WjQQSwG%B`vH5#_I^Qx(Ni9ri||IdNnJbE1a^Ou)q_f(o>H{zwYZ^ZhB!y4c16?X55`s^)%K#8P_(*ZuoU+T zVlB6ol;zRLJ9K#`>#wBv4d5(x-mX5nYV{C6s;bv~&=&Q|;~gmc+0DkVi?s0nMr47B^}D zuFAW4`pR)0%C6P<+*A2!b)vcx7-?kFTr6HNx9+97Jdv!HX@#lnY*Ol;cm)MyC{cc5 zFV&7xduyqElu9Mv)fdb|aYU??=HmD12>N;s%*9Y?Lew+5m~MV2Z@|HhklYned-ReBvIJ+LO&Q9 zHpG=FGJ|dRC$2JQ-xI%QLX) z(a-jGV;0oUjja%MeO1W&guGhF-9(KW&>lVOkT)5mW)ntrvOI{Uc=ia)jbxjPK1_3C5mA(AryCWJ zkVW!G=xsMPPIS_AQ9KjXznCo#bYoxkrQ&}m>=hr$l2SfQ)3aVB-Mi>nOe}TVXeE7J zlyuxv8L=*@ctI|QVShG_(T$je7}WX!-*oX}@1zlS>`BA?YYL6y*&h2*>)&F?bF~|d z=65lqDR8Hx-=xR`^=ygq;kqcl*nBGfP06_+yOR zQ1wW5xCb?I^FV6Y%x;veV>VUy_uTGX+*k_6&cJqyalcifOjsXnrS5xE%+F|v(Q3ZBa2I%U;UCh1BqWye#&UCh16-ILWK#GCa4^9EZY+|TwQTM%0-Y|nKk zTM%m$HobE1DHC6+m^PTCS9>a18{*nk_9ORr_K|RSQn73Zu>MDchQ@gMR^0L zJg~)*9O2DkV98@MnPQb>?#*!G1X{zM6bwH^g3V=53HBcyv0C=DV7M{~HjizTkd#B6G_HxN@fBf=(%3=4?$eUKCRmAP zJ0jRMEzO&P{j3#uQm~h_xOW9RrFota%&2+3FG*Gue@`=>7sk_?@e{#b*4QOAjh6It z!3Ju!Yl5xTY~Ki0q2;_Om_f7sC|ITzcN@&g*c{FHyD+|_1#+2sW|ijZB+D4Xf9Eqc zg)d;PvKt1iPk+W{@;c@&(-2PgBeqCm*93c%c?#RRf~{ihWc%2!Wj@@2m*heDnEbA-Sby55Wte;@7h%6tm{(^<;F#dV$V^$>Sc9G@+8z|VL zq7@feiD2a-O$)nEu$!WypRpl=eJ2XM!iEZVM-*|D4HK+Pcz(%72)0q={ECed%ui-k z6n~vPDClhA`YkIHY?erRgN+gFn3xy0*c8Dgi+S-Avk3MtF)w~$(*$@llrIrXhoizw9>tdmW+j`I$MNNYo_{YFZsD4lD26<>+vj3pE z2|&(*y7dG$#@_VP>zjS*bVKW&DemJxv~F7o;o$r}i0WG057;qg0Pxf9gMiQHmI4pv zjYe#*1gemfLKS*rz$9e$^rwn`8bHSZco9~MNow1hA< znsB@D-yTTvDPjFiXhH=(AoTwf8MdO*ob4BQt3SyLG6@@F!<;yKBfrWYd-DfGjgE*u zcsOS^l3u|OQ|CMkd4Jjx;4$+GU_-!aU|zsl;DoTJfJteMz%;{iz<}Zxfq9`X0V@o9 zfnWDK2#hay9k|AH4CrTii}WGy0+)rH1zP8)eTc6m<_o|NO_zW}!>o(N}t}MxgGc?M4Hy z$`cSgKBZbKSkEX-&*m1Y?eIc77GZ9y)xtSI2FVADsk(WC2pfckDy>$IGR#4S5!iC| z?6LHlR$K6Hk9ja0Eu^p?&;kVH*i+weNVKfTu77BNU49xfskJJOdg|&{{fmiysES&l zy!@MfRy|7;U9GC-VBWTxLvt3P5~_Yps6A}6XkTtRRaCV)dR}wro4MGgT7CXTwzBXz zDzZfsY>2WaUFcAiG>4WQO|~cfe<$0U^k;vo+Jd9W_JZ5We_hxD%zQn&=1tSKzYpQ~ z6f@fTgWD1zuK<>LsPbya$)2jb7IL;1$=|0@wK`basRkW_KM=B7p{=5m&xuiw@Sl&a z{_|{qsXe9W*Om4bf44;>_9q`2R?dEOe+rYm?G|Bm+^GI)Q~6^+tG}Mn6#M&v)gni^ zHKMJ5u6jHMlw!A9|I$pYr>%3psPA8G>wj19|5T6pzbUpSI^S`t^%8U2C^p60*=kJ> zqbdm=g}`{vKUQdjZ3Fx3;!hyzt~)iUZReveyJ8c1TeR}@pL*hBq5l;4rQ5eaD!wEf z%M6@7R%ZRuwCcqg&hIF$J2Jgx1J)GcbHZtHvWr0}*%8Y(DYJK+saWN?QHM*Xn(+~^ zFdMrU>tzVHu@gnIA=1WvDadk-vazp={S7fT_Exf&A zjjfVwrUwhhISgZ0If_w!-xVY` zmzb2Gm)durrWCLpNvf5a(x3gJF=|R7%k8Avb}5rz+K+o1qjoRnDauQ`m*UsHbz8&`#cyvq?!_qB`xGCge7^Tn+?o33E9D(3 z4O2xaGCRTd#Z()n+t`knIs+}p>2t!#Gpte>v@gs$1GjCU4lXxBml$f<4vp!T90TxnQsV-<#NhBY?! zb-&$)1{;en*lk#EV|mDl-}=?^PdMd;?l&~rj7g{rZrl)`6HaM{^#;0DOP>=?YfS46 zJ5&PZ2lkSUeI2si@Uo391AE2B=BFJo9I&w^=97lQ#HjrzoL)^iYdB&v1_YcnylG<} zgnn!|X=5Lvz;|tIX!v@=X&d_{V7=iz8ygsM#PC5Y^Yrakic>`ObHX#FpSQ+PK3bUa znc+XJMyH1oz1bxjdnDBxSCq6sr&~qdxT4g`#-z+?cg4nL;)>x_8}pC3Zm_e7Dc%mY zAB$_)7pkWf#g_yJv{JC7Vm-sned2S%sbd?q3ztvrw&QKs2kDNs8Mw%3_k0DLo1HzI zj{~(le>5x~B(6<^cdn|*C#Q&He`8+$r2z=6FMg=?fXTX3`^i^Y{w zyR9;_x}A+#ouV^VvTtpHYmztWzO%6}al!hAjh)3o$nM&>D8r zmgPdBw*#||ZePm2w;AK29T~&G*lmN10qh5xryLl-@DqploNyXn>|*%Q#ui1n7=E^~ zVY%MywvEk-xoP;-#x`1GZX52}Xg)faE>P0vgwuhdn-0u58kb^iwo4hzNEf$M&#Ucm zvB}1E`{jF|BoOo$zwif9bT}z@5_E1^g4lEc9Kf!CZ)9E$L z#m4qWIkKhxQ*?G)ozF%GHVe$v7KfvkRp(}-bog>_WuEf`YnX?PtwDF&S+}4XhM%a_ z%6L8)6yU%T5^5NJ{?}|72>}kwh@7~0K(lp4POF{PAt`PP(2UO^shu4$)-WHN?IX+t zJNv%J6%SvVjptOiv$N-Wl;T&I)|`8LcssCP!fF_uZEFSkh6ga5o@s1EkDCk&9F2|Z zfs;)eTipI8GuYVL_T0{#yivTd)#kJudyhaH+tbg1dA@++1L@i+eNK2D3kz^?4H>Xe z7i0@eAK=Y`ZS1%1E1Aj0KJ;-hm~HIQLM*LptY1n13$wAEI5vjc*svHqi@@2oR=iJe z4N;A?$A)KTpJLP^ZMJ(DH9IRTsbNtz+oX~JJ9DbRZU-BUn$zh@(MFw}z2(!+7z3Lq z|Ado!W+_8IYQ?wY-E?5T=5af7O6}~;;%uHz8){g*jlE(BursG!C4RbuR-4myOzsXg zrsQ}t+`^z8|2)qOC}oMQM$h%=3p?A5zOb_zOvEIc=M$KScJ>)6)5&IIu-TZ?I?n)O za;wd$eQK~VMKC)4dG3lWWu04%o+sL{eFcuTcMH57JZXKCZi`#h*^zBWKc#cJw_aW0 z;XI#vXA!%~=}4KuyAZR2(xEbg_tcDZaLnMt1gmG)FljRQ9M$GZ70u*pHAWT995sX%h5yl*D?n<`BF8Z(tV=f<}v4*rbV^6+9W4pn6@#7lXZ0=<2&F`qp z>T(#g5AU3b>`TT;$dVuxg{@v8LoUlH|0$!xCasFDjseu;pa3K z6EU+>BxW>xO8;uqGj>hW1 z#`4a+)GV)=o;Qx;l^Qz@_7HzoV_m~{8prbs8Y>RpX*EvZ{=L<}e+TR}PUJ-zy9zdm zFVa|C$RXooepqAqV3quq#@3}AHBR9j`>0u(z^3xC8vEY=q|w4RXv{0%q;VQQr?EYu zr;XO>+#^pb9<+-05o{q-Vm~xi^8*^I$Dv~ePwq#aS2?YaXYjEaqZRT@{5#Z)lX36tj3%fm#GDDQ59HjnUy~7C)^qIvmaBGJd+F z%Fyb04iDEDEj(-ZFpbf|vxcwI7_BsG_*RY4N^>r^9?&Qq)oS^KLNzHJ)#mX<8lwZr z0)ALybPlk9-_RHx)vP?Zh~gHrcj^3(j}`1Hr=#IQ{*lIL5&keY4p2*=MR+~G&#F;c zgxB**jnQ&)5pU8Mt!)?cQyQa1+G5_KFh3rl!6 zjnSFJ65eN^RSl%`lO=qSW~4*qqx_u4=uo+o#}%udbfjF)hiQyfy32W^#%N`~lE0@h zIt6)*U(pyX$sgl^C2AI0lCR=rCF1ydmD7pTD!xH8(yD(oKc_KTD6HllgVaD;Ot0oe z8l%PZ6a0q8HexNkmfv@u>Pc(qb$pJ-=(J`XU#KxUty#}EfT8_YIi1%$#dl~%TD3gI zT?VUZXhF4sKcF#MP(973Ym63DPxD7LMkf|e^Ftb=^NMHq6^+q(#WUP{h?>Y!)A`k|9;RgKXybU(kNF~(&96nQRW55-+DzRpKINUWaC?|<29e1q>6^eU(G-Ddua z#^?;UnQs_Pu2(so;U3}UGL_L;>`}f(V|2cIjE9%2Hag!u#@A?!&YF+$a~gZz-_3ZO zlV2TM9iH9)E2H&I8y#BogYlm>wzc1FBkn5IT>D0jbw0`aj3K^|T}|_5Z}UYOJMRCx z@g4rY#+v-y0^jA{6{=@rp-)aNviR*_vpZ{`3jAt_>2$y zh6heoZJb#GzvJ^XHrI7l;7z_&W3u~#z#sUqO4W0r$LPQx`STjf^&B1eGjG<|Hdj5n z&AUxeJqx`S2j1pSP7%kyg)F<>V}ZZ%k2K?4ueE`{b0>@HT8eJF$ITi$Dp;Dvit#hl zJw91uE>6U@Xe?MFc3NX^F=8&$)SM$(DcFi>;`q0ay)M#h)r?a`nnN0UN4ny1kAI-C zOdSP&sj+8qzu7&WH(gD7M!pF)L}O+rV!JgqU%qU-$Il6-UWyj?-ctD|JfEi{ibP51 zx(}^y>@2dYH=ep{wY`M3p47@b$A{N2x-p49C!A=tV`n7;mbu_2Zp|iP$);~*o&h-i zIjaoUKRxe6l`?1Pf~{`P1UgH%1iR`=Rdba(R#Bd-t`z7hm1&IPT%`*t<5X=|DX?02 zilvvEG(%%l8F%Th#;7u$(k;QP3mI*rUQ*c%HIUltEj_6*YOjxUT4k=(USCN!lROu* zDlAcbB@e+?2gc-_!-I-}s!d$$_m#p0t7i?mt$}!mQDaM`mjeByG?iJ|VfR-8{iSS& zzyPVY=9=$%G%!FKrLiKnqk#r#rh}(Zny=ZqxV;r++PS+SNQ{Lneu?SBgEe-7ABw3om~D)HO$oEH9r!gRx=mb+&2}hey`jC0?Ta}d zm|$ZR*U27d?a_xP+l+@|HW^ZFY+uaPzziFsKs>#QPisZH+iXnaJZ*EO7B<=# z1wPj%@Ohh!dSWawv@wdi&?fE^o9$4{5yPi8 zwl5|$=(3Gb+%+(?zjbr^%4R$ibJB3##`eW@47zD!6!?qA=s?nk-?rHf#hf+#W@Gze zvV-o~7{xisj+0bR%!=Y^J3MP}(Tw!7ZFZ1{jZvU)n?T%hX`9_28v<->Ura$zkd09s z9^Dn5YDL3sHtNwx!Eo;?6?i@{#%82Ix;53_Gk6P-U{uld2E4gPV-$zSJ~c*h>22aN zY&MF+8*d!q@G2W(IR1&T&utTk*TrbAG=_K)jK*jT@h%sQQGo;GTekhWTOe+FokiB; zY@**JuVOh)uuJ^c0eB`rE}BiYOZ?@yM6gkUSykg8d3TN7I7n{R7zN%ZyUe%S?vwH3 zH$LhSZ?GIGn7X7GEGGz7&&u1aWP{~y8oP6@k3P)ssb|&$9xDx{ z^6Yw|Y7zI#b%ND1i|0zi{j%R8yKT5^60DvDc&}u`;;aH!v(8nu~@&3kf*k>&C+bQMA9{FY#TJ&JW-j0 zZEVLi+XZLb?K48Yu-LJ{D}vRti!M}|Y2rQvwP!}ia|Ekr?>dpK^P`S&-2|&=*`hK- z+So>EHeXShC+s#W(yZ5v-wESub|Y+WYPJTE^piHWFE!iS!q#=EV`cgXR?mLZQv=tw zu{CP8AlR%Ud`$D~6At7msaMVGd*t?deFix5d;9gT9bW?LpI^Kcv63e9#}*e8m#{zQ&t7kvr zd}xIHL>t=%&34dvrD23Tb`{0dvm4l7jFR_iEXHl6VU&DbV}r22cu?;4xaw)}$Pau_ ze(P~@{KwYpSsYjak+7?C~Udst1zEvRPwvtf-W4t+U%IW!-v}k!^}R6=}#gRnFaDH%^sH zG)6Xy9QU-{W|6ZrMz(44if8P$Y4Qe*k!`wsz0q!)F5l4@*{bBCEo8&-j}C`b@+d*o z%2dmh&)Ng4<#`&Tz!~!C=j^r_a*M{uHdDUwyxlfaW-q9WY_sGQJM6Yu@&=Vn5Urmr zAJ}O(&X(WO7zNIeFYL10=E&DIMz$Jx>u$TPMn0f1vdxuCn(Vf@O6@1vJVV+4Nw#P4 zKzej9Sm0Xa%td3&2PLHOj3X?~q_h7Afq2EJ@M))_l6^5MC>5SE`z(d5Uw0-?(s0&J znSF7U+KV|!Ws0r#L;SOF=uBcmvQv9hAtvmE-h_d?= zeM&|ic}&4?oSYp^wxg=w6l>S0RuQSjd!EgrSk-5>GW{!~QqrPV!dn8JSBttGQgT}2 zeS(o2B}7rCTT}-n;s)L&BRoBVsT}mM@S#jH`#vAfT(e09ip$rLDCmop>DGg2uoLcz zrw58Bi)J_m{5i${&l=^!OFpQ{nM+0&s+<#5ZrXRLO4rZEK>hS*#*~A_-rhP?(A(RI zd8K<}-)bzRcHPM!TvkN*&;UZObm|SG^7&`^(zQY*>9Uz8DutJO`fWuUIctN;#>?~h zLrTb%kYY7>Zm>O(<6s?4_Qnl3d8ix59r;v%I^?R)k7D>$S)HJX%F-)6mD5*zm93w7 z`2SVqo5DYj=1R-uK)+AK6ll{B<^HRkdaE^3@%LzZy+#Q6%NWv7EhJGR&R$GZH4ZgZ zPF{_|TPwb~I#}%rgEH)kP;|%aFP_S5(-96`6X8#321ZIq+*!=BZjn?-ndsv}rQpjb zud_Mi6PDqPC;!jpD2<;OtZKU@UoxmYaZ3!xLey4bPj)5!-2#%wiw#ztU+O$^)c7;spV_*Hpxll-0=wQx#NyXb zbw8w)#lKGfbLmR%C13p4Dbv1o`3vifuXRe}*TMf2%m1`J$}cUxLATLUf7@ck?UHX$ zC}#EFdK7C!(^|Wt@svIc}d;h0*chzFYc(f_t`<=W4t>bP=v_N&0>G6RYIisX2 zJIV86bJ-;!^$ zg1)ZOHPH-zcCm+9GP4CmNzk14Pm@w~zYeHjU37&Bxb+i0R;tUf;-QkO?$m(Uz|$#1 z;kp^OC3QsbTB)-L?#w8xn^yO3@o&O&)qqc>KAPrG@o!R*kcWt|=X9PgC~^Z*d-ljH@k{a^IU*&%X`Ot%e~{B2`GM>(r%OC9&%%yii2CsJ z{MrEJ%Fl5@(>zL@&g+6>M>=tNRKhsm`~j1l&gjCFm|xPprWRS9Zt~?l9zlw`c)!Un zJ3No{t9LoC`yF^jSE5AR9)Ma{ZX5kr{~oSqbiMrgxSnB0aLWuPhqCT=C%hx|d8bW4(jL zDm{Mh|@RE-6x?elr zWP>nSOCfXRjbDv;o%n~p=JQ=j*l!`8g9}%B43cIQZ}p(9t>Cwin7RGVK@-yDBah+I zk(?_Y!=0|<-ji~tG1*^wluPH$HSAeFMp^z_&jK2gXT@CFi#jJs>*S$*SF$rY_oA+z z6Xh@Cb3GSIhvJJo_lj05l^(;*7)vD@!}Gd*F~dDqOIPx1*lOv1CE!k!r`w>h&WAB> zG~1t3^6qr9(v3>zbr}VC@_|q5ao2O5)4LfuuS+_*`=vAQS?KO{UN@qLFElNA9leet zmb)H@K1sUG=~vdJtaE&Z*GZl|sGHX|r-RAIU2bz4m)pE#KyRy|mn>k{kcj2+86{P$wz*E>m`FCZ(I4|I9ii_3eI^xxw%-!6XBt6U1| z@s5{|OugbGzfg!bEb&V@7FHwLS|inG-S7&MH~ZYgn=|$RYovFTRlle6;mVu8XY*Kv z-;Lt`Qey7LOTXqRC3lAfQ87MFfqt$&w|G#GWnOnUrM|;oP>$T~6hwQUa@|qSD?WR$ zE4}7(&FQ<$Z-EyS*LxwEybxCCxo^4r25y+S?Q|w)3#Omjpn6^|(``8uX8S$^-YJkbmL55G$45O``o#ABhGuMSjh#+6O1$Z!{40W{JQ;))P2bXht&YaF7Z%8aSCP1y-}Qz*@F7xTh$l z0LAPzSHS0|s0v(j3XiV96M(~m>x8vl$c;kY0-yNkEy8Du&~HPm$=ocg$6y^CeGIQx z2?tV!ld$fy2DJ$DC4raWG(Y;XNO4&>U4v6J{wM&oSmqV%g=m>mu*|oxGmt5rD__nM z%@M*U3O=`@ql8Zsd_rTQgikzte9b+DPjC37#`NaY7;A6gS^?FlmSERLxc zPW3{wMOe3Jas}HRa|}Ko11Zrlp}!;wxD356_OkH5EcDk-t5{64s+@aYZx!?C?ZaBtyR0PDV>a$&6y87hRn0-if! zC&C(SUMQ^f(0mYEFJkM3&r-=sUAIY?w}{{^!mtIdto;$8KL$CW{V@@COjs`o{bk{Q zS!gc9XGnWlrp83c6>LHKD7hZhiV~W5nVQiX`mODILmwX9Tj&eqftjvZYg{c&0FBJGH#0~c#E)ZgWlKN z4E!zl7_9r_j)~%r32O`VR-NgxAWXNMd75Nh1zt`k>$WrZcv(jkl67Lb>9(+>_;C0b zOi}Q;FFs26LqJ|HwG8?=Q-$!a5Sj}3ykU*6K-jhT zi7=bYb-)x;y^f~IQpo#)8i8F+TZCpC>HOSuwGpFUO z)FeAm9#_aeM1}(&G(`waJmklMa)IMb)&hL_CzJuFnI-}=%yqyT(^6oLxe@rVsTsK3 z)B;?Ci{s1L)249X^QK(jOQtg50aG3Dh^Y~H%G3;e&(s3EU}Db8+2A~4as6zFT-2K+wwB=CpGYrw~XwzyC`jtRUhP<9n9bETwFLXL;L zFQ~VW3m`|ED}+1|vah*b$Xf&+6L?vm>}C~-+(aTblH(yGk&p`@Bax6NLQXW-3wbGI zU-K3rZ-e}O@G&8ug#1I~Wg&BS$|ehp5Evz}r@-C<%iR?#oGJuaD6n4OCV^W79uas< z;7R-jWinq9@@0Y7pxGD1Jw#ywT|KDM5kig<7!OUNIakO%1@;zL0KL`MTqa1lzzTtN z0v8Ib7uYCplfW$kj|e;_@RGpG0`ay?YPUdFPpVvmkfQ|l6xdr}0j%!UgmOVD1Wtr1 zBw?YD>jf@_CN^P{khcij2FOY5B7|&>5?}F9^-t(6ndLb``JT762khejens7|WCn3*HxGdyr zkn0lUc2t;ayX9AwQAOTgU~FJxvuto@fOLGt~>S6!J9F79nqgTxvQd@A9ce83bX0kbOf5oYK4Sid z`%t1>fn@^g1U3q67T6*%-k&C50npbx5$K<=6qsRVCenusEHhEII)P<){U~;8K{RnT0LK3xUFckDGIW>&#`q&E`7bc5@5Ry4TFYm$TQ* z;lLB-T;RXWWx$Wjb-+vJM&MWGX5bIz7T_H-i&)N_Lc)PwA-TXBQyK7cQytJ4(g+L> zX$HoJv;b2>Smbh+9TE=g6Os!Y5K;yl8d3)wZ4GI}*Yl=k;DnGC;Pem{wVcfj2?y4P zlCA1DWE3^@aZUd}nKSU4~uEEkv% z7M{4ArG@1Je+w=HrkLu0I#UbKV9HIRgKrt|VN)Hj$W+&f4r7ft;leR3H?@g%3#&_| zdD|$kSzwDmmPYz;fw=<91l9>`6xb}VMIh@e`~~I;EE8BKuu)*Mz?RNp|IgAzfWTaV zWdiF2HVSMO*dmZ+2!DaO0?P!}32YSDEU-l&%M|_sa|Ms_ELqs=}IqJHpDco7k6OjlhU-)~$(^hnE2x!ppihv9sYVK(~m- z9!+deL^JR)YeWma-i#>g*Tn8bH20^1TLiK~Q3-*$g-t9wGFQlD0_y}e3TzhGB9Ik{ zD1o^G%LLX5Y!uimutlJi4G;kWa|blB+Q?iXmkF#B*eI}BV2eODP(%%EVuvHcg`6v} zOkkbBMuE)&TLiLV5hXBJV57B|c8$%zXmblN(Hvev3yNIe50PcS$Aaq0-$t)A3uI$R zZW)W-iVUBKZj34eZjNfUke*E=%oSKCuvs9RF7yKH1U3s~RqchLim*;#vp`lY^aAS$ z_wV%L3J(e>K91j}^FrSNRv6v_e%UBH1Pug*Rj});DKr z5Mwp5RX|61cRFeM#Sm6y%mV7-Nd72_@V{FvS>&VQBaxK!4`*axJ0M?Xn4(z^*2e z{~WA_{r4!ffK#HW?28C9ct?xTcfr^?Hk7yIJWH1%}5a&=VZ}0LH;z&J492pRK2RPsw#4FVgJF; zxZdmnkp9WInze@Op!o-oxDzyMxgMGZpoHHGo$(8*6VQb{$z7md2gLjSnJe_pKo>mw z=?48%K)flRxkIx7zg*Dcn;y`(Tk&#g7d(>b1=U6%{cYWL2=)ZJ;BibmA%e#+@gxi` zv-v>Z4(Ni1FMXlk0;CH2LGJ@}!6jdR@aKRMcmOoda|1Ll043(njL>Z5fzWINO7Ot^ z}EQ`zx3U`aqxy9-uTszY{3IF9iBvpbMUl42AwBpv1CS7&Ngr*6I`+Tr>b-}}m(a^jClR9vYz*rF&0*dVn%965F2N;2^Eyw0<_(~PzsT4Lnr5C1%@Lr)#<3J= zj`CD!jsYb$0hb!_>W_)|!evw58HP835{?Jy(462I(EM|MqLHUbF_+kTu>8*6NBi#r zC6>!SgxnJ-v0nT<aXeW5JLI|i9^_h}glEJ#9-Ojr8CYlK zPMqU68Yhs4xiheyyF#-FD6wVS9k`r(0$1>Mz?FD4FUJGZ^k+0yaX;YWJOG;2K+IXm z2=tbMpz#4pco4}1*$;>*C51o^07}dtg+Vq-4Yz{%Y3n?xH*|GU9&nMA4}3%_04|XV zfsaZ9fJ>!f;A&|Q&tnFCC%lI^P@ls3vS7%4nHh3E3x%A|!XeLLze1kF?m(_#cOlo{ z7vL1U`CM}D1k^#U#oy-W1az^2%)?*E=mhkDJfC?%p3l4?FJQiq7chUwR%U=~Wr2|E zSTN)|W`?|wg+gA)!XZD*A|XG_q9NnvXvp;}4)P+F0C^GX2>B6~1o;t`40$n2b@u6m zug)M#SOyGBSXP4^!W-Hz*Ja~ppj^IEH?#Tur8ZvIq zj2>f0k50)-X5C8gr#EH{v6PH`2!DlRT=|q9V@8ioO-^pO5zYM@yd$|w!{;&F+c`CP zG@QpbZ0yMc8-wiu#?ALMZ~IOzk^M=nV}+qM%Gk6;8VJ z)X~We_}hX8R8e?mXy2LIcNf)>r)kO4G`F;dZ81CyY7vzs%!Y;|C{RvK?c9(b%?J69 zA2(z42#aM(-|~tXmMYP%baFB94B^?ZHJTfx)GmTVq^71*3k#-BoH4Pya^l=^6p$`- z_l>Kxl#gxb6vItHsmU4ShOX>eRX$~0X;o!4Ii@8ytftndriyRWLAVW`VVNd+Cqq!G zQO~Ir6SUf>${t-PJhLG*k{cv^i(X7ozdNL5if%_-ukwn?y)Bik4H5c$3u)B?)PROb zvAl11T5=YJ6;B&Cwa>U&LoAlc>iZ{79c!6QuBj7v%Pv-X|YML6;<`=_+$kIN1IoiIWv zt;3tsfhXxwQF_CfDDE#Ok5(;mDumov?jHc*&)wf}sRO?zCb4illZZ*_lE@<(inrrs z;;F5)>6`2OG$4nhkg9 zRLzhHRhAhuD)EPc3Z~8&S2e4=lJxsy$McI(-a9{zE6j2JW#Ber$Jl>%uKHxZ|8hRZ z&($T@Q>HyB+rI*@%5V-yNy44Gc+HweYEo)aN@98Cv7L*0u!s^OCtxi1ViUgTNMh|J-vYeUO+9@#KxJ2yJx)ad4Xd`}Ae-K> zaXarKWo0#dyq%}JrgXt=$bGSPP+hWia5~JeZk%PR8tV>qVBX!qV;ex6Jlb?R)afqC zU2s-_dkNGUCGO<@F3Gr`Sky(7JaH!u;HeGPojeC$Z|vlm=<1($@;uDh?z{L9>?NPr z#Y=RZM<;h^$W7-#`|s`I+x3Pm+rD^(`i7pTqcLzJ(A zgNh1@DJUXog++@B(L5pk^uY#G?SqDVYGe9gYZGEHQA@S&x$K(u<9Xh>=bkxp=FGV> zXWpe|P%`{LQl)k(78pzMVl1gG=6fN)5YE^O{EcOd^_m#d;%R;NTgT^00^Ca0F?P!J z7j-z_ESWB(@r^ce-X+lrU7{3dGb-sNhEhJpFO>hwMk5$_jIAE6U>C}JY-2@f^j*%2 z?6eZqc0R^tA|JAg6;yn(y!_79 z?h*}TPO(BGU+AP4DtMcvm2;J|Rw&`KUF1B_#+^4f$6DToEPB0gMeHrIbLYJ-L0HrG zF5W^Vzb+jep_ay4-pZv~QPO)D_9H`d1LX|>ztY3&_+DW!OkZg#MWw|QCZ+`X-KMHb0}|G|5aFpRu}@>xEy z7OBx9=`HWszSf?;mr|r3={EXVZAQd*@{{gwweArmA;4-=8DQ-hdMPcLK)UJ)RvW)S zt4;Y!>Aol_6jqy7h1EtDWR(g;sV&HA6RWiLG`y5-gGo0#*lN=ooMK;L$5@4g2ZX#D zl!U!i1oYc8R&LAKU5C*F*a?$n=<@9NmXKvK|JyUqIJD1@@S?A-q__SG-KIF{UED3*GHKj}? z!Hmly$6Y%aIqrKlE^=8>)k#0;=&Xu4#t+U7DCV%|=bSz;&QX*@p9cGz_nR7b&A1e? zt>W>HGny&)?py4;i_Uk>cbTrHFH&Dcj(PmO`Dgt$i^_1j^!Vp>>gTUDtwKfKi?HHDdznG==(6S#Km{g z1CQ*e_D9?IxHP=y&<}kr9C;?48SnTkb!J=og<}^|YMNqE*8-u}HgEW!-diql?|*nY zYQ^)(iyNS)GS{V<`R;=qYa*JQ$^zZrNdD}7TN!eWiDMqib}v7=Q@!uOUy}pOLw_O({Uv|Z`oEnzh z>A#()8^_oatYCv|>LqEM!;GVcqOy*@;jsH6^h0n|Ju&{1qWK?9YuWMfU`lC6X|SBJ zPGso1{bv!cZ&(}C9RJ?dZ_8^6E1(a=Mmk*VShM-{NzvU+Uulvr@7VtkdYZRv$Jh&} zRy=l&KM~@4clRavbFDjLgK)HKmgm->-lH=*fBNUl{(+O@=)GV+cv*h$Ud_s=V|8CWeYXGE zs=Lq+AsJ6x%!5;=-HBK430rV`^5X?J6363mLPzAYH1(esd=qozSw>0t;Y(jNL$5_9 zs%QUX_vzL1GfpR^Z~7|wYN^x{dRzWx*xa&^DqG4htIVVxwtWbaQH@ z&$7fT=%CE%I{yCR$B<{yEfN2!{OM+JY`72ZQ(K-8K39?_;XA|U`julOr?e=61SC4sZpnzxDncJtFb1AC`!2X?pEa9-|RE+fmq3%q?IAoOUWMQLE6++O# zHqgQ)vav&IG4Vs#24if0AY&tVr!jt$5U!FjLol+8OqXDpeXyhRl>)sNd^5~7pkigr z3wtvSooWnj#lVZe&?|T%s8&p_#TF_;P#u`ugdi$We#+@U;w%k8-;D7@b%x;d2As5d43Y+otE>Jj<O$g=3QqR))zV$r(On z8el*`Rd5&%7!YJQ`a9sb2!U5XPQ=p>&Kc~s`7&03fIH#43p&b54{X$!^a|$62A-g= zwhXHqK$>R3$O{Ae;hbU86s)ij@8O8PAC4Q)-+^Zh2CA`=BskB5!ve@D7()}(!g(X? zrLdF2PK*8lET#(nwU{gsL2F^(iav&H*+OqN#d>)LjyNJLd_;G4xO<5yKewPDdtFXe za!!FUe@jO8!cFG##VUzJ>djl0CJ3|mKbGzWM=M>X5d!(yWud|ies5W>aFM4jzaW^n zTUr)+i_?51j(+BSX#s+e%}>9jgzc@j&QI<^X6)H_fySJS%xvTG<(1A@6te5gq&F5D z3uYS1?gmlUz}r@q34=UB7Y}b6b#m_kf24?=I}WR*n~eFhvy3?f zG-EKY*U>E3b)FJiU;a1UPKjdx-?D0jpySt9d3r}9jZW-byWW(MlVi+IHY^`qK{OXu zdrqpPq_Uw$IT;&_v@WVLQg-HkB7!V1&dJSPzfRN#^VzFk!z{(Cr-KZCyn3oo$G=|f z>3<4QxiVuL)-^XDJ{AF+EHeypw>5Ha9kM57h9s*+LUFQz?r$xRTeDJ7^8;(9gZ^Gy zv)EfEMjDy-dX7HVU|jlUvc->y$E3f8FSao~%wrpNuLHaC`7&dEX6`1Vn5#kFmL4YY z^W*=U{)*7coia9gq#!JNrp%w6qc`Q|k1n{CS7$8tFA+aP)xzb*%w_A0g~;aIT>a)v zq9Yv_GL=FS4?$bWlQTnwhkRqET!`h{Gbae0yeV_K5Xo;r*7B#Y>EZr*jdw8iq%+%6 zG$-4bkv}IxZ?bF={Ql6-L(0zTL$S4SCuO${Dt-HD%>I z!r%+Lg=iD`I>Q=l&Z~wO5?K)cgK>&P>cgKI6NFYCw|0V1#aE#<@lv$+dHq@?e(`*| zHWYC_KwHP%vcj;6xU306FkhABi^z+!l#uJ8DdF8&8t-V-Felc0F+Zd5jm)>PDUopc zG=bdB6q;OuvuDrdomrf_IbV-8(S6p8b89R6_T3cY+5+)@!{@M(McrPKnWtqqu*$nZmCb`gW-fLPoMwn*)X3OWEi2cN`7x2DaV_Z_0TcQmUaJ(58N|ZJ> z%!bGB^ibH42BWFgQt=fFFjPpkcnfE9r`?74Wwdp-#+5cPdBE86Mt*g-Mi}6BRT}ip zMjOpb(VF<#Dl<0GhH6cS)cY6v!2gid7TJ+Gme1nXs>y@X9%^3~+pS{TEw)d^Hi~Op zsnF8wQYI}=m6eJ$~HR z`?>c1haG9x3n|?7uo7*=;i+gd4i}=m1$l@&9hrx-n|eekn9Q4xWZ5F1uYYq0ODb-h zilcO*QHc+Bt#J+xnp=|+`lzO-yKU3=sB(VO#%OK*nVQF zH*p8b2}MjC!kV9c^R*K;LVPf*VBXBT92TtDmJZ5?q6xk0@WTS-8pq+omo{5%6Pd!c z!s^C+xn+{1?EhdypzEE`3OM5P&@D|oqY9uKxD)6Dh~JF>k*J_lMNL2@K!v^spliqx zH+e8XWl0*!UXb6=bB1y#9%7I#C85}?$mh})IZZQlHk04O( zCTJ}%;7K6zLYVrm2;UOEe&fB}|3CbHE93|KINCt(^9TLLjDs^~+2 z42+5x8G-66F)YGpoi&g7U690n5PGRQpVGF-i3nRA(8IU4Eyf;bAc;S ONg~9=+9SEpA^$g0Z~mtM delta 4968 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 ONg~9=+9SEpA^$g0Z~mtM delta 4968 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 the version of the DLL. [DispId(2)] string Version { get; } + + /// Gets or sets the throttling interval in milliseconds. + [DispId(3)] int ThrottlingIntervalMs { get; set; } } /// @@ -73,8 +76,15 @@ public class WebView2Bridge : IBridgeActions private SynchronizationContext _syncContext; private readonly System.Diagnostics.Stopwatch _throttleStopwatch = System.Diagnostics.Stopwatch.StartNew(); - private long _lastMessageTicks = 0; - private const long ThrottlingIntervalTicks = TimeSpan.TicksPerSecond / 50; // max 50 calls/sec + private long _lastMessageMs = 0; + private int _throttlingIntervalMs = 20; // default 20ms + + /// Gets or sets the throttling interval in milliseconds. + public int ThrottlingIntervalMs + { + get => _throttlingIntervalMs; + set => _throttlingIntervalMs = value; + } // v2.0.0: Parent context for Sender-Aware events private object _sender; @@ -124,10 +134,12 @@ public void RaiseMessage(string message) { if (OnMessageReceived != null) { - // Throttling: Max 50 messages per second (Law #2: Performance) - long currentTicks = _throttleStopwatch.ElapsedTicks; - if (currentTicks - _lastMessageTicks < ThrottlingIntervalTicks) return; - _lastMessageTicks = currentTicks; + long currentMs = _throttleStopwatch.ElapsedMilliseconds; + if (_throttlingIntervalMs > 0) + { + if (currentMs - _lastMessageMs < _throttlingIntervalMs) return; + } + _lastMessageMs = currentMs; // v2.0.0: Pass sender and parentHandle for multi-instance support _syncContext?.Post(_ => OnMessageReceived?.Invoke(_sender, _parentHandle, message), null); diff --git a/src/Core/WebView2Manager.Main.cs b/src/Core/WebView2Manager.Main.cs index 0fc1047..c5675c7 100644 --- a/src/Core/WebView2Manager.Main.cs +++ b/src/Core/WebView2Manager.Main.cs @@ -139,6 +139,16 @@ public string FailureReportFolderPath get => _failureReportFolderPath; set => _failureReportFolderPath = value ?? ""; } + + /// + /// Gets or sets the throttling interval in milliseconds for messages sent from JavaScript to AutoIt. + /// Set to 0 to disable throttling entirely. + /// + public int ThrottlingIntervalMs + { + get => _bridge.ThrottlingIntervalMs; + set => _bridge.ThrottlingIntervalMs = value; + } #endregion #region 6. CORE INITIALIZATION diff --git a/src/Interfaces/IWebViewActions.cs b/src/Interfaces/IWebViewActions.cs index 26ecedc..b17a2cb 100644 --- a/src/Interfaces/IWebViewActions.cs +++ b/src/Interfaces/IWebViewActions.cs @@ -256,5 +256,8 @@ public interface IWebViewActions /// Gets or sets the folder path where WebView2 failure reports (crash dumps) are stored. [DispId(226)] string FailureReportFolderPath { get; set; } + + /// Gets or sets the throttling interval in milliseconds for messages sent from JavaScript to AutoIt. Default is 20ms. + [DispId(231)] int ThrottlingIntervalMs { get; set; } } } diff --git a/src/Properties/AssemblyInfo.cs b/src/Properties/AssemblyInfo.cs index c5059ea..dac439e 100644 --- a/src/Properties/AssemblyInfo.cs +++ b/src/Properties/AssemblyInfo.cs @@ -28,6 +28,6 @@ // Build Number // Revision // -[assembly: AssemblyVersion("2.2.1.0")] -[assembly: AssemblyFileVersion("2.2.1.0")] -[assembly: AssemblyInformationalVersion("2.2.1-alpha1")] +[assembly: AssemblyVersion("2.2.2.0")] +[assembly: AssemblyFileVersion("2.2.2.0")] +[assembly: AssemblyInformationalVersion("2.2.2-alpha")] From 18bfa544eabd9b789db4b5e8d93d7cefaad74de6 Mon Sep 17 00:00:00 2001 From: ioa747 <97930522+ioa747@users.noreply.github.com> Date: Fri, 26 Jun 2026 13:42:16 +0300 Subject: [PATCH 02/15] v2.2.2-alpha Added configurable message throttling for JavaScript to AutoIt communication and updated key features and enhancements. --- README.md | 82 ++++++++----------------------------------------------- 1 file changed, 11 insertions(+), 71 deletions(-) diff --git a/README.md b/README.md index 9dfda9f..4d0fddf 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,6 @@ A powerful bridge that allows **AutoIt** to use the modern **Microsoft Edge WebV https://www.autoitscript.com/forum/topic/213375-webview2autoit-autoit-webview2-component-com-interop --- - ### 🚀 Key Features * **Chromium Engine**: Leverage the speed and security of modern Microsoft Edge. @@ -29,7 +28,6 @@ https://www.autoitscript.com/forum/topic/213375-webview2autoit-autoit-webview2-c * *The registration script will check for this and provide a download link if missing.* --- - ### 📦 Deployment & Installation 1. **Extract** the `NetWebView2Lib` folder to a permanent location. @@ -56,7 +54,6 @@ https://www.autoitscript.com/forum/topic/213375-webview2autoit-autoit-webview2-c --- - ### ⚖️ License This project is provided "as-is". You are free to use, modify, and distribute it for both personal and commercial projects. @@ -65,85 +62,24 @@ This project is provided "as-is". You are free to use, modify, and distribute it

+## 🚀 What's New in v2.2.2-alpha - Configurable Message Throttling -## 🚀 What's New in v2.2.1-alpha1 - UI Responsiveness & Refactoring - -This release marks a major architectural milestone for the library by introducing **Event Object Refactoring**. Key events have been transitioned from passing raw data (strings) to passing full **COM-visible objects**, granting developers absolute control over the application's navigation flow. +Provide a configurable throttling mechanism for messages sent from JavaScript to AutoIt via the WebView2 bridge to prevent message loss when throttling is too restrictive for certain use cases, while keeping safety defaults. ### ⚡ Key Features & Enhancements -#### 1. Advanced Navigation Control (`IWebView2NavigationStartingEventArgs`) -Navigation is no longer a passive process. -With the new `Args` object, you can programmatically intervene in the navigation lifecycle before it even begins. - -- **`Cancel` [Property]**: The ability to kill a navigation request at its source. Perfect for content filtering, security, and custom protocol handling. - -- **`IsUserInitiated`**: Determine whether the navigation was triggered by a physical user click or programmatically via JavaScript. - -- **`IsRedirected`**: Automatically detect if the current request is a server-side or client-side redirect. - -- **`NavigationId`**: A unique identifier for precise request tracking across complex web sessions. - -#### 2. Event Object Refactoring & API Maturity -We are moving away from "Raw Parameter" callbacks toward an **Object-Oriented Event Model**. - -- **Breaking Change**: `OnNavigationStarting` and `OnFrameNavigationStarting` now return an **Args Object**. This change is essential to support bi-directional communication (e.g., AutoIt telling C# to `Cancel = True`). - -- **Future-Proofing**: Adding new metadata in future WebView2 updates will no longer break existing user code, as new properties will simply be appended to the existing object. - -#### 3. UI Responsiveness & Interception-Based Locking (Critical Patch) -Following the initial alpha release, we identified and resolved a critical issue where Developer Tools (F12) and Right-Click menus could become unresponsive after navigation. - -- **Interception-Based Locking**: We moved away from toggling engine-level properties (which caused state lag) to a robust **C# Interception Model**. Features are kept "On" at the engine level but are blocked via the `_isLocked` flag in C#, ensuring the "Inspect" menu item never disappears. - -- **C# Fast Path**: Common actions like F12 are now handled instantly within the C# layer, bypassing the AutoIt COM overhead for maximum performance. - -- **Guaranteed Unlock**: Improved the AutoIt navigation functions (`_NetWebView2_Navigate`) to ensure the browser is always unlocked, even if a navigation times out or fails. - -#### 4. Refactored: OnDownloadStarting Event -- **Transitioned from a parameter-based signature to a robust, object-oriented argument model.** - - **New Argument Wrapper**: `IWebView2DownloadStartingEventArgs` provides access to `Uri`, `ResultFilePath`, `Handled`, `Cancel`, `MimeType`, `ContentDisposition`, and `TotalBytesToReceive`. - - - **Hybrid Deferral Model**: Implemented a performance-optimized synchronization mechanism using `CoreWebView2Deferral`. The C# core now waits up to 5000ms for AutoIt to set `Handled` or `Cancel` on the argument object, proceeding immediately once a decision is made. - - - **MimeType Support (Issue #123)**: Exposed `MimeType` directly in the download arguments, allowing AutoIt scripts to identify "unviewable content" (e.g., PDFs, ZIPs) at the start of the download lifecycle. - -- **Improved: Download Logic**: Automatic redirection to `_customDownloadPath` is now applied *before* the event fires, allowing **AutoIt** to see and potentially override the final destination. - -#### 5. Refactored: OnDownloadStateChanged Event -- **Transitioned to an object-oriented argument model for consistent event handling.** - - **New Argument Wrapper**: `IWebView2DownloadStateChangedEventArgs` - provides access to `State`, `Uri`, `TotalBytesToReceive`, `BytesReceived`, and a new `PercentComplete` helper. - - - **Buffered Property Pattern**: Applied to ensure thread-safe progress updates during rapid download cycles. - -#### 6. Fixed: HTTP Status Code Detection -- Resolved a bug where `OnWebResourceResponseReceived` failed to fire due to a missing legacy header hack. Replaced with native `ResourceContext` detection. - - - -> [!CAUTION] -> **Breaking Change**: If you have custom scripts using `OnWebResourceResponseReceived` or `OnDownloadStateChanged`, please update their signatures to use the new `$oArgs` object as demonstrated in the updated examples. - - -### 🏗️ Architectural Inheritance & Refactoring - -Building on the foundation of v2.1.0, this version further strengthens the **Event Wrapper** hierarchy: - -- **Base Inheritance**: All new event objects inherit from `BaseWebViewEventArgs`, ensuring that core properties like `WindowHandle` and the `ManagerInstance` are consistently available. - -- **Uniformity**: Whether you are handling a sub-frame or the main browser instance, the parameter logic remains predictable and standardized. - - -> **Why this matters:** The shift to objects transforms **NetWebView2Lib** from a "simple browser wrapper" into a **Professional-Grade SDK** for AutoIt. It brings low-level control—previously reserved for languages like C# or C++—directly into the hands of the AutoIt developer. +#### 1. Implement the ThrottlingIntervalMs property on the manager class, forwarding to the bridge object. +- **`ThrottlingIntervalMs` [Property]**: Gets or sets the throttling interval in milliseconds for messages sent from JavaScript to AutoIt. + Set to 0 to disable throttling entirely. + Default is 20 ms.

-## 📖 NetWebView2Lib Version 2.2.1-alpha (Quick Reference) +## 📖 NetWebView2Lib Version 2.2.2-alpha (Quick Reference) ### 🟦 WebView2Manager (ProgId: NetWebView2Lib.WebView2Manager) @@ -202,6 +138,10 @@ Enables or disables custom context menu handling. Sets additional command-line arguments to be passed to the Chromium engine during initialization. Must be set BEFORE calling Initialize(). `object.AdditionalBrowserArguments = Value` +##### 🔧 ThrottlingIntervalMs +Gets or sets the throttling interval in milliseconds for messages sent from JavaScript to AutoIt. Set to 0 to disable throttling entirely. Default is 20ms. +`object.ThrottlingIntervalMs` = 20 + ##### 🔧 HiddenPdfToolbarItems Controls the visibility of buttons in the PDF viewer toolbar using a bitwise combination of CoreWebView2PdfToolbarItems (e.g., 1=Save, 2=Print, 4=Search). `object.HiddenPdfToolbarItems = Value` From 62517528725ee348a324c49f4b2ae72c050a4f99 Mon Sep 17 00:00:00 2001 From: ioa747 <97930522+ioa747@users.noreply.github.com> Date: Fri, 26 Jun 2026 13:42:54 +0300 Subject: [PATCH 03/15] v2.2.2-alpha Added details about configurable message throttling in v2.2.2-alpha. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4d0fddf..6cd3fdc 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ This project is provided "as-is". You are free to use, modify, and distribute it

+ ## 🚀 What's New in v2.2.2-alpha - Configurable Message Throttling Provide a configurable throttling mechanism for messages sent from JavaScript to AutoIt via the WebView2 bridge to prevent message loss when throttling is too restrictive for certain use cases, while keeping safety defaults. From 07cd09fbd4f6b672aabe1e424a8bb0e5907a650b Mon Sep 17 00:00:00 2001 From: ioa747 <97930522+ioa747@users.noreply.github.com> Date: Fri, 26 Jun 2026 13:43:58 +0300 Subject: [PATCH 04/15] v2.2.2-alpha Added a section about the new configurable message throttling feature in version 2.2.2-alpha. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6cd3fdc..d15dfdb 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ This project is provided "as-is". You are free to use, modify, and distribute it

+ ## 🚀 What's New in v2.2.2-alpha - Configurable Message Throttling Provide a configurable throttling mechanism for messages sent from JavaScript to AutoIt via the WebView2 bridge to prevent message loss when throttling is too restrictive for certain use cases, while keeping safety defaults. From 2dc30985635074b9d6cdd42b0ab5a5c84340a0f2 Mon Sep 17 00:00:00 2001 From: ioa747 <97930522+ioa747@users.noreply.github.com> Date: Fri, 26 Jun 2026 13:46:34 +0300 Subject: [PATCH 05/15] v2.2.2-alpha --- NetWebView2Lib.au3 | 107 +++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 56 deletions(-) diff --git a/NetWebView2Lib.au3 b/NetWebView2Lib.au3 index 0a3c54e..ef9f4c0 100644 --- a/NetWebView2Lib.au3 +++ b/NetWebView2Lib.au3 @@ -6,7 +6,7 @@ #Tidy_Parameters=/tcb=-1 -; NetWebView2Lib.au3 - Script Version: 2.2.1-alpha1 (2026.04.14.10) 🚩 +; NetWebView2Lib.au3 - Script Version: 2.2.1-alpha1 (2026.04.14.07) 🚩 #include #include @@ -150,23 +150,25 @@ Global Enum _ ; Indicates the reason for the process failure. ; Name ..........: _NetWebView2_CreateManager ; Description ...: Create WebView2 object ; Syntax ........: _NetWebView2_CreateManager([$sUserAgent = ""[, $s_fnEventPrefix = ""[, $s_AddBrowserArgs = ""[, -; $bVerbose = False]]]]) -; Parameters ....: $sUserAgent - [optional] a string value. Default is "". -; $s_fnEventPrefix - [optional] a string value. Default is "". -; $s_AddBrowserArgs - [optional] a string value. Default is "". Allows passing command-line switches (e.g., --disable-gpu --mute-audio --proxy-server="...") to the Chromium engine. -; $bVerbose - [optional] True/False - Enable/Disable diagnostic logging. Default is False = Disabled. +; $bVerbose = False[, $iThrottlingIntervalMs = 20]]]]]) +; Parameters ....: $sUserAgent - [optional] a string value. Default is "". +; $s_fnEventPrefix - [optional] a string value. Default is "". +; $s_AddBrowserArgs - [optional] a string value. Default is "". +; Allows passing command-line switches (e.g., "--disable-gpu --mute-audio") to the Chromium engine. +; $bVerbose - [optional] True/False - Enable/Disable diagnostic logging. Default is False = Disabled. +; $iThrottlingIntervalMs - [optional] an integer value. Default is 20. +; Sets the JS-to-AutoIt message throttling interval in ms. Set to 0 to disable throttling. ; Return values .: None ; Author ........: mLipok, ioa747 ; Modified ......: -; Remarks .......: $s_AddBrowserArgs must be set before calling _NetWebView2_Initialize(). -; Multiple arguments must be separated by a SPACE, not a comma (e.g., "--mute-audio --disable-gpu"). +; Remarks .......: $s_AddBrowserArgs must be set before calling Initialize(). ; Related .......: ; Link ..........: https://www.chromium.org/developers/how-tos/run-chromium-with-flags ; Link ..........: https://chromium.googlesource.com/chromium/src/+/main/docs/configuration.md#switches ; Link ..........: https://peter.sh/experiments/chromium-command-line-switches/ ; Example .......: No ; =============================================================================================================================== -Func _NetWebView2_CreateManager($sUserAgent = "", $s_fnEventPrefix = "", $s_AddBrowserArgs = "", $bVerbose = False) +Func _NetWebView2_CreateManager($sUserAgent = "", $s_fnEventPrefix = "", $s_AddBrowserArgs = "", $bVerbose = False, $iThrottlingIntervalMs = 20) Local Const $s_Prefix = "[_NetWebView2_CreateManager]: fnEventPrefix:" & $s_fnEventPrefix & " AddBrowserArgs:" & $s_AddBrowserArgs Local $ERR = 0, $EXT = 0, $RET = False, $MSG = "" ; predefined endpoint results Local $oMyError = ObjEvent("AutoIt.Error", __NetWebView2_COMErrFunc) ; Local COM Error Handler @@ -184,6 +186,7 @@ Func _NetWebView2_CreateManager($sUserAgent = "", $s_fnEventPrefix = "", $s_AddB ; Verbose property was added to allow real-time diagnostic logging to the SciTE console (or any stdout listener). ; The diagnostic logs use a distinctive prefix and include the instance handle for easier filtering in multi-window applications. $oWebV2M.Verbose = $bVerbose + $oWebV2M.ThrottlingIntervalMs = $iThrottlingIntervalMs ;~ If $_g_bNetWebView2_DebugDev Then __NetWebView2_ObjName_FlagsValue($oWebV2M) ; FOR DEV TESTING ONLY If $sUserAgent Then $oWebV2M.SetUserAgent($sUserAgent) @@ -760,7 +763,7 @@ Func _NetWebView2_NavigateToString($oWebV2M, $s_HTML, $iWaitMessage = $NETWEBVIE _NetWebView2_LoadWait($oWebV2M, $iWaitMessage, $sExpectedTitle, $iTimeOut_ms) $ERR = @error $EXT = @extended - $MSG = " LoadWait internal Error" & " #SLN=" & @ScriptLineNumber + $MSG = ($ERR ? " LoadWait internal Error" : " Success") & " #SLN=" & @ScriptLineNumber EndIf $oWebV2M.UnLockWebView() EndIf @@ -2411,28 +2414,25 @@ EndFunc ;==>__NetWebView2_Events__OnContextMenu ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __NetWebView2_Events__OnWebResourceResponseReceived -; Description ...: Internal handler for the WebResourceResponseReceived event. -; Syntax ........: __NetWebView2_Events__OnWebResourceResponseReceived($oWebV2M, $hGUI, $oArgs) +; Description ...: +; Syntax ........: __NetWebView2_Events__OnWebResourceResponseReceived($oWebV2M, $hGUI, $iStatusCode, $sReasonPhrase, +; $sRequestUrl) ; Parameters ....: $oWebV2M - WebView2 object that fired the event -; $hGUI - A handle to Window that fired the event -; $oArgs - An Event Arguments Object containing: -; | .StatusCode (int) [RO]: The HTTP status code (e.g., 200, 404). -; | .ReasonPhrase (string) [RO]: The HTTP reason phrase (e.g., "OK"). -; | .RequestUri (string) [RO]: The URL of the request. -; | .IsDocument (bool) [RO]: True if the resource is the main document. +; $hGUI - a handle to Window that fired the event +; $iStatusCode - HTTP StatusCode +; $sReasonPhrase - StatusCode rephrased to human resonable string +; $sRequestUrl - the URL that fired the event ; Return values .: None -; Author ........: ioa747, mLipok -; Modified ......: 2026-04-14 (Refactored to Object-Oriented Event Model) +; Author ........: mLipok +; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: https://learn.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.core.corewebview2.webresourceresponsereceived -; Example .......: 007-HTTP_StatusCodeTracking.au3 +; Example .......: No ; =============================================================================================================================== -Volatile Func __NetWebView2_Events__OnWebResourceResponseReceived($oWebV2M, $hGUI, $oArgs) ; <<--( NEW )--<< - Local Const $s_Prefix = ">>>[EVENT: OnWebResourceResponseReceived]: GUI:" & $hGUI & _ - " HTTPStatusCode:" & $oArgs.StatusCode & " (" & $oArgs.ReasonPhrase & ") URL:" & $oArgs.RequestUri & " URL:" & $oArgs.IsDocument - - __NetWebView2_Log(@ScriptLineNumber, $s_Prefix, 1) +Volatile Func __NetWebView2_Events__OnWebResourceResponseReceived($oWebV2M, $hGUI, $iStatusCode, $sReasonPhrase, $sRequestUrl) + Local Const $s_Prefix = ">>>[EVENT: OnWebResourceResponseReceived]: GUI:" & $hGUI & " HTTPStatusCode:" & $iStatusCode & " (" & $sReasonPhrase & ") URL:" & $sRequestUrl + __NetWebView2_Log(@ScriptLineNumber, (StringLen($s_Prefix) > 150 ? StringLeft($s_Prefix, 150) & "..." : $s_Prefix), 1) __NetWebView2_LastMessage_KEEPER($oWebV2M, $NETWEBVIEW2_MESSAGE__RESPONSE_RECEIVED) EndFunc ;==>__NetWebView2_Events__OnWebResourceResponseReceived @@ -2458,8 +2458,11 @@ EndFunc ;==>__NetWebView2_Events__OnWebResourceResponseReceived ; Link ..........: https://learn.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.core.corewebview2downloadstartingeventargs ; Example .......: 021 - Handle Unviewable Content (MIME).au3 ; =============================================================================================================================== -Volatile Func __NetWebView2_Events__OnDownloadStarting($oWebV2M, $hGUI, $oArgs) ; <<--( NEW )--<< - Local Const $s_Prefix = "[>>>EVENT: OnDownloadStarting]: GUI:" & $hGUI & " URL: " & $oArgs.Uri & " PATH: " & $oArgs.ResultFilePath & " MIME: " & $oArgs.MimeType +Volatile Func __NetWebView2_Events__OnDownloadStarting($oWebV2M, $hGUI, $oArgs) ; <<--( NEW )--<< + Local $sURL = $oArgs.Uri + Local $sDefaultPath = $oArgs.ResultFilePath + Local $sMimeType = $oArgs.MimeType + Local Const $s_Prefix = "[EVENT: OnDownloadStarting]: GUI:" & $hGUI & " URL: " & $sURL & " PATH: " & $sDefaultPath & " MIME: " & $sMimeType __NetWebView2_Log(@ScriptLineNumber, (StringLen($s_Prefix) > 150 ? StringLeft($s_Prefix, 150) & "..." : $s_Prefix), 1) __NetWebView2_LastMessage_KEEPER($oWebV2M, $NETWEBVIEW2_MESSAGE__DOWNLOAD_STARTING) EndFunc ;==>__NetWebView2_Events__OnDownloadStarting @@ -2471,56 +2474,48 @@ EndFunc ;==>__NetWebView2_Events__OnDownloadStarting ; $iReceived_Bytes) ; Parameters ....: $oWebV2M - an object. ; $hGUI - a handle value. -; $oArgs - An Event Arguments Object containing: -; | .Uri (String) [RO]: The source URL of the download. -; | .State (String) [RO]: The current state ("InProgress", "Completed", "Interrupted"). -; | .TotalBytesToReceive (int) [RO]: Estimated total size. -; | .BytesReceived (int) [RO]: Number of bytes received so far. -; | .PercentComplete (int) [RO]: Calculation (0-100) or -1 if unknown. +; $sState - a string value. +; $sURL - a string value. +; $iTotal_Bytes - an integer value. +; $iReceived_Bytes - an integer value. ; Return values .: None ; Author ........: ioa747, mLipok ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: -; Example .......: 006-DownloadDemo.au3 +; Example .......: No ; =============================================================================================================================== -Volatile Func __NetWebView2_Events__OnDownloadStateChanged($oWebV2M, $hGUI, $oArgs) ; <<--( NEW )--<< - Local $iReceived_MB = Round($oArgs.BytesReceived / 1048576, 2) ; 1024*1024 - Local $iTotal_MB = Round($oArgs.TotalBytesToReceive / 1048576, 2) +Volatile Func __NetWebView2_Events__OnDownloadStateChanged($oWebV2M, $hGUI, $sState, $sURL, $iTotal_Bytes, $iReceived_Bytes) + Local Const $s_Prefix = ">>>[EVENT: OnDownloadStateChanged]: GUI:" & $hGUI & " State:" & $sState & " URL:" & $sURL & " Total_Bytes:" & $iTotal_Bytes & " Received_Bytes:" & $iReceived_Bytes + Local $iPercent = 0 + If $iTotal_Bytes > 0 Then $iPercent = Round(($iReceived_Bytes / $iTotal_Bytes), 5) * 100 - Local Const $s_Prefix = "[>>>EVENT: OnDownloadStateChanged]: GUI:" & $hGUI & " State: " & $oArgs.State & " | " & _ - $oArgs.PercentComplete & "% (" & $iReceived_MB & "/" & $iTotal_MB & " MB) URL: " & $oArgs.Uri + ; Convert to MB for easy-to-read log + Local $iReceived_MegaBytes = Round($iReceived_Bytes / 1024 / 1024) + Local $iTotal_MegaBytes = Round($iTotal_Bytes / 1024 / 1024) - __NetWebView2_Log(@ScriptLineNumber, $s_Prefix, 1) - - Switch $oArgs.State + Local Const $s_Message = " " & $iPercent & "% (" & $iReceived_MegaBytes & " / " & $iTotal_MegaBytes & " Mega Bytes)" + Switch $sState Case "InProgress" + __NetWebView2_Log(@ScriptLineNumber, $s_Prefix & $s_Message, 1) __NetWebView2_LastMessage_KEEPER($oWebV2M, $NETWEBVIEW2_MESSAGE__DOWNLOAD_IN_PROGRESS) Case "Interrupted" + __NetWebView2_Log(@ScriptLineNumber, $s_Prefix & $s_Message, 1) __NetWebView2_LastMessage_KEEPER($oWebV2M, $NETWEBVIEW2_MESSAGE__DOWNLOAD_INTERRUPTED) Case "Completed" + __NetWebView2_Log(@ScriptLineNumber, $s_Prefix & $s_Message, 1) __NetWebView2_LastMessage_KEEPER($oWebV2M, $NETWEBVIEW2_MESSAGE__DOWNLOAD_COMPLETED) EndSwitch -EndFunc +EndFunc ;==>__NetWebView2_Events__OnDownloadStateChanged ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __NetWebView2_Events__OnAcceleratorKeyPressed -; Description ...: It allows the application to intercept and handle system keys and keyboard shortcuts (Accelerators) before the WebView2 engine processes them. +; Description ...: ; Syntax ........: __NetWebView2_Events__OnAcceleratorKeyPressed($oWebV2M, $hGUI, $oArgs) ; Parameters ....: $oWebV2M - an object. ; $hGUI - a handle value. -; $oArgs - An Event Arguments Object containing: -; | .VirtualKey (uint) [RO]: The VK code of the key. -; | .KeyEventKind (int) [RO]: Type of key event (0:KeyDown, 1:KeyUp, etc.). -; | .RepeatCount (uint) [RO]: The number of times the key has repeated. -; | .ScanCode (uint) [RO]: Hardware scan code. -; | .IsExtendedKey (bool) [RO]: True if it's an extended key (e.g., right Alt). -; | .IsMenuKeyDown (bool) [RO]: True if Alt is pressed. -; | .WasKeyDown (bool) [RO]: True if the key was already down. -; | .IsKeyReleased (bool) [RO]: True if the event is a key up. -; | .KeyEventLParam (int) [RO]: The native LPARAM window message value. -; | .Handled (bool) [RW]: Set to True to prevent the browser from executing the default action. +; $oArgs - an object. ; Return values .: None ; Author ........: ioa747, mLipok ; Modified ......: From 60d64e392906206c32dfc47271435f877749fa5d Mon Sep 17 00:00:00 2001 From: ioa747 <97930522+ioa747@users.noreply.github.com> Date: Fri, 26 Jun 2026 13:50:33 +0300 Subject: [PATCH 06/15] v2.2.2-alpha --- examples/024-ConfigurableThrottling.au3 | 155 ++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 examples/024-ConfigurableThrottling.au3 diff --git a/examples/024-ConfigurableThrottling.au3 b/examples/024-ConfigurableThrottling.au3 new file mode 100644 index 0000000..87c9531 --- /dev/null +++ b/examples/024-ConfigurableThrottling.au3 @@ -0,0 +1,155 @@ +#AutoIt3Wrapper_UseX64=y +#AutoIt3Wrapper_Run_AU3Check=Y +#AutoIt3Wrapper_AU3Check_Stop_OnWarning=y + +; 022-ConfigurableThrottling.au3 + +#include +#include +#include "..\NetWebView2Lib.au3" + +Global $iReceivedCount = 0 +Global $sCurrentPhase = "No Throttling" + +$_g_bNetWebView2_DebugInfo = False + +Main() + +Func Main() + Local $oMyError = ObjEvent("AutoIt.Error", __NetWebView2_COMErrFunc) + #forceref $oMyError + + ; Create the UI + Local $hGUI = GUICreate("WebView2 Throttling Test", 800, 600) + GUISetState(@SW_SHOW, $hGUI) + + ; Initialize WebView2 Manager with throttling disabled (0ms) + Local $oWebV2M = _NetWebView2_CreateManager("", "", "--disable-gpu", False, 0) + If @error Then Return MsgBox(16, "Error", "CreateManager failed: " & @error) + + ; Initialize JavaScript Bridge + Local $oJSBridge = _NetWebView2_GetBridge($oWebV2M, "_BridgeEventsHandler_") + If @error Then Return MsgBox(16, "Error", "GetBridge failed: " & @error) + + Local $sProfileDirectory = @ScriptDir & "\NetWebView2Lib-UserDataFolder" + _NetWebView2_Initialize($oWebV2M, $hGUI, $sProfileDirectory, 0, 0, 0, 0, True, True, 1.0, "0x2B2B2B", False) + If @error Then Return MsgBox(16, "Error", "Initialize failed: " & @error) + + ; Navigate to our test HTML content + _NetWebView2_NavigateToString($oWebV2M, GetTestHTML()) + + _NetWebView2_ExecuteScript($oWebV2M, "window.chrome.webview.postMessage('READY');") + + ; Main Loop + While 1 + Switch GUIGetMsg() + Case $GUI_EVENT_CLOSE + ExitLoop + EndSwitch + WEnd + + GUIDelete($hGUI) + _NetWebView2_CleanUp($oWebV2M, $oJSBridge) +EndFunc ;==>Main + +; MY EVENT HANDLER: Bridge (JavaScript Messages) +Volatile Func _BridgeEventsHandler_OnMessageReceived($oWebV2M, $hGUI, $sMessage) + ConsoleWrite("$sMessage=" & $sMessage & @CRLF) + #forceref $hGUI + + ; 1. Check Phase Change + $sCurrentPhase = StringTrimLeft($sMessage, 6) + $iReceivedCount = 0 + ConsoleWrite("+++ Starting Phase: " & $sCurrentPhase & @CRLF) + Return + EndIf + + ; 2. Check Test End + If $sMessage = "TEST_END" Then + ConsoleWrite(">>> Phase '" & $sCurrentPhase & "' Complete. Received count: " & $iReceivedCount & " / 100." & @CRLF) + Return + EndIf + + ; 3. Message Count + If StringLeft($sMessage, 4) == "MSG_" Then + $iReceivedCount += 1 + + ; If we are in Phase 1 and we reached 100, we automatically return to Phase 2 + If $iReceivedCount = 100 And $sCurrentPhase = "No Throttling" Then + ConsoleWrite(">>> Phase 'No Throttling' Complete: All 100/100 messages received successfully!" & @CRLF) + $oWebV2M.ThrottlingIntervalMs = 20 + ConsoleWrite(">>> Dynamically updated ThrottlingIntervalMs = " & $oWebV2M.ThrottlingIntervalMs & "ms" & @CRLF) + _NetWebView2_ExecuteScript($oWebV2M, "runThrottledTest();") + EndIf + EndIf + +EndFunc ;==>_BridgeEventsHandler_OnMessageReceived + +Func GetTestHTML() + Local $sTxt = "" + $sTxt &= "" & @CRLF + $sTxt &= "" & @CRLF + $sTxt &= "" & @CRLF + $sTxt &= " " & @CRLF + $sTxt &= " Fixed Throttling Test" & @CRLF + $sTxt &= " " & @CRLF + $sTxt &= "" & @CRLF + $sTxt &= "" & @CRLF + $sTxt &= "" & @CRLF + $sTxt &= "

WebView2 Bridge Message Throttling Test

" & @CRLF + $sTxt &= " " & @CRLF + $sTxt &= "
Status: Ready to test
" & @CRLF + $sTxt &= "" & @CRLF + $sTxt &= " " & @CRLF + $sTxt &= "" & @CRLF + $sTxt &= "" + Return $sTxt +EndFunc ;==>GetTestHTML + From f5ce3b5e06fbe308379f5410082a057ec91f4823 Mon Sep 17 00:00:00 2001 From: ioa747 <97930522+ioa747@users.noreply.github.com> Date: Fri, 26 Jun 2026 20:53:11 +0300 Subject: [PATCH 07/15] v2.2.2-alpha --- examples/024-ConfigurableThrottling.au3 | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/024-ConfigurableThrottling.au3 b/examples/024-ConfigurableThrottling.au3 index 87c9531..adf1c7d 100644 --- a/examples/024-ConfigurableThrottling.au3 +++ b/examples/024-ConfigurableThrottling.au3 @@ -58,6 +58,7 @@ Volatile Func _BridgeEventsHandler_OnMessageReceived($oWebV2M, $hGUI, $sMessage) #forceref $hGUI ; 1. Check Phase Change + If StringLeft($sMessage, 6) == "PHASE:" Then $sCurrentPhase = StringTrimLeft($sMessage, 6) $iReceivedCount = 0 ConsoleWrite("+++ Starting Phase: " & $sCurrentPhase & @CRLF) From e146e75364e42392c0cde8e4566fe8e594266b3f Mon Sep 17 00:00:00 2001 From: ioa747 <97930522+ioa747@users.noreply.github.com> Date: Sat, 27 Jun 2026 18:14:24 +0300 Subject: [PATCH 08/15] 2.2.2-alpha --- NetWebView2Lib.au3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NetWebView2Lib.au3 b/NetWebView2Lib.au3 index ef9f4c0..75a0380 100644 --- a/NetWebView2Lib.au3 +++ b/NetWebView2Lib.au3 @@ -6,7 +6,7 @@ #Tidy_Parameters=/tcb=-1 -; NetWebView2Lib.au3 - Script Version: 2.2.1-alpha1 (2026.04.14.07) 🚩 +; NetWebView2Lib.au3 - Script Version: 2.2.2-alpha (2026.06.27.18) 🚩 #include #include From c9c0c6197a81731943de0714e7992835873ca131 Mon Sep 17 00:00:00 2001 From: ioa747 <97930522+ioa747@users.noreply.github.com> Date: Sat, 27 Jun 2026 19:41:40 +0300 Subject: [PATCH 09/15] v2.2.2-alpha Added support for dynamic throttling in the WebView2 test, allowing phase transitions and message counting. Updated the HTML structure for better user interaction and feedback. --- examples/024-ConfigurableThrottling.au3 | 63 +++++++++++++++---------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/examples/024-ConfigurableThrottling.au3 b/examples/024-ConfigurableThrottling.au3 index adf1c7d..ccfd29b 100644 --- a/examples/024-ConfigurableThrottling.au3 +++ b/examples/024-ConfigurableThrottling.au3 @@ -54,13 +54,21 @@ EndFunc ;==>Main ; MY EVENT HANDLER: Bridge (JavaScript Messages) Volatile Func _BridgeEventsHandler_OnMessageReceived($oWebV2M, $hGUI, $sMessage) - ConsoleWrite("$sMessage=" & $sMessage & @CRLF) #forceref $hGUI + ConsoleWrite("$sMessage=" & $sMessage & @CRLF) + ; 1. Check Phase Change If StringLeft($sMessage, 6) == "PHASE:" Then $sCurrentPhase = StringTrimLeft($sMessage, 6) $iReceivedCount = 0 + + ; If restart the test, reset the Throttling back to 0ms + If $sCurrentPhase = "No Throttling" Then + $oWebV2M.ThrottlingIntervalMs = 0 + ConsoleWrite(">>> Test Reset: ThrottlingIntervalMs forced back to 0ms" & @CRLF) + EndIf + ConsoleWrite("+++ Starting Phase: " & $sCurrentPhase & @CRLF) Return EndIf @@ -115,31 +123,35 @@ Func GetTestHTML() $sTxt &= "" & @CRLF $sTxt &= " // English: Enhanced loop that triggers termination ONLY when done" & @CRLF $sTxt &= " function sendBulkMessages(isThrottled = false) {" & @CRLF - $sTxt &= " let i = 1;" & @CRLF - $sTxt &= " function sendNext() {" & @CRLF - $sTxt &= " if (i <= 100) {" & @CRLF - $sTxt &= " safePost(""MSG_"" + i);" & @CRLF - $sTxt &= " i++;" & @CRLF - $sTxt &= " setTimeout(sendNext, 0);" & @CRLF - $sTxt &= " } else {" & @CRLF - $sTxt &= " // English: Loop finished! If we are in Phase 2, send TEST_END safely" & @CRLF - $sTxt &= " if (isThrottled) {" & @CRLF - $sTxt &= " setTimeout(() => {" & @CRLF - $sTxt &= " safePost(""TEST_END"");" & @CRLF - $sTxt &= " document.getElementById(""status-log"").innerText = ""Test Finished!"";" & @CRLF - $sTxt &= " }, 100); // English: 100ms ensures we are way outside the 20ms throttling window" & @CRLF - $sTxt &= " }" & @CRLF - $sTxt &= " }" & @CRLF - $sTxt &= " }" & @CRLF - $sTxt &= " sendNext();" & @CRLF - $sTxt &= " }" & @CRLF + $sTxt &= " let i = 1;" & @CRLF + $sTxt &= " function sendNext() {" & @CRLF + $sTxt &= " if (i <= 100) {" & @CRLF + $sTxt &= " safePost(""MSG_"" + i);" & @CRLF + $sTxt &= " i++;" & @CRLF + $sTxt &= " setTimeout(sendNext, 0);" & @CRLF + $sTxt &= " } else {" & @CRLF + $sTxt &= " if (isThrottled) {" & @CRLF + $sTxt &= " setTimeout(() => {" & @CRLF + $sTxt &= " safePost(""TEST_END"");" & @CRLF + $sTxt &= " document.getElementById(""status-log"").innerText = ""Test Finished!"";" & @CRLF + $sTxt &= " // English: Re-enable the button so the user can start a fresh test" & @CRLF + $sTxt &= " document.querySelector("".btn"").disabled = false;" & @CRLF + $sTxt &= " }, 100);" & @CRLF + $sTxt &= " }" & @CRLF + $sTxt &= " }" & @CRLF + $sTxt &= " }" & @CRLF + $sTxt &= " sendNext();" & @CRLF + $sTxt &= " }" & @CRLF $sTxt &= "" & @CRLF - $sTxt &= " function startTest() {" & @CRLF - $sTxt &= " document.getElementById(""status-log"").style.color = ""#00ff00"";" & @CRLF - $sTxt &= " document.getElementById(""status-log"").innerText = ""Running Phase 1: No Throttling..."";" & @CRLF - $sTxt &= " safePost(""PHASE:No Throttling"");" & @CRLF - $sTxt &= " setTimeout(() => { sendBulkMessages(false); }, 50);" & @CRLF - $sTxt &= " }" & @CRLF + $sTxt &= " function startTest() {" & @CRLF + $sTxt &= " // English: Disable button during the test execution to avoid overlapping loops" & @CRLF + $sTxt &= " document.querySelector("".btn"").disabled = true; " & @CRLF + $sTxt &= " " & @CRLF + $sTxt &= " document.getElementById(""status-log"").style.color = ""#00ff00"";" & @CRLF + $sTxt &= " document.getElementById(""status-log"").innerText = ""Running Phase 1: No Throttling..."";" & @CRLF + $sTxt &= " safePost(""PHASE:No Throttling"");" & @CRLF + $sTxt &= " setTimeout(() => { sendBulkMessages(false); }, 50);" & @CRLF + $sTxt &= " }" $sTxt &= "" & @CRLF $sTxt &= " function runThrottledTest() {" & @CRLF $sTxt &= " setTimeout(() => {" & @CRLF @@ -153,4 +165,3 @@ Func GetTestHTML() $sTxt &= "" Return $sTxt EndFunc ;==>GetTestHTML - From 17e4b46996fde294353d2bfaeafc205cde39d052 Mon Sep 17 00:00:00 2001 From: ioa747 <97930522+ioa747@users.noreply.github.com> Date: Sat, 27 Jun 2026 19:43:48 +0300 Subject: [PATCH 10/15] v2.2.2-alpha Added as a new parameter to the signature of `_NetWebView2_CreateManager` `_NetWebView2_CreateManager($sUserAgent = "", $s_fnEventPrefix = "", $s_AddBrowserArgs = "", $bVerbose = False, $iThrottlingIntervalMs = 20)` $iThrottlingIntervalMs - [optional] an integer value. Sets the JS-to-AutoIt message throttling interval in ms. Default is 20. Set to 0 to disable throttling. --- NetWebView2Lib.au3 | 90 +++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 41 deletions(-) diff --git a/NetWebView2Lib.au3 b/NetWebView2Lib.au3 index 75a0380..155e3fa 100644 --- a/NetWebView2Lib.au3 +++ b/NetWebView2Lib.au3 @@ -6,7 +6,7 @@ #Tidy_Parameters=/tcb=-1 -; NetWebView2Lib.au3 - Script Version: 2.2.2-alpha (2026.06.27.18) 🚩 +; NetWebView2Lib.au3 - Script Version: 2.2.2-alpha (2026.06.27.19) 🚩 #include #include @@ -1862,7 +1862,7 @@ EndFunc ;==>__NetWebView2_freezer #EndRegion ; === NetWebView2Lib UDF === #INTERNAL_USE_ONLY# #Region ; === NetWebView2Lib UDF === EVENT HANDLERS ***** Collection ***** - +; ******************************************************************************************************************************* #Region ; === NetWebView2Lib UDF === EVENT HANDLERS === Error Handlers === ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __NetWebView2_SilentErrorHandler @@ -2414,25 +2414,28 @@ EndFunc ;==>__NetWebView2_Events__OnContextMenu ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __NetWebView2_Events__OnWebResourceResponseReceived -; Description ...: -; Syntax ........: __NetWebView2_Events__OnWebResourceResponseReceived($oWebV2M, $hGUI, $iStatusCode, $sReasonPhrase, -; $sRequestUrl) +; Description ...: Internal handler for the WebResourceResponseReceived event. +; Syntax ........: __NetWebView2_Events__OnWebResourceResponseReceived($oWebV2M, $hGUI, $oArgs) ; Parameters ....: $oWebV2M - WebView2 object that fired the event -; $hGUI - a handle to Window that fired the event -; $iStatusCode - HTTP StatusCode -; $sReasonPhrase - StatusCode rephrased to human resonable string -; $sRequestUrl - the URL that fired the event +; $hGUI - A handle to Window that fired the event +; $oArgs - An Event Arguments Object containing: +; | .StatusCode (int) [RO]: The HTTP status code (e.g., 200, 404). +; | .ReasonPhrase (string) [RO]: The HTTP reason phrase (e.g., "OK"). +; | .RequestUri (string) [RO]: The URL of the request. +; | .IsDocument (bool) [RO]: True if the resource is the main document. ; Return values .: None -; Author ........: mLipok -; Modified ......: +; Author ........: ioa747, mLipok +; Modified ......: 2026-04-14 (Refactored to Object-Oriented Event Model) ; Remarks .......: ; Related .......: ; Link ..........: https://learn.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.core.corewebview2.webresourceresponsereceived -; Example .......: No +; Example .......: 007-HTTP_StatusCodeTracking.au3 ; =============================================================================================================================== -Volatile Func __NetWebView2_Events__OnWebResourceResponseReceived($oWebV2M, $hGUI, $iStatusCode, $sReasonPhrase, $sRequestUrl) - Local Const $s_Prefix = ">>>[EVENT: OnWebResourceResponseReceived]: GUI:" & $hGUI & " HTTPStatusCode:" & $iStatusCode & " (" & $sReasonPhrase & ") URL:" & $sRequestUrl - __NetWebView2_Log(@ScriptLineNumber, (StringLen($s_Prefix) > 150 ? StringLeft($s_Prefix, 150) & "..." : $s_Prefix), 1) +Volatile Func __NetWebView2_Events__OnWebResourceResponseReceived($oWebV2M, $hGUI, $oArgs) ; <<--( NEW )--<< + Local Const $s_Prefix = ">>>[EVENT: OnWebResourceResponseReceived]: GUI:" & $hGUI & _ + " HTTPStatusCode:" & $oArgs.StatusCode & " (" & $oArgs.ReasonPhrase & ") URL:" & $oArgs.RequestUri & " URL:" & $oArgs.IsDocument + + __NetWebView2_Log(@ScriptLineNumber, $s_Prefix, 1) __NetWebView2_LastMessage_KEEPER($oWebV2M, $NETWEBVIEW2_MESSAGE__RESPONSE_RECEIVED) EndFunc ;==>__NetWebView2_Events__OnWebResourceResponseReceived @@ -2458,11 +2461,8 @@ EndFunc ;==>__NetWebView2_Events__OnWebResourceResponseReceived ; Link ..........: https://learn.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.core.corewebview2downloadstartingeventargs ; Example .......: 021 - Handle Unviewable Content (MIME).au3 ; =============================================================================================================================== -Volatile Func __NetWebView2_Events__OnDownloadStarting($oWebV2M, $hGUI, $oArgs) ; <<--( NEW )--<< - Local $sURL = $oArgs.Uri - Local $sDefaultPath = $oArgs.ResultFilePath - Local $sMimeType = $oArgs.MimeType - Local Const $s_Prefix = "[EVENT: OnDownloadStarting]: GUI:" & $hGUI & " URL: " & $sURL & " PATH: " & $sDefaultPath & " MIME: " & $sMimeType +Volatile Func __NetWebView2_Events__OnDownloadStarting($oWebV2M, $hGUI, $oArgs) ; <<--( NEW )--<< + Local Const $s_Prefix = "[>>>EVENT: OnDownloadStarting]: GUI:" & $hGUI & " URL: " & $oArgs.Uri & " PATH: " & $oArgs.ResultFilePath & " MIME: " & $oArgs.MimeType __NetWebView2_Log(@ScriptLineNumber, (StringLen($s_Prefix) > 150 ? StringLeft($s_Prefix, 150) & "..." : $s_Prefix), 1) __NetWebView2_LastMessage_KEEPER($oWebV2M, $NETWEBVIEW2_MESSAGE__DOWNLOAD_STARTING) EndFunc ;==>__NetWebView2_Events__OnDownloadStarting @@ -2474,48 +2474,56 @@ EndFunc ;==>__NetWebView2_Events__OnDownloadStarting ; $iReceived_Bytes) ; Parameters ....: $oWebV2M - an object. ; $hGUI - a handle value. -; $sState - a string value. -; $sURL - a string value. -; $iTotal_Bytes - an integer value. -; $iReceived_Bytes - an integer value. +; $oArgs - An Event Arguments Object containing: +; | .Uri (String) [RO]: The source URL of the download. +; | .State (String) [RO]: The current state ("InProgress", "Completed", "Interrupted"). +; | .TotalBytesToReceive (int) [RO]: Estimated total size. +; | .BytesReceived (int) [RO]: Number of bytes received so far. +; | .PercentComplete (int) [RO]: Calculation (0-100) or -1 if unknown. ; Return values .: None ; Author ........: ioa747, mLipok ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: -; Example .......: No +; Example .......: 006-DownloadDemo.au3 ; =============================================================================================================================== -Volatile Func __NetWebView2_Events__OnDownloadStateChanged($oWebV2M, $hGUI, $sState, $sURL, $iTotal_Bytes, $iReceived_Bytes) - Local Const $s_Prefix = ">>>[EVENT: OnDownloadStateChanged]: GUI:" & $hGUI & " State:" & $sState & " URL:" & $sURL & " Total_Bytes:" & $iTotal_Bytes & " Received_Bytes:" & $iReceived_Bytes - Local $iPercent = 0 - If $iTotal_Bytes > 0 Then $iPercent = Round(($iReceived_Bytes / $iTotal_Bytes), 5) * 100 +Volatile Func __NetWebView2_Events__OnDownloadStateChanged($oWebV2M, $hGUI, $oArgs) ; <<--( NEW )--<< + Local $iReceived_MB = Round($oArgs.BytesReceived / 1048576, 2) ; 1024*1024 + Local $iTotal_MB = Round($oArgs.TotalBytesToReceive / 1048576, 2) - ; Convert to MB for easy-to-read log - Local $iReceived_MegaBytes = Round($iReceived_Bytes / 1024 / 1024) - Local $iTotal_MegaBytes = Round($iTotal_Bytes / 1024 / 1024) + Local Const $s_Prefix = "[>>>EVENT: OnDownloadStateChanged]: GUI:" & $hGUI & " State: " & $oArgs.State & " | " & _ + $oArgs.PercentComplete & "% (" & $iReceived_MB & "/" & $iTotal_MB & " MB) URL: " & $oArgs.Uri - Local Const $s_Message = " " & $iPercent & "% (" & $iReceived_MegaBytes & " / " & $iTotal_MegaBytes & " Mega Bytes)" - Switch $sState + __NetWebView2_Log(@ScriptLineNumber, $s_Prefix, 1) + + Switch $oArgs.State Case "InProgress" - __NetWebView2_Log(@ScriptLineNumber, $s_Prefix & $s_Message, 1) __NetWebView2_LastMessage_KEEPER($oWebV2M, $NETWEBVIEW2_MESSAGE__DOWNLOAD_IN_PROGRESS) Case "Interrupted" - __NetWebView2_Log(@ScriptLineNumber, $s_Prefix & $s_Message, 1) __NetWebView2_LastMessage_KEEPER($oWebV2M, $NETWEBVIEW2_MESSAGE__DOWNLOAD_INTERRUPTED) Case "Completed" - __NetWebView2_Log(@ScriptLineNumber, $s_Prefix & $s_Message, 1) __NetWebView2_LastMessage_KEEPER($oWebV2M, $NETWEBVIEW2_MESSAGE__DOWNLOAD_COMPLETED) EndSwitch -EndFunc ;==>__NetWebView2_Events__OnDownloadStateChanged +EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __NetWebView2_Events__OnAcceleratorKeyPressed -; Description ...: +; Description ...: It allows the application to intercept and handle system keys and keyboard shortcuts (Accelerators) before the WebView2 engine processes them. ; Syntax ........: __NetWebView2_Events__OnAcceleratorKeyPressed($oWebV2M, $hGUI, $oArgs) ; Parameters ....: $oWebV2M - an object. ; $hGUI - a handle value. -; $oArgs - an object. +; $oArgs - An Event Arguments Object containing: +; | .VirtualKey (uint) [RO]: The VK code of the key. +; | .KeyEventKind (int) [RO]: Type of key event (0:KeyDown, 1:KeyUp, etc.). +; | .RepeatCount (uint) [RO]: The number of times the key has repeated. +; | .ScanCode (uint) [RO]: Hardware scan code. +; | .IsExtendedKey (bool) [RO]: True if it's an extended key (e.g., right Alt). +; | .IsMenuKeyDown (bool) [RO]: True if Alt is pressed. +; | .WasKeyDown (bool) [RO]: True if the key was already down. +; | .IsKeyReleased (bool) [RO]: True if the event is a key up. +; | .KeyEventLParam (int) [RO]: The native LPARAM window message value. +; | .Handled (bool) [RW]: Set to True to prevent the browser from executing the default action. ; Return values .: None ; Author ........: ioa747, mLipok ; Modified ......: @@ -2802,5 +2810,5 @@ EndFunc ;==>__NetWebView2_Events__FrameKeeper ;~ https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/winrt/microsoft_web_webview2_core/corewebview2frame?view=webview2-winrt-1.0.3595.46#screencapturestarting ;~ EndFunc ;==>__NetWebView2_Events__OnScreenCaptureStarting #EndRegion ; === NetWebView2Lib UDF === EVENT HANDLERS * #TODO === - +; ******************************************************************************************************************************* #EndRegion ; === NetWebView2Lib UDF === EVENT HANDLERS ***** Collection ***** From b7adf98e91742fbf9d33e3f5f4b059ef1ff4d51c Mon Sep 17 00:00:00 2001 From: ioa747 <97930522+ioa747@users.noreply.github.com> Date: Sat, 27 Jun 2026 19:48:36 +0300 Subject: [PATCH 11/15] Delete bin/BackUp --- bin/BackUp/Alt_VersionCheker_old4.au3 | 139 -------------------------- 1 file changed, 139 deletions(-) delete mode 100644 bin/BackUp/Alt_VersionCheker_old4.au3 diff --git a/bin/BackUp/Alt_VersionCheker_old4.au3 b/bin/BackUp/Alt_VersionCheker_old4.au3 deleted file mode 100644 index 42f1747..0000000 --- a/bin/BackUp/Alt_VersionCheker_old4.au3 +++ /dev/null @@ -1,139 +0,0 @@ - -#include - -_WebView2_CheckInstalledVersion(@ScriptDir) - - -Func _WebView2_CheckInstalledVersion($sBasePath, $sMinReq = "128.0.2739.15") -;~ Local $sArch = @AutoItX64 ? "\x64" : "\x86" -;~ Local $sLoaderPath = $sBasePath & $sArch & "\WebView2Loader.dll" ; $sArch depending on the host -;~ Local $sLoaderPath = @ScriptDir & $sArch & "\WebView2Loader.dll" ; $sArch depending on the host -;~ ConsoleWrite("$sLoaderPath=" & $sLoaderPath & @CRLF) -;~ Local $sMinReq = "128.0.2739.15" - - Local $sArch = @AutoItX64 ? "\x64" : "\x86" - Local $sLoaderPath = $sBasePath & $sArch & "\WebView2Loader.dll" ; $sArch depending on the host - Local $sCurrentVersion = "0.0.0.0" ;= _WebView2_GetInstalledVersion($sLoaderPath) - - ;----------------- - ; 1. Load the Loader DLL (WebView2Loader.dll) - Local $hLoader = DllOpen($sLoaderPath) - If $hLoader <> -1 Then ;Return SetError(1, 0, "!Error: DLL not found") - - ; 2. Call the function - ; The first parameter is 'ptr' (NULL) to search in default paths. - ; The second parameter is 'ptr*' to receive the pointer to the version string. - Local $aRet = DllCall($hLoader, "long", "GetAvailableCoreWebView2BrowserVersionString", _ - "ptr", 0, _ ; browserExecutableFolder: NULL for default - "ptr*", 0) ; versionInfo: output pointer - - ; Check for errors or non-S_OK (0) return value - If @error Or $aRet[0] <> 0 Then - DllClose($hLoader) - $sCurrentVersion = "0.0.0.0" - Else - - - ; 3. Get the pointer to the string from the return array - Local $pVersionInfo = $aRet[2] - - ; 4. Use 'Ptr' and 'wstr' logic to read the string directly - ; AutoIt can read a wide string from a pointer using DllStructCreate - Local $tString = DllStructCreate("wchar[128]", $pVersionInfo) - Local $sVersion = DllStructGetData($tString, 1) - - ; 5. IMPORTANT: Free the memory allocated by the DLL using CoTaskMemFree - DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $pVersionInfo) - - DllClose($hLoader) - $sCurrentVersion = $sVersion - EndIf - EndIf - ;--------------- - - - - If $sCurrentVersion = "0.0.0.0" Then - MsgBox(16, "Error", "WebView2 Runtime not found installed.") - Exit - EndIf - - ConsoleWrite("$sCurrentVersion=" & $sCurrentVersion & @CRLF) - - ; Version comparison - If _VersionCompare($sCurrentVersion, $sMinReq) = -1 Then - MsgBox(48, "Update Required", "Version " & $sCurrentVersion & " is out of date." & @CRLF & _ - "At least " & $sMinReq & " is required") - ; Here you can open the download URL - ; ShellExecute("https://developer.microsoft.com/en-us/microsoft-edge/webview2/") - Exit - EndIf - - ConsoleWrite("WebView2 OK: " & $sCurrentVersion & @CRLF) -EndFunc ;==>_WebView2_CheckInstalledVersion - - -#CS -Local $sArch = @AutoItX64 ? "\x64" : "\x86" - -Local $sLoaderPath = @ScriptDir & $sArch & "\WebView2Loader.dll" ; $sArch depending on the host -ConsoleWrite("$sLoaderPath=" & $sLoaderPath & @CRLF) -Local $sMinReq = "128.0.2739.15" -Local $sCurrentVersion = _WebView2_GetInstalledVersion($sLoaderPath) - - - -If $sCurrentVersion = "0.0.0.0" Then - MsgBox(16, "Error", "WebView2 Runtime not found installed.") - Exit -EndIf - -ConsoleWrite("$sCurrentVersion=" & $sCurrentVersion & @CRLF) - -; Version comparison -If _VersionCompare($sCurrentVersion, $sMinReq) = -1 Then - MsgBox(48, "Update Required", "Version " & $sCurrentVersion & " is out of date." & @CRLF & _ - "At least " & $sMinReq & " is required") - ; Here you can open the download URL - ; ShellExecute("https://developer.microsoft.com/en-us/microsoft-edge/webview2/") - Exit -EndIf - -ConsoleWrite("WebView2 OK: " & $sCurrentVersion & @CRLF) - - -Func _WebView2_GetInstalledVersion($sLoaderPath) - ; 1. Load the Loader DLL (WebView2Loader.dll) - Local $hLoader = DllOpen($sLoaderPath) - If $hLoader = -1 Then Return "Error: DLL not found" - - ; 2. Call the function - ; The first parameter is 'ptr' (NULL) to search in default paths. - ; The second parameter is 'ptr*' to receive the pointer to the version string. - Local $aRet = DllCall($hLoader, "long", "GetAvailableCoreWebView2BrowserVersionString", _ - "ptr", 0, _ ; browserExecutableFolder: NULL for default - "ptr*", 0) ; versionInfo: output pointer - - ; Check for errors or non-S_OK (0) return value - If @error Or $aRet[0] <> 0 Then - DllClose($hLoader) - Return "0.0.0.0" - EndIf - - ; 3. Get the pointer to the string from the return array - Local $pVersionInfo = $aRet[2] - - ; 4. Use 'Ptr' and 'wstr' logic to read the string directly - ; AutoIt can read a wide string from a pointer using DllStructCreate - Local $tString = DllStructCreate("wchar[128]", $pVersionInfo) - Local $sVersion = DllStructGetData($tString, 1) - - ; 5. IMPORTANT: Free the memory allocated by the DLL using CoTaskMemFree - DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $pVersionInfo) - - DllClose($hLoader) - Return $sVersion -EndFunc ;==>_WebView2_GetInstalledVersion - -#CE - From 085789cf87de96f0e45c2863050090c44b8b4460 Mon Sep 17 00:00:00 2001 From: ioa747 <97930522+ioa747@users.noreply.github.com> Date: Sat, 27 Jun 2026 19:48:57 +0300 Subject: [PATCH 12/15] Delete bin/BackUp --- bin/BackUp/Alt_VersionCheker_old1.au3 | 80 --------------------------- 1 file changed, 80 deletions(-) delete mode 100644 bin/BackUp/Alt_VersionCheker_old1.au3 diff --git a/bin/BackUp/Alt_VersionCheker_old1.au3 b/bin/BackUp/Alt_VersionCheker_old1.au3 deleted file mode 100644 index 3f14359..0000000 --- a/bin/BackUp/Alt_VersionCheker_old1.au3 +++ /dev/null @@ -1,80 +0,0 @@ - -#include - -Local $sArch = @AutoItX64 ? "\x64" : "\x86" - -Local $sLoaderPath = @ScriptDir & $sArch & "\WebView2Loader.dll" ; $sArch depending on the host -ConsoleWrite("$sLoaderPath=" & $sLoaderPath & @CRLF) -Local $sMinReq = "128.0.2739.15" -Local $sCurrentVersion = _WebView2_GetInstalledVersion($sLoaderPath) - - - -If $sCurrentVersion = "0.0.0.0" Then - MsgBox(16, "Error", "WebView2 Runtime not found installed.") - Exit -EndIf - -ConsoleWrite("$sCurrentVersion=" & $sCurrentVersion & @CRLF) - -; Version comparison -If _VersionCompare($sCurrentVersion, $sMinReq) = -1 Then -MsgBox(48, "Update Required", "Version " & $sCurrentVersion & " is out of date." & @CRLF & _ -"At least " & $sMinReq is required) -; Here you can open the download URL -; ShellExecute("https://developer.microsoft.com/en-us/microsoft-edge/webview2/") -Exit -EndIf - -ConsoleWrite("WebView2 OK: " & $sCurrentVersion & @CRLF) - -ConsoleWrite("WebView2Loader.dll v: " & _GetProperty($sLoaderPath) & @CRLF) - -;~ $sLoaderPath=D:\i\Pro\.AutoIT\_Test\100_NetWebView2\NetWebView2Lib\bin\x86\WebView2Loader.dll -;~ $sCurrentVersion=145.0.3800.70 -;~ WebView2 OK: 145.0.3800.70 -;~ WebView2Loader.dll v: 1.0.2739.15 - -Func _WebView2_GetInstalledVersion($sLoaderPath) - ; 1. Load the Loader DLL (WebView2Loader.dll) - Local $hLoader = DllOpen($sLoaderPath) - If $hLoader = -1 Then Return "Error: DLL not found" - - ; 2. Call the function - ; The first parameter is 'ptr' (NULL) to search in default paths. - ; The second parameter is 'ptr*' to receive the pointer to the version string. - Local $aRet = DllCall($hLoader, "long", "GetAvailableCoreWebView2BrowserVersionString", _ - "ptr", 0, _ ; browserExecutableFolder: NULL for default - "ptr*", 0) ; versionInfo: output pointer - - ; Check for errors or non-S_OK (0) return value - If @error Or $aRet[0] <> 0 Then - DllClose($hLoader) - Return "0.0.0.0" - EndIf - - ; 3. Get the pointer to the string from the return array - Local $pVersionInfo = $aRet[2] - - ; 4. Use 'Ptr' and 'wstr' logic to read the string directly - ; AutoIt can read a wide string from a pointer using DllStructCreate - Local $tString = DllStructCreate("wchar[128]", $pVersionInfo) - Local $sVersion = DllStructGetData($tString, 1) - - ; 5. IMPORTANT: Free the memory allocated by the DLL using CoTaskMemFree - DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $pVersionInfo) - - DllClose($hLoader) - Return $sVersion -EndFunc - - -Func _GetProperty($sPath) - Local $sFile = StringTrimLeft($sPath, StringInStr($sPath, "\", 0, -1)) - Local $sDir = StringTrimRight($sPath, (StringLen($sPath) - StringInStr($sPath, "\", 0, -1))) - Local $oShellApp = ObjCreate("shell.application") - Local $oDir = $oShellApp.NameSpace($sDir) - Local $oFile = $oDir.Parsename($sFile) - Local $sFileVersion = $oFile.ExtendedProperty("System.FileVersion") - Return $sFileVersion -EndFunc ;==>_GetProperty \ No newline at end of file From 5e1c59fa9cff6e3b49fc95862706fae5c4cdb36f Mon Sep 17 00:00:00 2001 From: ioa747 <97930522+ioa747@users.noreply.github.com> Date: Sat, 27 Jun 2026 19:49:24 +0300 Subject: [PATCH 13/15] Delete bin/BackUp --- bin/BackUp/Alt_VersionCheker_old2.au3 | 71 --------------------------- 1 file changed, 71 deletions(-) delete mode 100644 bin/BackUp/Alt_VersionCheker_old2.au3 diff --git a/bin/BackUp/Alt_VersionCheker_old2.au3 b/bin/BackUp/Alt_VersionCheker_old2.au3 deleted file mode 100644 index 3321fbb..0000000 --- a/bin/BackUp/Alt_VersionCheker_old2.au3 +++ /dev/null @@ -1,71 +0,0 @@ - -#include - -_WebView2_CheckInstalledVersion(@ScriptDir & $sArch & "\WebView2Loader.dll") - - -Func _WebView2_CheckInstalledVersion($sLoaderPath) -Local $sArch = @AutoItX64 ? "\x64" : "\x86" - -Local $sLoaderPath = @ScriptDir & $sArch & "\WebView2Loader.dll" ; $sArch depending on the host -ConsoleWrite("$sLoaderPath=" & $sLoaderPath & @CRLF) -Local $sMinReq = "128.0.2739.15" -Local $sCurrentVersion = _WebView2_GetInstalledVersion($sLoaderPath) - - - -If $sCurrentVersion = "0.0.0.0" Then - MsgBox(16, "Error", "WebView2 Runtime not found installed.") - Exit -EndIf - -ConsoleWrite("$sCurrentVersion=" & $sCurrentVersion & @CRLF) - -; Version comparison -If _VersionCompare($sCurrentVersion, $sMinReq) = -1 Then - MsgBox(48, "Update Required", "Version " & $sCurrentVersion & " is out of date." & @CRLF & _ - "At least " & $sMinReq & " is required") - ; Here you can open the download URL - ; ShellExecute("https://developer.microsoft.com/en-us/microsoft-edge/webview2/") - Exit -EndIf - -ConsoleWrite("WebView2 OK: " & $sCurrentVersion & @CRLF) -EndFunc - - - - -Func _WebView2_GetInstalledVersion($sLoaderPath) - ; 1. Load the Loader DLL (WebView2Loader.dll) - Local $hLoader = DllOpen($sLoaderPath) - If $hLoader = -1 Then Return "Error: DLL not found" - - ; 2. Call the function - ; The first parameter is 'ptr' (NULL) to search in default paths. - ; The second parameter is 'ptr*' to receive the pointer to the version string. - Local $aRet = DllCall($hLoader, "long", "GetAvailableCoreWebView2BrowserVersionString", _ - "ptr", 0, _ ; browserExecutableFolder: NULL for default - "ptr*", 0) ; versionInfo: output pointer - - ; Check for errors or non-S_OK (0) return value - If @error Or $aRet[0] <> 0 Then - DllClose($hLoader) - Return "0.0.0.0" - EndIf - - ; 3. Get the pointer to the string from the return array - Local $pVersionInfo = $aRet[2] - - ; 4. Use 'Ptr' and 'wstr' logic to read the string directly - ; AutoIt can read a wide string from a pointer using DllStructCreate - Local $tString = DllStructCreate("wchar[128]", $pVersionInfo) - Local $sVersion = DllStructGetData($tString, 1) - - ; 5. IMPORTANT: Free the memory allocated by the DLL using CoTaskMemFree - DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $pVersionInfo) - - DllClose($hLoader) - Return $sVersion -EndFunc ;==>_WebView2_GetInstalledVersion - From a50c6fce9a853820c2981630901af5c4c5325343 Mon Sep 17 00:00:00 2001 From: ioa747 <97930522+ioa747@users.noreply.github.com> Date: Sat, 27 Jun 2026 19:49:41 +0300 Subject: [PATCH 14/15] Delete bin/BackUp --- bin/BackUp/Alt_VersionCheker_old3.au3 | 96 --------------------------- 1 file changed, 96 deletions(-) delete mode 100644 bin/BackUp/Alt_VersionCheker_old3.au3 diff --git a/bin/BackUp/Alt_VersionCheker_old3.au3 b/bin/BackUp/Alt_VersionCheker_old3.au3 deleted file mode 100644 index f44d16e..0000000 --- a/bin/BackUp/Alt_VersionCheker_old3.au3 +++ /dev/null @@ -1,96 +0,0 @@ - -#include - -_WebView2_CheckInstalledVersion(@ScriptDir & $sArch & "\WebView2Loader.dll") - - -Func _WebView2_CheckInstalledVersion($sLoaderPath) -Local $sArch = @AutoItX64 ? "\x64" : "\x86" - -Local $sLoaderPath = @ScriptDir & $sArch & "\WebView2Loader.dll" ; $sArch depending on the host -ConsoleWrite("$sLoaderPath=" & $sLoaderPath & @CRLF) -Local $sMinReq = "128.0.2739.15" -Local $sCurrentVersion = _WebView2_GetInstalledVersion($sLoaderPath) - - - -If $sCurrentVersion = "0.0.0.0" Then - MsgBox(16, "Error", "WebView2 Runtime not found installed.") - Exit -EndIf - -ConsoleWrite("$sCurrentVersion=" & $sCurrentVersion & @CRLF) - -; Version comparison -If _VersionCompare($sCurrentVersion, $sMinReq) = -1 Then - MsgBox(48, "Update Required", "Version " & $sCurrentVersion & " is out of date." & @CRLF & _ - "At least " & $sMinReq & " is required") - ; Here you can open the download URL - ; ShellExecute("https://developer.microsoft.com/en-us/microsoft-edge/webview2/") - Exit -EndIf - -ConsoleWrite("WebView2 OK: " & $sCurrentVersion & @CRLF) -EndFunc - -;~ Local $sArch = @AutoItX64 ? "\x64" : "\x86" - -;~ Local $sLoaderPath = @ScriptDir & $sArch & "\WebView2Loader.dll" ; $sArch depending on the host -;~ ConsoleWrite("$sLoaderPath=" & $sLoaderPath & @CRLF) -;~ Local $sMinReq = "128.0.2739.15" -;~ Local $sCurrentVersion = _WebView2_GetInstalledVersion($sLoaderPath) - - - -;~ If $sCurrentVersion = "0.0.0.0" Then -;~ MsgBox(16, "Error", "WebView2 Runtime not found installed.") -;~ Exit -;~ EndIf - -;~ ConsoleWrite("$sCurrentVersion=" & $sCurrentVersion & @CRLF) - -;~ ; Version comparison -;~ If _VersionCompare($sCurrentVersion, $sMinReq) = -1 Then -;~ MsgBox(48, "Update Required", "Version " & $sCurrentVersion & " is out of date." & @CRLF & _ -;~ "At least " & $sMinReq & " is required") -;~ ; Here you can open the download URL -;~ ; ShellExecute("https://developer.microsoft.com/en-us/microsoft-edge/webview2/") -;~ Exit -;~ EndIf - -;~ ConsoleWrite("WebView2 OK: " & $sCurrentVersion & @CRLF) - - -Func _WebView2_GetInstalledVersion($sLoaderPath) - ; 1. Load the Loader DLL (WebView2Loader.dll) - Local $hLoader = DllOpen($sLoaderPath) - If $hLoader = -1 Then Return "Error: DLL not found" - - ; 2. Call the function - ; The first parameter is 'ptr' (NULL) to search in default paths. - ; The second parameter is 'ptr*' to receive the pointer to the version string. - Local $aRet = DllCall($hLoader, "long", "GetAvailableCoreWebView2BrowserVersionString", _ - "ptr", 0, _ ; browserExecutableFolder: NULL for default - "ptr*", 0) ; versionInfo: output pointer - - ; Check for errors or non-S_OK (0) return value - If @error Or $aRet[0] <> 0 Then - DllClose($hLoader) - Return "0.0.0.0" - EndIf - - ; 3. Get the pointer to the string from the return array - Local $pVersionInfo = $aRet[2] - - ; 4. Use 'Ptr' and 'wstr' logic to read the string directly - ; AutoIt can read a wide string from a pointer using DllStructCreate - Local $tString = DllStructCreate("wchar[128]", $pVersionInfo) - Local $sVersion = DllStructGetData($tString, 1) - - ; 5. IMPORTANT: Free the memory allocated by the DLL using CoTaskMemFree - DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $pVersionInfo) - - DllClose($hLoader) - Return $sVersion -EndFunc ;==>_WebView2_GetInstalledVersion - From 1211a4bbc129cabc1ff313df23ad2ec60fad345a Mon Sep 17 00:00:00 2001 From: ioa747 <97930522+ioa747@users.noreply.github.com> Date: Sat, 27 Jun 2026 19:52:19 +0300 Subject: [PATCH 15/15] Delete bin/Alt_VersionCheker.au3 --- bin/Alt_VersionCheker.au3 | 54 --------------------------------------- 1 file changed, 54 deletions(-) delete mode 100644 bin/Alt_VersionCheker.au3 diff --git a/bin/Alt_VersionCheker.au3 b/bin/Alt_VersionCheker.au3 deleted file mode 100644 index 4e1bfe3..0000000 --- a/bin/Alt_VersionCheker.au3 +++ /dev/null @@ -1,54 +0,0 @@ - -#include - -_WebView2_CheckInstalledVersion(@ScriptDir) - -Func _WebView2_CheckInstalledVersion($sBasePath, $sMinReq = "128.0.2739.15") - Local $sArch = @AutoItX64 ? "\x64" : "\x86" - Local $sLoaderPath = $sBasePath & $sArch & "\WebView2Loader.dll" ; $sArch depending on the host - Local $sCurrentVersion = "0.0.0.0" ;= _WebView2_GetInstalledVersion($sLoaderPath) - - ; Load the Loader DLL (WebView2Loader.dll) - Local $hLoader = DllOpen($sLoaderPath) - If $hLoader <> -1 Then - - ; === Call the function === - ; The first parameter is 'ptr' (NULL) to search in default paths. - ; The second parameter is 'ptr*' to receive the pointer to the version string. - Local $aRet = DllCall($hLoader, "long", "GetAvailableCoreWebView2BrowserVersionString", _ - "ptr", 0, _ ; browserExecutableFolder: NULL for default - "ptr*", 0) ; versionInfo: output pointer - - ; Check for errors or non-S_OK (0) return value - If @error Or $aRet[0] <> 0 Then - DllClose($hLoader) - Else - - Local $pVersionInfo = $aRet[2] - Local $tString = DllStructCreate("wchar[128]", $pVersionInfo) - Local $sVersion = DllStructGetData($tString, 1) - - ; Free the memory allocated by the DLL using CoTaskMemFree - DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $pVersionInfo) - - DllClose($hLoader) - $sCurrentVersion = $sVersion - EndIf - EndIf - - If $sCurrentVersion = "0.0.0.0" Then - MsgBox(16, "Error", "WebView2 Runtime not found installed.") - Exit - EndIf - - ; Version comparison - If _VersionCompare($sCurrentVersion, $sMinReq) = -1 Then - MsgBox(48, "Update Required", "Version " & $sCurrentVersion & " is out of date." & @CRLF & _ - "At least " & $sMinReq & " is required") - ; ShellExecute("https://developer.microsoft.com/en-us/microsoft-edge/webview2/") - Exit - EndIf - - ConsoleWrite("WebView2 OK: " & $sCurrentVersion & @CRLF) -EndFunc ;==>_WebView2_CheckInstalledVersion -