# Описание Welrok local API

# Введение

Для устройств Wi-Fi доступна опция прямого управления через локальную сеть. Обмен информацией осуществляется посредством POST запросов на http://`dev_ip`/api.cgi, где `dev_ip` - ip адрес устройства в локальной сети. Для обнаружения новых устройств в локальной сети используются широковещательные (смотри: broadcast_ru.html) пакеты. Данные представлены в формате JSON.

> **Important:** Возможность управления по локальной сети без токена безопасности по умолчанию заблокирована (смотри: safety_ru.html) в целях безопасности. Это может быть актуальным, например, при использовании локального управления в общественных местах. Если данная мера безопасности не нужна, отключите ее на устройстве, переведя параметр `bLc` в значение **oFF**. В противном случае запросы на изменение без данного токена не будут выполняться.

Доступны следующие ключи JSON:

`sn` - серийный номер устройства, обязателен при передаче новых параметров.

`cmd` - отправка команды (смотри: commands_ru.html) для получения данных от устройства (параметры (смотри: parameters_ru.html), расписание (смотри: schedule_ru.html), телеметрия (смотри: telemetry_ru.html))

`par` - изменение параметров устройства (смотри: parameters_ru.html)

`tt` - передача расписания (смотри: schedule_ru.html)

`ttAir` - передача расписания (смотри: schedule_ru.html) при контроле по воздуху (воздуху с ограничением по полу), для устройств с датчиком воздуха

`time`, `auth` - аутентификация (смотри: safety_ru.html)

> **Important:** Нельзя в одном запросе передавать расписание и параметры, а также несколько дней расписания.

> **Note:** На устройстве существует страница http://`dev_ip`/api.html, на которой можно проверить верность запросов и протестировать протокол обмена.
Функция управления через API доступна так-же при работе утройства в режиме точки доступа. Для этого переведите устройство в режим «AP», подключитесь к нему и перейдите по ссылке: http://192.168.0.1/api.html

> **Note:** На устройстве существует страница http://`dev_ip`/index.html, где доступна функция подключения устройства к облаку `API` `CLOUD`. Если пункт `CLOUD` включен, связь устройства с облаком активна. Если пункт `CLOUD` выключен, связь устройства с облаком отсутствует. При отключении связи с облаком гарантированно не передаются никакие данные на облако. Однако при этом не осуществляется и синхронизации времени на устройстве с облаком. Страница доступна так-же при работе утройства в режиме точки доступа. Для этого переведите устройство в режим «AP», подключитесь к нему и перейдите по ссылке: http://192.168.0.1/index.html

# Поиск устройств

Для получения списка доступных устройств в локальной сети используются широковещательных UDP-пакетов. Каждое устройство после подключения к сети несколько раз в минуту посылает UDP-пакет на порт 23500 с JSON-данными вида:

```json
{
   "sn":"404CCAAAD4E8A89860609800000149",
   "hw":"oz",
   "cloud":"true",
   "connection":"cloudCon",
   "wifi":"-71",
   "display":"23.0"
}
```

`sn` - серийный номер устройства

`hw` - тип устройства

`cloud` - битовый параметр подключения к облаку. Может возвращать:

`connection` - состояние подключения к облаку

`wifi` - уровень сигнала Wi-Fi в dBm

`display` - показание дисплея устройства на момент запроса

# Команды

> **Important:** Возможность управления по локальной сети без токена безопасности по умолчанию заблокирована (смотри: safety_ru.html) в целях безопасности. Это может быть актуальным, например, при использовании локального управления в общественных местах. Если данная мера безопасности не нужна, отключите ее на устройстве, переведя параметр `bLc` в значение **oFF**. В противном случае запросы на изменение без данного токена не будут выполняться.

Для получения параметров устройства служит ключ `cmd`.
Возможные значения:

- 1 - запрос на получение параметров (смотри: parameters_ru.html)
- 2 - запрос на получение расписания (смотри: schedule_ru.html) при контроле по полу
- 3 - запрос на получение времени устройства
- 4 - запрос на получение телеметрии (смотри: telemetry_ru.html)
- 5 - запрос cброса параметров (смотри: parameters_ru.html)
- 6 - запрос cброса расписания (смотри: schedule_ru.html)
- 10 - запрос на получение расписания (смотри: schedule_ru.html) при контроле по воздуху и по воздуху с ограничением по полу

