рд▓рд┐рдВрдбрд░рдбреИрдо рдкрд╣реЗрд▓реА рдореЗрдВ рдЙрдкрд▓рдмреНрдзрд┐ рдкреНрд░рдгрд╛рд▓реА

рдЗрддрдирд╛ рд╕рдордп рдкрд╣рд▓реЗ рдирд╣реАрдВ, рдЧреЗрдо рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрд▓рдмреНрдзрд┐ рдкреНрд░рдгрд╛рд▓реА рдХреЛ рдбрд┐рдЬрд╛рдЗрди рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ Habr├й рдкрд░ рд╕рд╡рд╛рд▓ рдЙрдард╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд╡рд┐рднрд┐рдиреНрди рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреА рддреВрдлрд╛рдиреА рдФрд░ рдЙрдкрдпреЛрдЧреА рдЪрд░реНрдЪрд╛ рд╣реБрдИред рдлрд┐рд░ рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЕрдкрдиреЗ рдЦреЗрд▓ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛, рдЬреЛ рд░рд┐рд▓реАрдЬ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдерд╛ рдФрд░ рдореИрдВ рдмрд╣рд╕ рдореЗрдВ рднрд╛рдЧ рдирд╣реАрдВ рд▓реЗ рд╕рдХрд╛ред рд▓реЗрдХрд┐рди рдЬрдм рдЙрдиреНрд╣реЛрдВрдиреЗ рдЗрд╕ рд╡рд┐рд╖рдп рдХреЛ рджреЗрдЦрд╛, рддреЛ рдЙрдиреНрд╣реЛрдВрдиреЗ рддреБрд░рдВрдд рд╕реЛрдЪрд╛: тАЬрд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЗрд╕ рддрд░рд╣ рдХреА рдХрд╛рд░реНрдп рдкреНрд░рдгрд╛рд▓реА рд╣реИред рдЙрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд░рддреЗ? тАЭ рд╕реЛрдЪрд╛ рдФрд░ рдЯреВрдбреВ-рд▓рд┐рд╕реНрдЯ рдореЗрдВ рд▓рд┐рдЦ рджрд┐рдпрд╛ред рдЖрдЬ рдпрд╣ рдмрддрд╛рдиреЗ рдХрд╛ рд╕рдордп рд╣реИ рдХрд┐ рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдВрдбрд░рдбреИрдо рдкрд╣реЗрд▓реА рдЧреЗрдо рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред



рдЙрдкрд▓рдмреНрдзрд┐ рдПрдХ рдРрд╕рд╛ рдЖрдпрддрд╛рдХрд╛рд░ рдкрджрдХ рд╣реИ, рдЬрд┐рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдХреБрдЫ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд▓рд┐рдВрдбрд░рдбреИрдо рдкрд╣реЗрд▓реА рдореЗрдВ рд▓рдЧрднрдЧ рд╕реМ рдРрд╕реЗ рдкрджрдХ рд╣реИрдВред рдпрд╣рд╛рдБ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдпреВрдЖрдИ рдореЗрдВ рдХреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ:

рдЫрд╡рд┐

рдХреБрдЫ рд╡рд┐рдЪрд╛рд░:



рд╣рдо рдХреЛрдб рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдореЛрдЯреА рджреБрд╢реНрдордиреА рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рд╣рдо рд╡рд╣ рд╕рдм рдХреБрдЫ рд╕реВрдЪреАрдмрджреНрдз рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╣реИ,

enum LAchievement { LA_SUPPORTER = 0, LA_REVIEWER, LA_MONTHLING, LA_CASUAL, LA_ENTHUSIAST, LA_FANATIC, LA_PUZZLENEWBIE3X3, // ... // -  ,    }; 


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

рджреЛ рдкреНрд░рдХрд╛рд░ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░реЗрдВ:

 typedef bool (*HasAchievementProc)(void); // ,    typedef LString (*GetNoteProc)(void); //  -, , " 99 " 


рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХреЛрдИ рдЧреБрдкреНрдд рдЙрдкрд▓рдмреНрдзрд┐ рд╣реИ рдпрд╛ рдирд╣реАрдВ, рд╣рдо рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:

 enum AchievementVisibility { L_VIS, L_HID, }; 


рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рдХреЛ рдмрд╕ рдмреВрд▓ рдХреЗ рд╕рд╛рде рдорд┐рд▓ рд╕рдХрддрд╛ рд╣реИ (рдФрд░ рдпрд╣ рдмрд╣реБрдд рд╢реБрд░реБрдЖрдд рдореЗрдВ рдерд╛), рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЛрдВрдиреЗ рд╡рд┐рдХрд╛рд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рджреМрд░рд╛рди рдмреВрд▓ рд╕реЗ рдЗрдирдХрд╛рд░ рдХрд░ рджрд┐рдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рд╕реНрдерд┐рд░рд╛рдВрдХ рднрд░рддреЗ рд╕рдордп, рд╡рд┐рднрд┐рдиреНрди рдмреВрд▓ рд╕реЗ рдЙрдкрд▓рдмреНрдзрд┐рдпрд╛рдВ рдЖрдВрдЦреЛрдВ рдореЗрдВ рд▓рд╣рд░рд╛рдиреЗ рд▓рдЧреАрдВред

рдПрдХ рдЙрдкрд▓рдмреНрдзрд┐ рдХрд╛ рд╡рд░реНрдгрди рдЕрдВрддрддрдГ рдЗрд╕ рддрд░рд╣ рд╕реЗ рджреЗрдЦрдиреЗ рд▓рдЧрд╛:

 struct sAchievement { int FID; //  LAchievement bool FPaidVersion; //     ? const char* FName; //  ,    const char* FDescription; // ,     HasAchievementProc FProc; AchievementVisibility FHidden; const char* FProgressNote; //    ,  "%s solved" GetNoteProc FNoteProc; bool FShowNoteAfterAwarding; //         //   ,     . //       . // generated at runtime iGUIView* FViewPlate; iGUIView* FViewNote; clCVar* FAwarded; }; 


рдЗрд╕рдХреЗ рдмрд╛рдж рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ рдЙрдкрд▓рдмреНрдзрд┐рдпреЛрдВ рдХрд╛ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХрд░рдиреЗ рдХрд╛ рд░рдЪрдирд╛рддреНрдордХ рдХрд╛рдо рдФрд░ рд╕рд╛рдХрдЪреА рддрддреНрд╡реЛрдВ рдХреА рдПрдХ рд╡рд┐рд╢рд╛рд▓ рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рднрд░рдиреЗ рдХрд╛ рдХрд╛рдоред рдпрд╣ рд╣рдорд╛рд░реА рдкреВрд░реА рдЙрдкрд▓рдмреНрдзрд┐ рдкреНрд░рдгрд╛рд▓реА рдХрд╛ рджрд┐рд▓ рд╣реИред рдпрд╣рд╛рдБ рдЗрд╕рд╕реЗ рдХреБрдЫ рдкрдВрдХреНрддрд┐рдпрд╛рдБ рд╣реИрдВ:

 static sAchievement Achievements[] = { { LA_SUPPORTER, false, "Supporter", "Purchased Linderdaum Puzzle HD", &Check_Supporter, L_VIS, NULL }, { LA_REVIEWER, false, "Reviewer", "Added a review on Google Play", &Check_Reviewer, L_VIS, NULL }, { LA_MONTHLING, false, "Month's campaign", "Used the game for one month", &Check_Monthling, L_VIS, "%s days", &Get_DaysSinceFirstUse, true }, { LA_CASUAL, false, "Casual", "Spent half an hour in game", &Check_Casual, L_VIS, "%s minutes", &Get_MinutesInGame, false }, { LA_ENTHUSIAST, false, "Enthusiast", "Spent 2 hours in game", &Check_Enthusiast, L_VIS, "%s minutes", &Get_MinutesInGame, false }, { LA_FANATIC, true, "Fanatic", "Spent 10 hours in game", &Check_Fanatic, L_VIS, "%s hours", &Get_HoursInGame, false }, // ... // -  ,    } 


Check_ * рдлрд╝рдВрдХреНрд╢рди "рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЕрдиреБрдХреНрд░рдо" рдкреНрд░рдХрд╛рд░ рдХреА рдЙрдкрд▓рдмреНрдзрд┐рдпреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢рд░реНрддреЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рд╕рдорд╛рд░реЛрд╣ рдХреА рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рд╛рдордЧреНрд░реА:

 bool Check_Monthling() { LDate FirstRun = LDate( FirstRunDate.GetString() ); LDate Today; int Days = Today-FirstRun; return Days >= 30; } 


рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ "рдПрдХрд▓ рдШрдЯрдирд╛" рдкреНрд░рдХрд╛рд░ рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП, рдРрд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдФрд░ рдЙрдирдХреЗ рд▓рд┐рдП рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ NULL рд╣реИред рдкреБрд░рд╕реНрдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдХрддрд╛рд░ рдореЗрдВ рдРрд╕реА рдЙрдкрд▓рдмреНрдзрд┐рдпрд╛рдВ рд▓рд╛рдирд╛ рд╕реАрдзреЗ рдЦреЗрд▓ рдХреЛрдб рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

 if ( Time < 5.0 ) g_Achievements->Award( LA_BLINKOFANEYE ); 


рдЖрдкрдиреЗ рд╢рд╛рдпрдж рдпрд╣ рднреА рджреЗрдЦрд╛ рдХрд┐ FProgressNote рдФрд░ FNoteProc рд╣реИрдВ ред рдЖрдк рд╕рд┐рд░реНрдл рдПрдХ FNoteProc рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд░ рд╕рдХреЗ рдФрд░ рддреБрд░рдВрдд рдПрдХ рд╡рд╛рдХреНрдпрд╛рдВрд╢ рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИред рд╡рд░реНрддрдорд╛рди рднрд╛рд╖рд╛ рдореЗрдВ рд╡рд╛рдХреНрдпрд╛рдВрд╢ рдХреЛ рд╕реНрдерд╛рдиреАрдп рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдПред рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕реНрдерд╛рдиреАрдпрдХреГрдд рд╣реИ, рдФрд░ рдлрд┐рд░ рдЙрд╕рдореЗрдВ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ-рд╕рдВрдЦреНрдпрд╛ рджреА рдЧрдИ рд╣реИ, рдЬрд┐рд╕реЗ FNoteProc рд╕реЗ рд▓реМрдЯрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ ред

рдЕрдм рд╕рдм рдХреБрдЫ рд╕реНрдерд┐рд░ рдбреЗрдЯрд╛ рдореЗрдВ рдЬреАрд╡рди рд╕рд╛рдБрд╕ рд▓реЗрдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдереЛрдбрд╝рд╛ рдФрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╣рдореЗрдВ рдЕрдЪреАрд╡рдореЗрдВрдЯ рдореИрдиреЗрдЬрд░ рдФрд░ рдЕрдЪреАрд╡рдореЗрдВрдЯ рдХреЗ рд▓рд┐рдП UI рдореИрдиреЗрдЬрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рд╡реЗ рдХреНрдпрд╛ рдХрд░рддреЗ рд╣реИрдВред

 class clAchievementsManager: public iObject { public: //    // // clAchievementsManager // /// trigger the award for a one-time achievement virtual void Award( LAchievement Achievement ); virtual void AwardName( const LString& AchievementName ); virtual bool IsAwarded( LAchievement Achievement ) const; /// called automatically every 6 seconds or so to check new achievements virtual void ProcessAchievements(); virtual void RecheckAchievements(); //     -     public: std::deque<LAchievement> FPendingAwards; iGUIView* FAchievementsText; mlNode* FNode_Awarded; }; 


ProcessAchievements () рд╣рд░ 6 рд╕реЗрдХрдВрдб рдореЗрдВ рдПрдХ рдмрд╛рд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рд╣рд╛рдереА рдкрджрдХ рд╡рд┐рддрд░рд┐рдд рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдЗрд╕ рддрд░рд╣ рдХреА рдХреЙрд▓ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

 Env->SendAsyncCapsule( BindCapsule( &clAchievementsManager::ProcessAchievements, this ), 6.0 ); 


рдЕрдВрджрд░, рдЗрд╕ рдХреЛрдб рдХреА рддрд░рд╣ рдХреБрдЫ (рдереЛрдбрд╝рд╛ рддрд▓реЗ рд╣реБрдП):

 void clAchievementsManager::ProcessAchievements() { // save gamestate // ... RecheckAchievements(); // check achievements once in a while Env->SendAsyncCapsule( BindCapsule( &clAchievementsManager::ProcessAchievements, this ), 6.0 ); // nothing new to award if ( FPendingAwards.empty() ) return; LAchievement A = FPendingAwards.front(); FPendingAwards.pop_front(); // this achievement had been awarded long time ago if ( Achievements[ A ].FAwarded->GetBool() ) return; Achievements[ A ].FAwarded->SetBool( true ); // don't lose achievements in case of crash g_Game->SaveAchievements( g_SaveAchievementsFileName ); // show nice message here Env->Renderer->GetCanvas()->AnnounceObject( Construct<clAchievementAnnouncer>( Env, A, FNode_Awarded ), 0.0, 5.0 ); clPuzzl_AchievementsContainer* C = Env->GUI->FindView<clPuzzl_AchievementsContainer>("AchievementsContainer"); // update UI if ( C ) C->RecreateSubViews(); } 


рдХреБрдЫ рднреА рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реИред рдХреЗрд╡рд▓ рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреА рдЬрд╛рдБрдЪ рдХрд░рдирд╛ рдФрд░ "рдЗрд╡реЗрдВрдЯ" рдкреНрд░рдХрд╛рд░ рдХреА рдЙрдкрд▓рдмреНрдзрд┐рдпреЛрдВ рдХреЛ рдЙрд╕ рдХрддрд╛рд░ рд╕реЗ рдЯрд╛рдЗрдк рдХрд░рдирд╛ рдЬрд┐рд╕рдореЗрдВ рдкреБрд░рд╕реНрдХрд╛рд░ () рд╡рд┐рдзрд┐ рдЗрд╕реЗ рдбрд╛рд▓рддреА рд╣реИред ClAchievementAnnouncer рдХреНрд▓рд╛рд╕ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдкреВрд░реЗ UI рдХреЗ рдКрдкрд░ рдПрдХ рд╕реБрдВрджрд░ рдкреНрд▓реЗрдЯ рдЦреАрдВрдЪрддреА рд╣реИ:

рдЫрд╡рд┐

рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЦреЗрд▓ рдХреЛ рд╣рд░ 6 рд╕реЗрдХрдВрдб рдореЗрдВ рд╕рд╣реЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИ - рд╣рдо рдирд╣реАрдВ рдЪрд╛рд╣рддреЗ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдкрдиреА рдкреНрд░рдЧрддрд┐ рдЦреЛ рджреЗред

RecheckAchievements () рд╡рд┐рдзрд┐ UI рдХреЛ рд╕рднреА рдЙрдкрд▓рдмреНрдзрд┐рдпреЛрдВ рдХреА рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд╕рд╛рде рдЕрдкрдбреЗрдЯ рдХрд░рддреА рд╣реИ, рдЬреЛ рдкрд╣рд▓реЗ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рдореЗрдВ рдереАред UI рд╕реАрдзреЗ clPuzzl_AchievementsContainer рд╡рд░реНрдЧ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдЖрдкрдХреЗ UI рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдмрд╣реБрдд рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╣реЛрдЧрд╛ред рд╣рдорд╛рд░реЗ рд╕рд╛рде, рд╡рд╣ рдХреЗрд╡рд▓ рдкреНрдпрд╛рд▓реЛрдВ рдХреЛ рдкреНрдпрд╛рд▓реЛрдВ рд╕реЗ рднрд░рддрд╛ рд╣реИ (рдлрд┐рд░ рд╕реЗ, рдкрд╣рд▓реЗ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рджреЗрдЦреЗрдВ)ред

рд╢рд╡рдкрд░реАрдХреНрд╖рд╛


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

рдореИрдВ рдЬреЛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдЙрд╕рдХреЗ рдкрд╛рд╕ рд╕рдордп рдирд╣реАрдВ рдерд╛:



PS рдЦреЗрд▓ Linderdaum рдЗрдВрдЬрди рдкрд░ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред

Source: https://habr.com/ru/post/In161949/


All Articles