Rystem 9.0.9

dotnet add package Rystem --version 9.0.9                
NuGet\Install-Package Rystem -Version 9.0.9                
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="Rystem" Version="9.0.9" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Rystem --version 9.0.9                
#r "nuget: Rystem, 9.0.9"                
#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.
// Install Rystem as a Cake Addin
#addin nuget:?package=Rystem&version=9.0.9

// Install Rystem as a Cake Tool
#tool nuget:?package=Rystem&version=9.0.9                

What is Rystem?


Table of Contents


Discriminated Union in C#

This library introduces a AnyOf<T0, T1, ...> class that implements discriminated unions in C#. Discriminated unions are a powerful type system feature that allows variables to store one of several predefined types, enabling type-safe and concise programming.

This library also includes integration with JSON serialization and deserialization.

What is a Discriminated Union?

A discriminated union is a type that can hold one of several predefined types at a time. It provides a way to represent and operate on data that may take different forms, ensuring type safety and improving code readability.

For example, a union can represent a value that is either an integer, a string, or a boolean:

AnyOf<int, string, bool> value;

The value can hold an integer, a string, or a boolean, but never more than one type at a time.


AnyOf Classes

The AnyOf class provides the ability to define a discriminated union of up to 8 types.

  • AnyOf<T0, T1>
  • AnyOf<T0, T1, T2>
  • ...
  • AnyOf<T0, T1, ..., T7>

Each class supports the following features:

  1. Implicit Conversion: Allows seamless assignment of any supported type to the union.
public AnyOf<int, string> GetSomething(bool check)
{
    if (check)
        return 42;
    else
        return "Hello";
}
  1. Type Checking and Casting: Methods to check and retrieve the stored type.
  2. Serialization Support: Built-in JSON serialization and deserialization integration.
  3. Matching and Switching: Methods to process the stored value using delegates or lambdas.

JSON Integration

This library supports seamless JSON serialization and deserialization for discriminated unions. It uses a mechanism called "Signature" to identify the correct class during deserialization. The "Signature" is constructed based on the names of all properties that define each class in the union.

Serialization and Deserialization

The AnyOf class integrates with JSON serialization and deserialization. The integration supports:

  1. Implicit Serialization: The active value in the union is serialized to JSON directly.
  2. Signature-Based Deserialization: Uses property names ("signatures") to determine the correct type during deserialization.
How "Signature" Works
  1. During deserialization, the library analyzes the properties present in the JSON.
  2. The "Signature" matches the property names in the JSON to a predefined signature for each class in the union.
  3. Once a match is found, the correct class is instantiated and populated with the data.

Matching and Switching

The AnyOf class includes methods to simplify processing the stored value:

Match Method

The Match method allows you to provide delegates for each possible type, returning a value based on the stored type.

Example:
var union = new AnyOf<int, string>(42);
var result = union.Match(
    i => $"Integer: {i}",
    s => $"String: {s}"
);
Console.WriteLine(result); // Outputs: "Integer: 42"

Switch Method

The Switch method allows you to perform different actions based on the stored type without returning a value.

Example:
var union = new AnyOf<int, string>("Hello");
union.Switch(
    i => Console.WriteLine($"Integer: {i}"),
    s => Console.WriteLine($"String: {s}")
);

Async Matching and Switching

Async versions of Match and Switch are also available for asynchronous operations.

Async Match Example:
var union = new AnyOf<int, string>("Hello");
var result = await union.MatchAsync(
    async i => await Task.FromResult($"Integer: {i}"),
    async s => await Task.FromResult($"String: {s}")
);
Console.WriteLine(result); // Outputs: "String: Hello"
Async Switch Example:
await union.SwitchAsync(
    async i => { await Task.Delay(100); Console.WriteLine($"Integer: {i}"); },
    async s => { await Task.Delay(100); Console.WriteLine($"String: {s}"); }
);

Usage Examples

Defining Unions

Here’s how to define and use a discriminated union:

var testClass = new CurrentTestClass
{
    OneClass_String = new FirstClass { FirstProperty = "OneClass_String.FirstProperty", SecondProperty = "OneClass_String.SecondProperty" },
    SecondClass_OneClass = new SecondClass
    {
        FirstProperty = "SecondClass_OneClass.FirstProperty",
        SecondProperty = "SecondClass_OneClass.SecondProperty"
    },
    OneClass_string__2 = "ExampleString",
    Bool_Int = 3,
    Decimal_Bool = true,
    OneCLass_SecondClass_Int = 42,
    FirstClass_SecondClass_Int_ThirdClass = new ThirdClass
    {
        Stringable = "StringContent",
        SecondClass = new SecondClass { FirstProperty = "Nested.FirstProperty", SecondProperty = "Nested.SecondProperty" }
    }
};
Serializing and Deserializing JSON
Example:
var json = testClass.ToJson();
var deserialized = json.FromJson<CurrentTestClass>();
Console.WriteLine(deserialized.OneClass_String.AsT0.FirstProperty); // Outputs: OneClass_String.FirstProperty

Deserialization with Attributes

Attributes allow more control over deserialization, specifying how the correct type is chosen:

Example:

public sealed class ChosenClass
{
    public AnyOf<TheFirstChoice, TheSecondChoice>? FirstProperty { get; set; }
    public string? SecondProperty { get; set; }
}

public sealed class TheFirstChoice
{
    [AnyOfJsonSelector("first")]
    public string Type { get; init; }
    public int Flexy { get; set; }
}
public sealed class TheSecondChoice
{
    [AnyOfJsonSelector("third", "second")]
    public string Type { get; init; }
    public int Flexy { get; set; }
}

var testClass = new ChosenClass
{
    FirstProperty = new TheSecondChoice
    {
        Type = "first",
        Flexy = 1,
    }
};
var json = testClass.ToJson();
var deserialized = json.FromJson<ChosenClass>();
Assert.True(deserialized.FirstProperty.Is<TheFirstChoice>());

I want to use this example that you find in the unit test to explain the attribute AnyOfJsonSelector. In this example FirstProperty of ChosenClass has a value for TheSecondChoice with a value in Type equal to "first". The attribute AnyOfJsonSelector is used to define the correct class to use during deserialization, therefore when the deserialization happens the library will use the class TheFirstChoice because the value of Type is "first". Both classes have the same properties and so the signatures are equals. Follow the next example to understand completely.

public sealed class ChosenClass
{
    public AnyOf<TheFirstChoice, TheSecondChoice>? FirstProperty { get; set; }
    public string? SecondProperty { get; set; }
}

public sealed class TheFirstChoice
{
    [AnyOfJsonSelector("first")]
    public string Type { get; init; }
    public int Flexy { get; set; }
}
public sealed class TheSecondChoice
{
    [AnyOfJsonSelector("third", "second")]
    public string Type { get; init; }
    public int Flexy { get; set; }
}

var testClass = new ChosenClass
{
    FirstProperty = new TheSecondChoice
    {
        Type = "third",
        Flexy = 1,
    }
};
var json = testClass.ToJson();
var deserialized = json.FromJson<ChosenClass>();
Assert.True(deserialized.FirstProperty.Is<TheSecondChoice>());

In this second example the property has a value of "third" and so the library will use the class TheSecondChoice.

Further attributes

Set a class as default class for AnyOf

 [AnyOfJsonDefault]
public sealed class RunResult : ApiBaseResponse
{
}

Use regex as selector

public sealed class FifthGetClass
{
    [AnyOfJsonRegexSelector("fift[^.]*.")]
    public string? FirstProperty { get; set; }
    public string? SecondProperty { get; set; }
}

Use over a class and not only over a property, like a value or like a regex.

