LgyUtil 1.1.27
See the version list below for details.
dotnet add package LgyUtil --version 1.1.27
NuGet\Install-Package LgyUtil -Version 1.1.27
<PackageReference Include="LgyUtil" Version="1.1.27" />
paket add LgyUtil --version 1.1.27
#r "nuget: LgyUtil, 1.1.27"
// Install LgyUtil as a Cake Addin #addin nuget:?package=LgyUtil&version=1.1.27 // Install LgyUtil as a Cake Tool #tool nuget:?package=LgyUtil&version=1.1.27
C#通用工具类说明
- 工具的每个部分,都发布了独立的包,可以按需引入(LgyUtil、LgyUtil.Cache、LgyUtil.Compress、LgyUtil.ModelCheck、LgyUtil.Net、LgyUtil.SSH)
- 下面每个说明最后括号内标记的内容,为工具所在的包,如 (LgyUtil),说明在LgyUtil包下
- 每个方法若写为EncryptUtil.EncryptDES,则是通过帮助类,静态调用。若只有方法名ContainsAny,则为对象直接点出方法来使用(new List<string>(). ContainsAny("1"))。
一、ArrayUtil,数组扩展类(LgyUtil)
ForEach(),Exists(),Find(),FindAll(),FindIndex(),Sort(),ConvertAll(),普通数组[]增加扩展功能,都是List存在的功能
用法:(以ForEach为例) string[] str={"a","b","c"}; str.ForEach(s=>s+"1");
JoinToString(),将数组内容拼接成字符串,普通数组[]和List数组扩展功能
用法: 1)用英文逗号拼接数组所有内容 string[] str={"a","b","c"}; Console.WriteLine(str.JoinToString()) //JoinToString不填写参数,默认用英文逗号分隔 输出结果 a,b,c 2)自定义拼接内容 public class Test { public int a; public string b; } List<Test> tests=new List<Test>(); //选择属性b,并且用+来拼接成字符串 tests.JoinToString(t=>t.b,"+");
ContainsAny(),包含参数内多个内容的某一个即可返回ture,普通数组[]和List数组扩展功能
用法:(解决了Contains方法只能输入一个参数进行判断) string[] str={"a","b","c","d"}; str.ContainsAny("b","c");//数组某项 包含b 或者 包含c,就能返回true
Slice(),数组切片,普通数组[]和List数组扩展功能
用法:(.net6 出现了新的切片语法糖[1..2],可以替代这个方法) string[] str={"a","b","c","d"}; str.Slice(1,2);//返回结果{"b","c"},参数从0开始
HaveContent(),数组是否有内容,普通数组[]和List数组扩展功能
用法: string[] str={"a","b","c","d"}; str.HaveContent()---->true string[] str={}; str.HaveContent()---->false string[] str=null; str.HaveContent()---->false
IsNullOrEmpty(),数组是否为空,普通数组[]和List数组扩展功能
用法: string[] str={"a","b","c","d"}; str.IsNullOrEmpty()---->false string[] str={}; str.IsNullOrEmpty()---->true string[] str=null; str.IsNullOrEmpty()---->true
二、CronUtil,定时帮助类,对Quartz进行了封装(LgyUtil)
- 开始必须初始化定时对象,执行:CronUtil.InitScheduler()
- 添加定时任务
- AddCronJob(),按照cron表达式定时
- AddSecondJob(),按照秒定时
- AddMinuteJob(),按照分钟定时
- AddHourJob(),按照小时定时
- AddJob(),自定义定时方式(TriggerBuilder对象)
- 停止方法StopJob
三、DataTable扩展,效率不高,程序中避免使用DataTable(LgyUtil)
- ToList<T>(),将表转成数组
- ToDictionary<string,T>(),将表转成字典
- ToDataTable(),将DataRow[]转成DateTable,一般在表的Select以后使用
- ToModel<T>(),将DataRow转成模型
四、DateTimeUtil,日期扩展方法(LgyUtil)
ToyyyyMMdd(),new DateTime(2000,5,2).ToyyyyMMdd() 输出:2000-05-02
ToyyyyMMddCH(),new DateTime(2000,5,2).ToyyyyMMddCH() 输出:2000年05月02日
ToyyyyMMddHHmmss(),new DateTime(2000,5,2,10,8,20).ToyyyyMMddHHmmss() 输出:2000-05-02 10:08:20
ToyyyyMMddHHmmssCH(),new DateTime(2000,5,2,10,8,20).ToyyyyMMddHHmmssCH() 输出:2000年05月02日 10:08:20
GetTimestamp(),获取当前unix时间戳(13位)
GetDateTimeByTimestamp(),js时间戳转本地日期
AddQuarter(),给传入日期 添加季度
GetQuarter(),获取传入日期的 季度
GetMonthBetween(),获取月份差,例如:5月和3月的月份差为2
GetYearsStart(),获取传入日期 年的第一天
GetYearsEnd(),获取传入日期 年的最后一天
GetQuarterStart(),获取传入日期 季度的第一天
GetQuarterEnd(),获取传入日期 季度最后一天
GetMonthStart(),获取传入日期 月的第一天
GetMonthEnd(),获取传入日期 月最后一天
GetDaysStart(),获取传入日期 0点0分0秒
GetDaysEnd(),获取传入日期 23点59分59秒
GetHourStart(),获取传入日期 0分0秒
GetHourEnd(),获取传入日期 59分59秒
GetMinuteStart(),获取传入日期 0秒
GetMinuteEnd(),获取传入日期 59秒
ToStringExt(),格式化日期扩展,Q代表季度,只解析第一个Q
new DateTime(2010,5,3).ToStringExt("yyyy/Q")
五、EncryptUtil,加密算法帮助类(LgyUtil)
AES加密解密(对称加密):
string key="1234567890123456";//秘钥必须16位 string vector = "1234567890123456";//偏移向量也必须是16位,有默认值,可以不填写 var model=CipherMode.CBC;//加密模式,默认是CBC,可以不填写 padding=PaddingMode.PKCS7;//偏移量,默认是PKCS7,可以不填写 //加密 string miwen = EncryptUtil.AESEncrypt("加密内容",key,model,padding); //解密 string mingwen = EncryptUtil.AESDecrypt(miwen,key,vector,model,padding);
DES加密解密(对称加密):与上面AES使用方法相同, 只是秘钥和向量都必须是8位长度
EncryptUtil.EncryptDES() EncryptUtil.DecryptDES()
RSA加密(非对称加密)两种格式的秘钥xml、pem:
1)先获取公钥和私钥 //xml格式秘钥 (string publicKey,string privateKey) = EncryptUtil.GetRSAKey_Xml(); //pem格式秘钥,有两种格式,在获取秘钥时,填写第一个参数 //1.带标准头尾的 -----BEGIN PUBLIC这种 //2.无换行的纯Base64字符串的 (string publicKey,string privateKey) = EncryptUtil.GetRSAKey_Pem(); 2)公钥加密: EncryptUtil.RSAPublicEncrypt_Xml("数据","xml公钥"); EncryptUtil.RSAPublicEncrypt_Pem("数据","pem公钥"); 3)私钥解密: EncryptUtil.RSAPrivateDecrypt_Xml("xml加密数据","xml私钥"); EncryptUtil.RSAPrivateDecrypt_Pem("pem加密数据","pem私钥");
GetMd5(),获取字符串的md5
六、EnumUtil,枚举帮助和扩展(LgyUtil)
GetEnumDescription(),获取枚举[Description]标签的描述
EnumUtil.GetEnumDescriptionList(),获取所有枚举的[Description]标签描述
EnumUtil.GetEnumDescriptionDic(),获取所有枚举的[Description]标签描述的字典
返回:Dictionary<string:枚举名, string:描述>
EnumUtil.GetEnumNameValueDic,获取所有枚举描述的字典
返回:Dictionary<string:枚举名, int:枚举数值>
七、FileUtil,文件帮助类(LgyUtil)
- FileUtil.GetMD5(),计算并返回文件的md5,大文件慎用。
- FileUtil.GetSHA1(),计算并返回文件的哈希值,大文件慎用。
- FileUtil.WatchFileChanged(),监视文件夹变化
- FileUtil.Copy(),拷贝文件或文件夹
- FileUtil.ReadFileShare(),以非独占的方式,读取文件。解决windows下,用程序读取文件时,文件不能被文本编辑器打开。
- FileUtil.GetAllFiles(),获取文件夹下所有文件(返回文件名数组)
- FileUtil.GetAllFilesDeep(),深度查找文件或文件夹
- FileUtil.SortByWindowsFileName(),按照windows文件名排序规则,排序字符串
- FileUtil.SortByWindowsFileNameDesc(),按照windows文件名排序规则,倒序排序字符串
八、ObjectConvertUtil,类型转换方法(LgyUtil)
- ToInt(),ToDouble(),ToLong(),ToDecimal(),ToFloat(),任何对象都可以调用,原理是Convert.ToXXX,支持转为科学计数法
- ToBool(),字符串"true"(不区分大小写),"1",数值1,都会返回true,其余返回false
- ToBytes(),返回对象的二进制数组,若对象为类,必须加上[Serializable]标签
- ToObject(),根据二进制数组,返回对象,类必须打上[Serializable]标签
- ToEnum<Enum>(),将数值转换为枚举对象
九、ObjectUtil,对象扩展类(LgyUtil)
CloneNewtonJson(),用NewtonJson,序列化 再 序列化 克隆对象
CloneBinary(),用二进制方法克隆对象,类必须加上[Serializable]特性
CloneMapster(),使用Mapster克隆,只能克隆普通类,速度快
In(),类似sql的in,判断内容是否在数组中出现
NotIn(),类似sql的not in
SerializeNewtonJson(),将对象用NewtonJson序列化为json字符串
public class Test { public DateTime a; public string b; } var t=new Test(){ a= DateTime.Now,b="x" }; t.SerializeNewtonJson(); //输出为{"a":"2023-02-17 16:31:19","b":"x"}
7.MappingTo(),映射对象,比AutoFac简单,上手快。
//2个基础类
public class A {
public DateTime x;
public string y;
}
public class B {
public string y;
public int z;
}
var a=new A(){ x= DateTime.Now,y="x" };
var b=new B(){ y="abc",z=1};
//1、将a的属性,映射到b里
a.MappingTo(b);//b的内容为 y="x",z=1,覆盖同名同类型内容,其它不动
//2、将a的属性映射到b,并返回一个新的B实例,覆盖同名同类型内容,其它不动
B b = a.MappingTo<b>();
//3、自定义配置映射,具体配置参数,请参考https://github.com/MapsterMapper/Mapster
B b = a.MappingTo(setter =>
{
//null值不映射
setter.IgnoreNullValues(true);
});
十、RandomUtil,随机数帮助类(LgyUtil)
可以生成7种随机类型码:只有数字、只有大写字母、只有小写字母、大小写字母、小写字母和数字、大写字母和数字、大小写字母和数字。
也可以根据模板生成。随机数内容,用一对大括号包括。 n:数字 x:小写字母 X:大写字母。大括号里的内容,只能包含nXx三种字母,若出现{axnX},此为错误模板,不会解析。
使用方法:链式调用
//输出7位只有数字的随机数
RandomUtil.Init(7,Enum_RandomFormat.OnlyNumber).GetRandom();
//根据模板,生成随机数。注意:{anXx}为错误模板,不解析
RandomUtil.Init("1234-{nnXXxx}-{anXx}-567-{xxnnXX}").GetRandom();
//输出内容1234-62DGxg-{anXx}-567-td67IN
链式调用的所有方法:
GetRandom(),生成一个随机数
GetRandoms(),生成多个随机数(结果可能会出现重复的情况,设置SetNotSame后,只是生成的一个随机数里的内容不会重复)
SetNotSame(),生成的一个随机数中,不出现重复的内容,如生成3个不重复的数字,123,不会出现111。注:按模板生成时,此配置无效
SetPrefix(),设置随机码前缀
SetSuffix(),设置随机码后缀
十一、RegexUtil,正则表达式帮助类(LgyUtil)
只有简单的几个正则判断
1. RegexUtil.IsPhoneNumerCN(),是否是中国大陆手机号
2. RegexUtil.IsNumber(),是否是正数
3. RegexUtil.IsChinese(),是否全是汉字
4. RegexUtil.IsDomainName(),是否是域名
5. RegexUtil.IsEmail(),是否是邮件
6. RegexUtil.IsIP(),是否是IP地址
7. RegexUtil.IsPwd_NumberLetter(),密码验证:必须包含数字、字母(不区分大小写)
8. RegexUtil.IsPwd_NumberLetterSymbols(),密码验证:必须包含数字、字母(不区分大小写)、特殊符号(! @ # $ % ^ & * ( ) _ + - = . , { } [ ] ?)
9. RegexUtil.IsPwd_NumberLetterBigSmall(),密码验证:必须包含数字、大写字母、小写字母
10. RegexUtil.IsPwd_NumberLetterBigSmallSymbols(),密码验证:必须包含数字、大写字母、小写字母、特殊符号(! @ # $ % ^ & * ( ) _ + - = . , { } [ ] ?)
十二、StringUtil,字符串帮助和扩展类(LgyUtil)
IsNullOrEmpty(),字符串是否为空
IsNullOrEmptyTrim(),trim后,字符串是否为空
IsNotNullOrEmpty(),字符串是否不为空
Format(),就是string.Format
DeserializeNewtonJson(),使用NewtonJson,反序列化字符串为对象
ToDateTime(),转为时间,支持格式化时间,支持季度,Q代表季度,只解析第一个Q
//默认格式转换 "2010-05-06".ToDateTime() //格式化字符串转换 "20100506".ToDateTime("yyyyMMdd") //季度转日期 "2010/2".ToDateTime("yyyy/Q")
ToByteArr(),转为二进制数组
ByteToString(),二进制数组转为字符串
ToEnum<Enum>(),字符串转枚举
RegexIsMatch(),匹配正则表达式
ReplaceByIndex(),根据下标索引,替换字符串
//替换手机号 177****7777 "17777777777".ReplaceByIndex(3,4,"*");
ReplaceRegex(),根据正则表达式替换
GetStringByRegex(),根据正则表达式,返回匹配的第一组内容
Split(),将字符串拆分成数组,返回string[]
FormatTemplate(),根据模板格式化字符串,可以使用Dictionary<string, object>、匿名类、普通类
Dictionary<string, object>
string str="{a},{b}"; str.FormatTemplate(new Dictionary<string, object>{{"a",1},{"b","2"}}); //输出1,2
匿名类
string str="{a},{b}"; str.FormatTemplate(new {a=1,b="2"}); //输出1,2
普通类
string str="{a},{b}"; class Temp { public string a { get; set; } public int b { get; set; } } str.FormatTemplate(new Temp{a="1",b=2}); //输出1,2
Trim(),可以接填填写字符串,若替换一次后,开头或结尾还有要trim的内容,不再进行替换
TrimStart(),可直接填写字符串,若替换一次后,开头还有要trim的内容,不再进行替换
TrimEnd(),可直接填写字符串,若替换一次后,结尾还有要trim的内容,不再进行替换
EndsWith(),可以匹配多个字符串
StartsWith(),可以匹配多个字符串
ContainsAny(),字符串包含任意一个匹配项,就返回true
十三、TaskUtil,多线程帮助类(LgyUtil)
执行多线程时,控制并行线程个数
//最多10个线程并行执行 using(var taskMaxUtil = TaskUtil.GetTaskMaxUtil(10)) { //执行100次,最大线程数为10 for (int i = 0; i < 100; i++) { var tempI = i; taskMaxUtil.AddRunTask(() => { Console.WriteLine(tempI); Thread.Sleep(1000); }); } if (taskMaxUtil.WaitAll()) Console.WriteLine("所有线程执行完成"); }
十四、ICache,缓存帮助类(<font color="red">LgyUtil.Cache</font>)
缓存分为本地缓存(MemoryCache)、Redis缓存(RedisCache)。两个使用方法一样,构造一个静态变量,全局使用
// 本地缓存,构造函数中,可以设置清理缓存时间,默认5分钟清理一次,使用TimeSpan.Zero,不进行清理 // MemoryCache(TimeSpan? clearExpirationTime = null) public static ICache cache=new MemoryCache(); // Redis缓存 public static ICache cacheRedis=new ReidsCache("localhost");//构造函数,填写redis连接字符串
设置缓存,Set<T>(string key, T value, TimeSpan? expiresSliding = null,DateTime? expiressAbsoulte = null),可以设置滑动过期时间和绝对过期时间
//设置缓存后,每读取一次,缓存有效期延长1小时,缓存最多保持1天,1天后,缓存一定消失 cache.Set("test",new List<string>(){"1","2"},TimeSpan.FromHours(1),DateTime.Now.AddDays(1)); //设置缓存后,每读取一次,缓存有效期延长1小时,一直读取,一直延长。1小时内没有读取,缓存过期 cache.Set("test",new List<string>(){"1","2"},TimeSpan.FromHours(1)); //设置缓存后,读取也不会延长缓存有效期,缓存最多保持1天,1天后,缓存一定消失 cache.Set("test",new List<string>(){"1","2"},null,DateTime.Now.AddDays(1));
获取缓存,Get<T>(string key)
获取字符串缓存,GetString(string key)
验证是否存在缓存,Exists(string key)
删除一个缓存,Remove(string key)
清空缓存,或清空多个缓存,RemoveAll(params string[] keys)
根据key前缀,清空缓存,RemoveAllPrefix(string prefix)
根据key前缀,获取缓存,GetKeysByPrefix(string prefix)
获取所有key,GetAllKeys()
十五、网络请求帮助类(<font color="red">LgyUtil.Net</font>)
获取HttpClient对象,使用完,不用释放
NetUtil.GetHttpClient(string url, SocketsHttpHandler _socketsHttpHandler = null)
- 静态ip获取一个永久不变的对象
- 域名则是15分钟刷新一次的对象
发送Post、Get请求
NetUtil.Post
NetUtil.PostAsync
NetUtil.Get
NetUtil.GetAsync
HttpResponseMessage Post(string url, string postData = "", Dictionary<string, string> dicHeader = null, TimeSpan? timeout = null) HttpResponseMessage Get(string url, Dictionary<string, string> dicHeader = null, TimeSpan? timeout = null)
发送Post、Get请求,返回字符串
NetUtil.Post_ReturnString
NetUtil.PostAsync_ReturnString
NetUtil.Get_ReturnString
NetUtil.GetAsync_ReturnString
string Post_ReturnString(string url, string postData = "", Dictionary<string, string> dicHeader = null, TimeSpan? timeout = null) string Get_ReturnString(string url, Dictionary<string, string> dicHeader = null, TimeSpan? timeout = null)
发送Post、Get请求,返回模型类
NetUtil.Post_ReturnModel
NetUtil.PostAsync_ReturnModel
NetUtil.Get_ReturnModel
NetUtil.GetAsync_ReturnModel
T Post_ReturnModel<T>(string url, string postData = "", Dictionary<string, string> dicHeader = null, TimeSpan? timeout = null) T Get_ReturnModel<T>(string url, Dictionary<string, string> dicHeader = null, TimeSpan? timeout = null)
发送Post、Get请求,返回流
NetUtil.Post_ReturnStream
NetUtil.PostAsync_ReturnStream
NetUtil.Get_ReturnStream
NetUtil.GetAsync_ReturnStream
Stream Post_ReturnStream(string url, string postData = "", Dictionary<string, string> dicHeader = null, TimeSpan? timeout = null) Stream Get_ReturnStream(string url, Dictionary<string, string> dicHeader = null, TimeSpan? timeout = null)
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. 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. |
.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. |
-
.NETStandard 2.0
- BouncyCastle.Cryptography (>= 2.2.0)
- Mapster (>= 7.3.0)
- Newtonsoft.Json (>= 13.0.3)
- Quartz (>= 3.6.2)
- System.Collections.Immutable (>= 7.0.0)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on LgyUtil:
Package | Downloads |
---|---|
LgyUtil.Net
源码:https://github.com/lgy123123123/LgyUtil post get请求帮助类(NetUtil) 2.0以后,仅支持net5、6、7 如遇到bug,请将问题发送至邮箱565493752@qq.com,我会第一时间回复并解决 |
|
LgyUtil.Quartz
源码:https://github.com/lgy123123123/LgyUtil 源码:https://gitee.com/linguangyu996/LgyUtil CronUtil,Quartz.net的定时帮助类 如遇到bug,请将问题发送至邮箱565493752@qq.com,我会第一时间回复并解决 |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.8.2 | 96 | 9/13/2024 |
1.8.1 | 99 | 7/16/2024 |
1.8.0 | 122 | 7/4/2024 |
1.7.1 | 132 | 5/9/2024 |
1.7.0 | 117 | 4/25/2024 |
1.6.0 | 440 | 12/28/2023 |
1.5.2 | 509 | 11/22/2023 |
1.5.0 | 486 | 10/24/2023 |
1.4.2 | 499 | 10/12/2023 |
1.4.1 | 473 | 9/27/2023 |
1.4.0 | 709 | 8/18/2023 |
1.3.2 | 625 | 8/4/2023 |
1.3.1 | 589 | 8/3/2023 |
1.3.0 | 734 | 8/2/2023 |
1.2.2 | 629 | 7/27/2023 |
1.2.1 | 604 | 7/27/2023 |
1.2.0 | 645 | 7/25/2023 |
1.1.27 | 653 | 7/17/2023 |
1.1.26 | 621 | 7/17/2023 |
1.1.25 | 635 | 7/14/2023 |
1.1.24 | 646 | 7/13/2023 |
1.1.23 | 640 | 7/10/2023 |
1.1.22 | 643 | 7/4/2023 |
1.1.21 | 833 | 6/25/2023 |
1.1.20 | 621 | 5/25/2023 |
1.1.19 | 735 | 4/24/2023 |
1.1.18 | 663 | 4/23/2023 |
1.1.17 | 664 | 4/21/2023 |
1.1.16 | 706 | 4/18/2023 |
1.1.15 | 987 | 3/27/2023 |
1.1.14 | 718 | 3/24/2023 |
1.1.13 | 734 | 3/10/2023 |
1.1.12 | 738 | 3/8/2023 |
1.1.11 | 784 | 3/1/2023 |
1.1.10 | 724 | 2/28/2023 |
1.1.9 | 763 | 2/27/2023 |
1.1.8 | 743 | 2/23/2023 |
1.1.7 | 749 | 2/20/2023 |
1.1.5 | 986 | 2/16/2023 |
1.1.4 | 764 | 2/16/2023 |
1.1.3 | 775 | 2/13/2023 |
1.1.2 | 804 | 1/6/2023 |
1.1.1 | 828 | 1/4/2023 |
1.1.0 | 1,352 | 11/25/2022 |
1.0.16 | 929 | 6/29/2022 |
1.0.15 | 930 | 6/28/2022 |
1.0.14 | 925 | 6/28/2022 |
1.0.13 | 932 | 6/23/2022 |
1.0.12 | 909 | 6/22/2022 |
1.0.11 | 908 | 6/9/2022 |
1.0.10 | 929 | 6/9/2022 |
1.0.9 | 938 | 6/7/2022 |
1.0.8 | 1,153 | 6/7/2022 |
1.0.7 | 907 | 6/7/2022 |
1.0.6 | 924 | 4/21/2022 |
1.0.5 | 1,187 | 4/7/2022 |
1.0.4 | 1,201 | 2/16/2022 |
1.0.3 | 748 | 1/6/2022 |
1.0.2 | 1,015 | 12/17/2021 |
1.0.1 | 1,533 | 11/10/2021 |
1.0.0 | 840 | 11/9/2021 |