1 (изменено: adeckwatt, 2023-03-03 16:05:41)

Тема: AHK: Выделение текста и отправка в поисковик сайта

Горячо приветствую всех участников форума!

Продолжаю медленное и неуверенное, в основном копипастно-компиляторское, но изучение AHK)

Оказалось, что существует способ, с помощью которого по нажатию минимального количества клавиш можно забить в поисковик выделенное где угодно слово. Нашел вот такой рабочий пример:

F1::
{
Send, ^c
Sleep 50
Run, https://yandex.ru/search/?text=%clipboard%
Return
}

Поскольку часто смотрю написание всяких слов в онлайн-словарях, захотелось прикрутить к этому скрипту соответствующие поисковики. Грамота.ру добавил без особых проблем, нужно просто заменить в вышеуказанном куске кода адрес Яндекса на http://gramota.ru/slovari/dic/?word=%cl … &all=x.

Но есть еще один, не менее авторитетный словарь (кстати, рекомендую всем, в нем больше слов, особенно новопоявляющихся, чем в Грамоте, тот же "ковид" уже внесен) по адресу https://orfo.ruslang.ru/search/word. Так вот его никак не могу вставить правильно в этот код, все время на сайте ошибка появляется, которую я не могу никак проинтерпретировать и понять, что его (сайт) не устраивает. Хотел для вашего удобства вставить весь текст ошибки, но форум мне запретил вставлять больше четырех ссылок, а они там есть, так что...

Может кто-нибудь подсказать, как оформить правильно ссылку, чтобы вставить в код? Понимаю, что запрос немного не по адресу, тут как будто бы проблема на стороне сайта, а не AHK, и все же вдруг что-то можно сделать. В крайнем случае хотя бы больше людей узнает про этот словарь, хоть какая-то польза)

Сам скрипт, кстати, далек от идеального, поскольку генерирует новую вкладку для каждого поискового запроса, что способно при активном серчинге перенагрузить всю систему через браузер, но в принципе сойдет.

Ах да, слышал, что AHK 2.0 вышла, но я пока на 1-й версии, если это имеет значение.

Всем добра!

2

Re: AHK: Выделение текста и отправка в поисковик сайта

adeckwatt пишет:

Сам скрипт, кстати, далек от идеального, поскольку генерирует новую вкладку для каждого поискового запроса

Не везде можно использовать URL для такого запроса, надо использовать chrome.ahk, заодно можно не дублировать вкладки.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

3

Re: AHK: Выделение текста и отправка в поисковик сайта

adeckwatt, ознакомьтесь, пожалуйста, с Правилами, отредактируйте свой пост. Обратите внимание на оформление ссылок и точки в конце предложений.

adeckwatt пишет:

P.S. Прочитал правила форума – всецело разделяю ваш посыл "мы пишем грамотно", спасибо вам за него.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

4

Re: AHK: Выделение текста и отправка в поисковик сайта

serzh82saratov пишет:

Не везде можно использовать URL для такого запроса, надо использовать chrome.ahk

Ну, теоретически, если заморочиться, можно и без chrome.ahk обойтись. Если для Хрома, алгоритм примерно такой:

  • Используя IAccessible или IUIAutomation просмотреть заголовки всех вкладок

  • Если найдена нужная — активировать, если нет — открыть

  • Через адресную строку запустить javascript, который будет ждать, пока страница полностью загрузится, и появятся нужные элементы

  • После этого тем же скриптом ввести искомое слово, отметить чекбоксы и нажать кнопку поиска

Последние два пункта скорее всего также можно реализовать через IAccessible или IUIAutomation.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

5

Re: AHK: Выделение текста и отправка в поисковик сайта

Я бы отправлял через winhttprequest.

6

Re: AHK: Выделение текста и отправка в поисковик сайта

А смысл? Там ответ может быть на несколько страниц.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

7

Re: AHK: Выделение текста и отправка в поисковик сайта

