{"id":369891,"date":"2024-05-21T04:13:25","date_gmt":"2024-05-21T04:13:25","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=369891"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2024-05-21T04:13:25","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=369891","title":{"rendered":"<span>\u041a\u043e\u0433\u0434\u0430 \u043f\u0438\u0448\u0435\u0448\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0441\u0435\u0431\u044f<\/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-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><a href=\"https:\/\/habr.com\/ru\/companies\/ruvds\/articles\/797915\/\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/sc\/wi\/f-\/scwif-sz-b_ciuplqjo0ltckc_a.png\" data-src=\"https:\/\/habrastorage.org\/webt\/sc\/wi\/f-\/scwif-sz-b_ciuplqjo0ltckc_a.png\"\/><\/a><br \/>  <i><font color=\"gray\"><\/p>\n<pre><code class=\"ruby\">require 'glimmer-dsl-libui' include Glimmer window('hello world').show<\/code><\/pre>\n<p><\/font><\/i><br \/>  \u041f\u043e\u0447\u0442\u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0435\u0439 \u0425\u0430\u0431\u0440\u0430 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 \u0434\u043e\u043c\u0430\u0448\u043d\u044e\u044e \u0441\u0435\u0442\u044c, \u043f\u0438\u0448\u0435\u0442 \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u0443\u043c\u043d\u043e\u0433\u043e \u0434\u043e\u043c\u0430, \u0430\u0434\u043c\u0438\u043d\u0438\u0442 \u0434\u043e\u043c\u0430\u0448\u043d\u0438\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u0442.\u00a0\u0434. \u0412\u0441\u0451 \u044d\u0442\u043e \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u00ab\u0441\u0435\u043c\u0435\u0439\u043d\u044b\u0435 \u043e\u0431\u044f\u0437\u0430\u043d\u043d\u043e\u0441\u0442\u0438\u00bb \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430, \u043a\u0430\u043a \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u043c\u0443\u0441\u043e\u0440 \u0434\u043b\u044f \u0441\u0435\u043c\u0435\u0439\u043d\u043e\u0433\u043e \u043c\u0443\u0436\u0447\u0438\u043d\u044b.<\/p>\n<p>  \u0410 \u043a\u0430\u043a \u043d\u0430\u0441\u0447\u0451\u0442 <a href=\"https:\/\/www.robinsloan.com\/notes\/home-cooked-app\/\">\u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0434\u043b\u044f \u0441\u0432\u043e\u0435\u0439 \u0441\u0435\u043c\u044c\u0438 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/a>? \u042d\u0442\u043e \u0443\u0436\u0435 \u043d\u043e\u0432\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c. <br \/>  <a name=\"habracut\"><\/a>  <\/p>\n<h2><font color=\"#3AC1EF\">\u258d \u0421\u043e\u0444\u0442 \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u0438 \u0441\u0435\u043c\u044c\u0438<\/font><\/h2>\n<p>  \u0425\u043e\u0442\u044f \u0420\u043e\u0431\u0438\u043d \u0421\u043b\u043e\u0430\u043d (Robian Sloan) \u0432\u043e\u0432\u0441\u0435 \u043d\u0435 \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442, \u0430 <a href=\"https:\/\/www.robinsloan.com\/about\/\">\u0443\u0441\u043f\u0435\u0448\u043d\u044b\u0439 \u043f\u0438\u0441\u0430\u0442\u0435\u043b\u044c-\u0444\u0430\u043d\u0442\u0430\u0441\u0442<\/a>, \u0435\u0433\u043e \u0437\u043d\u0430\u043d\u0438\u0439 \u0445\u0432\u0430\u0442\u0438\u043b\u043e \u0434\u043b\u044f <a href=\"https:\/\/www.robinsloan.com\/notes\/home-cooked-app\/\">\u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u043e\u0433\u043e \u0432\u0438\u0434\u0435\u043e\u0447\u0430\u0442\u0430 \u043f\u043e\u0434 iOS<\/a>. \u0412 \u043f\u0435\u0440\u0432\u044b\u0439 \u0436\u0435 \u0434\u0435\u043d\u044c \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u0445\u043e\u0434\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b BoopSnoop \u0432 \u044f\u043d\u0432\u0430\u0440\u0435 2020\u00a0\u0433\u043e\u0434\u0430 \u0435\u0451 \u0441\u043a\u0430\u0447\u0430\u043b\u0438 \u0447\u0435\u0442\u044b\u0440\u0435 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430 \u0438\u0437 \u0440\u0430\u0437\u043d\u044b\u0445 \u0447\u0430\u0441\u043e\u0432\u044b\u0445 \u043f\u043e\u044f\u0441\u043e\u0432 (\u043c\u0430\u043c\u0430, \u043f\u0430\u043f\u0430, \u0441\u0435\u0441\u0442\u0440\u0430 \u0438 \u043e\u043d \u0441\u0430\u043c). \u0412\u0441\u0435 \u043e\u043d\u0438 \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u0441\u0447\u0430\u0441\u0442\u043b\u0438\u0432\u044b\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438.<\/p>\n<p>  \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0430 \u043f\u043e \u043e\u0431\u0440\u0430\u0437\u0446\u0443 <a href=\"https:\/\/techcrunch.com\/tag\/taptalk\/?guccounter=1\">Taptalk<\/a>: \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0432\u0438\u0434\u0435\u043e\u043f\u043e\u0442\u043e\u043a \u0441 \u043a\u0430\u043c\u0435\u0440\u044b \u0438 \u0447\u0435\u0442\u044b\u0440\u0435 \u0438\u043a\u043e\u043d\u043a\u0438 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0444\u043e\u0442\u043e \u0438\u043b\u0438 \u0432\u0438\u0434\u0435\u043e (\u043c\u0430\u043c\u0430, \u043f\u0430\u043f\u0430, \u0441\u0435\u0441\u0442\u0440\u0430, \u0433\u0440\u0443\u043f\u043f\u0430 \u0434\u043b\u044f \u0432\u0441\u0435\u0445) \u043e\u0434\u043d\u0438\u043c \u00ab\u0442\u0430\u043f\u043e\u043c\u00bb (\u043d\u0430\u0436\u0430\u0442\u0438\u0435\u043c), \u043e\u0442\u0441\u044e\u0434\u0430 \u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435. <\/p>\n<div class=\"oembed\">\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/65e5af3387bb36d4b35a7dcf\" data-style=\"\" id=\"65e5af3387bb36d4b35a7dcf\" width=\"\"><\/div>\n<\/div>\n<p><i><font color=\"gray\">\u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Taptalk<\/font><\/i><\/p>\n<p>  \u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0431\u0438\u0440\u0430\u0435\u0442\u0435 \u043f\u0430\u043b\u0435\u0446\u00a0\u2014 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043b\u0438\u0448\u043d\u0438\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439. \u0414\u0430\u0436\u0435 \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u043a\u0438 \u043d\u0435 \u0432\u0435\u0434\u0451\u0442\u0441\u044f, \u0432\u0441\u0451 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e.<\/p>\n<p>  \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0441\u0435\u0440\u0432\u0438\u0441 Tapstack <a href=\"https:\/\/medium.com\/@onnofaber\/tapstack-is-shutting-down-this-is-how-we-got-started-and-what-weve-learned-formerly-taptalk-and-d35800ee1865\">\u0437\u0430\u043a\u0440\u044b\u043b\u0441\u044f<\/a> 15\u00a0\u043d\u043e\u044f\u0431\u0440\u044f 2019\u00a0\u0433\u043e\u0434\u0430 (\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u0435\u0437 \u0440\u0435\u043a\u043b\u0430\u043c\u044b \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u043b\u0438, \u0447\u0442\u043e \u043e\u043d\u043e \u0441\u0442\u0430\u043d\u0435\u0442 \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u043c). \u042d\u0442\u043e \u0438 \u0441\u0442\u0430\u043b\u043e \u0434\u043b\u044f \u0420\u043e\u0431\u0438\u043d\u0430 \u043f\u0440\u0438\u0447\u0438\u043d\u043e\u0439 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u044b.<\/p>\n<p>  \u041e\u043d \u043d\u0430\u0448\u0451\u043b \u043e\u043f\u0435\u043d\u0441\u043e\u0440\u0441\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a <a href=\"https:\/\/github.com\/Awalz\/SwiftyCam?utm_source=Robin_Sloan_sent_me\">SwiftyCam<\/a>, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0432\u0441\u0451 \u0438 \u0441\u0434\u0435\u043b\u0430\u043b \u0437\u0430 \u043d\u0435\u0434\u0435\u043b\u044e (\u043f\u043b\u044e\u0441 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u0438\u043d\u0441\u0442\u0430\u043d\u0441 S3 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0444\u043e\u0442\u043e \u0438 \u0432\u0438\u0434\u0435\u043e, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u0430\u0440\u043e\u0447\u043a\u0430 \u043b\u044f\u043c\u0431\u0434\u0430-\u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u043e\u0432\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439). \u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 BoopSnoop \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0435\u0449\u0451 \u043f\u0440\u043e\u0449\u0435, \u0443 \u043d\u0435\u0433\u043e \u0434\u0430\u0436\u0435 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435\u0442, \u0432\u0438\u0434\u0435\u043e \u0432\u0441\u0435\u0433\u0434\u0430 \u0432 \u043f\u043e\u043b\u043d\u043e\u044d\u043a\u0440\u0430\u043d\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435, \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043d\u043e\u043f\u043a\u0430 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u0446\u0438\u0444\u0440\u0430 \u0432 \u043f\u0440\u0430\u0432\u043e\u043c \u0432\u0435\u0440\u0445\u043d\u0435\u043c \u0443\u0433\u043b\u0443 (\u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043d\u0435\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439):<\/p>\n<div class=\"oembed\">\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/65e5b082ee68229db6f6baa8\" data-style=\"\" id=\"65e5b082ee68229db6f6baa8\" width=\"\"><\/div>\n<\/div>\n<p><i><font color=\"gray\">BoopSnoop<\/font><\/i><\/p>\n<p>  \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0432\u0440\u043e\u0434\u0435 <a href=\"http:\/\/shoesrb.com\/\">Shoes!<\/a> \u0438\u043b\u0438 <a href=\"https:\/\/github.com\/AndyObtiva\/glimmer-dsl-libui\">Glimmer DSL<\/a> (\u043d\u0430 \u041a\u0414\u041f\u0412) \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c GUI\u00a0\u2014 \u0434\u0435\u043b\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043c\u0438\u043d\u0443\u0442 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430, \u043d\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u043e\u0433\u043e \u0441 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0434\u0438\u0437\u0430\u0439\u043d\u043e\u043c. \u041d\u043e \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u043e\u0441\u043e\u0431\u043e\u0433\u043e GUI \u0434\u0430\u0436\u0435 \u043d\u0435\u0442. \u042d\u0442\u043e \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 <a href=\"https:\/\/web.archive.org\/web\/20050120085129\/http:\/\/www.shirky.com\/writings\/situated_software.html\">\u0441\u0438\u0442\u0443\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u043e\u0444\u0442<\/a> (situated software), \u0442\u043e \u0435\u0441\u0442\u044c \u0443\u0437\u043a\u043e\u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u041f\u041e \u0441 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. \u041e\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u043b\u044e\u0434\u0435\u0439.<\/p>\n<p>  \u0420\u043e\u0431\u0438\u043d \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u044f\u0435\u0442 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0441\u0440\u0435\u0434\u0438 \u0440\u043e\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u0438\u043a\u043e\u0432 \u043a\u0430\u043a \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u0443\u044e \u0431\u0435\u0442\u0443 \u0447\u0435\u0440\u0435\u0437 <a href=\"https:\/\/apps.apple.com\/us\/app\/testflight\/id899247664\">Apple TestFlight<\/a>. \u0422\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043b\u043e\u0436\u0438\u0442\u044c \u0435\u0451 \u0432 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u0434\u043b\u044f \u0432\u0441\u0435\u0445. \u041d\u043e \u044d\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043a\u0443\u0447\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c. \u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u0435\u0439 \u043d\u0430\u0447\u043d\u0443\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u0440\u0443\u0433\u0438\u0435 \u043b\u044e\u0434\u0438, \u0441\u043e\u0442\u043d\u0438 \u0438 \u0442\u044b\u0441\u044f\u0447\u0438 \u043b\u044e\u0434\u0435\u0439? \u041d\u0430\u0447\u043d\u0443\u0442 \u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0431\u0430\u0433\u0438, \u043f\u0440\u0438\u0441\u044b\u043b\u0430\u0442\u044c \u0444\u0438\u0447\u0430-\u0440\u0435\u043a\u0432\u0435\u0441\u0442\u044b \u0438 \u0442\u0440\u0435\u0431\u0443\u044f \u0443\u0441\u0442\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043d\u0435\u0434\u043e\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u043b\u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0435 \u043a\u043e\u0441\u044f\u043a\u0438. \u041a\u0430\u043a \u043d\u0430 \u043d\u0438\u0445 \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c? \u041d\u0435 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0445\u043e\u0431\u0431\u0438 \u0432 \u0440\u0430\u0431\u043e\u0442\u0443. \u0422\u0435\u043c \u0431\u043e\u043b\u0435\u0435, \u0440\u043e\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u0438\u043a\u043e\u0432 \u0432\u0441\u0451 \u0443\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442, \u0430 \u0434\u043b\u044f \u043d\u0438\u0445 \u044d\u0442\u043e \u0438 \u043f\u0438\u0441\u0430\u043b\u043e\u0441\u044c \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c. \u0417\u0430 \u0434\u0432\u0430 \u0433\u043e\u0434\u0430 \u0420\u043e\u0431\u0438\u043d \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u043b\u0430 \u043c\u0430\u043c\u0430.<\/p>\n<p>  \u041a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e \u00ab\u0434\u043b\u044f \u043b\u044e\u0434\u0435\u0439\u00bb \u0432\u044b\u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0439, \u0447\u0435\u043c \u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e \u00ab\u0434\u043b\u044f \u0441\u0435\u0431\u044f\u00bb. \u041a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c, \u0442\u0430\u043c \u043d\u0430\u0434\u043e \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 (\u043b\u043e\u0433\u0438\u043d-\u043f\u0430\u0440\u043e\u043b\u044c), \u0430 \u0437\u0434\u0435\u0441\u044c \u043e\u043d\u0430 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u0430. \u041d\u0430\u0434\u043e \u043f\u0440\u0438\u0434\u0443\u043c\u044b\u0432\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u043a\u043e\u043d\u0442\u0430\u043a\u0442\u043e\u0432 \u0438 \u0442.\u00a0\u0434. \u0412\u0441\u0451 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0430 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0441\u043b\u043e\u0436\u043d\u0435\u0435. \u0422\u0430\u043a \u0447\u0442\u043e \u043a\u043e\u0433\u0434\u0430 \u0443 \u0432\u0430\u0441 \u0441\u043f\u0440\u043e\u0441\u044f\u0442 \u00ab\u041a\u043b\u0430\u0441\u0441\u043d\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043a\u0430, \u043a\u0430\u043a \u0435\u0451 \u0441\u043a\u0430\u0447\u0430\u0442\u044c?\u00bb, \u043e\u0442\u0432\u0435\u0442 \u0431\u0443\u0434\u0435\u0442 \u043e\u0434\u043d\u043e\u0437\u043d\u0430\u0447\u043d\u044b\u043c: \u00ab\u041d\u0438\u043a\u0430\u043a!\u00bb<\/p>\n<p>  \u0418\u043d\u043e\u0433\u0434\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u00ab\u0434\u043b\u044f \u0441\u0435\u0431\u044f\u00bb \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u043f\u0435\u0440\u0435\u0440\u0430\u0441\u0442\u0430\u0435\u0442 \u0432 \u043d\u0435\u0447\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0435\u0435. \u0422\u0430\u043a \u0441\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0441 \u041c\u0438\u0445\u0430\u0438\u043b\u043e\u043c \u041b\u0430\u043f\u0443\u0448\u043a\u0438\u043d\u044b\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0436\u0435 \u0434\u0435\u0432\u044f\u0442\u044c \u043b\u0435\u0442 (\u0441 2015\u00a0\u0433\u043e\u0434\u0430) <a href=\"https:\/\/papereditor.app\/dev\">\u043f\u0438\u0448\u0435\u0442 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u043f\u043e\u0434 Mac<\/a>. \u041a\u043e\u0433\u0434\u0430-\u0442\u043e \u0434\u0430\u0432\u043d\u043e \u043e\u043d \u0443\u0432\u0438\u0434\u0435\u043b <a href=\"https:\/\/ia.net\/writer?ref=papereditor.app\/dev\">iA Writer<\/a> \u0438 \u0437\u0430\u0445\u043e\u0442\u0435\u043b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0435\u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u0436\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0438 \u044d\u043b\u0435\u0433\u0430\u043d\u0442\u043d\u043e\u0435.<\/p>\n<p>  \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0435\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u044b \u0432 \u043f\u043e\u0433\u043e\u043d\u0435 \u0437\u0430 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u044b\u043c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u0438\u0437\u043c\u043e\u043c \u0441\u0442\u0430\u043b \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 <a href=\"https:\/\/papereditor.app\/\">Paper<\/a>, \u0432\u043f\u043e\u043b\u043d\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0435 \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u043d\u043e <a href=\"https:\/\/apps.apple.com\/us\/app\/paper-writing-app\/id1143513744?mt=12\">\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0438\u0437 Mac App Store<\/a>. \u041f\u043e\u0442\u043e\u043c \u0432\u044b\u0448\u043b\u0430 <a href=\"https:\/\/apps.apple.com\/us\/app\/paper-writing-app\/id1476984841\">\u0432\u0435\u0440\u0441\u0438\u044f \u043f\u043e\u0434 iOS<\/a>.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/lx\/4b\/jq\/lx4bjqf2biifl84wzfugbsylzms.png\" data-src=\"https:\/\/habrastorage.org\/webt\/lx\/4b\/jq\/lx4bjqf2biifl84wzfugbsylzms.png\"\/><\/p>\n<p>  \u041b\u0430\u043f\u0443\u0448\u043a\u0438\u043d \u0432\u044b\u0431\u0440\u0430\u043b \u043f\u0440\u043e\u0431\u043d\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c \u043c\u043e\u043d\u0435\u0442\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u043f\u043b\u0430\u0442\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0430 \u043f\u043e\u0442\u043e\u043c \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u043b\u043e\u0441\u044c \u043a\u0443\u043f\u0438\u0442\u044c \u0432\u0435\u0440\u0441\u0438\u044e Pro (In-App Purchase):  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/90\/tb\/mu\/90tbmuvurvp6qkp9hnecb4ifcj4.png\" data-src=\"https:\/\/habrastorage.org\/webt\/90\/tb\/mu\/90tbmuvurvp6qkp9hnecb4ifcj4.png\"\/><\/div>\n<p>  \u0418\u0441\u0442\u043e\u0440\u0438\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 Paper (\u0432 <a href=\"https:\/\/papereditor.app\/dev\">\u0434\u0432\u0443\u0445<\/a> <a href=\"https:\/\/papereditor.app\/internals\">\u0447\u0430\u0441\u0442\u044f\u0445<\/a>) \u0432\u0435\u0441\u044c\u043c\u0430 \u0443\u0432\u043b\u0435\u043a\u0430\u0442\u0435\u043b\u044c\u043d\u0430. \u0412\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u041c\u0438\u0445\u0430\u0438\u043b \u043e\u0447\u0435\u043d\u044c \u043b\u044e\u0431\u0438\u0442 \u0441\u0432\u043e\u0451 \u0434\u0435\u043b\u043e \u0438 \u043f\u043e\u0433\u0440\u0443\u0436\u0435\u043d \u0432 \u043d\u0435\u0433\u043e \u0441 \u0433\u043e\u043b\u043e\u0432\u043e\u0439. \u041d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u0442\u0430\u043a\u043e\u043c\u0443 \u0443\u0432\u043b\u0435\u0447\u0451\u043d\u043d\u043e\u043c\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0443 \u043f\u043e\u043c\u043e\u0449\u044c \u043a\u043e\u043b\u043b\u0435\u0433 \u043c\u043e\u0436\u0435\u0442 \u0434\u0430\u0436\u0435 \u043f\u043e\u043c\u0435\u0448\u0430\u0442\u044c.<\/p>\n<h2><font color=\"#3AC1EF\">\u258d \u0421\u043e\u043b\u043e-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430<\/font><\/h2>\n<p>  \u041c\u043d\u043e\u0433\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u044b \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043a\u0430\u0440\u044c\u0435\u0440\u044b \u0434\u0435\u043b\u044f\u0442\u0441\u044f \u043e\u043f\u044b\u0442\u043e\u043c \u0443\u0434\u0430\u0447\u043d\u043e\u0439 \u0441\u043e\u043b\u043e-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u041f\u0443\u0441\u0442\u044c \u043e\u043d\u0430 \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u0440\u0438\u043d\u043e\u0441\u0438\u0442 \u0431\u043e\u043b\u044c\u0448\u0435 \u0434\u0435\u043d\u0435\u0433, \u043d\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430 \u0441\u0447\u0430\u0441\u0442\u043b\u0438\u0432\u0435\u0435. <\/p>\n<p>  \u041c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u0439 <a href=\"https:\/\/docs.emailengine.app\/how-i-turned-my-open-source-project-into\/\">\u0431\u0438\u0437\u043d\u0435\u0441 \u043d\u0430 \u043e\u043f\u0435\u043d\u0441\u043e\u0440\u0441\u0435<\/a>, \u0442\u043e \u0435\u0441\u0442\u044c \u043d\u0430 \u0441\u0432\u043e\u0451\u043c \u043b\u0438\u0447\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u043b\u0441\u044f \u043a\u0430\u043a \u0445\u043e\u0431\u0431\u0438. \u0410\u043d\u0434\u0440\u0438\u0441 \u0420\u0435\u0439\u043d\u043c\u0430\u043d (Andris Reinman) \u0443\u0447\u0430\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u043e\u043f\u0435\u043d\u0441\u043e\u0440\u0441\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u043e\u043a\u043e\u043b\u043e 15 \u043b\u0435\u0442, \u0430 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043e\u043d \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u043a\u043b\u0438\u0435\u043d\u0442 <a href=\"https:\/\/emailengine.app\/\">EmailEngine Email API<\/a> (\u043f\u043e\u0447\u0442\u043e\u0432\u044b\u0439 \u043a\u043b\u0438\u0435\u043d\u0442 \u0434\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0430 \u043d\u0435 \u0434\u043b\u044f \u043b\u044e\u0434\u0435\u0439) \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u044b \u0432 \u043b\u044e\u0431\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441, \u0447\u0442\u043e\u0431\u044b \u043a\u043b\u0438\u0435\u043d\u0442\u044b \u043d\u0435 \u0437\u0430\u043c\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043b\u0438\u0441\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 SMTP \u0438 IMAP, \u0430 \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/bu\/fq\/id\/bufqidpmlkhk9kvwm2cc1wj8nhg.png\" data-src=\"https:\/\/habrastorage.org\/webt\/bu\/fq\/id\/bufqidpmlkhk9kvwm2cc1wj8nhg.png\"\/><br \/>  <i><font color=\"gray\">EmailEngine Email API<\/font><\/i><\/p>\n<p>  \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0441 <a href=\"https:\/\/github.com\/postalsys\/emailengine\">\u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c<\/a> \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0431\u044b\u043b\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043f\u043e\u0434 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0439 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0435\u0439 AGPL \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043d\u0430 \u0441\u0432\u043e\u0451\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u0430 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u044f MIT \u0441\u0442\u043e\u0438\u043b\u0430 \u20ac250 \u0432 \u0433\u043e\u0434. \u041f\u043e\u0442\u043e\u043c \u0430\u0432\u0442\u043e\u0440 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0435\u0440\u0435\u0448\u0451\u043b \u043d\u0430 \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u0443\u044e \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u044e\u00a0\u2014 \u0438 \u0432 \u043f\u0435\u0440\u0432\u044b\u0439 \u0436\u0435 \u043c\u0435\u0441\u044f\u0446 \u043f\u0440\u043e\u0434\u0430\u043b \u0441\u0435\u043c\u044c \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0439. \u0417\u0430\u0442\u0435\u043c \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u043b \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c \u0434\u043e \u20ac495, \u20ac695, \u20ac795, \u20ac895\u00a0\u2014 \u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043d\u0435 \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u043b\u043e\u0441\u044c. \u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0438 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u20ac6100 \u0432 \u0433\u043e\u0434, \u0442\u0430\u043a \u0447\u0442\u043e \u0434\u0435\u0441\u044f\u0442\u043a\u0430 \u0438\u043b\u0438 \u0434\u0432\u0443\u0445 \u0434\u0435\u0441\u044f\u0442\u043a\u043e\u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u0432\u043f\u043e\u043b\u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u044d\u0441\u0442\u043e\u043d\u0446\u0443 \u043d\u0430 \u0436\u0438\u0437\u043d\u044c.<\/p>\n<p>  \u0410\u043d\u0434\u0440\u0438\u0441 \u0433\u043e\u0432\u043e\u0440\u0438\u0442, \u0447\u0442\u043e \u0440\u0430\u043d\u044c\u0448\u0435 \u0431\u044b\u043b \u0440\u043e\u043c\u0430\u043d\u0442\u0438\u0447\u043d\u044b\u043c \u0434\u0443\u0440\u0430\u043a\u043e\u043c, \u043a\u043e\u0433\u0434\u0430 \u043f\u0438\u0441\u0430\u043b \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0439 \u043a\u043e\u0434 \u0438 \u0434\u0430\u0436\u0435 \u043e\u0442\u043a\u0430\u0437\u044b\u0432\u0430\u043b\u0441\u044f \u043e\u0442 \u043f\u043e\u0436\u0435\u0440\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0439 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043a\u0440\u0443\u043f\u043d\u044b\u0445 \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0438 \u00ab\u043d\u0435 \u043f\u0440\u043e\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f\u00bb. \u0421 \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u043e\u043c \u0435\u0433\u043e \u0432\u0437\u0433\u043b\u044f\u0434\u044b \u043d\u0430 \u0436\u0438\u0437\u043d\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438\u0441\u044c, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043a\u043e\u0433\u0434\u0430 \u0447\u0443\u0436\u043e\u0439 \u0441\u0442\u0430\u0440\u0442\u0430\u043f <a href=\"https:\/\/nodemailer.com\/\">Nodemailer<\/a> \u043d\u0430 \u0435\u0433\u043e \u043e\u043f\u0435\u043d\u0441\u043e\u0440\u0441\u043d\u043e\u043c \u0441\u043e\u0444\u0442\u0435 \u043f\u0440\u043e\u0434\u0430\u043b\u0441\u044f \u0437\u0430 $500\u00a0\u043c\u043b\u043d.<\/p>\n<p>  \u041e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u0434\u0435\u043d\u044c\u0433\u0438\u00a0\u2014 \u043d\u0435 \u0442\u0430\u043a\u043e\u0435 \u0443\u0436 \u0438 \u0437\u043b\u043e, \u043a\u0430\u043a \u0434\u0443\u043c\u0430\u044e\u0442 \u043c\u043e\u043b\u043e\u0434\u044b\u0435 \u044d\u043d\u0442\u0443\u0437\u0438\u0430\u0441\u0442\u044b. \u0418 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u0443\u044e \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u044e (\u043f\u0443\u0441\u0442\u044c \u0438 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c\u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u043c\u0438) \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u043b \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0439 \u0434\u043e\u0445\u043e\u0434.<\/p>\n<p>  \u0418\u043b\u0438 \u0432\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u0430\u044f \u0436\u0435 \u0438\u0441\u0442\u043e\u0440\u0438\u044f. \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u043a\u0430 \u042d\u043b\u043b\u0438 \u0425\u0430\u043a\u0441\u0442\u0435\u0439\u0431\u043b (Ellie Huxtable) \u0442\u043e\u0436\u0435 <a href=\"https:\/\/ellie.wtf\/posts\/i-quit-my-job-to-work-full-time-on-my-open-source-project\">\u0431\u0440\u043e\u0441\u0438\u043b\u0430 \u0440\u0430\u0431\u043e\u0442\u0443 \u0440\u0430\u0434\u0438 \u0441\u0432\u043e\u0435\u0433\u043e \u043e\u043f\u0435\u043d\u0441\u043e\u0440\u0441\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/a>. \u041d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043b\u0435\u0442 \u043e\u043d\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0430 \u0443\u0442\u0438\u043b\u0438\u0442\u0443 <a href=\"https:\/\/github.com\/ellie\/atuin\">Atuin<\/a> \u0434\u043b\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0441\u0442\u043e\u0440\u0438\u0438 \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043c\u0430\u043d\u0434, \u043f\u043e\u0438\u0441\u043a\u0430 \u0438 \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u043e\u0433\u043e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f (\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f Bash, ZSH, Fish \u0438 NuShell). \u0418\u0441\u0442\u043e\u0440\u0438\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u043c\u0430\u043d\u0434 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u0435\u0434\u0438\u043d\u043e\u0439 \u0411\u0414, \u0441 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/gs\/vo\/tg\/gsvotgf8dydifhwl72u65n6afdw.png\" width=\"550\" data-src=\"https:\/\/habrastorage.org\/webt\/gs\/vo\/tg\/gsvotgf8dydifhwl72u65n6afdw.png\"\/><\/div>\n<p>  \u041e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u044d\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0439 \u0441\u043e\u0444\u0442 \u0434\u043b\u044f \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438\u00a0\u2014 \u0438 \u0442\u044b\u0441\u044f\u0447\u0438 \u043b\u044e\u0434\u0435\u0439 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u044e\u0442 \u044d\u0442\u043e \u043c\u043d\u0435\u043d\u0438\u0435, \u0441\u0443\u0434\u044f \u043f\u043e <a href=\"https:\/\/star-history.com\/#atuinsh\/atuin&amp;Date\">\u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u0437\u0432\u0451\u0437\u0434\u043e\u0447\u0435\u043a \u043d\u0430 \u0413\u0438\u0442\u0445\u0430\u0431\u0435<\/a>.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/20\/ro\/uk\/20roukb_zsruveqzmx2cwwmrlkw.png\" data-src=\"https:\/\/habrastorage.org\/webt\/20\/ro\/uk\/20roukb_zsruveqzmx2cwwmrlkw.png\"\/><\/p>\n<p>  \u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u0431\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u0437\u0430\u0440\u0435\u0437 \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0443, \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u0443\u044e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u0441\u044f\u0446\u0435\u0432 \u0438\u043b\u0438 \u043b\u0435\u0442 \u043d\u0430\u0437\u0430\u0434 \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043d\u043e\u0432\u043e \u0435\u0451 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u043e\u043c \u043f\u0440\u043e\u0431 \u0438 \u043e\u0448\u0438\u0431\u043e\u043a. <\/p>\n<p>  \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043e\u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u0432\u043e\u0441\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u043d\u043e\u0439, \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u0445\u043e\u0431\u0431\u0438. \u0410\u0432\u0442\u043e\u0440 \u0443\u043b\u0443\u0447\u0448\u0430\u043b\u0430 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 (\u0437\u0430 \u0434\u043e\u043d\u0430\u0442\u044b \u043e\u0442 \u0441\u043f\u043e\u043d\u0441\u043e\u0440\u043e\u0432 \u043d\u0430 GitHub), \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u043b\u0430 \u043d\u0430 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u043d\u044b\u0445 \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u044f\u0445, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u043b\u0430 PR&#8217;\u044b \u043e\u0442 \u0434\u0435\u0441\u044f\u0442\u043a\u043e\u0432 \u043a\u043e\u043d\u0442\u0440\u0438\u0431\u044c\u044e\u0442\u043e\u0440\u043e\u0432.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/ko\/yn\/y8\/koyny8ivlcrv8ybd6ui1_f43ke8.png\" data-src=\"https:\/\/habrastorage.org\/webt\/ko\/yn\/y8\/koyny8ivlcrv8ybd6ui1_f43ke8.png\"\/><br \/>  <i><font color=\"gray\">\u0420\u043e\u0441\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439<\/font><\/i><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/yb\/ah\/zb\/ybahzbtnqkigk1osfrylc76urku.png\" data-src=\"https:\/\/habrastorage.org\/webt\/yb\/ah\/zb\/ybahzbtnqkigk1osfrylc76urku.png\"\/><i><font color=\"gray\">\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u0440\u043e\u043a \u0438\u0441\u0442\u043e\u0440\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u043b\u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0435\u0436\u0435\u0434\u043d\u0435\u0432\u043d\u043e<\/font><\/i><\/p>\n<p>  \u0412 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432 \u043e\u043d\u0430 \u043e\u0442\u043a\u0440\u044b\u043b\u0430 <a href=\"https:\/\/atuin.sh\/\">\u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u0443\u044e \u0444\u0438\u0440\u043c\u0443<\/a> \u0432\u043e\u043a\u0440\u0443\u0433 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430, \u0443\u0432\u043e\u043b\u0438\u043b\u0430\u0441\u044c \u0441 \u043f\u0440\u0435\u0436\u043d\u0435\u0433\u043e \u043c\u0435\u0441\u0442\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0432 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043d\u043e\u0439 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 <a href=\"https:\/\/posthog.com\/\">PostHog<\/a>\u00a0\u2014 \u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u0441\u0432\u044f\u0442\u0438\u043b\u0430 \u0441\u0435\u0431\u044f \u043b\u0438\u0447\u043d\u043e\u043c\u0443 \u0431\u0438\u0437\u043d\u0435\u0441\u0443. \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c, \u0438 \u0435\u0451 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0445\u043e\u0441\u0442\u0438\u0442\u044c \u043d\u0430 \u0441\u0432\u043e\u0451\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u043d\u043e \u0437\u0430 \u0434\u0435\u043d\u044c\u0433\u0438 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e\u0442\u0441\u044f \u043f\u0440\u0435\u043c\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u043e\u0431\u043b\u0430\u043a\u0435 (\u043f\u043b\u044e\u0441 \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u0438\u0435 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0438 \u0434\u043b\u044f \u0431\u0438\u0437\u043d\u0435\u0441\u0430).<\/p>\n<p>  \u041e\u0442\u043a\u0440\u044b\u0442\u0438\u0435 \u0441\u0432\u043e\u0435\u0433\u043e \u0431\u0438\u0437\u043d\u0435\u0441\u0430\u00a0\u2014 \u044d\u0442\u043e \u0435\u0449\u0451 \u0438 \u0441\u043f\u043e\u0441\u043e\u0431 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u044b\u0433\u043e\u0440\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 <a href=\"https:\/\/codecodeship.com\/blog\/2023-04-14-mike-perham\">\u043e\u0447\u0435\u043d\u044c \u0447\u0430\u0441\u0442\u043e \u043d\u0430\u0441\u0442\u0438\u0433\u0430\u0435\u0442 \u043c\u0435\u0439\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u043e\u043f\u0435\u043d\u0441\u043e\u0440\u0441\u0430<\/a>.<\/p>\n<h2><font color=\"#3AC1EF\">\u258d \u0423\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u0435, \u0430 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430<\/font><\/h2>\n<p>  \u0412 \u0446\u0435\u043b\u043e\u043c, \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u0432\u043e\u043f\u0440\u043e\u0441, \u043a\u0430\u043a\u0443\u044e \u0440\u043e\u043b\u044c \u0438\u0433\u0440\u0430\u0435\u0442 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u0436\u0438\u0437\u043d\u0438\u00a0\u2014 \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430 \u0438\u043b\u0438 \u0445\u043e\u0431\u0431\u0438? \u0412\u0435\u0434\u044c \u0435\u0441\u043b\u0438 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0433\u043b\u0430\u0432\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043a\u0430\u043a \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0441\u0440\u0435\u0434\u0441\u0442\u0432 \u0434\u043b\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f, \u0442\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u0435 \u043e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430. \u042d\u0442\u043e \u0441\u0440\u043e\u0434\u043d\u0438 \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043a\u0440\u0435\u043d\u043d\u0435 \u0434\u0440\u0443\u0436\u0438\u0442\u044c \u0441\u043e \u0441\u0432\u043e\u0438\u043c \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u043c. \u0418\u043b\u0438 \u0441 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0432\u0430\u0441 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0438\u0442\u044c \u043f\u043e \u0449\u0435\u043b\u0447\u043a\u0443 \u043f\u0430\u043b\u044c\u0446\u0435\u0432. \u041f\u0440\u043e\u0441\u0442\u043e \u043c\u043e\u0437\u0433 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430 \u0442\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d, \u0447\u0442\u043e \u043e\u043d \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u0435 \u0432 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438, \u0430 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e \u0432\u0430\u0436\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442\u0441\u044f \u043a\u0430\u043a \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0443\u0433\u0440\u043e\u0437\u044b.<\/p>\n<p>  \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0433\u0430\u0440\u043c\u043e\u043d\u0438\u0438 \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0443 \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u043d\u0435\u043a\u0438\u0435 \u0445\u043e\u0431\u0431\u0438-\u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0434\u043b\u044f \u0434\u0443\u0448\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u0430\u043a antirez (<a href=\"https:\/\/habr.com\/ru\/companies\/ruvds\/articles\/758112\/\">\u0421\u0430\u043b\u044c\u0432\u0430\u0442\u043e\u0440\u0435 \u0421\u0430\u043d\u0444\u0438\u043b\u0438\u043f\u043f\u043e, \u0430\u0432\u0442\u043e\u0440 \u0421\u0423\u0411\u0414 Redis<\/a> \u0438, \u043a\u0441\u0442\u0430\u0442\u0438, \u0442\u043e\u0436\u0435 \u043f\u0438\u0441\u0430\u0442\u0435\u043b\u044c-\u0444\u0430\u043d\u0442\u0430\u0441\u0442) \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0446\u0435\u043f\u0442 \u0447\u0430\u0442-\u0441\u0435\u0440\u0432\u0435\u0440\u0430 <a href=\"https:\/\/github.com\/antirez\/smallchat\">smallchat<\/a> \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0434\u0440\u0443\u0437\u0435\u0439. \u041e\u043d \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0439 \u0447\u0430\u0442-\u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430 C, \u043a\u0430\u043a \u043d\u0430 <a href=\"https:\/\/www.ioccc.org\/\">\u043a\u043e\u043d\u043a\u0443\u0440\u0441\u0430\u0445 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430<\/a>, \u0432 \u0441\u0442\u0438\u043b\u0435 IRC, \u0438 \u0441\u043c\u043e\u0433 \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0441\u0435\u0433\u043e \u0432 200 \u0441\u0442\u0440\u043e\u043a\u0430\u0445 \u043a\u043e\u0434\u0430, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u0435\u043b\u044b \u0438 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438:<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0427\u0430\u0442-\u0441\u0435\u0440\u0432\u0435\u0440 smallchat<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">\/* smallchat.c -- Read clients input, send to all the other connected clients.  *  * Copyright (c) 2023, Salvatore Sanfilippo &lt;antirez at gmail dot com>  * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions are met:  *  *   * Redistributions of source code must retain the above copyright notice,  *     this list of conditions and the following disclaimer.  *   * Redistributions in binary form must reproduce the above copyright  *     notice, this list of conditions and the following disclaimer in the  *     documentation and\/or other materials provided with the distribution.  *   * Neither the project name of nor the names of its contributors may be used  *     to endorse or promote products derived from this software without  *     specific prior written permission.  *  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  * POSSIBILITY OF SUCH DAMAGE.  *\/  #include &lt;stdio.h> #include &lt;string.h> #include &lt;stdlib.h> #include &lt;assert.h> #include &lt;sys\/select.h> #include &lt;unistd.h>  #include \"chatlib.h\"  \/* ============================ Data structures =================================  * The minimal stuff we can afford to have. This example must be simple  * even for people that don't know a lot of C.  * =========================================================================== *\/  #define MAX_CLIENTS 1000 \/\/ This is actually the higher file descriptor. #define SERVER_PORT 7711  \/* This structure represents a connected client. There is very little  * info about it: the socket descriptor and the nick name, if set, otherwise  * the first byte of the nickname is set to 0 if not set.  * The client can set its nickname with \/nick &lt;nickname> command. *\/ struct client {     int fd;     \/\/ Client socket.     char *nick; \/\/ Nickname of the client. };  \/* This global structure encapsulates the global state of the chat. *\/ struct chatState {     int serversock;     \/\/ Listening server socket.     int numclients;     \/\/ Number of connected clients right now.     int maxclient;      \/\/ The greatest 'clients' slot populated.     struct client *clients[MAX_CLIENTS]; \/\/ Clients are set in the corresponding                                          \/\/ slot of their socket descriptor. };  struct chatState *Chat; \/\/ Initialized at startup.  \/* ====================== Small chat core implementation ========================  * Here the idea is very simple: we accept new connections, read what clients  * write us and fan-out (that is, send-to-all) the message to everybody  * with the exception of the sender. And that is, of course, the most  * simple chat system ever possible.  * =========================================================================== *\/  \/* Create a new client bound to 'fd'. This is called when a new client  * connects. As a side effect updates the global Chat state. *\/ struct client *createClient(int fd) {     char nick[32]; \/\/ Used to create an initial nick for the user.     int nicklen = snprintf(nick,sizeof(nick),\"user:%d\",fd);     struct client *c = chatMalloc(sizeof(*c));     socketSetNonBlockNoDelay(fd); \/\/ Pretend this will not fail.     c->fd = fd;     c->nick = chatMalloc(nicklen+1);     memcpy(c->nick,nick,nicklen);     assert(Chat->clients[c->fd] == NULL); \/\/ This should be available.     Chat->clients[c->fd] = c;     \/* We need to update the max client set if needed. *\/     if (c->fd > Chat->maxclient) Chat->maxclient = c->fd;     Chat->numclients++;     return c; }  \/* Free a client, associated resources, and unbind it from the global  * state in Chat. *\/ void freeClient(struct client *c) {     free(c->nick);     close(c->fd);     Chat->clients[c->fd] = NULL;     Chat->numclients--;     if (Chat->maxclient == c->fd) {         \/* Ooops, this was the max client set. Let's find what is          * the new highest slot used. *\/         int j;         for (j = Chat->maxclient-1; j >= 0; j--) {             if (Chat->clients[j] != NULL) {                 Chat->maxclient = j;                 break;             }         }         if (j == -1) Chat->maxclient = -1; \/\/ We no longer have clients.     }     free(c); }  \/* Allocate and init the global stuff. *\/ void initChat(void) {     Chat = chatMalloc(sizeof(*Chat));     memset(Chat,0,sizeof(*Chat));     \/* No clients at startup, of course. *\/     Chat->maxclient = -1;     Chat->numclients = 0;      \/* Create our listening socket, bound to the given port. This      * is where our clients will connect. *\/     Chat->serversock = createTCPServer(SERVER_PORT);     if (Chat->serversock == -1) {         perror(\"Creating listening socket\");         exit(1);     } }  \/* Send the specified string to all connected clients but the one  * having as socket descriptor 'excluded'. If you want to send something  * to every client just set excluded to an impossible socket: -1. *\/ void sendMsgToAllClientsBut(int excluded, char *s, size_t len) {     for (int j = 0; j &lt;= Chat->maxclient; j++) {         if (Chat->clients[j] == NULL ||             Chat->clients[j]->fd == excluded) continue;          \/* Important: we don't do ANY BUFFERING. We just use the kernel          * socket buffers. If the content does not fit, we don't care.          * This is needed in order to keep this program simple. *\/         write(Chat->clients[j]->fd,s,len);     } }  \/* The main() function implements the main chat logic:  * 1. Accept new clients connections if any.  * 2. Check if any client sent us some new message.  * 3. Send the message to all the other clients. *\/ int main(void) {     initChat();      while(1) {         fd_set readfds;         struct timeval tv;         int retval;          FD_ZERO(&amp;readfds);         \/* When we want to be notified by select() that there is          * activity? If the listening socket has pending clients to accept          * or if any other client wrote anything. *\/         FD_SET(Chat->serversock, &amp;readfds);          for (int j = 0; j &lt;= Chat->maxclient; j++) {             if (Chat->clients[j]) FD_SET(j, &amp;readfds);         }          \/* Set a timeout for select(), see later why this may be useful          * in the future (not now). *\/         tv.tv_sec = 1; \/\/ 1 sec timeout         tv.tv_usec = 0;          \/* Select wants as first argument the maximum file descriptor          * in use plus one. It can be either one of our clients or the          * server socket itself. *\/         int maxfd = Chat->maxclient;         if (maxfd &lt; Chat->serversock) maxfd = Chat->serversock;         retval = select(maxfd+1, &amp;readfds, NULL, NULL, &amp;tv);         if (retval == -1) {             perror(\"select() error\");             exit(1);         } else if (retval) {              \/* If the listening socket is \"readable\", it actually means              * there are new clients connections pending to accept. *\/             if (FD_ISSET(Chat->serversock, &amp;readfds)) {                 int fd = acceptClient(Chat->serversock);                 struct client *c = createClient(fd);                 \/* Send a welcome message. *\/                 char *welcome_msg =                     \"Welcome to Simple Chat! \"                     \"Use \/nick &lt;nick> to set your nick.\\n\";                 write(c->fd,welcome_msg,strlen(welcome_msg));                 printf(\"Connected client fd=%d\\n\", fd);             }              \/* Here for each connected client, check if there are pending              * data the client sent us. *\/             char readbuf[256];             for (int j = 0; j &lt;= Chat->maxclient; j++) {                 if (Chat->clients[j] == NULL) continue;                 if (FD_ISSET(j, &amp;readfds)) {                     \/* Here we just hope that there is a well formed                      * message waiting for us. But it is entirely possible                      * that we read just half a message. In a normal program                      * that is not designed to be that simple, we should try                      * to buffer reads until the end-of-the-line is reached. *\/                     int nread = read(j,readbuf,sizeof(readbuf)-1);                      if (nread &lt;= 0) {                         \/* Error or short read means that the socket                          * was closed. *\/                         printf(\"Disconnected client fd=%d, nick=%s\\n\",                             j, Chat->clients[j]->nick);                         freeClient(Chat->clients[j]);                     } else {                         \/* The client sent us a message. We need to                          * relay this message to all the other clients                          * in the chat. *\/                         struct client *c = Chat->clients[j];                         readbuf[nread] = 0;                          \/* If the user message starts with \"\/\", we                          * process it as a client command. So far                          * only the \/nick &lt;newnick> command is implemented. *\/                         if (readbuf[0] == '\/') {                             \/* Remove any trailing newline. *\/                             char *p;                             p = strchr(readbuf,'\\r'); if (p) *p = 0;                             p = strchr(readbuf,'\\n'); if (p) *p = 0;                             \/* Check for an argument of the command, after                              * the space. *\/                             char *arg = strchr(readbuf,' ');                             if (arg) {                                 *arg = 0; \/* Terminate command name. *\/                                 arg++; \/* Argument is 1 byte after the space. *\/                             }                              if (!strcmp(readbuf,\"\/nick\") &amp;&amp; arg) {                                 free(c->nick);                                 int nicklen = strlen(arg);                                 c->nick = chatMalloc(nicklen+1);                                 memcpy(c->nick,arg,nicklen+1);                             } else {                                 \/* Unsupported command. Send an error. *\/                                 char *errmsg = \"Unsupported command\\n\";                                 write(c->fd,errmsg,strlen(errmsg));                             }                         } else {                             \/* Create a message to send everybody (and show                              * on the server console) in the form:                              *   nick> some message. *\/                             char msg[256];                             int msglen = snprintf(msg, sizeof(msg),                                 \"%s> %s\", c->nick, readbuf);                              \/* snprintf() return value may be larger than                              * sizeof(msg) in case there is no room for the                              * whole output. *\/                             if (msglen >= (int)sizeof(msg))                                 msglen = sizeof(msg)-1;                             printf(\"%s\",msg);                              \/* Send it to all the other clients. *\/                             sendMsgToAllClientsBut(j,msg,msglen);                         }                     }                 }             }         } else {             \/* Timeout occurred. We don't do anything right now, but in              * general this section can be used to wakeup periodically              * even if there is no clients activity. *\/         }     }     return 0; }<\/code><\/pre>\n<\/div><\/div>\n<p>  <a href=\"https:\/\/github.com\/antirez\/smallchat\/blob\/main\/smallchat-client.c\">\u041a\u043b\u0438\u0435\u043d\u0442 smallchat<\/a> \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u044b\u0439.<\/p>\n<p>  \u0418 \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u043e\u043b\u043e-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0442\u043e\u0436\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0442\u0430\u043a\u0438\u0445 \u0445\u043e\u0431\u0431\u0438-\u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u043d\u043e\u0433\u0434\u0430 \u0441\u0434\u0435\u043b\u0430\u043d\u044b \u0447\u0438\u0441\u0442\u043e \u0434\u043b\u044f \u0441\u0435\u0431\u044f, \u0430 \u0438\u043d\u043e\u0433\u0434\u0430 \u0432 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0446\u0435\u043b\u044f\u0445 \u0434\u043b\u044f \u0432\u0441\u0435\u0445. \u041a\u0442\u043e-\u0442\u043e \u0432\u044b\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u044d\u0442\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0432 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f, \u0430 \u043a\u0442\u043e-\u0442\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e\u0433\u043e. Antirez \u0441\u0440\u0430\u0437\u0443 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0430\u0435\u0442 \u043e \u043f\u0443\u043b\u043b-\u0440\u0435\u043a\u0432\u0435\u0441\u0442\u0430\u0445: <\/p>\n<blockquote><p>\u00ab\u0418\u043c\u0435\u0439\u0442\u0435 \u0432 \u0432\u0438\u0434\u0443, \u0447\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e PR \u043d\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u044b. C\u043c\u044b\u0441\u043b \u044d\u0442\u043e\u0433\u043e \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0443\u043b\u0443\u0447\u0448\u0430\u0442\u044c \u0435\u0433\u043e \u0448\u0430\u0433 \u0437\u0430 \u0448\u0430\u0433\u043e\u043c \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0432\u0438\u0434\u0435\u043e\u0440\u043e\u043b\u0438\u043a\u0430\u0445 [\u0441\u043c. <a href=\"https:\/\/www.youtube.com\/watch?v=eT02gzeLmF0\">\u043f\u0435\u0440\u0432\u044b\u0439<\/a> \u0438 <a href=\"https:\/\/youtu.be\/yogoUJ2zVYY\">\u0432\u0442\u043e\u0440\u043e\u0439<\/a> \u044d\u043f\u0438\u0437\u043e\u0434\u044b]. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0436\u0438\u0432\u044b\u0445 \u0441\u0435\u0441\u0441\u0438\u0439 (\u0438\u043b\u0438 \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0442\u044c \u0432 \u0432\u0438\u0434\u0435\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433\u0430), \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0434\u043b\u044f \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b (linenoise, rax \u0438 \u0442.\u00a0\u0434.). \u0422\u0430\u043a \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0443\u043f\u0440\u0430\u0436\u043d\u0435\u043d\u0438\u044f\u00a0\u2014 \u0432\u043f\u0435\u0440\u0451\u0434! \u041e\u0442\u043b\u0438\u0447\u043d\u0430\u044f \u0438\u0434\u0435\u044f. \u041d\u043e \u044f \u043d\u0435 \u0431\u0443\u0434\u0443 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0444\u0438\u0447\u0438, \u0442\u0430\u043a \u043a\u0430\u043a \u0441\u043c\u044b\u0441\u043b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0432 \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e\u043c \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0438 \u043d\u0430 \u0436\u0438\u0432\u044b\u0445 \u0441\u0435\u0441\u0441\u0438\u044f\u0445\u00bb.<\/p><\/blockquote>\n<p>  \u0425\u043e\u0431\u0431\u0438-\u043f\u0440\u043e\u0435\u043a\u0442\u044b \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u044e\u0442, \u0447\u0442\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u00a0\u2014 \u044d\u0442\u043e \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u0435\u043d\u044c\u0433\u0438, \u043d\u043e \u0435\u0449\u0451 \u0438 \u043e\u0447\u0435\u043d\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435 \u0437\u0430\u043d\u044f\u0442\u0438\u0435. \u041c\u044b \u0431\u044b \u0441 \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u0435\u043c \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0438\u0441\u044c \u0438\u043c \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e, \u0435\u0441\u043b\u0438 \u0431\u044b \u0437\u0430 \u044d\u0442\u043e \u043d\u0435 \u043f\u043b\u0430\u0442\u0438\u043b\u0438.<\/p>\n<p>  \u041d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0441\u0435\u0431\u044f\u00a0\u2014 \u044d\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043a\u0430\u043a \u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0434\u043e\u043c\u0430. \u0412\u0440\u043e\u0434\u0435 \u043a\u0430\u043a \u0438 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u043e \u043b\u044e\u0434\u0438 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u044e\u0442 \u0434\u043b\u044f \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u044f. \u0418\u043d\u043e\u0433\u0434\u0430 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0432\u044b\u0439\u0442\u0438 \u0437\u0430 \u0440\u0430\u043c\u043a\u0438 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0438 \u0447\u0442\u043e-\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0438\u043c\u0438 \u0440\u0443\u043a\u0430\u043c\u0438. \u0412 \u0446\u0435\u043b\u043e\u043c, \u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0447\u0438\u0441\u0442\u043e \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u043d\u0430 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043f\u0440\u043e\u0449\u0435 \u0438 \u043f\u0440\u0438\u044f\u0442\u043d\u0435\u0435, \u0447\u0435\u043c \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438\u043b\u0438 \u0440\u0430\u0431\u043e\u0442\u043e\u0434\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p>  \u0410 \u0435\u0441\u043b\u0438 \u044d\u0442\u043e\u0442 \u0445\u043e\u0431\u0431\u0438-\u043f\u0440\u043e\u0435\u043a\u0442 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u0438\u043c \u0438 \u043f\u0440\u0438\u043d\u043e\u0441\u0438\u0442 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0434\u0435\u043d\u044c\u0433\u0438, \u0442\u0435\u043c \u043b\u0443\u0447\u0448\u0435.<\/p>\n<blockquote><p><b><font color=\"#3AC1EF\"><a href=\"https:\/\/t.me\/ruvds_community\">Telegram-\u043a\u0430\u043d\u0430\u043b \u0441\u043e \u0441\u043a\u0438\u0434\u043a\u0430\u043c\u0438, \u0440\u043e\u0437\u044b\u0433\u0440\u044b\u0448\u0430\u043c\u0438 \u043f\u0440\u0438\u0437\u043e\u0432 \u0438 \u043d\u043e\u0432\u043e\u0441\u0442\u044f\u043c\u0438 IT ? <\/a><\/font><\/b><\/p><\/blockquote>\n<p><a href=\"http:\/\/ruvds.com\/ru-rub?utm_source=habr&amp;utm_medium=article&amp;utm_campaign=alizar&amp;utm_content=kogda_pishesh_prilozheniya_dlya_sebya\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/tp\/sk\/z-\/tpskz-7w7a8e74isoowuep40xeg.png\" data-src=\"https:\/\/habrastorage.org\/webt\/tp\/sk\/z-\/tpskz-7w7a8e74isoowuep40xeg.png\"\/><\/a><\/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\/797915\/\"> https:\/\/habr.com\/ru\/articles\/797915\/<\/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-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><a href=\"https:\/\/habr.com\/ru\/companies\/ruvds\/articles\/797915\/\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/sc\/wi\/f-\/scwif-sz-b_ciuplqjo0ltckc_a.png\" data-src=\"https:\/\/habrastorage.org\/webt\/sc\/wi\/f-\/scwif-sz-b_ciuplqjo0ltckc_a.png\"\/><\/a><br \/>  <i><font color=\"gray\"><\/p>\n<pre><code class=\"ruby\">require 'glimmer-dsl-libui' include Glimmer window('hello world').show<\/code><\/pre>\n<p><\/font><\/i><br \/>  \u041f\u043e\u0447\u0442\u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0435\u0439 \u0425\u0430\u0431\u0440\u0430 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 \u0434\u043e\u043c\u0430\u0448\u043d\u044e\u044e \u0441\u0435\u0442\u044c, \u043f\u0438\u0448\u0435\u0442 \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u0443\u043c\u043d\u043e\u0433\u043e \u0434\u043e\u043c\u0430, \u0430\u0434\u043c\u0438\u043d\u0438\u0442 \u0434\u043e\u043c\u0430\u0448\u043d\u0438\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u0442.\u00a0\u0434. \u0412\u0441\u0451 \u044d\u0442\u043e \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u00ab\u0441\u0435\u043c\u0435\u0439\u043d\u044b\u0435 \u043e\u0431\u044f\u0437\u0430\u043d\u043d\u043e\u0441\u0442\u0438\u00bb \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430, \u043a\u0430\u043a \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u043c\u0443\u0441\u043e\u0440 \u0434\u043b\u044f \u0441\u0435\u043c\u0435\u0439\u043d\u043e\u0433\u043e \u043c\u0443\u0436\u0447\u0438\u043d\u044b.<\/p>\n<p>  \u0410 \u043a\u0430\u043a \u043d\u0430\u0441\u0447\u0451\u0442 <a href=\"https:\/\/www.robinsloan.com\/notes\/home-cooked-app\/\">\u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0434\u043b\u044f \u0441\u0432\u043e\u0435\u0439 \u0441\u0435\u043c\u044c\u0438 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/a>? \u042d\u0442\u043e \u0443\u0436\u0435 \u043d\u043e\u0432\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c.   <\/p>\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-369891","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/369891","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=369891"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/369891\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=369891"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=369891"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=369891"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}