I-Synergy.Framework.AspNetCore.Authentication 2026.10110.10203

Prefix Reserved
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package I-Synergy.Framework.AspNetCore.Authentication --version 2026.10110.10203
                    
NuGet\Install-Package I-Synergy.Framework.AspNetCore.Authentication -Version 2026.10110.10203
                    
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="I-Synergy.Framework.AspNetCore.Authentication" Version="2026.10110.10203" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="I-Synergy.Framework.AspNetCore.Authentication" Version="2026.10110.10203" />
                    
Directory.Packages.props
<PackageReference Include="I-Synergy.Framework.AspNetCore.Authentication" />
                    
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 I-Synergy.Framework.AspNetCore.Authentication --version 2026.10110.10203
                    
#r "nuget: I-Synergy.Framework.AspNetCore.Authentication, 2026.10110.10203"
                    
#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 I-Synergy.Framework.AspNetCore.Authentication@2026.10110.10203
                    
#: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=I-Synergy.Framework.AspNetCore.Authentication&version=2026.10110.10203
                    
Install as a Cake Addin
#tool nuget:?package=I-Synergy.Framework.AspNetCore.Authentication&version=2026.10110.10203
                    
Install as a Cake Tool

I-Synergy Framework AspNetCore Authentication

Authentication and identity management extensions for ASP.NET Core applications. This package provides JWT token handling, claims-based authorization utilities, custom password validation, and integration with OpenIddict for OAuth 2.0/OpenID Connect workflows.

NuGet License .NET

Features

  • JWT token configuration with symmetric key support for secure authentication
  • Claims-based authorization with rich extension methods for ClaimsPrincipal
  • Custom password validation with regex pattern support
  • OpenIddict integration for OAuth 2.0 and OpenID Connect
  • Type-safe claim retrieval with automatic type conversion
  • Exception handling for authentication failures via filter attributes
  • Identity options with enhanced password policy enforcement
  • Extension methods for retrieving user identity, account, tenant, and client information

Installation

Install the package via NuGet:

dotnet add package I-Synergy.Framework.AspNetCore.Authentication

Quick Start

1. Configure JWT Authentication

In your Program.cs:

using ISynergy.Framework.AspNetCore.Authentication.Options;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;

var builder = WebApplication.CreateBuilder(args);

// Configure JWT options
builder.Services.Configure<JwtOptions>(
    builder.Configuration.GetSection(nameof(JwtOptions)));

var jwtOptions = builder.Configuration
    .GetSection(nameof(JwtOptions))
    .Get<JwtOptions>();

// Add JWT authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = jwtOptions.Issuer,
            ValidAudience = jwtOptions.Audience,
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(jwtOptions.SymmetricKeySecret))
        };
    });

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();

app.Run();

2. Configure JWT Options in appsettings.json

{
  "JwtOptions": {
    "SymmetricKeySecret": "your-secret-key-minimum-32-characters-long",
    "Issuer": "https://your-api.com",
    "Audience": "https://your-app.com"
  }
}

3. Using Claims Extensions

Retrieve user information from ClaimsPrincipal:

using ISynergy.Framework.Core.Extensions;
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
[Authorize]
public class UserController : ControllerBase
{
    [HttpGet("profile")]
    public IActionResult GetProfile()
    {
        // Get user ID from claims
        var userId = User.GetUserId();

        // Get username
        var username = User.GetUserName();

        // Get account ID (tenant identifier)
        var accountId = User.GetAccountId();

        // Get client ID
        var clientId = User.GetClientId();

        return Ok(new
        {
            UserId = userId,
            Username = username,
            AccountId = accountId,
            ClientId = clientId
        });
    }

    [HttpGet("claims")]
    public IActionResult GetClaims()
    {
        // Get single claim value
        var email = User.GetSingleClaim("email");

        // Get multiple claims
        var roles = User.GetClaims("role");

        // Get claim as specific type
        var age = User.GetSingleClaimAsInt("age");

        // Get claim as enum
        var status = User.GetSingleClaimAsEnum<UserStatus>("status");

        // Check if claim exists
        bool hasEmail = User.HasClaim("email");

        return Ok(new
        {
            Email = email,
            Roles = roles,
            Age = age,
            Status = status,
            HasEmail = hasEmail
        });
    }
}

4. Custom Password Validation

Configure enhanced password validation with regex patterns:

using ISynergy.Framework.AspNetCore.Authentication.Options;
using ISynergy.Framework.AspNetCore.Authentication.Validators;
using Microsoft.AspNetCore.Identity;
using System.Text.RegularExpressions;

var builder = WebApplication.CreateBuilder(args);

// Configure password options
builder.Services.Configure<IdentityPasswordOptions>(options =>
{
    options.RequiredLength = 8;
    options.RequireDigit = true;
    options.RequireLowercase = true;
    options.RequireUppercase = true;
    options.RequireNonAlphanumeric = true;
    options.RequiredUniqueChars = 4;

    // Custom regex pattern for additional validation
    // Example: Require at least one special character from a specific set
    options.RequiredRegexMatch = new Regex(@"^(?=.*[!@#$%^&*])");
});