Где? В словарях?

8

Re: AHK: Выделение текста и отправка в поисковик сайта

Ну да.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

9

Re: AHK: Выделение текста и отправка в поисковик сайта

Пример дай.
У меня с данными словарями несколько страниц не показывается.
Но даже если бы показывалось можно эти страницы объединить в одну.

10

Re: AHK: Выделение текста и отправка в поисковик сайта

В словаре https://orfo.ruslang.ru/search можно делать запросы с подстановками ?, *, например за*я. Да и ответ приходит в виде html, потом нужно будет парсить. Проще сразу на странице смотреть.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

11 (изменено: Malcev, 2023-03-03 13:14:26)

Re: AHK: Выделение текста и отправка в поисковик сайта

teadrinker пишет:

Проще сразу на странице смотреть.

Ну это кому как.
Ты, например, в онлайн-переводчике используешь winhttprequet, а не смотришь на странице.

12

Re: AHK: Выделение текста и отправка в поисковик сайта

Ну, если предполагается, что ответ будет небольшим, можно и запросом.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

13

Re: AHK: Выделение текста и отправка в поисковик сайта

teadrinker пишет:

adeckwatt, ознакомьтесь, пожалуйста, с Правилами, отредактируйте свой пост

Здравствуйте! Спасибо, поправил вроде ссылки, ну и точки закономерно появились. Тут своеобразная интерференция произошла, потому что на многих форумах ссылки на сторонние ресурсы требуют оформлять под спойлером во избежание спама, запамятовал, что тут по-другому. 

serzh82saratov пишет:

надо использовать chrome.ahk, заодно можно не дублировать вкладки.

И вас приветствую! Посмотрел, что за зверь такой хромой.ахк. При всем уважении, инструкция по прикручиванию этого дела к Хрому охладила весь пыл с этим разбираться (тем более я с Эджа сижу), больно сложно это все городить для моего минорного запроса, легче переориентироваться на другой словарь. Я просто думал, что надо как-то ссылку правильно оформить в скрипте. Сайт на самом деле кривоват в принципе, периодически что-то с ним происходит неладное, так что я не удивлен, что к нему нельзя прикрутить скрипт. Тем не менее как направление программной мысли и для последующих рассуждений очень интересно было это рассмотреть, спасибо!


Благодарю всех откликнувшихся на мой ламерский зов!) Удачи и успехов вам!

14

Re: AHK: Выделение текста и отправка в поисковик сайта

adeckwatt
Считаю, вы должны быть вознаграждены за адекватность примером кода:

query := "прок*ция"

if !html := SendQueryToOrfo(query)
   return
MsgBox % ParseHtml(html)

SendQueryToOrfo(query) {
   static url := "https://orfo.ruslang.ru/search/word"

   body := EncodeDecodeURI("word=" . query . "&submit=Поиск&title_check=yes&text_check=yes",, false)

   headers := { "content-length": StrLen(body)
              , "content-type": "application/x-www-form-urlencoded"
              , "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
                            . "(KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.57" }
                           
   html := WebRequest(url, "POST", headers, body, error := "")
   if error {
      MsgBox % error
      return
   }
   return html
}

EncodeDecodeURI(str, encode := true, component := true) {
   static Doc, JS
   if !Doc {
      Doc := ComObjCreate("htmlfile")
      Doc.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=9"">")
      JS := Doc.parentWindow
      ( Doc.documentMode < 9 && JS.execScript() )
   }
   Return JS[ (encode ? "en" : "de") . "codeURI" . (component ? "Component" : "") ](str)
}

WebRequest(url, method := "GET", HeadersArray := "", body := "", ByRef error := "") {
   Whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
   Whr.Open(method, url, true)
   for name, value in HeadersArray
      Whr.SetRequestHeader(name, value)
   Whr.Send(body)
   Whr.WaitForResponse()
   status := Whr.status
   if (status != 200)
      error := "HttpRequest error, status: " . status
   Arr := Whr.responseBody
   pData := NumGet(ComObjValue(arr) + 8 + A_PtrSize)
   length := arr.MaxIndex() + 1
   Return StrGet(pData, length, "UTF-8")
}

