From 49038de2b5453088fd4325440f46d41620519280 Mon Sep 17 00:00:00 2001 From: Piotr Dudek Date: Fri, 11 Jul 2025 00:18:14 +0200 Subject: [PATCH] New version --- .gitignore | 55 + Drab.Core/Configuration/DrabSettings.cs | 9 + Drab.Core/Configuration/IDrabSettings.cs | 8 + .../Configuration/LocalDbConfiguration.cs | 9 + Drab.Core/Configuration/PcmDbConfiguration.cs | 13 + Drab.Core/Drab.Core.csproj | 17 + Drab.Core/Ioc/IocCoreRegister.cs | 13 + Drab.Core/Models/Result.cs | 82 + Drab.LocalDb/Drab.LocalDb.csproj | 19 + Drab.LocalDb/Entities/OrderDb.cs | 16 + Drab.LocalDb/IoC/ILocalDbConfiguration.cs | 6 + Drab.LocalDb/IoC/IocLocalDbRegister.cs | 13 + Drab.LocalDb/LocalDbContext.cs | 18 + .../20211101180516_Initial.Designer.cs | 52 + .../Migrations/20211101180516_Initial.cs | 35 + .../Migrations/LocalDbContextModelSnapshot.cs | 50 + Drab.Logic/Constants.cs | 11 + Drab.Logic/Drab.Logic.csproj | 42 + Drab.Logic/Dtos/DokDto.cs | 32 + Drab.Logic/Dtos/MagDto.cs | 23 + Drab.Logic/Dtos/PozDokDto.cs | 26 + Drab.Logic/Dtos/TowarDto.cs | 25 + Drab.Logic/Interfaces/IDbFetcher.cs | 8 + Drab.Logic/Interfaces/ILocalOrderStore.cs | 12 + Drab.Logic/Interfaces/IOrderPdfGenerator.cs | 9 + Drab.Logic/Interfaces/IOrderProcessor.cs | 9 + Drab.Logic/Interfaces/IOrderStore.cs | 12 + Drab.Logic/Interfaces/IPrintService.cs | 9 + Drab.Logic/Ioc/IocLogicRegister.cs | 21 + Drab.Logic/Models/PrintDocument.cs | 7 + Drab.Logic/Services/LocalOrderStore.cs | 47 + .../Services/OldOrdersCleanupService.cs | 58 + Drab.Logic/Services/OrderEventBus.cs | 13 + Drab.Logic/Services/OrderPdfGenerator.cs | 51 + Drab.Logic/Services/OrderProcessor.cs | 154 + Drab.Logic/Services/OrdersStore.cs | 78 + Drab.Logic/Services/PrintService.cs | 71 + Drab.Logic/System.Printing.dll | Bin 0 -> 158256 bytes Drab.Logic/Templates/Order.frx | 90 + Drab.Logic/Utils/DbFetcher.cs | 62 + Drab.sln | 49 + Drab.sln.DotSettings.user | 4 + Drab/Drab.csproj | 35 + Drab/Drab.csproj.user | 10 + Drab/FileController.cs | 18 + Drab/Program.cs | 79 + .../PublishProfiles/FolderProfile.pubxml | 24 + .../PublishProfiles/FolderProfile.pubxml.user | 11 + Drab/Properties/launchSettings.json | 28 + Drab/Ui/App.razor | 25 + Drab/Ui/Pages/Index.razor | 109 + Drab/Ui/_Imports.razor | 1 + Drab/Ui/components/MainLayout.razor | 18 + Drab/Ui/components/PdfViewer.razor | 9 + Drab/Ui/components/Routes.razor | 12 + Drab/add migration.txt | 1 + Drab/appsettings.Development.json | 10 + Drab/appsettings.json | 26 + Drab/nlog.config | 33 + Drab/wwwroot/css/common.css | 37 + Pcm.Db/Entities/Akwizytor.cs | 20 + Pcm.Db/Entities/Artykul.cs | 21 + Pcm.Db/Entities/Asort.cs | 43 + Pcm.Db/Entities/Bank.cs | 26 + Pcm.Db/Entities/Blokadum.cs | 14 + Pcm.Db/Entities/CentrStanZgody.cs | 19 + Pcm.Db/Entities/Cza.cs | 20 + Pcm.Db/Entities/DefinicjaKodu.cs | 25 + Pcm.Db/Entities/Dok.cs | 134 + Pcm.Db/Entities/DokDodKth.cs | 13 + Pcm.Db/Entities/DokKasa.cs | 12 + Pcm.Db/Entities/DokKontoBankowe.cs | 12 + Pcm.Db/Entities/DokKontr.cs | 15 + Pcm.Db/Entities/DokKur.cs | 18 + Pcm.Db/Entities/DokPunkty.cs | 15 + Pcm.Db/Entities/DokWalutum.cs | 15 + Pcm.Db/Entities/DostProd.cs | 13 + Pcm.Db/Entities/Dostawca.cs | 15 + Pcm.Db/Entities/DzienRozl.cs | 22 + Pcm.Db/Entities/DzienRozlParam.cs | 14 + Pcm.Db/Entities/FormZgod.cs | 14 + Pcm.Db/Entities/FormaPlatnPos7.cs | 27 + Pcm.Db/Entities/FormaPlatnosci.cs | 11 + Pcm.Db/Entities/GrWartosc.cs | 13 + Pcm.Db/Entities/GrupaAkcyzowa.cs | 32 + Pcm.Db/Entities/GrupaTow.cs | 19 + Pcm.Db/Entities/GrupaUz.cs | 12 + Pcm.Db/Entities/HarmCeny.cs | 22 + Pcm.Db/Entities/HarmCykl.cs | 16 + Pcm.Db/Entities/HarmHarm.cs | 13 + Pcm.Db/Entities/HarmWpi.cs | 38 + Pcm.Db/Entities/Istw.cs | 26 + Pcm.Db/Entities/Jm.cs | 22 + Pcm.Db/Entities/KartaLoj.cs | 31 + Pcm.Db/Entities/KasKod.cs | 30 + Pcm.Db/Entities/KasPar.cs | 12 + Pcm.Db/Entities/KasTow.cs | 20 + Pcm.Db/Entities/Kasa.cs | 41 + Pcm.Db/Entities/KasaFormaPlatn.cs | 13 + Pcm.Db/Entities/KatParam.cs | 14 + Pcm.Db/Entities/Kategorium.cs | 21 + Pcm.Db/Entities/KodDod.cs | 19 + Pcm.Db/Entities/KodWazony.cs | 18 + Pcm.Db/Entities/Komentarz.cs | 11 + Pcm.Db/Entities/Konfig.cs | 10 + Pcm.Db/Entities/KontoBankowe.cs | 35 + Pcm.Db/Entities/KontoBankoweKontr.cs | 23 + Pcm.Db/Entities/KontoLoj.cs | 44 + Pcm.Db/Entities/KontrOpi.cs | 12 + Pcm.Db/Entities/Kontrahent.cs | 155 + Pcm.Db/Entities/Kraj.cs | 33 + Pcm.Db/Entities/KrajStawka.cs | 12 + Pcm.Db/Entities/KthParWartosc.cs | 25 + Pcm.Db/Entities/KthParam.cs | 22 + Pcm.Db/Entities/KthTypO.cs | 12 + Pcm.Db/Entities/KthWartosc.cs | 12 + Pcm.Db/Entities/KursWaluty.cs | 21 + Pcm.Db/Entities/LiniaLotnicza.cs | 14 + Pcm.Db/Entities/LogOperation.cs | 30 + Pcm.Db/Entities/LogTypeDef.cs | 14 + Pcm.Db/Entities/LogValChangeNum.cs | 17 + Pcm.Db/Entities/LogValChangeTxt.cs | 17 + Pcm.Db/Entities/Lotnisko.cs | 16 + Pcm.Db/Entities/Magazyn.cs | 37 + Pcm.Db/Entities/MarZakre.cs | 13 + Pcm.Db/Entities/Marzownik.cs | 31 + Pcm.Db/Entities/Notatki.cs | 13 + Pcm.Db/Entities/NrRej.cs | 21 + Pcm.Db/Entities/NrRejKartum.cs | 13 + Pcm.Db/Entities/NumDok.cs | 19 + Pcm.Db/Entities/NumMag.cs | 14 + Pcm.Db/Entities/OdbProd.cs | 13 + Pcm.Db/Entities/Odbiorca.cs | 18 + Pcm.Db/Entities/OfKod.cs | 14 + Pcm.Db/Entities/OfSlownik.cs | 13 + Pcm.Db/Entities/Ofertum.cs | 37 + Pcm.Db/Entities/OpisZdarzLoj.cs | 17 + Pcm.Db/Entities/Oplatum.cs | 24 + Pcm.Db/Entities/Osoba.cs | 11 + Pcm.Db/Entities/Panel.cs | 35 + Pcm.Db/Entities/PanelParam.cs | 12 + Pcm.Db/Entities/ParBon.cs | 14 + Pcm.Db/Entities/ParPunkty.cs | 15 + Pcm.Db/Entities/ParWalutum.cs | 15 + Pcm.Db/Entities/ParWartosc.cs | 13 + Pcm.Db/Entities/Paragon.cs | 56 + Pcm.Db/Entities/Parametr.cs | 28 + Pcm.Db/Entities/Partium.cs | 27 + Pcm.Db/Entities/PcfUser.cs | 27 + Pcm.Db/Entities/Ph.cs | 27 + Pcm.Db/Entities/Phdane.cs | 12 + Pcm.Db/Entities/PhodbDane.cs | 13 + Pcm.Db/Entities/Phodbiorca.cs | 20 + Pcm.Db/Entities/Phrozliczenie.cs | 16 + Pcm.Db/Entities/PolMag.cs | 12 + Pcm.Db/Entities/PolParam.cs | 13 + Pcm.Db/Entities/Polityka.cs | 25 + Pcm.Db/Entities/PowKontLoj.cs | 13 + Pcm.Db/Entities/Powiadomienie.cs | 30 + Pcm.Db/Entities/PowiadomienieParam.cs | 14 + Pcm.Db/Entities/Powiazanie.cs | 14 + Pcm.Db/Entities/PowiazanieSklep.cs | 16 + Pcm.Db/Entities/PowiazanieUz.cs | 12 + Pcm.Db/Entities/PowiazanieUzNaSklep.cs | 12 + Pcm.Db/Entities/PozAkcyza.cs | 14 + Pcm.Db/Entities/PozDok.cs | 60 + Pcm.Db/Entities/PozPar.cs | 31 + Pcm.Db/Entities/PozParSzczeg.cs | 12 + Pcm.Db/Entities/PozWz.cs | 15 + Pcm.Db/Entities/Profil.cs | 28 + Pcm.Db/Entities/ProfilKasa.cs | 12 + Pcm.Db/Entities/ProfilKonfig.cs | 18 + Pcm.Db/Entities/PrtMag.cs | 41 + Pcm.Db/Entities/Przydzial.cs | 12 + Pcm.Db/Entities/RapWartPocz.cs | 28 + Pcm.Db/Entities/RapWartPoczDane.cs | 15 + Pcm.Db/Entities/Regula.cs | 61 + Pcm.Db/Entities/RegulaAsort.cs | 13 + Pcm.Db/Entities/RegulaDok.cs | 30 + Pcm.Db/Entities/RegulaDokSzczeg.cs | 16 + Pcm.Db/Entities/RegulaKod.cs | 15 + Pcm.Db/Entities/RegulaPar.cs | 30 + Pcm.Db/Entities/RegulaParSzczeg.cs | 16 + Pcm.Db/Entities/RegulaParam.cs | 13 + Pcm.Db/Entities/RegulaPozDok.cs | 16 + Pcm.Db/Entities/RegulaPozDokSzczeg.cs | 22 + Pcm.Db/Entities/RegulaPozPar.cs | 16 + Pcm.Db/Entities/RegulaPozParSzczeg.cs | 22 + Pcm.Db/Entities/RegulaProg.cs | 15 + Pcm.Db/Entities/RegulaSklep.cs | 16 + Pcm.Db/Entities/RegulaTowar.cs | 16 + Pcm.Db/Entities/Rola.cs | 24 + Pcm.Db/Entities/RozPrtMag.cs | 20 + Pcm.Db/Entities/RozbicieDok.cs | 15 + Pcm.Db/Entities/Rozlicza.cs | 15 + Pcm.Db/Entities/RozliczeniePartii.cs | 15 + Pcm.Db/Entities/Sesja.cs | 23 + Pcm.Db/Entities/SesjaAktywna.cs | 22 + Pcm.Db/Entities/SkladnikDefinicjiKodu.cs | 14 + Pcm.Db/Entities/SkladnikWzorca.cs | 32 + Pcm.Db/Entities/Sklep.cs | 98 + Pcm.Db/Entities/SklepArtykul.cs | 22 + Pcm.Db/Entities/SklepBank.cs | 27 + Pcm.Db/Entities/SklepDefinicjaKodu.cs | 27 + Pcm.Db/Entities/SklepDok.cs | 119 + Pcm.Db/Entities/SklepDokDodKth.cs | 14 + Pcm.Db/Entities/SklepDokKur.cs | 19 + Pcm.Db/Entities/SklepDokPunkty.cs | 17 + Pcm.Db/Entities/SklepDokWalutum.cs | 16 + Pcm.Db/Entities/SklepDost.cs | 16 + Pcm.Db/Entities/SklepDzienRozl.cs | 24 + Pcm.Db/Entities/SklepDzienRozlParam.cs | 15 + Pcm.Db/Entities/SklepFlagi.cs | 35 + Pcm.Db/Entities/SklepFormZgod.cs | 15 + Pcm.Db/Entities/SklepFormaPlatnPos7.cs | 29 + Pcm.Db/Entities/SklepGrupaAkcyzowa.cs | 23 + Pcm.Db/Entities/SklepGrupaUz.cs | 13 + Pcm.Db/Entities/SklepIstw.cs | 18 + Pcm.Db/Entities/SklepKartaLoj.cs | 30 + Pcm.Db/Entities/SklepKasa.cs | 31 + Pcm.Db/Entities/SklepKasaFormaPlatn.cs | 14 + Pcm.Db/Entities/SklepKontoBankowe.cs | 26 + Pcm.Db/Entities/SklepKontoBankoweKontr.cs | 24 + Pcm.Db/Entities/SklepKontoLoj.cs | 36 + Pcm.Db/Entities/SklepKontr.cs | 88 + Pcm.Db/Entities/SklepKontrOpi.cs | 13 + Pcm.Db/Entities/SklepKontrSklep.cs | 26 + Pcm.Db/Entities/SklepKthPrzydzial.cs | 12 + Pcm.Db/Entities/SklepKthTypO.cs | 13 + Pcm.Db/Entities/SklepMagazyn.cs | 29 + Pcm.Db/Entities/SklepNarzDost.cs | 13 + Pcm.Db/Entities/SklepNotatki.cs | 14 + Pcm.Db/Entities/SklepNrRej.cs | 22 + Pcm.Db/Entities/SklepNrRejKartum.cs | 14 + Pcm.Db/Entities/SklepOplatum.cs | 25 + Pcm.Db/Entities/SklepPanel.cs | 33 + Pcm.Db/Entities/SklepPanelParam.cs | 13 + Pcm.Db/Entities/SklepParBon.cs | 15 + Pcm.Db/Entities/SklepParPunkty.cs | 17 + Pcm.Db/Entities/SklepParWalutum.cs | 16 + Pcm.Db/Entities/SklepParagon.cs | 58 + Pcm.Db/Entities/SklepPartium.cs | 28 + Pcm.Db/Entities/SklepPowKontLoj.cs | 14 + Pcm.Db/Entities/SklepPowiazanieUz.cs | 13 + Pcm.Db/Entities/SklepPozAkcyza.cs | 15 + Pcm.Db/Entities/SklepPozDok.cs | 52 + Pcm.Db/Entities/SklepPozPar.cs | 32 + Pcm.Db/Entities/SklepPozParSzczeg.cs | 13 + Pcm.Db/Entities/SklepProfil.cs | 29 + Pcm.Db/Entities/SklepProfilKonfig.cs | 19 + Pcm.Db/Entities/SklepPrtMag.cs | 41 + Pcm.Db/Entities/SklepPrzydzial.cs | 12 + Pcm.Db/Entities/SklepRapWartPocz.cs | 30 + Pcm.Db/Entities/SklepRapWartPoczDane.cs | 16 + Pcm.Db/Entities/SklepRegula.cs | 45 + Pcm.Db/Entities/SklepRegulaAsort.cs | 14 + Pcm.Db/Entities/SklepRegulaDok.cs | 32 + Pcm.Db/Entities/SklepRegulaDokSzczeg.cs | 17 + Pcm.Db/Entities/SklepRegulaPar.cs | 32 + Pcm.Db/Entities/SklepRegulaParSzczeg.cs | 17 + Pcm.Db/Entities/SklepRegulaParam.cs | 15 + Pcm.Db/Entities/SklepRegulaPozDok.cs | 17 + Pcm.Db/Entities/SklepRegulaPozDokSzczeg.cs | 23 + Pcm.Db/Entities/SklepRegulaPozPar.cs | 17 + Pcm.Db/Entities/SklepRegulaPozParSzczeg.cs | 23 + Pcm.Db/Entities/SklepRegulaTowar.cs | 17 + Pcm.Db/Entities/SklepRola.cs | 20 + Pcm.Db/Entities/SklepRozPrtMag.cs | 20 + Pcm.Db/Entities/SklepRozbicieDok.cs | 16 + Pcm.Db/Entities/SklepRozlPartii.cs | 16 + Pcm.Db/Entities/SklepRozlicza.cs | 17 + Pcm.Db/Entities/SklepSkladnikDefinicjiKodu.cs | 15 + Pcm.Db/Entities/SklepSkladnikWzorca.cs | 33 + Pcm.Db/Entities/SklepSklep.cs | 12 + Pcm.Db/Entities/SklepStanPrtMag.cs | 17 + Pcm.Db/Entities/SklepSzczegPrtMag.cs | 14 + Pcm.Db/Entities/SklepTekstDok.cs | 13 + Pcm.Db/Entities/SklepTekstPoz.cs | 14 + Pcm.Db/Entities/SklepTekstZgody.cs | 14 + Pcm.Db/Entities/SklepTowAkcyza.cs | 18 + Pcm.Db/Entities/SklepTowDodatek.cs | 19 + Pcm.Db/Entities/SklepTowKod.cs | 19 + Pcm.Db/Entities/SklepTowPowiazanie.cs | 14 + Pcm.Db/Entities/SklepTowStraty.cs | 14 + Pcm.Db/Entities/SklepTowar.cs | 120 + Pcm.Db/Entities/SklepTowarSkladnika.cs | 18 + Pcm.Db/Entities/SklepTypO.cs | 29 + Pcm.Db/Entities/SklepUprawnienie.cs | 13 + Pcm.Db/Entities/SklepUzytkownik.cs | 52 + Pcm.Db/Entities/SklepWalutum.cs | 41 + Pcm.Db/Entities/SklepZaleznosc.cs | 14 + Pcm.Db/Entities/SklepZasob.cs | 14 + Pcm.Db/Entities/SklepZdarzO.cs | 33 + Pcm.Db/Entities/SklepZdarzOsOpi.cs | 14 + Pcm.Db/Entities/SklepZgodum.cs | 32 + Pcm.Db/Entities/Sprzedaz.cs | 58 + Pcm.Db/Entities/StanPrtMag.cs | 16 + Pcm.Db/Entities/StanZgody.cs | 20 + Pcm.Db/Entities/Struktura73.cs | 13 + Pcm.Db/Entities/Subsy.cs | 19 + Pcm.Db/Entities/SzczegPrtMag.cs | 13 + Pcm.Db/Entities/TabelaAkcyzowa.cs | 16 + Pcm.Db/Entities/TekstDok.cs | 12 + Pcm.Db/Entities/TekstPoz.cs | 13 + Pcm.Db/Entities/TekstZgody.cs | 16 + Pcm.Db/Entities/TowAkcyza.cs | 17 + Pcm.Db/Entities/TowDodatek.cs | 18 + Pcm.Db/Entities/TowKraj.cs | 29 + Pcm.Db/Entities/TowPowiazanie.cs | 13 + Pcm.Db/Entities/TowStraty.cs | 21 + Pcm.Db/Entities/TowStratyDlaSklepu.cs | 14 + Pcm.Db/Entities/TowWartosc.cs | 13 + Pcm.Db/Entities/Towar.cs | 194 + Pcm.Db/Entities/TowarSkladnika.cs | 17 + Pcm.Db/Entities/TypO.cs | 30 + Pcm.Db/Entities/Uprawnienie.cs | 12 + Pcm.Db/Entities/UprawnienieNaSklep.cs | 12 + Pcm.Db/Entities/UzNaSklep.cs | 40 + Pcm.Db/Entities/Uzytkownik.cs | 53 + Pcm.Db/Entities/Vat.cs | 8 + Pcm.Db/Entities/Walutum.cs | 47 + Pcm.Db/Entities/Wersja72.cs | 10 + Pcm.Db/Entities/Wzorzec.cs | 25 + Pcm.Db/Entities/Zaleznosc.cs | 12 + Pcm.Db/Entities/Zasob.cs | 11 + Pcm.Db/Entities/ZdarzLoj.cs | 37 + Pcm.Db/Entities/ZdarzO.cs | 33 + Pcm.Db/Entities/ZdarzOsOpi.cs | 13 + Pcm.Db/Entities/Zgodum.cs | 36 + Pcm.Db/Entities/ZlecKomunikat.cs | 14 + Pcm.Db/Entities/ZlecParam.cs | 13 + Pcm.Db/Entities/Zlecenie.cs | 32 + Pcm.Db/Entities/Zmiana.cs | 27 + Pcm.Db/Entities/ZmianaTabeli.cs | 11 + Pcm.Db/Enums/KontrOpisZnaczenie.cs | 20 + Pcm.Db/Enums/TekstDokZnaczenie.cs | 35 + Pcm.Db/Enums/TypDok.cs | 86 + Pcm.Db/Ioc/IDbConfiguration.cs | 10 + Pcm.Db/Ioc/IocPcmDbRegister.cs | 19 + Pcm.Db/Pcm.Db.csproj | 13 + Pcm.Db/PcmDbContext.cs | 9865 +++++++++++++++++ 341 files changed, 18364 insertions(+) create mode 100644 .gitignore create mode 100644 Drab.Core/Configuration/DrabSettings.cs create mode 100644 Drab.Core/Configuration/IDrabSettings.cs create mode 100644 Drab.Core/Configuration/LocalDbConfiguration.cs create mode 100644 Drab.Core/Configuration/PcmDbConfiguration.cs create mode 100644 Drab.Core/Drab.Core.csproj create mode 100644 Drab.Core/Ioc/IocCoreRegister.cs create mode 100644 Drab.Core/Models/Result.cs create mode 100644 Drab.LocalDb/Drab.LocalDb.csproj create mode 100644 Drab.LocalDb/Entities/OrderDb.cs create mode 100644 Drab.LocalDb/IoC/ILocalDbConfiguration.cs create mode 100644 Drab.LocalDb/IoC/IocLocalDbRegister.cs create mode 100644 Drab.LocalDb/LocalDbContext.cs create mode 100644 Drab.LocalDb/Migrations/20211101180516_Initial.Designer.cs create mode 100644 Drab.LocalDb/Migrations/20211101180516_Initial.cs create mode 100644 Drab.LocalDb/Migrations/LocalDbContextModelSnapshot.cs create mode 100644 Drab.Logic/Constants.cs create mode 100644 Drab.Logic/Drab.Logic.csproj create mode 100644 Drab.Logic/Dtos/DokDto.cs create mode 100644 Drab.Logic/Dtos/MagDto.cs create mode 100644 Drab.Logic/Dtos/PozDokDto.cs create mode 100644 Drab.Logic/Dtos/TowarDto.cs create mode 100644 Drab.Logic/Interfaces/IDbFetcher.cs create mode 100644 Drab.Logic/Interfaces/ILocalOrderStore.cs create mode 100644 Drab.Logic/Interfaces/IOrderPdfGenerator.cs create mode 100644 Drab.Logic/Interfaces/IOrderProcessor.cs create mode 100644 Drab.Logic/Interfaces/IOrderStore.cs create mode 100644 Drab.Logic/Interfaces/IPrintService.cs create mode 100644 Drab.Logic/Ioc/IocLogicRegister.cs create mode 100644 Drab.Logic/Models/PrintDocument.cs create mode 100644 Drab.Logic/Services/LocalOrderStore.cs create mode 100644 Drab.Logic/Services/OldOrdersCleanupService.cs create mode 100644 Drab.Logic/Services/OrderEventBus.cs create mode 100644 Drab.Logic/Services/OrderPdfGenerator.cs create mode 100644 Drab.Logic/Services/OrderProcessor.cs create mode 100644 Drab.Logic/Services/OrdersStore.cs create mode 100644 Drab.Logic/Services/PrintService.cs create mode 100644 Drab.Logic/System.Printing.dll create mode 100644 Drab.Logic/Templates/Order.frx create mode 100644 Drab.Logic/Utils/DbFetcher.cs create mode 100644 Drab.sln create mode 100644 Drab.sln.DotSettings.user create mode 100644 Drab/Drab.csproj create mode 100644 Drab/Drab.csproj.user create mode 100644 Drab/FileController.cs create mode 100644 Drab/Program.cs create mode 100644 Drab/Properties/PublishProfiles/FolderProfile.pubxml create mode 100644 Drab/Properties/PublishProfiles/FolderProfile.pubxml.user create mode 100644 Drab/Properties/launchSettings.json create mode 100644 Drab/Ui/App.razor create mode 100644 Drab/Ui/Pages/Index.razor create mode 100644 Drab/Ui/_Imports.razor create mode 100644 Drab/Ui/components/MainLayout.razor create mode 100644 Drab/Ui/components/PdfViewer.razor create mode 100644 Drab/Ui/components/Routes.razor create mode 100644 Drab/add migration.txt create mode 100644 Drab/appsettings.Development.json create mode 100644 Drab/appsettings.json create mode 100644 Drab/nlog.config create mode 100644 Drab/wwwroot/css/common.css create mode 100644 Pcm.Db/Entities/Akwizytor.cs create mode 100644 Pcm.Db/Entities/Artykul.cs create mode 100644 Pcm.Db/Entities/Asort.cs create mode 100644 Pcm.Db/Entities/Bank.cs create mode 100644 Pcm.Db/Entities/Blokadum.cs create mode 100644 Pcm.Db/Entities/CentrStanZgody.cs create mode 100644 Pcm.Db/Entities/Cza.cs create mode 100644 Pcm.Db/Entities/DefinicjaKodu.cs create mode 100644 Pcm.Db/Entities/Dok.cs create mode 100644 Pcm.Db/Entities/DokDodKth.cs create mode 100644 Pcm.Db/Entities/DokKasa.cs create mode 100644 Pcm.Db/Entities/DokKontoBankowe.cs create mode 100644 Pcm.Db/Entities/DokKontr.cs create mode 100644 Pcm.Db/Entities/DokKur.cs create mode 100644 Pcm.Db/Entities/DokPunkty.cs create mode 100644 Pcm.Db/Entities/DokWalutum.cs create mode 100644 Pcm.Db/Entities/DostProd.cs create mode 100644 Pcm.Db/Entities/Dostawca.cs create mode 100644 Pcm.Db/Entities/DzienRozl.cs create mode 100644 Pcm.Db/Entities/DzienRozlParam.cs create mode 100644 Pcm.Db/Entities/FormZgod.cs create mode 100644 Pcm.Db/Entities/FormaPlatnPos7.cs create mode 100644 Pcm.Db/Entities/FormaPlatnosci.cs create mode 100644 Pcm.Db/Entities/GrWartosc.cs create mode 100644 Pcm.Db/Entities/GrupaAkcyzowa.cs create mode 100644 Pcm.Db/Entities/GrupaTow.cs create mode 100644 Pcm.Db/Entities/GrupaUz.cs create mode 100644 Pcm.Db/Entities/HarmCeny.cs create mode 100644 Pcm.Db/Entities/HarmCykl.cs create mode 100644 Pcm.Db/Entities/HarmHarm.cs create mode 100644 Pcm.Db/Entities/HarmWpi.cs create mode 100644 Pcm.Db/Entities/Istw.cs create mode 100644 Pcm.Db/Entities/Jm.cs create mode 100644 Pcm.Db/Entities/KartaLoj.cs create mode 100644 Pcm.Db/Entities/KasKod.cs create mode 100644 Pcm.Db/Entities/KasPar.cs create mode 100644 Pcm.Db/Entities/KasTow.cs create mode 100644 Pcm.Db/Entities/Kasa.cs create mode 100644 Pcm.Db/Entities/KasaFormaPlatn.cs create mode 100644 Pcm.Db/Entities/KatParam.cs create mode 100644 Pcm.Db/Entities/Kategorium.cs create mode 100644 Pcm.Db/Entities/KodDod.cs create mode 100644 Pcm.Db/Entities/KodWazony.cs create mode 100644 Pcm.Db/Entities/Komentarz.cs create mode 100644 Pcm.Db/Entities/Konfig.cs create mode 100644 Pcm.Db/Entities/KontoBankowe.cs create mode 100644 Pcm.Db/Entities/KontoBankoweKontr.cs create mode 100644 Pcm.Db/Entities/KontoLoj.cs create mode 100644 Pcm.Db/Entities/KontrOpi.cs create mode 100644 Pcm.Db/Entities/Kontrahent.cs create mode 100644 Pcm.Db/Entities/Kraj.cs create mode 100644 Pcm.Db/Entities/KrajStawka.cs create mode 100644 Pcm.Db/Entities/KthParWartosc.cs create mode 100644 Pcm.Db/Entities/KthParam.cs create mode 100644 Pcm.Db/Entities/KthTypO.cs create mode 100644 Pcm.Db/Entities/KthWartosc.cs create mode 100644 Pcm.Db/Entities/KursWaluty.cs create mode 100644 Pcm.Db/Entities/LiniaLotnicza.cs create mode 100644 Pcm.Db/Entities/LogOperation.cs create mode 100644 Pcm.Db/Entities/LogTypeDef.cs create mode 100644 Pcm.Db/Entities/LogValChangeNum.cs create mode 100644 Pcm.Db/Entities/LogValChangeTxt.cs create mode 100644 Pcm.Db/Entities/Lotnisko.cs create mode 100644 Pcm.Db/Entities/Magazyn.cs create mode 100644 Pcm.Db/Entities/MarZakre.cs create mode 100644 Pcm.Db/Entities/Marzownik.cs create mode 100644 Pcm.Db/Entities/Notatki.cs create mode 100644 Pcm.Db/Entities/NrRej.cs create mode 100644 Pcm.Db/Entities/NrRejKartum.cs create mode 100644 Pcm.Db/Entities/NumDok.cs create mode 100644 Pcm.Db/Entities/NumMag.cs create mode 100644 Pcm.Db/Entities/OdbProd.cs create mode 100644 Pcm.Db/Entities/Odbiorca.cs create mode 100644 Pcm.Db/Entities/OfKod.cs create mode 100644 Pcm.Db/Entities/OfSlownik.cs create mode 100644 Pcm.Db/Entities/Ofertum.cs create mode 100644 Pcm.Db/Entities/OpisZdarzLoj.cs create mode 100644 Pcm.Db/Entities/Oplatum.cs create mode 100644 Pcm.Db/Entities/Osoba.cs create mode 100644 Pcm.Db/Entities/Panel.cs create mode 100644 Pcm.Db/Entities/PanelParam.cs create mode 100644 Pcm.Db/Entities/ParBon.cs create mode 100644 Pcm.Db/Entities/ParPunkty.cs create mode 100644 Pcm.Db/Entities/ParWalutum.cs create mode 100644 Pcm.Db/Entities/ParWartosc.cs create mode 100644 Pcm.Db/Entities/Paragon.cs create mode 100644 Pcm.Db/Entities/Parametr.cs create mode 100644 Pcm.Db/Entities/Partium.cs create mode 100644 Pcm.Db/Entities/PcfUser.cs create mode 100644 Pcm.Db/Entities/Ph.cs create mode 100644 Pcm.Db/Entities/Phdane.cs create mode 100644 Pcm.Db/Entities/PhodbDane.cs create mode 100644 Pcm.Db/Entities/Phodbiorca.cs create mode 100644 Pcm.Db/Entities/Phrozliczenie.cs create mode 100644 Pcm.Db/Entities/PolMag.cs create mode 100644 Pcm.Db/Entities/PolParam.cs create mode 100644 Pcm.Db/Entities/Polityka.cs create mode 100644 Pcm.Db/Entities/PowKontLoj.cs create mode 100644 Pcm.Db/Entities/Powiadomienie.cs create mode 100644 Pcm.Db/Entities/PowiadomienieParam.cs create mode 100644 Pcm.Db/Entities/Powiazanie.cs create mode 100644 Pcm.Db/Entities/PowiazanieSklep.cs create mode 100644 Pcm.Db/Entities/PowiazanieUz.cs create mode 100644 Pcm.Db/Entities/PowiazanieUzNaSklep.cs create mode 100644 Pcm.Db/Entities/PozAkcyza.cs create mode 100644 Pcm.Db/Entities/PozDok.cs create mode 100644 Pcm.Db/Entities/PozPar.cs create mode 100644 Pcm.Db/Entities/PozParSzczeg.cs create mode 100644 Pcm.Db/Entities/PozWz.cs create mode 100644 Pcm.Db/Entities/Profil.cs create mode 100644 Pcm.Db/Entities/ProfilKasa.cs create mode 100644 Pcm.Db/Entities/ProfilKonfig.cs create mode 100644 Pcm.Db/Entities/PrtMag.cs create mode 100644 Pcm.Db/Entities/Przydzial.cs create mode 100644 Pcm.Db/Entities/RapWartPocz.cs create mode 100644 Pcm.Db/Entities/RapWartPoczDane.cs create mode 100644 Pcm.Db/Entities/Regula.cs create mode 100644 Pcm.Db/Entities/RegulaAsort.cs create mode 100644 Pcm.Db/Entities/RegulaDok.cs create mode 100644 Pcm.Db/Entities/RegulaDokSzczeg.cs create mode 100644 Pcm.Db/Entities/RegulaKod.cs create mode 100644 Pcm.Db/Entities/RegulaPar.cs create mode 100644 Pcm.Db/Entities/RegulaParSzczeg.cs create mode 100644 Pcm.Db/Entities/RegulaParam.cs create mode 100644 Pcm.Db/Entities/RegulaPozDok.cs create mode 100644 Pcm.Db/Entities/RegulaPozDokSzczeg.cs create mode 100644 Pcm.Db/Entities/RegulaPozPar.cs create mode 100644 Pcm.Db/Entities/RegulaPozParSzczeg.cs create mode 100644 Pcm.Db/Entities/RegulaProg.cs create mode 100644 Pcm.Db/Entities/RegulaSklep.cs create mode 100644 Pcm.Db/Entities/RegulaTowar.cs create mode 100644 Pcm.Db/Entities/Rola.cs create mode 100644 Pcm.Db/Entities/RozPrtMag.cs create mode 100644 Pcm.Db/Entities/RozbicieDok.cs create mode 100644 Pcm.Db/Entities/Rozlicza.cs create mode 100644 Pcm.Db/Entities/RozliczeniePartii.cs create mode 100644 Pcm.Db/Entities/Sesja.cs create mode 100644 Pcm.Db/Entities/SesjaAktywna.cs create mode 100644 Pcm.Db/Entities/SkladnikDefinicjiKodu.cs create mode 100644 Pcm.Db/Entities/SkladnikWzorca.cs create mode 100644 Pcm.Db/Entities/Sklep.cs create mode 100644 Pcm.Db/Entities/SklepArtykul.cs create mode 100644 Pcm.Db/Entities/SklepBank.cs create mode 100644 Pcm.Db/Entities/SklepDefinicjaKodu.cs create mode 100644 Pcm.Db/Entities/SklepDok.cs create mode 100644 Pcm.Db/Entities/SklepDokDodKth.cs create mode 100644 Pcm.Db/Entities/SklepDokKur.cs create mode 100644 Pcm.Db/Entities/SklepDokPunkty.cs create mode 100644 Pcm.Db/Entities/SklepDokWalutum.cs create mode 100644 Pcm.Db/Entities/SklepDost.cs create mode 100644 Pcm.Db/Entities/SklepDzienRozl.cs create mode 100644 Pcm.Db/Entities/SklepDzienRozlParam.cs create mode 100644 Pcm.Db/Entities/SklepFlagi.cs create mode 100644 Pcm.Db/Entities/SklepFormZgod.cs create mode 100644 Pcm.Db/Entities/SklepFormaPlatnPos7.cs create mode 100644 Pcm.Db/Entities/SklepGrupaAkcyzowa.cs create mode 100644 Pcm.Db/Entities/SklepGrupaUz.cs create mode 100644 Pcm.Db/Entities/SklepIstw.cs create mode 100644 Pcm.Db/Entities/SklepKartaLoj.cs create mode 100644 Pcm.Db/Entities/SklepKasa.cs create mode 100644 Pcm.Db/Entities/SklepKasaFormaPlatn.cs create mode 100644 Pcm.Db/Entities/SklepKontoBankowe.cs create mode 100644 Pcm.Db/Entities/SklepKontoBankoweKontr.cs create mode 100644 Pcm.Db/Entities/SklepKontoLoj.cs create mode 100644 Pcm.Db/Entities/SklepKontr.cs create mode 100644 Pcm.Db/Entities/SklepKontrOpi.cs create mode 100644 Pcm.Db/Entities/SklepKontrSklep.cs create mode 100644 Pcm.Db/Entities/SklepKthPrzydzial.cs create mode 100644 Pcm.Db/Entities/SklepKthTypO.cs create mode 100644 Pcm.Db/Entities/SklepMagazyn.cs create mode 100644 Pcm.Db/Entities/SklepNarzDost.cs create mode 100644 Pcm.Db/Entities/SklepNotatki.cs create mode 100644 Pcm.Db/Entities/SklepNrRej.cs create mode 100644 Pcm.Db/Entities/SklepNrRejKartum.cs create mode 100644 Pcm.Db/Entities/SklepOplatum.cs create mode 100644 Pcm.Db/Entities/SklepPanel.cs create mode 100644 Pcm.Db/Entities/SklepPanelParam.cs create mode 100644 Pcm.Db/Entities/SklepParBon.cs create mode 100644 Pcm.Db/Entities/SklepParPunkty.cs create mode 100644 Pcm.Db/Entities/SklepParWalutum.cs create mode 100644 Pcm.Db/Entities/SklepParagon.cs create mode 100644 Pcm.Db/Entities/SklepPartium.cs create mode 100644 Pcm.Db/Entities/SklepPowKontLoj.cs create mode 100644 Pcm.Db/Entities/SklepPowiazanieUz.cs create mode 100644 Pcm.Db/Entities/SklepPozAkcyza.cs create mode 100644 Pcm.Db/Entities/SklepPozDok.cs create mode 100644 Pcm.Db/Entities/SklepPozPar.cs create mode 100644 Pcm.Db/Entities/SklepPozParSzczeg.cs create mode 100644 Pcm.Db/Entities/SklepProfil.cs create mode 100644 Pcm.Db/Entities/SklepProfilKonfig.cs create mode 100644 Pcm.Db/Entities/SklepPrtMag.cs create mode 100644 Pcm.Db/Entities/SklepPrzydzial.cs create mode 100644 Pcm.Db/Entities/SklepRapWartPocz.cs create mode 100644 Pcm.Db/Entities/SklepRapWartPoczDane.cs create mode 100644 Pcm.Db/Entities/SklepRegula.cs create mode 100644 Pcm.Db/Entities/SklepRegulaAsort.cs create mode 100644 Pcm.Db/Entities/SklepRegulaDok.cs create mode 100644 Pcm.Db/Entities/SklepRegulaDokSzczeg.cs create mode 100644 Pcm.Db/Entities/SklepRegulaPar.cs create mode 100644 Pcm.Db/Entities/SklepRegulaParSzczeg.cs create mode 100644 Pcm.Db/Entities/SklepRegulaParam.cs create mode 100644 Pcm.Db/Entities/SklepRegulaPozDok.cs create mode 100644 Pcm.Db/Entities/SklepRegulaPozDokSzczeg.cs create mode 100644 Pcm.Db/Entities/SklepRegulaPozPar.cs create mode 100644 Pcm.Db/Entities/SklepRegulaPozParSzczeg.cs create mode 100644 Pcm.Db/Entities/SklepRegulaTowar.cs create mode 100644 Pcm.Db/Entities/SklepRola.cs create mode 100644 Pcm.Db/Entities/SklepRozPrtMag.cs create mode 100644 Pcm.Db/Entities/SklepRozbicieDok.cs create mode 100644 Pcm.Db/Entities/SklepRozlPartii.cs create mode 100644 Pcm.Db/Entities/SklepRozlicza.cs create mode 100644 Pcm.Db/Entities/SklepSkladnikDefinicjiKodu.cs create mode 100644 Pcm.Db/Entities/SklepSkladnikWzorca.cs create mode 100644 Pcm.Db/Entities/SklepSklep.cs create mode 100644 Pcm.Db/Entities/SklepStanPrtMag.cs create mode 100644 Pcm.Db/Entities/SklepSzczegPrtMag.cs create mode 100644 Pcm.Db/Entities/SklepTekstDok.cs create mode 100644 Pcm.Db/Entities/SklepTekstPoz.cs create mode 100644 Pcm.Db/Entities/SklepTekstZgody.cs create mode 100644 Pcm.Db/Entities/SklepTowAkcyza.cs create mode 100644 Pcm.Db/Entities/SklepTowDodatek.cs create mode 100644 Pcm.Db/Entities/SklepTowKod.cs create mode 100644 Pcm.Db/Entities/SklepTowPowiazanie.cs create mode 100644 Pcm.Db/Entities/SklepTowStraty.cs create mode 100644 Pcm.Db/Entities/SklepTowar.cs create mode 100644 Pcm.Db/Entities/SklepTowarSkladnika.cs create mode 100644 Pcm.Db/Entities/SklepTypO.cs create mode 100644 Pcm.Db/Entities/SklepUprawnienie.cs create mode 100644 Pcm.Db/Entities/SklepUzytkownik.cs create mode 100644 Pcm.Db/Entities/SklepWalutum.cs create mode 100644 Pcm.Db/Entities/SklepZaleznosc.cs create mode 100644 Pcm.Db/Entities/SklepZasob.cs create mode 100644 Pcm.Db/Entities/SklepZdarzO.cs create mode 100644 Pcm.Db/Entities/SklepZdarzOsOpi.cs create mode 100644 Pcm.Db/Entities/SklepZgodum.cs create mode 100644 Pcm.Db/Entities/Sprzedaz.cs create mode 100644 Pcm.Db/Entities/StanPrtMag.cs create mode 100644 Pcm.Db/Entities/StanZgody.cs create mode 100644 Pcm.Db/Entities/Struktura73.cs create mode 100644 Pcm.Db/Entities/Subsy.cs create mode 100644 Pcm.Db/Entities/SzczegPrtMag.cs create mode 100644 Pcm.Db/Entities/TabelaAkcyzowa.cs create mode 100644 Pcm.Db/Entities/TekstDok.cs create mode 100644 Pcm.Db/Entities/TekstPoz.cs create mode 100644 Pcm.Db/Entities/TekstZgody.cs create mode 100644 Pcm.Db/Entities/TowAkcyza.cs create mode 100644 Pcm.Db/Entities/TowDodatek.cs create mode 100644 Pcm.Db/Entities/TowKraj.cs create mode 100644 Pcm.Db/Entities/TowPowiazanie.cs create mode 100644 Pcm.Db/Entities/TowStraty.cs create mode 100644 Pcm.Db/Entities/TowStratyDlaSklepu.cs create mode 100644 Pcm.Db/Entities/TowWartosc.cs create mode 100644 Pcm.Db/Entities/Towar.cs create mode 100644 Pcm.Db/Entities/TowarSkladnika.cs create mode 100644 Pcm.Db/Entities/TypO.cs create mode 100644 Pcm.Db/Entities/Uprawnienie.cs create mode 100644 Pcm.Db/Entities/UprawnienieNaSklep.cs create mode 100644 Pcm.Db/Entities/UzNaSklep.cs create mode 100644 Pcm.Db/Entities/Uzytkownik.cs create mode 100644 Pcm.Db/Entities/Vat.cs create mode 100644 Pcm.Db/Entities/Walutum.cs create mode 100644 Pcm.Db/Entities/Wersja72.cs create mode 100644 Pcm.Db/Entities/Wzorzec.cs create mode 100644 Pcm.Db/Entities/Zaleznosc.cs create mode 100644 Pcm.Db/Entities/Zasob.cs create mode 100644 Pcm.Db/Entities/ZdarzLoj.cs create mode 100644 Pcm.Db/Entities/ZdarzO.cs create mode 100644 Pcm.Db/Entities/ZdarzOsOpi.cs create mode 100644 Pcm.Db/Entities/Zgodum.cs create mode 100644 Pcm.Db/Entities/ZlecKomunikat.cs create mode 100644 Pcm.Db/Entities/ZlecParam.cs create mode 100644 Pcm.Db/Entities/Zlecenie.cs create mode 100644 Pcm.Db/Entities/Zmiana.cs create mode 100644 Pcm.Db/Entities/ZmianaTabeli.cs create mode 100644 Pcm.Db/Enums/KontrOpisZnaczenie.cs create mode 100644 Pcm.Db/Enums/TekstDokZnaczenie.cs create mode 100644 Pcm.Db/Enums/TypDok.cs create mode 100644 Pcm.Db/Ioc/IDbConfiguration.cs create mode 100644 Pcm.Db/Ioc/IocPcmDbRegister.cs create mode 100644 Pcm.Db/Pcm.Db.csproj create mode 100644 Pcm.Db/PcmDbContext.cs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c5fcada --- /dev/null +++ b/.gitignore @@ -0,0 +1,55 @@ +# These are some examples of commonly ignored file patterns. +# You should customize this list as applicable to your project. +# Learn more about .gitignore: +# https://www.atlassian.com/git/tutorials/saving-changes/gitignore + +# Node artifact files +node_modules/ +dist/ + +# Compiled Java class files +*.class + +# Compiled Python bytecode +*.py[cod] + +# Log files +*.log + +# Package files +*.jar + +# Maven +target/ +dist/ + +# JetBrains IDE +.idea/ + +# Unit test reports +TEST*.xml + +# Generated by MacOS +.DS_Store + +# Generated by Windows +Thumbs.db + +# Applications +*.app +*.exe +*.war + +# Large media files +*.mp4 +*.tiff +*.avi +*.flv +*.mov +*.wmv + +.vs +*/bin +*/obj +Drab/.config +Drab/drab.db diff --git a/Drab.Core/Configuration/DrabSettings.cs b/Drab.Core/Configuration/DrabSettings.cs new file mode 100644 index 0000000..5fdd3e0 --- /dev/null +++ b/Drab.Core/Configuration/DrabSettings.cs @@ -0,0 +1,9 @@ +namespace Drab.Core.Configuration; + +public class DrabSettings : IDrabSettings +{ + public const string SectionName = "DrabSettings"; + public int DbPollingFrequencyInSeconds { get; set; } + public int PrinterTimeoutSeconds { get; set; } + public string IgnoreOrdersBefore { get; set; } +} \ No newline at end of file diff --git a/Drab.Core/Configuration/IDrabSettings.cs b/Drab.Core/Configuration/IDrabSettings.cs new file mode 100644 index 0000000..8a42878 --- /dev/null +++ b/Drab.Core/Configuration/IDrabSettings.cs @@ -0,0 +1,8 @@ +namespace Drab.Core.Configuration; + +public interface IDrabSettings +{ + int DbPollingFrequencyInSeconds { get; } + int PrinterTimeoutSeconds { get; } + public string IgnoreOrdersBefore { get; set; } +} \ No newline at end of file diff --git a/Drab.Core/Configuration/LocalDbConfiguration.cs b/Drab.Core/Configuration/LocalDbConfiguration.cs new file mode 100644 index 0000000..cfa3026 --- /dev/null +++ b/Drab.Core/Configuration/LocalDbConfiguration.cs @@ -0,0 +1,9 @@ +using Drab.LocalDb.IoC; + +namespace Drab.Core.Configuration; + +public class LocalDbConfiguration : ILocalDbConfiguration +{ + public const string SectionName = "LocalDbConnection"; + public string ConnectionString { get; set; } +} \ No newline at end of file diff --git a/Drab.Core/Configuration/PcmDbConfiguration.cs b/Drab.Core/Configuration/PcmDbConfiguration.cs new file mode 100644 index 0000000..966b943 --- /dev/null +++ b/Drab.Core/Configuration/PcmDbConfiguration.cs @@ -0,0 +1,13 @@ +using Pcm.Db.Ioc; + +namespace Drab.Core.Configuration; + +public class PcmDbConfiguration : IDbConfiguration +{ + public const string SectionName = "PcmDbSettings"; + public string Host { get; set; } + public string Port { get; set; } + public string User { get; set; } + public string Password { get; set; } + public string Database { get; set; } +} \ No newline at end of file diff --git a/Drab.Core/Drab.Core.csproj b/Drab.Core/Drab.Core.csproj new file mode 100644 index 0000000..8c03505 --- /dev/null +++ b/Drab.Core/Drab.Core.csproj @@ -0,0 +1,17 @@ + + + + net9.0-windows + false + + + + + + + + + + + + diff --git a/Drab.Core/Ioc/IocCoreRegister.cs b/Drab.Core/Ioc/IocCoreRegister.cs new file mode 100644 index 0000000..7b73f85 --- /dev/null +++ b/Drab.Core/Ioc/IocCoreRegister.cs @@ -0,0 +1,13 @@ +using Drab.Core.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace Drab.Core.Ioc; + +public static class IocCoreRegister +{ + public static IServiceCollection AddDrabCore(this IServiceCollection services, IDrabSettings settings) + { + services.AddSingleton(settings); + return services; + } +} \ No newline at end of file diff --git a/Drab.Core/Models/Result.cs b/Drab.Core/Models/Result.cs new file mode 100644 index 0000000..4231941 --- /dev/null +++ b/Drab.Core/Models/Result.cs @@ -0,0 +1,82 @@ +using System; + +namespace Drab.Core.Models; + +public class Result +{ + private TBad _error; + private TOk _ok; + public bool IsOk { get; } + public bool IsNotOk => !IsOk; + + public Result(bool isOk, TOk ok, TBad bad) + { + IsOk = isOk; + + if (IsOk) + { + if (ok == null) + throw new ArgumentNullException(nameof(ok), "If IsOk flag is set to true parameter 'ok' needs to be non null"); + + Value = ok; + } + else + { + if (bad == null) + throw new ArgumentNullException(nameof(bad), "If IsOk flag is set to false parameter 'bad' needs to be non null"); + + Error = bad; + } + } + + public TBad Error + { + get + { + if (IsOk) + throw new InvalidOperationException("Result has IsOk flag set to true only Value property is available"); + return _error; + } + private set => _error = value; + } + + public TOk Value + { + get + { + if (!IsOk) + throw new InvalidOperationException("Result has IsOk flag set to false only Error property is available"); + return _ok; + } + private set => _ok = value; + } + + public Result Map(Func map) where TNew : class + { + if (IsOk) + return new Result(IsOk, map(Value), default); + else + return new Result(false, default, Error); + } + + public TOk ValueWithDefault(Func defaultCreator) => IsOk ? Value : defaultCreator(Error); + + public void Do(Action action) + { + if (IsOk) + action(Value); + } +} + +public class Result +{ + public static Result Failed(TK wrong) + { + return new Result(false, default(T), wrong); + } + + public static Result Ok(T ok) + { + return new Result(true, ok, default(TK)); + } +} \ No newline at end of file diff --git a/Drab.LocalDb/Drab.LocalDb.csproj b/Drab.LocalDb/Drab.LocalDb.csproj new file mode 100644 index 0000000..b2b8cb4 --- /dev/null +++ b/Drab.LocalDb/Drab.LocalDb.csproj @@ -0,0 +1,19 @@ + + + + net9.0-windows + false + + + + + + + + + + + + + + diff --git a/Drab.LocalDb/Entities/OrderDb.cs b/Drab.LocalDb/Entities/OrderDb.cs new file mode 100644 index 0000000..6dc9376 --- /dev/null +++ b/Drab.LocalDb/Entities/OrderDb.cs @@ -0,0 +1,16 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace Drab.LocalDb.Entities; + +public class OrderDb +{ + [Key] + public long OrderId { get; set; } + public long DokId { get; set; } + public DateTime Created { get; set; } + public bool IsPrinted { get; set; } + public string Filename { get; set; } + public string Shop { get; set; } + public string OrderNumber { get; set; } +} \ No newline at end of file diff --git a/Drab.LocalDb/IoC/ILocalDbConfiguration.cs b/Drab.LocalDb/IoC/ILocalDbConfiguration.cs new file mode 100644 index 0000000..91f6b50 --- /dev/null +++ b/Drab.LocalDb/IoC/ILocalDbConfiguration.cs @@ -0,0 +1,6 @@ +namespace Drab.LocalDb.IoC; + +public interface ILocalDbConfiguration +{ + public string ConnectionString { get; set; } +} \ No newline at end of file diff --git a/Drab.LocalDb/IoC/IocLocalDbRegister.cs b/Drab.LocalDb/IoC/IocLocalDbRegister.cs new file mode 100644 index 0000000..b14e1ad --- /dev/null +++ b/Drab.LocalDb/IoC/IocLocalDbRegister.cs @@ -0,0 +1,13 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; + +namespace Drab.LocalDb.IoC; + +public static class IocLocalDbRegister +{ + public static IServiceCollection AddLocalDatabase(this IServiceCollection services, ILocalDbConfiguration localDbConfiguration) + { + services.AddDbContext(cx => cx.UseSqlite(localDbConfiguration.ConnectionString)); + return services; + } +} \ No newline at end of file diff --git a/Drab.LocalDb/LocalDbContext.cs b/Drab.LocalDb/LocalDbContext.cs new file mode 100644 index 0000000..cab5712 --- /dev/null +++ b/Drab.LocalDb/LocalDbContext.cs @@ -0,0 +1,18 @@ +using Drab.LocalDb.Entities; +using Microsoft.EntityFrameworkCore; + +namespace Drab.LocalDb; + +public class LocalDbContext : DbContext +{ + public LocalDbContext() + { + } + + public LocalDbContext(DbContextOptions options) + : base(options) + { + } + + public DbSet Orders { get; set; } +} \ No newline at end of file diff --git a/Drab.LocalDb/Migrations/20211101180516_Initial.Designer.cs b/Drab.LocalDb/Migrations/20211101180516_Initial.Designer.cs new file mode 100644 index 0000000..2d54a1d --- /dev/null +++ b/Drab.LocalDb/Migrations/20211101180516_Initial.Designer.cs @@ -0,0 +1,52 @@ +// +using System; +using Drab.LocalDb; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Drab.LocalDb.Migrations +{ + [DbContext(typeof(LocalDbContext))] + [Migration("20211101180516_Initial")] + partial class Initial + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.11"); + + modelBuilder.Entity("Drab.LocalDb.Entities.OrderDb", b => + { + b.Property("OrderId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("DokId") + .HasColumnType("INTEGER"); + + b.Property("Filename") + .HasColumnType("TEXT"); + + b.Property("IsPrinted") + .HasColumnType("INTEGER"); + + b.Property("OrderNumber") + .HasColumnType("TEXT"); + + b.Property("Shop") + .HasColumnType("TEXT"); + + b.HasKey("OrderId"); + + b.ToTable("Orders"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Drab.LocalDb/Migrations/20211101180516_Initial.cs b/Drab.LocalDb/Migrations/20211101180516_Initial.cs new file mode 100644 index 0000000..736a739 --- /dev/null +++ b/Drab.LocalDb/Migrations/20211101180516_Initial.cs @@ -0,0 +1,35 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Drab.LocalDb.Migrations +{ + public partial class Initial : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Orders", + columns: table => new + { + OrderId = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + DokId = table.Column(type: "INTEGER", nullable: false), + Created = table.Column(type: "TEXT", nullable: false), + IsPrinted = table.Column(type: "INTEGER", nullable: false), + Filename = table.Column(type: "TEXT", nullable: true), + Shop = table.Column(type: "TEXT", nullable: true), + OrderNumber = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Orders", x => x.OrderId); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Orders"); + } + } +} diff --git a/Drab.LocalDb/Migrations/LocalDbContextModelSnapshot.cs b/Drab.LocalDb/Migrations/LocalDbContextModelSnapshot.cs new file mode 100644 index 0000000..ca5fb17 --- /dev/null +++ b/Drab.LocalDb/Migrations/LocalDbContextModelSnapshot.cs @@ -0,0 +1,50 @@ +// +using System; +using Drab.LocalDb; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Drab.LocalDb.Migrations +{ + [DbContext(typeof(LocalDbContext))] + partial class LocalDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.11"); + + modelBuilder.Entity("Drab.LocalDb.Entities.OrderDb", b => + { + b.Property("OrderId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("DokId") + .HasColumnType("INTEGER"); + + b.Property("Filename") + .HasColumnType("TEXT"); + + b.Property("IsPrinted") + .HasColumnType("INTEGER"); + + b.Property("OrderNumber") + .HasColumnType("TEXT"); + + b.Property("Shop") + .HasColumnType("TEXT"); + + b.HasKey("OrderId"); + + b.ToTable("Orders"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Drab.Logic/Constants.cs b/Drab.Logic/Constants.cs new file mode 100644 index 0000000..181dcce --- /dev/null +++ b/Drab.Logic/Constants.cs @@ -0,0 +1,11 @@ +using Drab.Logic.Services; +using System.IO; +using System.Reflection; + +namespace Drab.Logic; + +internal static class Constants +{ + internal static readonly string ReportsTemplatesPath = Path.Combine(Path.GetDirectoryName(Assembly.GetAssembly(typeof(OrderPdfGenerator)).Location), "Templates"); + internal static readonly string ReportsOutputPath = Path.Combine(Path.GetDirectoryName(Assembly.GetAssembly(typeof(OrderPdfGenerator)).Location), "Orders"); +} \ No newline at end of file diff --git a/Drab.Logic/Drab.Logic.csproj b/Drab.Logic/Drab.Logic.csproj new file mode 100644 index 0000000..848c1b8 --- /dev/null +++ b/Drab.Logic/Drab.Logic.csproj @@ -0,0 +1,42 @@ + + + + net9.0-windows + false + + + + ./System.Printing.dll + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + diff --git a/Drab.Logic/Dtos/DokDto.cs b/Drab.Logic/Dtos/DokDto.cs new file mode 100644 index 0000000..a61b2a0 --- /dev/null +++ b/Drab.Logic/Dtos/DokDto.cs @@ -0,0 +1,32 @@ +using Pcm.Db.Entities; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Drab.Logic.Dtos; + +public class DokDto +{ + public long DokId { get; set; } + public string NrDok { get; set; } + public DateTime Data { get; set; } + public string Sklep { get; set; } + public IEnumerable PozDok { get; set; } + public string Opis { get; set; } +} + +internal static class DokExtensions +{ + internal static DokDto ToDokDto(this Dok dok) + { + return new DokDto + { + DokId = (long)dok.DokId, + Data = dok.Zmiana, + NrDok = dok.NrDok, + Sklep = dok.DokKontr.Kontr.Nazwa, + Opis = string.Join(' ', dok.TekstDoks.Select(x => x.Tekst)), + PozDok = dok.PozDoks.Select(x => x.ToPozDokDto()).ToList() + }; + } +} \ No newline at end of file diff --git a/Drab.Logic/Dtos/MagDto.cs b/Drab.Logic/Dtos/MagDto.cs new file mode 100644 index 0000000..9222b99 --- /dev/null +++ b/Drab.Logic/Dtos/MagDto.cs @@ -0,0 +1,23 @@ +using Pcm.Db.Entities; + +namespace Drab.Logic.Dtos; + +public class MagDto +{ + public long MagId { get; set; } + public string Nazwa { get; set; } + public short Numer { get; set; } +} + +internal static class MagazynExtensions +{ + internal static MagDto ToMagDto(this Magazyn magazyn) + { + return new MagDto + { + MagId = (long)magazyn.MagId, + Numer = magazyn.Numer ?? 0, + Nazwa = magazyn.Nazwa + }; + } +} \ No newline at end of file diff --git a/Drab.Logic/Dtos/PozDokDto.cs b/Drab.Logic/Dtos/PozDokDto.cs new file mode 100644 index 0000000..61d1730 --- /dev/null +++ b/Drab.Logic/Dtos/PozDokDto.cs @@ -0,0 +1,26 @@ +using System.Linq; +using Pcm.Db.Entities; + +namespace Drab.Logic.Dtos; + +public class PozDokDto +{ + public long DokId { get; set; } + public TowarDto Towar { get; set; } + public decimal Ilosc { get; set; } + public string Komentarz { get; set; } +} + +internal static class PozDokExtensions +{ + internal static PozDokDto ToPozDokDto(this PozDok pozDok) + { + return new PozDokDto + { + DokId = (long)pozDok.DokId, + Ilosc = pozDok.IloscPlus, + Towar = pozDok.Tow.ToTowarDto(), + Komentarz = string.Join("; ", pozDok.TekstPozs.Select(x => x.Tekst.Trim())) + }; + } +} \ No newline at end of file diff --git a/Drab.Logic/Dtos/TowarDto.cs b/Drab.Logic/Dtos/TowarDto.cs new file mode 100644 index 0000000..e0bea02 --- /dev/null +++ b/Drab.Logic/Dtos/TowarDto.cs @@ -0,0 +1,25 @@ +using Pcm.Db.Entities; + +namespace Drab.Logic.Dtos; + +public class TowarDto +{ + public long TowId { get; set; } + public string Nazwa { get; set; } + public string Kod { get; set; } + public string Jm { get; set; } +} + +internal static class TowarExtension +{ + internal static TowarDto ToTowarDto(this Towar towar) + { + return new TowarDto + { + TowId = (long)towar.TowId, + Nazwa = towar.Nazwa, + Kod = towar.Kod, + Jm = towar.Jm.Nazwa + }; + } +} \ No newline at end of file diff --git a/Drab.Logic/Interfaces/IDbFetcher.cs b/Drab.Logic/Interfaces/IDbFetcher.cs new file mode 100644 index 0000000..f817294 --- /dev/null +++ b/Drab.Logic/Interfaces/IDbFetcher.cs @@ -0,0 +1,8 @@ +using System.Threading.Tasks; + +namespace Drab.Logic.Interfaces; + +public interface IDbFetcher +{ + Task Start(); +} \ No newline at end of file diff --git a/Drab.Logic/Interfaces/ILocalOrderStore.cs b/Drab.Logic/Interfaces/ILocalOrderStore.cs new file mode 100644 index 0000000..96f35dd --- /dev/null +++ b/Drab.Logic/Interfaces/ILocalOrderStore.cs @@ -0,0 +1,12 @@ +using Drab.LocalDb.Entities; +using Drab.Logic.Dtos; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Drab.Logic.Interfaces; + +public interface ILocalOrderStore +{ + public Task> GetAll(); + public Task GetOrderById(long dokId); +} \ No newline at end of file diff --git a/Drab.Logic/Interfaces/IOrderPdfGenerator.cs b/Drab.Logic/Interfaces/IOrderPdfGenerator.cs new file mode 100644 index 0000000..8c5e53e --- /dev/null +++ b/Drab.Logic/Interfaces/IOrderPdfGenerator.cs @@ -0,0 +1,9 @@ +using Drab.Logic.Dtos; +using System.Threading.Tasks; + +namespace Drab.Logic.Interfaces; + +public interface IOrderPdfGenerator +{ + Task GenerateOrder(DokDto order); +} \ No newline at end of file diff --git a/Drab.Logic/Interfaces/IOrderProcessor.cs b/Drab.Logic/Interfaces/IOrderProcessor.cs new file mode 100644 index 0000000..7e948e2 --- /dev/null +++ b/Drab.Logic/Interfaces/IOrderProcessor.cs @@ -0,0 +1,9 @@ +using Drab.Logic.Dtos; +using System.Threading.Tasks; + +namespace Drab.Logic.Interfaces; + +public interface IOrderProcessor +{ + Task ProcessOrder(DokDto order); +} \ No newline at end of file diff --git a/Drab.Logic/Interfaces/IOrderStore.cs b/Drab.Logic/Interfaces/IOrderStore.cs new file mode 100644 index 0000000..92af7ae --- /dev/null +++ b/Drab.Logic/Interfaces/IOrderStore.cs @@ -0,0 +1,12 @@ +using Drab.Core.Models; +using Drab.Logic.Dtos; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Drab.Logic.Interfaces; + +public interface IOrdersStore : IDisposable +{ + Task, string>> FetchOrders(); +} \ No newline at end of file diff --git a/Drab.Logic/Interfaces/IPrintService.cs b/Drab.Logic/Interfaces/IPrintService.cs new file mode 100644 index 0000000..8c5b044 --- /dev/null +++ b/Drab.Logic/Interfaces/IPrintService.cs @@ -0,0 +1,9 @@ +using Drab.Logic.Models; +using System.Threading.Tasks; + +namespace Drab.Logic.Interfaces; + +public interface IPrintService +{ + Task PrintPdf(PrintDocumentRequest request); +} \ No newline at end of file diff --git a/Drab.Logic/Ioc/IocLogicRegister.cs b/Drab.Logic/Ioc/IocLogicRegister.cs new file mode 100644 index 0000000..7021f62 --- /dev/null +++ b/Drab.Logic/Ioc/IocLogicRegister.cs @@ -0,0 +1,21 @@ +using Drab.Logic.Interfaces; +using Drab.Logic.Services; +using Drab.Logic.Utils; +using Microsoft.Extensions.DependencyInjection; + +namespace Drab.Logic.Ioc; + +public static class IocLogicRegister +{ + public static IServiceCollection AddDrabLogic(this IServiceCollection services) + { + services.AddSingleton(); + services.AddSingleton(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddHostedService(); + services.AddTransient(); + return services; + } +} \ No newline at end of file diff --git a/Drab.Logic/Models/PrintDocument.cs b/Drab.Logic/Models/PrintDocument.cs new file mode 100644 index 0000000..0115232 --- /dev/null +++ b/Drab.Logic/Models/PrintDocument.cs @@ -0,0 +1,7 @@ +using System.Drawing; + +namespace Drab.Logic.Models; + +public record PrintDocumentRequest(string FilePath, long DokId); + +public record PrintDocumentResult(bool IsSuccess, string Message); \ No newline at end of file diff --git a/Drab.Logic/Services/LocalOrderStore.cs b/Drab.Logic/Services/LocalOrderStore.cs new file mode 100644 index 0000000..c25fd41 --- /dev/null +++ b/Drab.Logic/Services/LocalOrderStore.cs @@ -0,0 +1,47 @@ +using System; +using Drab.LocalDb; +using Drab.LocalDb.Entities; +using Drab.Logic.Dtos; +using Drab.Logic.Interfaces; +using Microsoft.Extensions.DependencyInjection; +using NLog; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Drab.Logic.Services; + +public class LocalOrderStore : ILocalOrderStore +{ + + private readonly ILogger _logger; + private readonly IServiceScopeFactory _serviceScopeFactory; + + public LocalOrderStore(IServiceScopeFactory serviceScopeFactory) + { + _logger = LogManager.GetCurrentClassLogger(); + _serviceScopeFactory = serviceScopeFactory; + } + + public async Task> GetAll() + { + using var scope = _serviceScopeFactory.CreateScope(); + await using var dbContext = scope.ServiceProvider.GetService(); + var fromDate = DateTime.UtcNow.AddDays(-30); + + var orders = dbContext.Orders + .Where(x => x.Created >= fromDate) + .OrderByDescending(x => x.Created) + .ToList(); + return orders; + } + + public async Task GetOrderById(long dokId) + { + using var scope = _serviceScopeFactory.CreateScope(); + await using var dbContext = scope.ServiceProvider.GetService(); + var order = dbContext.Orders.FirstOrDefault(x => x.DokId == dokId); + + return new DokDto(); + } +} \ No newline at end of file diff --git a/Drab.Logic/Services/OldOrdersCleanupService.cs b/Drab.Logic/Services/OldOrdersCleanupService.cs new file mode 100644 index 0000000..3266a09 --- /dev/null +++ b/Drab.Logic/Services/OldOrdersCleanupService.cs @@ -0,0 +1,58 @@ +using System; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Drab.LocalDb; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace Drab.Logic.Services; + +public class OldOrdersCleanupService : BackgroundService +{ + private readonly IServiceProvider _services; + private readonly ILogger _logger; + private readonly TimeSpan _interval = TimeSpan.FromHours(24); + + public OldOrdersCleanupService(IServiceProvider services, ILogger logger) + { + _services = services; + _logger = logger; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + while (!stoppingToken.IsCancellationRequested) + { + try + { + using var scope = _services.CreateScope(); + var dbContext = scope.ServiceProvider.GetRequiredService(); + + var threshold = DateTime.Now.AddDays(-45); + var oldOrders = dbContext.Orders + .Where(o => o.Created < threshold) + .ToList(); + + if (oldOrders.Count != 0) + { + dbContext.Orders.RemoveRange(oldOrders); + await dbContext.SaveChangesAsync(stoppingToken); + + _logger.LogInformation("Usunięto {OldOrdersCount} starych zamówień.", oldOrders.Count); + } + else + { + _logger.LogInformation("Nie znaleziono starych zamówień do usunięcia."); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Błąd podczas usuwania starych zamówień."); + } + + await Task.Delay(_interval, stoppingToken); + } + } +} \ No newline at end of file diff --git a/Drab.Logic/Services/OrderEventBus.cs b/Drab.Logic/Services/OrderEventBus.cs new file mode 100644 index 0000000..d9132f1 --- /dev/null +++ b/Drab.Logic/Services/OrderEventBus.cs @@ -0,0 +1,13 @@ +using System; + +namespace Drab.Logic.Services; + +public class OrderEventBus +{ + public event Action? OrdersChanged; + + public void NotifyOrdersChanged() + { + OrdersChanged?.Invoke(); + } +} \ No newline at end of file diff --git a/Drab.Logic/Services/OrderPdfGenerator.cs b/Drab.Logic/Services/OrderPdfGenerator.cs new file mode 100644 index 0000000..78903e4 --- /dev/null +++ b/Drab.Logic/Services/OrderPdfGenerator.cs @@ -0,0 +1,51 @@ +using Drab.Logic.Dtos; +using Drab.Logic.Interfaces; +using FastReport; +using FastReport.Export.PdfSimple; +using NLog; +using System; +using System.IO; +using System.Reflection; +using System.Threading.Tasks; + +namespace Drab.Logic.Services; + +internal class OrderPdfGenerator : IOrderPdfGenerator +{ + private readonly ILogger _logger; + + public OrderPdfGenerator() + { + _logger = LogManager.GetCurrentClassLogger(); + } + + public Task GenerateOrder(DokDto order) + { + _logger.Info($"Generate pdf document: {order.NrDok}"); + var cleanFilename = order.NrDok.Replace('/', '-'); + var orderFilename = $"Zam_{cleanFilename}_{order.Data:yyyy-MM-dd}_{order.Sklep}_{order.DokId}.pdf"; + var templatePath = Path.Combine(Constants.ReportsTemplatesPath, "Order.frx"); + var outputFile = Path.Combine(Constants.ReportsOutputPath, orderFilename); + var version = Assembly.GetEntryAssembly().GetCustomAttribute().InformationalVersion; + var generatedAt = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss}"; + + var data = new[] { order }; + try + { + var report = new Report(); + report.Load(templatePath); + report.SetParameterValue("generatedAt", generatedAt); + report.SetParameterValue("version", version); + report.RegisterData(data, "Order"); + report.Prepare(); + var pdfExport = new PDFSimpleExport(); + pdfExport.Export(report, outputFile); + return Task.FromResult(orderFilename); + } + catch (Exception e) + { + _logger.Error(e, "Error on generating order document: {OrderNo}", order.NrDok); + return Task.FromResult(string.Empty); + } + } +} \ No newline at end of file diff --git a/Drab.Logic/Services/OrderProcessor.cs b/Drab.Logic/Services/OrderProcessor.cs new file mode 100644 index 0000000..65959e1 --- /dev/null +++ b/Drab.Logic/Services/OrderProcessor.cs @@ -0,0 +1,154 @@ +using Drab.LocalDb; +using Drab.LocalDb.Entities; +using Drab.Logic.Dtos; +using Drab.Logic.Interfaces; +using Drab.Logic.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using NLog; +using System; +using System.IO; +using System.Threading.Tasks; + +namespace Drab.Logic.Services; + +public class OrderProcessor : IOrderProcessor +{ + private readonly ILogger _logger; + private readonly IServiceScopeFactory _serviceScopeFactory; + private readonly IPrintService _printService; + private readonly IOrderPdfGenerator _orderPdfGenerator; + private readonly OrderEventBus _eventBus; + + public OrderProcessor(IServiceScopeFactory serviceScopeFactory, + IPrintService printService, + IOrderPdfGenerator orderPdfGenerator, + OrderEventBus eventBus) + { + _logger = LogManager.GetCurrentClassLogger(); + _serviceScopeFactory = serviceScopeFactory; + _printService = printService; + _orderPdfGenerator = orderPdfGenerator; + _eventBus = eventBus; + } + + public async Task ProcessOrder(DokDto order) + { + var dok = await GetOrCreateOrder(order); + + if (dok.IsPrinted) + return; + + var filePath = await EnsureOrderPdfExists(order, dok); + + var printResult = await PrintOrder(order, filePath); + + if (printResult.IsSuccess) + { + dok.IsPrinted = true; + await SaveOrderIfChanged(dok); + } + } + + private async Task GetOrCreateOrder(DokDto order) + { + var dok = await GetOrder(order.DokId); + + if (dok != null) + return dok; + + _logger.Info("Creating new order - {OrderNo}", order.NrDok); + + dok = new OrderDb + { + DokId = order.DokId, + Created = order.Data, + OrderId = order.DokId, + Filename = string.Empty, + IsPrinted = false, + Shop = order.Sklep, + OrderNumber = order.NrDok + }; + + await SaveOrderIfChanged(dok); + return dok; + } + + private async Task EnsureOrderPdfExists(DokDto order, OrderDb dok) + { + if (!string.IsNullOrEmpty(dok.Filename)) + { + var fullPath = Path.Combine(Constants.ReportsOutputPath, dok.Filename); + if (File.Exists(fullPath)) + return fullPath; + } + + _logger.Info("Generating order file: {OrderNo}", order.NrDok); + + var generatedFilename = await _orderPdfGenerator.GenerateOrder(order); + var newPath = Path.Combine(Constants.ReportsOutputPath, generatedFilename); + + if (string.Equals(dok.Filename, generatedFilename, StringComparison.OrdinalIgnoreCase)) + return newPath; + dok.Filename = generatedFilename; + await SaveOrderIfChanged(dok); + + return newPath; + } + + private async Task PrintOrder(DokDto order, string filePath) + { + _logger.Info("Printing order: {OrderNo}", order.NrDok); + + var result = await _printService.PrintPdf(new PrintDocumentRequest(filePath, order.DokId)); + + _logger.Info("Printing result - OrderNo: {OrderNo}, Success: {IsSuccess}, Message: {Message}", + order.NrDok, result.IsSuccess, result.Message); + + return result; + } + + private async Task GetOrder(long dokId) + { + try + { + using var scope = _serviceScopeFactory.CreateScope(); + var context = scope.ServiceProvider.GetRequiredService(); + + return await context.Orders + .FirstOrDefaultAsync(x => x.DokId == dokId); + } + catch (Exception e) + { + _logger.Error(e, "Error retrieving order from database"); + return null; + } + } + + private async Task SaveOrderIfChanged(OrderDb order) + { + using var scope = _serviceScopeFactory.CreateScope(); + var context = scope.ServiceProvider.GetRequiredService(); + + var existing = await context.Orders.FirstOrDefaultAsync(x => x.DokId == order.DokId); + + if (existing == null) + { + await context.Orders.AddAsync(order); + await context.SaveChangesAsync(); + _eventBus.NotifyOrdersChanged(); + return; + } + + if (existing.IsPrinted == order.IsPrinted && existing.Filename == order.Filename) + return; + + existing.IsPrinted = order.IsPrinted; + existing.Filename = order.Filename; + + context.Orders.Update(existing); + await context.SaveChangesAsync(); + + _eventBus.NotifyOrdersChanged(); + } +} diff --git a/Drab.Logic/Services/OrdersStore.cs b/Drab.Logic/Services/OrdersStore.cs new file mode 100644 index 0000000..5284a33 --- /dev/null +++ b/Drab.Logic/Services/OrdersStore.cs @@ -0,0 +1,78 @@ +using Drab.Core.Models; +using Drab.Logic.Dtos; +using Drab.Logic.Interfaces; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using NLog; +using Pcm.Db; +using Pcm.Db.Enums; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Threading.Tasks; +using Drab.Core.Configuration; + +namespace Drab.Logic.Services; + +public class OrdersStore : IOrdersStore, IDisposable +{ + private readonly ILogger _logger; + private readonly IServiceScopeFactory _serviceScopeFactory; + private readonly IDrabSettings _drabSettings; + + public OrdersStore(IServiceScopeFactory serviceScopeFactory, IDrabSettings drabSettings) + { + _serviceScopeFactory = serviceScopeFactory; + _drabSettings = drabSettings; + _logger = LogManager.GetCurrentClassLogger(); + } + + public async Task, string>> FetchOrders() + { + _logger.Info("Fetch new orders"); + + DateTime date; + try + { + date = DateTime.ParseExact(_drabSettings.IgnoreOrdersBefore, "yyyy-MM-dd", CultureInfo.InvariantCulture); + } + catch + { + date = DateTime.Now - TimeSpan.FromDays(30); + } + + using var scope = _serviceScopeFactory.CreateScope(); + await using var dbContext = scope.ServiceProvider.GetService(); + try + { + var orders = await dbContext.Dokumenty + .Where(x => x.Aktywny == 1 + && x.TypDok == (short)TypDok.RejestracjaZamowieniaOdOdbiorcy + && x.Opcja1 == 0 + && x.Data >= date) + .Include(x => x.DokKontr) + .ThenInclude(x => x.Kontr) + .Include(x => x.TekstDoks.Where(y => + y.Znaczenie == (short)TekstDokZnaczenie.InfoDoZamowienia || + y.Znaczenie == (short)TekstDokZnaczenie.TekstDod2)) + .Include(x => x.PozDoks) + .ThenInclude(x => x.TekstPozs.Where(y => y.Znaczenie == 0 || y.Znaczenie == 13)) + .Include(x => x.PozDoks) + .ThenInclude(x => x.Tow) + .ThenInclude(x => x.Jm) + .ToListAsync(); + + return Result.Ok, string>(orders.Select(x => x.ToDokDto()).ToList()); + } + catch (Exception e) + { + _logger.Error(e, "Error on fetching orders"); + return Result.Failed, string>(e.Message); + } + } + + public void Dispose() + { + } +} \ No newline at end of file diff --git a/Drab.Logic/Services/PrintService.cs b/Drab.Logic/Services/PrintService.cs new file mode 100644 index 0000000..145eb20 --- /dev/null +++ b/Drab.Logic/Services/PrintService.cs @@ -0,0 +1,71 @@ +using Drab.Core.Configuration; +using Drab.Logic.Interfaces; +using Drab.Logic.Models; +using PdfiumViewer; +using System; +using System.Collections.Generic; +using System.Drawing.Printing; +using System.IO; +using System.Linq; +using System.Printing; +using System.Threading.Tasks; + +namespace Drab.Logic.Services; + +public class PrintService : IPrintService +{ + private readonly IDrabSettings _drabSettings; + + public PrintService(IDrabSettings drabSettings) + { + _drabSettings = drabSettings; + } + + public async Task PrintPdf(PrintDocumentRequest request) + { + try + { + var oldJobs = GetPrintJobs(request.DokId.ToString()); + if (oldJobs.Any(x => !x.IsRetained)) + { + oldJobs.ForEach(x => x.Cancel()); + await Task.Delay(TimeSpan.FromSeconds(2)); + } + + var (filePath, dokId) = request; + using (var document = PdfDocument.Load(filePath)) + { + using (var printDocument = document.CreatePrintDocument()) + { + var fileName = Path.GetFileName(filePath); + + printDocument.PrinterSettings.PrintFileName = fileName; + printDocument.DocumentName = dokId.ToString(); + printDocument.PrintController = new StandardPrintController(); + printDocument.Print(); + } + } + + await Task.Delay(TimeSpan.FromSeconds(_drabSettings.PrinterTimeoutSeconds)); + + var jobs = GetPrintJobs(request.DokId.ToString()); + if (jobs.Count == 0) + return new PrintDocumentResult(true, "Print success."); + + jobs.ForEach(x => x.Cancel()); + return new PrintDocumentResult(false, "Print failed - timeout expired."); + } + catch (Exception e) + { + return new PrintDocumentResult(false, $"Print failed - {e.Message}"); + } + } + + private static List GetPrintJobs(string jobName) + { + var printQueue = LocalPrintServer.GetDefaultPrintQueue(); + return printQueue.GetPrintJobInfoCollection() + .Where(x => x.Name == jobName) + .ToList(); + } +} \ No newline at end of file diff --git a/Drab.Logic/System.Printing.dll b/Drab.Logic/System.Printing.dll new file mode 100644 index 0000000000000000000000000000000000000000..d2bc9b75c8d9906b3c4f1a96dba929caf9229cca GIT binary patch literal 158256 zcmeF)cU%-#_$d4{JF_#hyTH=BxY)(mHCF7sS43TA5;j<6hS zVXfYF27b@Nsx;t#Cs~*q_{$o1Xvd5kxSt&}jZ z|M>nK3jfoH*Wv%M5>Wj6(}+hZC5%gm{o>LwFc{{B0ACC_>7ytLpx3K>IrN95_$^GwCWUNWo zHcb?~U=-JR6KYhdQmJ~C>Q(DNnpQS~m$khWR&oYooA}@Lw=q_->-dDBqXv(I8b9SJ zcr;cVb9{4E|*u$QO%9dfz2ST}fDU^Hp8l63>3H{7%bv>>OOK$?}PsBr6 zWlUI<&bDN~T3Ch+8iwn!hch#vm5;4MgwBST9U{uGg`;6ja)Vb3b(R^o$zNwxM_rH8 z+02Phj$97qC-b44%jcsrqv1(jUTp|#>hy;-j#wy1Hh?t?d9(z(yy9Vx5-e}1!sl?i z_4T+CtYz!ip*lMUto#dSJc*>K1loposhW$J)gb9oQEj?TWF z39|}~hn~;2h4SSpC>!^_9v8;iEPv3Q&vtzAWImrx*W>K0`lMMy?W|w|lyxUUIR}?- z^Rfhck*P%4S+hD{F1E9r`cR(C{Bm&__PQT#&zZ0$c_y?9oDXH{JSd0a@;`jJ1gk$k zmY2y`?wA(~(O6hNC>GYw8V{v?B9zbh8l6RtY0As~>zeX4_mW|ol+T2+T&ssYJXpP9 zf7Z0KYeRh&@Vz9`XF&;8hxf_r<7?53zdAaL!E)=yD?HOaEg<)yy`fK=4VGu&mRZ~Y z)}#-HZM$VYZ1bo_SGs$!F8KPk=KE3z3op-D88(#fAv)96!d@|@HY~5~4a={iVGoR5 z1N+{X1+X>l<2G5o4%Q#&2J7QS94hO<-1(N**^AXMpEe!8-=wpiX;9AT#D?+Lu08A< ze|CWV;S@#>wukj&I>P$)F;ITr0oHWoub0l6bbz*b9pDvwuOqC_!TPCDn;?I@ky&4n_09F)QBp%i@bk0Zav{}=EpNX?i7bV!bNDc^^&R6Lt7_Ir!3Iwx}Ng3j3GsX`y)iNbH1&`~Z=mRw(` z0AmlS<^@y))%+H9lwv=i-jMEad9nt%qL;@QYcWXZSB#xqDa6lzyyn!FLK>c?wzU{t z9_HzW8aYN~(j}OR9%TXedUA#PNQZ1Y0+iHO1I(iRJrr;%bSp?&|b zk3Hlu#-jOLpyngR!ne|`1jf#D{l;_PhkpXJOXGsrj#dy$W2yyIme>4>Wsn~B6*Bl+ zjVF7*Z)Trt9&=crm#R%N`3M=z6JyKzw(1M90F1S2(yA}S;6{!oTiB;Lw&S;Gc)PGB z&9PlM%Pc-m@8u7BK+TF4D2ag(b*)_gMQVUMd^11t)k=aDv;VWMIEM^Em7?$))sZ2VjWQzNnKGjsb&vUUs5mB zcv3%9D7A}2StvFbrBG}*suaJo16yJ=stU!%X|woi^yQY9$*|2PYOuG8Ju;ImM2S5z zlPy7sJu;J}i5TvYnJhz7c)KT?UM6Sr*I|vOgnP1=n}t3=x$zMomWMT`Q0y!!m15ta zT%-p=TSdEt80v^R0W;3P;stepF57x{2yXx@%=TwtJ-5 zcOUW?W5vdZz5E&0?1)FeY8I(OFDC~)>@k$BW=;9MUr%P`S44?iF{l;uj74=XZW)fEa&^=k4Yt3Qf}C?Dot0azi0D9d(7Y9BbZeBVyU8 zFHq~)TC8~xYi?xx0+si9Y8jlpH?m!*k4XDbS4erhohR#1J0s;huXz+zsWoU5>GqI^ zJVjOb;F#gE4faf{%DXh^%qN&avD{cVxM6kKj)YD3qG7pu&Yo6hn zZ$K{{d*@93ie)KlFxF_Ah^-Sf*Fm4z%1%_PF`%`|epJv{p@W!h&KekRt#SnQSxZo^ zavW9Lr;`0&wJoC3Mf3`Df7>p$NURg?JrILzHw-A>XDE&UN7ecPumy9Ki#Xm4expGM zYW9s2H7^=aGnH!oWO#CYkJ~d>`N@D|Y#<(SAc&p&AH-mvSU6ma@RPw@p8S45Yx_t( zy3l};LboyY1=nG9y>gGwnlZl_t?dVt^~w|6@@*Ekwx8#BRSI#|)3aOit+bJJ9gm#1 zS{4jj@U5B`(ZnL^TSN&>-tE(cTNiqP{ElLNZ~J^*4>AJzu(}?1bRXvHexH{+aru-1 z%Uj)`tmyrSmya?EbsxoUyx_}!je5nGr&?jTVK-P`6_+3T!*Zks>wDnxGZmIAt%CKv zux*Xe&^90I@2LKUN0+p-@Hu=m+Q!S-Jz!1k+I(3#h5bB@;8A5JEGu?w_4y*G-*`6E zDXT;OBcTW7KGxX_YZL>^_1Hs}!;?n~yrAY_H|YO`ov&f#ad{Ii|KSc>pbgYyVSX^f zuPo3{@>W0IR)Mz4(6XU?dGgkhPvrYDr+%0}>3fA~PFnz&{F*1yIe`YqICzJsgs zI!&Cld0FUyIXG~XJunKp3vF42!LYSkLQUmUXvad23 z_^Zi0>Nn)`Y=zr75Jw+|H9KR?hS*yau0Mv$Rk7!_*mFbdxd+y-iuEgEomyCbI<6m! z>pSC!gK@<0m3;dsS8>GYSSDiqyV!Ot_MeaaPsje3VL!{UpE#_u0_%T_>%YSF^Kkto zT>lc6mt#L)V?WuvAAi=TRTD$^oX`}?7mcCpjB70O-sn23)~~stvzpcJ=(^s&>>E8Q zX?p86MpRO7EQe#cn3r#(rPDg{XgrozhIBN1k}_godsgKA^KA>Gum`QX@p5&Sp1f?( zwJ$I4REpze@H2VjYw_CqnsP4U|9P zSUcCl^5b|YH;jhzAn*U}7UgOi|q(F;mrJ(Q^}p|m7J zSt}aKM>V0mF&xSQELZWGZ~H&dawT8ib_tXlajl~$U(j)I}^%3 znjVzv+qXD^YoN@|g!0f3C?|}9^6Vxkw_>?57nY}Ed9M>JXCy(Hk^<$5X;600hO)*? zD08Mm*=i}2R~tjgRzTUAmv3iPa>EI}X5&UEv$3qR36`s2*`x|AcN_<0Ml_UdhCn$2 z%O`7L`AOvyvbV_%K9kEOH=N_qjT@oN#PSgwX;lPa*>aU7Hx(NMM-0_6xSpR9%D zCzYXW-sPO^bKB^z_?n>+Q114J@=d~5{9F;63+JwhTi@s!`!eBMeio_`P{`L%5<@O{TtunrPb#? zFE^z=f%U=n`B*iv4E2A;*W9lMHG?Bx@G^ES%;fSKXmvOq%G*7mJT?Q`=G28~!XW4& zY1J#kmu+0~nwKk30j-yfEp>z#br z&j*%Utn}f_r!#y^g&l}_!+#sUz7ooh>Oi@3X&_(!as@2MCWP|k!d^EFg;Sf5(*~9JoCopiAB9a_UW501 zGYgiR)`I0v_;yyLjE3fq*ozd(}r(bg$>NP&zGxozt7)ma%#f6#t+kL zn_~a$36XFew@}gmkdq4IUdx3a)w2tjdOwb|x2^HQ8{|%;ew9T5JUA zP?LYm+H53gSc2VFkBuUEMflhv+32_JmIm7zurZ_qkv+_YY%D21HQd&iC6Hdnm9sTr z<4EVKR<<=|<4JvH*Ri!=iKIDm+S%H(38eU0J#3xWL{h`mv9_*k63JO_ysZbDOd367 zimfM`Lb{SYgKH}3kI{2%F>D%XV$KpSQ1HiI-WF2fefW|HDcwJ`g$BvLKZ zEYg;e5SvX}hOuPQQ*5r03Ij+Tz(FQgmnwa}Zlh`Vh5*WEO+iQqrst&@$5YV9;{XV~nMdyiw_-3Ul__ z2C)^S4v|M~gV{<_?`G$0!&wID-2A<^QEV0I(xAPz(JYfxe#Tzg7`B@9OSiqYv1|=# z`JfhN0?Q(WR`|}Az_Ll&xSwp}*;>*kTc6q{uyrKcw!OBAEQgfG`<%pbg#ts8T9}jB zdWt35U)v_L4Wv;vhkXj$NP4)nn0*@CL|V1AynQ;`ObX?%(G0eQG>E@OGuT#A^~SaB zGuSrL$>mMBwv)=IHL=fRACUfB-qN1Lc951VZ($~}ouqQ_x8<>2q(0qSn6ub!(kj%4 zBx5qfJ|b;c1=>Se-@C1S7TZf=ecIY*vwft)JeJJ%lYZ#k!kohnkRDI$XrIGACdCep zx6fyvkY@9m^Vvbt#KA*(41SWBzpK&YvGxU09k>>wv3%3HB8-SU&c<8N}>u#y;Gs)XQWJ?!!q_c=`PP<89PI&kK>&sHNu)- zkd|W2bEFYi^E@dRXLf;fA7^%vREnP&ma#8MCB}ljA~ir=BE7_3z9vQDmbgqBfphtW zl!tTqmUIr=T_Jg6yQ`#9xOKlH4Z+woQasM=I_U&IpDknGlTP7yKae~zqZ_17*yoR= zbnNpd(l(6UBt68~Ez&R8=WS9w?33}IB#k;%-_g-#H62^twzKx*<85b!*e8qt`bDaqV>^3>Do~*24)$Eg1|#fX zzmj0|9qffrV;FA-`wf-Cb~S6_*u{PqF$G57&Hg}%9QLr6q9z}`o?{RDlWM|v``9ZX z9B&`{iv;8CV}A?bc>CCElo;;-`$xoZypP!%lo;<2W8sYdq(u8AwR9X}iV)_W$1JFO zm~9?YQ3W`99@9uLdLFYcv!~9TUgfE!Ch~Wt5SO7}ocaa5(ntZ&Lj*BdaYQlJ5vS5@L?@Ja!g7Lm&p;QyL z;FqkJ5N^RsEDR+^_=Xin!4|CN_=dTt9gJ{=g`>o4bcK~5!4|y2N{X78(G^yT+QDn| z9V?9zBYe-wpkRcSj_+AnstF_fz{;V-2tTm$BpBfb7C|*3haXr4AXXfHoL>BiWuf_hgB2p@Tj`Ss#812=sv4K?O^LZVl_og zo>2sQ#NL;x$78jq9pv|f)qbbl6IO==`8{EEMNJ(239Co#;Fx~O>Qf9xFJzG@k?nKV z041`0&KgS9b3A8_L_5s(1#65F*}h;+NRYz|)>PEQ(Oy121GdmWX!d=pCjb zbr1Wjpp1AY_MS5Go!EQIsCQx&mC^6SDk@{%iB(d@z7wmYB)k)=tc-gnR#_SUPOOTO z_)e^fG69vrMmEfGR8=OT#FnV0OnRqgb!9Rtg)Q#7*-=B8BDK>|OPPvNOgN*|Ri=p; z=3ZBsPBoKj9&prEW{}=nbJ$T|nTZm6R-}@If>$hpMJlsI&1k=*la5Gbwv>xCRFb9U zIT|T*P-51NmANRft(zz*qGqEn6VE!DD)UGmPr1l7pLA^6H;!h?0#c<#-#A(*3rRc6 zfA46eq`s}0blcHJSwuQr{;{LIvKV!*5gY-XlqDoM0=g(msit#El%uP%jC6;`x+%-4 zCLA5zl{69@9Z^a;3672^Wd#Y2jvmTNR6#2^9-@^DArp>=Xk`^DrBTqDXIz<5e>q~5 z)lwF>UdkHMmKC0Eu}T)H!P;=QcqLniCD*LrHbhxVf>&&~vJQ2x5geN%lpJc8#Pb`i z^wg~GHeT648W>;QZIZH))SuU!rfebwZLIE=q--W#kE-W3N7+L9 z)U4;0qHHC#j<4r7U)e_bV?#Z+h01nPJ>G7S@&PKP(UmDp+?FUiq*}WzS9Vg(W0O0$ zr7IsvMY*k14wFI`4R%|v93gp(811%6IZA55wM98bdNXB;ZJTnORB7sHw{1#3DW~Za z+Xu=CR7#@`RiYdpC?`>3pWmUJ5;d8BbPIEba+=fvRX~bbFy3v4@)=4T9XplJQE;W| zVmp;HC~*YrQqBtD*=DzLP6+qU50$GV*gy9u-;rP++^bw8!9KW8xlV$8aG&x$3HHJL z$`2&i3l1nZgm8~MsQf5|d*ngoCzP1yLFJ~1HCBSAx*bw(krF3Iu*1r2QlF`yJ3_5t zFF&l@MWwV_kv7-uuyT*&F)5YnKI)VLzbze69-zc;OGlN5s0?`;NMq`! zxm{77le*N;;QEzRAvewKs`7&5%+28XjZ}S5n%j5E?&Eo!A%C^YE zUA4UJrTLUlce~WD!$-UEPd3vC<@gcjCUt*GxVyVlPWcFTr_{mn@4Nd+eU#MDJy^zeWIHKZCO&33ORb=gdHZzQ#Q@=EvSQUz0T+*?VF;M=U7)Y`ys z_x2V`37DIBjXGLXR0jK|M!dbFMI+rPzsS(!^j(8c%<{D%P!FB~o@p6?NgDs&_O&mil z#YjJNsp%MI2}6nN){&OtQqSE-T3jfR?PyE55YA<^r37heg;(yQEhR~%`YIk{ETu@V zW-4r~rL>Uw*BaAftfdSIuAvhwZ!`KV+ub9S>7Wp?poDjvZbO_9gpdjN~Aemn|jQ$R2DLacIn_T z*HQ%~-bvHPSEOki9JT}i#mvo_3ACLK#dZhKO2YD>8)F*A9G}>dKC6Z*cp6;>O(tz}&)qIbo zmWC*i(Q*rHYagcb>&P^Zw;H76MrL}XQ*4lu6}k2uEsxylv9d_J3|TWb@C6M;`OYwlpdMBf{SE+|;w$AwIKjJq}u8C5N8y+Vtaj0Z-^RPQyFlRVR zWvz-}C#7ygg9c*F0^7?bk3CLW;!!6ZN>dk)4Wd}U>OzlGmcgiGGbsBvF45;nrsf)!YXp-!rcD;drL%W%@xieApoEhA9ke)3t%NYou$QuQdu7nV_^ zrPWKbbC%JlIV_alPd;xMgIdAz=Y%-VTgIZ&*{QiMt^}0Wo);|RP~xiVf@M5PTyupxqJ>eM2!X{cnrpSgH!I_eaIrx8|l2I?MzyFO-h zZ3g?Uq0UCZ-qXS~)nrnKu6a&VokRM(OTN>l&L#Dze8%ZeQ%El>eeHBt=b`T4Ts+nJ zD6tQEsS8kIW?t$-63om?O+|@}ywpV~F*9#F|#mrH3?=Grmi8u z%!;d7B$!#anoWY4l~mWF#LUX5>ri55Wz`%MjDEveR?S7Fn3GoAb(T}tla{Wy!L@Mn|X9rM^(N!?AcdohJvA5!e^m5-g3 z)sHCV$=g*{_lOwIx{A72#JFBKtEl^gqWzNoc2-mOOR1jK)dNDTZXLU44fSKGK+jt0 zC#29i5v-1S5LLh)wJYgaM?EA}(X*bKCso6x39X%VXN2Q`X zo2bX6Vm+Iw$E5~)Hdphd#(K6?PoPrxTqb$8Qcp^`SR3^e)l7&;@@%V~mP+;PpcY7# z^z5X5CRNe1i~6}#x@TAQjMO^MDD|vV4bN!x3#kU4G3q&~EuOv9^HO^}`>GeDntR5o z7o|FS4p6_8I^-FrekFCvbC7yTD#~++`n6Q7=P>oM)H%=L>NiqXJV&YDN)7fLqh663 z>zSZlMWwKWh)JH~)bFHREK$8iHK#{JunFpQQufRrJtwH&OFj0Sr2Zge-mmtI>jtT8 z^=F=w)gOgydi9r{Q`Da*=39w*O;c}@+Hp-+Z&A(4l?<;L>TQbIYB;@;)H|e_T(i`> zR5PrGzt?Q_9>rW$!@TCG_et%z=Bf{#I+#5i)P3 z-*9eK-;n0S#(Hg2SxI;=PG+t7tGQiONS{?1?6pI+2=VjFD6ieBDmBAvuc}Ec@%mV` zN@aQ-RCQDVJJv3O<*5c~56UDxY8U01r`n`qJrApPQbNQb&m*cs>Xhek)lDkO^MvXy z73+CQ^&r81eOh&r%Ey8{QORuV#0_4jRWA~}4h5<=3a&%8dws6@px|0#pVwK{SIWiC zseV%Y8dLR0rL*@&<$0Y~1Kx>UP+@Dr6*XIZ%^ZwlHl8pVB8Nt4hsd3@jkc2nJ#uu4J--SrkD*|ncnx+AX2MV9$djB`2FF58bVT< zy4V9XRETfu2=-7dhJyEEKktWXm{geeW3{-fS<3r~>XNGN{find)yVsWT0*Lw_e-^; zR1fdJ)KXG$-v6kjrAB%yS{bPc-kMexmCS4tW_asbIZ}(7Q4U=zPfF)^!3`~fr0|%j zRY0Y)*8P*cZQ6TME4-arZK)mJAzCx3eD6|PC(@vHqunC3&Zrc2JNc6Lds-K%t6W`4 zJ_BxgSJb*m-RJ5~nwWz0*tp}<=S-|g0Ro9|PnJqv)spgRK4xj2;j8uS6 zEv=W7%cri^TPnh*zSc*os!ycWSIC@JwKR*=`jG}!jdC>5Vo6@}YWXzO`cu0-=vLlr2#krAwsHc-fRcEd17BQ2hEWkU?tAk;k*_N>O*U=r+EjkO_Ev+br~ zjwaerQol_xT*F9>fTHwArN2*?qW@Nr5v5`gGLhkgCia z#x<8TXZl#5PFf1;lr3xeM6P+L6f?KkV~@_-d{XtLGkiL03rNu^bGR0g*73UlowZcb zUo-e~N^KEo>j?gwQd>;g&iBD?+7i+i6ZvyWZ7HcuwJ1lFwv4nTjz5{ymXlVsjB-S4 zX{2*qqZ~c8bkYYKq8u^W3R1b~C`T`CCFybhC`WHCgVdoxl%tQfiZs4Ql%ubfN$SSc zPg_kI&U=Z~){p`c_}yhKi}aMA^#^F#r2RaHIBhNI&YCF4Ky4lA3eP=W%OP!9ALSUN z<&r+-TVk-bo|HX0$}vRSKnjnKatzfrlJ4;H*)VMrY1Z;6$8c>kDS&UY5!x0~0dF@_ z+e(_w&x)h8ZKSv){ybINP8zv3$}vX!fRtA`$}v{kK^nr_C1^WIA61HSjMH|J4%Civ zjMsLflFie#OS44nLsW+OEB}n{1nncL`R(9gjtSZxQqJ1aY=X9zw1|&BQQLFK zt=&HJv@<05{e6LUmIS}QFVwyu!SC;jv~wi*{e6jcp44>NCqB!y3#7rzj{2l&7fH?@ zr+w13FG)3fT<}?;eMO2+&#8yFU6l&--JpGkN@w3s3-{fqT|*_aL*vW&Zq}|#RrlSdeJ@qd_XF(* zQh#1^hjv4%p6_n$M^fYQO?*Gpej=?MUz+XHZc0V4{n{EveC-M8)y(0(`P$E@41Pzqr9EGJD%!EB6;#iBtq>)~JE8r8I>kTRTbiBFo}u7M zZi4Sg?YU^jHN*F`_N&x<-_NxdQY(DF(0-H3_C2rtF16A3g7$~h2fklwFQr`UlJ=)m z1p8WhCB$Mo@ALgy`&%mC_o~LfSOiz9Job(6ZOvEef$w9@50$}6b`JObMe~;$?e<&? zpqgfv-+fL1NTg0s{=TDYibS~ooQ_(v;2D!#$RVJNg;cDx|dN?p#$#HHQpynAU2jWV6MP7_RCR>%n6-YYmDG z;W3-FCdJOJ9pC&q7?* zHl%8E$N0IdZBcW~r92~-wH;{-&nVp59tB77M86W&4k$RI%rfv(NfSZp-8)NGL{<|>Ypf;6z^wH?KT!^w@JowBd7ask;;mk)@-3}Scja=@(ODZce z(|@-VwA)jp-Ch~Xjoj?NUn(ndr~d&dXm_wkyF)UT8+pk8Q>m=T zF24hELJB_T@vorWsUq!8%bK~7=lwsE%8I<~|G5;j`@%X9&r;%<{yB{CdzJ1(yZq+y zuf}z`>3_}|k2RCc-u(UHymb(2jya0IKU}a57QHCjhTinQXdOZ|;l1%o>rfKBH-2Ru zMykIx%5jN*00{QbWV6-Q((G&N2+|_{&V1QAlC+w?Gk;?pg%VHyzqO7=%`xHW{}t;P z51yolj5{p++{blxt_FNAIZZkO3 z-jIT4*Efr_yCq}rjQx%jJY&Bn1??UcY4=#h;2HbRQt*tuPzu`pTBO|z8G~o+ze~Y0 z_CKYd-9Oeu%og6m@A<#6PLL|}x9Ag5@Lu(Yzot);axq<>j4I%tv--`$(5DEsf_=i! zr=pV0or$mgO??{aXrdZm>eEpf=GPha0GmET$}7OG&qSp&!xkLi(341~+I;PF(`QMY zaXR(cQu$6VJz0uB*VgBt#8r^5J{KkO^V3tL3jG81c_@)zus&bP#X|K3D3M<=eIW_* zE2gKSAiwefVfrG{(ZtGJi&2o@`vJxEB~lFoT>4T}IxE%V{eWgiH>&hq*Sl*lhaUx^a=RnRk}3jHhTt571pDte}ri&fKCqeOny^))2OuezRv zg8W(p)X=j@M-$s|twlk8T?1!f-Gyszh=(wQ@^S3oU2mjwCM*4Im&an{o}NaZ^t z^^H<_&W8FXl*q4T)R+^UqV1zeYe!qfOh(aD1JT2GitAYBz4BwN#7%t@9d)QmCAE=)Ayl7 zM&0%OD3MW=en6_wzo-5&N@Uba|3u2g`sfEyBBQ?gArfTNSI1R-o(bjgQ4EY-aqafXVs=61-wl^ovqwoYVC$rShFK^{=GzoU`;xD3RZ6{cDuSFIm4VRp_6h ze}fYF&DXz`a+xQ}2seXe5`7P6blse-~*ME}AcdpcLO656M>9A7CY9&hr9VfB{C4ZVqC|cl>Mx`U{rBp>p+tWB z_1~pj>|^~8l*sQB{Ur&GxKH#yQIKEFz=QfL($U0vTz{b;zb1i)^uMLr2IlFnQR(c$ zw6=kt>i>`+zr*?)sWZ-FIx7uVL2zv5JM(o#D$jXRx1dCRr*su1@;j|-QicAX>sFM= z@2sv%@u$_gffD(h*G&@ScV4%lAit=<3%Z?jG_g0A0|oiT1zyzMq(%gOsk@`nS$y`0 zz^`-<66AMDcS@acexrLzY4BEQ>uAPMrjtp}kXzlni&^kCA_#OYiiD9CS4;9WgbYH{E_y%;K;ot(Zn@V*{K zg8Uxn#ih7}F!{a@&%Q6j(J^)gZ}_EIm4 z68Zh9mm@)bf9mB?kY8rtD?NgAG;tkQ1r+4BIq)z2J*nM+f9n-d>1<{C?!ec2B@*QK zkIpZ-X^%YPR1AI#Pwt({0aiSjQUa+0=BdL66kkMEw&lzGgL5ciAjixA(UooSZRH47iXpR#3l`vXJxmYQq zB}(L1+Gs_B{7M_GQIOx&z%mB^H3hbyc{K3`S6dY1cQ>%C(N5}VU^$~bDxI~O`82S+ z(SZc{MHn5W&NwR?ouu-em5t6)dCsav7nI1an$Z;{@~duilPdIo-{_7K`PDX}q+G17 z(E}y&t7k-$AisJ>PZZ?$XJCCJhIBOX4OcG|l5(+5#$c4l zud^|P1o?F~hN2+9;GizXFw)UP7uRqUDdrBr2WV*-$U2yD^FcuV0ig zTI!6mr!ht<-`UF;E0yQ$VRs$ZxPQ zi3Ir#HYTGWzqUa`j47m}iJiHoq9DKMprOVzss2I3jOnO!Hlfvspy9?06680+m??F} zIoe2)%6E=6W=Z8a#~HIxBERuQGD_r^Xv~o+^q*wRMTz{T7%5Wx$*VCBCGwkY%qKy9 z(~Siv$ZuNE3}YebXyRs*YQlAB77;91KtXGTAf>s&pNRVHqkt21+nPuck!tFXImQN*$S>E}h!Xj&H#SKX`foBeqeOmNj4e_ww$0dz68UX6wviye?Z$Q#h?La|(w}W;VJEfik?KF0w(%EONo&@bOc9S5#-NuJfXPkSCkEHUQ`;0wO zdCmjIUX;l1V`Cpme17l~V?PQqieQI~148_n=^sIdjE_+T4DOia8K00|m)q|3sd12M zZrak*dBiwG`e@5PK}U@|l=yDMapO~zxSy4892Pb4JvHArB4pNR@z~>parB*bCyZn7 zv^!}Wm+kc6lSV$Zdo;&A_>^(topz^;lkc=UZJa{Es~O`sZJZV|pR5|@C@>08>FimS zPjG?p8A;6!3jW;qoMfBX!aQS~A^pB6DEN$VmUMGbSnyfn3zT@G@`Z5@1>=aUE?|`*?ciR zhUXD0X(k!r=SHj}*JIVY>f)<0p!xb{^(OnrWky}?V)jpV(!6)1v8TTmGCV80Sv2mYby^~|O9#Cv*jbV-_ z#zTs&s1d{Uh+?*G!yG>wk16KYEr#m}#kSO37W~xsnPQ*TJmmk>cuKK9dkk|F8igc% zX-06N@e9@TUAo!7(0E3%_BEm$zZlO+@%+R%-;6&<@X4{?jh7_&B-bCtpCtGM*h}LTX)pf-(Vxa&r2TxnSH|C@;&TFusgvOOreYc>ah6g{liGD#ALFo?Hc}*)YT8M8{L^om=^$N* z|+Ku3{+hIhG(Z3RBYsuQ3MB6eT1YkXJ<_9gX^xs^MbbUKhtxJJkxKP(3#n~Z zCXM6gy1Hf+(v4ovg6o=9Q7P=qYTuB0W;GQ5G(A7pMVi%7Vw**pHAwL9`ZX|XigtXP zg@!aR-$xbL{%ZT1M>De)sX?QNkY;9WQPV8Zy9!qwiUsjcFE%sllHllXZq}okeQK0u zEzJ6;WR}doSJ2Xo6fr*D`ynmO22|4{hJR+(gyRi9lYhNygOJu{Ls_$BNE@>e)vPn1 zb4WY0u@Jl7HOkS>Y=RQ+zU|GXDDm#w!E7dK^6?^A2eUb14J+iC#LJZAHwi!oLI1#cYR~Wj1W?;{R{V_7uCzKQr6a>_D;K znz>k4vm+{l{nm4|TQ{>4O5_k_c1DRDdYD~MFuIHNFuMww9r$?BW;aqfK0>tF9VL2+ zHu?Y3mH&uddYU~%O*W`)-;kbWG^ttJAtAlYo}{q02_b#V7}D=;riJt~dyxjVJ@4P& z>`iLIHNfmc3gwD3`;uO?IqyHv>_$Y?VTbx*;6 z>A)O_%HYqrJ`Ndc#-r}wzg{`k9E1|DQGz)bCC)Di<`Ak0PZ$%-p(wE>#+k!J44*KL zGl!#6SXj#8ka6Y+((iK%LK4l9q`Pgu44G(-A_dmE9x~Y+je?oo51D3;L5Z17GsmLD z%%+#4y`+=Dc^>tuyDNAouhB>&yj0 z?9sBup*iM4A+uuSP5+H%Dyc-|ZyuY>MJRCuY%&+4#CV&{B`7ho&E`_k4oBE*E)!z= zQrd-XF_)9hC-o2gz)VAlK0h?mQKHX}%oU<0_VSUrlGA9~Qtlq2xpSIpH#v<4;qHKs#m7U~rKYfO1&_B%B{ zHP^lq`_x?bPVBImgA%N{>hly&!e0ero7NsRQ-ThkhwF zCMGrXE2+|4m!t-BeJyoi@a53UQiobz4!t6EcJQsxYf=YVz6iY`H7(IBc1!9+-L%lV zQcJn+OYKMvEcQ^UPHR`O$5MNF%_mZK*Of2!RBB30V6o>?&s)|j_ChLQRoh~(r1s9} zUhK70{Gk5D-bf|#5fmG|1HgVZcHq!rs#L#$6N*`-Ru7z2%#eB#y}X!RYC-&(Vh*XR zLHmk%O7$3YteBV7$3bU{`ABKAZWjxYnj7@ASTU((fiH`>q?Ts#uaZgK=TV`c( z?IJyxwIQstZ8vF0)-XqR+lQnVDg0Y7wvR}In(PXTvh5*FYRtbAW7{iadN$k_*2A_> zh@XiLaqXv?d!s)Ki?JO*WtjVyTn_7P`&ibDV7+ahP)+#vkb2t=k|I+;he+AAukm(y zq(iAcaeYcE9$dlE+jjVEJJbmC9HB4kGGv7?VVA!_#oS9(uKiQiVwCGkPfx1Qhb>0Gt$|? z^^1?ReNH;ivTgAM+ZocBm}_B)wzH(ts4qx^QRhf27DpFPv|S}xmyIbt)Ak){TH^HL zb8Od00WtH7r`WEOmPcF*TVVU1bfo^u;tOm)koMKT7PioKgA_k#ZSjS+A4$(@Y$~2= z`-!xRznY6|H%Vd34uvhT-6HLY-%)(I?KbJ#o}U)au-%b5ReY80F6sE1bHy`l_ej^4 zM6fK|eIe7~6XnRVJwSB_ARzT(r=N&99wO_kUmNHr}$ReGt$D;$Ik7x=cqZX%q-Kj z-S#W#Nmnn|4%-V--rxY&F57P?@o$5EWc!_Bhw6m6KC=CRTEW_`DeKy6dr7gjYpS>o z*#0DKnH9l4vAsg2u=uoEu1{=#kshvV<~nTqTZkWH5$uTVHN^rdw09k`{X=Thpr`A& z?G0(+h-+cTZLBPuhf~vvr&6f$e=#^_V@b zhqhXz!7;~OPi(bGXX>AKJ+;*#RqA=&^^2`ONp1Da^{1^BDS4n0{4P9!_-k7m z(!|kz;flR2$?z`~Znd`~JwQj^T%Et@L+qqtjYhS82cb0wtmL=@KF0;Qjc1jiig>UkT$oR8eZH!6g7u!iJlW)%05iQ z_~?tn%i4!i%@V6ugqOFEAeG|#S$X?N(vubZdjWPM2CJ97IlQucjEI@T zm+T9#W*foflryK9O{F z^vUqr_DQ6tqc4Wnw@)UW8GR$Xv3&~ZGFLPERMI1^miB3+lcOJpx3Nzrg|;irI@@QE zs%FJFy4YuuW^#44C!xeys+%3o3va)H@K%HP=Uex z&z0>)mdLQLrIXTn50VU>{Y2PSojxUjE--HtPDzojINpP=nt$hm#?p3a{ZzXB` zh|95WBf*`^T>Ews+_}uPe?Wpem$~*GLJaOXuD9 z!5zr$_K#5FF5?IGJtVlxxWm3z)WrL(JM8;Nki$;AoA*Kw4{?~py81o`FJPoTtpoo7FZ63-j+?59w$m+$jBY(FjKVn^)-@6|Y3(6GpBmamId*v~c8VuJfn@{+Z{;9%tc|a*;FPlQ(Q3@1jp@p`9(?BUu3Y1dd1s=)+3Ot~cwiI}@KmOly=G;Y= z?IaJ{-~aRbG;q$DbLPyM_0F9+GgtoVuXcT!IXwoS-1Qmew6Ekz%sn0zDiD65}s>L(YI{%w$Z)S=f>szqFeN3U>dM6OF3H+cNlxV??1g?)(2HCOL6TgJ zl6zGZmyp`Q$2G0s7V~pkRjQ}XBF#?L^spxBd$`tK?iWKn=&IdyT&mNNyP;k`$0<)D z#W}LI19Oz`8>qFR)^a)TyMZK2(7%Sd17VL^JDc!(36ftA>``yep)g52>ZX3e_*ZR> zD`LFrs(P}}R2WXq`a0DRe19dS4ZsVcb*x;-=18f$>fY;z#_ACcT+O8_$FP<_e|go+ zPAcaCv#8Av1=e!>oOPbU8eh;unkUU9$yT%#+T?7K{Ng+c(?2g`gYn4aq-ZPlKab?_ zafB0#*aE_a`pJc=8h_VvDPd|2k6N;TV!arF25b7%Zs(Hx1hlYMp}(rFme&$p_jl72 z`!@Q~rK!W8i+9tceVvSi@qLL^t|&Jv)e?= z%SX|U=m&Vz6)%%9Y1_QRHUB)$&)pw;X*@q3b4KrCj8(5X?kXw|g*|HO0L`>hxnB?# ziR+1mgk~qNx)HT7)SD|v=LuMLNpu-T$4K?;HABnXz|S4Ek0Ec&AriZGe_KfTYWzwA z>?&r)J^}u50a89=t~k^=}=H zJ}g&z)t@f2bUbR98{?`%-Gi`S-Gtt+R6oav9iu#``!4GDwMy-(u0BVp-PE%;DYd)$F|cKa zax`fEx65$X$=eU(odOFegHC0q9d_hE(>+>-^qRHbJ)_ zl0EqufdrZq>ro`JMmx2Mp}Om+H)*b`Q2Si!#KyA}OLAX{{FE}ev)VD#o;dx`Z+yM} z(Gs7kfxJRBZ#UMj+CE2}O0~qcX01c?YQ!n?=%w9}^6ZEOU6L{CRJ%Oo?NeUDa?3le zW34}(nwIy4uARG;%1gB)y*5%g%dJ`Ee-)$1tNtDHGe6M?(>OHLxjY(we>IJk`+@yx zs!4N82yfCc>Z8MHZfV4fy{pXI^i*1DzZ&skB*(t(McP}xO_q-g((JAGT;9{HdBY>` z!39|RdDX(Xq)A~5+bdE?5VoH$_qz0@5T)HWNU6StHLXWY;jmtB=rQ)wRV3f%)KctK z6L<%TH#K4p&66E^BO9~^M)|dca`~H$L-k4GQ%9qfJnCYsy+_Ahbw6|r^{X|Ork3bb zcyDs~ozdb^7h-SdRbK}7$a=;dtMv(cS<@)de2LrV7hj{a?snGi5xw$vxB2s|sj(3z zo8!1V+f6%c@9c;*ZTTTmT|YL?j6FzwW?b)hf(B}-gLqS_l2*dFWjkgX$f!7zSjAu&8nkUQFuq} zd(}%PI;kkUW2v-#cUni{<9by%^+Kysy*%na@Pu*;BTOq3t4DOKyY9n>c~-P7(5mLM zS)disXS1*uuQu`Kg`KY_2~Xx7K?pt~kBV{lS`L4FGD#+Icqw|vt3LQ9N%r75fg~Pv z@@$fmHA7A36^@qZ@U83v(RoqWqn^Q9PV4Ki+ky^zl#icoor=O9_3+tFDhhkl`6!!L z{hVVd>`_i$hT3(pBXNg^FNvkE%ck{5E2pKeYpV5~b||lfrLXIy^+&6trLSwP^>?HN zCSFQy66K!N9w&|6^TubFZ$6LOb|gFc{i5*$l~kVe7}DQaxh}KLYoze8-23j>-{vUC z3)$PI!$Q46QeZ)_h_B2x1qcnD}UfMA8_|zf1Rv#)aT_ZuqZVl4+ zs$;%DHqX70u=YQbht{j$<3$VXhp>;m)0Urs{H2C?wzcM^>`m3Bx|H9%8b7m^?0m#) z2934kIJ`j&mix%phkSQLUe!w_Dc3KT44+qNE@aIm(QV?!?pPWLn3;X*|9r#Qw;p+Z ziG^Wx)}2G^&!@019itMM8+TEcBHvxrcWY^H`=d>?x6R(Pqjs*ine0%iU3N5;-PhFS z9-hf99OL=K18k_-izwEScz8vP^9$^(4K-~e)m_i7w9q(7eRm1J9R~J!U zLy~vJBP&3?BGs!${Uqw}POXAqO|SPf))we_vBsN;-o%;Fp)}s!jnRnOm3L2$+{3Y6 zj>XK$v7~RExZz|6Va&|-sHU(-)niWcDnHgI+UMYsNUTdzqGQR==aoFhaJ7#-IY`yd zqf5`s@aiC6x6kmog;bX}fGtm;UbpMkbI(5%Hq@iMs_(soEbCT<&k7dwzD$Ry#rW(4 zd5t8|bDhSHj$2=cvFF0G=H*$-;91MZ-ZuC%FQB@N6if4!Uv0yaSgF=tMYGLKcoKI} z58@fzRXvKQcsF$cKfj|}xEnK7CF_sbzJ5t>T5oDSU+G-*Ske*-d!;?yVco)7Q{x}B zQ%#4(GCy#vJG>+M(7`-rr_#NtpS~|{pd59$doWG4w>x zdAj9Cveyid>lw`b{JLi_Ds8EEZm6dA?dW;$|7U(4^q?~j8)cp)cdRvUqlJ;`YTjeE z^IO}EwY9apH+0YE?yz3}KvTE*XDq|NaT(nBUuF2e+XDaO-0k-@#-TfmaivG*Ke;@1 zzW;Zh3wQ4SY6o{~{A)b?YdrjGJh)rnU*o~u8vmLfKFfG0@yzoX8J#J3lv}~^Y*2mu3 z3h~xzO&zN}v|8d0f0nem42!rVS@z04%HE-UPolD2z+T4;ImO?r-qToFNu&VhiV^Jcc?7yIP<6bq%%u;m1(>j2^2?pR?I1(lgfZijlSlo0k;FQ4Tyg`o z!=`+Rg^}{I%X8tksNFRF$#+UeZ`l)vRE0C?RN@Yt(HJUtEzQgy@VQJC&jy6O>L>e< zO@yIo#nN{%9p54O4AhrnA^9Sn8Y_ItX;#>yD))85j%BTB>7VsYs(T90yCpf~T9T}W z+>&UWw;=Hiqj?U?t46iZdaPq@ohzJ1YkTDGjjr`dSFA3{KJc9Tl-s^r=M_F@*%znb zJ~j3*>brvw_N(0vcXGVsO8S!M6+R)-xqOe`q&hs=m1D#e{wwAvY5{61HQlaAlFgnbz!$ts)=7D{W@TuI`9J0zZ3oLS4ZQ_ zu2NON!Wi{;)Ws^p7}H7HiChfjmb`rp)$uHT7wEi>!kg4k|AjW;eyqmVE+~nieuFP! zeCowzl;cytel_Me$MPlI`&R<{R3B=D8;@u=zq%P^t5n|u9-|&Ona+J)!@Rw#x)C?| zcT;;{)a|Zbo1;{fdMQKJBDK^eA)evs3pgKtfmK0YV8I%G%cL6qaFo`oW`wC!k6%xc zSH44%I50`**5x%k4mZQ+hOeuTuc4m6+r+2tKY?;7Mu+C2zXGE#=Ja=S9=fYwKfiQu zL4QeS(05^4ZpTtvc~x^KDg7O20xiu%jo{_=5uRd9d#xxXs8 zzs7KX?ZW-FtJ;%i3F;mFwV=Vh0k@Ld$# zOvA{;`ie`g!*;*h{j25rM&%NWBJ2Avtahrs>US82_;$|@8!B)ONfw_^nlmk5`mmD2 zb|K9oo-eP`eYf{U8l}4L=EH(6p+|M$>G1M8%1|5mw4J`_#Ojx8eG%RThPnv;d7qks zFuywxtH1hO&E*+-hsSz%JcTuebz_TaGJYraS`48|C8)bjVS zjxyA-$5Z>e<@!6>U-N8C*sIoYpK1xsT0D2zEv)A;6Mc#=hWIU@zk$7r%k${TREzg8 z50uuFW^a70i5b#R4X*EwU&<-lvYttRZAm@PX?j+nuaAAI5i^)a9fkJys`i;=O{bzS zj(N=6Y3D-Us}h_ewYHD%Zs~7?t+FkM(wIDV3E5nM=h3SQxWi+p^i+~`v*a$EBH?>j zo+10kkj-(J;SEJ{-%zf1HwUz#g@EMF2zUgO=pKtIJvG*y?Xrz0IUiCOX5juPb<|2Fz#H*nF17xAnrBAax z=2(8lwaz_VWZ~AUY5eSYB=zY_i^aaq*Nu^O_}%Lc>`be9KjpUO4u5vbu;BLm&>cw2 z1EB9i{%>Lp`Nmw|qI6rhsozkSU~M%P>$I_$4aZ_G9E%m&Sgg;+Vs$naYqPOx55S&) zy#RXy_5th*7>Bfz)lF(DU^-w1__=^)SZr1aPcywpc&X#?~& zAbhTRPW>C`1!{u#0?-RVF9f{^@J)t<=VH)r11<$z2DlvXOLdgzMKAp_>ix!k`2*Es zz}4y*;EC!*4sQcKLcPV|_knAa$45H508dnV10SIdWXU+jhcliGJWZ62c)twEGVgfctGtH+U(2xtj{Po6ZfD6|EV;*f zG<5FsP67UzcP8+lcMkBw-df;adKUoy%6lU4)81C#7udo}Y@x^&Uh{TB{wCXb$9pou ze`ITa@dgq8h;9CjZ7PFo`iv;>7=tYDZjj}@46;1dhyfp9B!RzVWPz)VHNX>$wZMlN zUk5(QI2U-5aUt+D;}YOm#udPGjB9}F4a#wmK{Z-zP)SCFO;e11!ZK^b>yDj3hi#cs8r(MR9Q&*zFz`=*Y_mw?Y`dt-{pHA_#WR&!1r;Pf9BhU@SyMa zzz_T02L2W2`!whKTh8|d&i5tGx5)Xv#`(U<`M$&X{*m+j3+MY0=c_8XJsIy_LG89z z1-0AQ3aZ5c71VlPs-Rj_S5Pe`R8TDrtDyEgs)A}Use)=Tt%7PXtAc6~U~BbkZ4p~r z%+^k+_#Q?;w726SIFZ35AQ)Uiy*t4^jzsufJ9ir#VRfr+G7 zr+&xuMB&>d{R+{Gs8=|CmBeS&JItRUdh6A0hmf5M)EAgus-`o&MlE2vNiAV|o4SDM z4`H_!`c&Sq&^##Rw@&ztLN^QDCUl%f(h1!tbeqs|UL79*C3|7v*9*T<_)WrZ7JiHH z+k}5rc#om&8K7iuobcm?uM-*;c|`a@p_@g%P3SnEwznSi&+5KIh`tTGn_QISn?=u4 zq4mcJ4S-TPYK0F89~M3@{5s(`3f(Mpn_t^ohZW^dVP~Vz%|f>c9fwsl#n%cA3(bRW zft=_QpaoDW4^iSbf>OFckrO33{f4pO*?dS*~9pkL6H+B`DT$9g(phsw~72!;ju7e zIZ-aJ@YTWxgeOYzwV+h4knlvwZr(*nZ=L8BM2{%x4GP^X@kQZ@QaUVBb$LKv1@8f+ z{Hj5@d=ei3rEx*@ZNw8L`?a8?9}+oHk`pEUbrL@aO7=DjUj!vRqFjzW97=Lb>$)7E z#8-ooJ)%_3aS~rEbhFSRDCuL-&C~<>Q%Wy0o z&~+l;g42S1J-d2d6*?YX!-K%r35^I{FSGzk<=P}Xwg7B*JSf=-2wx|B2$bp>5q`bU zO+vT0=y)oJ@I;AM`|11)P_jQBl*=c41hgIRMWPg+2c`0@7oI4^7eJ~0n?ybcN_s`1 z)$p7W9{?r2LE*Q6lHH>4uL^JMujSRCly1E60Z>Z6UgVpE4vKt>@I~R(0g|uKJSgWc zv?y|Qpw_DvS_ewy3W1V-1eDr~D9P6gPn7sg!V@Ka5R}TjMfjrduYz(vh+KV9>lvVw zjwr>C7oI5b0Z=MOoyZ4;FM?7&Si~?5fs$T9_)VZ(K2WkVDDo}B6Q%f9U6l0Hm!w>v z#2cWbR}D(`$BUdO$?IH{^drI(B|ZJ%u6eZp`Sn>nq{DiLqrSV3T z^g|LK5k3z}_Sb`w9#PUOh$B)!mp&=4r;=Y?Mu`4tnG$b@HbR8(!D+oU*v?z3&#H(YpJr5}9R|`K* z_<-=W!iR(}2tO#aD71Q#wigf@0_FA-z94i^Xi+GfhCI%yg^mNIbOGUOg%1gz7rr3; zpwOaFHAU?3TLU#AC$`}6z)Ri3l={^){Do9-W5O$$vjZ?%ZLRpg*#XHaNSC|+`0pK4HwC;F4Iu)nZp@Kxjy4UT8t+pwOaF)i3#iQuzWxLqhWsUl2ODM$aGlyhABn0X&swP-yX6 zI=*p@J`-J{P)BI0$eew@z zS`Zp~P}|Q7EeIVHS`?}t61_*Xy}+ZI4++f+4g6Bahd`;n@Tw-kEi@oBBs4E{5cCro55gCP!s){87kEa>BXm$`;Wt`7D75-n;e{4|t9cwfa{C8B zsXqpPr}?7L!RNKVh$z*!C_GW()eAbFDDfc|C4Wy|c%sA)x+vQNPyMf66nmiTClWs3 zq9hN2C;t^uN}m^=DDedsCA~r6i4tEFo+$C^KO|pJ;;V%xN_@aYxqcEK5_#T5Ie*~` zqBkf!QHn1LPn38#b#*yFiLVx(DDeT|i4q@jQ7T_vc%sA?geOY;po>!aqQn!Wc=eK$ z1C;n`7v=mVJ|Oati&A`E;)!zpE=uu(5>J%ki^3D-{9kq`=~oL+l=BxpAbd!8qMW~r za{j^>L~qbVNxvxZL^=Qel=_1bU+totzr+Vb9ul4?>F0$f%J~al5Pnd2q7+|rQL?XI zk^Dh9e;4Kag%5~c$VEwCZIgLQXdaZ(6@(57RsW^+szKSV(2&rg#A6cR_-dg6p&_Ap zp#`CXLW@GxYm#1QKxjy4UT8t+pwOaF^}3`N8W0*1nipDd(N9p{LE(!+)$hfQ(16g8 z&^##3cSO0pgbsqzd=z*?%R@qoLIZDUc^;JX289-ds{fXD78(F0`yo)uk0|kZp#`CX zLW@E%7<4}f4G0Yh%?nlUh@Q}Z(2&qPD3!AybWo^zSIP-WVOswl^rW=%SyXT8D0rmy#4_FC^09FCAfU^O&0PX}l1$Z9d@oe=QfC@k*U=Ppp{=ESE0LFS=^v{KC z9-s-Z5|9840L}+o4Y(QbL%>6TrvR@2-UECJ*wee!{}sUDfFl9N0A>Pe0Sf_*fTe)t zfE9q1fFK|YFabS)KEQgw2Ea9dn*p}~ZUx*1xD)UL@ALk906zlU=Y7$?8M0>p&jDTm zYy-RncpvaFz+-In9}E}|XaqC?P6BiSRsdE4A^;N*1M~yV09*&S8E`M)r+_B`&jDTr zJmlNz-vW39@Ejmmfi!^20apU923!ZI^l$a=1{epJ31|W=t=#Ir8&EX{Z3fsI&hepPwp zVEx`N`!52t?DMj}9dPzO&-*v*Q}l1z2W<+t12A)6j152&U^!qVzyz!UoC`P~Z~@?E zz}tX#0lSRd>OTlD9WWa(56}*X0D1s1Kmw2g^a1(-X9Ly&HUQ2ATmZNTa0%d2z%_sy z02=|D08ap(1Uv(H7VsiqE8tbY>wvcaZv)-~ybt&Q@FCz+fUzIO2%r+MFW^AH;ehFY znSj}V;{bC3^8lTIrGVvt6@Zn1EMN@odp_i?RMR{`!%z=+&hi=R5n!)+%o{Yk>Mh0} zGv3=E$C}_gqehZ&oUV~i7wPh&j5 zcrD{~j5jbopYi34ujZ0m$9N;-n;GBA_zuQ*v*x{w?`Qk~beQYabdd_wGyh1IE+Gp5^na*#{o$$KPi9%2_^zd&f#`1i+1}ZUpQO*aR30 zxCt-@a5EqP_;)}r;1&Rqs_z0Q{r3Q*cbm}LK@R}j0U*5}3H`Cq`-I*PO6eX4kp2?@ z%Kuk@n>x28#incts;jUB>@B#o^6x^*= zv_;{1VJpFQv6Sb0u_R~yO;9QimfB3QRA!2$Fw=L0VyVjde-`=|p;%h797{o_Sn4tT z2o%*(SlY22EbW+L>BjVLY9YmY+a|-Z_qb{AQ@94!yhl$(8gDzx=diq;`Z-n+$d#L@u?T=PG5R!w?N(V#w6|}}U#Ei$G z{~_wj>QGg!j)3H7geKtta~inmxOqN9)#C?B8`NBsvra8Ws0pEFb+Kx}Uwdy=1>8j6 zsNxt835Myv-{y*wG^(k(%E6;_>`1ck+ryp*-aq&f@ZUq! zK05c?+y4vUOQ({~!PmYCe9+bJ05>i86Y#~W{tCQ0N#RQ``y24sE4<_3aX*>x#T;I_ zg2L?_p2*?zLVieoe<|r}JFhnG4v8+?2Yve>e8D+XyOkFczP5qv|DExEjJF+2z4<=l zZkBAij!O6+J*59(&;GFR*esIVQ$sjDiSUER5I&7Hd-4=s$MVNb3Li9u@PJtub=Rrt|xp@hHz>b;blt+uVLJFJcZv26F!P#zkefz zpKd37%|gQ8ix6(+GCajL@8BG76s3lF^Q}_2$_}Z%oe^^KOiafR3?^_A4EfC(s_?DX}to!J3 z4)1sFJXp?i*$%$80pah>ptAjevDTc>+X(qP+}iJ4M;79}gim06#j+;Ewqz;Qd~W|K zH?>1DoAI@qD7=aB_#3Hg4QEgC&vuudwV;LOr87B`-0HdlArgPuJ9^X z_%v6z-xXf#3a@vC&v%6{c7-o@g|BgiH@d>NxWae1!asC{?{|eCa)lppg`aSRpRvQU z_(}Z3H=c*&k5^JV|Axm>?M4bG80!(zd=j{$}(3v0j82Hl@ zX*}F`GTDrDeG19P{G@!H=Zd2^oZ#^7?G+PfwCu)sZ{WaON~`D3Uu38jI(*fQ`y=+K z+Ajg`xi6LBzHfdN;g9B0Ev8*V_?L{gZlKxeqHi9C*oRk;`~dDFcU{Ktj8R^r9ntw_ z;+P40sTaLotOH&Eu2%m6>{T~lg;1@Y_xkYu{~hoc^&GGl@9YYMf8+H-{w#2{`YkZN z_2ZSqQ(kYFdus7Kq z^1HD1sK!@MdqDCF;JwtN!1!xKSc{BNTfBQg@-T3i6n!;6JG&f&YNj zj2BM1V}SpvCIc(aRNzmsvOzm}W&&4wW&`izISzOa&s^XydgcLt0bgNY7vre|p5SQ! zp5$2we6*(#_(;!*z{h)qoRk(L8!k03>#CtX* z-v;)oi@oa*{uZ!TUF2Pl@Hc@`FYg9~FJ%0>_gsWu^PUg9k8uHF_XhUhJG6@s-V>O< zAG{dhtBgw!zS6i9_zL54;LD9GfiE+z2ENp|2Kd{?b-VIlVB7+{-nbR=Zvdl(joX0N8Fv8ZjXQzQHtq&K%lIMiTH{{eGmReupJCh&e7f;d z-~r<9Tg#&eDRA)f<`U$Zw3MEF?7GmL{EnPwae$#lkB zjIThln{ON>yE6X77!S$c82^tk5%P~2e`FjA`G>~gko*-Gf0M#E65+o90|MW!=ei;}o<}(rg1LJpm zJ&?Q$jNfeW#Ss3K@!x%`Ao&~PJt`8A@5#8TA_e*G!1%iu6{jKmWnhmwxFU=2mw-L$ zn2J7xYZxC@(GSVdjOSGhKz=;qITdF>K9_Mz#ahUlfjz3J;%tN$1LMo?iggHo4cMbr zR;)+(6voMl4UnW5Co0Z`JkI#6it`~qoAKI;3m`ue7=I(L;v$5<35>r7T5&PL7Xo|K z4HcIld_Ci9D=vlPI>vWaTn_p78Q)%UCFFN7eyHMV$R7mus0S*pLHK9DXzhyY5dJme zUsc=y$&{a7&?&4Kn_1_CT&i`ZJYXAMfU-ADG_{;tWfDgvG40^%88TcUo7T_=X z9|1nl|0wVQ{>Om#_dfyr1^<(wgB4ef-ZtvNz*B{m((N7vnwr&qH1X z>`}Y>UqpB}V0;4R--_@qz#cWm|1!drj4N<5Z4^{gnt0_;&&RH~((Hm;0-Lug7T? z{+5S-Z-nn=yv4sS!jJj)1OBCde_*5XK;Ydg4+5T1c`)#vm0tnAsB#?eg_YxhFQ}Xd z{BMO%7qBO3EZr{UTNSL1J2qVe=jP0MR-Lx z7k=UT+rx$MkHVE$rzy{KDlp&yeO@(#1~8w_40`e9{A5pLjRAhD=Rb~s+&kUVae@zY zre`73*`7VFGgLkN*Iz!c0yJzK$uwdtIe>W6h%w(|T+1|OoOn9PR~f(H_=NEi)09!i z@uwN9na>($G3_(XV0phW^CC(&V2tJTXBck{5Wm(~!trMt*E7G)=wrIxSa}A;Z!jL2 zNAz67cNo$0jqfpkfid?x#9w4|b3PXfy~Nmu?OkfjWO})=f%Ci4xb6Vd-?O%A#<%>S zXIK4hAEN83zHoydcCM^?lKHEvUSWDo)fUit&vjMr?@xL+RMkK);MrKUk<)LgT5$=* z-&}Rh0VKbr>e3^K-dgq09HO^X-OKcjs`Sak-&r-0>D^U5On+GQ>mHKdTXp|JqCc*B zoca5!?q&X`RcH2*{DG>UA4~M1s*9O!uDb04;9Ak# zd7|o1Z0E_U%#|d6s_F-45q+l0>?Znb)hbT+T-9k&;-9YyGJUb?YNlJO-dRTSm#fY< z$=)kfv$_7;s+J;sz30`c&DRlqy~?+a=o?jk$P<05DmjbNyMy`ER0w#MIt6&PS`2)w>Ht1Y#eoAV4P38szzftG;6>_8 z;1g6Hc(M8haEm$*xJ_LM+@Zb&yhL3Fyi8pMe6qS0_!M;$a7Yz^!|J=h5p_GTsqO;q zQTG7H)P2CK)X#tuY7jW3eg&LWzXZ;yhk^Ul)4=`ex4;AH1>iH(OTcSY5%_HN8t^*x zCh&Uo4)6x$%WDrf9Nq8*)9JxmOC1SGo79TKiTVi1za{FfuTjt~Yf@VyLuEmA%Ce!d zCUtaIxok|CY>7JVgrRy%)W))Wm#7aL%k`)h`X6RQHEF%VUh@d-G>=j>fMWnN(YLbz zvjN8fjswgAw5gL+JD>y530MMH3RnhM4mcUG0&ogoCE#m-ARq(?1G)eaKonpCx&giD z!x-RHz$(CP@WS5?JcvuDn*oo(v;N;W)p$qINrswNJ88}28B?ZDicFbQv#4`n!-QBe zmWzesvD3}W1dcYRbVp`Iqa#I6pE_y!?C|8tBczUYO`bGm_LLE$XH1(tBQk5mXw#fB zb<)&nBNz`)nb9?KMs)fJ(KBbw3`fjqGe(G>K6!H2jG0qsju1VqYtpQ#v!{(5Jv}ll z5*{gf=FFMhGpEmNil z*3>DJx@SjgBEiMAZ3`P(TNW=TSlH5BIyvl|t%YqZovrPq7AU)!U6JXN&G6Kk_S#^Z z8IF#k5$ulV`m*L|DlpO%9_TVhu>zH)nOJT+DpZtV)ON1U3sTA4{J!pPGt-Xww6sh+ zU}@^iDUq(|>~KwMY>gRjNM~d5RC1@SOt$)SWGh4ap*dBW%h34cX0}uzn~U<;aUPxa zL^vJ~rn*iwBe`I*FA+@VG9x5%o`)SsG_)wqsoF@y%nmV4S}wD>a4r_9jmJ}w_FO6x z?lBje-MP{l>`ZsGg|m2A(4+Ii$tbt#;#eZK^9Jpn*&&0$U|%vBPMFb2lP0O!;3Ty= z9PcwHsd@8)^XE;TH*aw&9Bs{*Su;u1O(mOwSDS%yQD-t6?lyIFlbP#HMYDmWvEWJ88#xNlhy{2ygnA8<_l*A zLQ`}}iNpt{pte(0u(hqRxuc;i*x0b`n27mmfV$Jcc9#F?q|Kw#sDPQt4a|?H zx{gzzSeH%@U&v9)Kg3ku$R(?(X`N78yF@ojK(|sLpyoB&E7GWp>AJp5 z2JKXzN`zy{z{qVEpkX>?>9p2Nss~R-HZUbnTVk)(%+#jSV&`+Sx+F&rLpJca8ALHr z1)AnQqs?H(><&g!eaT#)HrKEwmRp>PtlC}!PFhsjXggU3O5K@swiVI;MS4uBU1o;k7GZjho0-w4vrde;re%u)Jf%%* zL}6)5G;PxC>Cu>AR_ItdlK0WHtXqp`+Sp%+{OT z;l8-_2<_ZR4K@#LrPxTVL;dtQG#%#{%a*^(=%r^yxf%cI@4snWD(bvdJM%QP)-Kb{ zXYW(oGhE54WGA1L)*19_9%{Vg+57y>m(9-q&@9{&_CFw_(#PT-kb(0mlb6IlG!N&! z@p)zA%)&z^-iAyjmHCHF%S*66Yt3csiFLk8wue`n(fT@tH4)aBCPH-?Gn}J9y%{$- zKsw;tbKwkTx(Jr3w5-L7w=c)an5z+;2=)T^n7QDhaF+R0cX!sz)u~fcU5)i>LTx4! z9_YYoX~KjF^OsMW(oiOvUM`wn7Z^r3A1ji&`3>cMw{lk-OKe{YxoTKqdsiHZ!6lDNEHTpruoVe8l%FI!@JG#rWL!>}c`*TR;R`l(7A zh+P|{E#!#oCUS|aHgbuqMsh@UD>)*&nH-VbPL9ZKD7VP%B`R$yN6T(2M`SmaOJuc{ zBeI)Ii?*|U?MT(NEN*FQYgnMVu=W`HdY- zwXL+rQhFm$)7YXqBI(9fluJLJtt!~QxUsz>xTvAFzM)M8JK0@@jaf&-LgGu=ohy^} zR;ggavbu)Wj>eYeU~3ES``T4qJ8fDQv^00LQ%Tzz>N<#Wyuuo#Lj_N0nXmVUla~(J z2$H~#oia4GOfYSz#`K|rnL`D$h6-jcwP(hqG+Uav`a0;ebapImY;NdiSk}?h(9zZi z8EWBXrQzWRh^G3pHCX@Fw8QN|X9GL{YT9&~hUU&DbUd|4!?OA%OI7Kve5oqka&!C% zsV>j>$)x+>YiWkx1Nw_#xjk)0P=*DmIEHL%IM=&W)kfj?z(6!J zb*W?$4kxUzm&#jUn23eZ7+waA$?gWDKwFYIy8}5ZIYav z1AUo@*|5f~-I$EVGH4Q#Zs!r8#>GCwT!u$1S)YzAqmE?C;^hikleoEDVwX$oa=3BU zM1qNMFwAeq+Q3OOnp)>$AxaUk;OgA45uD=mky4aJu-nf%&Vk1(*x+6?e-3T|+G$al zN6*N;{M^aKd8rp-$Flo890@y?le1F%Csb=EvshF+N*zjeH=n2B&%8x;7usIR=%Gs< z203&M&~nGEY9F`Ss+Oco)m|Lhs+Oco)m{?Ws+Oc&)mkb!sv;>@wU$thsz}OI?WL8i zYDvme?IoA3YDvme?WLHlYDvme?IoJ6YDtDsm8F|YRZGfL?bWZXYDvme?WLZrYDvme z?IobCYDvmft)-!(Dv~l)d&y|4T9PtVYjoDws+J_c>&+b;uw}Z|_;l=Al5)G&0CjXN z$uPPjkJ+*^L`NR9WxCcFb;@8#%FAF4Qb*U4lNy_b7Bh}HhB;~r+P<3=I$uPPjkKVHKT7%WGYe~xO+K0;a__ZVfIc9c`U@J~r zwoaMd8di%td0Ub|aM(l30GzpQ16Ff61}w=A8YnFzuTtdToNB~p-tPQHSLcK69ap!{ z!goALb85$Rahkm2%GP$_9?7ARxC-Nd~X_X-IfTzDaBVP0`|gs zhwbY9<>zIs^q#>^Sha5$*mbug0rzczov>)NozoYV zum_G(F1Ia#OJRtl4hPYEe}JwOq~wA?&MZw?l$tyd?8Y9PgOM&3 z?NW(sB$bKBx>P#eMIH+5^;J{5bM1;N%WcGGl{NLeP3I{km0pm_kiNdkfGmk&H3{2y z9P9`*4yS;ZhAk7b81C@-Xk-Um1oLCLL^xfSikcA>VI1#n z%)u!Xu?A&bDjwHPm~72LGYOYbM0F-3s=E(}Up=+i0R-#9$%q-(;aFDFMHzHE9tb$n z7KbxEcoZUPSv$~jLTNxlGTWCiQN6~fvWkx2sVqp~h#U_Qc;{HEo$j72!gVgaw;yud zj2{}5gx+xqN3TrjC~=f44K<6y$(}ysBd5SM`T{{`GEV92mx0sQu9pT}Xt|U6poSrV zLDOcUs9CyH5sSof@qv01C-eZc3`O8#-f$5;c;MRmaPP^);isa<&*7TF$v(Kp5T&B# zYTV~AJCliU5~Za^!37z9qU(B51xU1y4yf zwOvbF;y69)!jWDKR~q<@+19?Ucr5GixVwbTh^knUPX2l@n7P3h$C4zC4kOcs?UK0F zbrhWvx}}ck=9F7*884L%F+W@+Wl$>Db(2EVGu@bV7zxF2aU_Emxz!T$W6@YclGY4b zLWiL^>%g@cacySAgiE?Pm5X)9BJA0>lHuYRUVM0eJ2}iZ&9udnRX5LX zs79SeKb@AQt{YyeEy?&msj%K$jhQ23ONZPRsgGrK=ED@zj%!KEsMD_$G=}@>&_ZgW z(&xe@FMT4M2-maV2(^`x9NBou_;=K)?mYVOKs9C^Iknz!@|a5}mR%6T%hc-b)^OU) zoDfdn5~w^1^{G^bjwvA6&UKrIr4nD~Ar--W$#! zPOp*Lu-2kmuMl7mqAGD*qFrsq>u~x<$l$`Lvm*^Y*>xb&Kpj})s4eNmvrc`3ME}ToQ6FDhl|7+jJXCaKuuQ{Pf;MEiEcHF z<1|b4Q*X06wlz$5-j(H+usWXaI1Cx+I4z@_4`l=0k(ag=9k1yGt`>5HCGFx8m$Zf> z*Tr>sT^om&>hMXO9v97hi7qqK(%p*HiC(s%?38TSh@{y+tX$ib=?w-NF-c+)bgg&o z+j^=2XIN=#-Nw358|GTy_MWCzGwB%RDGT#hEMm6D5`A%=L*3ClC|bjjRj6kNEo*b` zSd_rp0`fA+iEGAmjzUreX?aF#mA)=qcO)S-Q<)G=R3_8S!>coDoB63VNG)f(?xngM ztm0aGRM7(1SwWAw7IyBD)?gv)+;5U`>XzsMF+}2Kby4vW4-dG-I$fC<@7_{9o!s)u z#D}pld>qxb_Rl<%X;T6h`sfzU>%E4edl{9fb7_|wS@L34k zMLTW?-2O-UaEJYm3XZ(ylnyR5bL5nwgM39BV-7%Qo$jlJ@qu(NZ6vx$C1(ZduvOAe zl4}Pig0xWG&GgjpBgapI>k-7q23P||u$7_*QX$h4o)(C9q<-}Hsat?=Y-s1%ju#hg zzp&BNw+gHXzCC8gvhRVP>*3?O#oUloym@Ztb9$wZ>$f-4p#1fX^J$wDHL+ooKz(dA z@rcBowO-ndZ_f^2&|^jHGqSk)%VDm8o(%LjrDuUQjkrER&Bwv06YORInr41D7wKgt zmUV?uJkyTQ(eqa^Z8vkS5avQ1+lntMXpLj(l<!G+)NwoPyb~R;RG>Q*OzILk0{T)#OL>_`n^TMleQicF{q)HYj~`mvb*Hp+0rYH#Ls{(nzF0ik zkVxkSM%EenOw!^2o*q1%9AXcVg!nzrVH!g0DOLDFg%Z?f!u>iF>m-+uGU)7?1hvmKdmGK+YQZ#8N?x@lD!=Na;^_#;8w+Wb_-&({E5dUy`&H>)t}5tkeZ0y zwoAh?yocyx8%2e8vCbqR@k6Hs($_6euF#U?CLSre8GF^ylDA`jifiH{+i!^V^yWrW zXpgNaiymd5xt7AgUfmqHTdo6{l>RESmUhlqhQpnK6()tL72C~pI1|P_cIsT7Xi6m+ z*-e*9xnp=?Un-9!OZjYx^=K-Ba}Eqp&MV~v8+iz5w_i7v1N)7kBI&-NV(sl2Dotln zYzG4rdBxlC2_sH1tgjhWU9TBgWvvox>6Bss3iX%|bSUbC`f0z#(P>S#Gds{D!RnMX zo>?e6|;h;iZQ%C*(iE| zDJ^|D;BFn4q0>mt0c*ih0ctCkg|T3WTS00uF1)@+%zf_Wk&0gDY?9iO>!?RG%c6W^mxJ8+ ze4t@#>+=memJPdPWN=X`tG(&S#}&o-y7+9VVJ-%n!#jh%{Y>d1a3`H!Ld72r?MVD!yMxAiWd+wm`9k#l1$*`#v2lgSRGlyb);ChkY;`8MDTJ=B_kM#P2ub+ zTy5r9y^b0-3JGohOj9^*rQlNP2b3-7Uz)J8()(rR^p=IU`s_=P{BYRHCYa@B!4u#} zXe&==ceMDTMx^6Hy=Zh~C>g(1F$U<#!o2_|E=Ox}dTcp0%lVPE?CM99BXeY5cR0SG zMRz(s6H$kc=k#V{L97QS>v%(BZQhbxfF(S!Y!^*PKMbLlXqov~O)9L7>9Y_H2Qg4^ z1_xIdB7)u60_vcwJlQ)IM4j;5=EXVtCf(8|cy#c*X7S~TR6S}195a|HtbH6myS#X(N5)iW z)C_Gz<1rHpF_Pfzst+q%3LMcC#=u?EMhjZnCuf;_`r!K`N-VaNJIzjjJU-5mtE}n)G@?9%GziY&%M6rKu?4dU2k^v z_4Hr> zMmS!k)sB%Chu;f#+LCD5NUlu7%A_9iUM9xBr{H8_%|BUb^A6{}96X==(+Jph;&94I z;@IP89G!-4cwXYAq7H?5 zi>brT{Tj_%FE7n;DfB6YEE??&)(UzJFhq#So@1$@heYYDF$#3@EU(1ertJGa3d>L( z;S^Ec^!Cjniyu;oQnBm8kN&+VQ(r_QAF9s4DlhGkw1n%8hYyQgxh$qH6suOetTOcL z272?d0QYyeiE#qk!s8n2dh+^04F4*A-30+_LScrwn0}K^MY@;}kEZ1?b+i>mQS2Z` z#*)qt+HG&WMlXEp_BVb_kT##L#Bh4JxHWtT&Z}qbopQx>**~GjXNg>no$)T%Cp4pZ ziLE!Xc;jn=&IvS~=i;mvt%cPN5uAt8;b;)I&~jRmreEmeI6bs5-;I`;%TtKAGAY|5 za>rBZPk%`tYhwBZHk!8Rg=3xW(}@i3`Xp_Etl9CCVk1OgBU7XADGZZ}FPYcSp$bLv zh5%!i$Edzht+z_thjP_ZYhhrIu7&3hCoC{Z!w}au=+~Tx9c?zVpJ;MBbfjptz#Dn& z-_j$Mk00}4%cNs4qvBP8!s;gu%Mk3<9)yY!eyXtnV)_1=K$cki1 z2XR)8t_vb0!Ue|^2pP8q4Zj|227L_ACw3yVO2U0{+yTYr13@yXFQNxq!`ZB?SyhxS z2;q#cmk#)PF$H2P3c4VUvoraEz8xbg%7a?_B?!qCs<`Tg!c;|#klcpt4!uhGgX-&BNeCDQkY)f5t z`m{`jv1atyuMT(7A)>;&B^JfPr?a_^R-TIPTyTIof&cNjHIW zxhQB7p9DyVyHba#5^IlDc_Z+qUDn_%er+ z4z4vgUY#u6yy=R=PCqMZ(SEJo&lRGgFE*1ss2c^*(zpjNf=>F(gc{!wp_y>oEKwrM zx)m_*N^1CI$to6OF?1)LyVA{Jg}Y=bnvSU~{~~2)CZ^!~Q@!wPsooy^7#%1TgtzFl zqnM9D%ANw7v7=}(Qu zHQRYh)zEU5JZt1mn>xkjKEsQzhNop-d~3`6l=20Qettu0>1a7{S*#y}rS+-(a&?uJ zv%%YuOFx>m?KOex>`=FYThL}=(qE9li?$#B@e;?SBaPwR&-akA!6T0^{Ed3Y#|-=4 zOWeNPv$9x#wp}|`Cu2@r+{7Jckuyn2-qJF<5V%oMszN!^c4Uy2J|?z7FE7 z@7IJ~t)=ut(u<=GA9lsnP>(jA1AMFHG@QbEU4OU1Z3RE9+z-LJ$Mq?Sj)XCCzo7)f z#Zqege)O^`Vx;zc*w$z)8mwY))30N z>CX(!W;j#g=^4D58q2VDTLM}py#9F_If}S9( zvWsv#4=wr9I#O~QNEaik2{ksh@!V)=PQ1Mn+)VYji^GFhw>__&hsuI*lC7Sf%H>iC z{PY`>czPL4FWVdQXaj2iEyb6t(T>zI?o>{TU*B?=9{E7FBc&B-E?_N~7$U)vq+CLm zf`>?Po*L^O7$Qu-|3sHkot#^-o^?3APz%Q$30As2Nr!Dsr5z>_%-ID^=cqZ7w4741 ztin183^hGIIJ4X>ElGV@idInUPJ{r*s7b|x4Ate)sCUEi&7zJ%y@!iRSxQ(d>M?_h zF8B;pubL=~l_?%j3gK8XsjM9;$MEG?gmfVn#iCIbFU0v967ny*cVH!!R9ODu?xy}y zNPCRnUCrJlM)WdL?gVEa&htJtDy%|LBgj=JVO&_30*ImUfSnaK zBRuBXv29L-u{NP|7LKG17VX_iW76d!vV>1g^!!q4;Z%G`D<b87AsTK0 zY0%n;Tvj}9*^G6E$rf<2c!IY@v7{Z0TSlVTRKZQh2CW|)AmeybV4By?G5Si}VYV|L zFT^!jxwL1!`nb`sjH!{c1F|n~MLDdffe*~t(G{$9&QP@$+B23|w!L&z z6ci(kJrg_Tgtu=t>t|7`$Yp0oWEI}*mM`{IpLK=B`7}ts-?;}|LcG+_5-tJSi`xec zPAh76jC^s3A3etp2UtH2pzyoBZkC1w-fraUrq7&RdLu};g!}}i(sG>4 zXIw&k4F+Cku0u%_zr==((TQ9~Vdd#Yifr%47sL9;EocyCOIi9&2p+%a?^LGEq+>=> z!yrPtSsZsXj_&YVmiWbHx=lbjJYeL+jOP&Rl#FAV@e2r4bsiw{)v0XUxaP>gK206% ztwFxUe*GbyzEw?M$n1E^;nGmSwMEAc&7nhONla;`D=%lPV?^jj*D)|mMsi)p(TQPb zWE@uZWp0ryLikOff4IRqamG3Z4dEmDm9CUhoOC9&8qyCKt@ zQuu|GjuZ|A;{)UhmLUDY2)*(m^Uc%o0g^~3%2qiMhdekOhd4g1yR&N)p( zUEkDH@igj}byWy8F8|7l?$Yr`Q&wD`YatqRV$n7+YBS!Ub@ZpKORN+e+8QJq<_)9E zMUmyN6(?@=6*;BePJio<32{czMn4wRnU#xZ@^H$g=nhebDfj_7UGVSZl-3edQxdH zdIA@w&dfNUtm%)|HE%8OM5aeHcOX)fE(UZ5^XMs4z|0Lxd`@P?CG{_2qa5UeM@#4f zbd`kfRD#yoy|Rzq$&F_jav!@ZedKOm)3m33nq2AAC%sGz(7 zjhBz&hmDiFp~J@M_tdaa3HB#t6n08z2bx7`_QKYfe%}NV>Znpl0#~N+su)(t z$!Ow68b#mA)A|LC5@RSY-+|+G>d+XM<&r3q7O7T^F`%qqFV5m|mrpgPI^bo{BO2a7 z&Ghysqb>cGnEku-a~jx0VUpB0`4^dSVuRvyfbW=Ca;)NaFL>8zQe_~c@idHBZ!Ik) ztCjE@_BxdwIy6wMzp$d^{h9=Wd{EPw#5<1;!6_rm_O%qCI|tT=&mDz}2jyb-2@lqL zWh&{RX{?Fu|6}hx0HQj&{^7ezTRJSFsGy6zfx8p|6%`Q$3l^}W2<%dnCZK}R$buR* z8ckyFHEQf7(Zt>od)H_ZjV*Q)qsA7?_d7H9ZUHRGljnQ?@Av)Dojdi+%$YN1&YWo? zWQKRqF2O|1U!I!AmyBBb@!a)PAPI5(Ln!5O$35(|_2g@7rS>H1E z;?dX^jFJ&cdX}8Jad5^78`w47@(B1e`!AWNsh>%vrrxZ0ELT%sG_AA;6IxF$FA11h zNmdSwY1k#NFfAkpY>t8qS|Xa+G?7=p+>1klmPUGdL97*MMuN_YY2p@ZQz8Om8tC*u zJCA@Arh8PR<|yrLfLB&@fGy$8qlYE3#SWe!E1{WBwum+uMaEK5TF?fp!3*A`BSMiNsjQex*HIV*oG17XVPT(f~?(5&+Q`@(Tz~s!$9D z9|j=>j6}MrhO-r;3!Kg9pomPd#MgWo2QqbMi~fcN6iGnzmIy&|@^eK}n%oZg+9B=v zbsy{qpP=O*287R_#o?CC8POQxtb~Wr))Pa3NgAp7O@rA8PXHvPC6FzHn98iqKYq9(X!0l|D+<%{%8@yC3nK^6>}wB3lOHEf-de56Yk zC=@uw5kc`9R*5*dzln<;GLAyuX8?VZD4}l>`@~~DU6xXqybXMkVS}%FLDr)nHf z(sqC5$D$(wCOOzyYWmO)VThKa=%zzlDkEu~TBRkVWYW1^cp(NCg4t!dx$h!l!xH2B zMW-2UEEWRkSuP=4{Ne^!%;H1`@|V1mTIEXiw+{}!VcPzf))*nMEt5PGX}wkqOys`d z{D=s@j4Bs{3sxM=o{}!(-RM#ZDO>@CjTc%h(!LW-j3yx;NQ=xwgWcG^8Ked41nObo zjp-{X0SyyT;&Ej~0R7SQ{!PIo$l%Zs#xF6s;V#jrOs=G+yEvpkDRXhsYbXsPDa@*T ziS5&LIG2&RM7Jb7Ivt)dJ^UiveMJBOenRItXu0Y36 z4U^4i+K)|AQ3f9GF5#O3z5;%XsSm9#@tCwdh1)2U)LH0&>`Zd5fD0GWjmH5g77s58 zo%>3xlu!r>kclunL>w82q@ZV~DW14Bo(D@5#;-r%H%1$&*B9i<<7M+tf;6vY#pZs} zux+R?uN@C$#o?Kdm`!)%=Av!Io9W(q(9{^ucz_hkE~a3>tT9_4ki@o)1z^2_A;HAY zh#3>lYy-MXJO?LXvI=fYx7V}5f=))~3W>~==$Ti_oXfK;8NW7WmMci|0FR6P9R-m% zIl~Uc3Ik#;LkaSR z0=*@&2vF3Dh$@;g!ITk&YbnqWQk{)eNFX%h%xc=-Vo*>YBWF%^zO>#cJ%;34_G3tfc!r01-ViSZqX-s< z>E395EZ()g@T?;$fbHno{|rrSKyKy zAPa0>;xoL)rM*pk2%-sVGA*&VX~U=u=Xd`ywn1l^aOo`T|5}>$VnE2r)#VY7U{`43 z(oZZ#VnRSBXqSD(rVup{2<5sSgIlC(iFrwr#a!$|=NFBjq*&I&f@KQhp)3GpPWQ^0h}-aE_pJDuK0!ipTE}L=i^YZ#92Zj{8GmE}-kfl`TeRn*7CO<+6}F-S zEXFXfkW?zoxEV^yh{L3?vLey3BPvBMJKkeV36_;KKy(s2YDL!w(ejfqN=Ywtmy%wz zNK5xuvgR@s$*`q116OKOe8Y)+v+!){V`e_dnPS!^z-Y0Ojwb4I#4x@_Ejkzs(VoSt z8J|OyCDOxPpzJ*5+oo71%Mc7b#3u7{uvzMFCBg{z4^p9p|5h%*zG3l+uEQWVLjc&3 zxZuPYA?KCoVSE)z^dyvE+%xygFX=(+R}yQi)k7rvK%pYLI>?* zGmSwks-z!y!H|R;ZAov6DxR(>83c7iNv}aAGNQ~SbvJbbu}lQC3~vA|!&gF|X$1(b zSSnL*lfs&Mv)(Q>C>vEwLrn;wR9Lo2p`pqLA(B>$cquMdBMYQ_UA|~1os+?l#luOk zFp*lo1RKaRE}5V~s!AstQ+u*&MN4h*;l6L$$HPNumh|@99`dGMXWEP%x;X^_X6WYC?8tXTRiTos)?Pk`ER~B`Y5G6O$#0UtQ+lw4AI=28#E2 z*4@pn-#6c6MJLxKwjqcMDLBPs95{e7+XjKob2i-|GQusw*%0BA9~6ryPE&NX$gaueow7zmMJle@%2YV43bHcpy^ zps^W^@_2Y7fHDH>^$ggZRAAlbIwSGYeN? z&@+yh8gL{MU$8DG`H?asfp!r~9)x!8DfzH{nv#Q7 zsqheH0gobWERjN!#GE47eaCd=Z6|*F%OL0w1`Fv~Db(X(8-mF{T_WVG%^A!#TGHw# z!w{Y_pj~wBvxZ>(J)ia$P>FEr7U*GOd_+EIJp*+v?GG|*72Yu?1yT6oJVn9M8JoSq zGb27d2$AUMD67lDQ4r&mp!#yuoxhJsCDE zh*776ja`8w+B4#FQnKk{L<$(pKTJZ!z4oQ#Q}TP0bV^}wmpLg0P8#Ex4rns5bOU6F zpZEfX_pZ_n&>fRoB@{4%Ea63T$i`!$L}RQHURWsypJja(EGWBxUG7G2Y%&+Fab)%c zX7as1#Hsk`n^b@y7Uaj@=n@AS+^vZ_klDk8XsVnPrqE|aHuO4x!54F*(w>Z6V60{gyHy&~LlX#oMGJZo zSSg%@8F6bTKOQb#Yny9OyzomsbMeX&rX>ZXb&zHOQihTzfft2Db{O8U4$i7lb_k`B zdMC+95I7C*B)>~6GVG5q07$~1VsNn2Fye`FRGq)QEaIT$pxgoh1dX%d7|C$C8QTs8 zM6+-S!DdY$4L@ipLpYOesMMnRlxdU*oOuik&u@vr9=tJ0LMWjzju*@TiCAwL-V|Fz zZ5g4I=*^*$AZ^Gao9e-bU6JrGu{DHJR?@gbY6M1^3`eDXO^Q`I(4K5FGdWMM| z92B0?u_dI)F94I|oQ%8TwbikBzk_UDJPr8jd|m# z`Zn|ZfcX3Hw-<=-QVGh! z0}6MgexOXL4-hRyF4iiU%vFEc5+5frOqfQn6a*Rmef46} z4f%+akE#r5Jn`b#;Qd~w<=^VQQF-<2*=*|G&vaGB%-+?!oco=xny+-#thPVpzwftx z-YGuQJZ@{2t={H1-=<;BbHl&QI^g`W=O?Fs47}DpWPC)p&CRP#M%F49y86JMQ;V~v z?SImy)34Lwv{yXlMO=I|pk94tn^k*s_5a+Xu)U zP?1qc21*SBNh}3~SPCv=s9;cROSlBf7G&Tb{=;f16q12-Fyv&gFa_CM$WW2df{a2k z1es+L0gwsKR5YYekl{d1YYMO-!F`ZJEMLJ+D4gpn zD;!y3@bK+q+{A$!9Fo`*8Ad+?3vZyx!1c~K>1l}#R1i~W(?@84ubTcfP=!PDh8Gn= zGx=Tc4ODFJVG;yTc1ufWVo*>*U{YWsO^APhP8}TLE{m1B#0+5bZNt;tGQAhdH(D$o z$x7hs{LVL1OPOUePxMbpsP<0|Ob$xcXtaUq1pkD>Pi3)P3yaL*zO689_R&CPp5R|7 zh!q1&J*{xo|0&Iw0uf0t09s zG(+fG|DA4E9_{7|4Fg*@=VL#5mQ3a@Q^+jk^*UM9>m-v~%jMR#mewjO4>A;1)|H8~ z!s;luR#@ZfS`^1WJuIzVi}y2o@oD}!$3H*w&n0VXXG(2h?F_i~a%&H{wG$E*ErwCJ zl8lX(*2=;KWZWd<8X5P=xC=v%cuM_zG7wp*Uq)&Bk)b6cm5g*UvdPFJBcF_6WE7II znT)Mu>?C6^8T-jNOvZ6CPQ%a-ms{IdSbJF^mmQw6gY67CXqT9W1Ps zI=Qtcm17k=U5joa0T9J3u09C%Mp$usitv?%wJW6r2-w`of3HH2scaSG1B_TRhr&vb z%N-r91eqMs$#jK}LP7qHj*f`r=;G>VBgkBfBV8Ts1vvn?xVpNyx;qHgGFL=#LUP&f%Fl0u=Z>FTPi>*@nA$Xu!M5G-V>KvmIAWr+F528B_E zDnk{5gS#+PBBzY%p$xSbEELKxxeK|FrI(e`TN!~eDkGHM__+GG`j9J1*@0Y+ z%FedPN!i&&?jlzTHZm{QVoMhkpBK8T9RdlG3rY$r>ZDM(A!m1GPr1UzUD-!wL52-0 zL;`T;1e;RlL_kqT8-{@)- z5zr;Olam8#Yj9B-Pi284K9Zj@!%2`)GRebHkU23sdO-1US2V_O1RocJk2{%Ub(|+P zghA#2stfhX5J*8XPgI6}a(755)IFSSomn^GCPEZwD;9#PIpZHhEZ4$O6;L{7l@(IJ zG_kn|GSN@`fKcEgV@V+wIorDk7OKLrARcF#!Wo60ZwFc^oS=a9CbN#En%*S}Eu4U4 zwy0d;1bl6IL<+rcr6P!AqMN7$FDqM>1rV)3PqR`9Fl|(pGAAb|1p<|^7AnEkN+tJn zB2(_Od!-2|}k8&u> zA-)`@6aUx(AY8Vr)cBx`NTe*Bg5+d#1V_Zj7CyGhSQnKgf#xw#mE}MQiysR(ate}z zNaf0W)L)Q$;)`75NQmmnZBaG&C{-?k1HRH9NE&IB<(zD7Ez$p+KmwRP6cVx-w&Xyz zvTzkuM_ITI#NvTyG7o3L!9xP!1Q^zWg@=a|edHb<{KMD^T;LKYKGniWnI?CDyvtp1 zpeM?moIR8dc7m1M0|m8pwgs!P^>A|L4tvZ-Je;`QQLvHQigssKSP!rTxw7ypX9bG~ zra=G{43@2jt&^YtP|?>J^|w@b@ap2LbU{5(R4TW!@EagOE+-3eQNUZoIAEbLfMv@q z&I;HpoSo6)APdm zIZy@20u2Qk^`vlHgm84v#z$E=+n%TutQ_|FJj_E`Bv4q90Ez^ODhtn1ZBPkI8H(#^ z%fFyTJHgV^10`7CBDVs~7A`}lQx zqVNoQJpw(woE%i3yECweB~$8WJMpp_66j|m2JlHip7t!hlP5)|s=`lMc*2qU!bbj- zp5np@R*l5W$}$izU!RR3g98HsMF1Fvq$E^3up?G$VoHwG%#PHanCcS>5c-mR^Z}04 z9rY9)qW~Be#gUPfVMLF-XYiQdk`xB=6+MWjh)H=28TW8B#Bk&ut_BZRDuWZ`7}O6* z2{ML^R zpQ6)?JO2=!-rRXlbk-EVb;Ylb_|#v*n*c88zP*XK=>H2 z$SJ2mgmwIiWJ1=WylX1M@TQ&2zLUQSM|)J>fr zAnpa<2ANZ+lNZ{rkU@om#!TLDO}RI+yz^6Z>3%hVaY5tBC}@hOubXzS#0&f<*c(Vhto-A;i~V-vF)nw z3HmTNsXG?AI60v=&p=7J9cU*Dynq|B5%?k(mI>*|U4?*cUarI*JWT^_0iF9WCgSPh=;BDM8-xn-BZ*lb z!1z!o4TUq%c%W=dsZe`-32o#=h#d4x!UC5bl=?IW-r%fo>2@jsTE;<06hQ3{GC547 zA<+@pFp~itiJ^srBsdwpqwbW3VnAR42#HwSRQ8g~Kq*R9!PsTTEL*h)Ps43DPN zJD7$vHE|FVJ`ave<-ttLkZHb@LB7#%nB+Ii=$9w?Pmei2pv?j7KE>;Ivf^Ecre4!k5Yy(CyU#j$8C>DPUO20 ziO>%>vcOI}u#=5IlQ;cl>Q-qKYcmVh@?b5}f&!KLt(b_wLJ_vI2&p_mD)Ubz|D7yu zDl9BQERPV&yCluN-;_p+kk zODs5#r_W;>*I0ypJVHMf0YeZ?9nm2u!c7)oB#$r>5uk`s>hB@~EEM6c zh!s#R!^&NjU<^+%h9wxL)Zb?bhEan1VgisfOK_hh7|#=oX9@C@`bR859wm4rCIG#& z1dmvPNj$+M2i}Uql_5&~Q;`JVpoC9Z#OXZZbgCTsg8l_nu5bZGc)^2a^X`Cggmr;F zELk6DYGgG1#Pk)EMj9SsQ$P!iN6eydz-%2Je5~ZdegKV;Tu32d#tAdBA`CKO90!5M zQ*t5o-6q21rNnn;t{cvW_vq4w}u}=Cbn6e}T0<}1b@Fgk$k_y8{AhCoPElAV| zaH8RfTaXzTvK{dQI~om$2|<+v76GA2L3X6IvvbvdN-!|=O>tCNqX$c|7;?BMeV$@K z&4yec0H`3cu!y!X|TjVKZno`VT6+k_b76~_(@7QsBN&` z1)ZeI3ey_;51Ex1aM2^QI(-zN3};~Xk(U*O7x>(V#-?Vezwrbk>+@fsW?1#Q>3vWDTt;#L&sC?Nujf?O5~YEo8eE0RTvo_bk{PG@|fIZ${Y zUxkADCexm}xOTNfzrjoe(hh_p0WvG8x1iE!3&R7WB(m54%s(Rh1RgrdBA} zeFu;|kj33Zz))zb1h6hJ2<32Dkj%rgIS6GC@(sz1i&P*6&MlaMzc8j zLY;@wGjt*iP2ix3E-nXTi%LTnppZM zh)?&CxpoEaNxKbNaaDn+C^s|(5bZ9P0|8@f?OXTLqxe2t7gpEwfDS zNjOA%V(yL=2O<#_Y5n1YIf4v}2IvZ|?)Jn~#FY+oDP?gFu{qH;0z*AuQt8+TCzcc? zw<1r;396E@R-kw;DjObl#1WI;6PU5FQP6-&8VXG@h*<+RJ4m=Ljw5ul?xR1$S_`Cx zmM0OkSd?wgfVQ|>S)7X2^JHNzPDH^Ny4F$spk%j0w+H*ypO-U*VexG0(S^Ghl4!Yu zSV0Dx)Npg4WgY0|t?EEND72^}*un{YGmJF26qX9o&DRm+hye95Ggnb)IhJCv6~YUb zA%Z6hItQB**@^__o&mQb#neZTiA6PpHEn9eXlNNZ^D^uqX<>2{qV{b{sMy8 zCxpAy>PBim<{^d$`UUz2X#6!4llhYkzr?`gq!6_(NbMJt+$bnGNTUl1@=pj(*6M;o z{DYH%HCkU zPSys71naZ`+64bVT|hvRe@JjrKwyBsI!G6+^Y>2-4)ANF3Gmk@=#oN`149}G`!`As z2}%l14hjegRO0m*wuVe!O<8rrub+1tM(wX7h4>qDod1B`z zRkJI8^w%k@75xvG9j>2s;ITgY?B1eHN9q-Cad|fC)XEhf9gd0})8d0GWBMwef8yTf z$mfs8KmGjtlUGwl1ZbvJ-Sc{yT}qGXTc$Riadmt4j04Wc7qoDHxUf!}`h znitQ%*QVO~KR;}9?D4MI=bvu-*7A8mgU+vCU-{G`>BR`gj^D;9S2dpEo>b{4&#d3B zSNUXtiz@cZ=-T@>y{H{)<5YjB-)*16hl-s)(vrTP=_}7H3r-ffR%zWl>;uafv=H( zHLi*vGz-ISz!dD{%fL>)Ozhl?D7C-PSBOH$VC?0?)0x=M7YSP?zO?s`{+j-M5ZxHC zK>*+h0Il8!Ks0s}W(v_rl7hsv_i-@nMnD<>daufK0w7%0QwE4=faua1!MH7$= zxVi>F-QHEA4yYC`bb*OiQ&2UXFc4&t2ISC|&~R)NrD|(IFs7ANgT~&8!%o0i4t|6o z+SiIJzhNe$tUSw(@G(b70l>C?SBX0z8Ic8%hYn3dRgZ-&A8sR|ta_gkN)2GFrc^eL z4r*HL{#zwpjs-|?*P``G>}^5 z&DH9_sz;dPU56^nJC+2nDTbB5QBkUxAM5DG>Pny{092>SPs7;Jjy+vqdOBnASKfqyhIl%1+{KgIoqrG`s6M&97E0hEsHD^R1+4u5L2 zB%v`9C%=DUW6ZWFeIldJEVMao%;$~8{V5*#Q#Leo(t&~)WEE=!@GkTiV|E639sBuW z)T7bR7)BXP2VfII`)7bnTjLS{MjP|^X8_Id91amI``-YW2jL%&h_WAHmJ3P5MmSoG zST7JhMW${4(@bgXjbf*?=+3uUCUD8xHv0^EPxbR>Hu10Ydt zs&Ek?|6}qZkh#DkNg!bmm*f7^X6XSe=8D{nIu62u9^MrcM}y&Kv5 zBW_`yjX4{|W?MmP%PM0( zi5@gKq?^>t*gA9~@L#B32V~J796bj@8=*}SzDW|y#6OasX@VdL#qIyCY-s>||7<@- zw*LajN24CZz~5B61IXrIAbIoQ=QV)-3nWi;`F4^|f>vm#DIvdId^L?}$|h;Xl?Z9s znEL%lV>PlLEi;8`giw|oTXxLSBC~NK-U`f5~Yb zX>tFi*kC$wD63Cw1jxT32GcBM0DgES7iM=hWAVp)JOV^YbHf|~y9b4SWs|5mKI2hA z($gh?uTXV+U_^^SU+rKrvT?-3v!0w{qI|oIOq!LQ32{Vzh@Iq5Vg+Gv6IMwJ*&bhN zu5{rEK={2ch;SrGU;u)kV1MsqByRJLI}pj#@0(jJicOR3sYqm^w=pHnu25lz15pG$ zm7ymW*iSc+YD+2>zXq^YWtZSxz)1GyT1rCV>3Y0jTbpWR6 zKLf)n-Ua|XiG8F9?O+x_6-RAN@-IhkJR;QL5)1qYi8^t{YiwiANX#d*rgNcKFcy;NvcRVE zgwpI|4Xt!>pvJtZLCuTKV;n=|wq->&CM{iT>M~kJNSr>5abE$PtP;NxR5dsueUMI- zmaEFl$|Fab)>r1%tqjk~+>AI2em4b9%8~pema#_mz0jDQfL#0Dj`or*V?FXO(0!)=__kaw@XS+vm!QD zu?LO_MAt4+p|w9y53k)o#cp7t0C;GI*Y=gQWdSN&iKI)><%m^9HuS`s3U}k-;W!nG z%6)jLQIgsp_zkaZmZ7h#O$VxYDqaRcFtSsz7oZHKdta!&GF-u*jHhiglXO}Y0I5(^ z%1W0;?@_DRQ!tq+s;nH-28qOG3wq5!MHeZG_28vQrpMU`b?;RtUs?OI3ZIp1hIuNE zR1OphJ0=DWqQ^8uTqQ_vFZs%XIQBp`pdkYRsqo-{IY2`ajyqqOzt}RI>=HQPl|X5U zQu)d>CFwybq@jSN@~Or1!R3Z@*NW8UBDEVXs|Ee`=+Itj@FBYNbRT*%0eeKGg0c$( zRk^8IgVMD`{e+fWP?{! zA~wO$H=Azj(&hN7@F0i3pGudLla;np4^@*#NHO@~DE z>I1#*#o8K;NH?PqI%E}CDa1=^j1YWf;co+&%^#SM0P_tch&#Nkm`SER zkQEMt5SXF(h*=r6j(i(96W&vzwq-y{d>f?q}~XlNgMA%{j(Cws9)c=r8RIL&K3ay^DvUC*<{aG z6;4kxzzdhH8)YaqPHJ^|kdz^4Rics`lhe4&x;2RA?Xs3BZVl?5kPX;LPJdxjYVzcNDoqKucM(^GK# z!TJ(aWRO%4CNSRtkyYs$9WF6p&PL2j(g(x-6?;q*5vy+#4!fx+Z0TEdwpS zGF~p|bAY0B;)ey8*6T8jy-(Jzj4Hf0R!ZWdg4kA2fr0W3ni5}GEv8l?-XNAJQ3oao zhAnan&J94Ocx?a^QZNrj1?+xo6gxwFmP6)4ywZfVu$pCNsmz`~l3u9umHE6QTfB_K zD1sH+7n`gFA*1~9+m&Ybwyo1Mq9|*|t|?IyGNY=iL+jZm>W#dKHkEY%p zeX*c%dR*0m&DRSrBV%l1`?QF86g#r6_0`p>)fcWUKIS^;V3VqyCRBEcw%hvGb)SX@ zz6^andO+NtQ%7#;>pXqz%6+E;%KzBDUXMG%=^y1+8;qPkbK4KYM*rBlK`8duihr%i zu995l-(Zt?f`B)Ca$2RQcSuOf6xiLnIvqc-gha1v0tS{6{&)SM=GNE%YmKdh*4PPS zjbjqlI1*uvR+ZjUnqXf@N14=3;e?HYl&Yte%3L}hTrG-O~!8uepB)L-_;`jZ@N& zod$Se7;(}N*BDDcNsT)!`0jXG6r&hac3-Te(3&_lKL}M#;F)hhp|S-aZZLlSLXgl% z(7>if>F96;)t*Y4h@2YZ8x4%dB7QLN9)UWe=i)Dtm6vct+bweNrKKoi?ccYYMM6WA zlUAGQm{B^zPd0Lxx-nv=EV@{YviXXbRv~Ai4a#!}qmu#1yRm@l zElR*F*{Wr=Db+7Pz%@7`of1@PGw@2}LyPr;SstNiUD_eV4_9I7Ua%GOGoJ8iDN=_P zX}ROs26{ z+ge-Ice0RIvJ%wot?lYt%PeI@L2{Yp{ATK=>Ix=4&T3l=nK0jSp}bH~dz+-QEH`%b zftM-c)9?7~nZ4!Q@(*p=#!VIG7rBp77g_$OF0$A?-$E{v%iSPb$`lKqMK#{J^;QpR z4w*vjXegM>3Pl*gN@UU1(%MblHAds6cD05>;bzx8fh|4cWo2qy)K27S<7U%Er_I3o zXqqZ&Px7&IEBm4cjkmfggJ%QPu2R8K6RZyQ^Y_E04t_zs z;0)1d3{JKFpn1s%ajazW?qUC+L_X^Jl-%B}hOtCZIl6S3cz48_A)C7As@S8wI<2Ob zx(1K#6`Pun4%JI+OpGcbCc1H0aDc`qpk>PdpYX5{e@#twbzV_VBUqD)l0pK{D5{HO z)l3nOOU^BdWX_-ynVq~yCKI;I8P)B6XjX+2uNuu8ur}z2i8DXBaN~G~<85Oa)~G-G zxAWGgmfP*z_~OZVpR~#$`+Zi1cKg=zgz{B-_A85f-~Dh?`^(fj>n(pgoi`%z^4Xfl ztm2dpyS15ctZl`uIm3G_vR`N0c|g{%(XN}WCVX1#`1OzNo#Gax9#8$E*R^Y7W)8kG zZ`hc2m%K+-+Ir!3$|hfcPnMnu33NCXV=z1 zr=iDkwgpzJJJPlDuH|PtuHD?bxa~ESdi{yPi+YFM?O$I}%dX4Mn7pH!l$YDk(2UfIj9NjgzKEjkVXZ)CwX(92$t>He+o~faw^}~BshGi#Aw$Z_ z087$uhMcE%qw?0YbWqz#AT3JvQ;>^HP@g`%b#LQ8&fI9-_7mUb4MJONtDfXNe%F%A z>jrN)oKg94QS%;C|E$nG6;OH@|&g8eIAA_T-EC3tt%A@esYh&@`>kxV=txfc z9y_9@1wG&A*tq}MjJWUX4{dOuiDSEneLuS%nd>vW*9E(&ZBi7w`nEha+~bKy)q)@D z`S)u7sCn-9Q);enb>iEr37XZvAGYgMv2LZK0d=>2*zL+-*B$QdA5TuL9b^aY_7k|< z9uw}i?!vuqV{hp;$3yNCWa~^j8F9A)a~|?9akuJfZ{F#Rx02wR8z{?S(o!->5ohFY zK^i~YFr(3gF#d+CVH$}}b>4raXd+{_cmrd8CnK8GWqZd48@*x!j71RcY>~ zHFsn3v-TX;s6TrAq)~l!i=L6K3p+16;!t?uYTLO!d0p>bU)pNu8Mp0^cGnp0@Y4Ut z_3H66kDRWXAwT2StAFidYY)gip1kH)hmVI=9bV0?c=Ur_?M{tM>RxF;RDR>wTN5vj z`tH}}Q)}Mn`)vQA?-x9HP}#9s?{6Bu7=P=hI(xfT`1gqs?GS_A=jG+Pi`#V zLv|p@*S~!EZ`#katE%osSyr{|s0PQI4~{oF;&1UgkS+)pG#jrD_VL&FfI`)b-AAr!mTS#A2l%l)ZAM?O(`Fy3CL~`K6Rmd$nu7v32l>l{xNO%i7r$6jas&~ za)eFu^SdTK>GbC}A1cOPYq___Ct*9M1V>fL+VuP^=(lO!_bMb$@@(jn zG2pfRpkKdKUU-JwIk?CN$G_Dt}zeY7pG&c2Js$24EAbX%a#p6{wIvf2vvwwSXw zy9EDQxMBr=ni9xT$1^d_&i1ofV?Te;Kr5?Q-U4HprXop?CZ4v2p-v-8KNhCa58I^| zPP?U&(~?Nt9X2R0mA$#iWHYro*dNRbubBCPcj4YG=JX@y|0G*|mn5}5r)OM6wRVTs z%zi3W%Nc`X(wkL2n|1imAGZg*npWQB(l3qkiYskuIN$H?>x;WvMpr+RBm5ND-EQo` z)vBmR_fuDPXg6WWwt{v8XSK2U@ny|l<_sEh?91F%BYx2T^l;mQMvD)`Mf|*GRp_NU zsnaSgU6PaA?T-qRue}VMoHPII;P@&-B8o=^mp`7{+v?ktE)$llPiy#NMf+Eu<<-41 zxMA#ta_XK>PfkdDdFViVYfYzbYP(%)p+1&V*QHLi?}MU4=lg|DIDF^T>WYR)<>ZzQRqUX%qa$JALYNsZ zb6Q!{uSK`o(|)b#_M+ZpyO=3GuPx^6vnsJqb;SJe`C+4*zdtWC&^zr-@gzf5)j|=CY_K zcj5=#Yv07@hwxSQuMXYv(JZQdcvz?Dh2DKuhBj>f?ZRcm`omXE*ixmVODKHFCXwDSDT z#l4cy=R#m_@1xVdxBYFD)A)`VPHxem!|F!P&N=Zg{ot;<*^9b=)_wTo3G*vQTJ(By zY*C6`-jYW5d>U5Re?2Ei`6z2$)0CoTUDi+VFR!cOH12}SMeU=kqpeS$s&K1dujR&5 ze>M1}>bSWp?f!DB-D1_XXP1|cXuZXzUmIP&7SU^4-i^MuVQ|4Yy8zn^&q7VrD^9T& zeqHd_uWejbX{W#LRNi;k4lD1WSEhv3PTTYO#3=_RoSWsn+A(hS{e`PXrxrW(_t`Rd zfZ#QC)r0aMJT6~cZj1DidbJLOE+wJ3CryhZ=l zX|twYaarcFF{qQ`?4D3{k+lu@_wN$_E}u$Tdz={gpWxr>Al!)v1|I0ICfUwftu^0Ruw2KZLIyzR=>eKR^&@3iXZ1&`<&&cB^ldZPWRJhjU8 zj?J0aDeh5|E4Tb?_4GJ(tsjK}H$T{RcdU)`6DP~*_s1TtddR=VM{^!LO7U#);)5Gw zyl&r!UbJ9W^_YVbo<|(BJ>GZC@wF{27e4zU{qvL`>ipa~X6@+Xzt(B(TYKf`j$OMr zT(fBKSN}bpQfS*I*|m1vVcNyw^4Vm29S0C&ehiMcw+|ri;~EZ`tb;J8w;u{4mXs!?S*A zQvCUX1o>B9j_Y1LnYCVav|78^*Uzl>>{i)J+X!ORYW;-5a%HjK1xbq&{_EmJkxRj<@(bF|U$UxwZjVPcZoazzHC+F_X6nGT z%d~NO;w)Mg?`h@2@fnGmyUPzntK2%x zxG=QEmF`>C^qA>+*-JKh<(B*hA0NNlME2X2?Gx>+_D_hsazDoXLdO-KUAr-%|Cz#F z*C#))ZaB)~)~EGqRLlPB@r!HuGkhJN*j&lp>JdHXlL2-)Q#LOMnVsUZud~zb#JJ|= zr+=(!e#NGe-?PJ-wu3dH^>gg^-_8zwJ<87Qm)&*=pWOdpbA>z6ACK46jev-_!@U5EtP#M?VnrC`*`@R`nR?`iagxl z^f|x6_O@q7 zU+nm@&3$Fo%W;0`>tFrSdH?w82a>nV@%l)qm52JQ={a%pHSb@)T6-{QV}7jF=`i0; zD<`jAlD}fZ{HcQ~o&W43w?Wk!`Ylsr&hI_G=8pNlk38so_D+?K2WI{jb?J#rmo?UY z`2Mv0*E4S~opw}H_qEf$-f`zTR9>e}(O@+qTau>#@~SazFB3+VgtI zT=&Sq4?5gvdhD)ua`@RjukU`l^j4>g)8Ev!-tyyuucw}!6@M?Sf?LPA6PsH{SKfWq z?_`tjT72-`Y@a3b?=9*1-Pnse8e5ecvU1an52sC-ytVEt&pg|lZ5wWXth97d%Z@I( zJliAjk2;U8t!i@V@~a1N9kZWaJhdkIhy4Q@|M>lP{nqC@HnSW3$sd2|*UYYS&VKvC zPwzL~-f+{0iM3j~Y}jg{pc6ywX5B z8fQXbztNF0orR?w-Ax^5OpH}3QUtwmm5QkWdu0`LPo-?X0sB4!(Zty48;kuo?R*&3jw3R)1Yo&Kb31*x=E_bJh)>m2iEW zwtefPU!Q3_e#qxTQoLt>-OIXfo6&zZJz;y$G4#m#TMIhnpBOpjimYk17i*>}4)>X{ z^WL2$y{3Qm=l&Ma{d3n`yqY)kRDA1cTd$p;@!-}hbER`b=%I*$TI7p$yzCSLt%lWXPr z-&uFivbrQ)e+cP%C|5<)q-7)neYaQ0B;|mGsiL>d_ML|=f6@GW1ROIKQ$GlPoeyXi@Vt`MRWewaX*F70D^?KlIhok$g%a@;9 zW8IaIXPHj<=Nu}3UAJHD!2va9UHE3&phL1ItBRE6s}+uQAGu|EC)L^twMIv+IXXPT zJv?CQF@2mzgVUcsNLg_ucYo-jBQN}_^z*#6wzB%K23u@=r;hwQqE2kwk*P1||D-?n zwfbQAx`&ZF*SGfU(|2&a9`jEB_TbU;$o5|)e7tsi*sU)&&zbb-b^n&m-!!}Bba(QL z358qouU220-+O&V)n`3-4gdN?$bo`O#h(4_ehgiE;$EX25jM9fH_H4qw276)($h<8 zDkokayvS`sM6Ym7(U0dwuKs3i)j@wg_8Q*VHK_K@uL4I7eA4~P)z8NcJTU#_++Nzj z+sE%2?%w~?KgvCNa6VA8`KO%c8wc$lGpqlO=@H*2um9oo(a$Cgx_0OK=#%>^|5STt z?we?&-~gA3RQXe`Zn9*>%*H9cS+NvipU8-~BmI^{Df*nFnv3xD(JO zbkOr^ce^(4Uom8W%dK9`KY3I=U%mdp7r}=DCww`*XN?w{8>cL`iJ$-KT$3obzZ@># zv(G5*boBm+W|z(@ZjSeE8@Bu6olkoIX0gXBGxK_EU~)>%uu8YPJg&Akr}=7ik&aWTyUt#^wZ*$gP*U0+ctROcI0vhO9g8lG*1lO`OVonVN7HC=i zrw6GbdFf3Da@uqt$EE}HxfS=H=eT(Kt~!_bWsysVfNvjs-NSoc%gXfz-0Ico%gxro zl`Nya9kIuu%7vf--zm@8-w)nB!+P!hkTbG!nwF==Iu>X@`fzf;8tH51M$NvJ+V|uy zvtriUHQ2M}{POy%huW_BVQSBV{VG}AN*;XEuS+du!y79UosMm2wW-g!y}lNMR-`^W zl<}}}+=B9tT7P>fSi3S)8<_va{3K_eQ!PG!diA1>M zTECY|)ehb2EF7A1N!fT)RNr&=?uCC^eEx&=AB?VizS+9*eQu8JII_}%1r2*%o7BW- zwSSL&o0`4yJGH?gblv(jp9Oz-a!z4`Kcl;S>K#~fPe`VAM9jCdomW+?KJw6`Z!Jbo zcoKjAc$XdHCx5hcr*~e>c#k??AFf>|xaRbbwvCPrTld*&&+1E;C*Mt|+W&H$s5$Xt zuGH*v%DY{&E_=V~-n@pz{S!lbH#}4QYIYyz&aH=Rcq&}px>8;g|I<$Q4cjW8?%M7~ z$O7kE)uXn0Y;H9y;@Yk~IYTey+^F%(j@C2w{l43?`%lFa?skY$FJ1A;FL!&-Tl3<= z+T<&{rs+SpclKVp8&P$ay4Cq&>F|`o>*Eshe44N7(ZH=wzbP}Db@U(k9Lw+80_NJ{_%c(Y_RJq4Q?3h zx~My;qa`;6yOwX7fbwl3(n$9f_<3smJSx1(Qa??tpRCq@YS6;@TB!BK>gG~*a#?x* zw`E6zw>B#&7dunZG7@qMlCpDsQ}Z&^EertU>VPVKDle0*!|`leHC?8Ygbl>;*kCGM zDkW`t^;LP5HTtGJ7`zNgORrBs_`Kh^be(q}VTP91)-z+uuZUA%9DW>5Fz zoX9ACwY~XGyMs-3v{}CBVcJhgJE{dPnbt=)a??uOX8|uH4cdXcd}2wE9E0;a^P3E1vM^P%U}udb`KDY+1bA z%3;>M)aR+bQ|8xeUT;8;sHCd4X_>vIPrX+BXy?R-t?OTW(d78Hz~3`#uKsmR?R&>B zJak$!qt3MH9h^e#A1KD2t-8n0O_nqDD?^dn;b^ZCD+{bi|=n?EU zuy&;p>mJp9da*%cRoe9RJ;$bIW-Z;6x2J`b^%t^wb($45ck7UBzjH%}KQB)l;hE(= zJYwnKUt84EE!xwkOXBD~UP+CnjsE4whfg1rUof-w1~zuHtU{B!Qp9RoJCn|9^Sp!`aAZwJjN z@M!n??1t*8gRZZ6{^H|1_Jz08nyh)DzGvC~lV5%rl#%pl=!rSqqC4&=>|Sj_zN?@2 z(BH%C);0fY+2O@~b}bk)tNXxi(UB25TOOD-xVK$lG zZ;@TT_P81I^y8j&b|_N*Id<;zp!BToeEU`RP7fP1rrqlY^Tu~C$hooO=x-YieIGe< zbJG=L+I+D)&8Bd@|E4d$wz<{uK(9rSZE9^u9o6fF&~$XSnA-;n;@Xa1cwuLAP17+o ztekJSj(8N=H1>;p``9l&b~s@_t$2I+xhL%&SLtcjr^YW|Z!O%OcY1o?8l98IUAy|% zfnd*<1J7?<^hfwdXSDL~Hd{7!7`MdQ=KK8TSyc|ocH}l&H04AwtL_Tgmr6`w}* zY9G;X)bsiaij=>qixFwj>WfQ=EBg>u=W`TFCF^+!r=VEvaipNTt8 z?cGdvoQB~DE%tDjY-D}&239}6Mgcw%{{9g@LBZIc^o|XzbaoyaSmzfx0e_Z%KudGp zsHG8pZ~vhGkB2PhG$2u3_`Sr?q8|2N5!J=5xfX6-Mp4~l%PsaXk$A4=IvNe0iu2Rp zA-6_+6AN@VqVxY#?E~5_E$f?ZF#akyy?F8o{qDxKVrTCC_;ju6SNA>Wka=$5?oaA@ z1}fE^T@Qa>eC723JJr0aMVbXC>svK%(Y^D@<@ZP1ygqyB$F$5ZR`1+;NZ&eqebet2 zwckHC>HA;*O4$-WxpS4B+oPvUdiZKw2j!EV{pQy@zrDuiN55M(-u-@sVw<@iEZK9h z?~Pks=FH8@_Uu;w!QQ9wy**w8{II2&ckZsc=gVC>^qp5w)ZV;igB<&=OZ6F3)J7lf zHgHv1hsRfaJ1-kv@snzSS35qPGoYK#M<*ulx!yK=t8M%90aV$5zwV^tF{#Kb3*03MRW? z+H32#^$%|P{Sa+MH@jBTM?UUQ*T+l`b0(>A+&Imohv6R#Yh8Jte`>E$8D0O=4R@ec z>@21YcSNX66Qg0m>A$ey?hUX@s$kx=kO?I#+mknF$9FBa-`u(A;?c?Z36)mnKf9P$ z-`o3S#oM=)1CnR^_L#YQ;m}VTw77S@eg2`EOWn(l59xpISPS17XTv{k@ssV*Wsd6O z?fo3ACSG1KdD%sW8w(zU{v78Rv+VKL6B@+Y%P#1uPR&XE{?vzd-)}tAWYWr2w}SLJ z+v1yS^yz%&<2|qP!c;%paY_CyVBDPlXTQsj1nj)~-RQoke1b^+e(7}`Gi1$wMW`^{ z^X{2m5_jy#x*2*OeP%mK^4UdScrE*GrSZn=Z|w9U!hcpwTWs7_aj&gy!scuyP5bJt zaaa1vO4x55FJ68{#%{{$36}Twd|g;ks=VmV!uGb}#k^fy-YnlHEq;`y-IBEsxTd2J zSnx%{#w9o#wZLT^6M9)UXvQTV1t0JhO5nhvA@FKQQ&7QY3gMc7xC2})6Dp}z%JS|h z7woc9c=Jbi`qy9enNzY$LIkcZ9Hap#&yyjZ5LAYAeVprY^ufDoBp53pK zU=)$y_9?=>&8S7LBr$zrd}GMQ^OJoh9Xzru_F|%Np2jh$pKT4h?bJ1d{Vx{9BxPK*oiZW%`ng#WM<^}y;Js#Op=YLR zWK69>4~N;n-uMD=ZydA$vT>?G<0ON|ev}S*qk%2FKg}p+h_gc;;OzqC!( zBBDDEy6Xnf9Y>sROQ1W>{;VUA_tCKjGwd4+nQiATUZ|MA`Sr3hUk&%2XMMEt->>jo zNrTOYj;5W=y8re0hl;(&SIkp={BzIS?2vE{?Z74%q2D`$d(M1G5b7#Byjf?`K$CS!^;*Gu43!r?-bjWxLok` ztQ&mpvl@C{@ z9;?6KE2>M(&M#ltczQYK8q3{pj-9^Iw58~*?3W#_jB*XXr8~7kEH_2pI>8${v#Pz= zn&a6F-B-O2jP-;xzaG#JQCIwaVvXM|jU5|T-k!E;xznPP=OrC|AGH0{nzdLk&EWFx z5+m>X$<<$HcIitWS6m;tb=@5oo9O|C*B4$o8u~c%UiiU__Y4mFJ@d@>H}C#f|Ce*+ zBrWv!oR47Dd(XQd!1UI8PIZ~9o9j&FICkAKyL~yn|6WOlr_jPCrgOkiTHvNY;Odbd z3x{8KVv#Zz&};0_jgZWu45~{N9_T(l71PwAf8nBT$-b@U6k`_vhszopmedV!eTBMT zl8Ke!fjhgAfszD2tp8_dW&&I%9|ae%gbEmx0}B_(@)=-f6FBXz4{YjjK@9*7zXRF8 z%b1x|^_hU{vf06G!Q&7G9ub>B3e1qSGZ_MBr{U{wK)qL{1zZLkAZ^U-3l$c^*oSPnDnwl zEi%+@@p>8SA8R;O4b_uA^Hg3EDCcG8W&H25!}p=1>NHQI1MjEwPuLv%_Thti>#xmq z`CFcb3F)oPot-7^nN@a1EM>VXBa3F*R>65Iz9?wDZ(GzPr+H23s$ml|FR<^(2~N?I z2R25*!%Nt@uE@hnO^jX!Qt%N6;JPSYlraSZ^zkBJg%jsyH5sh5iJA3hvR3Q?C#IM0 zIkt)9F1O~M)vD5BWzhHw$p9vO!^T$zjn54lpBOamWl>n*`D$tCB-6-e%ht`AvV5Di zcYoG8buPbYiUu25?!T+t1zfs02(kk9fCCPexo9q5Wjee551(z?{@xgGVTGE1vFE01 z?3S6@;w1B{bP95U1a>SyYjW6^*$C`W-ud_NjO~86oc}FertfW}o?^_nAz{%?p@-7* zU7PwGZj}ZY-tb@1aaJKa&oG7SRUE5aNo9n8!@V@`CrvLz+nnc%=l{^VmRxfqp=fsL z$EDkXv&`QY`0#f`e6Ntc=KdwjWwx1(nSJer-->^WJ)BNl%(c7dee$yF>8qLdR~i`2 zJFk2%KQ^~TN`0$C{{JuH@#%-p6ub + + +