diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 331bbd4..22f0edf 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -6,7 +6,7 @@ cli: plugins: sources: - id: trunk - ref: v1.7.1 + ref: v1.7.2 uri: https://github.com/trunk-io/plugins # Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes) runtimes: @@ -20,12 +20,12 @@ lint: - trufflehog@3.90.5 - yamllint@1.37.1 - bandit@1.8.6 - - checkov@3.2.461 + - checkov@3.2.466 - terrascan@1.19.9 - - trivy@0.64.1 + - trivy@0.65.0 #- trufflehog@3.63.2-rc0 - - taplo@0.9.3 - - ruff@0.12.7 + - taplo@0.10.0 + - ruff@0.12.10 - isort@6.0.1 - markdownlint@0.45.0 - oxipng@9.1.5 @@ -34,7 +34,7 @@ lint: - flake8@7.3.0 - hadolint@2.12.1-beta - shfmt@3.6.0 - - shellcheck@0.10.0 + - shellcheck@0.11.0 - black@25.1.0 - git-diff-check - gitleaks@8.28.0 diff --git a/locale/lv_i18n.c b/locale/lv_i18n.c index 1c79d07..4f4d343 100644 --- a/locale/lv_i18n.c +++ b/locale/lv_i18n.c @@ -37,8 +37,13 @@ static inline uint32_t op_t(uint32_t val) UNUSED(val); return 0; } +static inline uint32_t op_e(uint32_t val) +{ + UNUSED(val); + return 0; +} -static lv_i18n_phrase_t en_singulars[] = { +static const lv_i18n_phrase_t en_singulars[] = { {"No map tiles found on SDCard!", "Map tiles not found!"}, {NULL, NULL} // End mark }; @@ -61,7 +66,7 @@ static const lv_i18n_lang_t en_lang = {.locale_name = "en", .locale_plural_fn = en_plural_fn}; -static lv_i18n_phrase_t de_singulars[] = { +static const lv_i18n_phrase_t de_singulars[] = { {"User name: %s", "Benutzer: %s"}, {"Device Role: %s", "Gerätemodus: %s"}, {"no new messages", "keine Nachrichten"}, @@ -184,11 +189,11 @@ static lv_i18n_phrase_t de_singulars[] = { {NULL, NULL} // End mark }; -static lv_i18n_phrase_t de_plurals_one[] = { +static const lv_i18n_phrase_t de_plurals_one[] = { {"%d active chat(s)", "%d aktives Gespräch"}, {"%d of %d nodes online", "1 Gerät online"}, {NULL, NULL} // End mark }; -static lv_i18n_phrase_t de_plurals_other[] = { +static const lv_i18n_phrase_t de_plurals_other[] = { {"%d active chat(s)", "%d aktive Gespräche"}, {"%d of %d nodes online", "%d / %d Geräte online"}, {NULL, NULL} // End mark }; @@ -212,7 +217,7 @@ static const lv_i18n_lang_t de_lang = {.locale_name = "de", .plurals[LV_I18N_PLURAL_TYPE_OTHER] = de_plurals_other, .locale_plural_fn = de_plural_fn}; -static lv_i18n_phrase_t el_singulars[] = { +static const lv_i18n_phrase_t el_singulars[] = { {"no new messages", "κανένα νέο μήνυμα"}, {"1 of 1 nodes online", "1 Κόμβος online"}, {"uptime 00:00:00", "Χρόν.λειτ. 00:00:00"}, @@ -350,11 +355,11 @@ static lv_i18n_phrase_t el_singulars[] = { {NULL, NULL} // End mark }; -static lv_i18n_phrase_t el_plurals_one[] = { +static const lv_i18n_phrase_t el_plurals_one[] = { {"%d active chat(s)", "%d ενεργ. συνομιλία"}, {"%d of %d nodes online", "1 Κόμβος online"}, {NULL, NULL} // End mark }; -static lv_i18n_phrase_t el_plurals_other[] = { +static const lv_i18n_phrase_t el_plurals_other[] = { {"%d active chat(s)", "%d ενεργ. συνομιλίες"}, {"%d of %d nodes online", "%d / %d Κόμβοι online"}, {NULL, NULL} // End mark }; @@ -374,7 +379,7 @@ static const lv_i18n_lang_t el_lang = {.locale_name = "el", .plurals[LV_I18N_PLURAL_TYPE_OTHER] = el_plurals_other, .locale_plural_fn = el_plural_fn}; -static lv_i18n_phrase_t es_singulars[] = { +static const lv_i18n_phrase_t es_singulars[] = { {"no new messages", "Sin mensajes nuevos"}, {"1 of 1 nodes online", "1 de 1 nodos activos"}, {"DEL", "BOR"}, @@ -514,11 +519,11 @@ static lv_i18n_phrase_t es_singulars[] = { {NULL, NULL} // End mark }; -static lv_i18n_phrase_t es_plurals_one[] = { +static const lv_i18n_phrase_t es_plurals_one[] = { {"%d active chat(s)", "1 chat activo"}, {"%d of %d nodes online", "1 nodo activo"}, {NULL, NULL} // End mark }; -static lv_i18n_phrase_t es_plurals_other[] = { +static const lv_i18n_phrase_t es_plurals_other[] = { {"%d active chat(s)", "%d chat activos"}, {"%d of %d nodes online", "%d de %d nodos activos"}, {NULL, NULL} // End mark }; @@ -526,9 +531,17 @@ static uint8_t es_plural_fn(int32_t num) { uint32_t n = op_n(num); UNUSED(n); - + uint32_t e = op_e(n); + UNUSED(e); + uint32_t i = op_i(n); + UNUSED(i); + uint32_t v = op_v(n); + UNUSED(v); + uint32_t i1000000 = i % 1000000; if ((n == 1)) return LV_I18N_PLURAL_TYPE_ONE; + if ((e == 0 && i != 0 && i1000000 == 0 && v == 0) || ((!(0 <= e && e <= 5)))) + return LV_I18N_PLURAL_TYPE_MANY; return LV_I18N_PLURAL_TYPE_OTHER; } @@ -538,7 +551,7 @@ static const lv_i18n_lang_t es_lang = {.locale_name = "es", .plurals[LV_I18N_PLURAL_TYPE_OTHER] = es_plurals_other, .locale_plural_fn = es_plural_fn}; -static lv_i18n_phrase_t fi_singulars[] = { +static const lv_i18n_phrase_t fi_singulars[] = { {"no new messages", "ei uusia viestejä"}, {"1 of 1 nodes online", "1/1 nodea verkossa"}, {"uptime 00:00:00", "käyttöaika 00:00:00"}, @@ -669,7 +682,7 @@ static const lv_i18n_lang_t fi_lang = {.locale_name = "fi", .locale_plural_fn = fi_plural_fn}; -static lv_i18n_phrase_t fr_singulars[] = { +static const lv_i18n_phrase_t fr_singulars[] = { {"no new messages", "0 nouveau message"}, {"1 of 1 nodes online", "1 sur 1 noeud actif"}, {"uptime 00:00:00", "Activité: 00:00:00"}, @@ -808,11 +821,11 @@ static lv_i18n_phrase_t fr_singulars[] = { {NULL, NULL} // End mark }; -static lv_i18n_phrase_t fr_plurals_one[] = { +static const lv_i18n_phrase_t fr_plurals_one[] = { {"%d active chat(s)", "%d chat actif"}, {"%d of %d nodes online", "%d sur %d noeud actif"}, {NULL, NULL} // End mark }; -static lv_i18n_phrase_t fr_plurals_other[] = { +static const lv_i18n_phrase_t fr_plurals_other[] = { {"%d active chat(s)", "%d chats actifs"}, {"%d of %d nodes online", "%d sur %d noeuds actifs"}, {NULL, NULL} // End mark }; @@ -822,9 +835,15 @@ static uint8_t fr_plural_fn(int32_t num) UNUSED(n); uint32_t i = op_i(n); UNUSED(i); - + uint32_t e = op_e(n); + UNUSED(e); + uint32_t v = op_v(n); + UNUSED(v); + uint32_t i1000000 = i % 1000000; if ((((i == 0) || (i == 1)))) return LV_I18N_PLURAL_TYPE_ONE; + if ((e == 0 && i != 0 && i1000000 == 0 && v == 0) || ((!(0 <= e && e <= 5)))) + return LV_I18N_PLURAL_TYPE_MANY; return LV_I18N_PLURAL_TYPE_OTHER; } @@ -834,7 +853,7 @@ static const lv_i18n_lang_t fr_lang = {.locale_name = "fr", .plurals[LV_I18N_PLURAL_TYPE_OTHER] = fr_plurals_other, .locale_plural_fn = fr_plural_fn}; -static lv_i18n_phrase_t it_singulars[] = { +static const lv_i18n_phrase_t it_singulars[] = { {"no new messages", "nessun messaggio"}, {"1 of 1 nodes online", "1 di 1 nodi online"}, {"uptime 00:00:00", "tempo di attività 00:00:00"}, @@ -969,11 +988,11 @@ static lv_i18n_phrase_t it_singulars[] = { {NULL, NULL} // End mark }; -static lv_i18n_phrase_t it_plurals_one[] = { +static const lv_i18n_phrase_t it_plurals_one[] = { {"%d active chat(s)", "%d chat attiva"}, {"%d of %d nodes online", "1 nodo online"}, {NULL, NULL} // End mark }; -static lv_i18n_phrase_t it_plurals_other[] = { +static const lv_i18n_phrase_t it_plurals_other[] = { {"%d active chat(s)", "%d chat attive"}, {"%d of %d nodes online", "%d di %d nodi online"}, {NULL, NULL} // End mark }; @@ -985,9 +1004,13 @@ static uint8_t it_plural_fn(int32_t num) UNUSED(i); uint32_t v = op_v(n); UNUSED(v); - + uint32_t e = op_e(n); + UNUSED(e); + uint32_t i1000000 = i % 1000000; if ((i == 1 && v == 0)) return LV_I18N_PLURAL_TYPE_ONE; + if ((e == 0 && i != 0 && i1000000 == 0 && v == 0) || ((!(0 <= e && e <= 5)))) + return LV_I18N_PLURAL_TYPE_MANY; return LV_I18N_PLURAL_TYPE_OTHER; } @@ -997,7 +1020,7 @@ static const lv_i18n_lang_t it_lang = {.locale_name = "it", .plurals[LV_I18N_PLURAL_TYPE_OTHER] = it_plurals_other, .locale_plural_fn = it_plural_fn}; -static lv_i18n_phrase_t nl_singulars[] = { +static const lv_i18n_phrase_t nl_singulars[] = { {"no new messages", "0 nieuwe berichten"}, {"1 of 1 nodes online", "1 van 1 nodes online"}, {"uptime 00:00:00", "uptime 00:00:00"}, @@ -1155,11 +1178,11 @@ static lv_i18n_phrase_t nl_singulars[] = { {NULL, NULL} // End mark }; -static lv_i18n_phrase_t nl_plurals_one[] = { +static const lv_i18n_phrase_t nl_plurals_one[] = { {"%d active chat(s)", "%d actieve chats"}, {"%d of %d nodes online", "1 node online"}, {NULL, NULL} // End mark }; -static lv_i18n_phrase_t nl_plurals_other[] = { +static const lv_i18n_phrase_t nl_plurals_other[] = { {"%d active chat(s)", "%d actieve chats"}, {"%d of %d nodes online", "%d van %d nodes online"}, {NULL, NULL} // End mark }; @@ -1183,7 +1206,7 @@ static const lv_i18n_lang_t nl_lang = {.locale_name = "nl", .plurals[LV_I18N_PLURAL_TYPE_OTHER] = nl_plurals_other, .locale_plural_fn = nl_plural_fn}; -static lv_i18n_phrase_t no_singulars[] = { +static const lv_i18n_phrase_t no_singulars[] = { {"no new messages", "Ingen nye meldinger"}, {"1 of 1 nodes online", "1 av 1 noder online"}, {"uptime 00:00:00", "oppetid 00:00:00"}, @@ -1344,11 +1367,11 @@ static lv_i18n_phrase_t no_singulars[] = { {NULL, NULL} // End mark }; -static lv_i18n_phrase_t no_plurals_one[] = { +static const lv_i18n_phrase_t no_plurals_one[] = { {"%d active chat(s)", "1 aktiv chat"}, {"%d of %d nodes online", "1 node online"}, {NULL, NULL} // End mark }; -static lv_i18n_phrase_t no_plurals_other[] = { +static const lv_i18n_phrase_t no_plurals_other[] = { {"%d active chat(s)", "%d aktive chat"}, {"%d of %d nodes online", "%d av %d noder online"}, {NULL, NULL} // End mark }; @@ -1368,7 +1391,7 @@ static const lv_i18n_lang_t no_lang = {.locale_name = "no", .plurals[LV_I18N_PLURAL_TYPE_OTHER] = no_plurals_other, .locale_plural_fn = no_plural_fn}; -static lv_i18n_phrase_t pl_singulars[] = { +static const lv_i18n_phrase_t pl_singulars[] = { {"no new messages", "Brak wiadomości"}, {"1 of 1 nodes online", "1 z 1 węzłów online"}, {"User name: ", "Nazwa"}, @@ -1498,7 +1521,7 @@ static const lv_i18n_lang_t pl_lang = {.locale_name = "pl", .locale_plural_fn = pl_plural_fn}; -static lv_i18n_phrase_t pt_singulars[] = { +static const lv_i18n_phrase_t pt_singulars[] = { {"no new messages", "Nenhuma mensagem"}, {"1 of 1 nodes online", "1 dispositivo online"}, {"uptime 00:00:00", "Tempo ligado\n00:00:00"}, @@ -1624,11 +1647,11 @@ static lv_i18n_phrase_t pt_singulars[] = { {NULL, NULL} // End mark }; -static lv_i18n_phrase_t pt_plurals_one[] = { +static const lv_i18n_phrase_t pt_plurals_one[] = { {"%d of %d nodes online", "1 dispositivo online"}, {NULL, NULL} // End mark }; -static lv_i18n_phrase_t pt_plurals_other[] = { +static const lv_i18n_phrase_t pt_plurals_other[] = { {"%d of %d nodes online", "%d/%d dispositivos online"}, {NULL, NULL} // End mark }; @@ -1638,9 +1661,15 @@ static uint8_t pt_plural_fn(int32_t num) UNUSED(n); uint32_t i = op_i(n); UNUSED(i); - + uint32_t e = op_e(n); + UNUSED(e); + uint32_t v = op_v(n); + UNUSED(v); + uint32_t i1000000 = i % 1000000; if (((0 <= i && i <= 1))) return LV_I18N_PLURAL_TYPE_ONE; + if ((e == 0 && i != 0 && i1000000 == 0 && v == 0) || ((!(0 <= e && e <= 5)))) + return LV_I18N_PLURAL_TYPE_MANY; return LV_I18N_PLURAL_TYPE_OTHER; } @@ -1670,7 +1699,7 @@ static const lv_i18n_lang_t ro_lang = {.locale_name = "ro", .locale_plural_fn = ro_plural_fn}; -static lv_i18n_phrase_t ru_singulars[] = { +static const lv_i18n_phrase_t ru_singulars[] = { {"no new messages", "нет новых сообщений"}, {"1 of 1 nodes online", "1 из 1 узлов онлайн"}, {"DEL", "DEL"}, @@ -1817,7 +1846,7 @@ static const lv_i18n_lang_t ru_lang = {.locale_name = "ru", .locale_plural_fn = ru_plural_fn}; -static lv_i18n_phrase_t se_singulars[] = { +static const lv_i18n_phrase_t se_singulars[] = { {"no new messages", "inga nya meddelanden"}, {"1 of 1 nodes online", "1 av 1 noder online"}, {"uptime 00:00:00", "upptid 00:00:00"}, @@ -1966,11 +1995,11 @@ static lv_i18n_phrase_t se_singulars[] = { {NULL, NULL} // End mark }; -static lv_i18n_phrase_t se_plurals_one[] = { +static const lv_i18n_phrase_t se_plurals_one[] = { {"%d active chat(s)", "1 aktiv chatt"}, {"%d of %d nodes online", "1 nod online"}, {NULL, NULL} // End mark }; -static lv_i18n_phrase_t se_plurals_other[] = { +static const lv_i18n_phrase_t se_plurals_other[] = { {"%d active chat(s)", "%d aktiva chattar"}, {"%d of %d nodes online", "%d av %d noder online"}, {NULL, NULL} // End mark }; @@ -1992,7 +2021,7 @@ static const lv_i18n_lang_t se_lang = {.locale_name = "se", .plurals[LV_I18N_PLURAL_TYPE_OTHER] = se_plurals_other, .locale_plural_fn = se_plural_fn}; -static lv_i18n_phrase_t sl_singulars[] = { +static const lv_i18n_phrase_t sl_singulars[] = { {"User name: %s", "Uporabniško ime: %s"}, {"Device Role: %s", "Vloga: %s"}, {"no new messages", "ni novih sporočil"}, @@ -2133,11 +2162,11 @@ static lv_i18n_phrase_t sl_singulars[] = { {NULL, NULL} // End mark }; -static lv_i18n_phrase_t sl_plurals_one[] = { +static const lv_i18n_phrase_t sl_plurals_one[] = { {"%d of %d nodes online", "1 vozlišč povezano"}, {NULL, NULL} // End mark }; -static lv_i18n_phrase_t sl_plurals_other[] = { +static const lv_i18n_phrase_t sl_plurals_other[] = { {"%d of %d nodes online", "%d / %d vozl. povezanih"}, {NULL, NULL} // End mark }; @@ -2165,7 +2194,7 @@ static const lv_i18n_lang_t sl_lang = {.locale_name = "sl", .plurals[LV_I18N_PLURAL_TYPE_OTHER] = sl_plurals_other, .locale_plural_fn = sl_plural_fn}; -static lv_i18n_phrase_t sr_singulars[] = { +static const lv_i18n_phrase_t sr_singulars[] = { {"no new messages", "nema novih poruka"}, {"1 of 1 nodes online", "1 od 1 nodova online"}, {"uptime 00:00:00", "uključen pre 00:00:00"}, @@ -2320,7 +2349,7 @@ static const lv_i18n_lang_t sr_lang = {.locale_name = "sr", .locale_plural_fn = sr_plural_fn}; -static lv_i18n_phrase_t tr_singulars[] = { +static const lv_i18n_phrase_t tr_singulars[] = { {"no new messages", "Yeni mesaj yok"}, {"1 of 1 nodes online", "1/1 düğüm aktif"}, {"uptime 00:00:00", "Çalışma süresi %s"}, @@ -2451,11 +2480,11 @@ static lv_i18n_phrase_t tr_singulars[] = { {NULL, NULL} // End mark }; -static lv_i18n_phrase_t tr_plurals_one[] = { +static const lv_i18n_phrase_t tr_plurals_one[] = { {"%d of %d nodes online", "1 düğüm çevrimiçi"}, {NULL, NULL} // End mark }; -static lv_i18n_phrase_t tr_plurals_other[] = { +static const lv_i18n_phrase_t tr_plurals_other[] = { {"%d of %d nodes online", "%d / %d düğümler çevrimiçi"}, {NULL, NULL} // End mark }; @@ -2475,9 +2504,9 @@ static const lv_i18n_lang_t tr_lang = {.locale_name = "tr", .plurals[LV_I18N_PLURAL_TYPE_OTHER] = tr_plurals_other, .locale_plural_fn = tr_plural_fn}; -static lv_i18n_phrase_t uk_singulars[] = { +static const lv_i18n_phrase_t uk_singulars[] = { {"no new messages", "немає повідомлень"}, - {"1 of 1 nodes online", "1 нода онлайн"}, + {"1 of 1 nodes online", "1 вузол онлайн"}, {"uptime 00:00:00", "час роботи 00:00:00"}, {"no signal", "немає сигналу"}, {"silent", "тихий"}, @@ -2489,7 +2518,7 @@ static lv_i18n_phrase_t uk_singulars[] = { {"Channel: LongFast", "Канал: LongFast"}, {"Role: Client", "Роль: Client"}, {"WiFi: ", "WiFi: <не задано>"}, - {"Screen Timeout: 60s", "Таймаут Екрана: 60s"}, + {"Screen Timeout: 60s", "Таймаут Екрана: 60с"}, {"Lock: off/off", "Блокування: вимкн./вимкн."}, {"Screen Brightness: 60%", "Яскравість Екрана: 60%"}, {"Theme: Dark", "Тема: Темна"}, @@ -2514,8 +2543,8 @@ static lv_i18n_phrase_t uk_singulars[] = { {"Locations Map", "Мапа"}, {"no chats", "немає чатів"}, {"Node Search", "Пошук Нод"}, - {"Packet Statistics", "Статистика пакетів"}, - {"Node Options", "Параметри Ноди"}, + {"Packet Statistics", "Статистика Пакетів"}, + {"Node Options", "Параметри Вузла"}, {"LoRa TX off!", "LoRa TX вимкн.!"}, {"Short Name", "Коротке Ім'я"}, {"Long Name", "Довге Ім'я"}, @@ -2524,7 +2553,7 @@ static lv_i18n_phrase_t uk_singulars[] = { {"Secondary Channels", "Вторинні Канали"}, {"Brightness: 60%", "Яскравість: 60%"}, {"Dark\nLight", "Темна\nСвітла"}, - {"Timeout: 60s", "Таймаут: 60s"}, + {"Timeout: 60s", "Таймаут: 60с"}, {"Screen Lock", "Блокування Екрану"}, {"Settings Lock", "Блокування Налаштувань"}, {"Lock PIN", "PIN-код Блокування"}, @@ -2539,10 +2568,10 @@ static lv_i18n_phrase_t uk_singulars[] = { {"Backup", "Збереження"}, {"Restore", "Відновлення"}, {"Public/Private Key", "Публічний/Приватний Ключ"}, - {"NodeDB Reset\nFactory Reset\nClear Chat History", "Скидання NodeDB\nСкидання налаштувань\nОчистити історію чатів"}, - {"Channel Name", "Ім'я каналу"}, - {"Pre-shared Key", "PSK ключ"}, - {"Filter", "Фільтр"}, + {"NodeDB Reset\nFactory Reset\nClear Chat History", "Скидання NodeDB\nСкидання Налаштувань\nОчистити Історію Чатів"}, + {"Channel Name", "Ім'я Каналу"}, + {"Pre-shared Key", "PSK Ключ"}, + {"Filter", "Фільтрувати"}, {"Unknown", "Невідомо"}, {"Offline", "Не в мережі"}, {"Public Key", "Публічний Ключ"}, @@ -2550,12 +2579,12 @@ static lv_i18n_phrase_t uk_singulars[] = { {"Hops away", "Стрибки"}, {"Position", "Позиція"}, {"Name", "Ім'я"}, - {"Highlight", "Позначка"}, + {"Highlight", "Підсвічувати"}, {"Active Chat", "Активний Чат"}, {"Telemetry", "Телеметрія"}, {"Start", "Старт"}, - {"choose\nnode", "оберіть\nноду"}, - {"choose target node", "оберіть цільову ноду"}, + {"choose\nnode", "оберіть\nвузол"}, + {"choose target node", "оберіть цільовий вузол"}, {"New Message from\n", "Нове Повідомлення від\n"}, {"Restoring messages ...", "Відновлення повідомлень ..."}, {"Please set region and name", "Будь ласка, вкажіть регіон та ім'я"}, @@ -2577,7 +2606,7 @@ static lv_i18n_phrase_t uk_singulars[] = { {"FrequencySlot: %d (%g MHz)", "Частотний слот: %d (%g MHz)"}, {"Brightness: %d%%", "Яскравість: %d%%"}, {"Timeout: off", "Таймаут: вимкн."}, - {"Timeout: %ds", "Таймаут: %ds"}, + {"Timeout: %ds", "Таймаут: %dс"}, {"No map tiles found on SDCard!", "Мапи не знайдено!"}, {"Locations Map (%d/%d)", "Мапа (%d/%d)"}, {"Stop", "Стоп"}, @@ -2585,7 +2614,7 @@ static lv_i18n_phrase_t uk_singulars[] = { {"Packet Log: %d", "Журнал Пакетів: %d"}, {"Language: %s", "Мова: %s"}, {"Screen Timeout: off", "Таймаут Екрана: вимкн."}, - {"Screen Timeout: %ds", "Таймаут Екрана: %ds"}, + {"Screen Timeout: %ds", "Таймаут Екрана: %dс"}, {"Screen Brightness: %d%%", "Яскравість Екрана: %d%%"}, {"Theme: %s", "Тема: %s"}, {"Region: %s", "Регіон: %s"}, @@ -2608,7 +2637,7 @@ static lv_i18n_phrase_t uk_singulars[] = { {"Failed to retrieve keys!", "Не вдалося отримати ключі!"}, {"New message from \n%s", "Нове повідомлення від \n%s"}, {"Input Control: %s/%s", "Контроль Вводу: %s/%s"}, - {"Filter: %d of %d nodes", "Фільтр: %d з %d нод"}, + {"Filter: %d of %d nodes", "Фільтр: %d з %d вузлів"}, {"%d new message", "%d нове повідомлення"}, {"%d new messages", "%d нові повідомлення"}, {"uptime: %02d:%02d:%02d", "час роботи: %02d:%02d:%02d"}, @@ -2616,12 +2645,12 @@ static lv_i18n_phrase_t uk_singulars[] = { {NULL, NULL} // End mark }; -static lv_i18n_phrase_t uk_plurals_one[] = { - {"%d active chat(s)", "%d активний чат"}, {"%d of %d nodes online", "1 нода онлайн"}, {NULL, NULL} // End mark +static const lv_i18n_phrase_t uk_plurals_one[] = { + {"%d active chat(s)", "%d активний чат"}, {"%d of %d nodes online", "1 вузол онлайн"}, {NULL, NULL} // End mark }; -static lv_i18n_phrase_t uk_plurals_other[] = { - {"%d active chat(s)", "%d активні чати"}, {"%d of %d nodes online", "%d з %d нод онлайн"}, {NULL, NULL} // End mark +static const lv_i18n_phrase_t uk_plurals_other[] = { + {"%d active chat(s)", "%d активні чати"}, {"%d of %d nodes online", "%d з %d вузлів онлайн"}, {NULL, NULL} // End mark }; static uint8_t uk_plural_fn(int32_t num) @@ -2632,9 +2661,14 @@ static uint8_t uk_plural_fn(int32_t num) UNUSED(v); uint32_t i = op_i(n); UNUSED(i); - - if ((i == 1 && v == 0)) + uint32_t i10 = i % 10; + uint32_t i100 = i % 100; + if ((v == 0 && i10 == 1 && i100 != 11)) return LV_I18N_PLURAL_TYPE_ONE; + if ((v == 0 && (2 <= i10 && i10 <= 4) && (!(12 <= i100 && i100 <= 14)))) + return LV_I18N_PLURAL_TYPE_FEW; + if ((v == 0 && i10 == 0) || (v == 0 && (5 <= i10 && i10 <= 9)) || (v == 0 && (11 <= i100 && i100 <= 14))) + return LV_I18N_PLURAL_TYPE_MANY; return LV_I18N_PLURAL_TYPE_OTHER; } @@ -2644,7 +2678,7 @@ static const lv_i18n_lang_t uk_lang = {.locale_name = "uk", .plurals[LV_I18N_PLURAL_TYPE_OTHER] = uk_plurals_other, .locale_plural_fn = uk_plural_fn}; -static lv_i18n_phrase_t zh_cn_singulars[] = { +static const lv_i18n_phrase_t zh_cn_singulars[] = { {"no new messages", "暂无新消息"}, {"1 of 1 nodes online", "1/1 个节点在线"}, {"DEL", "删除"}, @@ -2829,6 +2863,14 @@ int lv_i18n_init(const lv_i18n_language_pack_t *langs) return 0; } +/** + * Sugar for simplified `lv_i18n_init` call + */ +int lv_i18n_init_default(void) +{ + return lv_i18n_init(lv_i18n_language_pack); +} + /** * Change the localization (language) * @param l_name name of the translation locale to use. E.g. "en-GB" @@ -2851,12 +2893,12 @@ int lv_i18n_set_locale(const char *l_name) return -1; } -static const char *__lv_i18n_get_text_core(lv_i18n_phrase_t *trans, const char *msg_id) +static const char *__lv_i18n_get_text_core(const lv_i18n_phrase_t *trans, const char *msg_id) { uint16_t i; for (i = 0; trans[i].msg_id != NULL; i++) { if (strcmp(trans[i].msg_id, msg_id) == 0) { - /*The msg_id has found. Check the translation*/ + /*The msg_id has been found. Check the translation*/ if (trans[i].translation) return trans[i].translation; } diff --git a/locale/lv_i18n.h b/locale/lv_i18n.h index 8a4af09..cd72c95 100644 --- a/locale/lv_i18n.h +++ b/locale/lv_i18n.h @@ -25,8 +25,8 @@ typedef struct { typedef struct { const char *locale_name; - lv_i18n_phrase_t *singulars; - lv_i18n_phrase_t *plurals[_LV_I18N_PLURAL_TYPE_NUM]; + const lv_i18n_phrase_t *singulars; + const lv_i18n_phrase_t *plurals[_LV_I18N_PLURAL_TYPE_NUM]; uint8_t (*locale_plural_fn)(int32_t num); } lv_i18n_lang_t; @@ -41,6 +41,11 @@ extern const lv_i18n_language_pack_t lv_i18n_language_pack[]; */ int lv_i18n_init(const lv_i18n_language_pack_t *langs); +/** + * Sugar for simplified `lv_i18n_init` call + */ +int lv_i18n_init_default(void); + /** * Change the localization (language) * @param l_name name of the translation locale to use. E.g. "en_GB" diff --git a/locale/uk.yml b/locale/uk.yml index d509318..34f71b4 100644 --- a/locale/uk.yml +++ b/locale/uk.yml @@ -1,6 +1,6 @@ uk: no new messages: немає повідомлень - 1 of 1 nodes online: 1 нода онлайн + 1 of 1 nodes online: 1 вузол онлайн uptime 00:00:00: час роботи 00:00:00 LoRa 0.0 MHz: ~ no signal: немає сигналу @@ -11,18 +11,18 @@ uk: map tiles not found!: мапи не знайдено! Settings: Налаштування "User name: ": "Ім'я користувача: " - "Modem Preset: LONG FAST": "Режим Модему: LONG FAST" - "Channel: LongFast": "Канал: LongFast" - "Role: Client": "Роль: Client" - "WiFi: ": "WiFi: <не задано>" - "Screen Timeout: 60s": "Таймаут Екрана: 60s" - "Lock: off/off": "Блокування: вимкн./вимкн." - "Screen Brightness: 60%": "Яскравість Екрана: 60%" - "Theme: Dark": "Тема: Темна" - "Screen Calibration: default": "Калібрування Екрана: за умовчанням" - "Input Control: none/none": "Контроль Вводу: немає/немає" - "Message Alert Buzzer: on": "Сповіщення: увімк." - "Language: English": "Мова: Українська" + 'Modem Preset: LONG FAST': 'Режим Модему: LONG FAST' + 'Channel: LongFast': 'Канал: LongFast' + 'Role: Client': 'Роль: Client' + 'WiFi: ': 'WiFi: <не задано>' + 'Screen Timeout: 60s': 'Таймаут Екрана: 60с' + 'Lock: off/off': 'Блокування: вимкн./вимкн.' + 'Screen Brightness: 60%': 'Яскравість Екрана: 60%' + 'Theme: Dark': 'Тема: Темна' + 'Screen Calibration: default': 'Калібрування Екрана: за умовчанням' + 'Input Control: none/none': 'Контроль Вводу: немає/немає' + 'Message Alert Buzzer: on': 'Сповіщення: увімк.' + 'Language: English': 'Мова: Українська' Configuration Reset: Скидання Налаштувань Backup & Restore: Збереження та Відновлення Reboot / Shutdown: Перезапуск / Вимкнення @@ -41,8 +41,8 @@ uk: Locations Map: Мапа no chats: немає чатів Node Search: Пошук Нод - Packet Statistics: Статистика пакетів - Node Options: Параметри Ноди + Packet Statistics: Статистика Пакетів + Node Options: Параметри Вузла LoRa TX off!: LoRa TX вимкн.! Short Name: Коротке Ім'я Long Name: Довге Ім'я @@ -53,9 +53,9 @@ uk: "Client\nClient Mute\nRouter\nRepeater\nTracker\nSensor\nTAK\nClient Hidden\nLost & Found\nTAK Tracker": ~ WiFi SSID: ~ WiFi pre-shared Key: ~ - "Brightness: 60%": "Яскравість: 60%" + 'Brightness: 60%': 'Яскравість: 60%' "Dark\nLight": "Темна\nСвітла" - "Timeout: 60s": "Таймаут: 60s" + 'Timeout: 60s': 'Таймаут: 60с' Screen Lock: Блокування Екрану Settings Lock: Блокування Налаштувань Lock PIN: PIN-код Блокування @@ -70,10 +70,10 @@ uk: Backup: Збереження Restore: Відновлення Public/Private Key: Публічний/Приватний Ключ - "NodeDB Reset\nFactory Reset\nClear Chat History": "Скидання NodeDB\nСкидання налаштувань\nОчистити історію чатів" - Channel Name: Ім'я каналу - Pre-shared Key: PSK ключ - Filter: Фільтр + "NodeDB Reset\nFactory Reset\nClear Chat History": "Скидання NodeDB\nСкидання Налаштувань\nОчистити Історію Чатів" + Channel Name: Ім'я Каналу + Pre-shared Key: PSK Ключ + Filter: Фільтрувати Unknown: Невідомо Offline: Не в мережі Public Key: Публічний Ключ @@ -82,13 +82,13 @@ uk: MQTT: ~ Position: Позиція Name: Ім'я - Highlight: Позначка + Highlight: Підсвічувати Active Chat: Активний Чат Telemetry: Телеметрія IAQ: ~ Start: Старт - "choose\nnode": "оберіть\nноду" - choose target node: оберіть цільову ноду + "choose\nnode": "оберіть\nвузол" + choose target node: оберіть цільовий вузол "New Message from\n": "Нове Повідомлення від\n" Restoring messages ...: Відновлення повідомлень ... Please set region and name: Будь ласка, вкажіть регіон та ім'я @@ -97,63 +97,63 @@ uk: OK: ~ Cancel: Скасувати now: зараз - "Lock: %s/%s": "Блокування: %s/%s" - "on": увімк. - "off": вимкн. - "Screen Calibration: %s": "Калібрування Екрана: %s" + 'Lock: %s/%s': 'Блокування: %s/%s' + 'on': увімк. + 'off': вимкн. + 'Screen Calibration: %s': 'Калібрування Екрана: %s' done: готово default: за умовчанням "Client\nClient Mute\nTracker\nSensor\nTAK\nClient Hidden\nLost & Found\nTAK Tracker": ~ Rebooting ...: Перезапуск ... - ">> Programming mode <<": ">> Режим програмування <<" + '>> Programming mode <<': '>> Режим програмування <<' Enter Text ...: Введіть Текст ... - "!Enter Filter ...": "!Введіть Фільтр ..." + '!Enter Filter ...': '!Введіть Фільтр ...' Enter Filter ...: Введіть Фільтр ... - "FrequencySlot: %d (%g MHz)": "Частотний слот: %d (%g MHz)" - "Brightness: %d%%": "Яскравість: %d%%" - "Timeout: off": "Таймаут: вимкн." - "Timeout: %ds": "Таймаут: %ds" + 'FrequencySlot: %d (%g MHz)': 'Частотний слот: %d (%g MHz)' + 'Brightness: %d%%': 'Яскравість: %d%%' + 'Timeout: off': 'Таймаут: вимкн.' + 'Timeout: %ds': 'Таймаут: %dс' No map tiles found on SDCard!: Мапи не знайдено! Locations Map (%d/%d): Мапа (%d/%d) Stop: Стоп - "heard: !%08x": "почуто: !%08x" - "Packet Log: %d": "Журнал Пакетів: %d" - "Language: %s": "Мова: %s" - "Screen Timeout: off": "Таймаут Екрана: вимкн." - "Screen Timeout: %ds": "Таймаут Екрана: %ds" - "Screen Brightness: %d%%": "Яскравість Екрана: %d%%" - "Theme: %s": "Тема: %s" - "Region: %s": "Регіон: %s" + 'heard: !%08x': 'почуто: !%08x' + 'Packet Log: %d': 'Журнал Пакетів: %d' + 'Language: %s': 'Мова: %s' + 'Screen Timeout: off': 'Таймаут Екрана: вимкн.' + 'Screen Timeout: %ds': 'Таймаут Екрана: %dс' + 'Screen Brightness: %d%%': 'Яскравість Екрана: %d%%' + 'Theme: %s': 'Тема: %s' + 'Region: %s': 'Регіон: %s' "User name: %s": "Ім'я користувача: %s" - "Device Role: %s": "Роль: %s" - "Modem Preset: %s": "Режим Модему: %s" - "WiFi: %s": ~ + 'Device Role: %s': 'Роль: %s' + 'Modem Preset: %s': 'Режим Модему: %s' + 'WiFi: %s': ~ : <не задано> Util %0.1f%% Air %0.1f%%: ~ - "hops: %d": "стрибки: %d" + 'hops: %d': 'стрибки: %d' unknown: невідомо Shutting down ...: Вимикання ... region unset: регіон не задано Banner & Sound: Банер та Звук Banner only: Тільки банер Sound only: Тільки звук - "Message Alert: %s": "Сповіщення: %s" - "Channel: %s": "Канал: %s" + 'Message Alert: %s': 'Сповіщення: %s' + 'Channel: %s': 'Канал: %s' Failed to write keys!: Не вдалося записати ключі! Failed to restore keys!: Не вдалося відновити ключі! Failed to parse keys!: Не вдалося розібрати ключі! Failed to retrieve keys!: Не вдалося отримати ключі! - "%d active chat(s)": - one: "%d активний чат" - other: "%d активні чати" + '%d active chat(s)': + one: '%d активний чат' + other: '%d активні чати' "New message from \n%s": "Нове повідомлення від \n%s" - "Input Control: %s/%s": "Контроль Вводу: %s/%s" - "%d of %d nodes online": - one: "1 нода онлайн" - other: "%d з %d нод онлайн" - "Filter: %d of %d nodes": "Фільтр: %d з %d нод" - "%d new message": "%d нове повідомлення" - "%d new messages": "%d нові повідомлення" - "uptime: %02d:%02d:%02d": "час роботи: %02d:%02d:%02d" + 'Input Control: %s/%s': 'Контроль Вводу: %s/%s' + '%d of %d nodes online': + one: 1 вузол онлайн + other: '%d з %d вузлів онлайн' + 'Filter: %d of %d nodes': 'Фільтр: %d з %d вузлів' + '%d new message': '%d нове повідомлення' + '%d new messages': '%d нові повідомлення' + 'uptime: %02d:%02d:%02d': 'час роботи: %02d:%02d:%02d' "%s (%0.1f GB)\nUsed: %d MB (%d%%)": "%s (%0.1f GB)\nВикорист.: %d MB (%d%%)" "Heap: %d (%d%%)\nLVGL: %d (%d%%)": ~ diff --git a/source/graphics/TFT/TFTView_320x240.cpp b/source/graphics/TFT/TFTView_320x240.cpp index 1fee328..b8a069e 100644 --- a/source/graphics/TFT/TFTView_320x240.cpp +++ b/source/graphics/TFT/TFTView_320x240.cpp @@ -5819,7 +5819,14 @@ void TFTView_320x240::updateLoRaConfig(const meshtastic_Config_LoRaConfig &cfg) { db.config.lora = cfg; db.config.has_lora = true; - showLoRaFrequency(cfg); + + // This must be run before displaying LoRa frequency as channel of 0 ("calculate from hash") leads to an integer underflow + if (!db.config.lora.channel_num) { + db.config.lora.channel_num = LoRaPresets::getDefaultSlot(db.config.lora.region, THIS->db.config.lora.modem_preset, + THIS->db.channel[0].settings.name); + } + + showLoRaFrequency(db.config.lora); char region[30]; lv_snprintf(region, sizeof(region), _("Region: %s"), LoRaPresets::loRaRegionToString(cfg.region)); @@ -5833,11 +5840,6 @@ void TFTView_320x240::updateLoRaConfig(const meshtastic_Config_LoRaConfig &cfg) uint32_t numChannels = LoRaPresets::getNumChannels(cfg.region, cfg.modem_preset); lv_slider_set_range(objects.frequency_slot_slider, 1, numChannels); - - if (!db.config.lora.channel_num) { - db.config.lora.channel_num = LoRaPresets::getDefaultSlot(db.config.lora.region, THIS->db.config.lora.modem_preset, - THIS->db.channel[0].settings.name); - } lv_slider_set_value(objects.frequency_slot_slider, db.config.lora.channel_num, LV_ANIM_OFF); if (db.config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_UNSET) { @@ -5855,8 +5857,8 @@ void TFTView_320x240::updateLoRaConfig(const meshtastic_Config_LoRaConfig &cfg) void TFTView_320x240::showLoRaFrequency(const meshtastic_Config_LoRaConfig &cfg) { char loraFreq[48]; - float frequency = LoRaPresets::getRadioFreq(cfg.region, cfg.modem_preset, cfg.channel_num) + db.config.lora.frequency_offset; - if (frequency > 1.0 && frequency < 10000.0) { + float frequency = LoRaPresets::getRadioFreq(cfg.region, cfg.modem_preset, cfg.channel_num) + cfg.frequency_offset; + if (cfg.region) { sprintf(loraFreq, "LoRa %g MHz\n[%s kHz]", frequency, LoRaPresets::getBandwidthString(cfg.modem_preset)); } else { strcpy(loraFreq, _("region unset"));