ParseHtml(html) {
   document := DocumentFromHtml(html)
   columns := document.querySelectorAll(".panel-body div[class^=col-md]")
   text := ""
   Loop % columns.Length {
      text .= columns[A_Index - 1].innerText . "`n"
   }
   return Trim(text, "`n")
}

DocumentFromHtml(html) {
   Doc := ComObjCreate("htmlfile")
   Doc.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=9"">")
   Doc.designMode := "on"
   Doc.write(html)
   Return Doc
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

15

Re: AHK: Выделение текста и отправка в поисковик сайта

teadrinker, ваш код просто убийственный!)

В первую очередь подтверждаю, что он абсолютно рабочий без каких-либо дополнительных телодвижений со стороны конечного пользователя. Но больше всего меня в нем потрясает то, что он работает даже в отсутствие какого-либо запущенного браузера, – на человека, несведущего в программировании, подобное обстоятельство производит поистине магическое впечатление.   

В коде фигурируют версия Windows, разрядность и опять же версии различных браузеров (то немногое, что мне понятно из кода, каюсь) – это именно user-agent, т. е. это то, что отправляется сайту словаря с моей стороны, чтобы сайт понимал, с кем имеет дело, правильно же? Я к тому, что при моем переходе, например, на Windows 11 или Edge 200.0 работоспособность кода сохранится, так ведь?) Впрочем, в какой-то момент будущего подставить актуальные для того самого будущего значения версий операционной системы и браузера вполне мне по силам должно быть.

Для максимального удобства осталось понять, как сделать так, чтобы стало возможно добавлять новые слова, не вскрывая скрипт. Еще не приходилось залезать в подобные дебри, занимаясь простенькими хотстрингами, прости господи, и клавиатурным ремаппингом, но вы меня в хорошем смысле этого слова раззадорили, да чего уж там – прямо воодушевили на поиски. Вот сейчас посмотрел бегло FAQ и начал догадываться, что вот эту входную строчку нужно как-то представить в качестве переменной Var, а уже в переменную добавлять значения (слова) с помощью InputBox. Осталось понять, как связать одно с другим.

Вроде вот как-то так должно это выглядеть:

InputBox, OutputVar, Слово для Орфорусланг,  , 320, 240

query := "%OutputVar%"

Но, конечно, чего-то в этом рецепте не хватает, поскольку мне сначала выдает на вид нормальное окно, я вбиваю в него слово, а затем уже скрипт выдает пустое окно без всяких результатов. Видимо, затык где-то на уровне переменной возникает.   

Ну а запуск из моего уже существующего скрипта данного скрипта по горячей клавише должно быть так:

F2::Run, D:\Орфорусланг.ahk 

Вот это уже работает исправно.)



Как бы там ни было, задача решена! teadrinker, мне очень приятно и одновременно неловко за оказанную мне честь, иначе не могу это воспринять. Низкий поклон вам!

16

Re: AHK: Выделение текста и отправка в поисковик сайта

adeckwatt пишет:
InputBox, OutputVar, Слово для Орфорусланг,  , 320, 240

query := "%OutputVar%"

Перемудрили с переменными. Просто подставьте переменную query в InputBox. Чтобы присвоить значение одной переменной другой не нужно ни кавычек, ни знаков процента.

a := "test"
b := a
MsgBox % b

Но в данном случае это не нужно, просто для информации.

adeckwatt пишет:

Я к тому, что при моем переходе, например, на Windows 11 или Edge 200.0 работоспособность кода сохранится, так ведь?

Если будет устареший user-agent, проблем не должно быть. Скорее на самом сайте что-то изменится и код перестанет работать.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

17

