Ecng.Net.SocketIO 1.0.504

dotnet add package Ecng.Net.SocketIO --version 1.0.504
                    
NuGet\Install-Package Ecng.Net.SocketIO -Version 1.0.504
                    
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.504" />
                    
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.504" />
                    
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.504
                    
#r "nuget: Ecng.Net.SocketIO, 1.0.504"
                    
#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.504
                    
#: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.504
                    
Install as a Cake Addin
#tool nuget:?package=Ecng.Net.SocketIO&version=1.0.504
                    
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.504 0 1/4/2026
1.0.503 54 1/1/2026
1.0.502 63 12/31/2025
1.0.501 83 12/30/2025
1.0.500 77 12/30/2025
1.0.499 90 12/29/2025
1.0.498 86 12/29/2025
1.0.497 92 12/26/2025
1.0.496 84 12/26/2025
1.0.495 81 12/26/2025
1.0.494 102 12/26/2025
1.0.493 173 12/25/2025
1.0.492 177 12/25/2025
1.0.491 183 12/24/2025
1.0.490 178 12/23/2025
1.0.489 170 12/22/2025
1.0.488 167 12/22/2025
1.0.487 175 12/22/2025
1.0.486 160 12/21/2025
1.0.485 217 12/19/2025
1.0.484 236 12/19/2025
1.0.483 280 12/18/2025
1.0.482 281 12/17/2025
1.0.481 278 12/15/2025
1.0.480 252 12/15/2025
1.0.479 227 12/14/2025
1.0.478 158 12/14/2025
1.0.477 160 12/13/2025
1.0.476 171 12/13/2025
1.0.475 139 12/12/2025
1.0.474 123 12/12/2025
1.0.473 117 12/12/2025
1.0.472 120 12/12/2025
1.0.471 114 12/12/2025
1.0.470 120 12/12/2025
1.0.469 120 12/12/2025
1.0.468 724 12/2/2025
1.0.467 679 12/2/2025
1.0.466 675 12/2/2025
1.0.465 274 11/30/2025
1.0.464 144 11/29/2025
1.0.463 141 11/28/2025
1.0.462 146 11/28/2025
1.0.461 191 11/27/2025
1.0.460 232 11/24/2025
1.0.459 201 11/24/2025
1.0.458 196 11/23/2025
1.0.457 172 11/23/2025
1.0.456 225 11/22/2025
1.0.455 438 11/20/2025
1.0.454 411 11/20/2025
1.0.453 410 11/20/2025
1.0.452 433 11/18/2025
1.0.451 413 11/18/2025
1.0.450 341 11/13/2025
1.0.449 277 11/10/2025
1.0.448 1,099 11/1/2025
1.0.447 207 10/31/2025
1.0.446 217 10/28/2025
1.0.445 323 10/27/2025
1.0.444 205 10/27/2025
1.0.443 134 10/25/2025
1.0.442 160 10/24/2025
1.0.441 272 10/20/2025
1.0.440 306 10/12/2025
1.0.439 155 10/11/2025
1.0.438 294 10/7/2025
1.0.437 234 10/6/2025
1.0.436 275 10/3/2025
1.0.435 247 10/1/2025
1.0.434 214 10/1/2025
1.0.433 214 9/30/2025
1.0.432 216 9/28/2025
1.0.431 232 9/25/2025
1.0.430 3,060 9/5/2025
1.0.429 246 9/2/2025
1.0.428 601 8/30/2025
1.0.427 268 8/30/2025
1.0.426 272 8/20/2025
1.0.425 215 8/20/2025
1.0.424 227 8/19/2025
1.0.423 236 8/15/2025
1.0.422 327 8/10/2025
1.0.421 1,052 7/16/2025
1.0.420 283 7/14/2025
1.0.419 255 7/13/2025
1.0.418 229 7/13/2025
1.0.417 207 7/12/2025
1.0.416 691 7/8/2025
1.0.415 265 7/4/2025
1.0.414 263 7/2/2025
1.0.413 427 6/24/2025
1.0.412 1,035 6/16/2025
1.0.411 415 6/9/2025
1.0.410 293 6/8/2025
1.0.409 619 5/21/2025
1.0.408 265 5/21/2025
1.0.407 253 5/17/2025
1.0.406 655 5/12/2025
1.0.405 350 5/12/2025
1.0.404 319 5/12/2025
1.0.403 241 5/11/2025
1.0.402 252 5/11/2025
1.0.401 207 5/10/2025
1.0.400 170 5/10/2025
1.0.399 288 5/6/2025
1.0.398 221 5/3/2025
1.0.397 387 4/17/2025
1.0.396 337 4/15/2025
1.0.395 236 4/12/2025
1.0.394 310 4/9/2025
1.0.393 269 4/6/2025
1.0.392 221 4/5/2025
1.0.391 1,097 3/22/2025
1.0.390 290 3/20/2025
1.0.389 283 3/20/2025
1.0.388 270 3/19/2025
1.0.387 839 2/26/2025
1.0.386 247 2/26/2025
1.0.385 769 2/8/2025
1.0.384 254 2/8/2025
1.0.383 225 2/8/2025
1.0.382 227 2/6/2025
1.0.381 218 2/6/2025
1.0.380 236 2/6/2025
1.0.379 240 2/6/2025
1.0.378 217 2/6/2025
1.0.377 218 2/5/2025
1.0.376 224 2/5/2025
1.0.375 242 2/5/2025
1.0.374 264 2/3/2025
1.0.373 246 2/2/2025
1.0.372 265 2/1/2025
1.0.371 247 1/31/2025
1.0.370 251 1/30/2025
1.0.369 232 1/26/2025
1.0.368 267 1/21/2025
1.0.367 254 1/20/2025
1.0.366 220 1/20/2025
1.0.365 234 1/19/2025
1.0.364 221 1/19/2025
1.0.363 248 1/15/2025
1.0.362 219 1/15/2025
1.0.361 212 1/14/2025
1.0.360 205 1/12/2025
1.0.359 195 1/12/2025
1.0.358 209 1/12/2025
1.0.357 181 1/12/2025
1.0.356 229 1/10/2025
1.0.355 1,067 12/30/2024
1.0.354 255 12/27/2024
1.0.353 279 12/19/2024
1.0.352 739 11/20/2024
1.0.351 254 11/19/2024
1.0.350 236 11/19/2024
1.0.349 796 11/18/2024
1.0.348 470 11/15/2024
1.0.347 223 11/14/2024
1.0.346 245 11/14/2024
1.0.345 250 11/14/2024
1.0.344 203 11/14/2024
1.0.343 227 11/14/2024
1.0.342 268 11/7/2024
1.0.341 280 10/31/2024
1.0.340 336 10/20/2024
1.0.339 261 10/20/2024
1.0.338 273 10/20/2024
1.0.337 268 10/19/2024
1.0.336 277 10/19/2024
1.0.335 278 10/19/2024
1.0.334 277 10/19/2024
1.0.333 273 10/19/2024
1.0.332 255 10/19/2024
1.0.331 282 10/19/2024
1.0.330 311 10/18/2024
1.0.329 269 10/17/2024
1.0.328 230 10/17/2024
1.0.327 248 10/17/2024
1.0.326 806 10/14/2024
1.0.325 233 10/13/2024
1.0.324 231 10/13/2024
1.0.323 251 10/12/2024
1.0.322 445 10/9/2024
1.0.321 252 10/9/2024
1.0.320 447 10/5/2024
1.0.319 776 9/18/2024
1.0.318 234 9/18/2024
1.0.317 254 9/18/2024
1.0.316 248 9/17/2024
1.0.315 745 9/3/2024
1.0.314 293 9/1/2024
1.0.313 962 8/9/2024
1.0.312 251 8/9/2024
1.0.311 272 8/8/2024
1.0.310 708 7/25/2024
1.0.309 267 7/23/2024
1.0.308 292 7/17/2024
1.0.307 557 7/4/2024
1.0.306 619 6/12/2024
1.0.305 259 6/12/2024
1.0.304 256 6/12/2024
1.0.303 450 5/28/2024
1.0.302 615 5/4/2024
1.0.301 406 4/23/2024
1.0.300 270 4/21/2024
1.0.299 297 4/14/2024
1.0.298 565 3/28/2024
1.0.297 334 3/17/2024
1.0.296 539 3/9/2024
1.0.295 355 2/23/2024
1.0.294 285 2/23/2024
1.0.293 496 2/18/2024
1.0.292 285 2/18/2024
1.0.291 259 2/17/2024
1.0.290 277 2/16/2024
1.0.289 397 2/14/2024
1.0.288 277 2/13/2024
1.0.287 349 2/8/2024
1.0.286 352 2/5/2024
1.0.285 270 2/4/2024
1.0.284 441 1/23/2024
1.0.283 259 1/23/2024
1.0.282 327 1/12/2024
1.0.281 695 1/2/2024
1.0.280 311 12/29/2023
1.0.279 360 12/17/2023
1.0.278 518 12/15/2023
1.0.277 288 12/15/2023
1.0.276 268 12/15/2023
1.0.275 300 12/13/2023
1.0.274 296 12/13/2023
1.0.273 303 12/10/2023
1.0.272 684 11/18/2023
1.0.271 228 11/18/2023
1.0.270 255 11/18/2023
1.0.269 237 11/17/2023
1.0.268 213 11/12/2023
1.0.267 211 11/12/2023
1.0.266 232 11/10/2023
1.0.265 197 11/10/2023
1.0.264 238 11/9/2023
1.0.263 198 11/9/2023
1.0.262 216 11/9/2023
1.0.261 241 11/3/2023
1.0.260 228 11/1/2023
1.0.259 210 11/1/2023
1.0.258 1,475 9/8/2023
1.0.257 267 9/8/2023
1.0.256 285 9/3/2023
1.0.255 350 8/27/2023
1.0.254 278 8/24/2023
1.0.253 243 8/21/2023
1.0.252 319 8/15/2023
1.0.251 288 8/14/2023
1.0.250 267 8/14/2023
1.0.249 298 8/10/2023
1.0.248 1,016 7/29/2023
1.0.247 1,092 7/1/2023
1.0.246 309 6/29/2023
1.0.245 800 5/27/2023
1.0.244 353 5/21/2023
1.0.243 296 5/19/2023
1.0.242 1,082 5/8/2023
1.0.241 355 5/7/2023
1.0.240 342 5/7/2023
1.0.239 319 5/7/2023
1.0.238 368 5/1/2023
1.0.237 412 4/22/2023
1.0.236 373 4/21/2023
1.0.235 339 4/21/2023
1.0.234 1,234 4/13/2023
1.0.233 1,135 4/3/2023
1.0.232 488 3/27/2023
1.0.231 433 3/21/2023
1.0.230 436 3/17/2023
1.0.229 427 3/13/2023
1.0.228 1,186 3/6/2023
1.0.227 497 2/26/2023
1.0.226 940 2/21/2023
1.0.225 456 2/20/2023
1.0.224 471 2/16/2023
1.0.223 456 2/15/2023
1.0.222 432 2/14/2023
1.0.221 428 2/14/2023
1.0.220 1,357 2/9/2023
1.0.219 833 2/7/2023
1.0.218 486 2/4/2023
1.0.217 469 2/4/2023
1.0.216 483 2/3/2023
1.0.215 446 2/3/2023
1.0.214 443 2/3/2023
1.0.213 886 2/2/2023
1.0.212 832 1/30/2023
1.0.211 467 1/30/2023
1.0.210 510 1/25/2023
1.0.209 504 1/23/2023
1.0.208 456 1/23/2023
1.0.207 490 1/18/2023
1.0.206 516 1/15/2023
1.0.205 515 1/6/2023
1.0.204 1,418 1/1/2023
1.0.203 482 12/31/2022
1.0.202 971 12/30/2022
1.0.201 501 12/29/2022
1.0.200 511 12/23/2022
1.0.199 1,390 12/12/2022
1.0.198 1,073 12/8/2022
1.0.197 489 12/4/2022
1.0.196 491 12/4/2022
1.0.195 493 12/2/2022
1.0.194 517 11/30/2022
1.0.193 481 11/29/2022
1.0.192 477 11/28/2022
1.0.191 518 11/26/2022
1.0.190 516 11/26/2022
1.0.189 517 11/25/2022
1.0.188 514 11/25/2022
1.0.187 529 11/18/2022
1.0.186 1,596 11/11/2022
1.0.185 552 11/11/2022
1.0.184 510 11/10/2022
1.0.183 574 11/5/2022
1.0.182 551 11/4/2022
1.0.181 532 11/2/2022
1.0.180 524 11/2/2022
1.0.179 1,435 11/1/2022
1.0.178 1,657 10/16/2022
1.0.177 742 9/25/2022
1.0.176 670 9/10/2022
1.0.175 2,982 9/8/2022
1.0.174 654 9/8/2022
1.0.173 662 9/8/2022
1.0.172 635 9/4/2022
1.0.171 635 9/4/2022
1.0.170 5,357 8/24/2022
1.0.169 717 8/8/2022
1.0.168 639 8/8/2022
1.0.167 1,270 7/31/2022
1.0.166 657 7/31/2022
1.0.165 669 7/26/2022
1.0.164 634 7/26/2022
1.0.163 3,202 7/21/2022
1.0.162 690 7/19/2022
1.0.161 3,159 7/18/2022
1.0.160 694 7/13/2022
1.0.159 676 7/8/2022
1.0.158 696 6/30/2022
1.0.157 710 6/20/2022
1.0.156 660 6/18/2022
1.0.155 702 6/6/2022
1.0.154 749 5/27/2022
1.0.153 5,214 4/30/2022
1.0.152 688 4/20/2022
1.0.151 718 4/10/2022
1.0.150 683 4/7/2022
1.0.149 667 4/7/2022
1.0.148 721 4/2/2022
1.0.147 680 3/29/2022
1.0.146 670 3/27/2022
1.0.145 671 3/27/2022
1.0.144 3,922 3/24/2022
1.0.143 2,687 2/20/2022
1.0.142 649 2/20/2022
1.0.141 658 2/20/2022
1.0.140 689 2/20/2022
1.0.139 703 2/20/2022
1.0.138 669 2/20/2022
1.0.137 662 2/20/2022
1.0.136 680 2/20/2022
1.0.135 684 2/20/2022
1.0.134 673 2/19/2022
1.0.133 4,570 2/10/2022
1.0.132 782 1/27/2022
1.0.131 708 1/27/2022
1.0.130 3,571 1/24/2022
1.0.129 655 1/24/2022
1.0.128 694 1/23/2022
1.0.127 7,022 12/29/2021
1.0.126 545 12/27/2021
1.0.125 488 12/27/2021
1.0.124 507 12/27/2021
1.0.123 1,767 12/20/2021
1.0.122 550 12/17/2021
1.0.121 541 12/16/2021
1.0.120 524 12/15/2021
1.0.119 513 12/14/2021
1.0.118 536 12/14/2021
1.0.117 494 12/13/2021
1.0.116 655 12/12/2021
1.0.115 1,634 12/10/2021
1.0.114 545 12/7/2021
1.0.113 545 12/7/2021
1.0.112 1,977 12/6/2021
1.0.111 543 12/6/2021
1.0.110 544 12/5/2021
1.0.109 1,239 12/3/2021
1.0.108 1,044 12/3/2021
1.0.107 578 12/2/2021
1.0.106 2,459 11/29/2021
1.0.105 5,271 11/23/2021
1.0.104 534 11/23/2021
1.0.103 1,617 11/22/2021
1.0.102 626 11/17/2021
1.0.101 582 11/14/2021
1.0.100 1,747 11/13/2021
1.0.99 597 11/11/2021
1.0.98 580 11/11/2021
1.0.97 563 11/10/2021
1.0.96 572 11/9/2021
1.0.95 2,602 11/6/2021
1.0.94 608 11/6/2021
1.0.93 2,172 11/5/2021
1.0.92 631 11/5/2021
1.0.91 592 11/4/2021
1.0.90 564 11/4/2021
1.0.89 619 11/3/2021
1.0.88 686 10/30/2021
1.0.87 2,051 10/21/2021
1.0.86 656 10/17/2021
1.0.85 666 10/17/2021
1.0.84 3,052 10/14/2021
1.0.83 590 10/13/2021
1.0.82 609 10/13/2021
1.0.81 588 10/12/2021
1.0.80 2,142 10/11/2021
1.0.79 572 10/9/2021
1.0.78 1,954 10/7/2021
1.0.77 2,157 10/7/2021
1.0.76 570 10/7/2021
1.0.75 602 10/6/2021
1.0.74 658 9/28/2021
1.0.73 2,368 9/23/2021
1.0.72 707 9/11/2021
1.0.71 607 9/10/2021
1.0.70 672 9/9/2021
1.0.69 575 9/8/2021
1.0.68 634 9/8/2021
1.0.67 2,159 9/6/2021
1.0.66 706 8/31/2021
1.0.65 566 8/30/2021
1.0.64 2,615 7/31/2021
1.0.63 3,046 7/30/2021
1.0.62 687 7/26/2021
1.0.61 4,485 7/5/2021
1.0.60 643 7/1/2021
1.0.59 3,823 6/4/2021
1.0.58 5,075 4/26/2021
1.0.57 2,186 4/19/2021
1.0.56 5,726 4/8/2021
1.0.55 1,809 4/7/2021
1.0.54 621 4/7/2021
1.0.53 1,888 4/3/2021
1.0.52 7,988 3/22/2021
1.0.51 5,775 3/4/2021
1.0.50 2,164 2/26/2021
1.0.49 8,280 2/2/2021
1.0.48 3,232 1/26/2021
1.0.47 3,002 1/24/2021
1.0.46 662 1/24/2021
1.0.45 716 1/23/2021
1.0.44 3,903 1/20/2021
1.0.43 718 1/20/2021
1.0.42 2,089 1/18/2021
1.0.41 633 1/18/2021
1.0.40 2,066 1/16/2021
1.0.39 6,316 12/17/2020
1.0.38 698 12/16/2020
1.0.37 3,216 12/14/2020
1.0.36 2,126 12/9/2020
1.0.35 678 12/9/2020
1.0.34 686 12/7/2020
1.0.33 791 12/6/2020
1.0.32 741 12/2/2020
1.0.31 711 12/2/2020
1.0.30 2,207 12/1/2020
1.0.29 7,367 11/12/2020
1.0.29-atestpub 566 11/11/2020
1.0.28 3,342 10/11/2020
1.0.27 8,620 9/9/2020
1.0.26 2,631 9/3/2020
1.0.25 2,690 8/20/2020
1.0.24 6,162 8/9/2020
1.0.23 2,710 7/28/2020
1.0.22 2,648 7/19/2020
1.0.21 4,458 7/6/2020
1.0.20 6,631 6/6/2020
1.0.19 2,620 6/4/2020
1.0.18 4,386 5/29/2020
1.0.17 4,428 5/21/2020
1.0.16 769 5/17/2020
1.0.15 4,525 5/12/2020
1.0.14 8,243 5/4/2020
1.0.13 791 4/24/2020
1.0.12 772 4/22/2020
1.0.11 757 4/22/2020
1.0.10 778 4/21/2020
1.0.9 3,231 4/18/2020
1.0.8 2,582 4/16/2020
1.0.7 785 4/16/2020
1.0.6 2,256 4/15/2020
1.0.5 2,671 4/11/2020
1.0.4 2,562 4/3/2020
1.0.3 779 4/1/2020
1.0.2 2,492 3/27/2020
1.0.1 2,608 3/22/2020
1.0.0 894 3/22/2020