[AnyOfJsonClassSelector(nameof(FirstProperty), "first.F")]
public sealed class FirstGetClass
{
    public string? FirstProperty { get; set; }
    public string? SecondProperty { get; set; }
}
[AnyOfJsonRegexClassSelector(nameof(FirstProperty), "secon[^.]*.[^.]*")]
public sealed class SecondGetClass
{
    public string? FirstProperty { get; set; }
    public string? SecondProperty { get; set; }
}

Benefits of Using It
  1. Type Safety: Ensures only predefined types are used.
  2. JSON Support: Automatically identifies and deserializes the correct type using "Signature".
  3. Code Clarity: Reduces boilerplate code for type management and error handling.

Extension methods

Stopwatch

You can monitor the time spent on an action, task or in a method. Some examples from Unit test.

var started = Stopwatch.Start();
//do something
await Task.Delay(2000);
var result = started.Stop();

or

var result = await Stopwatch.MonitorAsync(async () =>
{
    await Task.Delay(2000);
});

or with a return value

 var result = await Stopwatch.MonitorAsync(async () =>
{
    await Task.Delay(2000);
    return 3;
});

Linq expression serializer

Usually a linq expression is not serializable as string. With this method you can serialize your expression with some limits. Only primitives are allowed in the expression body. An example from Unit test.

Expression<Func<MakeIt, bool>> expression = ƒ => ƒ.X == q && ƒ.Samules.Any(x => x == k) && ƒ.Sol && (ƒ.X.Contains(q) || ƒ.Sol.Equals(IsOk)) && (ƒ.E == id | ƒ.Id == V) && (ƒ.Type == MakeType.Yes || ƒ.Type == qq);
var serialized = expression.Serialize();

with result

"ƒ => ((((((ƒ.X == \"dasda\") AndAlso ƒ.Samules.Any(x => (x == \"ccccde\"))) AndAlso ƒ.Sol) AndAlso (ƒ.X.Contains(\"dasda\") OrElse ƒ.Sol.Equals(True))) AndAlso ((ƒ.E == Guid.Parse(\"bf46510b-b7e6-4ba2-88da-cef208aa81f2\")) Or (ƒ.Id == 32))) AndAlso ((ƒ.Type == 1) OrElse (ƒ.Type == 2)))"

with deserialization

var newExpression = expressionAsString.Deserialize<MakeIt, bool>();

and usage, for instance, with Linq

var result = makes.Where(newExpression.Compile()).ToList();

you can deserialize and compile at the same time with

var newExpression = expressionAsString.DeserializeAndCompile<MakeIt, bool>();

you can deserialize as dynamic and use the linq dynamic methods

Expression<Func<MakeIt, int>> expression = x => x.Id;
string value = expression.Serialize();
LambdaExpression newLambda = value.DeserializeAsDynamic<MakeIt>();
var got = makes.AsQueryable();
var cut = got.OrderByDescending(newLambda).ThenByDescending(newLambda).ToList();

please see the unit test here to understand better how it works You may deal with return type of your lambda expression:

 LambdaExpression newLambda = value.DeserializeAsDynamic<MakeIt>();
 newLambda =  newLambda.ChangeReturnType<bool>();

or

 newLambda =  newLambda.ChangeReturnType(typeof(bool));

Reflection helper

Name of calling class

You can find the name of the calling class from your method, with deep = 1 the calling class of your method, with deep = 2 the calling class that calls the class that calls your method, and so on, with fullName set to true you obtain the complete name of the discovered class.

ReflectionHelper.NameOfCallingClass(deep, fullName);

Extensions for Type class

You can get the properties, fields and constructors for your class (and singleton them to save time during new requests)

Type.FetchProperties();
Type.FecthConstructors();
Type.FetchFields();

You can check if a Type is a son or a father or both of other type (in the example Zalo and Folli are Sulo). You may find more information in unit test here