Запрос `{"cmd":1}`

Получение параметров (смотри: parameters_ru.html)

Ответ:

```json
{
   "sn":"404CCAAAD4E8A89860609800000149",
   "par":[[64,6,"0"],[65,3,"300"],[23,2,"10"],
         [114,7,"0"],[115,7,"0"],[29,3,"0"],
         [66,6,"0"],[67,6,"0"],[0,6,"0"],[1,6,"0"],
         [2,2,"1"],[31,3,"230"],[3,2,"2"],[19,2,"10"],
         [18,2,"2"],[21,1,"0"],[5,3,"300"],[7,3,"50"],
         [109,7,"1"],[80,1,"0"],[81,1,"0"],[82,1,"0"],
         [25,2,"15"],[26,1,"45"],[27,1,"5"],[33,1,"35"],
         [34,1,"5"],[28,2,"16"],[17,4,"0"],[52,4,"0"],
         [53,4,"480"],[62,1,"35"],[63,1,"5"],[55,2,"24"],
         [20,1,"0"],[4,3,"230"],[6,3,"180"],[14,1,"0"],
         [15,1,"45"],[122,7,"0"],[35,2,"1"],[36,7,"1"],
         [117,7,"0"],[118,7,"0"],[121,7,"0"],[124,7,"0"],
         [125,7,"0"],[120,7,"0"]]
}
```

Запрос `{"cmd":2}`

Получение расписания (смотри: schedule_ru.html)

Ответ:

```json
{
   "sn":"404CCAAAD4E8A89860609800000149",
   "tt":{
         "0":[[360,300],[480,250],[1020,300],[1320,250]],
         "1":[[360,300],[480,250],[1020,300],[1320,250]],
         "2":[[360,300],[480,250],[1020,300],[1320,250]],
         "3":[[360,300],[480,250],[1020,300],[1320,250]],
         "4":[[360,300],[480,250],[1020,300],[1320,250]],
         "5":[[480,300],[1380,250]],
         "6":[[480,300],[1380,250]]
        }
}
```

Запрос `{"cmd":3}`

Получение времени устройства:

Ответ:

```json
{
   "sn":"9C9E6E854B44D8D5EBEBD50000014C",
   "time":"799767640",
   "tzone":"3"
}
```

Где `time` - время в секундах от 01.01.2000 00:00

`tzone` - часовой пояс

Запрос `{"cmd":4}`

Получение телеметрии (смотри: telemetry_ru.html)

Ответ:

```json
{
   "sn":"404CCAAAD4E8A89860609800000149",
   "t.0":"482","t.1":"399","t.2":"371","t.5":"368",
   "m.0":"2","m.1":"3","m.2":"1","m.5":"0","m.6":"255",
   "o.0":"-64","o.1":"1","o.5":"0","o.2":"0","o.4":"61",
   "t.7":"692","m.3":"0","f.3":"0","f.4":"0","f.5":"0",
   "f.6":"0","f.8":"0","f.7":"0","f.13":"0","f.0":"0",
   "f.17":"0","f.16":"0","f.9":"0","f.11":"0","f.12":"0",
   "f.20":"0","f.21":"0","f.22":"1","f.23":"0",
   "par.26":"45","par.27":"5","par.33":"35","par.34":"5",
   "time":"799767684","setPointStep":"0.5","setPointType":"3"
}
```

Запрос `{"cmd":5}`

Запрос сброса параметров (смотри: parameters_ru.html) на значение по умолчанию. В запрос необходимо включить «sn». При установленной блокировки изменений из локальной сети ([114,7,»1»]) в запрос необходимо включить ключ «auth» (см. Безопасность (смотри: safety_ru.html)).

```json
{"cmd":5,"sn":"404CCAAAD4E8A89860609800000149" }
```

Ответ:

При ([114,7,»0»]) (см. Безопасность (смотри: safety_ru.html)):

