Скрипты для Demagog

Говорящий текстовый редактор с открытым кодом, предназначенный для чтения вслух и записи в аудиофайл текстовых файлов с использованием пакетов речевых функций SAPI4\SAPI5.

Модератор: flegont

Ответить
Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#301

Сообщение tonio_k » 14 апр 2019 16:18

Пожелание, а есть возможность добавить что-то вроде показателя прогресса?
Пока висят консольные запросы на Яндекс, создается ощущение, что они ... "висят/зависли" :smile1:
Например, количество полученных аудиофайов из количества временных текстовых файлов.
(Получено 3 из 263)
Короче, что бы что-то двигалось, при условии, что действительно что-то в плане файлов двигается :big_smile:


Отправлено спустя 5 минут 42 секунды:
Может это сделать как отдельную утилиту (еще одно окно консоли)? Которая вызывается YaTTS после разбития на сериалы и занимается только сравнением содержимого временных файлов. И при их равенстве сама закрывается.

Аватара пользователя
wasyaka
V.I.P.

Скрипты для Demagog

#302

Сообщение wasyaka » 14 апр 2019 19:31

tonio_k писал(а):
14 апр 2019 16:24
Пожелание
А зделать, чтобы:
Открываем обработанный текст, заглавной буквой ударения, - универсализм - далее или на Макса- Таню или...
подключаем словари для Яндеса и обработка этими словарями с последующей записью одним целым действием? :thank:

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#303

Сообщение tonio_k » 14 апр 2019 20:01

wasyaka писал(а):
14 апр 2019 19:31
Открываем обработанный текст, заглавной буквой ударения
можно по пунктам как вы хотите что бы работало?

Если я правильно понял, в папку dic вы хотите добавить свои словари (rex, dic).
В Демагоге открыть текст, в котором предварительно уже проставили все ударения заглавными буквами (как для Максима).
И теперь нужно, что бы к открытому тексту в Демагоге, Запустить всего один скрипт, который обработал текст вашими подключичными словарями и начал его отправлять на Яндекс и получать mp3?

Аватара пользователя
wasyaka
V.I.P.

Скрипты для Demagog

#304

Сообщение wasyaka » 14 апр 2019 21:30

tonio_k писал(а):
14 апр 2019 20:01
И теперь нужно, что бы к открытому тексту в Демагоге, Запустить всего один скрипт, который обработал текст вашими подключичными словарями и начал его отправлять на Яндекс и получать mp3?
В точку.
После первичной обработки текста словарями добиваю раставляю омографы вручную в Homograph, а после одним действом, если исключить Homograph, то получится - всавил текст -
включил скрипт - получил запись...

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#305

Сообщение tonio_k » 14 апр 2019 23:05

Пока готовил скрипт под вашу просьбу, всплыла проблема Version 7.29.370 при работе скрипта со словарями. flegont я проблему описал. Скрипт уже готов. Как проблема решится - сразу скину сборку с комментариями для редактирования

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#306

Сообщение flegont » 15 апр 2019 00:13

Завтра буду разбираться с 370-й, сравню по архиву версий :thinking:
UPDATE: исправил, версия обновлена до 371

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#307

Сообщение tonio_k » 15 апр 2019 00:36

wasyaka писал(а):
14 апр 2019 21:30
- всавил текст -
включил скрипт - получил запись...
Решил не дожидаться исправления и сделал сборку на основе предыдущей версии 7.29.369
черновик

Инструкция:
1) Кроме файла СПИСОК СЛОВАРЕЙ.lua содержимое папки \Demagog-Yandex\dic - можно удалить
2) Помещаем свои словари в папку \Demagog-Yandex\dic\
3) Открываем через блокнот (удобнее через Notepad++) \СПИСОК СЛОВАРЕЙ.lua
4) Редактируем только строки начинающиеся с

Код: Выделить всё

WFilter(0,0,dic..
путем удаления ненужных строк и вставки наименование файлов своих словарей.
Строки можно сортировать в той последовательности, в которой нужно что бы словари сработали.

Что бы не путаться, можно везде поставить выбор алгоритма применения словаря:

Код: Выделить всё

false)  --перебором (галочка убрана)
если словарь rex, то false) или true) можно поставить любой - ошибкой не будет

После редактирования СПИСОК СЛОВАРЕЙ.lua
1) запускаем Демагог
2) Ctrl+F2 - запускаем YaTTS_configure.lua и сохраняем настройки. (сохранённые настройки будут применяться для всех последующих запусков Демагога.)

