Ecng.Net.SocketIO 1.0.524

There is a newer version of this package available.
See the version list below for details.
dotnet add package Ecng.Net.SocketIO --version 1.0.524
                    
NuGet\Install-Package Ecng.Net.SocketIO -Version 1.0.524
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Ecng.Net.SocketIO" Version="1.0.524" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Ecng.Net.SocketIO" Version="1.0.524" />
                    
Directory.Packages.props
<PackageReference Include="Ecng.Net.SocketIO" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Ecng.Net.SocketIO --version 1.0.524
                    
#r "nuget: Ecng.Net.SocketIO, 1.0.524"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Ecng.Net.SocketIO@1.0.524
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Ecng.Net.SocketIO&version=1.0.524
                    
Install as a Cake Addin
#tool nuget:?package=Ecng.Net.SocketIO&version=1.0.524
                    
Install as a Cake Tool

Ecng.Net.SocketIO

A high-performance .NET client library for WebSocket communication with automatic reconnection, message resending, and comprehensive connection state management.

Features

  • WebSocket Client Implementation - Full-featured WebSocket client with async/await support
  • Automatic Reconnection - Configurable reconnection attempts with exponential backoff
  • Command Resending - Automatic resend of commands after reconnection
  • Connection State Tracking - Track and aggregate connection states across multiple connections
  • JSON Serialization - Built-in JSON serialization for object messages
  • Flexible Logging - Customizable logging hooks for info, error, and verbose messages
  • RestSharp Integration - Helper methods for REST API calls with authentication
  • Thread-Safe - Safe to use in multi-threaded environments

Installation

Add the package reference to your project:

<PackageReference Include="Ecng.Net.SocketIO" Version="x.x.x" />

Quick Start

Basic WebSocket Connection

using Ecng.Net;

var socket = new WebSocketClient(
    url: "wss://example.com/socket",
    stateChanged: state => Console.WriteLine($"State: {state}"),
    error: ex => Console.WriteLine($"Error: {ex.Message}"),
    process: (msg, ct) =>
    {
        Console.WriteLine($"Received: {msg.AsString()}");
        return ValueTask.CompletedTask;
    },
    infoLog: (fmt, args) => Console.WriteLine(fmt, args),
    errorLog: (fmt, args) => Console.Error.WriteLine(fmt, args),
    verboseLog: (fmt, args) => Console.WriteLine($"[VERBOSE] {fmt}", args)
);

await socket.ConnectAsync(CancellationToken.None);

Sending Messages

// Send JSON object
await socket.SendAsync(new { type = "subscribe", channel = "trades" });

// Send string
await socket.SendAsync("Hello, WebSocket!");

// Send raw bytes
byte[] data = Encoding.UTF8.GetBytes("Raw message");
await socket.SendAsync(data, WebSocketMessageType.Text);

Core Components

WebSocketClient

The main class for WebSocket communication.

Constructor Parameters
public WebSocketClient(
    string url,                              // WebSocket URL (ws:// or wss://)
    Action<ConnectionStates> stateChanged,   // Connection state change callback
    Action<Exception> error,                 // Error handler
    Func<WebSocketMessage, CancellationToken, ValueTask> process,  // Message processor
    Action<string, object> infoLog,          // Info log handler
    Action<string, object> errorLog,         // Error log handler
    Action<string, object> verboseLog        // Verbose log handler (can be null)
)
Configuration Properties
// Reconnection settings
socket.ReconnectAttempts = 10;              // -1 for infinite, 0 for no reconnect
socket.ReconnectInterval = TimeSpan.FromSeconds(5);
socket.ResendInterval = TimeSpan.FromSeconds(2);
socket.ResendTimeout = TimeSpan.FromMilliseconds(500);

// Message encoding
socket.Encoding = Encoding.UTF8;

// Buffer sizes
socket.BufferSize = 1024 * 1024;            // 1MB for compressed data
socket.BufferSizeUncompress = 10 * 1024 * 1024; // 10MB for uncompressed

// JSON serialization
socket.Indent = true;
socket.SendSettings = new JsonSerializerSettings { ... };

// Auto-resend control
socket.DisableAutoResend = false;
Connection Management
// Connect
await socket.ConnectAsync(cancellationToken);
socket.Connect(); // Synchronous version

// Disconnect
socket.Disconnect();

// Check connection state
bool isConnected = socket.IsConnected;
ConnectionStates currentState = socket.State;

// Abort connection immediately
socket.Abort();
Sending Messages with Subscription Tracking
// Send with subscription ID for automatic resend after reconnect
long subscriptionId = 12345;
await socket.SendAsync(
    obj: new { action = "subscribe", symbol = "BTCUSD" },
    subId: subscriptionId
);

// Unsubscribe (negative ID removes from resend queue)
await socket.SendAsync(
    obj: new { action = "unsubscribe", symbol = "BTCUSD" },
    subId: -subscriptionId
);