Zalo zalo = new();
Zalo zalo2 = new();
Folli folli = new();
Sulo sulo = new();
object quo = new();
int x = 2;
decimal y = 3;
Assert.True(zalo.IsTheSameTypeOrASon(sulo));
Assert.True(folli.IsTheSameTypeOrASon(sulo));
Assert.True(zalo.IsTheSameTypeOrASon(zalo2));
Assert.True(zalo.IsTheSameTypeOrASon(quo));
Assert.False(sulo.IsTheSameTypeOrASon(zalo));
Assert.True(sulo.IsTheSameTypeOrAParent(zalo));
Assert.False(y.IsTheSameTypeOrAParent(x));

Mock a Type

If you need to create a type over an abstract class or interface you may use the mocking system of Rystem. For example, if you have an abstract class like this one down below.

public abstract class Alzio
{
    private protected string X { get; }
    public string O => X;
    public string A { get; set; }
    public Alzio(string x)
    {
        X = x;
    }
}

you can create an instace of it or simply mock it with

var mocked = typeof(Alzio).CreateInstance("AAA") as Alzio;
mocked.A = "rrrr";

and you can use the class like a real class. You also may do it with

Alzio alzio = null!;
var mocked = alzio.CreateInstance("AAA");
mocked.A = "rrrr";

or

Mocking.CreateInstance<Alzio>("AAA");

you may see "AAA" as argument for your constructor in abstract class.

Check nullability for properties, fields and parameters.

Following an example from unit test.

private sealed class InModel
{
    public string? A { get; set; }
    public string B { get; set; }
    public string? C;
    public string D;
    public InModel(string? b, string c)
    {
        A = b;
        B = c;
    }
    public void SetSomething(string? b, string c)
    {
        A = b;
        B = c;
    }
}
[Fact]
public void Test1()
{
    var type = typeof(InModel);
    var constructorParameters = type.GetConstructors().First().GetParameters().ToList();
    Assert.True(constructorParameters[0].IsNullable());
    Assert.False(constructorParameters[1].IsNullable());
    var methodParameters = type.GetMethod(nameof(InModel.SetSomething)).GetParameters().ToList();
    Assert.True(methodParameters[0].IsNullable());
    Assert.False(methodParameters[1].IsNullable());
    var properties = type.GetProperties().ToList();
    Assert.True(properties[0].IsNullable());
    Assert.False(properties[1].IsNullable());
    var fields = type.GetFields().ToList();
    Assert.True(fields[0].IsNullable());
    Assert.False(fields[1].IsNullable());
}

Text extensions

You may convert as fast as possible byte[] to string or stream to byte[] or byte[] to stream or stream to string or string to stream. For example, string to byte array and viceversa.

string olfa = "daskemnlandxioasndslam dasmdpoasmdnasndaslkdmlasmv asmdsa";
var bytes = olfa.ToByteArray();
string value = bytes.ConvertToString();

For example, string to stream and viceversa.

string olfa = "daskemnlandxioasndslam dasmdpoasmdnasndaslkdmlasmv asmdsa";
var stream = olfa.ToStream();
string value = stream.ConvertToString();

You may read a string with break lines as an enumerable of string

string olfa = "daskemnlandxioasndslam\ndasmdpoasmdnasndaslkdmlasmv\nasmdsa";
var stream = olfa.ToStream();
var strings = new List<string>();
await foreach (var x in stream.ReadLinesAsync())
{
    strings.Add(x);
}

A simple method to make uppercase the first character.

string olfa = "dasda";
var olfa2 = olfa.ToUpperCaseFirst();

A simple method to check if a char is contained at least X times.

string value = "abcderfa";
bool containsAtLeastTwoAChar = value.ContainsAtLeast(2, 'a');

Character separated-value (CSV)

Transform any kind of IEnumerable data in a CSV string.

string value = _models.ToCsv();

Minimization of a model (based on CSV concept)

It's a brand new idea to serialize any kind of objects (with lesser occupied space of json), the idea comes from Command separated-value standard. To serialize

string value = _models.ToMinimize();

To deserialize (for instance in a List of a class named CsvModel)

value.FromMinimization<List<CsvModel>>();

Extensions for json

I don't know if you are fed up to write JsonSerializer.Serialize, I do, and so, you may use the extension method to serialize faster. To serialize