```json
{
   "sn":"404CCAAAD4E8A89860609800000149",
   "par":[[64,6,"725328000"],[65,3,"300"],[23,2,"10"],
         [114,7,"0"],[115,7,"0"],[29,3,"300"],[66,6,"0"],
         [67,6,"0"],[0,6,"0"],[1,6,"0"],[2,2,"1"],[31,3,"300"],
         [3,2,"0"],[19,2,"10"],[18,2,"2"],[21,1,"0"],[5,3,"300"],
         [7,3,"50"],[109,7,"0"],[80,1,"0"],[81,1,"0"],[82,1,"0"],
         [25,2,"15"],[26,1,"45"],[27,1,"5"],[33,1,"35"],
         [34,1,"5"],[28,2,"16"],[17,4,"0"],[52,4,"1320"],
         [53,4,"480"],[62,1,"35"],[63,1,"5"],[55,2,"24"],
         [20,1,"0"],[4,3,"230"],[6,3,"180"],[14,1,"5"],
         [15,1,"45"],[122,7,"0"],[35,2,"1"],[36,7,"0"],
         [117,7,"0"],[118,7,"0"],[121,7,"0"],[124,7,"0"],
         [125,7,"0"],[120,7,"0"]]
}
```

При ([114,7,»1»]) (см. Безопасность (смотри: safety_ru.html)):

```json
{"sn":"404CCAAAD4E8A89860609800000149","success":"block"}
```

Запрос `{"cmd":6}`

Запрос сброса расписания (смотри: schedule_ru.html) на значение по умолчанию. В запрос необходимо включить «sn». При установленной блокировки изменений из локальной сети ([114,7,»1»]) в запрос необходимо включить ключ «auth» (см. Безопасность (смотри: safety_ru.html)).

```json
{"cmd":6,"sn":"404CCAAAD4E8A89860609800000149" }
```

Ответ:

При ([114,7,»0»]) (см. Безопасность (смотри: safety_ru.html)):

```json
{
   "sn":"404CCAAAD4E8A89860609800000149",
   "tt":{
         "0":[[360,300],[480,250],[1020,300],[1320,250]],
         "1":[[360,300],[480,250],[1020,300],[1320,250]],
         "2":[[360,300],[480,250],[1020,300],[1320,250]],
         "3":[[360,300],[480,250],[1020,300],[1320,250]],
         "4":[[360,300],[480,250],[1020,300],[1320,250]],
         "5":[[480,300],[1380,250]],
         "6":[[480,300],[1380,250]]
        }
   }
```

При ([114,7,»1»]) (см. Безопасность (смотри: safety_ru.html)):

```json
{"sn":"404CCAAAD4E8A89860609800000149","success":"block"}
```

Запрос `{"cmd":10}`

Получение расписания (смотри: schedule_ru.html) при контроле по воздуху и по воздуху с ограничением по полу

Ответ:

```json
{
   "sn":"404CCAAAD4E8A89860609800000149",
   "ttAir":{
            "0":[[360,300],[480,250],[1020,300],[1320,250]],
            "1":[[360,300],[480,250],[1020,300],[1320,250]],
            "2":[[360,300],[480,250],[1020,300],[1320,250]],
            "3":[[360,300],[480,250],[1020,300],[1320,250]],
            "4":[[360,300],[480,250],[1020,300],[1320,250]],
            "5":[[480,300],[1380,250]],
            "6":[[480,300],[1380,250]]
           }
}
```

# Безопасность

Возможность управления по локальной сети без «токена безопасности» по умолчанию заблокирована. Это может быть актуальным, например, при использовании локального управления в общественных местах. Токен безопасности необходимо добавлять ко всем запросам на изменение. Требование наличия токена безопасности в запросах определяется параметром (смотри: parameters_ru.html) `lanBlock` 114 = **1** или в меню терморегулятора пунктом `bLc` = **Lan**. Отключить данное требование можно изменив параметр (смотри: parameters_ru.html) `lanBlock` 114 на значение **0** или в меню терморегулятора пунктом `bLc` выбрав вариант **oFF**

> **Note:** На устройстве дополнительно реализована возможность блокирования работы через облако Welrok. Данная блокировка регулируется параметром (смотри: parameters_ru.html) `cloudBlock` 115 = **1** или со страницы http://`dev_ip`, где `dev_ip` - ip адрес устройства в локальной сети.

> **Important:** Если включены обе блокировки сразу (параметры (смотри: parameters_ru.html) `lanBlock` 114 = **1** и `cloudBlock` 115 = **1**; пункт меню самого устройства `bLc` = **on**), то устройство заблокировано полностью для удаленного управления. Управление возможно только с кнопок.

