diff --git a/NetWebView2Lib.au3 b/NetWebView2Lib.au3
index 0a3c54e..155e3fa 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.2-alpha (2026.06.27.19) 🚩
#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
@@ -1859,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
@@ -2807,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 *****
diff --git a/README.md b/README.md
index 9dfda9f..d15dfdb 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.
@@ -66,84 +63,25 @@ This project is provided "as-is". You are free to use, modify, and distribute it
-## 🚀 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.
-
-### ⚡ 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.
-
+## 🚀 What's New in v2.2.2-alpha - Configurable Message Throttling
-> [!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.
+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
-### 🏗️ 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 +140,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`
diff --git a/bin/x64/NetWebView2Lib.dll b/bin/x64/NetWebView2Lib.dll
index 9acc3b5..7287b21 100644
Binary files a/bin/x64/NetWebView2Lib.dll and b/bin/x64/NetWebView2Lib.dll differ
diff --git a/bin/x64/NetWebView2Lib.tlb b/bin/x64/NetWebView2Lib.tlb
index f93a865..dbb10a4 100644
Binary files a/bin/x64/NetWebView2Lib.tlb and b/bin/x64/NetWebView2Lib.tlb differ
diff --git a/bin/x86/NetWebView2Lib.dll b/bin/x86/NetWebView2Lib.dll
index 9acc3b5..7287b21 100644
Binary files a/bin/x86/NetWebView2Lib.dll and b/bin/x86/NetWebView2Lib.dll differ
diff --git a/bin/x86/NetWebView2Lib.tlb b/bin/x86/NetWebView2Lib.tlb
index f93a865..dbb10a4 100644
Binary files a/bin/x86/NetWebView2Lib.tlb and b/bin/x86/NetWebView2Lib.tlb differ
diff --git a/examples/024-ConfigurableThrottling.au3 b/examples/024-ConfigurableThrottling.au3
new file mode 100644
index 0000000..ccfd29b
--- /dev/null
+++ b/examples/024-ConfigurableThrottling.au3
@@ -0,0 +1,167 @@
+#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)
+ #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
+
+ ; 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
diff --git a/src/Core/WebView2Bridge.cs b/src/Core/WebView2Bridge.cs
index ea0d76f..e09540e 100644
--- a/src/Core/WebView2Bridge.cs
+++ b/src/Core/WebView2Bridge.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Runtime.InteropServices;
using System.Threading;
@@ -53,6 +53,9 @@ public interface IBridgeActions
/// Gets 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")]