Ecng.Net.SocketIO 1.0.522

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.522
                    
NuGet\Install-Package Ecng.Net.SocketIO -Version 1.0.522
                    
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.522" />
                    
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.522" />
                    
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.522
                    
#r "nuget: Ecng.Net.SocketIO, 1.0.522"
                    
#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.522
                    
#: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.522
                    
Install as a Cake Addin
#tool nuget:?package=Ecng.Net.SocketIO&version=1.0.522
                    
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 (6)

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.Binance

Binance

StockSharp.Okex

OKX connector

StockSharp.Bitmex

Bitmex

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.526 0 1/26/2026
1.0.525 29 1/26/2026
1.0.524 44 1/22/2026
1.0.523 38 1/22/2026
1.0.522 72 1/21/2026
1.0.521 116 1/19/2026
1.0.520 92 1/19/2026
1.0.519 91 1/18/2026
1.0.518 85 1/18/2026
1.0.517 92 1/16/2026
1.0.516 121 1/14/2026
1.0.515 93 1/13/2026
1.0.514 90 1/13/2026
1.0.513 95 1/12/2026
1.0.512 131 1/9/2026
1.0.511 112 1/9/2026
1.0.510 97 1/8/2026
1.0.509 99 1/8/2026
1.0.508 99 1/7/2026
1.0.507 99 1/6/2026
1.0.506 95 1/6/2026
1.0.505 102 1/5/2026
1.0.504 113 1/4/2026
1.0.503 115 1/1/2026
1.0.502 105 12/31/2025
1.0.501 105 12/30/2025
1.0.500 100 12/30/2025
1.0.499 110 12/29/2025
1.0.498 104 12/29/2025
1.0.497 109 12/26/2025
1.0.496 103 12/26/2025
1.0.495 98 12/26/2025
1.0.494 119 12/26/2025
1.0.493 192 12/25/2025
1.0.492 194 12/25/2025
1.0.491 203 12/24/2025
1.0.490 198 12/23/2025
1.0.489 187 12/22/2025
1.0.488 188 12/22/2025
1.0.487 193 12/22/2025
1.0.486 178 12/21/2025
1.0.485 234 12/19/2025
1.0.484 258 12/19/2025
1.0.483 297 12/18/2025
1.0.482 295 12/17/2025
1.0.481 297 12/15/2025
1.0.480 270 12/15/2025
1.0.479 254 12/14/2025
1.0.478 174 12/14/2025
1.0.477 173 12/13/2025
1.0.476 196 12/13/2025
1.0.475 163 12/12/2025
1.0.474 147 12/12/2025
1.0.473 135 12/12/2025
1.0.472 142 12/12/2025
1.0.471 137 12/12/2025
1.0.470 140 12/12/2025
1.0.469 143 12/12/2025
1.0.468 741 12/2/2025
1.0.467 700 12/2/2025
1.0.466 694 12/2/2025
1.0.465 294 11/30/2025
1.0.464 167 11/29/2025
1.0.463 160 11/28/2025
1.0.462 165 11/28/2025
1.0.461 210 11/27/2025
1.0.460 251 11/24/2025
1.0.459 221 11/24/2025
1.0.458 217 11/23/2025
1.0.457 192 11/23/2025
1.0.456 246 11/22/2025
1.0.455 455 11/20/2025
1.0.454 431 11/20/2025
1.0.453 429 11/20/2025
1.0.452 454 11/18/2025
1.0.451 433 11/18/2025
1.0.450 359 11/13/2025
1.0.449 298 11/10/2025
1.0.448 1,122 11/1/2025
1.0.447 226 10/31/2025
1.0.446 236 10/28/2025
1.0.445 354 10/27/2025
1.0.444 224 10/27/2025
1.0.443 153 10/25/2025
1.0.442 184 10/24/2025
1.0.441 291 10/20/2025
1.0.440 324 10/12/2025
1.0.439 173 10/11/2025
1.0.438 306 10/7/2025
1.0.437 248 10/6/2025
1.0.436 290 10/3/2025
1.0.435 261 10/1/2025
1.0.434 234 10/1/2025
1.0.433 233 9/30/2025
1.0.432 236 9/28/2025
1.0.431 250 9/25/2025
1.0.430 3,302 9/5/2025
1.0.429 266 9/2/2025
1.0.428 618 8/30/2025
1.0.427 288 8/30/2025
1.0.426 288 8/20/2025
1.0.425 234 8/20/2025
1.0.424 247 8/19/2025
1.0.423 256 8/15/2025
1.0.422 349 8/10/2025
1.0.421 1,067 7/16/2025
1.0.420 301 7/14/2025
1.0.419 273 7/13/2025
1.0.418 251 7/13/2025
1.0.417 224 7/12/2025
1.0.416 773 7/8/2025
1.0.415 286 7/4/2025
1.0.414 281 7/2/2025
1.0.413 444 6/24/2025
1.0.412 1,050 6/16/2025
1.0.411 435 6/9/2025
1.0.410 313 6/8/2025
1.0.409 636 5/21/2025
1.0.408 281 5/21/2025
1.0.407 269 5/17/2025
1.0.406 676 5/12/2025
1.0.405 370 5/12/2025
1.0.404 338 5/12/2025
1.0.403 260 5/11/2025
1.0.402 273 5/11/2025
1.0.401 225 5/10/2025
1.0.400 188 5/10/2025
1.0.399 313 5/6/2025
1.0.398 237 5/3/2025
1.0.397 402 4/17/2025
1.0.396 354 4/15/2025
1.0.395 252 4/12/2025
1.0.394 330 4/9/2025
1.0.393 288 4/6/2025
1.0.392 244 4/5/2025
1.0.391 1,118 3/22/2025
1.0.390 315 3/20/2025
1.0.389 304 3/20/2025
1.0.388 292 3/19/2025
1.0.387 859 2/26/2025
1.0.386 270 2/26/2025
1.0.385 788 2/8/2025
1.0.384 265 2/8/2025
1.0.383 249 2/8/2025
1.0.382 243 2/6/2025
1.0.381 235 2/6/2025
1.0.380 252 2/6/2025
1.0.379 262 2/6/2025
1.0.378 237 2/6/2025
1.0.377 240 2/5/2025
1.0.376 239 2/5/2025
1.0.375 259 2/5/2025
1.0.374 286 2/3/2025
1.0.373 268 2/2/2025
1.0.372 284 2/1/2025
1.0.371 269 1/31/2025
1.0.370 274 1/30/2025
1.0.369 256 1/26/2025
1.0.368 286 1/21/2025
1.0.367 271 1/20/2025
1.0.366 236 1/20/2025
1.0.365 254 1/19/2025
1.0.364 243 1/19/2025
1.0.363 269 1/15/2025
1.0.362 236 1/15/2025
1.0.361 230 1/14/2025
1.0.360 224 1/12/2025
1.0.359 214 1/12/2025
1.0.358 232 1/12/2025
1.0.357 197 1/12/2025
1.0.356 253 1/10/2025
1.0.355 1,085 12/30/2024
1.0.354 277 12/27/2024
1.0.353 296 12/19/2024
1.0.352 763 11/20/2024
1.0.351 272 11/19/2024
1.0.350 253 11/19/2024
1.0.349 816 11/18/2024
1.0.348 489 11/15/2024
1.0.347 239 11/14/2024
1.0.346 263 11/14/2024
1.0.345 269 11/14/2024
1.0.344 219 11/14/2024
1.0.343 249 11/14/2024
1.0.342 290 11/7/2024
1.0.341 299 10/31/2024
1.0.340 355 10/20/2024
1.0.339 278 10/20/2024
1.0.338 291 10/20/2024
1.0.337 282 10/19/2024
1.0.336 297 10/19/2024
1.0.335 299 10/19/2024
1.0.334 290 10/19/2024
1.0.333 292 10/19/2024
1.0.332 273 10/19/2024
1.0.331 302 10/19/2024
1.0.330 332 10/18/2024
1.0.329 284 10/17/2024
1.0.328 249 10/17/2024
1.0.327 271 10/17/2024
1.0.326 824 10/14/2024
1.0.325 251 10/13/2024
1.0.324 251 10/13/2024
1.0.323 268 10/12/2024
1.0.322 465 10/9/2024
1.0.321 270 10/9/2024
1.0.320 461 10/5/2024
1.0.319 792 9/18/2024
1.0.318 249 9/18/2024
1.0.317 272 9/18/2024
1.0.316 264 9/17/2024
1.0.315 766 9/3/2024
1.0.314 313 9/1/2024
1.0.313 980 8/9/2024
1.0.312 271 8/9/2024
1.0.311 287 8/8/2024
1.0.310 729 7/25/2024
1.0.309 290 7/23/2024
1.0.308 309 7/17/2024
1.0.307 581 7/4/2024
1.0.306 637 6/12/2024
1.0.305 274 6/12/2024
1.0.304 278 6/12/2024
1.0.303 469 5/28/2024
1.0.302 632 5/4/2024
1.0.301 425 4/23/2024
1.0.300 287 4/21/2024
1.0.299 317 4/14/2024
1.0.298 584 3/28/2024
1.0.297 353 3/17/2024
1.0.296 556 3/9/2024
1.0.295 371 2/23/2024
1.0.294 301 2/23/2024
1.0.293 512 2/18/2024
1.0.292 302 2/18/2024
1.0.291 279 2/17/2024
1.0.290 293 2/16/2024
1.0.289 418 2/14/2024
1.0.288 297 2/13/2024
1.0.287 368 2/8/2024
1.0.286 370 2/5/2024
1.0.285 285 2/4/2024
1.0.284 458 1/23/2024
1.0.283 279 1/23/2024
1.0.282 348 1/12/2024
1.0.281 714 1/2/2024
1.0.280 327 12/29/2023
1.0.279 379 12/17/2023
1.0.278 539 12/15/2023
1.0.277 305 12/15/2023
1.0.276 284 12/15/2023
1.0.275 318 12/13/2023
1.0.274 316 12/13/2023
1.0.273 318 12/10/2023
1.0.272 691 11/18/2023
1.0.271 237 11/18/2023
1.0.270 263 11/18/2023
1.0.269 246 11/17/2023
1.0.268 219 11/12/2023
1.0.267 217 11/12/2023
1.0.266 244 11/10/2023
1.0.265 204 11/10/2023
1.0.264 245 11/9/2023
1.0.263 208 11/9/2023
1.0.262 225 11/9/2023
1.0.261 252 11/3/2023
1.0.260 235 11/1/2023
1.0.259 223 11/1/2023
1.0.258 1,480 9/8/2023
1.0.257 276 9/8/2023
1.0.256 290 9/3/2023
1.0.255 361 8/27/2023
1.0.254 287 8/24/2023
1.0.253 254 8/21/2023
1.0.252 329 8/15/2023
1.0.251 296 8/14/2023
1.0.250 273 8/14/2023
1.0.249 309 8/10/2023
1.0.248 1,027 7/29/2023
1.0.247 1,103 7/1/2023
1.0.246 316 6/29/2023
1.0.245 810 5/27/2023
1.0.244 366 5/21/2023
1.0.243 302 5/19/2023
1.0.242 1,094 5/8/2023
1.0.241 365 5/7/2023
1.0.240 354 5/7/2023
1.0.239 331 5/7/2023
1.0.238 379 5/1/2023
1.0.237 420 4/22/2023
1.0.236 381 4/21/2023
1.0.235 348 4/21/2023
1.0.234 1,245 4/13/2023
1.0.233 1,143 4/3/2023
1.0.232 498 3/27/2023
1.0.231 441 3/21/2023
1.0.230 442 3/17/2023
1.0.229 437 3/13/2023
1.0.228 1,193 3/6/2023
1.0.227 502 2/26/2023
1.0.226 947 2/21/2023
1.0.225 462 2/20/2023
1.0.224 477 2/16/2023
1.0.223 466 2/15/2023
1.0.222 438 2/14/2023
1.0.221 435 2/14/2023
1.0.220 1,368 2/9/2023
1.0.219 844 2/7/2023
1.0.218 497 2/4/2023
1.0.217 481 2/4/2023
1.0.216 494 2/3/2023
1.0.215 455 2/3/2023
1.0.214 451 2/3/2023
1.0.213 892 2/2/2023
1.0.212 843 1/30/2023
1.0.211 477 1/30/2023
1.0.210 519 1/25/2023
1.0.209 510 1/23/2023
1.0.208 464 1/23/2023
1.0.207 498 1/18/2023
1.0.206 524 1/15/2023
1.0.205 522 1/6/2023
1.0.204 1,428 1/1/2023
1.0.203 494 12/31/2022
1.0.202 977 12/30/2022
1.0.201 512 12/29/2022
1.0.200 517 12/23/2022
1.0.199 1,401 12/12/2022
1.0.198 1,079 12/8/2022
1.0.197 495 12/4/2022
1.0.196 498 12/4/2022
1.0.195 504 12/2/2022
1.0.194 528 11/30/2022
1.0.193 490 11/29/2022
1.0.192 485 11/28/2022
1.0.191 527 11/26/2022
1.0.190 523 11/26/2022
1.0.189 525 11/25/2022
1.0.188 525 11/25/2022
1.0.187 539 11/18/2022
1.0.186 1,612 11/11/2022
1.0.185 560 11/11/2022
1.0.184 515 11/10/2022
1.0.183 579 11/5/2022
1.0.182 562 11/4/2022
1.0.181 538 11/2/2022
1.0.180 531 11/2/2022
1.0.179 1,440 11/1/2022
1.0.178 1,669 10/16/2022
1.0.177 750 9/25/2022
1.0.176 684 9/10/2022
1.0.175 2,992 9/8/2022
1.0.174 662 9/8/2022
1.0.173 670 9/8/2022
1.0.172 647 9/4/2022
1.0.171 641 9/4/2022
1.0.170 5,363 8/24/2022
1.0.169 726 8/8/2022
1.0.168 648 8/8/2022
1.0.167 1,276 7/31/2022
1.0.166 663 7/31/2022
1.0.165 675 7/26/2022
1.0.164 644 7/26/2022
1.0.163 3,209 7/21/2022
1.0.162 699 7/19/2022
1.0.161 3,166 7/18/2022
1.0.160 700 7/13/2022
1.0.159 683 7/8/2022
1.0.158 708 6/30/2022
1.0.157 714 6/20/2022
1.0.156 665 6/18/2022
1.0.155 709 6/6/2022
1.0.154 757 5/27/2022
1.0.153 5,222 4/30/2022
1.0.152 692 4/20/2022
1.0.151 724 4/10/2022
1.0.150 692 4/7/2022
1.0.149 672 4/7/2022
1.0.148 733 4/2/2022
1.0.147 689 3/29/2022
1.0.146 677 3/27/2022
1.0.145 682 3/27/2022
1.0.144 3,931 3/24/2022
1.0.143 2,695 2/20/2022
1.0.142 653 2/20/2022
1.0.141 664 2/20/2022
1.0.140 693 2/20/2022
1.0.139 713 2/20/2022
1.0.138 679 2/20/2022
1.0.137 672 2/20/2022
1.0.136 691 2/20/2022
1.0.135 696 2/20/2022
1.0.134 681 2/19/2022
1.0.133 4,579 2/10/2022
1.0.132 794 1/27/2022
1.0.131 718 1/27/2022
1.0.130 3,580 1/24/2022
1.0.129 665 1/24/2022
1.0.128 705 1/23/2022
1.0.127 7,027 12/29/2021
1.0.126 552 12/27/2021
1.0.125 495 12/27/2021
1.0.124 519 12/27/2021
1.0.123 1,776 12/20/2021
1.0.122 559 12/17/2021
1.0.121 550 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 665 12/12/2021
1.0.115 1,642 12/10/2021
1.0.114 550 12/7/2021
1.0.113 550 12/7/2021
1.0.112 1,987 12/6/2021
1.0.111 546 12/6/2021
1.0.110 554 12/5/2021
1.0.109 1,244 12/3/2021
1.0.108 1,050 12/3/2021
1.0.107 583 12/2/2021
1.0.106 2,466 11/29/2021
1.0.105 5,275 11/23/2021
1.0.104 541 11/23/2021
1.0.103 1,625 11/22/2021
1.0.102 636 11/17/2021
1.0.101 589 11/14/2021
1.0.100 1,757 11/13/2021
1.0.99 606 11/11/2021
1.0.98 585 11/11/2021
1.0.97 568 11/10/2021
1.0.96 583 11/9/2021
1.0.95 2,613 11/6/2021
1.0.94 614 11/6/2021
1.0.93 2,181 11/5/2021
1.0.92 638 11/5/2021
1.0.91 598 11/4/2021
1.0.90 568 11/4/2021
1.0.89 628 11/3/2021
1.0.88 692 10/30/2021
1.0.87 2,056 10/21/2021
1.0.86 664 10/17/2021
1.0.85 676 10/17/2021
1.0.84 3,063 10/14/2021
1.0.83 602 10/13/2021
1.0.82 618 10/13/2021
1.0.81 595 10/12/2021
1.0.80 2,150 10/11/2021
1.0.79 579 10/9/2021
1.0.78 1,963 10/7/2021
1.0.77 2,166 10/7/2021
1.0.76 578 10/7/2021
1.0.75 612 10/6/2021
1.0.74 667 9/28/2021
1.0.73 2,378 9/23/2021
1.0.72 711 9/11/2021
1.0.71 615 9/10/2021
1.0.70 681 9/9/2021
1.0.69 582 9/8/2021
1.0.68 644 9/8/2021
1.0.67 2,168 9/6/2021
1.0.66 714 8/31/2021
1.0.65 572 8/30/2021
1.0.64 2,626 7/31/2021
1.0.63 3,055 7/30/2021
1.0.62 694 7/26/2021
1.0.61 4,492 7/5/2021
1.0.60 652 7/1/2021
1.0.59 3,835 6/4/2021
1.0.58 5,085 4/26/2021
1.0.57 2,193 4/19/2021
1.0.56 5,738 4/8/2021
1.0.55 1,817 4/7/2021
1.0.54 631 4/7/2021
1.0.53 1,897 4/3/2021
1.0.52 7,996 3/22/2021
1.0.51 5,786 3/4/2021
1.0.50 2,171 2/26/2021
1.0.49 8,288 2/2/2021
1.0.48 3,241 1/26/2021
1.0.47 3,015 1/24/2021
1.0.46 674 1/24/2021
1.0.45 722 1/23/2021
1.0.44 3,915 1/20/2021
1.0.43 726 1/20/2021
1.0.42 2,098 1/18/2021
1.0.41 641 1/18/2021
1.0.40 2,073 1/16/2021
1.0.39 6,328 12/17/2020
1.0.38 704 12/16/2020
1.0.37 3,228 12/14/2020
1.0.36 2,135 12/9/2020
1.0.35 687 12/9/2020
1.0.34 700 12/7/2020
1.0.33 800 12/6/2020
1.0.32 752 12/2/2020
1.0.31 718 12/2/2020
1.0.30 2,216 12/1/2020
1.0.29 7,378 11/12/2020
1.0.29-atestpub 574 11/11/2020
1.0.28 3,358 10/11/2020
1.0.27 8,627 9/9/2020
1.0.26 2,643 9/3/2020
1.0.25 2,702 8/20/2020
1.0.24 6,173 8/9/2020
1.0.23 2,716 7/28/2020
1.0.22 2,655 7/19/2020
1.0.21 4,472 7/6/2020
1.0.20 6,640 6/6/2020
1.0.19 2,631 6/4/2020
1.0.18 4,397 5/29/2020
1.0.17 4,435 5/21/2020
1.0.16 774 5/17/2020
1.0.15 4,531 5/12/2020
1.0.14 8,248 5/4/2020
1.0.13 800 4/24/2020
1.0.12 789 4/22/2020
1.0.11 765 4/22/2020
1.0.10 787 4/21/2020
1.0.9 3,238 4/18/2020
1.0.8 2,597 4/16/2020
1.0.7 797 4/16/2020
1.0.6 2,273 4/15/2020
1.0.5 2,682 4/11/2020
1.0.4 2,572 4/3/2020
1.0.3 795 4/1/2020
1.0.2 2,502 3/27/2020
1.0.1 2,613 3/22/2020
1.0.0 902 3/22/2020