рдЗрд╕ рднрд╛рдЧ рдореЗрдВ, рдмреАрдЯ рд╕реЗрдмрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдореЙрдб рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╣рдо рдпреВрдирд┐рдЯреА рдЧреЗрдо рдХреЗ рд▓рд┐рдП рдореЙрдбреНрд╕ рдХреЗ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЛ рджреЗрдЦреЗрдВрдЧреЗ, рдкрддрд╛ рд▓рдЧрд╛рдПрдБ рдХрд┐ рдХреНрдпрд╛ рдХрдард┐рдирд╛рдЗрдпрд╛рдБ рд╣реИрдВ, рдФрд░ рд╣рд╛рд░реНрдордиреА рд╕реЗ рднреА рдкрд░рд┐рдЪрд┐рдд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рд░рд┐рдорд╡рд░реНрд▓реНрдб, рдмреИрдЯрд▓рдЯреЗрдХ, рд╕рд┐рдЯреАрдЬрд╝: рд╕реНрдХрд╛рдИрд▓рд╛рдЗрди, рдФрд░ рдХрдИ рдореЗрдВ рдкреНрд░рдпреБрдХреНрдд рдЧреЗрдо рдХреЛрдб рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╣реИред рдЕрдиреНрдп рдЦреЗрд▓ред
рдпрджреНрдпрдкрд┐ рдпрд╣ рд▓реЗрдЦ рдмреАрдЯ рд╕реЗрдмрд░ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдореЙрдб рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рддрд░реАрдХреЗ рдкрд░ рдПрдХ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреА рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ, рдЗрд╕рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдпрд╣ рджрд┐рдЦрд╛рдирд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рднреА рдХрд╕реНрдЯрдо рдореЙрдб рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рди рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рд╡рд┐рдХрд╛рд╕ рдХреЗ рджреМрд░рд╛рди рдЖрдкрдХреЛ рдХрд┐рди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд░рдирд╛ рд╣реИред рдХреБрдЫ рдЖрд░рдХреНрд╖рдг рдХреЗ рд╕рд╛рде рдпрд╣рд╛рдВ рд╡рд░реНрдгрд┐рдд рд╕рдм рдХреБрдЫ, рдХрдо рд╕реЗ рдХрдо рд╡рд┐рдВрдбреЛрдЬ рдкрд░ рд╕рднреА рдПрдХрддрд╛ рдХреЗ рдЦреЗрд▓ рдХреЗ рд▓рд┐рдП рд▓рд╛рдЧреВ рд╣реИред