Re: AHK: Выделение текста и отправка в поисковик сайта

teadrinker пишет:

Перемудрили с переменными. Просто подставьте переменную query в InputBox.

Признаться, даже это оказалось отнюдь не просто: мало было подставить, надо было еще дотумкать, чтобы... удалить первоначальную строчку с query, а не ковырять ее!) Метод проб и набитых шишек...

Все работает идеально теперь, это абсолютный успех! Огромное вам спасибо за помощь, teadrinker!!! Отдельная благодарность за подстегивание изучать AHK дальше, я столько нового узнал за сегодня, что прямо не верится.) Мне остается только пожелать вам сталкиваться по жизни исключительно с такими же профессионалами в своей области, как вы сами. Еще раз спасибо!

18

Re: AHK: Выделение текста и отправка в поисковик сайта

Ну, справедливости ради, этот код появился только из-за идеи коллеги Malcev'а о том, что можно получать результат с помощью веб-запроса, я больше думал об автоматизации управления страницей. Такой вариант был бы намного сложнее. Так что скажите ему спасибо, либо поставьте лайк!

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

19 (изменено: __Михаил__, 2023-03-04 18:40:19)

Re: AHK: Выделение текста и отправка в поисковик сайта

Более удобное решение с интерфейсом:

url := "https://orfo.ruslang.ru/search/word"
Name := "Test Gui"

GroupAdd, Group, %Name% ahk_class ahk_class AutoHotkeyGUI ahk_exe AutoHotkey.exe

Gui Font, s13, Arial
Gui Add, Text, x8 y8 w60 h23, Слово:
Gui Add, Edit, vquery x72 y8 w300 h23, Вер*ция
Gui Add, Button, gGo x376 y8 w60 h23, Поиск
Gui Add, Edit, vText x8 y40 w428 h365
Gui Show, w444 h413, % Name
Return

GuiEscape:
GuiClose:
ExitApp


#IfWinActive, Ahk_Group Group

~Enter::
KeyWait, Enter, U
ControlGetFocus, F, A
If (F = "Edit1")
 GoSub, Go
Return

#If

Go:
GuiControlGet, query
body := EncodeDecodeURI("word=" . query . "&submit=Поиск&title_check=yes&text_check=yes",, false)
headers := { "content-length" : StrLen(body)
           , "content-type": "application/x-www-form-urlencoded"
           , "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
                         . "(KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.57" }
                         
html := WebRequest(url, "POST", headers, body, error := "")
if error {
 GuiControl,, Text, % error
 Return
}
document := DocumentFromHtml(html)
columns := document.querySelectorAll(".panel-body div[class^=col-md]")
text := ""
Loop % columns.Length {
 text .= columns[A_Index - 1].innerText . "`n"
}
GuiControl,, Text, % text
Return

DocumentFromHtml(html) {
   Doc := ComObjCreate("htmlfile")
   Doc.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=9"">")
   Doc.designMode := "on"
   Doc.write(html)
   Return Doc
}

EncodeDecodeURI(str, encode := true, component := true) {
   static Doc, JS
   if !Doc {
      Doc := ComObjCreate("htmlfile")
      Doc.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=9"">")
      JS := Doc.parentWindow
      ( Doc.documentMode < 9 && JS.execScript() )
   }
   Return JS[ (encode ? "en" : "de") . "codeURI" . (component ? "Component" : "") ](str)
}

WebRequest(url, method := "GET", HeadersArray := "", body := "", ByRef error := "") {
   Whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
   Whr.Open(method, url, true)
   for name, value in HeadersArray
      Whr.SetRequestHeader(name, value)
   Whr.Send(body)
   Whr.WaitForResponse()
   status := Whr.status
   if (status != 200)
      error := "HttpRequest error, status: " . status
   Arr := Whr.responseBody
   pData := NumGet(ComObjValue(arr) + 8 + A_PtrSize)
   length := arr.MaxIndex() + 1
   Return StrGet(pData, length, "UTF-8")
}
Win10x64, AHK v1.1.37.01 (Unicode 64-bit) | AHK-Wiki | Переменные и выражения | RegEx101

