Ecng.StringSearch 1.0.220

dotnet add package Ecng.StringSearch --version 1.0.220
                    
NuGet\Install-Package Ecng.StringSearch -Version 1.0.220
                    
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.StringSearch" Version="1.0.220" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Ecng.StringSearch" Version="1.0.220" />
                    
Directory.Packages.props
<PackageReference Include="Ecng.StringSearch" />
                    
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.StringSearch --version 1.0.220
                    
#r "nuget: Ecng.StringSearch, 1.0.220"
                    
#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.StringSearch@1.0.220
                    
#: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.StringSearch&version=1.0.220
                    
Install as a Cake Addin
#tool nuget:?package=Ecng.StringSearch&version=1.0.220
                    
Install as a Cake Tool

StringSearch - Efficient String Search Data Structures

A collection of high-performance string search data structures including Trie, Patricia Trie, and Ukkonen's Suffix Tree implementations. These data structures are optimized for fast prefix and substring searching operations.

Features

  • Multiple trie implementations for different use cases
  • Fast prefix and substring searching
  • Generic value associations with string keys
  • Memory-efficient Patricia Trie (compressed trie)
  • Ukkonen's Suffix Tree for advanced substring searching
  • Concurrent trie support for multi-threaded scenarios
  • MIT licensed open-source implementation

Installation

Add a reference to the StringSearch project in your solution.

Quick Start

Basic Trie Usage

using Gma.DataStructures.StringSearch;

// Create a Patricia Trie (most commonly used)
var trie = new PatriciaTrie<int>();

// Add key-value pairs
trie.Add("apple", 1);
trie.Add("application", 2);
trie.Add("apply", 3);
trie.Add("banana", 4);

// Retrieve values by prefix
var results = trie.Retrieve("app");
// Returns: [1, 2, 3] (values associated with "apple", "application", "apply")

var results2 = trie.Retrieve("ban");
// Returns: [4] (value associated with "banana")

Data Structures

PatriciaTrie

A space-optimized trie (radix tree) that stores strings efficiently by compressing chains of nodes with single children.

Best for:

  • Prefix searching
  • Autocomplete features
  • Memory-efficient storage of strings with common prefixes
using Gma.DataStructures.StringSearch;

var trie = new PatriciaTrie<string>();

// Add entries
trie.Add("test", "Test Value");
trie.Add("testing", "Testing Value");
trie.Add("tester", "Tester Value");
trie.Add("tea", "Tea Value");

// Search by prefix
var results = trie.Retrieve("test");
// Returns: ["Test Value", "Testing Value", "Tester Value"]

var results2 = trie.Retrieve("te");
// Returns: ["Test Value", "Testing Value", "Tester Value", "Tea Value"]

PatriciaSuffixTrie

A Patricia Trie that indexes all suffixes of added strings, enabling substring searching.

Best for:

  • Substring searching
  • Finding all occurrences of a pattern within stored strings
  • "Contains" queries
using Gma.DataStructures.StringSearch;

// Create with minimum query length of 3 characters
var suffixTrie = new PatriciaSuffixTrie<string>(minQueryLength: 3);

// Add strings with associated values
suffixTrie.Add("hello world", "Document 1");
suffixTrie.Add("world peace", "Document 2");
suffixTrie.Add("hello there", "Document 3");

// Search for substring "wor"
var results = suffixTrie.Retrieve("wor");
// Returns: ["Document 1", "Document 2"] (both contain "world")

// Search for substring "hello"
var results2 = suffixTrie.Retrieve("hello");
// Returns: ["Document 1", "Document 3"]

SuffixTrie

A standard trie-based suffix tree implementation.

using Gma.DataStructures.StringSearch;

// Create with minimum suffix length of 2
var suffixTrie = new SuffixTrie<string>(minSuffixLength: 2);

suffixTrie.Add("programming", "Item 1");
suffixTrie.Add("grammar", "Item 2");