рдЫрд╡рд┐ рд╕реНрд░реЛрдд: 1 , 2
рдкрд┐рдЫрд▓реА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ
рдкрд┐рдЫрд▓рд╛ рд╣рд┐рд╕реНрд╕рд╛
рдкрд╣рд▓реЗ рднрд╛рдЧ рд╕реЗ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣рд╛рдВ рдХреНрдпрд╛ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА рдореИрдВ рдЖрдкрдХреЛ рдЗрд╕реЗ рдкрдврд╝рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВред
рдпрд╣рд╛рдБ рдЗрд╕рдХреА рд╕рдВрдХреНрд╖рд┐рдкреНрдд (рдмрд╣реБрдд) рд╕рд╛рдордЧреНрд░реА рд╣реИ:
( ) тАФ dll-, - , . , dll- . , BepInEx IPA. Beat Saber BSIPA тАФ IPA. Beat Saber, IPA Unity-.
Beat Saber ,
Beat Saber VR-. , , , , Beat Saber. , , , Youtube:
, . ( ), , , , , .. , .
, . 5 , . , . Unity: , , .
, . Beat Saber ModAssistant, ( ), BSIPA, SongCore BS_Utils . , , .
, , .
, , Beat Saber 1.9.1 BSIPA 4.0.5. , - , , .
0:
, , , .
Beat Saber Modding Group ( BSMG). , . Visual Studio тАФ , .
. C# ( Rider), C#-, Class Library .NET, Unity ( 4.7.2). . .
manifest.json
Json-, - BSIPA. EmbeddedResource, dll-.
{
"$schema": "https://github.com/beat-saber-modding-group/BSIPA-MetadataFileSchema/blob/master/Schema.json",
"author": "fck_r_sns",
"description": "A mod to track active time spent in the game",
"gameVersion": "1.8.0",
"id": "BeatSaberTimeTracker",
"name": "BeatSaberTimeTracker",
"version": "0.0.1-alpha",
"dependsOn": {}
}
$schema . GitHub BSIPA. , . dependsOn , . BSIPA , dll-. gameVersion version .
Plugin.cs
, . BSIPA 3 , IBeatSaberPlugin. BSIPA 3 dll- , , IBeatSaberPlugin, тАФ . BSIPA 4 IBeatSaberPlugin. BSIPA , [Plugin], [Init], [OnStart] [OnExit].
using IPA;
using Logger = IPA.Logging.Logger;
namespace BeatSaberTimeTracker
{
[Plugin(RuntimeOptions.SingleStartInit)]
internal class Plugin
{
public static Logger logger { get; private set; }
[Init]
public Plugin(Logger logger)
{
Plugin.logger = logger;
logger.Debug("Init");
}
[OnStart]
public void OnStart()
{
logger.Debug("OnStart");
}
[OnExit]
public void OnExit()
{
logger.Debug("OnExit");
}
}
}
, Plugin. , (namespace) , тАФ BeatSaberTimeTracker. , - .
, , [Plugin], [Init], [OnStart] [OnExit]. IPA.Loader.dll. , , , Beat Saber - Steam. , Unity, IPA Beat Saber/Beat Saber_Data/Managed. Steam GitHub, . BSMG .
, dll- Beat Saber/Plugins . VR-, fpfc. . , . , Beat Saber/Logs .
[DEBUG @ 20:50:03 | BeatSaberTimeTracker] Init
[DEBUG @ 20:50:03 | BeatSaberTimeTracker] OnStart
[DEBUG @ 20:50:21 | BeatSaberTimeTracker] OnExit
, .
0
. - main . , : - , - , - .
1:
, - , тАФ - , . TimeTracker. Plugin , .
TimeTracker canvas , .
Awake:
private void Awake()
{
Plugin.logger.Debug("TimeTracker.Awake()");
GameObject canvasGo = new GameObject("Canvas");
canvasGo.transform.parent = transform;
_canvas = canvasGo.AddComponent<Canvas>();
_canvas.renderMode = RenderMode.WorldSpace;
var canvasTransform = _canvas.transform;
canvasTransform.position = new Vector3(-1f, 3.05f, 2.5f);
canvasTransform.localScale = Vector3.one;
_currentTimeText = CreateText(_canvas, new Vector2(0f, 0f), "");
_totalTimeText = CreateText(_canvas, new Vector2(0f, -0.15f), "");
}
, Canvas, , . CreateText:
private static TextMeshProUGUI CreateText(Canvas canvas, Vector2 position, string text)
{
GameObject gameObject = new GameObject("CustomUIText");
gameObject.SetActive(false);
TextMeshProUGUI textMeshProUgui = gameObject.AddComponent<TextMeshProUGUI>();
textMeshProUgui.rectTransform.SetParent(canvas.transform, false);
textMeshProUgui.rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
textMeshProUgui.rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
textMeshProUgui.rectTransform.sizeDelta = new Vector2(1f, 1f);
textMeshProUgui.rectTransform.transform.localPosition = Vector3.zero;
textMeshProUgui.rectTransform.anchoredPosition = position;
textMeshProUgui.text = text;
textMeshProUgui.fontSize = 0.15f;
textMeshProUgui.color = Color.white;
textMeshProUgui.alignment = TextAlignmentOptions.Left;
gameObject.SetActive(true);
return textMeshProUgui;
}
, , , TextMeshProUGUI RectTransform, Unity.
Unity- тАФ Unity. , , тАФ . - : - , , . , , . , , .
, , 400 : 20 20. . - .