Для аутентификации источника при отправке команд на устройство используется TOTP протокол (**rfc4226**, **rfc6238**, Interval = 30 second, Digit = 9), который формирует токен безопасности. Для формирования токена безопасности необходимо знать ключ,
который представляет из себя последовательность из 16 байт. Он генерируется облаком в момент первого
подключения и при каждой привязке к аккаунту. Помните, что ключ меняется если устройство привязывается снова к учетной записи личного кабинета Welrok.

Получить ключ можно только через API сервера в 2 этапа:

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

**POST** https://app.welrok.com/api/login/

```json
{
   "email":"user@email.com",
   "password":"myPassword"
}
```

**Параметры:**

- **email** - почта зарегистрированного аккаунта приложения Welrok
- **password** - пароль от аккаунта приложения Welrok

**Ответ:**

```json
{
   "access_token":"9573e6a8e24b025fafbaf81dc2eccbc09b94d187",
   "user_name":"welrok",
   "is_timezone_chosen":true
}
```

`access_token` - искомый токен авторизации

**Пример запроса токена авторизации:**

```html
{
   POST /api/login/ HTTP/1.1
   Host: app.welrok.com
   Accept-Language: en
   Content-Type: application/json

   {"email":"demo@welrok.com","password":"demoaccount"}
}
```

**GET** https://app.welrok.com/api/device/ –header «Authorization: Token `access_token`»

**Параметры**

- `access_token` - токен авторизации в заголовке

Ответ:

```json
{
   "count": 4,
   "next": null,
   "previous": null,
   "results": [
               {
                  "id": 1,
                  "sn": "404CCAAAD4E8A89860609800000149",
                  "name": "az",
                  "":""
                  "totp_key": "AAD4EXAJX4E8A8XT"
               }
              ]
}
```

Поле `totp_key` в параметрах каждого устройства содержит искомый 16-тибайтный ключ для генерации TOTP токена.

**Пример запроса списка устройств с ключами:**

```HTML
{
   GET /api/device/ HTTP/1.1
   Host: app.welrok.com
   Accept-Language: en
   Content-Type: application/json
   Authorization: Token 9573e6a8e24b025fafbaf81dc2eccbc09b94d187
}
```

После получения ключа, используя TOTP протокол (**rfc4226**, **rfc6238**, Interval = 30 second, Digit = 9), можно формировать токен безопасности и использовать его в запросах на изменение по API.

При этом в таких запросах добавляется два поля перед полями с данными:

`time` - время в секундах от 01.01.2000 00:00

`auth` - вычисленный токен безопасности.

Тогда запрос, например, для включение устройства, изменение яркости на 1 и включение блокирования изменений по API, будет выглядеть так:

```json
{
   "sn":"404CCAAAD4E8A89860609800000149",
   "time":"634929122",
   "auth":"672201707",
   "par":[[125,7,"0"], [23,2,"1"], [114,7,"1"]]
}
```

> **Note:** В 2-х кнопочных устройствах для этого надо удерживать левую кнопку до появления меню `reg`. Нажатием левой кнопки перейти в пункт меню `bLc`. Нажатием правой кнопки выбрать пункт **oFF**

> **Note:** На устройстве существует страница http://`dev_ip`/index.html, где доступна функция подключения устройства к облаку `API` `CLOUD CONNECT`. Если пункт `CLOUD CONNECT` включен, связь устройства с облаком активна. Если пункт `CLOUD CONNECT` выключен, связь устройства с облаком отсутствует. При отключении связи с облаком гарантированно не передаются никакие данные на облако. Однако при этом не осуществляется и синхронизации времени на устройстве с облаком. Страница доступна так-же при работе утройства в режиме точки доступа. Для этого переведите устройство в режим «AP», подключитесь к нему и перейдите по ссылке: http://192.168.0.1/index.html