// Search for "gram"
var results = suffixTrie.Retrieve("gram");
// Returns: ["Item 1", "Item 2"] (both contain "gram")

UkkonenTrie

An implementation of Ukkonen's linear-time suffix tree construction algorithm.

Best for:

  • Large text indexing
  • Efficient substring search in big datasets
  • Advanced pattern matching
using Gma.DataStructures.StringSearch;

// Create with minimum suffix length
var ukkonen = new UkkonenTrie<string>(minSuffixLength: 3);

ukkonen.Add("banana", "Fruit 1");
ukkonen.Add("bandana", "Clothing 1");

// Search for "ana"
var results = ukkonen.Retrieve("ana");
// Returns: ["Fruit 1", "Clothing 1"]

ConcurrentTrie

Thread-safe trie implementation for concurrent access scenarios.

using Gma.DataStructures.StringSearch;
using System.Threading.Tasks;

var concurrentTrie = new ConcurrentTrie<int>();

// Safe for concurrent access
Parallel.For(0, 1000, i =>
{
    concurrentTrie.Add($"key{i}", i);
});

// Retrieve from multiple threads
var results = concurrentTrie.Retrieve("key1");

Common Interface: ITrie<TValue>

All trie implementations implement the ITrie<TValue> interface:

public interface ITrie<TValue>
{
    void Add(string key, TValue value);
    IEnumerable<TValue> Retrieve(string query);
    void Remove(TValue value);
    void RemoveRange(IEnumerable<TValue> values);
    void Clear();
}

Usage Examples

Autocomplete System

using Gma.DataStructures.StringSearch;

public class AutocompleteSystem
{
    private readonly PatriciaTrie<string> _trie;

    public AutocompleteSystem()
    {
        _trie = new PatriciaTrie<string>();
    }

    public void AddWord(string word)
    {
        _trie.Add(word.ToLower(), word);
    }

    public IEnumerable<string> GetSuggestions(string prefix)
    {
        return _trie.Retrieve(prefix.ToLower()).Distinct();
    }
}

// Usage
var autocomplete = new AutocompleteSystem();
autocomplete.AddWord("Apple");
autocomplete.AddWord("Application");
autocomplete.AddWord("Approach");
autocomplete.AddWord("Banana");

var suggestions = autocomplete.GetSuggestions("app");
// Returns: ["Apple", "Application", "Approach"]

Document Search Engine

using Gma.DataStructures.StringSearch;
using System.Linq;

public class DocumentSearchEngine
{
    private readonly PatriciaSuffixTrie<string> _index;

    public DocumentSearchEngine(int minQueryLength = 3)
    {
        _index = new PatriciaSuffixTrie<string>(minQueryLength);
    }

    public void IndexDocument(string documentId, string content)
    {
        // Index the document content
        _index.Add(content.ToLower(), documentId);
    }

    public IEnumerable<string> Search(string query)
    {
        if (query.Length < 3)
            return Enumerable.Empty<string>();

        return _index.Retrieve(query.ToLower()).Distinct();
    }
}

// Usage
var searchEngine = new DocumentSearchEngine();
searchEngine.IndexDocument("doc1", "The quick brown fox jumps over the lazy dog");
searchEngine.IndexDocument("doc2", "A quick movement in the forest");
searchEngine.IndexDocument("doc3", "The lazy cat sleeps");

var results = searchEngine.Search("quick");
// Returns: ["doc1", "doc2"]

var results2 = searchEngine.Search("lazy");
// Returns: ["doc1", "doc3"]

Phone Directory

using Gma.DataStructures.StringSearch;

public class Contact
{
    public string Name { get; set; }
    public string Phone { get; set; }

    public override string ToString() => $"{Name}: {Phone}";
}

public class PhoneDirectory
{
    private readonly PatriciaTrie<Contact> _trie;

    public PhoneDirectory()
    {
        _trie = new PatriciaTrie<Contact>();
    }

