Ecng.Net.SocketIO 1.0.511

dotnet add package Ecng.Net.SocketIO --version 1.0.511
                    
NuGet\Install-Package Ecng.Net.SocketIO -Version 1.0.511
                    
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.511" />
                    
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.511" />
                    
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.511
                    
#r "nuget: Ecng.Net.SocketIO, 1.0.511"
                    
#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.511
                    
#: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.511
                    
Install as a Cake Addin
#tool nuget:?package=Ecng.Net.SocketIO&version=1.0.511
                    
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 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. 
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.511 0 1/9/2026
1.0.510 26 1/8/2026
1.0.509 32 1/8/2026
1.0.508 39 1/7/2026
1.0.507 81 1/6/2026
1.0.506 77 1/6/2026
1.0.505 89 1/5/2026
1.0.504 101 1/4/2026
1.0.503 104 1/1/2026
1.0.502 92 12/31/2025
1.0.501 93 12/30/2025
1.0.500 86 12/30/2025
1.0.499 95 12/29/2025
1.0.498 90 12/29/2025
1.0.497 95 12/26/2025
1.0.496 88 12/26/2025
1.0.495 87 12/26/2025
1.0.494 108 12/26/2025
1.0.493 177 12/25/2025
1.0.492 181 12/25/2025
1.0.491 190 12/24/2025
1.0.490 182 12/23/2025
1.0.489 174 12/22/2025
1.0.488 172 12/22/2025
1.0.487 180 12/22/2025
1.0.486 166 12/21/2025
1.0.485 221 12/19/2025
1.0.484 239 12/19/2025
1.0.483 287 12/18/2025
1.0.482 285 12/17/2025
1.0.481 284 12/15/2025
1.0.480 257 12/15/2025
1.0.479 237 12/14/2025
1.0.478 163 12/14/2025
1.0.477 163 12/13/2025
1.0.476 179 12/13/2025
1.0.475 147 12/12/2025
1.0.474 131 12/12/2025
1.0.473 121 12/12/2025
1.0.472 127 12/12/2025
1.0.471 121 12/12/2025
1.0.470 124 12/12/2025
1.0.469 124 12/12/2025
1.0.468 728 12/2/2025
1.0.467 684 12/2/2025
1.0.466 683 12/2/2025
1.0.465 280 11/30/2025
1.0.464 152 11/29/2025
1.0.463 144 11/28/2025
1.0.462 151 11/28/2025
1.0.461 196 11/27/2025
1.0.460 237 11/24/2025
1.0.459 206 11/24/2025
1.0.458 205 11/23/2025
1.0.457 177 11/23/2025
1.0.456 230 11/22/2025
1.0.455 443 11/20/2025
1.0.454 418 11/20/2025
1.0.453 415 11/20/2025
1.0.452 439 11/18/2025
1.0.451 418 11/18/2025
1.0.450 345 11/13/2025
1.0.449 283 11/10/2025
1.0.448 1,103 11/1/2025
1.0.447 213 10/31/2025
1.0.446 222 10/28/2025
1.0.445 340 10/27/2025
1.0.444 209 10/27/2025
1.0.443 140 10/25/2025
1.0.442 166 10/24/2025
1.0.441 279 10/20/2025
1.0.440 312 10/12/2025
1.0.439 160 10/11/2025
1.0.438 297 10/7/2025
1.0.437 239 10/6/2025
1.0.436 279 10/3/2025
1.0.435 250 10/1/2025
1.0.434 219 10/1/2025
1.0.433 219 9/30/2025
1.0.432 222 9/28/2025
1.0.431 237 9/25/2025
1.0.430 3,100 9/5/2025
1.0.429 252 9/2/2025
1.0.428 606 8/30/2025
1.0.427 274 8/30/2025
1.0.426 277 8/20/2025
1.0.425 219 8/20/2025
1.0.424 232 8/19/2025
1.0.423 241 8/15/2025
1.0.422 335 8/10/2025
1.0.421 1,056 7/16/2025
1.0.420 289 7/14/2025
1.0.419 261 7/13/2025
1.0.418 238 7/13/2025
1.0.417 212 7/12/2025
1.0.416 702 7/8/2025
1.0.415 271 7/4/2025
1.0.414 269 7/2/2025
1.0.413 432 6/24/2025
1.0.412 1,039 6/16/2025
1.0.411 419 6/9/2025
1.0.410 301 6/8/2025
1.0.409 624 5/21/2025
1.0.408 268 5/21/2025
1.0.407 256 5/17/2025
1.0.406 660 5/12/2025
1.0.405 357 5/12/2025
1.0.404 324 5/12/2025
1.0.403 249 5/11/2025
1.0.402 256 5/11/2025
1.0.401 214 5/10/2025
1.0.400 174 5/10/2025
1.0.399 302 5/6/2025
1.0.398 226 5/3/2025
1.0.397 391 4/17/2025
1.0.396 341 4/15/2025
1.0.395 241 4/12/2025
1.0.394 313 4/9/2025
1.0.393 276 4/6/2025
1.0.392 229 4/5/2025
1.0.391 1,102 3/22/2025
1.0.390 296 3/20/2025
1.0.389 288 3/20/2025
1.0.388 276 3/19/2025
1.0.387 846 2/26/2025
1.0.386 253 2/26/2025
1.0.385 775 2/8/2025
1.0.384 257 2/8/2025
1.0.383 231 2/8/2025
1.0.382 232 2/6/2025
1.0.381 222 2/6/2025
1.0.380 240 2/6/2025
1.0.379 247 2/6/2025
1.0.378 222 2/6/2025
1.0.377 226 2/5/2025
1.0.376 231 2/5/2025
1.0.375 246 2/5/2025
1.0.374 269 2/3/2025
1.0.373 251 2/2/2025
1.0.372 270 2/1/2025
1.0.371 250 1/31/2025
1.0.370 257 1/30/2025
1.0.369 240 1/26/2025
1.0.368 273 1/21/2025
1.0.367 260 1/20/2025
1.0.366 224 1/20/2025
1.0.365 240 1/19/2025
1.0.364 227 1/19/2025
1.0.363 252 1/15/2025
1.0.362 225 1/15/2025
1.0.361 217 1/14/2025
1.0.360 210 1/12/2025
1.0.359 202 1/12/2025
1.0.358 215 1/12/2025
1.0.357 186 1/12/2025
1.0.356 237 1/10/2025
1.0.355 1,074 12/30/2024
1.0.354 259 12/27/2024
1.0.353 283 12/19/2024
1.0.352 747 11/20/2024
1.0.351 260 11/19/2024
1.0.350 242 11/19/2024
1.0.349 804 11/18/2024
1.0.348 476 11/15/2024
1.0.347 228 11/14/2024
1.0.346 252 11/14/2024
1.0.345 257 11/14/2024
1.0.344 208 11/14/2024
1.0.343 231 11/14/2024
1.0.342 274 11/7/2024
1.0.341 285 10/31/2024
1.0.340 342 10/20/2024
1.0.339 265 10/20/2024
1.0.338 279 10/20/2024
1.0.337 271 10/19/2024
1.0.336 284 10/19/2024
1.0.335 285 10/19/2024
1.0.334 280 10/19/2024
1.0.333 279 10/19/2024
1.0.332 259 10/19/2024
1.0.331 289 10/19/2024
1.0.330 316 10/18/2024
1.0.329 272 10/17/2024
1.0.328 233 10/17/2024
1.0.327 257 10/17/2024
1.0.326 812 10/14/2024
1.0.325 238 10/13/2024
1.0.324 237 10/13/2024
1.0.323 257 10/12/2024
1.0.322 449 10/9/2024
1.0.321 256 10/9/2024
1.0.320 450 10/5/2024
1.0.319 781 9/18/2024
1.0.318 239 9/18/2024
1.0.317 258 9/18/2024
1.0.316 252 9/17/2024
1.0.315 751 9/3/2024
1.0.314 299 9/1/2024
1.0.313 967 8/9/2024
1.0.312 255 8/9/2024
1.0.311 276 8/8/2024
1.0.310 717 7/25/2024
1.0.309 275 7/23/2024
1.0.308 295 7/17/2024
1.0.307 563 7/4/2024
1.0.306 623 6/12/2024
1.0.305 264 6/12/2024
1.0.304 263 6/12/2024
1.0.303 456 5/28/2024
1.0.302 621 5/4/2024
1.0.301 415 4/23/2024
1.0.300 276 4/21/2024
1.0.299 301 4/14/2024
1.0.298 569 3/28/2024
1.0.297 340 3/17/2024
1.0.296 544 3/9/2024
1.0.295 360 2/23/2024
1.0.294 289 2/23/2024
1.0.293 499 2/18/2024
1.0.292 290 2/18/2024
1.0.291 265 2/17/2024
1.0.290 284 2/16/2024
1.0.289 404 2/14/2024
1.0.288 285 2/13/2024
1.0.287 354 2/8/2024
1.0.286 357 2/5/2024
1.0.285 275 2/4/2024
1.0.284 446 1/23/2024
1.0.283 266 1/23/2024
1.0.282 333 1/12/2024
1.0.281 701 1/2/2024
1.0.280 316 12/29/2023
1.0.279 366 12/17/2023
1.0.278 522 12/15/2023
1.0.277 293 12/15/2023
1.0.276 274 12/15/2023
1.0.275 308 12/13/2023
1.0.274 303 12/13/2023
1.0.273 308 12/10/2023
1.0.272 688 11/18/2023
1.0.271 232 11/18/2023
1.0.270 257 11/18/2023
1.0.269 241 11/17/2023
1.0.268 214 11/12/2023
1.0.267 214 11/12/2023
1.0.266 234 11/10/2023
1.0.265 201 11/10/2023
1.0.264 239 11/9/2023
1.0.263 200 11/9/2023
1.0.262 221 11/9/2023
1.0.261 245 11/3/2023
1.0.260 231 11/1/2023
1.0.259 213 11/1/2023
1.0.258 1,478 9/8/2023
1.0.257 272 9/8/2023
1.0.256 287 9/3/2023
1.0.255 352 8/27/2023
1.0.254 280 8/24/2023
1.0.253 245 8/21/2023
1.0.252 322 8/15/2023
1.0.251 290 8/14/2023
1.0.250 269 8/14/2023
1.0.249 302 8/10/2023
1.0.248 1,019 7/29/2023
1.0.247 1,097 7/1/2023
1.0.246 311 6/29/2023
1.0.245 804 5/27/2023
1.0.244 357 5/21/2023
1.0.243 301 5/19/2023
1.0.242 1,087 5/8/2023
1.0.241 357 5/7/2023
1.0.240 344 5/7/2023
1.0.239 323 5/7/2023
1.0.238 372 5/1/2023
1.0.237 416 4/22/2023
1.0.236 376 4/21/2023
1.0.235 343 4/21/2023
1.0.234 1,238 4/13/2023
1.0.233 1,138 4/3/2023
1.0.232 492 3/27/2023
1.0.231 435 3/21/2023
1.0.230 438 3/17/2023
1.0.229 431 3/13/2023
1.0.228 1,187 3/6/2023
1.0.227 500 2/26/2023
1.0.226 944 2/21/2023
1.0.225 457 2/20/2023
1.0.224 475 2/16/2023
1.0.223 459 2/15/2023
1.0.222 435 2/14/2023
1.0.221 429 2/14/2023
1.0.220 1,360 2/9/2023
1.0.219 837 2/7/2023
1.0.218 490 2/4/2023
1.0.217 473 2/4/2023
1.0.216 490 2/3/2023
1.0.215 449 2/3/2023
1.0.214 447 2/3/2023
1.0.213 890 2/2/2023
1.0.212 837 1/30/2023
1.0.211 472 1/30/2023
1.0.210 511 1/25/2023
1.0.209 507 1/23/2023
1.0.208 458 1/23/2023
1.0.207 494 1/18/2023
1.0.206 520 1/15/2023
1.0.205 519 1/6/2023
1.0.204 1,419 1/1/2023
1.0.203 487 12/31/2022
1.0.202 974 12/30/2022
1.0.201 505 12/29/2022
1.0.200 516 12/23/2022
1.0.199 1,396 12/12/2022
1.0.198 1,075 12/8/2022
1.0.197 491 12/4/2022
1.0.196 495 12/4/2022
1.0.195 499 12/2/2022
1.0.194 522 11/30/2022
1.0.193 484 11/29/2022
1.0.192 479 11/28/2022
1.0.191 525 11/26/2022
1.0.190 518 11/26/2022
1.0.189 519 11/25/2022
1.0.188 518 11/25/2022
1.0.187 533 11/18/2022
1.0.186 1,600 11/11/2022
1.0.185 556 11/11/2022
1.0.184 512 11/10/2022
1.0.183 576 11/5/2022
1.0.182 555 11/4/2022
1.0.181 534 11/2/2022
1.0.180 526 11/2/2022
1.0.179 1,438 11/1/2022
1.0.178 1,662 10/16/2022
1.0.177 747 9/25/2022
1.0.176 675 9/10/2022
1.0.175 2,985 9/8/2022
1.0.174 656 9/8/2022
1.0.173 664 9/8/2022
1.0.172 637 9/4/2022
1.0.171 639 9/4/2022
1.0.170 5,358 8/24/2022
1.0.169 720 8/8/2022
1.0.168 645 8/8/2022
1.0.167 1,272 7/31/2022
1.0.166 660 7/31/2022
1.0.165 671 7/26/2022
1.0.164 636 7/26/2022
1.0.163 3,207 7/21/2022
1.0.162 694 7/19/2022
1.0.161 3,161 7/18/2022
1.0.160 698 7/13/2022
1.0.159 679 7/8/2022
1.0.158 700 6/30/2022
1.0.157 712 6/20/2022
1.0.156 663 6/18/2022
1.0.155 705 6/6/2022
1.0.154 750 5/27/2022
1.0.153 5,218 4/30/2022
1.0.152 691 4/20/2022
1.0.151 719 4/10/2022
1.0.150 689 4/7/2022
1.0.149 668 4/7/2022
1.0.148 725 4/2/2022
1.0.147 681 3/29/2022
1.0.146 673 3/27/2022
1.0.145 673 3/27/2022
1.0.144 3,924 3/24/2022
1.0.143 2,690 2/20/2022
1.0.142 650 2/20/2022
1.0.141 659 2/20/2022
1.0.140 691 2/20/2022
1.0.139 709 2/20/2022
1.0.138 671 2/20/2022
1.0.137 664 2/20/2022
1.0.136 686 2/20/2022
1.0.135 686 2/20/2022
1.0.134 677 2/19/2022
1.0.133 4,570 2/10/2022
1.0.132 783 1/27/2022
1.0.131 712 1/27/2022
1.0.130 3,574 1/24/2022
1.0.129 659 1/24/2022
1.0.128 697 1/23/2022
1.0.127 7,023 12/29/2021
1.0.126 548 12/27/2021
1.0.125 489 12/27/2021
1.0.124 513 12/27/2021
1.0.123 1,767 12/20/2021
1.0.122 554 12/17/2021
1.0.121 542 12/16/2021
1.0.120 525 12/15/2021
1.0.119 515 12/14/2021
1.0.118 539 12/14/2021
1.0.117 497 12/13/2021
1.0.116 659 12/12/2021
1.0.115 1,637 12/10/2021
1.0.114 548 12/7/2021
1.0.113 547 12/7/2021
1.0.112 1,981 12/6/2021
1.0.111 544 12/6/2021
1.0.110 548 12/5/2021
1.0.109 1,240 12/3/2021
1.0.108 1,046 12/3/2021
1.0.107 581 12/2/2021
1.0.106 2,461 11/29/2021
1.0.105 5,273 11/23/2021
1.0.104 536 11/23/2021
1.0.103 1,621 11/22/2021
1.0.102 632 11/17/2021
1.0.101 586 11/14/2021
1.0.100 1,751 11/13/2021
1.0.99 602 11/11/2021
1.0.98 581 11/11/2021
1.0.97 566 11/10/2021
1.0.96 575 11/9/2021
1.0.95 2,606 11/6/2021
1.0.94 610 11/6/2021
1.0.93 2,175 11/5/2021
1.0.92 635 11/5/2021
1.0.91 592 11/4/2021
1.0.90 565 11/4/2021
1.0.89 622 11/3/2021
1.0.88 688 10/30/2021
1.0.87 2,054 10/21/2021
1.0.86 659 10/17/2021
1.0.85 669 10/17/2021
1.0.84 3,057 10/14/2021
1.0.83 596 10/13/2021
1.0.82 612 10/13/2021
1.0.81 590 10/12/2021
1.0.80 2,147 10/11/2021
1.0.79 573 10/9/2021
1.0.78 1,957 10/7/2021
1.0.77 2,158 10/7/2021
1.0.76 571 10/7/2021
1.0.75 607 10/6/2021
1.0.74 661 9/28/2021
1.0.73 2,369 9/23/2021
1.0.72 708 9/11/2021
1.0.71 609 9/10/2021
1.0.70 677 9/9/2021
1.0.69 576 9/8/2021
1.0.68 636 9/8/2021
1.0.67 2,161 9/6/2021
1.0.66 709 8/31/2021
1.0.65 568 8/30/2021
1.0.64 2,617 7/31/2021
1.0.63 3,050 7/30/2021
1.0.62 688 7/26/2021
1.0.61 4,486 7/5/2021
1.0.60 644 7/1/2021
1.0.59 3,827 6/4/2021
1.0.58 5,078 4/26/2021
1.0.57 2,188 4/19/2021
1.0.56 5,730 4/8/2021
1.0.55 1,811 4/7/2021
1.0.54 624 4/7/2021
1.0.53 1,891 4/3/2021
1.0.52 7,989 3/22/2021
1.0.51 5,778 3/4/2021
1.0.50 2,165 2/26/2021
1.0.49 8,282 2/2/2021
1.0.48 3,235 1/26/2021
1.0.47 3,005 1/24/2021
1.0.46 664 1/24/2021
1.0.45 719 1/23/2021
1.0.44 3,906 1/20/2021
1.0.43 721 1/20/2021
1.0.42 2,091 1/18/2021
1.0.41 636 1/18/2021
1.0.40 2,068 1/16/2021
1.0.39 6,320 12/17/2020
1.0.38 700 12/16/2020
1.0.37 3,222 12/14/2020
1.0.36 2,130 12/9/2020
1.0.35 681 12/9/2020
1.0.34 690 12/7/2020
1.0.33 792 12/6/2020
1.0.32 744 12/2/2020
1.0.31 714 12/2/2020
1.0.30 2,212 12/1/2020
1.0.29 7,373 11/12/2020
1.0.29-atestpub 567 11/11/2020
1.0.28 3,346 10/11/2020
1.0.27 8,622 9/9/2020
1.0.26 2,633 9/3/2020
1.0.25 2,695 8/20/2020
1.0.24 6,165 8/9/2020
1.0.23 2,711 7/28/2020
1.0.22 2,651 7/19/2020
1.0.21 4,463 7/6/2020
1.0.20 6,633 6/6/2020
1.0.19 2,624 6/4/2020
1.0.18 4,389 5/29/2020
1.0.17 4,429 5/21/2020
1.0.16 770 5/17/2020
1.0.15 4,526 5/12/2020
1.0.14 8,246 5/4/2020
1.0.13 793 4/24/2020
1.0.12 775 4/22/2020
1.0.11 761 4/22/2020
1.0.10 782 4/21/2020
1.0.9 3,232 4/18/2020
1.0.8 2,585 4/16/2020
1.0.7 789 4/16/2020
1.0.6 2,260 4/15/2020
1.0.5 2,673 4/11/2020
1.0.4 2,565 4/3/2020
1.0.3 783 4/1/2020
1.0.2 2,494 3/27/2020
1.0.1 2,610 3/22/2020
1.0.0 896 3/22/2020