var text = value.ToJson();

To deserialize in a class (for instance a class named User)

var value = text.FromJson<User>();

Extensions for Task

I don't know if you still are fed up to write .ConfigureAwait(false) to eliminate the context waiting for a task. I do. Why should I set the configure await to false? To set configure await to false

await {your async task}.NoContext();

Instead, to get the result as synchronous result but with a configure await set to false.

{your async task}.ToResult();

You may change the behavior of your NoContext() or ToResult(), setting (in the bootstrap of your application for example)

RystemTask.WaitYourStartingThread = true;

When do I need a true? In windows application for example you have to return after a button clicked to the same thread that started the request.

TaskManager

When you need to run a list of tasks concurrently you may use this static method.

In the next example with TaskManager.WhenAll you may run a method ExecuteAsync {times} times with {concurrentTasks} times in concurrency, and running them when a time slot is free. For example if you run this function with 8 times and 3 concurrentsTasks and true in runEverytimeASlotIsFree You will have this behavior: first 3 tasks starts and since the fourth the implementation waits the end of one of the 3 started before. As soon as one of the 3 started is finished the implementation starts to run the fourth.

var bag = new ConcurrentBag<int>();
await TaskManager.WhenAll(ExecuteAsync, times, concurrentTasks, runEverytimeASlotIsFree).NoContext();

Assert.Equal(times, bag.Count);

async Task ExecuteAsync(int i, CancellationToken cancellationToken)
{
    await Task.Delay(i * 20, cancellationToken).NoContext();
    bag.Add(i);
}

You may run a {atLeast} times of tasks and stopping to wait the remaining tasks with TaskManager.WhenAtLeast

var bag = new ConcurrentBag<int>();
await TaskManager.WhenAtLeast(ExecuteAsync, times, atLeast, concurrentTasks).NoContext();

Assert.True(bag.Count < times);
Assert.True(bag.Count >= atLeast);

async Task ExecuteAsync(int i, CancellationToken cancellationToken)
{
    await Task.Delay(i * 20, cancellationToken).NoContext();
    bag.Add(i);
}

Concurrency

ConcurrentList

You can use the ConcurrentList implementation to have the List behavior with lock operations.

var items = new ConcurrentList<ItemClass>();
Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Rystem:

Package Downloads
Rystem.DependencyInjection

Rystem is a open-source framework to improve the System namespace in .Net

Rystem.Authentication.Social.Blazor