    public void AddContact(string name, string phone)
    {
        var contact = new Contact { Name = name, Phone = phone };
        _trie.Add(name.ToLower(), contact);
    }

    public IEnumerable<Contact> FindByPrefix(string namePrefix)
    {
        return _trie.Retrieve(namePrefix.ToLower());
    }

    public void RemoveContact(Contact contact)
    {
        _trie.Remove(contact);
    }

    public void Clear()
    {
        _trie.Clear();
    }
}

// Usage
var directory = new PhoneDirectory();
directory.AddContact("Alice Smith", "555-0001");
directory.AddContact("Alice Johnson", "555-0002");
directory.AddContact("Bob Brown", "555-0003");

var contacts = directory.FindByPrefix("alic");
// Returns all contacts starting with "alic"

IP Address Lookup

using Gma.DataStructures.StringSearch;

public class IpAddressLookup
{
    private readonly PatriciaTrie<string> _trie;

    public IpAddressLookup()
    {
        _trie = new PatriciaTrie<string>();
    }

    public void AddMapping(string ipPrefix, string location)
    {
        _trie.Add(ipPrefix, location);
    }

    public IEnumerable<string> FindLocations(string ipPrefix)
    {
        return _trie.Retrieve(ipPrefix);
    }
}

// Usage
var ipLookup = new IpAddressLookup();
ipLookup.AddMapping("192.168.1", "Local Network A");
ipLookup.AddMapping("192.168.2", "Local Network B");
ipLookup.AddMapping("10.0.0", "VPN Network");

var locations = ipLookup.FindLocations("192.168");
// Returns: ["Local Network A", "Local Network B"]

Tag Search System

using Gma.DataStructures.StringSearch;
using System.Collections.Generic;

public class TaggedItem
{
    public string Id { get; set; }
    public string Title { get; set; }
    public List<string> Tags { get; set; }
}

public class TagSearchSystem
{
    private readonly PatriciaTrie<TaggedItem> _tagIndex;

    public TagSearchSystem()
    {
        _tagIndex = new PatriciaTrie<TaggedItem>();
    }

    public void AddItem(TaggedItem item)
    {
        foreach (var tag in item.Tags)
        {
            _tagIndex.Add(tag.ToLower(), item);
        }
    }

    public IEnumerable<TaggedItem> SearchByTag(string tagPrefix)
    {
        return _tagIndex.Retrieve(tagPrefix.ToLower()).Distinct();
    }

    public void RemoveItem(TaggedItem item)
    {
        _tagIndex.Remove(item);
    }
}

// Usage
var tagSystem = new TagSearchSystem();

tagSystem.AddItem(new TaggedItem
{
    Id = "1",
    Title = "Article about C#",
    Tags = new List<string> { "csharp", "programming", "dotnet" }
});

tagSystem.AddItem(new TaggedItem
{
    Id = "2",
    Title = "Article about C++",
    Tags = new List<string> { "cpp", "programming", "native" }
});

var items = tagSystem.SearchByTag("prog");
// Returns both articles (both have "programming" tag)

var csharpItems = tagSystem.SearchByTag("csh");
// Returns only the first article
using Gma.DataStructures.StringSearch;

public class Symbol
{
    public string Name { get; set; }
    public string Type { get; set; }  // class, method, property, etc.
    public string FilePath { get; set; }
}

public class CodeSymbolIndex
{
    private readonly PatriciaTrie<Symbol> _symbolTrie;
    private readonly PatriciaSuffixTrie<Symbol> _substringTrie;

    public CodeSymbolIndex()
    {
        _symbolTrie = new PatriciaTrie<Symbol>();
        _substringTrie = new PatriciaSuffixTrie<Symbol>(minQueryLength: 2);
    }

    public void IndexSymbol(Symbol symbol)
    {
        var key = symbol.Name.ToLower();
        _symbolTrie.Add(key, symbol);
        _substringTrie.Add(key, symbol);
    }

    public IEnumerable<Symbol> SearchByPrefix(string prefix)
    {
        return _symbolTrie.Retrieve(prefix.ToLower());
    }