Теперь сама процедура:
3) Открываем/перетаскиваем/вставляем текст книги в любое окно кроме 0-статистика
4) Ctrl+F2 - запускаем 20_ОКНО ОБРАБОТАТЬ СЛОВАРЯМИ и получить MP3.lua
- выбираем папку куда сохранить mp3
- измененный словарями текст будет сохранен в файл \Demagog-Yandex\temp\0.txt
5) Ждем завершение работы скрипта (по готовности в окне статистики появится лог информация)
6) находим наши MP3 в папке которую ранее выбирали :wink:

В случае сбоя и расхождения в файлах от Яндекса:
6) открываем в любом окне Демагога файл \Demagog-Yandex\temp\0.txt
7) Ctrl+F2 - запускаем YaTTS.lua

Аватара пользователя
balaamster
Обыватель

Скрипты для Demagog

#308

Сообщение balaamster » 15 апр 2019 16:24

tonio_k писал(а):
14 апр 2019 16:24
Пожелание, а есть возможность добавить что-то вроде показателя прогресса?
Добавил прогрессбар

Обновлённая инструкция.
► Показать
Demagog+YandexTTS.zip
(6.32 КБ) 41 скачивание

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#309

Сообщение tonio_k » 16 апр 2019 19:17

В lua есть возможность вызвать скрипт в параллельном потоке?
Т.е. идет выполнение скрипта 1.
В скрипте 1 вызывается скрипт 2.
При этом, скрипт 1 работает дальше, а скрипт 2 в это время начинает делать свою задачу.

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#310

Сообщение flegont » 16 апр 2019 21:09

Конкретно так - нельзя.
Но в Lua есть понятие "сопрограммы" - coroutine.
Скрипт, в процессе своей работы может создать нужное количество сопрограмм. Каждая сопрограмма может находится в состоянии: выполняется, приостановлена, мертва.
Т.о. скрипт может работать в (псевдо) многозадачном режиме.

Но сопрограммы действуют только внутри виртуальной Lua-машины, и никак не связаны с потоками в операционной системе.
Подробно в этом я пока не разбирался. Надо будет учебник Р. Иерусалимского почитать, и в справочном руководстве Lua 5.3 пошарить. И поискать примеры скриптов с сопрограммами :pardon:

Аватара пользователя
balaamster
Обыватель

Скрипты для Demagog

#311

Сообщение balaamster » 16 апр 2019 21:25

flegont писал(а):
16 апр 2019 21:09
Но в Lua есть понятие "сопрограммы" - coroutine.
Это интересная часть Lua, но, прочитав один раз раздел книги Иерусалимского, так и не разобрался в вопросе. Понял, как можно написать генераторы, подобные генераторам в python, но не более.
Чувствую, что надо ещё раза два прочитать :)

Ещё один способ запустить несколько "потоков" это os.execute()
Но эти "потоки" будут "неконтролируемые".

Код: Выделить всё

os.execute('start "program1" D:\scripts\script_1.bat parameter1 parameterN')
os.execute('start "program1" "D:\scripts\script 2.cmd" parameter1 parameterN')
os.execute('start "program1" D:\scripts\lua53.exe "D:\script 3.lua" parameter1 parameterN')
Все три скрипта запустятся практически мгновенно друг за другом, так как start без ключа /wait запускает новый процесс и сам завершает работу.
Но, при таком исполнении, надо будет писать функцию, которая будет по какому-то критерию отслеживать завершение работы этих запущенных параллельно скриптов, если в дальнейшем понадобятся данные, произведённые этими скриптами (чтобы быть уверенным, что скрипт вернул все нужные данные или наоборот завершился с ошибкой).

P.S. lua-скрипт, из третьей строки, запустится в "чистом" lua. Ему будут недоступны внутренние функции из Demagog.

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#312

Сообщение tonio_k » 17 апр 2019 14:59

os.execute('start "program1" D:\scripts\lua53.exe "D:\script 3.lua" parameter1 parameterN')
я так понимаю это будет чисто в рамках lua без функций типа RexRepl от demagog?


Отправлено спустя 21 минуту 54 секунды:
Графическая библиотека Demagog дает возможность получать результаты работы скрипта в наглядной форме, в виде графиков и диаграмм. Для подключения в начале скрипта необходимо указать: require "profiles/grafica"

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

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#313

Сообщение flegont » 17 апр 2019 15:48

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

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#314

Сообщение flegont » 18 апр 2019 10:15

Простой графический индикатор

Код: Выделить всё

require "profiles/grafica"

