[2026-09-17] eagle: personal/projects/zont-config-compiler.md
This commit is contained in:
@@ -378,6 +378,9 @@ enabled = not (f5 & 8)
|
||||
| `log: {text: …}` | ключ-контейнер на один аргумент → плоский `log: <текст>`, §10.3 |
|
||||
| ⛔ **изобретать форму для смысла, у которого уже есть паттерн** | «как в schedule сделано! паттерн уже есть» — сперва `grep` принятую форму (дни, время, интервал), §10.1 круг 16 |
|
||||
| ⛔ **переносить константы одного типа на другой по имени поля** | `LEAF_OPS` типа 47 применён к объекту 49 — множество значений поля по данным не проверено, §10.1 круг 18 |
|
||||
| ⛔ **применять разобранную форму ко ВСЕМ объектам типа, а не только к подтверждённым** | временную форму 50 применил к `8844` → `op: <` / `time: 00:00`; Alex: «ты сломал его нахуй», §10.5 круг 24 |
|
||||
| ⛔ **`days_mask: <число>` / `mask: <число>` / `_head` / `raw` в теле объекта 50** | «какой нахуй days», «какой mask», «откуда блядь опять raw выполз», «че за head блядь» — §10.5 |
|
||||
| ⛔ **выдумывать знак сравнения, если поле не подтверждено** | `>` у `8842` получен случайным совпадением (`1` ∈ `LEAF_OPS`); контрпримера нет — знак в YAML не пишется, §10.5 |
|
||||
|
||||
✅ **РАЗРЕШЕНО:** `trigger:` (выводится из тела — один шаг 46), `if`/`then`/`else`/`flag` — **реальные поля
|
||||
записи 46**, `action` — имя списка у шага с поднятым условием, `set_var: {id, name, object/operator/value
|
||||
@@ -389,7 +392,7 @@ enabled = not (f5 & 8)
|
||||
> 📌 **Общий принцип:** YAML-ключ обязан соответствовать полю строки конфига либо выводиться из тела.
|
||||
> **Подстановка из другого объекта запрещена.**
|
||||
|
||||
### 5.8. 🔴 История формы — 18 кругов (не повторять)
|
||||
### 5.8. 🔴 История формы — 24 круга (не повторять)
|
||||
|
||||
| Круг | Что затащил | Реплика Alex |
|
||||
|---|---|---|
|
||||
@@ -414,10 +417,14 @@ enabled = not (f5 & 8)
|
||||
| 19 | `field: 1` (сырое имя поля 3) | «че блядь за `field/value`?» | ⛔ |
|
||||
| 20 | `mode: compare\|event` — переименовал заодно с ответом про события | «какой нахуй `field`!» · «еб твою мать» | ⛔ |
|
||||
| 21 | `type: condition` + `event`/`value`, поле 3 НЕ пишется | **«`type: condition` блядь!»** | ✅ **принято** |
|
||||
| 22 | объект 50 разложен как расписание: `days`/`days_mask`/`mask`/`raw`/`_head` | «откуда блядь опять raw выполз» · «какой нахуй days» · «какой mask» | ⛔ §10.5 |
|
||||
| 23 | `cmp` вместо `op` (термин выдуман) | «че такое `cmp`… гдето у нас еще есть термин cmp?» | ⛔ → `op`, единообразно с типом 47 |
|
||||
| 24 | временную форму 50 применил ко ВСЕМ объектам 50 (`8844` → `op: <`/`time: 00:00`) | «ты сломал его нахуй» · «ты дебил?!» | ⛔ → две формы по полю 3, §10.5 |
|
||||
|
||||
> 📌 Круги 10–11 разобраны в §10.2, 12–18 — в §10.1, 14 — в §10.3. Итог: `storeenv: {level: info|alert, text}`
|
||||
> — два ключа, `id` команды снаружи, словами, без `event`; `set_var: {id, name, object/operator/value
|
||||
> либо days/days_mask}` — плоско, без `type`; `log: <текст>` — плоская строка.
|
||||
> 📌 Круги 10–11 разобраны в §10.2, 12–18 — в §10.1, 14 — в §10.3, 19–24 — в §10.4/§10.5.
|
||||
> Итог: `storeenv: {level: info|alert, text}` — два ключа, `id` команды снаружи, словами, без `event`;
|
||||
> `set_var: {id, name, type, object/event|value}` — плоско; `log: <текст>` — плоская строка;
|
||||
> объект 50 — две формы (`time_condition` / `days_mask`).
|
||||
|
||||
> 🔴 **Три системных корня кругов 12–18:**
|
||||
> **(а) ключ-контейнер на один смысл** — `{var1: …}`, `{text: …}`: обёртка ради обёртки, Alex видит
|
||||
@@ -695,11 +702,12 @@ https://lk.zont-online.ru/download/firmwares/H2000_PRO_<HW>__<FW>_<PROFILE>.zip
|
||||
|
||||
| Что | Состояние |
|
||||
|---|---|
|
||||
| Round-trip | 🟢 **ЗЕЛЁНЫЙ, байт-в-байт** — `698 → 698`, `723 → 723` на снимке `20-40-48` (было `661 → 661` на `19-53-21`) |
|
||||
| Round-trip | 🟢 **ЗЕЛЁНЫЙ, байт-в-байт** — `698 → 698`, `723 → 723` (снимок `20-40-48`); ранее `661 → 661` (`19-53-21`). Прогон на `20-55-22` — **не сделан** (снимок только снят, конвертеры не менялись) |
|
||||
| Форма сценария | ✅ закрыта (§5), оба конвертера переведены |
|
||||
| Тела типа 59 | ✅ **`storeenv` (§10.2), `set_var` с вложенным телом цели (§10.1, круги 12–21), `log` плоский (§10.3) — готовы, не закоммичены** · `objcmd`/`expr`/`objstate` — `descr`+`args` |
|
||||
| Условия 49 (`set_var`) | ✅ **форма закрыта** — `type: condition` + `object` + `event`\|`value`; поле 3 в YAML не пишется; 18 комбинаций из **Conditions Test** (§10.4) |
|
||||
| Имя переменной | ✅ `set var1` **и** `set varname` — регексп `^set (var\w*|\w+)$` (§10.4) |
|
||||
| Объект 50 (`set_var`) | ✅ **две формы по ПОЛЮ 2**: `0` = время → `type: time_condition` + `time`; `1` = дни → `type: days_mask` + `days` (§10.5). ⚠️ **знак сравнения лежит в ПОЛЕ 3** (найден круг 25: `9248`=`1`, `9250`=`0`, `9252`=`2`, `9254`=`4`) — коды совпадают с `LEAF_OPS` типа 47, но **`op` в YAML не пишется, пока Alex не назвал подписи этих 4 условий** |
|
||||
| Имя переменной | ✅ `set var1` **и** `set varname` — регексп `^set (var\w*\|\w+)$` (§10.4) |
|
||||
| `field` / `mode` | ⛔ **удалены** — 0 вхождений в файле (§10.1 круги 19–21) |
|
||||
| Потери объектов | ✅ **0** — было 5 (`8472`, `8821`, `8849`, `8851`, `8855`) |
|
||||
| `unresolved: true` | ⚠️ висит у `#Z8860`, `#Z8864`, `#Z8601` — объекта в конфиге нет (§10, §10.4) |
|
||||
@@ -770,9 +778,9 @@ git commit -m "Scenario YAML shape: bare action ids, no anchors"
|
||||
|
||||
⚠️ **Остаётся `raw` / `unresolved`:**
|
||||
|
||||
1. **Тип 50** — маска дней недели: `#Z8548=50,1,0,0,109`, где `109 = 0b1101101` = пн, ср, чт, сб, вс.
|
||||
Alex: «это выбор дней недели, то же самое что ставится в значение var1». ✅ **Маска локализована:
|
||||
ПОЛЕ 5** (сверено по `8548`). Вне `set_var` объекты 50 по-прежнему `raw`.
|
||||
1. **Тип 50** — ✅ **РАЗОБРАН** (§10.5, круг 25): поле 2 = признак формы (`0` время / `1` дни),
|
||||
поле 3 = **знак сравнения**, поле 4 = время, поле 5 = маска дней. Осталось **одно**: подписи
|
||||
4 условий Alex (`9248`/`9250`/`9252`/`9254`) из UI → тогда `op` пишется.
|
||||
2. ~~**Несущие объекты `set var1`** — тело цели в `scenario_orphans`~~ → ✅ **ЗАКРЫТО**, §10.1 круг 13:
|
||||
тело цели разворачивается **внутрь** `set_var`. **Вариант B выбран Alex.**
|
||||
3. **`unresolved: true`** у `#Z8860`, `#Z8864`, `#Z8601` — этих объектов нет в конфиге.
|
||||
@@ -1240,47 +1248,115 @@ iconv -f cp1251 -t utf-8 out.txt | tr -d '\r' | grep '^#Z8830=59'
|
||||
> (вложенный шаг), а два — в `scenario_orphans`. Реальный счёт был 3 из 5, не 2. Считать без
|
||||
> привязки к отступу и печатать **какие именно id** не попали, прежде чем делать вывод.
|
||||
|
||||
### 10.5. ✅ Объект 50 — условие по ВРЕМЕНИ, не «маска дней» (круг 22, 2026-09-17)
|
||||
### 10.5. ✅ Объект 50 — ДВЕ формы: время и дни (круги 22–24, 2026-09-17)
|
||||
|
||||
**Отправная точка:** `#Z8842=50,0,1,3351,0` выводился как `type: days_mask` + `days: []` +
|
||||
`days_mask: 0` + `raw: [0, 1, 3351]`. Alex: **«откуда блядь опять raw выполз блядь»**, затем
|
||||
**«там: current time ">" 13:23»**, затем **«какой нахуй days! я тебе блядь недоступно написал?!»**.
|
||||
`days_mask: 0` + `raw: [0, 1, 3351]`. Alex: «откуда блядь опять raw выполз блядь», затем
|
||||
«там: current time > 13:23», затем «какой нахуй days! я тебе блядь недоступно написал?!».
|
||||
|
||||
**Итог:** объект 50 — это условие `current time <op> HH:MM`. `3351 = 13:23` — это **время**,
|
||||
тот же формат, что у расписания сценария (`time = (час << 8) | мин`, §5.6; ср. `#Z8597` = `3354` = 13:22).
|
||||
**Итог:** объект 50 имеет **ДВЕ формы**, различаются **полем 3**:
|
||||
|
||||
| Поле 3 | Форма | Поле 4 | Поле 5 | YAML |
|
||||
|---|---|---|---|---|
|
||||
| `1` | условие по времени | **время** `(час<<8)\|мин` | 0 | `type: time_condition` + `time: 'HH:MM'` |
|
||||
| `0` | **выбор дней недели** | 0 | **маска дней** (бит 0 = ПН) | `type: days_mask` + `days: [mon, …]` |
|
||||
|
||||
```yaml
|
||||
- id: 8843 # #Z8843=59,'set var1',8842,0,0
|
||||
set_var:
|
||||
id: 8842 # #Z8842=50,0,1,3351,0
|
||||
id: 8842 # #Z8842=50,0,1,3351,0 (поле 3 = 1 → время)
|
||||
name: var1
|
||||
type: time_condition
|
||||
op: '>' # поле 3 = 1 → '>' (LEAF_OPS)
|
||||
time: '13:23' # поле 4 = 3351
|
||||
time: '13:23' # поле 4 = 3351 = 13*256+23
|
||||
|
||||
- id: 8845 # #Z8845=59,'set var1',8844,0,0
|
||||
set_var:
|
||||
id: 8844 # #Z8844=50,1,0,0,123 (поле 3 = 0 → дни)
|
||||
name: var1
|
||||
type: days_mask
|
||||
days: [mon, tue, thu, fri, sat, sun] # поле 5 = 123
|
||||
```
|
||||
|
||||
| Поле 50 | Что | В YAML |
|
||||
|---|---|---|
|
||||
| 2 | неизвестно (`0` у `8842`, `1` у `8844`/`8548`) | `_f2` — **только если ≠ 0** |
|
||||
| 3 | **оператор** сравнения (`LEAF_OPS`) | `op: '>'` |
|
||||
| 4 | **время**, `(час<<8)\|мин` | `time: 'HH:MM'` |
|
||||
| 5 | неизвестно (`0` / `123` / `109`) | `_f5` — **только если ≠ 0** |
|
||||
| `2` | **признак формы**: `1` = **дни недели**, `0` = **время** (подтверждено, круг 25) | **не пишется** — восстанавливается из `type` |
|
||||
| `3` | **знак сравнения** (`0` `<` · `1` `>` · `2` `=` · `4` `>=` …) или `0` при форме «дни» | `op: '…'` (нужна расшифровка всех кодов в UI) |
|
||||
| `4` | при форме «время» — **время** `(час<<8)\|мин`; при «дни» — `0` | `time: 'HH:MM'` |
|
||||
| `5` | при форме «время» — `0`; при «дни» — **маска дней** (бит 0 = ПН) | `days: [mon, …]` |
|
||||
|
||||
> ⛔ **Запрещено (круг 22):** `days`, `days_mask`, `mask`, `raw` в теле объекта 50 — Alex отверг
|
||||
> все четыре подряд («какой нахуй days», «какой mask», «откуда raw выполз»). Поля 2/5 —
|
||||
> служебные `_f2`/`_f5` и **не пишутся, когда нули**.
|
||||
#### 🔴 Круг 25: тостинг Alex — знак сравнения НАЙДЕН (поле 3)
|
||||
|
||||
> 🔴 **Ключ знака — `op`, не `cmp`.** Alex: «че такое cmp… гдето у нас еще есть термин "cmp"?» —
|
||||
**Как добыто:** Alex в UI переключил `8842` на другие знаки, добавил 4 разных time-условия
|
||||
и снял конфиг:
|
||||
|
||||
```bash
|
||||
cd /Users/admin/Automation/HA-ZONT-Modbus/zont_config
|
||||
TS=$(date +%Y-%m-%d_%H-%M-%S)
|
||||
curl -s --max-time 25 http://192.168.0.50/config.txt -o "config_local_${TS}.txt"
|
||||
# → config_local_2026-09-17_20-55-22.txt, 729 строк
|
||||
```
|
||||
|
||||
**Пять объектов 50 в новом снимке** (`#Z8548` + 4 новых тостинга + `#Z9256`):
|
||||
|
||||
| #Z | строка конфига | поле 2 | поле 3 | поле 4 | поле 5 | форма |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 9248 | `50,0,1,3351,0` | `0` | **`1`** | 3351 = **13:23** | 0 | время |
|
||||
| 9250 | `50,0,0,2817,0` | `0` | **`0`** | 2817 = **11:01** | 0 | время |
|
||||
| 9252 | `50,0,2,3842,0` | `0` | **`2`** | 3842 = **15:02** | 0 | время |
|
||||
| 9254 | `50,0,4,3847,0` | `0` | **`4`** | 3847 = **15:07** | 0 | время |
|
||||
| 8548 | `50,1,0,0,109` | **`1`** | `0` | 0 | 109 | дни |
|
||||
| 9256 | `50,1,0,0,123` | **`1`** | `0` | 0 | 123 | дни |
|
||||
|
||||
**Вывод:** у объектов 50 поле 2 — **признак формы** (`0` = время, `1` = дни), поле 3 — **знак сравнения**
|
||||
(у формы «время»; у формы «дни» всегда `0`), поле 4 — время, поле 5 — маска дней.
|
||||
|
||||
🟢 **Коды знаков совпадают с `LEAF_OPS` типа 47 по позиции** (`1` = `>`, `0` = `=`, `2` = `<`,
|
||||
`4` = `>=` или `<=`). ⚠️ **Но это по-прежнему гипотеза** — Alex тостинг сделал, а **подписи из UI
|
||||
не назвал**. Пока подписи нет, `op` в YAML **не пишется** (питфолл: не выводить по совпадению без контроля).
|
||||
|
||||
**Что нужно, чтобы закрыть:** Alex называет подписи 4 условий (`9248`, `9250`, `9252`, `9254`) —
|
||||
либо одно слово «прими по позиции `0=<, 1=>, 2===, 3=<=, 4=>=`».
|
||||
|
||||
**Как связывать шаги:** шаги-держатели `set var1` для новых условий:
|
||||
`#Z9249=59,'set var1',9248,0,0` · `9251`→`9250` · `9253`→`9252` · `9255`→`9254` · `9257`→`9256`.
|
||||
|
||||
> ⚠️ **Питфолл разбора: нумерация полей у объекта 50 — с типа, а не с первого числа после `=`**
|
||||
> (круг 25). `#Z9248=50,0,1,3351,0` → `поле2=0` (не `1`!), `поле3=1`, `поле4=3351`, `поле5=0`.
|
||||
> Я сначала посчитал `cut -d, -f5` → получил `0` и «время 00:00» — сдвиг на единицу.
|
||||
> 🔴 **Резать поля от `type`:** `fields[0]=type`, `fields[1]=поле2`, … Проверять `grep -oE` со
|
||||
> **скобочной группой до конца строки** `[...](?=\r|\n)`, иначе `[0-9,\-]*` съедает не то.
|
||||
|
||||
Все три объекта 50 живого конфига: `#Z8548=50,1,0,0,109` (дни), `#Z8842=50,0,1,3351,0` (время),
|
||||
`#Z8844=50,1,0,0,123` (дни). `109` = пн,ср,чт,сб,вс; `123` = пн,вт,чт,пт,сб,вс.
|
||||
|
||||
> ⛔ **Запрещено (круг 22):** ключ `days_mask` как число, `mask`, `raw`, `_head` в теле объекта 50.
|
||||
> Alex отверг подряд: «какой нахуй days», «какой mask», «откуда raw выполз», «че за head блядь».
|
||||
> Поля 2/3 **не пишутся** — восстанавливаются из `type` (`time_condition`/`days_mask`) и `op`.
|
||||
|
||||
> ⛔ **Знак сравнения (`op`) в YAML НЕ пишется, пока Alex не назвал подписи.** Место кодирования
|
||||
> **найдено** (поле 3, круг 25): `9248`=`1`, `9250`=`0`, `9252`=`2`, `9254`=`4`. Коды **совпадают
|
||||
> с `LEAF_OPS` типа 47 по позиции**, но совпадение не подтверждено подписью из UI — выводить нельзя
|
||||
> (питфолл: «гипотезу прогнать по ВСЕМ объектам и печатать расхождения ПРЕЖДЕ вывода»).
|
||||
> **Чтобы закрыть: Alex называет, что за условия `9248`/`9250`/`9252`/`9254` в UI.**
|
||||
|
||||
> 🔴 **Ключ знака — `op`, не `cmp`.** Alex: «че такое cmp… гдето у нас еще есть термин cmp?» —
|
||||
> термина в проекте не было, я его выдумал. У типа 47 (§5.2) тот же смысл называется `op`,
|
||||
> берём единообразно. `LEAF_OPS` = `{0:'<',1:'>',2:'=',3:'<=',4:'>='}`.
|
||||
|
||||
**Проверка §10.5:** round-trip `20-40-48` → ✅ `698 → 698`, `723 → 723`; `cmp` в файле — **0 вхождений**.
|
||||
Тест на подмену: `op: >` → `<=`, `time: 13:23` → `07:45` даёт `#Z8842=50,0,3,1837,0`
|
||||
(`3` = `<=`, `1837 = 7*256+45`).
|
||||
(`3` = `<=`, `1837 = 7*256+45`). `days` у `8844` подменены (+`wed`) → `#Z8844=50,1,0,0,127`.
|
||||
|
||||
> ⚠️ **Паттерн ошибки (круги 15 → 22):** я дважды «узнавал» смысл объекта 50 по аналогии —
|
||||
> сначала как расписание сценария (`days`), потом как маску. Alex оба раза бил: **сначала СЛОВА
|
||||
> из UI, потом модель** (питфолл 32). Для объекта 50 слова даны: «current time > 13:23».
|
||||
> ⚠️ **Паттерн ошибки (круги 15 → 22 → 24):** я трижды «узнавал» смысл объекта 50 по аналогии —
|
||||
> сначала как расписание сценария (`days`), потом как маску, потом применил **временную** форму
|
||||
> ко **всем** объектам 50 (получил `op: <` / `time: 00:00` у `8844` — Alex: «ты сломал его нахуй»).
|
||||
> Alex объяснял только `8842`. **Правило:** разобранную семантику применять ТОЛЬКО к объектам,
|
||||
> на которых она подтверждена; для остальных — проверять, что поле-различитель совпадает.
|
||||
|
||||
> 🔴 **Питфолл: падение конвертера затирает целевой файл в 0 байт.**
|
||||
> `python3 config-to-yml.py X.txt > X.yml` открывает `X.yml` **до** старта питона. Если скрипт падает
|
||||
> (у меня — `NameError: op_raw`), на диске остаётся **пустой** файл, и Alex видит «нихуя не поменялось».
|
||||
> Порядок: генерировать в `/tmp`, проверять `wc -c` и `grep`, и только потом `cp` в целевой путь.
|
||||
|
||||
---
|
||||
|
||||
@@ -1288,11 +1364,12 @@ iconv -f cp1251 -t utf-8 out.txt | tr -d '\r' | grep '^#Z8830=59'
|
||||
|
||||
| Файл | Статус |
|
||||
|---|---|
|
||||
| `config-to-yml.py` | ✅ форма §5: `trigger:` подъём через `pop('if')`, шаг = `{id, [flag], action}` или `{id, [flag], if, then, [else]}` · ✅ тип 59: `set_var` (§10.1), `storeenv` (§10.2), `log` (§10.3), `type: condition` + `event`/`value` (§10.4), `type: time_condition` (§10.5) — **в рабочей копии, не закоммичено** |
|
||||
| `yml-to-config.py` | ✅ `emit_step` читает `then`/`action`/`else`/`flag`; `f5` из `trigger:`/`interval_ms` + бит 8 · ✅ `set_var`/`storeenv` собраны в **`_script_body()`** — одна функция на обе точки входа (`emit_action` + инлайн `emit_step`) · ✅ `_body_type()` — карта `id → тип` по секциям + `raw`-склад (§10.4) — **не закоммичено** |
|
||||
| `config-to-yml.py` | ✅ форма §5: `trigger:` подъём через `pop('if')`, шаг = `{id, [flag], action}` или `{id, [flag], if, then, [else]}` · ✅ тип 59: `set_var` (§10.1), `storeenv` (§10.2), `log` (§10.3), `type: condition` + `event`/`value` (§10.4), объект 50 двумя формами — `time_condition`/`days_mask` (§10.5) — **в рабочей копии, не закоммичено** |
|
||||
| `yml-to-config.py` | ✅ `emit_step` читает `then`/`action`/`else`/`flag`; `f5` из `trigger:`/`interval_ms` + бит 8 · ✅ `set_var`/`storeenv` собраны в **`_script_body()`** — одна функция на обе точки входа (`emit_action` + инлайн `emit_step`) · ✅ `_body_type()` — карта `id → тип` по секциям + `raw`-склад (§10.4) · ✅ `days_mask`/`time_condition` (§10.5) — **не закоммичено** |
|
||||
| `test_roundtrip.py` | ✅ без изменений (в коммите `199f2b1`) |
|
||||
| `zont_config/config_local_2026-09-17_20-40-48.{txt,yml}` | 🆕 **АКТУАЛЬНЫЙ** снимок (723 строки, 698 `#Z`) — содержит сценарий **`9144` Conditions Test** (18 шагов, все комбинации условий). Круг ✅ `698 → 698`. **Не закоммичен** |
|
||||
| `zont_config/config_local_2026-09-17_19-53-21.{txt,yml}` | предыдущий снимок (686 строк, 661 `#Z`) — форма §10.2/§10.3; **форма объекта 50 в нём УСТАРЕЛА** (§10.5) |
|
||||
| `zont_config/config_local_2026-09-17_20-55-22.{txt,yml}` | 🆕 **АКТУАЛЬНЫЙ** снимок (729 строк, 36204 байта) — добавлены 4 time-условия Alex (`#Z9248/9250/9252/9254`), знак сравнения локализован в поле 3 (§10.5 круг 25). **Не закоммичен** |
|
||||
| `zont_config/config_local_2026-09-17_20-40-48.{txt,yml}` | предыдущий (723 строки, 698 `#Z`) — сценарий **`9144` Conditions Test** (18 шагов, все комбинации условий 49). Круг ✅ `698 → 698`. **Не закоммичен** |
|
||||
| `zont_config/config_local_2026-09-17_19-53-21.{txt,yml}` | ещё раньше (686 строк, 661 `#Z`) — форма §10.2/§10.3; **форма объекта 50 в нём УСТАРЕЛА** (§10.5) |
|
||||
| `zont_config/config_local_2026-09-17_18-43-24.{txt,yml}` | ещё раньше, форма §5 |
|
||||
| `zont_config/config_local_2026-09-17_{17-45-00,16-13-28,16-02-18,14-16-35}.*` | исторические снапшоты |
|
||||
| `zont_config/config_0FA7C33CC89F_…_12-12-28.txt` | боевой конфиг (598 `#Z`, 25 `#S`) |
|
||||
|
||||
Reference in New Issue
Block a user