    public IEnumerable<Symbol> SearchBySubstring(string substring)
    {
        return _substringTrie.Retrieve(substring.ToLower());
    }
}

// Usage
var codeIndex = new CodeSymbolIndex();

codeIndex.IndexSymbol(new Symbol
{
    Name = "GetUserById",
    Type = "method",
    FilePath = "UserService.cs"
});

codeIndex.IndexSymbol(new Symbol
{
    Name = "UserRepository",
    Type = "class",
    FilePath = "UserRepository.cs"
});

// Prefix search
var prefixResults = codeIndex.SearchByPrefix("getuser");
// Returns: GetUserById

// Substring search
var substringResults = codeIndex.SearchBySubstring("user");
// Returns: GetUserById, UserRepository

Performance Characteristics

Data Structure Add Search Space Best Use Case
PatriciaTrie O(k) O(k) Low Prefix search, autocomplete
PatriciaSuffixTrie O(k²) O(k) Medium Substring search
SuffixTrie O(k²) O(k) High Suffix-based search
UkkonenTrie O(k) O(k) Medium Large text indexing
ConcurrentTrie O(k) O(k) Medium Multi-threaded scenarios

where k is the length of the string

Choosing the Right Data Structure

Use PatriciaTrie when:

  • You need prefix-based searching (autocomplete, type-ahead)
  • Memory efficiency is important
  • Your strings share common prefixes
  • You only need to find strings that START with a query

Use PatriciaSuffixTrie when:

  • You need substring searching (find strings CONTAINING a query)
  • You want to find all occurrences of a pattern
  • Memory usage is acceptable
  • Query strings have a minimum length

Use UkkonenTrie when:

  • You're indexing large amounts of text
  • You need the most efficient suffix tree construction
  • Substring search performance is critical
  • You have complex pattern matching requirements

Use ConcurrentTrie when:

  • Multiple threads need to access the trie simultaneously
  • Thread safety is required
  • You're building a shared index in a multi-threaded application

Important Notes

  1. Case Sensitivity: Most examples use .ToLower() for case-insensitive search. The trie itself is case-sensitive.

  2. Minimum Query Length: Suffix tries accept a minimum query/suffix length to reduce memory usage and improve performance.

  3. Duplicate Values: Retrieve() may return duplicate values if the same value was added with different keys. Use .Distinct() if needed.

  4. Remove Operations: Remove() removes all occurrences of a value, regardless of which keys it was added with.

  5. Thread Safety: Only ConcurrentTrie is thread-safe. Other implementations require external synchronization for concurrent access.

Target Frameworks

  • .NET Standard 2.0
  • .NET 6.0
  • .NET 10.0

License

This code is distributed under MIT license. Copyright (c) 2013 George Mamaladze See license.txt or http://opensource.org/licenses/mit-license.php

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Ecng.StringSearch:

Package Downloads
StockSharp.Algo

Trading algorithms. More info on web site https://stocksharp.com/store/

GitHub repositories (1)