> **Note:** На устройстве существует страница http://`dev_ip`/index.html, где доступна функция блокировки управления устройством из локальной сети или удалённо `CLOUD BLOCK`. Если на устройстве отключить блокировку (blc = off) (параметр [114,7,»0»]) и включить `CLOUD BLOCK`, то управление осуществляется только с помощью кнопок устройства или по локальной сети. Удалённое управление блокируется. В данных условиях включённый `CLOUD BLOCK` соответствует блокировке управления из облака (blc = cld) (параметр [114,7,»0»], [115,7,»1»]) на устройстве. Если на устройстве установить блокировку управления из локальной сети (blc = lan) (параметр [114,7,»1»]) и включить `CLOUD BLOCK`, то управление осуществляется только с помощью кнопок устройства. В этих условиях включённый `CLOUD BLOCK` соответствует блокировке любого управления по сети (blc = cld) (параметр [114,7,»1»], [115,7,»1»]) на устройстве. Страница доступна так-же при работе утройства в режиме точки доступа. Для этого переведите устройство в режим «AP», подключитесь к нему и перейдите по ссылке: http://192.168.0.1/index.html

# MQTT

> **Note:** На устройстве дополнительно реализована возможность блокирования работы через облако Welrok. Данная блокировка регулируется параметром (смотри: parameters_ru.html) `cloudBlock` 115 = **1** или со страницы http://`dev_ip`, где `dev_ip` - ip адрес устройства в локальной сети.
Если включены блокировки сразу  по параметрам (смотри: parameters_ru.html) `lanBlock` 114 = **1** и `cloudBlock` 115 = **1**; пункт меню самого устройства `bLc` = **on**, то устройство заблокировано полностью для удаленного управления. Управление возможно только с кнопок.

Доступна возможность сбора телеметрии и управление ключевыми параметрами по протоколу MQTT.
Настройки подключения к MQTT серверу доступны только через веб-интерфейс устройства, который доступен по его локальному IP адресу:

`Host`/`Port` - IP адрес и порт MQTT сервера

`User`/`Password` - имя пользователя и пароль для подключения к MQTT серверу

`Keep alive` - максимально допустимый промежуток времени без обмена данными

`QoS` - уровень качества обслуживания

`Publish prefix` - префикс публикации для отправки телеметрии

`Subscribe path` - название пути для подписки на комманды

`Client ID` - имя устройства

> **Note:** Если на сервере MQTT не настроена авторизация, то поля `User`/ `Password` игнорируются.

> **Important:** Максимальная длина имени `User` и `Password` составляет 30 символов.

Раз в минуту, с интервалом +/- 5 секунд, публикуются данные в следующие топики:

`Publish prefix`/`Client ID`/`get`/`floorTemp` - показания датчика температуры пола, возвращается значение аналогичное телеметрии (смотри: telemetry_ru.html), запрошенной по API по параметру **«t.1»** в °C строкой «xx.x»

`Publish prefix`/`Client ID`/`get`/`airTemp` - показания датчика температуры воздуха,, возвращается значение аналогичное телеметрии (смотри: telemetry_ru.html), запрошенной по API по параметру **«t.2»** в °C строкой «xx.x»

`Publish prefix`/`Client ID`/`get`/`protTemp` - показания внутреннего датчика перегрева, возвращается значение аналогичное телеметрии (смотри: telemetry_ru.html), запрошенной по API по параметру **«t.0»**. Возвращается в °C строкой «xx.x»

`Publish prefix`/`Client ID`/`get`/`setTemp` - температура уставки, возвращается значение аналогичное телеметрии (смотри: telemetry_ru.html), запрошенной по API по параметру **«t.5»**. Возвращается в °C строкой «xx.x»

`Publish prefix`/`Client ID`/`get`/`powerOff` - устройство выключено, возвращается значение аналогичное телеметрии (смотри: telemetry_ru.html), запрошенной по API по параметру **«f.16»**. Возвращается строкой, где «0» - включено, «1» - выключено

`Publish prefix`/`Client ID`/`get`/`load` - состояние нагрузки, возвращается значение аналогичное телеметрии (смотри: telemetry_ru.html), запрошенной по API по параметру **«f.0»**. Возвращается строкой, где «0» - выключена, «1» - включена

`Publish prefix`/`Client ID`/`get`/`typeCtrl` – тип контроля, возвращается значение аналогичное телеметрии (смотри: telemetry_ru.html), запрошенной по API по параметру **«m.0»**. Возвращается строкой, где 0-по полу, 1- по воздуху, 2- по воздуху с ограничением по полу

