From f4470b784f0cbe9ce3c294a57255d77f5706f865 Mon Sep 17 00:00:00 2001 From: AlexCube Date: Fri, 25 Sep 2026 00:09:01 +0300 Subject: [PATCH] =?UTF-8?q?1.4.2:=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D0=B8=20=D0=B8?= =?UTF-8?q?=D0=B3=D1=80=D1=8B=20=D0=B8=20=D1=85=D1=80=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=BB=D0=B8=D1=89=D0=B5,=20=D0=BA=D0=BE=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=BE=D0=B5=20=D0=BD=D0=B5=20=D1=81=D1=82=D0=B8=D1=80=D0=B0?= =?UTF-8?q?=D0=B5=D1=82=D1=81=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Повод: 1.4.1 на игре 3.3.0 experimental не смогла прочитать Пространственное хранилище (Bag переписан) и при сохранении записала пустой маркер - вещи пропали навсегда. GameVersionGuard: версия из Constants.cVersionInformation (не из const cVersionMinor - та вшивается в DLL), поддерживается Major 3 и Minor/10 == 2, то есть любая 3.2.x. На другой версии в главном меню окно «мод несовместим, обновите» с единственной кнопкой «Выйти из игры» (решение пользователя), а вместо PatchAll ставятся по отдельности только окно и четыре патча сохранения хранилища. Всё, чем пользуется защита, сверено с декомпиляцией 3.3. Хранилище: непрочитанные байты (чужая версия или упавший разбор) проходят Read -> ToPlayer -> FromPlayer -> Write нетронутыми, ключ - entityId, сброс при открытии главного меню (последнее сохранение игрока делается раньше, внутри SaveAndCleanupWorld - проверено по коду игры). Пока байты не прочитаны, хранилище не открывается и не пополняется, с подсказкой. Проверено в игре на 3.2 через отладочные файлы FORCE_VAULT_UNREAD и FORCE_VERSION_GUARD (в .gitignore, в архив не попадают): 603 байта хранилища прошли сохранение и прочитались обратно совпадающими с исходными (26 ячеек, 24 предмета); окно появляется, Esc его не закрывает, кнопка закрывает игру. На настоящей 3.3 не проверено. Localization: 4 новых ключа на 13 языках, всего 165; README - статус и число ключей (было 149). Co-Authored-By: Claude Opus 5.5 --- .gitignore | 2 + Config/Localization.csv | 4 + HarmonySrc/GameVersionGuard.cs | 151 ++++++++++++++++++++++++++ HarmonySrc/ModEntry.cs | 30 +++++ HarmonySrc/SpatialVaultPatch.cs | 7 ++ HarmonySrc/SpatialVaultPersistence.cs | 84 +++++++++++++- HarmonySrc/SpatialVaultPickupPatch.cs | 5 + ModInfo.xml | 2 +- NEXUS_CHANGELOG_1.4.2.txt | 4 + NEXUS_FILE_SUMMARY_1.4.2.txt | 1 + NecromancerHarmony.dll | Bin 117760 -> 122880 bytes NecromancerHarmony.pdb | Bin 36532 -> 37588 bytes README.md | 12 +- 13 files changed, 296 insertions(+), 6 deletions(-) create mode 100644 HarmonySrc/GameVersionGuard.cs create mode 100644 NEXUS_CHANGELOG_1.4.2.txt create mode 100644 NEXUS_FILE_SUMMARY_1.4.2.txt diff --git a/.gitignore b/.gitignore index 55a72b7..0e73657 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ TEPersistenceSrc/bin/ *.user BACKLOG.md FINAL_TEXT.md +FORCE_VERSION_GUARD +FORCE_VAULT_UNREAD diff --git a/Config/Localization.csv b/Config/Localization.csv index d6da77c..32248a3 100644 --- a/Config/Localization.csv +++ b/Config/Localization.csv @@ -160,3 +160,7 @@ buffNecroRatMarkName,buffs,Buff,,,,Spirit Mark,,Geistermal,Marca del espíritu,M buffNecroRatMarkDesc,buffs,Buff,,,,"Marked by a rat spirit: visible on its master’s compass and map, and rotting - every wound cuts deeper than it should.",,"Von einem Rattengeist gezeichnet: auf Kompass und Karte seines Herrn sichtbar - und faulend, sodass jede Wunde tiefer geht, als sie sollte.","Marcado por un espíritu de rata: visible en la brújula y el mapa de su amo, y pudriéndose - cada herida cala más hondo de lo que debería.","Marqué par un esprit de rat : visible sur la boussole et la carte de son maître, et en putréfaction - chaque blessure creuse plus profond qu’elle ne devrait.","Marchiato da uno spirito di ratto: visibile sulla bussola e sulla mappa del suo padrone, e in putrefazione - ogni ferita affonda più del dovuto.",ネズミの霊に印をつけられた。その主のコンパスと地図に映り、腐ってゆく - どんな傷も本来より深く刻まれる。,"쥐의 영혼에게 표식이 찍혔습니다. 그 주인의 나침반과 지도에 드러나며, 썩어들어 모든 상처가 본래보다 깊게 패입니다.","Naznaczony przez ducha szczura: widoczny na kompasie i mapie jego pana, i gnijący - każda rana sięga głębiej, niż powinna.","Marcado por um espírito de rato: visível na bússola e no mapa de seu mestre, e apodrecendo - cada ferida penetra mais fundo do que deveria.","Помечен духом крысы: виден на компасе и карте его хозяина и гниёт — каждая рана заходит глубже, чем должна.",Bir sıçan ruhu tarafından işaretlendi: efendisinin pusulasında ve haritasında görünür ve çürür - her yara olması gerekenden derine iner.,被鼠灵标记:显现在其主人的罗盘与地图上,并且开始腐烂——任何伤口都比应有的更深。,被鼠靈標記:顯現在其主人的羅盤與地圖上,並且開始腐爛——任何傷口都比應有的更深。 buffNecroRatBleedName,buffs,Buff,,,,Torn Open,,Aufgerissen,Desgarrado,Déchiré,Squarciato,裂傷,찢긴 상처,Rozszarpany,Dilacerado,Рваная рана,Parçalanmış,撕裂伤,撕裂傷 buffNecroRatBleedDesc,buffs,Buff,,,,Teeth found a vein. The wound will not close on its own while they keep worrying at it.,,"Zähne haben eine Ader gefunden. Die Wunde schließt sich nicht von selbst, solange sie daran weiterzerren.",Unos dientes dieron con una vena. La herida no se cerrará sola mientras sigan hurgando en ella.,Des dents ont trouvé une veine. La plaie ne se refermera pas d’elle-même tant qu’elles s’y acharneront.,I denti hanno trovato una vena. La ferita non si chiuderà da sola finché continuano ad accanirsi.,歯が血管を探り当てた。噛みつづけられているかぎり、傷はひとりでに塞がらない。,이빨이 혈관을 찾아냈습니다. 계속 물어뜯기는 동안 상처는 저절로 아물지 않습니다.,"Zęby trafiły na żyłę. Rana nie zamknie się sama, dopóki będą się w nią wgryzać.",Os dentes acharam uma veia. A ferida não vai fechar sozinha enquanto continuarem a remexer nela.,"Зубы нашли жилу. Пока в ней продолжают копаться, рана сама не затянется.",Dişler bir damar buldu. Onu kurcalamayı sürdürdükleri sürece yara kendiliğinden kapanmaz.,牙齿咬中了血管。只要还在撕扯,伤口就不会自行闭合。,牙齒咬中了血管。只要還在撕扯,傷口就不會自行閉合。 +necroVersionGuardTitle,UI,XUi MainMenu,x,,,Necromancer's Tome: incompatible game version,,Necromancer's Tome: inkompatible Spielversion,Necromancer's Tome: versión del juego incompatible,Necromancer's Tome : version du jeu incompatible,Necromancer's Tome: versione del gioco incompatibile,Necromancer's Tome: 互換性のないゲームバージョン,Necromancer's Tome: 호환되지 않는 게임 버전,Necromancer's Tome: niezgodna wersja gry,Necromancer's Tome: versão do jogo incompatível,Книга некроманта: несовместимая версия игры,Necromancer's Tome: uyumsuz oyun sürümü,Necromancer's Tome:游戏版本不兼容,Necromancer's Tome:遊戲版本不相容 +necroVersionGuardText,UI,XUi MainMenu,x,,,"Necromancer's Tome {0} is made for 7 Days to Die {1} and is not compatible with your game version ({2}). Playing with it would damage your saves. Please update the mod to the version made for your game, or remove it. The game will now close.",,Necromancer's Tome {0} ist für 7 Days to Die {1} gemacht und nicht mit deiner Spielversion ({2}) kompatibel. Damit zu spielen würde deine Spielstände beschädigen. Bitte aktualisiere die Mod auf die Version für dein Spiel oder entferne sie. Das Spiel wird jetzt beendet.,Necromancer's Tome {0} está hecho para 7 Days to Die {1} y no es compatible con tu versión del juego ({2}). Jugar con él dañaría tus partidas guardadas. Actualiza el mod a la versión para tu juego o elimínalo. El juego se cerrará ahora.,"Necromancer's Tome {0} est conçu pour 7 Days to Die {1} et n'est pas compatible avec ta version du jeu ({2}). Jouer avec endommagerait tes sauvegardes. Mets le mod à jour vers la version prévue pour ton jeu, ou retire-le. Le jeu va maintenant se fermer.",Necromancer's Tome {0} è fatto per 7 Days to Die {1} e non è compatibile con la tua versione del gioco ({2}). Giocarci danneggerebbe i tuoi salvataggi. Aggiorna la mod alla versione per il tuo gioco oppure rimuovila. Il gioco ora verrà chiuso.,Necromancer's Tome {0} は 7 Days to Die {1} 用に作られており、お使いのゲームバージョン({2})とは互換性がありません。このままプレイするとセーブデータが損傷します。お使いのゲーム用のバージョンにMODを更新するか、MODを削除してください。ゲームを終了します。,Necromancer's Tome {0}은(는) 7 Days to Die {1}용으로 만들어졌으며 현재 게임 버전({2})과 호환되지 않습니다. 이대로 플레이하면 저장 파일이 손상됩니다. 게임에 맞는 버전으로 모드를 업데이트하거나 모드를 제거하세요. 이제 게임이 종료됩니다.,Necromancer's Tome {0} jest przeznaczony dla 7 Days to Die {1} i nie jest zgodny z twoją wersją gry ({2}). Gra z nim uszkodziłaby twoje zapisy. Zaktualizuj moda do wersji dla twojej gry albo go usuń. Gra zostanie teraz zamknięta.,Necromancer's Tome {0} foi feito para 7 Days to Die {1} e não é compatível com a sua versão do jogo ({2}). Jogar com ele danificaria seus saves. Atualize o mod para a versão feita para o seu jogo ou remova-o. O jogo será fechado agora.,"Мод «Книга некроманта» {0} сделан для 7 Days to Die {1} и несовместим с вашей версией игры ({2}). Игра с ним повредит ваши сохранения. Пожалуйста, обновите мод до версии для вашей игры или удалите его. Сейчас игра закроется.","Necromancer's Tome {0}, 7 Days to Die {1} için yapıldı ve oyun sürümünüzle ({2}) uyumlu değil. Onunla oynamak kayıtlarınıza zarar verir. Lütfen modu oyununuza uygun sürüme güncelleyin veya kaldırın. Oyun şimdi kapanacak.",Necromancer's Tome {0} 为 7 Days to Die {1} 制作,与你的游戏版本({2})不兼容。继续使用会损坏你的存档。请将模组更新到适合你游戏的版本,或将其移除。游戏现在将关闭。,Necromancer's Tome {0} 為 7 Days to Die {1} 製作,與你的遊戲版本({2})不相容。繼續使用會損壞你的存檔。請將模組更新到適合你遊戲的版本,或將其移除。遊戲現在將關閉。 +necroVersionGuardQuit,UI,XUi MainMenu,x,,,Quit game,,Spiel beenden,Salir del juego,Quitter le jeu,Esci dal gioco,ゲームを終了,게임 종료,Wyjdź z gry,Sair do jogo,Выйти из игры,Oyundan çık,退出游戏,退出遊戲 +braceletSpatialVaultUnreadable,items,Item,,,,This storage rift was saved by another version of the mod. It is kept untouched until you install the mod made for your game version.,,"Dieser Lagerriss wurde von einer anderen Version der Mod gespeichert. Er bleibt unangetastet, bis du die Mod für deine Spielversion installierst.",Esta grieta de almacenamiento se guardó con otra versión del mod. Se conserva intacta hasta que instales el mod para tu versión del juego.,Cette faille de stockage a été enregistrée par une autre version du mod. Elle reste intacte jusqu'à ce que tu installes le mod prévu pour ta version du jeu.,Questa fenditura di deposito è stata salvata da un'altra versione della mod. Resta intatta finché non installi la mod per la tua versione del gioco.,この収納の裂け目は別のバージョンのMODで保存されました。お使いのゲームバージョン用のMODを入れるまで、手を付けずに保持されます。,이 보관 균열은 다른 버전의 모드로 저장되었습니다. 게임 버전에 맞는 모드를 설치할 때까지 그대로 보존됩니다.,"Ta szczelina magazynowa została zapisana przez inną wersję moda. Pozostaje nietknięta, dopóki nie zainstalujesz moda dla twojej wersji gry.",Esta fenda de armazenamento foi salva por outra versão do mod. Ela fica intacta até você instalar o mod feito para a sua versão do jogo.,"Этот разлом хранилища сохранён другой версией мода. Он останется нетронутым, пока вы не поставите мод для вашей версии игры.",Bu depolama yarığı modun başka bir sürümüyle kaydedildi. Oyun sürümünüze uygun modu kurana kadar dokunulmadan saklanır.,这个储物裂隙由另一个版本的模组保存。在你安装适合你游戏版本的模组之前,它会原样保留。,這個儲物裂隙由另一個版本的模組儲存。在你安裝適合你遊戲版本的模組之前,它會原樣保留。 diff --git a/HarmonySrc/GameVersionGuard.cs b/HarmonySrc/GameVersionGuard.cs new file mode 100644 index 0000000..58d3d5f --- /dev/null +++ b/HarmonySrc/GameVersionGuard.cs @@ -0,0 +1,151 @@ +using System; +using System.IO; +using HarmonyLib; +using UnityEngine; + +namespace NecromancerTome +{ + /// + /// ПРОВЕРКА ВЕРСИИ ИГРЫ, 1.4.2 (2026-09-24). Повод: 1.4.1 на игре 3.3.0 experimental молча + /// потеряла содержимое Пространственного хранилища - разбор в BACKLOG.md, «Игра 3.3.0 + /// experimental». Решение пользователя: при несовместимой версии мод показывает в главном меню + /// окно «мод несовместим, обновите» с ЕДИНСТВЕННОЙ кнопкой «Выйти из игры» - без «играть всё + /// равно». + /// + /// ПОЧЕМУ ЧИТАЕТСЯ cVersionInformation, А НЕ cVersionMinor. cVersionMinor - const, компилятор + /// вписывает её значение (20) прямо в нашу DLL, и на 3.3 она всё равно «видела» бы 20. + /// cVersionInformation - static readonly, её значение берётся из игры при запуске. + /// + /// ПОЧЕМУ Minor / 10. Игра хранит версию двузначным числом: 3.2.0 = 20, 3.2.1 = 21, 3.3.0 = 30 + /// (VersionInformation печатает его как {Minor/10}.{Minor%10}). Проверка по десяткам пропускает + /// любые хотфиксы 3.2.x и не пропускает 3.3 и всё, что будет после. + /// + /// ВСЁ, ЧЕМ ПОЛЬЗУЕТСЯ ЭТОТ ФАЙЛ, СВЕРЕНО С ДЕКОМПИЛЯЦИЕЙ 3.3.0 (build 25485021): Constants, + /// VersionInformation, XUiC_MainMenu.OnOpen, XUiC_MessageBoxWindowGroup (класс совпадает целиком), + /// Mod.VersionString. Иначе сборка под 3.2 упала бы на 3.3 раньше, чем показала окно. + /// + /// ОТЛАДКА НА 3.2: если в папке мода лежит файл FORCE_VERSION_GUARD, мод ведёт себя так, будто + /// версия несовместима. В релизный архив он не попадает - состав архива задан явным списком. + /// + public static class GameVersionGuard + { + /// Под какую версию собран мод: Major и десяток Minor (3.2.x = 3 и 2). + public const int SupportedMajor = 3; + public const int SupportedMinorTens = 2; + public const string SupportedText = "3.2"; + + private static bool? supported; + + public static bool IsSupported + { + get + { + if (supported == null) + { + supported = Check(); + } + return supported.Value; + } + } + + public static string GameVersionText + { + get + { + VersionInformation v = Constants.cVersionInformation; + return v != null ? v.LongStringNoBuild : "?"; + } + } + + private static bool Check() + { + if (ForcedByFile()) + { + Debug.LogWarning("[NecromancerTome] GameVersionGuard: FORCE_VERSION_GUARD file present - acting as if the game version were unsupported"); + return false; + } + VersionInformation v = Constants.cVersionInformation; + bool ok = v != null && v.Major == SupportedMajor && v.Minor / 10 == SupportedMinorTens; + Debug.Log("[NecromancerTome] GameVersionGuard: game " + GameVersionText + " (Major " + (v != null ? v.Major : -1) + + ", Minor " + (v != null ? v.Minor : -1) + "), mod built for " + SupportedText + " -> " + + (ok ? "supported" : "NOT SUPPORTED")); + return ok; + } + + private static bool ForcedByFile() + { + return DebugFileExists("FORCE_VERSION_GUARD"); + } + + /// Отладка сохранения хранилища байт в байт на 3.2: при файле FORCE_VAULT_UNREAD + /// в папке мода хранилище из сейва не разбирается, а проходит всю цепочку сохранения + /// нетронутым - ровно как на несовместимой версии, но без окна с выходом, так что в мир + /// можно зайти и сохраниться. + public static bool ForceVaultUnread + { + get { return DebugFileExists("FORCE_VAULT_UNREAD"); } + } + + private static bool DebugFileExists(string _name) + { + try + { + string folder = ModEntry.Instance != null ? ModEntry.Instance.Path : null; + return folder != null && File.Exists(Path.Combine(folder, _name)); + } + catch (Exception) + { + return false; + } + } + + public static void ShowIncompatibleWindow(XUi _xui) + { + string modVersion = ModEntry.Instance != null ? ModEntry.Instance.VersionString : "?"; + string text = string.Format(Localization.Get("necroVersionGuardText"), modVersion, SupportedText, GameVersionText); + XUiC_MessageBoxWindowGroup.ShowCustom(_xui, + Localization.Get("necroVersionGuardTitle"), + text, + "", + delegate(XUiC_MessageBoxWindowGroup _box) + { + _box.buttons[0].DefaultConfirm("necroVersionGuardQuit", delegate + { + Debug.Log("[NecromancerTome] GameVersionGuard: player pressed Quit"); + Application.Quit(); + }); + }, + _openMainMenuOnClose: false, + _modal: true, + _buttonOnOutsideClick: -1, + // Проверено в игре 2026-09-25: Esc модальное окно не закрывает - оно остаётся на + // экране, и уйти можно только кнопкой. Это и нужно. _buttonOnExternalClose: 0 - на + // случай, если игра всё же закроет окно извне: тогда это тоже выход. + _buttonOnExternalClose: 0); + Debug.LogWarning("[NecromancerTome] GameVersionGuard: incompatible game version, quit window shown"); + } + } + + /// Главное меню: здесь показывается окно, и здесь же сбрасываются непрочитанные байты + /// хранилища - возврат в меню значит, что прежний мир закрыт, и его данные не должны перейти к + /// персонажу следующего. + [HarmonyPatch(typeof(XUiC_MainMenu), "OnOpen")] + public static class Patch_XUiC_MainMenu_OnOpen_VersionGuard + { + public static void Postfix(XUiC_MainMenu __instance) + { + try + { + SpatialVaultPersistence.UnreadableByEntity.Clear(); + if (!GameVersionGuard.IsSupported) + { + GameVersionGuard.ShowIncompatibleWindow(__instance.xui); + } + } + catch (Exception e) + { + Debug.LogError("[NecromancerTome] GameVersionGuard: main menu postfix failed: " + e); + } + } + } +} diff --git a/HarmonySrc/ModEntry.cs b/HarmonySrc/ModEntry.cs index 357881f..f850c40 100644 --- a/HarmonySrc/ModEntry.cs +++ b/HarmonySrc/ModEntry.cs @@ -19,6 +19,36 @@ namespace NecromancerTome { Instance = _modInstance; var harmony = new Harmony("necromancertome.harmony"); + + // НЕСОВМЕСТИМАЯ ВЕРСИЯ ИГРЫ (1.4.2, см. GameVersionGuard.cs): ставятся только окно в + // главном меню и сохранение хранилища байт в байт - каждое отдельно, чтобы отказ одного + // не помешал другим. Остальной код мода, написанный под другую версию, не запускается + // вовсе: игра всё равно закроется из главного меню. + if (!GameVersionGuard.IsSupported) + { + System.Type[] safetyPatches = + { + typeof(Patch_XUiC_MainMenu_OnOpen_VersionGuard), + typeof(Patch_PlayerDataFile_Read_SpatialVault), + typeof(Patch_PlayerDataFile_ToPlayer_SpatialVault), + typeof(Patch_PlayerDataFile_FromPlayer_SpatialVault), + typeof(Patch_PlayerDataFile_Write_SpatialVault), + }; + foreach (System.Type patch in safetyPatches) + { + try + { + harmony.CreateClassProcessor(patch).Patch(); + Debug.Log("[NecromancerTome] ModEntry: unsupported game version - safety patch " + patch.Name + " applied"); + } + catch (System.Exception e) + { + Debug.LogError("[NecromancerTome] ModEntry: safety patch " + patch.Name + " failed: " + e); + } + } + return; + } + harmony.PatchAll(Assembly.GetExecutingAssembly()); PetFollowPatch.Init(); // SpatialVaultPersistence needs NO Init(): it is four Harmony postfixes that PatchAll diff --git a/HarmonySrc/SpatialVaultPatch.cs b/HarmonySrc/SpatialVaultPatch.cs index db1e9e1..fd0ba89 100644 --- a/HarmonySrc/SpatialVaultPatch.cs +++ b/HarmonySrc/SpatialVaultPatch.cs @@ -116,6 +116,13 @@ namespace NecromancerTome public static void OpenVault(EntityPlayerLocal player) { + // Хранилище из сейва не прочитано - открывать нечего, а пустое новое затёрло бы его при + // сохранении. См. SpatialVaultPersistence.UnreadableByEntity. + if (SpatialVaultPersistence.IsLocked(player)) + { + GameManager.ShowTooltip(player, "braceletSpatialVaultUnreadable"); + return; + } ProgressionValue progressionValue = player.Progression?.GetProgressionValue(NecromancySkillName); int level = progressionValue != null ? progressionValue.Level : 0; int slotCount = Mathf.RoundToInt(level / 10f); diff --git a/HarmonySrc/SpatialVaultPersistence.cs b/HarmonySrc/SpatialVaultPersistence.cs index ac6b1e6..02e999e 100644 --- a/HarmonySrc/SpatialVaultPersistence.cs +++ b/HarmonySrc/SpatialVaultPersistence.cs @@ -89,6 +89,37 @@ namespace NecromancerTome public class VaultSlot { public Bag Bag; + + /// Байты хранилища, которые эта сборка не прочитала: версия игры не та, под + /// которую собран мод, или разбор упал. Пишутся обратно в файл байт в байт. + public byte[] RawPayload; + } + + /// ХРАНИЛИЩЕ НЕ ДОЛЖНО ТЕРЯТЬСЯ НА ЧУЖОЙ ВЕРСИИ ИГРЫ, 1.4.2 (2026-09-24). В 1.4.1 на + /// игре 3.3 разбор хранилища падал, и при сохранении мод писал вместо него ПУСТОЙ маркер - + /// вещи пропадали навсегда. Теперь непрочитанные байты проходят всю цепочку сохранения + /// нетронутыми: Read кладёт их в слот файла, ToPlayer переносит к игроку (сюда), FromPlayer + /// отдаёт новому файлу (игра на каждом сохранении создаёт НОВЫЙ PlayerDataFile), Write + /// пишет их как есть. Сборка под нужную версию потом прочтёт их обычным путём. + /// + /// Ключ - entityId. Очищается при каждом открытии главного меню (GameVersionGuard.cs), чтобы + /// байты одного мира не перешли к персонажу другого. + /// + /// Пока байты здесь, хранилище не открывается и не пополняется (SpatialVaultPatch.OpenVault, + /// SpatialVaultPickup.Begin): вещи, положенные в новое пустое хранилище, всё равно не + /// сохранились бы - запись отдаёт приоритет нетронутым байтам. + public static readonly System.Collections.Generic.Dictionary UnreadableByEntity = + new System.Collections.Generic.Dictionary(); + + public static bool IsLocked(EntityPlayer _player) + { + return _player != null && UnreadableByEntity.ContainsKey(_player.entityId); + } + + public static void AttachRaw(PlayerDataFile _file, byte[] _raw) + { + AttachedVaults.Remove(_file); + AttachedVaults.Add(_file, new VaultSlot { RawPayload = _raw }); } /// Vault attached to a PlayerDataFile while it is being written, read or @@ -215,6 +246,17 @@ namespace NecromancerTome { return; } + if (SpatialVaultPersistence.UnreadableByEntity.TryGetValue(_player.entityId, out byte[] raw)) + { + SpatialVaultPersistence.AttachRaw(__instance, raw); + string rawLine = "FromPlayer entity " + _player.entityId + " - carrying " + raw.Length + " unread byte(s) unchanged"; + if (rawLine != SpatialVaultPersistence.lastSaveLogged) + { + SpatialVaultPersistence.lastSaveLogged = rawLine; + Debug.Log("[NecromancerTome] SpatialVaultPersistence: " + rawLine); + } + return; + } Patch_ItemActionEat_ExecuteAction_SpatialVault.PlayerVaults.TryGetValue(_player.entityId, out Bag bag); string source = bag != null ? "session cache" : null; if (bag == null && _player is EntityPlayerLocal && SpatialVaultPersistence.LastLoadedVault != null) @@ -260,6 +302,21 @@ namespace NecromancerTome string note; Bag bag; + if (SpatialVaultPersistence.AttachedVaults.TryGetValue(__instance, out SpatialVaultPersistence.VaultSlot rawSlot) && + rawSlot.RawPayload != null) + { + SpatialVaultPersistence.UnreadableByEntity[_player.entityId] = rawSlot.RawPayload; + Patch_ItemActionEat_ExecuteAction_SpatialVault.PlayerVaults.Remove(_player.entityId); + if (isLocal) + { + SpatialVaultPersistence.LastLoadedVault = null; + } + Debug.LogWarning("[NecromancerTome] SpatialVaultPersistence: ToPlayer entity " + _player.entityId + + " - vault kept as " + rawSlot.RawPayload.Length + " unread byte(s); it stays locked and is saved unchanged"); + return; + } + SpatialVaultPersistence.UnreadableByEntity.Remove(_player.entityId); + if (SpatialVaultPersistence.AttachedVaults.TryGetValue(__instance, out SpatialVaultPersistence.VaultSlot slot)) { bag = slot.Bag; @@ -309,6 +366,11 @@ namespace NecromancerTome try { SpatialVaultPersistence.AttachedVaults.TryGetValue(__instance, out SpatialVaultPersistence.VaultSlot slot); + if (slot != null && slot.RawPayload != null) + { + SpatialVaultBlobIO.Write(_bw, slot.RawPayload); + return; + } Bag bag = slot != null ? slot.Bag : null; SpatialVaultBlobIO.Write(_bw, SpatialVaultPersistence.BuildPayload(bag)); if (bag == null) @@ -346,7 +408,27 @@ namespace NecromancerTome return; } - Bag bag = SpatialVaultPersistence.ParsePayload(payload); + if (!GameVersionGuard.IsSupported || GameVersionGuard.ForceVaultUnread) + { + SpatialVaultPersistence.AttachRaw(__instance, payload); + Debug.LogWarning("[NecromancerTome] SpatialVaultPersistence: Read - game version not supported, " + + payload.Length + " byte(s) kept unread and will be saved unchanged"); + return; + } + Bag bag; + try + { + bag = SpatialVaultPersistence.ParsePayload(payload); + } + catch (Exception parseError) + { + // Упал сам разбор (на 3.3 это был MissingMethodException на Bag.Read). Байты не + // выбрасываем: они уйдут в файл как были. + SpatialVaultPersistence.AttachRaw(__instance, payload); + Debug.LogError("[NecromancerTome] SpatialVaultPersistence: Read - could not parse the vault, " + + payload.Length + " byte(s) kept unread and will be saved unchanged: " + parseError); + return; + } // Attached even when null: a blob that says "no vault" IS an answer, and ToPlayer // uses it to clear a stale cache when a different save is loaded. SpatialVaultPersistence.Attach(__instance, bag); diff --git a/HarmonySrc/SpatialVaultPickupPatch.cs b/HarmonySrc/SpatialVaultPickupPatch.cs index 3ce220a..6182e14 100644 --- a/HarmonySrc/SpatialVaultPickupPatch.cs +++ b/HarmonySrc/SpatialVaultPickupPatch.cs @@ -599,6 +599,11 @@ namespace NecromancerTome /// the same way in both places. public static Bag GetVault(EntityPlayerLocal _player) { + if (SpatialVaultPersistence.IsLocked(_player)) + { + Deny(_player, "braceletSpatialVaultUnreadable"); + return null; + } ProgressionValue progressionValue = _player.Progression?.GetProgressionValue( Patch_ItemActionEat_ExecuteAction_SpatialVault.NecromancySkillName); int level = progressionValue != null ? progressionValue.Level : 0; diff --git a/ModInfo.xml b/ModInfo.xml index 479c85e..9f6a970 100644 --- a/ModInfo.xml +++ b/ModInfo.xml @@ -4,6 +4,6 @@ - + diff --git a/NEXUS_CHANGELOG_1.4.2.txt b/NEXUS_CHANGELOG_1.4.2.txt new file mode 100644 index 0000000..9f54c0f --- /dev/null +++ b/NEXUS_CHANGELOG_1.4.2.txt @@ -0,0 +1,4 @@ +NEW: the mod now checks the game version at start. This build is for 7 Days to Die 3.2.x; on any other version (3.3 experimental included) the main menu shows a window saying the mod is incompatible and asking you to update it, with a single Quit game button. This is to stop what happened with 1.4.1 on 3.3: the Spatial Vault could not be read there and was saved empty, so its items were lost. +NEW: the Spatial Vault can no longer be wiped by a version it cannot read. If its saved contents cannot be read, they are kept untouched and written back byte for byte on every save, and the vault stays closed with a message instead of opening empty. Installing the right build of the mod brings the items back. +The new window and the vault message are translated into all 13 languages of the mod. +Drop-in over 1.4.1, saves carry over. For game version 3.2 only; a 3.3 version will come separately. Single-player. The mod ships Harmony libraries, so EasyAntiCheat must be off. diff --git a/NEXUS_FILE_SUMMARY_1.4.2.txt b/NEXUS_FILE_SUMMARY_1.4.2.txt new file mode 100644 index 0000000..ca83f55 --- /dev/null +++ b/NEXUS_FILE_SUMMARY_1.4.2.txt @@ -0,0 +1 @@ +Safety update: on an incompatible game version (e.g. 3.3 experimental) the mod asks you to update it and quits, and the Spatial Vault is never wiped - unreadable contents are kept as they are. For game 3.2. Drop-in over 1.4.1. diff --git a/NecromancerHarmony.dll b/NecromancerHarmony.dll index e4cd9976bc87cc1c1c23dc22d67f626996f6669d..c2e2a0628a8adb31abccecb3a599b55370eac83d 100644 GIT binary patch delta 48987 zcmb@v2YeLO7C(Mxc6YXfciB$h{^*z%w@BdK|lNh0jU5=|u1L-BI zNC#rg4~m!;D^(-0nM!Y8$=gU+0`%_KcB(P_8@U@5+D&C#&-mWo_&s#~fwtgV|2M3ZR#^7GagUdu*>Z5$G!Se&WgYZq8XN zgi;nX7rDivbzNyfI77?tkL~u(2iGv)ZijMvER?xfxg+*+W~*{%ETh{b5RUGaMp75} z&s9E-ee55gY>pLVS7zOg)P9$-SqNWMhC6zDY}yozy$6rZJyTKk$6gOM_gIf)?FYbBrbQ{<@fpQK9sj~3&8;2MK8ZDiYW=qM zo6@0uSqQ8TE)IF2+k;kjjY@cN{_LD4B(F+0XXS`RdJU52RCG4Qe#pNA2T%i2YdD?RIJrjHOP7&w z*Uw0X>e2^7%DS>Vb7Gj_?pl>2w-Pp_^y%5E-W#@CSC((iWpY8BOhS|7Lepe&ksD^Z z9Z{I+X~O6OEu`1`AaGYyo4bJ1haf}5e@(@$0pz?Wj(%U+4k8RdJQD1&`i2{Zb@de%`XBQ$!jGT?nt5%4Cp~1|nnHLeNeHGAvK4(4 z6|tamAS9d5flV_%AZB>I&u9d)!j0MyqRvCl7hC(6OV-tuVv&`tm|O7F2T|g!6iX%p zcUO~4GkYeK6;87-0uCx$CxJcc>+72ux=C@pK$6*!RmLL2UQ`qPz^5Kk&_SqO6fdiC z1S?(o6v*&7^ob-Z(n|~WEs;{jREb5|f}4Ul1@RPhsM%`bQ3x(0!K8pspM~^koU}N7 z`P$e|y?R)Q@}P;Ck3k07RJJfbA!$_1b!7$Sw~Q{dNTWl+aqt=gjsjAVnNdwC!mz7s zkHucI52K2Go#;}W#$d?E$aciZY39*HCWmHoTfU03)Z$2SwJ`*Y#bw4&JlF*s`Y=Q* z!m5tZOLjvJfxP+G*$iCg(`=zYdCnniJWAHy0%TbiVU1Rz52xUnBooZ6wYM=7VT}=r zK>nXfMMo0zU_y_gSUtr?Q>>0+V-U;f>W?UUM;F?LlUjHHJ;Ve&%VA`7@h-H8h#IQs z91C_eIu4;R9s&9Zj~1PPSe1&-5DgEVH-W~ai3lTvydeb%oD}X5haeoL^>y5fY8uPUuAEuM9r89IQlr`*@@C@{4C%#Flxb?H)YMw z=9FnjNsiz)=1|IqQ&UR((ZIVyGt=BiDXYvSU}Dh^Ba7d0D0eIxiyAVVLR6wwoEjHE z(~p2fFia%#O4n8_Xg?}5bHdl8R;I!iUoC_xg%~>GmeKoG=7pFoB-BJ^8ZAG4BAanR&H8l zD;vhmm7DHKt=B?55S|*Yv5BNi8ab@Z5QrEiecRGhTsU z^L2nJO{jmYsj|d+i;(jYNxq9Gk;-5q^IKm`WPC|6IvR?c%Sb)RZY@x&irSAkxDG?j ze29x=sOF?Nz#UNoib(A!Km}4gk}I~iGN0yu(gN)#A|;076OhnhJc5kWPP9#@eiRCq z=C%#gT{9QQB}dXF;AU=3KN5_Zc}aqtB?0ccjFTW;(`SOE9QLOwcZeqiMtb_GW-OUX z0^HMaD%HFnd3=uSm(~v0StF(OF_}ysy z7k6S(z)GAAB?4~M@0M!JquA+`y~pq23g}1ktgfbj2Nb_Y>cdX)U(`SsDfI}(_3+qw zSaC&?dMr(CG9yx&Ok|*>An&!!whvN!0$kE!!!IR#qU6yuAq<0yX}h*l+yk#h=SLRj z{%p2I^qFY`mxI74In7;aEK_o%E*HJr z(GBS3G>tpTw9Y}u-EFi(dc+&oN~vgvQoeM}ARRJ-0dM6w8nzQmKmi}cNSi>K$77s{ zNU&C}m#_v5WT5FT2F~xpBO5c%LB?4GrY$=T!>@66tWSM`buMY(GB3e{nalm&(2RiB z@AcL#mCck|1~pVTqLW){z-3+y_JGDMDv%xwWK@pwr~5Nj2QpQErgZ39f2Mg0xCp`R zt6O%rCDfdf({A%szlc3o-+d@cb92*>(psgoEY+VSrB(W~%tH!E%aX0cpY68=#kx0? zT7TXDW2qYOn46%5+f3_+iCw}(lw+ml;VHh339%emXu$x>U^9r)VD8|i8ABhW#KOUk zg^E_rC8s6%aK;w+UDQcsa%Hm6aRpd(ywET{Jb@XC{8-SztcF&qDJJeioUZ@H1@w#7``r0s|;(i&`7!SZ0<1!=7JWW)4q@pO6w? znuvGN>Y@T$7cSw&M6^GemZOXIF3h{Z)4l|Skn8+Gm|u#5+?}A6k-Q0 zwc}9U4vb!Lp!*I?4B|lk4hKx4f zIL)(wvZ*g4N?znF̓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 BB2fSU delta 44674 zcmcG%2Yggj`Zs>=otZl&1!g9hAw3}^+$57g3Zat_f}&Cd>4->?rUN%%VMuNiWkm$V zizuuOM6oN1tFG>fb;XLV4GV%5*51~-@c%x~xl>U0_x^wH=kt!{-1C(4oaa2}IsM#A z=WciB)$YqL?!M;cm!A^$?||rDoTl^^;z>maO(IYJV8d+_GmpHlh%t;%#jB1DCBgJ! zRip#)*+E52uu9a3HAU&^Tk-@F76bjHb%|1?JZ=3&>8U(x?N_?z)O`RFek1Uw3YYNQ zBgBWbicqd9*{AfqZ>%~;QLeS_cT88Vy)WSOs{ndvHz2Hb=UDr-(Lh(bKO~-j_ui~) zg;2^u#uB$!vaK^s2xoZR?be&#x!@Y&d()v@Z-q1ORc^4J&1_M&S{Yr&fH0#=8cAK? zKTp|becCrs=8i})P7g=ULkzd8SdEi*2F+r;SGfJMt9jr8@wN&->Z+eHV1ku zTkm@|aD}S8a^H;XWs35a^-8F@`!*zNI|QyWEk^P7!xRs<{|k>aw{}E(+iD2+_S@R; zOo#SmVX)q}JnV&T_nA2wm2h?Lw5)+hUY%}C%@RxWUPzu**)h=iKKCY&|D3lOVW0dq zgtz7&M7Xwq%yy{Ypwi_N)Lfa`ejAdPIoe^AqKgLa2hOKC+HV9>Q`@)GBSxVfR)kN} zVnoP4;tU;8+HXQM`Z+Q*-s&cnXe)2DwiFjDH(C!Dmvng#a@q=zBoxlpVmDcz7GKc+ zLzb%Ed; z%18H=cF$K#U%1j2sywyZI@?Ye1#Bmyl%AEj#y~vrc$OX_*xM;QaIGRC{Elb^l&elN z_LReFL!eouBNVL!E?R}arx_m+A%b`$)P2k5%|kk?p-I^In$UxZUo-w=CV0}rhPP*u zQb2J|oE}Og1QfjqX{+-(sv+5^0-I(WPs}y2W3&dyN_Thoy{Plh^O=^$a>=UdVo5+T z^6}7nQQ97enJLM@-Pt75Oq;^W8W$2Xm92wx?_OVD-_+1Win|mfnH^c>L}XYDt8~RHTO%sx6j6b`Gw9QbO-ZKJXCYDe4HATN4jLa0v+} z1$_F+kdww~i_+I!YmMsJ-Aoi{TUm}#Qc2a98xY1Q#JHT>%JPgUjLtVnqaz`73u?44 zvfNfyU@T`+A?!*@Y%44B8XFi@1I_GoX|DkI>Clhcf+h^+Us&29QB&sK{fMKw`$ zFutO)XdNEx0uH?%(aJ(qZ=ffY$01HadFa>C2e=ND4i*ZQXC2X6QL?s1Aj>)l8|_Q< zeiS^EWNIO%{>((!=m13^|Bt1j1Bn^Maz+PH3=P>C9ZWHJhBG<@v8>KIMA^a0s_Ynm#1f2-90p{BkQ1D8cb-O1zg1DA@^kHC$oXHmO#L7VoIHD(j78&f-hl5r<&gfDlmUvbYO*+~cfZ5UX z3gA+bMo&b->E-%yNaqPS_2Wr)Acev2jGhD*cX%>-SXL}L5^&SxqeqW&1*-xTAbOB3 zW9ZPG5wCo%C$k}HHCFbT&-F11>B3WdRXw?SwCHHSF$@e&S;R=1jUNNN21YH^>or-Y zV>x9SQc@MWqvI&$U8yN0{$%Tg%5Wdp%kManjiRV(IO-Il3U%q!SRqY65hW}Sr6mQY zYwH)Zjkj{Dip{&>3)N%%S`?$FFX;BWBQ1XS`p95bEZ{kk4Kt|$k6&viwGnZ*--n3b z6P*B!yhsSp=hysh9W4%-lG*&O@Z_M&@A5m>FQ{AN@J3GoZ#$W)C@tOx??L@+D+`3x z=tL?SdEK_MZbmR-Ex9ObRL=-e^AZg<->79w0W=S~0xr9u78(N?UF1y`&NC&2p~z<} zjaXHYoP2nO-?4tdIt+t~FO(Kaukvdihi4127;Bvt$(l0>8o2HHosIfMPvMtRseOg) z7A9*nt*V6$F7$dNN<>#@Z7SETTx_AAAJGIjRDoiI64WgJf;FROHW?Epy_mY zurY-ArzE6J1(>4E42-gKYcR_Cl3D1`*e9D2OQ+ssC@h4A6$(cEae*V&6hxBlL1zfSVcc_HCt~$*TK3R3^BN4Au+fIej=^nPYM;~X+@2#5{t^H^hRLj(! zmbpD!GE}ehh1rPAM3SJ>?~I*B5f>)mE*{~hwi812qNAOK2sg5Tb|f1;xf;N9lDfHo z=50scglD)NT@#*uSNl#x&=gKbqOh;Z^m)RQ(>-qVF{?WoKq4j1ff7Nt>UT>u=1^=l zW$*EO*uZ^g^3&NA^nl{`NPW1{|BD*v@T4B0xE>x`4>PVvQjb-s&0%;-bBOel6y$wF zv+ZNlRsa_dwc%RSuB`Lo2h)Uz&f#L(uIm)H!D}(7ki~nUu+gz5(Wj*KTL%K8Dj8Q3=02VnnKz|^QklG5Q&k12xXjcP(dpKfy246m z=2y9|@@Yx$>%ct9nI6ihD))G|1f41>eya6;U60(k&?+qybXC=$dZY6I<<=Ka^bD)G zzPBHqmFmPDeeau9?^M(=y{$7E`YU~{tqmv9Y%e88>QK>xJq1%%X&QHsX&sHo-5s3| z=@D;SE2Xk+5O~wIDCv+93VN%~)v!Q215nUMG14ZO=J7-qAQI~BHttU6#YZp$)wB>e zzYmW9rh@~biwI1+bUMbC=whqAPo8;@G;kSTQk@cWx!;R1(d+km>sHBTNG*dJA{^1l zEivdaegb*=-&QJ!(A(u5Q5uRmq3@5)SQxYVdF)= zu)>WwgISuJn}(FuBBgaz{avNBDt}kwh(gl3%2whJ_-#SfnT;iNf84iMDWRap$blAa zqYYuwL_hVmb~lDw?PV5mU^(ihaeV{FbNrYIYvo){%;1gN8Jp*K$-W*nM>O#!&E?`V>N9USK0<0jW=>F#`f=)rd8|0NJlPvaKO3pj+!2pEb`Eud zwE9d#9MR~x2-2B!UXnslreqX(<5`CL{0~`R;{|58tVz5tlC+gh1GvYoKP8-UUf1|(O}IO6!vl@MLe-it9?+|eLfhC zK8@C&2bIi4dqFRl?TBDOcLCu~YJ~e>RK#jCjJ4FNL7QCXE>Neta*n^u= z>4;toiHo|=n>Vj%s=fwstm1kDug#5K0?481NT&siv-&1?LB2)YLHkwKH-k$}>k9PpFp~N_R6cw!yl2NXgLF{$h#W zxk#S_MO5Q#f?N`EN3Vd4pytPHtX`>fV*s;&P?uxPqy*hkN_3;;X{tHnN)WI=R9@wF zhxJVWBo&h{B#&N2$zoR{tj@$tZ!>}6_APi+o~XvoMdgr998NA`Ws7kaw9x+yawi#0 zR?7j{r>}KwQ`k({2QsPrG`x0|(NrT)f1$}Tq-$)-h8j<(w$iic7>gQ@ATzrQFoq96 z#u#CIY%;rg+$oYWyq=7j6Z7M3aq|GHxj8GV_dx1pauOX$uF*Wun%`VZ-G;yIbE;}g zc>jvBV5{?CdN|u3p@*yeZ}iA?wqwbHr>p%@eroNz`RQ(djGvzN$MNjID&0vfMvIXw zd;OTB#Ym)aGL#5q=^v2xC@wWEv(lIktX$N+4O}>y4TH5^gP_dF9we5uUyEp(l;;j( zr}+yg+jbq0`t=AxvU_)l2UH=j>En0AZUEZOIa7^oO+XRUAcJzfdJ%-{wt_SE1cDCiFUlAaiza;=a%d-l&GRIp z?G)JXQv_2`2L8^b_NNhraKES8%|feOEHQ{pt{Yj|8Ka>T`3#CpnAmm%w2zT!?0%Q= z0o0G)LyQHa4#cCkSa-D)nYR+FFW@WFZ%Z;v)o%w7@Pz|D{SL$y zAt9+JI}jbU=F{(#?1X0hYw9s6y$i@-dLX?_zdK2us^0^EkULY6_Y%_d>G$CoObevx zyC{<3&xrW^8Qp3c`mKQ(kujMtm>I|f$Nk{o)f&)bIk{2`r1>-TzkpOVHO}589_bqB zf^-l3ak{R7v|jpye@sjBchMgL3BtSTf29a!(E7vH&%;WUFRjAX9FwcI`wP#H93pF# zYyGzs+DYyqJq4`kO~gMKJMmMR+FpSbrGNY%g^*_@ggh_PPoh-ENTDv?R)wQ+-@2ih zeXEnamwVw%^um~3#n&#?etWp6_Bf&=tc>B^hUX2o8(#=b_7RjGU317C`x|1BOn2<> zc-l^fEk(EfDB$HZ@k(rtVqG%AS~$F*bsn(Q9*@1L8>)0=@QwdY7i2ik+v!81zgh3$>S#H8)GAyOL2 z*v|1B>@0+;9N42vOYGd`8g~q_PCIVgSlW7^4Mu8U*f+$w{4dZg=qU=s`^;ygKrid(ZfGU#^kKm^|7Kvy|hrdAH1F&o_E7vB2-uyFZi0>YA)p|ML$ z5>35|PsaX{i0whl@8y1{?WshrkW233hc`7<(8lF)&>2&P7r<@Y+-&tcG2*>eE+3w3 zwwC&{vTP?zaXsHq>%tRt&QGq&$fIf2@Y^$*7lF6WXfWxBpV1ID<&5T~B-2u2>JMGZ zItfc>G&l<(x#*8XG3u!U(_d%wY2ZUC|~?I>|vl&PAQn-A4o%eo#;f9 zksZo$1medM+P{jlKX>npRyK z-v`#+@;IniU76r^uYBJ6)2PC6FM?OqUqaZvm!h$k5k}JFGx`buPsF2Ug}6IZ9U(Q= zL*^x#^>$b@9Q`MF5|g*Lhmt>;SG92Wb4+)cYj<^dT6LZAH!wg2BxT)G6q{oF0-F9R zNQPsWUB^{D3@_p-Y$;sWw2_`*FLf(~wPtjhb0|z~{W7Mn8_dF$Dj?o|8cYpFQ$ zhbXqVeamTJsN}7Grn4*7?apG;JH*v|2#RJBKwM#i!sM&(jD)L&B?u&l-` z_I2P;Mb9)hVnE=PPnw#?>l_KWYtAT)cjwZIb$wA}Oo6r3K_}Ok#MsmW9=R7(06ErO zW4hCkpTC0|fPI=sQHGIyXH()dalG~8n2MT2!@@X~EG=!0{#~_OjkH<1=7~LHjTxJB zJRL1Y<^oJwj0RXa-J1aeM*8_(U?zLMLDfj@!n2ZKdBC^`CGfjw5tn6G0C{-7a%4zS ztvALNW;O$(qupusvoNYzj&Tj49Z2R)+QRsW#AqbO^u(ymR%d$rPOsjERNRI=F>1J> zAs3^@AOsTagOOg|=$n8dhBvwoPh()~v68O>oa|ewPLk}^Rlj5W7L0!9O6%j3gC;iR zxysw#f=HQl^lgql4=o~%p4fAwV~v*&kG;vmV|yEb5AyUyWCO2$7L|ecJu&K(B0;Zy z4p7KLUyf(LD}Pg@0T)II!wT4X!1XYQxC8FE>vgs^o^I3dcn4HC1fOinpt-Fcm8ZW8 zg1(>9dN2aX_HCRp{8$S;G~7CPa(TmhVCy6os$8f#^aFs@oc4qCpiypc`}>GuOjW7D z@K24+vIdUtt<16(k1sT_0p{dhgy(+az|l&+I|*n9hwB&2xEd`fp)0L9u{-er#OfbX zz{*m99*bI?+r=vg)<50piGBne+Aa6mEAbpo4L7y|<%B=XPdEghJ~Nh_yE;R%#6AWf zrwcI{J>JwAqiSkwHmMJ(TKnmUsWBOnn0VWVUKmqfx0X%_nsbP!`_ZGO**=$|p?35$ zz)*?W&ybk;c*NB`?YHV4qpkkG)hLt9!#*KZ@}Ckcz~JatkClYZiOqxIVdyC#Gton9 z$<7)Y?{1#bP^)UjKDb4kAL6+$|D&E+UkxkS9V4<|N#j-7XkI2vo+t&lqn|*68Y81% z&rH9FQkZ{iRJw0M{b_oIPU+;>Kb?9{4ePq7_3Jf$uZbx*#d z>Z_=b(1D=vWQk1mEYo(aP&;{s?Uje1YVr~w)b9%Q z#_8n+lo84i?Clb$b^djHN-3m-a%vHukxV#1p_;FMj`-wuGns8_O+>!{HKazr#G~@> z*mj~yOZDUwwP*?y=5}*ax{G%f2Ypuv9fd)|xbt z+}GLx?D6E=YK$9}UAr<)7E7J*Bz#Af5F$@&RyoB~{VOPJ`ZRlvaym-M(S|@ks4Ej- zJGrwgqdgyz`9f4@bFVz~6vUcrdl1_FvvChL^+Cm4$Q45ykeD*l6d2tTH-SLhGA6{t zdx#X%$ozg+5OxK&x$R>qJ&qK_K5jddBgFmJvC1bVb2-P+{KE{(tdb)yEil`dmh;Cm zJZEAihWh@(E|6VVDNI(cjPsO}rFk4> z&!yJ`3(aJ1SgP8Gj{lU3+F4P5mQo$Gn)n7N{aX^He}}Mg9y@Y#I}J{1cKa+$3DHu& zC(@~T>u#sK_g+W!`EQ^)X{?e?cN9uuH^lF##%`h`_5-N>uK-RiH}v(WXu6qE24AVp zLkGu^K0s-6oD)qd4=;Zd7fzhJ>0iv=|@<)#VC`TP~gFh9|lTu_wkAhl_xj75b zVwAoyGc_fy*}g5T>(=B{6B{m+QKl&~^qMx@UiNj8ZpegY8E|be(wa5Br*gKnW_q4^ zDazV`85R20vQByyKLd`sv=9UO29PWBkZudGqvEF@mB*;YqNJ8s`BU3Wc)Z zKb=icSO)zU@$i{|aX&U;v%_@C)A?xB4JFGZRZoX8yWWeu$qH};(p`;e0knd5; zThk`;uy^l`r&8k7GeGh0k(RGe7vc_eH@%QtcZ=aY@z`dx@kHyhnfWGi#ELHs8uDGw zXgXrmb*ix!?8h9MWuA0w`Z<7;#~+vjWgul*Ky}A55m`j7ylJvK*2M;JIOUFYO;YrF z*g*H5f{Tfs04^#v2$AOvMFZeK>p(TUgFwcDz^TR^$nV(dH-4+qvtV)4gvRQ4Y*`gg}kufGZTuMM!n6(&bojGL&(kzwyBgk#4FM z!(zzUP66WBc5=2;P`L@`U3xxJs>~3VQ5|ti4K=+25%O6<3%ns5lgmb0F{ZI2 zYKAfj4yISeSv!`&&TUlyqY(sZ>^#6)wAxxeyR^^maoysJyUYkH96-Q%mY1|--yZw6fsAr1CZBVZRFP8}y ztH=b^4K`#1QA8}p|K~Cyl~Qe8Hz!v)g*0wujj^F@8%my~IqXw3l~1^6 zxwOk#F}J%(^+Z>Ifk>QZ#ZR&veixr)1yry8FogBn26J=G;@TA_bO$sfOdM#%6S{#+ zoMgq34jlVE1StUru0Q{kA`m-{9Uez|3WH2@y$96VJtVw9>p1Gq#z(lLCJaiIQsX|Pq zT6E}5K(kvVE0kMEv>5~}<+Q2=vdQ4=W++fWw{$|c^pfM^Pzz{&Ig+qn9Z~U`Nzh}h zJ|kpqrw)##LdY;;#D+4R!-jfYA^SNxr_%qAO$rr6V;2hj)lf3wFpkNF)C#d}!x3aS z_R_4AuR3|W(c@Gx$XA{nbb6!5gNpltV{tq*f}*$yDEAdk0OXEQI3<`CN1n*Y6Rk<} z%gvJzuik;_l=n!eA50hxqW5~o@65(63eGg>a_o&Haz)ESwzxa!vh(bRaZ=dXE+;-Z z&h7sXApIG5tS=Vi`l+SCh0ql` z1Zh9T%30XM91S*HF~*qf8vw5r9v*X|V}Oo?9q!9|pulp_r1#3k0$nx7!{d(R$vTEd zG7R(Z$n#qvG|VN06nP99eoV;}NJt?jmcqN}czK{{Jih`$>)cuBk*1R8v$}j)DXA^C z-jZrzu7C**4Sy`3Xp|cRpy7za<)%4thc$3f>8x=m)$$G$G{YP5d9hnVlZ9%RGjuXe ziX(Gzzt8MD{pNAv7;%xLS;Mf%`)@#zT( z^k50w;u2^oVVr_AHuX0WO1dGJlcB0J486D_Rh}{Qv1TmpuRb=~x_WV`IUWq*`Y!r| z5LTU|(Z-X8w=UFJA&uEZ2=s@5qVr0x*b0MUrflC_lDo-1zO|#%)g`*Lj$1og^a^Uc z?nP*^#Y3m@eJk8u>K#;#PoZt<9JbQzfE}^jRE~^ry=(%ssXnLUeBjEe-Q}LPQ-H|u zGNOKD;#9kI3?F}aqZ2{q{j#1&Pn!h?n3Cg-PCAy7YkWf#c|(z=gLb~dDPwPRGPtX1 zq&!crGHT;A~-B1g2JVCJ?N;414RN>)fe6@aWbw-^S~Pbbqy zX963bx5P%Y=%*oG4ZCXNeq&e6U}u3AJzW(JpFZ3A{Hzj_PgDMg*~481UjPdl%@7q| zw&~pCczBOFamvIm;URnM6xDI9$z6Zn8>NGKXQ-5;FFF@N6%EJp5Xq1Nrg)KPcXM*r zTt5Ru;5wUu@dT32L3X6;Rkk?86REdF4rDdDIA(6jr z0q{PpZ6O|M?r?Mwo@&++N4nb+U5vN~3qN=COvK#Lvk+?0sI_*<&@rcyxg$;$Z)oA= zj8NMW&>&_h9%=5Vfk(P0Tr(`;l^xIpn?!JcHqgi$9VfF(glXQ>X5}p{2+~}>+LaY_ z?k{xf%K!wO)@4gV)~ux^W+yaPqsxIT@8Edb&u|I6&-(@l(X)Y%w_+@^#Z1z!S~K#H z2afs3VSRjEJ`LAEsa-_RLBI`yFSo1QBqXv7Y2=M}t^X>>!aEt~X(rwb@kY+_MooyS zp688q;u*=1&uB5K8Xe3lZgf#yQ*hC9kxS6&HfrNCJu;8JaTvYOLP#?9yX;K8vGd~U zmGj#nxIIvJzT4_FG!rXC&^oF3C~O|~kl%-Xr=hIz+nlaZNMe2U0m{z@X|gf%n>nsMhjx0%p7tCrpqk z+}m*lN&qjw-d{jBp#meO5T>aSXMc!vKH5o4xPVP_E4MhJ3ffNexBZIzXoqP(sE!D( zp>-mCwO@-7!ceE67`wqzY0u!%wOKc<37D8pOBTMPmX1pl9=@ZNNZFW3=~;O`M8+;a zkm2@5SK-N{=Y^CJO=QqzCUZ=tvnjEQz!y0Y&}xbdW%QX4_$Pogxw#n6|CL}jQc30Y zzoBR-3g$9vASF~AFZWpq?UCIjmjApglkIVJ0`KzlosC+rEz;erNkz*t4RKEWFLIyB)LrW4`!c z?`G1wY#r|sk9@2AuaL;QnPr`XGT*d#6S1?g zb1`klK+;RVk5LY5#U3=e#ZxAo$xgz~gK0N=q}TSH%Sn@XlBDn0nduuq?zjR$)Iy-q z4Ph1DFQUeMhZ=+Lrqhk@!3pOumgwB)Z3u<^3GlZ$DVt+j$ z-)P}v1p$0`Lrnw|57XjO8>`3fd;wesrV%Jf6B-@irM&k}`c4Jr<^C@#jl-9EtD(TgP z==GeD)97+4GBRnr!J2mY2Dln-KWDq6H?TyfQBU+Z8RHplJx8)V(XD?#hS||aRYkJB z(QUsc+vA`^Y==S%NFjbLghyGk>c6cnQ`eSh?hqCpytZVGaGKWv>)VS;RW2$^cqT-P zN;fYm(^Gil{KvzyW_Pdd9-d5Rxb-PCfMYWWSH0}D9~LLP_VdsNy}gj@xDi~&OxPnU zzO>yAOl3`StY?!u!~-bdLMmaT(mw3yo^sgn2c0N74t_C%4ld-hvXKv}1s^a9 zA@e=U|79ScS<2MZ-d|?~ zj{0d=!k&lc8vkZ&o;P|6u*ubavZXs>au;K!WC_()xp8oHE4X8~A<$w6pr{u6Km>8J ziJR@1Xuc1O{uI2s%F0`nJK-R}c;&5zu|t)%s3GuteEH-<&?Be1`9>;9$d}R7T;y?a z2rVJ#a$^U3p%q?L82IRSg01{jIiueD9Xia`l#SCNUPi8qVdD-mG3xOTZH=PQw_pxi zcdjarf2&2>QX1c#{4Pp(N=6mbrw$HVqX_B6X8Vd_3p!`I1L>*n2k%a~yI27hc^lWr zI*o51(q@V5;~xb=_VF|~_J*yKFAP+j$*s2s5Ex>-nxk73K!s-Naip; zMVK6VDm6K9jfW&IC z;B@v{y!P77m~lGYxHi`kO8O(MQ=qLTA}Z9yukB6mfF9xYPvnFAu*|TCPM!q<7$xQVzYrSnjX^=gOjh5bP^Z#zPK}vcbU!qrOW(% zkBOPz-N^XZlm9B~){6rsS@zg&6a}HlMjf6@s6fX@91iqnDdmW^LUEuR%dbM;iAIf! z8}~qdPQ3#g>KHlc4C`@4h^5r@6HALMAIpgD1S`Hx(H--^d+BU~rpEexh;SdM*82eN z0_fYH1D5*{t9}iKAFd;zL5Z^+S|S>_7`r6pj+ybp8P>&X>dn6(1r4zDj6FcfmCCGi zzUr2WjXnrc&|NhUm!Kb_D3*Ux*J|A__dgxUtGcw-;$2hz*hB-qWRcxdz_ zY%yK~oYL*Kt)YHS&cE7cA-gnZjM^_+GTwYncT0$`y}7k0-R0I|r=s7Ck@y^U^zV2i zy4zk0WOqy1rN<`)-HaUzsOPm_TAO2{p#F|6kRN>%2|G4ZY&T+c8e=OZ<}qM=Rm-q3 z{y1Xz42?|k1OU8nT7b=kCn-wbt$GR(T&#K;k9ub~9iHRV{{f)-Ez}G?Ti2TK9E=`; z!HWJ2i0p3}-t3wH3-;OqqI*b~(4VFBtB_tC2@Ol6@7Q8(zqI?pKSSm0`Yr}_;4G(; zFdY=|)X^obf#ooK#*gBwy^gUwYQY=z=V5L6g*eQ>o}+wlz^cXmh1B{>prs`yTn{av zlL|Fwp>^E4a<$Jw>#TL?@N~=b&a4b> z1lanO=bo;rIWXM_F!M{0wDW?u*zl@~*dl3ws@3FuT$-Ff(I@HlfiwCRg0#fjIpY`d zJ5G*8)CBO2t>Y2l_myasI-aq4I5tdT^X;#-6liXI3}-F~*c3j87?ZPQ&D|JLwRS3` z8hsn#@043b0&CD9<;5wh@8$l`Iq(wWOCr$3-lt{Prx~S-ty3>A8_(}dY}uUC#O<4d z-@MZ>-R6_VyE;>D7FKe-RhZKuHJa0 zl&jKMc&1gbVce*9P^R|lQSWNoyA-{Fqx&hkm7@9zxFLNFlArU`*fwDGZg4Gn8;yZ{ z0F~W~jp zhk4=ToGg)z#EE^+FkKSVDjCF3FQK?4?@Cxo=@-NvQ3 z9U*NwY3+9~OrgET!5$1je0wQ+3#wn`YH7a{$f{Te)-bRFrLUoBlNuwu{yxk(nOS6N zE4VSsBnr~r&^%550Q9Mo;W8xJ?FJSXabO>ORe*BHYQGhDys|*W!FN(@ZCN%;Xj+b& z3MqNlqZ>{sNpF-S1UHS5n9AI?50TvpGY-d%j;;p>^Ozg)&$t4X$LeV`v@mj(q&8!2 zZ6W@GM7Z-f(u_Ytq4MV^)Yv18!6rQLaBqY#GQ!;)KE~nW_%NSS{|I{QcZXQUJJhMt zA&4p>V(B2Md84oX8)z*c|87zMt^DeE5RS(g}AIc;fVWiH&?AD2If%sLAbJ47crog@I$(d z%+o}7GpDp%6ZdwbFv{Vj9C{i5LzwXQgemcuoE4>-nAJ$(b72ZcWvwXniCul^i$eZ_ z7hIay+mG zb_E0C+!hL7>Pz9feecTiiR*GGSwj(pk3gIzI@BXBpGYqx%s&{Pn@#auu&__OQ76Rh zVltHTiT5)ptnN=CK0PF^5)&|MctCvD2YvO!^Z+3MLO|SHy(_4R`4Fv%bjJ}_K)emD z|H%p7;7}8vff^945mK&iF@<|s>5EiK>r<)p|6~<^Q7FETmAer32#F`UkPVvhr~sL$ z8obK$oI;uP$R<;d=|cASXZ76;n$TH^VO=Obsas_)O?(SZ7!Xw)5Jf#mP&2&OCsZee zd)Y#d>O_rnJ2&4a2J|ER`ksWju!8un#{6ZrQpHu{q`0a48;Jv=SJu^V2R~|56McKE zD4nhBg9rIU4x9HlAJy@s+82=h8pfQs3Doy-cMpkKICCoX)iEtc7)?8tf?g~Dq%tA|fPU(+j?{msx#B;^G4AT7>l%r7G z&gBSjO-CU@6T8{S6W9{z)Juq^VG8L^Bdh{%aHz8wGrxl34s`yS80=V4`it_C36xK~ z#5QOeM0NQoyWZGg6o0liWqcSuTqu?gpxS*>rMB=*_eQ5CVi5|@s%Uij#LZmRTWB&W zrg2$oSfSBeya%A@B(;I#^xbY$B2#a2nFPGX4(N6r?XC$ee?=)Asvl)`6I>}EuE^gN z>@K21NR>NL_dbD-3Zew7dX|>^#79tF6BAHn@SAc9?{A^75#{rVfv96myaca8D?m{- zu@Uir_$!K5e>iFR(^=OY`RXk_R5kqvtXtTkIPfSIj~Vf-epL@W{D$V(tC zQ#?J4x}!^mm6m6U0Sy#i1Z!y`s17X26y4BS`NRigb(~yq#;?IyqK>!V8UgV8{6z4UQH1i%b7@s)AN}R)G-GtKDh)=3EfP5#n;H%kLt^}th9)h19$Tm{t}M&LfE*HXM%qn81MTsQ4R}icSN#~eKYv5e9ECEu7#Of;}2>m-lca;*9fkBjL zZ>AH}1=T=MSC52(3=OiOEQW4vlC*4wzRe~m7mb z4#GuM0>}A?*d$J6Xq64kWT-!vq6t^7i1W4*;v6pKG1RM2LT4~^@=$_~$AKwv-tHyn zB(ad8N~Vp(nHbU30-}vEvE4~}M~gNDKT;-%6-?YXfQSpkT83hE61tS3yf8tF#N`Zq z#-(2@u3+f#Vxlb-SF_B%X&ZvyD@(;@rhUsrS|M&_=m8rtZ)0%kKuWj*BR1)_g6r25 zcQdqxX{*F8hW=th_cK&yLw{i?&4wOeXtqu=SK%LoAej!f+D7p>L(g#mH;N}r28VYi z)~m!b45cx&S?pox*PcY%ES_cP*8UQDo}qhl3A%=k!QlK+w1ZLNI`L0&0Wv%XL(wR4 zy$$WLp;wvqtw+*c6DF~aw27}X@j4rNgP~V!);G~?x{C2=t|WAya3CETGN5hZEwKvF z7!10j#Es$|rj20Qjd(eTIB7;YO57|yWN0Fk9VKoNpP>H(v7}gt<;q={g8Be8p}$(L z+-pPsL?^Ob*#$^NqDwL`5moL7L>bnh{f~lqKWCxn(gFRIIHBmT=x|1fC&ZTweT;5w z6fWm~m6Gm7@ip=@yNcl$o0ltl0g|StvY1zFXgfo%itkW=UB%BBMn{R)#1AZVGrFr$ z;tlaLLvJ(fP4P=g7VnB*S>{75Wj`QN?Lo{VM&V1cM+h>-9Sr^pcN()%Li`V9K1GC- z831sUAgEmQD%&9@c6JGDay5#ly3fm-*f}M42fmNF+Pg4sTxXZQJA_~4BAnPctK|^z zSJe^Eh~5<6TRShWQFPXx1&rz65;)L3BknFBv!tZb%!W{N4gpH!u zdpi{RXZ`&M_cqSU3yJeH9z|$YJPFJ_z%+_&99DbxAU?g%s|YKhbfehK{IRM-!UW3u zDw2&#e+SvT%&I8ml-cM^()4eP>4nlv?6gVDYL`HkDa(+K`X z5gYm`vN@i^J_sjvuBxZXdbWlveNrnG;7^`c^Cp^||4F0FKGP|@0i|pdCp3Nqg-E-J zo$d+>(|nZi75$0&6xU)}`XLNl0faCk^IXi9o8>0V>CF^M$uF{;$;bukEL4XkO8R_= zFw{bEb6$`LB@m&BjQnkwsf=RGS?OJs`%6%H+ zPwGn<*KxdnEwPq;%iTn2*8!u6LGT8wGB-p7@+!mU`NcAG1 z!kJ_i8GpECn@bU2g?6An7&zqm1Re>1xm`Wmr-&Q}RaxKSB}n@(lvNY2){umaIfQSG zEC>E*{R)Ja^y$pkv>8rP?$pXh;ebDRsioWXEa+_yZg8_XEK5G!kUG3tmbC6lX>RV zrdGMZHLMDg= z-oxM~@k7mnfG+I8tm5jlzvVkbI%d8?Y!Z>8r%|5MY-p|bg?zWT#fBa!+n4VZnHWpr zS!9Zn7}_Kb^*EfLDJIy^1>VE?UBqcNWL`h)tNgCwv6O@X@tI8=-ST68KpeunpR&I! z(@~Hu&c(!>AkE_|2#ITLXmm^0g0OhjhMHRP3UbAdHnhL7M?t=L5^D%bcS2o{f&%Ox zOXyE#R%Jn<_|66!yVMpGi7ZS&i1o}+--2Rsj}2WEsx2rHBe8izwB17n7jzecXwV0A z8aPYEH4I4u_YmLNw9zfY3wnqUmL$YEx@CMpxoAj0=B$DW@niyAP*5fA!LkWP6i*G= zm0u&eVh4wym3hkxYQ(EH^x}{Q^LvX|F|8olgI!h@)CzoJnxUiK3jn=|O<1B`owlx^ zftRL$xb7Rp)mW&KGEFU4ngxxb+h7TjC-f7?GbCC2iSag#>ad^KAZemF^SXlm;%OU7 z&%C){pm@iI9&Wm)V6YgA@l}W=ZUk_f`IJ;&K~05ImeeLevjs8kgb((ZtZxp3?`_;VUaGHuQ8eLBk~^ihA!U zI6=&?p*zdhf;Pv78g)RXSZssSb6x~%C+2%(no~30E;vcNX+y6!eNcdT?l4IU4jShk zE&j@oY<;oj&j%)`l{e$VeZDJ2!W&e z{a7$wIFFOiufbjU6U4k1Z&qc$Wm7Z#o+8YU4Z+$&=#j^Q>kM81Ar;S!NQnP>!ESlA{OPsaWyfumb4D_kyK zwTYu!t|~l7be%%18$_hyhQjm2Aci)HH%oRDt`K9UO4`R6cNeY{r%Q<4(iF=WBAE{s zn&Px+#7P-GTG%Nf(0Df0?(4MUp*x#bn&I~yXmyh4na2SyXR zT^#wQ&=S`W2*DYU6&XwiM**YhOg4UZ_gUrb*iq0X|y`45N(ZRpbC!}$-212%NC z+5K?-L*kVfvC0hpDh@D28ICRbt602}Xitk+@uZ@M#h-0xiu=rrN5o?`G&c8~jK7Qh zHnb?*p7E&o*@m*+muEaC^4q19uX=6CctYG^LpL>>&t*I*-ehpKxM-+`ZHDO`#JXA( zF|^%=LYU`0D=z2$VzqEHBsz(6lXzgrsYTC<)6SPrWY8H!FNhx*dRjbQcuvMk;=v1v zCVP*);uVItxMu!d@fCwq-lau*#gi9FF-HFL9v_P0RYQ=u>gXhPJhSTlA$k_iD-c z>A<5!-w1uPgzg+RqUc+3B16&^-;2pMjr{3*k-tT9Hnn()|1Hd4|181LE&k#k#XHwX zNc8Vk{F9h`t%N3(mK6U-WL-y)6na#Qyg|~MTJ++hV(eB4jc%zcR+Y;W(BNX1vhqer zyRfLW*sYwlT|&cpjV<;mt>#Sx>Z7>TNV}jm3tG=3;99iVH;{{*_WTKJaa4iGu7{+;#}pm z6xMuYe+p}%@+m{ogG-gH+bD}Tl+VyA5mA;Emnw}6Z4mo<$BKI>%{DZ;Wi_CUDe20T zYi{H5ZK#1(9aP%U>FSCTpb!U@%Q1t~mGGSmd0!md3J5(W(|+tv zoaHvH>ky*VFeJ0rm3|DZ5=Dx`r7O>*&?=O@$3SlqWZFioP!1##E-S83zO$h_VA4uu z)LoRl%%Vz}%+M15R1LCT9q?iutm2AS?niCII z@!dd*yZpq1e=`a^CXt<3BnzB^NHWD0#>h|=&lM16Vmc)Y1Sy&1{4$g9n};W3&)E;*(o?8ne}<_4f8trrBtOODsUF4x z=J#<$oPrgnDsJcr|5wDd83Y{1tTMcCkP1xcAWHlXu3c#^8Gn~KZ>%6586OoP31wIt zD`F!`sfcDSC0SGzQ+g&bgjdD4TxCQxRq<6LktORb?j)t*??WsGg^r$>4vJPhq>a;C>_v~8^x$g@ryk_a74RO~y28a4Y+d0KJlMLT%PlXYc$G;tp@;)jY!>#_Z`oPS z2@swP8#gB5e|&Qint0S{=8u%NculjlSAZky>3Hhs@Tn0Qd|)-l$_Gdsn1ZwgC6#O z>EYeD#7X~`ek(Ij#N0{}M4g6ecPX+>zXOA-;s~oXts)thO_zA$U5)H%hNFqP#MwI8 z>Ae8^|4--xRB>?)m0&4CMND8Xm2sJk)V-=VQB(Ub*$2c+L)6p){J>r^lAZdSE|iPJ z$dF{h|D~hJ3{vA%vbcGvWN`;P%vClL22{jH9KOj7OqTWRaw#eSqO$uq#9(kb#ecZrN#~MPCRL|Y4%BE;X^D{*%4FA*@uXv-|KH8J zOA)fKex0jhSwfH^Rx{>nR)|U#A4pQ;sg;r}eSAzwg+A6^|F|Sw+bsL&+oKUxjcYq_pDRP^&1zvqYJK9P&&O(UIW`x<;sF+!k$6;3vOE}ay#9p^b)S>F- zm}#A$(hMM7^cvEH{V$bPwI`^(Fw$pe$J<-^X$ z``#uL*ZTZ>fM3^iKSFa{`D0?M*x3BEcv)ShJ;zLY!89-L9{jr+lOk_`>Dsan#be@^ z;fD~;toc+t=6t*L8{i*J{}nuQybfivh-ctcwz8u8#95g#%Pi#}V-AX~!3yPNF|)Q8 z!hh8?AXT23)n6%bQ3-Nf>+^;vIj&7vtq5=8a5usVS4r~-B-BC* zkM^Aj%x8V)BK%&4+4l^#&& zHl;+FS!3Q0;1u`Y5#HDGBofT5+N<i)`g<;1jPY${gCLIiu?i6Xb z`aH|EwZ2x3h!2o)1QmCZ+Q5~yK$%{5syaxVP=RYW;^r<()$^5!S?3|VZ0I2|i1TW| zzG|JA<+`oD)>KNw^4++FG($EB@T;$v8(;vBAm>B!}Px|nkrs$4ewYt@{?;uf=@ zIjqDoCQlb9=N?g)F@7bBSPAM_$AzHIb6hGuXlW9cic4}xh;zL&Gc`nR5Ea!Qa{25DrmD7I4_~~Ls!x42lIFG<)=8XkA;K}K|2Ro;*<1BTp z>2Zd0rJ#&ga>g$!kJc}DzN~zJa3d$)$k}Y?_;!x(Q}$=Abna6QXIj_{2hJDmrWpN2i)-0XUKz|)BLGIL*Y?t~w{?%e8{S#tpKt__C}u2a8u z9#-D2`O&!<;URHY*_2Q5P5Bi6(M9neU5CU@WwZJV_)8lduAR#D!#u99omy}$8u0Gw zd$5>0H0&kkt6Yqs%AwXw*JkAPDSU!@mz4-{|MN-Pq=fnjmk>u^f3shdMCJsDw)+&T>X`3^Gugl{UtQlwa4{V-a^E;G@R=?=pxKv*ZciC zTzkYn;F5=(KlZ)I^^E?w~5xtTSk+Skr5!LH(Kk(W`ceJ%8iz6hH$h9Df1 z(TZ?+33WslmSA1v`Y!7vZKp!r)Kc|rZJM%2oK!zw`&ASc{9XA~4AGm!uO=J+A=h;w zhikfQ@#@Esm0F3mJ9v?{z_BrKm3F>*rAFbsgRawRwVWQ?H7Ba+Cf8>5#?pthHR{O9 zm$d%cg*{$Fcusa#@sR6{ewx_lTv+-qZG*adcpZ9$!q#uJp;}?-5858_BhF5zI4Pd4 znAAC>E9s>9=gzd_z}ev)>0Y4u z`i*nn%60je`j^mTcMn!8q7+vBU3pBc?0KHMfiZ&^ldn*p_$n8&mE$9o6HK69R!f@i zb?*^f8+V8aP{ne*te$~$-{}gq)H%wmVMo*rT21g{_e0{6x_`MBv$}i4uUehRSE!-p zE7V!#E7VUcW<^KZAr)+-vaYWpS{c*IX94>JE9IN+HMo+GAuQ0&IYc2FGkR&ZG0rFf}#Bt+vJ zpTm3(r*pVjqlw8@tz%e)ceD0cNiXlM+KIlQ-u`NB>sVmU?m5-#cU)UH+q;ZQ?04LZ z_-6LAoua)vjS+{N){3Fp4~?B(bBdE5ISz7@9LN5gE4=%hrCDemjtkIs&sWO|uk|i) zbVZM~Mvb7|Kjf;^w|Pq(zN|aFJH_Wv{e0Jd2HuPKkNB|h9`Qll1Bmypc*L_)46Rs+ zuy5I`-f@mYIs3d*9Pjlx;N7Eb#XXuSj#+3aQ%uJqG?hKtg8VwMz|p1oWADq_?6Ob6 zbV~lW-aX=?@HW>tN6fv=wNq?FxKg<~8Alsbh_yRXN4#FNcx%O%QUs+cJ7)5oh z@15D*ncbb8-I*kiKvp&+gai_rg#3Zwkso-4S3qMyiIP_XL8VGd{7+Neo!wB4f;I*^ zhJq3zVl4hdqG=SW0b3gZ6(3YkP!RALgjeyW$`fk8b2mZTZnEE;IrsnEbI!eU@62r7 z_;gQ;{M4wm%#z<6@e@xwzbdQVGr+D+Yw(h;JpJroLKN6mbq_dUxBo#; ztNcO6Z$0hu(Fq;EuP1B33&lLXF`1d@0@{F*1le16GMeWYH zYNj6bbhFecAA1HJdvnNf))tb|rB9yfZRc%O6+jvznnk}h3lnM2ok@;X4*$w3CTAC6ICTNCo1P>eJ zD|59JEnm4hc!@S3x2OLJ#h)5a6)Fg(YyIqh^NPTySzbTuK}D(RGc+1zW`j?fF-2*s zyj*LLUMs5C<_rJPAYITuW)0Hp^oQK}@{b+Mv{u(`@F?L`!fC7$4rG;ZCaXj{RtX`m z;xy-3!)ea5p3`h+J*Sz^8nH@R%~y@uuNl&3nVT?l&BD-C&DV_jK+BhJbaLN5IlHKU z?UVD06kk4{k6|gFe>0Qt0$eG;R#=#^MTS+zCLzo(OF-L(lPU#uS5CC zq;J8$t<vdUQ-$ZO^()bzEN1LTh8|~ignV7OZ5(UR@rsH1!Xq@U&;f)SUKJhGBVrB;ok-*TxUFf>aVXd$ zrSZSRmsIe*Gs5ZqLHRS>O4P;PAGd|=5gJf~VmPaDjDp9mabyAa2rWsG@2UJRe}(f< z)fN642P>)dcPZAyrTzvKu-VzIG-oXLce5)i*ZJMb-==T$*ExE!xB45L*%-11l+W{? z1HHNIC4ZxI1MC4-Z%1DuZF*;xey*^~pP@wgd*1Waw}OPapF@z~I;BVx-__aL1Iv z=edb?7ukWc%4J3C5xN++s2ThXT%M*tDo+Gz9Fx+YMGoh2gQMjB__{7$`H-ZKGZYtzL+<%i%@hKF60M zdch|TaYA^A)515L7JlM{P{2O+V$lWT3!YYPn&*Y8I&i5!9nbU86<{~}X?TXrD_m34 zFVX6peUppKeD(SX|YI zcsPAhLaQqoT4g!s@nXGBB{grCPKTz35uBSgDPftKf*rsv*RRU2!Q(S3yCp%zt{{kb)EWJpppF+rO$M%D z_X2NaM}T*-f+UsQ%c_&YI<8``Ow#cX)}N%|w)(e$8`(R+t?V!m7gPxS zlzjyH3pR3u%D!f)BXr!?od#t5a&R2H5wyzh25S5nU?Tqrn93K7RI%;UJW^wYyaias z9~h~HSvhaR$qfE5@N&KZk>>OJ(2j*1Fa2ZJaw_-+z6JD6ydC@%d@JZ%c{lJ*%7Xop zzW|JIs_tX_rI9*&mcIh*;cLM8J@V1*8TKfeqo2l;&9 z$NUc9X`VJhW1sSk$!I0AcCzz)GiXhs3I(KxkzJy+1u>JQw}7eAIbcXiP0?9~^h02l zbT=?ZdI^{(ody<4MWfJV(#^m!sTWu-odV7XOBY6=&!mjeXt$I-T4Reqqqn5p=+RrH zN#Jad4x_gYN_B{H7;(nq!JAu4CowPU4o$+l%3cJHW`}_3>_gy0HX&^io6IVKm$J)% zRcsOPM}q%jU=<#E$sS#W^}ulU=q2K02~LP!!bXja;qj6R;4N(Z*iP2Oy2i>p#zv)A z@h0}fxFw*SnVq0B#_s~Qk3SA{<9Dc<*sWPrzz?!w(sAS_%S~)%b~^B>>?+{M2}^)Y z6Jo%l6FPwl!V{|;P3*wL81RFvPGEV?E?`%V>}+CqZHhC-?#ZnJU7iyIcK@Ig*fil4 zXB+!<+Ah$^dB=gj$V+!osw!8Ey_dHH^v3)c&?x8xr@3Gk(3yE0oWw#|q1LA>P3*41 za1{=p6fRL>tfnXidPPYm@UxO#;M|idt0Jm;KZ#4wO9aN^e76vzz)pe31$a4&?%`6&Ml7Lc|XVyjEaD;6{P32s|o~W8D-#+|l;( zU#5k9O1@I0Y*h{_-zc)0txi=d)$7#dYE->nU9a}5d(@Naw`#HbcK1DQ+r7&j@Qm{0 zd*1T=pU3S@@{ab-_gdaZy_>zg-s9eHyplFao3350-J->``?ZI(KWiUpr?n}*D}9H3 zKu}G54DOgzAL)ghVWI&%ok+4HmxfI9pjKwm)7kCrqBU1$d>v-DSTU zq9r`uC1csV6!9f?3fo%}JB^L4YCPG-y*R<_6B)k6#{=Ky*}(n01o#)83p~hwfTAR6 zJkTL!16|TYpep48Jrad#Qa(^`yX#<8*i^T<08(l1%7S}8lM}gIoixHZ!~W+!)A-wW^ORwH5VS|ct*() zp_Tpbe_pDhoq+FnKTVi}9b9~{MfJVU53zGZ5wT}_@$(##{_7_j+kyZ3!3F!jeXzjs zZy)=gcthnk{Sz~u=B=^+mX>vkc;B^yV$@;lgkduQTZ8ysifv|IIp4&DUBmfN#g4i84A-2WUqAEan|sf@x$Uwa5AcTG zF$RB~+n<~KzTRIY@I!KM{Yd_#)6NU>H2Wt(KEiGe@{-=SgS?9OjvB+OWP8O}enan} zv0MxCB>UMJJhAtoDn4dp?+e%PCr9xTyY6b@!M=Gk7w98DX@=5 zxZZm<%BPN$A}a;I_slx}m1MAuuRq~A=$Kso%-6R(efr_N*X=Jh@VkA>oFQgfvk9Zi z?eHT!IoN1MvD%=*Jat`nFi6H5a&cXfBs03w?sw;;0g9h;zn_oEahysqQ2*azG^Th8VcVqy(10 z-GZVtaqh{B+<4~piVj}P8|^I}{9!3_-mcihZ*%<7hz{5^7+oqRdWn!Osg zgJpPYl^L4}Ww4e(Eruwn_CBu1^+Y$Vg+9e;)~aR=YKMP2@o`=jN*1DArYdp}$|b1^ zx_~H%N>vRj*0F%VzZAX~FR7MO}5)r?h(ykpfK#bH`O z(`r#w9Y2>Et1&C|pjm-`H>4_pf+|(61+)-gE&8So@`(vTsGdmg3b8PV)gEf9wHmUb zE`}F?7DYA?`Md|?Flbmk8LhR}!MLh61HLbkSiW~JkMqgFH@ClAi4`LkiVD^Ip{v~LZgtn50q5NYl_Tes`Taahg#Q%&s zqmHBs$ErG9Mr<_|ScfCnimXwvil)a_+m~XWIJFf`Fk@>er*JJ7*^?!hXn|GU}ieXHZ4ZRCj9-tppk1 zcxaoX73)%lV)#Qc&Mqc^l0n&O&FB%~3&!qoC;kQ5IG9rB6>gGMwB-*Ir{ z62|}^Dl9l|X(AwhhNm8oQdlLrMS^G@cl$(AsE+8SNPImey(-Nn!_dDK$O>!7!q^ z7$y$D>-OOv&gcl_?pK^fG@mRv(oG6WW)?f<#T#aD2q1_|5yl|=*)+s+=27oE(ECeC zd7@Ly=rk!PhDkFvNX8qdqtjqFK_~flic{glG1nC)**GQGIl2-p%teS79aRJ)=r*lc zh)(T+M+Va92Fgvv2_m4@Ml-upJr|sJ%fRSw7l6ZGz2Z1X+}}ZTr!jBT!T#NDe6ON9ew>+-GT4I#K3I!!MA&< zHFGel0W(2?xhynmhP+m^2IC_vJj4(IJ+*{KGV0o zBO(Sz)Su>7%~&<(n0PmiVY+5Ck0X~%j(P2Hyf6kuOztF_x;1BG@}e4bW^^ez2eUa> z$5RV5BZcKjnkI>f{19zkoFjrkJW0YGYfyU`b%(BqxdbK|R!}(8dUa1z!nb>Kk5rFX zjEj?>W0|QEFID+j?+4v{k<>eeuJS|MK51O7?$rq_a^tu&7C9PWOIhwCy z<^}1CnHlj{BJNP*=@c)Qk4wtR`z}H0aDI{YVI~eAK~a%Gx^Rh{5jaRC#HXYeDVoVxeFQTA(Q2ZCP6pS!03zePvtHr`uO`Q% zYtSoEZOrLv;0qyxkd7gU>+lRbU|36sj?1ZEAps2DP)h{honxRPgH#hYoD?RL+qd&s z;gv3OGZnaifF49PAh|@A4A%>tYK109NQmgI0TC*RSaH|XZq^_bTuwXH1P3iXkhNnX zPql}6F*kCd3x$hHfC?d`-?aXSM3QO8cJKn;ZojaDSBB5JLX_-WJez5nhR7J0@UO)y zaW07A(2c5LF54cEP+8#^aU>_?jOX1A8s(Eq9cI9UMX_+k7lx^*TTnF9njNpM-yLtx zocQ60{hL4V(864_8|_6!7MKe}#OMNA%Z4Yz^$lfPqf?bcIE00voMHwf3R5wjh{3&` zrf>_fY7^H@n5(V7%xBsE{W9N~Ra{bEUzndaxu~>sa$#LTaY23k;=+RblDgu_i|dN7 zE2_`SD_xRbRM$J}72d1#*8Q1J_ZM_NzUma?b1#>$d_qq@m4Ar4v0wdeafK*6kic*g zD|-iF@4RZi{SF@+kPd%+{IGg**6+WZ@J!F|W52N-2l;&kL)_$HF6F-R>cv+$e_66& zW6LdDGO;u@{3$0o)S5OzDmZQ*Jjg%l)!*gC@@2(Xd#lG^A>B@jAq=N2)xeSc1?ZR%f>z;XiX9w><7D>~K zCV^vKSQsCdJ-P4N`(IDGG4Md*kOLXlVWy1dw|DUNAreT}!)_do|APXNjuO;^ya9h2 zL|HhFfjAKDQ5Ca~pIG%ySaE@?6J9>mUOvYANBsx}0jGz@xxqiHj! zyG>Ak9LsR5!tqTU&*5k{1=TeT8i?a49GBtvB#!5CypE%fT~LtSpcEW4a9ob#Q}T+a z=Nj%1G~Qv*1{}BH_!*AhfOOch0t5jEl7l$BXfxy=VW%J{HNrtNptI2S zjt=te*SD;m0o%9aWHPT7bp+6y?C@-o5^?}Aj zdDBE_OB9idFU={ySJ3}KA<^Cx4dp=3KsTd(=r&|_^PvE!8`K->3r&D3yZO?K(0S-G z^bzzqbQ{Wx@ufA;D>2+TesnO#kG_R!#rjb!v_00(MOTri*WHgEhu(x9LQ{MA(bLdH zsBup}3Wu_wgHUEKKiUTc^!B5((BimSbP9@%uSNOsT#-LL8ShW;LRTU01b>Qy(i3Xa z5@;869Lh?pP34KM+B7dQfX*e>AzM-%a`dT7jr-K2rO*Q?v2Q)fg}nOJr}|JhlnkXo zXQA(*g#PuZ40;thl^jUtp`RghKp^=+Eub{09NGwt8W>2W&=b%R7k1x4ktu;R63T+| zQyNe)bOrhh`VR6R)PMq^F@u8WRmdwfh$5i@P$sky+Lqdo-h;k|?1LLpGbj>Dfr_Ac z&>rY26gH$GWkD|c(1z3X&cho~33L}4FrqOHg;qkFq0gXpX^p8T z^f)9T|B;QU8hS7?n99m${B7uR1#Ew+YqZj$w9JYj7;Q6UaTaGyr!8 zPt?2*+ygvGGtZ?xAK_jW?gGD+@tmOE@aO3K^T2W7DQI{yfq zA@eM7Z}{@He>Rw(#gm|6@XrBr{e)+;GR%d6uWv9k90Bvdyya+~59ViUy5#|IorskY1;`3jQ#pS8HBKh6`Qqevqf3fJM51MA$sc1GF|Y68^`uzXY5PUZVK~ zc$9^kfio=3C+J}wA7Pr8lFPuA#!>?sjSP?L0#|{@fLCbF7H(b%<{l{4{#D=rq^E0s z0=yP!UJr5pHQ*0S7z}egf%fo%c> z)i9PnieHC67k*y+v41~!1JdEpL~ymve-oSyenazqa1J%1H#KvkCX=fX9o2?N7^Wb= z!y_#0p7jWmQX@L10fCV20QX_gt zb6o_?urLp_LJQvl7vToHsN;`=i{XD?^Bd?$=4;>rl-&bjz78%$IudfR;bRz1vOyQ{ z3Ai3IchYVE@0<^kZD;O{hVM?CXga2xnqX}$;M@e!u^2QW|5 zXL&&H~>D^VSlYO-*Z<=l(es<_1(+xIcKVg&Uwk=ATg>PsPKu{}(XN zqV0M9ori$`>I%C(!qMRQ@c*j)<51uN@Nb&ATbX|chat@;-~#`l{YSu6;D?&K*xdYo zV7`M~AK^qf;4c^oV0crr5C&}oPtgS!;BZu)t=R@Xjo3-xg~)G$dE+}}5gy_mZVZ0R z!b#x8|1gh#!aV*@hT-6)V5csSZ?nh2UYhwfT4v#i;N@U%?f)H(Tmkme%$H=Pg?Uh~ zs$ukh4h*Yn3`8%3p8(g=1-uVl1NPV46TH^K+(YXu%qO(o!n{C{WUI;lx8~X?FMzNA zdT0Xz>gWo%g-=?z7WgR(^Ih;XxSo#ZE`P?tlfln|1GS$oBXa|A7}ESKU=9Mi_&(${ z-$q=BhC0I{bm1m&u;w)QH(QuT@fL6s?Qac!&ce6B&x1p?pBuQuUNPO{3^JG!1JFszNR~2XsH|U zx#rejz6D>=+y=}Kswbgch;Ogs`7U7Y01iYtRdYC)$3r}{8~z9#KO8-**abrboIFvm zp%b_W+*N1j4Bmz`Kg0LH-&Gf|LUS~@BhsPJUiiCd|I;`x=3ZcK5ce~4Z!ljj9`wwv zco^^{Ld{HUNC4Lc^W%{@3H&1X8h9VLFPJwztJf^d_xbA#Ky!aE=iLhJ zC#Q>&b%DIZszw2+n)w(-`rv1ELI0PQ8nFrk))U1Yi3>~&` zOYjkL{Sz=$8UA5@Kpa7aF(}Z1G|%76W5Ik&@&n~faHg)17a<<@MtYg%aq!ncdZy+q za6_c0Ku29DV7xAXTXf9AA84KkKR;+5)0_?F0agJWM|_UX&)4~cg{PxOtUN$-F5;Ub zwj6SCKpqS!a5jVCE$s7kfjeQdGC!V~3*ld;<4=N%bUY7SD{~Jrm%z`x%Y*c7aH)>J z%j42&;6cM&j(~AU^V5*I0(>56Zr~{lpP9M#6`5Vp4 zzoQO2f{qKXH)BY=(w}IJLs(Cxu{n9~L*x2X= z9bXLpW$+HouGe6=0>i7?5RRVvz{0=6e-*q(`*~ve5WH9ODKv_?8q9M5pE2_R@Fk>q zW@SDI{upV_e+_&HjLk(KVSgQl!)^oafPa|hZ62lUKLURjq^D~>3Qk12DfAKi$8>(? zk1f0z{0aDk_H!ecPlG4&yqE>U4H*8V0|tUW#U=6ZSe)U%!RNI96Zk*FL~}v2ANX?% zdx39SnEkgN;V(SQ*PksK$FcP#<+VY_Exp6z~kgzsCp1N=W)xGwk?3-gPOhgZTE4gHQe@uKJX z9|yx9ZUa*My$ioC@SBZpaS0nmqZ;N4goSycu~|3;Y+9Im)G3@b`T5!4tNi-;&jA6# zw$v+y*#`zfZUpp$L!8ZQwVJHT(9nVAl4tN)KCw+lP3{H6Y;|}MF zK^m)mcuk5!33j@}?>`Pz1U|UHfv*|}5;OtDnKWM&k*Vxlji3|C;sdY1vy8V*@CtfW z#mt2rFIFhpMyFJRIF04KvbRNy4GSD@BHNuR2A?HMR2%VG9|f(z-bNg1r!7Bph)Sfr)CsuD!Do7t-vNfg>qlHB(H%(OvCSpKp-daifZe1z+(bP8 zQN4o>!Q`a3EXD0ZK|ZV-4zxLTz*&dy^_*x6^6F zIOsTMP;-Z%czDq)SOkS~$KnH`+Vku#RH#Aa$Y!U(a(HNva~INrdds5FAeZ~1EI|>1 zURURrr}~Naf-+S(*HyDZRIW+N>mCQ!5HILGmFr(>AEs)2fIZe1%EDtys2(-c7{a3f zC79Gpl|0ymgWHWyFsitT$bgSd>b$*Br9)jHCoM*Q;Dd#V;fWY;ys8MU*i*q_6m6(@ zOwfpTsKH>+*QzPJ>=UXN-4+{O4%K{dN1ZD#xD48*&hI`du&Hb&{fW$W^-keb7B9Mi zNFqK8tPCtfoJq^Eo$_*YK9Mw6;CLS6{lL)dg&44F0?Ot z#r>vlBXq#@<_1j9;7J^`({A`>PWO(Eafm8iD@jS7=jL zvkTb-twW*s=?`waWMPkYfk*6kfm1O<)g|EJOw>+Ao>gi0z6)Xm<-%?dTkup>b?wC7 zP8+dzxM&>?PAb42OBDopGO*o79LhEpPs^kRk)VaJ8~6p2V=iNFQhV&}^gZ?t`WSm} z@aYV5+npcw4!>XpR{ z--&s1kL?+%+qppoHO2MA#~WpFd)Y2%%OiFJPX_LlJ@A@jsOmSNaSmDoix(xTMt4Up zK@pg*Q1moq;!se{9zX9Qn?c90$ErfbxHEH%pa;s!vmVwLsyJ?(`@KNua)Mwth;K_% zP12l?#ZOFwp2Pc^LhRHlrJ!3V+MxcbN}eCFG*RilRF#)h<2a2qk+Rgm-aQl8h|kHS zUvZY6$=)5qz2%-~@$QJyFyxWTuEqiSp9g}I+~c5=8V55`gh5rdUz-HED=R~0 z8!cAnv=9xk(|V-ck3FZF&b{b64Q9f2fMN8YfLgE-y92+}{s9xj53MB2C?ApJV>PwnLrk=hz$cH`ucZ+K)Qz zdSqNcTF?d*jW;IM=n<;7l3}q?I~0w^s59n^;yGi!D5kzBeG%b#=({ha;lTJ8Y7vHy z5^(c3EUuF8U3`W_1)jFMy*!dlx}qv`-)wx|g80(7-zaUWd+{F$)lhc{yvVbb@4naE z<-0r;@I7s#*HxEBpb-vr*Ltafy!9LqsLl^R6Qjyih&S+_!MS+(h1DOoSvUG2ES|}V z?+*O&M3vtkX;anWQ1=49m$;{w0SFg#3Ptm`Lr(KuZqRpVkbBuFC|gxrf-}Z%K+dsr zir>8u*{VHvh@koHIT-&o>A>A5sD3!VNeG(L)khtBMe(v&kc{$I#|O~?_<;k4Q{B`8 zoIZ=;Hw8f*;~S{snRtHP5cGQ@zX_tEe*Doz(09op>Ns;m7>>W-gH?dIO>J;yKl`*n zPqeD_Kbwsfcs0O)DEFQi;-I(*)m3ft3`c49tknEMdAt2NdvSJoPM+M|p_M3-mpYvC zo>4S;)RfY){35v~e4lM<(RA4(BFC#ZyR>XdztYm`jS=?*XHT16Bo}w8bmV21&L}FB z4?Cq)59s{2kyI}^d&U%Z0fosG*`<>^=9Kx36K2DZww-z>jac-2*w$?y9dp#*6twH! zs%-DGzi;`m?3vVsr-#()_D*F%`n!HdWpZS5@r9fgnP5EDO74#A-aI$#(#AvculzSB zt$EDqUk4_QI68W6(UXz(mMgwp8yvs-+Ivl*0VtxG-oyU7w*X5?;E!wq?k`XU<)_J!Ev+nH#cgOq=GX!s2pY$l6~Rx8uy+IlTiv z84)(S?UKOH5AT@tFw=WdROweUWJyfx7LWUe{e5j)-HkoEuH4^t)!`3E-rRTLX2pYP zb(i=2^?qFOsg)ag$v0zy#YlNQCQ+=D4P$$Wt1>+{&#^3ES^Z^A?=08@Xq)rGZc_rbSnG5ID!noTb-%GJ|2{?Cu$%)gK zW%HT44t+YR-{nPj66-`%2Gp+J^vR5{O#{}a|L@KVzd3q)Eef5#^uMbw?i~@n;Bucf zFF(xvdDHop^~}424pv5ZO$;jAbvv3aNF`2y0Jow{Nv^ z%AN3eos*tj|5M0o-<)6UyU5RXS(g}d+}V_Z6%l=-PW9XywRLjwr6oW5cufiaadQ9a z7Jpp)Vc^E8=XY&*E%@PxU-oCF?fYiwyY)Nz+n=}l^YB#ZJ+$m5?OTxZ zoD7RP5PRox{D-abBiDSAcj&^w*xRF9r{tzbxBctZo{FQx+pKzJ&4-hY2ORxjW`XQc z^3EUGYbt|(2+28fDCyAb8lds2ZNE^0qKFN%pvqabGOFd77IDZj4 z{l(5ka>Ll+KGVd`5;s=gAKO8IU-h_Kj>|B1HmaUKZn7glnfGUj{kb~$r%Bbq zCJA$X#Qv8Iaprw30EoL%I7Ji8s#4)wyj%Yk4rYy=WtE z<>rgFG9|BAw3A2k%0zqFDZi`eASdM~ig39jKVL*h|7o2?M;SkDgXknbM7p!I7mOBN z*E zFx(!C)HHduFr&7*PIw5>xT+;)ba&akC|dN8MMZy=6p6 zB#$BeA>w6KX@N+P_ezUJqRc8AD3avMWvxXY`F`062X|oOmU4Z0YtdI8 zDKAB_;T0`JKRK)-UG$ePRdf}}@{@{gVnB7k%tR5JdGimvbxoh!OIw%Aq1n)}Ff@ zQ{uC8+lX}e_S}AAlyuJPATng+yuD(y{BqtXF-CTupDM=6rSp4>OnGMhOJbZXSP&($ zs<$o>LX4N&UHM{y^s8EqZhfjMzQLS{7}|48FG@0vx`h9K;yG@*0QzvP}sG3`t@4TjS&~|+72;vh+n1r9Rt2W7<3wt;R<)D(P z*JRkDLG>;m2DgWb88jJ7_o}OM!J>Y>aPp$O$mSyon^WZ!d?c*;)$UDB6APa#(^a1$ zO~XkQ{AZ7D_(uqJVeG@B(23@Lw5Zo8193)E_rOE_RWD3MAq(4i3JEt|J|fNwBXxws zXu#L24*3~a9d$Adhp2jJx>8USRtJ4eR~;%c@d{eoG`wW|W8<6j$;DqM78cw6DV*;G z2ku-7%@XWy>xiPEPS2sxM(acbZ4G_aOQ@<)aQ~vElmxYXNGZO zcvN?++G>k0B2jf{(MCD)@gAaBu6g`vQ6k$c%M_*Zv1Q#wnLNHMNtCZ&o+~P3-tsnL zrd+%HEY=hmEBayqv3W(gm?P_~>>w&-@0Dd@u6%vvbTO|wWYtyC6j#}F6gztJaOWY@ luhi+o=Va&lb&mDtH9ueL+zL)4Oh?ka@G?){vTZx@nrx2 delta 10717 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 QZ?3k*RQcwzI6fTwA5cAnHvj+t diff --git a/README.md b/README.md index c8cabf7..f31cd2e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ *English version below — scroll past the Russian half.* -**Версия 1.4.1** — для 7 Days to Die 3.2 (с 3.3 experimental не совместима). Автор: Alex Cube. +**Версия 1.4.2** — для 7 Days to Die 3.2 (с 3.3 experimental не совместима и сама об этом скажет). Автор: Alex Cube. - Страница мода: https://www.alexcube.ru/7-days-to-die-moi-mody/kniga-nekromanta-necromancer-s-tome/ - Nexus Mods: https://www.nexusmods.com/7daystodie/mods/12547 @@ -150,7 +150,7 @@ HUD за этим следят два индикатора: череп в ста **13 языков полностью:** русский, английский, немецкий, испанский, французский, итальянский, японский, корейский, польский, португальский (Бразилия), турецкий, китайский упрощённый и -традиционный. Все 149 ключей `Config/Localization.csv` заполнены, пустых ячеек нет. +традиционный. Все 165 ключей `Config/Localization.csv` заполнены, пустых ячеек нет. ## Установка @@ -162,6 +162,8 @@ HUD за этим следят два индикатора: череп в ста ## Статус +Версия 1.4.2 — **защита от несовместимой версии игры**. Если мод запущен не на той версии игры, под которую собран (эта сборка — для 3.2.x), в главном меню появляется окно «мод несовместим, обновите» с единственной кнопкой «Выйти из игры». Если игрок всё же откроет мир, сохранённое Пространственное хранилище не разбирается и записывается обратно байт в байт — вещи дождутся правильной сборки мода. + Версия 1.4.1 — **исправлено падение FPS**. Красный труп «Жертвы» оставлял в памяти свои текстуры и материалы и не отдавал их до перезапуска игры: за пару часов набегали гигабайты видеопамяти, и FPS падал в разы. Теперь всё убирается вместе с трупом, а сам труп лежит 5 минут, а не час. Урон ножа пересчитывается раз в секунду, а не 10 раз. **Мод рассчитан на игру 3.2 и НЕ совместим с 3.3 experimental**: там перестаёт сохраняться содержимое Пространственного хранилища и ломается Пирамида Ереси. Версия под 3.3 выйдет отдельно. @@ -248,7 +250,7 @@ HUD за этим следят два индикатора: череп в ста # Necromancer's Tome (English) -**Version 1.4.1** - for 7 Days to Die 3.2 (not compatible with 3.3 experimental). By Alex Cube. +**Version 1.4.2** - for 7 Days to Die 3.2 (not compatible with 3.3 experimental, and says so itself). By Alex Cube. - Mod page: https://www.alexcube.ru/7-days-to-die-moi-mody/kniga-nekromanta-necromancer-s-tome/ - Nexus Mods: https://www.nexusmods.com/7daystodie/mods/12547 @@ -396,7 +398,7 @@ deliberately not retold here: a README gets read before the playthrough. ## Localization **13 languages, complete:** Russian, English, German, Spanish, French, Italian, Japanese, Korean, -Polish, Brazilian Portuguese, Turkish, Simplified and Traditional Chinese. All 149 keys in +Polish, Brazilian Portuguese, Turkish, Simplified and Traditional Chinese. All 165 keys in `Config/Localization.csv` are filled in, with no empty cells. ## Installation @@ -410,6 +412,8 @@ story scenes play without stopping time. ## Status +Version 1.4.2 - **protection against an incompatible game version**. If the mod runs on a game version it was not built for (this build is for 3.2.x), the main menu shows a "mod is incompatible, please update" window with a single "Quit game" button. And if a world does get opened, the saved Spatial Vault is not parsed but written back byte for byte - its items wait for the right build of the mod. + Version 1.4.1 - **the FPS drop is fixed**. A red Victim corpse left its textures and materials in memory and never gave them back until the game was restarted: within a couple of hours that was gigabytes of video memory, and the frame rate fell several times over. Everything is now cleaned up with the corpse, and the corpse itself stays for 5 minutes instead of an hour. The knife's damage is refreshed once a second instead of 10 times. **The mod is built for game version 3.2 and is NOT compatible with 3.3 experimental**: there the Spatial Vault stops saving its contents and the Pyramid of Heresy breaks. A 3.3 version will come separately.