Showing the top 1 popular GitHub repositories that depend on Ecng.StringSearch:

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.220 44 12/22/2025
1.0.219 49 12/21/2025
1.0.218 195 12/19/2025
1.0.217 188 12/19/2025
1.0.216 308 12/17/2025
1.0.215 309 12/15/2025
1.0.214 241 12/15/2025
1.0.213 218 12/14/2025
1.0.212 146 12/12/2025
1.0.211 107 12/12/2025
1.0.210 99 12/12/2025
1.0.209 105 12/12/2025
1.0.208 109 12/12/2025
1.0.207 765 12/2/2025
1.0.206 656 12/2/2025
1.0.205 657 12/2/2025
1.0.204 262 11/30/2025
1.0.203 117 11/29/2025
1.0.202 120 11/28/2025
1.0.201 118 11/28/2025
1.0.200 180 11/27/2025
1.0.199 279 11/24/2025
1.0.198 196 11/24/2025
1.0.197 206 11/23/2025
1.0.196 244 11/22/2025
1.0.195 471 11/20/2025
1.0.194 431 11/18/2025
1.0.193 389 11/18/2025
1.0.192 374 11/13/2025
1.0.191 275 11/10/2025
1.0.190 1,136 11/1/2025
1.0.189 234 10/28/2025
1.0.188 235 10/27/2025
1.0.187 185 10/27/2025
1.0.186 115 10/25/2025
1.0.185 1,189 10/3/2025
1.0.184 334 9/28/2025
1.0.183 258 9/25/2025
1.0.182 3,519 8/30/2025
1.0.181 2,707 7/13/2025
1.0.180 194 7/13/2025
1.0.179 168 7/12/2025
1.0.178 490 7/8/2025
1.0.177 465 7/4/2025
1.0.176 220 7/2/2025
1.0.175 1,477 6/16/2025
1.0.174 355 6/9/2025
1.0.173 258 6/8/2025
1.0.172 616 5/21/2025
1.0.171 186 5/17/2025
1.0.170 693 5/12/2025
1.0.169 266 5/12/2025
1.0.168 354 4/17/2025
1.0.167 1,405 3/22/2025
1.0.166 226 3/20/2025
1.0.165 210 3/20/2025
1.0.164 213 3/19/2025
1.0.163 1,103 2/26/2025
1.0.162 159 2/26/2025
1.0.161 1,325 2/5/2025
1.0.160 243 1/21/2025
1.0.159 178 1/14/2025
1.0.158 173 1/12/2025
1.0.157 181 1/10/2025
1.0.156 1,485 12/27/2024
1.0.155 360 11/20/2024
1.0.154 1,127 11/18/2024
1.0.153 503 11/7/2024
1.0.152 314 10/19/2024
1.0.151 889 10/12/2024
1.0.150 771 10/5/2024
1.0.149 1,165 9/18/2024
1.0.148 201 9/17/2024
1.0.147 888 9/3/2024
1.0.146 204 9/1/2024
1.0.145 3,638 6/12/2024
1.0.144 702 5/28/2024
1.0.143 1,319 5/4/2024
1.0.142 861 4/23/2024
1.0.141 211 4/21/2024
1.0.140 211 4/14/2024
1.0.139 1,097 3/28/2024
1.0.138 278 3/17/2024
1.0.137 1,360 2/23/2024
1.0.136 238 2/23/2024
1.0.135 1,002 2/18/2024
1.0.134 243 2/18/2024
1.0.133 259 2/16/2024
1.0.132 825 2/13/2024
1.0.131 715 2/8/2024
1.0.130 971 2/5/2024
1.0.129 273 2/4/2024
1.0.128 990 1/23/2024
1.0.127 267 1/23/2024
1.0.126 995 1/12/2024
1.0.125 1,093 1/2/2024
1.0.124 326 12/29/2023
1.0.123 3,248 11/12/2023
1.0.122 342 11/10/2023
1.0.121 306 11/10/2023
1.0.120 329 11/9/2023
1.0.119 361 11/3/2023
1.0.118 374 11/1/2023
1.0.117 325 11/1/2023
1.0.116 4,257 9/8/2023
1.0.115 423 9/8/2023
1.0.114 466 9/3/2023
1.0.113 557 8/21/2023
1.0.112 531 8/14/2023
1.0.111 563 8/10/2023
1.0.110 3,944 6/29/2023
1.0.109 2,163 5/27/2023
1.0.108 624 5/21/2023
1.0.107 608 5/19/2023
1.0.106 2,504 5/8/2023
1.0.105 684 4/21/2023
1.0.104 4,253 4/3/2023
1.0.103 827 3/13/2023
1.0.102 2,156 3/6/2023
1.0.101 708 2/26/2023
1.0.100 2,469 2/21/2023
1.0.99 663 2/20/2023
1.0.98 709 2/15/2023
1.0.97 687 2/14/2023
1.0.96 3,298 2/9/2023
1.0.95 2,349 2/7/2023
1.0.94 731 2/4/2023
1.0.93 2,469 2/2/2023
1.0.92 2,512 1/30/2023
1.0.91 819 1/18/2023
1.0.90 5,082 12/30/2022
1.0.89 748 12/23/2022
1.0.88 3,054 12/12/2022
1.0.87 2,791 12/4/2022
1.0.86 799 12/4/2022
1.0.85 770 11/30/2022
1.0.84 796 11/29/2022
1.0.83 787 11/28/2022
1.0.82 820 11/18/2022
1.0.81 3,387 11/11/2022
1.0.80 819 11/11/2022
1.0.79 834 11/10/2022
1.0.78 842 11/5/2022
1.0.77 822 11/4/2022
1.0.76 18,848 11/1/2022
1.0.75 21,105 10/16/2022
1.0.74 1,019 9/10/2022
1.0.73 42,623 9/8/2022
1.0.72 899 9/8/2022
1.0.71 938 9/8/2022
1.0.70 926 9/4/2022
1.0.69 83,765 8/24/2022
1.0.68 948 8/8/2022
1.0.67 962 7/26/2022
1.0.66 867 7/26/2022
1.0.65 43,442 7/19/2022
1.0.64 42,656 7/18/2022
1.0.63 948 7/8/2022
1.0.62 972 6/18/2022
1.0.61 959 6/6/2022
1.0.60 84,873 4/30/2022
1.0.59 948 4/20/2022
1.0.58 986 4/10/2022
1.0.57 981 4/7/2022
1.0.56 935 4/7/2022
1.0.55 1,001 4/2/2022
1.0.54 7,709 3/29/2022
1.0.53 934 3/27/2022
1.0.52 223,255 1/24/2022
1.0.51 144,854 12/29/2021
1.0.50 26,055 12/20/2021
1.0.49 848 12/13/2021
1.0.48 51,043 12/6/2021
1.0.47 826 12/2/2021
1.0.46 27,893 11/29/2021
1.0.45 26,014 11/22/2021
1.0.44 890 11/17/2021
1.0.43 26,912 11/13/2021
1.0.42 876 11/10/2021
1.0.41 837 11/9/2021
1.0.40 56,649 11/5/2021
1.0.39 847 11/4/2021
1.0.38 841 11/4/2021
1.0.37 882 11/3/2021
1.0.36 945 10/30/2021
1.0.35 29,712 10/21/2021
1.0.34 909 10/17/2021
1.0.33 55,808 10/14/2021
1.0.32 4,902 10/13/2021
1.0.31 868 10/12/2021
1.0.30 29,343 10/11/2021
1.0.29 882 10/9/2021
1.0.28 32,832 10/7/2021
1.0.27 31,402 10/7/2021
1.0.26 829 10/7/2021
1.0.25 860 10/6/2021
1.0.24 855 9/28/2021
1.0.23 30,463 9/23/2021
1.0.22 936 9/10/2021
1.0.21 890 9/9/2021
1.0.20 857 9/8/2021
1.0.19 834 9/8/2021
1.0.18 29,053 9/6/2021
1.0.17 901 8/31/2021
1.0.16 838 8/30/2021
1.0.15 30,026 7/31/2021
1.0.14 55,177 7/30/2021
1.0.13 953 7/26/2021
1.0.12 82,633 7/5/2021
1.0.11 817 7/1/2021
1.0.10 57,875 6/4/2021
1.0.9 83,470 4/26/2021
1.0.8 29,092 4/19/2021
1.0.7 136,305 4/7/2021
1.0.6 28,324 4/3/2021
1.0.5 163,814 3/22/2021
1.0.4 102,415 3/4/2021
1.0.3 28,189 2/26/2021
1.0.2 152,063 2/2/2021
1.0.1 101,901 1/24/2021
1.0.0 963 1/24/2021