// Add Identity with custom password validator
builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddPasswordValidator<IdentityPasswordValidator<ApplicationUser>>();

5. OpenIddict Integration

Using claims with OpenIddict authentication:

using ISynergy.Framework.Core.Extensions;
using Microsoft.AspNetCore.Mvc;
using static OpenIddict.Abstractions.OpenIddictConstants;

[ApiController]
[Route("api/[controller]")]
[Authorize(AuthenticationSchemes = "OpenIddict.Validation.AspNetCore")]
public class SecureController : ControllerBase
{
    [HttpGet("info")]
    public IActionResult GetUserInfo()
    {
        // Claims are automatically extracted from OpenIddict tokens
        var userId = User.GetUserId();        // Gets Claims.Subject
        var username = User.GetUserName();    // Gets Claims.Username
        var accountId = User.GetAccountId();  // Gets Claims.KeyId
        var clientId = User.GetClientId();    // Gets Claims.ClientId

        return Ok(new
        {
            UserId = userId,
            Username = username,
            AccountId = accountId,
            ClientId = clientId
        });
    }
}

Core Components

Options

ISynergy.Framework.AspNetCore.Authentication.Options/
├── JwtOptions                      # JWT configuration (issuer, audience, secret)
└── IdentityPasswordOptions         # Enhanced password validation with regex

Extensions

ISynergy.Framework.Core.Extensions/
└── ClaimsPrincipalExtensions       # Claims retrieval and conversion utilities

Validators

ISynergy.Framework.AspNetCore.Authentication.Validators/
└── IdentityPasswordValidator<T>    # Custom password validator with regex support

Exception Filters

ISynergy.Framework.AspNetCore.Authentication.Exceptions/
└── ClaimNotFoundExceptionFilterAttribute  # Handle missing claims gracefully

Advanced Features

Type-Safe Claim Retrieval

using ISynergy.Framework.Core.Extensions;

public class ClaimsExample
{
    public void ProcessUserClaims(ClaimsPrincipal user)
    {
        // Get single claim as string
        var email = user.GetSingleClaim("email");

        // Get single claim as int
        var userId = user.GetSingleClaimAsInt("user_id");

        // Get single claim as Guid
        var tenantId = user.GetSingleClaimAsGuid("tenant_id");

        // Get single claim as enum
        var role = user.GetSingleClaimAsEnum<UserRole>("role");

        // Get multiple claims as list
        var permissions = user.GetClaims("permission");

        // Get multiple claims as int list
        var groupIds = user.GetClaimsAsInt("group_id");

        // Get multiple claims as enum list
        var scopes = user.GetClaimsAsEnum<AccessScope>("scope");
    }
}

public enum UserRole
{
    User,
    Admin,
    SuperAdmin
}

public enum AccessScope
{
    Read,
    Write,
    Delete
}

Exception Handling for Missing Claims

using ISynergy.Framework.Core.Exceptions;
using ISynergy.Framework.Core.Extensions;

public class SecureService
{
    public string GetUserEmail(ClaimsPrincipal user)
    {
        try
        {
            // Throws ClaimNotFoundException if claim doesn't exist
            return user.GetSingleClaim("email");
        }
        catch (ClaimNotFoundException ex)
        {
            // Handle missing claim
            throw new UnauthorizedAccessException($"Missing required claim: {ex.Message}");
        }
        catch (DuplicateClaimException ex)
        {
            // Handle duplicate claims
            throw new InvalidOperationException($"Duplicate claim found: {ex.Message}");
        }
        catch (InvalidClaimValueException ex)
        {
            // Handle invalid claim value (type conversion failed)
            throw new ArgumentException($"Invalid claim value: {ex.Message}");
        }
    }

    public bool TryGetUserEmail(ClaimsPrincipal user, out string email)
    {
        email = string.Empty;

        // Safe check without throwing
        if (!user.HasClaim("email"))
            return false;

        try
        {
            email = user.GetSingleClaim("email");
            return true;
        }
        catch
        {
            return false;
        }
    }
}

Custom Password Validation Patterns

using ISynergy.Framework.AspNetCore.Authentication.Options;
using System.Text.RegularExpressions;

// Example 1: Require at least one special character
var options1 = new IdentityPasswordOptions
{
    RequiredLength = 8,
    RequireDigit = true,
    RequiredRegexMatch = new Regex(@"^(?=.*[!@#$%^&*(),.?""{}|<>])")
};

// Example 2: Prevent common password patterns
var options2 = new IdentityPasswordOptions
{
    RequiredLength = 10,
    RequiredRegexMatch = new Regex(@"^(?!.*(?:password|123456|qwerty))",
        RegexOptions.IgnoreCase)
};

// Example 3: Require specific character sets
var options3 = new IdentityPasswordOptions
{
    RequiredLength = 12,
    RequiredRegexMatch = new Regex(
        @"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&#])[A-Za-z\d@$!%*?&#]")
};

// Example 4: Maximum length restriction
var options4 = new IdentityPasswordOptions
{
    RequiredLength = 8,
    RequiredRegexMatch = new Regex(@"^.{8,50}$")
};

Usage Examples

Building a Secure API with JWT

Complete example of a secure Web API:

using ISynergy.Framework.AspNetCore.Authentication.Options;
using ISynergy.Framework.Core.Extensions;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

var builder = WebApplication.CreateBuilder(args);

// Configure JWT
var jwtOptions = builder.Configuration
    .GetSection(nameof(JwtOptions))
    .Get<JwtOptions>();

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = jwtOptions.Issuer,
            ValidAudience = jwtOptions.Audience,
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(jwtOptions.SymmetricKeySecret)),
            ClockSkew = TimeSpan.Zero
        };
    });

builder.Services.AddAuthorization();
builder.Services.AddControllers();

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();

app.Run();

[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
    private readonly JwtOptions _jwtOptions;

    public AuthController(IOptions<JwtOptions> jwtOptions)
    {
        _jwtOptions = jwtOptions.Value;
    }

    [HttpPost("login")]
    public IActionResult Login([FromBody] LoginRequest request)
    {
        // Validate credentials (implement your own logic)
        if (!ValidateCredentials(request.Username, request.Password))
            return Unauthorized();

        // Create claims
        var claims = new[]
        {
            new Claim(Claims.Subject, request.UserId),
            new Claim(Claims.Username, request.Username),
            new Claim(Claims.KeyId, request.AccountId.ToString()),
            new Claim(Claims.ClientId, "web-app"),
            new Claim("email", request.Email),
            new Claim("role", "User")
        };

        // Generate token
        var key = new SymmetricSecurityKey(
            Encoding.UTF8.GetBytes(_jwtOptions.SymmetricKeySecret));
        var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

        var token = new JwtSecurityToken(
            issuer: _jwtOptions.Issuer,
            audience: _jwtOptions.Audience,
            claims: claims,
            expires: DateTime.UtcNow.AddHours(1),
            signingCredentials: credentials);

        var tokenString = new JwtSecurityTokenHandler().WriteToken(token);

        return Ok(new { Token = tokenString });
    }

    [HttpGet("profile")]
    [Authorize]
    public IActionResult GetProfile()
    {
        return Ok(new
        {
            UserId = User.GetUserId(),
            Username = User.GetUserName(),
            AccountId = User.GetAccountId(),
            Email = User.GetSingleClaim("email"),
            Roles = User.GetClaims("role")
        });
    }
}

public record LoginRequest(
    string UserId,
    string Username,
    string Password,
    string Email,
    Guid AccountId);

Multi-Tenant Authentication

using ISynergy.Framework.Core.Extensions;
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/tenants/{tenantId}/[controller]")]
[Authorize]
public class TenantDataController : ControllerBase
{
    [HttpGet]
    public IActionResult GetData([FromRoute] Guid tenantId)
    {
        // Verify user belongs to this tenant
        var userTenantId = User.GetAccountId();

        if (userTenantId != tenantId)
            return Forbid();

        // Retrieve tenant-specific data
        var data = GetTenantData(tenantId);

        return Ok(data);
    }

    [HttpPost]
    public IActionResult CreateData([FromRoute] Guid tenantId, [FromBody] DataModel data)
    {
        var userTenantId = User.GetAccountId();

        if (userTenantId != tenantId)
            return Forbid();

        // Create tenant-specific data
        data.TenantId = tenantId;
        data.CreatedBy = User.GetUserId();

        SaveData(data);

        return CreatedAtAction(nameof(GetData), new { tenantId }, data);
    }
}

Best Practices

Store JWT secrets securely using Azure Key Vault or environment variables instead of hardcoding them in configuration files.

Use HTTPS in production to protect JWT tokens from interception during transmission.

Set appropriate token expiration times based on your security requirements. Shorter lifetimes are more secure but may impact user experience.

JWT Configuration

  • Use strong symmetric keys (minimum 32 characters, 256 bits)
  • Set appropriate token expiration times (1-24 hours typical)
  • Use refresh tokens for long-lived sessions
  • Validate issuer and audience to prevent token reuse
  • Set ClockSkew to minimize timing vulnerabilities
  • Rotate signing keys periodically

Claims Management

  • Use standard OpenID Connect claim types when possible
  • Keep claim payloads minimal to reduce token size
  • Don't store sensitive data in claims (they're not encrypted)
  • Validate claim values before using them
  • Use type-safe claim retrieval methods
  • Handle missing or invalid claims gracefully

Password Validation

  • Combine standard password options with regex validation
  • Test regex patterns thoroughly before deployment
  • Provide clear error messages for validation failures
  • Consider using passphrases instead of complex passwords
  • Implement password history to prevent reuse
  • Use password strength meters in UI