Update :
private void Update()
{
if (Time.time >= _nextTextUpdate)
{
_currentTimeText.text = DateTime.Now.ToString("HH:mm");
_totalTimeText.text = $"Total: {Mathf.FloorToInt(Time.time / 60f):00}:{Mathf.FloorToInt(Time.time % 60f):00}";
_nextTextUpdate += TEXT_UPDATE_PERIOD;
}
}
Plugin, TimeTracker:
[OnStart]
public void OnStart()
{
logger.Debug("OnStart");
GameObject timeTrackerGo = new GameObject("TimeTracker");
timeTrackerGo.AddComponent<TimeTracker>();
Object.DontDestroyOnLoad(timeTrackerGo);
}
, - , DontDestroyOnLoad(тАж). .
, Unity : UnityEngine.CoreModule.dll GameObject MonoBehaviour, UnityEngine.UI.dll Unity.TextMeshPro.dll TextMeshPro UnityEngine.UIModule.dll Canvas. , .
dll-, , .

:
[DEBUG @ 21:37:18 | BeatSaberTimeTracker] Init
[DEBUG @ 21:37:18 | BeatSaberTimeTracker] OnStart
[DEBUG @ 21:37:18 | BeatSaberTimeTracker] TimeTracker.Awake()
[DEBUG @ 21:37:24 | BeatSaberTimeTracker] OnExit
[DEBUG @ 21:37:25 | BeatSaberTimeTracker] TimeTracker.OnDestroy()
, . тАФ , . - : , . , . .

1
, , Unity , . , , , UI .
2:
. , , UI , . , .
Update. _trackActiveTime, . _activeTimeText. , , .
private void Update()
{
if (_trackActiveTime)
{
_activeTime += Time.deltaTime;
}
if (Time.time >= _nextTextUpdate)
{
_currentTimeText.text = DateTime.Now.ToString("HH:mm");
_totalTimeText.text = $"Total: {Mathf.FloorToInt(Time.time / 60f):00}:{Mathf.FloorToInt(Time.time % 60f):00}";
_activeTimeText.text = $"Active: {Mathf.FloorToInt(_activeTime / 60f):00}:{Mathf.FloorToInt(_activeTime % 60f):00}";
_nextTextUpdate += TEXT_UPDATE_PERIOD;
}
}
:
private void SetTrackingMode(bool isTracking)
{
_trackActiveTime = isTracking;
_canvas.gameObject.SetActive(!isTracking);
}
_trackActiveTime . , .
- , SetTrackingMode(true), - , SetTrackingMode(false), . . , , , .
BS_Utils. BS_Utils.dll Beat Saber/Plugins ( ModAssistant). BS_Utils . , .
"dependsOn": {
"BS Utils": "^1.4.0"
},
BS_Utils , , .
BSEvents.gameSceneActive += EnableTrackingMode;
BSEvents.menuSceneActive += DisableTrackingMode;
BSEvents.songPaused += DisableTrackingMode;
BSEvents.songUnpaused += EnableTrackingMode;
EnableTrackingMode DisableTrackingMode , .
private void EnableTrackingMode()
{
SetTrackingMode(true);
}
private void DisableTrackingMode()
{
SetTrackingMode(false);
}
, dll Plugins, , .



