{"id":410454,"date":"2024-06-29T21:24:28","date_gmt":"2024-06-29T21:24:28","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=410454"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=410454","title":{"rendered":"<span>Blazor: SPA \u0431\u0435\u0437 \u0434\u0436\u0430\u0432\u0430\u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0434\u043b\u044f SaaS \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/81f\/647\/c26\/81f647c26234f3267c1b0ca66bc90928.png\" width=\"812\" height=\"432\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/81f\/647\/c26\/81f647c26234f3267c1b0ca66bc90928.png\"\/><figcaption><\/figcaption><\/figure>\n<p>    \u041a\u043e\u0433\u0434\u0430 \u0432 \u043b\u044e\u0431\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0442\u0430\u043b\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 this&#8230; \u041a\u043e\u0433\u0434\u0430 \u043d\u0435\u044f\u0432\u043d\u043e\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0438\u043f\u043e\u0432 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0431\u044b\u043b\u0438\u043d\u0430\u0445 \u0430\u043a\u0441\u0430\u043a\u0430\u043b\u043e\u0432 \u044d\u043f\u043e\u0445\u0438 \u0437\u0430\u0440\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0432\u0435\u0431\u0430&#8230; \u041a\u043e\u0433\u0434\u0430 \u0443\u043c\u043d\u044b\u0435 \u043a\u043d\u0438\u0436\u043a\u0438 \u043f\u043e Javascript \u043d\u0430\u0448\u043b\u0438 \u0441\u0432\u043e\u0439 \u0431\u0435\u0441\u0441\u043b\u0430\u0432\u043d\u044b\u0439 \u043a\u043e\u043d\u0435\u0446 \u0432 \u043c\u0443\u0441\u043e\u0440\u043a\u0430\u0445&#8230;<\/p>\n<p>    \u0412\u0441\u0451 \u044d\u0442\u043e \u0441\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043a\u043e\u0433\u0434\u0430 \u043c\u0438\u0440 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0430 \u0441\u043f\u0430\u0441 \u041e\u043d.<\/p>\n<p>    \u041d\u0443 \u043b\u0430\u0434\u043d\u043e, \u0441\u0431\u0430\u0432\u0438\u043c \u043e\u0431\u043e\u0440\u043e\u0442\u044b \u0443 \u043d\u0430\u0448\u0435\u0439 \u043c\u0430\u0448\u0438\u043d\u044b \u043f\u0430\u0444\u043e\u0441\u0430.<\/p>\n<p>    \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u0432\u0430\u043c \u0432\u0437\u0433\u043b\u044f\u043d\u0443\u0442\u044c \u043d\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 Blazor \u0432 \u0432\u0435\u0440\u0441\u0438\u0438 .Net 6. \u0412\u043d\u0435\u0437\u0430\u043f\u043d\u043e, \u043f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0433\u043e \u041f\u0440\u0438\u0432\u0435\u0442\u041c\u0438\u0440, \u0430 \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0435 SaaS \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0435 \u043d\u0430 \u0411\u043b\u0435\u0439\u0437\u043e\u0440\u0435, \u043f\u043e\u0449\u0443\u043f\u0430\u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043b\u0443\u0447\u0448\u0435 \u043e\u0446\u0435\u043d\u0438\u0442\u044c: \u0443\u0431\u0438\u0439\u0446\u0430 \u0438\u043b\u0438 \u0447\u0438\u0436\u0438\u043a\u0430 \u0441\u044a\u0435\u043b?<\/p>\n<h2>\u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/h2>\n<p>    \u041c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435-\u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0440\u0435\u043a\u043b\u0430\u043c\u043d\u043e\u0439 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0438 \u0432 \u0441\u043e\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u0438 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435, \u0433\u0434\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0430 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0435\u0442 Blazor \u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435 (WebAssembly). \u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0435 (\u0432\u0441\u0435\u0433\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446), \u0442\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u0432 \u043d\u0451\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b:<\/p>\n<ul>\n<li>\n<p>\u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 (\u0442\u0435\u043d\u0430\u043d\u0442\u044b, \u043f\u0440\u0430\u0432\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430)<\/p>\n<\/li>\n<li>\n<p>\u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0432 \u0444\u043e\u0440\u043c\u0430\u0445 \u0432\u0432\u043e\u0434\u0430<\/p>\n<\/li>\n<li>\n<p>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c\u0438 Javascript-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u044b\u0445 API (\u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, Page Visibility API)<\/p>\n<\/li>\n<\/ul>\n<p>    \u0420\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0435\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0437\u0434\u0435\u0441\u044c: <a href=\"https:\/\/app.venando.ru\" rel=\"noopener noreferrer nofollow\">https:\/\/app.venando.ru<\/a><\/p>\n<p>    \u0414\u043b\u044f \u043b\u044e\u0431\u0438\u0442\u0435\u043b\u0435\u0439 \u043e\u0431\u043c\u0430\u0437\u0430\u0442\u044c\u0441\u044f, \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0437\u0434\u0435\u0441\u044c: <a href=\"https:\/\/github.com\/a-postx\/YA.BlazorVkParser\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/a-postx\/YA.BlazorVkParser<\/a><\/p>\n<p>    \u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u043f\u0440\u0435\u043f\u0430\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e.<\/p>\n<h2>\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b<\/h2>\n<p>    \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f WebAssembly (WASM) \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u0432, \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0435\u0451 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u043a\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043a\u0440\u043e\u043c\u043d\u0430\u044f. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 Blazor, \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u0433\u043b\u0430\u0432\u043d\u044b\u0445 \u0442\u043e\u0440\u043c\u043e\u0437\u043e\u0432 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0441\u043a\u0443\u0434\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u041d\u043e \u0441\u0435\u0433\u043e\u0434\u043d\u044f (\u043a\u043e\u043d\u0435\u0446 2021-\u0433\u043e \u0433\u043e\u0434\u0430) \u043d\u0430 \u0440\u044b\u043d\u043a\u0435 \u0434\u0430\u0436\u0435 \u0441\u0443\u0433\u0443\u0431\u043e \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0443\u0436\u0435 \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u0432\u044b\u0431\u043e\u0440.<\/p>\n<p>    \u041c\u044b \u0432 \u0441\u0432\u043e\u0451\u043c WASM-\u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u0440\u0430\u0437\u0432\u0438\u0442\u044b\u0445 \u043d\u0430\u0431\u043e\u0440\u043e\u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u0441\u0442\u0435\u043a\u0443 &#8212; <a href=\"https:\/\/blazorise.com\" rel=\"noopener noreferrer nofollow\">Blazorise<\/a>. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0443\u0436\u0435 \u043f\u043e\u0434 \u0441\u0432\u043e\u0438 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043d\u0443\u0436\u0434\u044b \u0438 \u044d\u0442\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0431\u0443\u0434\u0443\u0442 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f, \u0435\u0441\u043b\u0438 \u0432\u044b \u0440\u0435\u0448\u0438\u0442\u0435 \u0441\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u0438\u0437\u0443\u0430\u043b, \u0441\u043a\u0430\u0436\u0435\u043c, \u0441 Bootstrap \u043d\u0430 Material.<\/p>\n<p>    \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0434\u0438\u0430\u043b\u043e\u0433\u043e\u0432\u043e\u0435 \u043e\u043a\u043d\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0432 \u0441\u0430\u043c\u044b\u0445 \u0440\u0430\u0437\u043d\u044b\u0445 \u043c\u0435\u0441\u0442\u0430\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0411\u043b\u0435\u0439\u0437\u043e\u0440\u0430\u0439\u0441\u0430 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u0430\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442<\/p>\n<pre><code class=\"cs\">@using System.ComponentModel @using YA.WebClient.Application.Interfaces  @inject IJSRuntime JS @inject IThemeOptionsState ThemeOptions  &lt;Modal @ref=\"_modal\" Closing=\"@OnModalClosing\" ShowBackdrop=\"true\">     &lt;ModalContent Centered=\"true\" Size=\"ModalSize.Default\" Class=\"@ThemeOptions.ModalContentClass\">         &lt;ModalBody MaxHeight=\"65\">             &lt;Field>                 @MessageText             &lt;\/Field>         &lt;\/ModalBody>         &lt;ModalFooter>             &lt;Button Color=\"Color.Primary\" Block=\"false\" Clicked=\"@(() => Confirm())\">                 \u0414\u0430             &lt;\/Button>             &lt;Button Color=\"Color.Secondary\" Block=\"false\" Clicked=\"@(() => Hide())\">                 \u041e\u0442\u043c\u0435\u043d\u0430             &lt;\/Button>         &lt;\/ModalFooter>     &lt;\/ModalContent> &lt;\/Modal>   @code {     [Parameter]     public string MessageText { get; set; }     [Parameter]     public EventCallback&lt;string> MessageTextChanged { get; set; }      [Parameter]     public Action OnYesAction { get; set; }     [Parameter]     public EventCallback&lt;Action> OnYesActionChanged { get; set; }      \/\/ \u0435\u0441\u043b\u0438 \u0443\u0436\u0435 \u043e\u0442\u043a\u0440\u044b\u0442\u043e, \u0442\u043e \u0432\u044b\u043f\u0430\u0434\u0430\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u0443\u0435\u043c \u044d\u0442\u043e \u043d\u0430 \u043d\u0430\u0448\u0435\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u0435     public bool IsShowing { get; set; }      private Modal _modal;      public void Show()     {         if (!IsShowing)         {             _modal.Show();             IsShowing = true;         }     }      public void Hide()     {         if (IsShowing)         {             _modal.Hide();         }     }      private void Confirm()     {         Hide();         OnYesAction?.Invoke();     }      private void OnModalClosing(CancelEventArgs e)     {         IsShowing = false;     } }<\/code><\/pre>\n<p>    \u0418 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0435\u0433\u043e \u0432\u043e \u0432\u0441\u0435\u0445 \u043d\u0443\u0436\u043d\u044b\u0445 \u043c\u0435\u0441\u0442\u0430\u0445, \u0437\u0430\u0434\u0430\u0432 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0443 \u043a \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043a\u043e\u043b\u0431\u0435\u043a\u0430\u043c.<\/p>\n<pre><code class=\"cs\">&lt;ActionConfirmationModal @ref=\"_confirmationModal\"             @bind-OnYesAction=\"_confirmationAction\"             @bind-MessageText=\"_confirmationText\" \/>  @code {   private ActionConfirmationModal _confirmationModal;     private string _confirmationText = string.Empty;     private Action _confirmationAction = () => Empty();          private void ShowInvitationDeletionConfirmation(InvitationVm invitation)     {         _confirmationAction = async () => await DeleteInvitation(invitation.YaInvitationID);         _confirmationText = $\"\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0440\u0438\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u0435 \u0432 \u0430\u043a\u043a\u0430\u0443\u043d\u0442 \u0434\u043b\u044f {invitation.Email}?\";          _confirmationModal.Show();     }      private void ShowMembershipDeletionConfirmation(MembershipVm membership)     {         _confirmationAction = async () => await DeleteMembership(membership.MembershipID);         _confirmationText = $\"\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f {membership.User?.Email} \u043a \u044d\u0442\u043e\u043c\u0443 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0443?\";          _confirmationModal.Show();     } }<\/code><\/pre>\n<p>    \u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u044b \u043b\u043e\u0432\u0438\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438\u0437 \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0432 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c.<\/p>\n<p>    \u041a\u0430\u043a \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u043f\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044e \u0432 \u043a\u043e\u0434\u0435, \u0432 Blazorise \u0435\u0449\u0451 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0431\u043e\u043b\u044f\u0447\u0435\u043a, \u043d\u043e \u0441 \u043d\u0438\u043c\u0438 \u0443\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043a\u0430\u043a-\u0442\u043e \u0443\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f.<\/p>\n<p>    \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u0440\u043e\u0434\u0430 \u0431\u043e\u043b\u0435\u0437\u043d\u0438 \u0440\u043e\u0441\u0442\u0430, \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0431\u0443\u0436\u0434\u0430\u0435\u0442 \u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e Blazor \u043a\u0430\u043a \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438, \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u043d\u0430 \u0444\u0440\u043e\u043d\u0442\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u0441\u044f \u043c\u043e\u0449\u044c .Net.<\/p>\n<p>    \u041e\u0431\u0438\u043b\u044c\u043d\u044b\u0439 \u043f\u043e\u0441\u043b\u0443\u0436\u043d\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u0442\u043d\u0435\u0442\u0430 \u0432 \u0431\u0435\u043a\u0435\u043d\u0434\u0435 \u0434\u0430\u0451\u0442 \u0443\u0441\u043b\u043e\u0432\u043d\u043e\u043c\u0443 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0435\u0440\u0443 \u0448\u0438\u0440\u043e\u0447\u0430\u0439\u0448\u0438\u0439 \u043d\u0430\u0431\u043e\u0440 \u0441\u0440\u0435\u0434\u0441\u0442\u0432 \u043f\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044e \u0442\u0435\u0445 \u0438\u043b\u0438 \u0438\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u0432 \u043a\u043e\u0434\u0435, \u043d\u043e \u043a\u043e\u0433\u0434\u0430 \u0434\u0435\u043b\u043e \u0434\u043e\u0445\u043e\u0434\u0438\u0442 \u0434\u043e \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u0432, HTML \u0438 \u043f\u0440\u043e\u0447\u0438\u0445 \u044d\u0442\u0438\u0445 \u0432\u0430\u0448\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0442\u043e \u0442\u0443\u0442 \u0443\u0436\u0435 \u043d\u0435 \u0432\u0441\u0451 \u0442\u0430\u043a \u0440\u0430\u0434\u0443\u0436\u043d\u043e. <\/p>\n<p>    \u0411\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u043e, \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0411\u043b\u0435\u0439\u0437\u043e\u0440\u0430 \u043f\u043e\u043a\u0430 \u043d\u0435 \u0438\u0434\u0451\u0442 \u043d\u0438 \u0432 \u043a\u0430\u043a\u043e\u0435 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0441 \u0434\u0436\u0430\u0432\u0430\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u043e\u0439. \u0425\u043e\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e \u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u043f\u0440\u0438\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u0442 \u0438\u0437 \u043e\u043a\u0440\u0443\u0436\u0430\u044e\u0449\u0435\u0433\u043e \u043c\u0438\u0440\u0430 \u0432\u0441\u0451 \u043d\u043e\u0432\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0438 \u0434\u043e\u0442\u043d\u0435\u0442\u0447\u0438\u043a\u0443 \u0432 \u0434\u0438\u043b\u0435\u043c\u043c\u0435 &#171;\u0432\u0437\u044f\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0438\u0437 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430&#187; \u0438 &#171;\u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u0430\u043c\u043e\u043c\u0443, \u043f\u043e\u0433\u0440\u0443\u0437\u0438\u0432\u0448\u0438\u0441\u044c \u0432 Javascript&#187; \u0432\u0441\u0451 \u043c\u0435\u043d\u044c\u0448\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u0440\u0438\u0431\u0435\u0433\u0430\u0442\u044c \u043a \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c\u0443 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0443, \u043d\u043e \u0434\u043b\u044f \u0441\u043a\u043e\u043b\u044c-\u043b\u0438\u0431\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u0435\u0437 JS \u043d\u0435 \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c.<\/p>\n<p>    \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u0432 \u043f\u0430\u043f\u043a\u0435 js \u043d\u0430\u0448\u0435\u0433\u043e SPA-\u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0432\u0441\u0435\u0433\u043e \u043f\u044f\u0442\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u0438\u0442\u043e\u0433\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0445\u043e\u0436\u0435\u0433\u043e \u043f\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0414\u0436\u0430\u0432\u0430\u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0443\u0436\u0435 <em>\u043f\u043e\u0447\u0442\u0438<\/em> \u043d\u0435 \u043d\u0443\u0436\u043d\u043e. \u0412 \u043a\u043e\u0438-\u0442\u043e \u0432\u0435\u043a\u0435 \u043a\u043b\u0438\u043a\u0431\u0435\u0439\u0442\u043d\u044b\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u043f\u0440\u0430\u0432\u0434\u043e\u0439.<\/p>\n<h2>\u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f<\/h2>\n<p>    \u0412 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. \u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435 (App.razor) \u043e\u0431\u0440\u0430\u043c\u0438\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 CascadingAuthenticationState, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043d\u0430 \u043b\u044e\u0431\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 (\u0438\u043b\u0438 \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435) \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0440\u043e\u0431\u0440\u043e\u0441\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 AuthenticationState<\/p>\n<pre><code>@code {     [CascadingParameter]     public Task&lt;AuthenticationState> AuthState { get; set; } }<\/code><\/pre>\n<p>    \u0412\u0430\u043c \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442 [Authorize] \u0432 \u0444\u0430\u0439\u043b\u0435 _Imports.razor \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043a\u0440\u044b\u0442\u044c \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a\u043e \u0432\u0441\u0435\u043c \u043d\u0438\u0436\u0435\u043b\u0435\u0436\u0430\u0449\u0438\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c. \u041c\u043e\u0436\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0442\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435, \u0435\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0431\u0443\u0434\u0443\u0442 \u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0434\u043b\u044f \u0430\u043d\u043e\u043d\u0438\u043c\u0443\u0441\u043e\u0432.<\/p>\n<p>    \u0421\u0430\u043c\u0430 \u043f\u043e \u0441\u0435\u0431\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432 Blazor \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0438 \u043c\u043d\u043e\u0433\u043e \u0433\u0434\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0430. \u0412 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0430 \u043c\u044b \u0432\u044b\u0431\u0440\u0430\u043b\u0438 Auth0, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0435 \u0431\u044b\u043b\u043e \u0436\u0435\u043b\u0430\u043d\u0438\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043d\u044e\u0430\u043d\u0441 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 Auth0 &#8212; \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u044e \u0432\u0430\u0448\u0435\u0433\u043e \u0431\u0435\u043a\u0435\u043d\u0434-\u0410\u041f\u0418 \u0432 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0435 AdditionalProviderParameters. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u0442\u043e \u0432\u043c\u0435\u0441\u0442\u043e JWT-\u0442\u043e\u043a\u0435\u043d\u0430 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u0442\u043e\u043a\u0435\u043d \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0430 Auth0, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0430 \u0432\u0430\u0448\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0443\u0436\u0435 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f.<\/p>\n<pre><code class=\"json\">\"OauthOptions\": {     \"Authority\": \"https:\/\/yaapp-80.eu.auth0.com\",     \"ClientId\": \"OYXLTT9VPs2Ll6w0e6tOI3g4RAT3fZNS\",     \"MetadataUrl\": \"https:\/\/yaapp-80.eu.auth0.com\/.well-known\/openid-configuration\",     \"RedirectUri\": \"https:\/\/app.venando.ru\/authentication\/login-callback\",     \"AdditionalProviderParameters\": {       \"audience\": \"https:\/\/yaapp-prod.ru\"     } }<\/code><\/pre>\n<h2>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435<\/h2>\n<p>    \u0421\u0435\u0440\u0432\u0438\u0441\u044b \u0432 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u0435\u0441\u0441\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u044b\u0435, \u043d\u043e \u0432\u043e \u0444\u0440\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0431\u0435\u0437 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043d\u0435 \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a\u043e\u0439 \u0442\u0430\u0440\u0438\u0444\u043d\u044b\u0439 \u043f\u043b\u0430\u043d \u0443 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u0442\u0435\u043d\u0430\u043d\u0442\u0435 \u0438\u043b\u0438 \u043a\u0430\u043a\u0443\u044e \u0442\u0435\u043c\u0443 \u043e\u043d \u0441\u0435\u0439\u0447\u0430\u0441 \u0432\u044b\u0431\u0440\u0430\u043b \u0434\u043b\u044f \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<p>    \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438\u0437 \u0440\u0430\u0437\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u043c\u044b \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0441\u0438\u043d\u0433\u043b\u0442\u043e\u043d\u043e\u043c, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0438 \u0441\u0442\u0430\u043b\u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e.<\/p>\n<pre><code class=\"cs\">public class RuntimeState : IRuntimeState {     public RuntimeState()     {      }      public event EventHandler&lt;TenantUpdatedEventArgs> TenantUpdated;      private TenantVm _tenant;      private TenantVm Tenant     {         get         {             return _tenant;         }                  set         {             if (value != _tenant)             {                 _tenant = value;                 NotifyTenantUpdated(value);             }         }     }          private void NotifyTenantUpdated(TenantVm tenant)     {         TenantUpdated?.Invoke(this, new TenantUpdatedEventArgs { Tenant = tenant });     }      public TenantVm GetTenant() => Tenant;     public void PutTenant(TenantVm tenant)     {         Tenant = tenant;     }     public void RemoveTenant()     {         Tenant = null;     } }<\/code><\/pre>\n<p>    \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043c\u043e\u0434\u0435\u043b\u044c \u0430\u0440\u0435\u043d\u0434\u0430\u0442\u043e\u0440\u0430, \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 TenantUpdated \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0443\u044e \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u043b\u043e\u0433\u0438\u043a\u0443.<\/p>\n<p>    \u041f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0440\u0430\u0437\u0432\u0435\u0441\u0438\u0441\u0442\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435? \u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0442\u043e\u0433\u0434\u0430 \u0432\u0430\u043c \u0432 \u043f\u043e\u043c\u043e\u0449\u044c \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0434\u0443\u043a\u0441-\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f &#8212; \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u043e\u0435\u043a\u0442 <a href=\"https:\/\/github.com\/mrpmorris\/Fluxor\" rel=\"noopener noreferrer nofollow\">Fluxor<\/a>.  <\/p>\n<h2>\u041c\u0443\u043b\u044c\u0442\u0438\u0442\u0435\u043d\u0430\u043d\u0442<\/h2>\n<p>    \u041a\u043e\u0433\u0434\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u0434\u0435\u043b\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043e\u0442 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043e\u043d \u043e\u043f\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438, \u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u043b\u043e\u0439 \u0442\u0435\u043d\u0430\u043d\u0442\u0430. \u0420\u0430\u0431\u043e\u0442\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0433\u043e &#171;\u0430\u0440\u0435\u043d\u0434\u0430\u0442\u043e\u0440\u0430&#187; \u0442\u0430\u043a\u0436\u0435 \u0434\u0430\u0441\u0442 \u0438\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0448\u0430\u0440\u0438\u0442\u044c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439, \u0447\u0442\u043e \u0432\u0435\u0441\u044c\u043c\u0430 \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0430\u0441\u0442\u043e\u0439 \u0444\u0438\u0448\u043a\u043e\u0439 \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0445 \u0442\u0430\u0440\u0438\u0444\u043d\u044b\u0445 \u043f\u043b\u0430\u043d\u043e\u0432 SaaS-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432.<\/p>\n<p>    \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043d\u0430 \u0431\u0435\u043a\u0435\u043d\u0434\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 JWT-\u0442\u043e\u043a\u0435\u043d\u044b, \u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0448\u0430\u0433 \u043f\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u0430\u0440\u0435\u043d\u0434\u0430\u0442\u043e\u0440\u0430 \u043f\u0440\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f: \u043a\u043b\u0438\u0435\u043d\u0442 \u0434\u0451\u0440\u0433\u0430\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043f\u0435\u0440\u0435\u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0442\u043e\u043a\u0435\u043d.<\/p>\n<p>    \u041d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430\u044f \u0434\u0438\u043b\u0435\u043c\u043c\u0430 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0442\u0435\u043d\u0430\u043d\u0442\u0430\u043c\u0438: \u0432 \u0411\u043b\u0435\u0439\u0437\u043e\u0440\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0443\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u0435\u043d\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0430\u0440\u0435\u043d\u0434\u0430\u0442\u043e\u0440\u0430 \u0438\u043b\u0438 \u043b\u044e\u0431\u044b\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b.<\/p>\n<pre><code class=\"cs\">public class CustomUserFactory : AccountClaimsPrincipalFactory&lt;CustomUserAccount> {     public CustomUserFactory(IAccessTokenProviderAccessor accessor) : base(accessor)     {         _tokenProviderAccessor = accessor;     }      private readonly IAccessTokenProviderAccessor _tokenProviderAccessor;     private readonly JsonSerializerOptions _serializerOptions = new() { PropertyNameCaseInsensitive = true };      public override async ValueTask&lt;ClaimsPrincipal> CreateUserAsync(CustomUserAccount account, RemoteAuthenticationUserOptions options)     {         ClaimsPrincipal user = await base.CreateUserAsync(account, options);          if (user.Identity.IsAuthenticated)         {             ClaimsIdentity identity = (ClaimsIdentity)user.Identity;              AccessTokenResult tokenResult = await _tokenProviderAccessor.TokenProvider.RequestAccessToken();              if (tokenResult.TryGetToken(out AccessToken token))             {                 JwtSecurityTokenHandler handler = new();                 SecurityToken jsonToken = handler.ReadToken(token.Value);                 JwtSecurityToken tokenS = jsonToken as JwtSecurityToken;                  Claim metadataClaim = tokenS.Claims.FirstOrDefault(e => e.Type == \"http:\/\/yaapp.app_metadata\");                  if (metadataClaim != null)                 {                     AppMetadata appMetadata = JsonSerializer                         .Deserialize&lt;AppMetadata>(metadataClaim.Value, _serializerOptions);                      if (!string.IsNullOrEmpty(appMetadata.Tid))                     {                         identity.AddClaim(new Claim(\"tid\", appMetadata.Tid));                     }                 }             }         }          return user;     } }<\/code><\/pre>\n<p>    \u041e\u0434\u043d\u0430\u043a\u043e \u044d\u0442\u043e\u0442 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u0441\u043c\u0435\u043d\u0435 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f (\u043d\u0430\u043f\u0440. \u0441 \u041d\u0435\u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d \u043d\u0430 \u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0442\u0435\u043d\u0430\u043d\u0442\u0430\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u0432\u044b\u0445\u043e\u0434\u0430-\u0432\u0445\u043e\u0434\u0430, \u0447\u0442\u043e \u0443\u0445\u0443\u0434\u0448\u0430\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u043e\u043f\u044b\u0442 (\u0432 \u0441\u043b\u0443\u0447\u0430\u0435 OAuth \u0446\u0438\u043a\u043b \u043d\u0435 \u0442\u0430\u043a\u043e\u0439 \u0443\u0436 \u0431\u044b\u0441\u0442\u0440\u044b\u0439).<\/p>\n<p>    \u0412\u0432\u0438\u0434\u0443 \u044d\u0442\u043e\u0439 \u043f\u0435\u0447\u0430\u043b\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0430\u0440\u0435\u043d\u0434\u0430\u0442\u043e\u0440\u0430\u043c\u0438 \u0431\u044b\u043b\u043e \u0440\u0435\u0448\u0435\u043d\u043e \u043e\u0442\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430 \u0443\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u0435\u043d\u0438\u0439 &#8212; \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0442\u0435\u043d\u0430\u043d\u0442\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0442\u0430\u043b \u0447\u0430\u0441\u0442\u044c\u044e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0447\u0442\u043e \u0434\u0430\u043b\u043e \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u043d\u0430\u0434 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u043e\u043c \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 \u043a\u043e\u0440\u043d\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (App.razor) \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 UserAndTenantManager, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043c\u043e\u0436\u0435\u0442 \u0447\u0442\u043e-\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438.<\/p>\n<pre><code class=\"cs\">&lt;CascadingAuthenticationState>     &lt;Blazorise.ThemeProvider Theme=\"@_theme\" WriteVariables=\"true\">         @* \u044d\u0442\u0430\u043f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u0430\u0440\u0435\u043d\u0434\u0430\u0442\u043e\u0440\u0430, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f.         \u0418\u0437-\u0437\u0430 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0435\u0449\u0451 \u0434\u043e \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u043b\u043e\u0433\u0438\u043d\u0430,         \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 *@         &lt;UserAndTenantManager>             &lt;Router AppAssembly=\"@typeof(Program).Assembly\" PreferExactMatches=\"@true\">                 &lt;Found Context=\"routeData\">                     &lt;AuthorizeRouteView RouteData=\"@routeData\" DefaultLayout=\"@typeof(LoadingLayout)\">                         &lt;Authorizing>                             &lt;AuthorizingInProgress \/>                         &lt;\/Authorizing>                         &lt;NotAuthorized>                             @if (context.User.Identity?.IsAuthenticated ?? false)                             {                                 &lt;UserNotAuthorized \/>                             }                             else                             {                                 &lt;RedirectToLogin \/>                             }                         &lt;\/NotAuthorized>                     &lt;\/AuthorizeRouteView>                 &lt;\/Found>                 &lt;NotFound>                     &lt;PageNotFound \/>                 &lt;\/NotFound>             &lt;\/Router>         &lt;\/UserAndTenantManager>         &lt;ToastContainer \/>     &lt;\/Blazorise.ThemeProvider> &lt;\/CascadingAuthenticationState><\/code><\/pre>\n<h2>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438<\/h2>\n<p>    \u0412 \u043b\u044e\u0431\u043e\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0441\u043a\u043e\u0440\u0435\u0435 \u0440\u0430\u043d\u043e, \u0447\u0435\u043c \u043f\u043e\u0437\u0434\u043d\u043e \u0432\u0441\u0442\u0430\u0451\u0442 \u0432\u043e\u043f\u0440\u043e\u0441 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 JS-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u043f\u0440\u0438\u043a\u0440\u0443\u0442\u0438\u0442\u044c \u0447\u0430\u0442 \u0438 \u043f\u043b\u0435\u0435\u0440 \u042e\u0442\u0443\u0431\u0430.<\/p>\n<p>    \u0421 \u043f\u043b\u0435\u0435\u0440\u043e\u043c \u0432\u0441\u0451 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e, \u0431\u043b\u0430\u0433\u043e \u0432 \u043c\u0438\u0440\u0435 \u0414\u0436\u0430\u0432\u0430\u0441\u043a\u0440\u0438\u043f\u0442 \u0435\u0441\u0442\u044c <a href=\"https:\/\/github.com\/videojs\/video.js\" rel=\"noopener noreferrer nofollow\">VideoJs<\/a>. \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u043a\u0440\u0438\u043f\u0442 \u043f\u043b\u0435\u0435\u0440\u0430, \u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u043a \u043d\u0435\u043c\u0443 \u0438 \u043c\u0430\u0430\u0430\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u0441\u043a\u0440\u0438\u043f\u0442\u0438\u043a<\/p>\n<pre><code class=\"xml\">&lt;script src=\"https:\/\/vjs.zencdn.net\/7.14.3\/video.js\">&lt;\/script> &lt;script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/videojs-youtube\/2.6.1\/Youtube.min.js\">&lt;\/script> &lt;script src=\"js\/videoplayer.js\" asp-append-version=\"true\">&lt;\/script><\/code><\/pre>\n<p>    \u0421\u043a\u0440\u0438\u043f\u0442\u0438\u043a \u043d\u0443\u0436\u0435\u043d \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0437\u0430\u043f\u0443\u0441\u043a \u043f\u043b\u0435\u0435\u0440\u0430 \u0438\u0437 Blazor \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0430 \u0432\u043e\u0442 \u0438\u0437 JS &#8212; \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 (\u043d\u0435 \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0439\u0442\u0435 \u043c\u0435\u043d\u044f \u043f\u043e\u0447\u0435\u043c\u0443).<\/p>\n<p>    \u0417\u0430\u0442\u0435\u043c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043f\u043b\u0435\u0435\u0440\u0430 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0432 \u043d\u0435\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b.<\/p>\n<pre><code class=\"cs\">&lt;div class=\"row align-items-center\">     &lt;div class=\"col-8\">         &lt;video id=\"@_playerId\" controls class=\"video-js\">&lt;\/video>     &lt;\/div> &lt;\/div>   @code {     private string _playerId;      protected override void OnInitialized()     {         _playerId = \"home-player\";          base.OnInitialized();     }      protected override async Task OnAfterRenderAsync(bool firstRender)     {         await JS.InvokeVoidAsync(\"loadPlayer\", _playerId, new         {             controls = true,             autoplay = false,             preload = \"auto\",             width = 640,             height = 360,             techOrder = new[] { \"youtube\" },             sources = new[] {                 new { type = \"video\/youtube\", src = \"https:\/\/www.youtube.com\/watch?v=YhrzIDkNYPk\" }             },             youtube = new { ytControls = 2 }         });          await base.OnAfterRenderAsync(firstRender);     } }<\/code><\/pre>\n<p>    \u042d\u0442\u043e \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u043c\u0430\u043b\u043e \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u0434, \u043d\u043e \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0442\u043e \u0435\u0441\u0442\u044c.<\/p>\n<p>    \u0421 \u0447\u0430\u0442\u043e\u043c \u043f\u043e\u0432\u043e\u0437\u0438\u0442\u044c\u0441\u044f \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043f\u043e\u0431\u043e\u043b\u044c\u0448\u0435, \u043d\u043e \u0432 \u0438\u0442\u043e\u0433\u0435 \u0438 \u043e\u043d \u0431\u044b\u043b \u043f\u043e\u0431\u0435\u0436\u0434\u0451\u043d. \u0421\u0440\u0435\u0434\u0438 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043e\u043a \u0432\u044b\u0431\u043e\u0440 \u043f\u0430\u043b \u043d\u0430 <a href=\"https:\/\/chatra.com\/ru\/\" rel=\"noopener noreferrer nofollow\">\u0427\u0430\u0442\u0440\u0443<\/a>. \u0414\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0447\u0430\u0442\u0430 \u0432 \u043d\u0430\u0448\u0435 Blazor-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043c\u044b \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0445 \u0441\u043a\u0440\u0438\u043f\u0442.<\/p>\n<pre><code class=\"xml\">&lt;script>         window.ChatraSetup = {             startHidden: true         };         (function (d, w, c) {             w.ChatraID = '9Fff8PkPWdEwP6fAG';             var s = d.createElement('script');             w[c] = w[c] || function () {                 (w[c].q = w[c].q || []).push(arguments);             };             s.async = true;             s.src = 'https:\/\/call.chatra.io\/chatra.js';             if (d.head) d.head.appendChild(s);         })(document, window, 'Chatra');     &lt;\/script><\/code><\/pre>\n<p>    \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0441\u043a\u0440\u044b\u0442\u044b\u0439 \u0432\u0438\u0434\u0436\u0435\u0442 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435. \u041c\u044b \u043d\u0435 \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u0447\u0430\u0442 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u043b\u0441\u044f \u043d\u0435 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c, \u043d\u043e \u043f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 index.html \u0432\u0441\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u043e\u0442\u0442\u0443\u0434\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044f \u043d\u0430\u0448 \u0447\u0430\u0442 \u0435\u0449\u0451 \u0434\u043e \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0441\u044f WASM. \u041f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043c\u044b \u0441\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u0432\u0438\u0434\u0436\u0435\u0442, \u0430 \u0443\u0436\u0435 \u043f\u043e\u0441\u043b\u0435 \u0432\u0445\u043e\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438\u0437 C# \u043c\u044b \u0434\u0451\u0440\u0433\u0430\u0435\u043c \u0437\u0430 \u0440\u0443\u0447\u043a\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0447\u0430\u0442\u043e\u043c.<\/p>\n<pre><code class=\"cs\">@using YA.WebClient.Application.Interfaces @using YA.WebClient.Application.Models.ViewModels @using YA.WebClient.Application.Models.Dto @using YA.WebClient.Extensions @using YA.WebClient.Application.Events  @inject IJSRuntime JS @inject IThemeOptionsState ThemeOptions @inject IRuntimeState RuntimeState  @implements IDisposable  @code {     [CascadingParameter]     public Task&lt;AuthenticationState> AuthState { get; set; }      [CascadingParameter]     public UserAndTenantManager UserManager { get; set; }      private TenantVm _userTenant;      private EventHandler&lt;TenantUpdatedEventArgs> _tenantUpdatedHandler;       protected async override Task OnInitializedAsync()     {         TenantVm tenantVm = UserManager.GetTenant();          if (tenantVm != null)         {             _userTenant = tenantVm;         }          _tenantUpdatedHandler = async (s, args) => await RefreshTenantAsync(args);         RuntimeState.TenantUpdated += _tenantUpdatedHandler;          await ShowSupportChat();          await base.OnInitializedAsync();     }      private async Task RefreshTenantAsync(TenantUpdatedEventArgs args)     {         _userTenant = args.Tenant;         StateHasChanged();          await ShowSupportChat();     }      private async Task ShowSupportChat()     {         SupportChatUserInfo userInfo = new SupportChatUserInfo();          if (_userTenant != null)         {             userInfo.TenantId = _userTenant.TenantId.ToString();             userInfo.\u0422\u0430\u0440\u0438\u0444\u043d\u044b\u0439\u041f\u043b\u0430\u043d = _userTenant.PricingTier?.Title;         }          AuthenticationState authState = await AuthState;          userInfo.name = !string.IsNullOrEmpty(authState?.User?.Identity?.Name)             ? authState?.User?.Identity?.Name             : null;          await JS.InvokeVoidAsync(\"Chatra\", \"setIntegrationData\", userInfo);         await JS.InvokeVoidAsync(\"Chatra\", \"show\");     }      public void Dispose()     {         RuntimeState.TenantUpdated += _tenantUpdatedHandler;     } }<\/code><\/pre>\n<p>    Chatra \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0432\u043e\u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0432 \u0432\u0438\u0434\u0436\u0435\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0442\u0443\u0434\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0430\u0440\u0435\u043d\u0434\u0430\u0442\u043e\u0440\u0430 (\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0435\u0433\u043e, \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u043b\u0441\u044f \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u0442\u0435\u043d\u0430\u043d\u0442) \u0438 \u0435\u0433\u043e \u0442\u0430\u0440\u0438\u0444\u043d\u044b\u0439 \u043f\u043b\u0430\u043d, \u0447\u0442\u043e\u0431\u044b \u0430\u0433\u0435\u043d\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u043d\u0435 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u043b \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e.<\/p>\n<p>    \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0432 Blazor \u0445\u0443\u0434\u043e-\u0431\u0435\u0434\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0438 \u043a\u043e\u0434 \u0441 \u043f\u043e\u043c\u0435\u0442\u043a\u043e\u0439 &#171;\u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f Javascript&#187;, \u0447\u0442\u043e\u0431\u044b \u0431\u0440\u0430\u0442\u044c \u043b\u0443\u0447\u0448\u0435\u0435 \u0438\u0437 \u0434\u0432\u0443\u0445 \u043c\u0438\u0440\u043e\u0432.<\/p>\n<h2>\u0410 \u043f\u043e\u044f\u0441\u043d\u0438 \u0437\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438<\/h2>\n<p>    \u0414\u0435\u043c\u043e-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 <a href=\"https:\/\/app.venando.ru\" rel=\"noopener noreferrer nofollow\">https:\/\/app.venando.ru<\/a> \u043b\u0435\u0436\u0438\u0442 \u0432 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 Azure, \u043f\u043e\u0432\u0435\u0440\u0445 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d CDN \u043e\u0442 \u041c\u0430\u0439\u043a\u0440\u043e\u0441\u043e\u0444\u0442\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e\u0439 \u043a\u0430\u043a \u0432\u043e \u0412\u043b\u0430\u0434\u0438\u0432\u043e\u0441\u0442\u043e\u043a\u0435, \u0442\u0430\u043a \u0438 \u0432 \u041a\u0430\u043b\u0438\u043d\u0438\u043d\u0433\u0440\u0430\u0434\u0435. \u0416\u0435\u043b\u0430\u044e\u0449\u0438\u0435 \u043c\u043e\u0433\u0443\u0442 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0446\u0435\u043d\u0438\u0442\u044c \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u043d\u0435\u0437\u0430\u043f\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043d\u0430 Blazor \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0441\u0442\u0440\u0435\u043c\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u0432\u0430\u0448\u0435\u043c \u043b\u044e\u0431\u0438\u043c\u043e\u043c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0435.<\/p>\n<h2>\u0418\u0442\u043e\u0433\u0438<\/h2>\n<p>    \u0427\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e \u0438\u0442\u043e\u0433\u0430\u043c \u044d\u0442\u043e\u0433\u043e \u043e\u043f\u044b\u0442\u0430: \u043f\u0438\u0441\u0430\u0442\u044c SPA \u043d\u0430 .Net \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u0438\u044f\u0442\u043d\u043e, \u0435\u0433\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0434\u0430\u044e\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0443 \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u0430\u0434\u0451\u0436\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430.<\/p>\n<p>    \u0421\u0430\u043c\u0430\u044f \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0431\u043e\u043b\u044c \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0432 \u0434\u043e\u043b\u0433\u043e\u0439 \u043f\u0435\u0440\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u0434 \u0434\u0435\u0431\u0430\u0433\u043e\u043c. \u0425\u043e\u0440\u043e\u0448\u0430\u044f \u043d\u043e\u0432\u043e\u0441\u0442\u044c \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 .Net 6 \u0438 VS2022 \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0433\u043e\u0440\u044f\u0447\u0430\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0437\u0430\u043c\u0435\u0442\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0430\u0435\u0442 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u043f\u0440\u0438 \u0434\u0435\u0431\u0430\u0433\u0435.<\/p>\n<p>    \u041f\u043b\u043e\u0445\u0430\u044f \u043d\u043e\u0432\u043e\u0441\u0442\u044c \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u043e \u0447\u0430\u0441\u0442\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432\u0441\u0451 \u0435\u0449\u0451 \u0435\u0441\u0442\u044c \u043a\u0443\u0434\u0430 \u0441\u0442\u0440\u0435\u043c\u0438\u0442\u044c\u0441\u044f: \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u0430\u044f AOT-\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0446\u0435\u043d\u043e\u0439 \u0441\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u0434\u0443\u0432\u0430\u043d\u0438\u044f \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0447\u0442\u043e \u0434\u043b\u044f \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0445 \u043e\u0434\u043d\u043e\u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043d\u0438\u043a\u043e\u0432 \u043d\u0435\u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u043e.<\/p>\n<p>    \u0418\u0442\u0430\u043a: \u0443\u0431\u0438\u0439\u0446\u0430? \u041f\u043e\u043a\u0430 \u043d\u0435\u0442, \u043d\u043e \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u0438\u0437 \u0440\u0430\u0437\u0440\u044f\u0434\u0430 &#171;\u0432\u043e\u0442 \u043f\u043e\u0434\u043d\u0430\u0442\u043e\u0440\u0435\u0435\u0442&#8230;&#187;<\/p>\n<p>    \u041f\u0438\u0448\u0438\u0442\u0435 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043b\u043e\u0445 \u0438\u043b\u0438 \u0445\u043e\u0440\u043e\u0448 \u0411\u043b\u0435\u0439\u0437\u043e\u0440, \u043f\u043e\u043f\u043b\u0430\u0447\u0435\u043c\/\u043f\u043e\u0441\u043c\u0435\u0451\u043c\u0441\u044f \u0432\u043c\u0435\u0441\u0442\u0435.<\/p>\n<p>\u041d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u044e: \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0434\u0435\u0442\u0430\u043b\u044c\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u0432 <a href=\"https:\/\/github.com\/a-postx\/YA.BlazorVkParser\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/a-postx\/YA.BlazorVkParser<\/a><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/586130\/\"> https:\/\/habr.com\/ru\/articles\/586130\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>    \u041a\u043e\u0433\u0434\u0430 \u0432 \u043b\u044e\u0431\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0442\u0430\u043b\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 this&#8230; \u041a\u043e\u0433\u0434\u0430 \u043d\u0435\u044f\u0432\u043d\u043e\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0438\u043f\u043e\u0432 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0431\u044b\u043b\u0438\u043d\u0430\u0445 \u0430\u043a\u0441\u0430\u043a\u0430\u043b\u043e\u0432 \u044d\u043f\u043e\u0445\u0438 \u0437\u0430\u0440\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0432\u0435\u0431\u0430&#8230; \u041a\u043e\u0433\u0434\u0430 \u0443\u043c\u043d\u044b\u0435 \u043a\u043d\u0438\u0436\u043a\u0438 \u043f\u043e Javascript \u043d\u0430\u0448\u043b\u0438 \u0441\u0432\u043e\u0439 \u0431\u0435\u0441\u0441\u043b\u0430\u0432\u043d\u044b\u0439 \u043a\u043e\u043d\u0435\u0446 \u0432 \u043c\u0443\u0441\u043e\u0440\u043a\u0430\u0445&#8230;<\/p>\n<p>    \u0412\u0441\u0451 \u044d\u0442\u043e \u0441\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043a\u043e\u0433\u0434\u0430 \u043c\u0438\u0440 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0430 \u0441\u043f\u0430\u0441 \u041e\u043d.<\/p>\n<p>    \u041d\u0443 \u043b\u0430\u0434\u043d\u043e, \u0441\u0431\u0430\u0432\u0438\u043c \u043e\u0431\u043e\u0440\u043e\u0442\u044b \u0443 \u043d\u0430\u0448\u0435\u0439 \u043c\u0430\u0448\u0438\u043d\u044b \u043f\u0430\u0444\u043e\u0441\u0430.<\/p>\n<p>    \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u0432\u0430\u043c \u0432\u0437\u0433\u043b\u044f\u043d\u0443\u0442\u044c \u043d\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 Blazor \u0432 \u0432\u0435\u0440\u0441\u0438\u0438 .Net 6. \u0412\u043d\u0435\u0437\u0430\u043f\u043d\u043e, \u043f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0433\u043e \u041f\u0440\u0438\u0432\u0435\u0442\u041c\u0438\u0440, \u0430 \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0435 SaaS \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0435 \u043d\u0430 \u0411\u043b\u0435\u0439\u0437\u043e\u0440\u0435, \u043f\u043e\u0449\u0443\u043f\u0430\u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043b\u0443\u0447\u0448\u0435 \u043e\u0446\u0435\u043d\u0438\u0442\u044c: \u0443\u0431\u0438\u0439\u0446\u0430 \u0438\u043b\u0438 \u0447\u0438\u0436\u0438\u043a\u0430 \u0441\u044a\u0435\u043b?<\/p>\n<h2>\u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/h2>\n<p>    \u041c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435-\u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0440\u0435\u043a\u043b\u0430\u043c\u043d\u043e\u0439 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0438 \u0432 \u0441\u043e\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u0438 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435, \u0433\u0434\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0430 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0435\u0442 Blazor \u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435 (WebAssembly). \u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0435 (\u0432\u0441\u0435\u0433\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446), \u0442\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u0432 \u043d\u0451\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b:<\/p>\n<ul>\n<li>\n<p>\u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 (\u0442\u0435\u043d\u0430\u043d\u0442\u044b, \u043f\u0440\u0430\u0432\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430)<\/p>\n<\/li>\n<li>\n<p>\u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0432 \u0444\u043e\u0440\u043c\u0430\u0445 \u0432\u0432\u043e\u0434\u0430<\/p>\n<\/li>\n<li>\n<p>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c\u0438 Javascript-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u044b\u0445 API (\u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, Page Visibility API)<\/p>\n<\/li>\n<\/ul>\n<p>    \u0420\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0435\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0437\u0434\u0435\u0441\u044c: <a href=\"https:\/\/app.venando.ru\" rel=\"noopener noreferrer nofollow\">https:\/\/app.venando.ru<\/a><\/p>\n<p>    \u0414\u043b\u044f \u043b\u044e\u0431\u0438\u0442\u0435\u043b\u0435\u0439 \u043e\u0431\u043c\u0430\u0437\u0430\u0442\u044c\u0441\u044f, \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0437\u0434\u0435\u0441\u044c: <a href=\"https:\/\/github.com\/a-postx\/YA.BlazorVkParser\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/a-postx\/YA.BlazorVkParser<\/a><\/p>\n<p>    \u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u043f\u0440\u0435\u043f\u0430\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e.<\/p>\n<h2>\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b<\/h2>\n<p>    \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f WebAssembly (WASM) \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u0432, \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0435\u0451 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u043a\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043a\u0440\u043e\u043c\u043d\u0430\u044f. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 Blazor, \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u0433\u043b\u0430\u0432\u043d\u044b\u0445 \u0442\u043e\u0440\u043c\u043e\u0437\u043e\u0432 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0441\u043a\u0443\u0434\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u041d\u043e \u0441\u0435\u0433\u043e\u0434\u043d\u044f (\u043a\u043e\u043d\u0435\u0446 2021-\u0433\u043e \u0433\u043e\u0434\u0430) \u043d\u0430 \u0440\u044b\u043d\u043a\u0435 \u0434\u0430\u0436\u0435 \u0441\u0443\u0433\u0443\u0431\u043e \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0443\u0436\u0435 \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u0432\u044b\u0431\u043e\u0440.<\/p>\n<p>    \u041c\u044b \u0432 \u0441\u0432\u043e\u0451\u043c WASM-\u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u0440\u0430\u0437\u0432\u0438\u0442\u044b\u0445 \u043d\u0430\u0431\u043e\u0440\u043e\u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u0441\u0442\u0435\u043a\u0443 &#8212; <a href=\"https:\/\/blazorise.com\" rel=\"noopener noreferrer nofollow\">Blazorise<\/a>. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0443\u0436\u0435 \u043f\u043e\u0434 \u0441\u0432\u043e\u0438 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043d\u0443\u0436\u0434\u044b \u0438 \u044d\u0442\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0431\u0443\u0434\u0443\u0442 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f, \u0435\u0441\u043b\u0438 \u0432\u044b \u0440\u0435\u0448\u0438\u0442\u0435 \u0441\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u0438\u0437\u0443\u0430\u043b, \u0441\u043a\u0430\u0436\u0435\u043c, \u0441 Bootstrap \u043d\u0430 Material.<\/p>\n<p>    \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0434\u0438\u0430\u043b\u043e\u0433\u043e\u0432\u043e\u0435 \u043e\u043a\u043d\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0432 \u0441\u0430\u043c\u044b\u0445 \u0440\u0430\u0437\u043d\u044b\u0445 \u043c\u0435\u0441\u0442\u0430\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0411\u043b\u0435\u0439\u0437\u043e\u0440\u0430\u0439\u0441\u0430 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u0430\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442<\/p>\n<pre><code class=\"cs\">@using System.ComponentModel @using YA.WebClient.Application.Interfaces  @inject IJSRuntime JS @inject IThemeOptionsState ThemeOptions  &lt;Modal @ref=\"_modal\" Closing=\"@OnModalClosing\" ShowBackdrop=\"true\">     &lt;ModalContent Centered=\"true\" Size=\"ModalSize.Default\" Class=\"@ThemeOptions.ModalContentClass\">         &lt;ModalBody MaxHeight=\"65\">             &lt;Field>                 @MessageText             &lt;\/Field>         &lt;\/ModalBody>         &lt;ModalFooter>             &lt;Button Color=\"Color.Primary\" Block=\"false\" Clicked=\"@(() => Confirm())\">                 \u0414\u0430             &lt;\/Button>             &lt;Button Color=\"Color.Secondary\" Block=\"false\" Clicked=\"@(() => Hide())\">                 \u041e\u0442\u043c\u0435\u043d\u0430             &lt;\/Button>         &lt;\/ModalFooter>     &lt;\/ModalContent> &lt;\/Modal>   @code {     [Parameter]     public string MessageText { get; set; }     [Parameter]     public EventCallback&lt;string> MessageTextChanged { get; set; }      [Parameter]     public Action OnYesAction { get; set; }     [Parameter]     public EventCallback&lt;Action> OnYesActionChanged { get; set; }      \/\/ \u0435\u0441\u043b\u0438 \u0443\u0436\u0435 \u043e\u0442\u043a\u0440\u044b\u0442\u043e, \u0442\u043e \u0432\u044b\u043f\u0430\u0434\u0430\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u0443\u0435\u043c \u044d\u0442\u043e \u043d\u0430 \u043d\u0430\u0448\u0435\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u0435     public bool IsShowing { get; set; }      private Modal _modal;      public void Show()     {         if (!IsShowing)         {             _modal.Show();             IsShowing = true;         }     }      public void Hide()     {         if (IsShowing)         {             _modal.Hide();         }     }      private void Confirm()     {         Hide();         OnYesAction?.Invoke();     }      private void OnModalClosing(CancelEventArgs e)     {         IsShowing = false;     } }<\/code><\/pre>\n<p>    \u0418 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0435\u0433\u043e \u0432\u043e \u0432\u0441\u0435\u0445 \u043d\u0443\u0436\u043d\u044b\u0445 \u043c\u0435\u0441\u0442\u0430\u0445, \u0437\u0430\u0434\u0430\u0432 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0443 \u043a \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043a\u043e\u043b\u0431\u0435\u043a\u0430\u043c.<\/p>\n<pre><code class=\"cs\">&lt;ActionConfirmationModal @ref=\"_confirmationModal\"             @bind-OnYesAction=\"_confirmationAction\"             @bind-MessageText=\"_confirmationText\" \/>  @code {   private ActionConfirmationModal _confirmationModal;     private string _confirmationText = string.Empty;     private Action _confirmationAction = () => Empty();          private void ShowInvitationDeletionConfirmation(InvitationVm invitation)     {         _confirmationAction = async () => await DeleteInvitation(invitation.YaInvitationID);         _confirmationText = $\"\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0440\u0438\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u0435 \u0432 \u0430\u043a\u043a\u0430\u0443\u043d\u0442 \u0434\u043b\u044f {invitation.Email}?\";          _confirmationModal.Show();     }      private void ShowMembershipDeletionConfirmation(MembershipVm membership)     {         _confirmationAction = async () => await DeleteMembership(membership.MembershipID);         _confirmationText = $\"\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f {membership.User?.Email} \u043a \u044d\u0442\u043e\u043c\u0443 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0443?\";          _confirmationModal.Show();     } }<\/code><\/pre>\n<p>    \u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u044b \u043b\u043e\u0432\u0438\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438\u0437 \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0432 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c.<\/p>\n<p>    \u041a\u0430\u043a \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u043f\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044e \u0432 \u043a\u043e\u0434\u0435, \u0432 Blazorise \u0435\u0449\u0451 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0431\u043e\u043b\u044f\u0447\u0435\u043a, \u043d\u043e \u0441 \u043d\u0438\u043c\u0438 \u0443\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043a\u0430\u043a-\u0442\u043e \u0443\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f.<\/p>\n<p>    \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u0440\u043e\u0434\u0430 \u0431\u043e\u043b\u0435\u0437\u043d\u0438 \u0440\u043e\u0441\u0442\u0430, \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0431\u0443\u0436\u0434\u0430\u0435\u0442 \u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e Blazor \u043a\u0430\u043a \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438, \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u043d\u0430 \u0444\u0440\u043e\u043d\u0442\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u0441\u044f \u043c\u043e\u0449\u044c .Net.<\/p>\n<p>    \u041e\u0431\u0438\u043b\u044c\u043d\u044b\u0439 \u043f\u043e\u0441\u043b\u0443\u0436\u043d\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u0442\u043d\u0435\u0442\u0430 \u0432 \u0431\u0435\u043a\u0435\u043d\u0434\u0435 \u0434\u0430\u0451\u0442 \u0443\u0441\u043b\u043e\u0432\u043d\u043e\u043c\u0443 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0435\u0440\u0443 \u0448\u0438\u0440\u043e\u0447\u0430\u0439\u0448\u0438\u0439 \u043d\u0430\u0431\u043e\u0440 \u0441\u0440\u0435\u0434\u0441\u0442\u0432 \u043f\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044e \u0442\u0435\u0445 \u0438\u043b\u0438 \u0438\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u0432 \u043a\u043e\u0434\u0435, \u043d\u043e \u043a\u043e\u0433\u0434\u0430 \u0434\u0435\u043b\u043e \u0434\u043e\u0445\u043e\u0434\u0438\u0442 \u0434\u043e \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u0432, HTML \u0438 \u043f\u0440\u043e\u0447\u0438\u0445 \u044d\u0442\u0438\u0445 \u0432\u0430\u0448\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0442\u043e \u0442\u0443\u0442 \u0443\u0436\u0435 \u043d\u0435 \u0432\u0441\u0451 \u0442\u0430\u043a \u0440\u0430\u0434\u0443\u0436\u043d\u043e. <\/p>\n<p>    \u0411\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u043e, \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0411\u043b\u0435\u0439\u0437\u043e\u0440\u0430 \u043f\u043e\u043a\u0430 \u043d\u0435 \u0438\u0434\u0451\u0442 \u043d\u0438 \u0432 \u043a\u0430\u043a\u043e\u0435 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0441 \u0434\u0436\u0430\u0432\u0430\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u043e\u0439. \u0425\u043e\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e \u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u043f\u0440\u0438\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u0442 \u0438\u0437 \u043e\u043a\u0440\u0443\u0436\u0430\u044e\u0449\u0435\u0433\u043e \u043c\u0438\u0440\u0430 \u0432\u0441\u0451 \u043d\u043e\u0432\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0438 \u0434\u043e\u0442\u043d\u0435\u0442\u0447\u0438\u043a\u0443 \u0432 \u0434\u0438\u043b\u0435\u043c\u043c\u0435 &#171;\u0432\u0437\u044f\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0438\u0437 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430&#187; \u0438 &#171;\u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u0430\u043c\u043e\u043c\u0443, \u043f\u043e\u0433\u0440\u0443\u0437\u0438\u0432\u0448\u0438\u0441\u044c \u0432 Javascript&#187; \u0432\u0441\u0451 \u043c\u0435\u043d\u044c\u0448\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u0440\u0438\u0431\u0435\u0433\u0430\u0442\u044c \u043a \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c\u0443 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0443, \u043d\u043e \u0434\u043b\u044f \u0441\u043a\u043e\u043b\u044c-\u043b\u0438\u0431\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u0435\u0437 JS \u043d\u0435 \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c.<\/p>\n<p>    \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u0432 \u043f\u0430\u043f\u043a\u0435 js \u043d\u0430\u0448\u0435\u0433\u043e SPA-\u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0432\u0441\u0435\u0433\u043e \u043f\u044f\u0442\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u0438\u0442\u043e\u0433\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0445\u043e\u0436\u0435\u0433\u043e \u043f\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0414\u0436\u0430\u0432\u0430\u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0443\u0436\u0435 <em>\u043f\u043e\u0447\u0442\u0438<\/em> \u043d\u0435 \u043d\u0443\u0436\u043d\u043e. \u0412 \u043a\u043e\u0438-\u0442\u043e \u0432\u0435\u043a\u0435 \u043a\u043b\u0438\u043a\u0431\u0435\u0439\u0442\u043d\u044b\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u043f\u0440\u0430\u0432\u0434\u043e\u0439.<\/p>\n<h2>\u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f<\/h2>\n<p>    \u0412 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. \u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435 (App.razor) \u043e\u0431\u0440\u0430\u043c\u0438\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 CascadingAuthenticationState, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043d\u0430 \u043b\u044e\u0431\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 (\u0438\u043b\u0438 \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435) \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0440\u043e\u0431\u0440\u043e\u0441\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 AuthenticationState<\/p>\n<pre><code>@code {     [CascadingParameter]     public Task&lt;AuthenticationState> AuthState { get; set; } }<\/code><\/pre>\n<p>    \u0412\u0430\u043c \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442 [Authorize] \u0432 \u0444\u0430\u0439\u043b\u0435 _Imports.razor \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043a\u0440\u044b\u0442\u044c \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a\u043e \u0432\u0441\u0435\u043c \u043d\u0438\u0436\u0435\u043b\u0435\u0436\u0430\u0449\u0438\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c. \u041c\u043e\u0436\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0442\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435, \u0435\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0431\u0443\u0434\u0443\u0442 \u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0434\u043b\u044f \u0430\u043d\u043e\u043d\u0438\u043c\u0443\u0441\u043e\u0432.<\/p>\n<p>    \u0421\u0430\u043c\u0430 \u043f\u043e \u0441\u0435\u0431\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432 Blazor \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0438 \u043c\u043d\u043e\u0433\u043e \u0433\u0434\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0430. \u0412 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0430 \u043c\u044b \u0432\u044b\u0431\u0440\u0430\u043b\u0438 Auth0, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0435 \u0431\u044b\u043b\u043e \u0436\u0435\u043b\u0430\u043d\u0438\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043d\u044e\u0430\u043d\u0441 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 Auth0 &#8212; \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u044e \u0432\u0430\u0448\u0435\u0433\u043e \u0431\u0435\u043a\u0435\u043d\u0434-\u0410\u041f\u0418 \u0432 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0435 AdditionalProviderParameters. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u0442\u043e \u0432\u043c\u0435\u0441\u0442\u043e JWT-\u0442\u043e\u043a\u0435\u043d\u0430 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u0442\u043e\u043a\u0435\u043d \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0430 Auth0, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0430 \u0432\u0430\u0448\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0443\u0436\u0435 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f.<\/p>\n<pre><code class=\"json\">\"OauthOptions\": {     \"Authority\": \"https:\/\/yaapp-80.eu.auth0.com\",     \"ClientId\": \"OYXLTT9VPs2Ll6w0e6tOI3g4RAT3fZNS\",     \"MetadataUrl\": \"https:\/\/yaapp-80.eu.auth0.com\/.well-known\/openid-configuration\",     \"RedirectUri\": \"https:\/\/app.venando.ru\/authentication\/login-callback\",     \"AdditionalProviderParameters\": {       \"audience\": \"https:\/\/yaapp-prod.ru\"     } }<\/code><\/pre>\n<h2>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435<\/h2>\n<p>    \u0421\u0435\u0440\u0432\u0438\u0441\u044b \u0432 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u0435\u0441\u0441\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u044b\u0435, \u043d\u043e \u0432\u043e \u0444\u0440\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0431\u0435\u0437 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043d\u0435 \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a\u043e\u0439 \u0442\u0430\u0440\u0438\u0444\u043d\u044b\u0439 \u043f\u043b\u0430\u043d \u0443 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u0442\u0435\u043d\u0430\u043d\u0442\u0435 \u0438\u043b\u0438 \u043a\u0430\u043a\u0443\u044e \u0442\u0435\u043c\u0443 \u043e\u043d \u0441\u0435\u0439\u0447\u0430\u0441 \u0432\u044b\u0431\u0440\u0430\u043b \u0434\u043b\u044f \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<p>    \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438\u0437 \u0440\u0430\u0437\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u043c\u044b \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0441\u0438\u043d\u0433\u043b\u0442\u043e\u043d\u043e\u043c, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0438 \u0441\u0442\u0430\u043b\u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e.<\/p>\n<pre><code class=\"cs\">public class RuntimeState : IRuntimeState {     public RuntimeState()     {      }      public event EventHandler&lt;TenantUpdatedEventArgs> TenantUpdated;      private TenantVm _tenant;      private TenantVm Tenant     {         get         {             return _tenant;         }                  set         {             if (value != _tenant)             {                 _tenant = value;                 NotifyTenantUpdated(value);             }         }     }          private void NotifyTenantUpdated(TenantVm tenant)     {         TenantUpdated?.Invoke(this, new TenantUpdatedEventArgs { Tenant = tenant });     }      public TenantVm GetTenant() => Tenant;     public void PutTenant(TenantVm tenant)     {         Tenant = tenant;     }     public void RemoveTenant()     {         Tenant = null;     } }<\/code><\/pre>\n<p>    \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043c\u043e\u0434\u0435\u043b\u044c \u0430\u0440\u0435\u043d\u0434\u0430\u0442\u043e\u0440\u0430, \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 TenantUpdated \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0443\u044e \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u043b\u043e\u0433\u0438\u043a\u0443.<\/p>\n<p>    \u041f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0440\u0430\u0437\u0432\u0435\u0441\u0438\u0441\u0442\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435? \u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0442\u043e\u0433\u0434\u0430 \u0432\u0430\u043c \u0432 \u043f\u043e\u043c\u043e\u0449\u044c \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0434\u0443\u043a\u0441-\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f &#8212; \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u043e\u0435\u043a\u0442 <a href=\"https:\/\/github.com\/mrpmorris\/Fluxor\" rel=\"noopener noreferrer nofollow\">Fluxor<\/a>.  <\/p>\n<h2>\u041c\u0443\u043b\u044c\u0442\u0438\u0442\u0435\u043d\u0430\u043d\u0442<\/h2>\n<p>    \u041a\u043e\u0433\u0434\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u0434\u0435\u043b\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043e\u0442 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043e\u043d \u043e\u043f\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438, \u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u043b\u043e\u0439 \u0442\u0435\u043d\u0430\u043d\u0442\u0430. \u0420\u0430\u0431\u043e\u0442\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0433\u043e &#171;\u0430\u0440\u0435\u043d\u0434\u0430\u0442\u043e\u0440\u0430&#187; \u0442\u0430\u043a\u0436\u0435 \u0434\u0430\u0441\u0442 \u0438\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0448\u0430\u0440\u0438\u0442\u044c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439, \u0447\u0442\u043e \u0432\u0435\u0441\u044c\u043c\u0430 \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0430\u0441\u0442\u043e\u0439 \u0444\u0438\u0448\u043a\u043e\u0439 \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0445 \u0442\u0430\u0440\u0438\u0444\u043d\u044b\u0445 \u043f\u043b\u0430\u043d\u043e\u0432 SaaS-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432.<\/p>\n<p>    \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043d\u0430 \u0431\u0435\u043a\u0435\u043d\u0434\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-410454","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/410454","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=410454"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/410454\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=410454"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=410454"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=410454"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}