`Publish prefix`/`Client ID`/`get`/`maxFlrTmp` – максимально допустимая температура пола для режима контроля «по воздуху, с ограничением по полу», выполняется аналогично команде API в параметрах (смотри: parameters_ru.html).  `{"cmd":1}`

`Publish prefix`/`Client ID`/`get`/`minFlrTmp` – минимально допустимая температура пола для режима контроля «по воздуху, с ограничением по полу», выполняется аналогично команде API в параметрах (смотри: parameters_ru.html).  `{"cmd":1}`

`Publish prefix`/`Client ID`/`get`/`bright` – текущая яркость экрана терморегулятора, читается аналогично параметрам (смотри: parameters_ru.html), запрошенным по API командой `{"cmd":1}`.Возвращается строкой, со значениями от 0 до 10.

`Publish prefix`/`Client ID`/`get`/`parameters` – запрос параметров, выполняется аналогично команде API в параметрах (смотри: parameters_ru.html). `{"cmd":1}`

`Publish prefix`/`Client ID`/`get`/`schedule` - запрос расписания, выполняется аналогично команде API в параметрах (смотри: parameters_ru.html).  `{"cmd":2}`

`Publish prefix`/`Client ID`/`get`/`api` – ответ на отправку команды set/api

Доступны следующие топики для управления:

> **Note:** После отправки команды управления, через 3-5 секунд происходит внеочередная публикация данных.

`Subscribe path`/`Client ID`/`set`/`setTemp` - установка температуры уставки. Передается строкой в формате «xx.x»

`Subscribe path`/`Client ID`/`set`/`bright` - яркость дисплея. Передается строкой в формате «x». Значения от 0 до 10.

`Subscribe path`/`Client ID`/`set`/`powerOff` - выключение устройства. Передается строкой в формате «x». Значения 0 или 1, где 0 - включено 1 - выключено

`Subscribe path`/`Client ID`/`set`/`mode` - выбор режима работы. Передается строкой в формате «x». Значения от 0 или 1, где 0 - расписание, 3 - ручной.

`Subscribe path`/`Client ID`/`set`/`typeCtrl` – тип контроля: 0-по полу, 1- по воздуху, 2- по воздуху с ограничением по полу, аналогично параметру (смотри: parameters_ru.html) `controlType`

`Publish prefix`/`Client ID`/`set`/`maxFlrTmp` – максимально допустимая температура пола для режима контроля «по воздуху, с ограничением по полу».  Передается строкой в формате «xx.x»

`Publish prefix`/`Client ID`/`set`/`minFlrTmp` – минимально допустимая температура пола для режима контроля «по воздуху, с ограничением по полу». Передается строкой в формате «xx.x»

`Subscribe path`/`Client ID`/`set`/`schedule` – установка расписания (устанавливается на 1 день). Передача команды выполняется аналогично команде API в расписании (смотри: schedule_ru.html) отправкой JSON содержащим sn устройства, номер недели и двумерный массив с периодами и температурой.

`Subscribe path`/`Client ID`/`set`/`parameters` – установка параметров. Передача команды выполняется аналогично команде API в параметрах (смотри: parameters_ru.html) отправкой JSON содержащим sn устройства и двумерный массив с нужными параметрами, его типом и значением.

`Subscribe path`/`Client ID`/`set`/`api` – дублирует функционал webApi, позволяя передавать команды в формате API.

> **Important:** `setTemp` задается на основании выбранного типа контроля. Если выбран «по полу», то будет установлен для пола. Если выбран «по воздуху» или «по воздуху с ограничением по полу», то будет установлен для воздуха.

> **Note:** Температура датчика пола в пользовательском меню устройства и через MQTT изменяется с шагом в 1 °C во всем рабочем диапазоне. Температура датчика воздуха в пользовательском меню устройства изменяется с шагом 1 °C в диапазоне от -15 °C до -10 °C, с шагом 0.5 °C в диапазоне от -10 °C до 75 °C. Температура датчика воздуха при управлении через API изменяется с шагом 0.1 °C во всем рабочем диапазоне.

> **Note:** Параметры 29 и 31, в режиме работы по расписанию и временном режиме, могут принимать значения 127 и -127, что соответствует значениям уставки **on** (нагрузка всегда включена) и **off** (нагрузка всегда отключена) в графическом интерфейсе и на дисплее устройства.