-- графический индикатор процесса
-- i изменяется от 1 до imax
function Gauger(i,imax)
    Clear()
    Area(-100,-100,100,100) 
    Pen(Red,1)
    Brush('FFFFA4')
    Ellipse(-80,-80,80,80)
    Brush('')
    Brush(LightGreen)
    Pie(-80,-80,80,80,0,2*math.pi*i/imax)
    Render()
end


-- пример использования
Show()
imax = 1000
for i = 1,imax do
    Delay(1) -- имитирует процесс неких вычислений внутри цикла
    if i % 50 == 0 then -- достаточно 20 кадров по ходу процесса 
        Gauger(i,imax)  -- отображает готовность i-го шага вычислений
    end
end
Hide()

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#315

Сообщение flegont » 18 апр 2019 10:58

Простой графический индикатор 2
Если в предыдущем примере заменить функцию Gauger на приведенную ниже, то получится индикатор, дополнительно отображающий процент выполнения

Код: Выделить всё

-- графический индикатор процесса
-- i изменяется от 1 до imax
function Gauger(i,imax)
    Clear()
    Area(-100,-100,100,100) 
    Pen(Red,1)
    Brush('FFFFCE')
    Ellipse(-80,-80,80,80)
    Brush('')
    Brush(LightGreen)
    Pie(-80,-80,80,80,0,2*math.pi*i/imax)
    Brush(White)
    Ellipse(-55,-55,55,55)
    Font('Arial',20,Green)
    TextOut(-15,15,math.floor(100*i/imax))
    Render()
end

Аватара пользователя
balaamster
Обыватель

Скрипты для Demagog

#316

Сообщение balaamster » 23 апр 2019 22:11

Сегодня задался вопросом, почему никто не задал вопрос, о неработающем скрипте для Яндекс TTS.
Ведь по умолчанию выполнение powershell отключено в пользовательских ОС.

Обнаружил интересную особенность. При политиках по умолчанию (запуск скриптов отключен):

Код: Выделить всё

 Get-ExecutionPolicy -List
        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine      Restricted
Создаём в lib файл test.ps1, с содержимым:

Код: Выделить всё

get-executionpolicy -List | format-list
pause
Запускаем из окна Demagog по F2:
os.execute('powershell -file '..HomeFolder('lib')..'test.ps1')
Получаем (запуск скриптов включен, подпись не проверяется)

Код: Выделить всё

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine          Bypass
Получается в библиотеке Lua учтена эта особенность политики по умолчанию и внесена правка?

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#317

Сообщение tonio_k » 23 апр 2019 22:20

На сколько мне известно, powershell запущенный из под cmd не требует включения политик для самого powershell. А os.execute, как я понял, это что то вроде аналога cmd. Может в этом дело?

Аватара пользователя
balaamster
Обыватель

Скрипты для Demagog

#318

Сообщение balaamster » 10 май 2019 21:41

balaamster писал(а):
15 апр 2019 16:24
Demagog+YandexTTS
Обновил скрипты.
  • конфигуратор запроса к TTS-сервису выполнен в виде hta-файла
  • добавлена глобальная переменная clean_start, значение true - очистить папку со временными файлами, перед началом обработки. false (по умолчанию) - папка не очищается.
  • озвучка выделенного фрагмента перенесена в консоль PowerShell.
Способ работы со скриптами.
► Показать
Demagog+YandexTTS.zip
(28.04 КБ) 44 скачивания

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#319

Сообщение flegont » 10 май 2019 22:22

Обновлена соответствующая ссылка на сайте Demagog.

Аватара пользователя
zhukov23
Наблюдатель

Скрипты для Demagog

#320

Сообщение zhukov23 » 19 май 2019 14:35

Обновил скрипты.
конфигуратор запроса к TTS-сервису выполнен в виде hta-файла
добавлена глобальная переменная clean_start, значение true - очистить папку со временными файлами, перед началом обработки. false (по умолчанию) - папка не очищается.
озвучка выделенного фрагмента перенесена в консоль PowerShell.
Способ работы со скриптами.
Не знаю, конечно, кто может в этом разобраться. Ни одной нормальной инструкции. Откуда взять ключ разработчика? https://cloud.yandex.ru/docs/iam/operat ... key/create здесь я получил ключ, но он вот такого формата:
api_key:
id: ajeke74kbp5bfq7m6ka2
service_account_id: ajepg0mjt06siuj65usm
created_at: "2019-04-09T08:41:27Z"
secret: AQVN1HHJReSrfo9jU3aopsXrJyfq_UHsssT5ICtm

А что вставлять в YATtsConfigurator? Там ключ другого формата.

Аватара пользователя
balaamster
Обыватель

Скрипты для Demagog

#321

Сообщение balaamster » 19 май 2019 19:23

zhukov23 писал(а):
19 май 2019 14:35
Откуда
Текущий формат ключа, выдаваемого Яндексом, подходит только для новой версии сервиса, в котором запрос на озвучку идёт через метод POST.

У меня в скриптах идёт обращение к старой версии сервиса, где запрос через GET и ключ другого формата.

Если нет ранее полученного ключа старого формата, то в конфигураторе можно оставить демо-ключ для ознакомления с сервисом.

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#322

Сообщение flegont » 31 май 2019 11:16

Внес маленькое дополнение в текущую версию.
v. 7.29.373 (сборка от 31.05.2019)

Cancel() - функция встроенного интерпретатора. Возвращает true если была нажата глобальная клавиша прерывания длительных процессов (Break по умолчанию). Используется для досрочного прекращения работы скрипта.

Код: Выделить всё

-- ПРИМЕР 1
for i = 1,1000000000 do
    a = i
    if Cancel() then goto HALT end
end
::HALT::
ShowMessage(a)

Код: Выделить всё

-- ПРИМЕР 2
-- показ по отдельности всех слов из текста в окне 1
require "profiles/grafica"

cl = os.setlocale('', 'ctype')

s = WText(1)
s = string.gsub(s,'\9',' ')
s = string.gsub(s,'-','- ')
s = string.gsub(s,'\r',' ')
s = string.gsub(s,'\n',' ')
a = string.split(s,' ')

GaugeInit(#a)
Show()
for i = 1,#a do
    Clear()
    Area(-60,-12,60,12)
    Font('Verdana',8,Black)
    Pen(LightGray,2)
    Rectangle(-60,-12,60,12)
    if string.trim(Body(a[i])) ~= '' then
        TextOut(0,8,a[i],taCenter)
        Render()
        --StrSpeak(a[i]) -- если нужно чтение , то раскомментируйте эту строку
        Delay(300)   -- а эту - закомментируйте
    end
    Gauge(i)
    if Cancel() then break end
end
Hide()
Gauge(0)

os.setlocale(cl)

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#323

Сообщение tonio_k » 31 май 2019 11:58

Сразу пришла идея применения этой функции в качестве приостановки выполнения скрипта для для просмотра "текущего промежуточного" результата вычислений:

Код: Выделить всё

a=a+1
if Cancel() then ShowMessage(a) end

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#324

Сообщение tonio_k » 31 май 2019 12:04

flegont писал(а):
31 май 2019 11:16
Возвращает true если была нажата глобальная клавиша прерывания длительных процессов (Break по умолчанию).
Само событие присвоения true происходит на каком этапе?
1) Запустил Демагог - начинается мониторинг клавиши Break
2) Запустил Скрипт - начинается мониторинг клавиши Break

Два раза нажал клавишу Break, true меняется на false?

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#325

Сообщение tonio_k » 31 май 2019 12:23

Еще момент:
flegont писал(а):
31 май 2019 11:16
v. 7.29.373 (сборка от 31.05.2019)
в архиве присутствует файл $.cfg - он перезапишет "текущие пользовательские настройки" если не глядя перезаписать поверх старого Демагога

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#326

Сообщение flegont » 31 май 2019 12:32

Дистрибутив почистил от cfg, перезалил.
Ожидание нажатия Break начинается с момента запуска скрипта. Пока Break не нажата, флаг события = false. Как только Break нажата - то всё, труба пропела, любые дальнейшие вызовы Cancel() вернут true.


Отправлено спустя 6 минут 11 секунд:
Поэтому, единственное назначение функции Cancel() - воспринять сигнал об окончании работы скрипта. "Мюрат пошел в обход - нас хочет окружить! Фельдмаршал приказал нам отступить." (с)

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#327

Сообщение tonio_k » 31 май 2019 12:44

tonio_k писал(а):
31 май 2019 12:23
любые дальнейшие вызовы Cancel() вернут true.
а какой командой можно "обнулить" значение Cancel() ?

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#328

Сообщение flegont » 31 май 2019 12:47

Пока никакой, но я думал над этим. Добавить еще одну функцию - установку флага ожидания нажатия клавиши Break.
Показалось излишним, но если очень надо, то сделаю.

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#329

Сообщение tonio_k » 31 май 2019 13:00

flegont писал(а):
31 май 2019 12:47
но если очень надо, то сделаю.
не то что бы прямо очень надо :scratch:. Еще не начал ее применять из за отсутствия острой необходимости в этой функции для себя лично. Смутила заложенная в неё "одноразовость"

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#330

Сообщение flegont » 31 май 2019 13:14

Вообще-то, меня тоже... Так что, сейчас будет еще одно дополнение :smile1:

v. 7.29.373 (сборка от 31.05.2019 13:16)

Отправлено спустя 5 минут 49 секунд:
ForgotCancel() - функция встроенного интерпретатора. Сбрасывает флаг нажатия пользователем глобальной клавиши Break. Пример использования:

Код: Выделить всё

ShowMessage('НАЧАТЬ 1-Й ДЛИТЕЛЬНЫЙ ПРОЦЕСС')
for i = 1,1000000000 do
    a = i
    if Cancel() then break end
end
ShowMessage('a = '..a)

ForgotCancel()  -- заново ожидать нажатия Break
if Cancel() then goto HALT end

ShowMessage('НАЧАТЬ 2-Й ДЛИТЕЛЬНЫЙ ПРОЦЕСС')
for i = 1,1000000000 do
    b = i
    if Cancel() then break end
end
ShowMessage('b = '..b)

::HALT::
Если в этом примере закомментировать ForgotCancel(), то 2-й длительный процесс выполняться не будет - скрипт завершится сразу.

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#331

Сообщение tonio_k » 01 июн 2019 23:08

flegont писал(а):
18 апр 2019 10:58
Простой графический индикатор 2
► Показать
Это поле можно редактировать (указать свой вариант)?

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#332

Сообщение flegont » 02 июн 2019 09:21

Пока нет. Но идея мне нравится. Подумаю, что можно сделать.

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#333

Сообщение flegont » 02 июн 2019 15:01

v. 7.29.373 (сборка от 02.06.2019)

Headline(name) - функция встроенного интерпретатора; изменяет заголовок окна Инфографики, (по умолчанию: 'Инфографика').

Код: Выделить всё

require "profiles/grafica"

Clear()
Show()

Headline('У попа')
Delay(2000)
Headline('была собака')
Delay(2000)
Headline('') -- нет заголовка
Delay(2000)
Headline() -- заголовок по умолчанию

Аватара пользователя
wasyaka
V.I.P.

Скрипты для Demagog

#334

Сообщение wasyaka » 13 июн 2019 15:28

balaamster писал(а):
15 апр 2019 16:24
Если в процессе скачивания возникнут ошибки - сетевой сбой, ошибка работы моего скрипта, то
в конце работы скрипта появится сообщение, о несоответствии количества текстовых файлов сериала и полученных mp3-файлов, в проводнике откроется каталог, в котором находятся временные txt-файлы сериала, полученные mp3-файлы (подкаталог "audio") и лог-файл (подкаталог "log")
Процесс скачивания можно будет продолжить, заново запустив скрипт на вкладке с книгой и ответив на запрос "ДА - продолжить преобразование с последнего необработанного файла"
2019-06-13_150720.png
2019-06-13_150720.png (9.76 КБ) 241 просмотр
Запустил, ещё раз запустил и пошёл в Play_A
Там тоже не все, но имеющие сформировал, и от сбойного записал по новой через скрипт и добавил к записаным в Play_A.
Нельзя ли реализовать такой сценарий в скипте? (слишком часто стали возникать такие проблемы, пробывал начать не с проблемного файла а немного раньше - без проблем, ошибка не понятна, всегда на новом предложении)

Аватара пользователя
balaamster
Обыватель

Скрипты для Demagog

#335

Сообщение balaamster » 13 июн 2019 21:35

wasyaka писал(а):
13 июн 2019 15:28
Нельзя ли реализовать такой сценарий в скипте?
Как я понимаю, нужно сделать так, чтобы скрипт запускался заново, если в результате первого прохода получены не все аудио-файлы?
Если так, то это можно реализовать. Но, думаю, количество автоматических повторных запусков стоит ограничить до 5-10, а то можно и в бесконечный цикл уйти, при проблемах с сетью, недоступности сервиса со стороны Яндекса и т.д.

Аватара пользователя
wasyaka
V.I.P.

Скрипты для Demagog

#336

Сообщение wasyaka » 13 июн 2019 23:44

balaamster писал(а):
13 июн 2019 21:35
Как я понимаю, нужно сделать так, чтобы скрипт запускался заново, если в результате первого прохода получены не все аудио-файлы?
Если в логах сбойный файл не в числе нескольких последних - то повторный запуск - ОК
Если 1 2 3 последних то тупик - надо этот текст из проблемных удалить из текста,вставить в другое окно и записать по отдельности... в Play_A это ре5шается автоматом, в остатке только дозаписать.
Но если сложно, не ломайте голову, :thank: это можно обойти другим путём :thank:

Ответить

Вернуться в «Demagog»