Security Considerations

  • Never log or expose JWT tokens in error messages
  • Implement token revocation for logout scenarios
  • Use HTTPS everywhere to protect tokens in transit
  • Implement rate limiting on authentication endpoints
  • Monitor for suspicious authentication patterns
  • Use role-based and claim-based authorization together

Testing

Example unit tests for authentication components:

using ISynergy.Framework.Core.Extensions;
using System.Security.Claims;
using Xunit;

public class ClaimsExtensionsTests
{
    [Fact]
    public void GetUserId_WithValidClaim_ReturnsUserId()
    {
        // Arrange
        var claims = new[]
        {
            new Claim(Claims.Subject, "user-123")
        };
        var identity = new ClaimsIdentity(claims);
        var principal = new ClaimsPrincipal(identity);

        // Act
        var userId = principal.GetUserId();

        // Assert
        Assert.Equal("user-123", userId);
    }

    [Fact]
    public void GetAccountId_WithValidClaim_ReturnsGuid()
    {
        // Arrange
        var accountId = Guid.NewGuid();
        var claims = new[]
        {
            new Claim(Claims.KeyId, accountId.ToString())
        };
        var identity = new ClaimsIdentity(claims);
        var principal = new ClaimsPrincipal(identity);

        // Act
        var result = principal.GetAccountId();

        // Assert
        Assert.Equal(accountId, result);
    }

    [Fact]
    public void HasClaim_WithExistingClaim_ReturnsTrue()
    {
        // Arrange
        var claims = new[]
        {
            new Claim("email", "test@example.com")
        };
        var identity = new ClaimsIdentity(claims);
        var principal = new ClaimsPrincipal(identity);

        // Act
        var result = principal.HasClaim("email");

        // Assert
        Assert.True(result);
    }
}

Dependencies

  • Microsoft.AspNetCore.Authentication.JwtBearer - JWT authentication support
  • Microsoft.AspNetCore.Identity - Identity framework integration
  • OpenIddict.Abstractions - OAuth 2.0/OpenID Connect abstractions
  • ISynergy.Framework.Core - Core framework utilities

Documentation

For more information about the I-Synergy Framework:

  • I-Synergy.Framework.Core - Core framework components
  • I-Synergy.Framework.AspNetCore - Base ASP.NET Core integration
  • I-Synergy.Framework.AspNetCore.MultiTenancy - Multi-tenant support
  • I-Synergy.Framework.AspNetCore.Monitoring - SignalR monitoring
  • I-Synergy.Framework.EntityFramework - Data persistence

Support

For issues, questions, or contributions, please visit the GitHub repository.

Product Compatible and additional computed target framework versions.
.NET 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 (3)

Showing the top 3 NuGet packages that depend on I-Synergy.Framework.AspNetCore.Authentication:

Package Downloads
I-Synergy.Framework.AspNetCore.MultiTenancy

I-Synergy Framework MultiTenancy

I-Synergy.Framework.Monitoring.SignalR

I-Synergy Framework SignalR Monitoring for .net 8.0

I-Synergy.Framework.AspNetCore.Monitoring

I-Synergy Framework AspNetCore SignalR Monitoring

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2026.10116.10015-preview 45 1/15/2026
2026.10110.10203 108 1/10/2026
2026.10110.10121-preview 98 1/10/2026
2026.10109.12335-preview 99 1/9/2026
2026.10105.11358-preview 96 1/5/2026
2026.10105.11229-preview 92 1/5/2026
2025.11231.11750-preview 100 12/31/2025
2025.11225.12213 198 12/25/2025
2025.11225.12003-preview 185 12/25/2025
2025.11218.11301 287 12/18/2025
2025.11218.10050-preview 269 12/18/2025
2025.11211.11307-preview 426 12/11/2025
2025.11211.11225-preview 425 12/11/2025
2025.11210.10145-preview 451 12/10/2025
2025.11209.11459 455 12/9/2025
2025.11209.11422-preview 442 12/9/2025
2025.11207.11553-preview 217 12/7/2025
2025.11204.11448-preview 206 12/4/2025
2025.11130.12248 431 11/30/2025
2025.11130.12134-preview 352 11/30/2025
2025.11130.11725-preview 357 11/30/2025
2025.11130.11553-preview 354 11/30/2025
2025.11130.11515-preview 357 11/30/2025
2025.11130.11420.59-preview 360 11/30/2025
2025.11130.11323.56-preview 258 11/30/2025
2025.11129.10227.14-preview 113 11/29/2025
2025.11120.10114 417 11/20/2025
2025.11119.12324.6-preview 407 11/19/2025
2025.11119.10110 420 11/19/2025
2025.11118.12340.33-preview 407 11/18/2025
2025.11117.12349.4-preview 406 11/17/2025
2025.11117.11937.47-preview 400 11/17/2025
2025.11113.11532.29-preview 285 11/13/2025
2025.11113.10128.57-preview 287 11/13/2025
2025.11110.10306.55-preview 242 11/10/2025
2025.11109.10018.48-preview 149 11/8/2025
2025.11108.10119.29-preview 130 11/8/2025
2025.11106.10037.1-preview 204 11/6/2025
2025.11105.10254.54-preview 203 11/5/2025
2025.11105.10141.16-preview 211 11/5/2025
2025.11104.12308.54-preview 197 11/4/2025
2025.11104.10144.47-preview 202 11/4/2025
2025.11102.12003.8-preview 200 11/2/2025
2025.11102.11228.52-preview 172 11/2/2025
2025.11102.10309.42-preview 144 11/2/2025
2025.11029.11433.38-preview 210 10/29/2025
2025.11029.10201.38-preview 208 10/29/2025
2025.11027.11947.55-preview 201 10/27/2025
2025.11022.12207.12-preview 182 10/22/2025
2025.11019.12053.37-preview 178 10/19/2025
2025.11016.11750.24-preview 188 10/16/2025
2025.11015.10219.44-preview 186 10/15/2025
2025.11014.10245.12-preview 183 10/14/2025
2025.11012.10130.11-preview 142 10/12/2025
2025.11010.10052.52-preview 208 10/9/2025
2025.11001.12118.13-preview 201 10/1/2025
2025.10925.10144.25-preview 231 9/25/2025
2025.10921.11353.29-preview 259 9/21/2025
2025.10913.11841.29-preview 194 9/13/2025
2025.10912.12351.59-preview 131 9/12/2025
2025.10912.10210.52-preview 207 9/12/2025
2025.10911.10131.43-preview 203 9/10/2025
2025.10910.12340.34-preview 217 9/10/2025
2025.10910.11327.15-preview 199 9/10/2025
2025.10910.11206.45-preview 209 9/10/2025
2025.10910.10230.58-preview 207 9/10/2025
2025.10908.12343.47-preview 219 9/8/2025
2025.10904.12337.35-preview 226 9/4/2025
2025.10904.12245.51-preview 223 9/4/2025
2025.10904.11425.5-preview 214 9/4/2025
2025.10904.10323.39-preview 216 9/4/2025
2025.10826.11425.3-preview 279 8/26/2025
2025.10825.12350.9-preview 219 8/25/2025
2025.10810.10248-preview 179 8/10/2025
2025.10809.10146.35-preview 212 8/9/2025
2025.10806.12031.49-preview 275 8/6/2025
2025.10806.11955.54-preview 271 8/6/2025
2025.10806.11433.24-preview 279 8/6/2025
2025.10709.10105.39-preview 210 7/8/2025
2025.10707.12320.3-preview 220 7/7/2025
2025.10706.11957.9-preview 192 7/6/2025
2025.10702.11752.47-preview 200 7/2/2025
2025.10702.11256.17-preview 200 7/2/2025
2025.10702.11119.10-preview 213 7/2/2025
2025.10702.10000.31-preview 210 7/1/2025
2025.10701.11524.1-preview 208 7/1/2025
2025.10701.11310.13-preview 214 7/1/2025
2025.10630.12022.58-preview 201 6/30/2025
2025.10612.12134.8-preview 357 6/12/2025
2025.10611.12313.53-preview 366 6/11/2025
2025.10603.10159.54-preview 219 6/3/2025
2025.10602.11908.9-preview 214 6/2/2025
2025.10601.10124.29-preview 160 5/31/2025
2025.10531.12235.29-preview 164 5/31/2025
2025.10530.10121.50-preview 251 5/29/2025
2025.10527.12202.4-preview 216 5/27/2025
2025.10526.12034.25-preview 205 5/26/2025
2025.10521.11828.30-preview 221 5/21/2025
2025.10520.11715.6-preview 218 5/20/2025
2025.10520.11515.16-preview 218 5/20/2025
2025.10518.12303.43-preview 222 5/18/2025
2025.10518.11257.36-preview 225 5/18/2025
2025.10517.12347.27-preview 175 5/17/2025
2025.10517.12003.6-preview 177 5/17/2025
2025.10516.11720.13-preview 250 5/16/2025
2025.10514.12334.2-preview 325 5/14/2025
2025.10514.10015.27-preview 301 5/13/2025
2025.10511.11032.32-preview 240 5/11/2025
2025.10413.11530 328 4/13/2025
2025.10413.11434.33-preview 258 4/13/2025
2025.10413.10205.50-preview 206 4/13/2025
2025.10412.11526.4-preview 201 4/12/2025
2025.10412.10141 193 4/12/2025
2025.10411.11811.23-preview 197 4/11/2025
2025.10411.11645.1-preview 198 4/11/2025
2025.10410.11458.35-preview 250 4/10/2025
2025.10405.10143.28-preview 165 4/5/2025
2025.10403.12208.1-preview 245 4/3/2025
2025.10403.11954.16-preview 239 4/3/2025
2025.10401.11908.24-preview 231 4/1/2025
2025.10401.11559.45-preview 269 4/1/2025
2025.10331.12215.59-preview 217 3/31/2025
2025.10331.12130.34-preview 230 3/31/2025
2025.10331.10056.40-preview 225 3/30/2025
2025.10328.10150.21-preview 204 3/28/2025
2025.10323.11359-preview 339 3/23/2025
2025.10320.11800 236 3/20/2025
2025.10320.11616.45-preview 221 3/20/2025
2025.10320.10000 243 3/19/2025
2025.10319.12311.26-preview 231 3/19/2025
2025.10319.12238.6-preview 227 3/19/2025
2025.10319.12057.59-preview 222 3/19/2025
2025.10318.10055 227 3/18/2025
2025.10317.11728.13-preview 221 3/17/2025
2025.10317.11201.3-preview 213 3/17/2025
2025.10315.11523.14-preview 129 3/15/2025
2025.10305.12342 297 3/5/2025
2025.10305.12321.9-preview 298 3/5/2025
2025.10301.12313 200 3/1/2025
2025.10301.12129.38-preview 185 3/1/2025
2025.10221.10043.29-preview 161 2/21/2025
2025.1051.1246 199 2/20/2025
2025.1051.44.54-preview 162 2/20/2025
2025.1044.1 220 2/13/2025
2025.1044.0.2-preview 188 2/13/2025
2025.1043.0.2-preview 215 2/12/2025
2025.1041.0.1-preview 202 2/10/2025
2025.1038.1 223 2/7/2025
2025.1038.0.1-preview 176 2/7/2025
2025.1035.1 231 2/4/2025
2025.1035.0.1-preview 221 2/4/2025
2025.1034.1 226 2/3/2025
2025.1034.0.1-preview 203 2/3/2025
2025.1033.0.5-preview 200 2/2/2025
2025.1033.0.3-preview 198 2/2/2025
2025.1033.0.2-preview 213 2/2/2025
2025.1033.0.1-preview 178 2/2/2025
2025.1025.1 230 1/25/2025
2025.1025.0.1-preview 160 1/25/2025
2025.1021.1 204 1/21/2025
2025.1021.0.1-preview 175 1/21/2025
2025.1020.1 205 1/20/2025
2025.1020.0.3-preview 162 1/20/2025
2025.1020.0.1-preview 164 1/20/2025
2025.1018.0.7-preview 158 1/18/2025
2025.1018.0.5-preview 158 1/18/2025
2025.1018.0.4-preview 183 1/18/2025
2025.1017.0.2-preview 180 1/17/2025
2025.1017.0.1-preview 156 1/17/2025
2025.1016.0.1-preview 157 1/16/2025
2025.1010.1 199 1/10/2025
2025.1010.0.1-preview 159 1/9/2025
2025.1009.0.3-preview 177 1/9/2025
2025.1007.1 195 1/7/2025
2025.1007.0.5-preview 157 1/7/2025
2025.1007.0.3-preview 158 1/7/2025
2025.1006.1 209 1/7/2025
2025.1005.1 229 1/5/2025
2025.1005.0.2-preview 176 1/5/2025
2025.1004.1 215 1/4/2025
2024.1366.1 216 12/31/2024
2024.1366.0.2-preview 202 12/31/2024
2024.1366.0.1-preview 190 12/31/2024
2024.1365.0.2-preview 159 12/30/2024
2024.1365.0.1-preview 157 12/30/2024
2024.1361.0.2-preview 171 12/26/2024
2024.1353.0.1-preview 156 12/18/2024
2024.1352.0.3-preview 157 12/17/2024
2024.1352.0.2-preview 172 12/17/2024
2024.1352.0.1-preview 168 12/17/2024
2024.1351.1 233 12/16/2024
2024.1351.0.3-preview 173 12/16/2024
2024.1350.1 222 12/15/2024
2024.1343.1 196 12/8/2024
2024.1339.1 205 12/4/2024
2024.1336.1 211 12/1/2024
2024.1332.1 211 11/27/2024
2024.1330.1 198 11/25/2024
2024.1328.1 193 11/23/2024
2024.1325.1 202 11/20/2024
2024.1323.1 199 11/18/2024
2024.1316.1 124 11/11/2024
2024.1307.1 126 11/2/2024
2024.1300.1 117 10/26/2024
2024.1294.1 148 10/20/2024
2024.1290.1 235 10/16/2024
2024.1283.1 235 10/8/2024
2024.1282.1 216 10/8/2024
2024.1278.1 198 10/4/2024
2024.1277.1 212 10/3/2024
2024.1275.2 192 10/1/2024
2024.1275.1 195 10/1/2024
2024.1274.1 175 9/30/2024
2024.1263.1 213 9/19/2024
2024.1261.1 218 9/17/2024
2024.1258.1 210 9/13/2024
2024.1257.1 207 9/13/2024
2024.1256.1 170 9/12/2024
2024.1254.1 208 9/10/2024
2024.1250.1 229 9/6/2024
2024.1249.1 222 9/5/2024
2024.1246.1 229 9/2/2024
2024.1245.1 194 9/1/2024
2024.1237.1 251 8/24/2024
2024.1235.0.1-preview 180 8/23/2024
2024.1230.1 201 8/18/2024
2024.1229.1 214 8/16/2024
2024.1228.1 203 8/15/2024
2024.1222.1 223 8/8/2024
2024.1221.1 185 8/7/2024
2024.1221.0.2-preview 180 8/8/2024
2024.1221.0.1-preview 168 8/8/2024
2024.1220.1 186 8/7/2024
2024.1219.0.2-preview 175 8/6/2024
2024.1219.0.1-preview 147 8/6/2024
2024.1217.0.2-preview 140 8/4/2024
2024.1217.0.1-preview 161 8/4/2024
2024.1216.0.2-preview 153 8/3/2024
2024.1216.0.1-preview 135 8/3/2024
2024.1208.0.1-preview 169 7/26/2024
2024.1207.0.7-preview 157 7/25/2024
2024.1207.0.5-preview 169 7/25/2024
2024.1166.1 236 6/14/2024
2024.1165.1 198 6/13/2024
2024.1164.1 180 6/12/2024
2024.1162.1 204 6/10/2024
2024.1158.1 213 6/6/2024
2024.1156.1 195 6/4/2024
2024.1152.1 241 5/31/2024
2024.1151.1 240 5/29/2024
2024.1150.2 204 5/29/2024
2024.1150.1 200 5/29/2024
2024.1149.1 220 5/28/2024
2024.1147.1 227 5/26/2024
2024.1146.2 205 5/25/2024
2024.1146.1 199 5/25/2024
2024.1145.1 210 5/24/2024
2024.1135.2 222 5/14/2024
2024.1135.1 200 5/14/2024
2024.1134.1 206 5/13/2024
2024.1130.1 216 5/9/2024
2024.1123.1 204 5/2/2024
2024.1121.1 206 4/30/2024
2024.1114.1 228 4/22/2024
2024.1113.0.5-preview 224 4/22/2024
2024.1113.0.3-preview 196 4/22/2024
2024.1113.0.2-preview 204 4/22/2024
2024.1113.0.1-preview 181 4/22/2024
2024.1108.0.1-preview 190 4/17/2024
2024.1107.0.1-preview 179 4/16/2024
2024.1094.2 219 4/3/2024
2024.1094.1 194 4/3/2024
2024.1092.1 212 4/1/2024
2024.1088.1 218 3/28/2024
2024.1085.1 213 3/25/2024
2024.1080.2 233 3/20/2024
2024.1080.1 241 3/20/2024
2024.1078.1 228 3/18/2024
2024.1077.1 220 3/17/2024
2024.1073.1 246 3/13/2024
2024.1070.1 226 3/10/2024
2024.1069.1 254 3/9/2024
2024.1068.1 211 3/8/2024
2024.1066.2 237 3/6/2024
2024.1066.1 219 3/6/2024
2024.1065.1 216 3/5/2024
2024.1065.0.1-preview 191 3/5/2024
2024.1063.2 250 3/3/2024
2024.1063.1 231 3/3/2024
2024.1062.1 206 3/2/2024
2024.1061.2 257 3/1/2024
2024.1061.1 220 3/1/2024
2024.1060.2 226 2/29/2024
2024.1060.1 209 2/29/2024
2024.1060.0.5-preview 171 2/29/2024
2024.1060.0.3-preview 185 2/29/2024
2024.1059.0.1-preview 170 2/28/2024
2024.1058.1 208 2/27/2024
2024.1056.1 211 2/25/2024
2024.1055.1 218 2/24/2024
2024.1052.1 255 2/21/2024
2024.1050.2 245 2/20/2024
2024.1050.1 222 2/19/2024
2024.1049.1 203 2/18/2024
2024.1048.1 223 2/17/2024
2024.1047.1 232 2/16/2024
2024.1035.1 224 2/4/2024
2024.1034.2 194 2/3/2024
2024.1029.1 243 1/29/2024
2024.1023.1 232 1/23/2024
2024.1022.1 237 1/22/2024
2024.1020.1 220 1/20/2024
2024.1019.1 215 1/19/2024
2024.1017.1 263 1/17/2024
2024.1012.1 240 1/12/2024
2024.1010.1 246 1/10/2024
2024.1008.1 257 1/8/2024
2024.1007.1 263 1/7/2024
2024.1005.1 251 1/5/2024
2024.1004.1 236 1/4/2024
2023.1365.1 262 12/31/2023
2023.1362.1 227 12/28/2023
2023.1361.1 270 12/27/2023
2023.1359.1 254 12/25/2023
2023.1358.1 230 12/24/2023
2023.1357.1 269 12/23/2023
2023.1342.1 293 12/8/2023
2023.1336.1 266 12/2/2023
2023.1332.1 238 11/28/2023
2023.1330.1 237 11/26/2023
2023.1325.1 250 11/21/2023
2023.1323.1 208 11/19/2023
2023.1320.1 247 11/17/2023
2023.1318.1 234 11/15/2023
2023.1317.1 229 11/13/2023
2023.1307.1 258 11/3/2023
2023.1305.1 224 11/1/2023
2023.1304.1 230 10/31/2023
2023.1294.1 243 10/21/2023
2023.1290.1 244 10/16/2023
2023.1289.1 228 10/16/2023
2023.1284.1 265 10/11/2023
2023.1276.1 251 10/3/2023
2023.1275.1 239 10/2/2023
2023.1272.1 257 9/29/2023
2023.1269.1 234 9/26/2023
2023.1242.1 321 8/30/2023
2023.1231.1 294 8/19/2023
2023.1229.1 273 8/17/2023
2023.1228.1 285 8/16/2023
2023.1227.1 287 8/15/2023
2023.1224.2 283 8/12/2023
2023.1224.1 316 8/12/2023
2023.1213.2 305 8/1/2023
2023.1213.1 289 8/1/2023
2023.1209.1 277 7/27/2023
2023.1201.1 311 7/20/2023
2023.1197.1 315 7/16/2023
2023.1178.1 335 6/27/2023
2023.1175.1 356 6/24/2023
2023.1174.1 311 6/22/2023
2023.1169.1 347 6/18/2023
2023.1165.1 340 6/14/2023
2023.1161.1 381 6/11/2023
2023.1159.1 364 6/7/2023
2023.1157.1 341 6/6/2023
2023.1146.1 372 5/27/2023
2023.1139.1 357 5/19/2023
2023.1137.1 382 5/17/2023
2023.1136.1 398 5/16/2023
2023.1118.1 436 4/28/2023
2023.1111.1 428 4/21/2023
2023.1110.1 437 4/20/2023
2023.1105.1 441 4/15/2023
2023.1103.1 434 4/13/2023
2023.1102.1 427 4/12/2023
2023.1101.1 425 4/11/2023
2023.1090.1 442 3/31/2023
2023.1089.1 440 3/30/2023
2023.1088.1 466 3/29/2023
2023.1082.1 500 3/23/2023
2023.1078.1 497 3/19/2023
2023.1075.1 527 3/16/2023
2023.1070.1 499 3/11/2023
2023.1069.1 512 3/10/2023
2023.1064.1 470 3/5/2023
2023.1060.1 530 3/1/2023
2023.1057.1 533 2/26/2023
2023.1046.1 509 2/15/2023
2023.1043.2 566 2/12/2023
2023.1043.1 543 2/12/2023
2023.1042.1 538 2/11/2023
2023.1041.1 526 2/10/2023
2023.1039.1 567 2/8/2023
2023.1036.1 556 2/5/2023
2023.1035.1 549 2/4/2023
2023.1033.1 571 2/2/2023
2023.1030.1 597 1/30/2023
2023.1028.1 582 1/28/2023
2023.1026.1 580 1/26/2023
2023.1025.1 589 1/25/2023
2023.1024.1 559 1/24/2023
2023.1023.1 565 1/23/2023
2022.1319.1 604 11/15/2022
2022.1309.1 689 11/5/2022
2022.1307.1 710 11/3/2022
2022.1295.1 757 10/22/2022
2022.1290.1 790 10/17/2022
2022.1289.2 743 10/16/2022
2022.1289.1 741 10/16/2022
2022.1283.1 790 10/10/2022
2022.1282.1 744 10/9/2022
2022.1278.1 747 10/5/2022
2022.1272.2 760 9/29/2022
2022.1272.1 761 9/29/2022
2022.1271.1 793 9/28/2022
2022.1266.1 785 9/23/2022
2022.1259.1 798 9/16/2022
2022.1257.1 822 9/14/2022
2022.1250.1 833 9/7/2022
2022.1250.0.2-preview 325 9/7/2022
2022.1249.0.2-preview 325 9/6/2022
2022.1249.0.1-preview 333 9/6/2022
2022.1197.1 877 7/16/2022
2022.1196.1 839 7/15/2022
2022.1194.1 842 7/13/2022
2022.1182.1 811 7/1/2022
2022.1178.1 833 6/27/2022
2022.1166.1 874 6/15/2022
2022.1157.1 860 6/6/2022
2022.1150.1 847 5/30/2022
2022.1149.1 853 5/29/2022
2022.1144.1 858 5/24/2022
0.6.2 828 5/23/2022
0.6.1 836 5/23/2022
0.6.0 838 5/14/2022
0.5.3 813 5/8/2022
0.5.2 826 5/1/2022
0.5.1 813 5/1/2022
0.5.0 856 4/23/2022
0.4.1 885 4/15/2022
0.4.0 874 4/9/2022
0.3.3 871 4/8/2022
0.3.2 855 4/1/2022
0.3.1 837 3/29/2022
0.3.0 837 3/28/2022
0.2.3 847 3/28/2022
0.2.2 848 3/25/2022
0.2.1 880 3/21/2022
0.2.0 898 3/18/2022