// Manual resend management
socket.RemoveResend(subscriptionId);  // Remove specific subscription
socket.RemoveResend();                 // Remove all subscriptions
Advanced Features
// Custom initialization
socket.Init += ws =>
{
    ws.Options.SetRequestHeader("X-Custom-Header", "value");
    ws.Options.KeepAliveInterval = TimeSpan.FromSeconds(30);
};

// Post-connect hook
socket.PostConnect += async (isReconnect, ct) =>
{
    if (isReconnect)
        Console.WriteLine("Reconnected! Resubscribing...");

    await Task.CompletedTask;
};

// Pre-process received data (e.g., decompression)
socket.PreProcess2 = (input, output) =>
{
    // Decompress or transform data
    input.CopyTo(output);
    return input.Length;
};

// Send ping frame
await socket.SendOpCode(0x9);

WebSocketMessage

Represents an incoming message from the WebSocket.

// In your message processor
Func<WebSocketMessage, CancellationToken, ValueTask> process = (msg, ct) =>
{
    // Get as string
    string text = msg.AsString();

    // Deserialize to object
    var trade = msg.AsObject<TradeData>();

    // Deserialize to dynamic
    dynamic data = msg.AsObject();

    // Get JSON reader for streaming
    using var reader = msg.AsReader();

    // Access raw bytes
    ReadOnlyMemory<byte> bytes = msg.Memory;

    return ValueTask.CompletedTask;
};

Connection States

The ConnectionStates enum represents the current state of the connection:

public enum ConnectionStates
{
    Disconnected,   // Not connected
    Disconnecting,  // In process of disconnecting
    Connecting,     // In process of connecting
    Connected,      // Successfully connected
    Reconnecting,   // Attempting to reconnect
    Restored,       // Connection restored after reconnect
    Failed          // Connection failed
}

ConnectionStateTracker

Track and aggregate states across multiple connections.

var tracker = new ConnectionStateTracker();

// Add connections
tracker.Add(socket1);
tracker.Add(socket2);

// Monitor overall state
tracker.StateChanged += state =>
    Console.WriteLine($"Overall state: {state}");

// Connect all
await tracker.ConnectAsync(CancellationToken.None);

// Disconnect all
tracker.Disconnect();

// Remove connections
tracker.Remove(socket1);

The tracker aggregates states with the following logic:

  • Connected: All connections are connected
  • Reconnecting: Any connection is reconnecting
  • Restored: All connections are connected or restored
  • Failed: All connections have failed
  • Disconnected: All connections are disconnected or failed

IConnection Interface

Standard interface for connection management:

public interface IConnection
{
    event Action<ConnectionStates> StateChanged;
    ValueTask ConnectAsync(CancellationToken cancellationToken);
    void Disconnect();
}

Both WebSocketClient and ConnectionStateTracker implement this interface.

RestSharp Integration

The library includes helper methods for REST API calls, often used alongside WebSocket connections.

Basic REST Request

using Ecng.Net;
using RestSharp;

var request = new RestRequest(Method.Get);
request.AddQueryParameter("symbol", "BTCUSD");

var response = await request.InvokeAsync<PriceData>(
    url: new Uri("https://api.example.com/price"),
    caller: this,
    logVerbose: (fmt, args) => Console.WriteLine(fmt, args),
    token: CancellationToken.None
);

Console.WriteLine($"Price: {response.Price}");

Authentication

// Bearer token authentication
request.SetBearer(secureToken);

// Custom authenticator
var authenticator = new MyCustomAuthenticator();
var response = await request.InvokeAsync2<Data>(
    url: apiUrl,
    caller: this,
    logVerbose: logger,
    token: cancellationToken,
    auth: authenticator
);

Error Handling

try
{
    var response = await request.InvokeAsync<Data>(url, this, logger, token);
}
catch (RestSharpException ex)
{
    Console.WriteLine($"HTTP {ex.Response.StatusCode}: {ex.Response.Content}");
    Console.WriteLine($"Error: {ex.Message}");
}

Advanced REST Features

// Custom content converter
var response = await request.InvokeAsync<Data>(
    url: apiUrl,
    caller: this,
    logVerbose: logger,
    token: cancellationToken,
    contentConverter: content => content.Replace("null", "\"\"")
);

// Handle specific error status codes
var response = await request.InvokeAsync3<Data>(
    url: apiUrl,
    caller: this,
    logVerbose: logger,
    token: cancellationToken,
    handleErrorStatus: statusCode =>
    {
        if (statusCode == HttpStatusCode.TooManyRequests)
        {
            // Custom handling
            return true; // Handled
        }
        return false; // Not handled, will throw
    }
);

// Add body as string
request.AddBodyAsStr("{\"key\": \"value\"}");

// Remove parameters
request.RemoveWhere(p => p.Name == "old_param");

// Convert parameters to query string
string queryString = request.Parameters.ToQueryString();

JWT Decoding

string token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...";
var parts = token.DecodeJWT();

foreach (var part in parts)
{
    Console.WriteLine(part);
}

Complete Examples

Crypto Exchange WebSocket Client

public class CryptoExchangeClient : IDisposable
{
    private readonly WebSocketClient _socket;
    private long _subscriptionCounter;