Beat Saber, . , , , , . BS_Utils, . BS_Utils BSMG, , - . , . , .
2
, , , , . , Beat Saber BS_Utils , BSML тАФ , xml-.
3: BS_Utils,
BS_Utils . , BSEvents . .
, . Unity SceneManager, sceneLoaded, sceneUnloaded activeSceneChanged. . UnityEngine.CoreModule.dll , SceneManager .
private void Awake()
{
...
SceneManager.sceneLoaded += OnSceneLoaded;
SceneManager.sceneUnloaded += OnSceneUnloaded;
SceneManager.activeSceneChanged += OnActiveSceneChanged;
...
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
Plugin.logger.Debug("OnSceneLoaded: " + scene.name + " (" + mode + ")");
}
private void OnSceneUnloaded(Scene scene)
{
Plugin.logger.Debug("OnSceneUnloaded: " + scene.name);
}
private void OnActiveSceneChanged(Scene previous, Scene current)
{
Plugin.logger.Debug("OnActiveSceneChanged: " + previous.name + " -> " + current.name);
}
, , , , , .
[DEBUG @ 14:28:14 | BeatSaberTimeTracker] Plugin.Init
[DEBUG @ 14:28:14 | BeatSaberTimeTracker] Plugin.OnStart
[DEBUG @ 14:28:14 | BeatSaberTimeTracker] TimeTracker.Awake()
[DEBUG @ 14:28:15 | BeatSaberTimeTracker] OnSceneLoaded: EmptyTransition (Additive)
[DEBUG @ 14:28:15 | BeatSaberTimeTracker] OnActiveSceneChanged: PCInit -> EmptyTransition
[DEBUG @ 14:28:15 | BeatSaberTimeTracker] OnSceneLoaded: MainMenu (Additive)
[DEBUG @ 14:28:15 | BeatSaberTimeTracker] OnSceneLoaded: MenuCore (Additive)
[DEBUG @ 14:28:15 | BeatSaberTimeTracker] OnSceneLoaded: MenuEnvironment (Additive)
[DEBUG @ 14:28:15 | BeatSaberTimeTracker] OnSceneLoaded: MenuViewControllers (Additive)
[DEBUG @ 14:28:15 | BeatSaberTimeTracker] OnActiveSceneChanged: EmptyTransition -> MenuViewControllers
[DEBUG @ 14:28:15 | BeatSaberTimeTracker] OnSceneUnloaded: EmptyTransition
[DEBUG @ 14:28:22 | BeatSaberTimeTracker] OnSceneLoaded: BigMirrorEnvironment (Additive)
[DEBUG @ 14:28:22 | BeatSaberTimeTracker] OnSceneLoaded: StandardGameplay (Additive)
[DEBUG @ 14:28:23 | BeatSaberTimeTracker] OnSceneLoaded: GameplayCore (Additive)
[DEBUG @ 14:28:23 | BeatSaberTimeTracker] OnSceneLoaded: GameCore (Additive)
[DEBUG @ 14:28:23 | BeatSaberTimeTracker] OnActiveSceneChanged: MenuViewControllers -> GameCore
[DEBUG @ 14:28:29 | BeatSaberTimeTracker] OnActiveSceneChanged: GameCore -> MenuViewControllers
[DEBUG @ 14:28:29 | BeatSaberTimeTracker] OnActiveSceneChanged: MenuViewControllers -> MainMenu
[DEBUG @ 14:28:29 | BeatSaberTimeTracker] OnActiveSceneChanged: MainMenu -> MenuCore
[DEBUG @ 14:28:29 | BeatSaberTimeTracker] OnActiveSceneChanged: MenuCore -> MenuEnvironment
[DEBUG @ 14:28:29 | BeatSaberTimeTracker] OnActiveSceneChanged: MenuEnvironment -> MenuViewControllers
[DEBUG @ 14:28:29 | BeatSaberTimeTracker] OnSceneUnloaded: BigMirrorEnvironment
[DEBUG @ 14:28:29 | BeatSaberTimeTracker] OnSceneUnloaded: StandardGameplay
[DEBUG @ 14:28:29 | BeatSaberTimeTracker] OnSceneUnloaded: GameplayCore
[DEBUG @ 14:28:29 | BeatSaberTimeTracker] OnSceneUnloaded: GameCore
[DEBUG @ 14:28:34 | BeatSaberTimeTracker] Plugin.OnExit
[DEBUG @ 14:28:34 | BeatSaberTimeTracker] TimeTracker.OnDestroy()
, Beat Saber Additive. , тАФ . : , , GameCore. , тАФ MenuCore. MenuCore тАФ , , . MenuViewControllers. : , . .
OnActiveSceneChanged: :
private void OnActiveSceneChanged(Scene previous, Scene current)
{
Plugin.logger.Debug("OnActiveSceneChanged: " + previous.name + " -> " + current.name);
switch (current.name)
{
case "MenuViewControllers":
DisableTrackingMode();
break;
case "GameCore":
EnableTrackingMode();
break;
}
}
songPaused songUnpaused
, -. , Beat Saber. ┬лBeat Saber/Beat Saber_Data/Managed┬╗ 2 : Main.dll MainAssembly.dll. MainAssembly.dll, - 2 . , - Main.dll, MainAssembly.dll . MainAssembly.dll, Main.dll. , - .
, , , , Main.dll. , . BSMG dnSpy. Rider , , dnSpy , . , , тАФ , , Unity-.
: Main.dll , , . , - . Discord- BSMG . , , , , - Main.dll - ( ).
GamePause, . : Pause Resume. GamePause : didPauseEvent didResumeEvent. , - , GamePause , .
, - GamePause. Unity :
Resources.FindObjectsOfTypeAll<GamePause>();
, , . , . - , . , - . , . OnSceneLoaded OnActiveSceneChanged, GameCore GamePause. , , , : , , GamePause ( ), Resources.FindObjectsOfTypeAll , . , :
IEnumerator InitGamePauseCallbacks()
{
while (true)
{
GamePause[] comps = Resources.FindObjectsOfTypeAll<GamePause>();
if (comps.Length > 0)
{
Plugin.logger.Debug("GamePause has been found");
GamePause gamePause = comps[0];
gamePause.didPauseEvent += DisableTrackingMode;
gamePause.didResumeEvent += EnableTrackingMode;
break;
}
Plugin.logger.Debug("GamePause not found, skip a frame");
yield return null;
}
}
OnActiveSceneChanged GameCore:
private void OnActiveSceneChanged(Scene previous, Scene current)
{
Plugin.logger.Debug("OnActiveSceneChanged: " + previous.name + " -> " + current.name);
switch (current.name)
{
case "MenuViewControllers":
DisableTrackingMode();
break;
case "GameCore":
EnableTrackingMode();
StartCoroutine(InitGamePauseCallbacks());
break;
}
}
, , . . , GamePause GameCore, , . .
3
, . , , . .
4: Harmony
, Harmony тАФ C#-, . тАФ Andreas Pardeike (, GitHub), iOS- / (Swedish Police Authority). Mono.Cecil , dll- .NET-, Harmony (runtime). , , , . , .
Harmony (patches). :
тАФ Prefix Postfix. Transpiler , C#, IL-, , - Prefix/Postfix. Finalizer , , Harmony 2.0, .
, , Harmony , BS_Utils. , GamePause , , , Harmony. , GamePause didPauseEvent didResumeEvent, - .
, HarmonyPatcher. : public static void ApplyPatches() {}, :
Harmony harmony = new Harmony("com.fck_r_sns.BeatSaberTimeTracker");
harmony.PatchAll(Assembly.GetExecutingAssembly());
, , ( ). ┬лcom.fck_r_sns.BeatSaberTimeTracker┬╗ тАФ . , . Plugin, , HarmonyPatcher.ApplyPatches() TimeTracker.
. , , . тАФ . , , (, Prefix тАФ Prefix-), (, [HarmonyPrefix]). , , . GamePause.Pause(). Postfix-, , Pause() Postfix-.
[HarmonyPatch(typeof(GamePause), nameof(GamePause.Pause), MethodType.Normal)]
class GamePausePausePatch
{
[HarmonyPostfix]
static void TestPostfixPatch()
{
Plugin.logger.Debug("GamePause.Pause.TestPostfixPatch");
}
}
[HarmonyPatch] , . TestPostfixPatch [HarmonyPostfix], Postfix-. GamePause.Resume() ( ), , , , , , , .
, :
[DEBUG @ 16:21:55 | BeatSaberTimeTracker] Plugin.Init
[DEBUG @ 16:21:55 | BeatSaberTimeTracker] Plugin.OnStart
[DEBUG @ 16:21:55 | BeatSaberTimeTracker] HarmonyPatcher: Applied
[DEBUG @ 16:21:55 | BeatSaberTimeTracker] TimeTracker.Awake()
, Postfix- :
[DEBUG @ 16:22:24 | BeatSaberTimeTracker] GamePause.Pause.TestPostfixPatch
[DEBUG @ 16:22:31 | BeatSaberTimeTracker] GamePause.Resume.TestPostfixPatch
, Harmony , . , didPauseEvent didResumeEvent , , Postfix- - , TimeTracker . Harmony тАФ . TimeTracker тАФ , - . .
тАФ TimeTracker . , Resources.FindObjectsOfTypeAll(). BS_Utils, , .
тАФ BS_Utils.Utilities.BSEvents, . , .
EventsHelper:
namespace BeatSaberTimeTracker
{
public static class EventsHelper
{
public static event Action onGamePaused;
public static event Action onGameResumed;
}
}
, :
[HarmonyPatch(typeof(GamePause), nameof(GamePause.Pause), MethodType.Normal)]
class GamePausePatchPause
{
[HarmonyPostfix]
static void FireOnGamePausedEvent()
{
EventsHelper.FireOnGamePausedEvent();
}
}
GamePauseResumePatch . FireOnGamePausedEvent FireOnGameResumedEvent, - . TimeTracker EventsHelper. тАФ - , Resources.FindObjectsOfTypeAll().
, . , . GamePause.Pause() .
if (this._pause)
return;
this._pause = true;
тАж
Postfix- : , . , EventsHelper , . Prefix-, . Harmony , . Harmony :
- : , .
- __instance: , . this.
- __state: . , .
- __result: . , .
- : (3) (_) , Harmony .
, :
struct PauseState
{
public bool wasPaused;
}
, , , , . PauseState __state
тАФ , bool __state
.
Prefix-:
[HarmonyPrefix]
static void CheckIfAlreadyPaused(out PauseState __state, bool ____pause)
{
__state = new PauseState { wasPaused = ____pause };
}
out, , ____pause
(_pause
). ____pause
__state
тАФ .
Postfx-:
[HarmonyPostfix]
static void FireOnGamePausedEvent(PauseState __state, bool ____pause)
{
if (!__state.wasPaused && ____pause)
{
EventsHelper.FireOnGamePausedEvent();
}
}
__state
, Prefix-. wasPaused ____pause
, , .
, .
4
Harmony тАФ , RimWorld, Battletech, Cities: Skylines, Kerbal Space Program, Oxygen Not Included, Stardew Valley, Subnautica .
рдореЛрдб рдмрдирд╛рдирд╛ рдПрдХ рдХрдард┐рди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╣реИред рдореЙрдбреНрд╕ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рддреЗ рд╕рдордп, рдЖрдкрдХреЛ рд▓рдЧрд╛рддрд╛рд░ рдбрд┐рдХрдореНрдкреЛрдЬреНрдб рдХреЛрдб рдореЗрдВ рддрд▓реНрд▓реАрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЙрди рдХрдХреНрд╖рд╛рдУрдВ рдХреА рддрд▓рд╛рд╢ рдХрд░реЗрдВ рдЬреЛ рдЖрдкрдХреЛ рдЖрд╡рд╢реНрдпрдХ рд╣реИрдВ, рдЙрдиреНрд╣реЗрдВ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░реЗрдВ, рдЧреЗрдо рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореЙрдбреНрд╕ рдХреЛ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдПрдВ, рд╕рд╛рдорд╛рдиреНрдп рдбрд┐рдмрдЧрд┐рдВрдЧ рдореЛрдб рдХреА рдХрдореА рдФрд░ рдПрдХ рдкреВрд░реНрдг рдПрдХрддрд╛ рд╡рд╛рд▓реЗ рд╕рдВрдкрд╛рджрдХ рд╕реЗ рдкреАрдбрд╝рд┐рдд рд╣реЛрдВред
рдФрд░ рдлрд┐рд░ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдЧреЗрдо рдХрд╛ рдирдпрд╛ рд╕рдВрд╕реНрдХрд░рдг рдЬрд╛рд░реА рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рдЙрдиреНрд╣реЛрдВрдиреЗ рдореЙрдб рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рддрд░реНрдХ рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛, рдФрд░ рдЖрдкрдХреЛ рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред