{"id":345342,"date":"2023-02-12T21:01:30","date_gmt":"2023-02-12T21:01:30","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=345342"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=345342","title":{"rendered":"<span>Chrome Headless \u043f\u0440\u043e\u0442\u0438\u0432 cloudflare JS challenge<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0431\u043e\u0440\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0441 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 &#8212; \u043e\u0431\u044b\u0447\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0434\u043b\u044f \u043b\u044e\u0434\u0435\u0439 \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0444\u0435\u0440 \u0434\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0416\u0430\u043b\u044c, \u0447\u0442\u043e \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u044b\u0432\u0430\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 GET \u0437\u0430\u043f\u0440\u043e\u0441 \u0438 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 html. \u0412\u0435\u0431-\u0441\u0430\u0439\u0442\u044b, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 \u0437\u0430\u0449\u0438\u0442\u043d\u044b\u0435 \u043c\u0435\u0440\u044b \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432. \u041e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0442\u0430\u043a\u0438\u0445 \u043c\u0435\u0440 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 cloudflare. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a cloudflare \u0432\u044b\u044f\u0432\u043b\u044f\u0435\u0442 \u0431\u043e\u0442\u043e\u0432 \u0447\u0435\u0440\u0435\u0437 javascript \u0438 \u043a\u043e\u0441\u043d\u0451\u043c\u0441\u044f \u0442\u0435\u043c\u044b \u0434\u0435\u043e\u0431\u0444\u0443\u0441\u043a\u0430\u0446\u0438\u0438 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432. \u0414\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u043a\u0438\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c \u043a <a href=\"https:\/\/habr.com\/ru\/post\/710982\/\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0441\u0442\u0443<\/a>. <\/p>\n<p>\u0417\u0430 \u043e\u0441\u043d\u043e\u0432\u0443 \u0432\u043e\u0437\u044c\u043c\u0451\u043c <a href=\"https:\/\/esfaucets.com\/\" rel=\"noopener noreferrer nofollow\">\u0440\u0430\u043d\u0434\u043e\u043c\u043d\u044b\u0439 \u0441\u0430\u0439\u0442<\/a> \u0441\u0430\u0439\u0442 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0442\u0430\u043c \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d \u0440\u0435\u0448\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u0432\u0435\u0434\u044c \u043f\u0440\u0438 \u0437\u0430\u0445\u043e\u0434\u0435 \u043c\u043d\u0435 \u0435\u0449\u0451 \u043d\u0443\u0436\u043d\u043e \u043a\u043b\u0438\u043a\u043d\u0443\u0442\u044c \u043f\u043e \u043a\u0430\u043f\u0447\u0435 &#171;cloudflare turnstile&#187;:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9c6\/0a6\/b4b\/9c60a6b4ba8295e0e753a2a82d41946a.png\" width=\"2000\" height=\"759\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9c6\/0a6\/b4b\/9c60a6b4ba8295e0e753a2a82d41946a.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041f\u0440\u043e\u0431\u0443\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0431\u044b\u0447\u043d\u044b\u0439 GET \u0437\u0430\u043f\u0440\u043e\u0441:<\/p>\n<pre><code class=\"javascript\">const { gotScraping } = require('got-scraping');  gotScraping('https:\/\/esfaucets.com\/', {   method: 'get',   useHeaderGenerator: false,   headers: {     'accept': 'text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/avif,image\/webp,image\/apng,*\/*;q=0.8,application\/signed-exchange;v=b3;q=0.9',     'accept-encoding': 'gzip, deflate, br',     'accept-language': 'ru-RU,ru;q=0.9',     'cache-control': 'no-cache',     'sec-ch-ua': '\"Not_A Brand\";v=\"99\", \"Google Chrome\";v=\"109\", \"Chromium\";v=\"109\"',     'sec-ch-ua-mobile': '?0',     'sec-ch-ua-platform': '\"Windows\"',     'sec-fetch-dest': 'document',     'upgrade-insecure-requests': '1',     'user-agent': 'Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/109.0.0.0 Safari\/537.36'   }, }).then(response => {   console.log(response.body); })<\/code><\/pre>\n<p>\u0412\u0438\u0434\u0438\u043c \u043f\u043e\u0445\u043e\u0436\u0438\u0439 HTML:<\/p>\n<details class=\"spoiler\">\n<summary>response<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ca4\/54b\/817\/ca454b81734ac1289f18f96b4fc86a20.png\" width=\"2000\" height=\"1367\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ca4\/54b\/817\/ca454b81734ac1289f18f96b4fc86a20.png\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0427\u0435\u0433\u043e-\u0442\u043e \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442\u2026<\/p>\n<p>\u0411\u0435\u0436\u0438\u043c \u0432 devtools, \u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u043a\u0440\u0443\u0442\u043a\u0438 \u0432\u0441\u0435\u0445 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u0438 \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440 \u0432 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430\u043c \u043f\u0440\u0438\u0441\u043b\u0430\u043b \u043a\u0443\u043a\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>devtools<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cac\/1bb\/3f6\/cac1bb3f6ebb0a53b7b8a92a4e98170f.png\" width=\"2000\" height=\"1585\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cac\/1bb\/3f6\/cac1bb3f6ebb0a53b7b8a92a4e98170f.png\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p> \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043a\u0443\u043a\u0438 \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a, \u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u0438 \u0432\u0438\u0434\u0438\u043c html \u043d\u0430\u0448\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b:<\/p>\n<pre><code class=\"javascript\">gotScraping('https:\/\/esfaucets.com\/', {   method: 'get',   useHeaderGenerator: false,   headers: {     'accept': 'text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/avif,image\/webp,image\/apng,*\/*;q=0.8,application\/signed-exchange;v=b3;q=0.9',     'accept-encoding': 'gzip, deflate, br',     'accept-language': 'ru-RU,ru;q=0.9',     'cache-control': 'no-cache',     'cookie': '__cf_bm=dTN3MAm6iH.wkD88zG7_.Q.alXDWj8WdmwqRJVlm5uA-1675618593-0-AdrvgMdAtvCcdOvx6JTww5K+jGDKEMw7x4uSZ2t9RCc6COMyo\/LB5en7c\/2mj3o0BvaaAsB9fR6KaTIPd8t7KGN2X1J1XJ\/PGa2bIDZUAUlJIeMjMR0Hc0uEexo3kldB+ycfvhD7Lg807gh+Z58ipTY=; cf_clearance=V3TVYDLDgOd9E.8CzxdYz54aDdHnaFtfexpOIcpSL5U-1675619126-0-250; laravel_session=eyJpdiI6InpHQzU1bVJ3cnF3aUxRRXV4SGhXR1E9PSIsInZhbHVlIjoidTYyK1Nwb3VJRjBmM3ZueEgxQWhrMjQrRHBiSU9LakxJY2laUEVwczBsY0FNbEhjZFRqcUY3NUx2azdtWUZJYnhlS1hzR05CY0VyWVg2K1JOYkRaTFBwWWZaZkRxZnVLbEN3U1JxSG94dWc5dXJqY3pcL05PZURhOFJ3a2FIb0hZIiwibWFjIjoiZTVmY2Q4NjdmZDVlN2M0MjcxZGYyOWU5YTExYTFlY2Q5NzdiMmJmNDY2YWU1ZDU4N2JlYzZhMWM2Y2UzNjZlNSJ9',     'pragma': 'no-cache',     'sec-ch-ua': '\"Not_A Brand\";v=\"99\", \"Google Chrome\";v=\"109\", \"Chromium\";v=\"109\"',     'sec-ch-ua-mobile': '?0',     'sec-ch-ua-platform': '\"Windows\"',     'sec-fetch-dest': 'document',     'sec-fetch-mode': 'navigate',     'sec-fetch-site': 'none',     'sec-fetch-user': '?1',     'upgrade-insecure-requests': '1',     'user-agent': 'Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/109.0.0.0 Safari\/537.36',   },   http2: true }).then(response => {   console.log(response.body); })<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>response<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/305\/fe9\/d23\/305fe9d23bf8fea4625f66f77b25dc59.png\" width=\"2000\" height=\"907\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/305\/fe9\/d23\/305fe9d23bf8fea4625f66f77b25dc59.png\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043a\u0443\u043a\u0438, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 \u0441\u0432\u043e\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u0445. \u041d\u043e \u043e\u043d\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u043f\u043e\u0441\u043b\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 payload-\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u0441\u043a\u0440\u0438\u043f\u0442\u0430\u043c\u0438:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c9e\/d1f\/2f0\/c9ed1f2f00e81c4331660310bf1212bd.png\" width=\"2000\" height=\"278\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c9e\/d1f\/2f0\/c9ed1f2f00e81c4331660310bf1212bd.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u0443\u043a\u0438, \u043d\u0443\u0436\u043d\u043e \u043b\u0438\u0431\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440\u0430, \u0447\u0435\u043c, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440, \u043b\u0438\u0431\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 payload-a \u0438 \u0441\u0430\u043c\u043e\u043c\u0443 \u043d\u0430\u043b\u0435\u0442\u0443 \u0435\u0433\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0412\u0442\u043e\u0440\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u0440\u043e\u0441\u0442 \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u0442\u0430\u043a \u043a\u0430\u043a \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u0443 \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440\u0430 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0435, \u0442\u043e \u0435\u0441\u0442\u044c \u0441 \u043a\u0430\u0436\u0434\u044b\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0447\u0442\u043e-\u0442\u043e \u043d\u043e\u0432\u0435\u043d\u044c\u043a\u043e\u0435, \u043d\u043e, \u0442\u0430\u043a \u0443\u0436 \u0431\u044b\u0432\u0430\u0435\u0442, \u0432\u0430\u0440\u0438\u0430\u0446\u0438\u0439 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e, \u0438 \u044d\u0442\u043e \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0440 \u0434\u043b\u044f \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u0442\u0432\u0430.<\/p>\n<p>\u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043e\u0431\u0441\u0443\u0434\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0441 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432. \u0415\u0441\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044b \u043a \u0442\u043e\u043c\u0443, \u043a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c:<\/p>\n<ul>\n<li>\n<p>\u041c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u043e\u0431\u0438\u0435 <a href=\"https:\/\/www.npmjs.com\/package\/jsdom\" rel=\"noopener noreferrer nofollow\">JSDOM<\/a> \u0432 NodeJS, \u0434\u0430\u0431\u044b \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u201c\u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435\u201d \u0442\u0435\u043c, \u0447\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u0441\u043a\u0440\u0438\u043f\u0442\u044b, \u043d\u043e \u0432 \u0442\u0430\u043a\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435 \u0435\u0441\u0442\u044c \u043c\u0438\u043d\u0443\u0441\u044b: <\/p>\n<ul>\n<li>\n<p>\u0421\u0440\u0435\u0434\u0430 NodeJS \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435, \u0438, \u0435\u0441\u043b\u0438 \u0432\u044b \u0447\u0442\u043e-\u0442\u043e \u0443\u043f\u0443\u0441\u0442\u0438\u0442\u0435, \u0442\u043e \u0441 \u0432\u0430\u0448\u0438\u043c \u041f\u041a \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0439\u0442\u0438 \u0447\u0442\u043e-\u0442\u043e \u043d\u0435 \u0442\u0430\u043a. \u042d\u0442\u043e \u043d\u0435 \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440\u0430, \u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u043a\u043e\u0441\u043d\u0443\u0442\u044c\u0441\u044f \u0432\u0430\u0441, \u0435\u0441\u043b\u0438 \u0432\u044b \u0432\u043e\u0437\u044c\u043c\u0451\u0442\u0435 \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u0441\u043a\u0440\u0438\u043f\u0442 \u0438\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0438 \u0440\u0435\u0448\u0438\u0442\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u043c\u0435\u0441\u0442\u0435.<\/p>\n<\/li>\n<li>\n<p>JSDOM \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u043d\u0430 JavaScript. \u041c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0438 \u0441 DOM \u0438 \u0441\u0432\u043e\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u044b\u0445 \u0430\u043f\u0438 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e. \u041c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435, \u0447\u0435\u043c \u0432 \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435.<\/p>\n<\/li>\n<li>\n<p>Cloudflare \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u0432\u043e\u044e \u043a\u0430\u043f\u0447\u0443, \u0430 \u0438\u043d\u043e\u0433\u0434\u0430 \u0438 h-\u043a\u0430\u043f\u0447\u0443, \u0430 \u044d\u0442\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e-\u0442\u0430\u043a\u0438 \u0441\u0435\u0440\u044c\u0451\u0437\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043d\u043e\u0433\u043e\u0433\u043e \u0442\u0440\u0435\u0431\u0443\u044e\u0442. \u0421\u043b\u0438\u0448\u043a\u043e\u043c \u0434\u043e\u043b\u0433\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u043e\u0431\u0451\u0440\u0442\u043a\u0443.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u041e\u0431\u044b\u0447\u043d\u044b\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0441 \u043b\u0451\u0433\u043a\u043e\u0441\u0442\u044c\u044e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442 \u0432\u0441\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u043e\u0442 \u0431\u0440\u0430\u0443\u0437\u0435\u0440, \u0447\u0442\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 playwright \u0438\u043b\u0438 \u0432 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0445<\/p>\n<ul>\n<li>\n<p>Headless \u0440\u0435\u0436\u0438\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430. \u0422\u0430\u043a\u043e\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043d\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0438 \u043b\u0435\u0433\u0447\u0435. \u0417\u0432\u0443\u0447\u0438\u0442 \u043f\u043e\u043b\u0443\u0447\u0448\u0435, \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u044d\u0442\u043e \u043d\u0430\u0448 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043a\u0443\u043a.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0430\u043d\u0442\u0438\u0431\u043e\u0442\u043e\u0432 \u043d\u0430\u0446\u0435\u043b\u0435\u043d\u044b \u043d\u0430 \u0432\u044b\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u0443\u0435\u043c\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439. \u0412 \u044d\u0442\u043e\u043c \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f headless-\u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430. \u0412\u044b\u0445\u043e\u0434\u0438\u0442, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043a\u0430\u043a-\u0442\u043e \u0437\u0430\u043c\u0430\u0441\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043f\u043e\u0434 \u043e\u0431\u044b\u0447\u043d\u044b\u0439. \u041d\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0432\u044b\u044f\u0432\u0438\u0442\u044c \u0431\u043e\u0442\u0430 \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0447\u0435\u0440\u0435\u0437 JavaScript \u0442\u0430\u043a \u043c\u043d\u043e\u0433\u043e, \u0447\u0442\u043e \u0432\u0441\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u0435\u043b\u0430\u0435\u0442 cloudflare. \u0427\u0442\u043e\u0431\u044b \u0441 \u044d\u0442\u0438\u043c \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442\u044b, \u043d\u043e \u0432\u043e\u0442 \u043d\u0435 \u0437\u0430\u0434\u0430\u0447\u0430, \u043e\u043d\u0438 \u043e\u0431\u0444\u0443\u0441\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u044b\u2026 <br \/>\u0412 \u043e\u0431\u0449\u0435\u043c, \u043a\u043e\u0432\u044b\u0440\u044f\u044f devtools, \u0432\u0438\u0434\u0438\u043c \u0442\u0430\u043a\u0438\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0441\u0442\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>devtools<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/532\/51f\/bde\/53251fbdee400a81009b1381d49c0bdc.gif\" width=\"905\" height=\"818\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/532\/51f\/bde\/53251fbdee400a81009b1381d49c0bdc.gif\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0447\u0442\u043e-\u0442\u043e \u0438\u0437 <code>JSON<\/code>. \u0411\u043b\u0430\u0433\u043e \u0432 \u044d\u0442\u043e\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0435 \u0434\u0432\u0430 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u0430 &#8212; <code>parse<\/code> \u0438 <code>stringify<\/code>. \u0410 \u0435\u0449\u0451 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>eval<\/code> \u0438\u043b\u0438 <code>new Function(\u2026)()<\/code>, \u0438 \u0441\u043a\u0440\u0438\u043f\u0442 \u0442\u0430\u043c \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043d\u043e \u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u043e\u2026<\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f JSON. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 <code>addInitScript()<\/code> \u0432 playwright, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u043a\u043e\u0434 \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u0432\u0441\u0435\u0445 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432:<\/p>\n<pre><code class=\"javascript\">const playwright = require('playwright');  const browserOptions = {   ignoreHTTPSErrors: true,   headless: false, };  (async () => {   const browser = await playwright.chromium.launch(browserOptions);   const context = await browser.newContext({     colorScheme: 'dark'   });    const page = await context.newPage();    await context.addInitScript(`     const jsonStringify = JSON.stringify;     JSON.stringify = function() {       console.log(arguments);       return jsonStringify.apply(null, arguments);     }   `);    await page.goto('https:\/\/esfaucets.com\/'); })();<\/code><\/pre>\n<p>\u0412\u0438\u0434\u0438\u043c \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u043e\u0447\u0435\u043d\u044c \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442:<\/p>\n<details class=\"spoiler\">\n<summary>fingerprint<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e84\/500\/e58\/e84500e5864b679801f66dc87e9e2921.png\" width=\"2000\" height=\"2327\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e84\/500\/e58\/e84500e5864b679801f66dc87e9e2921.png\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0418\u0437-\u0437\u0430 \u0441\u0431\u043e\u0440\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043d\u0430\u0448 \u201c\u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u044b\u0439 \u043e\u0442\u043f\u0435\u0447\u0430\u0442\u043e\u043a\u201d. \u0421\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u043e\u043d \u043a\u043e\u0434\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 payload.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043d\u0430\u0436\u0430\u0442\u044c \u043d\u0430 \u043a\u0430\u043f\u0447\u0443 \u0432 \u201c\u0433\u043e\u043b\u043e\u043c\u201d playwright, \u0442\u043e \u043f\u043e\u043f\u0430\u0434\u0451\u043c \u0432 \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u201ccloudflare endless loop\u201d. \u041d\u0430\u0441 \u043d\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0442. \u0412\u0438\u0434\u0438\u043c\u043e, \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440 \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f.<\/p>\n<p>\u041e\u0434\u0438\u043d \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0445 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u0432\u043e\u0439c\u0442\u0432\u0430 navigator.webdriver. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f:<\/p>\n<pre><code class=\"javascript\">await context.addInitScript(`   Object.defineProperty(Object.getPrototypeOf(navigator), 'webdriver', {     get: () => false   }) `);<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u041d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u044b\u0439 \u0438 \u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7a8\/84a\/991\/7a884a99164e5e7265003fdc477b4f6d.gif\" width=\"784\" height=\"619\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7a8\/84a\/991\/7a884a99164e5e7265003fdc477b4f6d.gif\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/summary>\n<div class=\"spoiler__content\">\n<p> \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0442\u0430\u043a\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043e\u0447\u0435\u043d\u044c \u043b\u0435\u0433\u043a\u043e \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c:<\/p>\n<pre><code class=\"javascript\">Object.getOwnPropertyDescriptor(   Object.getPrototypeOf(navigator), 'webdriver' ).get.toString() \/\/'function get webdriver() { [native code] }' \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \/\/ '() => false' \u0443 \u043d\u0430\u0441  Navigator.prototype.webdriver \/\/ Uncaught TypeError: Illegal invocation \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \/\/ false \u0443 \u043d\u0430\u0441  Object.getOwnPropertyDescriptor(   Object.getPrototypeOf(navigator), 'webdriver' ).get.name \/\/ 'get webdriver' \/\/ 'get'<\/code><\/pre>\n<p>\u0418 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435 \u0438 \u0442\u043e\u043c\u0443 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435&#8230; \u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u044f \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440\u0430, \u0447\u0442\u043e\u0431\u044b \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u201c\u0441\u043e\u0448\u0451\u043b \u0437\u0430 \u0441\u0432\u043e\u0435\u0433\u043e\u201d.<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u043e \u043d\u0430\u0448\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430\u044f, \u0432\u0435\u0434\u044c \u043c\u044b \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u043b headless-\u0431\u0440\u0430\u0443\u0437\u0435\u0440. \u041e\u0431\u044b\u0447\u043d\u044b\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <code>webdriver<\/code> \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u043d\u0435 \u0432\u044b\u0439\u0434\u0435\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0438\u0437\u0443\u0447\u0438\u043c \u0441\u043a\u0440\u0438\u043f\u0442 \u0438\u0437 eval. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0440\u0430\u0437\u0432\u043b\u0435\u043a\u0430\u0442\u044c\u0441\u044f \u0441 \u0434\u0435\u0431\u0430\u0433\u0433\u0435\u0440\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0443\u043b\u043e\u0432\u0438\u0442\u044c \u0441\u0443\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b:<\/p>\n<details class=\"spoiler\">\n<summary>debugger<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/387\/2f9\/79e\/3872f979e9634e561329e2df51265789.gif\" width=\"1856\" height=\"913\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/387\/2f9\/79e\/3872f979e9634e561329e2df51265789.gif\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0417\u0430 \u0432\u0441\u044f\u043a\u0438\u043c\u0438 \u0432\u044b\u0437\u043e\u0432\u0430\u043c\u0438 \u0432\u0438\u0434\u0430 <code>x[y(z)]<\/code> \u0441\u0442\u043e\u044f\u0442 \u0441\u0442\u0440\u043e\u043a\u0438, \u0438 \u044d\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0434\u043b\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0439 \u043d\u0435\u0434\u0443\u0433 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0441\u043a\u0440\u0438\u043f\u0442\u0430.<\/p>\n<h2>\u0414\u0435\u043e\u0431\u0444\u0443\u0441\u043a\u0430\u0446\u0438\u044f<\/h2>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u043e\u0432\u0435 \u043d\u0435\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u043a\u0440\u0438\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e. JS-\u0441\u043a\u0440\u0438\u043f\u0442\u044b &#8212; \u044d\u0442\u043e \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u043d\u0430\u0448\u0435\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u043d\u0430 \u043d\u0430\u0448\u0435\u043c \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0435 \u0438 \u0431\u0435\u0437 \u043d\u0430\u0448\u0435\u0433\u043e \u0432\u0435\u0434\u043e\u043c\u0430. \u041c\u044b \u0438\u043c\u0435\u0435\u043c \u043f\u0440\u0430\u0432\u043e \u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u044e\u0442 \u0442\u0430\u043a\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b.<\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u0442\u0435\u043a\u0441\u0442\u043e\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u043d\u0430\u043c \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0435\u0433\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435. \u0422\u0430\u043a\u043e\u0432\u044b\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e(AST). \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043f\u0430\u0440\u0441\u0435\u0440 <a href=\"https:\/\/babeljs.io\/\" rel=\"noopener noreferrer nofollow\">babel<\/a>, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c AST, \u0437\u0430\u0442\u0435\u043c \u043f\u043e\u0431\u0440\u043e\u0434\u0438\u043c \u043f\u043e \u0443\u0437\u043b\u0430\u043c, \u0447\u0442\u043e-\u0442\u043e \u0433\u0434\u0435-\u0442\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u043c, \u0430 \u0441\u043b\u0435\u0434\u043e\u043c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043a\u043e\u0434 \u0438\u0437 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430. (\u0415\u0441\u043b\u0438 \u0432\u044b \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435\u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 AST \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f\u043c\u0438, \u0442\u043e \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/habr.com\/ru\/post\/439564\/\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e<\/a>, <a href=\"https:\/\/lihautan.com\/step-by-step-guide-for-writing-a-babel-transformation\/\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e<\/a> \u0438 <a href=\"https:\/\/lihautan.com\/manipulating-ast-with-javascript\/\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e<\/a>).<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0447\u043d\u0451\u043c \u0441 \u0447\u0435\u0433\u043e-\u0442\u043e \u043c\u0430\u043b\u043e\u0433\u043e. \u0412\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0430\u0448 \u0441\u043a\u0440\u0438\u043f\u0442 \u0432 <a href=\"https:\/\/astexplorer.net\/\" rel=\"noopener noreferrer nofollow\">astexplorer<\/a> \u0438 \u0432\u0438\u0434\u0438\u043c \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f11\/003\/415\/f110034154c59ab0247eef0d93707673.png\" width=\"2000\" height=\"983\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f11\/003\/415\/f110034154c59ab0247eef0d93707673.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u0438\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u044b\u0447\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e. \u041f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b \u043d\u0430\u043c \u0441\u0440\u0430\u0437\u0443 \u043d\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u044d\u0442\u0438 \u0443\u0437\u043b\u044b?<\/p>\n<p>\u0427\u0442\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c?<\/p>\n<ol>\n<li>\n<p>\u041d\u0430\u0439\u0442\u0438 \u0443\u0437\u0435\u043b<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0443\u0437\u0435\u043b<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u0438\u0441\u043a \u043e\u0431\u044b\u0447\u043d\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439. \u0413\u043b\u044f\u0434\u044f \u043d\u0430 \u0434\u0435\u0440\u0435\u0432\u043e, \u043c\u044b \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u043c, \u043a\u0430\u043a\u0438\u043c \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c \u0434\u043e\u043b\u0436\u0435\u043d \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0442\u044c \u0438\u0441\u043a\u043e\u043c\u044b\u0439 \u0443\u0437\u0435\u043b:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0438\u0441\u043a \u0443\u0437\u043b\u0430<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b83\/177\/628\/b83177628527f1dfdeb17d2212791cb3.gif\" width=\"1856\" height=\"569\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b83\/177\/628\/b83177628527f1dfdeb17d2212791cb3.gif\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0427\u0442\u043e \u043c\u044b \u0437\u0434\u0435\u0441\u044c \u0432\u0438\u0434\u0438\u043c: \u0442\u0438\u043f \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0443\u0437\u043b\u0430 &#8212; BinaryExpression, \u0434\u0435\u0442\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f NumericLiteral. \u041f\u0438\u0448\u0435\u043c:<\/p>\n<pre><code class=\"javascript\">const { parse } = require('@babel\/parser'); const traverse = require('@babel\/traverse').default; const generate = require('@babel\/generator').default; const t = require('@babel\/types'); const fs = require('fs');  const srcCode = fs.readFileSync('srcCode.js', { encoding: 'utf-8' }); const ast = parse(srcCode);  traverse(ast, {   BinaryExpression(path) {     const { node } = path;     if (t.isNumericLiteral(node.left) &amp;&amp; t.isNumericLiteral(node.right)) {       path.replaceWith(t.numericLiteral(path.evaluate().value));     }   } });<\/code><\/pre>\n<p>\u0414\u043e\u0441\u043b\u043e\u0432\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0442\u0430\u043a: \u0412 <code>BinaryExpression<\/code>, \u0435\u0441\u043b\u0438 <code>node.left<\/code> \u044d\u0442\u043e \u0447\u0438\u0441\u043b\u043e \u0438 <code>node.right<\/code> \u0442\u043e\u0436\u0435 \u0447\u0438\u0441\u043b\u043e, \u0442\u043e \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0443\u0437\u0435\u043b \u0447\u0438\u0441\u043b\u043e\u043c. \u041c\u0435\u0442\u043e\u0434 <code>evaluate()<\/code> \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u0434\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432. \u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0432\u0437\u044f\u0442\u044c \u0447\u0438\u0441\u043b\u0430 \u0441\u043b\u0435\u0432\u0430 \u0438 \u0441\u043f\u0440\u0430\u0432\u0430, \u0438 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u0430 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0438\u0437 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0435\u0432\u0430 \u0447\u0435\u0440\u0435\u0437 <code>generate(node).code<\/code> \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0435\u0433\u043e \u0447\u0435\u0440\u0435\u0437 <code>eval()<\/code>. \u041d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 path.evaluate() \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442.<\/p>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u0432 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u044f\u043c\u043e \u0432 astexplorer. \u041d\u0443\u0436\u043d\u043e \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c Transform:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/50a\/edc\/1a3\/50aedc1a3b23c7899a617af044d99ec3.png\" width=\"2000\" height=\"898\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/50a\/edc\/1a3\/50aedc1a3b23c7899a617af044d99ec3.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0439\u0441\u044f \u043a\u043e\u0434 \u0432 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u0438 \u043f\u0440\u0435\u0434\u043f\u0440\u0438\u043d\u044f\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0448\u0430\u0433. \u041c\u043d\u0435 \u0442\u0430\u043a\u0436\u0435 \u043d\u0435 \u043d\u0440\u0430\u0432\u044f\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432\u0438\u0434\u0430 <code>(number1, number2)<\/code>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ba5\/e99\/f57\/ba5e99f57ef9d451d66d6406b66c43ae.png\" width=\"2000\" height=\"459\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ba5\/e99\/f57\/ba5e99f57ef9d451d66d6406b66c43ae.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u043c <code>,<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0447\u0438\u0441\u043b\u043e. \u0418\u0437\u0443\u0447\u0430\u044f \u0434\u0435\u0440\u0435\u0432\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u043c, \u0447\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f: \u043d\u0443\u0436\u043d\u044b \u0443\u0437\u043b\u044b, \u0442\u0438\u043f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 SequenceExpression \u0438 \u0432\u0441\u0435 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0432 \u043d\u0435\u0433\u043e expressions \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0447\u0438\u0441\u043b\u0430\u043c\u0438. \u041f\u0438\u0448\u0435\u043c:<\/p>\n<pre><code class=\"javascript\">\/\/ ... traverse(ast, { SequenceExpression(path) {     const { node } = path;     let isAllNumbers = true;     for (let i = 0; i &lt; node.expressions.length; ++i) {       if (!types.isNumericLiteral(node.expressions[i])) {         isAllNumbers = false;         break;       }     }     if (isAllNumbers) {       path.replaceWith(t.numericLiteral(path.evaluate().value));     }   } });<\/code><\/pre>\n<p>\u0413\u0440\u0443\u0431\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u043c\u0441\u044f \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043c\u0430\u0441\u0441\u0438\u0432\u0443 <code>node.expressions<\/code>, \u0438, \u0435\u0441\u043b\u0438 \u0445\u043e\u0442\u044c \u043e\u0434\u0438\u043d \u0443\u0437\u0435\u043b \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>NumericLiteral<\/code>, \u0442\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0442\u0440\u043e\u0433\u0430\u0435\u043c, \u0438\u043d\u0430\u0447\u0435 \u043c\u0435\u043d\u044f\u0435\u043c \u0443\u0437\u0435\u043b \u0443\u0436\u0435 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u043c \u0434\u043b\u044f \u043d\u0430\u0441 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c.<\/p>\n<details class=\"spoiler\">\n<summary>\u041e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442!<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d5c\/393\/6d3\/d5c3936d3f09584e39b5626f0481e198.png\" alt=\"\u0418 \u0433\u043b\u0430\u0437\u0443 \u043f\u0440\u0438\u044f\u0442\u043d\u0435\u0435\" title=\"\u0418 \u0433\u043b\u0430\u0437\u0443 \u043f\u0440\u0438\u044f\u0442\u043d\u0435\u0435\" width=\"2000\" height=\"896\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d5c\/393\/6d3\/d5c3936d3f09584e39b5626f0481e198.png\"\/><figcaption>\u0418 \u0433\u043b\u0430\u0437\u0443 \u043f\u0440\u0438\u044f\u0442\u043d\u0435\u0435<\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u0441\u0442\u0440\u043e\u043a\u0430\u043c. \u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u201c\u0432\u043d\u0435\u0448\u043d\u0438\u0445\u201d. \u0412 \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u0447\u0443\u0434\u043d\u044b\u043c \u0438\u043c\u0435\u043d\u0435\u043c <code>_<\/code>, \u0430 \u0432 \u043a\u043e\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u0438 \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/029\/d6a\/a2b\/029d6aa2bb2d8726ce5c5f87075df013.png\" width=\"2000\" height=\"499\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/029\/d6a\/a2b\/029d6aa2bb2d8726ce5c5f87075df013.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0427\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<details class=\"spoiler\">\n<summary>AST<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/364\/5d2\/e49\/3645d2e49370a93dc8a9268b3f3de538.png\" width=\"2000\" height=\"559\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/364\/5d2\/e49\/3645d2e49370a93dc8a9268b3f3de538.png\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<ul>\n<li>\n<p>\u0414\u043e\u0441\u0442\u0430\u0442\u044c \u0441\u0430\u043c \u043c\u0430\u0441\u0441\u0438\u0432.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0439\u0442\u0438\u0441\u044c \u043f\u043e \u0432\u0441\u0435\u043c MemberExpression, \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 <code>node.object.name<\/code> \u044d\u0442\u043e <code>_<\/code>, \u0430 <code>node.property<\/code> \u044d\u0442\u043e \u0447\u0438\u0441\u043b\u043e.<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c MemberExpression \u043d\u0430 StringLiteral, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0438\u0437 \u043c\u0430\u0441\u0441\u0438\u0432\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e, \u043d\u0438\u0447\u0435\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0433\u043e \u0432 \u043f\u043e\u0438\u0441\u043a\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u043d\u0435\u0442. \u041f\u0440\u043e\u0441\u0442\u043e \u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0434\u0435\u0440\u0435\u0432\u043e \u0438 \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043d\u0443\u0436\u043d\u044b\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f, \u0437\u0430\u0442\u0435\u043c \u043f\u0440\u043e\u0431\u0435\u0433\u0430\u0435\u043c\u0441\u044f \u043f\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0438 \u043a\u043b\u0430\u0434\u0451\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0443\u0437\u043b\u0430 \u0432 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u043d\u0430\u043c\u0438 \u043c\u0430\u0441\u0441\u0438\u0432: <\/p>\n<details class=\"spoiler\">\n<summary>AST<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/7d2\/511\/e9f\/7d2511e9feb50499792c9170356cf913.png\" width=\"2000\" height=\"577\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7d2\/511\/e9f\/7d2511e9feb50499792c9170356cf913.png\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<pre><code class=\"javascript\">const mainArray = [];  traverse(ast, {   AssignmentExpression(path) {     const { node } = path;     if (       t.isMemberExpression(node.left) &amp;&amp;       node.left.property.name === '_'     ) {       const elementsArray = node.right.elements;        elementsArray.forEach((el) => {         mainArray.push(el.value);       });        path.stop();     }   }, });<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f20\/eac\/aea\/f20eacaea2987ef12bd67f0def67f656.png\" width=\"2000\" height=\"937\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f20\/eac\/aea\/f20eacaea2987ef12bd67f0def67f656.png\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041c\u0430\u0441\u0441\u0438\u0432 \u043f\u043e\u043b\u0443\u0447\u0435\u043d, \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0434\u0435\u043b\u043e \u0437\u0430 \u043c\u0430\u043b\u044b\u043c:<\/p>\n<pre><code>\/\/ ...   traverse(ast, {   MemberExpression(path) {     const { node } = path;      if (       node.object.name === '_' &amp;&amp;       t.isNumericLiteral(node.property)     ) {       path.replaceWith(         t.stringLiteral(mainArray[node.property.value])       );     }   }, });<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5a6\/8be\/17d\/5a68be17d1b72203828a2503ff19d504.png\" alt=\"\u041f\u0440\u043e\u0449\u0435 \u0438 \u0431\u044b\u0442\u044c \u043d\u0435 \u043c\u043e\u0436\u0435\u0442!\" title=\"\u041f\u0440\u043e\u0449\u0435 \u0438 \u0431\u044b\u0442\u044c \u043d\u0435 \u043c\u043e\u0436\u0435\u0442!\" width=\"2000\" height=\"908\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5a6\/8be\/17d\/5a68be17d1b72203828a2503ff19d504.png\"\/><figcaption>\u041f\u0440\u043e\u0449\u0435 \u0438 \u0431\u044b\u0442\u044c \u043d\u0435 \u043c\u043e\u0436\u0435\u0442!<\/figcaption><\/figure>\n<p>\u0411\u0435\u0436\u0438\u043c \u043f\u043e \u0432\u0441\u0435\u043c MemberExpression, \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 <code>object.name<\/code> \u0440\u0430\u0432\u0435\u043d \u0438\u043c\u0435\u043d\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 <code>_<\/code>, \u0430 <code>property<\/code> \u044d\u0442\u043e \u0447\u0438\u0441\u043b\u043e.<\/p>\n<p>\u0421\u043a\u0440\u0438\u043f\u0442 \u043f\u0440\u0438\u043e\u0431\u0440\u0435\u0442\u0430\u0435\u0442 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u043e\u0447\u0438\u0442\u0430\u0435\u043c\u044b\u0439 \u0432\u0438\u0434, \u043d\u043e \u044d\u0442\u043e \u0435\u0449\u0451 \u043d\u0435 \u0432\u0441\u0451. \u041e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043c\u0430\u043b\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u0438 \u0441\u0442\u0440\u043e\u043a\u0438, \u0432\u0435\u0434\u044c \u0435\u0441\u0442\u044c \u0435\u0449\u0451 \u0434\u0440\u0443\u0433\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0432\u0438\u0434\u0435\u043b\u0438 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e1e\/dba\/0eb\/e1edba0ebdbcb92c5e3dcabe063baca0.png\" width=\"2000\" height=\"646\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e1e\/dba\/0eb\/e1edba0ebdbcb92c5e3dcabe063baca0.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0418 \u0432\u043e\u0442 \u044d\u0442\u043e \u0443\u0436\u0435 \u0437\u0430\u0434\u0430\u0447\u043a\u0430 \u0441\u043e \u0437\u0432\u0451\u0437\u0434\u043e\u0447\u043a\u043e\u0439. \u041f\u0440\u043e\u0431\u0435\u0433\u0430\u044f\u0441\u044c \u0433\u043b\u0430\u0437\u0430\u043c\u0438 \u043f\u043e \u043a\u043e\u0434\u0443, \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043e\u043d \u0440\u0430\u0437\u0434\u0435\u043b\u0451\u043d \u043d\u0430 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e <code>case<\/code> \u0431\u043b\u043e\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u0430 \u0432 \u0441\u0430\u043c\u044b\u0445 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0431\u043b\u043e\u043a\u0430\u0445 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0441\u0432\u043e\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u043d\u0443\u0436\u043d\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438(\u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0435 \u0438\u0445 \u0438\u043c\u0435\u043d\u0430 <code>y<\/code> \u0438 <code>z<\/code>). \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043a\u043e\u0434:<\/p>\n<details class=\"spoiler\">\n<summary>\u041e\u0431\u0444\u0443\u0441\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/129\/68e\/56b\/12968e56bab172aab45b438664865b10.gif\" width=\"1230\" height=\"569\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/129\/68e\/56b\/12968e56bab172aab45b438664865b10.gif\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u0442\u0435\u0445 \u0431\u043b\u043e\u043a\u0430\u0445 \u043a\u043e\u0434\u0430, \u0433\u0434\u0435 \u043e\u0431\u0444\u0443\u0441\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0441\u0442\u0440\u043e\u043a\u0438, \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043f\u0443\u0442\u0451\u043c \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438. \u0415\u0441\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u044d\u0442\u043e\u0442 \u043c\u0430\u0441\u0441\u0438\u0432. \u041d\u043e \u0438 \u044d\u0442\u043e \u0435\u0449\u0451 \u043d\u0435 \u0432\u0441\u0451! \u0415\u0441\u0442\u044c \u0432\u043e\u0442 \u0442\u0430\u043a\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/88a\/7b2\/e02\/88a7b2e024c86a9bfe4e75aa528bfa87.png\" width=\"2000\" height=\"280\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/88a\/7b2\/e02\/88a7b2e024c86a9bfe4e75aa528bfa87.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 <code>,<\/code> \u0434\u0435\u043b\u0430\u0435\u0442 \u0438\u0437 \u043d\u0435\u0451 IIFE, \u0430 \u043e\u043d\u0430 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 <code>i.push(i.shift())<\/code>. \u0422\u0430\u043a\u0430\u044f \u0441\u0442\u0440\u043e\u0447\u043a\u0430 \u0432\u043e\u0437\u044c\u043c\u0451\u0442 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0438\u0437 \u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0438 \u043f\u043e\u043b\u043e\u0436\u0438\u0442 \u0435\u0433\u043e \u0432 \u043a\u043e\u043d\u0435\u0446:<\/p>\n<pre><code class=\"javascript\">const array = [1, 2, 3]; array.push(array.shift()); console.log(array); \/\/ [2, 3, 1]<\/code><\/pre>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0435\u0449\u0451 \u043a\u0430\u043a-\u0442\u043e <strong>\u043f\u0435\u0440\u0435\u043c\u0435\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f. <\/strong>\u0418 \u043d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u0443\u0436\u0435 \u043a\u0430\u043a-\u0442\u043e \u043c\u0430\u043b\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c\u2026 \u041d\u0430\u043c \u0432\u0440\u043e\u0434\u0435 \u0431\u044b \u043d\u0430\u0434\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u044b\u0437\u043e\u0432\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0438, \u043d\u043e \u0438\u043c\u0435\u043d\u0430 \u044d\u0442\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0440\u0430\u0437\u043d\u044b\u0435, \u043d\u0430\u0434\u043e \u043a\u0430\u043a-\u0442\u043e \u0432\u0437\u044f\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432, \u043d\u0430\u0434\u043e \u0435\u0433\u043e \u043a\u0430\u043a-\u0442\u043e \u0435\u0449\u0451 \u043f\u0435\u0440\u0435\u043c\u0435\u0448\u0430\u0442\u044c, \u0430 \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0438\u0437 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435\u043c, \u0442\u043e \u0435\u0441\u0442\u044c \u0435\u0449\u0451 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0432\u044b\u0446\u0435\u043f\u0438\u0442\u044c\u2026 \u0423\u0445, \u0432\u0440\u043e\u0434\u0435 \u0431\u044b \u0433\u043e\u043b\u043e\u0432\u0430 \u043a\u0440\u0443\u0433\u043e\u043c, \u043d\u043e\u2026<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043c\u0435\u0449\u0435\u043d\u0438\u0435<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4c8\/478\/a1f\/4c8478a1f67d04e57a16afb9655a4e57.png\" width=\"1199\" height=\"224\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4c8\/478\/a1f\/4c8478a1f67d04e57a16afb9655a4e57.png\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412\u044b \u0437\u0430\u043c\u0435\u0442\u0438\u043b\u0438 \u043a\u0430\u043a \u0438\u0437\u044f\u0449\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u201cGo to definition\u201d \u0432 VS Code? \u041d\u0430\u0436\u0438\u043c\u0430\u0435\u0448\u044c F12 \u0438 \u0442\u0435\u0431\u044f \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u0442 \u043a \u043d\u0443\u0436\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439. \u041a\u0440\u0430\u0441\u043e\u0442\u0430! \u042d\u0442\u0430 \u043a\u0440\u0430\u0441\u043e\u0442\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043d\u0430\u043c \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443  JavaScript \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442, \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0432 \u043d\u0430 \u043a\u043e\u0434, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043d\u044f\u0442\u044c \u043a\u0430\u043a \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u043b\u044e\u0431\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e. <\/p>\n<p>Babel \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e-\u0442\u0430\u043a\u0438 \u0443\u043c\u0451\u043d. \u0418 \u043e\u043d \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u043e\u0431\u043b\u0430\u0441\u0442\u044f\u043c\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438(scope). \u041f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435, \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u044b\u0439 \u0437\u0430\u0434\u0430\u0447\u043a\u0438 \u043d\u0430\u043c \u0435\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0445\u0432\u0430\u0442\u0438\u0442 \u0437\u0430 \u0433\u043b\u0430\u0437\u0430.<\/p>\n<h2>\u0414\u0435\u043e\u0431\u0444\u0443\u0441\u043a\u0430\u0446\u0438\u044f \u0441\u0442\u0440\u043e\u043a  <\/h2>\n<p>\u041a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e, \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043d\u044f\u0442\u044c \u043a\u0430\u043a\u0438\u0435 \u0443\u0437\u043b\u044b \u043d\u0430\u043c \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0412 \u044d\u0442\u043e\u043c \u0434\u0435\u043b\u0435 \u043c\u044b \u0443\u0436\u0435 \u043d\u0435 \u043d\u043e\u0432\u0438\u0447\u043a\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0447\u0438\u0442\u0430\u0435\u043c \u0434\u0435\u0440\u0435\u0432\u043e: <\/p>\n<details class=\"spoiler\">\n<summary>AST<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e75\/5e8\/460\/e755e8460f89d49d053b3099aba8e27f.png\" width=\"2000\" height=\"521\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e75\/5e8\/460\/e755e8460f89d49d053b3099aba8e27f.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0420\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u044f \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442, \u0432\u044b \u044f\u0432\u043d\u043e \u043f\u0440\u043e \u0441\u0435\u0431\u044f \u0443\u0436\u0435 \u0432\u0441\u0451 \u043f\u0440\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438: \u201c\u041d\u0430\u043c \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f MemberExpression\u2019\u044b, \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438(CallExpression), \u0430 \u0443 \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u0438\u043d \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u0438 \u044d\u0442\u043e\u0442 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 &#8212; \u0447\u0438\u0441\u043b\u043e\u201d.  <\/p>\n<\/div>\n<\/details>\n<p> \u041f\u0440\u043e\u0449\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e:<\/p>\n<pre><code class=\"javascript\">traverse(this._ast, {   MemberExpression: (path) => {     const { node } = path;     if (t.isCallExpression(node.property) &amp;&amp;       node.property.arguments.length === 1 &amp;&amp;       t.isNumericLiteral(node.property.arguments[0])     ) {       let callNode = node.property;        const scopeData = {         array: [],       }; }   }, });<\/code><\/pre>\n<p>\u041a\u0430\u0436\u0434\u0430\u044f \u043f\u043e\u0434\u043e\u0431\u043d\u0430\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0438\u043c\u0435\u0435\u0442 \u0441\u0432\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u0434\u043b\u044f \u043d\u0443\u0436\u043d\u043e\u0439 \u043d\u0430\u043c scope \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0435\u043a\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 <code>scopeData<\/code>.  \u0412 \u044d\u0442\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435.<\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 <code>path<\/code> \u0432 babel \u0438\u043c\u0435\u0435\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e scope, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438: <\/p>\n<pre><code class=\"javascript\">const currentScope = path.scope; \/\/ \u0442\u0435\u043a\u0443\u0449\u0430\u044f scope const scopeUid = currentScope.uid; \/\/ \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 const parentScope = currentScope.parent; \/\/ \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0430\u044f scope  currentScope.traverse(currentScope.block, { \/\/ \u041c\u043e\u0436\u0435\u043c \u043e\u0431\u043e\u0439\u0442\u0438 scope, \u043a\u0430\u043a \u043f\u043e\u0434\u0434\u0435\u0440\u0435\u0432\u043e \/\/ visitor })<\/code><\/pre>\n<p>\u0423 \u043a\u0430\u0436\u0434\u043e\u0439 scope \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0439 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 uid. \u041d\u043e \u043d\u0430\u0434\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0432\u0435\u0449\u044c:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d4f\/fad\/35b\/d4ffad35bbbf1b9e58103d2e295f23b5.png\" width=\"2000\" height=\"1079\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d4f\/fad\/35b\/d4ffad35bbbf1b9e58103d2e295f23b5.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u043d\u0430\u0448 path \u043d\u0430\u0442\u043a\u043d\u0443\u043b\u0441\u044f \u043d\u0430 \u043d\u0443\u0436\u043d\u044b\u0439 MemberExpression <code>window[getStringByIndex(0)]<\/code>. \u042d\u0442\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0430\u044f \u0434\u043b\u044f \u043d\u0430\u0441 \u043e\u0431\u0444\u0443\u0441\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430. \u041d\u043e \u044d\u0442\u043e <strong>scopeUid = 3<\/strong>, \u0430 \u043d\u0430\u0448 \u043c\u0430\u0441\u0441\u0438\u0432 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 <strong>scopeUid = 1<\/strong>. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0443\u044e scope, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0435\u0441\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432. \u0418 \u0437\u0434\u0435\u0441\u044c \u043d\u0430\u043c \u0443\u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0441\u0442\u0443\u043f\u0438\u0442\u044c \u0432 \u0440\u043e\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0449\u0435\u0442 \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u043e\u0431\u044a\u0435\u043a\u0442. \u0415\u0441\u043b\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043d\u0435\u0442 \u0432 \u043d\u0430\u0448\u0435\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438, \u0442\u043e \u043c\u044b \u0438\u0434\u0451\u043c \u043f\u043e \u0446\u0435\u043f\u043e\u0447\u043a\u0435 \u043e\u0431\u043b\u0430\u0441\u0442\u0435\u0439 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u043e\u0431\u0440\u0430\u0442\u043d\u0443\u044e \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438, \u0430 \u0435\u0441\u043b\u0438 \u043d\u0435\u0442 \u0438 \u0442\u0430\u043c, \u0442\u043e \u0432 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0439 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0439 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435\u2026<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0439\u043c\u0451\u043c \u043a\u0430\u043a\u0438\u043c \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c\u0438 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442 \u0438\u0441\u043a\u043e\u043c\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432:<\/p>\n<details class=\"spoiler\">\n<summary>AST<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/64f\/dfa\/070\/64fdfa07068d2d3149a15791e991444c.png\" width=\"1312\" height=\"307\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/64f\/dfa\/070\/64fdfa07068d2d3149a15791e991444c.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041c\u0430\u0441\u0441\u0438\u0432 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0443\u0437\u043b\u0435 CallExpression, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441 MemberExpression, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e <code>property<\/code> === &#8216;split&#8217;, \u0430 <code>object.type<\/code> === StringLiteral<\/p>\n<\/div>\n<\/details>\n<pre><code class=\"javascript\">function FindClosestScopeWithArray(scope) { const result = { array: [], scope: {} }  scope.traverse(scope.block, {       CallExpression(path) {         const { node } = path;         if (           node.callee &amp;&amp;           t.isMemberExpression(node.callee) &amp;&amp;           !node.callee.computed &amp;&amp;           t.isStringLiteral(node.callee.object) &amp;&amp;           t.isIdentifier(node.callee.property) &amp;&amp;           node.callee.property.name === 'split'         ) {           const delimiter = node.arguments[0].value;           result.array = node.callee.object.value.split(delimiter); result.scope = scope;           path_.stop();         }       },     });  }<\/code><\/pre>\n<p>\u0412\u0441\u0451 \u043f\u0440\u043e\u0441\u0442\u043e: \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c, \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u043c \u0441 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0438 \u043c\u0430\u0441\u0441\u0438\u0432 \u0433\u043e\u0442\u043e\u0432. \u041d\u043e\u2026 \u041c\u0430\u0441\u0441\u0438\u0432 \u0431\u044b \u0431\u044b\u043b \u0433\u043e\u0442\u043e\u0432, \u0435\u0441\u043b\u0438 \u0431\u044b \u043e\u043d \u0431\u044b\u043b \u0432 \u043d\u0443\u0436\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438. \u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0435\u0441\u043b\u0438 \u043c\u044b \u0435\u0449\u0451 \u043d\u0435 \u0437\u0430\u0431\u0440\u0430\u043b\u0438 \u043c\u0430\u0441\u0441\u0438\u0432, \u0442\u043e \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u043a \u0440\u043e\u0434\u0438\u043b\u044c\u0441\u043a\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438:<\/p>\n<pre><code class=\"javascript\">FindClosestScopeWithArray(scope) {   const result = {     array: [],     scope: {}   }    while(scope) {     scope.traverse(scope.block, {       CallExpression(path) {         const { node } = path;         if (           ...         ) {           const delimiter = node.arguments[0].value;           result.array = node.callee.object.value.split(delimiter);           result.scope = scope;           path.stop();         }       },     });            if (result.array.length === 0) { \/\/ \u0415\u0441\u043b\u0438 \u043c\u0430\u0441\u0441\u0438\u0432 \u0435\u0449\u0451 \u043f\u0443\u0441\u0442, \u0437\u043d\u0430\u0447\u0438\u0442 \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 scope                                      \/\/ \u043d\u0435 \u0431\u044b\u043b\u043e \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0443\u0437\u043b\u0430 CallExpression                                      \/\/ => \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0443\u044e scope         scope = scope.parent;     } else {         return result;     }   } }<\/code><\/pre>\n<p>\u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u043c \u043d\u0430\u0439\u0442\u0438 \u043d\u0443\u0436\u043d\u0443\u044e \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0438 \u0432\u043e\u0437\u044c\u043c\u0451\u0442 \u0438\u0437 \u043d\u0435\u0451 \u043c\u0430\u0441\u0441\u0438\u0432. \u041d\u043e \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 &#8212; \u044d\u0442\u043e \u0441\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435. \u0412\u0435\u0434\u044c \u0442\u0430\u043c, \u0433\u0434\u0435 \u0435\u0441\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432, \u0442\u0430\u043c \u0435\u0441\u0442\u044c \u0438 \u043d\u0443\u0436\u043d\u043e\u0435 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435, \u0435\u0441\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u0448\u0438\u0432\u0430\u043d\u0438\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0438 \u0432\u0441\u0451-\u0432\u0441\u0451-\u0432\u0441\u0451 \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e. \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043b\u0438\u0448\u044c \u044d\u0442\u043e \u043d\u0430\u0439\u0442\u0438. \u0410 \u0438\u0441\u043a\u0430\u0442\u044c \u0432 \u0434\u0435\u0440\u0435\u0432\u0435 \u043c\u044b \u0443\u0436\u0435 \u0443\u043c\u0435\u0435\u043c.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0435\u0449\u0451 \u0440\u0430\u0437 \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u043c\u0441\u044f \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u0448\u0438\u0432\u0430\u043d\u0438\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u0430. \u042f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043b \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u0435\u0435 \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442:<\/p>\n<details class=\"spoiler\">\n<summary>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u0448\u0438\u0432\u0430\u043d\u0438\u044f<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">!(function (getArray, shuffleOffset, getStringFromArray, array, j) {   for (getStringFromArray = b, array = getArray(); !![]; )     try {       if (         ((j =           (-parseInt(getStringFromArray(158)) \/ 1) * (parseInt(getStringFromArray(197)) \/ 2) +           -parseInt(getStringFromArray(192)) \/ 3 +           -parseInt(getStringFromArray(175)) \/ 4 +           (parseInt(getStringFromArray(163)) \/ 5) * (parseInt(getStringFromArray(168)) \/ 6) +           (-parseInt(getStringFromArray(187)) \/ 7) * (parseInt(getStringFromArray(194)) \/ 8) +           parseInt(getStringFromArray(174)) \/ 9 +           parseInt(getStringFromArray(152)) \/ 10),         j === shuffleOffset)       )         break;       else array.push(array.shift());     } catch (k) {       array.push(array.shift());     } })(a, 910768);<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f getString, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u043f\u0440\u0438 \u0432\u0437\u044f\u0442\u0438\u0438 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438\u0437 \u043c\u0430\u0441\u0441\u0438\u0432\u0430, \u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u0446\u0438\u043a\u043b \u043f\u0435\u0440\u0435\u043c\u0435\u0448\u0438\u0432\u0430\u043d\u0438\u044f \u0432 \u0431\u043e\u043b\u0435\u0435 \u0447\u0438\u0442\u0430\u0435\u043c\u044b\u0439 \u0432\u0438\u0434:<\/p>\n<pre><code class=\"javascript\">while(true) {   try {     const j = parseInt... parseInt... parseInt... parseInt... parseInt... parseInt...;     if (j === shuffleOffset) {       break;     } else {       array.push(array.shift());     }   } catch(e) {     array.push(array.shift());   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c, \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0441\u0442\u0440\u0430\u043d\u043d\u0430\u044f \u043c\u0430\u0433\u0438\u044f, \u043d\u043e \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u0443 \u043c\u0430\u0433\u0438\u044e \u201c\u0437\u0430\u0432\u0435\u0441\u0442\u0438\u201d \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u043c\u0430\u0441\u0441\u0438\u0432, <code>getStringFromArray()<\/code> \u0438 <code>shuffleOffset<\/code>. \u0410 \u0432\u043e\u0442 \u044d\u0442\u0443 \u0431\u0443\u0440\u0434\u0443 <code>parseInt... parseInt... parseInt... parseInt<\/code> \u043c\u044b \u0432\u043e\u0437\u044c\u043c\u0451\u043c \u0438\u0437 \u0434\u0435\u0440\u0435\u0432\u0430, \u0442\u043e \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0443\u0437\u0435\u043b, \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0438\u0437 \u043d\u0435\u0433\u043e \u043a\u043e\u0434 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043c <code>eval<\/code>. \u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0435\u043c.<\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u0438\u0441\u043a: \u0432\u0441\u0451 \u043d\u0443\u0436\u043d\u043e\u0435 \u043d\u0430\u043c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>FindClosestScopeWithArray<\/code>, \u0437\u043d\u0430\u0447\u0438\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u043f\u043e\u0438\u0441\u043a\u043e\u043c \u043d\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0435\u0442.<\/p>\n<details class=\"spoiler\">\n<summary>\u0418\u0449\u0435\u043c shuffleOffset<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4cf\/08f\/e20\/4cf08fe205587db99f6a0e26d914a8cb.png\" width=\"2000\" height=\"366\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4cf\/08f\/e20\/4cf08fe205587db99f6a0e26d914a8cb.png\"\/><figcaption><\/figcaption><\/figure>\n<pre><code class=\"javascript\">const getShuffleOffset = (scope) => {   let result;   scope.traverse(scope.block, {     CallExpression(path) {       const node = path.node;       if (         node.arguments.length === 2 &amp;&amp;         t.isNumericLiteral(node.arguments[1]) &amp;&amp;         t.isIdentifier(node.arguments[0]) &amp;&amp;         node.arguments[0].name === 'a'       ) {         result = node.arguments[1].value;         path.stop();       }     },   });   return result; };<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0418\u0449\u0435\u043c offset<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/689\/7e3\/159\/6897e31597a49fbcd7ea2ef4289fd868.png\" width=\"2000\" height=\"853\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/689\/7e3\/159\/6897e31597a49fbcd7ea2ef4289fd868.png\"\/><figcaption><\/figcaption><\/figure>\n<pre><code class=\"javascript\">const getOffsetForGetString = (scope) => {   let result;   scope.traverse(scope.block, {     ReturnStatement(path) {       const node = path.node;       if (         node.argument &amp;&amp;         t.isSequenceExpression(node.argument) &amp;&amp;         t.isAssignmentExpression(node.argument.expressions[0]) &amp;&amp;         t.isBinaryExpression(node.argument.expressions[0].right) &amp;&amp;         node.argument.expressions[0].right.operator === '-' &amp;&amp;         !isNaN(node.argument.expressions[0].right.right.value)       ) {         result = node.argument.expressions[0].right.right.value;         path.stop();       }     },   });   return result; };<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0418\u0449\u0435\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 paseInt\u2026paseInt\u2026paseInt\u2026paseInt\u2026paseInt\u2026<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f70\/581\/ed1\/f70581ed17250779235a0b20367b3b59.png\" width=\"2000\" height=\"809\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f70\/581\/ed1\/f70581ed17250779235a0b20367b3b59.png\"\/><figcaption><\/figcaption><\/figure>\n<pre><code class=\"javascript\">const getComparisonExpr = (scope) => {   let result;   scope.traverse(scope.block, {     IfStatement(path) {       const node = path.node;       if (         t.isSequenceExpression(node.test) &amp;&amp;         t.isAssignmentExpression(node.test.expressions[0]) &amp;&amp;         t.isBinaryExpression(node.test.expressions[0].right) &amp;&amp;         t.isBinaryExpression(node.test.expressions[0].right.left) &amp;&amp;         t.isBinaryExpression(node.test.expressions[0].right.left.left)       ) {         result = generate(node.test.expressions[0].right).code; \/\/ \u0431\u0435\u0440\u0451\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0435\u0432\u043e node.test.expressions[0].right \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0438\u0437 \u043d\u0435\u0433\u043e \u043a\u043e\u0434         path.stop();       }     },   });   return result; };<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0438\u0447\u0435\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0433\u043e \u043d\u0435\u0442. \u041f\u0440\u043e\u0441\u0442\u043e \u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0434\u0435\u0440\u0435\u0432\u043e \u0438 \u043f\u0438\u0448\u0435\u043c \u0443\u0441\u043b\u043e\u0432\u0438\u044f. \u041d\u0443\u0434\u043d\u043e, \u043d\u043e \u043d\u0435 \u0441\u043b\u043e\u0436\u043d\u043e. \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>generate()<\/code> \u043f\u0430\u043a\u0435\u0442\u0430 <a href=\"https:\/\/babeljs.io\/docs\/en\/babel-generator\" rel=\"noopener noreferrer nofollow\"><em>@babel\/generator<\/em><\/a> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437 \u0434\u0435\u0440\u0435\u0432\u0430 \u0441\u043d\u043e\u0432\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043e\u0434. \u0412 \u0438\u0442\u043e\u0433\u0435 \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <code>\u0441omparisonExpr<\/code> \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u043b\u0435\u0436\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0430: <code>-parseInt(x(158)) \/ 1 * (parseInt(x(197)) \/ 2) + -parseInt(x(192)) \/ 3 + -parseInt(x(175)) \/ 4 +  ...<\/code><\/p>\n<p>\u0412\u043e \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0430\u0445 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432\u0438\u0434\u0430 <code>x(%number)<\/code> <code>x<\/code> &#8212; \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>getStringFromArray<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u0432\u0437\u044f\u0442\u0438\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0438\u0437 \u043c\u0430\u0441\u0441\u0438\u0432\u0430, \u0430 \u0435\u0433\u043e \u043c\u044b \u0443\u0436\u0435 \u043d\u0430\u0448\u043b\u0438, \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0442\u0440\u0443\u0434\u0430 \u043d\u0435 \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u0442:<\/p>\n<pre><code class=\"javascript\">const getStringFromArray = (index) => { return scopeData.array[index - offset]; }<\/code><\/pre>\n<p>\u0414\u0430, \u0432\u043e \u0432\u0441\u0451\u043c \u043a\u043e\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 <code>-<\/code>. \u0421\u043f\u0430\u0441\u0438\u0431\u043e, cloudflare, \u0447\u0442\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0448\u044c \u043d\u0430\u043c \u0436\u0438\u0437\u043d\u044c.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435 \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u0442 \u0442\u0440\u0443\u0434\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u0448\u0430\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432:<\/p>\n<pre><code class=\"javascript\">function ShuffleArray(scope, scopeData) {   const shuffleOffset = getShuffleOffset(scope);   const offset = getOffsetForGetString(scope);   const \u0441omparisonExpr = getComparisonExpr(scope).replaceAll(     \/parseint\\(\\w+\\(\/gi,     'parseInt(getStringFromArray('   );    const getStringFromArray = (index) => {     return scopeData.array[index - offset];   };    scopeData.getString = getStringFromArray;    eval(`     while(true) {       try {         const f = ${\u0441omparisonExpr};         if (f === ${shuffleOffset}) break;         else scopeData.array.push(scopeData.array.shift());       } catch(e) {         scopeData.array.push(scopeData.array.shift());       }     }   `); }<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435 \u043a \u043a\u043e\u0434\u0443<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041c\u044b \u0445\u043e\u0442\u0438\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c <code>eval<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u044b <code>x(%number)<\/code> \u043d\u0430 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>getStringFromArray<\/code>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e55\/9a7\/dae\/e559a7dae5ff8c3ea328ab85d6f9a31d.png\" width=\"2000\" height=\"239\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e55\/9a7\/dae\/e559a7dae5ff8c3ea328ab85d6f9a31d.png\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0432 <code>ShuffleArray<\/code> \u043c\u0430\u0441\u0441\u0438\u0432 \u043a\u0430\u043a-\u0442\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u0430 \u0432 <code>scopeData<\/code> \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>getString()<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u0435\u0440\u043d\u0451\u0442 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443.<\/p>\n<p>\u041d\u0430\u0448 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u0445\u043e\u0434 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0442\u0430\u043a\u0438\u043c:<\/p>\n<pre><code class=\"javascript\">const scopeUidToData = new Map(); traverse(ast, {   MemberExpression: (path) => {     const { node } = path;     if (       t.isCallExpression(node.property) &amp;&amp;       node.property.arguments.length === 1 &amp;&amp;       t.isNumericLiteral(node.property.arguments[0])     ) {       let callNode = node.property;        const currentScope = path.scope;        const arrayAndScope = FindClosestScopeWithArray(currentScope);        const scopeData = {         array: arrayAndScope.array,       };       const requiredScope = arrayAndScope.scope;        if (scopeUidToData.has(requiredScope.uid)) {         const scopeData = scopeUidToData.get(requiredScope.uid);         node.property = t.stringLiteral(scopeData.getString(parseInt(callNode.arguments[0].value)));         return;       }        ShuffleArray(requiredScope, scopeData);        scopeUidToData.set(requiredScope.uid, scopeData);       node.property = t.stringLiteral(         scopeData.getString(parseInt(callNode.arguments[0].value))       );     }   }, });<\/code><\/pre>\n<p>\u042f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u043e\u0434\u0438\u043d <code>Map()<\/code> (scopeUid \u2192 scopeData), \u0447\u0442\u043e\u0431\u044b \u043f\u043e 100 \u0440\u0430\u0437 \u043d\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u0448\u0438\u0432\u0430\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432. \u041f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u0448\u0438\u0432\u0430\u043d\u0438\u044f \u043c\u044b \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0430\u0440\u0443 scopeUid-scopeData \u0432 \u0441\u043b\u043e\u0432\u0430\u0440\u044c, \u0430 \u043f\u043e\u0442\u043e\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0435\u0441\u0442\u044c \u043b\u0438 \u0443 \u043d\u0430\u0441 \u0443\u0436\u0435 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438.<\/p>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442(\u0441 \u0436\u0435\u043b\u0442\u044b\u043c \u0431\u0430\u0433\u043e\u043c) \u043d\u0435 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u043b \u0441\u0435\u0431\u044f \u0434\u043e\u043b\u0433\u043e \u0436\u0434\u0430\u0442\u044c: <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/197\/04b\/04d\/19704b04d7bd764a21baad4801bd139b.png\" width=\"2000\" height=\"411\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/197\/04b\/04d\/19704b04d7bd764a21baad4801bd139b.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043d\u0435\u0434\u043e\u0447\u0451\u0442 \u0432 \u043d\u0430\u0448\u0435\u0439 \u0434\u0435\u043e\u0431\u0444\u0443\u0441\u043a\u0430\u0446\u0438\u0438. \u041c\u044b \u0437\u0430\u043c\u0435\u043d\u044f\u043b\u0438 CallExpression\u2019\u044b \u0432\u043d\u0443\u0442\u0440\u0438 MemberExpression\u2019\u043e\u0432, \u0432 \u0438\u0442\u043e\u0433\u0435 \u043d\u0435 \u0432\u0441\u0451 \u0437\u0430\u043c\u0435\u043d\u0438\u043b\u043e\u0441\u044c \u043a\u0430\u043a \u043d\u0430\u0434\u043e. \u0418\u0441\u043f\u0440\u0430\u0432\u0438\u043c \u043d\u0430\u0448 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043e\u0431\u0445\u043e\u0434 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"javascript\">const scopeUidToData = new Map(); traverse(ast, {   CallExpression: (path) => {     const { node } = path;     if (       node.arguments.length == 1 &amp;&amp;       t.isNumericLiteral(node.arguments[0])     ) {       const currentScope = path.scope;        const arrayAndScope = FindClosestScopeWithArray(currentScope);        const scopeData = {         array: arrayAndScope.array,       };       const requiredScope = arrayAndScope.scope;        if (scopeUidToData.has(requiredScope.uid)) {         const scopeData = scopeUidToData.get(requiredScope.uid);         try {           path.replaceWith(             t.stringLiteral(scopeData.getString(parseInt(node.arguments[0].value)))           )         } catch(e) {}         return;       }        ShuffleArray(requiredScope, scopeData);        scopeUidToData.set(requiredScope.uid, scopeData);       try {         path.replaceWith(           t.stringLiteral(scopeData.getString(parseInt(node.arguments[0].value)))         )       } catch(e) {}     }   }, });<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u043b\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c\u0441\u044f \u043a \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u043c CallExpression\u2019\u0430\u043c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u044d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441 \u0447\u0438\u0441\u043b\u043e\u043c. \u041d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0437\u0430\u043c\u0435\u043d\u044f\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435. \u041f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>try-catch<\/code>, \u0447\u0442\u043e\u0431\u044b \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u0437\u0430\u043c\u0435\u043d\u044b \u0443\u0437\u043b\u0430 \u043e\u0431\u0445\u043e\u0434 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u043b\u0441\u044f. \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0431\u043e\u0440\u043e\u0442\u044c, \u043d\u043e \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0443\u0436\u0435 \u043d\u0430 \u044d\u0442\u043e\u043c \u0430\u043a\u0446\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043d\u044f\u0442\u044c\u0441\u044f \u0443\u043a\u0440\u0430\u0448\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e\u043c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c <code>foo[\"bar\"]<\/code> \u043d\u0430 <code>foo.bar<\/code>. \u0423 babel \u0435\u0441\u0442\u044c \u0443\u0436\u0435 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u0442\u0430\u043a\u043e\u0433\u043e. \u0422\u0443 \u0436\u0435 \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0443 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u043c\u0438\u043d\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u043e \u0442\u0438\u043f\u0443 UglifyJS. \u041d\u043e \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430\u0440\u043e\u0434\u043d\u044b\u043c \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"javascript\">const validIdentifierRegex =     \/^(?!(?:do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|this|true|void|with|break|catch|class|const|super|throw|while|yield|delete|export|import|public|return|static|switch|typeof|default|extends|finally|package|private|continue|debugger|function|arguments|interface|protected|implements|instanceof)$)[$A-Z\\_a-z\\xaa\\xb5\\xba\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\u02c1\\u02c6-\\u02d1\\u02e0-\\u02e4\\u02ec\\u02ee\\u0370-\\u0374\\u0376\\u0377\\u037a-\\u037d\\u0386\\u0388-\\u038a\\u038c\\u038e-\\u03a1\\u03a3-\\u03f5\\u03f7-\\u0481\\u048a-\\u0527\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05d0-\\u05ea\\u05f0-\\u05f2\\u0620-\\u064a\\u066e\\u066f\\u0671-\\u06d3\\u06d5\\u06e5\\u06e6\\u06ee\\u06ef\\u06fa-\\u06fc\\u06ff\\u0710\\u0712-\\u072f\\u074d-\\u07a5\\u07b1\\u07ca-\\u07ea\\u07f4\\u07f5\\u07fa\\u0800-\\u0815\\u081a\\u0824\\u0828\\u0840-\\u0858\\u08a0\\u08a2-\\u08ac\\u0904-\\u0939\\u093d\\u0950\\u0958-\\u0961\\u0971-\\u0977\\u0979-\\u097f\\u0985-\\u098c\\u098f\\u0990\\u0993-\\u09a8\\u09aa-\\u09b0\\u09b2\\u09b6-\\u09b9\\u09bd\\u09ce\\u09dc\\u09dd\\u09df-\\u09e1\\u09f0\\u09f1\\u0a05-\\u0a0a\\u0a0f\\u0a10\\u0a13-\\u0a28\\u0a2a-\\u0a30\\u0a32\\u0a33\\u0a35\\u0a36\\u0a38\\u0a39\\u0a59-\\u0a5c\\u0a5e\\u0a72-\\u0a74\\u0a85-\\u0a8d\\u0a8f-\\u0a91\\u0a93-\\u0aa8\\u0aaa-\\u0ab0\\u0ab2\\u0ab3\\u0ab5-\\u0ab9\\u0abd\\u0ad0\\u0ae0\\u0ae1\\u0b05-\\u0b0c\\u0b0f\\u0b10\\u0b13-\\u0b28\\u0b2a-\\u0b30\\u0b32\\u0b33\\u0b35-\\u0b39\\u0b3d\\u0b5c\\u0b5d\\u0b5f-\\u0b61\\u0b71\\u0b83\\u0b85-\\u0b8a\\u0b8e-\\u0b90\\u0b92-\\u0b95\\u0b99\\u0b9a\\u0b9c\\u0b9e\\u0b9f\\u0ba3\\u0ba4\\u0ba8-\\u0baa\\u0bae-\\u0bb9\\u0bd0\\u0c05-\\u0c0c\\u0c0e-\\u0c10\\u0c12-\\u0c28\\u0c2a-\\u0c33\\u0c35-\\u0c39\\u0c3d\\u0c58\\u0c59\\u0c60\\u0c61\\u0c85-\\u0c8c\\u0c8e-\\u0c90\\u0c92-\\u0ca8\\u0caa-\\u0cb3\\u0cb5-\\u0cb9\\u0cbd\\u0cde\\u0ce0\\u0ce1\\u0cf1\\u0cf2\\u0d05-\\u0d0c\\u0d0e-\\u0d10\\u0d12-\\u0d3a\\u0d3d\\u0d4e\\u0d60\\u0d61\\u0d7a-\\u0d7f\\u0d85-\\u0d96\\u0d9a-\\u0db1\\u0db3-\\u0dbb\\u0dbd\\u0dc0-\\u0dc6\\u0e01-\\u0e30\\u0e32\\u0e33\\u0e40-\\u0e46\\u0e81\\u0e82\\u0e84\\u0e87\\u0e88\\u0e8a\\u0e8d\\u0e94-\\u0e97\\u0e99-\\u0e9f\\u0ea1-\\u0ea3\\u0ea5\\u0ea7\\u0eaa\\u0eab\\u0ead-\\u0eb0\\u0eb2\\u0eb3\\u0ebd\\u0ec0-\\u0ec4\\u0ec6\\u0edc-\\u0edf\\u0f00\\u0f40-\\u0f47\\u0f49-\\u0f6c\\u0f88-\\u0f8c\\u1000-\\u102a\\u103f\\u1050-\\u1055\\u105a-\\u105d\\u1061\\u1065\\u1066\\u106e-\\u1070\\u1075-\\u1081\\u108e\\u10a0-\\u10c5\\u10c7\\u10cd\\u10d0-\\u10fa\\u10fc-\\u1248\\u124a-\\u124d\\u1250-\\u1256\\u1258\\u125a-\\u125d\\u1260-\\u1288\\u128a-\\u128d\\u1290-\\u12b0\\u12b2-\\u12b5\\u12b8-\\u12be\\u12c0\\u12c2-\\u12c5\\u12c8-\\u12d6\\u12d8-\\u1310\\u1312-\\u1315\\u1318-\\u135a\\u1380-\\u138f\\u13a0-\\u13f4\\u1401-\\u166c\\u166f-\\u167f\\u1681-\\u169a\\u16a0-\\u16ea\\u16ee-\\u16f0\\u1700-\\u170c\\u170e-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176c\\u176e-\\u1770\\u1780-\\u17b3\\u17d7\\u17dc\\u1820-\\u1877\\u1880-\\u18a8\\u18aa\\u18b0-\\u18f5\\u1900-\\u191c\\u1950-\\u196d\\u1970-\\u1974\\u1980-\\u19ab\\u19c1-\\u19c7\\u1a00-\\u1a16\\u1a20-\\u1a54\\u1aa7\\u1b05-\\u1b33\\u1b45-\\u1b4b\\u1b83-\\u1ba0\\u1bae\\u1baf\\u1bba-\\u1be5\\u1c00-\\u1c23\\u1c4d-\\u1c4f\\u1c5a-\\u1c7d\\u1ce9-\\u1cec\\u1cee-\\u1cf1\\u1cf5\\u1cf6\\u1d00-\\u1dbf\\u1e00-\\u1f15\\u1f18-\\u1f1d\\u1f20-\\u1f45\\u1f48-\\u1f4d\\u1f50-\\u1f57\\u1f59\\u1f5b\\u1f5d\\u1f5f-\\u1f7d\\u1f80-\\u1fb4\\u1fb6-\\u1fbc\\u1fbe\\u1fc2-\\u1fc4\\u1fc6-\\u1fcc\\u1fd0-\\u1fd3\\u1fd6-\\u1fdb\\u1fe0-\\u1fec\\u1ff2-\\u1ff4\\u1ff6-\\u1ffc\\u2071\\u207f\\u2090-\\u209c\\u2102\\u2107\\u210a-\\u2113\\u2115\\u2119-\\u211d\\u2124\\u2126\\u2128\\u212a-\\u212d\\u212f-\\u2139\\u213c-\\u213f\\u2145-\\u2149\\u214e\\u2160-\\u2188\\u2c00-\\u2c2e\\u2c30-\\u2c5e\\u2c60-\\u2ce4\\u2ceb-\\u2cee\\u2cf2\\u2cf3\\u2d00-\\u2d25\\u2d27\\u2d2d\\u2d30-\\u2d67\\u2d6f\\u2d80-\\u2d96\\u2da0-\\u2da6\\u2da8-\\u2dae\\u2db0-\\u2db6\\u2db8-\\u2dbe\\u2dc0-\\u2dc6\\u2dc8-\\u2dce\\u2dd0-\\u2dd6\\u2dd8-\\u2dde\\u2e2f\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303c\\u3041-\\u3096\\u309d-\\u309f\\u30a1-\\u30fa\\u30fc-\\u30ff\\u3105-\\u312d\\u3131-\\u318e\\u31a0-\\u31ba\\u31f0-\\u31ff\\u3400-\\u4db5\\u4e00-\\u9fcc\\ua000-\\ua48c\\ua4d0-\\ua4fd\\ua500-\\ua60c\\ua610-\\ua61f\\ua62a\\ua62b\\ua640-\\ua66e\\ua67f-\\ua697\\ua6a0-\\ua6ef\\ua717-\\ua71f\\ua722-\\ua788\\ua78b-\\ua78e\\ua790-\\ua793\\ua7a0-\\ua7aa\\ua7f8-\\ua801\\ua803-\\ua805\\ua807-\\ua80a\\ua80c-\\ua822\\ua840-\\ua873\\ua882-\\ua8b3\\ua8f2-\\ua8f7\\ua8fb\\ua90a-\\ua925\\ua930-\\ua946\\ua960-\\ua97c\\ua984-\\ua9b2\\ua9cf\\uaa00-\\uaa28\\uaa40-\\uaa42\\uaa44-\\uaa4b\\uaa60-\\uaa76\\uaa7a\\uaa80-\\uaaaf\\uaab1\\uaab5\\uaab6\\uaab9-\\uaabd\\uaac0\\uaac2\\uaadb-\\uaadd\\uaae0-\\uaaea\\uaaf2-\\uaaf4\\uab01-\\uab06\\uab09-\\uab0e\\uab11-\\uab16\\uab20-\\uab26\\uab28-\\uab2e\\uabc0-\\uabe2\\uac00-\\ud7a3\\ud7b0-\\ud7c6\\ud7cb-\\ud7fb\\uf900-\\ufa6d\\ufa70-\\ufad9\\ufb00-\\ufb06\\ufb13-\\ufb17\\ufb1d\\ufb1f-\\ufb28\\ufb2a-\\ufb36\\ufb38-\\ufb3c\\ufb3e\\ufb40\\ufb41\\ufb43\\ufb44\\ufb46-\\ufbb1\\ufbd3-\\ufd3d\\ufd50-\\ufd8f\\ufd92-\\ufdc7\\ufdf0-\\ufdfb\\ufe70-\\ufe74\\ufe76-\\ufefc\\uff21-\\uff3a\\uff41-\\uff5a\\uff66-\\uffbe\\uffc2-\\uffc7\\uffca-\\uffcf\\uffd2-\\uffd7\\uffda-\\uffdc][$A-Z\\_a-z\\xaa\\xb5\\xba\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\u02c1\\u02c6-\\u02d1\\u02e0-\\u02e4\\u02ec\\u02ee\\u0370-\\u0374\\u0376\\u0377\\u037a-\\u037d\\u0386\\u0388-\\u038a\\u038c\\u038e-\\u03a1\\u03a3-\\u03f5\\u03f7-\\u0481\\u048a-\\u0527\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05d0-\\u05ea\\u05f0-\\u05f2\\u0620-\\u064a\\u066e\\u066f\\u0671-\\u06d3\\u06d5\\u06e5\\u06e6\\u06ee\\u06ef\\u06fa-\\u06fc\\u06ff\\u0710\\u0712-\\u072f\\u074d-\\u07a5\\u07b1\\u07ca-\\u07ea\\u07f4\\u07f5\\u07fa\\u0800-\\u0815\\u081a\\u0824\\u0828\\u0840-\\u0858\\u08a0\\u08a2-\\u08ac\\u0904-\\u0939\\u093d\\u0950\\u0958-\\u0961\\u0971-\\u0977\\u0979-\\u097f\\u0985-\\u098c\\u098f\\u0990\\u0993-\\u09a8\\u09aa-\\u09b0\\u09b2\\u09b6-\\u09b9\\u09bd\\u09ce\\u09dc\\u09dd\\u09df-\\u09e1\\u09f0\\u09f1\\u0a05-\\u0a0a\\u0a0f\\u0a10\\u0a13-\\u0a28\\u0a2a-\\u0a30\\u0a32\\u0a33\\u0a35\\u0a36\\u0a38\\u0a39\\u0a59-\\u0a5c\\u0a5e\\u0a72-\\u0a74\\u0a85-\\u0a8d\\u0a8f-\\u0a91\\u0a93-\\u0aa8\\u0aaa-\\u0ab0\\u0ab2\\u0ab3\\u0ab5-\\u0ab9\\u0abd\\u0ad0\\u0ae0\\u0ae1\\u0b05-\\u0b0c\\u0b0f\\u0b10\\u0b13-\\u0b28\\u0b2a-\\u0b30\\u0b32\\u0b33\\u0b35-\\u0b39\\u0b3d\\u0b5c\\u0b5d\\u0b5f-\\u0b61\\u0b71\\u0b83\\u0b85-\\u0b8a\\u0b8e-\\u0b90\\u0b92-\\u0b95\\u0b99\\u0b9a\\u0b9c\\u0b9e\\u0b9f\\u0ba3\\u0ba4\\u0ba8-\\u0baa\\u0bae-\\u0bb9\\u0bd0\\u0c05-\\u0c0c\\u0c0e-\\u0c10\\u0c12-\\u0c28\\u0c2a-\\u0c33\\u0c35-\\u0c39\\u0c3d\\u0c58\\u0c59\\u0c60\\u0c61\\u0c85-\\u0c8c\\u0c8e-\\u0c90\\u0c92-\\u0ca8\\u0caa-\\u0cb3\\u0cb5-\\u0cb9\\u0cbd\\u0cde\\u0ce0\\u0ce1\\u0cf1\\u0cf2\\u0d05-\\u0d0c\\u0d0e-\\u0d10\\u0d12-\\u0d3a\\u0d3d\\u0d4e\\u0d60\\u0d61\\u0d7a-\\u0d7f\\u0d85-\\u0d96\\u0d9a-\\u0db1\\u0db3-\\u0dbb\\u0dbd\\u0dc0-\\u0dc6\\u0e01-\\u0e30\\u0e32\\u0e33\\u0e40-\\u0e46\\u0e81\\u0e82\\u0e84\\u0e87\\u0e88\\u0e8a\\u0e8d\\u0e94-\\u0e97\\u0e99-\\u0e9f\\u0ea1-\\u0ea3\\u0ea5\\u0ea7\\u0eaa\\u0eab\\u0ead-\\u0eb0\\u0eb2\\u0eb3\\u0ebd\\u0ec0-\\u0ec4\\u0ec6\\u0edc-\\u0edf\\u0f00\\u0f40-\\u0f47\\u0f49-\\u0f6c\\u0f88-\\u0f8c\\u1000-\\u102a\\u103f\\u1050-\\u1055\\u105a-\\u105d\\u1061\\u1065\\u1066\\u106e-\\u1070\\u1075-\\u1081\\u108e\\u10a0-\\u10c5\\u10c7\\u10cd\\u10d0-\\u10fa\\u10fc-\\u1248\\u124a-\\u124d\\u1250-\\u1256\\u1258\\u125a-\\u125d\\u1260-\\u1288\\u128a-\\u128d\\u1290-\\u12b0\\u12b2-\\u12b5\\u12b8-\\u12be\\u12c0\\u12c2-\\u12c5\\u12c8-\\u12d6\\u12d8-\\u1310\\u1312-\\u1315\\u1318-\\u135a\\u1380-\\u138f\\u13a0-\\u13f4\\u1401-\\u166c\\u166f-\\u167f\\u1681-\\u169a\\u16a0-\\u16ea\\u16ee-\\u16f0\\u1700-\\u170c\\u170e-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176c\\u176e-\\u1770\\u1780-\\u17b3\\u17d7\\u17dc\\u1820-\\u1877\\u1880-\\u18a8\\u18aa\\u18b0-\\u18f5\\u1900-\\u191c\\u1950-\\u196d\\u1970-\\u1974\\u1980-\\u19ab\\u19c1-\\u19c7\\u1a00-\\u1a16\\u1a20-\\u1a54\\u1aa7\\u1b05-\\u1b33\\u1b45-\\u1b4b\\u1b83-\\u1ba0\\u1bae\\u1baf\\u1bba-\\u1be5\\u1c00-\\u1c23\\u1c4d-\\u1c4f\\u1c5a-\\u1c7d\\u1ce9-\\u1cec\\u1cee-\\u1cf1\\u1cf5\\u1cf6\\u1d00-\\u1dbf\\u1e00-\\u1f15\\u1f18-\\u1f1d\\u1f20-\\u1f45\\u1f48-\\u1f4d\\u1f50-\\u1f57\\u1f59\\u1f5b\\u1f5d\\u1f5f-\\u1f7d\\u1f80-\\u1fb4\\u1fb6-\\u1fbc\\u1fbe\\u1fc2-\\u1fc4\\u1fc6-\\u1fcc\\u1fd0-\\u1fd3\\u1fd6-\\u1fdb\\u1fe0-\\u1fec\\u1ff2-\\u1ff4\\u1ff6-\\u1ffc\\u2071\\u207f\\u2090-\\u209c\\u2102\\u2107\\u210a-\\u2113\\u2115\\u2119-\\u211d\\u2124\\u2126\\u2128\\u212a-\\u212d\\u212f-\\u2139\\u213c-\\u213f\\u2145-\\u2149\\u214e\\u2160-\\u2188\\u2c00-\\u2c2e\\u2c30-\\u2c5e\\u2c60-\\u2ce4\\u2ceb-\\u2cee\\u2cf2\\u2cf3\\u2d00-\\u2d25\\u2d27\\u2d2d\\u2d30-\\u2d67\\u2d6f\\u2d80-\\u2d96\\u2da0-\\u2da6\\u2da8-\\u2dae\\u2db0-\\u2db6\\u2db8-\\u2dbe\\u2dc0-\\u2dc6\\u2dc8-\\u2dce\\u2dd0-\\u2dd6\\u2dd8-\\u2dde\\u2e2f\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303c\\u3041-\\u3096\\u309d-\\u309f\\u30a1-\\u30fa\\u30fc-\\u30ff\\u3105-\\u312d\\u3131-\\u318e\\u31a0-\\u31ba\\u31f0-\\u31ff\\u3400-\\u4db5\\u4e00-\\u9fcc\\ua000-\\ua48c\\ua4d0-\\ua4fd\\ua500-\\ua60c\\ua610-\\ua61f\\ua62a\\ua62b\\ua640-\\ua66e\\ua67f-\\ua697\\ua6a0-\\ua6ef\\ua717-\\ua71f\\ua722-\\ua788\\ua78b-\\ua78e\\ua790-\\ua793\\ua7a0-\\ua7aa\\ua7f8-\\ua801\\ua803-\\ua805\\ua807-\\ua80a\\ua80c-\\ua822\\ua840-\\ua873\\ua882-\\ua8b3\\ua8f2-\\ua8f7\\ua8fb\\ua90a-\\ua925\\ua930-\\ua946\\ua960-\\ua97c\\ua984-\\ua9b2\\ua9cf\\uaa00-\\uaa28\\uaa40-\\uaa42\\uaa44-\\uaa4b\\uaa60-\\uaa76\\uaa7a\\uaa80-\\uaaaf\\uaab1\\uaab5\\uaab6\\uaab9-\\uaabd\\uaac0\\uaac2\\uaadb-\\uaadd\\uaae0-\\uaaea\\uaaf2-\\uaaf4\\uab01-\\uab06\\uab09-\\uab0e\\uab11-\\uab16\\uab20-\\uab26\\uab28-\\uab2e\\uabc0-\\uabe2\\uac00-\\ud7a3\\ud7b0-\\ud7c6\\ud7cb-\\ud7fb\\uf900-\\ufa6d\\ufa70-\\ufad9\\ufb00-\\ufb06\\ufb13-\\ufb17\\ufb1d\\ufb1f-\\ufb28\\ufb2a-\\ufb36\\ufb38-\\ufb3c\\ufb3e\\ufb40\\ufb41\\ufb43\\ufb44\\ufb46-\\ufbb1\\ufbd3-\\ufd3d\\ufd50-\\ufd8f\\ufd92-\\ufdc7\\ufdf0-\\ufdfb\\ufe70-\\ufe74\\ufe76-\\ufefc\\uff21-\\uff3a\\uff41-\\uff5a\\uff66-\\uffbe\\uffc2-\\uffc7\\uffca-\\uffcf\\uffd2-\\uffd7\\uffda-\\uffdc0-9\\u0300-\\u036f\\u0483-\\u0487\\u0591-\\u05bd\\u05bf\\u05c1\\u05c2\\u05c4\\u05c5\\u05c7\\u0610-\\u061a\\u064b-\\u0669\\u0670\\u06d6-\\u06dc\\u06df-\\u06e4\\u06e7\\u06e8\\u06ea-\\u06ed\\u06f0-\\u06f9\\u0711\\u0730-\\u074a\\u07a6-\\u07b0\\u07c0-\\u07c9\\u07eb-\\u07f3\\u0816-\\u0819\\u081b-\\u0823\\u0825-\\u0827\\u0829-\\u082d\\u0859-\\u085b\\u08e4-\\u08fe\\u0900-\\u0903\\u093a-\\u093c\\u093e-\\u094f\\u0951-\\u0957\\u0962\\u0963\\u0966-\\u096f\\u0981-\\u0983\\u09bc\\u09be-\\u09c4\\u09c7\\u09c8\\u09cb-\\u09cd\\u09d7\\u09e2\\u09e3\\u09e6-\\u09ef\\u0a01-\\u0a03\\u0a3c\\u0a3e-\\u0a42\\u0a47\\u0a48\\u0a4b-\\u0a4d\\u0a51\\u0a66-\\u0a71\\u0a75\\u0a81-\\u0a83\\u0abc\\u0abe-\\u0ac5\\u0ac7-\\u0ac9\\u0acb-\\u0acd\\u0ae2\\u0ae3\\u0ae6-\\u0aef\\u0b01-\\u0b03\\u0b3c\\u0b3e-\\u0b44\\u0b47\\u0b48\\u0b4b-\\u0b4d\\u0b56\\u0b57\\u0b62\\u0b63\\u0b66-\\u0b6f\\u0b82\\u0bbe-\\u0bc2\\u0bc6-\\u0bc8\\u0bca-\\u0bcd\\u0bd7\\u0be6-\\u0bef\\u0c01-\\u0c03\\u0c3e-\\u0c44\\u0c46-\\u0c48\\u0c4a-\\u0c4d\\u0c55\\u0c56\\u0c62\\u0c63\\u0c66-\\u0c6f\\u0c82\\u0c83\\u0cbc\\u0cbe-\\u0cc4\\u0cc6-\\u0cc8\\u0cca-\\u0ccd\\u0cd5\\u0cd6\\u0ce2\\u0ce3\\u0ce6-\\u0cef\\u0d02\\u0d03\\u0d3e-\\u0d44\\u0d46-\\u0d48\\u0d4a-\\u0d4d\\u0d57\\u0d62\\u0d63\\u0d66-\\u0d6f\\u0d82\\u0d83\\u0dca\\u0dcf-\\u0dd4\\u0dd6\\u0dd8-\\u0ddf\\u0df2\\u0df3\\u0e31\\u0e34-\\u0e3a\\u0e47-\\u0e4e\\u0e50-\\u0e59\\u0eb1\\u0eb4-\\u0eb9\\u0ebb\\u0ebc\\u0ec8-\\u0ecd\\u0ed0-\\u0ed9\\u0f18\\u0f19\\u0f20-\\u0f29\\u0f35\\u0f37\\u0f39\\u0f3e\\u0f3f\\u0f71-\\u0f84\\u0f86\\u0f87\\u0f8d-\\u0f97\\u0f99-\\u0fbc\\u0fc6\\u102b-\\u103e\\u1040-\\u1049\\u1056-\\u1059\\u105e-\\u1060\\u1062-\\u1064\\u1067-\\u106d\\u1071-\\u1074\\u1082-\\u108d\\u108f-\\u109d\\u135d-\\u135f\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17b4-\\u17d3\\u17dd\\u17e0-\\u17e9\\u180b-\\u180d\\u1810-\\u1819\\u18a9\\u1920-\\u192b\\u1930-\\u193b\\u1946-\\u194f\\u19b0-\\u19c0\\u19c8\\u19c9\\u19d0-\\u19d9\\u1a17-\\u1a1b\\u1a55-\\u1a5e\\u1a60-\\u1a7c\\u1a7f-\\u1a89\\u1a90-\\u1a99\\u1b00-\\u1b04\\u1b34-\\u1b44\\u1b50-\\u1b59\\u1b6b-\\u1b73\\u1b80-\\u1b82\\u1ba1-\\u1bad\\u1bb0-\\u1bb9\\u1be6-\\u1bf3\\u1c24-\\u1c37\\u1c40-\\u1c49\\u1c50-\\u1c59\\u1cd0-\\u1cd2\\u1cd4-\\u1ce8\\u1ced\\u1cf2-\\u1cf4\\u1dc0-\\u1de6\\u1dfc-\\u1dff\\u200c\\u200d\\u203f\\u2040\\u2054\\u20d0-\\u20dc\\u20e1\\u20e5-\\u20f0\\u2cef-\\u2cf1\\u2d7f\\u2de0-\\u2dff\\u302a-\\u302f\\u3099\\u309a\\ua620-\\ua629\\ua66f\\ua674-\\ua67d\\ua69f\\ua6f0\\ua6f1\\ua802\\ua806\\ua80b\\ua823-\\ua827\\ua880\\ua881\\ua8b4-\\ua8c4\\ua8d0-\\ua8d9\\ua8e0-\\ua8f1\\ua900-\\ua909\\ua926-\\ua92d\\ua947-\\ua953\\ua980-\\ua983\\ua9b3-\\ua9c0\\ua9d0-\\ua9d9\\uaa29-\\uaa36\\uaa43\\uaa4c\\uaa4d\\uaa50-\\uaa59\\uaa7b\\uaab0\\uaab2-\\uaab4\\uaab7\\uaab8\\uaabe\\uaabf\\uaac1\\uaaeb-\\uaaef\\uaaf5\\uaaf6\\uabe3-\\uabea\\uabec\\uabed\\uabf0-\\uabf9\\ufb1e\\ufe00-\\ufe0f\\ufe20-\\ufe26\\ufe33\\ufe34\\ufe4d-\\ufe4f\\uff10-\\uff19\\uff3f]*$\/;  traverse(ast, {   MemberExpression(path) {     const { computed, object, property } = path.node;     if (       !computed ||       !t.isStringLiteral(property) ||       !validIdentifierRegex.test(property.value)     ) {       return;     }      path.replaceWith(       t.MemberExpression(object, t.identifier(property.value), false)     );   }, });<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/074\/37c\/56b\/07437c56b56ba7ff74f8168632f085fa.png\" alt=\"\u0412\u043e\u0442 \u0443\u0436\u0435 \u0438 \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u043a\u0438\u0439 \u0432\u0438\u0434\" title=\"\u0412\u043e\u0442 \u0443\u0436\u0435 \u0438 \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u043a\u0438\u0439 \u0432\u0438\u0434\" width=\"2000\" height=\"517\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/074\/37c\/56b\/07437c56b56ba7ff74f8168632f085fa.png\"\/><figcaption>\u0412\u043e\u0442 \u0443\u0436\u0435 \u0438 \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u043a\u0438\u0439 \u0432\u0438\u0434<\/figcaption><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044e \u043a\u043e\u0434\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>&#171;\u0414\u0435\u043e\u0431\u0444\u0443\u0441\u043a\u0430\u0442\u043e\u0440&#187;<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">const { parse } = require('@babel\/parser'); const traverse = require('@babel\/traverse').default; const generate = require('@babel\/generator').default; const t = require('@babel\/types'); const fs = require('fs');  const srcCode = fs.readFileSync('srcCode.js', { encoding: 'utf-8' }); const ast = parse(srcCode);  traverse(ast, {   BinaryExpression(path) {     const { node } = path;     if (t.isNumericLiteral(node.left) &amp;&amp; t.isNumericLiteral(node.right)) {       path.replaceWith(t.numericLiteral(path.evaluate().value));     }   }, });  traverse(ast, {   SequenceExpression(path) {     const { node } = path;     let isAllNumbers = true;     for (let i = 0; i &lt; node.expressions.length; ++i) {       if (!t.isNumericLiteral(node.expressions[i])) {         isAllNumbers = false;         break;       }     }     if (isAllNumbers) {       path.replaceWith(t.numericLiteral(path.evaluate().value));     }   }, });  const mainArray = [];  traverse(ast, {   AssignmentExpression(path) {     const { node } = path;     if (t.isMemberExpression(node.left) &amp;&amp; node.left.property.name === '_') {       const elementsArray = node.right.elements;        elementsArray.forEach((el) => {         mainArray.push(el.value);       });        path.stop();     }   }, });  traverse(ast, {   MemberExpression(path) {     const { node } = path;      if (node.object.name === '_' &amp;&amp; t.isNumericLiteral(node.property)) {       path.replaceWith(t.stringLiteral(mainArray[node.property.value]));     }   }, });  function FindClosestScopeWithArray(scope) {   const result = {     array: [],     scope: {},   };    while (scope) {     scope.traverse(scope.block, {       CallExpression(path) {         const { node } = path;         if (           node.callee &amp;&amp;           t.isMemberExpression(node.callee) &amp;&amp;           !node.callee.computed &amp;&amp;           t.isStringLiteral(node.callee.object) &amp;&amp;           t.isIdentifier(node.callee.property) &amp;&amp;           node.callee.property.name === 'split'         ) {           const delimiter = node.arguments[0].value;           result.array = node.callee.object.value.split(delimiter);           result.scope = scope;           path.stop();         }       },     });      if (result.array.length === 0) {       \/\/ \u0415\u0441\u043b\u0438 \u043c\u0430\u0441\u0441\u0438\u0432 \u0435\u0449\u0451 \u043f\u0443\u0441\u0442, \u0437\u043d\u0430\u0447\u0438\u0442 \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 scope \u043d\u0435 \u0431\u044b\u043b\u043e \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0443\u0437\u043b\u0430 CallExpression => \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0443\u044e scope       scope = scope.parent;     } else {       return result;     }   } }  const getShuffleOffset = (scope) => {   let result;   scope.traverse(scope.block, {     CallExpression(path) {       const node = path.node;       if (         node.arguments.length === 2 &amp;&amp;         t.isNumericLiteral(node.arguments[1]) &amp;&amp;         t.isIdentifier(node.arguments[0]) &amp;&amp;         node.arguments[0].name === 'a'       ) {         result = node.arguments[1].value;         path.stop();       }     },   });   return result; };  const getOffsetForGetString = (scope) => {   let result;   scope.traverse(scope.block, {     ReturnStatement(path) {       const node = path.node;       if (         node.argument &amp;&amp;         t.isSequenceExpression(node.argument) &amp;&amp;         t.isAssignmentExpression(node.argument.expressions[0]) &amp;&amp;         t.isBinaryExpression(node.argument.expressions[0].right) &amp;&amp;         node.argument.expressions[0].right.operator === '-' &amp;&amp;         !isNaN(node.argument.expressions[0].right.right.value)       ) {         result = node.argument.expressions[0].right.right.value;         path.stop();       }     },   });   return result; };  const getComparisonExpr = (scope) => {   let result;   scope.traverse(scope.block, {     IfStatement(path) {       const node = path.node;       if (         t.isSequenceExpression(node.test) &amp;&amp;         t.isAssignmentExpression(node.test.expressions[0]) &amp;&amp;         t.isBinaryExpression(node.test.expressions[0].right) &amp;&amp;         t.isBinaryExpression(node.test.expressions[0].right.left) &amp;&amp;         t.isBinaryExpression(node.test.expressions[0].right.left.left)       ) {         result = generate(node.test.expressions[0].right).code; \/\/ \u0431\u0435\u0440\u0451\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0435\u0432\u043e node.test.expressions[0].right \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0438\u0437 \u043d\u0435\u0433\u043e \u043a\u043e\u0434         path.stop();       }     },   });   return result; };  function ShuffleArray(scope, scopeData) {   const shuffleOffset = getShuffleOffset(scope);   const offset = getOffsetForGetString(scope);   const \u0441omparisonExpr = getComparisonExpr(scope).replaceAll(     \/parseint\\(\\w+\\(\/gi,     'parseInt(getStringFromArray('   );    const getStringFromArray = (index) => {     return scopeData.array[index - offset];   };    scopeData.getString = getStringFromArray;    eval(`     while(true) {       try {         const f = ${\u0441omparisonExpr};         if (f === ${shuffleOffset}) break;         else scopeData.array.push(scopeData.array.shift());       } catch(e) {         scopeData.array.push(scopeData.array.shift());       }     }   `); }  const scopeUidToData = new Map(); traverse(ast, {   CallExpression: (path) => {     const { node } = path;     if (       node.arguments.length == 1 &amp;&amp;       t.isNumericLiteral(node.arguments[0])     ) {       const currentScope = path.scope;        const arrayAndScope = FindClosestScopeWithArray(currentScope);        const scopeData = {         array: arrayAndScope.array,       };       const requiredScope = arrayAndScope.scope;        if (scopeUidToData.has(requiredScope.uid)) {         const scopeData = scopeUidToData.get(requiredScope.uid);         try {           path.replaceWith(             t.stringLiteral(scopeData.getString(parseInt(node.arguments[0].value)))           )         } catch(e) {}         return;       }        ShuffleArray(requiredScope, scopeData);        scopeUidToData.set(requiredScope.uid, scopeData);       try {         path.replaceWith(           t.stringLiteral(scopeData.getString(parseInt(node.arguments[0].value)))         )       } catch(e) {}     }   }, });  const validIdentifierRegex =     \/^(?!(?:do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|this|true|void|with|break|catch|class|const|super|throw|while|yield|delete|export|import|public|return|static|switch|typeof|default|extends|finally|package|private|continue|debugger|function|arguments|interface|protected|implements|instanceof)$)[$A-Z\\_a-z\\xaa\\xb5\\xba\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\u02c1\\u02c6-\\u02d1\\u02e0-\\u02e4\\u02ec\\u02ee\\u0370-\\u0374\\u0376\\u0377\\u037a-\\u037d\\u0386\\u0388-\\u038a\\u038c\\u038e-\\u03a1\\u03a3-\\u03f5\\u03f7-\\u0481\\u048a-\\u0527\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05d0-\\u05ea\\u05f0-\\u05f2\\u0620-\\u064a\\u066e\\u066f\\u0671-\\u06d3\\u06d5\\u06e5\\u06e6\\u06ee\\u06ef\\u06fa-\\u06fc\\u06ff\\u0710\\u0712-\\u072f\\u074d-\\u07a5\\u07b1\\u07ca-\\u07ea\\u07f4\\u07f5\\u07fa\\u0800-\\u0815\\u081a\\u0824\\u0828\\u0840-\\u0858\\u08a0\\u08a2-\\u08ac\\u0904-\\u0939\\u093d\\u0950\\u0958-\\u0961\\u0971-\\u0977\\u0979-\\u097f\\u0985-\\u098c\\u098f\\u0990\\u0993-\\u09a8\\u09aa-\\u09b0\\u09b2\\u09b6-\\u09b9\\u09bd\\u09ce\\u09dc\\u09dd\\u09df-\\u09e1\\u09f0\\u09f1\\u0a05-\\u0a0a\\u0a0f\\u0a10\\u0a13-\\u0a28\\u0a2a-\\u0a30\\u0a32\\u0a33\\u0a35\\u0a36\\u0a38\\u0a39\\u0a59-\\u0a5c\\u0a5e\\u0a72-\\u0a74\\u0a85-\\u0a8d\\u0a8f-\\u0a91\\u0a93-\\u0aa8\\u0aaa-\\u0ab0\\u0ab2\\u0ab3\\u0ab5-\\u0ab9\\u0abd\\u0ad0\\u0ae0\\u0ae1\\u0b05-\\u0b0c\\u0b0f\\u0b10\\u0b13-\\u0b28\\u0b2a-\\u0b30\\u0b32\\u0b33\\u0b35-\\u0b39\\u0b3d\\u0b5c\\u0b5d\\u0b5f-\\u0b61\\u0b71\\u0b83\\u0b85-\\u0b8a\\u0b8e-\\u0b90\\u0b92-\\u0b95\\u0b99\\u0b9a\\u0b9c\\u0b9e\\u0b9f\\u0ba3\\u0ba4\\u0ba8-\\u0baa\\u0bae-\\u0bb9\\u0bd0\\u0c05-\\u0c0c\\u0c0e-\\u0c10\\u0c12-\\u0c28\\u0c2a-\\u0c33\\u0c35-\\u0c39\\u0c3d\\u0c58\\u0c59\\u0c60\\u0c61\\u0c85-\\u0c8c\\u0c8e-\\u0c90\\u0c92-\\u0ca8\\u0caa-\\u0cb3\\u0cb5-\\u0cb9\\u0cbd\\u0cde\\u0ce0\\u0ce1\\u0cf1\\u0cf2\\u0d05-\\u0d0c\\u0d0e-\\u0d10\\u0d12-\\u0d3a\\u0d3d\\u0d4e\\u0d60\\u0d61\\u0d7a-\\u0d7f\\u0d85-\\u0d96\\u0d9a-\\u0db1\\u0db3-\\u0dbb\\u0dbd\\u0dc0-\\u0dc6\\u0e01-\\u0e30\\u0e32\\u0e33\\u0e40-\\u0e46\\u0e81\\u0e82\\u0e84\\u0e87\\u0e88\\u0e8a\\u0e8d\\u0e94-\\u0e97\\u0e99-\\u0e9f\\u0ea1-\\u0ea3\\u0ea5\\u0ea7\\u0eaa\\u0eab\\u0ead-\\u0eb0\\u0eb2\\u0eb3\\u0ebd\\u0ec0-\\u0ec4\\u0ec6\\u0edc-\\u0edf\\u0f00\\u0f40-\\u0f47\\u0f49-\\u0f6c\\u0f88-\\u0f8c\\u1000-\\u102a\\u103f\\u1050-\\u1055\\u105a-\\u105d\\u1061\\u1065\\u1066\\u106e-\\u1070\\u1075-\\u1081\\u108e\\u10a0-\\u10c5\\u10c7\\u10cd\\u10d0-\\u10fa\\u10fc-\\u1248\\u124a-\\u124d\\u1250-\\u1256\\u1258\\u125a-\\u125d\\u1260-\\u1288\\u128a-\\u128d\\u1290-\\u12b0\\u12b2-\\u12b5\\u12b8-\\u12be\\u12c0\\u12c2-\\u12c5\\u12c8-\\u12d6\\u12d8-\\u1310\\u1312-\\u1315\\u1318-\\u135a\\u1380-\\u138f\\u13a0-\\u13f4\\u1401-\\u166c\\u166f-\\u167f\\u1681-\\u169a\\u16a0-\\u16ea\\u16ee-\\u16f0\\u1700-\\u170c\\u170e-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176c\\u176e-\\u1770\\u1780-\\u17b3\\u17d7\\u17dc\\u1820-\\u1877\\u1880-\\u18a8\\u18aa\\u18b0-\\u18f5\\u1900-\\u191c\\u1950-\\u196d\\u1970-\\u1974\\u1980-\\u19ab\\u19c1-\\u19c7\\u1a00-\\u1a16\\u1a20-\\u1a54\\u1aa7\\u1b05-\\u1b33\\u1b45-\\u1b4b\\u1b83-\\u1ba0\\u1bae\\u1baf\\u1bba-\\u1be5\\u1c00-\\u1c23\\u1c4d-\\u1c4f\\u1c5a-\\u1c7d\\u1ce9-\\u1cec\\u1cee-\\u1cf1\\u1cf5\\u1cf6\\u1d00-\\u1dbf\\u1e00-\\u1f15\\u1f18-\\u1f1d\\u1f20-\\u1f45\\u1f48-\\u1f4d\\u1f50-\\u1f57\\u1f59\\u1f5b\\u1f5d\\u1f5f-\\u1f7d\\u1f80-\\u1fb4\\u1fb6-\\u1fbc\\u1fbe\\u1fc2-\\u1fc4\\u1fc6-\\u1fcc\\u1fd0-\\u1fd3\\u1fd6-\\u1fdb\\u1fe0-\\u1fec\\u1ff2-\\u1ff4\\u1ff6-\\u1ffc\\u2071\\u207f\\u2090-\\u209c\\u2102\\u2107\\u210a-\\u2113\\u2115\\u2119-\\u211d\\u2124\\u2126\\u2128\\u212a-\\u212d\\u212f-\\u2139\\u213c-\\u213f\\u2145-\\u2149\\u214e\\u2160-\\u2188\\u2c00-\\u2c2e\\u2c30-\\u2c5e\\u2c60-\\u2ce4\\u2ceb-\\u2cee\\u2cf2\\u2cf3\\u2d00-\\u2d25\\u2d27\\u2d2d\\u2d30-\\u2d67\\u2d6f\\u2d80-\\u2d96\\u2da0-\\u2da6\\u2da8-\\u2dae\\u2db0-\\u2db6\\u2db8-\\u2dbe\\u2dc0-\\u2dc6\\u2dc8-\\u2dce\\u2dd0-\\u2dd6\\u2dd8-\\u2dde\\u2e2f\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303c\\u3041-\\u3096\\u309d-\\u309f\\u30a1-\\u30fa\\u30fc-\\u30ff\\u3105-\\u312d\\u3131-\\u318e\\u31a0-\\u31ba\\u31f0-\\u31ff\\u3400-\\u4db5\\u4e00-\\u9fcc\\ua000-\\ua48c\\ua4d0-\\ua4fd\\ua500-\\ua60c\\ua610-\\ua61f\\ua62a\\ua62b\\ua640-\\ua66e\\ua67f-\\ua697\\ua6a0-\\ua6ef\\ua717-\\ua71f\\ua722-\\ua788\\ua78b-\\ua78e\\ua790-\\ua793\\ua7a0-\\ua7aa\\ua7f8-\\ua801\\ua803-\\ua805\\ua807-\\ua80a\\ua80c-\\ua822\\ua840-\\ua873\\ua882-\\ua8b3\\ua8f2-\\ua8f7\\ua8fb\\ua90a-\\ua925\\ua930-\\ua946\\ua960-\\ua97c\\ua984-\\ua9b2\\ua9cf\\uaa00-\\uaa28\\uaa40-\\uaa42\\uaa44-\\uaa4b\\uaa60-\\uaa76\\uaa7a\\uaa80-\\uaaaf\\uaab1\\uaab5\\uaab6\\uaab9-\\uaabd\\uaac0\\uaac2\\uaadb-\\uaadd\\uaae0-\\uaaea\\uaaf2-\\uaaf4\\uab01-\\uab06\\uab09-\\uab0e\\uab11-\\uab16\\uab20-\\uab26\\uab28-\\uab2e\\uabc0-\\uabe2\\uac00-\\ud7a3\\ud7b0-\\ud7c6\\ud7cb-\\ud7fb\\uf900-\\ufa6d\\ufa70-\\ufad9\\ufb00-\\ufb06\\ufb13-\\ufb17\\ufb1d\\ufb1f-\\ufb28\\ufb2a-\\ufb36\\ufb38-\\ufb3c\\ufb3e\\ufb40\\ufb41\\ufb43\\ufb44\\ufb46-\\ufbb1\\ufbd3-\\ufd3d\\ufd50-\\ufd8f\\ufd92-\\ufdc7\\ufdf0-\\ufdfb\\ufe70-\\ufe74\\ufe76-\\ufefc\\uff21-\\uff3a\\uff41-\\uff5a\\uff66-\\uffbe\\uffc2-\\uffc7\\uffca-\\uffcf\\uffd2-\\uffd7\\uffda-\\uffdc][$A-Z\\_a-z\\xaa\\xb5\\xba\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\u02c1\\u02c6-\\u02d1\\u02e0-\\u02e4\\u02ec\\u02ee\\u0370-\\u0374\\u0376\\u0377\\u037a-\\u037d\\u0386\\u0388-\\u038a\\u038c\\u038e-\\u03a1\\u03a3-\\u03f5\\u03f7-\\u0481\\u048a-\\u0527\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05d0-\\u05ea\\u05f0-\\u05f2\\u0620-\\u064a\\u066e\\u066f\\u0671-\\u06d3\\u06d5\\u06e5\\u06e6\\u06ee\\u06ef\\u06fa-\\u06fc\\u06ff\\u0710\\u0712-\\u072f\\u074d-\\u07a5\\u07b1\\u07ca-\\u07ea\\u07f4\\u07f5\\u07fa\\u0800-\\u0815\\u081a\\u0824\\u0828\\u0840-\\u0858\\u08a0\\u08a2-\\u08ac\\u0904-\\u0939\\u093d\\u0950\\u0958-\\u0961\\u0971-\\u0977\\u0979-\\u097f\\u0985-\\u098c\\u098f\\u0990\\u0993-\\u09a8\\u09aa-\\u09b0\\u09b2\\u09b6-\\u09b9\\u09bd\\u09ce\\u09dc\\u09dd\\u09df-\\u09e1\\u09f0\\u09f1\\u0a05-\\u0a0a\\u0a0f\\u0a10\\u0a13-\\u0a28\\u0a2a-\\u0a30\\u0a32\\u0a33\\u0a35\\u0a36\\u0a38\\u0a39\\u0a59-\\u0a5c\\u0a5e\\u0a72-\\u0a74\\u0a85-\\u0a8d\\u0a8f-\\u0a91\\u0a93-\\u0aa8\\u0aaa-\\u0ab0\\u0ab2\\u0ab3\\u0ab5-\\u0ab9\\u0abd\\u0ad0\\u0ae0\\u0ae1\\u0b05-\\u0b0c\\u0b0f\\u0b10\\u0b13-\\u0b28\\u0b2a-\\u0b30\\u0b32\\u0b33\\u0b35-\\u0b39\\u0b3d\\u0b5c\\u0b5d\\u0b5f-\\u0b61\\u0b71\\u0b83\\u0b85-\\u0b8a\\u0b8e-\\u0b90\\u0b92-\\u0b95\\u0b99\\u0b9a\\u0b9c\\u0b9e\\u0b9f\\u0ba3\\u0ba4\\u0ba8-\\u0baa\\u0bae-\\u0bb9\\u0bd0\\u0c05-\\u0c0c\\u0c0e-\\u0c10\\u0c12-\\u0c28\\u0c2a-\\u0c33\\u0c35-\\u0c39\\u0c3d\\u0c58\\u0c59\\u0c60\\u0c61\\u0c85-\\u0c8c\\u0c8e-\\u0c90\\u0c92-\\u0ca8\\u0caa-\\u0cb3\\u0cb5-\\u0cb9\\u0cbd\\u0cde\\u0ce0\\u0ce1\\u0cf1\\u0cf2\\u0d05-\\u0d0c\\u0d0e-\\u0d10\\u0d12-\\u0d3a\\u0d3d\\u0d4e\\u0d60\\u0d61\\u0d7a-\\u0d7f\\u0d85-\\u0d96\\u0d9a-\\u0db1\\u0db3-\\u0dbb\\u0dbd\\u0dc0-\\u0dc6\\u0e01-\\u0e30\\u0e32\\u0e33\\u0e40-\\u0e46\\u0e81\\u0e82\\u0e84\\u0e87\\u0e88\\u0e8a\\u0e8d\\u0e94-\\u0e97\\u0e99-\\u0e9f\\u0ea1-\\u0ea3\\u0ea5\\u0ea7\\u0eaa\\u0eab\\u0ead-\\u0eb0\\u0eb2\\u0eb3\\u0ebd\\u0ec0-\\u0ec4\\u0ec6\\u0edc-\\u0edf\\u0f00\\u0f40-\\u0f47\\u0f49-\\u0f6c\\u0f88-\\u0f8c\\u1000-\\u102a\\u103f\\u1050-\\u1055\\u105a-\\u105d\\u1061\\u1065\\u1066\\u106e-\\u1070\\u1075-\\u1081\\u108e\\u10a0-\\u10c5\\u10c7\\u10cd\\u10d0-\\u10fa\\u10fc-\\u1248\\u124a-\\u124d\\u1250-\\u1256\\u1258\\u125a-\\u125d\\u1260-\\u1288\\u128a-\\u128d\\u1290-\\u12b0\\u12b2-\\u12b5\\u12b8-\\u12be\\u12c0\\u12c2-\\u12c5\\u12c8-\\u12d6\\u12d8-\\u1310\\u1312-\\u1315\\u1318-\\u135a\\u1380-\\u138f\\u13a0-\\u13f4\\u1401-\\u166c\\u166f-\\u167f\\u1681-\\u169a\\u16a0-\\u16ea\\u16ee-\\u16f0\\u1700-\\u170c\\u170e-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176c\\u176e-\\u1770\\u1780-\\u17b3\\u17d7\\u17dc\\u1820-\\u1877\\u1880-\\u18a8\\u18aa\\u18b0-\\u18f5\\u1900-\\u191c\\u1950-\\u196d\\u1970-\\u1974\\u1980-\\u19ab\\u19c1-\\u19c7\\u1a00-\\u1a16\\u1a20-\\u1a54\\u1aa7\\u1b05-\\u1b33\\u1b45-\\u1b4b\\u1b83-\\u1ba0\\u1bae\\u1baf\\u1bba-\\u1be5\\u1c00-\\u1c23\\u1c4d-\\u1c4f\\u1c5a-\\u1c7d\\u1ce9-\\u1cec\\u1cee-\\u1cf1\\u1cf5\\u1cf6\\u1d00-\\u1dbf\\u1e00-\\u1f15\\u1f18-\\u1f1d\\u1f20-\\u1f45\\u1f48-\\u1f4d\\u1f50-\\u1f57\\u1f59\\u1f5b\\u1f5d\\u1f5f-\\u1f7d\\u1f80-\\u1fb4\\u1fb6-\\u1fbc\\u1fbe\\u1fc2-\\u1fc4\\u1fc6-\\u1fcc\\u1fd0-\\u1fd3\\u1fd6-\\u1fdb\\u1fe0-\\u1fec\\u1ff2-\\u1ff4\\u1ff6-\\u1ffc\\u2071\\u207f\\u2090-\\u209c\\u2102\\u2107\\u210a-\\u2113\\u2115\\u2119-\\u211d\\u2124\\u2126\\u2128\\u212a-\\u212d\\u212f-\\u2139\\u213c-\\u213f\\u2145-\\u2149\\u214e\\u2160-\\u2188\\u2c00-\\u2c2e\\u2c30-\\u2c5e\\u2c60-\\u2ce4\\u2ceb-\\u2cee\\u2cf2\\u2cf3\\u2d00-\\u2d25\\u2d27\\u2d2d\\u2d30-\\u2d67\\u2d6f\\u2d80-\\u2d96\\u2da0-\\u2da6\\u2da8-\\u2dae\\u2db0-\\u2db6\\u2db8-\\u2dbe\\u2dc0-\\u2dc6\\u2dc8-\\u2dce\\u2dd0-\\u2dd6\\u2dd8-\\u2dde\\u2e2f\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303c\\u3041-\\u3096\\u309d-\\u309f\\u30a1-\\u30fa\\u30fc-\\u30ff\\u3105-\\u312d\\u3131-\\u318e\\u31a0-\\u31ba\\u31f0-\\u31ff\\u3400-\\u4db5\\u4e00-\\u9fcc\\ua000-\\ua48c\\ua4d0-\\ua4fd\\ua500-\\ua60c\\ua610-\\ua61f\\ua62a\\ua62b\\ua640-\\ua66e\\ua67f-\\ua697\\ua6a0-\\ua6ef\\ua717-\\ua71f\\ua722-\\ua788\\ua78b-\\ua78e\\ua790-\\ua793\\ua7a0-\\ua7aa\\ua7f8-\\ua801\\ua803-\\ua805\\ua807-\\ua80a\\ua80c-\\ua822\\ua840-\\ua873\\ua882-\\ua8b3\\ua8f2-\\ua8f7\\ua8fb\\ua90a-\\ua925\\ua930-\\ua946\\ua960-\\ua97c\\ua984-\\ua9b2\\ua9cf\\uaa00-\\uaa28\\uaa40-\\uaa42\\uaa44-\\uaa4b\\uaa60-\\uaa76\\uaa7a\\uaa80-\\uaaaf\\uaab1\\uaab5\\uaab6\\uaab9-\\uaabd\\uaac0\\uaac2\\uaadb-\\uaadd\\uaae0-\\uaaea\\uaaf2-\\uaaf4\\uab01-\\uab06\\uab09-\\uab0e\\uab11-\\uab16\\uab20-\\uab26\\uab28-\\uab2e\\uabc0-\\uabe2\\uac00-\\ud7a3\\ud7b0-\\ud7c6\\ud7cb-\\ud7fb\\uf900-\\ufa6d\\ufa70-\\ufad9\\ufb00-\\ufb06\\ufb13-\\ufb17\\ufb1d\\ufb1f-\\ufb28\\ufb2a-\\ufb36\\ufb38-\\ufb3c\\ufb3e\\ufb40\\ufb41\\ufb43\\ufb44\\ufb46-\\ufbb1\\ufbd3-\\ufd3d\\ufd50-\\ufd8f\\ufd92-\\ufdc7\\ufdf0-\\ufdfb\\ufe70-\\ufe74\\ufe76-\\ufefc\\uff21-\\uff3a\\uff41-\\uff5a\\uff66-\\uffbe\\uffc2-\\uffc7\\uffca-\\uffcf\\uffd2-\\uffd7\\uffda-\\uffdc0-9\\u0300-\\u036f\\u0483-\\u0487\\u0591-\\u05bd\\u05bf\\u05c1\\u05c2\\u05c4\\u05c5\\u05c7\\u0610-\\u061a\\u064b-\\u0669\\u0670\\u06d6-\\u06dc\\u06df-\\u06e4\\u06e7\\u06e8\\u06ea-\\u06ed\\u06f0-\\u06f9\\u0711\\u0730-\\u074a\\u07a6-\\u07b0\\u07c0-\\u07c9\\u07eb-\\u07f3\\u0816-\\u0819\\u081b-\\u0823\\u0825-\\u0827\\u0829-\\u082d\\u0859-\\u085b\\u08e4-\\u08fe\\u0900-\\u0903\\u093a-\\u093c\\u093e-\\u094f\\u0951-\\u0957\\u0962\\u0963\\u0966-\\u096f\\u0981-\\u0983\\u09bc\\u09be-\\u09c4\\u09c7\\u09c8\\u09cb-\\u09cd\\u09d7\\u09e2\\u09e3\\u09e6-\\u09ef\\u0a01-\\u0a03\\u0a3c\\u0a3e-\\u0a42\\u0a47\\u0a48\\u0a4b-\\u0a4d\\u0a51\\u0a66-\\u0a71\\u0a75\\u0a81-\\u0a83\\u0abc\\u0abe-\\u0ac5\\u0ac7-\\u0ac9\\u0acb-\\u0acd\\u0ae2\\u0ae3\\u0ae6-\\u0aef\\u0b01-\\u0b03\\u0b3c\\u0b3e-\\u0b44\\u0b47\\u0b48\\u0b4b-\\u0b4d\\u0b56\\u0b57\\u0b62\\u0b63\\u0b66-\\u0b6f\\u0b82\\u0bbe-\\u0bc2\\u0bc6-\\u0bc8\\u0bca-\\u0bcd\\u0bd7\\u0be6-\\u0bef\\u0c01-\\u0c03\\u0c3e-\\u0c44\\u0c46-\\u0c48\\u0c4a-\\u0c4d\\u0c55\\u0c56\\u0c62\\u0c63\\u0c66-\\u0c6f\\u0c82\\u0c83\\u0cbc\\u0cbe-\\u0cc4\\u0cc6-\\u0cc8\\u0cca-\\u0ccd\\u0cd5\\u0cd6\\u0ce2\\u0ce3\\u0ce6-\\u0cef\\u0d02\\u0d03\\u0d3e-\\u0d44\\u0d46-\\u0d48\\u0d4a-\\u0d4d\\u0d57\\u0d62\\u0d63\\u0d66-\\u0d6f\\u0d82\\u0d83\\u0dca\\u0dcf-\\u0dd4\\u0dd6\\u0dd8-\\u0ddf\\u0df2\\u0df3\\u0e31\\u0e34-\\u0e3a\\u0e47-\\u0e4e\\u0e50-\\u0e59\\u0eb1\\u0eb4-\\u0eb9\\u0ebb\\u0ebc\\u0ec8-\\u0ecd\\u0ed0-\\u0ed9\\u0f18\\u0f19\\u0f20-\\u0f29\\u0f35\\u0f37\\u0f39\\u0f3e\\u0f3f\\u0f71-\\u0f84\\u0f86\\u0f87\\u0f8d-\\u0f97\\u0f99-\\u0fbc\\u0fc6\\u102b-\\u103e\\u1040-\\u1049\\u1056-\\u1059\\u105e-\\u1060\\u1062-\\u1064\\u1067-\\u106d\\u1071-\\u1074\\u1082-\\u108d\\u108f-\\u109d\\u135d-\\u135f\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17b4-\\u17d3\\u17dd\\u17e0-\\u17e9\\u180b-\\u180d\\u1810-\\u1819\\u18a9\\u1920-\\u192b\\u1930-\\u193b\\u1946-\\u194f\\u19b0-\\u19c0\\u19c8\\u19c9\\u19d0-\\u19d9\\u1a17-\\u1a1b\\u1a55-\\u1a5e\\u1a60-\\u1a7c\\u1a7f-\\u1a89\\u1a90-\\u1a99\\u1b00-\\u1b04\\u1b34-\\u1b44\\u1b50-\\u1b59\\u1b6b-\\u1b73\\u1b80-\\u1b82\\u1ba1-\\u1bad\\u1bb0-\\u1bb9\\u1be6-\\u1bf3\\u1c24-\\u1c37\\u1c40-\\u1c49\\u1c50-\\u1c59\\u1cd0-\\u1cd2\\u1cd4-\\u1ce8\\u1ced\\u1cf2-\\u1cf4\\u1dc0-\\u1de6\\u1dfc-\\u1dff\\u200c\\u200d\\u203f\\u2040\\u2054\\u20d0-\\u20dc\\u20e1\\u20e5-\\u20f0\\u2cef-\\u2cf1\\u2d7f\\u2de0-\\u2dff\\u302a-\\u302f\\u3099\\u309a\\ua620-\\ua629\\ua66f\\ua674-\\ua67d\\ua69f\\ua6f0\\ua6f1\\ua802\\ua806\\ua80b\\ua823-\\ua827\\ua880\\ua881\\ua8b4-\\ua8c4\\ua8d0-\\ua8d9\\ua8e0-\\ua8f1\\ua900-\\ua909\\ua926-\\ua92d\\ua947-\\ua953\\ua980-\\ua983\\ua9b3-\\ua9c0\\ua9d0-\\ua9d9\\uaa29-\\uaa36\\uaa43\\uaa4c\\uaa4d\\uaa50-\\uaa59\\uaa7b\\uaab0\\uaab2-\\uaab4\\uaab7\\uaab8\\uaabe\\uaabf\\uaac1\\uaaeb-\\uaaef\\uaaf5\\uaaf6\\uabe3-\\uabea\\uabec\\uabed\\uabf0-\\uabf9\\ufb1e\\ufe00-\\ufe0f\\ufe20-\\ufe26\\ufe33\\ufe34\\ufe4d-\\ufe4f\\uff10-\\uff19\\uff3f]*$\/;  traverse(ast, {   MemberExpression(path) {     const { computed, object, property } = path.node;     if (       !computed ||       !t.isStringLiteral(property) ||       !validIdentifierRegex.test(property.value)     ) {       return;     }      path.replaceWith(       t.MemberExpression(object, t.identifier(property.value), false)     );   }, });   fs.writeFileSync('deobfuscatedCode.js', generate(ast).code); <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u0414\u0435\u043e\u0431\u0444\u0443\u0441\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434<\/h2>\n<p>\u0423 \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440\u0430 \u0435\u0449\u0451 \u043c\u043d\u043e\u0433\u043e \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u0441 AST, \u043d\u043e \u0441\u0442\u0440\u043e\u043a\u0438 &#8212; \u044d\u0442\u043e \u0442\u043e, \u0438\u0437-\u0437\u0430 \u0447\u0435\u0433\u043e \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0433\u043b\u0430\u0437\u0430\u043c\u0438 \u043f\u043e\u043d\u044f\u0442\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0435. \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f &#8212; \u043f\u044b\u043b\u044c \u0432 \u0433\u043b\u0430\u0437\u0430, \u0434\u0430\u0436\u0435 \u043d\u0435 \u043f\u0435\u0441\u043e\u043a. \u0421\u0435\u0439\u0447\u0430\u0441 \u044f \u043c\u043e\u0433\u0443 \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u043a\u0430\u0436\u0434\u043e\u043c <code>case<\/code> \u044d\u0442\u043e\u0433\u043e \u043e\u0433\u0440\u043e\u043c\u043d\u043e\u0433\u043e <code>switch<\/code>. \u0421\u043f\u0430\u0441\u0438\u0431\u043e, \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440, \u0447\u0442\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u043b \u0432\u0441\u0435 \u0442\u0435\u0441\u0442\u044b \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0431\u043b\u043e\u043a\u0438. \u041e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e! \u0422\u0430\u043a\u043e\u0439 \u043c\u0435\u0442\u043e\u0434\u044b \u043e\u0431\u0444\u0443\u0441\u043a\u0430\u0446\u0438\u0438 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u201cControl Flow Flattening\u201d.<\/p>\n<p>\u042f \u043d\u0435 \u0431\u0443\u0434\u0443 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u0443\u044e \u0441\u0442\u0440\u043e\u0447\u043a\u0443, \u043b\u0438\u0448\u044c \u0430\u043a\u0446\u0435\u043d\u0442\u0438\u0440\u0443\u044e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0442\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b, \u0438\u0437-\u0437\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 headless-\u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u0432 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a.<\/p>\n<p> <strong>performance.memory<\/strong><\/p>\n<pre><code class=\"javascript\">function f(r, j) {   (r = p),     (j = Object.getOwnPropertyNames(       Object.getPrototypeOf(window.performance.memory)     ).filter(function (k, s) {       return (s = r), k !== 'constructor';     })),     j.map(function (k, t) {       (t = r), c.push(window.performance.memory[k].toString(36));     }); }  function i() {   if ((f(), h++, h === 3)) return void e();   setTimeout(i, 55); }<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u0414\u043b\u044f \u043b\u044e\u0434\u0435\u0439<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">const container = [];  const checkMemory = () => { const memoryInfoProps = Object.getOwnPropertyNames(   Object.getPrototypeOf(window.performance.memory) ).filter(prop => {   return prop !== 'constructor'; }); \/\/ ['totalJSHeapSize', 'usedJSHeapSize', 'jsHeapSizeLimit']  memoryInfoProps.map(prop => {       container.push(window.performance.memory[prop].toString(36)); }); }  setTimeout(checkMemory, 55); setTimeout(checkMemory, 110); setTimeout(checkMemory, 165);<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u043b\u044f \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0441\u0442\u0438 \u044f \u0443\u0431\u0440\u0430\u043b \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0432 36-\u0440\u0438\u0447\u043d\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0441\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f:<\/p>\n<details class=\"spoiler\">\n<summary>\u041e\u0431\u044b\u0447\u043d\u044b\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/599\/b47\/194\/599b471941209acdc373d543dd48c280.png\" width=\"640\" height=\"281\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/599\/b47\/194\/599b471941209acdc373d543dd48c280.png\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>Headless<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/418\/328\/497\/4183284976e2b3f5ed415ff1ad76cc24.png\" alt=\"\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u0438 \u0443 \u0432\u0441\u0435\u0445 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435\" title=\"\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u0438 \u0443 \u0432\u0441\u0435\u0445 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435\" width=\"676\" height=\"287\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/418\/328\/497\/4183284976e2b3f5ed415ff1ad76cc24.png\"\/><figcaption>\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u0438 \u0443 \u0432\u0441\u0435\u0445 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435<\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p><strong>plugins<\/strong><\/p>\n<p>\u041a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0435\u043b\u0438 \u0432\u044b\u0448\u0435, \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u043f\u043b\u0430\u0433\u0438\u043d\u044b, \u0430 \u0432 headless \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u0438\u0445 \u043d\u0435\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0445 \u0442\u043e\u0436\u0435 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u044d\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u041d\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u044d\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0447\u0435\u0440\u0435\u0437 js &#8212; \u044d\u0442\u043e \u0437\u0430\u0434\u0430\u0447\u043a\u0430 \u0441 \u0434\u0432\u0443\u043c\u044f \u0437\u0432\u0451\u0437\u0434\u043e\u0447\u043a\u0430\u043c\u0438. \u0418 \u043c\u044b \u0441\u043d\u043e\u0432\u0430 \u0432\u044b\u043d\u0443\u0436\u0434\u0435\u043d\u044b \u043f\u043e\u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u0438\u0442\u044c \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440 \u0437\u0430 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u0443\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u044d\u043c\u0443\u043b\u044f\u0446\u0438\u044e \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u043e\u043c \u201c\u0442\u044f\u043f \u0434\u0430 \u043b\u044f\u043f, \u0442\u044f\u043f \u043b\u044f\u043f, \u0448\u0430\u043b\u044f\u0439 \u0432\u0430\u043b\u044f\u0439, \u043a\u043e\u0435 \u043a\u0430\u043a, \u043a\u0430\u043a-\u043d\u0438\u0431\u0443\u0434\u044c\u201d, \u043d\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043d\u0435 \u0437\u0430\u0431\u044b\u0442\u044c \u043f\u0440\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u044e\u0430\u043d\u0441\u044b:<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440\u0430<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"json\">var __pl = navigator.plugins.item(4294967296);              var __n = '';              if (__pl) {               __n = __pl.name;             }              DMXvQpNm[DMXvQpNm[0]] *=               +(                 navigator.plugins.item(4294967297) ===                 navigator.plugins.item(1)               ) *<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u042d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0441\u0442\u0430\u0440\u044b\u0439 \u0434\u0435\u0442\u0435\u043a\u0442 \u043d\u0430 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>item()<\/code>. \u0412 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 Chromium \u0434\u0430\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0442\u0438\u043f unsigned, \u0447\u0435\u0439 \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c 4294967295. \u0415\u0441\u043b\u0438 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u043f\u0440\u0435\u0432\u044b\u0441\u0438\u0442\u044c, \u0442\u043e 4294967297 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u0441\u044f \u0432 1. \u042d\u0442\u043e \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0440\u043e\u043a\u0438 <code>navigator.plugins.item(4294967297) === navigator.plugins.item(1)<\/code>.<\/p>\n<p><strong>toString()<\/strong>&#8216;s<\/p>\n<p>\u041d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0437\u0430\u0431\u044b\u0432\u0430\u0442\u044c \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u0442\u044c <code>toString()<\/code> \u0443 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438 \u0437\u0430\u043f\u043e\u0434\u043e\u0437\u0440\u0438\u0442\u044c \u044d\u043c\u0443\u043b\u044f\u0446\u0438\u044e. \u0418 \u043e\u043d \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442:<\/p>\n<pre><code class=\"javascript\">(c = function (j, k, A) {     return (       (A = b),       k instanceof j.Function &amp;&amp;         j.Function.prototype.toString           .call(k)           .indexOf('[native code]') > 0     );   }),<\/code><\/pre>\n<p> \u0412\u044b \u043f\u043e\u043d\u044f\u043b\u0438, \u0434\u0430?) \u0413\u0440\u0443\u0431\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u0435\u0441\u043b\u0438 \u044f \u0441\u0434\u0435\u043b\u0430\u044e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"javascript\">const jsonStringify = JSON.stringify; JSON.stringify = function() {   '[native code]';   return jsonStringify.apply(null, arguments); }<\/code><\/pre>\n<p>\u041a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u0430\u043f\u043e\u0434\u043e\u0437\u0440\u0438\u0442.<\/p>\n<p> <strong>window.chrome<\/strong><\/p>\n<p>\u0412 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u044d\u0442\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432 headless \u043c\u043e\u0434\u0435 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442:<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440\u0430<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">... for (var m = 0; m &lt; 9; m++) {       k = new Array();       s = 0;       v = 0;       m2 = 0;       ns = 0;       pt = -1;        if (window.chrome &amp;&amp; window.chrome.csi) {         pt = window.chrome.csi().pageT;       }        if (         window.performance.timing &amp;&amp;         window.performance.timing.navigationStart       ) {         ns = window.performance.timing.navigationStart;       }        for (var j = 0; j &lt; 10; j++) {         k.push(Date.now() - ns - pt);       }  ...     }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0442\u043e\u0436\u0435 \u044d\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u041e\u043f\u044f\u0442\u044c \u0436\u0435, \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u043d\u0430 \u044d\u043c\u0443\u043b\u044f\u0446\u0438\u044e  \u044f \u043d\u0435 \u043d\u0430\u0448\u0451\u043b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 <code>window.chrome<\/code> \u0442\u0430\u043a\u0436\u0435, \u043a\u0430\u043a \u043e\u043d \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d \u0432 \u0432\u0430\u0448\u0435\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435.<\/p>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043c\u043d\u043e\u0433\u043e\u0432\u0430\u0442\u043e \u043a\u043e\u0434\u0430, \u043d\u043e \u0434\u043b\u044f \u043b\u044e\u0434\u0435\u0439, \u0437\u043d\u0430\u044e\u0449\u0438\u0445 javascript, \u0437\u0434\u0435\u0441\u044c \u043d\u0435\u0442 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e  \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439. \u042f \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u043b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u0437 \u0441\u0432\u043e\u0435\u0433\u043e \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>overrides.js<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">Object.defineProperty(Navigator.prototype, 'webdriver', {   get() {     return false;   }, });  (function chrome() {   window.chrome = {};   window.chrome.app = {     InstallState: {       DISABLED: 'disabled',       INSTALLED: 'installed',       NOT_INSTALLED: 'not_installed',     },     RunningState: {       CANNOT_RUN: 'cannot_run',       READY_TO_RUN: 'ready_to_run',       RUNNING: 'running',     },     getDetails: () => {       '[native code]';     },     getIsInstalled: () => {       '[native code]';     },     installState: () => {       '[native code]';     },     get isInstalled() {       return false;     },     runningState: () => {       '[native code]';     },   };    window.chrome.runtime = {     OnInstalledReason: {       CHROME_UPDATE: 'chrome_update',       INSTALL: 'install',       SHARED_MODULE_UPDATE: 'shared_module_update',       UPDATE: 'update',     },     OnRestartRequiredReason: {       APP_UPDATE: 'app_update',       OS_UPDATE: 'os_update',       PERIODIC: 'periodic',     },     PlatformArch: {       ARM: 'arm',       ARM64: 'arm64',       MIPS: 'mips',       MIPS64: 'mips64',       X86_32: 'x86-32',       X86_64: 'x86-64',     },     PlatformNaclArch: {       ARM: 'arm',       MIPS: 'mips',       MIPS64: 'mips64',       X86_32: 'x86-32',       X86_64: 'x86-64',     },     PlatformOs: {       ANDROID: 'android',       CROS: 'cros',       FUCHSIA: 'fuchsia',       LINUX: 'linux',       MAC: 'mac',       OPENBSD: 'openbsd',       WIN: 'win',     },     RequestUpdateCheckStatus: {       NO_UPDATE: 'no_update',       THROTTLED: 'throttled',       UPDATE_AVAILABLE: 'update_available',     },     connect() {       '[native code]';     },     sendMessage() {       '[native code]';     },     id: undefined,   };    let startE = Date.now();   window.chrome.csi = function () {     '[native code]';     return {       startE: startE,       onloadT: startE + 281,       pageT: 3947.235,       tran: 15,     };   };    window.chrome.loadTimes = function () {     '[native code]';     return {       get requestTime() {         return startE \/ 1000;       },       get startLoadTime() {         return startE \/ 1000;       },       get commitLoadTime() {         return startE \/ 1000 + 0.324;       },       get finishDocumentLoadTime() {         return startE \/ 1000 + 0.498;       },       get finishLoadTime() {         return startE \/ 1000 + 0.534;       },       get firstPaintTime() {         return startE \/ 1000 + 0.437;       },       get firstPaintAfterLoadTime() {         return 0;       },       get navigationType() {         return 'Other';       },       get wasFetchedViaSpdy() {         return true;       },       get wasNpnNegotiated() {         return true;       },       get npnNegotiatedProtocol() {         return 'h3';       },       get wasAlternateProtocolAvailable() {         return false;       },       get connectionInfo() {         return 'h3';       },     };   }; })();  (function plugins() {   const plugin0 = Object.create(Plugin.prototype);    const mimeType0 = Object.create(MimeType.prototype);   const mimeType1 = Object.create(MimeType.prototype);   Object.defineProperties(mimeType0, {     type: {       get: () => 'application\/pdf',     },     suffixes: {       get: () => 'pdf',     },   });    Object.defineProperties(mimeType1, {     type: {       get: () => 'text\/pdf',     },     suffixes: {       get: () => 'pdf',     },   });    Object.defineProperties(plugin0, {     name: {       get: () => 'Chrome PDF Viewer',     },     description: {       get: () => 'Portable Document Format',     },     0: {       get: () => {         return mimeType0;       },     },     1: {       get: () => {         return mimeType1;       },     },     length: {       get: () => 2,     },     filename: {       get: () => 'internal-pdf-viewer',     },   });    const plugin1 = Object.create(Plugin.prototype);   Object.defineProperties(plugin1, {     name: {       get: () => 'Chromium PDF Viewer',     },     description: {       get: () => 'Portable Document Format',     },     0: {       get: () => {         return mimeType0;       },     },     1: {       get: () => {         return mimeType1;       },     },     length: {       get: () => 2,     },     filename: {       get: () => 'internal-pdf-viewer',     },   });    const plugin2 = Object.create(Plugin.prototype);   Object.defineProperties(plugin2, {     name: {       get: () => 'Microsoft Edge PDF Viewer',     },     description: {       get: () => 'Portable Document Format',     },     0: {       get: () => {         return mimeType0;       },     },     1: {       get: () => {         return mimeType1;       },     },     length: {       get: () => 2,     },     filename: {       get: () => 'internal-pdf-viewer',     },   });    const plugin3 = Object.create(Plugin.prototype);   Object.defineProperties(plugin3, {     name: {       get: () => 'PDF Viewer',     },     description: {       get: () => 'Portable Document Format',     },     0: {       get: () => {         return mimeType0;       },     },     1: {       get: () => {         return mimeType1;       },     },     length: {       get: () => 2,     },     filename: {       get: () => 'internal-pdf-viewer',     },   });    const plugin4 = Object.create(Plugin.prototype);   Object.defineProperties(plugin4, {     name: {       get: () => 'WebKit built-in PDF',     },     description: {       get: () => 'Portable Document Format',     },     0: {       get: () => {         return mimeType0;       },     },     1: {       get: () => {         return mimeType1;       },     },     length: {       get: () => 2,     },     filename: {       get: () => 'internal-pdf-viewer',     },   });    const pluginArray = Object.create(PluginArray.prototype);    pluginArray['0'] = plugin0;   pluginArray['1'] = plugin1;   pluginArray['2'] = plugin2;   pluginArray['3'] = plugin3;   pluginArray['4'] = plugin4;    let refreshValue;    Object.defineProperties(pluginArray, {     length: {       get: () => 5,     },     item: {       value: (index) => {         if (index > 4294967295) {           index = index % 4294967296;         }         switch (index) {           case 0:             return plugin3;           case 1:             return plugin0;           case 2:             return plugin1;           case 3:             return plugin2;           case 4:             return plugin4;           default:             break;         }       },     },     refresh: {       get: () => {         return refreshValue;       },       set: (value) => {         refreshValue = value;       },     },     namedItem: {       value: function namedItem(name) {         '{ [native code] }';         switch (name) {           case 'PDF Viewer':             return plugin3;           case 'Chrome PDF Viewer':             return plugin0;           case 'Chromium PDF Viewer':             return plugin1;           case 'Microsoft Edge PDF Viewer':             return plugin2;           case 'WebKit built-in PDF':             return plugin4;           default:             return undefined;         }       },     },   });    Object.defineProperty(Object.getPrototypeOf(navigator), 'plugins', {     get: () => {       '[native code]';       return pluginArray;     },   });    Object.getOwnPropertyDescriptor(     Object.getPrototypeOf(navigator),     'plugins'   ).get.toString = function toString() {     return 'function get plugins() { [native code] }';   }; })();   (function performance_memory() {   const jsHeapSizeLimitInt = 4294705152;    const total_js_heap_size = 35244183;   const used_js_heap_size = [     17632315, 17632315, 17632315, 17634847, 17636091, 17636751,   ];    let counter = 0;    let MemoryInfoProto = Object.getPrototypeOf(performance.memory);   Object.defineProperties(MemoryInfoProto, {     jsHeapSizeLimit: {       get: () => {         return jsHeapSizeLimitInt;       },     },     totalJSHeapSize: {       get: () => {         return total_js_heap_size;       },     },     usedJSHeapSize: {       get: () => {         if (counter > 5) {           counter = 0;         }         return used_js_heap_size[counter++];       },     },   }); })();<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>Alert!<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041d\u0435 \u043d\u0443\u0436\u043d\u043e \u0432\u0441\u0435\u0440\u044c\u0451\u0437 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0430\u043d\u0442\u0438\u0431\u043e\u0442\u043e\u0432. \u0423 \u0432\u0430\u0441 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f. \u041a\u0430\u0436\u0434\u0430\u044f \u0441\u0442\u0440\u043e\u0447\u043a\u0430 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 overrides.js \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u0435\u0442\u0435\u043a\u0442\u0438\u0442\u0441\u044f.<\/p>\n<\/div>\n<\/details>\n<h2>\u041a\u0443\u043a\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u044b?<\/h2>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">const playwright = require('playwright');  const browserOptions = {   ignoreHTTPSErrors: true,   ignoreHTTPSErrors: true,   args: [     '--lang=ru-RU,ru;q=0.9',     '--disable-sync',     '--disable-features=IsolateOrigins,site-per-process',   ],   defaultViewport: {     width: 1920,     height: 1080,   },   headless: true, };  (async () => {   const browser = await playwright.chromium.launch(browserOptions);   const context = await browser.newContext({     colorScheme: 'dark',     userAgent: \"Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/109.0.5414.120 Safari\/537.36\"   });    const page = await context.newPage();    page.on('response', async (response) => {     const headers = await response.allHeaders();     if (       headers['set-cookie'] &amp;&amp;       headers['set-cookie'].includes('cf_clearance')     ) {       context.cookies().then(cookies => {         console.log(cookies);       })     }   });    await context.addInitScript({ path: 'overrides.js' });    await page.goto('https:\/\/esfaucets.com\/');    await page     .frameLocator(       'iframe[title=\"Widget containing a Cloudflare security challenge\"]'     )     .getByText('\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0447\u0435\u043b\u043e\u0432\u0435\u043a')     .click(); })();<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>Headless OFF<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cb2\/5eb\/71c\/cb25eb71c6ba00ab02d0ec0ec638e8b4.gif\" width=\"1103\" height=\"686\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cb2\/5eb\/71c\/cb25eb71c6ba00ab02d0ec0ec638e8b4.gif\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>Headless ON<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/273\/757\/809\/2737578092da865f32d0551a93430514.gif\" width=\"1103\" height=\"686\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/273\/757\/809\/2737578092da865f32d0551a93430514.gif\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041c\u0435\u0442\u043e\u0434, \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435, \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0438 \u043f\u043e\u0434 puppeteer, \u0438 \u043f\u043e\u0434 selenium \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435\u2026 \u042f \u0445\u043e\u0442\u0435\u043b \u043b\u0438\u0448\u044c \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u0437 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432 \u043a \u0442\u043e\u043c\u0443, \u043a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p> <!----> <!----><\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/716434\/\"> https:\/\/habr.com\/ru\/post\/716434\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0431\u043e\u0440\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0441 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 &#8212; \u043e\u0431\u044b\u0447\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0434\u043b\u044f \u043b\u044e\u0434\u0435\u0439 \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0444\u0435\u0440 \u0434\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0416\u0430\u043b\u044c, \u0447\u0442\u043e \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u044b\u0432\u0430\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 GET \u0437\u0430\u043f\u0440\u043e\u0441 \u0438 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 html. \u0412\u0435\u0431-\u0441\u0430\u0439\u0442\u044b, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 \u0437\u0430\u0449\u0438\u0442\u043d\u044b\u0435 \u043c\u0435\u0440\u044b \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432. \u041e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0442\u0430\u043a\u0438\u0445 \u043c\u0435\u0440 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 cloudflare. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a cloudflare \u0432\u044b\u044f\u0432\u043b\u044f\u0435\u0442 \u0431\u043e\u0442\u043e\u0432 \u0447\u0435\u0440\u0435\u0437 javascript \u0438 \u043a\u043e\u0441\u043d\u0451\u043c\u0441\u044f \u0442\u0435\u043c\u044b \u0434\u0435\u043e\u0431\u0444\u0443\u0441\u043a\u0430\u0446\u0438\u0438 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432. \u0414\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u043a\u0438\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c \u043a <a href=\"https:\/\/habr.com\/ru\/post\/710982\/\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0441\u0442\u0443<\/a>. <\/p>\n<p>\u0417\u0430 \u043e\u0441\u043d\u043e\u0432\u0443 \u0432\u043e\u0437\u044c\u043c\u0451\u043c <a href=\"https:\/\/esfaucets.com\/\" rel=\"noopener noreferrer nofollow\">\u0440\u0430\u043d\u0434\u043e\u043c\u043d\u044b\u0439 \u0441\u0430\u0439\u0442<\/a> \u0441\u0430\u0439\u0442 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0442\u0430\u043c \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d \u0440\u0435\u0448\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u0432\u0435\u0434\u044c \u043f\u0440\u0438 \u0437\u0430\u0445\u043e\u0434\u0435 \u043c\u043d\u0435 \u0435\u0449\u0451 \u043d\u0443\u0436\u043d\u043e \u043a\u043b\u0438\u043a\u043d\u0443\u0442\u044c \u043f\u043e \u043a\u0430\u043f\u0447\u0435 &#171;cloudflare turnstile&#187;:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u0440\u043e\u0431\u0443\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0431\u044b\u0447\u043d\u044b\u0439 GET \u0437\u0430\u043f\u0440\u043e\u0441:<\/p>\n<pre><code class=\"javascript\">const { gotScraping } = require('got-scraping');  gotScraping('https:\/\/esfaucets.com\/', {   method: 'get',   useHeaderGenerator: false,   headers: {     'accept': 'text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/avif,image\/webp,image\/apng,*\/*;q=0.8,application\/signed-exchange;v=b3;q=0.9',     'accept-encoding': 'gzip, deflate, br',     'accept-language': 'ru-RU,ru;q=0.9',     'cache-control': 'no-cache',     'sec-ch-ua': '\"Not_A Brand\";v=\"99\", \"Google Chrome\";v=\"109\", \"Chromium\";v=\"109\"',     'sec-ch-ua-mobile': '?0',     'sec-ch-ua-platform': '\"Windows\"',     'sec-fetch-dest': 'document',     'upgrade-insecure-requests': '1',     'user-agent': 'Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/109.0.0.0 Safari\/537.36'   }, }).then(response => {   console.log(response.body); })<\/code><\/pre>\n<p>\u0412\u0438\u0434\u0438\u043c \u043f\u043e\u0445\u043e\u0436\u0438\u0439 HTML:<\/p>\n<details class=\"spoiler\">\n<summary>response<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0427\u0435\u0433\u043e-\u0442\u043e \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442\u2026<\/p>\n<p>\u0411\u0435\u0436\u0438\u043c \u0432 devtools, \u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u043a\u0440\u0443\u0442\u043a\u0438 \u0432\u0441\u0435\u0445 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u0438 \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440 \u0432 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430\u043c \u043f\u0440\u0438\u0441\u043b\u0430\u043b \u043a\u0443\u043a\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>devtools<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p> \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043a\u0443\u043a\u0438 \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a, \u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u0438 \u0432\u0438\u0434\u0438\u043c html \u043d\u0430\u0448\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b:<\/p>\n<pre><code class=\"javascript\">gotScraping('https:\/\/esfaucets.com\/', {   method: 'get',   useHeaderGenerator: false,   headers: {     'accept': 'text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/avif,image\/webp,image\/apng,*\/*;q=0.8,application\/signed-exchange;v=b3;q=0.9',     'accept-encoding': 'gzip, deflate, br',     'accept-language': 'ru-RU,ru;q=0.9',     'cache-control': 'no-cache',     'cookie': '__cf_bm=dTN3MAm6iH.wkD88zG7_.Q.alXDWj8WdmwqRJVlm5uA-1675618593-0-AdrvgMdAtvCcdOvx6JTww5K+jGDKEMw7x4uSZ2t9RCc6COMyo\/LB5en7c\/2mj3o0BvaaAsB9fR6KaTIPd8t7KGN2X1J1XJ\/PGa2bIDZUAUlJIeMjMR0Hc0uEexo3kldB+ycfvhD7Lg807gh+Z58ipTY=; cf_clearance=V3TVYDLDgOd9E.8CzxdYz54aDdHnaFtfexpOIcpSL5U-1675619126-0-250; laravel_session=eyJpdiI6InpHQzU1bVJ3cnF3aUxRRXV4SGhXR1E9PSIsInZhbHVlIjoidTYyK1Nwb3VJRjBmM3ZueEgxQWhrMjQrRHBiSU9LakxJY2laUEVwczBsY0FNbEhjZFRqcUY3NUx2azdtWUZJYnhlS1hzR05CY0VyWVg2K1JOYkRaTFBwWWZaZkRxZnVLbEN3U1JxSG94dWc5dXJqY3pcL05PZURhOFJ3a2FIb0hZIiwibWFjIjoiZTVmY2Q4NjdmZDVlN2M0MjcxZGYyOWU5YTExYTFlY2Q5NzdiMmJmNDY2YWU1ZDU4N2JlYzZhMWM2Y2UzNjZlNSJ9',     'pragma': 'no-cache',     'sec-ch-ua': '\"Not_A Brand\";v=\"99\", \"Google Chrome\";v=\"109\", \"Chromium\";v=\"109\"',     'sec-ch-ua-mobile': '?0',     'sec-ch-ua-platform': '\"Windows\"',     'sec-fetch-dest': 'document',     'sec-fetch-mode': 'navigate',     'sec-fetch-site': 'none',     'sec-fetch-user': '?1',     'upgrade-insecure-requests': '1',     'user-agent': 'Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/109.0.0.0 Safari\/537.36',   },   http2: true }).then(response => {   console.log(response.body); })<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>response<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043a\u0443\u043a\u0438, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 \u0441\u0432\u043e\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u0445. \u041d\u043e \u043e\u043d\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u043f\u043e\u0441\u043b\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 payload-\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u0441\u043a\u0440\u0438\u043f\u0442\u0430\u043c\u0438:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u0443\u043a\u0438, \u043d\u0443\u0436\u043d\u043e \u043b\u0438\u0431\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440\u0430, \u0447\u0435\u043c, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440, \u043b\u0438\u0431\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 payload-a \u0438 \u0441\u0430\u043c\u043e\u043c\u0443 \u043d\u0430\u043b\u0435\u0442\u0443 \u0435\u0433\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0412\u0442\u043e\u0440\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u0440\u043e\u0441\u0442 \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u0442\u0430\u043a \u043a\u0430\u043a \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u0443 \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440\u0430 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0435, \u0442\u043e \u0435\u0441\u0442\u044c \u0441 \u043a\u0430\u0436\u0434\u044b\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0447\u0442\u043e-\u0442\u043e \u043d\u043e\u0432\u0435\u043d\u044c\u043a\u043e\u0435, \u043d\u043e, \u0442\u0430\u043a \u0443\u0436 \u0431\u044b\u0432\u0430\u0435\u0442, \u0432\u0430\u0440\u0438\u0430\u0446\u0438\u0439 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e, \u0438 \u044d\u0442\u043e \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0440 \u0434\u043b\u044f \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u0442\u0432\u0430.<\/p>\n<p>\u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043e\u0431\u0441\u0443\u0434\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0441 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432. \u0415\u0441\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044b \u043a \u0442\u043e\u043c\u0443, \u043a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c:<\/p>\n<ul>\n<li>\n<p>\u041c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u043e\u0431\u0438\u0435 <a href=\"https:\/\/www.npmjs.com\/package\/jsdom\" rel=\"noopener noreferrer nofollow\">JSDOM<\/a> \u0432 NodeJS, \u0434\u0430\u0431\u044b \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u201c\u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435\u201d \u0442\u0435\u043c, \u0447\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u0441\u043a\u0440\u0438\u043f\u0442\u044b, \u043d\u043e \u0432 \u0442\u0430\u043a\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435 \u0435\u0441\u0442\u044c \u043c\u0438\u043d\u0443\u0441\u044b: <\/p>\n<ul>\n<li>\n<p>\u0421\u0440\u0435\u0434\u0430 NodeJS \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435, \u0438, \u0435\u0441\u043b\u0438 \u0432\u044b \u0447\u0442\u043e-\u0442\u043e \u0443\u043f\u0443\u0441\u0442\u0438\u0442\u0435, \u0442\u043e \u0441 \u0432\u0430\u0448\u0438\u043c \u041f\u041a \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0439\u0442\u0438 \u0447\u0442\u043e-\u0442\u043e \u043d\u0435 \u0442\u0430\u043a. \u042d\u0442\u043e \u043d\u0435 \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440\u0430, \u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u043a\u043e\u0441\u043d\u0443\u0442\u044c\u0441\u044f \u0432\u0430\u0441, \u0435\u0441\u043b\u0438 \u0432\u044b \u0432\u043e\u0437\u044c\u043c\u0451\u0442\u0435 \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u0441\u043a\u0440\u0438\u043f\u0442 \u0438\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0438 \u0440\u0435\u0448\u0438\u0442\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u043c\u0435\u0441\u0442\u0435.<\/p>\n<\/li>\n<li>\n<p>JSDOM \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u043d\u0430 JavaScript. \u041c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0438 \u0441 DOM \u0438 \u0441\u0432\u043e\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u044b\u0445 \u0430\u043f\u0438 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e. \u041c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435, \u0447\u0435\u043c \u0432 \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435.<\/p>\n<\/li>\n<li>\n<p>Cloudflare \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u0432\u043e\u044e \u043a\u0430\u043f\u0447\u0443, \u0430 \u0438\u043d\u043e\u0433\u0434\u0430 \u0438 h-\u043a\u0430\u043f\u0447\u0443, \u0430 \u044d\u0442\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e-\u0442\u0430\u043a\u0438 \u0441\u0435\u0440\u044c\u0451\u0437\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043d\u043e\u0433\u043e\u0433\u043e \u0442\u0440\u0435\u0431\u0443\u044e\u0442. \u0421\u043b\u0438\u0448\u043a\u043e\u043c \u0434\u043e\u043b\u0433\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u043e\u0431\u0451\u0440\u0442\u043a\u0443.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u041e\u0431\u044b\u0447\u043d\u044b\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0441 \u043b\u0451\u0433\u043a\u043e\u0441\u0442\u044c\u044e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442 \u0432\u0441\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u043e\u0442 \u0431\u0440\u0430\u0443\u0437\u0435\u0440, \u0447\u0442\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 playwright \u0438\u043b\u0438 \u0432 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0445<\/p>\n<ul>\n<li>\n<p>Headless \u0440\u0435\u0436\u0438\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430. \u0422\u0430\u043a\u043e\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043d\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0438 \u043b\u0435\u0433\u0447\u0435. \u0417\u0432\u0443\u0447\u0438\u0442 \u043f\u043e\u043b\u0443\u0447\u0448\u0435, \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u044d\u0442\u043e \u043d\u0430\u0448 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043a\u0443\u043a.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0430\u043d\u0442\u0438\u0431\u043e\u0442\u043e\u0432 \u043d\u0430\u0446\u0435\u043b\u0435\u043d\u044b \u043d\u0430 \u0432\u044b\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u0443\u0435\u043c\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439. \u0412 \u044d\u0442\u043e\u043c \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f headless-\u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430. \u0412\u044b\u0445\u043e\u0434\u0438\u0442, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043a\u0430\u043a-\u0442\u043e \u0437\u0430\u043c\u0430\u0441\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043f\u043e\u0434 \u043e\u0431\u044b\u0447\u043d\u044b\u0439. \u041d\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0432\u044b\u044f\u0432\u0438\u0442\u044c \u0431\u043e\u0442\u0430 \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0447\u0435\u0440\u0435\u0437 JavaScript \u0442\u0430\u043a \u043c\u043d\u043e\u0433\u043e, \u0447\u0442\u043e \u0432\u0441\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u0435\u043b\u0430\u0435\u0442 cloudflare. \u0427\u0442\u043e\u0431\u044b \u0441 \u044d\u0442\u0438\u043c \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442\u044b, \u043d\u043e \u0432\u043e\u0442 \u043d\u0435 \u0437\u0430\u0434\u0430\u0447\u0430, \u043e\u043d\u0438 \u043e\u0431\u0444\u0443\u0441\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u044b\u2026 <br \/>\u0412 \u043e\u0431\u0449\u0435\u043c, \u043a\u043e\u0432\u044b\u0440\u044f\u044f devtools, \u0432\u0438\u0434\u0438\u043c \u0442\u0430\u043a\u0438\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0441\u0442\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>devtools<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0447\u0442\u043e-\u0442\u043e \u0438\u0437 <code>JSON<\/code>. \u0411\u043b\u0430\u0433\u043e \u0432 \u044d\u0442\u043e\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0435 \u0434\u0432\u0430 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u0430 &#8212; <code>parse<\/code> \u0438 <code>stringify<\/code>. \u0410 \u0435\u0449\u0451 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>eval<\/code> \u0438\u043b\u0438 <code>new Function(\u2026)()<\/code>, \u0438 \u0441\u043a\u0440\u0438\u043f\u0442 \u0442\u0430\u043c \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043d\u043e \u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u043e\u2026<\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f JSON. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 <code>addInitScript()<\/code> \u0432 playwright, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u043a\u043e\u0434 \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u0432\u0441\u0435\u0445 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432:<\/p>\n<pre><code class=\"javascript\">const playwright = require('playwright');  const browserOptions = {   ignoreHTTPSErrors: true,   headless: false, };  (async () => {   const browser = await playwright.chromium.launch(browserOptions);   const context = await browser.newContext({     colorScheme: 'dark'   });    const page = await context.newPage();    await context.addInitScript(`     const jsonStringify = JSON.stringify;     JSON.stringify = function() {       console.log(arguments);       return jsonStringify.apply(null, arguments);     }   `);    await page.goto('https:\/\/esfaucets.com\/'); })();<\/code><\/pre>\n<p>\u0412\u0438\u0434\u0438\u043c \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u043e\u0447\u0435\u043d\u044c \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442:<\/p>\n<details class=\"spoiler\">\n<summary>fingerprint<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0418\u0437-\u0437\u0430 \u0441\u0431\u043e\u0440\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043d\u0430\u0448 \u201c\u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u044b\u0439 \u043e\u0442\u043f\u0435\u0447\u0430\u0442\u043e\u043a\u201d. \u0421\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u043e\u043d \u043a\u043e\u0434\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 payload.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043d\u0430\u0436\u0430\u0442\u044c \u043d\u0430 \u043a\u0430\u043f\u0447\u0443 \u0432 \u201c\u0433\u043e\u043b\u043e\u043c\u201d playwright, \u0442\u043e \u043f\u043e\u043f\u0430\u0434\u0451\u043c \u0432 \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u201ccloudflare endless loop\u201d. \u041d\u0430\u0441 \u043d\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0442. \u0412\u0438\u0434\u0438\u043c\u043e, \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440 \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f.<\/p>\n<p>\u041e\u0434\u0438\u043d \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0445 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u0432\u043e\u0439c\u0442\u0432\u0430 navigator.webdriver. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f:<\/p>\n<pre><code class=\"javascript\">await context.addInitScript(`   Object.defineProperty(Object.getPrototypeOf(navigator), 'webdriver', {     get: () => false   }) `);<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u041d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u044b\u0439 \u0438 \u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/summary>\n<div class=\"spoiler__content\">\n<p> \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0442\u0430\u043a\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043e\u0447\u0435\u043d\u044c \u043b\u0435\u0433\u043a\u043e \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c:<\/p>\n<pre><code class=\"javascript\">Object.getOwnPropertyDescriptor(   Object.getPrototypeOf(navigator), 'webdriver' ).get.toString() \/\/'function get webdriver() { [native code] }' \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \/\/ '() => false' \u0443 \u043d\u0430\u0441  Navigator.prototype.webdriver \/\/ Uncaught TypeError: Illegal invocation \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \/\/ false \u0443 \u043d\u0430\u0441  Object.getOwnPropertyDescriptor(   Object.getPrototypeOf(navigator), 'webdriver' ).get.name \/\/ 'get webdriver' \/\/ 'get'<\/code><\/pre>\n<p>\u0418 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435 \u0438 \u0442\u043e\u043c\u0443 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435&#8230; \u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u044f \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440\u0430, \u0447\u0442\u043e\u0431\u044b \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u201c\u0441\u043e\u0448\u0451\u043b \u0437\u0430 \u0441\u0432\u043e\u0435\u0433\u043e\u201d.<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u043e \u043d\u0430\u0448\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430\u044f, \u0432\u0435\u0434\u044c \u043c\u044b \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u043a\u043b\u0430\u0443\u0434\u0444\u043b\u0435\u0435\u0440 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u043b headless-\u0431\u0440\u0430\u0443\u0437\u0435\u0440. \u041e\u0431\u044b\u0447\u043d\u044b\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <code>webdriver<\/code> \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u043d\u0435 \u0432\u044b\u0439\u0434\u0435\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0438\u0437\u0443\u0447\u0438\u043c \u0441\u043a\u0440\u0438\u043f\u0442 \u0438\u0437 eval. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0440\u0430\u0437\u0432\u043b\u0435\u043a\u0430\u0442\u044c\u0441\u044f \u0441 \u0434\u0435\u0431\u0430\u0433\u0433\u0435\u0440\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0443\u043b\u043e\u0432\u0438\u0442\u044c \u0441\u0443\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b:<\/p>\n<details class=\"spoiler\">\n<summary>debugger<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0417\u0430 \u0432\u0441\u044f\u043a\u0438\u043c\u0438 \u0432\u044b\u0437\u043e\u0432\u0430\u043c\u0438 \u0432\u0438\u0434\u0430 <code>x[y(z)]<\/code> \u0441\u0442\u043e\u044f\u0442 \u0441\u0442\u0440\u043e\u043a\u0438, \u0438 \u044d\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0434\u043b\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0439 \u043d\u0435\u0434\u0443\u0433 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0441\u043a\u0440\u0438\u043f\u0442\u0430.<\/p>\n<h2>\u0414\u0435\u043e\u0431\u0444\u0443\u0441\u043a\u0430\u0446\u0438\u044f<\/h2>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u043e\u0432\u0435 \u043d\u0435\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u043a\u0440\u0438\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e. JS-\u0441\u043a\u0440\u0438\u043f\u0442\u044b &#8212; \u044d\u0442\u043e \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u043d\u0430\u0448\u0435\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u043d\u0430 \u043d\u0430\u0448\u0435\u043c \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0435 \u0438 \u0431\u0435\u0437 \u043d\u0430\u0448\u0435\u0433\u043e \u0432\u0435\u0434\u043e\u043c\u0430. \u041c\u044b \u0438\u043c\u0435\u0435\u043c \u043f\u0440\u0430\u0432\u043e \u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u044e\u0442 \u0442\u0430\u043a\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b.<\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u0442\u0435\u043a\u0441\u0442\u043e\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u043d\u0430\u043c \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0435\u0433\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435. \u0422\u0430\u043a\u043e\u0432\u044b\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e(AST). \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043f\u0430\u0440\u0441\u0435\u0440 <a href=\"https:\/\/babeljs.io\/\" rel=\"noopener noreferrer nofollow\">babel<\/a>, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c AST, \u0437\u0430\u0442\u0435\u043c \u043f\u043e\u0431\u0440\u043e\u0434\u0438\u043c \u043f\u043e \u0443\u0437\u043b\u0430\u043c, \u0447\u0442\u043e-\u0442\u043e \u0433\u0434\u0435-\u0442\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u043c, \u0430 \u0441\u043b\u0435\u0434\u043e\u043c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043a\u043e\u0434 \u0438\u0437 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430. (\u0415\u0441\u043b\u0438 \u0432\u044b \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435\u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 AST \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f\u043c\u0438, \u0442\u043e \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/habr.com\/ru\/post\/439564\/\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e<\/a>, <a href=\"https:\/\/lihautan.com\/step-by-step-guide-for-writing-a-babel-transformation\/\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e<\/a> \u0438 <a href=\"https:\/\/lihautan.com\/manipulating-ast-with-javascript\/\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e<\/a>).<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0447\u043d\u0451\u043c \u0441 \u0447\u0435\u0433\u043e-\u0442\u043e \u043c\u0430\u043b\u043e\u0433\u043e. \u0412\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0430\u0448 \u0441\u043a\u0440\u0438\u043f\u0442 \u0432 <a href=\"https:\/\/astexplorer.net\/\" rel=\"noopener noreferrer nofollow\">astexplorer<\/a> \u0438 \u0432\u0438\u0434\u0438\u043c \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u0438\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u044b\u0447\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e. \u041f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b \u043d\u0430\u043c \u0441\u0440\u0430\u0437\u0443 \u043d\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u044d\u0442\u0438 \u0443\u0437\u043b\u044b?<\/p>\n<p>\u0427\u0442\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c?<\/p>\n<ol>\n<li>\n<p>\u041d\u0430\u0439\u0442\u0438 \u0443\u0437\u0435\u043b<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0443\u0437\u0435\u043b<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u0438\u0441\u043a \u043e\u0431\u044b\u0447\u043d\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439. \u0413\u043b\u044f\u0434\u044f \u043d\u0430 \u0434\u0435\u0440\u0435\u0432\u043e, \u043c\u044b \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u043c, \u043a\u0430\u043a\u0438\u043c \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c \u0434\u043e\u043b\u0436\u0435\u043d \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0442\u044c \u0438\u0441\u043a\u043e\u043c\u044b\u0439 \u0443\u0437\u0435\u043b:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0438\u0441\u043a \u0443\u0437\u043b\u0430<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0427\u0442\u043e \u043c\u044b \u0437\u0434\u0435\u0441\u044c \u0432\u0438\u0434\u0438\u043c: \u0442\u0438\u043f \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0443\u0437\u043b\u0430 &#8212; BinaryExpression, \u0434\u0435\u0442\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f NumericLiteral. \u041f\u0438\u0448\u0435\u043c:<\/p>\n<pre><code class=\"javascript\">const { parse } = require('@babel\/parser'); const traverse = require('@babel\/traverse').default; const generate = require('@babel\/generator').default; const t = require('@babel\/types'); const fs = require('fs');  const srcCode = fs.readFileSync('srcCode.js', { encoding: 'utf-8' }); const ast = parse(srcCode);  traverse(ast, {   BinaryExpression(path) {     const { node } = path;     if<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-345342","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/345342","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=345342"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/345342\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=345342"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=345342"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=345342"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}