20

Re: AHK: Выделение текста и отправка в поисковик сайта

__Михаил__
Я бы увеличил шрифт и добавил отправку по Enter, если поле ввода в фокусе.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

21

Re: AHK: Выделение текста и отправка в поисковик сайта

teadrinker
Обновил пост. Добавил предложенное.

Win10x64, AHK v1.1.37.01 (Unicode 64-bit) | AHK-Wiki | Переменные и выражения | RegEx101

22

Re: AHK: Выделение текста и отправка в поисковик сайта

Ну, с группой вы перемудрили.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

23

Re: AHK: Выделение текста и отправка в поисковик сайта

teadrinker
Почему же? Так больше вероятность что сработает точно со своим окном. Или есть более правильный вариант?

Win10x64, AHK v1.1.37.01 (Unicode 64-bit) | AHK-Wiki | Переменные и выражения | RegEx101

24

Re: AHK: Выделение текста и отправка в поисковик сайта

#If WinActive(name . " ahk_pid " . DllCall("GetCurrentProcessId"))
~Enter::
#If
KeyWait, Enter
ControlGetFocus, F, A
if !(F = "Edit1")
   Return

Go:
   GuiControlGet, query
...
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

25

Re: AHK: Выделение текста и отправка в поисковик сайта

__Михаил__ пишет:

Более удобное решение с интерфейсом

Категорически приветствую! Решение действительно выглядит отлично и по-своему удобно, и опять в обход браузера!) Благодарю покорно!

26

Re: AHK: Выделение текста и отправка в поисковик сайта

adeckwatt
Ещё одно обновление. Если быстро скопировать текст (дважды нажать Ctrl + C) окно тут же заменит текст в поле и отправит запрос на сайт. В целом можно много чего ещё прикрутить, было бы желание и время.

url := "https://orfo.ruslang.ru/search/word"
Name := "Orfo.ruslang.ru search word v1.2"

Gui Color, 0x67A0FF
Gui Font, s13, Arial
Gui Add, Text, x8 y8 w60 h23, Слово:
Gui Add, Edit, vquery x72 y8 w300 h23, Вер*ция
Gui Add, Button, gGo x376 y8 w60 h23, Поиск
Gui Add, Edit, vText x8 y40 w428 h365
Gui Show, w444 h413, % Name
Return

GuiEscape:
GuiClose:
ExitApp


#If WinActive(name . " ahk_pid " . DllCall("GetCurrentProcessId"))
~Enter::
#If
KeyWait, Enter
ControlGetFocus, F, A
if !(F = "Edit1")
 Return

Go:
GuiControlGet, query
body := EncodeDecodeURI("word=" . query . "&submit=Поиск&title_check=yes&text_check=yes",, false)
headers := { "content-length" : StrLen(body)
           , "content-type": "application/x-www-form-urlencoded"
           , "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
                         . "(KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.57" }
                         
html := WebRequest(url, "POST", headers, body, error := "")
if error {
 GuiControl,, Text, % error
 Return
}
document := DocumentFromHtml(html)
columns := document.querySelectorAll(".panel-body div[class^=col-md]")
text := ""
Loop % columns.Length {
 text .= columns[A_Index - 1].innerText . "`n"
}
GuiControl,, Text, % text
Return

DocumentFromHtml(html) {
   Doc := ComObjCreate("htmlfile")
   Doc.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=9"">")
   Doc.designMode := "on"
   Doc.write(html)
   Return Doc
}

EncodeDecodeURI(str, encode := true, component := true) {
   static Doc, JS
   if !Doc {
      Doc := ComObjCreate("htmlfile")
      Doc.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=9"">")
      JS := Doc.parentWindow
      ( Doc.documentMode < 9 && JS.execScript() )
   }
   Return JS[ (encode ? "en" : "de") . "codeURI" . (component ? "Component" : "") ](str)
}

