From f53a6cf05b8277b4b7756c7992b9d40395cce56e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= <454313500@qq.com> Date: Wed, 20 Mar 2024 17:52:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=AE=A2=E6=88=B7?= =?UTF-8?q?=E7=AB=AF=E4=BB=A3=E7=90=86=E5=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Yi.Abp.Net8/Yi.Abp.sln | 25 ++++++++++- .../client/Yi.Abp.Client.Console/Program.cs | 33 ++++++++++++++ .../Yi.Abp.Client.Console.csproj | 16 +++++++ .../YiAbpClientConsoleModule.cs | 15 +++++++ .../Controllers/AccountController.cs | 37 ++++++++++++++++ .../client/Yi.Abp.Client.WebApi/Program.cs | 28 ++++++++++++ .../Properties/launchSettings.json | 41 ++++++++++++++++++ .../Yi.Abp.Client.WebApi.csproj | 17 ++++++++ .../Yi.Abp.Client.WebApi.http | 6 +++ .../YiAbpClientWebApiModule.cs | 10 +++++ .../appsettings.Development.json | 8 ++++ .../Yi.Abp.Client.WebApi/appsettings.json | 9 ++++ .../Yi.Abp.HttpApi.Client.csproj | 20 +++++++++ .../YiAbpHttpApiClientModule.cs | 32 ++++++++++++++ .../IServices/IAccountService.cs | 6 ++- .../sample/Acme.BookStore.Web/yi-abp-dev.db | Bin 282624 -> 372736 bytes 16 files changed, 300 insertions(+), 3 deletions(-) create mode 100644 Yi.Abp.Net8/client/Yi.Abp.Client.Console/Program.cs create mode 100644 Yi.Abp.Net8/client/Yi.Abp.Client.Console/Yi.Abp.Client.Console.csproj create mode 100644 Yi.Abp.Net8/client/Yi.Abp.Client.Console/YiAbpClientConsoleModule.cs create mode 100644 Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Controllers/AccountController.cs create mode 100644 Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Program.cs create mode 100644 Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Properties/launchSettings.json create mode 100644 Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Yi.Abp.Client.WebApi.csproj create mode 100644 Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Yi.Abp.Client.WebApi.http create mode 100644 Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/YiAbpClientWebApiModule.cs create mode 100644 Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/appsettings.Development.json create mode 100644 Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/appsettings.json create mode 100644 Yi.Abp.Net8/client/Yi.Abp.HttpApi.Client/Yi.Abp.HttpApi.Client.csproj create mode 100644 Yi.Abp.Net8/client/Yi.Abp.HttpApi.Client/YiAbpHttpApiClientModule.cs diff --git a/Yi.Abp.Net8/Yi.Abp.sln b/Yi.Abp.Net8/Yi.Abp.sln index 7a75e175..8a606d74 100644 --- a/Yi.Abp.Net8/Yi.Abp.sln +++ b/Yi.Abp.Net8/Yi.Abp.sln @@ -117,7 +117,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.CodeGen.Domain EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Caching.FreeRedis", "framework\Yi.Framework.Caching.FreeRedis\Yi.Framework.Caching.FreeRedis.csproj", "{862BB0EF-3D4E-44FF-AB15-0EB74CE553D3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.CodeGen.SqlSugarCore", "module\code-gen\Yi.Framework.CodeGen.SqlSugarCore\Yi.Framework.CodeGen.SqlSugarCore.csproj", "{FB09ACC2-A27D-4D87-8D85-1435FDED4D04}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.CodeGen.SqlSugarCore", "module\code-gen\Yi.Framework.CodeGen.SqlSugarCore\Yi.Framework.CodeGen.SqlSugarCore.csproj", "{FB09ACC2-A27D-4D87-8D85-1435FDED4D04}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "client", "client", "{8B27846A-043D-4F2F-8140-5CEC9D1863B5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Abp.HttpApi.Client", "client\Yi.Abp.HttpApi.Client\Yi.Abp.HttpApi.Client.csproj", "{6B554DCC-3A81-4624-9141-4E39365ADA35}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Abp.Client.Console", "client\Yi.Abp.Client.Console\Yi.Abp.Client.Console.csproj", "{2D23B44A-DFA3-4C36-8516-4F5AE442403C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Abp.Client.WebApi", "client\Yi.Abp.Client.WebApi\Yi.Abp.Client.WebApi.csproj", "{00E49781-C6A0-491C-86A1-46F685C90915}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -301,6 +309,18 @@ Global {FB09ACC2-A27D-4D87-8D85-1435FDED4D04}.Debug|Any CPU.Build.0 = Debug|Any CPU {FB09ACC2-A27D-4D87-8D85-1435FDED4D04}.Release|Any CPU.ActiveCfg = Release|Any CPU {FB09ACC2-A27D-4D87-8D85-1435FDED4D04}.Release|Any CPU.Build.0 = Release|Any CPU + {6B554DCC-3A81-4624-9141-4E39365ADA35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6B554DCC-3A81-4624-9141-4E39365ADA35}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6B554DCC-3A81-4624-9141-4E39365ADA35}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6B554DCC-3A81-4624-9141-4E39365ADA35}.Release|Any CPU.Build.0 = Release|Any CPU + {2D23B44A-DFA3-4C36-8516-4F5AE442403C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2D23B44A-DFA3-4C36-8516-4F5AE442403C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2D23B44A-DFA3-4C36-8516-4F5AE442403C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2D23B44A-DFA3-4C36-8516-4F5AE442403C}.Release|Any CPU.Build.0 = Release|Any CPU + {00E49781-C6A0-491C-86A1-46F685C90915}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {00E49781-C6A0-491C-86A1-46F685C90915}.Debug|Any CPU.Build.0 = Debug|Any CPU + {00E49781-C6A0-491C-86A1-46F685C90915}.Release|Any CPU.ActiveCfg = Release|Any CPU + {00E49781-C6A0-491C-86A1-46F685C90915}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -355,6 +375,9 @@ Global {EEFF0F05-2709-4151-A8CE-667935CEAE0B} = {4FFE7212-21F2-476D-B628-3C65E6C5075E} {862BB0EF-3D4E-44FF-AB15-0EB74CE553D3} = {77B949E9-530E-45A5-9657-20F7D5C6875C} {FB09ACC2-A27D-4D87-8D85-1435FDED4D04} = {4FFE7212-21F2-476D-B628-3C65E6C5075E} + {6B554DCC-3A81-4624-9141-4E39365ADA35} = {8B27846A-043D-4F2F-8140-5CEC9D1863B5} + {2D23B44A-DFA3-4C36-8516-4F5AE442403C} = {8B27846A-043D-4F2F-8140-5CEC9D1863B5} + {00E49781-C6A0-491C-86A1-46F685C90915} = {8B27846A-043D-4F2F-8140-5CEC9D1863B5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {23D6FBC9-C970-4641-BC1E-2AEA59F51C18} diff --git a/Yi.Abp.Net8/client/Yi.Abp.Client.Console/Program.cs b/Yi.Abp.Net8/client/Yi.Abp.Client.Console/Program.cs new file mode 100644 index 00000000..31d28fb0 --- /dev/null +++ b/Yi.Abp.Net8/client/Yi.Abp.Client.Console/Program.cs @@ -0,0 +1,33 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Yi.Abp.Client.Console; +using Yi.Framework.Rbac.Application.Contracts.IServices; + +try +{ + IHost host = Host.CreateDefaultBuilder() + .ConfigureServices(async (host, service) => + { + await service.AddApplicationAsync(); + }) + .UseAutofac() + .Build(); + + //控制台直接调用 + var account = host.Services.GetRequiredService(); + + //获取验证码 + var data1 = await account.GetCaptchaImageAsync(); + + //登录 + var data2 = await account.PostLoginAsync(new Yi.Framework.Rbac.Application.Contracts.Dtos.Account.LoginInputVo { UserName = "cc", Password = "123456", Code = string.Empty, Uuid = string.Empty }); + + + host.Run(); + +} +catch (Exception ex) +{ + Console.WriteLine(ex.Message); + Console.WriteLine(ex.StackTrace); +} \ No newline at end of file diff --git a/Yi.Abp.Net8/client/Yi.Abp.Client.Console/Yi.Abp.Client.Console.csproj b/Yi.Abp.Net8/client/Yi.Abp.Client.Console/Yi.Abp.Client.Console.csproj new file mode 100644 index 00000000..fe3855c3 --- /dev/null +++ b/Yi.Abp.Net8/client/Yi.Abp.Client.Console/Yi.Abp.Client.Console.csproj @@ -0,0 +1,16 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + diff --git a/Yi.Abp.Net8/client/Yi.Abp.Client.Console/YiAbpClientConsoleModule.cs b/Yi.Abp.Net8/client/Yi.Abp.Client.Console/YiAbpClientConsoleModule.cs new file mode 100644 index 00000000..1ba0742d --- /dev/null +++ b/Yi.Abp.Net8/client/Yi.Abp.Client.Console/YiAbpClientConsoleModule.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Modularity; +using Yi.Abp.HttpApi.Client; + +namespace Yi.Abp.Client.Console +{ + [DependsOn(typeof(YiAbpHttpApiClientModule))] + public class YiAbpClientConsoleModule:AbpModule + { + } +} diff --git a/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Controllers/AccountController.cs b/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Controllers/AccountController.cs new file mode 100644 index 00000000..315a1b1e --- /dev/null +++ b/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Controllers/AccountController.cs @@ -0,0 +1,37 @@ +using Microsoft.AspNetCore.Mvc; +using Yi.Framework.Rbac.Application.Contracts.Dtos.Account; +using Yi.Framework.Rbac.Application.Contracts.IServices; + +namespace Yi.Abp.Client.WebApi.Controllers +{ + [ApiController] + [Route("[controller]")] + public class AccountController : ControllerBase + { + + + private readonly ILogger _logger; + private IAccountService _accountService; + public AccountController(ILogger logger, IAccountService accountService) + { + _logger = logger; + _accountService = accountService; + } + + [HttpPost("my-login")] + public async Task Login(LoginInputVo input) + { + await _accountService.PostLoginAsync(input); + return Ok(); + } + + + + [HttpGet("my-captcha-image")] + public async Task CaptchaImageAsync() + { + var output = await _accountService.GetCaptchaImageAsync(); + return Ok(output); + } + } +} diff --git a/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Program.cs b/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Program.cs new file mode 100644 index 00000000..e57274dd --- /dev/null +++ b/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Program.cs @@ -0,0 +1,28 @@ +using Autofac.Core; +using Yi.Abp.Client.WebApi; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +builder.Host.UseAutofac(); +builder.Services.AddControllers(); +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); +await builder.Services.AddApplicationAsync(); +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); diff --git a/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Properties/launchSettings.json b/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Properties/launchSettings.json new file mode 100644 index 00000000..d2d6c82d --- /dev/null +++ b/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:35597", + "sslPort": 44322 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5002", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7108;http://localhost:5002", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Yi.Abp.Client.WebApi.csproj b/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Yi.Abp.Client.WebApi.csproj new file mode 100644 index 00000000..19766ae3 --- /dev/null +++ b/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Yi.Abp.Client.WebApi.csproj @@ -0,0 +1,17 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + diff --git a/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Yi.Abp.Client.WebApi.http b/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Yi.Abp.Client.WebApi.http new file mode 100644 index 00000000..9d4c7641 --- /dev/null +++ b/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/Yi.Abp.Client.WebApi.http @@ -0,0 +1,6 @@ +@Yi.Abp.Client.WebApi_HostAddress = http://localhost:5002 + +GET {{Yi.Abp.Client.WebApi_HostAddress}}/weatherforecast/ +Accept: application/json + +### diff --git a/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/YiAbpClientWebApiModule.cs b/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/YiAbpClientWebApiModule.cs new file mode 100644 index 00000000..f6100d97 --- /dev/null +++ b/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/YiAbpClientWebApiModule.cs @@ -0,0 +1,10 @@ +using Volo.Abp.Modularity; +using Yi.Abp.HttpApi.Client; + +namespace Yi.Abp.Client.WebApi +{ + [DependsOn(typeof(YiAbpHttpApiClientModule))] + public class YiAbpClientWebApiModule:AbpModule + { + } +} diff --git a/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/appsettings.Development.json b/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/appsettings.Development.json new file mode 100644 index 00000000..0c208ae9 --- /dev/null +++ b/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/appsettings.json b/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/appsettings.json new file mode 100644 index 00000000..10f68b8c --- /dev/null +++ b/Yi.Abp.Net8/client/Yi.Abp.Client.WebApi/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/Yi.Abp.Net8/client/Yi.Abp.HttpApi.Client/Yi.Abp.HttpApi.Client.csproj b/Yi.Abp.Net8/client/Yi.Abp.HttpApi.Client/Yi.Abp.HttpApi.Client.csproj new file mode 100644 index 00000000..4fcf9216 --- /dev/null +++ b/Yi.Abp.Net8/client/Yi.Abp.HttpApi.Client/Yi.Abp.HttpApi.Client.csproj @@ -0,0 +1,20 @@ + + + + net8.0 + enable + enable + Library + + + + + + + + + + + + + diff --git a/Yi.Abp.Net8/client/Yi.Abp.HttpApi.Client/YiAbpHttpApiClientModule.cs b/Yi.Abp.Net8/client/Yi.Abp.HttpApi.Client/YiAbpHttpApiClientModule.cs new file mode 100644 index 00000000..5a9b0638 --- /dev/null +++ b/Yi.Abp.Net8/client/Yi.Abp.HttpApi.Client/YiAbpHttpApiClientModule.cs @@ -0,0 +1,32 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Autofac; +using Volo.Abp.Http.Client; +using Volo.Abp.Modularity; +using Yi.Framework.Rbac.Application.Contracts; + +namespace Yi.Abp.HttpApi.Client +{ + [DependsOn(typeof(AbpHttpClientModule), + typeof(AbpAutofacModule), + + + typeof(YiFrameworkRbacApplicationContractsModule))] + public class YiAbpHttpApiClientModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + //创建动态客户端代理 + context.Services.AddHttpClientProxies( + typeof(YiFrameworkRbacApplicationContractsModule).Assembly + + ); + Configure(options => + { + options.RemoteServices.Default = + new RemoteServiceConfiguration("http://localhost:19001"); + }); + } + + + } +} diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application.Contracts/IServices/IAccountService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application.Contracts/IServices/IAccountService.cs index 046a6ada..63f29c33 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application.Contracts/IServices/IAccountService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application.Contracts/IServices/IAccountService.cs @@ -1,11 +1,13 @@ -using Yi.Framework.Rbac.Application.Contracts.Dtos.Account; +using Volo.Abp.Application.Services; +using Yi.Framework.Rbac.Application.Contracts.Dtos.Account; using Yi.Framework.Rbac.Domain.Shared.Dtos; namespace Yi.Framework.Rbac.Application.Contracts.IServices { - public interface IAccountService + public interface IAccountService : IApplicationService { Task Get(); + Task GetCaptchaImageAsync(); Task PostLoginAsync(LoginInputVo input); } } diff --git a/Yi.Abp.Net8/sample/Acme.BookStore.Web/yi-abp-dev.db b/Yi.Abp.Net8/sample/Acme.BookStore.Web/yi-abp-dev.db index 0dd9bece05faac559186c5229a648142bb9b21d5..a74693eb7e606f779e16e4e254ca92aec87d6d67 100644 GIT binary patch delta 4270 zcmdT{e{3699lv+y_+rQQB@5wdl9o%eE(y-1KL0kQ&C(?8vLfEF8PD z&ufNMUD9mXU=r)rKOPfNffP1m@2IZF-LX8-WTWA!y548tBk-@?c9OqRUndyx}h>2 zpl(s0P=BUwoSl&=3K4ePi-vo)qoMZ8^S7w{Eee>c&FJS{*dinuu*Gu9dc%4FTf`oR z?F<-KS*<(jAUJ?K;n)No$iK^gYnJ@VL-;0e{4&lxVQK?;Qyczy6N^Nv@$(q<4h0;) zwSQ(`s``7?k~Ly&sk~Bo+F0L-`96xCP|jc$wH$ z0bRrR_Iz>>|0RGOBlvF1P%BBZEO;ye#bNwirHz^FPp70uCmB%^64QJV5qf40NtuL{ z5~N8cmY7PUWJK&vWQANdJCK`>NtsCo5v3_9gBV@u>1in?-_Gcq%1BZfxz*KTraPPf zOQb|;Cj0R5MLPvIMQ|!VJA!``z)#1}Y?~waWdLuD<1W}dj$g^QA3)*Y%?!NM3>vCB zbMn`toH{n0t2Qw|GF3BAm`>tdH6VgH-mqV@ziK;Sd6GOq%H}QPPSa4uUx}OeUBs`! zMG$d(Zf9(lZI9S!>?$@}wP^WE)e)={{gFxVg&`Nbd^gyn^rFx*QdS<8gmgyCM!7P= zK{AQG-CPeI)nd?w=wOnUrC!lUQlx9Rr*pK2=^g0qIe=1yLM=!z`v;1-oNSpi^d_0k ztk62xYo?p(2f@Q7hDQ@}QZmeru47i?ml@S)x=A!u7d$qBe@W?+9+8q!PJ8slJ4kvP z3+BiYPm!#Y=@oa!vg%9EjGW-f|qHK*m`C?uV$yC2zQrd#X4;Y3P7InWcK z@(1{7Nt630)>Xb{UllTJsx;l|eEZi(+UW!fL79&wrGd1Z5R7rJVQ{o_cV7>)RcCE& zv0LGuI&g1QQZX?5*9{zH3% zqFab^`t!c%4w80l26IG7;`-8PiKr9RUeK^-ov4aJT37{16k3sC#MT%l>AE_wuuY3C zKY5z45xC`N`P56qUfhIX_(u>e@2>{t$v%?aycs;sYl6G^)Hk~Lj97S%uT4aO42NDM zeDKL}{BHRAD};&cmJX$}2^rpO0?x`lJ}Y-;_`}*S`25R66P(=!Otuj@o#Ce>ZJ&V0 zYQZL|pPwlwI>}rzi5AYZrfn-Y9Fch$o_&$fa=N`A{%R{|PzuZ_S9m*sVZ?r}9?VfC ziS5cryqrjk+RzfLjlIfPvB10KeK6D{Zpv050z_shK4~~>rALKJ=gDe^!w(8c8TD|1zRy_pRqu9M9P19gLs+Ck< zs_L@cx3-uXL#t#}E~A>(2{mZ*vh^oY#qAqDT??F$IYTr;XFJ#oO{2JzK&`EAn|ae) z#NU)tm)y@XCM!WLW7KEVO=|h4HPyeTnk$JqAfp`+w-7X#%Aq%+f~c_wf)$-e1ht@^ zNQ=}05}u*p)g{nkY9S&3?pi`^wYUVn(qKn&R{IJ@y-7hTMzuLUaa?kI+cE0cVqZa8 zZ`u`~m5cz~iD5w@CVIr6oArtw9~6eyY_<_%2 zXvKLU7znz<)TaG31T0Tr9w`9?@@1Q86Mj6Dxmu<-4j{MM2H$^TfOX9~*NEewOniKQW&3t#MX? zA6Q;Ev3z0PXDUYK_lu$zh2s`IY%s`sSs{dyQkq2*Xj?w_ihW2k%fITW?sHqu(()c!kp)qLr4xA|(tU0v#hphM?JIsG{>H@sWBiyT$7Jx8bNW540cxQpn- u)r|$7JVR7K{CHY&b|4$KU5&dgyr<@YB)XJ)RHl8}8GNf+Mblw6-l||IW)| z8#DY6D`LdCt}BWsF-p}5+@Uto_yXvD8WTq4R9M>;i@~)^^llR0((OqcQ|Sy|0gUXK zzv~Xr(F{uUJBw>T%`7HpJBJ(8%wfc#k1$8a74<5QIta!@jGDWlmljMI!SH@s%VEHm zEEY=BQ^SAT0mkgdRX%C0)7(RzK%1mm3R`q0h5IZ4{)3*6<0`Gx`KUGGXIh%T6Zp>@ zW$Dg