    public CryptoExchangeClient(string wsUrl)
    {
        _socket = new WebSocketClient(
            url: wsUrl,
            stateChanged: OnStateChanged,
            error: OnError,
            process: ProcessMessage,
            infoLog: (fmt, args) => Console.WriteLine($"[INFO] {fmt}", args),
            errorLog: (fmt, args) => Console.Error.WriteLine($"[ERROR] {fmt}", args),
            verboseLog: null
        )
        {
            ReconnectAttempts = -1,  // Infinite reconnection
            ReconnectInterval = TimeSpan.FromSeconds(5),
            ResendTimeout = TimeSpan.FromSeconds(1)
        };

        _socket.Init += ws =>
        {
            ws.Options.KeepAliveInterval = TimeSpan.FromSeconds(20);
        };

        _socket.PostConnect += async (isReconnect, ct) =>
        {
            if (isReconnect)
            {
                Console.WriteLine("Reconnected! Subscriptions will be restored automatically.");
            }
        };
    }

    public async Task ConnectAsync()
    {
        await _socket.ConnectAsync(CancellationToken.None);
    }

    public async Task SubscribeToTradesAsync(string symbol)
    {
        var subId = ++_subscriptionCounter;

        await _socket.SendAsync(
            obj: new
            {
                type = "subscribe",
                channel = "trades",
                symbol = symbol
            },
            subId: subId
        );

        Console.WriteLine($"Subscribed to {symbol} trades (ID: {subId})");
    }

    public async Task UnsubscribeFromTradesAsync(long subscriptionId, string symbol)
    {
        await _socket.SendAsync(
            obj: new
            {
                type = "unsubscribe",
                channel = "trades",
                symbol = symbol
            },
            subId: -subscriptionId  // Negative to remove from resend queue
        );
    }

    private void OnStateChanged(ConnectionStates state)
    {
        Console.WriteLine($"Connection state: {state}");

        if (state == ConnectionStates.Connected)
        {
            // Connection established
        }
        else if (state == ConnectionStates.Restored)
        {
            // Connection restored after disconnect
        }
        else if (state == ConnectionStates.Failed)
        {
            // Connection failed after all retry attempts
        }
    }

    private void OnError(Exception ex)
    {
        Console.Error.WriteLine($"WebSocket error: {ex}");
    }

    private async ValueTask ProcessMessage(WebSocketMessage msg, CancellationToken ct)
    {
        try
        {
            var message = msg.AsObject<dynamic>();

            if (message.type == "trade")
            {
                Console.WriteLine($"Trade: {message.symbol} @ {message.price}");
            }
            else if (message.type == "error")
            {
                Console.Error.WriteLine($"Server error: {message.message}");
            }
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine($"Error processing message: {ex.Message}");
        }

        await ValueTask.CompletedTask;
    }

    public void Dispose()
    {
        _socket?.Disconnect();
        _socket?.Dispose();
    }
}

// Usage
await using var client = new CryptoExchangeClient("wss://api.exchange.com/ws");
await client.ConnectAsync();
await client.SubscribeToTradesAsync("BTCUSD");

// Keep running
await Task.Delay(Timeout.Infinite);

Multi-Connection Manager

public class MultiExchangeClient
{
    private readonly ConnectionStateTracker _tracker;
    private readonly WebSocketClient _exchangeA;
    private readonly WebSocketClient _exchangeB;

    public MultiExchangeClient()
    {
        _tracker = new ConnectionStateTracker();

        _exchangeA = CreateClient("wss://exchange-a.com/ws", "Exchange A");
        _exchangeB = CreateClient("wss://exchange-b.com/ws", "Exchange B");

        _tracker.Add(_exchangeA);
        _tracker.Add(_exchangeB);

        _tracker.StateChanged += state =>
        {
            Console.WriteLine($"Overall connection state: {state}");

            if (state == ConnectionStates.Connected)
            {
                Console.WriteLine("All exchanges connected!");
            }
        };
    }

    private WebSocketClient CreateClient(string url, string name)
    {
        return new WebSocketClient(
            url: url,
            stateChanged: state => Console.WriteLine($"{name}: {state}"),
            error: ex => Console.Error.WriteLine($"{name} error: {ex.Message}"),
            process: (msg, ct) =>
            {
                Console.WriteLine($"{name}: {msg.AsString()}");
                return ValueTask.CompletedTask;
            },
            infoLog: (fmt, args) => Console.WriteLine($"[{name}] {fmt}", args),
            errorLog: (fmt, args) => Console.Error.WriteLine($"[{name}] {fmt}", args),
            verboseLog: null
        )
        {
            ReconnectAttempts = 5,
            ReconnectInterval = TimeSpan.FromSeconds(3)
        };
    }

    public async Task ConnectAllAsync()
    {
        await _tracker.ConnectAsync(CancellationToken.None);
    }

    public void DisconnectAll()
    {
        _tracker.Disconnect();
    }
}

WebSocket with REST API Integration

public class TradingClient
{
    private readonly WebSocketClient _wsClient;
    private readonly Uri _restApiUrl;

