{"id":501113,"date":"2026-10-31T09:30:13","date_gmt":"2026-10-31T06:30:13","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=501113"},"modified":"2026-10-31T09:30:13","modified_gmt":"2026-10-31T06:30:13","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=501113","title":{"rendered":"\u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u042f\u043d\u0434\u0435\u043a\u0441.\u0414\u0438\u0441\u043a \u043a \u0441\u0435\u0431\u0435"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<blockquote>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0430\u0448\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043b\u0435\u0436\u0430\u0442 \u0432 &#171;\u043e\u0431\u043b\u0430\u043a\u0435&#187; &#8212; \u044d\u0442\u043e \u043d\u0435 \u0432\u0430\u0448\u0438 \u0434\u0430\u043d\u043d\u044b\u0435.<\/p>\n<\/blockquote>\n<p>\u0418\u0442\u0430\u043a, \u0432\u0432\u043e\u0434\u043d\u044b\u0435:<\/p>\n<ul>\n<li>\n<p>\u0435\u0441\u0442\u044c \u042f\u043d\u0434\u0435\u043a\u0441.\u0414\u0438\u0441\u043a \u043e\u0431\u044a\u0435\u043c\u043e\u043c ~500GB, \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0439 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0444\u043e\u0442\u043e (RAW \u0438 JPEG) \u0438 \u0432\u0438\u0434\u0435\u043e<\/p>\n<\/li>\n<li>\n<p>\u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0444\u0430\u0439\u043b\u043e\u0432 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 web-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043d\u0430 \u043f\u043e\u043b\u043d\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438<\/p>\n<\/li>\n<li>\n<p>\u0435\u0441\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0430 <strong>\u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u0435\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0434\u0438\u0441\u043a<\/strong>, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f <a href=\"https:\/\/habr.com\/ru\/articles\/1092652\/\" rel=\"noopener nofollow\">\u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f<\/a><\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u0440\u043e\u0434\u0435 \u0431\u044b \u0440\u043e\u0432\u043d\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438 \u043d\u0443\u0436\u0435\u043d <a href=\"https:\/\/360.yandex.ru\/disk\/download\/\" rel=\"noopener nofollow\">\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0438\u0435\u043d\u0442<\/a> &#8212; \u043d\u043e \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u043e\u043d \u043f\u043e\u0432\u0435\u043b \u0441\u0435\u0431\u044f \u043a\u0440\u0430\u0439\u043d\u0435 \u0441\u0442\u0440\u0430\u043d\u043d\u043e:<\/p>\n<ul>\n<li>\n<p>\u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0446\u0435\u043b\u0435\u0432\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u043d\u0438 \u043d\u0430 \u043a\u0430\u043a\u043e\u043c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u0434\u0438\u0441\u043a\u0435, \u043a\u0440\u043e\u043c\u0435 C:<\/p>\n<\/li>\n<li>\n<p> \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 <a href=\"https:\/\/habr.com\/ru\/news\/1100492\/\" rel=\"noopener nofollow\">\u043f\u043e\u0437\u0438\u0442\u0438\u0432\u043d\u044b\u0435 \u043d\u043e\u0432\u043e\u0441\u0442\u0438<\/a>, \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e \u043d\u0430\u0442\u044b\u043a\u0430\u043b\u0441\u044f \u043d\u0430 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0438 \u0432\u043f\u0430\u0434\u0430\u043b \u0432 \u0441\u0442\u0443\u043f\u043e\u0440<\/p>\n<\/li>\n<li>\n<p>\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u043b\u0430 \u0436\u0435\u043b\u0430\u0442\u044c \u043b\u0443\u0447\u0448\u0435\u0433\u043e<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0431\u0440\u0430\u0442\u044c \u0434\u0435\u043b\u043e \u0432 \u0441\u0432\u043e\u0438 \u0440\u0443\u043a\u0438, \u0430 \u0437\u0430\u043e\u0434\u043d\u043e \u043f\u043b\u043e\u0442\u043d\u0435\u0435 \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 <code>node:streams<\/code>&#8230;<\/p>\n<h2>\u041a\u0430\u043a \u0432\u0441\u0435 \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043e &#171;\u0434\u043b\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430&#187;<\/h2>\n<p>\u041f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/yandex.ru\/dev\/disk\/\" rel=\"noopener nofollow\">API \u0414\u0438\u0441\u043a\u0430<\/a> \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c &#171;\u0440\u043e\u0434\u043d\u043e\u0439&#187; \u043a\u043b\u0438\u0435\u043d\u0442 \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441\u043e\u0432\u0441\u0435\u043c &#8212; \u043b\u0443\u0447\u0448\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 web-\u043a\u043b\u0438\u0435\u043d\u0442 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435, \u0438 \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u0435\u043c\u0441\u044f \u043f\u0440\u0438\u043a\u0438\u043d\u0443\u0442\u044c\u0441\u044f \u0438\u043c.<\/p>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c-\u0442\u043e \u043e\u0442 \u043d\u0430\u0441 \u043d\u0438\u043a\u0442\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442, \u0438 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435\u0433\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0438\u043f\u043e\u0432 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 \u0440\u0430\u0437\u0434\u0435\u043b\u0430<\/h4>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043b\u044e\u0431\u043e\u0433\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0430, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>POST<\/code>-\u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 <code>https:\/\/disk.yandex.ru\/models-v2?m=mpfs\/resources<\/code>.<\/p>\n<p>\u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b:<\/p>\n<pre><code>{  sort       : 'name'  \/\/ \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430 \u043f\u043e \u0438\u043c\u0435\u043d\u0438, order      : '1', idContext  : '\/disk' \/\/ path \u0434\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430, amount     : 40      \/\/ \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435, offset     : 0       \/\/ \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0439 \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper\"><\/span><\/a><\/div><\/pre>\n<p>Web-\u043a\u043b\u0438\u0435\u043d\u0442 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043a\u0438 \u0444\u0430\u0439\u043b\u043e\u0432 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438 \u043f\u043e 40 \u0448\u0442\u0443\u043a, \u0438 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043d\u0430\u0440\u0443\u0448\u0430\u0442\u044c \u044d\u0442\u0443 \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u044e.<\/p>\n<p>\u0412 \u043e\u0442\u0432\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c JSON-\u043c\u0430\u0441\u0441\u0438\u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441 \u0432\u043f\u043e\u043b\u043d\u0435 \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439:<\/p>\n<pre><code>{  type  : \"dir\"              \/\/ \u0442\u0438\u043f \u043e\u0431\u044a\u0435\u043a\u0442\u0430: 'dir' \u0438\u043b\u0438 'file', id    : \"\/disk\/My Folder\/\" \/\/ \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443 \u043d\u0430 \u0414\u0438\u0441\u043a\u0435, name  : \"My Folder\"        \/\/ \u0438\u043c\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430, path  : \"\/disk\/My Folder\"  \/\/ \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443 \u043d\u0430 \u0414\u0438\u0441\u043a\u0435, \u0435\u0449\u0435 \u0440\u0430\u0437, meta  : {    size : 123456            \/\/ \u0440\u0430\u0437\u043c\u0435\u0440 - \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u0430  }  \/\/ \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f, \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, ... \u0432 Unix Timestamp, ctime : ..., mtime : ..., utime : ...}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<h4>\u041f\u0443\u0442\u044c \u043a \u0444\u0430\u0439\u043b\u0443<\/h4>\n<p>\u0415\u0449\u0435 \u043e\u0434\u0438\u043d <code>POST<\/code>-\u0437\u0430\u043f\u0440\u043e\u0441, \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 <code>https:\/\/disk.yandex.ru\/models-v2?m=mpfs\/url<\/code> \u0441 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c <code>path<\/code> \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043d\u0430\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c URL \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u0430:<\/p>\n<pre><code>{  file : \"\/\/downloader.disk.yandex.ru\/disk\/...\"}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<h4>\u0422\u0435\u043b\u043e \u0444\u0430\u0439\u043b\u0430<\/h4>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0432\u0448\u0438\u0441\u044c \u043a \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u043c\u0443 URL, \u0442\u0435\u043f\u0435\u0440\u044c \u0443\u0436\u0435 <code>GET<\/code>-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c HTTP 302-\u0440\u0435\u0434\u0438\u0440\u0435\u043a\u0442 \u0441 \u0430\u0434\u0440\u0435\u0441\u043e\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0435:<\/p>\n<p><code>location : https:\/\/mds.storage.yandex.net\/rdisk\/...<\/code><\/p>\n<p>\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0442\u0430\u043c \u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0438\u0441\u043a\u043e\u043c\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442.<\/p>\n<h2>\u0417\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a<\/h2>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b &#171;\u043f\u0440\u0438\u0442\u0432\u043e\u0440\u044f\u0442\u044c\u0441\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u043c&#187; \u0443\u0441\u043b\u043e\u0432\u043d\u043e-\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e, \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 \u043b\u044e\u0431\u043e\u0433\u043e \u0438\u0437 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044b\u0445 \u0432\u044b\u0448\u0435 <code>POST<\/code>-\u0437\u0430\u043f\u0440\u043e\u0441\u0430 &#8212; \u0438\u0445 \u043b\u0435\u0433\u043a\u043e \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u044f\u043c\u043e \u0438\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430:<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/extt\/e6\/43\/c2\/e643c29bb87cd24bb36c9d014bf944aa.png\" alt=\"\u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\" title=\"\u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\" width=\"2023\" height=\"1543\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/extt\/e6\/43\/c2\/e643c29bb87cd24bb36c9d014bf944aa.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/extt\/e6\/43\/c2\/e643c29bb87cd24bb36c9d014bf944aa.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0441\u0430\u043c\u0438 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 (<code>headers<\/code>) \u0438 \u0434\u0432\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u0432 <code>body<\/code>: <code>sk<\/code> \u0438 <code>connection_id<\/code>.<\/p>\n<blockquote>\n<p>\u0414\u0430\u043d\u043d\u044b\u0435 \u0441\u0435\u0441\u0441\u0438\u0438 (<code>sk \/ connection_id<\/code>) &#171;\u043f\u0440\u043e\u0442\u0443\u0445\u0430\u044e\u0442&#187; \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u0441\u0443\u0442\u043a\u0438 \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0441\u043b\u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0443 \u0432\u0430\u0441 \u043c\u043d\u043e\u0433\u043e &#8212; \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043e\u0442\u0432\u0430\u043b\u0438\u0442\u0441\u044f, \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u0437\u044f\u0442\u044c \u0438\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0440\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u044b.<\/p>\n<\/blockquote>\n<p>\u042f \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u043c\u0438\u043d\u0438\u043c\u0443\u043c\u043e\u043c \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a. \u041f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u043b\u0430\u0441\u044c \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u043d\u0430 &#8212; <a href=\"https:\/\/www.npmjs.com\/package\/utimes\" rel=\"noopener nofollow\">utimes<\/a> \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043d\u0430 \u0444\u0430\u0439\u043b\u0430\u0445 \u0438 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430\u0445 \u043f\u043e\u0434 Windows.<\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0432\u0435\u0441\u044c\u043c\u0430 \u043f\u0440\u043e\u0441\u0442:<\/p>\n<ul>\n<li>\n<p>\u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0437\u0430\u0434\u0430\u0447 <code>tasks<\/code>, \u043f\u043e\u043a\u0430 \u043e\u043d\u0430 \u043d\u0435 \u043e\u043f\u0443\u0441\u0442\u0435\u0435\u0442, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 &#171;\u043a\u043e\u0440\u043d\u044f&#187; <code>\/disk<\/code> (\u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0430\u044f \u043f\u0430\u043f\u043a\u0430 &#8212; \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u0435\u0435)<\/p>\n<\/li>\n<li>\n<p>\u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447\u0438-\u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 (<code>type == 'dir'<\/code>) \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438 \u043f\u043e 40 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0441\u0435 \u043b\u0435\u0436\u0430\u0449\u0438\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u043d\u0430\u0447\u0430\u043b\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0437\u0430\u0434\u0430\u0447<\/p>\n<\/li>\n<li>\n<p>\u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447\u0438-\u0444\u0430\u0439\u043b\u0430  (<code>type == 'file'<\/code>) \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442, \u0438 \u0435\u0441\u043b\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u043c &#8212; \u0432\u044b\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u0432 \u0446\u0435\u043b\u0435\u0432\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435<\/p>\n<\/li>\n<li>\n<p>\u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u043a \u0444\u0430\u0439\u043b\u0443 \u0441\u043b\u0443\u0447\u0430\u044e\u0442\u0441\u044f \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u044b, HTTP 500 \u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u0440\u044b\u0432 \u0432 \u0445\u043e\u0434\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 &#8212; \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0435\u043b\u0430\u0435\u043c \u043f\u0430\u0440\u0443 \u043f\u043e\u043f\u044b\u0442\u043e\u043a, \u043f\u043e\u043a\u0430 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432\u0435\u0441\u044c \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0439 \u043e\u0431\u044a\u0435\u043c \u0444\u0430\u0439\u043b\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0434\u0438\u0441\u043a \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e\u043c \u0441\u0435\u0442\u0435\u0432\u043e\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 <strong>\u0442\u0435\u043b\u043e \u0444\u0430\u0439\u043b\u0430 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u043e &#171;\u0447\u0430\u043d\u043a\u0430\u043c\u0438&#187; \u043f\u0438\u0448\u0435\u0442\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b<\/strong> \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u0434\u0438\u0441\u043a\u0435, \u0430 \u043f\u043e\u0442\u043e\u043c \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043a\u0443\u0434\u0430 \u043d\u0430\u0434\u043e.<\/p>\n<pre><code class=\"javascript\">\/\/ yad-dl.js\/\/ \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0437\u0430\u0434\u0430\u0447const tasks = [  {    id     : '\/disk\/'  , type   : 'dir'  , path   : '\/disk' \/\/ \u043e\u0442\u043a\u0443\u0434\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435  , name   : 'disk'  , depth  : 0  , target : 'Z:\\\\#ya.dsk.dump' \/\/ \u0446\u0435\u043b\u0435\u0432\u0430\u044f \u043f\u0430\u043f\u043a\u0430 \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u0434\u0438\u0441\u043a\u0435  }];\/\/ \u0440\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u044b \u0441\u0435\u0441\u0441\u0438\u0438const headers = {  ...,  \"Referer\": \"https:\/\/disk.yandex.ru\/client\/disk\"};const reqJSON = {  sk            : '...:...', connection_id : '...'};const path = require('node:path');const fs = require('node:fs');const {Readable, Transform} = require('node:stream');const {pipeline} = require('node:stream\/promises');const {utimes} = require('utimes');\/\/ \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u0443\u0435\u043c \u0442\u0430\u0439\u043c\u0441\u0442\u0430\u043c\u043f \u0432 \u0443\u0431\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435Date.prototype.toTimeStringEx = function() {  return `${this.getFullYear()}-${(this.getMonth() + 1).toString().padStart(2, '0')}-${this.getDate().toString().padStart(2, '0')} ${this.getHours().toString().padStart(2, '0')}:${this.getMinutes().toString().padStart(2, '0')}:${this.getSeconds().toString().padStart(2, '0')}.${this.getMilliseconds().toString().padStart(3, '0')}`;};\/\/ \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438const filestat = {  skip  : 0, dump  : 0, error : 0};\/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043f\u0430\u043f\u043a\u0443const temp = fs.mkdtempSync('yad-dl');(async () =&gt; {  \/\/ \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0437\u0430\u0434\u0430\u0447\u0438 \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043f\u043e \u043e\u0431\u043d\u043e\u0439  do {    const task = tasks.shift();    if (!task) {      break;    }    task.name = task.name.replaceAll(\/[\\:\\?\\\"]\/g, '+'); \/\/ \u0443\u0431\u0438\u0440\u0430\u0435\u043c \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u0438\u0437 \u0438\u043c\u0435\u043d\u0438    task.target = path.join(task.target, task.name);    console.log(`${new Date().toTimeStringEx()} | -- ${task.type == 'file' ? 'f' : 'd'} : ${JSON.stringify(task.path)}`);    console.log(`${new Date().toTimeStringEx()} | -- --- ${JSON.stringify(task.target)}`);    \/\/ \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u0430\u043f\u043a\u0438    if (task.type == 'dir') {      \/\/ \u0435\u0441\u043b\u0438 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u043f\u0430\u043f\u043a\u0438 \u0435\u0449\u0435 \u043d\u0435\u0442 - \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0435\u0435 \u0438 \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0432\u0440\u0435\u043c\u0435\u043d\u0438      if (!fs.existsSync(task.target)) {        try {          fs.mkdirSync(task.target);        }        catch (e) {          console.log(`${new Date().toTimeStringEx()} | mkdir`, e);        }        await utimes(task.target, {          btime : (task.ctime ?? 0) * 1000        , mtime : (task.mtime ?? 0) * 1000        , atime : (task.utime ?? 0) * 1000        });      }      else {        console.log(`${new Date().toTimeStringEx()} | -- -- : skip mkdir`);      }      \/\/ \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \"\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438\" \u043f\u043e 40 \u0448\u0442\u0443\u043a      const nested = [];      const amount = 40;      do {        console.log(`${new Date().toTimeStringEx()} | -- -- : get offset : ${nested.length.toString().padStart(9)}`);        const res = await fetch(          'https:\/\/disk.yandex.ru\/models-v2?m=mpfs\/resources'        , {            headers          , method : 'POST'          , body   : JSON.stringify({              ...reqJSON              , apiMethod     : 'mpfs\/resources'              , requestParams : {                  sort       : 'name'                , order      : '1'                , idContext  : task.path                , amount                , offset     : nested.length                , with_share : '1'                }            })          }        );        const {resources} = await res.json();        console.log(`${new Date().toTimeStringEx()} | -- -- : segment-sz : ${resources.length.toString().padStart(9)}`);        nested.push(...resources);        if (resources.length &lt; amount) {          break;        }      }      while (true);      \/\/ \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432\u0441\u0435\u043c \"\u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c\" \u0437\u0430\u0434\u0430\u0447\u0430\u043c \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u043d\u0430\u0447\u0430\u043b\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u0438      nested.forEach(item =&gt; item.target = task.target);      tasks.unshift(...nested);    }    \/\/ \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0444\u0430\u0439\u043b\u0430    if (task.type == 'file') {      console.log(`${new Date().toTimeStringEx()} | -- -- : vol = ${task.meta.size.toString().padStart(10)}`);      \/\/ \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c, \u0435\u0441\u043b\u0438 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0444\u0430\u0439\u043b \u0443\u0436\u0435 \u0435\u0441\u0442\u044c, \u0438 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430      let need = !fs.existsSync(task.target);      if (!need) {        const {size} = fs.statSync(task.target);        need ||= size != task.meta.size;        if (need) {          fs.rmSync(task.target); \/\/ \u0435\u0441\u043b\u0438 \u0440\u0430\u0437\u043c\u0435\u0440 \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u043b - \u0437\u0430\u0447\u0438\u0449\u0430\u0435\u043c        }        else {          console.log(`${new Date().toTimeStringEx()} | -- -- : skip file`);          filestat.skip++;        }      }      if (need) {        console.log(`${new Date().toTimeStringEx()} | -- -- : get storage : ${JSON.stringify(task.path)}`);        \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c URL \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0444\u0430\u0439\u043b\u0443        const res = await fetch(          'https:\/\/disk.yandex.ru\/models-v2?m=mpfs\/url'        , {            headers          , method : 'POST'          , body   : JSON.stringify({              ...reqJSON            , apiMethod     : 'mpfs\/url'            , requestParams : {                path : task.path              }            })          }        );        const data = await res.json();        if (data.file) {          let retry = 2; \/\/ \u0434\u043e 2 \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438          let success;          do {            console.log(`${new Date().toTimeStringEx()} | -- -- : rcv storage : ${data.file}`);            const res = await fetch('https:' + data.file, {              headers            , method : 'GET'            })              .catch(e =&gt; {                console.log(`${new Date().toTimeStringEx()} | GET`, e);              });            if (res?.status == 200) {              const tempfile = path.join(temp, task.name);              console.log(`${new Date().toTimeStringEx()} | -- -- : rcv data | ${tempfile}`);              \/\/ \u0441\u0447\u0438\u0442\u0430\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043c \u0444\u0430\u0439\u043b\u0430 \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u0432 \u043b\u043e\u0433 \u0440\u0430\u0437 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443              const tsb = Date.now();              let size = 0;              let tsl = tsb;              const monitor = new Transform({                transform(chunk, encoding, callback) {                  size += chunk.length;                  const tse = Date.now();                  if (tse &gt;= tsl + 1000 || size == task.meta.size) {                    console.log(`${new Date().toTimeStringEx()} | -- -- : rcv = ${size.toString().padStart(10)} (${(size\/task.meta.size * 100).toFixed(2).padStart(6)}%) | ${(size\/((tse - tsb)\/1000)\/1024\/1024).toFixed(2).padStart(6)} MB\/s | ETA = ${new Date(tse + (tse - tsb)\/size * (task.meta.size - size)).toTimeStringEx()}`);                    tsl = tse;                  }                  this.push(chunk);                  callback();                }              });              try {                \/\/ \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u0442\u043e\u043a \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0447\u0435\u0440\u0435\u0437 \u043d\u0430\u0448 \u043c\u043e\u043d\u0438\u0442\u043e\u0440 \u0432\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b                await pipeline(                  Readable.fromWeb(res.body)                   .on('error', e =&gt; {                     console.log(`${new Date().toTimeStringEx()} | bodyStream`, e);                   })                , monitor                , fs.createWriteStream(tempfile, {flags : 'wx'})                )                  .catch(e =&gt; {                    console.log(`${new Date().toTimeStringEx()} | finished`, e);                  });                \/\/ \u0435\u0441\u043b\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u043c - \u043f\u0435\u0440\u0435\u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0432 \u0446\u0435\u043b\u0435\u0432\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435                if (size == task.meta.size) {                  console.log(`${new Date().toTimeStringEx()} | -- -- : cpy = ${task.target}`);                  fs.copyFileSync(tempfile, task.target);                  await utimes(task.target, {                    btime : task.ctime * 1000                  , mtime : task.mtime * 1000                  , atime : task.utime * 1000                  });                  const tse = Date.now();                  console.log(`${new Date().toTimeStringEx()} | -- -- : mov = ${size.toString().padStart(10)} (${(size\/task.meta.size * 100).toFixed(2).padStart(6)}%) | ${(size\/((tse - tsl)\/1000)\/1024\/1024).toFixed(2).padStart(6)} MB\/s |`);                  success = true;                  filestat.dump++;                }                else {                  console.log(`${new Date().toTimeStringEx()} | -- -- : neq sizes : ${size} != ${task.meta.size}`);                }              }              catch (e) {                console.log(`${new Date().toTimeStringEx()} | catch`, e);              }              fs.rmSync(tempfile);            }            else {              console.log(`${new Date().toTimeStringEx()} | -- -- : ${res?.status} - ${res?.statusText}`);            }          }          while (!success &amp;&amp; --retry);          if (!success) {            \/\/ \u0444\u0430\u0439\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c, \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0432 STDERR            console.error(`${new Date().toTimeStringEx()} | ${task.path}`);            filestat.error++;          }        }        else {          console.log(data);        }      }    }  } while (true);  console.log(`${new Date().toTimeStringEx()} | finish | skip : ${filestat.skip}, dump : ${filestat.dump}, error : ${filestat.error}`);})();<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <a href=\"https:\/\/habr.com\/ru\/news\/1100492\/\" rel=\"noopener nofollow\">\u0447\u0430\u0441\u0442\u044c \u0444\u0430\u0439\u043b\u043e\u0432 \u0432\u0441\u0435 \u0435\u0449\u0435 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430<\/a>, \u043d\u043e \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e &#171;\u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f&#187;, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442. \u042f \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u0441\u0434\u0435\u043b\u0430\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 <code>bat<\/code>-\u0444\u0430\u0439\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u043d\u043e\u0432\u0443\u044e \u043f\u0430\u0440\u0443 <code>log\/err<\/code>-\u0444\u0430\u0439\u043b\u043e\u0432 \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0441\u0440\u0430\u0437\u0443 \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u0435\u0449\u0435 \u043d\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043b\u043e\u0441\u044c \u0432 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437:<\/p>\n<pre><code class=\"bash\">@echo offfor \/f \"tokens=2 delims==\" %%i in ('wmic OS Get localdatetime \/value') do set \"dt=%%i\"set \"timestamp=%dt:~0,14%\"node yad-dl.js &gt;_log-%timestamp% 2&gt;_err-%timestamp%<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<h2>\u0412\u043c\u0435\u0441\u0442\u043e \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f<\/h2>\n<p>\u041f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u043d\u043e\u0432\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a \u0441\u043a\u0440\u0438\u043f\u0442 \u043f\u0440\u0438\u043d\u043e\u0441\u0438\u0442 \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u043e\u0432\u044b\u0435, \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044f\u0445, \u0444\u0430\u0439\u043b\u044b &#8212; \u0442\u0430\u043a \u0447\u0442\u043e, \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043a\u043e\u043b\u043b\u0435\u0433\u0430\u043c \u0438\u0437 \u042f\u043d\u0434\u0435\u043a\u0441\u0430, \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0432\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0438 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u043d\u043e \u0443 \u043c\u0435\u043d\u044f \u043e\u043d \u0442\u0430\u043a \u0438 \u043d\u0435 \u0441\u043c\u043e\u0433 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0443\u0442\u0438\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043a\u0430\u043d\u0430\u043b\u0430 \u0432\u044b\u0448\u0435 1Mbps. \u042d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u044b \u0436\u0435 \u0441\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u043c \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0438, \u0447\u0442\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u0444\u0430\u0439\u043b\u044b \u043e\u0442\u0434\u0430\u044e\u0442\u0441\u044f \u0445\u043e\u0442\u044c \u0438 \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u0443\u0440\u043e\u0432\u043d\u044f\u0445 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438, \u0437\u0430\u0442\u043e \u043e\u0442 1.5Mbps <strong>\u0434\u043e 50Mbps<\/strong> (\u0432\u0438\u0434\u0438\u043c\u043e, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0426\u041e\u0414).<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/extt\/77\/f4\/74\/77f4745ded12bff2a4d9bb4a3bba1017.png\" alt=\"\u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u043e\u0432 \u0441 \u0414\u0438\u0441\u043a\u0430\" title=\"\u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u043e\u0432 \u0441 \u0414\u0438\u0441\u043a\u0430\" width=\"1787\" height=\"1486\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/extt\/77\/f4\/74\/77f4745ded12bff2a4d9bb4a3bba1017.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/extt\/77\/f4\/74\/77f4745ded12bff2a4d9bb4a3bba1017.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u043e\u0432 \u0441 \u0414\u0438\u0441\u043a\u0430<\/figcaption><\/div>\n<\/figure>\n<\/div>\n<p>\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\/1101968\/\">https:\/\/habr.com\/ru\/articles\/1101968\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0415\u0441\u043b\u0438 \u0432\u0430\u0448\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043b\u0435\u0436\u0430\u0442 \u0432 &#171;\u043e\u0431\u043b\u0430\u043a\u0435&#187; &#8212; \u044d\u0442\u043e \u043d\u0435 \u0432\u0430\u0448\u0438 \u0434\u0430\u043d\u043d\u044b\u0435.\u0418\u0442\u0430\u043a, \u0432\u0432\u043e\u0434\u043d\u044b\u0435:\u0435\u0441\u0442\u044c \u042f\u043d\u0434\u0435\u043a\u0441.\u0414\u0438\u0441\u043a \u043e\u0431\u044a\u0435\u043c\u043e\u043c ~500GB, \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0439 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0444\u043e\u0442\u043e (RAW \u0438 JPEG) \u0438 \u0432\u0438\u0434\u0435\u043e\u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0444\u0430\u0439\u043b\u043e\u0432 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 web-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043d\u0430 \u043f\u043e\u043b\u043d\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438\u0435\u0441\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u0435\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0434\u0438\u0441\u043a, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0412\u0440\u043e\u0434\u0435 \u0431\u044b \u0440\u043e\u0432\u043d\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438 \u043d\u0443\u0436\u0435\u043d \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0438\u0435\u043d\u0442 &#8212; \u043d\u043e \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u043e\u043d \u043f\u043e\u0432\u0435\u043b \u0441\u0435\u0431\u044f \u043a\u0440\u0430\u0439\u043d\u0435 \u0441\u0442\u0440\u0430\u043d\u043d\u043e:\u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0446\u0435\u043b\u0435\u0432\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u043d\u0438 \u043d\u0430 \u043a\u0430\u043a\u043e\u043c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u0434\u0438\u0441\u043a\u0435, \u043a\u0440\u043e\u043c\u0435 C: \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u043f\u043e\u0437\u0438\u0442\u0438\u0432\u043d\u044b\u0435 \u043d\u043e\u0432\u043e\u0441\u0442\u0438, \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e \u043d\u0430\u0442\u044b\u043a\u0430\u043b\u0441\u044f \u043d\u0430 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0438 \u0432\u043f\u0430\u0434\u0430\u043b \u0432 \u0441\u0442\u0443\u043f\u043e\u0440\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u043b\u0430 \u0436\u0435\u043b\u0430\u0442\u044c \u043b\u0443\u0447\u0448\u0435\u0433\u043e\u041f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0431\u0440\u0430\u0442\u044c \u0434\u0435\u043b\u043e \u0432 \u0441\u0432\u043e\u0438 \u0440\u0443\u043a\u0438, \u0430 \u0437\u0430\u043e\u0434\u043d\u043e \u043f\u043b\u043e\u0442\u043d\u0435\u0435 \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 node:streams&#8230;\u041a\u0430\u043a \u0432\u0441\u0435 \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043e &#171;\u0434\u043b\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430&#187;\u041f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c API \u0414\u0438\u0441\u043a\u0430 \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c &#171;\u0440\u043e\u0434\u043d\u043e\u0439&#187; \u043a\u043b\u0438\u0435\u043d\u0442 \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441\u043e\u0432\u0441\u0435\u043c &#8212; \u043b\u0443\u0447\u0448\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 web-\u043a\u043b\u0438\u0435\u043d\u0442 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435, \u0438 \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u0435\u043c\u0441\u044f \u043f\u0440\u0438\u043a\u0438\u043d\u0443\u0442\u044c\u0441\u044f \u0438\u043c.\u0412 \u043e\u0431\u0449\u0435\u043c-\u0442\u043e \u043e\u0442 \u043d\u0430\u0441 \u043d\u0438\u043a\u0442\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442, \u0438 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435\u0433\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0438\u043f\u043e\u0432 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439.\u041b\u0438\u0441\u0442\u0438\u043d\u0433 \u0440\u0430\u0437\u0434\u0435\u043b\u0430\u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043b\u044e\u0431\u043e\u0433\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0430, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f POST-\u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 https:\/\/disk.yandex.ru\/models-v2?m=mpfs\/resources.\u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b:{  sort       : &#8216;name&#8217;  \/\/ \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430 \u043f\u043e \u0438\u043c\u0435\u043d\u0438, order      : &#8216;1&#8217;, idContext  : &#8216;\/disk&#8217; \/\/ path \u0434\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430, amount     : 40      \/\/ \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435, offset     : 0       \/\/ \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0439 \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442}Web-\u043a\u043b\u0438\u0435\u043d\u0442 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043a\u0438 \u0444\u0430\u0439\u043b\u043e\u0432 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438 \u043f\u043e 40 \u0448\u0442\u0443\u043a, \u0438 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043d\u0430\u0440\u0443\u0448\u0430\u0442\u044c \u044d\u0442\u0443 \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u044e.\u0412 \u043e\u0442\u0432\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c JSON-\u043c\u0430\u0441\u0441\u0438\u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441 \u0432\u043f\u043e\u043b\u043d\u0435 \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439:{  type  : &#171;dir&#187;              \/\/ \u0442\u0438\u043f \u043e\u0431\u044a\u0435\u043a\u0442\u0430: &#8216;dir&#8217; \u0438\u043b\u0438 &#8216;file&#8217;, id    : &#171;\/disk\/My Folder\/&#187; \/\/ \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443 \u043d\u0430 \u0414\u0438\u0441\u043a\u0435, name  : &#171;My Folder&#187;        \/\/ \u0438\u043c\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430, path  : &#171;\/disk\/My Folder&#187;  \/\/ \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443 \u043d\u0430 \u0414\u0438\u0441\u043a\u0435, \u0435\u0449\u0435 \u0440\u0430\u0437, meta  : {    size : 123456            \/\/ \u0440\u0430\u0437\u043c\u0435\u0440 &#8212; \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u0430  }  \/\/ \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f, \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, &#8230; \u0432 Unix Timestamp, ctime : &#8230;, mtime : &#8230;, utime : &#8230;}\u041f\u0443\u0442\u044c \u043a \u0444\u0430\u0439\u043b\u0443\u0415\u0449\u0435 \u043e\u0434\u0438\u043d POST-\u0437\u0430\u043f\u0440\u043e\u0441, \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 https:\/\/disk.yandex.ru\/models-v2?m=mpfs\/url \u0441 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c path \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043d\u0430\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c URL \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u0430:{  file : &#171;\/\/downloader.disk.yandex.ru\/disk\/&#8230;&#187;}\u0422\u0435\u043b\u043e \u0444\u0430\u0439\u043b\u0430\u041e\u0431\u0440\u0430\u0442\u0438\u0432\u0448\u0438\u0441\u044c \u043a \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u043c\u0443 URL, \u0442\u0435\u043f\u0435\u0440\u044c \u0443\u0436\u0435 GET-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c HTTP 302-\u0440\u0435\u0434\u0438\u0440\u0435\u043a\u0442 \u0441 \u0430\u0434\u0440\u0435\u0441\u043e\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0435:location : https:\/\/mds.storage.yandex.net\/rdisk\/&#8230;\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0442\u0430\u043c \u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0438\u0441\u043a\u043e\u043c\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442.\u0417\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b &#171;\u043f\u0440\u0438\u0442\u0432\u043e\u0440\u044f\u0442\u044c\u0441\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u043c&#187; \u0443\u0441\u043b\u043e\u0432\u043d\u043e-\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e, \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 \u043b\u044e\u0431\u043e\u0433\u043e \u0438\u0437 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044b\u0445 \u0432\u044b\u0448\u0435 POST-\u0437\u0430\u043f\u0440\u043e\u0441\u0430 &#8212; \u0438\u0445 \u043b\u0435\u0433\u043a\u043e \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u044f\u043c\u043e \u0438\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430:\u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u041d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0441\u0430\u043c\u0438 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 (headers) \u0438 \u0434\u0432\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u0432 body: sk \u0438 connection_id.\u0414\u0430\u043d\u043d\u044b\u0435 \u0441\u0435\u0441\u0441\u0438\u0438 (sk \/ connection_id) &#171;\u043f\u0440\u043e\u0442\u0443\u0445\u0430\u044e\u0442&#187; \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u0441\u0443\u0442\u043a\u0438 \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0441\u043b\u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0443 \u0432\u0430\u0441 \u043c\u043d\u043e\u0433\u043e &#8212; \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043e\u0442\u0432\u0430\u043b\u0438\u0442\u0441\u044f, \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u0437\u044f\u0442\u044c \u0438\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0440\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u044b.\u042f \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u043c\u0438\u043d\u0438\u043c\u0443\u043c\u043e\u043c \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a. \u041f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u043b\u0430\u0441\u044c \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u043d\u0430 &#8212; utimes \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043d\u0430 \u0444\u0430\u0439\u043b\u0430\u0445 \u0438 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430\u0445 \u043f\u043e\u0434 Windows.\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0432\u0435\u0441\u044c\u043c\u0430 \u043f\u0440\u043e\u0441\u0442:\u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0437\u0430\u0434\u0430\u0447 tasks, \u043f\u043e\u043a\u0430 \u043e\u043d\u0430 \u043d\u0435 \u043e\u043f\u0443\u0441\u0442\u0435\u0435\u0442, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 &#171;\u043a\u043e\u0440\u043d\u044f&#187; \/disk (\u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0430\u044f \u043f\u0430\u043f\u043a\u0430 &#8212; \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u0435\u0435)\u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447\u0438-\u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 (type == &#8216;dir&#8217;) \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438 \u043f\u043e 40 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0441\u0435 \u043b\u0435\u0436\u0430\u0449\u0438\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u043d\u0430\u0447\u0430\u043b\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0437\u0430\u0434\u0430\u0447\u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447\u0438-\u0444\u0430\u0439\u043b\u0430  (type == &#8216;file&#8217;) \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442, \u0438 \u0435\u0441\u043b\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u043c &#8212; \u0432\u044b\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u0432 \u0446\u0435\u043b\u0435\u0432\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435\u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u043a \u0444\u0430\u0439\u043b\u0443 \u0441\u043b\u0443\u0447\u0430\u044e\u0442\u0441\u044f \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u044b, HTTP 500 \u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u0440\u044b\u0432 \u0432 \u0445\u043e\u0434\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 &#8212; \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0435\u043b\u0430\u0435\u043c \u043f\u0430\u0440\u0443 \u043f\u043e\u043f\u044b\u0442\u043e\u043a, \u043f\u043e\u043a\u0430 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432\u0435\u0441\u044c \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0439 \u043e\u0431\u044a\u0435\u043c \u0444\u0430\u0439\u043b\u0430\u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0434\u0438\u0441\u043a \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e\u043c \u0441\u0435\u0442\u0435\u0432\u043e\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0435\u043b\u043e \u0444\u0430\u0439\u043b\u0430 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u043e &#171;\u0447\u0430\u043d\u043a\u0430\u043c\u0438&#187; \u043f\u0438\u0448\u0435\u0442\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u0434\u0438\u0441\u043a\u0435, \u0430 \u043f\u043e\u0442\u043e\u043c \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043a\u0443\u0434\u0430 \u043d\u0430\u0434\u043e.\/\/ yad-dl.js\/\/ \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0437\u0430\u0434\u0430\u0447const tasks = [  {    id     : &#8216;\/disk\/&#8217;  , type   : &#8216;dir&#8217;  , path   : &#8216;\/disk&#8217; \/\/ \u043e\u0442\u043a\u0443\u0434\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435  , name   : &#8216;disk&#8217;  , depth  : 0  , target : &#8216;Z:\\\\#ya.dsk.dump&#8217; \/\/ \u0446\u0435\u043b\u0435\u0432\u0430\u044f \u043f\u0430\u043f\u043a\u0430 \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u0434\u0438\u0441\u043a\u0435  }];\/\/ \u0440\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u044b \u0441\u0435\u0441\u0441\u0438\u0438const headers = {  &#8230;,  &#171;Referer&#187;: &#171;https:\/\/disk.yandex.ru\/client\/disk&#187;};const reqJSON = {  sk            : &#8216;&#8230;:&#8230;&#8217;, connection_id : &#8216;&#8230;&#8217;};const path = require(&#8216;node:path&#8217;);const fs = require(&#8216;node:fs&#8217;);const {Readable, Transform} = require(&#8216;node:stream&#8217;);const {pipeline} = require(&#8216;node:stream\/promises&#8217;);const {utimes} = require(&#8216;utimes&#8217;);\/\/ \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u0443\u0435\u043c \u0442\u0430\u0439\u043c\u0441\u0442\u0430\u043c\u043f \u0432 \u0443\u0431\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435Date.prototype.toTimeStringEx = function() {  return `${this.getFullYear()}-${(this.getMonth() + 1).toString().padStart(2, &#8216;0&#8217;)}-${this.getDate().toString().padStart(2, &#8216;0&#8217;)} ${this.getHours().toString().padStart(2, &#8216;0&#8217;)}:${this.getMinutes().toString().padStart(2, &#8216;0&#8217;)}:${this.getSeconds().toString().padStart(2, &#8216;0&#8217;)}.${this.getMilliseconds().toString().padStart(3, &#8216;0&#8217;)}`;};\/\/ \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438const filestat = {  skip  : 0, dump  : 0, error : 0};\/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043f\u0430\u043f\u043a\u0443const temp = fs.mkdtempSync(&#8216;yad-dl&#8217;);(async () =&gt; {  \/\/ \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0437\u0430\u0434\u0430\u0447\u0438 \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043f\u043e \u043e\u0431\u043d\u043e\u0439  do {    const task = tasks.shift();    if (!task) {      break;    }    task.name = task.name.replaceAll(\/[\\:\\?\\&#187;]\/g, &#8216;+&#8217;); \/\/ \u0443\u0431\u0438\u0440\u0430\u0435\u043c \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u0438\u0437 \u0438\u043c\u0435\u043d\u0438    task.target = path.join(task.target, task.name);    console.log(`${new Date().toTimeStringEx()} | &#8212; ${task.type == &#8216;file&#8217; ? &#8216;f&#8217; : &#8216;d&#8217;} : ${JSON.stringify(task.path)}`);    console.log(`${new Date().toTimeStringEx()} | &#8212; &#8212; ${JSON.stringify(task.target)}`);    \/\/ \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u0430\u043f\u043a\u0438    if (task.type == &#8216;dir&#8217;) {      \/\/ \u0435\u0441\u043b\u0438 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u043f\u0430\u043f\u043a\u0438 \u0435\u0449\u0435 \u043d\u0435\u0442 &#8212; \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0435\u0435 \u0438 \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0432\u0440\u0435\u043c\u0435\u043d\u0438      if (!fs.existsSync(task.target)) {        try {          fs.mkdirSync(task.target);        }        catch (e) {          console.log(`${new Date().toTimeStringEx()} | mkdir`, e);        }        await utimes(task.target, {          btime : (task.ctime ?? 0) * 1000        , mtime : (task.mtime ?? 0) * 1000        , atime : (task.utime ?? 0) * 1000        });      }      else {        console.log(`${new Date().toTimeStringEx()} | &#8212; &#8212; : skip mkdir`);      }      \/\/ \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b &#171;\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438&#187; \u043f\u043e 40 \u0448\u0442\u0443\u043a      const nested = [];      const amount = 40;      do {        console.log(`${new Date().toTimeStringEx()} | &#8212; &#8212; : get offset : ${nested.length.toString().padStart(9)}`);        const res = await fetch(          &#8216;https:\/\/disk.yandex.ru\/models-v2?m=mpfs\/resources&#8217;        , {            headers          , method : &#8216;POST&#8217;          , body   : JSON.stringify({              &#8230;reqJSON              , apiMethod     : &#8216;mpfs\/resources&#8217;              , requestParams : {                  sort       : &#8216;name&#8217;                , order      : &#8216;1&#8217;                , idContext  : task.path                , amount                , offset     : nested.length                , with_share : &#8216;1&#8217;                }            })          }        );        const {resources} = await res.json();        console.log(`${new Date().toTimeStringEx()} | &#8212; &#8212; : segment-sz : ${resources.length.toString().padStart(9)}`);        nested.push(&#8230;resources);        if (resources.length &lt; amount) {          break;        }      }      while (true);      \/\/ \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432\u0441\u0435\u043c &#171;\u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c&#187; \u0437\u0430\u0434\u0430\u0447\u0430\u043c \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u043d\u0430\u0447\u0430\u043b\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u0438      nested.forEach(item =&gt; item.target = task.target);      tasks.unshift(&#8230;nested);    }    \/\/ \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0444\u0430\u0439\u043b\u0430    if (task.type == &#8216;file&#8217;) {      console.log(`${new Date().toTimeStringEx()} | &#8212; &#8212; : vol = ${task.meta.size.toString().padStart(10)}`);      \/\/ \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c, \u0435\u0441\u043b\u0438 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0444\u0430\u0439\u043b \u0443\u0436\u0435 \u0435\u0441\u0442\u044c, \u0438 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430      let need = !fs.existsSync(task.target);      if (!need) {        const {size} = fs.statSync(task.target);        need ||= size != task.meta.size;        if (need) {          fs.rmSync(task.target); \/\/ \u0435\u0441\u043b\u0438 \u0440\u0430\u0437\u043c\u0435\u0440 \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u043b &#8212; \u0437\u0430\u0447\u0438\u0449\u0430\u0435\u043c        }        else {          console.log(`${new Date().toTimeStringEx()} | &#8212; &#8212; : skip file`);          filestat.skip++;        }      }      if (need) {        console.log(`${new Date().toTimeStringEx()} | &#8212; &#8212; : get storage : ${JSON.stringify(task.path)}`);        \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c URL \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0444\u0430\u0439\u043b\u0443        const res = await fetch(          &#8216;https:\/\/disk.yandex.ru\/models-v2?m=mpfs\/url&#8217;        , {            headers          , method : &#8216;POST&#8217;          , body   : JSON.stringify({              &#8230;reqJSON            , apiMethod     : &#8216;mpfs\/url&#8217;            , requestParams : {                path : task.path              }            })          }        );        const data = await res.json();        if (data.file) {          let retry = 2; \/\/ \u0434\u043e 2 \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438          let success;          do {            console.log(`${new Date().toTimeStringEx()} | &#8212; &#8212; : rcv storage : ${data.file}`);            const res = await fetch(&#8216;https:&#8217; + data.file, {              headers            , method : &#8216;GET&#8217;            })              .catch(e =&gt; {                console.log(`${new Date().toTimeStringEx()} | GET`, e);              });            if (res?.status == 200) {              const tempfile = path.join(temp, task.name);              console.log(`${new Date().toTimeStringEx()} | &#8212; &#8212; : rcv data | ${tempfile}`);              \/\/ \u0441\u0447\u0438\u0442\u0430\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043c \u0444\u0430\u0439\u043b\u0430 \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u0432 \u043b\u043e\u0433 \u0440\u0430\u0437 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443              const tsb = Date.now();              let size = 0;              let tsl = tsb;              const monitor = new Transform({                transform(chunk, encoding, callback) {                  size += chunk.length;                  const tse = Date.now();                  if (tse &gt;= tsl + 1000 || size == task.meta.size) {                    console.log(`${new Date().toTimeStringEx()} | &#8212; &#8212; : rcv = ${size.toString().padStart(10)} (${(size\/task.meta.size * 100).toFixed(2).padStart(6)}%) | ${(size\/((tse &#8212; tsb)\/1000)\/1024\/1024).toFixed(2).padStart(6)} MB\/s | ETA = ${new Date(tse + (tse &#8212; tsb)\/size *&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-501113","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/501113","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=501113"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/501113\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=501113"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=501113"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=501113"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}