Rystem.Authentication.Social helps you to integrate with new .Net Identity system and social logins.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
9.0.9 167 1/7/2025
9.0.8 12,266 1/6/2025
9.0.7 243 1/6/2025
9.0.5 19,100 12/30/2024
9.0.4 92,478 12/23/2024
9.0.3 325 12/22/2024
9.0.2 10,830 12/21/2024
9.0.1 1,311 12/21/2024
9.0.0 173,300 11/16/2024
9.0.0-rc.1 242 10/18/2024
6.2.0 219,699 10/9/2024
6.1.2 110 10/9/2024
6.1.1 403 10/9/2024
6.1.0 48,277 9/29/2024
6.0.24 660 9/11/2024
6.0.23 340,611 7/18/2024
6.0.22 120 7/18/2024
6.0.21 508 6/18/2024
6.0.20 728,109 6/16/2024
6.0.19 31,046 6/14/2024
6.0.18 469 6/14/2024
6.0.17 468 6/14/2024
6.0.16 50,338 6/10/2024
6.0.15 464 6/9/2024
6.0.14 94,824 5/24/2024
6.0.13 474 5/23/2024
6.0.12 389 5/23/2024
6.0.11 481 5/20/2024
6.0.9 511 5/19/2024
6.0.7 486 5/18/2024
6.0.6 438 5/10/2024
6.0.5 389 5/10/2024
6.0.4 550,403 4/3/2024
6.0.3 1,927 3/25/2024
6.0.2 380,546 3/11/2024
6.0.1 51,110 3/8/2024
6.0.0 1,171,492 11/21/2023
6.0.0-rc.6 194 10/25/2023
6.0.0-rc.5 144 10/25/2023
6.0.0-rc.4 113 10/23/2023
6.0.0-rc.3 119 10/19/2023
6.0.0-rc.2 183 10/18/2023
6.0.0-rc.1 209 10/16/2023
5.0.20 640,776 9/25/2023
5.0.19 2,916 9/10/2023
5.0.18 2,219 9/6/2023
5.0.17 2,044 9/6/2023
5.0.16 2,132 9/5/2023
5.0.15 2,102 9/5/2023
5.0.14 2,108 9/5/2023
5.0.13 2,186 9/1/2023
5.0.12 2,039 8/31/2023
5.0.11 2,038 8/30/2023
5.0.10 2,065 8/29/2023
5.0.9 2,111 8/24/2023
5.0.8 2,114 8/24/2023
5.0.7 451,596 8/23/2023
5.0.6 19,621 8/21/2023
5.0.5 6,285 8/21/2023
5.0.4 2,169 8/16/2023
5.0.3 214,873 8/2/2023
5.0.2 3,925 8/2/2023
5.0.1 13,723 8/1/2023
5.0.0 14,032 7/31/2023
4.1.26 143,215 7/20/2023
4.1.25 24,692 7/16/2023
4.1.24 402,176 6/13/2023
4.1.23 47,797 6/13/2023
4.1.22 131,795 5/30/2023
4.1.21 57,889 5/20/2023
4.1.20 407,159 4/19/2023
4.1.19 97,853 3/20/2023
4.1.18 2,502 3/20/2023
4.1.17 2,795 3/16/2023
4.1.16 2,547 3/16/2023
4.1.15 2,943 3/15/2023
4.1.14 12,357 3/9/2023
4.1.13 2,664 3/7/2023
4.1.12 3,029 2/9/2023
4.1.11 2,674 1/26/2023
4.1.10 2,922 1/22/2023
4.1.9 2,531 1/20/2023
4.1.8 2,726 1/18/2023
4.1.7 2,778 1/18/2023
4.1.6 2,630 1/17/2023
4.1.5 375 1/15/2023
4.1.4 375 1/15/2023
4.1.3 367 1/15/2023
4.1.2 384 1/15/2023
4.1.1 2,616 1/4/2023
4.1.0 2,804 12/30/2022
4.0.102 2,810 12/21/2022
4.0.101 808 12/20/2022
4.0.100 364 12/19/2022
4.0.99 384 12/18/2022
4.0.98 6,462 12/7/2022
4.0.97 375 12/7/2022
4.0.96 370 12/7/2022
4.0.95 372 12/7/2022
4.0.94 4,367 12/1/2022
4.0.93 405 12/1/2022
4.0.92 3,357 11/29/2022
4.0.91 8,592 11/22/2022
4.0.90 4,593 11/18/2022
4.0.89 4,320 11/18/2022
4.0.88 4,470 11/15/2022
4.0.87 4,407 11/14/2022
4.0.86 4,538 11/13/2022
4.0.85 4,839 11/2/2022
4.0.84 4,548 11/2/2022
4.0.83 4,703 10/29/2022
4.0.82 4,806 10/29/2022
4.0.81 1,746 10/29/2022
4.0.80 14,142 10/16/2022
4.0.79 4,323 10/9/2022
4.0.78 469 10/9/2022
4.0.77 458 10/8/2022
4.0.76 21,506 10/5/2022
4.0.75 43,749 9/20/2022
4.0.74 4,881 9/20/2022
4.0.73 4,506 9/20/2022
4.0.72 691 9/20/2022
4.0.71 3,983 9/20/2022
4.0.70 564 9/14/2022
4.0.69 533 9/14/2022
4.0.68 4,736 9/13/2022
4.0.67 500 9/1/2022
4.0.66 4,491 8/19/2022
4.0.65 478 8/19/2022
4.0.64 492 8/19/2022
4.0.63 515 8/16/2022
4.0.62 528 8/16/2022
4.0.61 469 8/16/2022
4.0.60 506 8/14/2022
4.0.59 523 8/13/2022
4.0.58 495 8/13/2022
4.0.57 526 8/13/2022
4.0.56 502 8/13/2022
4.0.54 526 8/13/2022
4.0.53 517 8/12/2022
4.0.52 487 8/11/2022
4.0.51 510 8/9/2022
4.0.50 520 8/8/2022
4.0.49 503 8/8/2022
4.0.48 500 8/8/2022
4.0.47 506 8/6/2022
4.0.46 488 8/6/2022
4.0.45 499 8/5/2022
4.0.44 482 8/5/2022
4.0.43 507 8/4/2022
4.0.42 515 8/4/2022
4.0.41 510 8/4/2022
4.0.40 498 8/3/2022
4.0.39 507 8/3/2022
4.0.38 4,844 7/30/2022
4.0.37 4,563 7/29/2022
4.0.36 4,019 7/29/2022
4.0.35 504 7/29/2022
4.0.34 800 7/29/2022
4.0.33 4,760 7/29/2022
4.0.32 4,562 7/29/2022
4.0.31 514 7/29/2022
4.0.30 518 7/29/2022
4.0.29 4,634 7/27/2022
4.0.28 557 7/27/2022
4.0.26 4,535 7/27/2022
4.0.25 4,179 7/26/2022
4.0.24 4,683 7/25/2022
4.0.23 4,590 7/25/2022
4.0.22 4,485 7/22/2022
4.0.21 4,532 7/19/2022
4.0.20 4,573 7/19/2022
4.0.19 525 7/19/2022
4.0.18 4,593 7/19/2022
4.0.17 4,603 7/19/2022
4.0.16 4,670 7/18/2022
4.0.15 4,525 7/18/2022
4.0.14 536 7/18/2022
4.0.13 4,594 7/18/2022
4.0.12 4,102 7/17/2022
4.0.11 1,500 7/17/2022
4.0.10 539 7/17/2022
4.0.9 1,186 7/17/2022
4.0.8 13,821 7/15/2022
4.0.7 5,787 7/15/2022
4.0.6 6,525 7/8/2022
4.0.5 6,234 7/6/2022
4.0.4 11,423 7/1/2022
4.0.3 1,349 6/29/2022
4.0.1 1,832 6/29/2022
4.0.0 1,324 6/27/2022
3.0.2 1,180 5/5/2022
3.0.1 1,457 11/30/2021
3.0.0 1,409 11/12/2021
2.0.12 2,473 10/14/2021
2.0.11 1,552 10/14/2021
2.0.8 2,354 10/6/2021
2.0.7 1,737 10/2/2021
2.0.6 483 9/30/2021
2.0.5 438 9/30/2021
2.0.4 1,552 9/29/2021
2.0.3 1,655 9/28/2021
2.0.2 1,363 9/26/2021
2.0.1 1,240 9/24/2021
2.0.0 1,319 9/22/2021
1.4.0 1,405 9/14/2021
1.3.18 1,314 9/10/2021
1.3.17 1,129 9/9/2021
1.3.16 1,445 8/28/2021
1.3.15 1,204 8/26/2021
1.3.14 1,180 8/19/2021
1.3.13 1,192 8/13/2021
1.3.12 1,243 8/12/2021
1.3.11 514 7/29/2021
1.3.10 1,289 7/27/2021
1.3.9 1,242 7/27/2021
1.3.1 1,317 7/25/2021
1.3.0 1,980 7/17/2021
1.2.4 1,263 7/14/2021
1.2.3 465 7/14/2021
1.2.2 441 7/14/2021
1.2.1 1,312 7/14/2021
1.2.0 2,569 7/13/2021
1.1.0 667 4/14/2021
1.0.3 429 4/13/2021
1.0.2 433 4/13/2021
1.0.1 433 4/13/2021
1.0.0 449 4/12/2021