    public TradingClient(string wsUrl, string restUrl)
    {
        _restApiUrl = new Uri(restUrl);
        _wsClient = new WebSocketClient(
            url: wsUrl,
            stateChanged: state => Console.WriteLine($"WS State: {state}"),
            error: ex => Console.Error.WriteLine($"WS Error: {ex}"),
            process: ProcessWebSocketMessage,
            infoLog: (fmt, args) => Console.WriteLine(fmt, args),
            errorLog: (fmt, args) => Console.Error.WriteLine(fmt, args),
            verboseLog: null
        );
    }

    public async Task<AccountInfo> GetAccountInfoAsync()
    {
        var request = new RestRequest("/account", Method.Get);
        request.SetBearer(GetAuthToken());

        try
        {
            var account = await request.InvokeAsync<AccountInfo>(
                url: new Uri(_restApiUrl, request.Resource),
                caller: this,
                logVerbose: (fmt, args) => Console.WriteLine(fmt, args),
                token: CancellationToken.None
            );

            return account;
        }
        catch (RestSharpException ex)
        {
            Console.Error.WriteLine($"REST API Error: {ex.Message}");
            Console.Error.WriteLine($"Status: {ex.Response.StatusCode}");
            Console.Error.WriteLine($"Content: {ex.Response.Content}");
            throw;
        }
    }

    public async Task PlaceOrderAsync(string symbol, decimal price, decimal quantity)
    {
        var request = new RestRequest("/orders", Method.Post);
        request.SetBearer(GetAuthToken());
        request.AddBodyAsStr(new
        {
            symbol = symbol,
            price = price,
            quantity = quantity
        }.ToJson());

        var order = await request.InvokeAsync<Order>(
            url: new Uri(_restApiUrl, request.Resource),
            caller: this,
            logVerbose: (fmt, args) => Console.WriteLine(fmt, args),
            token: CancellationToken.None
        );

        Console.WriteLine($"Order placed: {order.Id}");
    }

    private async ValueTask ProcessWebSocketMessage(WebSocketMessage msg, CancellationToken ct)
    {
        var data = msg.AsObject<dynamic>();

        if (data.type == "order_update")
        {
            Console.WriteLine($"Order {data.orderId} status: {data.status}");
        }

        await ValueTask.CompletedTask;
    }

    private SecureString GetAuthToken()
    {
        // Return your authentication token
        throw new NotImplementedException();
    }
}

Best Practices

  1. Always handle errors: Provide error handlers to catch and log exceptions.

  2. Configure reconnection: Set appropriate reconnection attempts and intervals based on your use case.

  3. Use subscription IDs: Track subscriptions with IDs for automatic resend after reconnection.

  4. Monitor connection states: React to state changes to update your UI or trigger business logic.

  5. Dispose properly: Always dispose of WebSocketClient when done to clean up resources.

  6. Use async/await: Prefer async methods for better scalability.

  7. Implement backoff: Use increasing reconnection intervals to avoid overwhelming the server.

  8. Log appropriately: Use different log levels (info, error, verbose) for debugging and monitoring.

Thread Safety

The WebSocketClient class is designed to be thread-safe for the following operations:

  • Sending messages
  • Connection/disconnection
  • State management
  • Subscription tracking

However, you should not share a single WebSocketMessage instance across threads, as it contains read-only memory references.

Performance Considerations

  • Buffer Sizes: Adjust BufferSize and BufferSizeUncompress based on your message sizes.
  • Resend Interval: Lower intervals increase network traffic; higher intervals delay recovery.
  • Reconnect Attempts: Balance between reliability and resource usage.
  • Verbose Logging: Disable in production for better performance.

License

This library is part of the Ecng framework.

Support

For issues, questions, or contributions, please refer to the main StockSharp repository.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (7)

Showing the top 5 NuGet packages that depend on Ecng.Net.SocketIO:

Package Downloads
StockSharp.AlphaVantage

AlphaVantage

StockSharp.IEX

Trading and algorithmic trading platform (stock markets, forex, bitcoins and options). .NET API for InteractiveBrokers, GainCapital, OANDA, FIX/FAST, Binance etc. More info on web site https://stocksharp.com/store/api/

StockSharp.Web.Api.Client

StockSharp WebApi

StockSharp.Binance

Binance

StockSharp.Okex

OKX connector

GitHub repositories (1)

Showing the top 1 popular GitHub repositories that depend on Ecng.Net.SocketIO:

Repository Stars
StockSharp/StockSharp
Algorithmic trading and quantitative trading open source platform to develop trading robots (stock markets, forex, crypto, bitcoins, and options).
Version Downloads Last Updated
1.0.533 52 2/4/2026
1.0.532 78 2/4/2026
1.0.531 235 2/1/2026
1.0.530 88 1/30/2026
1.0.529 85 1/30/2026
1.0.528 83 1/30/2026
1.0.527 95 1/29/2026
1.0.526 103 1/26/2026
1.0.525 87 1/26/2026
1.0.524 100 1/22/2026
1.0.523 94 1/22/2026
1.0.522 94 1/21/2026
1.0.521 121 1/19/2026
1.0.520 97 1/19/2026
1.0.519 97 1/18/2026
1.0.518 91 1/18/2026
1.0.517 98 1/16/2026
1.0.516 127 1/14/2026
1.0.515 98 1/13/2026
1.0.514 95 1/13/2026
1.0.513 101 1/12/2026
1.0.512 136 1/9/2026
1.0.511 118 1/9/2026
1.0.510 102 1/8/2026
1.0.509 106 1/8/2026
1.0.508 105 1/7/2026
1.0.507 104 1/6/2026
1.0.506 102 1/6/2026
1.0.505 107 1/5/2026
1.0.504 119 1/4/2026
1.0.503 121 1/1/2026
1.0.502 109 12/31/2025
1.0.501 112 12/30/2025
1.0.500 106 12/30/2025
1.0.499 116 12/29/2025
1.0.498 109 12/29/2025
1.0.497 113 12/26/2025
1.0.496 108 12/26/2025
1.0.495 105 12/26/2025
1.0.494 125 12/26/2025
1.0.493 198 12/25/2025
1.0.492 202 12/25/2025
1.0.491 210 12/24/2025
1.0.490 204 12/23/2025
1.0.489 192 12/22/2025
1.0.488 193 12/22/2025
1.0.487 198 12/22/2025
1.0.486 184 12/21/2025
1.0.485 239 12/19/2025
1.0.484 263 12/19/2025
1.0.483 301 12/18/2025
1.0.482 300 12/17/2025
1.0.481 300 12/15/2025
1.0.480 274 12/15/2025
1.0.479 259 12/14/2025
1.0.478 180 12/14/2025
1.0.477 177 12/13/2025
1.0.476 199 12/13/2025
1.0.475 166 12/12/2025
1.0.474 152 12/12/2025
1.0.473 141 12/12/2025
1.0.472 146 12/12/2025
1.0.471 141 12/12/2025
1.0.470 143 12/12/2025
1.0.469 147 12/12/2025
1.0.468 745 12/2/2025
1.0.467 703 12/2/2025
1.0.466 698 12/2/2025
1.0.465 301 11/30/2025
1.0.464 177 11/29/2025
1.0.463 165 11/28/2025
1.0.462 171 11/28/2025
1.0.461 215 11/27/2025
1.0.460 255 11/24/2025
1.0.459 226 11/24/2025
1.0.458 222 11/23/2025
1.0.457 197 11/23/2025
1.0.456 251 11/22/2025
1.0.455 459 11/20/2025
1.0.454 435 11/20/2025
1.0.453 433 11/20/2025
1.0.452 458 11/18/2025
1.0.451 439 11/18/2025
1.0.450 365 11/13/2025
1.0.449 302 11/10/2025
1.0.448 1,125 11/1/2025
1.0.447 230 10/31/2025
1.0.446 241 10/28/2025
1.0.445 361 10/27/2025
1.0.444 228 10/27/2025
1.0.443 159 10/25/2025
1.0.442 188 10/24/2025
1.0.441 295 10/20/2025
1.0.440 330 10/12/2025
1.0.439 177 10/11/2025
1.0.438 311 10/7/2025
1.0.437 253 10/6/2025
1.0.436 294 10/3/2025
1.0.435 265 10/1/2025
1.0.434 237 10/1/2025
1.0.433 237 9/30/2025
1.0.432 241 9/28/2025
1.0.431 256 9/25/2025
1.0.430 3,416 9/5/2025
1.0.429 271 9/2/2025
1.0.428 623 8/30/2025
1.0.427 292 8/30/2025
1.0.426 293 8/20/2025
1.0.425 237 8/20/2025
1.0.424 255 8/19/2025
1.0.423 260 8/15/2025
1.0.422 353 8/10/2025
1.0.421 1,070 7/16/2025
1.0.420 306 7/14/2025
1.0.419 278 7/13/2025
1.0.418 255 7/13/2025
1.0.417 227 7/12/2025
1.0.416 818 7/8/2025
1.0.415 290 7/4/2025
1.0.414 286 7/2/2025
1.0.413 447 6/24/2025
1.0.412 1,059 6/16/2025
1.0.411 443 6/9/2025
1.0.410 318 6/8/2025
1.0.409 642 5/21/2025
1.0.408 289 5/21/2025
1.0.407 273 5/17/2025
1.0.406 682 5/12/2025
1.0.405 374 5/12/2025
1.0.404 343 5/12/2025
1.0.403 264 5/11/2025
1.0.402 279 5/11/2025
1.0.401 234 5/10/2025
1.0.400 192 5/10/2025
1.0.399 319 5/6/2025
1.0.398 240 5/3/2025
1.0.397 408 4/17/2025
1.0.396 360 4/15/2025
1.0.395 256 4/12/2025
1.0.394 334 4/9/2025
1.0.393 291 4/6/2025
1.0.392 248 4/5/2025
1.0.391 1,123 3/22/2025
1.0.390 320 3/20/2025
1.0.389 307 3/20/2025
1.0.388 300 3/19/2025
1.0.387 866 2/26/2025
1.0.386 274 2/26/2025
1.0.385 793 2/8/2025
1.0.384 270 2/8/2025
1.0.383 253 2/8/2025
1.0.382 246 2/6/2025
1.0.381 238 2/6/2025
1.0.380 257 2/6/2025
1.0.379 265 2/6/2025
1.0.378 243 2/6/2025
1.0.377 243 2/5/2025
1.0.376 243 2/5/2025
1.0.375 263 2/5/2025
1.0.374 290 2/3/2025
1.0.373 271 2/2/2025
1.0.372 289 2/1/2025
1.0.371 275 1/31/2025
1.0.370 279 1/30/2025
1.0.369 260 1/26/2025
1.0.368 292 1/21/2025
1.0.367 275 1/20/2025
1.0.366 242 1/20/2025
1.0.365 257 1/19/2025
1.0.364 246 1/19/2025
1.0.363 273 1/15/2025
1.0.362 241 1/15/2025
1.0.361 234 1/14/2025
1.0.360 228 1/12/2025
1.0.359 219 1/12/2025
1.0.358 238 1/12/2025
1.0.357 204 1/12/2025
1.0.356 258 1/10/2025
1.0.355 1,091 12/30/2024
1.0.354 281 12/27/2024
1.0.353 300 12/19/2024
1.0.352 769 11/20/2024
1.0.351 275 11/19/2024
1.0.350 258 11/19/2024
1.0.349 821 11/18/2024
1.0.348 493 11/15/2024
1.0.347 243 11/14/2024
1.0.346 268 11/14/2024
1.0.345 276 11/14/2024
1.0.344 224 11/14/2024
1.0.343 255 11/14/2024
1.0.342 294 11/7/2024
1.0.341 303 10/31/2024
1.0.340 359 10/20/2024
1.0.339 281 10/20/2024
1.0.338 297 10/20/2024
1.0.337 285 10/19/2024
1.0.336 302 10/19/2024
1.0.335 303 10/19/2024
1.0.334 295 10/19/2024
1.0.333 296 10/19/2024
1.0.332 276 10/19/2024
1.0.331 307 10/19/2024
1.0.330 336 10/18/2024
1.0.329 288 10/17/2024
1.0.328 252 10/17/2024
1.0.327 277 10/17/2024
1.0.326 828 10/14/2024
1.0.325 257 10/13/2024
1.0.324 255 10/13/2024
1.0.323 272 10/12/2024
1.0.322 469 10/9/2024
1.0.321 273 10/9/2024
1.0.320 465 10/5/2024
1.0.319 796 9/18/2024
1.0.318 252 9/18/2024
1.0.317 277 9/18/2024
1.0.316 269 9/17/2024
1.0.315 770 9/3/2024
1.0.314 318 9/1/2024
1.0.313 985 8/9/2024
1.0.312 277 8/9/2024
1.0.311 292 8/8/2024
1.0.310 735 7/25/2024
1.0.309 294 7/23/2024
1.0.308 316 7/17/2024
1.0.307 587 7/4/2024
1.0.306 641 6/12/2024
1.0.305 278 6/12/2024
1.0.304 282 6/12/2024
1.0.303 476 5/28/2024
1.0.302 636 5/4/2024
1.0.301 430 4/23/2024
1.0.300 292 4/21/2024
1.0.299 322 4/14/2024
1.0.298 590 3/28/2024
1.0.297 358 3/17/2024
1.0.296 559 3/9/2024
1.0.295 377 2/23/2024
1.0.294 305 2/23/2024
1.0.293 518 2/18/2024
1.0.292 310 2/18/2024
1.0.291 288 2/17/2024
1.0.290 303 2/16/2024
1.0.289 423 2/14/2024
1.0.288 301 2/13/2024
1.0.287 374 2/8/2024
1.0.286 374 2/5/2024
1.0.285 290 2/4/2024
1.0.284 462 1/23/2024
1.0.283 285 1/23/2024
1.0.282 355 1/12/2024
1.0.281 720 1/2/2024
1.0.280 331 12/29/2023
1.0.279 385 12/17/2023
1.0.278 543 12/15/2023
1.0.277 309 12/15/2023
1.0.276 289 12/15/2023
1.0.275 325 12/13/2023
1.0.274 320 12/13/2023
1.0.273 325 12/10/2023
1.0.272 695 11/18/2023
1.0.271 238 11/18/2023
1.0.270 266 11/18/2023
1.0.269 248 11/17/2023
1.0.268 221 11/12/2023
1.0.267 219 11/12/2023
1.0.266 249 11/10/2023
1.0.265 205 11/10/2023
1.0.264 246 11/9/2023
1.0.263 209 11/9/2023
1.0.262 226 11/9/2023
1.0.261 255 11/3/2023
1.0.260 237 11/1/2023
1.0.259 225 11/1/2023
1.0.258 1,482 9/8/2023
1.0.257 277 9/8/2023
1.0.256 294 9/3/2023
1.0.255 363 8/27/2023
1.0.254 289 8/24/2023
1.0.253 257 8/21/2023
1.0.252 332 8/15/2023
1.0.251 300 8/14/2023
1.0.250 276 8/14/2023
1.0.249 312 8/10/2023
1.0.248 1,030 7/29/2023
1.0.247 1,107 7/1/2023
1.0.246 319 6/29/2023
1.0.245 814 5/27/2023
1.0.244 368 5/21/2023
1.0.243 305 5/19/2023
1.0.242 1,095 5/8/2023
1.0.241 366 5/7/2023
1.0.240 356 5/7/2023
1.0.239 334 5/7/2023
1.0.238 381 5/1/2023
1.0.237 423 4/22/2023
1.0.236 383 4/21/2023
1.0.235 349 4/21/2023
1.0.234 1,246 4/13/2023
1.0.233 1,145 4/3/2023
1.0.232 500 3/27/2023
1.0.231 443 3/21/2023
1.0.230 446 3/17/2023
1.0.229 439 3/13/2023
1.0.228 1,194 3/6/2023
1.0.227 506 2/26/2023
1.0.226 949 2/21/2023
1.0.225 463 2/20/2023
1.0.224 479 2/16/2023
1.0.223 467 2/15/2023
1.0.222 440 2/14/2023
1.0.221 441 2/14/2023
1.0.220 1,370 2/9/2023
1.0.219 848 2/7/2023
1.0.218 499 2/4/2023
1.0.217 485 2/4/2023
1.0.216 495 2/3/2023
1.0.215 459 2/3/2023
1.0.214 453 2/3/2023
1.0.213 895 2/2/2023
1.0.212 845 1/30/2023
1.0.211 479 1/30/2023
1.0.210 522 1/25/2023
1.0.209 515 1/23/2023
1.0.208 465 1/23/2023
1.0.207 500 1/18/2023
1.0.206 527 1/15/2023
1.0.205 528 1/6/2023
1.0.204 1,432 1/1/2023
1.0.203 495 12/31/2022
1.0.202 980 12/30/2022
1.0.201 515 12/29/2022
1.0.200 519 12/23/2022
1.0.199 1,403 12/12/2022
1.0.198 1,081 12/8/2022
1.0.197 496 12/4/2022
1.0.196 502 12/4/2022
1.0.195 505 12/2/2022
1.0.194 530 11/30/2022
1.0.193 492 11/29/2022
1.0.192 489 11/28/2022
1.0.191 528 11/26/2022
1.0.190 526 11/26/2022
1.0.189 529 11/25/2022
1.0.188 527 11/25/2022
1.0.187 541 11/18/2022
1.0.186 1,613 11/11/2022
1.0.185 563 11/11/2022
1.0.184 517 11/10/2022
1.0.183 581 11/5/2022
1.0.182 563 11/4/2022
1.0.181 542 11/2/2022
1.0.180 535 11/2/2022
1.0.179 1,443 11/1/2022
1.0.178 1,670 10/16/2022
1.0.177 758 9/25/2022
1.0.176 687 9/10/2022
1.0.175 2,994 9/8/2022
1.0.174 666 9/8/2022
1.0.173 671 9/8/2022
1.0.172 648 9/4/2022
1.0.171 644 9/4/2022
1.0.170 5,364 8/24/2022
1.0.169 729 8/8/2022
1.0.168 650 8/8/2022
1.0.167 1,277 7/31/2022
1.0.166 666 7/31/2022
1.0.165 678 7/26/2022
1.0.164 647 7/26/2022
1.0.163 3,213 7/21/2022
1.0.162 700 7/19/2022
1.0.161 3,170 7/18/2022
1.0.160 702 7/13/2022
1.0.159 685 7/8/2022
1.0.158 711 6/30/2022
1.0.157 716 6/20/2022
1.0.156 667 6/18/2022
1.0.155 711 6/6/2022
1.0.154 759 5/27/2022
1.0.153 5,224 4/30/2022
1.0.152 694 4/20/2022
1.0.151 726 4/10/2022
1.0.150 693 4/7/2022
1.0.149 673 4/7/2022
1.0.148 733 4/2/2022
1.0.147 691 3/29/2022
1.0.146 677 3/27/2022
1.0.145 683 3/27/2022
1.0.144 3,933 3/24/2022
1.0.143 2,695 2/20/2022
1.0.142 654 2/20/2022
1.0.141 665 2/20/2022
1.0.140 695 2/20/2022
1.0.139 716 2/20/2022
1.0.138 681 2/20/2022
1.0.137 674 2/20/2022
1.0.136 695 2/20/2022
1.0.135 697 2/20/2022
1.0.134 686 2/19/2022
1.0.133 4,579 2/10/2022
1.0.132 797 1/27/2022
1.0.131 719 1/27/2022
1.0.130 3,580 1/24/2022
1.0.129 667 1/24/2022
1.0.128 706 1/23/2022
1.0.127 7,030 12/29/2021
1.0.126 554 12/27/2021
1.0.125 496 12/27/2021
1.0.124 519 12/27/2021
1.0.123 1,778 12/20/2021
1.0.122 562 12/17/2021
1.0.121 551 12/16/2021
1.0.120 534 12/15/2021
1.0.119 519 12/14/2021
1.0.118 544 12/14/2021
1.0.117 501 12/13/2021
1.0.116 668 12/12/2021
1.0.115 1,643 12/10/2021
1.0.114 551 12/7/2021
1.0.113 550 12/7/2021
1.0.112 1,987 12/6/2021
1.0.111 549 12/6/2021
1.0.110 555 12/5/2021
1.0.109 1,246 12/3/2021
1.0.108 1,051 12/3/2021
1.0.107 584 12/2/2021
1.0.106 2,469 11/29/2021
1.0.105 5,277 11/23/2021
1.0.104 541 11/23/2021
1.0.103 1,632 11/22/2021
1.0.102 637 11/17/2021
1.0.101 592 11/14/2021
1.0.100 1,761 11/13/2021
1.0.99 606 11/11/2021
1.0.98 585 11/11/2021
1.0.97 569 11/10/2021
1.0.96 584 11/9/2021
1.0.95 2,614 11/6/2021
1.0.94 614 11/6/2021
1.0.93 2,186 11/5/2021
1.0.92 641 11/5/2021
1.0.91 603 11/4/2021
1.0.90 569 11/4/2021
1.0.89 632 11/3/2021
1.0.88 693 10/30/2021
1.0.87 2,057 10/21/2021
1.0.86 665 10/17/2021
1.0.85 676 10/17/2021
1.0.84 3,064 10/14/2021
1.0.83 602 10/13/2021
1.0.82 624 10/13/2021
1.0.81 596 10/12/2021
1.0.80 2,152 10/11/2021
1.0.79 582 10/9/2021
1.0.78 1,964 10/7/2021
1.0.77 2,169 10/7/2021
1.0.76 582 10/7/2021
1.0.75 615 10/6/2021
1.0.74 669 9/28/2021
1.0.73 2,380 9/23/2021
1.0.72 715 9/11/2021
1.0.71 617 9/10/2021
1.0.70 682 9/9/2021
1.0.69 584 9/8/2021
1.0.68 647 9/8/2021
1.0.67 2,170 9/6/2021
1.0.66 715 8/31/2021
1.0.65 574 8/30/2021
1.0.64 2,627 7/31/2021
1.0.63 3,058 7/30/2021
1.0.62 695 7/26/2021
1.0.61 4,492 7/5/2021
1.0.60 653 7/1/2021
1.0.59 3,835 6/4/2021
1.0.58 5,086 4/26/2021
1.0.57 2,196 4/19/2021
1.0.56 5,740 4/8/2021
1.0.55 1,820 4/7/2021
1.0.54 633 4/7/2021
1.0.53 1,897 4/3/2021
1.0.52 7,997 3/22/2021
1.0.51 5,787 3/4/2021
1.0.50 2,173 2/26/2021
1.0.49 8,290 2/2/2021
1.0.48 3,245 1/26/2021
1.0.47 3,015 1/24/2021
1.0.46 674 1/24/2021
1.0.45 724 1/23/2021
1.0.44 3,917 1/20/2021
1.0.43 727 1/20/2021
1.0.42 2,099 1/18/2021
1.0.41 642 1/18/2021
1.0.40 2,073 1/16/2021
1.0.39 6,329 12/17/2020
1.0.38 705 12/16/2020
1.0.37 3,229 12/14/2020
1.0.36 2,137 12/9/2020
1.0.35 688 12/9/2020
1.0.34 701 12/7/2020
1.0.33 802 12/6/2020
1.0.32 755 12/2/2020
1.0.31 719 12/2/2020
1.0.30 2,217 12/1/2020
1.0.29 7,379 11/12/2020
1.0.29-atestpub 577 11/11/2020
1.0.28 3,362 10/11/2020
1.0.27 8,628 9/9/2020
1.0.26 2,644 9/3/2020
1.0.25 2,704 8/20/2020
1.0.24 6,174 8/9/2020
1.0.23 2,719 7/28/2020
1.0.22 2,657 7/19/2020
1.0.21 4,472 7/6/2020
1.0.20 6,641 6/6/2020
1.0.19 2,632 6/4/2020
1.0.18 4,398 5/29/2020
1.0.17 4,438 5/21/2020
1.0.16 776 5/17/2020
1.0.15 4,531 5/12/2020
1.0.14 8,250 5/4/2020
1.0.13 801 4/24/2020
1.0.12 791 4/22/2020
1.0.11 765 4/22/2020
1.0.10 787 4/21/2020
1.0.9 3,241 4/18/2020
1.0.8 2,599 4/16/2020
1.0.7 799 4/16/2020
1.0.6 2,273 4/15/2020
1.0.5 2,682 4/11/2020
1.0.4 2,574 4/3/2020
1.0.3 796 4/1/2020
1.0.2 2,504 3/27/2020
1.0.1 2,616 3/22/2020
1.0.0 903 3/22/2020