WebRequest(url, method := "GET", HeadersArray := "", body := "", ByRef error := "") {
   Whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
   Whr.Open(method, url, true)
   for name, value in HeadersArray
      Whr.SetRequestHeader(name, value)
   Whr.Send(body)
   Whr.WaitForResponse()
   status := Whr.status
   if (status != 200)
      error := "HttpRequest error, status: " . status
   Arr := Whr.responseBody
   pData := NumGet(ComObjValue(arr) + 8 + A_PtrSize)
   length := arr.MaxIndex() + 1
   Return StrGet(pData, length, "UTF-8")
}

~^c::
KeyWait, C, U
If !(A_ThisHotkey = A_PriorHotkey && A_TimeSincePriorHotkey < 300)
 Return
GuiControl,, query, % ClipBoard
GoTo Go
Win10x64, AHK v1.1.37.01 (Unicode 64-bit) | AHK-Wiki | Переменные и выражения | RegEx101

27 (изменено: adeckwatt, 2023-03-08 03:16:51)

Re: AHK: Выделение текста и отправка в поисковик сайта

__Михаил__ пишет:

Ещё одно обновление.

Работает! Правда, не сразу смог понять, насколько быстро необходимо прожимать буквенное комбо, но в итоге приноровился. В принципе циферку, за этот параметр отвечающую, вижу, так что смогу в случае чего подправить под свою индивидуальную тормознутость.) Потрясающе! Спасибо!!!

__Михаил__ пишет:

В целом можно много чего ещё прикрутить, было бы желание и время

Да, это удивительно, какие поистине удобные штуки можно творить, была бы сила мысли и время, чтобы ее развивать. Желаю вам, чтобы обеих этих компонент у вас было в достатке и даже в избытке!;)



serzh82saratov пишет:

надо использовать chrome.ahk

Кстати, по поводу обращения к первоначальному сайту через браузер мне тут пришла в голову такая идея. Если AHK способен за меня прожимать клавиши, причем много и как минимум подряд, если не за раз, то, по идее, возможна такая комбинация для реализации искомого функционала:

0) через Ctrl+C скопировать в буфер требуемое слово;
1) по Alt+Tab вызвать список открытых окон, выбрать браузер (догадываюсь, что активировать какое-то из свернутых окон можно и иначе наверняка);
2) в браузере если закрепить вкладку со словарем, по крайней мере в Edge и Firefox можно будет на нее переключиться, прожав Ctrl+номер вкладки, она будет всегда статична по номеру, будучи закрепленной;
3) затем останется как-то сделать фокус на, постановку курсора в строку поиска сайта, что, как я где-то видел (ручаться не могу, просто на волне интереса просматривал разные темы), реально, если даже задать координаты этой самой строки на экране, которая на сайте тоже константно расположена...
4) ...ну и уже в ней прожать Ctrl+V.

И то же самое можно теоретически провернуть с Грамотой и Яндексом, и как раз можно было бы все запросы рерайтить каждый новый поверх старого, то есть отправлять все поисковые запросы в одну вкладку, а не плодить их сотнями. Ну то есть алгоритмически это вроде как может сработать, если прямо вот AHK указать те же действия, какие я до этого вручную выполнял. В общем, интересная разминка для ума выходит как ни крути)

UPD: сейчас перечитал тему и обнаружил, что это почти в точности то, что предложил изначально teadrinker, но только в случае закрепленной вкладки не нужно будет скрипту проверять заголовки, да и чекбоксы будут по умолчанию выставлены (я по крайней мере один раз их выставил в Edge и они так и стоят там всякий раз). Такой лоукост нубский вариант) Но, черт возьми, это действительно увлекательное дело, продумывать.



Я еще раз благодарю всех откликнувшихся за участие, поддержку и доброжелательность!