diff --git a/Localizable.xcstrings b/Localizable.xcstrings index 03836b7c..aa5cbd4c 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -6,6 +6,12 @@ }, "\t%@" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -17,11 +23,24 @@ "state" : "translated", "value" : "\t%@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "\t%@" + } } - } + }, + "shouldTranslate" : false }, " %@" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -33,21 +52,41 @@ "state" : "translated", "value" : " %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@" + } } - } + }, + "shouldTranslate" : false }, " %@%%" : { "localizations" : { - "sr" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@%%" + } + }, + "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", "value" : " %@%%" } } - } + }, + "shouldTranslate" : false }, ": %@" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : ": %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -59,11 +98,24 @@ "state" : "translated", "value" : ": %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : ": %@" + } } - } + }, + "shouldTranslate" : false }, ": %d" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : ": %d" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -75,11 +127,24 @@ "state" : "translated", "value" : ": %d" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : ": %d" + } } - } + }, + "shouldTranslate" : false }, "(Re)define PIN_GPS_EN for your board." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "(Ri)definire il PIN_GPS_EN per la propria scheda." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -91,11 +156,23 @@ "state" : "translated", "value" : "为你的电路板重新定义 PIN_GPS_EN" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "重新設定主板腳位 (PIN_GPS_EN)" + } } } }, "%@" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -107,14 +184,27 @@ "state" : "translated", "value" : "%@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@" + } } - } + }, + "shouldTranslate" : false }, "%@ - %@" : { "localizations" : { "en" : { "stringUnit" : { - "state" : "new", + "state" : "translated", + "value" : "%1$@ - %2$@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", "value" : "%1$@ - %2$@" } }, @@ -129,14 +219,27 @@ "state" : "translated", "value" : "%1$@ - %2$@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@ - %2$@" + } } - } + }, + "shouldTranslate" : false }, "%@ - %@ - %@" : { "localizations" : { "en" : { "stringUnit" : { - "state" : "new", + "state" : "translated", + "value" : "%1$@ - %2$@ - %3$@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", "value" : "%1$@ - %2$@ - %3$@" } }, @@ -151,17 +254,30 @@ "state" : "translated", "value" : "%1$@ - %2$@ - %3$@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@ - %2$@ - %3$@" + } } - } + }, + "shouldTranslate" : false }, "%@ - %@ Towards %@ Back" : { "localizations" : { "en" : { "stringUnit" : { - "state" : "new", + "state" : "translated", "value" : "%1$@ - %2$@ Towards %3$@ Back" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@ - %2$@ Verso %3$@ Indietro" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -173,6 +289,12 @@ "state" : "translated", "value" : "%1$@ - %2$@ Towards %3$@ Back" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@ - %2$@ 往 %3$@ 返" + } } } }, @@ -184,6 +306,12 @@ "value" : "%@ - Keine Antwort" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ - Nessuna risposta" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -195,6 +323,12 @@ "state" : "translated", "value" : "%@ - 没有响应" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@ - %2$@ 往 %3$@ 返" + } } } }, @@ -206,6 +340,12 @@ "value" : "%@ - Nicht gesendet" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ - Non inviato" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -217,6 +357,12 @@ "state" : "translated", "value" : "%@ - 未发送" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ - 未送出" + } } } }, @@ -224,7 +370,13 @@ "localizations" : { "en" : { "stringUnit" : { - "state" : "new", + "state" : "translated", + "value" : "%1$@ (%2$@)" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", "value" : "%1$@ (%2$@)" } }, @@ -239,14 +391,27 @@ "state" : "translated", "value" : "%1$@ (%2$@)" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@ (%2$@)" + } } - } + }, + "shouldTranslate" : false }, "%@ %@" : { "localizations" : { "en" : { "stringUnit" : { - "state" : "new", + "state" : "translated", + "value" : "%1$@ %2$@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", "value" : "%1$@ %2$@" } }, @@ -261,14 +426,27 @@ "state" : "translated", "value" : "%1$@ %2$@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@ %2$@" + } } - } + }, + "shouldTranslate" : false }, "%@ %lld" : { "localizations" : { "en" : { "stringUnit" : { - "state" : "new", + "state" : "translated", + "value" : "%1$@ %2$lld" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", "value" : "%1$@ %2$lld" } }, @@ -283,8 +461,15 @@ "state" : "translated", "value" : "%1$@ %2$lld" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@ %2$lld" + } } - } + }, + "shouldTranslate" : false }, "%@ away" : { "localizations" : { @@ -294,6 +479,12 @@ "value" : "%@ entfernt" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ via" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -305,11 +496,23 @@ "state" : "translated", "value" : "%@ 离开" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "距離%@" + } } } }, "%@ can be up to %@ bytes long." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ può essere lungo fino a %@ byte." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -321,11 +524,23 @@ "state" : "translated", "value" : "%1$@ 的长度可达 %2$@ 字节" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ 最長可以為 %@ bytes" + } } } }, "%@ Channels?" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ Canali?" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -337,11 +552,23 @@ "state" : "translated", "value" : "%@ 频道?" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ 頻道?" + } } } }, "%@ config data was requested over the admin channel but no response has been returned from the remote node." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "i dati di configurazione %@ sono stati richiesti attraverso il canale di amministrazione, ma non è stata fornita alcuna risposta dal nodo remoto." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -353,11 +580,23 @@ "state" : "translated", "value" : "已通过管理频道请求 %@ 配置数据,但远程节点未返回任何响应。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "透過管理通道請求 %@ 組態資料,但遠端節點未回應。" + } } } }, "%@ dB" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ dB" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -369,11 +608,16 @@ "state" : "translated", "value" : "%@ dB" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ dB" + } } } }, "%@ Please try connecting again and check the PIN carefully." : { - "extractionState" : "migrated", "localizations" : { "de" : { "stringUnit" : { @@ -393,18 +637,18 @@ "value" : "%@ בבקשה נסה שנית להתחבר למכשיר ובדוק את הקוד." } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ Si prega di provare a connettersi nuovamente e di controllare attentamente il PIN." + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "%@ Spróbuj połączyć się ponownie i dokładnie sprawdź PIN." } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "%@ Por favor, tente conectar novamente e verifique cuidadosamente o PIN." - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -432,41 +676,40 @@ } }, "%@ The app will automatically reconnect to the preferred radio if it comes back in range." : { - "extractionState" : "migrated", "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "%@ Die App wird automatisch wieder zum präferierten Gerät verbinden, sobald es in Reichweite kommt." } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "%@ L'application se reconnectera automatiquement à la radio en favori dès qu'elle sera à nouveau disponible." } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "%@ האפליקציה תנסה אוטומטית להתחבר מחדש למכשיר המועדף אם ייראה." } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ L'applicazione si riconnette automaticamente alla radio preferita se torna nel raggio d'azione." + } + }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "%@ Aplikacja automatycznie ponownie połączy się z preferowanym radiem, jeśli wróci w zasięg." } }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "%@ O App vai reconetar automaticamente ao rádio preferido se ele voltar ao alcance." - } - }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "%@ Appen kommer automatiskt att återansluta till den föredragna radion om den kommer inom räckhåll igen." } }, @@ -484,48 +727,47 @@ }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "needs_review", - "value" : "%@ 如果在首選電台的旁邊,App 將會自動重連。" + "state" : "translated", + "value" : "%@ 如果在首選節點的旁邊,App 將會自動重連。" } } } }, - "%@ This error usually cannot be fixed without forgetting the device unders Settings > Bluetooth and re-connecting to the radio." : { - "extractionState" : "migrated", + "%@ This error usually cannot be fixed without forgetting the device under Settings > Bluetooth and re-connecting to the radio." : { "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "%@ Dieser Fehler kann üblicherweise behoben werden, indem man unter Einstellungen > Bluetooth die Verbindung manuell löscht und sich erneut mit dem Gerät verbindet." } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "%@ Cette erreur ne peut généralement pas être corrigée sans aller dans Réglages > Bluetooth et faire > Oublier cet appareil, puis reconnecter la radio." } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "%@ שגיאה זו בדרך כלל אינה ניתנת לתיקון ללא שכחחת המכשיר בהגדרות מכשיר > בלוטוס ואז להתחבר מחדש למכשיר." } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ Questo errore di solito non può essere risolto senza dimenticare il dispositivo sotto Impostazioni > Bluetooth e riconnettersi alla radio." + } + }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "%@ Ten błąd zwykle nie może być naprawiony bez zapomnienia urządzenia w Ustawienia > Bluetooth i ponownego połączenia z radiem." } }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "%@ Esse erro geralmente não pode ser corrigido sem esquecer o dispositivo em Configurações > Bluetooth e reconetar ao rádio." - } - }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "%@ Detta fel kan vanligtvis inte åtgärdas utan att glömma enheten under Inställningar > Bluetooth och återansluta till radion." } }, @@ -543,8 +785,8 @@ }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "needs_review", - "value" : "%@ 這個錯誤通常無法自動修復,你需要在系統設定的藍芽選項中忽略該電台並重新配對。" + "state" : "translated", + "value" : "%@ 這個錯誤通常無法自動修復,您需要在系統設定的藍芽選項中忽略該節點並重新配對。" } } } @@ -553,7 +795,13 @@ "localizations" : { "en" : { "stringUnit" : { - "state" : "new", + "state" : "translated", + "value" : "%1$@, %2$@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", "value" : "%1$@, %2$@" } }, @@ -568,14 +816,27 @@ "state" : "translated", "value" : "%1$@, %2$@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@, %2$@" + } } - } + }, + "shouldTranslate" : false }, "%@: %lld / %lld" : { "localizations" : { "en" : { "stringUnit" : { - "state" : "new", + "state" : "translated", + "value" : "%1$@: %2$lld / %3$lld" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", "value" : "%1$@: %2$lld / %3$lld" } }, @@ -590,11 +851,24 @@ "state" : "translated", "value" : "%1$@: %2$lld / %3$lld" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@: %2$lld / %3$lld" + } } - } + }, + "shouldTranslate" : false }, "%@%%" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@%%" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -606,11 +880,23 @@ "state" : "translated", "value" : "%@%%" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@%%" + } } } }, "%@°F" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@°F" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -622,31 +908,67 @@ "state" : "translated", "value" : "%@°F" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@°F" + } } } }, "%@mA" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@mA" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "%@mA" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@mA" + } } } }, "%@V" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@V" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "%@V" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@V" + } } } }, "%d" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%d" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -658,6 +980,12 @@ "state" : "translated", "value" : "%d" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%d" + } } } }, @@ -674,14 +1002,32 @@ }, "other" : { "stringUnit" : { - "state" : "new", + "state" : "translated", "value" : "%d Hops" } - }, - "zero" : { + } + } + } + }, + "it" : { + "variations" : { + "plural" : { + "many" : { "stringUnit" : { "state" : "translated", - "value" : "Direct" + "value" : "%d Hop" + } + }, + "one" : { + "stringUnit" : { + "state" : "translated", + "value" : "%d Hop" + } + }, + "other" : { + "stringUnit" : { + "state" : "translated", + "value" : "%d Hop" } } } @@ -707,12 +1053,6 @@ "state" : "translated", "value" : "%d скокова" } - }, - "zero" : { - "stringUnit" : { - "state" : "translated", - "value" : "Директно" - } } } } @@ -722,14 +1062,20 @@ "plural" : { "other" : { "stringUnit" : { - "state" : "new", + "state" : "translated", "value" : "%d Hops" } - }, - "zero" : { + } + } + } + }, + "zh-Hant-TW" : { + "variations" : { + "plural" : { + "other" : { "stringUnit" : { "state" : "translated", - "value" : "Direct" + "value" : "%d 跳數" } } } @@ -739,6 +1085,12 @@ }, "%d%%" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%d%%" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -750,11 +1102,23 @@ "state" : "translated", "value" : "%d%%" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%d%%" + } } } }, "%lf" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%lf" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -766,11 +1130,23 @@ "state" : "translated", "value" : "%lf" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%lf" + } } } }, "%lld" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%lld" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -782,6 +1158,12 @@ "state" : "translated", "value" : "%lld" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%lld" + } } } }, @@ -793,36 +1175,78 @@ "value" : "%lld oder weniger Hops entfernt" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%lld o meno hops di distanza" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "%lld или мање скокова" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%lld 個跳數以內" + } } } }, "%lld Readings Total" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%lld Letture Totale" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Укупно %lld читања" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%lld 筆讀數總計" + } } } }, "%lld Total Detection Events" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%lld Totale eventi di rilevamento" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Укупно %lld догађаја детекције" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%lld 次偵測事件總計" + } } } }, "%lld%%" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%lld%%" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -834,6 +1258,12 @@ "state" : "translated", "value" : "%lld%%" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%lld%%" + } } } }, @@ -845,6 +1275,12 @@ "value" : "%llddb Übertragungsleistung" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%llddb Potenza di trasmissione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -856,6 +1292,12 @@ "state" : "translated", "value" : "发射功率 %llddb" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "發射功率 %lld db" + } } } }, @@ -867,16 +1309,34 @@ "value" : "%llddBm Übertragungsleistung" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%llddBm Potenza di trasmissione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "%llddBm снага преноса" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "發射功率 %lld dBm" + } } } }, "< 1%" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "< 1%" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -888,21 +1348,45 @@ "state" : "translated", "value" : "< 1%" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "< 1%" + } } } }, "🦕 End of life Version 🦖 ☄️" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "🦕 Versione di fine vita 🦖 ☄️" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "🦕 Верзија за крај живота 🦖 ☄" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "🦕 該版本已停止支援 🦖 ☄️" + } } } }, "1 byte" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "1 byte" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -914,11 +1398,23 @@ "state" : "translated", "value" : "1 byte" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "1 byte" + } } } }, "1 hop away" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "a 1 salto di distanza" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -930,22 +1426,45 @@ "state" : "translated", "value" : "1 跳" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "距離一個跳數" + } } } }, "2.4 Ghz" : { - "extractionState" : "manual", "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "2.4 Ghz" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "2.4 GHz" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "2.4 Ghz" + } } } }, "7" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "7" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -957,11 +1476,23 @@ "state" : "translated", "value" : "7" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "7" + } } } }, "8" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "8" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -973,11 +1504,23 @@ "state" : "translated", "value" : "8" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "8" + } } } }, "25" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "25" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -989,11 +1532,23 @@ "state" : "translated", "value" : "25" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "25" + } } } }, "50" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "50" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1005,11 +1560,23 @@ "state" : "translated", "value" : "50" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "50" + } } } }, "75" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "75" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1021,11 +1588,23 @@ "state" : "translated", "value" : "75" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "75" + } } } }, "100" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "100" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1037,11 +1616,23 @@ "state" : "translated", "value" : "100" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "100" + } } } }, "128 bit" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "128 bit" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1053,11 +1644,23 @@ "state" : "translated", "value" : "128 bit" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "128 bit" + } } } }, "256 bit" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "256 bit" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1069,36 +1672,136 @@ "state" : "translated", "value" : "256 bit" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "256 bit" + } + } + } + }, + "A Meshtastic QR code contains the LoRa config and channel values needed for radios to communicate. You can share a complete channel configuration using the Replace Channels option, if you choose Add Channels your shared channels will be added to the channels on the receiving radio." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "In a Meshtastic LoRa Mesh there are up to 8 channels. The first one is the Primary channel where most activity happens and is required. If you don't share your primary channel your first shared channel becomes the primary channel on the other network. It talks on its primary and your secondary channel. A channel with the name 'admin' controls nodes remotely. Other channels are for private groups, each with its own key." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Un code QR Meshtastic contient la configuration LoRa et les valeurs de canal nécessaires pour communiquer. La plupart des activités du maillage ont lieu sur le canal principal requis. Si vous ne partagez pas votre canal principal, votre premier canal partagé devient le canal principal de l’autre réseau. Les autres canaux sont pour les groupes privés, chacun avec sa propre clé." + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "במשטסטיק יש עד 8 ערוצים. הראשון הינו הראשי והינו היכן שרוב הפעילות מתבצעת והכרחי. אם לא תשתף את הערוץ הראשי שלך הערוץ הראשון שלך נהיה הערוץ הראשי ברשת השניה. הוא מדבר בערוץ הראשי שלו במשני שלך. ערוץ בעל השם 'admin' הינו לשליטה מרחוק. ערוצים נוספים הינם לקבוצות פרטיות, כל אחת עם מפתח הצפנה משלה." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Un codice QR Meshtastic contiene la configurazione LoRa e i valori dei canali necessari alle radio per comunicare. È possibile condividere una configurazione completa dei canali utilizzando l'opzione Sostituisci canali; se si sceglie Aggiungi canali, i canali condivisi verranno aggiunti ai canali della radio ricevente." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "In a Meshtastic LoRa Mesh there are up to 8 channels. The first one is the Primary channel where most activity happens and is required. If you don't share your primary channel your first shared channel becomes the primary channel on the other network. It talks on its primary and your secondary channel. A channel with the name 'admin' controls nodes remotely. Other channels are for private groups, each with its own key." + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "En Meshtastic QR-kod innehåller LoRa-konfigurationen och kanalvärden som behövs för kommunikation. De flesta aktiviteter i mesh-nätverket sker på den obligatoriska primärkanalen. Om du inte delar din primärkanal blir din första delade kanal primärkanalen på det andra nätverket. Andra kanaler är för privata grupper, varje med sin egen nyckel." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "QR код за Мештастик садржи LoRA конфигурацију и вредности канала које су потребне радијима за комуникацију. Можете поделити потпуну конфигурацију канала користећи опцију „Замени канале“, а ако изаберете „Додај канале“, ваши делени канали ће бити додати каналима на примајућем радију." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "在 Meshtastic 网络中最多有 8 个频道。第一个频道是主频道,大多数活动都发生在这里,也是必需的。如果您不共享主频道,您的第一个共享频道就会成为其他网络的主频道。它会在其主频道和您的辅助频道上对话。名称为 admin 的频道可远程控制节点。其他频道用于私人群组,每个群组都有自己的密钥。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Meshtastic QR Code 包含 LoRa 設定與頻道資訊。選擇「取代頻道」可分享完整設定,「新增頻道」則會將分享的頻道新增到接收設備中。" + } } } }, "A Trace Route was sent, no response has been received." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "È stata inviata una rotta di tracciamento, ma non è stata ricevuta alcuna risposta." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Трејсрут је послат, али одговор није примљен." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "已發送追蹤路由(Trace Route),但未收到任何回應。" + } } } }, "About" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Circa" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "О" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "關於" + } } } }, "About Meshtastic" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Informazioni su Meshtastic" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "О Мештастику" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "關於Meshtastic" + } } } }, @@ -1110,41 +1813,147 @@ "value" : "Genauigkeit %@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Precisione %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Прецизност %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "精確度 %@" + } } } }, "Ack SNR: %@ dB" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "SNR Ack: %@ dB" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Ack SNR: %@ dB" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ack SNR: %@ dB" + } } } }, "Ack Time: %@" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tempo di risposta: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Ack време: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "確認時間: %@" + } + } + } + }, + "Acknowledged" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bestätigt" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Confirmé" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "מאשר" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Riconosciuto" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Potwierdzono" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bekräftad" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Потврђено" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "确认" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "已確認" + } } } }, "Acknowledged by another node" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Riconosciuto da un altro nodo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Потврђен од стране другог чвора" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "已被其他節點確認接收" + } } } }, @@ -1156,11 +1965,23 @@ "value" : "Aktionen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Azioni" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Акције" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "動作" + } } } }, @@ -1172,11 +1993,23 @@ "value" : "Aktiv" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Attivo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Активан" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "在線" + } } } }, @@ -1188,6 +2021,12 @@ "value" : "Aktivität" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Attività" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1199,26 +2038,102 @@ "state" : "translated", "value" : "活动" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "活動" + } + } + } + }, + "ADC Override" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "ADC Override" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "ADC Override" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Override ADC" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "ADC Override" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "ADC-överskrivning" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Преписивање ADC-а" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "ADC校正" + } } } }, "Add Channel" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aggiungi canale" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Додај канал" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "增加頻道" + } } } }, "Add Channels" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aggiungi canali" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Додај канале" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "增加頻道" + } } } }, @@ -1230,16 +2145,34 @@ "value" : "Zu Favoriten hinzufügen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aggiungi ai preferiti" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Додај у омиљене" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "加入最愛" + } } } }, "Additional help" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aiuto supplementare" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1251,11 +2184,23 @@ "state" : "translated", "value" : "其他帮助" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "更多幫助" + } } } }, "Address" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Indirizzo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1267,6 +2212,12 @@ "state" : "translated", "value" : "地址" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "地址" + } } } }, @@ -1278,6 +2229,12 @@ "value" : "Schlüssel für Administrator und Direktnachrichten" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tasti amministratore e messaggi diretti" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1289,11 +2246,23 @@ "state" : "translated", "value" : "管理员 & 私信密钥" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "管理與直接訊息加密金鑰" + } } } }, "Administration" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Amministrazione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1305,11 +2274,26 @@ "state" : "translated", "value" : "管理员" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "遠端管理" + } } } + }, + "Administration Enabled" : { + }, "Advanced" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Avanzato" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1321,11 +2305,23 @@ "state" : "translated", "value" : "高级" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "進階" + } } } }, "Advanced Device GPS" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dispositivo avanzato GPS" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1337,11 +2333,23 @@ "state" : "translated", "value" : "高级设备 GPS" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "進階裝置 GPS" + } } } }, "Advanced GPIO Options" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Opzioni GPIO avanzate" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1353,11 +2361,23 @@ "state" : "translated", "value" : "高级 GPIO 选项" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "進階 GPIO 選項" + } } } }, "Advanced Position Flags" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Flags di posizione avanzati" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1369,65 +2389,131 @@ "state" : "translated", "value" : "高级位置标志" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "進階位置標記" + } } } }, - "ago" : { - "comment" : "Three hours ago = Три сата пре", - "extractionState" : "manual", + "After" : { "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", - "value" : "her" + "state" : "translated", + "value" : "Nach" } }, - "fr" : { + "it" : { "stringUnit" : { - "state" : "needs_review", - "value" : "auparavant" - } - }, - "he" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "עברו" - } - }, - "pl" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "temu" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "há" + "state" : "translated", + "value" : "Dopo" } }, "se" : { "stringUnit" : { - "state" : "needs_review", - "value" : "sedan" + "state" : "translated", + "value" : "Efter" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "пре" + "value" : "Након" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "之後" + } + } + } + }, + "After config values save the node will reboot." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nach dem Ändern der Einstellungen wird das Gerät neu starten." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Une fois la configuration sauvegardée, le noeud redémarrera." + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "לאחר שמירת הגדרות המכשיר יתחיל מחדש." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dopo il salvataggio dei valori di configurazione, il nodo si riavvia." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Po zapisaniu wartości konfiguracji węzeł zostanie zrestartowany." + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Efter att konfigurationsvärdena sparats kommer noden att starta om." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Након што сачувате вредности конфигурације, чвор ће се поново покренути." } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "之前" + "value" : "节点将会在保存配置后重启。" } }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "needs_review", - "value" : "ago" + "state" : "translated", + "value" : "節點將會在設定儲存後重啟。" + } + } + } + }, + "Afternoon" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nachmittag" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pomeriggio" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Пре подне" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "上午" } } } @@ -1436,37 +2522,37 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Airtime" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Temps d'émission" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "זמן אוויר" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ora d'aria" + } + }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Czas nadawania" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Tempo ao Ár" - } - }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Sändningstid" } }, @@ -1484,24 +2570,42 @@ }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "needs_review", - "value" : "廣播時間" + "state" : "translated", + "value" : "空中時間" } } } }, "Alert" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Allarme" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Узбуна" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "發送提醒" + } } } }, "Alert GPIO buzzer when receiving a bell" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Avvisare il buzzer GPIO quando si riceve un campanello" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1513,21 +2617,45 @@ "state" : "translated", "value" : "收到铃声时发出警报 GPIO 蜂鸣器" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "接收鈴鐺通知時觸發 GPIO 蜂鳴器警報" + } } } }, "Alert GPIO buzzer when receiving a message" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Avvisare il cicalino GPIO quando si riceve un messaggio" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Упозорите GPIO зујалицу када примите поруку" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "接收訊息時觸發 GPIO 蜂鳴器警報" + } } } }, "Alert GPIO vibra motor when receiving a bell" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Avviso GPIO del motore a vibrazione quando si riceve una campana" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1539,21 +2667,45 @@ "state" : "translated", "value" : "收到铃声时提醒 GPIO 振动电机" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "接收鈴鐺通知時觸發 GPIO 振動馬達警報" + } } } }, "Alert GPIO vibra motor when receiving a message" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Avviso GPIO del motore vibrante alla ricezione di un messaggio" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Упозорите GPIO вибра мотор када примите поруку" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "接收訊息時觸發 GPIO 振動馬達警報" + } } } }, "Alert when receiving a bell" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Avviso di ricezione di un campanello" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1565,16 +2717,34 @@ "state" : "translated", "value" : "收到铃声时发出警报" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "接收鈴鐺通知時觸發通知" + } } } }, "Alert when receiving a message" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Avviso di ricezione di un messaggio" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Упозори када примиш поруку" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "接收訊息時觸發通知" + } } } }, @@ -1586,6 +2756,12 @@ "value" : "Alle" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tutti" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1597,11 +2773,23 @@ "state" : "translated", "value" : "全部" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "全部" + } } } }, "All device and app data will be deleted." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tutti i dati del dispositivo e delle app verranno eliminati." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1613,6 +2801,12 @@ "state" : "translated", "value" : "所有设备以及 App 数据都会被删除。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "全部的設備及App資料將會被刪除。" + } } } }, @@ -1624,31 +2818,67 @@ "value" : "Erlaubt die eingehende Gerätesteuerung über den unsicheren Legacy-Admin-Kanal." } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Consentire il controllo del dispositivo in entrata attraverso il canale di amministrazione legacy non sicuro." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Дозволите контролу долазног уређаја над небезбедним старим администраторским каналом." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "允許經由不安全的傳統管理通道接收裝置控制指令。" + } } } }, "Allow Position Requests" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Consentire le richieste di posizione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Дозволи захтеве позиција" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "允許請求位置" + } } } }, "Alt" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Alt" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Висина" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "高度" + } } } }, @@ -1660,11 +2890,23 @@ "value" : "Höhe" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Altitudine" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Висина" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "高度" + } } } }, @@ -1676,70 +2918,105 @@ "value" : "Höhe %@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Altitudine %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Висина %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "高度 %@" + } } } }, "Altitude Geoidal Separation" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Altitudine Separazione geoidale" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Висинска геоидна сепарација" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "大地分離高度(Altitude Geoidal Separation)" + } } } }, "Altitude is Mean Sea Level" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "L'altitudine è il livello medio del mare" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Надморска висина је средњи ниво мора" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "高度為平均海平面高度" + } } } }, "Always On" : { - "extractionState" : "migrated", "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Immer an" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "En permanence" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "תמיד דלוק" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sempre acceso" + } + }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Zawsze włączone" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Sempre Ligado" - } - }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Alltid på" } }, @@ -1757,7 +3034,7 @@ }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "常亮" } } @@ -1771,11 +3048,23 @@ "value" : "Immer nach Norden zeigen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Punta sempre verso nord" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Увек усмеравајте на север" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "永遠指北" + } } } }, @@ -1783,37 +3072,31 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Ambient Lighting" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Lumière ambiante" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "תאורת סביבה" } }, - "pl" : { + "it" : { "stringUnit" : { - "state" : "needs_review", - "value" : "Ambient Lighting" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Iluminação Ambiental" + "state" : "translated", + "value" : "Illuminazione ambientale" } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Omgivningsbelysning" } }, @@ -1831,7 +3114,7 @@ }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "環境照明" } } @@ -1841,37 +3124,31 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Ambient Lighting Config" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Configuration de la lumière ambiante" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "הגדרות תאורת סביבה" } }, - "pl" : { + "it" : { "stringUnit" : { - "state" : "needs_review", - "value" : "Ambient Lighting Config" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Configuração Iluminação Ambiental" + "state" : "translated", + "value" : "Configurazione dell'illuminazione ambientale" } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Konfiguration av omgivningsbelysning" } }, @@ -1889,12 +3166,64 @@ }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "環境照明設定" } } } }, + "Ambient Lighting module config received: %@" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configuration du module lumière ambiante reçue : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הגדרות מודולת תאורת סביבה התקבלו: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione del modulo di illuminazione ambientale ricevuta: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ambient Lighting module config received: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Konfiguration för omgivningsbelysningsmodulen mottagen: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Примљена конфигурација модула амбијенталног осветљења: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ambient Lighting module config received: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ambient Lighting module config received: %@" + } + } + } + }, "An open source, off-grid, decentralized, mesh network that runs on affordable, low-power radios." : { "localizations" : { "de" : { @@ -1903,6 +3232,12 @@ "value" : "Ein quelloffenes, netzunabhängiges, dezentrales Mesh-Netzwerk, das auf kostengünstigen, stromsparenden Funkgeräten läuft." } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Una rete mesh open source, off-grid, decentralizzata, che funziona con radio a basso costo e a bassa potenza." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1914,11 +3249,23 @@ "state" : "translated", "value" : "这是一个开源、离网、分布式 Mesh 网络,可在价格低廉的低功率无线电设备上运行。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "一個開源、離線運作、去中心化的網狀網路,運行於平價且低功耗的無線電設備上。" + } } } }, "Any missed messages will be delivered again." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "I messaggi persi saranno consegnati nuovamente." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1930,11 +3277,81 @@ "state" : "translated", "value" : "任何错过的信息都会再次发送。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "任何未送出的訊息都會重新傳送。" + } + } + } + }, + "App connected or stand alone messaging device." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Client (Standard) - Mit App verbundener Client." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Application connectée ou appareil de messagerie autonome." + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "אפליקציה מחוברת או מכשיר תקשורת עצמאי." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dispositivo di messaggistica collegato all'app o indipendente." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Klient (domyślnie) - Klient połączony z aplikacją." + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Appansluten eller fristående meddelandeenhet." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Апликација повезана или самостални уређај за размену порука." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "连接 App 或独立的消息发送设备。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "可連接 App 或作為獨立運作的訊息裝置。" + } } } }, "App Data" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dati dell'applicazione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1946,11 +3363,23 @@ "state" : "translated", "value" : "App 数据" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "App 資料" + } } } }, "App Files" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "File dell'applicazione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1962,11 +3391,23 @@ "state" : "translated", "value" : "App 文件" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "App 檔案" + } } } }, "App Settings" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Impostazioni dell'app" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1978,11 +3419,23 @@ "state" : "translated", "value" : "App 设置" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "App 設定" + } } } }, "Apple Apps" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Applicazioni Apple" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -1994,6 +3447,12 @@ "state" : "translated", "value" : "Apple Apps" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Apple Apps" + } } } }, @@ -2005,16 +3464,34 @@ "value" : "Ungefährer Standort" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Posizione approssimativa" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Приближна локација" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "大略位置" + } } } }, "Are you sure you want to delete this message?" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sei sicuro di voler cancellare questo messaggio?" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -2026,6 +3503,12 @@ "state" : "translated", "value" : "你确定删除这条消息么?" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "您確定要刪除這則訊息嗎?" + } } } }, @@ -2037,6 +3520,12 @@ "value" : "Bist du sicher dass du den Knoten auf die Werkseinstellungen zurücksetzen willst?" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Siete sicuri di voler resettare il nodo?" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -2048,6 +3537,12 @@ "state" : "translated", "value" : "你确定要初始化这个节点么?" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "您確定要將此節點恢復原廠設定嗎?" + } } } }, @@ -2055,37 +3550,37 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Bist Du sicher?" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Êtes-vous sûr ?" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "האם אתה בטוח?" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sei sicuro?" + } + }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Jesteś pewny?" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Tem a certeza?" - } - }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Är du säker?" } }, @@ -2103,25 +3598,42 @@ }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "needs_review", - "value" : "是否確定?" + "state" : "translated", + "value" : "您確定嗎?" } } } }, "Australia / New Zealand" : { - "extractionState" : "manual", "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Australia / Nuova Zelanda" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Аустралија / Нови Зеланд" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "澳洲 / 紐西蘭" + } } } }, "Automatically toggles to the next page on the screen like a carousel, based the specified interval." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Passa automaticamente alla pagina successiva sullo schermo come un carosello, in base all'intervallo specificato." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -2133,11 +3645,23 @@ "state" : "translated", "value" : "根据指定的时间间隔,像旋转木马一样自动切换到屏幕上的下一页。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "依照設定的間隔時間,自動切換至螢幕上的下一頁,類似輪播效果。" + } } } }, "Available modem presets, default is Long Fast." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Preimpostazioni modem disponibili, l'impostazione predefinita è Lungo veloce." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -2149,6 +3673,12 @@ "state" : "translated", "value" : "可用的调制解调器预置,默认为 “Long Fast”。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "可用的數據機預設組態,預設為 Long Fast" + } } } }, @@ -2156,37 +3686,37 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Geräte in der Nähe" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Radios disponibles" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "מכשירים זמינים" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Radio disponibili" + } + }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Dostępne radia" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Rádios Disponíveis" - } - }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Tillgängliga radioapparater" } }, @@ -2204,12 +3734,144 @@ }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "可以連接的設備" } } } }, + "Back" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zurück" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Retour" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "אחרוה" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Indietro" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wstecz" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bakåt" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Назад" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "后退" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "返回" + } + } + } + }, + "Bad" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pessimo" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Лош" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "弱" + } + } + } + }, + "Bad Request" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Requête incorrecte" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "בקשה לא תקינה" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Richiesta negativa" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Złe żądanie" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Felaktig begäran" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Лош захтев" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "错误请求" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "錯誤請求" + } + } + } + }, "Bandwidth" : { "localizations" : { "de" : { @@ -2218,6 +3880,12 @@ "value" : "Bandbreite" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Larghezza di banda" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -2229,11 +3897,23 @@ "state" : "translated", "value" : "带宽" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻寬" + } } } }, "Bar" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bar" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -2245,11 +3925,23 @@ "state" : "translated", "value" : "Bar" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "格" + } } } }, "Bar Series" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Serie Bar" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -2261,11 +3953,23 @@ "state" : "translated", "value" : "Bar Series" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "長條圖系列" + } } } }, "Barometric Pressure" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pressione barometrica" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -2277,6 +3981,64 @@ "state" : "translated", "value" : "气压" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "大氣壓力" + } + } + } + }, + "Battery" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Batterie" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "Battery" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Batteria" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Battery" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Batteri" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Батерија" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "电池" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "電池" + } } } }, @@ -2284,37 +4046,37 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Batterie Ladung" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Niveau de batterie" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "רמת סוללה" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Livello della batteria" + } + }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Poziom naładowania baterii" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Nível de Bataria" - } - }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Batterinivå" } }, @@ -2332,7 +4094,7 @@ }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "電池電量" } } @@ -2340,6 +4102,12 @@ }, "Battery Level %" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Livello della batteria %" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -2351,11 +4119,23 @@ "state" : "translated", "value" : "电池电量 %" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "電池電量 %" + } } } }, "Baud" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Baud" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -2367,6 +4147,108 @@ "state" : "translated", "value" : "波特率" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "鮑率(Baud)" + } + } + } + }, + "biking" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "biken" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "tour in bicicletta" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "тура бициклом" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "自行车旅行" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "自行車" + } + } + } + }, + "Biking" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Biken" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "In bicicletta" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Вожња бицикле" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "自行车" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "自行車" + } + } + } + }, + "BLE" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "BLE" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "BLE" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "БЛЕ" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "BLE" + } } } }, @@ -2374,37 +4256,37 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "BLE Name" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Nom du BLE" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "שם בלוטוס" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nome BLE" + } + }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Nazwa BLE" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Nome BLE" - } - }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "BLE-namn" } }, @@ -2422,7 +4304,7 @@ }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "藍芽名稱" } } @@ -2432,37 +4314,37 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Die Bluetooth Pin muss 6 Stellen lang sein." } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Le code pin BLE doit avoir 6 chiffres." } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "קוד בלוטוס חייבת להיות בת 6 ספרות." } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il pin BLE deve essere composto da 6 cifre." + } + }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Pin BLE musi mieć długość 6 cyfr." } }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "O Pin do BLE deve ter 6 dígitos." - } - }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "BLE-PIN måste vara 6 siffror lång." } }, @@ -2480,7 +4362,7 @@ }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "藍芽 PIN 碼必須是 6 位數字。" } } @@ -2488,6 +4370,12 @@ }, "BLE RSSI: %lld" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "RSSI BLE: %lld" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -2499,11 +4387,23 @@ "state" : "translated", "value" : "BLE RSSI: %lld" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "藍牙訊號強度(RSSI):%lld" + } } } }, "BLE: %@" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "BLE: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -2515,6 +4415,12 @@ "state" : "translated", "value" : "BLE: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "藍牙名稱:%@" + } } } }, @@ -2538,13 +4444,13 @@ "value" : "בלוטוס" } }, - "pl" : { + "it" : { "stringUnit" : { "state" : "translated", "value" : "Bluetooth" } }, - "pt-PT" : { + "pl" : { "stringUnit" : { "state" : "translated", "value" : "Bluetooth" @@ -2580,37 +4486,37 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Bluetooth Konfiguration" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Configuration Bluetooth" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "הגדרות בלוטוס" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione Bluetooth" + } + }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Konfiguracja Bluetooth" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Configuração Bluetooth" - } - }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Bluetooth-konfiguration" } }, @@ -2628,8 +4534,66 @@ }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "needs_review", - "value" : "藍芽設置" + "state" : "translated", + "value" : "藍芽設定" + } + } + } + }, + "Bluetooth config received: %@" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bluetooth Konfiguration empfangen: %@" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configuration Bluetooth reçue : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הגדרות בלוטוס התקבלו: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione Bluetooth ricevuta: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Otrzymano konfigurację Bluetooth: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bluetooth-konfiguration mottagen: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Примљена конфигурација блутута: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bluetooth config received: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bluetooth config received: %@" } } } @@ -2638,37 +4602,37 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Bluetooth ist aus" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Le Bluetooth est arrêté" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "בלוטוס כבוי" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il Bluetooth è spento" + } + }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Bluetooth jest wyłączony" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Bluetooth está desligado" - } - }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Bluetooth är avstängt" } }, @@ -2686,7 +4650,7 @@ }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "藍芽已關閉" } } @@ -2694,6 +4658,12 @@ }, "Broadcast Interval" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Intervallo di trasmissione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -2705,11 +4675,197 @@ "state" : "translated", "value" : "广播间隔" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "廣播間隔" + } + } + } + }, + "Broadcasts GPS position packets as priority." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sendet GPS-Positionspakete mit Priorität." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Transmet les paquets de positions GPS en priorité." + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "משדר מיקום GPS בעדיפות גבוהה." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trasmette i pacchetti di posizione GPS come priorità." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tracker - Do użytku z urządzeniami przeznaczonymi jako śledzenie GPS. Pakiety pozycyjne wysyłane z tego urządzenia będą miały wyższy priorytet, z nadawaniem pozycji co dwie minuty. Inteligentna transmisja pozycji będzie domyślnie wyłączona." + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sänder ut GPS-positionspaket som prioritet." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Емитује пакете са GPS позицијом као приоритет." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "定位模式 - 用于作为 GPS 跟踪器。从该设备发送的定位数据包优先级较高,每两分钟广播一次。智能位置广播默认为关闭。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "優先傳送 GPS 位置封包。" + } + } + } + }, + "Broadcasts location as message to default channel regularly for to assist with device recovery." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sendet den Standort regelmäßig als Nachricht an den Standardkanal, um die Suche nach dem Gerät zu unterstützen." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Transmet régulièrement la position par message dans le canal par défaut pour vous aider à retrouver l'appareil." + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "משדר מיקום כהודעה לערוץ ברירת מחדל לעיתים קבועות בכדי לסייע במציאת המכשיר." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trasmette regolarmente la posizione come messaggio al canale predefinito per assistere il recupero del dispositivo." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Broadcasts location as message to default channel regularly for to assist with device recovery." + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sänder regelbundet ut plats som meddelande till standardkanalen för att underlätta återhämtning av enheten." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Редовно емитује локацију као поруку подразумеваном каналу ради помоћи при проналаску уређаја." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "定期向默认信道发送位置信息,以协助设备恢复。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "裝置會定期把位置廣播到預設頻道,方便找回遺失設備。\n" + } + } + } + }, + "Broadcasts telemetry packets as priority." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sendet Telemetriepakete mit Priorität." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Transmet les paquets de télémétrie en priorité." + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "משדר טלמטריה בעדיפות גבוהה." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trasmette i pacchetti di telemetria come priorità." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Broadcasts telemetry packets as priority." + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sänder ut telemetripaket som prioritet." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Емитује телеметријске пакете као приоритет." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "将遥测数据包优先广播。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "優先廣播遙測指標。" + } } } }, "Button GPIO" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pulsante GPIO" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -2721,11 +4877,23 @@ "state" : "translated", "value" : "按钮 GPIO" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "按鈕 GPIO" + } } } }, "Buy Complete Radios" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Acquistare radio complete" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -2737,11 +4905,23 @@ "state" : "translated", "value" : "购买完整的电台" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "購買完整套件" + } } } }, "Buzzer GPIO" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Buzzer GPIO" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -2753,45 +4933,60 @@ "state" : "translated", "value" : "蜂鸣器 GPIO" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "蜂鳴器 GPIO" + } + } + } + }, + "By enabling this feature, you acknowledge and expressly consent to the transmission of your device’s real-time geographic location over the MQTT protocol without encryption. This location data may be used for purposes such as live map reporting, device tracking, and related telemetry functions." : { + "localizations" : { + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "啟用此功能即表示您已知悉並明確同意,您的裝置即時地理位置將透過 MQTT 協議以未加密的方式傳輸。這些位置資料可能會用於即時地圖報告、裝置追蹤及相關的遙測功能。" + } } } }, "Bytes" : { - "extractionState" : "migrated", "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Bytes" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Octets" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "בייטים" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Byte" + } + }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Bajty" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Bytes" - } - }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Bytes" } }, @@ -2809,7 +5004,7 @@ }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "位元組" } } @@ -2817,6 +5012,12 @@ }, "Call Sign" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Segnale di chiamata" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -2828,11 +5029,23 @@ "state" : "translated", "value" : "呼号" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "呼號" + } } } }, "Call Sign must not be empty" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il nominativo non deve essere vuoto" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -2844,6 +5057,12 @@ "state" : "translated", "value" : "呼号不能为空" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "呼號不能為空" + } } } }, @@ -2851,37 +5070,37 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Abbrechen" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Annuler" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "בטל" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Annullamento" + } + }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Anuluj" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Cancelar" - } - }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Avbryt" } }, @@ -2899,47 +5118,99 @@ }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "取消" } } } }, + "Canned Message module config received: %@" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configuration du module messages préformatés reçue : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הגדרות מודולת תגובות שמורות התקבלו: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione del modulo Canned Message ricevuta: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Otrzymano konfigurację modułu wiadomości gotowych: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Konfiguration för modulen med fördefinierade meddelanden mottagen: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Конфигурација модула за унапред припремљене поруке примљена: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Canned Message module config received: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Canned Message module config received: %@" + } + } + } + }, "Canned Messages" : { "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Canned Messages" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Messages préformatés" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "הודעות קבועות" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Messaggi in scatola" + } + }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Gotowe wiadomości" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Mensagens Enlatados" - } - }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Fördefinierade meddelanden" } }, @@ -2957,7 +5228,7 @@ }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "罐頭訊息" } } @@ -2967,37 +5238,37 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Canned Messages Config" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Configuration des messages préformatés" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "הגדרות הודעות קבועות" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione dei messaggi in scatola" + } + }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Konfiguracja gotowych wiadomości" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Configuração dos Mensagens Enlatados" - } - }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Konfiguration av fördefinierade meddelanden" } }, @@ -3015,214 +5286,83 @@ }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "needs_review", - "value" : "通知設定" + "state" : "translated", + "value" : "罐頭訊息設定" } } } }, - "canned.messages.preset.cardkb" : { - "extractionState" : "migrated", + "Canned Messages Messages Received For: %@" : { "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "M5 Stack Card KB / RAK Tastenfeld" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "M5 Stack Card KB / RAK Keypad" - } - }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Clavier M5 Stack Card KB / RAK" + "value" : "Messages préformatés reçus pour : %@" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "M5 Stack Card KB / RAK Keypad" + "value" : "הודעות עבור הודעות שמורות התקבלו מ-%@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Messaggi in scatola Messaggi ricevuti per: %@" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "M5 Stack Card KB / RAK Keypad" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "M5 Stack Card KB / Teclado RAK" + "value" : "Otrzymano Wiadomości Gotowe Dla: %@" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "M5 Stack Card KB / RAK Keypad" + "value" : "Mottagna meddelanden för fördefinierade meddelanden För: %@" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "M5 стек картица KB / RAK тастатура" + "value" : "Примљене поруке за унапред припремљене поруке за: %@" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "M5 Stack 卡片键盘 / RAK 键盘" + "value" : "Canned Messages Messages Received For: %@" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "M5Stack 卡片鍵盤 / RAK 鍵盤" - } - } - } - }, - "canned.messages.preset.manual" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Manuelle Konfiguration" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Manual Configuration" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration manuelle" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרה ידנית" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Konfiguracja ręczna" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração Manual" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Manuell konfiguration" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ручна конфигурација" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "手动配置" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "手動設定" - } - } - } - }, - "canned.messages.preset.rakrotary" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "RAK Drehimpulsgeber Modul" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "RAK Rotary Encoder Module" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Module d'encodage rotatif RAK" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "RAK Rotary Encoder Module" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Moduł kodera obrotowego RAK" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Module Codificador do RAK Rotary" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "RAK Rotary Encoder-modul" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "RAK Rotary енкодер модул" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "RAK 编码器" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "RAK 旋轉編碼器" + "value" : "Canned Messages Messages Received For: %@" } } } }, "Carousel Interval" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Intervallo del carosello" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Интервал карусела" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "輪播時間間隔" + } } } }, @@ -3234,6 +5374,12 @@ "value" : "Kategorien" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Categorie" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -3245,66 +5391,172 @@ "state" : "translated", "value" : "分类" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "分類" + } + } + } + }, + "Category" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kategorie" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Categoria" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Категорија" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Category" + } } } }, "Ch1 Current" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Corrente Ch1" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Канал 1 струја" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻道1 電流" + } } } }, "Ch1 Voltage" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tensione Ch1" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Канал 1 напон" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻道1 電壓" + } } } }, "Ch2 Current" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Corrente Ch2" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Канал 2 струја" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻道2 電流" + } } } }, "Ch2 Voltage" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tensione Ch2" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Канал 2 напон" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻道2 電壓" + } } } }, "Ch3 Current" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Corrente Ch3" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Канал 3 струја" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻道3 電流" + } } } }, "Ch3 Voltage" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tensione Ch3" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Канал 3 напон" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻道3 電壓" + } } } }, @@ -3312,37 +5564,37 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Kanal" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Canal" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "ערוץ" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Canale" + } + }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Kanał" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Canal" - } - }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Kanal" } }, @@ -3360,7 +5612,7 @@ }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "頻道" } } @@ -3368,6 +5620,12 @@ }, "Channel 0 Included" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Canale 0 Incluso" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -3379,21 +5637,45 @@ "state" : "translated", "value" : "包含频道 0" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "已包含頻道0" + } } } }, "Channel 1" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Canale 1" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Канал 1" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻道1" + } } } }, "Channel 1 Included" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Canale 1 Incluso" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -3405,21 +5687,45 @@ "state" : "translated", "value" : "包含频道 1" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "已包含頻道1" + } } } }, "Channel 2" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Canale 2" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Канал 2" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻道2" + } } } }, "Channel 2 Included" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Canale 2 incluso" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -3431,21 +5737,45 @@ "state" : "translated", "value" : "包含频道 2" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "已包含頻道2" + } } } }, "Channel 3" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Canale 3" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Канал 3" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻道3" + } } } }, "Channel 3 Included" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Canale 3 incluso" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -3457,11 +5787,23 @@ "state" : "translated", "value" : "包含频道 3" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "已包含頻道3" + } } } }, "Channel 4 Included" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Canale 4 Incluso" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -3473,11 +5815,23 @@ "state" : "translated", "value" : "包含频道 4" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "已包含頻道4" + } } } }, "Channel 5 Included" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Canale 5 Incluso" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -3489,11 +5843,23 @@ "state" : "translated", "value" : "包含频道 5" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "已包含頻道5" + } } } }, "Channel 6 Included" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Canale 6 Incluso" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -3505,11 +5871,23 @@ "state" : "translated", "value" : "包含频道 6" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "已包含頻道6" + } } } }, "Channel 7 Included" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Canale 7 Incluso" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -3521,11 +5899,23 @@ "state" : "translated", "value" : "包含频道 7" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "已包含頻道7" + } } } }, "channel details" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "dettagli del canale" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -3537,11 +5927,23 @@ "state" : "translated", "value" : "频道详情" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻道資料" + } } } }, "Channel Name" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nome del canale" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -3553,11 +5955,23 @@ "state" : "translated", "value" : "频道名称" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻道名稱" + } } } }, "Channel number must be between 0 and 7." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il numero del canale deve essere compreso tra 0 e 7." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -3569,11 +5983,23 @@ "state" : "translated", "value" : "频道编号必须介于 0 和 7 之间。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻道名稱必須在0和7之間。" + } } } }, "Channel Role" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ruolo del canale" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -3585,225 +6011,38 @@ "state" : "translated", "value" : "频道角色" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻道模式" + } } } }, "Channel URL" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "URL del canale" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Линк канала" } - } - } - }, - "Channel Utilization %@%%" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Искоришћеност канала %@%%" - } - } - } - }, - "channel.role.disabled" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Deaktiviert" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Disabled" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Désactivé" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "כבוי" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wyłączony" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Desativado" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Inaktiverad" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Онемогућено" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "禁用" - } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "關閉" + "value" : "頻道網址" } } } }, - "channel.role.primary" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Primär" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Primary" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Principal" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "עיקרי" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Podstawowy" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Primário" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Primär" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Примарни" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "主要" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "主要" - } - } - } - }, - "channel.role.secondary" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sekundär" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Secondary" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Secondaire" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "משני" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wtórny" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Secundária" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sekundär" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Секундарни" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "次要" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "次要" - } - } - } - }, - "channel.utilization" : { + "Channel Utilization" : { "localizations" : { "de" : { "stringUnit" : { @@ -3811,12 +6050,6 @@ "value" : "Kanalbelegung" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Channel Utilization" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -3829,18 +6062,18 @@ "value" : "שימוש ערוץ" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Utilizzo del canale" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Wykorzystanie kanału" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Utilização do Canal" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -3867,7 +6100,23 @@ } } }, - "channels" : { + "Channel Utilization %@%%" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Utilizzo del canale %@%%" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻道利用率 %@%%" + } + } + } + }, + "Channels" : { "localizations" : { "de" : { "stringUnit" : { @@ -3875,12 +6124,6 @@ "value" : "Kanäle" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Channels" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -3893,18 +6136,18 @@ "value" : "ערוצים" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Canali" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Kanały" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Canais" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -3933,6 +6176,12 @@ }, "Channels being added from the QR code did not save. When adding channels the names must be unique." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "I canali aggiunti dal codice QR non venivano salvati. Quando si aggiungono canali, i nomi devono essere unici." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -3944,11 +6193,23 @@ "state" : "translated", "value" : "通过二维码添加的频道无法保存。添加频道时,名称必须唯一。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "從 QR Code 新增的頻道未成功儲存。新增頻道時,頻道名稱不能重複。" + } } } }, "Chart" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Grafico" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -3960,32 +6221,67 @@ "state" : "translated", "value" : "图表" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "圖表" + } } } }, "CHG" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "CHG" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "ПУЊ" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "充電中" + } } } }, "China" : { - "extractionState" : "manual", "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cina" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Кина" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "中國" + } } } }, "Clear" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Libero" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -3997,20 +6293,16 @@ "state" : "translated", "value" : "清除" } - } - } - }, - "Clear Log" : { - "localizations" : { - "sr" : { + }, + "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Очисти логове" + "value" : "清除" } } } }, - "clear.app.data" : { + "Clear App Data" : { "localizations" : { "de" : { "stringUnit" : { @@ -4018,12 +6310,6 @@ "value" : "App Daten löschen" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Clear App Data" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -4036,18 +6322,18 @@ "value" : "אפס הגדרות אפליקציה" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancella i dati dell'app" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Wyczyść dane aplikacji" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Apagar os dados do App" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -4074,8 +6360,36 @@ } } }, + "Clear Log" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancella registro" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Очисти логове" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "清除 Log 檔" + } + } + } + }, "Client" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cliente" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -4087,11 +6401,57 @@ "state" : "translated", "value" : "客户端" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Client" + } + } + } + }, + "Client Hidden" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Client - Versteckt" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cliente Nascosto" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Скривени клијент" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "客户端隐藏" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Client Hidden" + } } } }, "Client History" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Storia del cliente" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -4103,11 +6463,23 @@ "state" : "translated", "value" : "客户端历史" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "客戶端歷史紀錄" + } } } }, "Client History Request Sent" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Richiesta di cronologia clienti inviata" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -4119,11 +6491,51 @@ "state" : "translated", "value" : "已发送客户端历史记录请求" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "客戶端歷史紀錄請求已送出" + } + } + } + }, + "Client Mute" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cliente Muto" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Клијент мутиран" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "客户端静默" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Client Mute" + } } } }, "Client options" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Opzioni del cliente" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -4135,11 +6547,23 @@ "state" : "translated", "value" : "客户端选项" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "客戶端選項" + } } } }, "Clockwise Rotary Event" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Evento rotariano in senso orario" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -4151,10 +6575,16 @@ "state" : "translated", "value" : "顺时针旋转活动" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "順時針旋轉操作" + } } } }, - "close" : { + "Close" : { "localizations" : { "de" : { "stringUnit" : { @@ -4162,12 +6592,6 @@ "value" : "Schließen" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Close" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -4180,18 +6604,18 @@ "value" : "סגור" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Chiudere" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Zamknij" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fechar" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -4220,6 +6644,12 @@ }, "Coding Rate" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tasso di codifica" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -4231,6 +6661,12 @@ "state" : "translated", "value" : "编码率" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "編碼率" + } } } }, @@ -4242,6 +6678,12 @@ "value" : "Farbe" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Colore" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -4253,31 +6695,61 @@ "state" : "translated", "value" : "颜色" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "顏色" + } } } }, "Communicating" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Comunicare" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Комуницирам" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "通訊中" + } } } }, "Community Support" : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Подршка заједнице" + "value" : "Supporto alla community" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "社群支援" } } } }, "Config" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -4289,1302 +6761,11 @@ "state" : "translated", "value" : "配置" } - } - } - }, - "config.module.paxcounter.enabled.description" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "When enabled the PAX Counter module counts the number of people passing by using WiFi and Bluetooth. Both WiFI and Bluetooth must be disabled for PAX counter to work." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "When enabled the PAX Counter module counts the number of people passing by using WiFi and Bluetooth. Both WiFI and Bluetooth must be disabled for PAX counter to work." - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "When enabled the PAX Counter module counts the number of people passing by using WiFi and Bluetooth. Both WiFI and Bluetooth must be disabled for PAX counter to work." - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "When enabled the PAX Counter module counts the number of people passing by using WiFi and Bluetooth. Both WiFI and Bluetooth must be disabled for PAX counter to work." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Quando ativado, o módulo de Contador de PAX conta o número de pessoas que passam usando Wi-Fi e Bluetooth. Tanto o Wi-Fi quanto o Bluetooth devem estar desativados para que o contador de PAX funcione." - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "När aktiverad räknar PAX-räknarmodulen antalet personer som passerar med WiFi och Bluetooth. Både WiFi och Bluetooth måste vara aktiverade för att PAX-räknaren ska fungera." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Када је омогућен, модул бројача пролазника броји број људи који пролазе користећи ВајФај и Блутут. И ВајФај и Блутут морају бити онемогућени да би бројач пролазника радио." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "启用 PAX 计数器模块时,通过使用 WiFi 和蓝牙来计算经过的人数。为了使 PAX 计数器正常工作,必须将 WiFi 和蓝牙都禁用。" - } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "啟用後,人流計數器模組將透過 WiFi 和藍牙計算經過的人數。必須停用 WiFi 和藍牙才能讓 PAX 計數器正常工作。" - } - } - } - }, - "config.module.paxcounter.settings" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Counter" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Counter" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Counter" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Counter" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Contador de PAX" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Räknare" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Бројач пролазника" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX 计数器" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "人流計數器" - } - } - } - }, - "config.module.paxcounter.title" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Counter Config" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Counter Config" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Counter Config" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Counter Config" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração do Contador de PAX" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Räknare Konfiguration" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Подешавања бројача пролазника" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX 计数器配置" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "人流計數器設定" - } - } - } - }, - "config.module.paxcounter.updateinterval" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Update Interval" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Update Interval" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Update Interval" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Update Interval" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Intervalo de Atualização" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Uppdateringsintervall" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Интервал ажурирања" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "更新间隔" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "更新時間間隔" - } - } - } - }, - "config.module.paxcounter.updateinterval.description" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "How often we can send a message to the mesh when people are detected." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "How often we can send a message to the mesh when people are detected." - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "How often we can send a message to the mesh when people are detected." - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "How often we can send a message to the mesh when people are detected." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Com que frequência podemos enviar uma mensagem para a malha quando as pessoas são detectadas." - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Hur ofta vi kan skicka ett meddelande till mesh-nätverket när personer upptäcks." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Колико често можемо послати поруку мрежи када се открију људи." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "检测到人员时,我们可以隔多久发送一条消息到 Mesh" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "當檢測到人員時,我們可以多久發送一次訊息到網狀網路。" - } - } - } - }, - "config.power.adc.multiplier" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Multiplier" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Multiplier" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Multiplier" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Multiplier" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Multiplicador" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Multiplikator" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Мултипликатор" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "修正倍數" - } - } - } - }, - "config.power.adc.override" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "ADC Override" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "ADC Override" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "ADC Override" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "ADC Override" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Substituir ADC" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "ADC-överskrivning" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Преписивање ADC-а" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "ADC校正" - } - } - } - }, - "config.power.ls.secs" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Light Sleep Interval" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Light Sleep Interval" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Light Sleep Interval" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Intervalo de Dormir Leve" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Intervall för Ljussömn" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Интервал благог спавања" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "轻度睡眠间隔" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "輕度休眠間隔" - } - } - } - }, - "config.power.min.wake.secs" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Minimum Wake Interval" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Minimum Wake Interval" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Minimum Wake Interval" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Intervalo Mínimo de Despertar" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Minsta Väckningsintervall" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Минимални интервал будног стања" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "最小唤醒间隔" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "最小的喚醒間隔時間" - } - } - } - }, - "config.power.saving" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Stromsparen" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Power Saving" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Power Saving" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Power Saving" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Poupar a Energia" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Strömsparläge" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Уштеда енергије" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "省电模式" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "省電模式" - } - } - } - }, - "config.power.saving.description" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio. Don't use this setting if you want to use your device with the phone apps or are using a device without a user button." - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio. Don't use this setting if you want to use your device with the phone apps or are using a device without a user button." - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio. Don't use this setting if you want to use your device with the phone apps or are using a device without a user button." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Vai por dormir o máximo possível, para o papel do rastreador e o papel do sensor isso incluirá também o rádio lora. Não use essa configuração se deseja usar seu dispositivo com os aplicativos do telefone ou está usando um dispositivo sem um botão do usuário." - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sätter allt i viloläge så mycket som möjligt, för spårnings- och sensorläge kommer detta också inkludera LoRa-radion. Använd inte denna inställning om du vill använda din enhet med mobilappar eller använder en enhet utan en användarknapp." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Спаваће све што је више могуће, за улогу трагача и сензора ово ће укључивати и лора радио. Не користите ово подешавање ако желите да користите свој уређај са мобилним апликацијама или користите уређај без корисничког дугмета." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "尽可能让所有设备处于睡眠状态,对于跟踪器和传感器来说,这也包括 LoRa 无线电。如果您想将电台与手机 App 一起使用,或使用没有用户按钮的电台,请不要使用此设置。" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "為了追蹤器和感測器的角色,這將包括將 LoRa 無線電設備盡可能地進入睡眠模式。如果您想要使用手機應用程式操作您的設備,或者使用沒有用戶按鈕的設備,請不要使用此設定。" - } - } - } - }, - "config.power.section.battery" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Batterie" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Battery" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Battery" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Battery" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Bataria" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Batteri" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Батерија" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "电池" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "電池" - } - } - } - }, - "config.power.section.sleep" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Schlafmodus" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sleep" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sleep" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sleep" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dormir" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sömn" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Стане спавања" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "休眠" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "休眠" - } - } - } - }, - "config.power.settings" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Strom" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Power" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Power" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Power" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Energia" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ström" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Снага" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "电源" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "電源" - } - } - } - }, - "config.power.shutdown.after.secs" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nach" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "After" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "After" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "After" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Após" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Efter" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Након" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "之後" - } - } - } - }, - "config.power.shutdown.on.power.loss" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Herunterfahren bei Stromunterbruch" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Shutdown on Power Loss" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Shutdown on Power Loss" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Shutdown on Power Loss" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Desligar em caso de Perda de Energia" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Stäng av vid Strömförlust" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Искључи уређај при губитку напајања" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "断电时关机" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "失去電源後關機" - } - } - } - }, - "config.power.title" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Stromkonfiguration" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Power Config" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Power Config" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Power Config" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração de Energia" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Strömkonfiguration" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Подешавања напајња" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "电源配置" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "電源設定" - } - } - } - }, - "config.power.wait.bluetooth.secs" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Bluetooth Aus nach" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Bluetooth Off After" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Bluetooth Off After" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Bluetooth Off After" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Desligar o Bluetooth Após" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Bluetooth Stängs Av Efter" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Блутут се искључује након" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "蓝牙关闭 After" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "等待藍芽" - } - } - } - }, - "config.ringtone" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "RTTTL Klingelton" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "RTTTL Ringtone" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "RTTTL Ringtone" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "RTTTL Ringtone" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Toque RTTTL" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "RTTTL Ringsignal" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "RTTTL мелодија звона" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "RTTTL 铃声" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "RTTTL 鈴聲" - } - } - } - }, - "config.ringtone.description" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ringtone Transfer Language(RTTTL) Ringtone String used by supported buzzers in external notifications." - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ringtone Transfer Language(RTTTL) Ringtone String used by supported buzzers in external notifications." - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ringtone Transfer Language(RTTTL) Ringtone String used by supported buzzers in external notifications." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Idioma de Transferência de Toque (RTTTL) Sequência de Toque usada por campainhas suportadas em notificações externas." - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ringsignalöverföringsspråk (RTTTL) Ringsignalsträng som används av stödda buzzers i externa notifikationer." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Језик преноса мелдоије звона (RTTTL) Стринг мелодије звона који користе подржани звучни сигнали у спољним обавештењима." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "支持外部通知中使用的铃声传输语言 (RTTTL) 铃声字符串。" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "RTTTL 鈴聲字串(Ringtone Transfer Language)被用於外部通知中支援的蜂鳴器。" - } - } - } - }, - "config.ringtone.label" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ringtone Transfer Language" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ringtone Transfer Language" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ringtone Transfer Language" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Idioma de Transferência de Toque" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Språk för Överföring av Ringsignal" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Језик преноса мелодије звона" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "铃声传输语言" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "鈴聲傳輸語言(RTTTL)" - } - } - } - }, - "config.ringtone.title" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Klingelton Konfiguration" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ringtone Config" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ringtone Config" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ringtone Config" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração de Toque" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ringsignalskonfiguration" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Конфигурација звона" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "铃声配置" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "鈴聲" - } - } - } - }, - "config.save.confirm" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nach dem Ändern der Einstellungen wird das Gerät neu starten." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "After config values save the node will reboot." - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Une fois la configuration sauvegardée, le noeud redémarrera." - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "לאחר שמירת הגדרות המכשיר יתחיל מחדש." - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Po zapisaniu wartości konfiguracji węzeł zostanie zrestartowany." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Após salvar os valores de configuração, o nó reiniciará" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Efter att konfigurationsvärdena sparats kommer noden att starta om." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Након што сачувате вредности конфигурације, чвор ће се поново покренути." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "节点将会在保存配置后重启。" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "電台將會在設定儲存後重啟。" + "value" : "設定" } } } @@ -5597,16 +6778,34 @@ "value" : "Konfiguration für: %@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione per: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Конфигурација за: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "正在設定: %@" + } } } }, "Configuration Presets" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Preset di configurazione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -5618,6 +6817,12 @@ "state" : "translated", "value" : "配置预设" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "設定預設組態" + } } } }, @@ -5629,20 +6834,38 @@ "value" : "Konfigurieren" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurare" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Конфигуриши" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "設定" + } } } }, "Confirm" : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Потврди" + "value" : "Conferma" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "確認" } } } @@ -5655,25 +6878,53 @@ "value" : "Verbunden mit einem Knoten" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Collegarsi a un nodo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Повежите се са чвором" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "正在連接節點" + } + } + } + }, + "Connect to MQTT via Proxy" : { + "localizations" : { + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "透過Proxy連接到MQTT" + } } } }, "Connect to new radio?" : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Повезати се на нови радио?" + "value" : "Collegare alla nuova radio?" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "連接新的節點?" } } } }, - "connected" : { + "Connected" : { "localizations" : { "de" : { "stringUnit" : { @@ -5681,12 +6932,6 @@ "value" : "Derzeit verbunden" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Bluetooth Connected" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -5699,18 +6944,18 @@ "value" : "מחובר בבלוטוס" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bluetooth collegato" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Podłączony" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Bluetooth Connectado" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -5745,79 +6990,43 @@ "value" : "Verbunden mit Knoten %@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nodo collegato %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Повезани чвор %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "已連接的節點 %@" + } } } }, - "connected.radio" : { + "Connected Radio" : { "localizations" : { - "de" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Verbundenes Gerät" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Connected Radio" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Radio connectée" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "מכשיר מחובר" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Podłączone radio" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Rádio Conectado" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ansluten Radio" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Повезани радио" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "电台已连接" + "value" : "Radio connessa" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "已連接的電台" + "value" : "已連接的節點" } } } }, - "connecting" : { + "Connecting . ." : { "localizations" : { "de" : { "stringUnit" : { @@ -5825,12 +7034,6 @@ "value" : "Verbinde..." } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Connecting . ." - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -5843,18 +7046,18 @@ "value" : "מתחבר . ." } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Collegamento. ." + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Łączenie . ." } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Conectando . ." - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -5876,17 +7079,23 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "連接中..." + "value" : "連接中⋯⋯" } } } }, "Connecting to a new radio will clear all app data on the phone." : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Повезивање са новим радио уређајем ће очистити све локалне податке апликације на телефону." + "value" : "La connessione a una nuova radio cancellerà tutti i dati delle app sul telefono." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "連接到新的設備時,手機上的 App 資料將會被清除。" } } } @@ -5899,6 +7108,12 @@ "value" : "Verbindungsversuch %lld von 10" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tentativo di connessione %lld di 10" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -5910,11 +7125,16 @@ "state" : "translated", "value" : "连接尝试 %lld,共 10 次" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "嘗試連接 %lld / 10" + } } } }, "Connection failed after %d attempts to connect to %@. You may need to forget your device under Settings > Bluetooth." : { - "extractionState" : "migrated", "localizations" : { "de" : { "stringUnit" : { @@ -5922,12 +7142,6 @@ "value" : "Verbindung nach %d Versuchen zu %@ fehlgeschlagen. Evtl. hilft es, die Verbindung unter Einstellungen > Bluetooth manuell zu löschen." } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Connection failed after %d attempts to connect to %@. You may need to forget your device under Settings > Bluetooth." - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -5940,18 +7154,18 @@ "value" : "התחברות נכשלה לאחר %d נסיונות להתחבר ל%@. יתכן ויש צורך 'לשכוח' את המכשיר בהגדרות מכשיר > בלוטוס." } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Connessione fallita dopo %d tentativi di connessione a %@. Potrebbe essere necessario disaccoppiare il tuo dispositivo in Impostazioni > Bluetooth." + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Połączenie nie powiodło się po %d próbach połączenia z %@. Zapomnij o urządzeniu w Ustawienia > Bluetooth." } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Falha de conexão após %d tentativas de conectar a %@. Você pode precisar esquecer seu dispositivo em Configurações > Bluetooth." - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -5973,78 +7187,22 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "嘗試連接%d失敗,你可能需要在系统設定的藍芽選項中忽略該電台。" + "value" : "嘗試連接%d失敗,您可能需要在系统設定的藍芽選項中忽略該節點。" } } } }, - "contacts" : { - "extractionState" : "manual", + "Consent to Share Unencrypted Node Data via MQTT" : { "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Kontakte" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Contacts" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Contacts" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "אנשי קשר" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Kontakty" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Contactos" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Kontakter" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Контакти" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "联系人" - } - }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "聯絡人" + "value" : "同意透過 MQTT 傳輸未加密的節點資料" } } } }, - "contacts %@" : { - "extractionState" : "migrated", + "Contacts (%@)" : { "localizations" : { "de" : { "stringUnit" : { @@ -6052,12 +7210,6 @@ "value" : "Kontakte (%@)" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Contacts (%@)" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -6070,18 +7222,18 @@ "value" : "אנשי קשר (%@)" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Contatti (%@)" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Kontakty (%@)" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Contactos (%@)" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -6110,6 +7262,12 @@ }, "Control Type" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tipo di controllo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -6121,11 +7279,23 @@ "state" : "translated", "value" : "控制类型" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "控制模式" + } } } }, "Controls the blinking LED on the device. For most devices this will control one of the up to 4 LEDS, the charger and GPS LEDs are not controllable." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Controlla il LED lampeggiante del dispositivo. Per la maggior parte dei dispositivi controlla uno dei 4 LED, mentre i LED del caricatore e del GPS non sono controllabili." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -6137,6 +7307,12 @@ "state" : "translated", "value" : "控制设备上闪烁的 LED。 对大多数设备而言,这将控制最多 4 个 LED 中的一个,充电指示灯和 GPS 状态灯无法控制。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "控制裝置上的閃爍 LED。對於大多數裝置而言,這將能控制最多 4 顆 LED 其中之一,但充電指示燈和 GPS 指示燈無法被控制。" + } } } }, @@ -6148,11 +7324,23 @@ "value" : "Konvexe Hülle" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Scafo convesso" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Конвексна љуштура" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "凸包" + } } } }, @@ -6164,11 +7352,23 @@ "value" : "Koordinate" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Coordinare" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Координате" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "經緯度" + } } } }, @@ -6180,6 +7380,12 @@ "value" : "Koordinate %1$@, %2$@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Coordinate %@, %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -6191,6 +7397,12 @@ "state" : "translated", "value" : "坐标 %1$@, %2$@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "經緯度 %@, %@" + } } } }, @@ -6202,11 +7414,23 @@ "value" : "Koordinaten:" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Coordinate:" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Координате:" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "經緯度:" + } } } }, @@ -6230,18 +7454,18 @@ "value" : "העתק" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Copia" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Kopiuj" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Copiar" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -6276,6 +7500,12 @@ "value" : "Knoten nicht gefunden" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Impossibile trovare il nodo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -6287,16 +7517,34 @@ "state" : "translated", "value" : "无法找到节点" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "找不到節點" + } } } }, "Counter Clockwise Rotary Event" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Evento rotativo antiorario" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Ротациони догађај у смеру супротном од казаљке на сату" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "逆時針旋轉操作" + } } } }, @@ -6308,11 +7556,23 @@ "value" : "Wegpunkt erstellen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Creare un waypoint" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Креирајте путну тачку" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "建立路徑點" + } } } }, @@ -6324,21 +7584,45 @@ "value" : "Erstellt: %@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Creato: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Креирано : %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "建立: %@" + } } } }, "Current" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Attuale" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Струја" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "電流" + } } } }, @@ -6350,6 +7634,12 @@ "value" : "Aktuelle Firmware Version: %@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Versione attuale del firmware: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -6361,6 +7651,12 @@ "state" : "translated", "value" : "当前固件版本号:%@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "目前韌體版本:%@" + } } } }, @@ -6372,6 +7668,12 @@ "value" : "Aktuelle Firmware Version: %1$@, neuste Firmware Version %2$@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Versione attuale del firmware: %@, Ultima versione del firmware: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -6383,6 +7685,12 @@ "state" : "translated", "value" : "当前固件版本号:%1$@,最新固件版本号:%2$@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "目前韌體版本:%@;最新韌體版本:%@" + } } } }, @@ -6394,26 +7702,50 @@ "value" : "Aktuell: %lld" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Corrente: %lld" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Тренутно: %lld" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "電流:%lld" + } } } }, "Currently showing modules that may not be supported by this node." : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Тренутно се приказују модули које овај чвор можда не подржава." + "value" : "Attualmente mostra i moduli che potrebbero non essere supportati da questo nodo." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "目前顯示的模組可能不受此節點支援。" } } } }, "Currently the recommended way to update ESP32 devices is using the web flasher on a desktop computer from a chrome based browser. It does not work on mobile devices or over BLE." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Attualmente il modo consigliato per aggiornare i dispositivi ESP32 è quello di utilizzare il flasher web su un computer desktop da un browser basato su chrome. Non funziona su dispositivi mobili o tramite BLE." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -6425,6 +7757,12 @@ "state" : "translated", "value" : "目前,更新 ESP32 设备的推荐方法是在电脑上使用基于 Chrome 浏览器的 Web Flasher。该方法不适用于移动设备或通过 BLE 进行更新。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "目前建議使用電腦透過以 Chrome 為基礎的瀏覽器,使用網頁刷機工具來更新 ESP32 裝置。此方法無法在行動裝置上或透過 BLE 使用。" + } } } }, @@ -6436,16 +7774,34 @@ "value" : "Datum" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Data" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Датум" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "日期" + } } } }, "Debug" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Debug" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -6457,6 +7813,12 @@ "state" : "translated", "value" : "Debug" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "偵錯" + } } } }, @@ -6468,26 +7830,107 @@ "value" : "Fehlersuchprotokolle" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Registri di debug" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Дебаг логови" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "偵錯紀錄" + } } } }, "Debug Logs%@" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Registri di debug%@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Debug логови%@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "偵錯紀錄%@" + } } } }, - "default" : { - "extractionState" : "migrated", + "Decimal Degrees Format" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dezimalgrad Format" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Format décimal pour les degrés" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "פורמט קואורדינטות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Formato dei gradi decimali" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Format Dziesiętny Stopni" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Decimalgrader" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Формат децималних степени" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "十进制" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "十進制" + } + } + } + }, + "Default" : { "localizations" : { "de" : { "stringUnit" : { @@ -6495,12 +7938,6 @@ "value" : "Standard" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Default" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -6513,18 +7950,18 @@ "value" : "ברירת מחדל" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Predefinito" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Domyślny" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Padrão" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -6551,29 +7988,12 @@ } } }, - "Default" : { + "Default 128x64 screen layout" : { "localizations" : { - "de" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Standard" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Подразумевано" - } - } - } - }, - "default.128x64.screen.layout" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Default 128x64 screen layout" + "value" : "Layout dello schermo 128x64 predefinito" } }, "sr" : { @@ -6587,10 +8007,74 @@ "state" : "translated", "value" : "默认 128x64 屏幕布局" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "預設 128x64 版型" + } } } }, - "delete" : { + "Degrees Minutes Seconds" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Grad Minuten Sekunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Degrés Minutes Secondes" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "מעלות דקות שניות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Gradi Minuti Secondi" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Stopnie Minuty Sekundy" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Grader Minuter Sekunder" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Степени Минути Секунде" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "度分秒" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "度分秒" + } + } + } + }, + "Delete" : { "localizations" : { "de" : { "stringUnit" : { @@ -6598,12 +8082,6 @@ "value" : "Löschen" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Delete" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -6616,18 +8094,18 @@ "value" : "מחק" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancellare" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Usuń" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Apagar" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -6654,8 +8132,66 @@ } } }, + "Delete all device metrics?" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Effacer toutes les mesures de l’appareil?" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "נקה יומן מכשיר?" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancellare tutte le metriche del dispositivo?" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Usunąć wszystkie metryki urządzenia?" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ta bort alla enhetsmätvärden?" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Избришите све метрике уређаја?" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "删除所有设备指标?" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "要刪除所有裝置指標嗎?" + } + } + } + }, "Delete all environment metrics?" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancellare tutte le metriche dell'ambiente?" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -6667,52 +8203,106 @@ "state" : "translated", "value" : "删除所有环境指标?" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "刪除所有環境指標?" + } } } }, - "Delete all map tiles?" : { + "Delete all pax data?" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancellare tutti i dati dei passeggeri?" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Radera all paxdata?" + } + }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Избрисати све плочице мапе?" + "value" : "Избриши све PAX податке?" } }, - "zh-Hans" : { + "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "删除所有瓦片地图?" + "value" : "要刪除所有 PAX 資料嗎?" } } } }, "Delete all positions?" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancellare tutte le posizioni?" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Избрисати све позиције?" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "刪除所有位置資料?" + } } } }, "Delete Message" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancellare il messaggio" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Обриши поруку" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "刪除訊息" + } } } }, "Delete Messages" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancellare i messaggi" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Обриши поруке" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "刪除訊息" + } } } }, @@ -6724,11 +8314,23 @@ "value" : "Knoten löschen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancellare il nodo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Обриши чвор" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "刪除節點" + } } } }, @@ -6740,36 +8342,78 @@ "value" : "Knoten löschen?" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancellare il nodo?" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Обрисати чвор?" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "刪除節點?" + } } } }, "Delete Power metrics?" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancellare le metriche di potenza?" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Обрисати метрике снаге?" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "刪除電源指標?" + } } } }, "Description" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Descrizione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Опис" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "描述" + } } } }, "Description must be less than 100 bytes" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La descrizione deve essere inferiore a 100 byte" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -6781,56 +8425,61 @@ "state" : "translated", "value" : "描述必须少于 100 字节" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "描述必須小於 100 bytes" + } } } }, "Detection" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rilevamento" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Откривање" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "檢測感測器" + } } } }, "Detection event" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Evento di rilevamento" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Догађај откривања" } - } - } - }, - "Detection Sensor Log" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Логови сензора откривања" - } - } - } - }, - "Detection sensor messages are received as text messages. If you enable notifications you will recieve a notification for each detection message received and a corresponding unread message badge." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Поруке сензора за откривање се примају као текстуалне поруке. Ако омогућите обавештења, добићете обавештење за сваку примљену поруку за откривање и одговарајућу значку непрочитане поруке." - } }, - "zh-Hans" : { + "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "检测传感器信息以文本信息的形式接收。如果启用通知功能,则每收到一条检测信息都会收到一条通知,并显示相应的未读信息。" + "value" : "檢測感測器事件" } } } }, - "detection.sensor" : { + "Detection Sensor" : { + "extractionState" : "manual", "localizations" : { "de" : { "stringUnit" : { @@ -6838,12 +8487,6 @@ "value" : "Detection Sensor" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Detection Sensor" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -6856,18 +8499,18 @@ "value" : "חיישן זיהוי" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sensore di rilevamento" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Detection Sensor" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sensor de Detecção" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -6894,14 +8537,8 @@ } } }, - "detection.sensor.config" : { + "Detection Sensor Config" : { "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Detection Sensor Config" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -6914,10 +8551,10 @@ "value" : "הגדרות חיישן זיהוי" } }, - "pt-PT" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Configuração do Sensor de Detecção" + "value" : "Configurazione del sensore di rilevamento" } }, "se" : { @@ -6937,39 +8574,21 @@ "state" : "translated", "value" : "检测传感器配置" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "檢測感應器設定" + } } } }, - "detection.sensor.log" : { + "Detection Sensor Log" : { "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Detection Sensor Log" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Journal du capteur de détection" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "יומן חיישן זיהוי" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Log Sensor de Detecção" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Logg för Detektionssensor" + "value" : "Registro del sensore di rilevamento" } }, "sr" : { @@ -6978,16 +8597,102 @@ "value" : "Логови сензора откривања" } }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "檢測感測器紀錄" + } + } + } + }, + "Detection sensor messages are received as text messages. If you enable notifications you will recieve a notification for each detection message received and a corresponding unread message badge." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "I messaggi del sensore di rilevamento vengono ricevuti come messaggi di testo. Se si attivano le notifiche, si riceverà una notifica per ogni messaggio di rilevamento ricevuto e un badge per il messaggio non letto corrispondente." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Поруке сензора за откривање се примају као текстуалне поруке. Ако омогућите обавештења, добићете обавештење за сваку примљену поруку за откривање и одговарајућу значку непрочитане поруке." + } + }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "检测传感器日志" + "value" : "检测传感器信息以文本信息的形式接收。如果启用通知功能,则每收到一条检测信息都会收到一条通知,并显示相应的未读信息。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "偵測感測器的訊息會以文字訊息的形式接收。若啟用通知功能,每當接收到偵測訊息時,您將會收到一則通知,並顯示對應的未讀訊息標記。" + } + } + } + }, + "Detection Sensor module config received: %@" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configuration du module capteur de détection reçue : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הגדרות מודולת חיישן זיהוי התקבלו: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione del modulo sensore di rilevamento ricevuta: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Detection Sensor module config received: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Konfiguration för detektionssensormodulen mottagen: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Конфигурација модула за сензор детекције примљена: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Detection Sensor module config received: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Detection Sensor module config received: %@" } } } }, "Developers" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sviluppatori" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -6999,10 +8704,16 @@ "state" : "translated", "value" : "开发者" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "開發者" + } } } }, - "device" : { + "Device" : { "localizations" : { "de" : { "stringUnit" : { @@ -7010,12 +8721,6 @@ "value" : "Gerät" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Device" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -7028,18 +8733,18 @@ "value" : "מכשיר" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dispositivo" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Urządzenie" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dispositivo" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -7066,131 +8771,7 @@ } } }, - "Device GPS" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Geräte-GPS" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "GPS уређај" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "设备 GPS" - } - } - } - }, - "Device is managed by a mesh administrator, the user is unable to access any of the device settings." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Уређајем управља администратор мреже, корисник не може да приступи ниједном подешавању уређаја." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "设备由 Mesh 管理员管理,用户无法访问任何设备设置。" - } - } - } - }, - "Device Metrics" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Метрика уређаја" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "设备指标" - } - } - } - }, - "Device Metrics Log" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Логови метрике уређаја" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "设备指标日志" - } - } - } - }, - "Device Model: %@" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gerätemodell: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Модел уређаја: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "设备模型:%@" - } - } - } - }, - "Device Role" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Улога уређаја" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "设备角色" - } - } - } - }, - "Device Screen" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Екран уређаја" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "设备屏幕" - } - } - } - }, - "device.config" : { + "Device Config" : { "localizations" : { "de" : { "stringUnit" : { @@ -7198,12 +8779,6 @@ "value" : "Gerätekonfiguration" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Device Config" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -7216,18 +8791,18 @@ "value" : "הגדרות מכשיר" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione del dispositivo" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Konfiguracja urządzenia" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração do Dispositivo" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -7249,12 +8824,70 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "電台設定" + "value" : "節點設定" } } } }, - "device.configuration" : { + "Device config received: %@" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Gerätekonfiguration empfangen: %@" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configuration de l'appareil reçue : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הגדרות מכשיר התקבלו: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione dispositivo ricevuta: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Otrzymano konfigurację urządzenia: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enhetskonfiguration mottagen: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Примљена конфигурација уређаја: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Device config received: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Device config received: %@" + } + } + } + }, + "Device Configuration" : { "localizations" : { "de" : { "stringUnit" : { @@ -7262,28 +8895,10 @@ "value" : "Gerätekonfiguration" } }, - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Device Configuration" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Device Configuration" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Device Configuration" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração do Dispositivo" + "value" : "Configurazione del dispositivo" } }, "se" : { @@ -7312,106 +8927,160 @@ } } }, - "device.metrics.delete" : { + "Device GPS" : { "localizations" : { - "en" : { + "de" : { "stringUnit" : { "state" : "translated", - "value" : "Delete all device metrics?" + "value" : "Geräte-GPS" } }, - "fr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Effacer toutes les mesures de l’appareil?" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "נקה יומן מכשיר?" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Usunąć wszystkie metryki urządzenia?" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Apagar todas as métricas do dispositivo?" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ta bort alla enhetsmätvärden?" + "value" : "Dispositivo GPS" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Избришите све метрике уређаја?" + "value" : "GPS уређај" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "删除所有设备指标?" + "value" : "设备 GPS" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "刪除所有電台指標??" + "value" : "裝置 GPS" } } } }, - "device.metrics.log" : { + "Device is managed by a mesh administrator, the user is unable to access any of the device settings." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il dispositivo è gestito da un amministratore di rete, ma l'utente non può accedere alle impostazioni del dispositivo." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Уређајем управља администратор мреже, корисник не може да приступи ниједном подешавању уређаја." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "设备由 Mesh 管理员管理,用户无法访问任何设备设置。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "裝置由 Mesh 遠端管理,使用者無法存取任何裝置設定。" + } + } + } + }, + "Device Metadata received from: %@" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Device Metrics Log" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Device Metrics Log" + "value" : "Device Metadata empfangen von: %@" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Journal des mesures de l'appareil" + "value" : "Metadatas de l'appareil reçues de : %@" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "יומן מכשיר" + "value" : "מטא-דאטה של מכשיר התקבל מ-%@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Metadati del dispositivo ricevuti da: %@" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Dziennik metryk urządzenia" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Log g de Métricas do Dispositivo" + "value" : "Otrzymano metadane urządzenia od: %@" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Logg för Enhetsmätvärden" + "value" : "Metadata för enhet mottagen från: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Метаподаци уређаја примљени од: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Device Metadata admin message received from: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Device Metadata received from: %@" + } + } + } + }, + "Device Metrics" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Metriche del dispositivo" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Метрика уређаја" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "设备指标" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "裝置數據" + } + } + } + }, + "Device Metrics Log" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Registro delle metriche del dispositivo" } }, "sr" : { @@ -7429,143 +9098,102 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "電台指標紀錄檔" + "value" : "裝置數據記錄" } } } }, - "device.role.client" : { - "extractionState" : "migrated", + "Device Model: %@" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Client (Standard) - Mit App verbundener Client." + "value" : "Gerätemodell: %@" } }, - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "App connected or stand alone messaging device." - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Application connectée ou appareil de messagerie autonome." - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "אפליקציה מחוברת או מכשיר תקשורת עצמאי." - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Klient (domyślnie) - Klient połączony z aplikacją." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dispositivo conectado ao App ou independente para mensagens." - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Appansluten eller fristående meddelandeenhet." + "value" : "Modello dispositivo: %@" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Апликација повезана или самостални уређај за размену порука." + "value" : "Модел уређаја: %@" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "连接 App 或独立的消息发送设备。" + "value" : "设备模型:%@" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "標準模式 - App 可以連接到電台進行收發操作,並且會自動轉發 Mesh 網路中其他中繼點的消息。" + "value" : "裝置型號:%@" } } } }, - "device.role.clienthidden" : { - "extractionState" : "migrated", + "Device Role" : { "localizations" : { - "de" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Gerät, das nur bei Bedarf sendet, um nicht entdeckt zu werden oder Strom zu sparen." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Device that only broadcasts as needed for stealth or power savings." - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Appareil ne diffusant que si nécessaire pour la discrétion et l'économie d'énergie." - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "מכשיר שרק משדר לפי צורך בכדי לחסוך בחשמל או לשמור על חשאיות." - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : " Used for nodes that \"only speak when spoken to\" Turns all of the routine broadcasts but allows for ad-hoc communication. Still rebroadcasts, but with local only rebroadcast mode (known meshes only). Can be used for private operation or to dramatically reduce airtime / power consumption." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dispositivo que apenas transmite conforme necessário em modo furtivo ou economia de energia." - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enhet som endast sänder ut när det behövs för stealth eller energibesparing." + "value" : "Ruolo del dispositivo" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Уређај који емитује само по потреби ради прикривености или уштеде енергије." + "value" : "Улога уређаја" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "只在需要时才广播的设备,以达到隐蔽或省电的目的。" + "value" : "设备角色" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "隱藏模式 - 用於那些\"只在被問到時才回答\"的節點,關閉所有常規廣播,但允許臨時通訊。依然會進行轉播,但只在本地轉播模式下進行(僅限已知的網狀網路)。可以用於私密操作或顯著減少空中時間/功耗。" + "value" : "裝置模式" } } } }, - "device.role.clientmute" : { - "extractionState" : "migrated", + "Device Screen" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Schermata del dispositivo" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Екран уређаја" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "设备屏幕" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "裝置螢幕" + } + } + } + }, + "Device that does not forward packets from other devices." : { "localizations" : { "de" : { "stringUnit" : { @@ -7573,12 +9201,6 @@ "value" : "Gerät, das keine Pakete von anderen Geräten weiterleitet." } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Device that does not forward packets from other devices." - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -7591,18 +9213,18 @@ "value" : "מכשיר שאינו מעביר הודעות ממכשירים אחרים הלאה." } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dispositivo che non inoltra pacchetti da altri dispositivi." + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Wyciszenie klienta - To samo, co klient, z wyjątkiem pakietów, które nie przeskakują przez ten węzeł, nie przyczynia się do routingu pakietów dla siatki." } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dispositivo que não encaminha pacotes de outros dispositivos." - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -7624,897 +9246,88 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "靜音模式 - 與標準模式類似,App 可以連接到電台進行收發操作,但不會轉發 Mesh 網路中其他中繼點的消息。" + "value" : "裝置不會轉發來自其他設備的封包。" } } } }, - "device.role.lostandfound" : { - "extractionState" : "migrated", + "Device that only broadcasts as needed for stealth or power savings." : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Sendet den Standort regelmäßig als Nachricht an den Standardkanal, um die Suche nach dem Gerät zu unterstützen." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Broadcasts location as message to default channel regularly for to assist with device recovery." + "value" : "Gerät, das nur bei Bedarf sendet, um nicht entdeckt zu werden oder Strom zu sparen." } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Transmet régulièrement la position par message dans le canal par défaut pour vous aider à retrouver l'appareil." + "value" : "Appareil ne diffusant que si nécessaire pour la discrétion et l'économie d'énergie." } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "משדר מיקום כהודעה לערוץ ברירת מחדל לעיתים קבועות בכדי לסייע במציאת המכשיר." + "value" : "מכשיר שרק משדר לפי צורך בכדי לחסוך בחשמל או לשמור על חשאיות." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dispositivo che trasmette solo quando è necessario, per non dare nell'occhio o per risparmiare energia." } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Broadcasts location as message to default channel regularly for to assist with device recovery." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Transmite a localização como mensagem para o canal padrão regularmente para auxiliar na recuperação do dispositivo." + "value" : " Used for nodes that \"only speak when spoken to\" Turns all of the routine broadcasts but allows for ad-hoc communication. Still rebroadcasts, but with local only rebroadcast mode (known meshes only). Can be used for private operation or to dramatically reduce airtime / power consumption." } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Sänder regelbundet ut plats som meddelande till standardkanalen för att underlätta återhämtning av enheten." + "value" : "Enhet som endast sänder ut när det behövs för stealth eller energibesparing." } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Редовно емитује локацију као поруку подразумеваном каналу ради помоћи при проналаску уређаја." + "value" : "Уређај који емитује само по потреби ради прикривености или уштеде енергије." } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "定期向默认信道发送位置信息,以协助设备恢复。" + "value" : "只在需要时才广播的设备,以达到隐蔽或省电的目的。" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "遺失物模式 - 用於自動頻繁地向網狀網路發送一條包含設備當前位置的短信:\"I'm lost! Position: lat / long\"" - } - } - } - }, - "device.role.name.client" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Client" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Client" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Клијент" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "客户端" - } - } - } - }, - "device.role.name.clientHidden" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Client - Versteckt" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Client Hidden" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Скривени клијент" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "客户端隐藏" - } - } - } - }, - "device.role.name.clientMute" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Client Mute" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Клијент мутиран" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "客户端静默" - } - } - } - }, - "device.role.name.lostAndFound" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tracker" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Lost and Found" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Изгубљено и нађено" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "失物招领" - } - } - } - }, - "device.role.name.repeater" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Repeater" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Repeater" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Поновљач" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "中继" - } - } - } - }, - "device.role.name.router" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Router" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Router" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Рутер" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "路由" - } - } - } - }, - "device.role.name.routerClient" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Router & Client" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Router & Client" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Рутер и клијент" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "路由 & 客户端" - } - } - } - }, - "device.role.name.routerlate" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Router mit Verzögerung" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Router Late" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Рутер са кашњењем" - } - } - } - }, - "device.role.name.sensor" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sensor" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sensor" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Сензор" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "传感器" - } - } - } - }, - "device.role.name.tak" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "TAK" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "TAK" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "TAK" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "TAK" - } - } - } - }, - "device.role.name.takTracker" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "TAK Tracker" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "TAK Tracker" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "ТАК Трекер" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "TAK 追踪器" - } - } - } - }, - "device.role.name.tracker" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tracker" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tracker" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Трекер" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "追踪器" - } - } - } - }, - "device.role.repeater" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Infrastruktur-Knoten nur auf einem Turm oder einer Bergspitze. Nicht für Dächer oder mobile Knoten verwenden. Übermittelt Nachrichten mit minimalem Mehraufwand. Nicht sichtbar in der Knotenliste." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Infrastructure node on a tower or mountain top only. Not to be used for roofs or mobile nodes. Relays messages with minimal overhead. Not visible in Nodes list." - } - }, - "fr" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Noeud d'infrastructure qui étend la couverture du réseau en relayant les messages avec un minimum de surcharge. Invisible dans la liste des noeuds." - } - }, - "he" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "מכשיר תשתית להרחבת המש על ידי העברת הודעות עם דאטה נוסף מינימלי." - } - }, - "pl" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Przekaźnik - Pakiety siatki będą preferować trasowanie przez ten węzeł. Ta rola eliminuje niepotrzebny nadmiar, taki jak NodeInfo, DeviceTelemetry i inne pakiety siatki, skutkując tym, że urządzenie nie będzie widoczne jako część sieci. Proszę zobaczyć tryb Rebroadcast dla dodatkowych ustawień specyficznych dla tej roli." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Nó de infraestrutura para ampliar a cobertura da rede transmitindo mensagens com sobrecarga mínima. Não visível na lista de Nós." - } - }, - "se" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Infrastrukturnod för att utöka nätverkstäckningen genom att vidarebefordra meddelanden med minimal overhead. Syns inte i Noder-listan." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Инфраструктурни чвор само на торњу или врху планине. Није намењен за кровове или мобилне чворове. Прослеђује поруке уз минимално оптерећење. Није видљив у листи чворова." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "仅用于塔顶或山顶的基础设施节点。 不得用于屋顶或移动节点。以最小的开销中继信息。在节点列表中不可见。" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "中繼模式 - Mesh 網路數據包將優先通過此中繼點路由。此模式可消除不必要的開銷,如 NodeInfo、DeviceTelemetry 和任何其他 Mesh 數據包,從而使設備不顯示為 Mesh 網路的一部分。有關此角色的其他特定設置,請參閱轉播模式。" - } - } - } - }, - "device.role.router" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Router - Mesh Pakete werden bevorzugt über diesen Knoten gerouted. Dieser Knoten wird nicht von einer Client App benutzt. WLAN, Bluetooth und Display sind aus." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Infrastructure node on a tower or mountain top only. Not to be used for roofs or mobile nodes. Needs exceptional coverage. Visible in Nodes list." - } - }, - "fr" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Noeud d'infrastructure qui étend la couverture du réseau en relayant les messages. Visible dans la liste des noeuds." - } - }, - "he" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "מכשיר תשתית להרחבת המש על ידי העברת הודעות. מופיע ברשימת מכשירים." - } - }, - "pl" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Router - Pakiety siatki będą preferować trasowanie przez ten węzeł. Zakłada, że urządzenie będzie działać samodzielnie, umieszczone w miejscu z przewagą zasięgu. UWAGA: Radia BLE/Wi-Fi i ekran OLED zostaną uśpione." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Nó de infraestrutura para ampliar a cobertura da rede transmitindo mensagens. Visível na lista de Nós." - } - }, - "se" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Infrastrukturnod för att utöka nätverkstäckningen genom att vidarebefordra meddelanden. Synlig i Noder-listan." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Инфраструктурни чвор само на торњу или врху планине. Не користи се за кровове или мобилне чворове. Потребна му је изузетна покривеност. Видљиво на листи чворова." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "仅用于塔顶或山顶的基础设施节点。 不得用于屋顶或移动节点。 需要特殊的覆盖范围。在节点列表中可见。" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "纯路由模式 - 自動轉發 Mesh 網路中其他中繼點的消息,中繼模式下螢幕會熄滅,Wi-Fi 和藍芽將會進入睡眠模式,App 將無法連接到電台進行收發操作。" - } - } - } - }, - "device.role.routerclient" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Router Client - Mesh Pakete werden bevorzugt über diesen Knoten gerouted. Der Router Client kann parallel auch von einer Client-App genutzt werden." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Deprecated role use client." - } - }, - "fr" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Combinaison des modes ROUTER et CLIENT. Pas pour les appareils mobiles." - } - }, - "he" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "קומבינציה של ROUTER וCLIENT. לא למכשירים ניידים." - } - }, - "pl" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Router Client - Hybryda ról klienta i routera. Podobnie jak w przypadku routera, z tym że Router Client może być używany zarówno jako router, jak i klient połączony z aplikacją. Radia BLE/Wi-Fi i ekran OLED nie zostaną uśpione." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Combinação de ROTEADOR e CLIENTE. Não para dispositivos móveis." - } - }, - "se" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Kombination av både ROUTER och CLIENT. Inte för mobila enheter." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Застарело. Користи клијент ролу." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "已废弃的角色,使用客户端。" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "路由客户端模式 - 優先轉發 Mesh 網路中其他中繼點的消息,App 也可以連接到電台進行收發操作。" - } - } - } - }, - "device.role.routerlate" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Infrastrukturknoten, der Pakete immer nur einmal weiterleitet, aber erst nach allen anderen Betriebsarten, um eine zusätzliche Abdeckung für lokale Cluster zu gewährleisten. Sichtbar in der Liste der Knoten." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Infrastructure node that always rebroadcasts packets once but only after all other modes, ensuring additional coverage for local clusters. Visible in Nodes list." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Нод инфраструктуре који увек поново преноси пакете једном, али тек након свих других начина, обезбеђујући додатно покриће за локалне кластере. Видљив на листи нодова." - } - } - } - }, - "device.role.sensor" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sendet Telemetriepakete mit Priorität." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Broadcasts telemetry packets as priority." - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Transmet les paquets de télémétrie en priorité." - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "משדר טלמטריה בעדיפות גבוהה." - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Broadcasts telemetry packets as priority." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Transmite pacotes de telemetria como prioridade." - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sänder ut telemetripaket som prioritet." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Емитује телеметријске пакете као приоритет." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "将遥测数据包优先广播。" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "傳感器模式 - 優先廣播傳感器數據包" - } - } - } - }, - "device.role.tak" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Optimiert für ATAK-Systemkommunikation, verringert die Anzahl der Routineübertragungen." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Optimized for ATAK system communication, reduces routine broadcasts." - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Optimisé pour le système de communication ATAK, diminue les émissions de routine." - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "מותאם למערכת ATAK, מקטין תקשורת קבועה." - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Optimized for ATAK system communication, reduces routine broadcasts." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Otimizado para comunicação do sistema ATAK, reduz transmissões rotineiras." - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Optimerad för kommunikation med ATAK-systemet, minskar rutinutsändningar." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Оптимизован за комуникацију са ATAK системом, смањује рутинске емисије." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "针对 ATAK 系统通信进行优化,减少常规广播。" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "TAK模式 - 優化了 ATAK 系統通訊,減少常規廣播。" - } - } - } - }, - "device.role.taktracker" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Aktiviert automatische TAK-PLI-Übertragungen und verringert die Anzahl der Routineübertragungen." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enables automatic TAK PLI broadcasts and reduces routine broadcasts." - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enables automatic TAK PLI broadcasts and reduces routine broadcasts." - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enables automatic TAK PLI broadcasts and reduces routine broadcasts." - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enables automatic TAK PLI broadcasts and reduces routine broadcasts." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Permite transmissões automáticas de TAK PLI e reduz transmissões rotineiras." - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Aktiverar automatiska TAK PLI-utsändningar och minskar rutinutsändningar." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Омогућава аутоматске TAK PLI емисије и смањује рутинске емисије." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "启用自动 TAK PLI(Position Location Information)广播,并减少常规广播。" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "TAK TRACKER追蹤器 - 啟用自動 TAK PLI 廣播並減少常規廣播。" - } - } - } - }, - "device.role.tracker" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sendet GPS-Positionspakete mit Priorität." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Broadcasts GPS position packets as priority." - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Transmet les paquets de positions GPS en priorité." - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "משדר מיקום GPS בעדיפות גבוהה." - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tracker - Do użytku z urządzeniami przeznaczonymi jako śledzenie GPS. Pakiety pozycyjne wysyłane z tego urządzenia będą miały wyższy priorytet, z nadawaniem pozycji co dwie minuty. Inteligentna transmisja pozycji będzie domyślnie wyłączona." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Transmite pacotes de posição GPS como prioridade." - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sänder ut GPS-positionspaket som prioritet." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Емитује пакете са GPS позицијом као приоритет." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "定位模式 - 用于作为 GPS 跟踪器。从该设备发送的定位数据包优先级较高,每两分钟广播一次。智能位置广播默认为关闭。" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "追蹤模式 - 用於作為 GPS 追蹤器。從該設備發送的定位數據包優先級較高,每兩分鐘廣播一次。智能位置廣播預設為關閉。" + "value" : "裝置僅在必要時廣播,以達到隱蔽性或節能目的。" } } } }, "Dilution of precision (DOP) PDOP used by default" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Diluizione della precisione (DOP) PDOP utilizzato per impostazione predefinita" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Разређење прецизности (DOP) PDOP се користи као подразумевано" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "精度稀釋(DOP),預設使用 PDOP" + } } } }, @@ -8526,6 +9339,12 @@ "value" : "Direkt" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Diretto" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -8537,11 +9356,23 @@ "state" : "translated", "value" : "直频" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "直連" + } } } }, "Direct Message Help" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aiuto per i messaggi diretti" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -8553,42 +9384,16 @@ "state" : "translated", "value" : "私信帮助" } - } - } - }, - "Direct messages are using the new public key infrastructure for encryption. Requires firmware version 2.5 or greater." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Директне поруке користе нову инфраструктуру јавних кључева за енкрипцију. Захтева верзију фирмвера 2.5 или новију." - } }, - "zh-Hans" : { + "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "私聊使用新的公钥基础设施进行加密。需要 2.5 或更高版本的固件。" + "value" : "私訊功能使用指南" } } } }, - "Direct messages are using the shared key for the channel." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Директне поруке користе дељени кључ за канал." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "私聊使用频道的共享密钥。" - } - } - } - }, - "direct.messages" : { + "Direct Messages" : { "localizations" : { "de" : { "stringUnit" : { @@ -8596,12 +9401,6 @@ "value" : "Direktnachrichten" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Direct Messages" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -8614,18 +9413,18 @@ "value" : "הודעה פרטית" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Messaggi diretti" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Bezpośrednie Wiadomości" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mensagens Directas" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -8647,7 +9446,63 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "聊天" + "value" : "私人訊息" + } + } + } + }, + "Direct messages are using the new public key infrastructure for encryption. Requires firmware version 2.5 or greater." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "I messaggi diretti utilizzano la nuova infrastruttura a chiave pubblica per la crittografia. Richiede la versione firmware 2.5 o superiore." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Директне поруке користе нову инфраструктуру јавних кључева за енкрипцију. Захтева верзију фирмвера 2.5 или новију." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "私聊使用新的公钥基础设施进行加密。需要 2.5 或更高版本的固件。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "私訊已使用新的公開金鑰基礎設施進行加密,需韌體版本 2.5 或更高版本才能支援。" + } + } + } + }, + "Direct messages are using the shared key for the channel." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "I messaggi diretti utilizzano la chiave condivisa del canale." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Директне поруке користе дељени кључ за канал." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "私聊使用频道的共享密钥。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "私訊使用共用金鑰進行加密傳輸。" } } } @@ -8657,7 +9512,37 @@ "de" : { "stringUnit" : { "state" : "translated", - "value" : "Ausgeschaltet" + "value" : "Deaktiviert" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Désactivé" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "כבוי" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Disattivato" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wyłączony" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inaktiverad" } }, "sr" : { @@ -8671,6 +9556,12 @@ "state" : "translated", "value" : "禁用" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "關閉" + } } } }, @@ -8682,12 +9573,6 @@ "value" : "Trennen" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Disconnect" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -8700,18 +9585,18 @@ "value" : "התנתק" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Disconnessione" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Rozłącz" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Desconectar" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -8746,12 +9631,6 @@ "value" : "Tastatur ausblenden" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dismiss" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -8764,18 +9643,18 @@ "value" : "סגור מקלדת" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sospendere" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Zamknij" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dispensar" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -8810,12 +9689,6 @@ "value" : "Display (Device Screen)" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Display" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -8828,18 +9701,18 @@ "value" : "צג מכשיר" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Display" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Wyświetlacz (Ekran Urządzenia)" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Icrã" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -8861,67 +9734,13 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "螢幕(電台螢幕)" + "value" : "螢幕" } } } }, - "Display Fahrenheit" : { + "Display Config" : { "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Приказ фаренхајта" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "展示华氏度" - } - } - } - }, - "Display Mode" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Режим приказа" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "显示模式" - } - } - } - }, - "Display Units" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Јединице приказа" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "显示单位" - } - } - } - }, - "display.config" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Display Config" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -8934,18 +9753,18 @@ "value" : "הגדרות צג" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione del display" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Konfiguracja Wyświetlacza" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração do Icrãn" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -8972,49 +9791,160 @@ } } }, - "distance" : { - "extractionState" : "migrated", + "Display config received: %@" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Entfernung" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Distance" + "value" : "Display Konfiguration empfangen: %@" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Distance" + "value" : "Configuration de l'écran reçue : %@" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "מרחק" + "value" : "הגדרות תצוגה התקבלו: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Visualizzazione della configurazione ricevuta: %@" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Odległość" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Distância" + "value" : "Otrzymano konfigurację wyświetlacza: %@" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Distans" + "value" : "Skärmkonfiguration mottagen: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Примљена конфигурација приказа: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Display config received: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Display config received: %@" + } + } + } + }, + "Display Fahrenheit" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Display Fahrenheit" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Приказ фаренхајта" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "展示华氏度" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "顯示華氏溫度" + } + } + } + }, + "Display Mode" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Modalità di visualizzazione" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Режим приказа" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "显示模式" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "顯示模式" + } + } + } + }, + "Display Units" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Unità di visualizzazione" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Јединице приказа" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "显示单位" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "顯示單位" + } + } + } + }, + "Distance" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Distanz" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Distanza" } }, "sr" : { @@ -9037,30 +9967,14 @@ } } }, - "Distance" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Distanz" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Раздаљина" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "距离" - } - } - } - }, "Documentation" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Documentazione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9072,11 +9986,23 @@ "state" : "translated", "value" : "文档" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "文檔" + } } } }, "Double Tap as Button" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Doppio tocco come pulsante" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9088,11 +10014,81 @@ "state" : "translated", "value" : "双击作为按钮" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "將雙擊作為按鈕使用" + } + } + } + }, + "Down" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Runter" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bas" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "למטה" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "In basso" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "W Dół" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ner" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Доле" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "下" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "下" + } } } }, "Downlink Enabled" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Downlink abilitato" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9104,11 +10100,23 @@ "state" : "translated", "value" : "启用下载" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "啟用下行(Downlink)" + } } } }, "Drag & Drop Firmware Update" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aggiornamento del firmware con il drag & drop" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9120,11 +10128,23 @@ "state" : "translated", "value" : "拖放升级固件" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "拖放更新韌體" + } } } }, "Drag & Drop Firmware Update Documentation" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Documentazione sull'aggiornamento del firmware con il drag & drop" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9136,11 +10156,23 @@ "state" : "translated", "value" : "拖放升级固件文档" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "拖放更新韌體操作說明" + } } } }, "Drag & Drop is the recommended way to update firmware for NRF devices. If your iPhone or iPad is USB-C it will work with your regular USB-C charging cable, for lightning devices you need the Apple Lightning to USB camera adaptor." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il Drag & Drop è il metodo consigliato per aggiornare il firmware dei dispositivi NRF. Se l'iPhone o l'iPad è USB-C funzionerà con il normale cavo di ricarica USB-C, mentre per i dispositivi lightning è necessario l'adattatore Apple Lightning to USB camera." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9152,33 +10184,107 @@ "state" : "translated", "value" : "拖放是更新 NRF 设备固件的推荐方式。如果您的 iPhone 或 iPad 是 USB-C 接口,则可以使用普通的 USB-C 充电线;如果是 Lightning 设备,则需要使用 Apple Lightning to USB 摄像头适配器。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "拖放(Drag & Drop)是更新 NRF 裝置韌體的建議方式。如果您的 iPhone 或 iPad 是 USB-C 版本,可以直接使用一般的 USB-C 充電線。若是 Lightning 裝置,則需要使用 Apple 的 Lightning 對 USB 相機轉接器。" + } + } + } + }, + "driving" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "fahren" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "guida" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "вожња" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "驾驶" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "開車" + } + } + } + }, + "Driving" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fahren" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Guida" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Вожња аута" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "驾驶" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "開車" + } } } }, "Drop Pin in Maps" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Spillo in Mappe" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Постави ознаку на мапама" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "在地圖上放置圖釘" + } } } }, - "echo" : { + "Echo" : { "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Echo" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Echo" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -9191,13 +10297,7 @@ "value" : "הד" } }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Echo" - } - }, - "pt-PT" : { + "it" : { "stringUnit" : { "state" : "translated", "value" : "Eco" @@ -9224,98 +10324,121 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "echo" + "value" : "Echo" } } } }, "Editing Waypoint" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Modifica di Waypoint" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Уређивање путне тачке" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "編輯路徑點" + } + } + } + }, + "Eighteen Hours" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Achtzehn Stunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dix huit heures" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שמונה עשר שעות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Diciotto ore" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Osiemnaście Godzin" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Arton Timmar" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Осамнаест сати" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "十八小时" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "18 小時" + } } } }, "Elev. Gain" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Elev. Guadagno" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Повећање надморске висине" } - } - } - }, - "email.address" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Email Adresse" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Email Address" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Adresse mail" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "כתובת דואר אלקטרוני" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Adres Email" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Endereço de Email" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "E-postadress" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Имејл адреса" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "邮件地址" - } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "電子信箱" + "value" : "爬升高度" } } } }, "Emoji" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Emoji" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9327,11 +10450,23 @@ "state" : "translated", "value" : "Emoji" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Emoji" + } } } }, "Empty" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vuoto" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9343,21 +10478,39 @@ "state" : "translated", "value" : "空" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "空白" + } } } }, "Enable broadcasting packets via UDP over the local network." : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Омогућите емитовање пакета путем UDP-а преко локалне мреже." + "value" : "Abilita la trasmissione di pacchetti via UDP sulla rete locale." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "啟用透過本地網路以 UDP 廣播封包。" } } } }, "Enable Notifications" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Abilita le notifiche" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9369,20 +10522,32 @@ "state" : "translated", "value" : "启用通知" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "啟用通知" + } } } }, "Enable this device as a Store and Forward server. Requires an ESP32 device with PSRAM." : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Омогућите овај уређај као сервер за складиштење и прослеђивање. Захтева ESP32 уређај са PSRAM-ом." + "value" : "Abilita questo dispositivo come server Store and Forward. Richiede un dispositivo ESP32 con PSRAM." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "啟用此裝置作為儲存與轉送伺服器。需使用具備 PSRAM 的 ESP32 裝置。" } } } }, - "enabled" : { + "Enabled" : { "localizations" : { "de" : { "stringUnit" : { @@ -9390,12 +10555,6 @@ "value" : "Aktiviert" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enabled" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -9408,18 +10567,18 @@ "value" : "מופעל" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Abilitato" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Włączony" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Activado" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -9446,8 +10605,72 @@ } } }, + "Enables automatic TAK PLI broadcasts and reduces routine broadcasts." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aktiviert automatische TAK-PLI-Übertragungen und verringert die Anzahl der Routineübertragungen." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enables automatic TAK PLI broadcasts and reduces routine broadcasts." + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enables automatic TAK PLI broadcasts and reduces routine broadcasts." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Abilita le trasmissioni automatiche di TAK PLI e riduce le trasmissioni di routine." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enables automatic TAK PLI broadcasts and reduces routine broadcasts." + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aktiverar automatiska TAK PLI-utsändningar och minskar rutinutsändningar." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Омогућава аутоматске TAK PLI емисије и смањује рутинске емисије." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用自动 TAK PLI(Position Location Information)广播,并减少常规广播。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "啟用自動傳送 TAK PLI 資訊,並降低例行廣播頻率。" + } + } + } + }, "Enables devices with native I2S audio output to use the RTTTL over speaker like a buzzer. T-Watch S3 and T-Deck for example have this capability." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Consente ai dispositivi con uscita audio I2S nativa di utilizzare l'RTTTL tramite altoparlante come un cicalino. T-Watch S3 e T-Deck, ad esempio, dispongono di questa funzionalità." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9459,11 +10682,23 @@ "state" : "translated", "value" : "使具有本地 I2S 音频输出的设备能够通过扬声器使用 RTTTL,就像使用蜂鸣器一样。例如,T-Watch S3 和 T-Deck 就具有这种功能。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "啟用具備原生 I2S 音訊輸出的裝置,透過喇叭以類似蜂鳴器的方式播放 RTTTL。以 T-Watch S3 和 T-Deck 為例,它們就具備此功能。" + } } } }, "Enables the detection sensor module, it needs to be enabled on both the node with the sensor, and any nodes that you want to receive detection sensor text messages or view the detection sensor log and chart." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Abilita il modulo del sensore di rilevamento; deve essere abilitato sia sul nodo con il sensore, sia su tutti i nodi che si desidera ricevere messaggi di testo del sensore di rilevamento o visualizzare il registro e il grafico del sensore di rilevamento." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9475,21 +10710,33 @@ "state" : "translated", "value" : "启用检测传感器模块,需要在装有传感器的节点和要接收检测传感器文本信息或查看检测传感器日志和图表的任何节点上启用该模块。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "啟用偵測感測器模組。此功能需在裝有感測器的節點及希望接收偵測感測器文字訊息或瀏覽偵測日誌與圖表的節點上同時啟用。" + } } } }, "Enables the store and forward module." : { "localizations" : { - "sr" : { + "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Омогућава модул за складиштење и прослеђивање." + "value" : "啟用儲存與轉送(Store and Forward)模組" } } } }, "Enabling Ethernet will disable the bluetooth connection to the app." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Abilitando l'Ethernet si disabilita la connessione bluetooth all'applicazione." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9501,11 +10748,23 @@ "state" : "translated", "value" : "启用以太网将禁用应用程序的蓝牙连接。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "啟用乙太網路後,將會停用與應用程式的藍牙連線。" + } } } }, "Enabling WiFi will disable the bluetooth connection to the app." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "L'attivazione del WiFi disabilita la connessione bluetooth all'applicazione." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9517,20 +10776,38 @@ "state" : "translated", "value" : "启用 WiFi 将禁用应用程序的蓝牙连接。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "啟用 Wi-Fi 後,將會停用與應用程式的藍牙連線。" + } } } }, "Encoder Press Event" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Evento di pressione dell'encoder" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Догађај притиска енкодера" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "編碼器按壓事件" + } } } }, - "encrypted" : { + "Encrypted" : { "localizations" : { "de" : { "stringUnit" : { @@ -9538,12 +10815,6 @@ "value" : "Verschlüsselt" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Encrypted" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -9556,18 +10827,18 @@ "value" : "מוצפן" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Crittografato" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Zaszyfrowany" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Encriptado" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -9589,35 +10860,47 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "加密" + "value" : "已加密" } } } }, - "Encrypted" : { + "Encrypted Send Failed" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Verschlüsselt" + "value" : "Verschlüsseltes Senden fehlgeschlagen" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Invio crittografato fallito" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Шифровано" + "value" : "Шифровано слање није успело" } }, - "zh-Hans" : { + "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "加密" + "value" : "加密傳送失敗" } } } }, "Encryption Enabled" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Crittografia abilitata" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9629,6 +10912,12 @@ "state" : "translated", "value" : "启用加密" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "加密已啟用" + } } } }, @@ -9640,6 +10929,12 @@ "value" : "DFÜ-Modus aktivieren" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Entrare in modalità DFU" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9651,11 +10946,23 @@ "state" : "translated", "value" : "进入 DFU 模式" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "進入 DFU 模式" + } } } }, "environment" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "ambiente" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9667,6 +10974,12 @@ "state" : "translated", "value" : "环境" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "環境" + } } } }, @@ -9678,6 +10991,12 @@ "value" : "Umgebung" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ambiente" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9689,11 +11008,51 @@ "state" : "translated", "value" : "环境" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "環境" + } + } + } + }, + "Environment Metrics" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Metriche dei sensori" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Метрике сензора" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "传感器指标" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "傳感器數據" + } } } }, "Environment Metrics Log" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Registro delle metriche ambientali" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9705,6 +11064,12 @@ "state" : "translated", "value" : "环境指标日志" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "環境數據記錄" + } } } }, @@ -9716,6 +11081,12 @@ "value" : "Alle App-Daten löschen?" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancellare tutti i dati delle app?" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9727,6 +11098,12 @@ "state" : "translated", "value" : "擦除所有 App 数据?" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "刪除所有 App 數據?" + } } } }, @@ -9738,6 +11115,12 @@ "value" : "Alle Geräte- und App-Daten löschen?" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancellare tutti i dati del dispositivo e delle app?" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9749,11 +11132,23 @@ "state" : "translated", "value" : "擦除所有设备和 App 数据?" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "刪除所有裝置及 App 數據?" + } } } }, "Error: %@" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Errore: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9765,11 +11160,23 @@ "state" : "translated", "value" : "错误:%@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "錯誤:%@" + } } } }, "ESP 32 OTA update is a work in progress, click the button below to send your device a reboot into ota admin message." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "L'aggiornamento OTA di ESP 32 è in corso, fare clic sul pulsante qui sotto per inviare al dispositivo un messaggio di riavvio in amministrazione ota." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9781,11 +11188,23 @@ "state" : "translated", "value" : "ESP 32 OTA 更新正在进行中,请单击下面的按钮向您的设备发送重新启动进入 OTA 管理信息。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "ESP32 的 OTA 更新功能尚在開發中,請點擊下方按鈕以傳送重新啟動至 OTA 管理模式的訊息至您的裝置。" + } } } }, "ESP32 Device Firmware Update" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aggiornamento del firmware del dispositivo ESP32" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -9797,26 +11216,43 @@ "state" : "translated", "value" : "ESP32 设备固件升级" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "ESP32 裝置韌體更新" + } } } }, "Ethernet Options" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Opzioni Ethernet" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Етернет опције" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "乙太網路選項" + } } } }, "European Union 433MHz" : { - "extractionState" : "manual", "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "European Union 433MHz" + "value" : "Unione Europea 433MHz" } }, "sr" : { @@ -9824,16 +11260,21 @@ "state" : "translated", "value" : "Европска унија 433MHz" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "歐盟 433MHz" + } } } }, "European Union 868MHz" : { - "extractionState" : "manual", "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "European Union 868MHz" + "value" : "Unione Europea 868MHz" } }, "sr" : { @@ -9841,91 +11282,195 @@ "state" : "translated", "value" : "Европска унија 868MHz" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "歐盟 868MHz" + } + } + } + }, + "Evening" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Abend" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sera" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Вече" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "下午" + } } } }, "Exchange Positions" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Scambio di posizioni" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Размени локације" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "交換位置" + } + } + } + }, + "Exclamation" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ausrufezeichen" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Point d'exclamation" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "סימן קריאה" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Esclamativo" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wykrzyknik" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Utropstecken" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Узвичник" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "感叹号" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "驚嘆號" + } } } }, "Expire" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Scadenza" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Истиче" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "過期" + } } } }, "Expires" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Scadenza" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Истиче" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "過期" + } } } }, "Expires: %@" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Scadenza: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Истиче: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "過期:%@" + } } } }, - "export" : { + "Export" : { "localizations" : { - "de" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Export" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Export" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Export" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Export" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Export" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Exportar" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Export" + "value" : "Esportazione" } }, "sr" : { @@ -9934,12 +11479,6 @@ "value" : "Извоз" } }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Export" - } - }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", @@ -9948,7 +11487,7 @@ } } }, - "external.notification" : { + "External Notification" : { "localizations" : { "de" : { "stringUnit" : { @@ -9956,12 +11495,6 @@ "value" : "Externe Benachrichtigung" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "External Notification" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -9974,18 +11507,18 @@ "value" : "נוטיפיקציה חיצונית" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Notifica esterna" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Zewnętrzne Powiadomienie" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Notificação Externa" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -10012,7 +11545,7 @@ } } }, - "external.notification.config" : { + "External Notification Config" : { "localizations" : { "de" : { "stringUnit" : { @@ -10020,12 +11553,6 @@ "value" : "Einstellungen der externen Benachrichtigung" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "External Notification Config" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -10038,18 +11565,18 @@ "value" : "הגדרות נוטיפיקציה חיצונית" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione della notifica esterna" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Konfiguracja Zewnętrznego Powiadomienia" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração de Notificação Externa" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -10076,6 +11603,58 @@ } } }, + "External Notification module config received: %@" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configuration du module notification extérieure reçue : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הגדרות מודולת נוטיפיקציה חיצונית התקבלו: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione del modulo di notifica esterno ricevuta: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Otrzymano konfigurację modułu zewnętrznych powiadomień: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Konfiguration för modulen för externa notifikationer mottagen: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Конфигурација модула за екстерне нотификације примљена: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "External Notification module config received: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "External Notification module config received: %@" + } + } + } + }, "Factory Reset" : { "localizations" : { "de" : { @@ -10084,11 +11663,23 @@ "value" : "Werkseinstellungen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Reset di fabbrica" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Ресетовање на фабричка подешавања" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "恢復原廠設定" + } } } }, @@ -10100,41 +11691,117 @@ "value" : "Gerät und App auf Werkseinstellungen zurücksetzen?" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Resettare il dispositivo e l'applicazione? " + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Вратите уређај и апликацију на фабричка подешавања?" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "要將您的裝置與應用程式恢復原廠設定嗎?" + } } } }, "Failed to encode message content" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Impossibile codificare il contenuto del messaggio" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Неуспело кодирање садржаја поруке" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "訊息內容編碼失敗" + } } } }, "Failed to get a valid position to exchange" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Impossibile ottenere una posizione valida per lo scambio" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Добијање важеће позиције за размену није успело" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "無法取得有效的位置進行交換。" + } } } }, "Failed to get a valid position to exchange." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Impossibile ottenere una posizione valida per lo scambio." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Добијање важеће позиције за размену није успело." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "無法取得有效的位置進行交換。" + } + } + } + }, + "Fair" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ordentliche Signalstärke" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fiera" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Прихватљив" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "尚可" + } } } }, @@ -10146,11 +11813,23 @@ "value" : "Favorit" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Preferito" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Омиљени" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "最愛" + } } } }, @@ -10162,16 +11841,34 @@ "value" : "Favoriten" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Preferiti" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Омиљени" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "最愛" + } } } }, "Favorites and nodes with recent messages show up at the top of the contact list." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "I preferiti e i nodi con messaggi recenti appaiono in cima all'elenco dei contatti." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -10183,6 +11880,12 @@ "state" : "translated", "value" : "收藏夹和有最近信息的节点会显示在联系人列表的顶部。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "收藏項目和最近有訊息的節點會顯示在聯絡人列表的最上方。" + } } } }, @@ -10194,31 +11897,125 @@ "value" : "Letzte Position eines Knotens holen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Recuperare l'ultima posizione di un nodo cetaneo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Преузмите најновију позицију одређеног чвора" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "取得某個節點的最新位置" + } } } }, "Fifteen Minutes" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quindici minuti" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Петнаест минута" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "15 分鐘" + } + } + } + }, + "Fifteen Seconds" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fünfzehn Sekunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quinze secondes" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "חמש עשרה שניות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quindici secondi" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Piętnaście Sekund" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Femton Sekunder" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Петнаест секунди" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "十五秒" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "15 秒" + } } } }, "File Storage" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Archiviazione dei file" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Складиште података" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "檔案儲存" + } } } }, @@ -10230,11 +12027,23 @@ "value" : "Kontakt suchen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trova un contatto" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Пронађи контакт" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "搜尋聯絡人" + } } } }, @@ -10246,15 +12055,27 @@ "value" : "Einen Knoten finden" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trovare un nodo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Пронађи чвор" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "搜尋節點" + } } } }, - "finish" : { + "Finish" : { "localizations" : { "de" : { "stringUnit" : { @@ -10262,12 +12083,6 @@ "value" : "Beenden" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Finish" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -10280,18 +12095,18 @@ "value" : "סיים" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fine" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Finish" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Terminar" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -10326,6 +12141,12 @@ "value" : "Firmware" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Firmware" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -10337,11 +12158,23 @@ "state" : "translated", "value" : "固件" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "韌體" + } } } }, "Firmware update docs" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Documentazione sull'aggiornamento del firmware" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -10353,6 +12186,12 @@ "state" : "translated", "value" : "固件升级文档" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "韌體更新說明文件" + } } } }, @@ -10364,6 +12203,12 @@ "value" : "Firmwareaktualisierungen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aggiornamenti del firmware" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -10375,10 +12220,16 @@ "state" : "translated", "value" : "固件升级" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "韌體更新" + } } } }, - "firmware.version" : { + "Firmware Version" : { "localizations" : { "de" : { "stringUnit" : { @@ -10386,12 +12237,6 @@ "value" : "Firmware Version" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Firmware Version" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -10404,18 +12249,18 @@ "value" : "גרסת קושחה" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Versione del firmware" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Wersja Oprogramowania" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Versão do Firmware" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -10442,77 +12287,82 @@ } } }, - "firmware.version.unsupported" : { - "extractionState" : "migrated", + "First heard" : { "localizations" : { - "de" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Nicht unterstützte Firmware Version erkannt. Kann nicht verbinden." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Unsupported Firmware Version Detected, unable to connect to device." - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Version non supportée du firmware détectée, impossible de se connecter à l'appareil." - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "גרסת קושחה אינה נתמכת, לא ניתן להתחבר למכשיר." - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wykryto nieobsługiwany wersję oprogramowania, brak możliwości połączenia z urządzeniem." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Versão de Firmware não suportada detetada, impossível conectar ao dispositivo." - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Okänd Firmwareversion upptäckt, kan inte ansluta till enheten." + "value" : "Sentito per la prima volta" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Откривена је неподржана верзија фирмвера, није могуће повезати са уређајем." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "检测到不支持的固件版本,无法连接到设备。" + "value" : "Прво откривање" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "檢測到不支援的韌體版本,無法連接到電台。" + "value" : "首次通訊" } } } }, - "First heard" : { + "Five Hours" : { "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fünf Stunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cinq heures" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "חמש שעות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cinque ore" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pięć Godzin" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fem Timmar" + } + }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Прво откривање" + "value" : "Пет сати" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "五小时" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "5 小時" } } } @@ -10525,11 +12375,81 @@ "value" : "Fünf Minuten" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cinque minuti" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Пет минута" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "5 分鐘" + } + } + } + }, + "Five Seconds" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fünf Sekunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cinq secondes" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "חמש שניות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cinque secondi" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pięć Sekund" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fem Sekunder" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Пет секунди" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "五秒" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "5 秒" + } } } }, @@ -10541,12 +12461,6 @@ "value" : "Feste PIN" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fixed PIN" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -10559,18 +12473,18 @@ "value" : "קוד קבוע" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "PIN fisso" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Stały PIN" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "PIN fixo" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -10599,36 +12513,194 @@ }, "Fixed Position" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Posizione fissa" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Фиксна локација" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "固定位置" + } } } }, "Flip Screen" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Schermo ribaltabile" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Окрени екран" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "翻轉畫面" + } } } }, "Flip screen vertically" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Capovolgere lo schermo in verticale" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Окрени екран вертикално" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "將螢幕畫面垂直翻轉顯示" + } + } + } + }, + "Follow" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Folgen" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Suivre" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "עקוב" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Seguire" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Śledź" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Följ" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Прати" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "跟随" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "置中" + } + } + } + }, + "Follow with heading" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Folgen mit Steuerkurs" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Suivre avec le cap" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "עקוב עם כיוון" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Seguire con l'intestazione" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Śledź z kierunkiem" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Följ med riktning" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Прати са правцем" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "跟随航向" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "跟隨與方向" + } } } }, "For all Mqtt functionality other than the map report you must also set uplink and downlink for each channel you want to bridge over Mqtt." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Per tutte le funzionalità Mqtt diverse dal rapporto sulle mappe, è necessario impostare anche l'uplink e il downlink per ogni canale che si desidera collegare tramite Mqtt." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -10640,6 +12712,12 @@ "state" : "translated", "value" : "对于除地图报告外的所有 MQTT 功能,您还必须为希望通过 MQTT 桥接的每个信道设置上行和下行链路。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "除了地圖回報之外,若要使用其他所有 MQTT 功能,您必須為每個想透過 MQTT 橋接的頻道設定上行(Uplink)與下行(Downlink)參數。" + } } } }, @@ -10651,11 +12729,23 @@ "value" : "Für alle" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Per tutti" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "За све" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "對所有人" + } } } }, @@ -10667,11 +12757,255 @@ "value" : "Für mich" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Per me" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "За мене" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "對自己" + } + } + } + }, + "Forty Eight Hours" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Achtundvierzig Stunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quarante huit heures" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "ארבעים ושמונה שעות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quarantotto ore" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Czterdzieści Osiem Godzin" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fyrtioåtta Timmar" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Четртесет и осам сати" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "四十八小时" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "48小時" + } + } + } + }, + "Forty Five Seconds" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fündundvierzig Sekunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quarante cinq secondes" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "ארבעים וחמש שניות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quarantacinque secondi" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Czterdzieści Pięć Sekund" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fyrtiofem Sekunder" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Четрдесет и пет секунди" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "四十五秒" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "45 秒" + } + } + } + }, + "Four Hours" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vier Stunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quatre heures" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "ארבע שעות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quattro ore" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cztery Godziny" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fyra Timmar" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Четири сата" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "四小时" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "4 小時" + } + } + } + }, + "Four Seconds" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vier Sekunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quatre secondes" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "ארבע שניות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quattro secondi" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cztery Sekundy" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fyra Sekunder" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Четири секунде" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "四秒" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "4 秒" + } } } }, @@ -10683,36 +13017,78 @@ "value" : "Frequenz" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Frequenza" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Фреквенција" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻率" + } } } }, "Frequency Override" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Override di frequenza" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Измена фреквенције" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻率覆寫(Frequency Override)" + } } } }, "Frequency Slot" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Slot di frequenza" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Фреквенцијски слот" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻率槽位" + } } } }, "Friendly name" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nome amichevole" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -10724,11 +13100,23 @@ "state" : "translated", "value" : "友好名称" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "友善名稱" + } } } }, "Friendly name used to format message sent to mesh. Example: A name \"Motion\" would result in a message \"Motion detected\"" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nome amichevole usato per formattare il messaggio inviato alla rete. Esempio: Il nome \"Movimento\" si tradurrebbe nel messaggio \"Movimento rilevato\"" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -10740,144 +13128,32 @@ "state" : "translated", "value" : "用于格式化发送到 Mesh 网络的信息的友好名称。例如名称为 “运动”时,发送的信息为 “检测到运动”。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "用來格式化發送到 Mesh 網路的友善名稱。例如:名稱設定為「移動」,則傳送的訊息將會是「偵測到移動」。" + } } } }, "Full Support" : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Потпуна подршка" - } - } - } - }, - "gas" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gas" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gas" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gaz" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "דלק" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gaz" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gas" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gas" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Гас" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "气体" + "value" : "Supporto completo" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Gas" + "value" : "完整支援" } } } }, - "gas.resistance" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gas Resistance" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Résistence du gaz" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gas Resistance" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Odporność na Gaz" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Resistência ao Gas" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gasmotstånd" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Отпорност на гас" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "气体阻抗" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gas Resistance" - } - } - } - }, - "generate.qr.code" : { + "Generate QR Code" : { "localizations" : { "de" : { "stringUnit" : { @@ -10885,12 +13161,6 @@ "value" : "QR Code Erzeugen" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Generate QR Code" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -10903,18 +13173,18 @@ "value" : "צור קוד QR" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Generare un codice QR" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Generuj Kod QR" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gerar Código QR" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -10936,18 +13206,30 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "生成QRcode" + "value" : "生成 QRcode" } } } }, "Get custom waterproof solar and detection sensor router nodes, aluminium desktop nodes and rugged handsets." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nodi router con sensori solari e di rilevamento personalizzati e impermeabili, nodi da tavolo in alluminio e portatili robusti." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Набавите прилагођене водоотпорне соларне и детекционе сензорске рутер чворове, алуминијумске десктоп чворове и издржљиве мобилне уређаје." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "提供客製化防水太陽能感測路由器節點、鋁製桌面節點,以及耐候型手持裝置。" + } } } }, @@ -10959,6 +13241,12 @@ "value" : "Knotenposition ermitteln" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ottenere la posizione del nodo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -10970,11 +13258,23 @@ "state" : "translated", "value" : "获取节点位置" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "取得 Node 位置" + } } } }, "Get NRF DFU from the App Store" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Scarica NRF DFU dall'App Store" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -10986,11 +13286,23 @@ "state" : "translated", "value" : "从 App Store 获取 NRF DFU" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "從 App Store 下載 NRF DFU" + } } } }, "Get the latest alpha firmware" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ottenere l'ultimo firmware alfa" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -11002,11 +13314,23 @@ "state" : "translated", "value" : "获取最新测试版固件" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "取得最新的Alpha版本韌體" + } } } }, "Get the latest stable firmware" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ottenere l'ultimo firmware stabile" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -11018,11 +13342,45 @@ "state" : "translated", "value" : "获取最新稳定版固件" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "取得最新的穩定版本韌體" + } + } + } + }, + "Good" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Buono" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Добро" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "良好" + } } } }, "GPIO" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "GPIO" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -11034,61 +13392,133 @@ "state" : "translated", "value" : "GPIO" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "GPIO" + } } } }, "GPIO Output Duration" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Durata dell'uscita GPIO" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Трајање GPIO излаза" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "GPIO 輸出長度" + } } } }, "GPIO pin for rotary encoder A port." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pin GPIO per la porta A dell'encoder rotativo." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "GPIO пин за A порт ротационог енкодера." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "旋轉編碼器 A 埠對應的 GPIO 腳位。" + } } } }, "GPIO pin for rotary encoder B port." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pin GPIO per la porta B dell'encoder rotativo." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "GPIO пин за Б порт ротационог енкодера." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "旋轉編碼器 B 埠對應的 GPIO 腳位。" + } } } }, "GPIO pin for rotary encoder Press port." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pin GPIO per encoder rotativo Porta di stampa." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "GPIO пин за порт клика ротационог енкодера." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "旋轉編碼器按壓埠對應的 GPIO 腳位。" + } } } }, "GPIO Pin to monitor" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pin GPIO da monitorare" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "GPIO пин за надгледање" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "要監控的 GPIO 腳位" + } } } }, "GPS EN GPIO" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "GPS IT GPIO" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -11100,11 +13530,23 @@ "state" : "translated", "value" : "GPS EN GPIO" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "GPS 啟用 GPIO" + } } } }, "GPS Format" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Formato GPS" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -11116,11 +13558,23 @@ "state" : "translated", "value" : "GPS 格式" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "GPS 格式" + } } } }, "GPS Receive GPIO" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ricezione GPS GPIO" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -11132,11 +13586,23 @@ "state" : "translated", "value" : "GPS Receive GPIO" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "GPS 輸入 GPIO" + } } } }, "GPS Transmit GPIO" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trasmissione GPS GPIO" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -11148,548 +13614,11 @@ "state" : "translated", "value" : "GPS Transmit GPIO" } - } - } - }, - "gpsformat.dec" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dezimalgrad Format" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Decimal Degrees Format" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Format décimal pour les degrés" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "פורמט קואורדינטות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Format Dziesiętny Stopni" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Formato de Graus Decimais" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Decimalgrader" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Формат децималних степени" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "十进制" - } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "十進制" - } - } - } - }, - "gpsformat.dms" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Grad Minuten Sekunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Degrees Minutes Seconds" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Degrés Minutes Secondes" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "מעלות דקות שניות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Stopnie Minuty Sekundy" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Graus Minutos Segundos" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Grader Minuter Sekunder" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Степени Минути Секунде" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "度分秒" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "度分秒" - } - } - } - }, - "gpsformat.mgrs" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Militärisches Gitternetz-Referenzsystem" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Military Grid Reference System" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Military Grid Reference System" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Military Grid Reference System" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wojskowa siatka odniesienia" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sistema de Referência de Grelha Militar" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Militärt rutnätsreferenssystem" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Војни референтни систем мреже" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "军事网格参考系统" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "軍事網格參考系統" - } - } - } - }, - "gpsformat.olc" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Open Location Code (aka Plus Codes)" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Open Location Code (aka Plus Codes)" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Open Location Code (alias Plus Codes)" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Open Location Code (aka Plus Codes)" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Otwarty Kod Lokalizacji (tzw. Plus Kody)" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Código de Localização Aberto (também conhecido como Plus Codes)" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Öppen Platskod (även känd som Pluskoder)" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Отворени код локације (тј. Плус кодови)" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "开放的位置代码(又称加码)" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "開放位置代碼" - } - } - } - }, - "gpsformat.osgr" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ordnance Survey Gitterreferenz" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ordnance Survey Grid Reference" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ordnance Survey Grid Reference" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ordnance Survey Grid Reference" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Brytyjski Układ Odniesienia" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Referência de Grelha da Ordnance Survey" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ordnance Survey Rutnätsreferens" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Референца мреже Орданс Сурвеја" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "英国国土测量局网格参考" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "英國國土測量局網格參考系統" - } - } - } - }, - "gpsformat.utm" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Universal Transversal Mercator" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Universal Transverse Mercator" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Projection Mercator Transverse Universelle" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Universal Transverse Mercator" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Uniwersalny Układ Transwersalny Mercatora" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Universal Transverse Mercator" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Universal Transversal Mercator" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Универзални трансверзални Меркаторов пројекат" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "通用横轴墨卡托投影" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "通用橫軸墨卡托投影" - } - } - } - }, - "gpsmode.disabled" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ausgeschaltet" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Disabled" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Désactivé" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "כבוי" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Desativado" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Inaktiverad" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Онемогућен" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "禁用" - } - } - } - }, - "gpsmode.enabled" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Eingeschaltet" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enabled" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Activé" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "מופעל" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ativado" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Aktiverad" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Омогућен" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "启用" - } - } - } - }, - "gpsmode.notPresent" : { - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Not Present" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Absent" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "לא קיים" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Não Presente" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Inte närvarande" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Није пристуно" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "不存在" + "value" : "GPS 輸出 GPIO" } } } @@ -11702,6 +13631,12 @@ "value" : "Gruppennachricht" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Messaggio di gruppo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -11713,21 +13648,79 @@ "state" : "translated", "value" : "群聊" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "群組訊息" + } } } }, "Gusts %@" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Raffiche %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Јаки удари ветра %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "陣風 %@" + } + } + } + }, + "HaHa" : { + "localizations" : { + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "חחח" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "HaHa" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Хахаха" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "哈哈" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "哈哈" + } } } }, "Hardware" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hardware" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -11739,31 +13732,82 @@ "state" : "translated", "value" : "硬件" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "硬體" + } + } + } + }, + "Hazardous" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pericoloso" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Опасно" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "危險" + } } } }, "Heading" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Intestazione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Смер" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "朝向" + } } } }, "Heading: %@" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Intestazione: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Смер: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "朝向:%@" + } } } }, - "heard" : { - "extractionState" : "migrated", + "Heard" : { "localizations" : { "de" : { "stringUnit" : { @@ -11771,12 +13815,6 @@ "value" : "Gehört" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Heard" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -11789,18 +13827,18 @@ "value" : "נשמע" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ascoltato" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Usłyszano" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ouvido" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -11822,78 +13860,77 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "收到" + "value" : "通訊" } } } }, - "heard.last" : { - "extractionState" : "manual", + "Heart" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Zuletzt gehört" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Last Heard" + "value" : "Herz" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Capté pour la dernière fois" + "value" : "Coeur" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "נשמע לאחרונה" + "value" : "לב" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cuore" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Ostatnio Słyszane" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Último Ouvido" + "value" : "Serce" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Senast Hörd" + "value" : "Hjärta" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Прво откривање" + "value" : "Срце" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "最后收到" + "value" : "心" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "最後收到" + "value" : "心" } } } }, "Help with App Development" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aiuto per lo sviluppo di app" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -11905,26 +13942,56 @@ "state" : "translated", "value" : "帮助开发应用程序" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "幫助App開發" + } } } }, "Hide alerts" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nascondere gli avvisi" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Сакриј упозорења" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "靜音通知" + } } } }, "Hide Alerts" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nascondi avvisi" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Сакриј алертове" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "靜音通知" + } } } }, @@ -11936,6 +14003,12 @@ "value" : "HOCH" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "ALTO" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -11947,26 +14020,124 @@ "state" : "translated", "value" : "高" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "高" + } + } + } + }, + "hiking" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "wandern" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "escursione" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "планинарње" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "徒步" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "登山" + } + } + } + }, + "Hiking" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wandern" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Escursioni" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Планинарење" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "徒步" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "登山" + } } } }, "History Return Max" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Storia Rendimento Max" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Максимални повратак историје" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "歷史返回最大值" + } } } }, "History Return Window" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Finestra di restituzione della cronologia" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Временски прозор поврата историје" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "歷史返回時間範圍\n" + } } } }, @@ -11978,11 +14149,23 @@ "value" : "Hops Entfernt" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Via il luppolo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Скокови удаљености" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "跳數" + } } } }, @@ -11994,11 +14177,23 @@ "value" : "Hops Entfernt %d" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Luppolo lontano %d" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Удаљено %d скокова" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%d 個跳數" + } } } }, @@ -12010,11 +14205,23 @@ "value" : "Hops Entfernt:" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Via il luppolo:" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Скокови удаљености:" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "跳數距離:" + } } } }, @@ -12026,11 +14233,23 @@ "value" : "Hops Entfernt: %d" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Luppolo in partenza: %d" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Скокови удаљености: %d" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "跳數距離:%d" + } } } }, @@ -12042,6 +14261,12 @@ "value" : "Stunde" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ora" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12053,21 +14278,45 @@ "state" : "translated", "value" : "小时" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "小時" + } } } }, "Hourly Duty Cycle" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ciclo di lavoro orario" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Натпросечни циклус дужности по сату" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "每小時 Duty Cycle" + } } } }, "How long the screen remains on after the user button is pressed or messages are received." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Per quanto tempo lo schermo rimane acceso dopo la pressione del tasto utente o la ricezione di messaggi." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12079,11 +14328,23 @@ "state" : "translated", "value" : "按下用户按钮或收到消息后屏幕保持亮屏的时间。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "使用者按下按鈕或收到訊息後,螢幕維持亮起的時間長度。" + } } } }, "How often device metrics are sent out over the mesh. Default is 30 minutes." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Con quale frequenza vengono inviate le metriche del dispositivo attraverso la rete. L'impostazione predefinita è 30 minuti." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12095,27 +14356,23 @@ "state" : "translated", "value" : "设备指标通过网格发送的频率。默认为 30 分钟。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "裝置指標透過網狀網路發送的頻率。預設為每 30 分鐘一次。" + } } } }, - "How often power metrics are sent out over the mesh. Default is 30 minutes." : { + "How often environment metrics are sent out over the mesh. Default is 30 minutes." : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Колико често се метрике снаге шаљу преко мреже. Подразумевано је 30 минута." + "value" : "Con quale frequenza vengono inviate le metriche dei sensori sulla rete. L'impostazione predefinita è 30 minuti." } }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "通过网格发送功率指标的频率。默认为 30 分钟。" - } - } - } - }, - "How often sensor metrics are sent out over the mesh. Default is 30 minutes." : { - "localizations" : { "sr" : { "stringUnit" : { "state" : "translated", @@ -12127,11 +14384,51 @@ "state" : "translated", "value" : "通过网格发送传感器指标的频率。默认为 30 分钟。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "感測器數據透過網狀網路發送的頻率。預設為每 30 分鐘一次。\n" + } + } + } + }, + "How often power metrics are sent out over the mesh. Default is 30 minutes." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Con quale frequenza vengono inviate le metriche di potenza attraverso la rete. L'impostazione predefinita è 30 minuti." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Колико често се метрике снаге шаљу преко мреже. Подразумевано је 30 минута." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "通过网格发送功率指标的频率。默认为 30 分钟。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "電力指標透過網狀網路發送的頻率。預設為每 30 分鐘一次。" + } } } }, "How often should we try to get a GPS position." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Con quale frequenza dobbiamo cercare di ottenere una posizione GPS." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12143,11 +14440,23 @@ "state" : "translated", "value" : "尝试获取 GPS 定位的频率。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "嘗試取得 GPS 位置的頻率。" + } } } }, "How often to send detection sensor state to mesh regardless of detection. Default is Never." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Con quale frequenza inviare lo stato del sensore di rilevamento alla rete, indipendentemente dal rilevamento. L'impostazione predefinita è Mai." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12159,6 +14468,64 @@ "state" : "translated", "value" : "无论是否检测到,向网格发送检测传感器状态的频率。默认为从不。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "不論是否偵測到事件,將偵測感測器狀態發送至網狀網路的頻率。預設為「從不」。" + } + } + } + }, + "How often we can send a message to the mesh when people are detected." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "How often we can send a message to the mesh when people are detected." + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "How often we can send a message to the mesh when people are detected." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quanto spesso possiamo inviare un messaggio alla rete quando le persone vengono rilevate." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "How often we can send a message to the mesh when people are detected." + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hur ofta vi kan skicka ett meddelande till mesh-nätverket när personer upptäcks." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Колико често можемо послати поруку мрежи када се открију људи." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "检测到人员时,我们可以隔多久发送一条消息到 Mesh" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "當檢測到人員時,我們可以多久發送一次訊息到網狀網路。" + } } } }, @@ -12170,6 +14537,12 @@ "value" : "Wie wird die Firmware aktualisiert" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Come aggiornare il firmware" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12181,16 +14554,34 @@ "state" : "translated", "value" : "如何升级固件" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "如何更新韌體" + } } } }, "Hum" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Um" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Влажност" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "濕度" + } } } }, @@ -12202,29 +14593,28 @@ "value" : "Luftfeuchtigkeit" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Umidità" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Влажност" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "濕度" + } } } }, - "hybrid" : { - "extractionState" : "migrated", + "Hybrid" : { "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Hybrid" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Hybrid" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -12237,18 +14627,18 @@ "value" : "היברידי" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ibrido" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Hybrydowy" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Híbrido" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -12275,21 +14665,8 @@ } } }, - "hybrid.flyover" : { - "extractionState" : "migrated", + "Hybrid Flyover" : { "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Hybrid Flyover" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Hybrid Flyover" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -12302,18 +14679,18 @@ "value" : "היברידי מלמעלה" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Flyover ibrido" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Hybrydowy Przelot" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Híbrido o de Sobrevoo" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -12340,8 +14717,24 @@ } } }, + "I have read and understand the above. I voluntarily consent to the unencrypted transmission of my node data via MQTT." : { + "localizations" : { + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "我已閱讀並理解上述內容,並自願同意透過 MQTT 未加密地傳輸我的節點資料。" + } + } + } + }, "IAQ" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "IAQ" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12353,11 +14746,23 @@ "state" : "translated", "value" : "IAQ" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "IAQ" + } } } }, "IAQ " : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "IAQ " + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12369,11 +14774,23 @@ "state" : "translated", "value" : "IAQ " } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "IAQ" + } } } }, "IAQ %lld" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "IAQ %lld" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12385,11 +14802,23 @@ "state" : "translated", "value" : "IAQ %lld" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "IAQ %lld" + } } } }, "Icon" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Icona" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12401,11 +14830,23 @@ "state" : "translated", "value" : "图标" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "圖示" + } } } }, "If DOP is set, use HDOP / VDOP values instead of PDOP" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Se è impostato DOP, utilizzare i valori HDOP / VDOP invece di PDOP" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12417,11 +14858,23 @@ "state" : "translated", "value" : "如果设置了 DOP,则使用 HDOP / VDOP 值而不是 PDOP" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "若已設定 DOP,則使用 HDOP / VDOP 值取代 PDOP。" + } } } }, "If enabled, the 'output' Pin will be pulled active high, disabled means active low." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Se abilitato, il pin di 'uscita' sarà tirato attivo alto, mentre se disabilitato significa attivo basso." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12433,11 +14886,23 @@ "state" : "translated", "value" : "如果启用,“输出 ”引脚将被拉高,禁用则表示拉低。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "若啟用,則「輸出」腳位將被拉為高電位;若停用,則為低電位。" + } } } }, "If it is hard to access your device's reset button enter DFU mode here." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Se è difficile accedere al pulsante di ripristino del dispositivo, accedere alla modalità DFU." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12449,11 +14914,23 @@ "state" : "translated", "value" : "如果难以访问设备的重置按钮,请在此进入 DFU 模式。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "若無法輕易按下裝置的重置按鈕,可於此進入 DFU 模式。" + } } } }, "If set, any packets you send will be echoed back to your device." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Se è impostata, i pacchetti inviati saranno ritrasmessi al dispositivo." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12465,11 +14942,23 @@ "state" : "translated", "value" : "如果设置了,您发送的任何数据包都会回传到设备。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "若啟用,您傳送的所有封包都會回傳至您的裝置。" + } } } }, "If the default region topic is too busy you can choose a more local topic." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Se l'argomento predefinito della regione è troppo frequentato, è possibile scegliere un argomento più locale." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12481,11 +14970,23 @@ "state" : "translated", "value" : "如果默认区域话题太忙,您可以选择一个更本地化的话题。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "如果預設的區域主題過於繁忙,您可以選擇一個較在地的主題。" + } } } }, "Ignore MQTT" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ignorare MQTT" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12497,11 +14998,23 @@ "state" : "translated", "value" : "忽略 MQTT" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "忽略 MQTT" + } } } }, "Ignore Node" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ignorare il nodo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12513,11 +15026,23 @@ "state" : "translated", "value" : "忽略节点" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "忽略該節點" + } } } }, "Ignored" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ignorato" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12529,11 +15054,43 @@ "state" : "translated", "value" : "忽略" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "已忽略" + } + } + } + }, + "Ignores observed messages from foreign meshes like Local Only, but takes it step further by also ignoring messages from nodes not already in the node's known list." : { + "localizations" : { + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "忽略來自其他 Mesh 的訊息(像 Local Only 那樣),並更進一步連來自不在該節點已知清單中的節點所發出的訊息也一併忽略。" + } + } + } + }, + "Ignores observed messages from foreign meshes that are open or those which it cannot decrypt. Only rebroadcasts message on the nodes local primary / secondary channels." : { + "localizations" : { + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "忽略來自其他 Mesh 的訊息(例如開放的或無法解密的),只會在該節點的本地主要/次要頻道上重新轉發訊息。" + } } } }, "Import Route" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Percorso di importazione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12545,10 +15102,16 @@ "state" : "translated", "value" : "导入路线" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "輸入路徑" + } } } }, - "include" : { + "Include" : { "localizations" : { "de" : { "stringUnit" : { @@ -12556,12 +15119,6 @@ "value" : "Include" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Include" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -12574,18 +15131,18 @@ "value" : "כלול" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Includere" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Dołącz" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Incluir" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -12613,7 +15170,6 @@ } }, "incomplete" : { - "extractionState" : "manual", "localizations" : { "de" : { "stringUnit" : { @@ -12621,34 +15177,16 @@ "value" : "Unvollständig" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Incomplete" - } - }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Incomplete" } }, - "he" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Incomplete" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Incomplete" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Incomplete" + "value" : "Incompleto" } }, "sr" : { @@ -12657,39 +15195,38 @@ "value" : "Недовршен" } }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Incomplete" - } - }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Incomplete" + "value" : "尚未完成" } } } }, "India" : { - "extractionState" : "manual", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "India" - } - }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Индија" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "印度" + } } } }, "Indoor Air Quality" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Qualità dell'aria interna" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12701,11 +15238,23 @@ "state" : "translated", "value" : "室内空气质量" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "室內空氣品質" + } } } }, "Indoor Air Quality (IAQ)" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Qualità dell'aria interna (IAQ)" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -12717,206 +15266,586 @@ "state" : "translated", "value" : "室内空气质量 (IAQ)" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "室內空氣品質(IAQ)" + } } } }, - "inputevent.back" : { - "extractionState" : "migrated", + "Infrastructure node on a tower or mountain top only. Not to be used for roofs or mobile nodes. Needs exceptional coverage. Visible in Nodes list." : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Zurück" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Back" + "value" : "Router - Mesh Pakete werden bevorzugt über diesen Knoten gerouted. Dieser Knoten wird nicht von einer Client App benutzt. WLAN, Bluetooth und Display sind aus." } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Retour" + "value" : "Noeud d'infrastructure qui étend la couverture du réseau en relayant les messages. Visible dans la liste des noeuds." } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "אחרוה" + "value" : "מכשיר תשתית להרחבת המש על ידי העברת הודעות. מופיע ברשימת מכשירים." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nodo infrastrutturale solo su una torre o sulla cima di una montagna. Non deve essere utilizzato per tetti o nodi mobili. Necessita di una copertura eccezionale. Visibile nell'elenco dei nodi." } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Wstecz" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Voltar" + "value" : "Router - Pakiety siatki będą preferować trasowanie przez ten węzeł. Zakłada, że urządzenie będzie działać samodzielnie, umieszczone w miejscu z przewagą zasięgu. UWAGA: Radia BLE/Wi-Fi i ekran OLED zostaną uśpione." } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Bakåt" + "value" : "Infrastrukturnod för att utöka nätverkstäckningen genom att vidarebefordra meddelanden. Synlig i Noder-listan." } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Назад" + "value" : "Инфраструктурни чвор само на торњу или врху планине. Не користи се за кровове или мобилне чворове. Потребна му је изузетна покривеност. Видљиво на листи чворова." } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "后退" + "value" : "仅用于塔顶或山顶的基础设施节点。 不得用于屋顶或移动节点。 需要特殊的覆盖范围。在节点列表中可见。" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "返回" + "value" : "僅適用於安裝於塔台或山頂的基礎設施節點。不適用於屋頂或移動式節點,需具備卓越的訊號覆蓋能力。此類節點會顯示於節點列表中。" } } } }, - "inputevent.cancel" : { - "extractionState" : "migrated", + "Infrastructure node on a tower or mountain top only. Not to be used for roofs or mobile nodes. Relays messages with minimal overhead. Not visible in Nodes list." : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Abbrechen" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cancel" + "value" : "Infrastruktur-Knoten nur auf einem Turm oder einer Bergspitze. Nicht für Dächer oder mobile Knoten verwenden. Übermittelt Nachrichten mit minimalem Mehraufwand. Nicht sichtbar in der Knotenliste." } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Annuler" + "value" : "Noeud d'infrastructure qui étend la couverture du réseau en relayant les messages avec un minimum de surcharge. Invisible dans la liste des noeuds." } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "בטל" + "value" : "מכשיר תשתית להרחבת המש על ידי העברת הודעות עם דאטה נוסף מינימלי." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nodo infrastrutturale solo su una torre o sulla cima di una montagna. Non deve essere utilizzato per tetti o nodi mobili. Trasmette i messaggi con un overhead minimo. Non visibile nell'elenco dei nodi." } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Anuluj" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cancelar" + "value" : "Przekaźnik - Pakiety siatki będą preferować trasowanie przez ten węzeł. Ta rola eliminuje niepotrzebny nadmiar, taki jak NodeInfo, DeviceTelemetry i inne pakiety siatki, skutkując tym, że urządzenie nie będzie widoczne jako część sieci. Proszę zobaczyć tryb Rebroadcast dla dodatkowych ustawień specyficznych dla tej roli." } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Avbryt" + "value" : "Infrastrukturnod för att utöka nätverkstäckningen genom att vidarebefordra meddelanden med minimal overhead. Syns inte i Noder-listan." } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Откажи" + "value" : "Инфраструктурни чвор само на торњу или врху планине. Није намењен за кровове или мобилне чворове. Прослеђује поруке уз минимално оптерећење. Није видљив у листи чворова." } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "取消" + "value" : "仅用于塔顶或山顶的基础设施节点。 不得用于屋顶或移动节点。以最小的开销中继信息。在节点列表中不可见。" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "取消" + "value" : "僅適用於安裝於塔台或山頂。不適用於屋頂或移動式節點。具備高效的訊息轉發能力,資源消耗極低。此類節點不會顯示於節點列表中。" } } } }, - "inputevent.down" : { - "extractionState" : "migrated", + "Infrastructure node that always rebroadcasts packets once but only after all other modes, ensuring additional coverage for local clusters. Visible in Nodes list." : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Runter" + "value" : "Infrastrukturknoten, der Pakete immer nur einmal weiterleitet, aber erst nach allen anderen Betriebsarten, um eine zusätzliche Abdeckung für lokale Cluster zu gewährleisten. Sichtbar in der Liste der Knoten." } }, - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Down" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Bas" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "למטה" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "W Dół" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Para Baixo" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ner" + "value" : "Nodo infrastruttura che ritrasmette sempre i pacchetti una volta, ma solo dopo tutte le altre modalità, garantendo una copertura aggiuntiva per i cluster locali. Visibile nell'elenco dei nodi." } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Доле" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "下" + "value" : "Нод инфраструктуре који увек поново преноси пакете једном, али тек након свих других начина, обезбеђујући додатно покриће за локалне кластере. Видљив на листи нодова." } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "下" + "value" : "基礎設施節點,會在所有其他模式完成轉發後,固定將封包重新轉發一次,以確保鄰近節點群擁有額外的覆蓋範圍。此節點會顯示於節點列表中。" } } } }, - "inputevent.left" : { - "extractionState" : "migrated", + "Inputs" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingressi" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Улази" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "输入" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "輸入" + } + } + } + }, + "Inverted top bar for 2 Color display" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Barra superiore invertita per la visualizzazione a 2 colori" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Обрнута горња трака за екран у 2 боје" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "倒置顶栏,用于双色显示" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "雙色螢幕(頂部工具列反轉配色)" + } + } + } + }, + "Issuing Want Config to %@" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Envoi d'un Want Config à %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שולח בקשת הגדרות ל-%@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Emissione di Want Config a %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wydawanie Want Config to %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Utfärdar Want Config till %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Издавање захтева за конфигурацију на: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Issuing Want Config to %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Issuing Want Config to %@" + } + } + } + }, + "Japan" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Giappone" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Јапан" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "日本" + } + } + } + }, + "JSON Enabled" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "JSON abilitato" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "JSON омогућен" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用 JSON" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "啟用 JSON" + } + } + } + }, + "JSON mode is a limited, unencrypted MQTT output for locally integrating with home assistant" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La modalità JSON è un output MQTT limitato e non criptato per l'integrazione locale con l'assistente domestico" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "JSON режим је ограничен, нешифрован MQTT излаз за локалну интеграцију са Home Assistant-ом." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "JSON 模式是一种有限的、未加密的 MQTT 输出,用于与家庭助理进行本地集成" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "JSON 模式提供受限且未加密的 MQTT 輸出,適用於在本地端整合 Home Assistant。" + } + } + } + }, + "Jump to present" : { + "localizations" : { + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "跳至最新訊息" + } + } + } + }, + "Key" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Schlüssel" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Chiave" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Кључ" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Key" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "金鑰" + } + } + } + }, + "Key Mapping" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mappatura delle chiavi" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Мапирање кључева" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "按鍵綁定" + } + } + } + }, + "Key Size" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Schlüsselgröße" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dimensione della chiave" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Величина кључа" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "金鑰長度" + } + } + } + }, + "Korea" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Corea" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Кореја" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "韓國" + } + } + } + }, + "Last heard" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zuletzt gehört" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "L'ultima volta che si è sentito" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Последње откривање" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "最后听到" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "最後通訊" + } + } + } + }, + "Latitude" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Breitengrad" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Latitudine" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ширина" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "纬度" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "緯度" + } + } + } + }, + "LED Heartbeat" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Battito cardiaco a LED" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "LED срчани откуцаји" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "LED 心跳" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "LED 心跳燈 (Heartbeat)" + } + } + } + }, + "LED State" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Stato del LED" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "LED статус" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "LED 状态" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "LED 狀態燈" + } + } + } + }, + "Left" : { "localizations" : { "de" : { "stringUnit" : { @@ -12924,12 +15853,6 @@ "value" : "Links" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Left" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -12942,18 +15865,18 @@ "value" : "שמאלה" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "A sinistra" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "W Lewo" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Esquerda" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -12980,2456 +15903,6 @@ } } }, - "inputevent.none" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Keins" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "None" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Aucun" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "ללא" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Brak" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nenhum" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ingen" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ништа" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "无" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "無" - } - } - } - }, - "inputevent.right" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Rechts" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Right" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Droite" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "ימינה" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "W Prawo" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Direita" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Höger" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Десно" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "右" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "右" - } - } - } - }, - "inputevent.select" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Auswählen" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Select" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sélectionner" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "בחר" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wybierz" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Selecionar" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Välj" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Изабери" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "选择" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "選擇" - } - } - } - }, - "inputevent.up" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Hoch" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Up" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Haut" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "למעלה" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "W Górę" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Para Cima" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Upp" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Горе" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "上" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "上" - } - } - } - }, - "Inputs" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Улази" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "输入" - } - } - } - }, - "interval.eighteen.hours" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Achtzehn Stunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Eighteen Hours" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dix huit heures" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שמונה עשר שעות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Osiemnaście Godzin" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dezoito Horas" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Arton Timmar" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Осамнаест сати" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "十八小时" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "十八小時" - } - } - } - }, - "interval.eventytwo.hours" : { - "extractionState" : "manual", - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Двадесет и два сата" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "七十二小时" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "七十二小時" - } - } - } - }, - "interval.fifteen.minutes" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fünfzehn Minuten" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fifteen Minutes" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Quinze minutes" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "חמש עשרה דקות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Piętnaście Minut" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Quinze Minutos" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Femton Minuter" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Петнаест минута" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "十五分钟" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "十五分鐘" - } - } - } - }, - "interval.fifteen.seconds" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fünfzehn Sekunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fifteen Seconds" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Quinze secondes" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "חמש עשרה שניות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Piętnaście Sekund" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Quinze Segundos" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Femton Sekunder" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Петнаест секунди" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "十五秒" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "十五秒" - } - } - } - }, - "interval.five.hours" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fünf Stunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Five Hours" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cinq heures" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "חמש שעות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Pięć Godzin" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cinco Horas" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fem Timmar" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Пет сати" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "五小时" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "五小時" - } - } - } - }, - "interval.five.minutes" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fünf Minuten" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Five Minutes" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cinq minutes" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "חמש דקות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Pięć Minut" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cinco Minutos" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fem Minuter" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Пет минута" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "五分钟" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "五分鐘" - } - } - } - }, - "interval.five.seconds" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fünf Sekunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Five Seconds" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cinq secondes" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "חמש שניות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Pięć Sekund" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cinco Segundos" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fem Sekunder" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Пет секунди" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "五秒" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "五秒" - } - } - } - }, - "interval.fortyeight.hours" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Achtundvierzig Stunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Forty Eight Hours" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Quarante huit heures" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "ארבעים ושמונה שעות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Czterdzieści Osiem Godzin" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Quarenta e Oito Horas" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fyrtioåtta Timmar" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Четртесет и осам сати" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "四十八小时" - } - } - } - }, - "interval.fortyfive.seconds" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fündundvierzig Sekunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Forty Five Seconds" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Quarante cinq secondes" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "ארבעים וחמש שניות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Czterdzieści Pięć Sekund" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Quarenta e Cinco Segundos" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fyrtiofem Sekunder" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Четрдесет и пет секунди" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "四十五秒" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "四十五秒" - } - } - } - }, - "interval.four.hours" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Vier Stunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Four Hours" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Quatre heures" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "ארבע שעות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cztery Godziny" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Quatro Horas" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fyra Timmar" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Четири сата" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "四小时" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "四小時" - } - } - } - }, - "interval.four.seconds" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Vier Sekunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Four Seconds" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Quatre secondes" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "ארבע שניות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cztery Sekundy" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Quatro Segundos" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fyra Sekunder" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Четири секунде" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "四秒" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "四秒" - } - } - } - }, - "interval.one.hour" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Eine Stunde" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "One Hour" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Une heure" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שעה אחת" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Jedna Godzina" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Uma Hora" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "En Timme" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Један сат" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "一小时" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "一小時" - } - } - } - }, - "interval.one.minute" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Eine Minute" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "One Minute" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Une minute" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "דקה אחת" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Jedna Minuta" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Um Minuto" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "En Minut" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Један минут" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "一分钟" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "一分鐘" - } - } - } - }, - "interval.one.second" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Eine Sekunde" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "One Second" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Une seconde" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שניה אחת" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Jedna Sekunda" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Um Segundo" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "En Sekund" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Један секунд" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "一秒" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "一秒" - } - } - } - }, - "interval.seventytwo.hours" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Zweiundsiebzig Stunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Seventy Two Hours" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Soixante douze heures" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שבעים ושתיים שעות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Siedemdziesiąt Dwie Godziny" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Setenta e Duas Horas" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sjuttiotvå Timmar" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Седамдесет и два сата" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "七十二小时" - } - } - } - }, - "interval.six.hours" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sechs Stunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Six Hours" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Six heures" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שש שעות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sześć Godzin" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Seis Horas" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sex Timmar" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Шест сати" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "六小时" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "六小時" - } - } - } - }, - "interval.ten.minutes" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Zehn Minuten" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ten Minutes" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dix minutes" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "עשר דקות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dziesięć Minut" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dez Minutos" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tio Minuter" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Десет минута" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "十分钟" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "十分鐘" - } - } - } - }, - "interval.ten.seconds" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Zehn Sekunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ten Seconds" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dix secondes" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "עשר שניות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dziesięć Sekund" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dez Segundos" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tio Sekunder" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Десет секунди" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "十秒" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "十秒" - } - } - } - }, - "interval.thirty.minutes" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dreißig Minuten" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Thirty Minutes" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trente minutes" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שלושים דקות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trzydzieści Minut" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trinta Minutos" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trettio Minuter" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Пола сата" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "三十分钟" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "三十分鐘" - } - } - } - }, - "interval.thirty.seconds" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dreißig Sekunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Thirty Seconds" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trente secondes" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שלושים שניות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trzydzieści Sekund" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trinta Segundos" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trettio Sekunder" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Тридесет секунди" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "三十秒" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "三十秒" - } - } - } - }, - "interval.thirtysix.hours" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sechsunddreissig Stunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Thirty Six Hours" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trente six heures" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שלושים ושש שעות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trzydzieści Sześć Godzin" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trinta e Seis Horas" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trettiosex Timmar" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Тридесет и шест сати" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "三十六小时" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "三十六小時" - } - } - } - }, - "interval.three.hours" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Drei Stunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Three Hours" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trois heures" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שלוש שעות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trzy Godziny" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Três Horas" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tre Timmar" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Три сата" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "三小时" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "三小時" - } - } - } - }, - "interval.three.seconds" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Drei Sekunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Three Seconds" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trois secondes" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שלוש שניות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trzy Sekundy" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Três Segundos" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tre Sekunder" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Три секунде" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "三秒" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "三秒" - } - } - } - }, - "interval.twelve.hours" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Zwölf Stunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Twelve Hours" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Douze heures" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שניים עשר שעות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dwanaście Godzin" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Doze Horas" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tolv Timmar" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Дванаест сати" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "十二小时" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "十二小時" - } - } - } - }, - "interval.twenty.seconds" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Zwanzig Sekunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Twenty Seconds" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Vingt secondes" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "עשרים שניות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dwadzieścia Sekund" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Vinte Segundos" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tjugo Sekunder" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Двадесет секунди" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "二十秒" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "二十秒" - } - } - } - }, - "interval.twentyfive.seconds" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fünfundzwanzig Sekunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Twenty Five Seconds" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Vingt cinq secondes" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "עשרים וחמש שניות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dwadzieścia Pięć Sekund" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Vinte e Cinco Segundos" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tjugofem Sekunder" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Двадесет пет секунди" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "二十五秒" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "二十五秒" - } - } - } - }, - "interval.twentyfour.hours" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Vierundzwanzig Stunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Twenty Four Hours" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Vingt quatre heures" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "עשרים וארבע שעות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dwadzieścia Cztery Godziny" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Vinte e Quatro Horas" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tjugofyra Timmar" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Двадесет четири сата" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "二十四小时" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "二十四小時" - } - } - } - }, - "interval.two.hours" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Zwei Stunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Two Hours" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Deux heures" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שעתיים" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dwie Godziny" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Duas Horas" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Två Timmar" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Два сата" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "两小时" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "兩小時" - } - } - } - }, - "interval.two.minutes" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Zwei Minutes" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Two Minutes" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Deux minutes" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שתי דקות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dwie Minuty" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dois Minutos" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Två Minuter" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Два минута" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "两分钟" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "兩分鐘" - } - } - } - }, - "interval.two.seconds" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Zwei Sekunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Two Seconds" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Deux secondes" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שתי שניות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dwie Sekundy" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dois Segundos" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Två Sekunder" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Две секунде" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "两秒" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "兩秒" - } - } - } - }, - "inverted.top.bar.for.2.color.display" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Inverted top bar for 2 Color display" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Обрнута горња трака за екран у 2 боје" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "倒置顶栏,用于双色显示" - } - } - } - }, - "Japan" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Japan" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Јапан" - } - } - } - }, - "JSON Enabled" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "JSON омогућен" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "启用 JSON" - } - } - } - }, - "JSON mode is a limited, unencrypted MQTT output for locally integrating with home assistant" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "JSON режим је ограничен, нешифрован MQTT излаз за локалну интеграцију са Home Assistant-ом." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "JSON 模式是一种有限的、未加密的 MQTT 输出,用于与家庭助理进行本地集成" - } - } - } - }, - "Key" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Schlüssel" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Кључ" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Key" - } - } - } - }, - "Key Mapping" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Мапирање кључева" - } - } - } - }, - "Key Size" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Schlüsselgröße" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Величина кључа" - } - } - } - }, - "keyboard.type" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Keyboard Typ" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Keyboard Type" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Type de clavier" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "סוג מקלדת" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Typ Klawiatury" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tipo de Teclado" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tangentbordstyp" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Тип тастатуре" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "键盘类型" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "鍵盤類型" - } - } - } - }, - "Korea" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Korea" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Кореја" - } - } - } - }, - "Last heard" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Zuletzt gehört" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Последње откривање" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "最后听到" - } - } - } - }, - "Latitude" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Breitengrad" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ширина" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "纬度" - } - } - } - }, - "LED Heartbeat" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "LED срчани откуцаји" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "LED 心跳" - } - } - } - }, - "LED State" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "LED статус" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "LED 状态" - } - } - } - }, "Legacy Administration" : { "localizations" : { "de" : { @@ -15438,213 +15911,27 @@ "value" : "Alte Administrationsart" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Amministrazione del patrimonio" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Стари начин администрације" } - } - } - }, - "Licensed Operator" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Лиценцирани оператор" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "持证操作员" - } - } - } - }, - "Limit all periodic broadcast intervals especially telemetry and position. If you need to increase hops, do it on nodes at the edges, not the ones in the middle. MQTT is not advised when you are duty cycle restricted because the gateway node is then doing all the work." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ограничите све периодичне интервале емитовања, посебно телеметрију и позицију. Ако је потребно повећати број скокова, то радите на чворовима на ивицама, а не на оним у средини. MQTT није препоручен када сте ограничени циклусом дужности јер у том случају чвор-рутер ради сав посао." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "限制所有周期性广播间隔,尤其是遥测和位置。如果需要增加跳数,请在边缘节点而不是中间节点上进行。在占空比受限的情况下,不建议使用 MQTT,因为网关节点会承担所有工作。" - } - } - } - }, - "Line Series" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Линијска серија" - } - } - } - }, - "Loading Logs. . ." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Учитавам логове. . ." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "加载日志. . ." - } - } - } - }, - "Location" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Standort" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Локација:" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "位置" - } - } - } - }, - "Location:" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Standrot:" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Локација:" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "位置:" - } - } - } - }, - "Locked" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gesperrt" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Закључан" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "锁定" - } - } - } - }, - "Log Levels" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Нивои логова" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "日志等级" - } - } - } - }, - "log.category" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Kategorie" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Category" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Category" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Category" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Category" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Category" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Категорија" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Category" - } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Category" + "value" : "舊版遠端管理" } } } }, - "log.level" : { + "Level" : { "localizations" : { "de" : { "stringUnit" : { @@ -15652,12 +15939,6 @@ "value" : "Level" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Level" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -15670,6 +15951,12 @@ "value" : "Level" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Livello" + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -15702,249 +15989,245 @@ } } }, - "log.message" : { + "Licensed Operator" : { "localizations" : { - "de" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Nachricht" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message" + "value" : "Operatore con licenza" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Порука" + "value" : "Лиценцирани оператор" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Message" + "value" : "持证操作员" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Message" + "value" : "持照操作員" } } } }, - "log.process" : { - "extractionState" : "migrated", + "Limit all periodic broadcast intervals especially telemetry and position. If you need to increase hops, do it on nodes at the edges, not the ones in the middle. MQTT is not advised when you are duty cycle restricted because the gateway node is then doing all the work." : { "localizations" : { - "de" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Prozess" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Process" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Process" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Process" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Process" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Process" + "value" : "Limitare tutti gli intervalli di trasmissione periodica, in particolare la telemetria e la posizione. Se è necessario aumentare gli hop, farlo sui nodi ai margini, non su quelli al centro. MQTT è sconsigliato quando il ciclo di lavoro è limitato, perché è il nodo gateway a svolgere tutto il lavoro." } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Процес" + "value" : "Ограничите све периодичне интервале емитовања, посебно телеметрију и позицију. Ако је потребно повећати број скокова, то радите на чворовима на ивицама, а не на оним у средини. MQTT није препоручен када сте ограничени циклусом дужности јер у том случају чвор-рутер ради сав посао." } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Process" + "value" : "限制所有周期性广播间隔,尤其是遥测和位置。如果需要增加跳数,请在边缘节点而不是中间节点上进行。在占空比受限的情况下,不建议使用 MQTT,因为网关节点会承担所有工作。" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Process" + "value" : "請限制所有定期廣播的間隔時間,特別是遙測(telemetry)和位置(position)指標。如果需要增加跳數(hops),應該在網路邊緣的節點上進行,而不是在中間的節點。當您受到頻率使用限制(duty cycle)時,不建議使用 MQTT,因為此時閘道節點(gateway)會承擔所有負載。" } } } }, - "log.subsystem" : { - "extractionState" : "migrated", + "Line Series" : { "localizations" : { - "de" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Subsystem" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Subsystem" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Subsystem" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Subsystem" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Subsystem" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Subsystem" + "value" : "Serie di linee" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Подсистем" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Subsystem" + "value" : "Линијска серија" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Subsystem" + "value" : "折線圖系列" } } } }, - "log.time" : { + "Loading Logs. . ." : { "localizations" : { - "de" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Zeit" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Time" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Time" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Time" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Time" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Time" + "value" : "Caricamento dei log. . ." } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Време" + "value" : "Учитавам логове. . ." } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Time" + "value" : "加载日志. . ." } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Time" + "value" : "正在載入紀錄⋯⋯" } } } }, - "logging" : { + "Location" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Logging" + "value" : "Standort" } }, - "en" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Posizione" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Локација:" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "位置" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "位置" + } + } + } + }, + "Location:" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Standrot:" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Posizione:" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Локација:" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "位置:" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "位置:" + } + } + } + }, + "Locked" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Gesperrt" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bloccato" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Закључан" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "锁定" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "已上鎖" + } + } + } + }, + "Log Levels" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Livelli del registro" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Нивои логова" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "日志等级" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "日誌等級" + } + } + } + }, + "Logging" : { + "localizations" : { + "de" : { "stringUnit" : { "state" : "translated", "value" : "Logging" @@ -15962,18 +16245,18 @@ "value" : "רישום" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Registrazione" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Rejestracja" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Registo" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -15995,13 +16278,19 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "加載中" + "value" : "Logging" } } } }, "Logs" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Registri" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -16013,11 +16302,23 @@ "state" : "translated", "value" : "日志" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "紀錄" + } } } }, "Logs:" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Registri:" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -16029,6 +16330,12 @@ "state" : "translated", "value" : "日志:" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "紀錄:" + } } } }, @@ -16040,6 +16347,12 @@ "value" : "Langer Name" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nome lungo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -16051,6 +16364,12 @@ "state" : "translated", "value" : "长名称" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "完整名稱" + } } } }, @@ -16062,6 +16381,12 @@ "value" : "Langer Name: %@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nome lungo: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -16073,11 +16398,23 @@ "state" : "translated", "value" : "长名称: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "完整名稱:%@" + } } } }, "Long press to favorite or mute the contact or delete a conversation." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Premere a lungo per privilegiare o silenziare il contatto o eliminare una conversazione." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -16089,16 +16426,21 @@ "state" : "translated", "value" : "长按可收藏联系人或将其静音或删除对话。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "長按可將聯絡人加入最愛、靜音或刪除對話。" + } } } }, - "long.range.fast" : { - "extractionState" : "manual", + "Long Range - Fast" : { "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Long Range - Fast" + "value" : "A lungo raggio - Veloce" } }, "sr" : { @@ -16106,16 +16448,21 @@ "state" : "translated", "value" : "Дугачки домет - Брзо" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Long Range - Fast" + } } } }, - "long.range.moderate" : { - "extractionState" : "manual", + "Long Range - Moderate" : { "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Long Range - Moderate" + "value" : "Lungo raggio - Moderato" } }, "sr" : { @@ -16123,16 +16470,21 @@ "state" : "translated", "value" : "Дугачки домет - Умерено" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Long Range - Moderate" + } } } }, - "long.range.slow" : { - "extractionState" : "manual", + "Long Range - Slow" : { "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Long Range - Slow" + "value" : "Lungo raggio - Lento" } }, "sr" : { @@ -16140,6 +16492,12 @@ "state" : "translated", "value" : "Дугачки домет - Споро" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Long Range - Slow" + } } } }, @@ -16151,6 +16509,12 @@ "value" : "Längengrad" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Longitudine" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -16162,10 +16526,16 @@ "state" : "translated", "value" : "经度" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "緯度" + } } } }, - "lora" : { + "LoRa" : { "localizations" : { "de" : { "stringUnit" : { @@ -16173,12 +16543,6 @@ "value" : "LoRa" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "LoRa" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -16191,13 +16555,13 @@ "value" : "לורה" } }, - "pl" : { + "it" : { "stringUnit" : { "state" : "translated", "value" : "LoRa" } }, - "pt-PT" : { + "pl" : { "stringUnit" : { "state" : "translated", "value" : "LoRa" @@ -16229,7 +16593,7 @@ } } }, - "lora.config" : { + "LoRa Config" : { "localizations" : { "de" : { "stringUnit" : { @@ -16237,12 +16601,6 @@ "value" : "LoRa Einstellungen" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "LoRa Config" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -16255,18 +16613,18 @@ "value" : "הגדרות לורה" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione LoRa" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Konfiguracja LoRa" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração LoRa" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -16293,115 +16651,166 @@ } } }, - "lora.signal.strength.bad" : { - "extractionState" : "manual", + "LoRa config received: %@" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Schlechte Signalstärke" + "value" : "LoRa config empfangen: %@" } }, - "en" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Bad" + "value" : "Configuration LoRa reçue : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הגדרות לורה התקבלו: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione LoRa ricevuta: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Otrzymano konfigurację LoRa: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "LoRa-konfiguration mottagen: %@" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Лош" + "value" : "Конфигурација LoRA примљена: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "LoRa config received: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "LoRa config received: %@" } } } }, - "lora.signal.strength.fair" : { - "extractionState" : "manual", + "Lost and Found" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Ordentliche Signalstärke" + "value" : "Tracker" } }, - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Fair" + "value" : "Oggetti smarriti" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Прихватљив" - } - } - } - }, - "lora.signal.strength.good" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gute Signalstärke" + "value" : "Изгубљено и нађено" } }, - "en" : { + "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Good" + "value" : "失物招领" } }, - "sr" : { + "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Добар" - } - } - } - }, - "lora.signal.strength.none" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Keine Verbindung" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "None" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Без" + "value" : "Lost and Found" } } } }, "LOW" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "BASSO" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "НИЗАК" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "低" + } } } }, - "Malaysia 433mhz" : { - "extractionState" : "manual", + "M5 Stack Card KB / RAK Keypad" : { "localizations" : { - "en" : { + "de" : { "stringUnit" : { "state" : "translated", - "value" : "Malaysia 433MHz" + "value" : "M5 Stack Card KB / RAK Tastenfeld" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Clavier M5 Stack Card KB / RAK" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "M5 Stack Card KB / Tastiera RAK" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "M5 стек картица KB / RAK тастатура" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "M5 Stack 卡片键盘 / RAK 键盘" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "M5Stack 卡片鍵盤 / RAK 鍵盤" + } + } + } + }, + "Malaysia 433MHz" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Malesia 433MHz" } }, "sr" : { @@ -16409,16 +16818,21 @@ "state" : "translated", "value" : "Малезија 433MHz" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "馬來西亞 433MHz" + } } } }, - "Malaysia 919mhz" : { - "extractionState" : "manual", + "Malaysia 919MHz" : { "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Malaysia 919MHz" + "value" : "Malesia 919MHz" } }, "sr" : { @@ -16426,11 +16840,81 @@ "state" : "translated", "value" : "Малезија 919MHz" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "馬來西亞 919MHz" + } + } + } + }, + "Manage Channels" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kanäle verwalten" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Gérer les canaux" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "Manage Channels" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Gestire i canali" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Manage Channels" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hantera Kanaler" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Управљај каналима" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "管理频道" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "管理頻道" + } } } }, "Managed Device" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dispositivo gestito" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -16442,69 +16926,69 @@ "state" : "translated", "value" : "管理设备" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "管理裝置" + } } } }, - "map" : { + "Manual Configuration" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Mesh Karte" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mesh Map" + "value" : "Manuelle Konfiguration" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Carte de maillage" + "value" : "Configuration manuelle" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "מפת מש" + "value" : "הגדרה ידנית" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione manuale" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Mapa Sieci" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mapa do Mesh" + "value" : "Konfiguracja ręczna" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Mesh Karta" + "value" : "Manuell konfiguration" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Мапа меша" + "value" : "Ручна конфигурација" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Mesh 地图" + "value" : "手动配置" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Mesh 地圖" + "value" : "手動設定" } } } @@ -16517,6 +17001,12 @@ "value" : "Kartenoptionen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Opzioni mappa" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -16528,11 +17018,23 @@ "state" : "translated", "value" : "地图选项" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "地圖選項" + } } } }, "Map Publish Interval" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Intervallo di pubblicazione della mappa" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -16544,11 +17046,23 @@ "state" : "translated", "value" : "地图发布间隔" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "地圖回報間隔" + } } } }, "Map Report" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rapporto sulla mappa" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -16560,540 +17074,79 @@ "state" : "translated", "value" : "地图报告" } - } - } - }, - "Map Tile Data" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Подаци плочица мапе" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "瓦片地图数据" - } - } - } - }, - "map.centering" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Centering Mode" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mode centré" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "מכשיר במרכז" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tryb Wyśrodkowania" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Modo de Centralização" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Centreringsläge" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Режим центрирања" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "居中" - } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "置中" + "value" : "地圖回報" } } } }, - "map.tiles.delete" : { - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Delete All Map Tiles" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Supprimer toutes les tuiles de carte" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "מחק כל חלקי מפה שמורים" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Usuń Wszystkie Kafle Mapy" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Apagar Todas as Imagens da Mapa" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Radera Alla Kartplattor" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Обриши све плочице мапе" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "删除所有瓦片地图" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "刪除已緩存的地圖區塊" - } - } - } - }, - "map.type" : { - "extractionState" : "manual", + "Max Retransmission Reached" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Kartentyp" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Default Type" + "value" : "Maximale Wiederholungen erreicht" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Type par défaut" + "value" : "Nombre maximum de retransmissions atteint" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "סוג ברירת מחדל" + "value" : "הגיע למקסימום השליחות מדש" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Raggiunta la massima ritrasmissione" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Domyślny Typ" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tipo Padrão" + "value" : "Osiągnięto limit retransmisji" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Standardtyp" + "value" : "Max antal omsändningar nått" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Подразумевани тип" + "value" : "Достигнут максималан број поновних слања" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "地图类型" + "value" : "已达到最大重试次数" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "地圖類型" + "value" : "已達到最大重試次數" } } } }, - "map.use.legacy" : { - "extractionState" : "manual", + "Medium Range - Fast" : { "localizations" : { - "de" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Use Legacy Mesh Map" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Use Legacy Mesh Map" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Utiliser l'ancienne génération de carte de maillage" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "השתמש במפה מדור קודם" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Use Legacy Mesh Map" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Utilizar Mapa do Mesh Antigo" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Använd Äldre Mesh Karta" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Користите легаси мрежну мапу" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "使用传统网状地图" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "使用傳統Mesh地圖" - } - } - } - }, - "map.usertrackingmode" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "User tracking mode" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "User tracking mode" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mode suivre l'utilisateur" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "מצב מעקב אחר משתמש" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tryb śledzenia użytkownika" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Modo de Rastreamento do Utilizador" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Spårningsläge för användare" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Мод праћења корисника" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "用户跟随模式" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "使用者跟隨模式" - } - } - } - }, - "map.usertrackingmode.follow" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Folgen" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Follow" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Suivre" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "עקוב" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Śledź" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Seguir" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Följ" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Прати" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "跟随" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "跟隨" - } - } - } - }, - "map.usertrackingmode.followwithheading" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Folgen mit Steuerkurs" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Follow with heading" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Suivre avec le cap" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "עקוב עם כיוון" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Śledź z kierunkiem" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Seguir com Direção" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Följ med riktning" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Прати са правцем" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "跟随航向" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "跟隨與方向" - } - } - } - }, - "map.usertrackingmode.none" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Keiner" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "None" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Aucun" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "ללא" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Brak" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nenhum" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ingen" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ни један" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "无" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "無" - } - } - } - }, - "medium.range.fast" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Medium Range - Fast" + "value" : "Medio raggio - Veloce" } }, "sr" : { @@ -17101,16 +17154,21 @@ "state" : "translated", "value" : "Средњи домет - Брзо" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Medium Range - Fast" + } } } }, - "medium.range.slow" : { - "extractionState" : "manual", + "Medium Range - Slow" : { "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Medium Range - Slow" + "value" : "Medio raggio - Lento" } }, "sr" : { @@ -17118,20 +17176,38 @@ "state" : "translated", "value" : "Средњи домет - Споро" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Medium Range - Slow" + } } } }, "Mesh activity update" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aggiornamento dell'attività di rete" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Ажурирање активности мреже" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mesh 活動更新" + } } } }, - "mesh.live.activity" : { + "Mesh Live Activity" : { "localizations" : { "de" : { "stringUnit" : { @@ -17139,12 +17215,6 @@ "value" : "Mesh Live Aktivität" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mesh Live Activity" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -17157,18 +17227,18 @@ "value" : "פעילות מש חיה" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rete Attività live" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Aktywność na Żywo" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Atividade Ao Vivo do Mesh" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -17195,2470 +17265,60 @@ } } }, - "mesh.log.ambientlighting.config %@" : { - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ambient Lighting module config received: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration du module lumière ambiante reçue : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרות מודולת תאורת סביבה התקבלו: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ambient Lighting module config received: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração do módulo de Iluminação Ambiente recebida: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Konfiguration för omgivningsbelysningsmodulen mottagen: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Примљена конфигурација модула амбијенталног осветљења: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ambient Lighting module config received: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ambient Lighting module config received: %@" - } - } - } - }, - "mesh.log.bluetooth.config %@" : { - "extractionState" : "migrated", + "Mesh Map" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Bluetooth Konfiguration empfangen: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Bluetooth config received: %@" + "value" : "Mesh Karte" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Configuration Bluetooth reçue : %@" + "value" : "Carte de maillage" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "הגדרות בלוטוס התקבלו: %@" + "value" : "מפת מש" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mappa della mesh" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Otrzymano konfigurację Bluetooth: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração Bluetooth recebida: %@" + "value" : "Mapa Sieci" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Bluetooth-konfiguration mottagen: %@" + "value" : "Mesh Karta" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Примљена конфигурација блутута: %@" + "value" : "Мапа меша" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Bluetooth config received: %@" + "value" : "Mesh 地图" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Bluetooth config received: %@" - } - } - } - }, - "mesh.log.cannedmessage.config %@" : { - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Canned Message module config received: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration du module messages préformatés reçue : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרות מודולת תגובות שמורות התקבלו: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Otrzymano konfigurację modułu wiadomości gotowych: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração do módulo de Mensagens Padrão recebida: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Konfiguration för modulen med fördefinierade meddelanden mottagen: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Конфигурација модула за унапред припремљене поруке примљена: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Canned Message module config received: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "Canned Message module config received: %@" - } - } - } - }, - "mesh.log.cannedmessages.messages.get %@" : { - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Requested Canned Messages Module Messages for node: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Messages du module messages préformatés demandés pour le noeud : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "התבקשו הודעות מודולת הודעות שמורות עבור מכשיר: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Zażądano Wiadomości z Modułu Wiadomości Gotowych dla węzła: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mensagens Padrão solicitadas para o módulo de mensagens para o nó: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Begärda meddelanden för modulen med fördefinierade meddelanden för nod: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Захтеване поруке модула за унапред припремљене поруке за чвор: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Requested Canned Messages Module Messages for node: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "Requested Canned Messages Module Messages for node: %@" - } - } - } - }, - "mesh.log.cannedmessages.messages.received %@" : { - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Canned Messages Messages Received For: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Messages préformatés reçus pour : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הודעות עבור הודעות שמורות התקבלו מ-%@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Otrzymano Wiadomości Gotowe Dla: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mensagens Padrão recebidas para: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mottagna meddelanden för fördefinierade meddelanden För: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Примљене поруке за унапред припремљене поруке за: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Canned Messages Messages Received For: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "Canned Messages Messages Received For: %@" - } - } - } - }, - "mesh.log.channel.sent %@ %d" : { - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sent a Channel for: %@ Channel Index %d" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Canal envoyé pour : %@ Canal index %d" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "נשלח ערוץ עבור: %@ אינדקס ערוצים %d" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wysłano kanał dla: %@ Indeks kanału %d" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Um Canal Enviado para: %@ Índice do Canal %d" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Skickade en kanal för: %@ Kanalindex %d" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Послат је канал за: %@ Индекс канала %d" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sent a Channel for: %@ Channel Index %d" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sent a Channel for: %@ Channel Index %d" - } - } - } - }, - "mesh.log.detectionsensor.config %@" : { - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Detection Sensor module config received: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration du module capteur de détection reçue : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרות מודולת חיישן זיהוי התקבלו: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Detection Sensor module config received: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração do módulo de sensor de detecção recebida: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Konfiguration för detektionssensormodulen mottagen: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Конфигурација модула за сензор детекције примљена: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Detection Sensor module config received: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到偵測感應器模組配置:%@" - } - } - } - }, - "mesh.log.device.config %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gerätekonfiguration empfangen: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Device config received: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration de l'appareil reçue : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרות מכשיר התקבלו: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Otrzymano konfigurację urządzenia: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração do dispositivo recebida: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enhetskonfiguration mottagen: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Примљена конфигурација уређаја: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Device config received: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到裝置設定: %@" - } - } - } - }, - "mesh.log.device.metadata.received %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Device Metadata empfangen von: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Device Metadata received from: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Metadatas de l'appareil reçues de : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "מטא-דאטה של מכשיר התקבל מ-%@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Otrzymano metadane urządzenia od: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Os Metadados do dispositivo recebidos de: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Metadata för enhet mottagen från: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Метаподаци уређаја примљени од: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Device Metadata admin message received from: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "從 %@ 收到設備元數據管理消息" - } - } - } - }, - "mesh.log.devicemetadata %@" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Anforderung der Geräte Metadaten für %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Requesting Device Metadata for %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Demande des metadatas de l'appareil à %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "מבקש מטא-דאטה עבור %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Żądanie metadanych urządzenia dla %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Solicitando os Metadados do Dispositivo para %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Begär metadata för enhet för %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Захтевање метаподатака уређаја за %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Requesting Device Metadata for %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "請求設備元數據:%@" - } - } - } - }, - "mesh.log.display.config %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Display Konfiguration empfangen: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Display config received: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration de l'écran reçue : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרות תצוגה התקבלו: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Otrzymano konfigurację wyświetlacza: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração do icrãn recebida: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Skärmkonfiguration mottagen: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Примљена конфигурација приказа: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Display config received: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到顯示模組設定: %@" - } - } - } - }, - "mesh.log.externalnotification.config %@" : { - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "External Notification module config received: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration du module notification extérieure reçue : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרות מודולת נוטיפיקציה חיצונית התקבלו: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Otrzymano konfigurację modułu zewnętrznych powiadomień: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração do módulo de notificação externa recebida: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Konfiguration för modulen för externa notifikationer mottagen: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Конфигурација модула за екстерне нотификације примљена: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "External Notification module config received: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到外部通知模組配置:%@" - } - } - } - }, - "mesh.log.lora.config %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "LoRa config empfangen: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "LoRa config received: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration LoRa reçue : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרות לורה התקבלו: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Otrzymano konfigurację LoRa: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração LoRa recebida: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "LoRa-konfiguration mottagen: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Конфигурација LoRA примљена: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "LoRa config received: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到LoRa設定: %@" - } - } - } - }, - "mesh.log.lora.config.sent %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "LoRa.Config gesendet für: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sent a LoRa.Config for: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration LoRa envoyée à : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "נשלחו הגדרות לורה עבור: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wysłano konfigurację LoRa dla: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração do LoRa Enviado para: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Skickade en LoRa.Konfiguration för: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Послата LoRA конфигурација за: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sent a LoRa.Config for: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "發送LoRa配置給:%@" - } - } - } - }, - "mesh.log.mqtt.config %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "MQTT Modulkonfiguration empfangen: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "MQTT module config received: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration du module MQTT reçue : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרות מודולת MQTT התקבלו: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Otrzymano konfigurację modułu MQTT: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração do módulo MQTT recebida: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "MQTT-modulkonfiguration mottagen: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Конфигурација MQTT модула примљена: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到 MQTT 模块配置:%@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到MQTT模組配置:%@" - } - } - } - }, - "mesh.log.myinfo %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "MyInfo empfangen: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "MyInfo received: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "MesInfos reçues : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "MyInfo התקבל: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Otrzymano Moje Informacje: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "MyInfo recebido: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Min info mottagen: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Моје информације примљене: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "MyInfo received: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到我的資訊:%@" - } - } - } - }, - "mesh.log.network.config %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Netzwerkkonfiguration empfangen: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Network config received: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration du réseau reçue : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרות רשת התקבלו: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Odebrano konfigurację sieci: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração de rede recebida: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nätverkskonfiguration mottagen: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Конфигурација мреже примљена: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Network config received: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到網路設定: %@" - } - } - } - }, - "mesh.log.nodeinfo.received %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Knoteninformation empfangen für: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Node info received for: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Information du noeud reçue pour : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "מידע אודות מכשיר התקבל: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Odebrano informacje o węźle dla: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Informações do nó recebidas para: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nodinformation mottagen för: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Информације о чвору примљене за: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Node info received for: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到中繼點訊息: %@" - } - } - } - }, - "mesh.log.paxcounter %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Counter message received for: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Counter message received from: %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Counter packet received for: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Counter packet received for: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mensagem do Contador PAX recebida de: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX-räknarmeddelande mottaget från: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Порука PAX бројача примљена од: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Counter message received for: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "為 %@ 收到PAX計數器消息" - } - } - } - }, - "mesh.log.paxcounter.config %@" : { - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Counter config received: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração do Contador PAX recebida: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX-räknarkonfiguration mottagen: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Конфигурација PAX бројача примљена: %@" - } - } - } - }, - "mesh.log.position.config %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Positionskonfiguration empfangen: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Positon config received: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration de la position reçue : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרות מיקום התקבלו: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Odebrano konfigurację pozycji: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração de posição recebida: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Positionskonfiguration mottagen: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Конфигурација позиције примљена: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Positon config received: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到位置配置:%@" - } - } - } - }, - "mesh.log.position.received %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Position empfangen von Knoten: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Position Packet received from node: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Paquet de la position reçu du noeud : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הודעת מיקום התקבלו מ-%@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Odebrano pakiet pozycji od węzła: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Pacote de posição recebido do nó: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Positionspaket mottaget från nod: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Пакет позиције примљен од чвора: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Position Packet received from node: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "從中繼點接收到定位封包: %@" - } - } - } - }, - "mesh.log.power.config %@" : { - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Power config received: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração de energia recebida: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Strömkonfiguration mottagen: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Конфигурација напајања примљена: %@" - } - } - } - }, - "mesh.log.rangetest.config %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Range Test Modul konfiguration empfangen: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Range Test module config received: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration du module test deportée reçue : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרות מודולת בדיקת טווח התקבלו: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Odebrano konfigurację modułu testu zasięgu: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração do módulo de teste de alcance recebida: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Konfiguration för räckviddstestmodulen mottagen: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Конфигурација модула теста домета примљена: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到范围测试模块配置: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到拉距測試模組設定: %@" - } - } - } - }, - "mesh.log.ringtone.config %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "RTTTL Klingeltonkonfiguration empfangen: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "RTTTL Ringtone config received: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration de la sonnerie RTTTL reçue : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרות RTTTL רינגטון התקבלו: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Odebrano konfigurację dzwonka RTTTL: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração de toque RTTTL recebida: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Konfiguration för RTTTL-ringsignal mottagen: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Конфигурација RTTTL мелодије примљена: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "RTTTL Ringtone config received: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到RTTTL鈴聲配置:%@" - } - } - } - }, - "mesh.log.routing.message %@ %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Routing empfangen für RequestID: %@ Ack Status: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Routing received for RequestID: %@ Ack Status: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Routage reçu pour la demande numéro : %@ Status de l'accusé de réception : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "התקבל מסלול עבור בקשה: %@ מצב שליחה: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Odebrano trasowanie dla RequestID: %@ Ack Status: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Roteamento recebido para RequestID: %@ Estado de Ack: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Routing mottagen för RequestID: %@ Ack Status: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Рутирање примљено за ИД захтева: %@ Статус потврде: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Routing received for RequestID: %@ Ack Status: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "為請求ID: %@ 收到路由 Ack狀態: %@" - } - } - } - }, - "mesh.log.serial.config %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Serial Modul Konfiguration empfangen: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Serial module config received: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration du module série reçue : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרות מודולת תקשורת סיריאלית התקבלו: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Odebrano konfigurację modułu szeregowego: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração do módulo serial recebida: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Seriekonfigurationsmodul mottagen: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Конфигурација серијског модула примљена: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Serial module config received: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到串列模組配置:%@" - } - } - } - }, - "mesh.log.sharelocation %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Position von Apple Gerät an Knoten gesendet: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sent a Position Packet from the Apple device GPS to node: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Paquet envoyé avec la position GPS de l'appareil Apple vers le noeud : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "נשלח מיקום ממכשיר האפל למכשיר המשטסטיק: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wysłano pakiet pozycji z GPS urządzenia Apple do węzła: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enviado um Pacote de Posição do GPS do dispositivo Apple para o nó: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Skickade ett positionspaket från Apple-enhetens GPS till nod: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Позициони пакет послат са Епл уређаја на чвор: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sent a Position Packet from the Apple device GPS to node: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "傳送iOS裝置的GPS定位封包到中繼點上: %@" - } - } - } - }, - "mesh.log.storeforward.config %@" : { - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Store & Forward module config received: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration du module Stocker et Transmettre reçue : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרות מודולת שמירה ושליחה התקבלו: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Store & Forward module config received: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração do módulo Store & Forward recebida: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Konfiguration för Store & Forward-modulen mottagen: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Конфигурација модула за чување и прослеђивање примљена: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Store & Forward module config received: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到儲存與轉發模組配置:%@" - } - } - } - }, - "mesh.log.telemetry.config %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Telemetrie Modul Konfiguration empfangen: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Telemetry module config received: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration du module télémetrie reçue : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרות מודולת טלמטריה התקבלו: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Odebrano konfigurację modułu telemetrii: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração do módulo de telemetria recebida: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Telemetrimodulkonfiguration mottagen: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Конфигурација модула телеметрије примљена: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Telemetry module config received: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到遠測模組設定: %@" - } - } - } - }, - "mesh.log.telemetry.received %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Telemetrie empfangen für: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Telemetry received for: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Télémetrie reçue pour : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "התקבל טלמטריה עבור: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Telemetria odebrana dla: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Telemetria recebida para: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Telemetri mottagen för: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Телеметрија примљена за: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Telemetry received for: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到遠測資料: %@" - } - } - } - }, - "mesh.log.textmessage.received" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nachricht von der Textnachricht-App empfangen." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message received from the text message app." - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message reçu depuis l'application de messagerie texte." - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הודעת טקסט התקבלה." - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wiadomość odebrana z aplikacji do wysyłania wiadomości tekstowych." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mensagem recebida do App de mensagem de texto." - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Meddelande mottaget från textmeddelandeappen." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Порука примљена из апликације за текстуалне поруке." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message received from the text message app." - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "從文字消息應用程序收到消息。" - } - } - } - }, - "mesh.log.textmessage.send.failed %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nachricht senden fehlgeschlagen. Nicht korrekt verbunden zu %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message Send Failed, not properly connected to %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Erreur d'envoi du message, mauvaise connexion à %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שליחת הודעה נכשלה, אין חיבוריות ל-%@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nieudane wysłanie wiadomości, brak prawidłowego połączenia z %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Falha no envio da mensagem, não conectado corretamente a %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Misslyckades med att skicka meddelande, inte korrekt ansluten till %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Слање поруке није успело, није правилно повезано са: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message Send Failed, not properly connected to %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "訊息傳送失敗, 沒有正確連接到 %@" - } - } - } - }, - "mesh.log.textmessage.sent %@ %@ %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sende Nachricht %@ von %@ an %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sent message %@ from %@ to %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Envoi du message %@ de %@ à %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "נשלחה הודעה %@ מ-%@ ל-%@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wysłano wiadomość %@ od %@ do %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mensagem enviada %@ de %@ para %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Skickade meddelande %@ från %@ till %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Порука послата %@ са %@ на %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sent message %@ from %@ to %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "傳送訊息 %@ 從 %@ 到 %@" - } - } - } - }, - "mesh.log.traceroute.received.direct %@" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Traceroute Anforderung an Knoten gesendet: %@ wurde direkt empfangen." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trace Route request sent to node: %@ was recieived directly." - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "La demande de Trace Route envoyée au noeud : %@ a été directement reçue." - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "בקשת בדיקת מסלול נשלחה למכשיר: %@ התקבל ישירות." - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Żądanie śledzenia trasy wysłane do węzła: %@ zostało odebrane bezpośrednio." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Solicitação de Rastreamento enviada para o nó: %@\" foi recebida diretamente." - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Spårruttförfrågan skickad till nod: %@ mottogs direkt." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Захтев за тражење путања послат на чвор: %@ је примљен директно." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trace Route request sent to node: %@ was recieived directly." - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "直接收到發送至節點的追蹤路由請求:%@" - } - } - } - }, - "mesh.log.traceroute.received.route %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Traceroute Ergebnis: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trace Route request returned: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "La demande de Trace Route est revenue : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "בקשת בדיקת מסלול הצליחה: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Żądanie śledzenia trasy zwrócone: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Solicitação de Rastreamento retornada: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Spårruttförfrågan returnerade: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Захтев за тражење путања враћен: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trace Route request returned: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "返回的追蹤路由請求:%@" - } - } - } - }, - "mesh.log.traceroute.sent %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sende Traceroute Anforderung zu Knoten: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sent a Trace Route Request to node: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Envoi d'une demande de Trace Route au noeud : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "נשלחה בקשת בדיקת מסלול למכשיר: %@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wysłano żądanie śledzenia trasy do węzła: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enviei uma solicitação de Rastreamento para o nó: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Skickade en spårruttförfrågan till nod: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Захтев за тражење путања послат на чвор: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sent a Trace Route Request to node: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "發送追蹤路由請求至節點:%@" - } - } - } - }, - "mesh.log.wantconfig %@" : { - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Issuing Want Config to %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Envoi d'un Want Config à %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שולח בקשת הגדרות ל-%@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wydawanie Want Config to %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Emitindo Configuração Desejada para %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Utfärdar Want Config till %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Издавање захтева за конфигурацију на: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Issuing Want Config to %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "對 %@ 發出配置請求" - } - } - } - }, - "mesh.log.waypoint.received %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wegpunkt von Knoten empfangen: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Waypoint Packet received from node: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Paquet Waypoint reçu du noeud : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "נקודת ציון התקבלה מ-%@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Odebrano pakiet punktu orientacyjnego od węzła: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Pacote de Ponto de Referência recebido do nó: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Vägpunktspaket mottaget från nod: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Пакет са тачкама пута примљен од чвора: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Waypoint Packet received from node: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "從節點收到航點封包:%@" - } - } - } - }, - "mesh.log.waypoint.sent %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wegpunkt gesendet von: %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sent a Waypoint Packet from: %@" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Paquet Waypoint envoyé depuis : %@" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "נשלחה נקודת ציון מ-%@" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wysłano pakiet punktu orientacyjnego z: %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enviado um Pacote de Ponto de Referência de: %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Skickade en vägpunktspaket från: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Пакет са тачкама пута послат од: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sent a Waypoint Packet from: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "從 %@ 發送航點封包" + "value" : "Mesh 地圖" } } } @@ -19671,87 +17331,50 @@ "value" : "Meshtastic Knoten %@ hat Kanäle mit dir geteilt" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il Nodo Meshtastic %@ ha condiviso i canali con voi" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Meshtastic чвор %@ је поделио канале са вама." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Meshtastic 節點 %@ 向您分享頻道資訊" + } } } }, "Meshtastic® Copyright Meshtastic LLC" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Meshtastic® Copyright Meshtastic LLC" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Meshtastic® Ауторска права Meshtastic LLC" } - } - } - }, - "message" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nachricht" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הודעה" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wiadomość" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mensagem" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Meddelande" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Порука" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "消息" - } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "訊息" + "value" : "Meshtastic® Copyright Meshtastic LLC" } } } + }, + "message" : { + }, "Message" : { "localizations" : { @@ -19761,11 +17384,23 @@ "value" : "Nachricht" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Messaggio" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Порука" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "訊息" + } } } }, @@ -19777,25 +17412,27 @@ "value" : "Nachrichteninhalt überschreitet 200 Bytes." } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il contenuto del messaggio supera i 200 byte." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Садржај поруке премашује 200 бајтова." } - } - } - }, - "Message Status Options" : { - "localizations" : { - "sr" : { + }, + "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Опције статуса поруке" + "value" : "訊息內容超過 200 位元組。" } } } }, - "message.details" : { + "Message Details" : { "localizations" : { "de" : { "stringUnit" : { @@ -19803,12 +17440,6 @@ "value" : "Nachrichtendetails" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message Details" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -19821,18 +17452,18 @@ "value" : "פרטי הודעה" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dettagli del messaggio" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Szczegóły wiadomości" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dados de Mensagem" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -19854,29 +17485,155 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "詳細訊息" + "value" : "詳細資訊" } } } }, - "messages" : { + "Message received from the text message app." : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Nachrichten" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Messages" + "value" : "Nachricht von der Textnachricht-App empfangen." } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Messages" + "value" : "Message reçu depuis l'application de messagerie texte." + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הודעת טקסט התקבלה." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Messaggio ricevuto dall'app messaggi di testo." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wiadomość odebrana z aplikacji do wysyłania wiadomości tekstowych." + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Meddelande mottaget från textmeddelandeappen." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Порука примљена из апликације за текстуалне поруке." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Message received from the text message app." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Message received from the text message app." + } + } + } + }, + "Message Send Failed, not properly connected to %@" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nachricht senden fehlgeschlagen. Nicht korrekt verbunden zu %@" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Erreur d'envoi du message, mauvaise connexion à %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שליחת הודעה נכשלה, אין חיבוריות ל-%@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Invio messaggio fallito, connessione non corretta a %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nieudane wysłanie wiadomości, brak prawidłowego połączenia z %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Misslyckades med att skicka meddelande, inte korrekt ansluten till %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Слање поруке није успело, није правилно повезано са: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Message Send Failed, not properly connected to %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Message Send Failed, not properly connected to %@" + } + } + } + }, + "Message Status Options" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Opzioni di stato del messaggio" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Опције статуса поруке" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "訊息狀態選項" + } + } + } + }, + "Messages" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nachrichten" } }, "he" : { @@ -19885,18 +17642,18 @@ "value" : "הודעות" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Messaggi" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Wiadomości" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mensagens" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -19923,22 +17680,6 @@ } } }, - "Messages" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nachrichten" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Поруке" - } - } - } - }, "Messages separate with |" : { "localizations" : { "de" : { @@ -19947,21 +17688,131 @@ "value" : "Nachrichten getrennt mit |" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "I messaggi sono separati da |" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Поруке се раздвајају са |" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "使用「 | 」來隔開訊息" + } } } }, "Metric" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Metrico" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Метрика" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "公制" + } + } + } + }, + "Midday" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mittag" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mezzogiorno" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Подне" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "中午" + } + } + } + }, + "Military Grid Reference System" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Militärisches Gitternetz-Referenzsystem" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Military Grid Reference System" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "Military Grid Reference System" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sistema di riferimento della griglia militare" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wojskowa siatka odniesienia" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Militärt rutnätsreferenssystem" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Војни референтни систем мреже" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "军事网格参考系统" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "軍事網格參考系統" + } } } }, @@ -19973,11 +17824,23 @@ "value" : "Minimum Distanz" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Distanza minima" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Минимум раздаљине" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "最短距離" + } } } }, @@ -19989,35 +17852,71 @@ "value" : "Minimum Intervall" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Intervallo minimo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Минимални интервал" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "最短時間間隔" + } } } }, "Minimum time between detection broadcasts" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tempo minimo tra le trasmissioni di rilevamento" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Минимално време између емитовања детекције" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "偵測廣播之間的最短時間間隔" + } } } }, "Mininum time between detection broadcasts. Default is 45 seconds." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tempo minimo tra le trasmissioni di rilevamento. L'impostazione predefinita è 45 secondi." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Минимално време између емитовања детекције. Подразумевано је 45 секунди." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "偵測廣播之間的最短時間間隔,預設為 45 秒。" + } } } }, - "mode" : { + "Mode" : { "localizations" : { "de" : { "stringUnit" : { @@ -20025,12 +17924,6 @@ "value" : "Modus" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mode" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -20043,18 +17936,18 @@ "value" : "מצב" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Modalità" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Tryb" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Modo" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -20083,6 +17976,12 @@ }, "Model" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Modello" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -20094,10 +17993,44 @@ "state" : "translated", "value" : "模型" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "型號" + } } } }, - "module.configuration" : { + "Moderate" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Moderato" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Умерено" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "适度" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "中等" + } + } + } + }, + "Module Configuration" : { "localizations" : { "de" : { "stringUnit" : { @@ -20105,12 +18038,6 @@ "value" : "Modul Konfiguration" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Module Configuration" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -20123,18 +18050,18 @@ "value" : "הגדרות מודולה" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione del modulo" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Konfiguracja modułu" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração do Módulo" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -20156,50 +18083,100 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "模塊設定" + "value" : "模組設定" } } } }, - "mqtt" : { + "Morning" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "MQTT" + "value" : "Morgen" } }, - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "MQTT" + "value" : "Mattina" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Јутро" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "早晨" + } + } + } + }, + "Most data on your mesh is sent over the primary channel. You can set up secondary channels to create additional messaging groups secured by their own key. [Channel config tips](https://meshtastic.org/docs/configuration/tips/)" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Die meisten Daten in deinem Mesh werden über den primären Kanal gesendet. Du kannst sekundäre Kanäle einrichten, um zusätzliche Nachrichtengruppen zu erstellen, die durch ihren eigenen Schlüssel gesichert sind. [Tipps zur Kanalkonfiguration](https://meshtastic.org/docs/configuration/radio/channels/)" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "MQTT" + "value" : "La pluspart des données de votre maillage sont envoyées sur le canal principal. Vous pouvez définir des canaux secondaires pour créer des groupes de messagerie additionnelle sécurisés avec leur propre clé. [Conseils de configuration du canal](https://meshtastic.org/docs/configuration/tips/)" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "MQTT" + "value" : "Most data on your mesh is sent over the primary channel. You can set up secondary channels to create additional messaging groups secured by their own key. [Channel config tips](https://meshtastic.org/docs/configuration/radio/channels/)" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La maggior parte dei dati sulla rete viene inviata attraverso il canale primario. È possibile impostare canali secondari per creare gruppi di messaggistica aggiuntivi protetti da una propria chiave. [Suggerimenti per la configurazione del canale](https://meshtastic.org/docs/configuration/tips/)" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "MQTT" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "MQTT" + "value" : "Most data on your mesh is sent over the primary channel. You can set up secondary channels to create additional messaging groups secured by their own key. [Channel config tips](https://meshtastic.org/docs/configuration/radio/channels/)" } }, "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "De flesta data i ditt mesh-nätverk skickas över primärkanalen. Du kan ställa in sekundära kanaler för att skapa ytterligare meddelandegrupper skyddade av sin egen nyckel. Tips för kanalkonfiguration" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Већина података на вашој мрежи шаље се преко примарног канала. Можете подесити секундарне канале како бисте креирали додатне групе за размену порука, које су обезбеђене сопственим кључем. [Савети за конфигурацију канала](https://meshtastic.org/docs/configuration/tips/)" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mesh 网格上的大部分数据都通过主频道发送。您可以设置辅助频道以创建由其自身密钥保护的消息组。[频道配置提示](https://meshtastic.org/docs/configuration/tips/)" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "您的Mesh網路中大部分資料將透過主要頻道傳輸。若需要額外的訊息群組,您可以設定次要頻道,並設定專屬金鑰進行保護。" + } + } + } + }, + "MQTT" : { + "localizations" : { + "it" : { "stringUnit" : { "state" : "translated", "value" : "MQTT" @@ -20225,23 +18202,7 @@ } } }, - "MQTT" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "MQTT" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "MQTT" - } - } - } - }, - "mqtt.clientproxy" : { + "MQTT Client Proxy" : { "localizations" : { "de" : { "stringUnit" : { @@ -20249,12 +18210,6 @@ "value" : "MQTT Client Proxy" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "MQTT Client Proxy" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -20267,18 +18222,18 @@ "value" : "MQTT Client Proxy" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Proxy client MQTT" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Klient Proxy MQTT" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Proxy do Cliente MQTT" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -20305,7 +18260,7 @@ } } }, - "mqtt.config" : { + "MQTT Config" : { "localizations" : { "de" : { "stringUnit" : { @@ -20313,12 +18268,6 @@ "value" : "MQTT Konfiguration" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "MQTT Config" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -20331,18 +18280,18 @@ "value" : "הגדרות MQTT" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione MQTT" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Konfiguracja MQTT" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração MQTT" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -20369,221 +18318,213 @@ } } }, - "mqtt.connect" : { - "extractionState" : "migrated", + "MQTT module config received: %@" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Verbunden mit MQTT" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Connect to MQTT" + "value" : "MQTT Modulkonfiguration empfangen: %@" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Connecter à MQTT" + "value" : "Configuration du module MQTT reçue : %@" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "התחבר ל-MQTT" + "value" : "הגדרות מודולת MQTT התקבלו: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione del modulo MQTT ricevuta: %@" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Connect to MQTT" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Conectar ao MQTT" + "value" : "Otrzymano konfigurację modułu MQTT: %@" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Anslut till MQTT" + "value" : "MQTT-modulkonfiguration mottagen: %@" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Повежи се на MQTT" + "value" : "Конфигурација MQTT модула примљена: %@" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "连接至 MQTT" + "value" : "收到 MQTT 模块配置:%@" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "連線到 MQTT" + "value" : "MQTT module config received: %@" } } } }, - "mqtt.disconnect" : { - "extractionState" : "migrated", + "Multiplier" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Trennen von MQTT" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Disconnect from MQTT" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Déconnecter le MQTT" + "value" : "Multiplier" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "התנתק מ-MQTT" + "value" : "Multiplier" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Moltiplicatore" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Disconnect from MQTT" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Desconectar do MQTT" + "value" : "Multiplier" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Koppla från MQTT" + "value" : "Multiplikator" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Развежи се од MQTT" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "断开 MQTT 连接" + "value" : "Мултипликатор" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "是否與 MQTT 連接" - } - } - } - }, - "mqtt.username" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Benutzername" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Username" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nom d'utilisateur" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שם משתמש" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nazwa użytkownika" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nome de Utilizador" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Användarnamn" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Корисничко име" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "用户名称" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "用戶名稱" + "value" : "修正倍數" } } } }, "Must be a single emoji" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Deve essere una singola emoji" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Мора бити један емотикон" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "必須只使用一個表情符號" + } + } + } + }, + "MyInfo received: %@" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "MyInfo empfangen: %@" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "MesInfos reçues : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "MyInfo התקבל: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "MyInfo ricevuto: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Otrzymano Moje Informacje: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Min info mottagen: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Моје информације примљене: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "MyInfo received: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "MyInfo received: %@" + } } } }, "Nag timeout" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Timeout di Nag" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Период чекања је истекао" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "提醒逾時" + } } } }, - "name" : { + "Name" : { "localizations" : { "de" : { "stringUnit" : { @@ -20591,42 +18532,12 @@ "value" : "Name" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Name" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nom" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שם" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nazwa" - } - }, - "pt-PT" : { + "it" : { "stringUnit" : { "state" : "translated", "value" : "Nome" } }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Namn" - } - }, "sr" : { "stringUnit" : { "state" : "translated", @@ -20647,28 +18558,6 @@ } } }, - "Name" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Name" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Име" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "名称" - } - } - } - }, "Name must be less than 30 bytes" : { "localizations" : { "de" : { @@ -20677,6 +18566,12 @@ "value" : "Name muss kürzer als 30 Bytes sein" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il nome deve essere inferiore a 30 byte" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -20688,30 +18583,60 @@ "state" : "translated", "value" : "名称必须少于 30 字节" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "名稱必須小於 30 bytes 。" + } } } }, "Navigate to node" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Spostarsi sul nodo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Пребаци се на чвор" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "導航至該節點" + } } } }, "Nearby Topics" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Argomenti vicini" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Теме у окружењу" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "鄰近的主題" + } } } }, - "network" : { + "Network" : { "localizations" : { "de" : { "stringUnit" : { @@ -20719,12 +18644,6 @@ "value" : "Netzwerk" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Network" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -20737,18 +18656,18 @@ "value" : "רשת" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rete" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Sieć" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Rede" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -20775,39 +18694,7 @@ } } }, - "Network Status Orange" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Статус мреже: Наранџаст" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "网络状态 橙色" - } - } - } - }, - "Network Status Red" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Статус мреже: Црвен" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "网络状态 红色" - } - } - } - }, - "network.config" : { + "Network Config" : { "localizations" : { "de" : { "stringUnit" : { @@ -20815,12 +18702,6 @@ "value" : "Netzwerkeinstellungen" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Network Config" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -20833,18 +18714,18 @@ "value" : "הגדרות רשת" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione della rete" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Konfiguracja sieci" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração de Rede" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -20871,6 +18752,120 @@ } } }, + "Network config received: %@" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Netzwerkkonfiguration empfangen: %@" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configuration du réseau reçue : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הגדרות רשת התקבלו: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione di rete ricevuta: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Odebrano konfigurację sieci: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nätverkskonfiguration mottagen: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Конфигурација мреже примљена: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Network config received: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Network config received: %@" + } + } + } + }, + "Network Status Orange" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Stato della rete Arancione" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Статус мреже: Наранџаст" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "网络状态 橙色" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "網路狀態 橘" + } + } + } + }, + "Network Status Red" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Stato della rete Rosso" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Статус мреже: Црвен" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "网络状态 红色" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "網路狀態 紅" + } + } + } + }, "Never" : { "localizations" : { "de" : { @@ -20879,108 +18874,76 @@ "value" : "Nie" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mai" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Никада" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "永不" + } } } }, "New Node" : { - "extractionState" : "manual", "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nuovo nodo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Нови чвор" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "新節點" + } } } }, "New Node has been discovered" : { - "extractionState" : "manual", "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "È stato scoperto un nuovo nodo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Откривен је нови чвор" } - } - } - }, - "New Node Notifications" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mitteilungen über neue Knoten" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "New Node Notifications" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "New Node Notifications" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "New Node Notifications" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "New Node Notifications" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Notificações de Nó Novo" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "New Node Notifications" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Обавештења о новим чворовима" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "新节点通知" - } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "新節點通知" + "value" : "已發現新節點" } } } }, - "New Zealand 865mhz" : { - "extractionState" : "manual", + "New Zealand 865MHz" : { "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "New Zealand 865MHz" + "value" : "Nuova Zelanda 865MHz" } }, "sr" : { @@ -20988,6 +18951,12 @@ "state" : "translated", "value" : "Нови зеланд 865MHz" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "紐西蘭 865MHz" + } } } }, @@ -20999,6 +18968,12 @@ "value" : "Neuere Firmware ist verfügbar" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "È disponibile un firmware più recente" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -21010,6 +18985,156 @@ "state" : "translated", "value" : "有固件可以更新" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "有更新的韌體可供使用" + } + } + } + }, + "Nighttime" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nacht" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Notte" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ноћ" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "夜晚" + } + } + } + }, + "NMEA Positions" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "NMEA Positionen" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Positions NMEA" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "מיקומי NMEA" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Posizioni NMEA" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pozycje NMEA" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "NMEA-positioner" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "NMEA позиције" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "NMEA 位置" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "NMEA 位置" + } + } + } + }, + "No Channel" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kein Kanal" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pas de canal" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "אין ערוץ" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nessun canale" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Brak kanału" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingen kanal" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Нема канала" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "没有频道" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "没有頻道" + } } } }, @@ -21021,26 +19146,114 @@ "value" : "Kein verbundener Knoten" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nessun nodo collegato" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Нема повезаног чвора" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "沒有已連接的節點" + } + } + } + }, + "No device connected" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kein Gerät verbunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aucun appareil connecté" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "אין מכשיר מחובר" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nessun dispositivo collegato" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Brak podłączonych urządzeń" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingen enhet ansluten" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Нема повезаних уређаја" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "设备未连接" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "未連接到節點" + } } } }, "No Device Metrics" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nessuna metrica del dispositivo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Нема метрика уређаја." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "沒有已連接的節點" + } } } }, "No Environment Metrics" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nessuna metrica ambientale" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -21052,11 +19265,102 @@ "state" : "translated", "value" : "没有环境指标" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "無環境數據" + } + } + } + }, + "No Interface" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Keine Schnittstelle" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pas d'interface" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "אין ממשק" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nessuna interfaccia" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Brak interfejsu" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inget gränssnitt" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Нема интерфејса" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "无连接" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "無連接" + } + } + } + }, + "No PAX Counter Logs" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nessun registro del contatore PAX" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inga loggar för PAX-räknare" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Нема логова PAX бројача" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "沒有 PAX 計數器日誌" + } } } }, "No PIN (Just Works)" : { - "extractionState" : "migrated", "localizations" : { "de" : { "stringUnit" : { @@ -21064,12 +19368,6 @@ "value" : "Keine PIN (geht einfach)" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "No PIN (Just Works)" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -21082,18 +19380,18 @@ "value" : "ללא קוד (פשוט עובד)" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nessun PIN (funziona e basta)" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Brak PINu (po prostu działa)" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sem PIN (Simplesmente Funciona)" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -21128,85 +19426,160 @@ "value" : "Keine Positionen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nessuna posizione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Нема позиција" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "沒有位置" + } } } }, "No Power Metrics" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nessuna metrica di potenza" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Нема метрике снаге" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "沒有電源指標" + } } } }, - "no.nodes" : { - "extractionState" : "manual", + "No Response" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Keine Meshtastic Knoten gefunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "No Meshtastic Nodes Found" + "value" : "Keine Antwort" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Aucun noeud Meshtastic trouvé" + "value" : "Pas de réponse" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "לא נמצאו מכשירי משטסטיק" + "value" : "אין תגובה" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nessuna risposta" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Nie znaleziono węzłów Meshtastic" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nenhum Nó Meshtastic Encontrado" + "value" : "Brak odpowiedzi" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Inga Meshtastic-noder hittades" + "value" : "Inget svar" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Нема пронађених Мештастик чворова" + "value" : "Нема одговора" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "未找到 Meshtastic 节点" + "value" : "无响应" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "未找到 Meshtastic 中繼點" + "value" : "無回應" + } + } + } + }, + "No Route" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Keine Route" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pas de route" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "אין מסלול" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nessun percorso" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Brak trasy" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingen rutt" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Нема руте" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "找不到目标" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "找不到目標" } } } @@ -21219,11 +19592,23 @@ "value" : "Knoten" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nodo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Чвор" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "節點" + } } } }, @@ -21231,10 +19616,16 @@ "localizations" : { "en" : { "stringUnit" : { - "state" : "new", + "state" : "translated", "value" : "Node Core Data Backup %1$@/%2$@ - %3$@ - %4$@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Backup dei dati del nucleo del nodo %1$@/%2$@ - %3$@ - %4$@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -21246,6 +19637,12 @@ "state" : "translated", "value" : "节点核心数据备份 %1$@/%2$@ - %3$@ - %4$@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Node Core Data Backup %1$@/%2$@ - %3$@ - %4$@" + } } } }, @@ -21257,11 +19654,23 @@ "value" : "Knoten hat keine Position" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il nodo non ha posizioni" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Чвор нема позиције" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "節點沒有位置資訊" + } } } }, @@ -21273,21 +19682,103 @@ "value" : "Knoten Historie" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Storia del nodo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Историја чвора" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "節點歷史位置" + } } } }, "Node Info Broadcast Interval" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Intervallo di trasmissione delle informazioni sul nodo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Интервал емитовања информација о чвору" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "節點資訊廣播間隔" + } + } + } + }, + "Node info received for: %@" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Knoteninformation empfangen für: %@" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Information du noeud reçue pour : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "מידע אודות מכשיר התקבל: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ricevute informazioni sul nodo per: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Odebrano informacje o węźle dla: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nodinformation mottagen för: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Информације о чвору примљене за: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Node info received for: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Node info received for: %@" + } } } }, @@ -21299,11 +19790,23 @@ "value" : "Knotenkarte" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mappa dei nodi" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Мапа чворова" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "節點地圖" + } } } }, @@ -21315,80 +19818,27 @@ "value" : "Knotennummer" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Numero di nodo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Број чвора" } - } - } - }, - "nodelist.filter.distance %@" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "bis zu %@ entfernt" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "up to %@ away" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "up to %@ away" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "up to %@ away" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "up to %@ away" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "até %@ de distância" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "upp till %@ bort" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "удаљено до максималних %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "最远距离 %@" - } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "距離達 %@ 以內" + "value" : "節點編號" } } } }, - "nodes" : { + "Nodes" : { "localizations" : { "de" : { "stringUnit" : { @@ -21396,12 +19846,6 @@ "value" : "Knoten" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nodes" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -21414,10 +19858,10 @@ "value" : "מכשירים" } }, - "pt-PT" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Nós" + "value" : "Nodi" } }, "se" : { @@ -21441,13 +19885,12 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "中繼點" + "value" : "節點" } } } }, - "nodes %@" : { - "extractionState" : "migrated", + "Nodes (%@)" : { "localizations" : { "de" : { "stringUnit" : { @@ -21455,12 +19898,6 @@ "value" : "Knoten (%@)" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nodes (%@)" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -21473,18 +19910,18 @@ "value" : "מכשירים (%@)" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nodi (%@)" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Węzły (%@)" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nós (%@)" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -21506,81 +19943,191 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "中繼點 (%@)" + "value" : "節點 (%@)" + } + } + } + }, + "None" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Keins" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aucun" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "ללא" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nessuno" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Brak" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingen" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ништа" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "无" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "無" } } } }, "Not a valid route file" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Non è un file di percorso valido" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Није валидна датотека путања" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "不是一個有效的路徑檔案" + } } } }, - "not.connected" : { + "Not Authorized" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Kein Gerät verbunden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "No device connected" + "value" : "Nicht authorisiert" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Aucun appareil connecté" + "value" : "Non autorisé" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "אין מכשיר מחובר" + "value" : "לא מאושר" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Non autorizzato" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Brak podłączonych urządzeń" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nenhum dispositivo conectado" + "value" : "Nieautoryzowany" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Ingen enhet ansluten" + "value" : "Inte auktoriserad" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Нема повезаних уређаја" + "value" : "Није ауторизовано" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "设备未连接" + "value" : "未授权" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "未連接到電台" + "value" : "未授權" + } + } + } + }, + "Not Present" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Absent" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "לא קיים" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Non presente" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inte närvarande" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Није пристуно" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "不存在" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "無模組" } } } @@ -21593,11 +20140,23 @@ "value" : "Knoten" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Note" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Белешке" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "筆記" + } } } }, @@ -21609,11 +20168,23 @@ "value" : "Anzahl: %@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Num: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Број: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Num: %@" + } } } }, @@ -21625,11 +20196,23 @@ "value" : "Anzahl Hops" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Numero di hop" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Број хопова" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "轉送跳數" + } } } }, @@ -21641,11 +20224,23 @@ "value" : "Anzahl Einträge" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Numero di record" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Број записа" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "記錄數量" + } } } }, @@ -21657,81 +20252,27 @@ "value" : "Anzahl Satelliten" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Numero di satelliti" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Број сателита" } - } - } - }, - "numbers.punctuation" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ziffern und Interpunktion" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Numbers and Punctuation" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nombres and Ponctuation" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "מספרים וסימני פיסוק " - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cyfry i interpunkcja" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Números e Pontuação" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Siffror och skiljetecken" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Бројеви и интерпункција" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "数字和标点符号" - } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "數字和標點符號" + "value" : "衛星數量" } } } }, - "off" : { - "extractionState" : "migrated", + "Off" : { "localizations" : { "de" : { "stringUnit" : { @@ -21739,12 +20280,6 @@ "value" : "Aus" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Off" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -21757,18 +20292,18 @@ "value" : "כבוי" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Spento" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Wyłączony" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Desligado" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -21795,71 +20330,6 @@ } } }, - "offline" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Offline" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Offline" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Hors ligne" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "מנותק" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Offline" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Offline" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Offline" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ван мреже" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "离线" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "離線" - } - } - } - }, "OK" : { "localizations" : { "de" : { @@ -21868,16 +20338,34 @@ "value" : "Ok" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "OK" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "ОК" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "OK" + } } } }, "Ok to MQTT" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ok a MQTT" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -21889,6 +20377,12 @@ "state" : "translated", "value" : "Ok to MQTT" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ok to MQTT" + } } } }, @@ -21900,6 +20394,12 @@ "value" : "OLED Typ" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tipo OLED" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -21911,11 +20411,16 @@ "state" : "translated", "value" : "OLED 类型" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "OLED 類型" + } } } }, - "on.boot" : { - "extractionState" : "migrated", + "On Boot Only" : { "localizations" : { "de" : { "stringUnit" : { @@ -21923,12 +20428,6 @@ "value" : "Nur beim Starten" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "On Boot Only" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -21941,18 +20440,18 @@ "value" : "רק בעת הדלקה" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Solo all'avvio" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Tylko przy uruchomieniu" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "No arranque" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -21981,6 +20480,12 @@ }, "Onboarding for licensed operators requires firmware 2.0.20 or greater. Make sure to refer to your local regulations and contact the local amateur frequency coordinators with questions." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Per l'attivazione degli operatori con licenza è necessario il firmware 2.0.20 o superiore. Assicuratevi di consultare le normative locali e di contattare i coordinatori delle frequenze amatoriali locali per eventuali domande." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -21992,6 +20497,12 @@ "state" : "translated", "value" : "业余无线电使用需要固件 2.0.20 或更高版本。请务必参考当地法规,并联系当地业余频率协调人员咨询相关问题。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "持照操作員的需使用韌體版本 2.0.20 或以上。請務必參考當地法規,若有疑問,請聯繫當地的業餘無線電頻率協調單位。" + } } } }, @@ -22003,11 +20514,53 @@ "value" : "Eine Stunde" } }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Une heure" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שעה אחת" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Un'ora" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Jedna Godzina" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "En Timme" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Један сат" } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "一小时" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "1 小時" + } } } }, @@ -22019,10 +20572,110 @@ "value" : "Eine Minute" } }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Une minute" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "דקה אחת" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Un minuto" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Jedna Minuta" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "En Minut" + } + }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Једна минута" + "value" : "Један минут" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "一分钟" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "1 分鐘" + } + } + } + }, + "One Second" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Eine Sekunde" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Une seconde" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שניה אחת" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Un secondo" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Jedna Sekunda" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "En Sekund" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Један секунд" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "一秒" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "1 秒" } } } @@ -22035,11 +20688,101 @@ "value" : "Online" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "In linea" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "На мрежи" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "在線" + } + } + } + }, + "Only permitted for SENSOR, TRACKER and TAK_TRACKER roles, this will inhibit all rebroadcasts, not unlike CLIENT_MUTE role." : { + "localizations" : { + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "僅允許用於 SENSOR、TRACKER 和 TAK_TRACKER 角色,啟用後會禁止所有訊息的重新廣播,效果類似於 CLIENT_MUTE 角色。" + } + } + } + }, + "Only rebroadcasts packets from the core portnums: NodeInfo, Text, Position, Telemetry, and Routing." : { + "localizations" : { + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "僅會重傳來自核心 portnum 的封包:NodeInfo、Text、Position、Telemetry 和 Routing" + } + } + } + }, + "Open Location Code (aka Plus Codes)" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Open Location Code (aka Plus Codes)" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Open Location Code (alias Plus Codes)" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "Open Location Code (aka Plus Codes)" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Codice di localizzazione aperto (alias Codice Plus)" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Otwarty Kod Lokalizacji (tzw. Plus Kody)" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Öppen Platskod (även känd som Pluskoder)" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Отворени код локације (тј. Плус кодови)" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "开放的位置代码(又称加码)" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "開放位置代碼" + } } } }, @@ -22051,6 +20794,12 @@ "value" : "Einstellungen öffnen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aprire le impostazioni" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -22062,16 +20811,21 @@ "state" : "translated", "value" : "打开设置" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "打開設定" + } } } }, - "optimized.for.2.color.displays" : { - "extractionState" : "manual", + "Optimized for 2 color displays" : { "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Optimized for 2 color displays" + "value" : "Ottimizzato per i display a 2 colori" } }, "sr" : { @@ -22079,11 +20833,81 @@ "state" : "translated", "value" : "Оптимизовано за двобојне дисплеје" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "為雙色螢幕最佳化" + } + } + } + }, + "Optimized for ATAK system communication, reduces routine broadcasts." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Optimiert für ATAK-Systemkommunikation, verringert die Anzahl der Routineübertragungen." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Optimisé pour le système de communication ATAK, diminue les émissions de routine." + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "מותאם למערכת ATAK, מקטין תקשורת קבועה." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ottimizzato per la comunicazione del sistema ATAK, riduce le trasmissioni di routine." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Optimized for ATAK system communication, reduces routine broadcasts." + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Optimerad för kommunikation med ATAK-systemet, minskar rutinutsändningar." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Оптимизован за комуникацију са ATAK системом, смањује рутинске емисије." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "针对 ATAK 系统通信进行优化,减少常规广播。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "為 ATAK 系統通訊最佳化,並減少例行廣播頻率。" + } } } }, "Optional fields to include when assembling position messages. the more fields are included, the larger the message will be - leading to longer airtime and a higher risk of packet loss" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Campi opzionali da includere quando si assemblano i messaggi di posizione. Più campi sono inclusi, più grande sarà il messaggio, con conseguente allungamento dei tempi di trasmissione e un maggiore rischio di perdita di pacchetti" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -22095,20 +20919,38 @@ "state" : "translated", "value" : "包含的字段越多,信息就越大,导致通讯时间更长,丢包风险更高" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "組合位置訊息時可選擇加入的可選欄位。加入的欄位越多,訊息體積越大,將導致空中傳輸時間增加,並提高封包遺失的風險。" + } } } }, "Optional GPIO" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "GPIO opzionale" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Опциони GPIO" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "可選 GPIO" + } } } }, - "options" : { + "Options" : { "localizations" : { "de" : { "stringUnit" : { @@ -22116,12 +20958,6 @@ "value" : "Optionen" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Options" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -22134,18 +20970,18 @@ "value" : "הגדרות" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Opzioni" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Opcje" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Opções" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -22172,50 +21008,122 @@ } } }, - "Options" : { + "Ordnance Survey Grid Reference" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Optionen" + "value" : "Ordnance Survey Gitterreferenz" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ordnance Survey Grid Reference" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ordnance Survey Grid Reference" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Riferimento di griglia Ordnance Survey" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Brytyjski Układ Odniesienia" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ordnance Survey Rutnätsreferens" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Опције" + "value" : "Референца мреже Орданс Сурвеја" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "选项" + "value" : "英国国土测量局网格参考" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "英國國土測量局網格參考系統" } } } }, "OS Log Entry Details" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dettagli della voce del registro OS" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Детаљи уноса ОС дневника" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "作業系統日誌條目詳細資訊" + } } } }, "OTA Updates are not supported on this NRF Device." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Gli aggiornamenti OTA non sono supportati da questo dispositivo NRF." + } + }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "OTA ажурирања нису подржана на овом NRF уређају." + "value" : "ОТА ажурирања нису подржана на овом NRF уређају." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "OTA 更新不支持 NRF 设备" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "此 NRF 裝置不支援 OTA(無線)更新。" } } } }, "OTA Updates are not supported on your platform." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Gli aggiornamenti OTA non sono supportati dalla vostra piattaforma." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -22227,16 +21135,34 @@ "state" : "translated", "value" : "OTA 更新不支持你的平台" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "您的平台不支援 OTA(無線)更新。" + } } } }, "Other data sources" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Altre fonti di dati" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Остали извори података" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "其他資料來源" + } } } }, @@ -22248,51 +21174,167 @@ "value" : "Ausgabe von Echtzeit-Fehlersuchprotokollen über die serielle Schnittstelle, Anzeige und Export von positionskorrigierten Geräteprotokollen über Bluetooth." } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Emissione di registrazioni di debug in tempo reale via seriale, visualizzazione ed esportazione di registri del dispositivo con correzione della posizione via Bluetooth." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Излаз дебаговања уживо преко серијског интерфејса, прегледајте и извозите логове уређаја са редукованим позицијама преко блутута." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "透過序列埠輸出即時偵錯記錄,並可透過藍芽檢視與匯出經位置隱藏處理的裝置日誌。" + } } } }, "Output pin buzzer GPIO " : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pin di uscita cicalino GPIO " + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Излазни пин за зујалицу GPIO" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "蜂鳴器輸出腳位 GPIO" + } } } }, "Output pin GPIO" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pin di uscita GPIO" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Излазни пин GPIO" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "輸出腳位 GPIO" + } } } }, "Output pin vibra GPIO" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pin di uscita vibra GPIO" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Излазни пин за вибрацију GPIO" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "振動馬達輸出腳位 GPIO" + } + } + } + }, + "overlanding" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "overland drive" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Вожња преко копна" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "越野" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "開車 (overland drive)" + } + } + } + }, + "Overlanding" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Overlanding" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Оверлендинг" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "越野" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "越野旅行" + } } } }, "Override automatic OLED screen detection." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Annulla il rilevamento automatico dello schermo OLED." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Премаши аутоматско откривање OLED екрана." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "覆寫自動偵測 OLED 螢幕" + } } } }, @@ -22304,12 +21346,6 @@ "value" : "Pairing Modus" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Pairing Mode" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -22322,18 +21358,18 @@ "value" : "מצב הצמדה" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Modalità di accoppiamento" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Tryb parowania" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Modo Pairing" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -22360,7 +21396,7 @@ } } }, - "password" : { + "Password" : { "localizations" : { "de" : { "stringUnit" : { @@ -22368,12 +21404,6 @@ "value" : "Passwort" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Password" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -22386,18 +21416,18 @@ "value" : "סיסמא" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Password" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Hasło" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Senha" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -22424,7 +21454,7 @@ } } }, - "pause" : { + "Pause" : { "localizations" : { "de" : { "stringUnit" : { @@ -22432,12 +21462,6 @@ "value" : "Pause" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Pause" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -22450,18 +21474,18 @@ "value" : "הפסק" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pausa" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Pause" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Pausa" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -22488,102 +21512,120 @@ } } }, - "paxcounter.ble" : { + "PAX Counter" : { "localizations" : { - "en" : { + "he" : { "stringUnit" : { "state" : "translated", - "value" : "BLE" + "value" : "PAX Counter" } }, - "pt-PT" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "BLE" + "value" : "Contatore PAX" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "PAX Counter" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "BLE" + "value" : "PAX Räknare" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "БЛЕ" + "value" : "Бројач пролазника" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "PAX 计数器" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "PAX 計數器" } } } }, - "paxcounter.content.unavailable" : { + "PAX Counter Config" : { "localizations" : { - "en" : { + "he" : { "stringUnit" : { "state" : "translated", - "value" : "No PAX Counter Logs" + "value" : "PAX Counter Config" } }, - "pt-PT" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Nenhum Log do Contador PAX Disponível" + "value" : "Configurazione del contatore PAX" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Inga loggar för PAX-räknare" + "value" : "PAX Räknare Konfiguration" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Нема логова PAX бројача" + "value" : "Подешавања бројача пролазника" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "PAX 计数器配置" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "PAX 計數器設定" } } } }, - "paxcounter.delete" : { + "PAX Counter config received: %@" : { "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Delete all pax data?" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Apagar todos os dados de pax?" + "value" : "Configurazione del contatore PAX ricevuta: %@" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Radera all paxdata?" + "value" : "PAX-räknarkonfiguration mottagen: %@" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Избриши све PAX податке?" + "value" : "Конфигурација PAX бројача примљена: %@" } } } }, - "paxcounter.log" : { + "PAX Counter Log" : { "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "PAX Counter Log" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Log do Contador PAX" + "value" : "Registro del contatore PAX" } }, "se" : { @@ -22597,64 +21639,69 @@ "state" : "translated", "value" : "Логови PAX бројача" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "PAX 計數器日誌" + } } } }, - "paxcounter.total" : { + "PAX Counter message received from: %@" : { "localizations" : { - "en" : { + "de" : { "stringUnit" : { "state" : "translated", - "value" : "Total PAX" + "value" : "PAX Counter message received for: %@" } }, - "pt-PT" : { + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Total de PAX" + "value" : "PAX Counter packet received for: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Messaggio del contatore PAX ricevuto da: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "PAX Counter packet received for: %@" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Totalt PAX" + "value" : "PAX-räknarmeddelande mottaget från: %@" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Укупно PAX" + "value" : "Порука PAX бројача примљена од: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "PAX Counter message received for: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "PAX Counter message received from: %@" } } } }, - "paxcounter.wifi" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "WiFi" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "WiFi" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "WiFi" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "ВајФај" - } - } - } + "paxcounter.log" : { + }, "Perform a factory reset on the node you are connected to" : { "localizations" : { @@ -22664,21 +21711,32 @@ "value" : "Verbundenen Knoten auf Werkseinstellungen zurücksetzen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Eseguire un reset di fabbrica sul nodo a cui si è connessi" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Изврши фабричко ресетовање чвора на који сте повезани" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "對目前連線的節點執行恢復原廠設定。" + } } } }, - "Philippines 433mhz" : { - "extractionState" : "manual", + "Philippines 433MHz" : { "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Philippines 433MHz" + "value" : "Filippine 433MHz" } }, "sr" : { @@ -22686,16 +21744,21 @@ "state" : "translated", "value" : "Филипини 433MHz" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "菲律賓 433MHz" + } } } }, - "Philippines 868mhz" : { - "extractionState" : "manual", + "Philippines 868MHz" : { "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Philippines 868MHz" + "value" : "Filippine 868MHz" } }, "sr" : { @@ -22703,16 +21766,21 @@ "state" : "translated", "value" : "Филипини 868MHz" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "菲律賓 868MHz" + } } } }, - "Philippines 915mhz" : { - "extractionState" : "manual", + "Philippines 915MHz" : { "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Philippines 915MHz" + "value" : "Filippine 915MHz" } }, "sr" : { @@ -22720,10 +21788,16 @@ "state" : "translated", "value" : "Филипини 915MHz" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "菲律賓 915MHz" + } } } }, - "phone.gps" : { + "Phone GPS" : { "localizations" : { "de" : { "stringUnit" : { @@ -22731,12 +21805,6 @@ "value" : "Telefon GPS" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Phone GPS" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -22749,18 +21817,18 @@ "value" : "GPS מהטלפון" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Telefono GPS" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "GPS telefonu" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "GPS do Telefone" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -22787,98 +21855,69 @@ } } }, - "phone.gps.interval.description" : { - "extractionState" : "manual", + "Pin %lld" : { "localizations" : { - "de" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Wie häufig das Telefon den Standort an das Gerät sendet. Standortaktualisierungen an das Mesh werden vom Gerät verwaltet." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "How frequently your phone will send your location to the device, location updates to the mesh are managed by the device." - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "La fréquence à laquelle votre téléphone envoie votre position à l'appareil, les mises à jour de la position vers le maillage sont gérées par l'appareil." - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "כל כמה זמן מכשיר הטלפון ישלח את מיקומך למכשיר המשטסטיק. עדכוני מיקום למש מנוהלות על ידי המכשיר." - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Jak często Twój telefon będzie wysyłał swoją lokalizację do urządzenia, aktualizacje lokalizacji w sieci są zarządzane przez urządzenie." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Com que frequência seu telefone enviará sua localização para o dispositivo, as atualizações de localização no mesh são geridas pelo dispositivo." - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Hur ofta din telefon skickar din plats till enheten, platsuppdateringar till mesh-nätverket hanteras av enheten." + "value" : "Pin %lld" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Колико често ваш телефон шаље вашу локацију уређају, ажурирања локације на мрежу се управљају од стране уређаја." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "电台通过手机获取定位的时间间隔,但是向 Mesh 网络中发送定位的时间间隔由电台控制。" + "value" : "Пин %lld" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "電台通過手機獲得定位的時間間隔,但是向 Mesh 網路中更新定位的時間間隔由電台控制。" - } - } - } - }, - "Pin %lld" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Пин %lld" + "value" : "Pin %lld" } } } }, "Pin A" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pin A" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Пин А" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pin A" + } } } }, "Pin B" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pin B" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Пин Б" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pin B" + } } } }, @@ -22890,6 +21929,12 @@ "value" : "PKI-basierte Knotenadministration, benötigt Firmware Version 2.5+" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Amministrazione dei nodi basata su PKI, richiede la versione firmware 2.5+" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -22901,11 +21946,33 @@ "state" : "translated", "value" : "基于 PKI 的节点管理,需要 2.5 以上版本的固件" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "基於 PKI 的遠端管理,需搭配 2.5 版以上的韌體。" + } + } + } + }, + "Please be advised that because the map report is not encrypted, your data may be stored and displayed permanently by third parties. Meshtastic does not assume responsibility for any such storage, display or disclosure of this data." : { + "localizations" : { + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "請注意,由於地圖報告內容未經加密,您的資料可能會被第三方永久儲存、展示或公開揭露。Meshtastic 對於任何此類資料的儲存、展示或揭露行為,不承擔任何責任。" + } } } }, "Please connect to a radio to configure settings." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Collegarsi a una radio per configurare le impostazioni." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -22917,16 +21984,21 @@ "state" : "translated", "value" : "请连接电台以修改配置。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "請先連接裝置來進行設定。" + } } } }, "Please set a region" : { - "extractionState" : "manual", "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Please set a region" + "value" : "Impostare una regione" } }, "sr" : { @@ -22934,63 +22006,115 @@ "state" : "translated", "value" : "Молимо изаберите регион" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "請設定地區" + } } } }, "Points of Interest" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Punti di interesse" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Тачке интересовања" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "興趣點" + } } } }, - "position" : { + "Poop" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Position" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Position" + "value" : "Kacke" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Position" + "value" : "Caca" } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "חרא" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cacca" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kupa" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bajs" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Кака" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "便便" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "便便" + } + } + } + }, + "Position" : { + "localizations" : { "he" : { "stringUnit" : { "state" : "translated", "value" : "מיקום" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Posizione" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Pozycja" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Posição" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Position" - } - }, "sr" : { "stringUnit" : { "state" : "translated", @@ -23011,83 +22135,7 @@ } } }, - "Position Exchange Failed" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Неуспела размена позиција" - } - } - } - }, - "Position Exchange Requested" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Захтевана размена позиција" - } - } - } - }, - "Position Flags" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Заставице позиције" - } - } - } - }, - "Position Log" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Логови позиција" - } - } - } - }, - "Position Log %lld Points" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Дневник позиција %lld тачака" - } - } - } - }, - "Position Packet" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Пакети позиција" - } - } - } - }, - "Position Sent" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Position gesendet" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Позиција послата" - } - } - } - }, - "position.config" : { + "Position Config" : { "localizations" : { "de" : { "stringUnit" : { @@ -23095,12 +22143,6 @@ "value" : "Positionseinstellungen" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Position Config" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -23113,18 +22155,18 @@ "value" : "הגדרות מיקום" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione della posizione" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Konfiguracja pozycji" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração de Posição" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -23151,43 +22193,232 @@ } } }, - "position.precision %@" : { - "extractionState" : "migrated", + "Position Exchange Failed" : { "localizations" : { - "de" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Innerhalb %@" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Within %@" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dentro de %@" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Inom %@" + "value" : "Scambio di posizioni non riuscito" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "У кругу %@" + "value" : "Неуспела размена позиција" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "位置交換失敗" + } + } + } + }, + "Position Exchange Requested" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Scambio di posizioni richiesto" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Захтевана размена позиција" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "已請求位置交換" + } + } + } + }, + "Position Flags" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bandiere di posizione" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Заставице позиције" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "位置標記" + } + } + } + }, + "Position Log" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Diario di posizione" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Логови позиција" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "位置紀錄" + } + } + } + }, + "Position Log %lld Points" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Posizione Log %lld Punti" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Дневник позиција %lld тачака" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "位置紀錄 %lld 個紀錄" + } + } + } + }, + "Position Packet" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pacchetto posizione" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Пакети позиција" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "位置封包" + } + } + } + }, + "Position Packet received from node: %@" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Position empfangen von Knoten: %@" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Paquet de la position reçu du noeud : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הודעת מיקום התקבלו מ-%@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Posizione Pacchetto ricevuto dal nodo: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Odebrano pakiet pozycji od węzła: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Positionspaket mottaget från nod: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Пакет позиције примљен од чвора: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Position Packet received from node: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Position Packet received from node: %@" + } + } + } + }, + "Position Sent" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Position gesendet" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Posizione inviata" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Позиција послата" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "位置資料已送出" } } } }, "Positions Enabled" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Posizioni abilitate" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -23199,11 +22430,23 @@ "state" : "translated", "value" : "启用定位" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "發送位置" + } } } }, "Positions will be provided by your device GPS, if you select disabled or not present you can set a fixed position." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Le posizioni saranno fornite dal GPS del dispositivo; se si seleziona disabilitato o non presente, è possibile impostare una posizione fissa." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -23215,109 +22458,351 @@ "state" : "translated", "value" : "位置将由设备 GPS 提供,如果选择禁用或不存在,则可以设置固定位置。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "裝置的 GPS 會提供定位資訊,如果選擇「已停用」或「無此功能」,則可以手動設定固定位置。" + } + } + } + }, + "Positon config received: %@" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Positionskonfiguration empfangen: %@" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configuration de la position reçue : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הגדרות מיקום התקבלו: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione della posizione ricevuta: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Odebrano konfigurację pozycji: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Positionskonfiguration mottagen: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Конфигурација позиције примљена: %@" + } } } }, "Power" : { "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Strom" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "Power" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Potenza" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Power" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ström" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Снага" } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "电源" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "休眠" + } + } + } + }, + "Power Config" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Stromkonfiguration" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "Power Config" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione dell'alimentazione" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Power Config" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Strömkonfiguration" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Подешавања напајња" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "电源配置" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "電源設定" + } + } + } + }, + "Power config received: %@" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione dell'alimentazione ricevuta: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Strömkonfiguration mottagen: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Конфигурација напајања примљена: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Power config received: %@" + } } } }, "Power Metrics" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Metriche di potenza" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Мерни подаци о снази" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "電源指標" + } } } }, "Power Metrics Log" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Registro delle metriche di potenza" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Логови метрике снаге" } - } - } - }, - "Power Metrics Log}" : { - "localizations" : { - "sr" : { + }, + "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Логови метрике снаге}" + "value" : "電源指標紀錄" } } } }, "Power Off" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Spegnimento" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Искључи" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "關機" + } } } }, "Power Options" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Opzioni di alimentazione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Опције снаге" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "電源選項" + } + } + } + }, + "Power Saving" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Stromsparen" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "Power Saving" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Risparmio energetico" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Power Saving" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Strömsparläge" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Уштеда енергије" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "省电模式" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "省電模式" + } } } }, "Power Screen" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Schermo di alimentazione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Снага екрана" } - } - } - }, - "power.metrics.delete" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Delete all power metrics?" - } }, - "sr" : { + "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Обрисати све логове метрике снаге?" - } - } - } - }, - "power.metrics.log" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Power Metrics Log" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Логови метрике снаге" + "value" : "電源畫面" } } } @@ -23330,11 +22815,23 @@ "value" : "Angeschaltet" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Potenziato" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Напајано" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "使用電源" + } } } }, @@ -23346,81 +22843,34 @@ "value" : "Genaue Position" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Posizione precisa" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Прецизне локације" } - } - } - }, - "preferred.radio" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Bevorzugtes Gerät" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Preferred Radio" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Radio favorie" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "רדיו מועדף" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Preferowane radio" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Rádio Preferido" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Föredragen Radio" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Преферирани радио" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "默认电台" - } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "首選電台" + "value" : "精確位置" } } } }, "Presets" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Preimpostazioni" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -23432,35 +22882,107 @@ "state" : "translated", "value" : "预设" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "首選節點" + } } } }, "Press Pin" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pin a pressione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Притисни пин" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "按下圖釘" + } } } }, "Pressure" : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Притисак" + "value" : "Pressione" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "氣壓" } } } }, "Primary" : { "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Primär" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Principal" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "עיקרי" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Primario" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Podstawowy" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Primär" + } + }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Основни" + "value" : "Примарни" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "主要" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "主要" } } } @@ -23473,6 +22995,12 @@ "value" : "Erster Admin-Schlüssel" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Chiave amministrativa primaria" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -23484,16 +23012,34 @@ "state" : "translated", "value" : "一级管理员密钥" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "主要管理公鑰" + } } } }, "Primary GPIO" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "GPIO primario" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Основни GPIO" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "主要 GPIO" + } } } }, @@ -23505,6 +23051,12 @@ "value" : "Privater Schlüssel" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Chiave privata" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -23516,11 +23068,81 @@ "state" : "translated", "value" : "私钥" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "私鑰" + } + } + } + }, + "Process" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Prozess" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Process" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "Process" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Processo" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Process" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Process" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Процес" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Process" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Process" + } } } }, "Project information" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Informazioni sul progetto" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -23532,6 +23154,70 @@ "state" : "translated", "value" : "项目信息" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "專案資訊" + } + } + } + }, + "Protobufs" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Protobufs" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Protobufs" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "Protobufs" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Protobufs" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Protobufy" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Protobufs" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Протобафови" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Protobufs" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Protobufs" + } } } }, @@ -23543,6 +23229,12 @@ "value" : "Öffentlicher Schlüssel" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Chiave pubblica" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -23554,11 +23246,23 @@ "state" : "translated", "value" : "公钥" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "公鑰" + } } } }, "Public Key Encryption" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Crittografia a chiave pubblica" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -23570,11 +23274,23 @@ "state" : "translated", "value" : "公钥加密" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "公鑰加密" + } } } }, "Public Key Mismatch" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mancata corrispondenza della chiave pubblica" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -23586,41 +23302,112 @@ "state" : "translated", "value" : "公钥不匹配" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "公鑰與已知不符" + } } } }, "PWD" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Alimentato" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "PWD" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "電源" + } + } + } + }, + "Question" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fragezeichen" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Point d'interrogation" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "סימן שאלה" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Interrogativo" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Znak zapytania" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Frågetecken" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Знак питања" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "问号" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "問號" + } } } }, "Radiation" : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Радијација" + "value" : "Radiazioni" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "輻射" } } } }, - "Radio Disconnected" : { - "extractionState" : "manual", - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Радио веза је прекинута" - } - } - } - }, - "radio.configuration" : { + "Radio Configuration" : { "localizations" : { "de" : { "stringUnit" : { @@ -23628,12 +23415,6 @@ "value" : "Geräteeinstellungen" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Radio Configuration" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -23646,18 +23427,18 @@ "value" : "הגדרות רדיו" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione radio" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Konfiguracja radia" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração de Rádio" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -23679,77 +23460,92 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "電台設定" + "value" : "無線設定" } } } }, - "Random PIN" : { - "extractionState" : "manual", + "Radio Disconnected" : { "localizations" : { - "de" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Zufällige PIN" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Random PIN" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Code PIN aléatoire" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "קוד אקראי" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Losowy PIN" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "PIN Aleatório" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Slumpmässig PIN" + "value" : "Radio scollegata" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Насумичан ПИН" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "随机 PIN 码" + "value" : "Радио веза је прекинута" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "隨機 PIN 碼" + "value" : "已斷線" } } } }, - "range.test" : { + "RAK Rotary Encoder" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "RAK Drehimpulsgeber Modul" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Module d'encodage rotatif RAK" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "RAK Rotary Encoder Module" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Modulo encoder rotativo RAK" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kodera obrotowego RAK" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "RAK Rotary Encoder-modul" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "RAK Rotary енкодер модул" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "RAK 编码器" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "RAK 旋轉編碼器" + } + } + } + }, + "Range Test" : { "localizations" : { "de" : { "stringUnit" : { @@ -23757,12 +23553,6 @@ "value" : "Entfernungstest" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Range Test" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -23775,18 +23565,18 @@ "value" : "בדיקת טווח" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Test della gamma" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Test zasięgu" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Teste de Alcance" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -23813,72 +23603,7 @@ } } }, - "range.test.blocked" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Block Range Test" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Block Range Test" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Test de portée bloqué" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "חסום בדיקות טווח" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Block Range Test" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Bloquear Teste de Alcance" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Blockera räckviddstest" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Тест домета блока" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "区块范围测试" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "區塊範圍測試" - } - } - } - }, - "range.test.config" : { + "Range Test Config" : { "localizations" : { "de" : { "stringUnit" : { @@ -23886,12 +23611,6 @@ "value" : "Entfernungstest Konfiguration" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Range Test Config" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -23904,18 +23623,18 @@ "value" : "הגדרות בדיקת טווח" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione del test di portata" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Konfiguracja testu zasięgu" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração do teste de Alcance" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -23937,12 +23656,70 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "拉距測試設定" + "value" : "區塊範圍測試" } } } }, - "reboot" : { + "Range Test module config received: %@" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Range Test Modul konfiguration empfangen: %@" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configuration du module test deportée reçue : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הגדרות מודולת בדיקת טווח התקבלו: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione del modulo Range Test ricevuta: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Odebrano konfigurację modułu testu zasięgu: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Konfiguration för räckviddstestmodulen mottagen: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Конфигурација модула теста домета примљена: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "收到范围测试模块配置: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Range Test module config received: %@" + } + } + } + }, + "Reboot" : { "localizations" : { "de" : { "stringUnit" : { @@ -23950,12 +23727,6 @@ "value" : "Neustart" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Reboot" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -23968,18 +23739,18 @@ "value" : "התחל מחדש" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Riavvio" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Uruchom ponownie" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Reiniciar" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -24006,7 +23777,7 @@ } } }, - "Reboot Node?" : { + "Reboot node?" : { "localizations" : { "de" : { "stringUnit" : { @@ -24014,28 +23785,6 @@ "value" : "Knoten neustarten?" } }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Поново покрени чвор?" - } - } - } - }, - "reboot.node" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Knoten neustarten?" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Reboot node?" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -24048,18 +23797,18 @@ "value" : "התחל מכשיר מחדש??" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Riavviare il nodo?" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Uruchomić ponownie węzeł?" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Reiniciar nó?" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -24081,13 +23830,29 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "重啟中繼點" + "value" : "重啟節點" + } + } + } + }, + "Rebroadcast any observed message, if it was on our private channel or from another mesh with the same lora params." : { + "localizations" : { + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "只要是在私人頻道上,或是來自使用相同 LoRa 參數的其他 Mesh 的訊息,都會進行重新廣播。" } } } }, "Rebroadcast Mode" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Modalità di ritrasmissione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -24099,20 +23864,96 @@ "state" : "translated", "value" : "转播模式" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "中繼轉發模式" + } } } }, "Receive data (rxd) GPIO pin" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dati di ricezione (rxd) Pin GPIO" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Пријемни податак (rxd) GPIO пин" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "接收資料(RXD)GPIO 腳位" + } } } }, - "received.ack" : { + "Received a negative acknowledgment" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Negative Empfangsbestätigung empfangen" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Accusé de réception négatif reçu" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "התקבל אישור מסירה שלילי" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ricevuto un riscontro negativo" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Otrzymano negatywne potwierdzenie" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mottog ett negativt kvitto" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Примљено негативно признање" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "收到否认" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "收到 NACK(否定確認)" + } + } + } + }, + "Received Ack" : { "localizations" : { "de" : { "stringUnit" : { @@ -24120,12 +23961,6 @@ "value" : "Empfangsbestätigung" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Received Ack" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -24138,18 +23973,18 @@ "value" : "התקבל אישור מסירה" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ricevuto Ack" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Odebrano potwierdzenie" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ack Recebido" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -24171,12 +24006,12 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "收到確認" + "value" : "已接收確認" } } } }, - "received.ack.real" : { + "Recipient Ack" : { "localizations" : { "de" : { "stringUnit" : { @@ -24184,12 +24019,6 @@ "value" : "Recipient Ack" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Recipient Ack" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -24202,18 +24031,18 @@ "value" : "התקבל אישור מסירה מהנמען" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Destinatario Ack" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Odbiorca potwierdzenia" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ack do Destinário" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -24248,21 +24077,45 @@ "value" : "Route aufzeichnen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Percorso di registrazione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Снимање руте" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "記錄路線" + } } } }, "Refresh device metadata" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aggiornare i metadati del dispositivo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Освежи метаподатке уређаја" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "重新整理裝置中繼資料(Metadata)" + } } } }, @@ -24274,6 +24127,12 @@ "value" : "Region" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Regione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -24285,191 +24144,158 @@ "state" : "translated", "value" : "区域" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "區域" + } } } }, - "relativetimeofday.afternoon" : { - "extractionState" : "migrated", + "Regional Duty Cycle Limit Reached" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Nachmittag" + "value" : "Regionale Einschaltdauergrenze erreicht" } }, - "en" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Afternoon" + "value" : "Limite du cycle de service régional atteinte" } }, - "pt-PT" : { + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Tarde" + "value" : "הגיע למקסימום שימוש אזורי לשעה זו" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Raggiunto il limite del ciclo di lavoro regionale" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Osiągnięto regionalny limit cyklu pracy" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Regionala sändningsgränsen nådd" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Пре подне" - } - } - } - }, - "relativetimeofday.evening" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Abend" + "value" : "Достигнут регионални лимит радног циклуса" } }, - "en" : { + "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Evening" + "value" : "已达到当前区域循环周期发射上限" } }, - "pt-PT" : { + "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Noite" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Вече" - } - } - } - }, - "relativetimeofday.midday" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mittag" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Midday" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Meio-dia" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Подне" - } - } - } - }, - "relativetimeofday.morning" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Morgen" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Morning" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Manhã" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Јутро" - } - } - } - }, - "relativetimeofday.nighttime" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nacht" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nighttime" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Noite" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ноћ" + "value" : "已達到頻道占用循環週期發射上限" } } } }, "Release Notes" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Note di rilascio" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Белешке о издању" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "版本更新說明" + } } } }, "Remote administration for: %@" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Amministrazione remota per: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Даљинска администрација за: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "正在為 %@ 執行遠端設定" + } } } }, "Remote Legacy Admin: %@" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Amministratore legacy remoto: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Администрација застарелих система на даљину: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "遠端管理(舊版):%@" + } } } }, "Remote PKI Admin: %@" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Amministratore PKI remoto: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Администрација PKI на даљину: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "遠端 PKI 公鑰管理:%@" + } } } }, @@ -24481,11 +24307,23 @@ "value" : "Entfernen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rimuovere" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Уклони" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "移除" + } } } }, @@ -24497,16 +24335,34 @@ "value" : "Von Favoriten entfernen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rimuovi dai preferiti" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Уклони из омиљених" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "從最愛中移除" + } } } }, "Remove from ignored" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rimuovere da ignorato" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -24518,16 +24374,68 @@ "state" : "translated", "value" : "从忽略中删除" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "從忽略中移除" + } + } + } + }, + "Repeater" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Repeater" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ripetitore" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Поновљач" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "中继" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Repeater" + } } } }, "Replace Channels" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sostituire i canali" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Замени канале" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "更換頻道" + } } } }, @@ -24539,12 +24447,6 @@ "value" : "Antworten" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Reply" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -24557,18 +24459,18 @@ "value" : "תגובה" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Risposta" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Odpowiedz" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Responder" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -24590,38 +24492,129 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "回復" + "value" : "回覆" } } } + }, + "Replying to a message" : { + }, "Request Legacy Admin: %@" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Richiesta amministratore legacy: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Захтевај администрацију застарелих система: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "請求舊版管理:%@" + } } } }, "Request PKI Admin: %@" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Richiesta PKI Admin: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Захтевај PKI администрацију: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "請求 PKI 管理:%@" + } + } + } + }, + "Requested Canned Messages Module Messages for node: %@" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Messages du module messages préformatés demandés pour le noeud : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "התבקשו הודעות מודולת הודעות שמורות עבור מכשיר: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Messaggi in scatola richiesti Messaggi del modulo per il nodo: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zażądano Wiadomości z Modułu Wiadomości Gotowych dla węzła: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Begärda meddelanden för modulen med fördefinierade meddelanden för nod: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Захтеване поруке модула за унапред припремљене поруке за чвор: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Requested Canned Messages Module Messages for node: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Requested Canned Messages Module Messages for node: %@" + } } } }, "Requires that there be an accelerometer on your device." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Richiede la presenza di un accelerometro sul dispositivo." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Захтева да уређај има акцелерометар." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "需要您的裝置內建加速度感測器。" + } } } }, @@ -24633,6 +24626,12 @@ "value" : "App-Einstellungen zurücksetzen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ripristino delle impostazioni dell'app" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -24644,6 +24643,12 @@ "state" : "translated", "value" : "重置 App 设置" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "重置 App 設定" + } } } }, @@ -24655,11 +24660,23 @@ "value" : "Knotendatenbank zurücksetzen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Azzeramento di NodeDB" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Ресетовање базе чворова (NodeDB)" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "重置 NodeDB" + } } } }, @@ -24671,11 +24688,23 @@ "value" : "Neustarten" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Riavvio" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Поновно покретање" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "重啟" + } } } }, @@ -24687,15 +24716,27 @@ "value" : "Verbundenen Knoten neustarten" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Riavviare al nodo a cui si è collegati" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Поновно покретање на чвор на који сте повезани" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "重新啟動您所連線的節點" + } } } }, - "resume" : { + "Resume" : { "localizations" : { "de" : { "stringUnit" : { @@ -24703,12 +24744,6 @@ "value" : "Fortsetzen" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Resume" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -24721,18 +24756,18 @@ "value" : "החל מחדש" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il curriculum" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Resume" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Continuar" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -24767,6 +24802,12 @@ "value" : "App bewerten" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Esaminare l'applicazione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -24778,10 +24819,74 @@ "state" : "translated", "value" : "审查应用程序" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "為應用程式留下評價" + } } } }, - "ringtone" : { + "Right" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rechts" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Droite" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "ימינה" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Diritto" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "W Prawo" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Höger" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Десно" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "右" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "右" + } + } + } + }, + "Ringtone" : { "localizations" : { "de" : { "stringUnit" : { @@ -24789,12 +24894,6 @@ "value" : "Klingelton" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ringtone" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -24807,18 +24906,18 @@ "value" : "רינגטון" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Suoneria" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Dzwonek" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Toque" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -24845,8 +24944,7 @@ } } }, - "ringtone.config" : { - "extractionState" : "manual", + "Ringtone Config" : { "localizations" : { "de" : { "stringUnit" : { @@ -24854,58 +24952,126 @@ "value" : "Klingelton Konfiguration" } }, - "en" : { + "he" : { "stringUnit" : { "state" : "translated", "value" : "Ringtone Config" } }, - "fr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Configuration de la sonnerie" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרות רינגטון" + "value" : "Configurazione della suoneria" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Konfiguracja dzwonka" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração de Toque" + "value" : "Ringtone Config" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Ringsignalsinställningar" + "value" : "Ringsignalskonfiguration" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Подешавање мелодије звона" + "value" : "Конфигурација звона" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "铃声设置" + "value" : "铃声配置" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "鈴聲設定" + "value" : "鈴聲" + } + } + } + }, + "Ringtone Transfer Language" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Lingua di trasferimento della suoneria" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Språk för Överföring av Ringsignal" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Језик преноса мелодије звона" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "铃声传输语言" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "鈴聲傳輸語言(RTTTL)" + } + } + } + }, + "Ringtone Transfer Language(RTTTL) Ringtone String used by supported buzzers in external notifications." : { + "localizations" : { + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ringtone Transfer Language(RTTTL) Ringtone String used by supported buzzers in external notifications." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ringtone Transfer Language(RTTTL) Stringa di suoneria utilizzata dai cicalini supportati nelle notifiche esterne." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ringtone Transfer Language(RTTTL) Ringtone String used by supported buzzers in external notifications." + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ringsignalöverföringsspråk (RTTTL) Ringsignalsträng som används av stödda buzzers i externa notifikationer." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Језик преноса мелдоије звона (RTTTL) Стринг мелодије звона који користе подржани звучни сигнали у спољним обавештењима." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "支持外部通知中使用的铃声传输语言 (RTTTL) 铃声字符串。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "RTTTL 鈴聲字串(Ringtone Transfer Language)被用於外部通知中支援的蜂鳴器。" } } } @@ -24918,11 +25084,23 @@ "value" : "Rolle" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ruolo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Улога" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Role" + } } } }, @@ -24934,11 +25112,23 @@ "value" : "Rolle: %@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ruolo: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Улога: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Role: %@" + } } } }, @@ -24950,26 +25140,56 @@ "value" : "Rollen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ruoli" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Улоге" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Roles" + } } } }, "Root Topic" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Argomento radice" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Корен тема" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "根主題" + } } } }, "Rotary 1" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rotary 1" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -24981,46 +25201,100 @@ "state" : "translated", "value" : "旋转一次" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "編碼器 1" + } } } }, "Route Back: %@" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Percorso di ritorno: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Путања назад: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "路徑(返): %@" + } } } }, "Route Lines" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Linee di percorso" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Линије руте" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "路徑線" + } } } }, "Route Recorder" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Registratore di percorso" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Снимач руте" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "路徑紀錄" + } } } }, "Route recording paused" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Registrazione del percorso in pausa" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Снимање руте паузирано" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "路徑紀錄已暫停" + } } } }, @@ -25032,1323 +25306,341 @@ "value" : "Route: %@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Percorso: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Рута: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "路徑(往): %@ " + } + } + } + }, + "Router" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Router" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Router" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Рутер" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "路由" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Router" + } + } + } + }, + "Router Late" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Router mit Verzögerung" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Router tardivo" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Рутер са кашњењем" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Router Late" + } } } }, "Routes" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Percorsi" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Руте" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "路徑" + } } } }, - "routes.activitytype.biking" : { - "extractionState" : "migrated", + "Routing received for RequestID: %@ Ack Status: %@" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Biken" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Biking" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Passeio de Bicicleta" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Вожња бицикле" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "自行车" - } - } - } - }, - "routes.activitytype.driving" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fahren" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Driving" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Conduzir" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Вожња аута" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "驾驶" - } - } - } - }, - "routes.activitytype.filename.biking" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "biken" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "bike tour" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Passeio de Bicicleta" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "тура бициклом" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "自行车旅行" - } - } - } - }, - "routes.activitytype.filename.driving" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "fahren" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "drive" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Conduzir" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "вожња" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "驾驶" - } - } - } - }, - "routes.activitytype.filename.hiking" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "wandern" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "hike" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Caminhar na Montanha" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "планинарње" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "徒步" - } - } - } - }, - "routes.activitytype.filename.overlanding" : { - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "overland drive" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Caminhar overland" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Вожња преко копна" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "越野" - } - } - } - }, - "routes.activitytype.filename.skiing" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "skitour" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "ski tour" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Passeio de esqui" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "ски тура" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "滑雪之旅" - } - } - } - }, - "routes.activitytype.filename.walking" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "gehen" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "walk" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Caminhar" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "шетња" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "步行" - } - } - } - }, - "routes.activitytype.hiking" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wandern" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Hiking" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Caminhada na Montanha" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Планинарење" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "徒步" - } - } - } - }, - "routes.activitytype.overlanding" : { - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Overlanding" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Overlanding" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Оверлендинг" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "越野" - } - } - } - }, - "routes.activitytype.skiing" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Skifahren" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Skiing" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Esqui" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Скијање" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "滑雪" - } - } - } - }, - "routes.activitytype.walking" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gehen" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Walking" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Caminhada" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Шетња" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "步行" - } - } - } - }, - "routing.acknowledged" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Bestätigt" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Acknowledged" + "value" : "Routing empfangen für RequestID: %@ Ack Status: %@" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Confirmé" + "value" : "Routage reçu pour la demande numéro : %@ Status de l'accusé de réception : %@" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "מאשר" + "value" : "התקבל מסלול עבור בקשה: %@ מצב שליחה: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Routing ricevuto per RequestID: %@ Ack Status: %@" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Potwierdzono" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Reconhecido" + "value" : "Odebrano trasowanie dla RequestID: %@ Ack Status: %@" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Bekräftad" + "value" : "Routing mottagen för RequestID: %@ Ack Status: %@" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Потврђено" + "value" : "Рутирање примљено за ИД захтева: %@ Статус потврде: %@" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "确认" + "value" : "Routing received for RequestID: %@ Ack Status: %@" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "確認" - } - } - } - }, - "routing.badRequest" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Bad Request" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Bad Request" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Requête incorrecte" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "בקשה לא תקינה" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Złe żądanie" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Pedido Ruim" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Felaktig begäran" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Лош захтев" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "错误请求" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "錯誤請求" - } - } - } - }, - "routing.dutycyclelimit" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Regionale Einschaltdauergrenze erreicht" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Regional Duty Cycle Limit Reached" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Limite du cycle de service régional atteinte" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגיע למקסימום שימוש אזורי לשעה זו" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Osiągnięto regionalny limit cyklu pracy" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "O limite do Regional Duty Cycle foi abrangido" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Regionala sändningsgränsen nådd" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Достигнут регионални лимит радног циклуса" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "已达到当前区域循环周期发射上限" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "已達到頻道占用循環週期發射上限" - } - } - } - }, - "routing.gotnak" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Negative Empfangsbestätigung empfangen" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Received a negative acknowledgment" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Accusé de réception négatif reçu" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "התקבל אישור מסירה שלילי" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Otrzymano negatywne potwierdzenie" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Recebido um reconhecimento negativo" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mottog ett negativt kvitto" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Примљено негативно признање" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到否认" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "收到否認" - } - } - } - }, - "routing.maxretransmit" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Maximale Wiederholungen erreicht" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Max Retransmission Reached" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nombre maximum de retransmissions atteint" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגיע למקסימום השליחות מדש" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Osiągnięto limit retransmisji" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Máximo de Retransmissão Alcançado" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Max antal omsändningar nått" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Достигнут максималан број поновних слања" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "已达到最大重试次数" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "已達到最大重試次數" - } - } - } - }, - "routing.nochannel" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Kein Kanal" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "No Channel" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Pas de canal" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "אין ערוץ" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Brak kanału" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sem Canal" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ingen kanal" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Нема канала" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "没有频道" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "没有頻道" - } - } - } - }, - "routing.nointerface" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Keine Schnittstelle" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "No Interface" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Pas d'interface" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "אין ממשק" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Brak interfejsu" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sem Interface" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Inget gränssnitt" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Нема интерфејса" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "无连接" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "無連接" - } - } - } - }, - "routing.noresponse" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Keine Antwort" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "No Response" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Pas de réponse" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "אין תגובה" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Brak odpowiedzi" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sem Resposta" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Inget svar" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Нема одговора" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "无响应" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "無回應" - } - } - } - }, - "routing.noroute" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Keine Route" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "No Route" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Pas de route" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "אין מסלול" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Brak trasy" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sem Rota" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ingen rutt" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Нема руте" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "找不到目标" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "找不到目標" - } - } - } - }, - "routing.notauthorized" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nicht authorisiert" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Not Authorized" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Non autorisé" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "לא מאושר" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nieautoryzowany" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Não Autorizado" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Inte auktoriserad" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Није ауторизовано" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "未授权" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "未授權" - } - } - } - }, - "routing.pkifailed" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Verschlüsseltes Senden fehlgeschlagen" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Encrypted Send Failed" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Шифровано слање није успело" - } - } - } - }, - "routing.pkiunknownpubkey" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Unbekannter öffentlicher Schlüssel" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Unknown Public Key" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Непознат јавни кључ" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "未知的公钥" - } - } - } - }, - "routing.timeout" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Zeitlimit erreicht" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Timeout" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Délai d'expiration" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "נגמר הזמן" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Limit czasu" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tempo Esgotado" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tidsgräns överskriden" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Време истекло" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "超时" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "逾時" - } - } - } - }, - "routing.toolarge" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Das Paket ist zu groß" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "The packet is too large" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Le paquet est trop grand" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "ההודעה ארוכה/גדולה מידי" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Pakiet jest zbyt duży" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "O pacote é grande de mais" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Paketet är för stort" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Пакет је превелики" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "数据包过大" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "數據包過大" + "value" : "Routing received for RequestID: %@ Ack Status: %@" } } } }, "RSSI %@ dBm" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "RSSI %@ dBm" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "RSSI %@ dBm" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "RSSI %@ dBm" + } } } }, "RSSI %ddB" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "RSSI %ddB" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "RSSI %ddB" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "RSSI %ddB" + } } } }, "RSSI %llddB" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "RSSI %llddB" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "RSSI %llddB" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "RSSI %llddB" + } } } }, - "Russia" : { - "extractionState" : "manual", + "RTTTL Ringtone config received: %@" : { "localizations" : { - "en" : { + "de" : { "stringUnit" : { "state" : "translated", - "value" : "Russia" + "value" : "RTTTL Klingeltonkonfiguration empfangen: %@" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configuration de la sonnerie RTTTL reçue : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הגדרות RTTTL רינגטון התקבלו: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "RTTTL Configurazione suoneria ricevuta: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Odebrano konfigurację dzwonka RTTTL: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Konfiguration för RTTTL-ringsignal mottagen: %@" } }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Конфигурација RTTTL мелодије примљена: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "RTTTL Ringtone config received: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "RTTTL Ringtone config received: %@" + } + } + } + }, + "Russia" : { + "localizations" : { "sr" : { "stringUnit" : { "state" : "translated", "value" : "Русија" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "俄羅斯" + } } } }, "RX Boosted Gain" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Guadagno potenziato RX" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Појачање пријемника" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "訊號接收增益(RX Boosted Gain)" + } } } }, - "satellite" : { - "extractionState" : "migrated", + "Same as behavior as ALL but skips packet decoding and simply rebroadcasts them. Only available in Repeater role. Setting this on any other roles will result in ALL behavior." : { + "localizations" : { + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "行為與 ALL 相同,但會略過封包解碼,直接重新廣播。僅在 Repeater 角色中可用;若設定於其他角色,則會自動採用 ALL 的行為。" + } + } + } + }, + "Satellite" : { "localizations" : { "de" : { "stringUnit" : { @@ -26356,18 +25648,6 @@ "value" : "Satellit" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Satellite" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Satellite" - } - }, "he" : { "stringUnit" : { "state" : "translated", @@ -26380,12 +25660,6 @@ "value" : "Satelita" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Satéllite" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -26412,21 +25686,8 @@ } } }, - "satellite.flyover" : { - "extractionState" : "migrated", + "Satellite Flyover" : { "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Satellite Flyover" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Satellite Flyover" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -26439,18 +25700,18 @@ "value" : "לווין בשמיים" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sorvolo satellitare" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Przelot satelity" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Passagem de Satélite" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -26485,11 +25746,23 @@ "value" : "Satelliten" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sats" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Сателита" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "衛星" + } } } }, @@ -26501,11 +25774,23 @@ "value" : "Satelliten Schätzung %lld" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Stima Sats %lld" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Процена броја сателита %lld" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "衛星估計數:%lld 顆" + } } } }, @@ -26517,15 +25802,27 @@ "value" : "Satelliten in Sicht: %@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Saturazione in vista: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Сателити на видику: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "目前可見衛星:%@ 顆" + } } } }, - "save" : { + "Save" : { "localizations" : { "de" : { "stringUnit" : { @@ -26533,12 +25830,6 @@ "value" : "Speichern" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Save" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -26551,18 +25842,18 @@ "value" : "שמור" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Risparmiare" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Zapisz" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Salvar" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -26589,56 +25880,29 @@ } } }, - "Save" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Speichern" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Сачувај" - } - } - } - }, "Save Channel Settings" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Salvare le impostazioni del canale" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Сачувај подешавања канала" } - } - } - }, - "Save User Config to %@?" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Benutzerkonfiguration nach %@ speichern?" - } }, - "sr" : { + "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Сачувати корисничу конфигурацију за %@?" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "保存用户配置到 %@?" + "value" : "儲存頻道設定" } } } }, - "save.config %@" : { - "extractionState" : "migrated", + "Save Config for %@" : { "localizations" : { "de" : { "stringUnit" : { @@ -26646,12 +25910,6 @@ "value" : "Speichere Konfiguration für %@" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Save Config for %@" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -26664,18 +25922,18 @@ "value" : "שמור הגדרות עבור %@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Salva la configurazione per %@" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Zapisz konfigurację dla %@" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Salvar a Configuração para %@" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -26702,8 +25960,48 @@ } } }, + "Save User Config to %@?" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Benutzerkonfiguration nach %@ speichern?" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Salvare la configurazione utente in %@?" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Сачувати корисничу конфигурацију за %@?" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "保存用户配置到 %@?" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "將使用者設定儲存到 %@?" + } + } + } + }, "Saves a CSV with the range test message details, currently only available on ESP32 devices with a web server." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Salva un CSV con i dettagli del messaggio di test di portata, attualmente disponibile solo sui dispositivi ESP32 con un server web." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -26715,16 +26013,34 @@ "state" : "translated", "value" : "保存包含量程测试报文详细信息的 CSV 文件,目前仅适用于配有网络服务器的 ESP32 设备。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "將距離測試訊息詳情儲存為 CSV 檔,目前僅限於搭載網頁伺服器的 ESP32 裝置使用。" + } } } }, "Screen on for" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Schermo acceso per" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Екран укључен за" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "螢幕開啟時間為" + } } } }, @@ -26736,31 +26052,103 @@ "value" : "Suchen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ricerca" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Претражи" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "搜尋" + } } } }, "Second" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Secondo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Други" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "秒" + } } } }, "Secondary" : { "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sekundär" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Secondaire" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "משני" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Secondario" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wtórny" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sekundär" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Секундарни" } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "次要" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "次要" + } } } }, @@ -26772,6 +26160,12 @@ "value" : "Zweiter Admin-Schlüssel" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Chiave amministrativa secondaria" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -26783,6 +26177,12 @@ "state" : "translated", "value" : "二级管理员密钥" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "次要管理公鑰" + } } } }, @@ -26794,6 +26194,12 @@ "value" : "Sicherheit" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sicurezza" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -26805,6 +26211,12 @@ "state" : "translated", "value" : "安全" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "安全性" + } } } }, @@ -26816,6 +26228,12 @@ "value" : "Sicherheitskonfiguration" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione della sicurezza" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -26827,6 +26245,12 @@ "state" : "translated", "value" : "安全配置" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "安全性設定" + } } } }, @@ -26838,6 +26262,12 @@ "value" : "Sicherheitskonfigurationseinstellungen erfordern eine Firmware mit Version 2.5 oder höher" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Le impostazioni di configurazione della sicurezza richiedono una versione del firmware 2.5+" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -26849,6 +26279,70 @@ "state" : "translated", "value" : "安全配置需要固件版本 2.5+" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "安全性設定需要韌體版本 2.5 以上" + } + } + } + }, + "Select" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Auswählen" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sélectionner" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "בחר" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Selezionare" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wybierz" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Välj" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Изабери" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "选择" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "選擇" + } } } }, @@ -26860,120 +26354,118 @@ "value" : "Kanal wählen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Selezionare un canale" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Одабери канал" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "選擇一個頻道" + } } } }, "Select a conversation" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Selezionare una conversazione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Изабери разговор" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "選擇一個對話" + } } } }, "Select a conversation type" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Selezionare un tipo di conversazione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Изабери тип разговора" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "選擇對話類型" + } } } + }, + "Select a node from the drop down to manage connected or remote devices." : { + }, "Select a Trace Route" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Selezionare un percorso di tracciamento" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Изабери пут праћења кроз мрежу" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "選擇一個追蹤路由(Trace Route)紀錄" + } } } }, "Select Channel" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Selezionare il canale" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Одабери канал" } - } - } - }, - "select.contact" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Kontakt wählen" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Select a Contact" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sélectioner un contact" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "בחר איש קשר" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wybierz kontakt" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Seleciona a Contacto" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Välj en kontakt" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Одабери контакт" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "选择一名联系人" - } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "選擇聯絡人" + "value" : "選擇頻道" } } } }, - "select.node" : { + "Select Node" : { "localizations" : { "de" : { "stringUnit" : { @@ -26981,12 +26473,6 @@ "value" : "Knoten auswählen" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Select a Node" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -26999,18 +26485,18 @@ "value" : "בחר מכשיר" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Selezionare un nodo" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Wybierz węzeł" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Seleciona a Nó" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -27032,7 +26518,7 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "選擇中繼點" + "value" : "選擇節點" } } } @@ -27045,11 +26531,23 @@ "value" : "Senden" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inviare" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Пошаљи" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "發送" + } } } }, @@ -27061,31 +26559,67 @@ "value" : "Sende ${messageContent} an ${channelNumber}" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Invia ${messaggioContenuto} a ${canaleNumero}" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Пошаљи ${messageContent} на ${channelNumber}" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Send ${messageContent} to ${channelNumber}" + } } } }, "Send ${messageContent} to ${nodeNumber}" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Invia ${messaggioContenuto} a ${nodoNumero}" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Пошаљи ${messageContent} на ${nodeNumber}" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Send ${messageContent} to ${nodeNumber}" + } } } }, "Send a Direct Message" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inviare un messaggio diretto" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Пошаљи директну поруку" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "發送私訊" + } } } }, @@ -27097,46 +26631,94 @@ "value" : "Gruppennachricht senden" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inviare un messaggio di gruppo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Пошаљи групну поруку" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "發送群組訊息" + } } } }, "Send a heartbeat to advertise the server's presence." : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Пошаљите откуцај срца да бисте рекламирали присуство сервера." + "value" : "Invia un heartbeat per pubblicizzare la presenza del server." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "發送心跳訊號來宣告伺服器的存在。" } } } }, "Send a message to a certain meshtastic channel" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inviare un messaggio a un certo canale meshtastic" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Пошаљи поруку на одређени месхтастичан канал" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "向特定 Meshtastic 頻道發送訊息" + } } } }, "Send a message to a certain meshtastic node" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inviare un messaggio a un certo nodo meshtastico" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Пошаљи поруку одређеном мештастик чвору" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "向特定 Meshtastic 節點發送訊息" + } } } }, "Send a position on the primary channel when the user button is triple clicked." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Invia una posizione sul canale primario quando si fa triplo clic sul pulsante utente." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -27148,6 +26730,12 @@ "state" : "translated", "value" : "当用户按钮被点击三次时,在主通道上发送定位。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "當使用者按鈕被連續按下三次時,透過主要頻道傳送位置資料。" + } } } }, @@ -27159,11 +26747,23 @@ "value" : "Herunterfahren an verbundenen Knoten senden" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inviare uno spegnimento al nodo a cui si è connessi" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Пошаљи искључење чвору на који си повезан" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "向您所連線的節點發送關機指令" + } } } }, @@ -27175,16 +26775,34 @@ "value" : "Wegpunkt senden" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inviare un waypoint" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Пошаљи тачку путање" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "發送一個路徑點" + } } } }, "Send ASCII bell with alert message. Useful for triggering external notification on bell." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Invia una campana ASCII con un messaggio di avviso. Utile per attivare una notifica esterna sul campanello." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -27196,6 +26814,12 @@ "state" : "translated", "value" : "发送带有警报信息的 ASCII 铃声。用于触发外部铃声通知。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "發送帶有警示訊息的 ASCII 鈴鐺圖示。此功能可用於觸發外部鈴聲通知。" + } } } }, @@ -27207,6 +26831,12 @@ "value" : "Sende Glocke" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Invia la campana" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -27218,11 +26848,81 @@ "state" : "translated", "value" : "发送铃声" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "傳送鈴鐺圖示" + } + } + } + }, + "Send Heartbeat" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Herzschlag senden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Envoyer une impulsion" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שלח דופק" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inviare il battito cardiaco" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Send Heartbeat" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Skicka hjärtslag" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Пошаљи откуцај срца" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "发送心跳包" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "發送心跳訊號(Heartbeat)" + } } } }, "Send Reboot OTA" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inviare il riavvio OTA" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -27234,11 +26934,23 @@ "state" : "translated", "value" : "发送重启 OTA" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "發送重啟 OTA 指令" + } } } }, "Sender Interval" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Intervallo del mittente" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -27250,42 +26962,433 @@ "state" : "translated", "value" : "发送间隔" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "傳送頻率" + } } } }, - "Sensor Metrics" : { + "Sensor" : { "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sensor" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sensore" + } + }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Метрике сензора" + "value" : "Сензор" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "传感器指标" + "value" : "传感器" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sensor" } } } }, "Sensor options" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Opzioni del sensore" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Опције сензора" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "傳感器選項" + } } } }, "Sensor Options" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Opzioni del sensore" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Опције сензора" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "傳感器選項" + } + } + } + }, + "Sent a Channel for: %@ Channel Index %d" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Canal envoyé pour : %@ Canal index %d" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "נשלח ערוץ עבור: %@ אינדקס ערוצים %d" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inviato un canale per: %@ Canale Indice %d" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wysłano kanał dla: %@ Indeks kanału %d" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Skickade en kanal för: %@ Kanalindex %d" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Послат је канал за: %@ Индекс канала %d" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sent a Channel for: %@ Channel Index %d" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sent a Channel for: %@ Channel Index %d" + } + } + } + }, + "Sent a LoRa.Config for: %@" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "LoRa.Config gesendet für: %@" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configuration LoRa envoyée à : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "נשלחו הגדרות לורה עבור: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inviato un LoRa.Config per: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wysłano konfigurację LoRa dla: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Skickade en LoRa.Konfiguration för: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Послата LoRA конфигурација за: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sent a LoRa.Config for: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sent a LoRa.Config for: %@" + } + } + } + }, + "Sent a Position Packet from the Apple device GPS to node: %@@" : { + "extractionState" : "manual", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Position von Apple Gerät an Knoten gesendet: %@" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Paquet envoyé avec la position GPS de l'appareil Apple vers le noeud : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "נשלח מיקום ממכשיר האפל למכשיר המשטסטיק: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inviato un pacchetto di posizione dal GPS del dispositivo Apple al nodo: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wysłano pakiet pozycji z GPS urządzenia Apple do węzła: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Skickade ett positionspaket från Apple-enhetens GPS till nod: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Позициони пакет послат са Епл уређаја на чвор: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sent a Position Packet from the Apple device GPS to node: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sent a Position Packet from the Apple device GPS to node: %@" + } + } + } + }, + "Sent a Trace Route Request to node: %@" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sende Traceroute Anforderung zu Knoten: %@" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Envoi d'une demande de Trace Route au noeud : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "נשלחה בקשת בדיקת מסלול למכשיר: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ha inviato una richiesta di tracciamento della rotta al nodo: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wysłano żądanie śledzenia trasy do węzła: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Skickade en spårruttförfrågan till nod: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Захтев за тражење путања послат на чвор: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sent a Trace Route Request to node: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sent a Trace Route Request to node: %@" + } + } + } + }, + "Sent a Waypoint Packet from: %@" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wegpunkt gesendet von: %@" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Paquet Waypoint envoyé depuis : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "נשלחה נקודת ציון מ-%@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inviato un pacchetto Waypoint da: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wysłano pakiet punktu orientacyjnego z: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Skickade en vägpunktspaket från: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Пакет са тачкама пута послат од: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sent a Waypoint Packet from: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sent a Waypoint Packet from: %@" + } + } + } + }, + "Sent message %@ from %@ to %@" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sende Nachricht %@ von %@ an %@" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Envoi du message %@ de %@ à %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "נשלחה הודעה %@ מ-%@ ל-%@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inviato messaggio %@ da %@ a %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wysłano wiadomość %@ od %@ do %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Skickade meddelande %@ från %@ till %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Порука послата %@ са %@ на %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sent message %@ from %@ to %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sent message %@ from %@ to %@" + } } } }, @@ -27297,11 +27400,23 @@ "value" : "Wird an andere Knoten im Netz gesendet, damit diese einen gemeinsamen geheimen Schlüssel berechnen können." } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inviato agli altri nodi della rete per consentire loro di calcolare una chiave segreta condivisa." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Послато другим чворовима на меш мрежи како би им омогућило да израчунају заједнички тајни кључ." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "傳送到網路上的其他節點,以便共同計算一組共享私鑰。" + } } } }, @@ -27313,11 +27428,23 @@ "value" : "Sequenznummer" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Numero di sequenza" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Број секвенце" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "序列編號" + } } } }, @@ -27329,28 +27456,28 @@ "value" : "Sequenz: %@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sequenza: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Секвенца: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "序列: %@" + } } } }, - "serial" : { + "Serial" : { "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Serial" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Serial" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -27363,18 +27490,18 @@ "value" : "סיריאלי" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Seriale" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Seryjny" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Serial" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -27396,44 +27523,12 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "串口" + "value" : "序列" } } } }, - "Serial Console" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Serielle Konsole" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Серијска конзола" - } - } - } - }, - "Serial Console over the Stream API." : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Serielle Konsole über die Stream-API." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Серијска конзола преко Stream API-ја." - } - } - } - }, - "serial.config" : { + "Serial Config" : { "localizations" : { "de" : { "stringUnit" : { @@ -27441,12 +27536,6 @@ "value" : "Serial Konfiguration" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Serial Config" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -27459,18 +27548,18 @@ "value" : "'הגדרות מודולה 'סיריאלי" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione seriale" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Konfiguracja seryjna" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração Serial" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -27492,343 +27581,144 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "串口設定" + "value" : "序列設定" } } } }, - "serial.mode.default" : { - "extractionState" : "migrated", + "Serial Console" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Standard" + "value" : "Serielle Konsole" } }, - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Default" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Défaut" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "ברירת מחדל" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Domyślny" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Padrão" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Standard" + "value" : "Console seriale" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Основни" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "默认" + "value" : "Серијска конзола" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "預設" + "value" : "序列主控台" } } } }, - "serial.mode.nmea" : { - "extractionState" : "migrated", + "Serial Console over the Stream API." : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "NMEA Positionen" + "value" : "Serielle Konsole über die Stream-API." } }, - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "NMEA Positions" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Positions NMEA" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "מיקומי NMEA" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Pozycje NMEA" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Posições NMEA" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "NMEA-positioner" + "value" : "Console seriale tramite l'API Stream." } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "NMEA позиције" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "NMEA 位置" + "value" : "Серијска конзола преко Stream API-ја." } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "NMEA 位置" + "value" : "透過串流 API 的序列主控台。" } } } }, - "serial.mode.proto" : { - "extractionState" : "migrated", + "Serial module config received: %@" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Protobufs" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Protobufs" + "value" : "Serial Modul Konfiguration empfangen: %@" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Protobufs" + "value" : "Configuration du module série reçue : %@" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "Protobufs" + "value" : "הגדרות מודולת תקשורת סיריאלית התקבלו: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione modulo seriale ricevuta: %@" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Protobufy" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Protobufs" + "value" : "Odebrano konfigurację modułu szeregowego: %@" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Protobufs" + "value" : "Seriekonfigurationsmodul mottagen: %@" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Протобафови" + "value" : "Конфигурација серијског модула примљена: %@" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Protobufs" + "value" : "Serial module config received: %@" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Protobufs" - } - } - } - }, - "serial.mode.simple" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Einfach" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Simple" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Simple" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "פשוט" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Prosty" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Simples" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enkel" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Једноставни" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "简单" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "簡單" - } - } - } - }, - "serial.mode.txtmsg" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Textnachricht" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Text Message" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message texte" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הודעת טקסט" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wiadomość tekstowa" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mensagem de Texto" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Textmeddelande" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Текстуална порука" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "文本消息" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "文本訊息" + "value" : "Serial module config received: %@" } } } }, "Series" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Serie" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Серије" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Series" + } } } }, @@ -27840,11 +27730,23 @@ "value" : "Server" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Server" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Сервер" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "伺服器" + } } } }, @@ -27856,45 +27758,65 @@ "value" : "Serveradresse" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Indirizzo del server" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Адреса сервера" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "伺服器地址" + } } } }, "Server Option" : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Опција сервера" + "value" : "Opzione server" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "伺服器選項" } } } }, "Set" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Set" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Подеси" } - } - } - }, - "Set the GPIO pins for RXD and TXD." : { - "localizations" : { - "sr" : { + }, + "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Подеси GPIO пинове за RXD и TXD." + "value" : "設定" } } } }, - "set.region" : { + "Set LoRa Region" : { "localizations" : { "de" : { "stringUnit" : { @@ -27902,12 +27824,6 @@ "value" : "Setze LoRa Region" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Set LoRa Region" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -27920,18 +27836,18 @@ "value" : "בחר אזור לורה" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Impostare la regione LoRa" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Ustaw region LoRa" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Seleciona o Região da LoRa" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -27958,17 +27874,51 @@ } } }, + "Set the GPIO pins for RXD and TXD." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Impostare i pin GPIO per RXD e TXD." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Подеси GPIO пинове за RXD и TXD." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "設定 RXD 和 TXD 的 GPIO 腳位。" + } + } + } + }, "Sets the maximum number of hops, default is 3. Increasing hops also increases congestion and should be used carefully. O hop broadcast messages will not get ACKs." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Imposta il numero massimo di hop, l'impostazione predefinita è 3. L'aumento degli hop aumenta anche la congestione e deve essere usato con attenzione. I messaggi di broadcasting a un hop non riceveranno ACK." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Подешава максималан број скокова. Подразумевано је 3, а повећање броја одобрених скокова такође повећава загушење и треба га користити опрезно. Поруке емитоване са 0 скокова неће добити потврде пријема (ACK)." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "設定最大轉送跳數,預設值為 3。提高跳數會增加網路擁擠程度,請謹慎使用。跳數為 0 的廣播訊息將不會收到確認回應(ACK)。" + } } } }, - "settings" : { + "Settings" : { "localizations" : { "de" : { "stringUnit" : { @@ -27976,12 +27926,6 @@ "value" : "Einstellungen" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Settings" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -27994,18 +27938,18 @@ "value" : "הגדרות" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Impostazioni" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Ustawienia" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Definições" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -28032,23 +27976,65 @@ } } }, - "Share QR Code & Link" : { + "Seventy Two Hours" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "QR Code & Link teilen" + "value" : "Zweiundsiebzig Stunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Soixante douze heures" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שבעים ושתיים שעות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Settantadue ore" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Siedemdziesiąt Dwie Godziny" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sjuttiotvå Timmar" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Дели QR код и линк" + "value" : "Седамдесет и два сата" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "七十二小时" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "72小時" } } } }, - "share.channels" : { + "Share QR Code" : { "localizations" : { "de" : { "stringUnit" : { @@ -28056,12 +28042,6 @@ "value" : "Kanal QR Code teilen" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Share QR Code" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -28074,18 +28054,18 @@ "value" : "שתף ערוצים באמצעות קוד QR" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Condividi il codice QR" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Udostępnij kod QR kanałów" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Partilhar o Código do QR" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -28107,72 +28087,35 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "分享頻道QRcode" + "value" : "分享 QR Code" } } } }, - "share.position" : { - "extractionState" : "manual", + "Share QR Code & Link" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Position teilen" + "value" : "QR Code & Link teilen" } }, - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Share Position" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Partager la position" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שתף מיקום" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Udostępnij pozycję" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Partilhar o Posição" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dela position" + "value" : "Condividi il codice QR e il link" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Подели позицију" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "分享位置" + "value" : "Дели QR код и линк" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "分享位置" + "value" : "分享 QR Code 及連結" } } } @@ -28185,11 +28128,81 @@ "value" : "Gemeinsamer Schlüssel" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Chiave condivisa" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Дељени кључ" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "共用金鑰" + } + } + } + }, + "Sharing Meshtastic Channels" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Meshtastic Kanäle teilen" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Partage des canaux Meshtastic" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "משתף ערוצי משטסטיק" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Condividere i canali Meshtastic" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sharing Meshtastic Channels" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dela Meshtastic-kanaler" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Дељење Мештастик канала" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "共享 Meshtastic 频道" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "分享 Meshtastic 頻道" + } } } }, @@ -28201,6 +28214,12 @@ "value" : "Kurzname" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nome breve" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -28212,6 +28231,12 @@ "state" : "translated", "value" : "短名称" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "簡短名稱" + } } } }, @@ -28223,6 +28248,12 @@ "value" : "Kurzname: %@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nome breve: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -28234,16 +28265,21 @@ "state" : "translated", "value" : "短名称: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "簡短名稱:%@" + } } } }, - "short.range.fast" : { - "extractionState" : "manual", + "Short Range - Fast" : { "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Short Range - Fast" + "value" : "Corto raggio - Veloce" } }, "sr" : { @@ -28251,16 +28287,21 @@ "state" : "translated", "value" : "Кратки домет - Брзо" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Short Range - Fast" + } } } }, - "short.range.slow" : { - "extractionState" : "manual", + "Short Range - Slow" : { "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Short Range - Slow" + "value" : "Corto raggio - Lento" } }, "sr" : { @@ -28268,16 +28309,21 @@ "state" : "translated", "value" : "Кратки домет - Споро" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Short Range - Slow" + } } } }, - "short.range.turbo" : { - "extractionState" : "manual", + "Short Range - Turbo" : { "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Short Range - Turbo" + "value" : "Corto raggio - Turbo" } }, "sr" : { @@ -28285,6 +28331,12 @@ "state" : "translated", "value" : "Кратки домет - Турбо" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Short Range - Turbo" + } } } }, @@ -28296,11 +28348,23 @@ "value" : "Zeige Alarme" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mostra avvisi" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Прикажи узбуне" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "顯示通知" + } } } }, @@ -28312,11 +28376,23 @@ "value" : "Zeige Alarme" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mostra avvisi" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Прикажи узбуне" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "顯示通知" + } } } }, @@ -28328,11 +28404,23 @@ "value" : "Zeige Knoten" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mostra i nodi" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Прикажи чворове" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "顯示節點" + } } } }, @@ -28344,11 +28432,23 @@ "value" : "Zeige auf dem Gerätebildschirm" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mostra sullo schermo del dispositivo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Прикажи на екрану уређаја" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "在裝置螢幕上顯示" + } } } }, @@ -28360,11 +28460,23 @@ "value" : "Zeige auf der Netzwerkkarte." } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mostra sulla mappa della mesh." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Прикажи на мапи меш мреже." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "在 Mesh 地圖上顯示" + } } } }, @@ -28376,20 +28488,38 @@ "value" : "Zeige Wegpunkte" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mostra waypoint " + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Прикажи тачке путање" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "顯示路徑點" + } } } }, "Shows information for the Lora radio connected via bluetooth. You can swipe left to disconnect the radio and long press start the live activity." : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Приказује информације за Lora радио повезан преко Bluetooth-а. Можете превући улево да бисте прекинули везу са радиом, а дугим притиском покрећете „уживо“ активност." + "value" : "Mostra le informazioni relative alla radio Lora collegata via bluetooth. È possibile scorrere il dito verso sinistra per scollegare la radio e premere a lungo per avviare l'attività live." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "顯示透過藍牙連接的 LoRa 裝置資訊。您可以向左滑動來斷開裝置,長按則可啟動即時活動。" } } } @@ -28402,11 +28532,23 @@ "value" : "Herunterfahren" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Spegnimento" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Искључи" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "關機" + } } } }, @@ -28418,11 +28560,23 @@ "value" : "Knoten herunterfahren?" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Spegnere il nodo?" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Искључити чвор?" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "關機?" + } } } }, @@ -28434,28 +28588,161 @@ "value" : "Knoten herunterfahren?" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Arresto del nodo?" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Искључити чвор?" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "關機?" + } + } + } + }, + "Shutdown on Power Loss" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Herunterfahren bei Stromunterbruch" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "Shutdown on Power Loss" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Spegnimento in caso di perdita di alimentazione" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Shutdown on Power Loss" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Stäng av vid Strömförlust" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Искључи уређај при губитку напајања" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "断电时关机" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "斷電自動關機" + } } } }, "Signal %@" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Segnale %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Сигнал %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "訊號%@" + } } } }, - "Singapore 923mhz" : { - "extractionState" : "manual", + "Simple" : { "localizations" : { - "en" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Einfach" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Simple" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "פשוט" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Semplice" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Prosty" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enkel" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Једноставни" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "简单" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "簡易" + } + } + } + }, + "Singapore 923MHz" : { + "localizations" : { + "it" : { "stringUnit" : { "state" : "translated", "value" : "Singapore 923MHz" @@ -28466,76 +28753,280 @@ "state" : "translated", "value" : "Сингапур 923MHz" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "新加坡 923MHz" + } + } + } + }, + "Six Hours" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sechs Stunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Six heures" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שש שעות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sei ore" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sześć Godzin" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sex Timmar" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Шест сати" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "六小时" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "6 小時" + } + } + } + }, + "skiing" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "skitour" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "tour sciistico" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "ски тура" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "滑雪之旅" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "滑雪" + } + } + } + }, + "Skiing" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Skifahren" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sci" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Скијање" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "滑雪" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "滑雪" + } } } }, "Smart Position" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Posizione intelligente" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Паметно позиционирање" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "智慧位置" + } } } }, "SNR" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "SNR" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "SNR" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "SNR" + } } } }, "SNR %@ dB" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "SNR %@ dB" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "SNR %@ dB" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "SNR %@ dB" + } } } }, "SNR %@dB" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "SNR %@dB" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "SNR %@dB" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "SNR %@dB" + } } } }, "Soil Moisture" : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Влага земљишта" + "value" : "Umidità del suolo" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "土壤溼度" } } } }, "Soil Temp" : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Температура земљиша" + "value" : "Temperatura del suolo" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "土壤溫度" } } } }, "Specifies how long the monitored GPIO should output." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Specifica la durata dell'uscita del GPIO monitorato." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Одређује колико дуго треба да траје излазни сигнал надзираног GPIO-а." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "指定監控中的 GPIO 應該輸出的時間長度。" + } } } }, @@ -28547,11 +29038,23 @@ "value" : "Geschwindigkeit" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Velocità" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Брзина" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "速度" + } } } }, @@ -28563,11 +29066,23 @@ "value" : "Geschwindigkeit %@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Velocità %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Брзина %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "速度 %@" + } } } }, @@ -28579,25 +29094,49 @@ "value" : "Geschwindigkeit: %@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Velocità: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Брзина: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "速度:%@" + } } } }, "Spread Factor" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fattore di diffusione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Фактор ширења" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "擴頻參數" + } } } }, - "ssid" : { + "SSID" : { "localizations" : { "de" : { "stringUnit" : { @@ -28605,12 +29144,6 @@ "value" : "SSID" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "SSID" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -28623,13 +29156,13 @@ "value" : "שם רשת וויפי" } }, - "pl" : { + "it" : { "stringUnit" : { "state" : "translated", "value" : "SSID" } }, - "pt-PT" : { + "pl" : { "stringUnit" : { "state" : "translated", "value" : "SSID" @@ -28661,27 +29194,8 @@ } } }, - "standard" : { - "extractionState" : "migrated", + "Standard" : { "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Standard" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Standard" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Standard" - } - }, "he" : { "stringUnit" : { "state" : "translated", @@ -28694,18 +29208,6 @@ "value" : "Standardowy" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Padrão" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Standard" - } - }, "sr" : { "stringUnit" : { "state" : "translated", @@ -28726,21 +29228,8 @@ } } }, - "standard.muted" : { - "extractionState" : "migrated", + "Standard Muted" : { "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Standard Muted" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Standard Muted" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -28753,18 +29242,18 @@ "value" : "סטנדרתי-השתק" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Standard Silenzioso" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Standardowy wyłączony" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Padrão Silenciado" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -28791,7 +29280,7 @@ } } }, - "start" : { + "Start" : { "localizations" : { "de" : { "stringUnit" : { @@ -28799,12 +29288,6 @@ "value" : "Start" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Start" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -28817,18 +29300,18 @@ "value" : "החל" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inizio" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Start" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Iniciar" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -28857,16 +29340,34 @@ }, "State Broadcast Interval" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Stato Intervallo di trasmissione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Интервал емитовања стања" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "狀態廣播間隔" + } } } }, "Store & Forward" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Memorizzare e inoltrare" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -28878,11 +29379,23 @@ "state" : "translated", "value" : "储存 & 转发" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "儲存與轉送" + } } } }, "Store & Forward Config" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione Store & Forward" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -28894,79 +29407,79 @@ "state" : "translated", "value" : "储存 & 转发设置" } - } - } - }, - "Store and forward servers require an ESP32 device with PSRAM or Linux Native." : { - "localizations" : { - "sr" : { + }, + "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Сервери за складиштење и прослеђивање захтевају ESP32 уређај са PSRAM-ом или Линук native-ом." + "value" : "儲存與轉送設定" } } } }, - "storeforward.heartbeat" : { + "Store & Forward module config received: %@" : { "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Herzschlag senden" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Send Heartbeat" - } - }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Envoyer une impulsion" + "value" : "Configuration du module Stocker et Transmettre reçue : %@" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "שלח דופק" + "value" : "הגדרות מודולת שמירה ושליחה התקבלו: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione del modulo Store & Forward ricevuta: %@" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Send Heartbeat" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enviar Batimento Cardíaco" + "value" : "Store & Forward module config received: %@" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Skicka hjärtslag" + "value" : "Konfiguration för Store & Forward-modulen mottagen: %@" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Пошаљи откуцај срца" + "value" : "Конфигурација модула за чување и прослеђивање примљена: %@" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "发送心跳包" + "value" : "Store & Forward module config received: %@" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "發送心跳包" + "value" : "Store & Forward module config received: %@" + } + } + } + }, + "Store and forward servers require an ESP32 device with PSRAM or Linux Native." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "I server Store and Forward richiedono un dispositivo ESP32 con PSRAM o Linux Native." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "儲存與轉送伺服器需要使用具有 PSRAM 的 ESP32 裝置或是原生 Linux 系統。" } } } @@ -28979,11 +29492,39 @@ "value" : "מחובר למש" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Abbonati" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Претплаћен" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "已建立連線" + } + } + } + }, + "Subsystem" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sottosistema" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Подсистем" + } } } }, @@ -28995,16 +29536,34 @@ "value" : "Unterstützt" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Supportato" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Подржан" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "支援" + } } } }, "Supported I2C Connected sensors will be detected automatically, sensors are BMP280, BME280, BME680, MCP9808, INA219, INA260, LPS22 and SHTC3." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "I sensori I2C supportati vengono rilevati automaticamente: BMP280, BME280, BME680, MCP9808, INA219, INA260, LPS22 e SHTC3." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -29016,43 +29575,140 @@ "state" : "translated", "value" : "将自动检测支持 I2C 连接的传感器,包括 BMP280、BME280、BME680、MCP9808、INA219、INA260、LPS22 和 SHTC3。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "支援的 I2C 連接感測器將自動偵測,這些感測器包括 BMP280、BME280、BME680、MCP9808、INA219、INA260、LPS22 和 SHTC3。" + } } } }, "Table" : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Табела" - } - } - } - }, - "Taiwan" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Taiwan" + "value" : "Tabella" } }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Табела" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "表格" + } + } + } + }, + "Taiwan" : { + "localizations" : { "sr" : { "stringUnit" : { "state" : "translated", "value" : "Тајван" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "臺灣 🇹🇼" + } + } + } + }, + "TAK" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "TAK" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "TAK" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "TAK" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "TAK" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "TAK" + } + } + } + }, + "TAK Tracker" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "TAK Tracker" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tracker TAK" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "ТАК Трекер" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "TAK 追踪器" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "TAK Tracker" + } } } }, "Takes a Meshtastic channel URL and saves the channel settings." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Prende l'URL di un canale Meshtastic e salva le impostazioni del canale." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Узима URL канала Meshtastic и чува подешавања канала." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "輸入一個 Meshtastic 頻道網址,並儲存該頻道的設定。" + } } } }, @@ -29064,12 +29720,6 @@ "value" : "Tapback Antwort" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tapback Response" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -29082,18 +29732,18 @@ "value" : "תגובה מהירה" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Risposta di Tapback" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Odpowiedź na stuknięcie" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Resposta Tapback" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -29115,338 +29765,1656 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "響應" + "value" : "表情回應" } } } }, - "tapback.exclamation" : { - "extractionState" : "migrated", + "Telemetry" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Ausrufezeichen" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Exclamation Mark" + "value" : "Telemetrie (Sensoren)" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Point d'exclamation" + "value" : "Télémetrie (Capteurs)" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "סימן קריאה" + "value" : "טלמטריה (חיישנים)" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Telemetria (sensori)" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Wykrzyknik" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ponto de Exclamação" + "value" : "Telemetria (czujniki)" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Utropstecken" + "value" : "Telemetri (Sensorer)" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Узвичник" + "value" : "Телеметрија (сензори)" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "感叹号" + "value" : "遥测(传感器)" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "驚嘆號" + "value" : "遙測(傳感器)" } } } }, - "tapback.haha" : { - "extractionState" : "migrated", + "Telemetry Config" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "HaHa" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "HaHa" + "value" : "Telemetrie Einstellungen" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "HaHa" + "value" : "Configuration de télémetrie" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "חחח" + "value" : "הגדרות טלמטריה" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione della telemetria" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "HaHa" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "HaHa" + "value" : "Konfiguracja telemetrii" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "HaHa" + "value" : "Telemetriinställningar" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Хахаха" + "value" : "Конфигурација телеметрије" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "哈哈" + "value" : "遥测配置" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "哈哈" + "value" : "遙測設定" } } } }, - "tapback.heart" : { - "extractionState" : "migrated", + "Telemetry module config received: %@" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Herz" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Heart" + "value" : "Telemetrie Modul Konfiguration empfangen: %@" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Coeur" + "value" : "Configuration du module télémetrie reçue : %@" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "לב" + "value" : "הגדרות מודולת טלמטריה התקבלו: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione del modulo di telemetria ricevuta: %@" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Serce" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Coração" + "value" : "Odebrano konfigurację modułu telemetrii: %@" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Hjärta" + "value" : "Telemetrimodulkonfiguration mottagen: %@" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Срце" + "value" : "Конфигурација модула телеметрије примљена: %@" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "心" + "value" : "Telemetry module config received: %@" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "心" + "value" : "Telemetry module config received: %@" } } } }, - "tapback.poop" : { - "extractionState" : "migrated", + "Telemetry received for: %@" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Kacke" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Poop" + "value" : "Telemetrie empfangen für: %@" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Caca" + "value" : "Télémetrie reçue pour : %@" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "חרא" + "value" : "התקבל טלמטריה עבור: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Telemetria ricevuta per: %@" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Kupa" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cocó" + "value" : "Telemetria odebrana dla: %@" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Bajs" + "value" : "Telemetri mottagen för: %@" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Кака" + "value" : "Телеметрија примљена за: %@" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "便便" + "value" : "Telemetry received for: %@" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "便便" + "value" : "Telemetry received for: %@" } } } }, - "tapback.question" : { - "extractionState" : "migrated", + "Temp" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Fragezeichen" + "value" : "Temp" } }, - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Question Mark" + "value" : "Temp" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Темп." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "溫度" + } + } + } + }, + "Temperature" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Temperatur" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Temperatura" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Температура" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "溫度" + } + } + } + }, + "Ten Minutes" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zehn Minuten" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Point d'interrogation" + "value" : "Dix minutes" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "סימן שאלה" + "value" : "עשר דקות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dieci minuti" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Znak zapytania" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ponto de Interrogação" + "value" : "Dziesięć Minut" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Frågetecken" + "value" : "Tio Minuter" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Знак питања" + "value" : "Десет минута" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "问号" + "value" : "十分钟" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "問號" + "value" : "10 分鐘" } } } }, - "tapback.thumbsdown" : { - "extractionState" : "migrated", + "Ten Seconds" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zehn Sekunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dix secondes" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "עשר שניות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dieci secondi" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dziesięć Sekund" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tio Sekunder" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Десет секунди" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "十秒" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "10 秒" + } + } + } + }, + "Tertiary Admin Key" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dritter Admin-Schlüssel" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Chiave amministrativa terziaria" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Терцијарни административни кључ" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "三级管理员密钥" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "第三組管理公鑰" + } + } + } + }, + "Text Message" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Textnachricht" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Message texte" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הודעת טקסט" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Messaggio di testo" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wiadomość tekstowa" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Textmeddelande" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Текстуална порука" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "文本消息" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "文字訊息" + } + } + } + }, + "TFT Full Color Displays" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Display TFT a colori" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "TFT екрани у пуној боји" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "TFT全彩螢幕" + } + } + } + }, + "Thailand" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Thailandia" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Тајланд" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "泰國" + } + } + } + }, + "The amount of time to wait before we consider your packet as done." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il tempo di attesa prima che il pacchetto venga considerato completato." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Време чекања пре него што сматрамо да је ваш пакет завршен." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "在將您的封包視為已完成之前需等待的時間長度。" + } + } + } + }, + "The compass heading on the screen outside of the circle will always point north." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La direzione della bussola sullo schermo all'esterno del cerchio punterà sempre verso nord." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Смер компаса на екрану изван круга увек ће указивати на север." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "畫面上圓圈外的指北針方向將永遠指向北方。" + } + } + } + }, + "The dew point is %@ right now." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Der Taupunkt ist gerade %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il punto di rugiada è %@ in questo momento." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Тачка росе тренутно износи %@." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "當前露點為 %@" + } + } + } + }, + "The fastest that position updates will be sent if the minimum distance has been satisfied" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La velocità con cui verranno inviati gli aggiornamenti della posizione se la distanza minima è stata soddisfatta" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Најбржа брзина којом ће се ажурирати позиција уколико је задовољен минимални услов за растојање." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "當達到最短距離變化時,位置更新傳送的最短間隔時間" + } + } + } + }, + "The format used to display GPS coordinates on the device screen." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il formato utilizzato per visualizzare le coordinate GPS sullo schermo del dispositivo." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Формат који се користи за приказивање GPS координата на екрану уређаја." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "用于在设备屏幕上显示 GPS 坐标的格式。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "用於在裝置螢幕上顯示 GPS 座標的格式。" + } + } + } + }, + "The last 4 of the device MAC address will be appended to the short name to set the device's BLE Name. Short name can be up to 4 bytes long." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Gli ultimi 4 dell'indirizzo MAC del dispositivo vengono aggiunti al nome breve per impostare il nome BLE del dispositivo. Il nome breve può avere una lunghezza massima di 4 byte." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Последња 4 знака MAC адресе уређаја ће бити додата кратком имену како би се подесило BLE име уређаја. Кратко име може бити до 4 бајта дуго." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "设备 MAC 地址的后 4 位将附加到短名称中,以设置设备的 BLE 名称。 短名称的长度最多为 4 个字节。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "裝置的 BLE 名稱將由簡短名稱加上裝置 MAC 位址的最後 4 碼組成。簡短名稱最多可為 4 個位元組長。" + } + } + } + }, + "The maximum interval that can elapse without a node broadcasting a position" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "L'intervallo massimo che può trascorrere senza che un nodo trasmetta una posizione" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Максимални интервал који може протећи без да чвор емитује позицију." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "節點在未廣播位置資訊時允許的最長間隔時間" + } + } + } + }, + "The Meshtastic Apple apps support firmware version %@ and above." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Le applicazioni Meshtastic Apple supportano la versione firmware %@ e successive." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Мештастик апликације за Епл уређаје подржавају верзију фирмвера %@ и новије." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Meshtastic Apple 应用程序支持 %@ 及以上版本的固件。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Meshtastic 的 Apple 應用程式支援 %@ 版本及以上的韌體。" + } + } + } + }, + "The minimum distance change in meters to be considered for a smart position broadcast." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La variazione di distanza minima in metri da considerare per la trasmissione di una posizione intelligente." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Минимална промена растојања у метрима која ће се узети у обзир за паметно емитовање позиције." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "智能位置广播考虑的最小距离变化(以米为单位)。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "觸發智慧位置廣播時需達到的最小距離變化(以公尺為單位)" + } + } + } + }, + "The most recent public key for this node does not match the previously recorded key. You can delete the node and let it exchange keys again, but this also may indicate a more serious security problem. Contact the user through another trusted channel to determine if the key change was due to a factory reset or other intentional action." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La chiave pubblica più recente di questo nodo non corrisponde alla chiave registrata in precedenza. È possibile eliminare il nodo e fargli scambiare nuovamente le chiavi, ma questo potrebbe indicare un problema di sicurezza più serio. Contattare l'utente attraverso un altro canale fidato per determinare se la modifica della chiave è dovuta a un reset di fabbrica o a un'altra azione intenzionale." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Најновији јавни кључ за овај чвор се не подудара са претходно снимљеним кључем. Можете избрисати чвор и дозволити му да поново размени кључеве, али ово такође може указивати на озбиљнији безбедносни проблем. Контактирајте корисника преко другог поузданог канала како бисте утврдили да ли је промена кључа резултат фабричког ресетовања или друге намерне акције." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "该节点的最新公钥与之前记录的公钥不匹配。您可以删除该节点,让它重新交换公钥,但这也可能表明存在更严重的安全问题。通过其他可信渠道联系用户,以确定公钥更改是否是由于出厂重置或其他故意行为造成的。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "此節點最新的公開金鑰與先前記錄的不符。您可以刪除此節點並讓它重新交換金鑰,但這也可能代表出現了更嚴重的安全問題。請透過其他可信的聯絡方式與該使用者確認金鑰變更是否因為恢復原廠設定或其他有意的操作所導致。" + } + } + } + }, + "The packet is too large" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Das Paket ist zu groß" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Le paquet est trop grand" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "ההודעה ארוכה/גדולה מידי" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il pacchetto è troppo grande" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pakiet jest zbyt duży" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Paketet är för stort" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Пакет је превелики" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "数据包过大" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "數據包過大" + } + } + } + }, + "The primary public key authorized to send admin messages to this node." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Der erste öffentliche Schlüssel, der berechtigt ist, Admin-Nachrichten an diesen Knoten zu senden." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La chiave pubblica primaria autorizzata a inviare messaggi di amministrazione a questo nodo." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Примарни јавни кључ овлашћен за слање административних порука овом чвору." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "授权向该节点发送管理信息的一级管理员公钥。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "被授權向此節點發送管理訊息的主要公鑰。" + } + } + } + }, + "The public key does not match the recorded key. You may delete the node and let it exchange keys again, but this may indicate a more serious security problem. Contact the user through another trusted channel, to determine if the key change was due to a factory reset or other intentional action." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La chiave pubblica non corrisponde alla chiave registrata. È possibile eliminare il nodo e fargli scambiare nuovamente le chiavi, ma questo potrebbe indicare un problema di sicurezza più serio. Contattare l'utente attraverso un altro canale fidato, per determinare se la modifica della chiave è dovuta a un reset di fabbrica o a un'altra azione intenzionale." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Јавни кључ се не подудара са снимљеним кључем. Можете избрисати чвор и дозволити му да поново размени кључеве, али ово може указивати на озбиљнији безбедносни проблем. Контактирајте корисника преко другог поузданог канала како бисте утврдили да ли је промена кључа резултат фабричког ресетовања или друге намерне акције." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "公钥与记录的公钥不匹配。您可以删除节点,让它重新交换公钥,但这可能表明存在更严重的安全问题。通过其他可信渠道联系用户,以确定公钥更改是否是由于出厂重置或其他故意行为造成的。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "公開金鑰與原先記錄的不符。您可以刪除此節點並讓它重新交換金鑰,但這可能表示存在更嚴重的安全問題。請透過其他可信的聯絡方式與該使用者確認,此次金鑰變更是否因為恢復原廠設定或其他有意的操作所造成。" + } + } + } + }, + "The region where you will be using your radios." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La regione in cui si utilizzeranno le radio." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Регион у коме ћете користити ваше радио уређаје." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "使用电台的地区。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "您將使用無線電的地區。" + } + } + } + }, + "The root topic to use for MQTT." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "L'argomento principale da usare per MQTT." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Корен тема која ће се користити за MQTT." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "用于 MQTT 的根主题。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "MQTT 使用的根主題" + } + } + } + }, + "The Router roles are designed for high vantage locations like mountaintops and towers. This node needs to be able to have a good direct connection to most of the nodes on the network or else this will significantly hurt the network." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "I ruoli di router sono progettati per posizioni elevate, come le cime delle montagne e le torri. Questo nodo deve essere in grado di avere una buona connessione diretta con la maggior parte dei nodi della rete, altrimenti danneggia significativamente la rete." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Router 模式專為高處位置(如山頂或塔台)設計。此節點必須能夠與網路中的大多數節點保持良好的直接連線,否則將會嚴重影響整體網路效能。" + } + } + } + }, + "The secondary public key authorized to send admin messages to this node." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Der zweite öffentliche Schlüssel, der berechtigt ist, Admin-Nachrichten an diesen Knoten zu senden." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La chiave pubblica secondaria autorizzata a inviare messaggi di amministrazione a questo nodo." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Секундарни јавни кључ овлашћен за слање административних порука овом чвору." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "授权向该节点发送管理信息的二级管理员公钥。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "被授權向此節點發送管理訊息的次要公鑰。" + } + } + } + }, + "The specified device has disconnected from us" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il dispositivo specificato si è disconnesso" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Наведени уређај је прекинуо везу са нама" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "指定的裝置已斷線" + } + } + } + }, + "The state of the LED (on/off)" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Lo stato del LED (acceso/spento)" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Стање LED диоде (укључено/искључено)" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "LED狀態燈開關" + } + } + } + }, + "The tertiary public key authorized to send admin messages to this node." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Der dritte öffentliche Schlüssel, der berechtigt ist, Admin-Nachrichten an diesen Knoten zu senden." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La chiave pubblica terziaria autorizzata a inviare messaggi di amministrazione a questo nodo." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Терцијарни јавни кључ овлашћен за слање административних порука овом чвору." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "授权向该节点发送管理信息的三级管理员公钥。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "被授權向此節點發送管理訊息的第三公鑰。" + } + } + } + }, + "The URL for the channel settings" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "L'URL per le impostazioni del canale" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "URL за подешавања канала" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻道設定的網址" + } + } + } + }, + "There has been no response to a request for device metadata over the admin channel for this node." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Non è stata data risposta a una richiesta di metadati del dispositivo sul canale di amministrazione per questo nodo." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Није било одговора на захтев за метаподатке уређаја преко административног канала за овај чвор." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "此節點的管理頻道未回應設備中繼資料的請求。" + } + } + } + }, + "These settings will %@ channels. The current LoRa Config will be replaced, if there are substantial changes to the LoRa config the device will reboot" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Queste impostazioni saranno %@ canali. La configurazione LoRa corrente verrà sostituita; se vengono apportate modifiche sostanziali alla configurazione LoRa, il dispositivo si riavvierà" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ова подешавања ће %@ канале. Тренутна LoRA конфигурација ће бити замењена. Ако дође до значајних промена у LoRA конфигурацији, уређај ће се поново покренути." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "這些設定將會 %@ 頻道。當前的 LoRa 設定將被取代,若 LoRa 設定有重大變更,裝置將會重新啟動。" + } + } + } + }, + "Thirty Minutes" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dreißig Minuten" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trente minutes" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שלושים דקות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trenta minuti" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trzydzieści Minut" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trettio Minuter" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Пола сата" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "三十分钟" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "30 分鐘" + } + } + } + }, + "Thirty Seconds" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dreißig Sekunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trente secondes" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שלושים שניות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trenta secondi" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trzydzieści Sekund" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trettio Sekunder" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Тридесет секунди" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "三十秒" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "30 秒" + } + } + } + }, + "Thirty Six Hours" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sechsunddreissig Stunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trente six heures" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שלושים ושש שעות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trentasei ore" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trzydzieści Sześć Godzin" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trettiosex Timmar" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Тридесет и шест сати" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "三十六小时" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "36 小時" + } + } + } + }, + "This conversation will be deleted." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Questa conversazione sarà cancellata." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Овај разговор ће бити обрисан." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "此對話紀錄將會被刪除。" + } + } + } + }, + "This could take a while, response will appear in the trace route log for the node it was sent to." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La risposta potrebbe richiedere un po' di tempo e verrà visualizzata nel registro delle rotte di tracciamento per il nodo a cui è stata inviata." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ово може потрајати. Одговор ће се појавити у евиденцији трасе праћења за чвор којем је послат." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "這可能需要一段時間,回應將會顯示在被發送節點的路由追蹤紀錄中。" + } + } + } + }, + "This could take a while. The response will appear in the trace route log for the node it was sent to." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "L'operazione potrebbe richiedere un po' di tempo. La risposta apparirà nel registro delle rotte di tracciamento per il nodo a cui è stata inviata." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ово може потрајати. Одговор ће се појавити у евиденцији трасе праћења за чвор којем је послат." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "這可能需要一段時間。回應將會顯示在被發送節點的路由追蹤紀錄中。" + } + } + } + }, + "This device will send out range test messages on the selected interval." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il dispositivo invia messaggi di test di portata all'intervallo selezionato." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Овај уређај ће слати поруке за тестирање домета у одабраном интервалу." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "该设备将按所选时间间隔发送测距信息。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "裝置將按照設定的時間間隔發送距離測試訊息。" + } + } + } + }, + "This message was likely not delivered." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Diese Nachricht wurde höchstwahrscheinlich nicht übermittelt." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "È probabile che questo messaggio non sia stato consegnato." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ова порука вероватно није била примљена." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "此訊息可能未被傳送。" + } + } + } + }, + "This node does not support any configurable modules." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Questo nodo non supporta alcun modulo configurabile." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "此節點不支援任何可設定的模組。" + } + } + } + }, + "This will disable fixed position and remove the currently set position." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "In questo modo si disattiva la posizione fissa e si rimuove la posizione attualmente impostata." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ово ће онемогућити фиксну позицију и уклонити тренутно постављену позицију." + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "這將禁用固定位置並移除當前設定的位置。" + } + } + } + }, + "This will send a current position from your phone and enable fixed position." : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "In questo modo si invia la posizione corrente dal telefono e si abilita la posizione fissa." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ово ће послати тренутну позицију са вашег телефона и омогућити фиксну позицију." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "这将从手机发送当前位置并启用固定位置。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "這將傳送您手機的當前位置並啟用固定位置。" + } + } + } + }, + "Three Hours" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Drei Stunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trois heures" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שלוש שעות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tre ore" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trzy Godziny" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tre Timmar" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Три сата" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "三小时" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "3 小時" + } + } + } + }, + "Three Seconds" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Drei Sekunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trois secondes" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שלוש שניות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tre secondi" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trzy Sekundy" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tre Sekunder" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Три секунде" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "三秒" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "3 秒" + } + } + } + }, + "Thumbs Down" : { "localizations" : { "de" : { "stringUnit" : { @@ -29454,12 +31422,6 @@ "value" : "Daumen runter" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Thumbs Down" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -29472,18 +31434,18 @@ "value" : "אגודל למטה" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pollici in giù" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Kciuk w dół" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Polegar para Baixo" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -29510,8 +31472,7 @@ } } }, - "tapback.thumbsup" : { - "extractionState" : "migrated", + "Thumbs Up" : { "localizations" : { "de" : { "stringUnit" : { @@ -29519,12 +31480,6 @@ "value" : "Daumen hoch" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Thumbs Up" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -29537,18 +31492,18 @@ "value" : "אגודל למעלה" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pollici in su" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Kciuk w górę" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Polegar para Cima" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -29575,836 +31530,6 @@ } } }, - "tapback.wave" : { - "extractionState" : "migrated", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Welle" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wave" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wave" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wave" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wave" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Adeus" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Vinka" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Махање" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wave" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "招手" - } - } - } - }, - "telementry.hazardous" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Hazardous" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Опасно" - } - } - } - }, - "telementry.unhealthy" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Unhealthy" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Нездраво" - } - } - } - }, - "telementry.veryUnhealthy" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Very Unhealthy" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Веома нездраво" - } - } - } - }, - "telemetry" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Telemetrie (Sensoren)" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Telemetry (Sensors)" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Télémetrie (Capteurs)" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "טלמטריה (חיישנים)" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Telemetria (czujniki)" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Telemetria (Sensores)" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Telemetri (Sensorer)" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Телеметрија (сензори)" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "遥测(传感器)" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "遠測(傳感器)" - } - } - } - }, - "telemetry.config" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Telemetrie Einstellungen" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Telemetry Config" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration de télémetrie" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרות טלמטריה" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Konfiguracja telemetrii" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuração Telemetria" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Telemetriinställningar" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Конфигурација телеметрије" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "遥测配置" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "遠側設定" - } - } - } - }, - "telemetry.good" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Good" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Добро" - } - } - } - }, - "telemetry.moderate" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Moderate" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Умерено" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "适度" - } - } - } - }, - "telemetry.sensitive" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Unhealthy for Sensitive Groups" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Нездраво за осетљиве групе" - } - } - } - }, - "Temp" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Temp" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Темп." - } - } - } - }, - "Temperature" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Temperatur" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Температура" - } - } - } - }, - "Ten Minutes" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Zehn Minuten" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Десет пинута" - } - } - } - }, - "Tertiary Admin Key" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dritter Admin-Schlüssel" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Терцијарни административни кључ" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "三级管理员密钥" - } - } - } - }, - "tft.full.color.displays" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "TFT Full Color Displays" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "TFT екрани у пуној боји" - } - } - } - }, - "Thailand" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Thailand" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Тајланд" - } - } - } - }, - "The amount of time to wait before we consider your packet as done." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Време чекања пре него што сматрамо да је ваш пакет завршен." - } - } - } - }, - "The compass heading on the screen outside of the circle will always point north." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Смер компаса на екрану изван круга увек ће указивати на север." - } - } - } - }, - "The dew point is %@ right now." : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Der Taupunkt ist gerade %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Тачка росе тренутно износи %@." - } - } - } - }, - "The fastest that position updates will be sent if the minimum distance has been satisfied" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Најбржа брзина којом ће се ажурирати позиција уколико је задовољен минимални услов за растојање." - } - } - } - }, - "The format used to display GPS coordinates on the device screen." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Формат који се користи за приказивање GPS координата на екрану уређаја." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "用于在设备屏幕上显示 GPS 坐标的格式。" - } - } - } - }, - "The last 4 of the device MAC address will be appended to the short name to set the device's BLE Name. Short name can be up to 4 bytes long." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Последња 4 знака MAC адресе уређаја ће бити додата кратком имену како би се подесило BLE име уређаја. Кратко име може бити до 4 бајта дуго." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "设备 MAC 地址的后 4 位将附加到短名称中,以设置设备的 BLE 名称。 短名称的长度最多为 4 个字节。" - } - } - } - }, - "The maximum interval that can elapse without a node broadcasting a position" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Максимални интервал који може протећи без да чвор емитује позицију." - } - } - } - }, - "The Meshtastic Apple apps support firmware version %@ and above." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Мештастик апликације за Епл уређаје подржавају верзију фирмвера %@ и новије." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Meshtastic Apple 应用程序支持 %@ 及以上版本的固件。" - } - } - } - }, - "The minimum distance change in meters to be considered for a smart position broadcast." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Минимална промена растојања у метрима која ће се узети у обзир за паметно емитовање позиције." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "智能位置广播考虑的最小距离变化(以米为单位)。" - } - } - } - }, - "The most recent public key for this node does not match the previously recorded key. You can delete the node and let it exchange keys again, but this also may indicate a more serious security problem. Contact the user through another trusted channel to determine if the key change was due to a factory reset or other intentional action." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Најновији јавни кључ за овај чвор се не подудара са претходно снимљеним кључем. Можете избрисати чвор и дозволити му да поново размени кључеве, али ово такође може указивати на озбиљнији безбедносни проблем. Контактирајте корисника преко другог поузданог канала како бисте утврдили да ли је промена кључа резултат фабричког ресетовања или друге намерне акције." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "该节点的最新公钥与之前记录的公钥不匹配。您可以删除该节点,让它重新交换公钥,但这也可能表明存在更严重的安全问题。通过其他可信渠道联系用户,以确定公钥更改是否是由于出厂重置或其他故意行为造成的。" - } - } - } - }, - "The primary public key authorized to send admin messages to this node." : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Der erste öffentliche Schlüssel, der berechtigt ist, Admin-Nachrichten an diesen Knoten zu senden." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Примарни јавни кључ овлашћен за слање административних порука овом чвору." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "授权向该节点发送管理信息的一级管理员公钥。" - } - } - } - }, - "The public key does not match the recorded key. You may delete the node and let it exchange keys again, but this may indicate a more serious security problem. Contact the user through another trusted channel, to determine if the key change was due to a factory reset or other intentional action." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Јавни кључ се не подудара са снимљеним кључем. Можете избрисати чвор и дозволити му да поново размени кључеве, али ово може указивати на озбиљнији безбедносни проблем. Контактирајте корисника преко другог поузданог канала како бисте утврдили да ли је промена кључа резултат фабричког ресетовања или друге намерне акције." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "公钥与记录的公钥不匹配。您可以删除节点,让它重新交换公钥,但这可能表明存在更严重的安全问题。通过其他可信渠道联系用户,以确定公钥更改是否是由于出厂重置或其他故意行为造成的。" - } - } - } - }, - "The region where you will be using your radios." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Регион у коме ћете користити ваше радио уређаје." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "使用电台的地区。" - } - } - } - }, - "The root topic to use for MQTT." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Корен тема која ће се користити за MQTT." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "用于 MQTT 的根主题。" - } - } - } - }, - "The Router roles are designed for high vantage locations like mountaintops and towers. This node needs to be able to have a good direct connection to most of the nodes on the network or else this will significantly hurt the network." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Улоге рутера су дизајниране за локације са високим погледом као што су врхови планина и куле. Овај чвор мора бити у могућности да има добру директну везу са већином чворова на мрежи или ће то значајно наштетити мрежи." - } - } - } - }, - "The secondary public key authorized to send admin messages to this node." : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Der zweite öffentliche Schlüssel, der berechtigt ist, Admin-Nachrichten an diesen Knoten zu senden." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Секундарни јавни кључ овлашћен за слање административних порука овом чвору." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "授权向该节点发送管理信息的二级管理员公钥。" - } - } - } - }, - "The specified device has disconnected from us" : { - "extractionState" : "manual", - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Наведени уређај је прекинуо везу са нама" - } - } - } - }, - "The state of the LED (on/off)" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Стање LED диоде (укључено/искључено)" - } - } - } - }, - "The tertiary public key authorized to send admin messages to this node." : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Der dritte öffentliche Schlüssel, der berechtigt ist, Admin-Nachrichten an diesen Knoten zu senden." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Терцијарни јавни кључ овлашћен за слање административних порука овом чвору." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "授权向该节点发送管理信息的三级管理员公钥。" - } - } - } - }, - "The URL for the channel settings" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "URL за подешавања канала" - } - } - } - }, - "There has been no response to a request for device metadata over the admin channel for this node." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Није било одговора на захтев за метаподатке уређаја преко административног канала за овај чвор." - } - } - } - }, - "These settings will %@ channels. The current LoRa Config will be replaced, if there are substantial changes to the LoRa config the device will reboot" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ова подешавања ће %@ канале. Тренутна LoRA конфигурација ће бити замењена. Ако дође до значајних промена у LoRA конфигурацији, уређај ће се поново покренути." - } - } - } - }, - "Thirty Minutes" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dreißig Minuten" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Тридесет минута" - } - } - } - }, - "This conversation will be deleted." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Овај разговор ће бити обрисан." - } - } - } - }, - "This could take a while, response will appear in the trace route log for the node it was sent to." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ово може потрајати. Одговор ће се појавити у евиденцији трасе праћења за чвор којем је послат." - } - } - } - }, - "This could take a while. The response will appear in the trace route log for the node it was sent to." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ово може потрајати. Одговор ће се појавити у евиденцији трасе праћења за чвор којем је послат." - } - } - } - }, - "This device will send out range test messages on the selected interval." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Овај уређај ће слати поруке за тестирање домета у одабраном интервалу." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "该设备将按所选时间间隔发送测距信息。" - } - } - } - }, - "This message was likely not delivered." : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Diese Nachricht wurde höchstwahrscheinlich nicht übermittelt." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ова порука вероватно није била примљена." - } - } - } - }, - "This node does not support any configurable modules." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Овај чвор не подржава ниједан конфигурабилан модул." - } - } - } - }, - "This will disable fixed position and remove the currently set position." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ово ће онемогућити фиксну позицију и уклонити тренутно постављену позицију." - } - } - } - }, - "This will send a current position from your phone and enable fixed position." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ово ће послати тренутну позицију са вашег телефона и омогућити фиксну позицију." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "这将从手机发送当前位置并启用固定位置。" - } - } - } - }, "Time" : { "localizations" : { "de" : { @@ -30413,11 +31538,23 @@ "value" : "Zeit" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tempo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Време" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "時間" + } } } }, @@ -30429,11 +31566,23 @@ "value" : "Zeitstempel" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Timbro del tempo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Временски жиг" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "時間戳記" + } } } }, @@ -30445,11 +31594,23 @@ "value" : "Zeitzone" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fuso orario" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Временска зона" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "時區" + } } } }, @@ -30461,15 +31622,27 @@ "value" : "Zeitzone für Daten auf dem Gerätebildschirm und Log." } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fuso orario per le date sullo schermo del dispositivo e sul registro." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Временска зона за датуме на екрану уређаја и у евиденцији." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "用於裝置螢幕顯示與日誌記錄日期的時區設定" + } } } }, - "timeout" : { + "Timeout" : { "localizations" : { "de" : { "stringUnit" : { @@ -30477,12 +31650,6 @@ "value" : "Zeitlimit erreicht" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Timeout" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -30495,18 +31662,18 @@ "value" : "זמן קצוב" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Timeout" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Limit czasu" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tempo Limite" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -30528,17 +31695,7 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "超時" - } - } - } - }, - "timestamp" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "временска ознака" + "value" : "逾時長度" } } } @@ -30551,12 +31708,6 @@ "value" : "Zeitstempel" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Timestamp" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -30569,18 +31720,18 @@ "value" : "שעה/תאריך" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Timestamp" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Znacznik czasu" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Carimbo de Data/Hora" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -30609,528 +31760,34 @@ }, "Timing & Format" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tempi e formati" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Време и формат" } - } - } - }, - "tip.channel.admin.message" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Admin Kanal erkannt: Wähle einen Knoten vom Dropdown aus um verbundene oder entfernte Geräte zu verwalten." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Admin channel detected: Select a node from the drop down to manage connected or remote devices." - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Admin channel detected: Select a node from the drop down to manage connected or remote devices." - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Admin channel detected: Select a node from the drop down to manage connected or remote devices." - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Admin channel detected: Select a node from the drop down to manage connected or remote devices." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Canal de administração detectado: Selecione um nó do menu suspenso para gerir dispositivos conectados ou remotos." - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Administratörskanal upptäckt: Välj en nod från rullgardinsmenyn för att hantera anslutna eller fjärranslutna enheter." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Детектован админ канал: Изаберите чвор из падајућег менија да бисте управљали повезаним или удаљеним уређајима." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "检测到 admin 频道:请从下拉菜单中选择一个节点,来管理已连接或远程设备。" - } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "偵測到管理頻道:從下拉選單中選擇一個節點來管理連接或遠端設備。" - } - } - } - }, - "tip.channel.admin.title" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Admin Kanal" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Admin Channel" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Admin Channel" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Admin Channel" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Admin Channel" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Canal de Administração" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Administratörskanal" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Административни канал" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "admin 频道" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "管理頻道" - } - } - } - }, - "tip.channels.create.message" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Die meisten Daten in deinem Mesh werden über den primären Kanal gesendet. Du kannst sekundäre Kanäle einrichten, um zusätzliche Nachrichtengruppen zu erstellen, die durch ihren eigenen Schlüssel gesichert sind. [Tipps zur Kanalkonfiguration](https://meshtastic.org/docs/configuration/radio/channels/)" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Most data on your mesh is sent over the primary channel. You can set up secondary channels to create additional messaging groups secured by their own key. [Channel config tips](https://meshtastic.org/docs/configuration/tips/)" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "La pluspart des données de votre maillage sont envoyées sur le canal principal. Vous pouvez définir des canaux secondaires pour créer des groupes de messagerie additionnelle sécurisés avec leur propre clé. [Conseils de configuration du canal](https://meshtastic.org/docs/configuration/tips/)" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Most data on your mesh is sent over the primary channel. You can set up secondary channels to create additional messaging groups secured by their own key. [Channel config tips](https://meshtastic.org/docs/configuration/radio/channels/)" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Most data on your mesh is sent over the primary channel. You can set up secondary channels to create additional messaging groups secured by their own key. [Channel config tips](https://meshtastic.org/docs/configuration/radio/channels/)" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "A maioria dos dados na sua malha é enviada pelo canal principal. Você pode configurar canais secundários para criar grupos de mensagens adicionais protegidos por sua própria chave. [Channel config tips](https://meshtastic.org/docs/configuration/tips/)" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "De flesta data i ditt mesh-nätverk skickas över primärkanalen. Du kan ställa in sekundära kanaler för att skapa ytterligare meddelandegrupper skyddade av sin egen nyckel. Tips för kanalkonfiguration" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Већина података на вашој мрежи шаље се преко примарног канала. Можете подесити секундарне канале како бисте креирали додатне групе за размену порука, које су обезбеђене сопственим кључем. [Савети за конфигурацију канала](https://meshtastic.org/docs/configuration/tips/)" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mesh 网格上的大部分数据都通过主频道发送。您可以设置辅助频道以创建由其自身密钥保护的消息组。[频道配置提示](https://meshtastic.org/docs/configuration/tips/)" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "現在 Mesh 上的資料會通過主通道發送。您可以設定輔助通道來建立由自己的金鑰保護的其他訊息組 [頻道設定提示](https://meshtastic.org/docs/configuration/radio/channels/)" - } - } - } - }, - "tip.channels.create.title" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Kanäle verwalten" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Manage Channels" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gérer les canaux" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Manage Channels" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Manage Channels" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gerir Canais" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Hantera Kanaler" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Управљај каналима" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "管理频道" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "管理頻道" - } - } - } - }, - "tip.channels.share.message" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "In a Meshtastic LoRa Mesh there are up to 8 channels. The first one is the Primary channel where most activity happens and is required. If you don't share your primary channel your first shared channel becomes the primary channel on the other network. It talks on its primary and your secondary channel. A channel with the name 'admin' controls nodes remotely. Other channels are for private groups, each with its own key." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "A Meshtastic QR code contains the LoRa config and channel values needed for radios to communicate. You can share a complete channel configuration using the Replace Channels option, if you choose Add Channels your shared channels will be added to the channels on the receiving radio." - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Un code QR Meshtastic contient la configuration LoRa et les valeurs de canal nécessaires pour communiquer. La plupart des activités du maillage ont lieu sur le canal principal requis. Si vous ne partagez pas votre canal principal, votre premier canal partagé devient le canal principal de l’autre réseau. Les autres canaux sont pour les groupes privés, chacun avec sa propre clé." - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "במשטסטיק יש עד 8 ערוצים. הראשון הינו הראשי והינו היכן שרוב הפעילות מתבצעת והכרחי. אם לא תשתף את הערוץ הראשי שלך הערוץ הראשון שלך נהיה הערוץ הראשי ברשת השניה. הוא מדבר בערוץ הראשי שלו במשני שלך. ערוץ בעל השם 'admin' הינו לשליטה מרחוק. ערוצים נוספים הינם לקבוצות פרטיות, כל אחת עם מפתח הצפנה משלה." - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "In a Meshtastic LoRa Mesh there are up to 8 channels. The first one is the Primary channel where most activity happens and is required. If you don't share your primary channel your first shared channel becomes the primary channel on the other network. It talks on its primary and your secondary channel. A channel with the name 'admin' controls nodes remotely. Other channels are for private groups, each with its own key." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Um código QR Meshtastic contém a configuração LoRa e os valores do canal necessários para os rádios se comunicarem. Você pode compartilhar uma configuração completa do canal usando a opção Substituir Canais; se você escolher Adicionar Canais, seus canais compartilhados serão adicionados aos canais no rádio receptor." - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "En Meshtastic QR-kod innehåller LoRa-konfigurationen och kanalvärden som behövs för kommunikation. De flesta aktiviteter i mesh-nätverket sker på den obligatoriska primärkanalen. Om du inte delar din primärkanal blir din första delade kanal primärkanalen på det andra nätverket. Andra kanaler är för privata grupper, varje med sin egen nyckel." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "QR код за Мештастик садржи LoRA конфигурацију и вредности канала које су потребне радијима за комуникацију. Можете поделити потпуну конфигурацију канала користећи опцију „Замени канале“, а ако изаберете „Додај канале“, ваши делени канали ће бити додати каналима на примајућем радију." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "在 Meshtastic 网络中最多有 8 个频道。第一个频道是主频道,大多数活动都发生在这里,也是必需的。如果您不共享主频道,您的第一个共享频道就会成为其他网络的主频道。它会在其主频道和您的辅助频道上对话。名称为 admin 的频道可远程控制节点。其他频道用于私人群组,每个群组都有自己的密钥。" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "在 Meshtastic 網路中最多有 8 個頻道。第一個頻道是主頻道,大多數活動都發生在這裡,也是必需的。如果您不共享主頻道,您的第一個共享頻道就會成為其他網路的主頻道。它會在其主頻道和您的輔助頻道上對話。名稱為 admin 的頻道可遠端控制中繼點。其他頻道用於私人群组,每個群組都有自己的密鑰。" - } - } - } - }, - "tip.channels.share.title" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Meshtastic Kanäle teilen" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sharing Meshtastic Channels" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Partage des canaux Meshtastic" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "משתף ערוצי משטסטיק" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sharing Meshtastic Channels" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Compartilhando Canais Meshtastis" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dela Meshtastic-kanaler" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Дељење Мештастик канала" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "共享 Meshtastic 频道" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "共享 Meshtastic 頻道" - } - } - } - }, - "tip.messages.message" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Du kannst Kanalnachrichten (Gruppenchats) und Direktnachrichten senden und empfangen. Bei jeder Nachricht kannst du lange drücken, um verfügbare Aktionen wie Kopieren, Antworten, Tapback und Löschen sowie Zustelldetails anzuzeigen." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "You can send and receive channel (group chats) and direct messages. From any message you can long press to see available actions like copy, reply, tapback and delete as well as delivery details." - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Vous pouvez envoyer et recevoir des canaux (chats de groupe) et des messages directs. Depuis n’importe quel message, vous pouvez faire un appui long pour voir les actions possibles comme copier, répondre, tapback et supprimer ainsi que les détails de l'envoi." - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "ניתן לשלוח הודעות ערוץ (קבוצות צ'אט) והודעות פרטיות. על הודעה ניתן לעשות לחיצה ארוכה בכדי לראות פעולות אפשריות כגון העתק, הגב, תגובה מהירה, מחק ובנוסף לראות מצב שליחה." - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "You can send and receive channel (group chats) and direct messages. From any message you can long press to see available actions like copy, reply, tapback and delete as well as delivery details." - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Você pode enviar e receber mensagens de canal (conversas em grupo) e mensagens diretas. De qualquer mensagem, você pode pressionar por um longo período para ver ações disponíveis como copiar, responder, tapback e excluir, bem como detalhes de entrega." - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Du kan skicka och ta emot kanalmeddelanden (gruppchatt) och direkta meddelanden. Från alla meddelanden kan du långtrycka för att se tillgängliga åtgärder som kopiera, svara, tapback och radera samt leveransdetaljer." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Можете слати и примати поруке у каналима (групним четовима) и директне поруке. Из било које поруке можете дуго притиснути да бисте видели доступне радње као што су копирање, одговор, реакција и брисање, као и детаље о испоруци." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "您可以发送和接收群聊或私聊消息。在任何消息中,您都可以长按查看可用的操作,如复制、回复、拍一拍、删除以及投递详情。" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "您可以發送和接收1對1聊天和群聊。在任何訊息中,您都可以長按查看可用的操作,如複製、回復、拍一拍、刪除以及詳情。" - } - } - } - }, - "tip.messages.title" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nachrichten" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Messages" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Messages" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הודעות" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Messages" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mensagens" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Meddelanden" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Поруке" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "消息" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "消息" + "value" : "時序與格式" } } } }, "TLS Enabled" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "TLS abilitato" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -31142,17 +31799,44 @@ "state" : "translated", "value" : "启用 TLS" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "啟用 TLS" + } + } + } + }, + "To comply with privacy laws like CCPA and GDPR, we avoid sharing exact location data. Instead, we use anonymized or approximate (imprecise) location information to protect your privacy." : { + "localizations" : { + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "為遵守如 CCPA 和 GDPR 等隱私法規,我們避免分享精確的位置信息。取而代之,我們使用匿名化或近似(不精確)的位置資訊,以保護您的隱私。" + } } } }, "Topic: %@" : { - "extractionState" : "manual", "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Argomento: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Тема: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "主題: %@" + } } } }, @@ -31164,71 +31848,257 @@ "value" : "Total" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Totale" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Укупно" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "總共" + } + } + } + }, + "Total PAX" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Totale PAX" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Totalt PAX" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Укупно PAX" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "PAX 總數" + } } } }, "Trace Route" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Percorso di tracciamento" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Праћење руте" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "追蹤路由(Trace Route)" + } } } }, "Trace Route Log" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Registro del percorso di tracciamento" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Лог праћења руте комуникације" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "追蹤路由(Trace Route)紀錄" + } + } + } + }, + "Trace Route request returned: %@" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Traceroute Ergebnis: %@" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "La demande de Trace Route est revenue : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "בקשת בדיקת מסלול הצליחה: %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Traccia Richiesta di rotta restituita: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Żądanie śledzenia trasy zwrócone: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Spårruttförfrågan returnerade: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Захтев за тражење путања враћен: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trace Route request returned: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trace Route request returned: %@" + } } } }, "Trace Route Sent" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Traccia del percorso inviato" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Захтев за праћење руте комуникације послат." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "追蹤路由(Trace Route)已送出" + } } } }, "Trace route sent to %@" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Traccia del percorso inviato a %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Захтев за праћење руте комуникације послат до %@." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "追蹤路由(Trace Route)已送給 %@" + } } } }, "Trace route to %@ was not sent." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La rotta di tracciamento verso %@ non è stata inviata." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Захтев за праћење руте комуникације до %@ није послат." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "給 %@ 的追蹤路由(Trace Route)未送出。" + } } } }, "Trace Route was rate limited. You can send a trace route a maximum of once every thirty seconds." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La rotta di traccia era limitata dalla velocità. È possibile inviare una rotta di tracciamento al massimo una volta ogni trenta secondi." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Праћење руте комуникације је било ограничено по брзини. Можете послати захтев за праћење руте комуникације највише једном у сваких тридесет секунди." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "路由追蹤(Trace Route)已被限速。您每 30 秒最多只能發送一次路由追蹤請求。" + } + } + } + }, + "Tracker" : { + "localizations" : { + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Трекер" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "追踪器" + } } } }, @@ -31240,26 +32110,56 @@ "value" : "Verkehr" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Traffico" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Саобраћај" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "交通狀況" + } } } }, "Transmit data (txd) GPIO pin" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dati di trasmissione (txd) Pin GPIO" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "GPIO pin за трансмисију података (txd)" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "傳送資料(TXD)GPIO 腳位" + } } } }, "Transmit Enabled" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trasmissione abilitata" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -31271,11 +32171,23 @@ "state" : "translated", "value" : "启用传输" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "啟用傳輸" + } } } }, "Treat double tap on supported accelerometers as a user button press." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tratta il doppio tocco sugli accelerometri supportati come una pressione di un tasto utente." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -31287,26 +32199,56 @@ "state" : "translated", "value" : "将支持双击的加速度计视为按下用户按钮。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "將支援的加速度計上的雙擊視為使用者按下按鈕。" + } } } }, "TriggerType" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tipo di innesco" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Тип покретача" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "觸發類型" + } } } }, "Triple Click Ad Hoc Ping" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ping ad hoc a triplo clic" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Троструки клик за Ad Hoc пинг" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "按下三次傳送即時 Ping" + } } } }, @@ -31318,106 +32260,338 @@ "value" : "Erneut versuchen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Riprova" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Покушај поново" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "請再試一次" + } } } }, - "twitter" : { - "extractionState" : "manual", + "Twelve Hours" : { "localizations" : { "de" : { "stringUnit" : { "state" : "translated", - "value" : "Twitter" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Twitter" + "value" : "Zwölf Stunden" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Twitter" + "value" : "Douze heures" } }, "he" : { "stringUnit" : { "state" : "translated", - "value" : "טוויטר" + "value" : "שניים עשר שעות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dodici ore" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Twitter" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Twitter" + "value" : "Dwanaście Godzin" } }, "se" : { "stringUnit" : { "state" : "translated", - "value" : "Twitter" + "value" : "Tolv Timmar" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "X.com" + "value" : "Дванаест сати" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Twitter" + "value" : "十二小时" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Twitter" + "value" : "12 小時" + } + } + } + }, + "Twenty Four Hours" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vierundzwanzig Stunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vingt quatre heures" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "עשרים וארבע שעות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ventiquattro ore" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dwadzieścia Cztery Godziny" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tjugofyra Timmar" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Двадесет четири сата" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "二十四小时" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "24 小時" } } } }, "Two Hours" : { "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zwei Stunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Deux heures" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שעתיים" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Due ore" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dwie Godziny" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Två Timmar" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Два сата" } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "两小时" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "2 小時" + } + } + } + }, + "Two Minutes" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zwei Minutes" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Deux minutes" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שתי דקות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Due minuti" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dwie Minuty" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Två Minuter" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Два минута" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "两分钟" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "2 分鐘" + } + } + } + }, + "Two Seconds" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zwei Sekunden" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Deux secondes" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שתי שניות" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Due secondi" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dwie Sekundy" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Två Sekunder" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Две секунде" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "两秒" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "2 秒" + } } } }, "UDP Broadcast" : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "UDP емитовање" + "value" : "Trasmissione UDP" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "UDP 廣播" } } } }, - "Ukraine 433mhz" : { - "extractionState" : "manual", + "Ukraine 433MHz" : { "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Ukraine 433MHz" + "value" : "Ucraina 433MHz" } }, "sr" : { @@ -31425,16 +32599,21 @@ "state" : "translated", "value" : "Украјина 433MHz" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "烏克蘭 433MHz" + } } } }, - "Ukraine 868mhz" : { - "extractionState" : "manual", + "Ukraine 868MHz" : { "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Ukraine 868MHz" + "value" : "Ucraina 868MHz" } }, "sr" : { @@ -31442,26 +32621,87 @@ "state" : "translated", "value" : "Украјина 868MHz" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "烏克蘭 868MHz" + } } } }, "Un-Favorite" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Non preferito" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Уклони са фаворита" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "移除最愛" + } + } + } + }, + "Unhealthy" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Non sano" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Нездраво" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "不健康" + } + } + } + }, + "Unhealthy for Sensitive Groups" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Insalubre per i gruppi sensibili" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Нездраво за осетљиве групе" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "對敏感群體不健康" + } } } }, "United States" : { - "extractionState" : "manual", "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "United States" + "value" : "Stati Uniti" } }, "sr" : { @@ -31469,43 +32709,97 @@ "state" : "translated", "value" : "Сједињене Америчке државе" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "美國" + } } } }, "Units displayed on the device screen" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Unità visualizzate sullo schermo del dispositivo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Јединице приказане на екрану уређаја" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "裝置螢幕上顯示的單位" + } } } }, - "unknown" : { + "Universal Transverse Mercator" : { "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Universal Transversal Mercator" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Projection Mercator Transverse Universelle" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "Universal Transverse Mercator" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mercatore Universale Trasverso" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Uniwersalny Układ Transwersalny Mercatora" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Universal Transversal Mercator" + } + }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "непознато" + "value" : "Универзални трансверзални Меркаторов пројекат" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "通用横轴墨卡托投影" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "通用橫軸墨卡托投影" } } } }, "Unknown" : { "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Unknown" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Unknown" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -31518,18 +32812,18 @@ "value" : "לא ידוע" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sconosciuto" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Nieznany" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Desconhecido" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -31556,7 +32850,7 @@ } } }, - "unknown.age" : { + "Unknown Age" : { "localizations" : { "de" : { "stringUnit" : { @@ -31564,12 +32858,6 @@ "value" : "Unbekanntes alter" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Unknown Age" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -31582,18 +32870,18 @@ "value" : "גיל לא ידוע" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Età sconosciuta" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Nieznany wiek" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Idade Desconhecido" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -31620,7 +32908,7 @@ } } }, - "unset" : { + "Unset" : { "localizations" : { "de" : { "stringUnit" : { @@ -31628,12 +32916,6 @@ "value" : "Unset" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Unset" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -31646,18 +32928,18 @@ "value" : "לא נקבע" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Non impostato" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Nieustawiony" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Não Definido" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -31679,23 +32961,157 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "未設置" + "value" : "未設定" } } } }, "Unsupported" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Non supportato" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Није подржано" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "不支援" + } + } + } + }, + "Unsupported Firmware Version Detected, unable to connect to device." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nicht unterstützte Firmware Version erkannt. Kann nicht verbinden." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Version non supportée du firmware détectée, impossible de se connecter à l'appareil." + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "גרסת קושחה אינה נתמכת, לא ניתן להתחבר למכשיר." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rilevata versione firmware non supportata, impossibile connettersi al dispositivo." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wykryto nieobsługiwany wersję oprogramowania, brak możliwości połączenia z urządzeniem." + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Okänd Firmwareversion upptäckt, kan inte ansluta till enheten." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Откривена је неподржана верзија фирмвера, није могуће повезати са уређајем." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "检测到不支持的固件版本,无法连接到设备。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "檢測到不支援的韌體版本,無法連接到節點。" + } + } + } + }, + "Up" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hoch" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Haut" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "למעלה" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Su" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "W Górę" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Upp" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Горе" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "上" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "上" + } } } }, "Up Down 1" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Su Giù 1" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -31707,20 +33123,96 @@ "state" : "translated", "value" : "上下一次" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "上 下 1" + } + } + } + }, + "up to %@ away" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "bis zu %@ entfernt" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "up to %@ away" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "up to %@ away" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "fino a %@ di distanza" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "up to %@ away" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "upp till %@ bort" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "удаљено до максималних %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "最远距离 %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "距離%@以內" + } } } }, "Update Interval" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Intervallo di aggiornamento" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Интервал ажурирања" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "更新間隔" + } } } }, - "update.firmware" : { + "Update Your Firmware" : { "localizations" : { "de" : { "stringUnit" : { @@ -31728,12 +33220,6 @@ "value" : "Firmware aktualisieren" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Update Your Firmware" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -31746,18 +33232,18 @@ "value" : "עדכן קושחה" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aggiornare il firmware" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Zaktualizuj firmware" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Atualiza o Seu Firmware" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -31784,76 +33270,24 @@ } } }, - "update.interval" : { + "Updated Node Stats Data." : { "localizations" : { - "de" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Aktualisierungsintervall" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Update Interval" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Intervale de mise à jour" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "זמן בין עדכונים" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Interwał aktualizacji" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Intervalo de Atualização" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Uppdateringsintervall" + "value" : "Dati aggiornati sulle statistiche dei nodi." } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Интервал ажурирања" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "更新间隔" + "value" : "Ажурирани подаци о статистици чвора." } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "更新間隔" - } - } - } - }, - "Updated Node Stats Data." : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ажурирани подаци о статистици чвора." + "value" : "已更新的節點統計資料" } } } @@ -31866,16 +33300,34 @@ "value" : "Aktualisiert: %@" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aggiornato: %@" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Ажуриран: %@" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "已更新: %@" + } } } }, "Uplink Enabled" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Uplink abilitato" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -31887,27 +33339,21 @@ "state" : "translated", "value" : "启用上传" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "啟用上行(Uplink)" + } } } }, - "uptime" : { + "Uptime" : { "localizations" : { - "de" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Uptime" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Uptime" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tempo No Ár" + "value" : "Tempo di attività" } }, "se" : { @@ -31921,21 +33367,23 @@ "state" : "translated", "value" : "Време рада" } - } - } - }, - "Uptime" : { - "localizations" : { - "sr" : { + }, + "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Време рада" + "value" : "已開機時間" } } } }, "Use a PWM output (like the RAK Buzzer) for tunes instead of an on/off output. This will ignore the output, output duration and active settings and use the device config buzzer GPIO option instead." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Utilizzare un'uscita PWM (come il cicalino RAK) per le sintonie invece di un'uscita on/off. In questo modo si ignorano le impostazioni di uscita, durata e attivazione e si utilizza invece l'opzione GPIO del buzzer configurata dal dispositivo." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -31947,21 +33395,45 @@ "state" : "translated", "value" : "使用 PWM 输出(如 RAK 蜂鸣器)代替开/关输出进行调谐。这将忽略输出、输出持续时间和激活设置,而使用设备配置蜂鸣器 GPIO 选项。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "使用 PWM 輸出(如 RAK 蜂鳴器)來播放音樂,而非開/關輸出。這將忽略輸出、輸出持續時間和啟用設定,改為使用裝置配置中的蜂鳴器 GPIO 選項。" + } } } }, "Use I2S As Buzzer" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Utilizzare I2S come cicalino" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Користи I2S као звучник" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "使用 I2S 作為蜂鳴器" + } } } }, "Use Preset" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Utilizzare la preimpostazione" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -31973,11 +33445,23 @@ "state" : "translated", "value" : "使用预设" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "使用預設組態" + } } } }, "Use PWM Buzzer" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Utilizzare il cicalino PWM" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -31989,20 +33473,38 @@ "state" : "translated", "value" : "使用 PWM 蜂鸣器" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "使用 PWM 蜂鳴器" + } } } }, "Used to create a shared key with a remote device." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Si usa per creare una chiave condivisa con un dispositivo remoto." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Користи се за креирање заједничког кључа са удаљеним уређајем." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "用於與遠端裝置建立共用金鑰。" + } } } }, - "user" : { + "User" : { "localizations" : { "de" : { "stringUnit" : { @@ -32010,12 +33512,6 @@ "value" : "Benutzer" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "User" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -32028,18 +33524,18 @@ "value" : "משתמש" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Utente" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Użytkownik" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Utilizador" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -32068,6 +33564,12 @@ }, "User Config" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione utente" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -32079,101 +33581,21 @@ "state" : "translated", "value" : "用户配置" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "使用者設定" + } } } }, "User Details" : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Кориснички детаљи" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "用户信息" - } - } - } - }, - "User Id" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "ИД корисника" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "用户 ID" - } - } - } - }, - "User Initiated Disconnect" : { - "extractionState" : "manual", - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Корисник је покренуо прекид везе" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "用户主动断开连接" - } - } - } - }, - "user.details" : { - "extractionState" : "manual", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Benutzer Details" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "User Details" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Détails de l'utilisateur" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "פרטי משתמש" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Szczegóły użytkownika" - } - }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dados do Utilizador" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Användaruppgifter" + "value" : "Dettagli utente" } }, "sr" : { @@ -32191,23 +33613,155 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "使用者資料" + "value" : "使用者詳情" + } + } + } + }, + "User Id" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Id utente" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "ИД корисника" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "用户 ID" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "使用者 ID" + } + } + } + }, + "User Initiated Disconnect" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Disconnessione avviata dall'utente" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Корисник је покренуо прекид везе" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "用户主动断开连接" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "使用者主動斷線" + } + } + } + }, + "Username" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Benutzername" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nom d'utilisateur" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שם משתמש" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nome utente" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nazwa użytkownika" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Användarnamn" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Корисничко име" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "用户名称" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "使用者名稱" } } } }, "Uses pullup resistor" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Utilizza una resistenza di pullup" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Користи pull-up отпорник" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "使用上拉電阻" + } } } }, "Utilizes the network connection on your phone to connect to MQTT." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Utilizza la connessione di rete del telefono per connettersi a MQTT." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -32219,6 +33773,12 @@ "state" : "translated", "value" : "利用手机上的网络连接到 MQTT。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "透過手機的網路連線來連接至 MQTT 伺服器。" + } } } }, @@ -32230,11 +33790,23 @@ "value" : "Fahrzeugsteuerkurs" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Direzione del veicolo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Правац возила" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "載具朝向" + } } } }, @@ -32246,11 +33818,23 @@ "value" : "Fahrzeuggeschwindigkeit" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Velocità del veicolo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Брзина возила" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "載具速度" + } } } }, @@ -32258,10 +33842,16 @@ "localizations" : { "en" : { "stringUnit" : { - "state" : "new", + "state" : "translated", "value" : "Version %1$@ includes substantial network optimizations and extensive changes to devices and client apps. Only nodes version %2$@ and above are supported." } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La versione %1$@ include sostanziali ottimizzazioni di rete e modifiche estese ai dispositivi e alle applicazioni client. Sono supportati solo i nodi versione %2$@ e superiori." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -32273,10 +33863,26 @@ "state" : "translated", "value" : "版本 %1$@ 包括大量网络优化以及对设备和客户端应用程序的广泛更改。仅支持 %2$@ 及以上版本的节点。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "第 %1$@ 版本包含大量網路優化,以及對設備與用戶端應用程式的廣泛變更。僅支援版本為 %2$@ 或以上的節點。" + } } } }, - "Version: %@ (%@) " : { + "Version: %@ (%@)" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Version: %1$@ (%2$@)" + } + } + } + }, + "Version: %1$@ (%2$@)" : { "localizations" : { "de" : { "stringUnit" : { @@ -32284,10 +33890,10 @@ "value" : "Version: %1$@ (%2$@) " } }, - "en" : { + "it" : { "stringUnit" : { - "state" : "new", - "value" : "Version: %1$@ (%2$@) " + "state" : "translated", + "value" : "Versione: %1$@ (%2$@) " } }, "sr" : { @@ -32301,22 +33907,33 @@ "state" : "translated", "value" : "版本号: %1$@ (%2$@) " } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "版本: %1$@ (%2$@) " + } } } }, - "very.long.range.slow" : { - "extractionState" : "manual", + "Very Unhealthy" : { "localizations" : { - "en" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Very Long Range - Slow" + "value" : "Molto malsano" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Веома дугачки домет - Споро" + "value" : "Веома нездраво" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "非常不健康" } } } @@ -32329,11 +33946,23 @@ "value" : "Via Lora" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Via Lora" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Преко LoRA" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "經由 LoRa" + } } } }, @@ -32345,6 +33974,12 @@ "value" : "Via Mqtt" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Via Mqtt" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -32356,10 +33991,16 @@ "state" : "translated", "value" : "通过 MQTT" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "經由 Mqtt" + } } } }, - "voltage" : { + "Voltage" : { "localizations" : { "de" : { "stringUnit" : { @@ -32367,12 +34008,6 @@ "value" : "Voltage" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Voltage" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -32385,18 +34020,18 @@ "value" : "וולטז'" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tensione" + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Napięcie" } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tensão" - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -32423,22 +34058,18 @@ } } }, - "Voltage" : { - "localizations" : { - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Напон" - } - } - } - }, "Volts %@" : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Волти %@" + "value" : "Volt %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ V" } } } @@ -32451,12 +34082,6 @@ "value" : "Warte..." } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Waiting. . ." - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -32469,18 +34094,18 @@ "value" : "ממתין. . ." } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "In attesa. . ." + } + }, "pl" : { "stringUnit" : { "state" : "translated", "value" : "Czekam. . ." } }, - "pt-PT" : { - "stringUnit" : { - "state" : "translated", - "value" : "À Espara. . ." - } - }, "se" : { "stringUnit" : { "state" : "translated", @@ -32509,21 +34134,147 @@ }, "Waiting to be acknowledged. . ." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "In attesa di essere riconosciuti. . ." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Чека се на потврду пријема..." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "等待確認中⋯⋯" + } } } }, "Wake Screen on tap or motion" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Svegliare lo schermo al tocco o al movimento" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Пробуди екран додиром или покретом" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "輕觸或移動時喚醒螢幕" + } + } + } + }, + "walk" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "gehen" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "passeggiata" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "шетња" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "步行" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "走路" + } + } + } + }, + "Walking" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Gehen" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Camminare" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Шетња" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "步行" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "走路" + } + } + } + }, + "Wave" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Welle" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Onda" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vinka" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Махање" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "招手" + } } } }, @@ -32535,11 +34286,81 @@ "value" : "Wegpunktoptionen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Opzioni Waypoint" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Опције за тачке пута" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "路徑點選項" + } + } + } + }, + "Waypoint Packet received from node: %@" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wegpunkt von Knoten empfangen: %@" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Paquet Waypoint reçu du noeud : %@" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "נקודת ציון התקבלה מ-%@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pacchetto Waypoint ricevuto dal nodo: %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Odebrano pakiet punktu orientacyjnego od węzła: %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vägpunktspaket mottaget från nod: %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Пакет са тачкама пута примљен од чвора: %@" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Waypoint Packet received from node: %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Waypoint Packet received from node: %@" + } } } }, @@ -32551,6 +34372,12 @@ "value" : "Wetterverhältnisse" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Condizioni meteo" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -32562,21 +34389,45 @@ "state" : "translated", "value" : "天气状况" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "天氣狀況" + } } } }, "Web Flasher" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Lampeggiatore web" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Веб флашер" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "網頁刷機工具" + } } } }, "Website" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sito web" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -32588,15 +34439,27 @@ "state" : "translated", "value" : "网站" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "網站" + } } } }, "Weight" : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Тежина" + "value" : "Peso" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "重量" } } } @@ -32609,6 +34472,12 @@ "value" : "Was bedeutet das Schloß?" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Che cosa significa il lucchetto?" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -32620,6 +34489,12 @@ "state" : "translated", "value" : "锁意味着什么?" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "鎖頭圖示代表什麼意思?" + } } } }, @@ -32631,6 +34506,12 @@ "value" : "Was ist Meshtastic?" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Che cos'è Meshtastic?" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -32642,11 +34523,23 @@ "state" : "translated", "value" : "什么是 Meshtastic?" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "什麼是 Meshtastic?" + } } } }, "What licensed operator mode does:\n* Sets the node name to your call sign \n* Broadcasts node info every 10 minutes \n* Overrides frequency, dutycycle and tx power \n* Disables encryption" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cosa fa la modalità operatore con licenza:\n* Imposta il nome del nodo con il proprio nominativo\n* Trasmette informazioni sul nodo ogni 10 minuti\n* Sovrascrive la frequenza, il dutycycle e la potenza di trasmissione\n* Disabilita la crittografia" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -32658,11 +34551,63 @@ "state" : "translated", "value" : "业余无线电模式的作用:\n* 将节点名称设置为您的呼号 \n* 每 10 分钟广播一次节点信息 \n* 覆盖频率、占空比和发射功率 \n* 禁用加密" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "持照操作員模式的功能如下:\n* 將節點名稱自動設定為您的業餘無線電呼號\n* 每 10 分鐘定期廣播節點資訊(如位置、狀態等)\n* 自動覆蓋頻率、頻率使用時間限制及發射功率設定,符合當地業餘無線電規範\n* 關閉通訊加密功能,以符合透明通訊的法規要求" + } + } + } + }, + "When enabled the PAX Counter module counts the number of people passing by using WiFi and Bluetooth. Both WiFI and Bluetooth must be disabled for PAX counter to work." : { + "localizations" : { + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "When enabled the PAX Counter module counts the number of people passing by using WiFi and Bluetooth. Both WiFI and Bluetooth must be disabled for PAX counter to work." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quando è abilitato, il modulo PAX Counter conta il numero di persone che passano utilizzando il WiFi e il Bluetooth. Per il funzionamento del contatore PAX, sia il WiFI che il Bluetooth devono essere disattivati." + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "När aktiverad räknar PAX-räknarmodulen antalet personer som passerar med WiFi och Bluetooth. Både WiFi och Bluetooth måste vara aktiverade för att PAX-räknaren ska fungera." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Када је омогућен, модул бројача пролазника броји број људи који пролазе користећи ВајФај и Блутут. И ВајФај и Блутут морају бити онемогућени да би бројач пролазника радио." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用 PAX 计数器模块时,通过使用 WiFi 和蓝牙来计算经过的人数。为了使 PAX 计数器正常工作,必须将 WiFi 和蓝牙都禁用。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "啟用後,人流計數器模組將透過 WiFi 和藍牙計算經過的人數。必須停用 WiFi 和藍牙才能讓 PAX 計數器正常工作。" + } } } }, "When using in GPIO mode, keep the output on for this long. " : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quando si utilizza la modalità GPIO, mantenere l'uscita attiva per questo tempo. " + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -32674,16 +34619,62 @@ "state" : "translated", "value" : "在 GPIO 模式下使用时,请将输出保持接通这么长时间。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "在 GPIO 模式下,保持輸出啟用這麼長時間。" + } } } }, "Whether or not use INPUT_PULLUP mode for GPIO pin. Only applicable if the board uses pull-up resistors on the pin" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Utilizza o meno la modalità INPUT_PULLUP per il pin GPIO. Si applica solo se la scheda utilizza resistenze di pull-up sul pin" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Да ли се користи режим INPUT_PULLUP за GPIO пин. Примењује се само ако плоча користи pull-up отпорнике на пину." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "是否使用 INPUT_PULLUP 模式來設定 GPIO 腳位。僅在板子使用上拉電阻時適用。" + } + } + } + }, + "WiFi" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "WiFi" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "WiFi" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "ВајФај" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "WiFi" + } } } }, @@ -32695,20 +34686,84 @@ "value" : "WiFi Optionen" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Opzioni WiFi" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Опције вајфаја" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "WiFi 選項" + } + } + } + }, + "Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio. Don't use this setting if you want to use your device with the phone apps or are using a device without a user button." : { + "localizations" : { + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio. Don't use this setting if you want to use your device with the phone apps or are using a device without a user button." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sospenderà tutto il più possibile, per il ruolo di tracker e sensore questo includerà anche la radio lora. Non utilizzare questa impostazione se si desidera utilizzare il dispositivo con le applicazioni del telefono o se si utilizza un dispositivo senza pulsante utente." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio. Don't use this setting if you want to use your device with the phone apps or are using a device without a user button." + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sätter allt i viloläge så mycket som möjligt, för spårnings- och sensorläge kommer detta också inkludera LoRa-radion. Använd inte denna inställning om du vill använda din enhet med mobilappar eller använder en enhet utan en användarknapp." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Спаваће све што је више могуће, за улогу трагача и сензора ово ће укључивати и лора радио. Не користите ово подешавање ако желите да користите свој уређај са мобилним апликацијама или користите уређај без корисничког дугмета." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "尽可能让所有设备处于睡眠状态,对于跟踪器和传感器来说,这也包括 LoRa 无线电。如果您想将电台与手机 App 一起使用,或使用没有用户按钮的电台,请不要使用此设置。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "此設定會讓裝置盡可能休眠,包括 LoRa 無線電(用於 Tracker 和 Sensor 角色)。若您要搭配手機 App,或裝置沒有用戶按鈕,請不要使用此設定。" + } } } }, "Wind" : { "localizations" : { - "sr" : { + "it" : { "stringUnit" : { "state" : "translated", - "value" : "Ветар" + "value" : "Vento" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "風" } } } @@ -32721,11 +34776,23 @@ "value" : "Windrichtung" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Direzione del vento" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Правац ветра" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "風向" + } } } }, @@ -32737,21 +34804,79 @@ "value" : "Windgeschwindigkeit" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Velocità del vento" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Брзина ветра" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "風速" + } + } + } + }, + "Within %@" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Innerhalb %@" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Entro il %@" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inom %@" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "У кругу %@" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ 之內" + } } } }, "x" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "x" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "x" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "x" + } } } }, @@ -32759,7 +34884,13 @@ "localizations" : { "en" : { "stringUnit" : { - "state" : "new", + "state" : "translated", + "value" : "X: %1$@, Y: %2$d" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", "value" : "X: %1$@, Y: %2$d" } }, @@ -32774,14 +34905,27 @@ "state" : "translated", "value" : "X: %1$@, Y: %2$d" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "X: %1$@, Y: %2$d" + } } - } + }, + "shouldTranslate" : false }, "X: %@, Y: %f" : { "localizations" : { "en" : { "stringUnit" : { - "state" : "new", + "state" : "translated", + "value" : "X: %1$@, Y: %2$f" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", "value" : "X: %1$@, Y: %2$f" } }, @@ -32796,14 +34940,27 @@ "state" : "translated", "value" : "X: %1$@, Y: %2$f" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "X: %1$@, Y: %2$f" + } } - } + }, + "shouldTranslate" : false }, "X: %@, Y: %lld" : { "localizations" : { "en" : { "stringUnit" : { - "state" : "new", + "state" : "translated", + "value" : "X: %1$@, Y: %2$lld" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", "value" : "X: %1$@, Y: %2$lld" } }, @@ -32818,11 +34975,24 @@ "state" : "translated", "value" : "X: %1$@, Y: %2$lld" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "X: %1$@, Y: %2$lld" + } } - } + }, + "shouldTranslate" : false }, "y" : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "y" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -32834,6 +35004,12 @@ "state" : "translated", "value" : "y" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "y" + } } } }, @@ -32845,16 +35021,34 @@ "value" : "Gestern" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ieri" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Јуче" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "昨天" + } } } }, "You can also update your Meshtastic device over bluetooth using the Nordic DFU app." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "È anche possibile aggiornare il dispositivo Meshtastic tramite bluetooth utilizzando l'applicazione Nordic DFU." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -32866,11 +35060,81 @@ "state" : "translated", "value" : "您还可以使用 Nordic DFU 应用程序通过蓝牙更新 Meshtastic 设备。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "您亦可透過藍牙,使用 Nordic DFU 應用程式來更新您的 Meshtastic 裝置。" + } + } + } + }, + "You can send and receive channel (group chats) and direct messages. From any message you can long press to see available actions like copy, reply, tapback and delete as well as delivery details." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Du kannst Kanalnachrichten (Gruppenchats) und Direktnachrichten senden und empfangen. Bei jeder Nachricht kannst du lange drücken, um verfügbare Aktionen wie Kopieren, Antworten, Tapback und Löschen sowie Zustelldetails anzuzeigen." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vous pouvez envoyer et recevoir des canaux (chats de groupe) et des messages directs. Depuis n’importe quel message, vous pouvez faire un appui long pour voir les actions possibles comme copier, répondre, tapback et supprimer ainsi que les détails de l'envoi." + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "ניתן לשלוח הודעות ערוץ (קבוצות צ'אט) והודעות פרטיות. על הודעה ניתן לעשות לחיצה ארוכה בכדי לראות פעולות אפשריות כגון העתק, הגב, תגובה מהירה, מחק ובנוסף לראות מצב שליחה." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "È possibile inviare e ricevere messaggi di canale (chat di gruppo) e messaggi diretti. Da qualsiasi messaggio è possibile premere a lungo per visualizzare le azioni disponibili, come copia, risposta, tapback e cancellazione, nonché i dettagli di consegna." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "You can send and receive channel (group chats) and direct messages. From any message you can long press to see available actions like copy, reply, tapback and delete as well as delivery details." + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Du kan skicka och ta emot kanalmeddelanden (gruppchatt) och direkta meddelanden. Från alla meddelanden kan du långtrycka för att se tillgängliga åtgärder som kopiera, svara, tapback och radera samt leveransdetaljer." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Можете слати и примати поруке у каналима (групним четовима) и директне поруке. Из било које поруке можете дуго притиснути да бисте видели доступне радње као што су копирање, одговор, реакција и брисање, као и детаље о испоруци." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "您可以发送和接收群聊或私聊消息。在任何消息中,您都可以长按查看可用的操作,如复制、回复、拍一拍、删除以及投递详情。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "您可以傳送及接收頻道(群組聊天)和私人訊息。對任何訊息長按,可顯示操作選單,包括複製、回覆、表情回應、刪除及傳送詳情等功能。" + } } } }, "Your current location will be set as the fixed position and broadcast over the mesh on the position interval." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La posizione attuale viene impostata come posizione fissa e trasmessa sulla mesh nell'intervallo di posizione." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -32882,6 +35146,12 @@ "state" : "translated", "value" : "您当前的位置将被设置为固定位置,并以定位间隔向 Mesh 网络广播。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "您的目前位置將被設定為固定位置,並按照位置廣播間隔在Mesh網路中定期發送。" + } } } }, @@ -32893,6 +35163,12 @@ "value" : "Deine Firmware ist aktuell" } }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il firmware è aggiornato" + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -32904,31 +35180,77 @@ "state" : "translated", "value" : "你的固件已经是最新版本" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "您的韌體已是最新版本" + } } } }, "Your MQTT Server must support TLS." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il server MQTT deve supportare TLS." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Ваш MQTT сервер мора подржавати TLS." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "您所使用的 MQTT 伺服器需支援 TLS 加密傳輸。" + } + } + } + }, + "Your node will periodically send an unencrypted map report packet to the configured MQTT server, this includes id, short and long name, approximate location, hardware model, role, firmware version, LoRa region, modem preset and primary channel name." : { + "localizations" : { + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "您的節點將定期向配置的 MQTT 伺服器發送未加密的地圖報告封包,內容包括 ID、簡短名稱和完整名稱、大略位置、硬體型號、角色(Role)、韌體版本、LoRa 區域、Modem預設值以及主要頻道名稱。" + } } } }, "Your node’s operating frequency is calculated based on the region, modem preset, and this field. When 0, the slot is automatically calculated based on the primary channel name." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La frequenza operativa del nodo viene calcolata in base alla regione, alla preimpostazione del modem e a questo campo. Se il campo è 0, lo slot viene calcolato automaticamente in base al nome del canale primario." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Оперативна фреквенција вашег нода се израчунава на основу региона, модемског пресета и овог поља. Када је 0, слот се аутоматски израчунава на основу назива примарног канала." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "您的節點運作頻率是根據地區、數據機預設值,以及此欄位共同計算得出。當此欄位設為 0 時,系統會根據主要頻道名稱自動計算頻率槽位。" + } } } }, "Your position has been sent with a request for a response with their position. You will receive a notification when a position is returned." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La vostra posizione è stata inviata con una richiesta di risposta con la loro posizione. Riceverete una notifica quando la posizione verrà restituita." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -32940,11 +35262,23 @@ "state" : "translated", "value" : "您的位置已发送,并请求对方回复其位置。位置返回后,您将收到通知。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "您的位置已發送並附帶回傳位置的請求。當對方回傳其位置時,系統將通知您。" + } } } }, "Your region has a %lld%% duty cycle. MQTT is not advised when you are duty cycle restricted, the extra traffic will quickly overwhelm your LoRa mesh." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La vostra regione ha un ciclo di lavoro di %lld%%. MQTT è sconsigliato quando il ciclo di lavoro è limitato, perché il traffico extra sovraccaricherà rapidamente la rete LoRa." + } + }, "sr" : { "stringUnit" : { "state" : "translated", @@ -32956,26 +35290,56 @@ "state" : "translated", "value" : "您所在地区的占空比为 %lld%%。在占空比受限的情况下,不建议使用 MQTT,因为额外的流量会很快压垮您的 LoRa 网格。" } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "您所在地區的占空比限制為 %lld%%。在占空比受限的情況下,不建議啟用 MQTT,因為額外的通訊流量可能迅速造成您的 LoRa 網狀網路過載。" + } } } }, "Your region has a %lld%% hourly duty cycle, your radio will stop sending packets when it reaches the hourly limit." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La regione ha un ciclo di funzionamento orario del %lld%%; la radio smette di inviare pacchetti quando raggiunge il limite orario." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Ваш регион има %lld%% радни циклус по сату, ваш радио ће престати да шаље пакете када достигне ограничење по сату." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "您的地區每小時的頻率使用限制為 %lld%%,當無線電達到該上限時,將會停止傳送封包。" + } } } }, "Your route file must have both Latitude and Longitude columns and headers." : { "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il file di percorso deve avere entrambe le colonne Latitudine e Longitudine e le intestazioni." + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Ваша датотека руте мора имати колоне и заглавља и ширину и дужину." } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "您的路線檔案必須包含緯度(Latitude)與經度(Longitude)欄位及其標題。" + } } } } diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index 58e2baa5..403492d2 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -56,12 +56,12 @@ B399E8A42B6F486400E4488E /* RetryButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B399E8A32B6F486400E4488E /* RetryButton.swift */; }; B3E905B12B71F7F300654D07 /* TextMessageField.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3E905B02B71F7F300654D07 /* TextMessageField.swift */; }; BC47C2EF2CE0017D008245CA /* MessageNodeIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC47C2EE2CE0017D008245CA /* MessageNodeIntent.swift */; }; - BC5EBA3C2D002A2000C442FF /* MessageNodeIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC5EBA3B2D002A2000C442FF /* MessageNodeIntent.swift */; }; BC6B45FF2CB2F98900723CEB /* SaveChannelSettingsIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC6B45FE2CB2F98900723CEB /* SaveChannelSettingsIntent.swift */; }; BCB613812C67290800485544 /* SendWaypointIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCB613802C67290800485544 /* SendWaypointIntent.swift */; }; BCB613832C672A2600485544 /* MessageChannelIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCB613822C672A2600485544 /* MessageChannelIntent.swift */; }; BCB613852C68703800485544 /* NodePositionIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCB613842C68703800485544 /* NodePositionIntent.swift */; }; BCB613872C69A0FB00485544 /* AppIntentErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCB613862C69A0FB00485544 /* AppIntentErrors.swift */; }; + BCDDFA9A2DBB180D0065189C /* ScrollToBottomButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCDDFA992DBB180D0065189C /* ScrollToBottomButton.swift */; }; BCE2D3C32C7ADF42008E6199 /* ShutDownNodeIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCE2D3C22C7ADF42008E6199 /* ShutDownNodeIntent.swift */; }; BCE2D3C52C7AE369008E6199 /* RestartNodeIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCE2D3C42C7AE369008E6199 /* RestartNodeIntent.swift */; }; BCE2D3C72C7B0D0A008E6199 /* ShortcutsProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCE2D3C62C7B0D0A008E6199 /* ShortcutsProvider.swift */; }; @@ -145,7 +145,6 @@ DD8EBF43285058FA00426DCA /* DisplayConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8EBF42285058FA00426DCA /* DisplayConfig.swift */; }; DD8ED9C52898D51F00B3B0AB /* NetworkConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8ED9C42898D51F00B3B0AB /* NetworkConfig.swift */; }; DD8ED9C8289CE4B900B3B0AB /* RoutingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8ED9C7289CE4B900B3B0AB /* RoutingError.swift */; }; - DD90860E26F69BAE00DC5189 /* NodeMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD90860D26F69BAE00DC5189 /* NodeMap.swift */; }; DD913639270DFF4C00D7ACF3 /* LocalNotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD913638270DFF4C00D7ACF3 /* LocalNotificationManager.swift */; }; DD93800B2BA3F968008BEC06 /* NodeMapContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD93800A2BA3F968008BEC06 /* NodeMapContent.swift */; }; DD93800E2BA74D0C008BEC06 /* ChannelForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD93800D2BA74D0C008BEC06 /* ChannelForm.swift */; }; @@ -176,8 +175,6 @@ DDB6CCFB2AAF805100945AF6 /* NodeMapSwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB6CCFA2AAF805100945AF6 /* NodeMapSwiftUI.swift */; }; DDB75A0F2A05920E006ED576 /* FileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB75A0E2A05920E006ED576 /* FileManager.swift */; }; DDB75A112A059258006ED576 /* Url.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB75A102A059258006ED576 /* Url.swift */; }; - DDB75A142A0593E2006ED576 /* OfflineTileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB75A132A0593E2006ED576 /* OfflineTileManager.swift */; }; - DDB75A162A0594AD006ED576 /* TileOverlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB75A152A0594AD006ED576 /* TileOverlay.swift */; }; DDB75A1A2A05EB67006ED576 /* alpha.png in Resources */ = {isa = PBXBuildFile; fileRef = DDB75A192A05EB67006ED576 /* alpha.png */; }; DDB75A1E2A0B0CD0006ED576 /* LoRaSignalStrengthIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB75A1D2A0B0CD0006ED576 /* LoRaSignalStrengthIndicator.swift */; }; DDB75A212A12B954006ED576 /* LoRaSignalStrength.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB75A202A12B954006ED576 /* LoRaSignalStrength.swift */; }; @@ -326,6 +323,7 @@ BCB613822C672A2600485544 /* MessageChannelIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageChannelIntent.swift; sourceTree = ""; }; BCB613842C68703800485544 /* NodePositionIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodePositionIntent.swift; sourceTree = ""; }; BCB613862C69A0FB00485544 /* AppIntentErrors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppIntentErrors.swift; sourceTree = ""; }; + BCDDFA992DBB180D0065189C /* ScrollToBottomButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollToBottomButton.swift; sourceTree = ""; }; BCE2D3C22C7ADF42008E6199 /* ShutDownNodeIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShutDownNodeIntent.swift; sourceTree = ""; }; BCE2D3C42C7AE369008E6199 /* RestartNodeIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestartNodeIntent.swift; sourceTree = ""; }; BCE2D3C62C7B0D0A008E6199 /* ShortcutsProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutsProvider.swift; sourceTree = ""; }; @@ -437,7 +435,6 @@ DD8ED9C42898D51F00B3B0AB /* NetworkConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkConfig.swift; sourceTree = ""; }; DD8ED9C7289CE4B900B3B0AB /* RoutingError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoutingError.swift; sourceTree = ""; }; DD90860A26F645B700DC5189 /* Meshtastic.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Meshtastic.entitlements; sourceTree = ""; }; - DD90860D26F69BAE00DC5189 /* NodeMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeMap.swift; sourceTree = ""; }; DD913638270DFF4C00D7ACF3 /* LocalNotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalNotificationManager.swift; sourceTree = ""; }; DD93800A2BA3F968008BEC06 /* NodeMapContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeMapContent.swift; sourceTree = ""; }; DD93800D2BA74D0C008BEC06 /* ChannelForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelForm.swift; sourceTree = ""; }; @@ -475,8 +472,6 @@ DDB759E12A04B264006ED576 /* MeshtasticDataModelV12.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV12.xcdatamodel; sourceTree = ""; }; DDB75A0E2A05920E006ED576 /* FileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileManager.swift; sourceTree = ""; }; DDB75A102A059258006ED576 /* Url.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Url.swift; sourceTree = ""; }; - DDB75A132A0593E2006ED576 /* OfflineTileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfflineTileManager.swift; sourceTree = ""; }; - DDB75A152A0594AD006ED576 /* TileOverlay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileOverlay.swift; sourceTree = ""; }; DDB75A192A05EB67006ED576 /* alpha.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = alpha.png; sourceTree = ""; }; DDB75A1D2A0B0CD0006ED576 /* LoRaSignalStrengthIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoRaSignalStrengthIndicator.swift; sourceTree = ""; }; DDB75A1F2A10766D006ED576 /* MeshtasticDataModelV13.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV13.xcdatamodel; sourceTree = ""; }; @@ -733,7 +728,6 @@ DDDB263E2AABEE20003AFCB7 /* NodeList.swift */, DD769E0228D18BF0001A3F05 /* DeviceMetricsLog.swift */, DDAD49EC2AFB39DC00B4425D /* MeshMap.swift */, - DD90860D26F69BAE00DC5189 /* NodeMap.swift */, DD73FD1028750779000852D6 /* PositionLog.swift */, DD4F23CC28779A3C001D37CB /* EnvironmentMetricsLog.swift */, 6DEDA5592A957B8E00321D2E /* DetectionSensorLog.swift */, @@ -918,15 +912,6 @@ path = Map; sourceTree = ""; }; - DDB75A122A0593CD006ED576 /* Map */ = { - isa = PBXGroup; - children = ( - DDB75A132A0593E2006ED576 /* OfflineTileManager.swift */, - DDB75A152A0594AD006ED576 /* TileOverlay.swift */, - ); - path = Map; - sourceTree = ""; - }; DDC2E14B26CE248E0042C5E4 = { isa = PBXGroup; children = ( @@ -1064,7 +1049,6 @@ isa = PBXGroup; children = ( DDD43FE12A78C86B0083A3E9 /* Mqtt */, - DDB75A122A0593CD006ED576 /* Map */, DDAF8C5226EB1DF10058C060 /* BLEManager.swift */, DDC2E1A626CEB3400042C5E4 /* LocationHelper.swift */, DD913638270DFF4C00D7ACF3 /* LocalNotificationManager.swift */, @@ -1121,6 +1105,7 @@ DDDB26412AABF655003AFCB7 /* NodeListItem.swift */, DDDCD56F2BB26F5C00BE6B60 /* NodeListFilter.swift */, 251926882C3BAF2E00249DF5 /* Actions */, + BCDDFA992DBB180D0065189C /* ScrollToBottomButton.swift */, ); path = Helpers; sourceTree = ""; @@ -1251,7 +1236,7 @@ attributes = { BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 1540; - LastUpgradeCheck = 1600; + LastUpgradeCheck = 1630; TargetAttributes = { 25F5D5C62C4375A8008036E3 = { CreatedOnToolsVersion = 15.4; @@ -1278,10 +1263,9 @@ pl, he, fr, - "zh-Hant-TW", se, - "pt-PT", sr, + it, ); mainGroup = DDC2E14B26CE248E0042C5E4; packageReferences = ( @@ -1416,7 +1400,6 @@ DDC4D568275499A500A4208E /* Persistence.swift in Sources */, DDD6EEAF29BC024700383354 /* Firmware.swift in Sources */, DD77093B2AA1ABB8007A8BF0 /* BluetoothTips.swift in Sources */, - DD90860E26F69BAE00DC5189 /* NodeMap.swift in Sources */, D9C9839D2B79CFD700BDBE6A /* TextMessageSize.swift in Sources */, DDC94FCE29CF55310082EA6E /* RtttlConfig.swift in Sources */, DD964FBD296E6B01007C176F /* EmojiOnlyTextField.swift in Sources */, @@ -1446,7 +1429,6 @@ DDDB444229F8A88700EE2349 /* Double.swift in Sources */, DDF45C342BC1A48E005ED5F2 /* MQTTIcon.swift in Sources */, DDA9515A2BC6624100CEA535 /* TelemetryWeather.swift in Sources */, - DDB75A162A0594AD006ED576 /* TileOverlay.swift in Sources */, DD1BD0EB2C601795008C0C70 /* CLLocation.swift in Sources */, DDF924CA26FBB953009FE055 /* ConnectedDevice.swift in Sources */, DD3CC6BE28E4CD9800FA9159 /* BatteryGauge.swift in Sources */, @@ -1499,7 +1481,6 @@ 251926872C3BAE2200249DF5 /* NodeAlertsButton.swift in Sources */, DDA1C48E28DB49D3009933EC /* ChannelRoles.swift in Sources */, DDD5BB092C285DDC007E03CA /* AppLog.swift in Sources */, - BC5EBA3C2D002A2000C442FF /* MessageNodeIntent.swift in Sources */, DD8ED9C8289CE4B900B3B0AB /* RoutingError.swift in Sources */, 233E99C52D84A0B600CC3A77 /* CompactWidget.swift in Sources */, DDC1B81A2AB5377B00C71E39 /* MessagesTips.swift in Sources */, @@ -1521,7 +1502,6 @@ DD6F65762C6EA5490053C113 /* AckErrors.swift in Sources */, DDDB445029F8AC9C00EE2349 /* UIImage.swift in Sources */, DD86D40F2881BE4C00BAEB7A /* CsvDocument.swift in Sources */, - DDB75A142A0593E2006ED576 /* OfflineTileManager.swift in Sources */, DDB75A1E2A0B0CD0006ED576 /* LoRaSignalStrengthIndicator.swift in Sources */, DDA6B2E928419CF2003E8C16 /* MeshPackets.swift in Sources */, DDCE4E2C2869F92900BE9F8F /* UserConfig.swift in Sources */, @@ -1562,6 +1542,7 @@ DDA9515E2BC6F56F00CEA535 /* IndoorAirQuality.swift in Sources */, DDDB444E29F8AB0E00EE2349 /* Int.swift in Sources */, DD3CC6BC28E366DF00FA9159 /* Meshtastic.xcdatamodeld in Sources */, + BCDDFA9A2DBB180D0065189C /* ScrollToBottomButton.swift in Sources */, DDC4C9FF2A8D982900CE201C /* DetectionSensorConfig.swift in Sources */, 2344A2AF2D6697A700170A77 /* TelemetryEntity+CoreDataClass.swift in Sources */, 2344A2B02D6697A700170A77 /* TelemetryEntity+CoreDataProperties.swift in Sources */, @@ -1621,7 +1602,6 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; GENERATE_INFOPLIST_FILE = YES; @@ -1645,7 +1625,6 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = GCH7VS5Y9R; GCC_C_LANGUAGE_STANDARD = gnu17; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 17.0; @@ -1695,6 +1674,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; ENABLE_USER_SCRIPT_SANDBOXING = NO; @@ -1759,6 +1739,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_USER_SCRIPT_SANDBOXING = YES; @@ -1795,7 +1776,6 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"Meshtastic/Preview Content\""; - DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = Meshtastic/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Meshtastic; @@ -1805,7 +1785,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.5.22; + MARKETING_VERSION = 2.6.2; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -1829,7 +1809,6 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"Meshtastic/Preview Content\""; - DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = Meshtastic/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Meshtastic; @@ -1839,7 +1818,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.5.22; + MARKETING_VERSION = 2.6.2; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -1860,7 +1839,6 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = GCH7VS5Y9R; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Widgets/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Widgets; @@ -1871,7 +1849,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.5.22; + MARKETING_VERSION = 2.6.2; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1893,7 +1871,6 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = GCH7VS5Y9R; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Widgets/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Widgets; @@ -1904,7 +1881,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.5.22; + MARKETING_VERSION = 2.6.2; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/Meshtastic.xcodeproj/xcshareddata/xcschemes/Meshtastic.xcscheme b/Meshtastic.xcodeproj/xcshareddata/xcschemes/Meshtastic.xcscheme index 508a6cab..53ea5ca7 100644 --- a/Meshtastic.xcodeproj/xcshareddata/xcschemes/Meshtastic.xcscheme +++ b/Meshtastic.xcodeproj/xcshareddata/xcschemes/Meshtastic.xcscheme @@ -1,6 +1,6 @@ some IntentResult & ProvidesDialog { if !BLEManager.shared.isConnected { throw AppIntentErrors.AppIntentError.notConnected } - + let fetchNodeInfoRequest: NSFetchRequest = NSFetchRequest(entityName: "NodeInfoEntity") fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum)) - + do { guard let fetchedNode = try PersistenceController.shared.container.viewContext.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity], fetchedNode.count == 1 else { throw $nodeNum.needsValueError("Could not find node") } - + let nodeInfo = fetchedNode[0] if let latitude = nodeInfo.latestPosition?.coordinate.latitude, let longitude = nodeInfo.latestPosition?.coordinate.longitude { - + let url = URL(string: "maps://?saddr=&daddr=\(latitude),\(longitude)") - + if let mapURL = url, UIApplication.shared.canOpenURL(mapURL) { // Request to continue in foreground before opening the app try await requestToContinueInForeground() - + // Open Apple Maps for navigation UIApplication.shared.open(mapURL, options: [:], completionHandler: nil) return .result(dialog: "Navigating to node location.") diff --git a/Meshtastic/AppIntents/RestartNodeIntent.swift b/Meshtastic/AppIntents/RestartNodeIntent.swift index 7ae8095a..5f317a28 100644 --- a/Meshtastic/AppIntents/RestartNodeIntent.swift +++ b/Meshtastic/AppIntents/RestartNodeIntent.swift @@ -15,7 +15,7 @@ struct RestartNodeIntent: AppIntent { func perform() async throws -> some IntentResult { - try await requestConfirmation(result: .result(dialog: "Reboot Node?")) + try await requestConfirmation(result: .result(dialog: "Reboot node?")) if !BLEManager.shared.isConnected { throw AppIntentErrors.AppIntentError.notConnected diff --git a/Meshtastic/AppIntents/SaveChannelSettingsIntent.swift b/Meshtastic/AppIntents/SaveChannelSettingsIntent.swift index 902a66cc..095112ff 100644 --- a/Meshtastic/AppIntents/SaveChannelSettingsIntent.swift +++ b/Meshtastic/AppIntents/SaveChannelSettingsIntent.swift @@ -29,12 +29,9 @@ struct SaveChannelSettingsIntent: AppIntent { if channelUrl.absoluteString.lowercased().contains("meshtastic.org/e/#") { // Split the URL to get the portion after "#" let components = channelUrl.absoluteString.components(separatedBy: "#") - // Add channels flag based on the URL query parameter (if present) let addChannels = Bool(channelUrl["add"] ?? "false") ?? false - var channelSettings: String? - // Extract the Base64 encoded channel settings (after "#") if let lastComponent = components.last { channelSettings = lastComponent.components(separatedBy: "?").first // Ignore any query parameters @@ -44,7 +41,6 @@ struct SaveChannelSettingsIntent: AppIntent { if let channelSettings = channelSettings { // Call the BLEManager to save the channel settings let saveResult = BLEManager.shared.saveChannelSet(base64UrlString: channelSettings, addChannels: addChannels) - if !saveResult { throw AppIntentErrors.AppIntentError.message("Failed to save the channel settings.") } diff --git a/Meshtastic/Assets.xcassets/THINKNODEM1.imageset/Contents.json b/Meshtastic/Assets.xcassets/THINKNODEM1.imageset/Contents.json new file mode 100644 index 00000000..7001ca9b --- /dev/null +++ b/Meshtastic/Assets.xcassets/THINKNODEM1.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "thinknode_m1.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Meshtastic/Assets.xcassets/THINKNODEM1.imageset/thinknode_m1.svg b/Meshtastic/Assets.xcassets/THINKNODEM1.imageset/thinknode_m1.svg new file mode 100644 index 00000000..27e21a0b --- /dev/null +++ b/Meshtastic/Assets.xcassets/THINKNODEM1.imageset/thinknode_m1.svg @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Meshtastic/Assets.xcassets/THINKNODEM2.imageset/Contents.json b/Meshtastic/Assets.xcassets/THINKNODEM2.imageset/Contents.json new file mode 100644 index 00000000..81ee0ac1 --- /dev/null +++ b/Meshtastic/Assets.xcassets/THINKNODEM2.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "thinknode_m2.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Meshtastic/Assets.xcassets/THINKNODEM2.imageset/thinknode_m2.svg b/Meshtastic/Assets.xcassets/THINKNODEM2.imageset/thinknode_m2.svg new file mode 100644 index 00000000..5e5a0e3c --- /dev/null +++ b/Meshtastic/Assets.xcassets/THINKNODEM2.imageset/thinknode_m2.svg @@ -0,0 +1,391 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Meshtastic/Assets.xcassets/XIAONRF52KIT.imageset/Contents.json b/Meshtastic/Assets.xcassets/XIAONRF52KIT.imageset/Contents.json new file mode 100644 index 00000000..08990d2d --- /dev/null +++ b/Meshtastic/Assets.xcassets/XIAONRF52KIT.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "seeed_xiao_nrf52_kit.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Meshtastic/Assets.xcassets/XIAONRF52KIT.imageset/seeed_xiao_nrf52_kit.svg b/Meshtastic/Assets.xcassets/XIAONRF52KIT.imageset/seeed_xiao_nrf52_kit.svg new file mode 100644 index 00000000..95f7211b --- /dev/null +++ b/Meshtastic/Assets.xcassets/XIAONRF52KIT.imageset/seeed_xiao_nrf52_kit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Meshtastic/Enums/AppSettingsEnums.swift b/Meshtastic/Enums/AppSettingsEnums.swift index b12a10a6..8355c4b4 100644 --- a/Meshtastic/Enums/AppSettingsEnums.swift +++ b/Meshtastic/Enums/AppSettingsEnums.swift @@ -19,17 +19,17 @@ enum MeshMapTypes: Int, CaseIterable, Identifiable { var description: String { switch self { case .standard: - return "standard".localized + return "Standard".localized case .mutedStandard: - return "standard.muted".localized + return "Standard Muted".localized case .hybrid: - return "hybrid".localized + return "Hybrid".localized case .hybridFlyover: - return "hybrid.flyover".localized + return "Hybrid Flyover".localized case .satellite: - return "satellite".localized + return "Satellite".localized case .satelliteFlyover: - return "satellite.flyover".localized + return "Satellite Flyover".localized } } func MKMapTypeValue() -> MKMapType { @@ -66,7 +66,7 @@ enum MeshMapDistances: Double, CaseIterable, Identifiable { var id: Double { self.rawValue } var description: String { let distanceFormatter = MKDistanceFormatter() - return String.localizedStringWithFormat("nodelist.filter.distance %@".localized, distanceFormatter.string(fromDistance: Double(self.rawValue))) + return String.localizedStringWithFormat("up to %@ away".localized, distanceFormatter.string(fromDistance: Double(self.rawValue))) } } @@ -78,11 +78,11 @@ enum UserTrackingModes: Int, CaseIterable, Identifiable { var description: String { switch self { case .none: - return "map.usertrackingmode.none".localized + return "None".localized case .follow: - return "map.usertrackingmode.follow".localized + return "Follow".localized case .followWithHeading: - return "map.usertrackingmode.followwithheading".localized + return "Follow with heading".localized } } var icon: String { @@ -117,21 +117,21 @@ enum LocationUpdateInterval: Int, CaseIterable, Identifiable { var description: String { switch self { case .tenSeconds: - return "interval.ten.seconds".localized + return "Ten Seconds".localized case .fifteenSeconds: - return "interval.fifteen.seconds".localized + return "Fifteen Seconds".localized case .thirtySeconds: - return "interval.thirty.seconds".localized + return "Thirty Seconds".localized case .fortyFiveSeconds: - return "interval.fortyfive.seconds".localized + return "Forty Five Seconds".localized case .oneMinute: - return "interval.one.minute".localized + return "One Minute".localized case .fiveMinutes: - return "interval.five.minutes".localized + return "Five Minutes".localized case .tenMinutes: - return "interval.ten.minutes".localized + return "Ten Minutes".localized case .fifteenMinutes: - return "interval.fifteen.minutes".localized + return "Fifteen Minutes".localized } } } diff --git a/Meshtastic/Enums/CannedMessagesConfigEnums.swift b/Meshtastic/Enums/CannedMessagesConfigEnums.swift index f197eced..d08829bc 100644 --- a/Meshtastic/Enums/CannedMessagesConfigEnums.swift +++ b/Meshtastic/Enums/CannedMessagesConfigEnums.swift @@ -19,11 +19,11 @@ enum ConfigPresets: Int, CaseIterable, Identifiable { switch self { case .unset: - return "canned.messages.preset.manual".localized + return "Manual Configuration".localized case .rakRotaryEncoder: - return "canned.messages.preset.rakrotary".localized + return "RAK Rotary Encoder".localized case .cardKB: - return "canned.messages.preset.cardkb".localized + return "M5 Stack Card KB / RAK Keypad".localized } } } @@ -45,21 +45,21 @@ enum InputEventChars: Int, CaseIterable, Identifiable { switch self { case .none: - return "inputevent.none".localized + return "None".localized case .up: - return "inputevent.up".localized + return "Up".localized case .down: - return "inputevent.down".localized + return "Down".localized case .left: - return "inputevent.left".localized + return "Left".localized case .right: - return "inputevent.right".localized + return "Right".localized case .select: - return "inputevent.select".localized + return "Select".localized case .back: - return "inputevent.back".localized + return "Back".localized case .cancel: - return "inputevent.cancel".localized + return "Cancel".localized } } func protoEnumValue() -> ModuleConfig.CannedMessageConfig.InputEventChar { diff --git a/Meshtastic/Enums/ChannelRoles.swift b/Meshtastic/Enums/ChannelRoles.swift index 186cff0b..ea1c0e8b 100644 --- a/Meshtastic/Enums/ChannelRoles.swift +++ b/Meshtastic/Enums/ChannelRoles.swift @@ -19,11 +19,11 @@ enum ChannelRoles: Int, CaseIterable, Identifiable { switch self { case .disabled: - return "channel.role.disabled".localized + return "Disabled".localized case .primary: - return "channel.role.primary".localized + return "Primary".localized case .secondary: - return "channel.role.secondary".localized + return "Secondary".localized } } func protoEnumValue() -> Channel.Role { diff --git a/Meshtastic/Enums/DeviceEnums.swift b/Meshtastic/Enums/DeviceEnums.swift index 4e0bdf27..a859fc20 100644 --- a/Meshtastic/Enums/DeviceEnums.swift +++ b/Meshtastic/Enums/DeviceEnums.swift @@ -21,65 +21,60 @@ enum DeviceRoles: Int, CaseIterable, Identifiable { case takTracker = 10 case repeater = 4 case router = 2 - case routerClient = 3 case routerLate = 11 var id: Int { self.rawValue } var name: String { switch self { case .client: - return "device.role.name.client".localized + return "Client".localized case .clientMute: - return "device.role.name.clientMute".localized + return "Client Mute".localized case .router: - return "device.role.name.router".localized - case .routerClient: - return "device.role.name.routerClient".localized + return "Router".localized case .repeater: - return "device.role.name.repeater".localized + return "Repeater".localized case .tracker: - return "device.role.name.tracker".localized + return "Tracker".localized case .sensor: - return "device.role.name.sensor".localized + return "Sensor".localized case .tak: - return "device.role.name.tak".localized + return "TAK".localized case .takTracker: - return "device.role.name.takTracker".localized + return "TAK Tracker".localized case .clientHidden: - return "device.role.name.clientHidden".localized + return "Client Hidden".localized case .lostAndFound: - return "device.role.name.lostAndFound".localized + return "Lost and Found".localized case .routerLate: - return "device.role.name.routerlate".localized + return "Router Late".localized } } var description: String { switch self { case .client: - return "device.role.client".localized + return "App connected or stand alone messaging device.".localized case .clientMute: - return "device.role.clientmute".localized + return "Device that does not forward packets from other devices.".localized case .router: - return "device.role.router".localized - case .routerClient: - return "device.role.routerclient".localized + return "Infrastructure node on a tower or mountain top only. Not to be used for roofs or mobile nodes. Needs exceptional coverage. Visible in Nodes list.".localized case .repeater: - return "device.role.repeater".localized + return "Infrastructure node on a tower or mountain top only. Not to be used for roofs or mobile nodes. Relays messages with minimal overhead. Not visible in Nodes list.".localized case .tracker: - return "device.role.tracker".localized + return "Broadcasts GPS position packets as priority.".localized case .sensor: - return "device.role.sensor".localized + return "Broadcasts telemetry packets as priority.".localized case .tak: - return "device.role.tak".localized + return "Optimized for ATAK system communication, reduces routine broadcasts.".localized case .takTracker: - return "device.role.taktracker".localized + return "Enables automatic TAK PLI broadcasts and reduces routine broadcasts.".localized case .clientHidden: - return "device.role.clienthidden".localized + return "Device that only broadcasts as needed for stealth or power savings.".localized case .lostAndFound: - return "device.role.lostandfound".localized + return "Broadcasts location as message to default channel regularly for to assist with device recovery.".localized case .routerLate: - return "device.role.routerlate".localized + return "Infrastructure node that always rebroadcasts packets once but only after all other modes, ensuring additional coverage for local clusters. Visible in Nodes list.".localized } } @@ -89,7 +84,7 @@ enum DeviceRoles: Int, CaseIterable, Identifiable { return "apps.iphone" case .clientMute: return "speaker.slash" - case .router, .routerClient, .routerLate: + case .router, .routerLate: return "wifi.router" case .repeater: return "repeat" @@ -116,8 +111,6 @@ enum DeviceRoles: Int, CaseIterable, Identifiable { return Config.DeviceConfig.Role.clientMute case .router: return Config.DeviceConfig.Role.router - case .routerClient: - return Config.DeviceConfig.Role.routerClient case .repeater: return Config.DeviceConfig.Role.repeater case .tracker: @@ -144,36 +137,41 @@ enum RebroadcastModes: Int, CaseIterable, Identifiable { case allSkipDecoding = 1 case localOnly = 2 case knownOnly = 3 - case corePortnums = 4 + case none = 4 + case corePortnums = 5 var id: Int { self.rawValue } var name: String { switch self { case .all: - return "All" + return "All".localized case .allSkipDecoding: - return "All Skip Decoding" + return "All Skip Decoding".localized case .localOnly: - return "Local Only" + return "Local Only".localized case .knownOnly: - return "Known Only" + return "Known Only".localized + case .none: + return "None".localized case .corePortnums: - return "Core Portnums Only" + return "Core Portnums Only".localized } } var description: String { switch self { case .all: - return "Rebroadcast any observed message, if it was on our private channel or from another mesh with the same lora params." + return "Rebroadcast any observed message, if it was on our private channel or from another mesh with the same lora params.".localized case .allSkipDecoding: - return "Same as behavior as ALL but skips packet decoding and simply rebroadcasts them. Only available in Repeater role. Setting this on any other roles will result in ALL behavior." + return "Same as behavior as ALL but skips packet decoding and simply rebroadcasts them. Only available in Repeater role. Setting this on any other roles will result in ALL behavior.".localized case .localOnly: - return "Ignores observed messages from foreign meshes that are open or those which it cannot decrypt. Only rebroadcasts message on the nodes local primary / secondary channels." + return "Ignores observed messages from foreign meshes that are open or those which it cannot decrypt. Only rebroadcasts message on the nodes local primary / secondary channels.".localized case .knownOnly: - return "Ignores observed messages from foreign meshes like Local Only, but takes it step further by also ignoring messages from nodes not already in the node's known list." + return "Ignores observed messages from foreign meshes like Local Only, but takes it step further by also ignoring messages from nodes not already in the node's known list.".localized + case .none: + return "Only permitted for SENSOR, TRACKER and TAK_TRACKER roles, this will inhibit all rebroadcasts, not unlike CLIENT_MUTE role.".localized case .corePortnums: - return "Only rebroadcasts packets from the core portnums: NodeInfo, Text, Position, Telemetry, and Routing." + return "Only rebroadcasts packets from the core portnums: NodeInfo, Text, Position, Telemetry, and Routing.".localized } } func protoEnumValue() -> Config.DeviceConfig.RebroadcastMode { @@ -187,6 +185,8 @@ enum RebroadcastModes: Int, CaseIterable, Identifiable { return Config.DeviceConfig.RebroadcastMode.localOnly case .knownOnly: return Config.DeviceConfig.RebroadcastMode.knownOnly + case .none: + return Config.DeviceConfig.RebroadcastMode.none case .corePortnums: return Config.DeviceConfig.RebroadcastMode.corePortnumsOnly } diff --git a/Meshtastic/Enums/DisplayEnums.swift b/Meshtastic/Enums/DisplayEnums.swift index 25753f02..664d72a5 100644 --- a/Meshtastic/Enums/DisplayEnums.swift +++ b/Meshtastic/Enums/DisplayEnums.swift @@ -49,21 +49,21 @@ enum ScreenOnIntervals: Int, CaseIterable, Identifiable { var description: String { switch self { case .fifteenSeconds: - return "interval.fifteen.seconds".localized + return "Fifteen Seconds".localized case .thirtySeconds: - return "interval.thirty.seconds".localized + return "Thirty Seconds".localized case .oneMinute: - return "interval.one.minute".localized + return "One Minute".localized case .fiveMinutes: - return "interval.five.minutes".localized + return "Five Minutes".localized case .tenMinutes: - return "interval.ten.minutes".localized + return "Ten Minutes".localized case .fifteenMinutes: - return "interval.fifteen.minutes".localized + return "Fifteen Minutes".localized case .thirtyMinutes: - return "interval.thirty.minutes".localized + return "Thirty Minutes".localized case .oneHour: - return "interval.one.hour".localized + return "One Hour".localized case .max: return "Always On".localized } @@ -87,17 +87,17 @@ enum ScreenCarouselIntervals: Int, CaseIterable, Identifiable { case .off: return "off".localized case .fifteenSeconds: - return "interval.fifteen.seconds".localized + return "Fifteen Seconds".localized case .thirtySeconds: - return "interval.thirty.seconds".localized + return "Thirty Seconds".localized case .oneMinute: - return "interval.one.minute".localized + return "One Minute".localized case .fiveMinutes: - return "interval.five.minutes".localized + return "Five Minutes".localized case .tenMinutes: - return "interval.ten.minutes".localized + return "Ten Minutes".localized case .fifteenMinutes: - return "interval.fifteen.minutes".localized + return "Fifteen Minutes".localized } } } @@ -149,13 +149,13 @@ enum DisplayModes: Int, CaseIterable, Identifiable { var description: String { switch self { case .defaultMode: - return "default.128x64.screen.layout".localized + return "Default 128x64 screen layout".localized case .twoColor: - return "optimized.for.2.color.displays".localized + return "Optimized for 2 color displays".localized case .inverted: - return "inverted.top.bar.for.2.color.display".localized + return "Inverted top bar for 2 Color display".localized case .color: - return "tft.full.color.displays".localized + return "TFT Full Color Displays".localized } } func protoEnumValue() -> Config.DisplayConfig.DisplayMode { diff --git a/Meshtastic/Enums/IntervalEnums.swift b/Meshtastic/Enums/IntervalEnums.swift index 0f967f28..a0513ad0 100644 --- a/Meshtastic/Enums/IntervalEnums.swift +++ b/Meshtastic/Enums/IntervalEnums.swift @@ -22,21 +22,21 @@ enum NagIntervals: Int, CaseIterable, Identifiable { var description: String { switch self { case .unset: - return "unset".localized + return "Unset".localized case .oneSecond: - return "interval.one.second".localized + return "One Second".localized case .fiveSeconds: - return "interval.five.seconds".localized + return "Five Seconds".localized case .tenSeconds: - return "interval.ten.seconds".localized + return "Ten Seconds".localized case .fifteenSeconds: - return "interval.fifteen.seconds".localized + return "Fifteen Seconds".localized case .thirtySeconds: - return "interval.thirty.seconds".localized + return "Thirty Seconds".localized case .oneMinute: - return "interval.one.minute".localized + return "One Minute".localized case .fiveMinutes: - return "interval.five.minutes".localized + return "Five Minutes".localized } } } @@ -59,25 +59,25 @@ enum OutputIntervals: Int, CaseIterable, Identifiable { switch self { case .unset: - return "unset".localized + return "Unset".localized case .oneSecond: - return "interval.one.second".localized + return "One Second".localized case .twoSeconds: - return "interval.two.seconds".localized + return "Two Seconds".localized case .threeSeconds: - return "interval.three.seconds".localized + return "Three Seconds".localized case .fourSeconds: - return "interval.four.seconds".localized + return "Four Seconds".localized case .fiveSeconds: - return "interval.five.seconds".localized + return "Five Seconds".localized case .tenSeconds: - return "interval.ten.seconds".localized + return "Ten Seconds".localized case .fifteenSeconds: - return "interval.fifteen.seconds".localized + return "Fifteen Seconds".localized case .thirtySeconds: - return "interval.thirty.seconds".localized + return "Thirty Seconds".localized case .oneMinute: - return "interval.one.minute".localized + return "One Minute".localized } } } @@ -100,25 +100,25 @@ enum SenderIntervals: Int, CaseIterable, Identifiable { var description: String { switch self { case .off: - return "off".localized + return "Off".localized case .fifteenSeconds: - return "interval.fifteen.seconds".localized + return "Fifteen Seconds".localized case .thirtySeconds: - return "interval.thirty.seconds".localized + return "Thirty Seconds".localized case .fortyFiveSeconds: - return "interval.fortyfive.seconds".localized + return "Forty Five Seconds".localized case .oneMinute: - return "interval.one.minute".localized + return "One Minute".localized case .fiveMinutes: - return "interval.five.minutes".localized + return "Five Minutes".localized case .tenMinutes: - return "interval.ten.minutes".localized + return "Ten Minutes".localized case .fifteenMinutes: - return "interval.fifteen.minutes".localized + return "Fifteen Minutes".localized case .thirtyMinutes: - return "interval.thirty.minutes".localized + return "Thirty Minutes".localized case .oneHour: - return "interval.one.hour".localized + return "One Hour".localized } } } @@ -153,49 +153,49 @@ enum UpdateIntervals: Int, CaseIterable, Identifiable { switch self { case .tenSeconds: - return "interval.ten.seconds".localized + return "Ten Seconds".localized case .fifteenSeconds: - return "interval.fifteen.seconds".localized + return "Fifteen Seconds".localized case .thirtySeconds: - return "interval.thirty.seconds".localized + return "Thirty Seconds".localized case .fortyFiveSeconds: - return "interval.fortyfive.seconds".localized + return "Forty Five Seconds".localized case .oneMinute: - return "interval.one.minute".localized + return "One Minute".localized case .twoMinutes: - return "interval.two.minutes".localized + return "Two Minutes".localized case .fiveMinutes: - return "interval.five.minutes".localized + return "Five Minutes".localized case .tenMinutes: - return "interval.ten.minutes".localized + return "Ten Minutes".localized case .fifteenMinutes: - return "interval.fifteen.minutes".localized + return "Fifteen Minutes".localized case .thirtyMinutes: - return "interval.thirty.minutes".localized + return "Thirty Minutes".localized case .oneHour: - return "interval.one.hour".localized + return "One Hour".localized case .twoHours: - return "interval.two.hours".localized + return "Two Hours".localized case .threeHours: - return "interval.three.hours".localized + return "Three Hours".localized case .fourHours: - return "interval.four.hours".localized + return "Four Hours".localized case .fiveHours: - return "interval.five.hours".localized + return "Five Hours".localized case .sixHours: - return "interval.six.hours".localized + return "Six Hours".localized case .twelveHours: - return "interval.twelve.hours".localized + return "Twelve Hours".localized case .eighteenHours: - return "interval.eighteen.hours".localized + return "Eighteen Hours".localized case .twentyFourHours: - return "interval.twentyfour.hours".localized + return "Twenty Four Hours".localized case .thirtySixHours: - return "interval.thirtysix.hours".localized + return "Thirty Six Hours".localized case .fortyeightHours: - return "interval.fortyeight.hours".localized + return "Forty Eight Hours".localized case .seventyTwoHours: - return "interval.seventytwo.hours".localized + return "Seventy Two Hours".localized } } } diff --git a/Meshtastic/Enums/LoraConfigEnums.swift b/Meshtastic/Enums/LoraConfigEnums.swift index e6cd4dae..c6dc7628 100644 --- a/Meshtastic/Enums/LoraConfigEnums.swift +++ b/Meshtastic/Enums/LoraConfigEnums.swift @@ -105,27 +105,27 @@ enum RegionCodes: Int, CaseIterable, Identifiable { case .in: return "India".localized case .nz865: - return "New Zealand 865mhz".localized + return "New Zealand 865MHz".localized case .th: return "Thailand".localized case .ua433: - return "Ukraine 433mhz".localized + return "Ukraine 433MHz".localized case .ua868: - return "Ukraine 868mhz".localized + return "Ukraine 868MHz".localized case .lora24: return "2.4 Ghz".localized case .my433: - return "Malaysia 433mhz".localized + return "Malaysia 433MHz".localized case .my919: - return "Malaysia 919mhz".localized + return "Malaysia 919MHz".localized case .sg923: - return "Singapore 923mhz".localized + return "Singapore 923MHz".localized case .ph433: - return "Philippines 433mhz".localized + return "Philippines 433MHz".localized case .ph868: - return "Philippines 868mhz".localized + return "Philippines 868MHz".localized case .ph915: - return "Philippines 915mhz".localized + return "Philippines 915MHz".localized } } var dutyCycle: Int { @@ -280,7 +280,6 @@ enum ModemPresets: Int, CaseIterable, Identifiable { case longFast = 0 case longSlow = 1 case longModerate = 7 - case vLongSlow = 2 case medSlow = 3 case medFast = 4 case shortSlow = 5 @@ -291,23 +290,21 @@ enum ModemPresets: Int, CaseIterable, Identifiable { var description: String { switch self { case .longFast: - return "long.range.fast".localized + return "Long Range - Fast".localized case .longSlow: - return "long.range.slow".localized + return "Long Range - Slow".localized case .longModerate: - return "long.range.moderate".localized - case .vLongSlow: - return "very.long.range.slow".localized + return "Long Range - Moderate".localized case .medSlow: - return "medium.range.slow".localized + return "Medium Range - Slow".localized case .medFast: - return "medium.range.fast".localized + return "Medium Range - Fast".localized case .shortSlow: - return "short.range.slow".localized + return "Short Range - Slow".localized case .shortFast: - return "short.range.fast".localized + return "Short Range - Fast".localized case .shortTurbo: - return "short.range.turbo".localized + return "Short Range - Turbo".localized } } var name: String { @@ -318,8 +315,6 @@ enum ModemPresets: Int, CaseIterable, Identifiable { return "LongSlow" case .longModerate: return "LongModerate" - case .vLongSlow: - return "VLongFast" case .medSlow: return "MediumSlow" case .medFast: @@ -340,8 +335,6 @@ enum ModemPresets: Int, CaseIterable, Identifiable { return -7.5 case .longModerate: return -17.5 - case .vLongSlow: - return -20 case .medSlow: return -15 case .medFast: @@ -362,8 +355,6 @@ enum ModemPresets: Int, CaseIterable, Identifiable { return Config.LoRaConfig.ModemPreset.longSlow case .longModerate: return Config.LoRaConfig.ModemPreset.longModerate - case .vLongSlow: - return Config.LoRaConfig.ModemPreset.veryLongSlow case .medSlow: return Config.LoRaConfig.ModemPreset.mediumSlow case .medFast: diff --git a/Meshtastic/Enums/MessagingEnums.swift b/Meshtastic/Enums/MessagingEnums.swift index 193060fa..29f84eac 100644 --- a/Meshtastic/Enums/MessagingEnums.swift +++ b/Meshtastic/Enums/MessagingEnums.swift @@ -46,21 +46,21 @@ enum Tapbacks: Int, CaseIterable, Identifiable { var description: String { switch self { case .wave: - return "tapback.wave".localized + return "Wave".localized case .heart: - return "tapback.heart".localized + return "Heart".localized case .thumbsUp: - return "tapback.thumbsup".localized + return "Thumbs Up".localized case .thumbsDown: - return "tapback.thumbsdown".localized + return "Thumbs Down".localized case .haHa: - return "tapback.haha".localized + return "HaHa".localized case .exclamation: - return "tapback.exclamation".localized + return "Exclamation".localized case .question: - return "tapback.question".localized + return "Question".localized case .poop: - return "tapback.poop".localized + return "Poop".localized } } } diff --git a/Meshtastic/Enums/PositionConfigEnums.swift b/Meshtastic/Enums/PositionConfigEnums.swift index 4853d050..24607df3 100644 --- a/Meshtastic/Enums/PositionConfigEnums.swift +++ b/Meshtastic/Enums/PositionConfigEnums.swift @@ -21,17 +21,17 @@ enum GpsFormats: Int, CaseIterable, Identifiable { var description: String { switch self { case .gpsFormatDec: - return "gpsformat.dec".localized + return "Decimal Degrees Format".localized case .gpsFormatDms: - return "gpsformat.dms".localized + return "Degrees Minutes Seconds".localized case .gpsFormatUtm: - return "gpsformat.utm".localized + return "Universal Transverse Mercator".localized case .gpsFormatMgrs: - return "gpsformat.mgrs".localized + return "Military Grid Reference System".localized case .gpsFormatOlc: - return "gpsformat.olc".localized + return "Open Location Code (aka Plus Codes)".localized case .gpsFormatOsgr: - return "gpsformat.osgr".localized + return "Ordnance Survey Grid Reference".localized } } func protoEnumValue() -> Config.DisplayConfig.GpsCoordinateFormat { @@ -73,29 +73,29 @@ enum GpsUpdateIntervals: Int, CaseIterable, Identifiable { var description: String { switch self { case .thirtySeconds: - return "interval.thirty.seconds".localized + return "Thirty Seconds".localized case .oneMinute: - return "interval.one.minute".localized + return "One Minute".localized case .twoMinutes: - return "interval.two.minutes".localized + return "Two Minutes".localized case .fiveMinutes: - return "interval.five.minutes".localized + return "Five Minutes".localized case .tenMinutes: - return "interval.ten.minutes".localized + return "Ten Minutes".localized case .fifteenMinutes: - return "interval.fifteen.minutes".localized + return "Fifteen Minutes".localized case .thirtyMinutes: - return "interval.thirty.minutes".localized + return "Thirty Minutes".localized case .oneHour: - return "interval.one.hour".localized + return "One Hour".localized case .sixHours: - return "interval.six.hours".localized + return "Six Hours".localized case .twelveHours: - return "interval.twelve.hours".localized + return "Twelve Hours".localized case .twentyFourHours: - return "interval.twentyfour.hours".localized + return "Twenty Four Hours".localized case .maxInt32: - return "on.boot".localized + return "On Boot Only".localized } } } @@ -110,11 +110,11 @@ enum GpsMode: Int, CaseIterable, Equatable { var description: String { switch self { case .disabled: - return "gpsmode.disabled".localized + return "Disabled".localized case .enabled: - return "gpsmode.enabled".localized + return "Enabled".localized case .notPresent: - return "gpsmode.notPresent".localized + return "Not Present".localized } } func protoEnumValue() -> Config.PositionConfig.GpsMode { diff --git a/Meshtastic/Enums/RouteEnums.swift b/Meshtastic/Enums/RouteEnums.swift index 052d0407..06876b4a 100644 --- a/Meshtastic/Enums/RouteEnums.swift +++ b/Meshtastic/Enums/RouteEnums.swift @@ -20,34 +20,34 @@ enum ActivityType: Int, CaseIterable, Identifiable { var description: String { switch self { case .walking: - return "routes.activitytype.walking".localized + return "Walking".localized case .hiking: - return "routes.activitytype.hiking".localized + return "Hiking".localized case .biking: - return "routes.activitytype.biking".localized + return "Biking".localized case .driving: - return "routes.activitytype.driving".localized + return "Driving".localized case .overlanding: - return "routes.activitytype.overlanding".localized + return "Overlanding".localized case .skiing: - return "routes.activitytype.skiing".localized + return "Skiing".localized } } var fileNameString: String { switch self { case .walking: - return "routes.activitytype.filename.walking".localized + return "walk".localized case .hiking: - return "routes.activitytype.filename.hiking".localized + return "hiking".localized case .biking: - return "routes.activitytype.filename.biking".localized + return "biking".localized case .driving: - return "routes.activitytype.filename.driving".localized + return "driving".localized case .overlanding: - return "routes.activitytype.filename.overlanding".localized + return "overlanding".localized case .skiing: - return "routes.activitytype.filename.skiing".localized + return "skiing".localized } } } diff --git a/Meshtastic/Enums/RoutingError.swift b/Meshtastic/Enums/RoutingError.swift index 628e1b3f..985794b3 100644 --- a/Meshtastic/Enums/RoutingError.swift +++ b/Meshtastic/Enums/RoutingError.swift @@ -32,31 +32,31 @@ enum RoutingError: Int, CaseIterable, Identifiable { switch self { case .none: - return "routing.acknowledged".localized + return "Acknowledged".localized case .noRoute: - return "routing.noroute".localized + return "No Route".localized case .gotNak: - return "routing.gotnak".localized + return "Received a negative acknowledgment".localized case .timeout: - return "routing.timeout".localized + return "Timeout".localized case .noInterface: - return "routing.nointerface".localized + return "No Interface".localized case .maxRetransmit: - return "routing.maxretransmit".localized + return "Max Retransmission Reached".localized case .noChannel: - return "routing.nochannel".localized + return "No Channel".localized case .tooLarge: - return "routing.toolarge".localized + return "The packet is too large".localized case .noResponse: - return "routing.noresponse".localized + return "No Response".localized case .dutyCycleLimit: - return "routing.dutycyclelimit".localized + return "Regional Duty Cycle Limit Reached".localized case .badRequest: - return "routing.badRequest".localized + return "Bad Request".localized case .notAuthorized: - return "routing.notauthorized".localized + return "Not Authorized".localized case .pkiFailed: - return "routing.pkifailed".localized + return "Encrypted Send Failed".localized case .pkiUnknownPubkey: return "Unknown public key".localized case .adminBadSessionKey: diff --git a/Meshtastic/Enums/SerialConfigEnums.swift b/Meshtastic/Enums/SerialConfigEnums.swift index ff937207..131b3d26 100644 --- a/Meshtastic/Enums/SerialConfigEnums.swift +++ b/Meshtastic/Enums/SerialConfigEnums.swift @@ -31,7 +31,7 @@ enum SerialBaudRates: Int, CaseIterable, Identifiable { switch self { case .baudDefault: - return "default".localized + return "Default".localized case .baud110: return "110 Baud" case .baud300: @@ -118,17 +118,17 @@ enum SerialModeTypes: Int, CaseIterable, Identifiable { var description: String { switch self { case .default: - return "serial.mode.default".localized + return "Default".localized case .simple: - return "serial.mode.simple".localized + return "Simple".localized case .proto: - return "serial.mode.proto".localized + return "Protobufs".localized case .txtmsg: - return "serial.mode.txtmsg".localized + return "Text Message".localized case .nmea: - return "serial.mode.nmea".localized + return "NMEA Positions".localized case .caltopo: - return "serial.mode.caltopo".localized + return "CALTOPO".localized } } func protoEnumValue() -> ModuleConfig.SerialConfig.Serial_Mode { @@ -166,21 +166,21 @@ enum SerialTimeoutIntervals: Int, CaseIterable, Identifiable { var description: String { switch self { case .unset: - return "unset".localized + return "Unset".localized case .oneSecond: - return "interval.one.second".localized + return "One Second".localized case .fiveSeconds: - return "interval.five.seconds".localized + return "Five Seconds".localized case .tenSeconds: - return "interval.ten.seconds".localized + return "Ten Seconds".localized case .fifteenSeconds: - return "interval.fifteen.seconds".localized + return "Fifteen Seconds".localized case .thirtySeconds: - return "interval.thirty.seconds".localized + return "Thirty Seconds".localized case .oneMinute: - return "interval.one.minute".localized + return "One Minute".localized case .fiveMinutes: - return "interval.five.minutes".localized + return "Five Minutes".localized } } } diff --git a/Meshtastic/Enums/TelemetryEnums.swift b/Meshtastic/Enums/TelemetryEnums.swift index 68d65961..82856e71 100644 --- a/Meshtastic/Enums/TelemetryEnums.swift +++ b/Meshtastic/Enums/TelemetryEnums.swift @@ -20,17 +20,17 @@ enum Aqi: Int, CaseIterable, Identifiable { var description: String { switch self { case .good: - return "telemetry.good".localized + return "Good".localized case .moderate: - return "telemetry.moderate".localized + return "Moderate".localized case .sensitive: - return "telemetry.sensitive".localized + return "Unhealthy for Sensitive Groups".localized case .unhealthy: - return "telementry.unhealthy".localized + return "Unhealthy".localized case .veryUnhealthy: - return "telementry.veryUnhealthy".localized + return "Very Unhealthy".localized case .hazardous: - return "telementry.hazardous".localized + return "Hazardous".localized } } var color: Color { diff --git a/Meshtastic/Export/CsvDocument.swift b/Meshtastic/Export/CsvDocument.swift index f4bb04ac..7133633e 100644 --- a/Meshtastic/Export/CsvDocument.swift +++ b/Meshtastic/Export/CsvDocument.swift @@ -20,13 +20,10 @@ struct CsvDocument: FileDocument { } init(configuration: ReadConfiguration) throws { - if let data = configuration.file.regularFileContents { - - csvData = String(decoding: data, as: UTF8.self) + csvData = String(data: data, encoding: .utf8) ?? "" } else { - throw CocoaError(.fileReadCorruptFile) } } diff --git a/Meshtastic/Export/WriteCsvFile.swift b/Meshtastic/Export/WriteCsvFile.swift index 66835b4a..badc6f9b 100644 --- a/Meshtastic/Export/WriteCsvFile.swift +++ b/Meshtastic/Export/WriteCsvFile.swift @@ -14,7 +14,7 @@ func telemetryToCsvFile(telemetry: [TelemetryEntity], metricsType: Int) -> Strin let dateFormatString = (localeDateFormat ?? "MM/dd/YY j:mma").replacingOccurrences(of: ",", with: "") if metricsType == 0 { // Create Device Metrics Header - csvString = "\("battery.level".localized), \("Voltage".localized), \("channel.utilization".localized), \("airtime".localized), \("uptime".localized), \("Timestamp".localized)" + csvString = "\("battery.level".localized), \("Voltage".localized), \("Channel Utilization".localized), \("airtime".localized), \("Uptime".localized), \("Timestamp".localized)" for dm in telemetry where dm.metricsType == 0 { csvString += "\n" csvString += dm.batteryLevel?.formatted(.number.grouping(.never)) ?? "" @@ -27,7 +27,7 @@ func telemetryToCsvFile(telemetry: [TelemetryEntity], metricsType: Int) -> Strin csvString += ", " csvString += dm.uptimeSeconds?.formatted(.number.grouping(.never)) ?? "" csvString += ", " - csvString += dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized + csvString += dm.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized } } else if metricsType == 1 { // Create Environment Telemetry Header @@ -44,7 +44,7 @@ func telemetryToCsvFile(telemetry: [TelemetryEntity], metricsType: Int) -> Strin csvString += ", " csvString += dm.gasResistance?.formatted(.number.grouping(.never)) ?? "" csvString += ", " - csvString += dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized + csvString += dm.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized } } else if metricsType == 2 { // Create Power Metrics Header @@ -63,7 +63,7 @@ func telemetryToCsvFile(telemetry: [TelemetryEntity], metricsType: Int) -> Strin csvString += ", " csvString += dm.powerCh3Current?.formatted(.number.grouping(.never)) ?? "" csvString += ", " - csvString += dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized + csvString += dm.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized } } return csvString @@ -121,7 +121,7 @@ func paxToCsvFile(pax: [PaxCounterEntity]) -> String { csvString += ", " csvString += String(p.uptime) csvString += ", " - csvString += p.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized + csvString += p.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized } return csvString } @@ -150,7 +150,7 @@ func positionToCsvFile(positions: [PositionEntity]) -> String { csvString += ", " csvString += String(pos.snr) csvString += ", " - csvString += pos.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized + csvString += pos.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized } return csvString } diff --git a/Meshtastic/Extensions/CoreData/PositionEntityExtension.swift b/Meshtastic/Extensions/CoreData/PositionEntityExtension.swift index a9eea507..4e05bcd6 100644 --- a/Meshtastic/Extensions/CoreData/PositionEntityExtension.swift +++ b/Meshtastic/Extensions/CoreData/PositionEntityExtension.swift @@ -89,6 +89,6 @@ extension PositionEntity { extension PositionEntity: MKAnnotation { public var coordinate: CLLocationCoordinate2D { nodeCoordinate ?? LocationsHandler.DefaultLocation } - public var title: String? { nodePosition?.user?.shortName ?? "unknown".localized } + public var title: String? { nodePosition?.user?.shortName ?? "Unknown".localized } public var subtitle: String? { time?.formatted() } } diff --git a/Meshtastic/Extensions/Date.swift b/Meshtastic/Extensions/Date.swift index d8cdd30f..f0b27331 100644 --- a/Meshtastic/Extensions/Date.swift +++ b/Meshtastic/Extensions/Date.swift @@ -13,7 +13,7 @@ extension Date { if self.timeIntervalSince1970 > 0 && self < Calendar.current.date(byAdding: .year, value: 1, to: Date())! { formatted() } else { - "unknown.age".localized + "Unknown Age".localized } } @@ -23,18 +23,18 @@ extension Date { if self.timeIntervalSince1970 > 0 && self < Calendar.current.date(byAdding: .year, value: 1, to: Date())! { return dateformat.string(from: self) } else { - return "unknown.age".localized + return "Unknown Age".localized } } func relativeTimeOfDay() -> String { let hour = Calendar.current.component(.hour, from: self) switch hour { - case 6..<12: return "relativetimeofday.morning".localized - case 12: return "relativetimeofday.midday".localized - case 13..<17: return "relativetimeofday.afternoon".localized - case 17..<22: return "relativetimeofday.evening".localized - default: return "relativetimeofday.nighttime".localized + case 6..<12: return "Morning".localized + case 12: return "Midday".localized + case 13..<17: return "Afternoon".localized + case 17..<22: return "Evening".localized + default: return "Nighttime".localized } } } diff --git a/Meshtastic/Extensions/OSLogEntryLog.swift b/Meshtastic/Extensions/OSLogEntryLog.swift index fe2dc2cf..c60c7aca 100644 --- a/Meshtastic/Extensions/OSLogEntryLog.swift +++ b/Meshtastic/Extensions/OSLogEntryLog.swift @@ -18,7 +18,7 @@ extension OSLogEntryLog.Level { case .notice: "⚠️ Notice" case .error: "🚨 Error" case .fault: "💥 Fault" - @unknown default: "default" + @unknown default: "Default".localized } } var color: Color { diff --git a/Meshtastic/Extensions/UserDefaults.swift b/Meshtastic/Extensions/UserDefaults.swift index 740f04e2..ee9e7c21 100644 --- a/Meshtastic/Extensions/UserDefaults.swift +++ b/Meshtastic/Extensions/UserDefaults.swift @@ -19,11 +19,11 @@ struct UserDefault { var wrappedValue: T { get { - if defaultValue as? any RawRepresentable != nil { + if defaultValue is any RawRepresentable { let storedValue = UserDefaults.standard.object(forKey: key.rawValue) guard let storedValue, - let jsonString = (storedValue as? String != nil) ? "\"\(storedValue)\"" : "\(storedValue)", + let jsonString = (storedValue is String) ? "\"\(storedValue)\"" : "\(storedValue)", let data = jsonString.data(using: .utf8), let value = (try? JSONDecoder().decode(T.self, from: data)) else { return defaultValue } @@ -72,6 +72,7 @@ extension UserDefaults { case firmwareVersion case environmentEnableWeatherKit case enableAdministration + case mapReportingOptIn case testIntEnum } @@ -97,7 +98,7 @@ extension UserDefaults { @UserDefault(.meshMapDistance, defaultValue: 800000) static var meshMapDistance: Double - @UserDefault(.enableMapWaypoints, defaultValue: false) + @UserDefault(.enableMapWaypoints, defaultValue: true) static var enableMapWaypoints: Bool @UserDefault(.enableMapRecentering, defaultValue: false) @@ -118,24 +119,6 @@ extension UserDefaults { @UserDefault(.enableMapPointsOfInterest, defaultValue: false) static var enableMapPointsOfInterest: Bool - @UserDefault(.enableOfflineMaps, defaultValue: false) - static var enableOfflineMaps: Bool - - @UserDefault(.mapTileServer, defaultValue: .openStreetMap) - static var mapTileServer: MapTileServer - - @UserDefault(.enableOverlayServer, defaultValue: false) - static var enableOverlayServer: Bool - - @UserDefault(.mapOverlayServer, defaultValue: .baseReReflectivityCurrent) - static var mapOverlayServer: MapOverlayServer - - @UserDefault(.mapTilesAboveLabels, defaultValue: false) - static var mapTilesAboveLabels: Bool - - @UserDefault(.mapUseLegacy, defaultValue: false) - static var mapUseLegacy: Bool - @UserDefault(.enableDetectionNotifications, defaultValue: false) static var enableDetectionNotifications: Bool @@ -166,6 +149,9 @@ extension UserDefaults { @UserDefault(.enableAdministration, defaultValue: false) static var enableAdministration: Bool + @UserDefault(.mapReportingOptIn, defaultValue: false) + static var mapReportingOptIn: Bool + @UserDefault(.testIntEnum, defaultValue: .one) static var testIntEnum: TestIntEnum } diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index 9f633f30..ba65f66a 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -231,7 +231,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate cancelPeripheralConnection() if errorCode == 14 { // Peer removed pairing information // Forgetting and reconnecting seems to be necessary so we need to show the user an error telling them to do that - lastConnectionError = "🚨 " + String.localizedStringWithFormat("%@ This error usually cannot be fixed without forgetting the device unders Settings > Bluetooth and re pairing the radio.".localized, e.localizedDescription) + lastConnectionError = "🚨 " + String.localizedStringWithFormat("%@ This error usually cannot be fixed without forgetting the device under Settings > Bluetooth and re pairing the radio.".localized, e.localizedDescription) Logger.services.error("🚨 [BLE] Failed to connect: \(peripheral.name ?? "Unknown".localized) Error Code: \(errorCode, privacy: .public) Error: \(self.lastConnectionError, privacy: .public)") } else { lastConnectionError = "🚨 \(e.localizedDescription)" @@ -261,7 +261,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate Notification( id: (peripheral.identifier.uuidString), title: "Radio Disconnected".localized, - subtitle: "\(peripheral.name ?? "unknown".localized)", + subtitle: "\(peripheral.name ?? "Unknown".localized)", content: e.localizedDescription, target: "bluetooth", path: "meshtastic:///bluetooth" @@ -273,7 +273,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate Logger.services.error("🚨 [BLE] Disconnected: \(peripheral.name ?? "Unknown".localized, privacy: .public) Error Code: \(errorCode, privacy: .public) Error: \(e.localizedDescription, privacy: .public)") } else if errorCode == 14 { // Peer removed pairing information // Forgetting and reconnecting seems to be necessary so we need to show the user an error telling them to do that - lastConnectionError = "🚨 " + String.localizedStringWithFormat("%@ This error usually cannot be fixed without forgetting the device unders Settings > Bluetooth and re-connecting to the radio.".localized, e.localizedDescription) + lastConnectionError = "🚨 " + String.localizedStringWithFormat("%@ This error usually cannot be fixed without forgetting the device under Settings > Bluetooth and re-connecting to the radio.".localized, e.localizedDescription) Logger.services.error("🚨 [BLE] Disconnected: \(peripheral.name ?? "Unknown".localized) Error Code: \(errorCode, privacy: .public) Error: \(self.lastConnectionError, privacy: .public)") } else { if UserDefaults.preferredPeripheralId == peripheral.identifier.uuidString { @@ -281,7 +281,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate Notification( id: (peripheral.identifier.uuidString), title: "Radio Disconnected".localized, - subtitle: "\(peripheral.name ?? "unknown".localized)", + subtitle: "\(peripheral.name ?? "Unknown".localized)", content: e.localizedDescription, target: "bluetooth", path: "meshtastic:///bluetooth" @@ -428,7 +428,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate return 0 } - let messageDescription = "🛎️ [Device Metadata] Requested for node \(toUser.longName ?? "unknown".localized) by \(fromUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ [Device Metadata] Requested for node \(toUser.longName ?? "Unknown".localized) by \(fromUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return Int64(meshPacket.id) } @@ -477,14 +477,14 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate traceRoute.node = receivingNode do { try context.save() - Logger.data.info("💾 Saved TraceRoute sent to node: \(String(receivingNode?.user?.longName ?? "unknown".localized), privacy: .public)") + Logger.data.info("💾 Saved TraceRoute sent to node: \(String(receivingNode?.user?.longName ?? "Unknown".localized), privacy: .public)") } catch { context.rollback() let nsError = error as NSError Logger.data.error("Error Updating Core Data BluetoothConfigEntity: \(nsError, privacy: .public)") } - let logString = String.localizedStringWithFormat("mesh.log.traceroute.sent %@".localized, destNum.toHex()) + let logString = String.localizedStringWithFormat("Sent a Trace Route Request to node: %@".localized, destNum.toHex()) Logger.mesh.info("🪧 \(logString, privacy: .public)") } catch { @@ -498,13 +498,13 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate guard connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected else { return } if FROMRADIO_characteristic == nil { - Logger.mesh.error("🚨 \("firmware.version.unsupported".localized, privacy: .public)") + Logger.mesh.error("🚨 \("Unsupported Firmware Version Detected, unable to connect to device.".localized, privacy: .public)") invalidVersion = true return } else { - let nodeName = connectedPeripheral?.peripheral.name ?? "unknown".localized - let logString = String.localizedStringWithFormat("mesh.log.wantconfig %@".localized, nodeName) + let nodeName = connectedPeripheral?.peripheral.name ?? "Unknown".localized + let logString = String.localizedStringWithFormat("Issuing Want Config to %@".localized, nodeName) Logger.mesh.info("🛎️ \(logString, privacy: .public)") // BLE Characteristics discovered, issue wantConfig var toRadio: ToRadio = ToRadio() @@ -579,7 +579,6 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { if let error { - Logger.services.error("🚫 [BLE] didUpdateValueFor Characteristic error \(error.localizedDescription, privacy: .public)") let errorCode = (error as NSError).code if errorCode == 5 || errorCode == 15 { @@ -633,14 +632,9 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } catch { Logger.services.error("💥 \(error.localizedDescription, privacy: .public) \(characteristic.value!, privacy: .public)") } - // Publish mqttClientProxyMessages received on the from radio if decodedInfo.payloadVariant == FromRadio.OneOf_PayloadVariant.mqttClientProxyMessage(decodedInfo.mqttClientProxyMessage) { - let message = CocoaMQTTMessage( - topic: decodedInfo.mqttClientProxyMessage.topic, - payload: [UInt8](decodedInfo.mqttClientProxyMessage.data), - retained: decodedInfo.mqttClientProxyMessage.retained - ) + let message = CocoaMQTTMessage(topic: decodedInfo.mqttClientProxyMessage.topic, payload: [UInt8](decodedInfo.mqttClientProxyMessage.data), retained: decodedInfo.mqttClientProxyMessage.retained) mqttManager.mqttClientProxy?.publish(message) } else if decodedInfo.payloadVariant == FromRadio.OneOf_PayloadVariant.clientNotification(decodedInfo.clientNotification) { if decodedInfo.clientNotification.hasReplyID { @@ -686,8 +680,8 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate if myInfo != nil { UserDefaults.preferredPeripheralNum = Int(myInfo?.myNodeNum ?? 0) connectedPeripheral.num = myInfo?.myNodeNum ?? 0 - connectedPeripheral.name = myInfo?.bleName ?? "unknown".localized - connectedPeripheral.longName = myInfo?.bleName ?? "unknown".localized + connectedPeripheral.name = myInfo?.bleName ?? "Unknown".localized + connectedPeripheral.longName = myInfo?.bleName ?? "Unknown".localized let newConnection = Int64(UserDefaults.preferredPeripheralNum) != Int64(decodedInfo.myInfo.myNodeNum) if newConnection { // Onboard a new device connection here @@ -702,7 +696,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate if self.connectedPeripheral != nil && self.connectedPeripheral.num == nodeInfo.num { if nodeInfo.user != nil { connectedPeripheral.shortName = nodeInfo.user?.shortName ?? "?" - connectedPeripheral.longName = nodeInfo.user?.longName ?? "unknown".localized + connectedPeripheral.longName = nodeInfo.user?.longName ?? "Unknown".localized } } } @@ -745,7 +739,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate let supportedVersion = connectedVersion == "0.0.0" || self.minimumVersion.compare(connectedVersion, options: .numeric) == .orderedAscending || minimumVersion.compare(connectedVersion, options: .numeric) == .orderedSame if !supportedVersion { invalidVersion = true - lastConnectionError = "🚨" + "update.firmware".localized + lastConnectionError = "🚨" + "Update Your Firmware".localized return } } @@ -782,13 +776,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate adminAppPacket(packet: decodedInfo.packet, context: context) case .replyApp: Logger.mesh.info("🕸️ MESH PACKET received for Reply App handling as a text message") - textMessageAppPacket( - packet: decodedInfo.packet, - wantRangeTestPackets: wantRangeTestPackets, - connectedNode: (self.connectedPeripheral != nil ? connectedPeripheral.num : 0), - context: context, - appState: appState - ) + textMessageAppPacket(packet: decodedInfo.packet, wantRangeTestPackets: wantRangeTestPackets, connectedNode: (self.connectedPeripheral != nil ? connectedPeripheral.num : 0), context: context, appState: appState) case .ipTunnelApp: Logger.mesh.info("🕸️ MESH PACKET received for IP Tunnel App UNHANDLED UNHANDLED") case .serialApp: @@ -873,13 +861,13 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } hopNodes.append(traceRouteHop) - let hopName = hopNode?.user?.longName ?? (node == 4294967295 ? "Repeater" : String(hopNode?.num.toHex() ?? "unknown".localized)) + let hopName = hopNode?.user?.longName ?? (node == 4294967295 ? "Repeater" : String(hopNode?.num.toHex() ?? "Unknown".localized)) let mqttLabel = hopNode?.viaMqtt ?? false ? "MQTT " : "" let snrLabel = (traceRouteHop.snr != -32) ? String(traceRouteHop.snr) : "unknown ".localized routeString += "\(hopName) \(mqttLabel)(\(snrLabel)dB) --> " } let destinationHop = TraceRouteHopEntity(context: context) - destinationHop.name = traceRoute?.node?.user?.longName ?? "unknown".localized + destinationHop.name = traceRoute?.node?.user?.longName ?? "Unknown".localized destinationHop.time = Date() // If nil, set to unknown, INT8_MIN (-128) then divide by 4 destinationHop.snr = Float(routingMessage.snrTowards.last ?? -128) / 4 @@ -892,14 +880,14 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } hopNodes.append(destinationHop) /// Add the destination node to the end of the route towards string and the beginning of the route back string - routeString += "\(traceRoute?.node?.user?.longName ?? "unknown".localized) \((traceRoute?.node?.num ?? 0).toHex()) (\(destinationHop.snr != -32 ? String(destinationHop.snr) : "unknown ".localized)dB)" + routeString += "\(traceRoute?.node?.user?.longName ?? "Unknown".localized) \((traceRoute?.node?.num ?? 0).toHex()) (\(destinationHop.snr != -32 ? String(destinationHop.snr) : "unknown ".localized)dB)" traceRoute?.routeText = routeString // Default to -1 only fill in if routeBack is valid below traceRoute?.hopsBack = -1 // Only if hopStart is set and there is an SNR entry if decodedInfo.packet.hopStart > 0 && routingMessage.snrBack.count > 0 { traceRoute?.hopsBack = Int32(routingMessage.routeBack.count) - var routeBackString = "\(traceRoute?.node?.user?.longName ?? "unknown".localized) \((traceRoute?.node?.num ?? 0).toHex()) --> " + var routeBackString = "\(traceRoute?.node?.user?.longName ?? "Unknown".localized) \((traceRoute?.node?.num ?? 0).toHex()) --> " for (index, node) in routingMessage.routeBack.enumerated() { var hopNode = getNodeInfo(id: Int64(node), context: context) if hopNode == nil && hopNode?.num ?? 0 > 0 && node != 4294967295 { @@ -930,7 +918,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } hopNodes.append(traceRouteHop) - let hopName = hopNode?.user?.longName ?? (node == 4294967295 ? "Repeater" : String(hopNode?.num.toHex() ?? "unknown".localized)) + let hopName = hopNode?.user?.longName ?? (node == 4294967295 ? "Repeater" : String(hopNode?.num.toHex() ?? "Unknown".localized)) let mqttLabel = hopNode?.viaMqtt ?? false ? "MQTT " : "" let snrLabel = (traceRouteHop.snr != -32) ? String(traceRouteHop.snr) : "unknown ".localized routeBackString += "\(hopName) \(mqttLabel)(\(snrLabel)dB) --> " @@ -950,7 +938,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate id: (UUID().uuidString), title: "Traceroute Complete", subtitle: "TR received back from \(destinationHop.name ?? "unknown")", - content: "Hops from: \(tr.hopsTowards), Hops back: \(tr.hopsBack)\n\(tr.routeText ?? "unknown".localized)\n\(tr.routeBackText ?? "unknown".localized)", + content: "Hops from: \(tr.hopsTowards), Hops back: \(tr.hopsBack)\n\(tr.routeText ?? "Unknown".localized)\n\(tr.routeBackText ?? "Unknown".localized)", target: "nodes", path: "meshtastic:///nodes?nodenum=\(connectedNode.user?.num ?? 0)" ) @@ -966,7 +954,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate let nsError = error as NSError Logger.data.error("Error Updating Core Data TraceRouteHop: \(nsError, privacy: .public)") } - let logString = String.localizedStringWithFormat("mesh.log.traceroute.received.route %@".localized, routeString) + let logString = String.localizedStringWithFormat("Trace Route request returned: %@".localized, routeString) Logger.mesh.info("🪧 \(logString, privacy: .public)") } case .neighborinfoApp: @@ -1069,8 +1057,8 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate if preferredPeripheral != nil && preferredPeripheral?.peripheral != nil { connectTo(peripheral: preferredPeripheral!.peripheral) } - let nodeName = connectedPeripheral?.peripheral.name ?? "unknown".localized - let logString = String.localizedStringWithFormat("mesh.log.textmessage.send.failed %@".localized, nodeName) + let nodeName = connectedPeripheral?.peripheral.name ?? "Unknown".localized + let logString = String.localizedStringWithFormat("Message Send Failed, not properly connected to %@".localized, nodeName) Logger.mesh.info("🚫 \(logString, privacy: .public)") success = false @@ -1156,7 +1144,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected { connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse) - let logString = String.localizedStringWithFormat("mesh.log.textmessage.sent %@ %@ %@".localized, String(newMessage.messageId), fromUserNum.toHex(), toUserNum.toHex()) + let logString = String.localizedStringWithFormat("Sent message %@ from %@ to %@".localized, String(newMessage.messageId), fromUserNum.toHex(), toUserNum.toHex()) Logger.mesh.info("💬 \(logString, privacy: .public)") do { @@ -1204,7 +1192,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate guard let binaryData: Data = try? toRadio.serializedData() else { return false } - let logString = String.localizedStringWithFormat("mesh.log.waypoint.sent %@".localized, String(fromNodeNum)) + let logString = String.localizedStringWithFormat("Sent a Waypoint Packet from: %@".localized, String(fromNodeNum)) Logger.mesh.info("📍 \(logString, privacy: .public)") if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected { connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse) @@ -1304,7 +1292,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } else { return false } - let messageDescription = "🚀 Sent Set Fixed Postion Admin Message to: \(fromUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)" + let messageDescription = "🚀 Sent Set Fixed Postion Admin Message to: \(fromUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -1329,7 +1317,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } else { return false } - let messageDescription = "🚀 Sent Remove Fixed Position Admin Message to: \(fromUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)" + let messageDescription = "🚀 Sent Remove Fixed Position Admin Message to: \(fromUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -1368,7 +1356,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected { connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse) - let logString = String.localizedStringWithFormat("mesh.log.sharelocation %@".localized, String(fromNodeNum)) + let logString = String.localizedStringWithFormat("Sent a Position Packet from the Apple device GPS to node: %@".localized, String(fromNodeNum)) Logger.services.debug("📍 \(logString, privacy: .public)") return true } else { @@ -1434,7 +1422,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } else { return false } - let messageDescription = "🚀 Sent Shutdown Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)" + let messageDescription = "🚀 Sent Shutdown Admin Message to: \(toUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -1462,7 +1450,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } else { return false } - let messageDescription = "🚀 Sent Reboot Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)" + let messageDescription = "🚀 Sent Reboot Admin Message to: \(toUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -1490,7 +1478,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } else { return false } - let messageDescription = "🚀 Sent Reboot OTA Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)" + let messageDescription = "🚀 Sent Reboot OTA Admin Message to: \(toUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -1519,7 +1507,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate return false } automaticallyReconnect = false - let messageDescription = "🚀 Sent enter DFU mode Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)" + let messageDescription = "🚀 Sent enter DFU mode Admin Message to: \(toUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -1547,7 +1535,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate return false } - let messageDescription = "🚀 Sent Factory Reset Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)" + let messageDescription = "🚀 Sent Factory Reset Admin Message to: \(toUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -1574,7 +1562,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🚀 Sent NodeDB Reset Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)" + let messageDescription = "🚀 Sent NodeDB Reset Admin Message to: \(toUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -1617,7 +1605,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.wantResponse = true meshPacket.decoded = dataMessage - let messageDescription = "🎛️ Requested Channel \(channel.index) for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🎛️ Requested Channel \(channel.index) for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return Int64(meshPacket.id) } @@ -1641,7 +1629,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.wantResponse = true meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Channel \(channel.index) for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Channel \(channel.index) for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return Int64(meshPacket.id) } @@ -1723,7 +1711,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected { self.connectedPeripheral.peripheral.writeValue(binaryData, for: self.TORADIO_characteristic, type: .withResponse) - let logString = String.localizedStringWithFormat("mesh.log.channel.sent %@ %d".localized, String(connectedPeripheral.num), chan.index) + let logString = String.localizedStringWithFormat("Sent a Channel for: %@ Channel Index %d".localized, String(connectedPeripheral.num), chan.index) Logger.mesh.info("🎛️ \(logString, privacy: .public)") } } @@ -1752,7 +1740,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected { self.connectedPeripheral.peripheral.writeValue(binaryData, for: self.TORADIO_characteristic, type: .withResponse) - let logString = String.localizedStringWithFormat("mesh.log.lora.config.sent %@".localized, String(connectedPeripheral.num)) + let logString = String.localizedStringWithFormat("Sent a LoRa.Config for: %@".localized, String(connectedPeripheral.num)) Logger.mesh.info("📻 \(logString, privacy: .public)") } @@ -1790,7 +1778,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } else { return 0 } - let messageDescription = "🛟 Saved User Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved User Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return Int64(meshPacket.id) } @@ -1972,7 +1960,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.payload = adminData dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Ham Parameters for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Ham Parameters for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return Int64(meshPacket.id) } @@ -1998,7 +1986,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.payload = adminData dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Bluetooth Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Bluetooth Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertBluetoothConfigPacket(config: config, nodeNum: toUser.num, sessionPasskey: toUser.userNode?.sessionPasskey, context: context) @@ -2029,7 +2017,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.payload = adminData dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Device Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Device Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertDeviceConfigPacket(config: config, nodeNum: toUser.num, sessionPasskey: toUser.userNode?.sessionPasskey, context: context) return Int64(meshPacket.id) @@ -2059,7 +2047,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.payload = adminData dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Display Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Display Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertDisplayConfigPacket(config: config, nodeNum: toUser.num, sessionPasskey: toUser.userNode?.sessionPasskey, context: context) return Int64(meshPacket.id) @@ -2088,7 +2076,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.payload = adminData dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved LoRa Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved LoRa Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertLoRaConfigPacket(config: config, nodeNum: toUser.num, sessionPasskey: toUser.userNode?.sessionPasskey, context: context) @@ -2120,7 +2108,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Position Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Position Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertPositionConfigPacket(config: config, nodeNum: toUser.num, context: context) @@ -2151,7 +2139,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Power Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Power Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertPowerConfigPacket(config: config, nodeNum: toUser.num, context: context) @@ -2184,7 +2172,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Network Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Network Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertNetworkConfigPacket(config: config, nodeNum: toUser.num, context: context) @@ -2217,7 +2205,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Security Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Security Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertSecurityConfigPacket(config: config, nodeNum: toUser.num, context: context) @@ -2249,7 +2237,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Ambient Lighting Module Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Ambient Lighting Module Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertAmbientLightingModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) @@ -2281,7 +2269,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Canned Message Module Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Canned Message Module Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertCannedMessagesModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) @@ -2314,7 +2302,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.wantResponse = true meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Canned Message Module Messages for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Canned Message Module Messages for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { @@ -2347,7 +2335,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Detection Sensor Module Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Detection Sensor Module Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertDetectionSensorModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) return Int64(meshPacket.id) @@ -2378,7 +2366,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved External Notification Module Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved External Notification Module Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertExternalNotificationModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) return Int64(meshPacket.id) @@ -2409,7 +2397,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved PAX Counter Module Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved PAX Counter Module Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertPaxCounterModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) return Int64(meshPacket.id) @@ -2440,7 +2428,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved RTTTL Ringtone Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved RTTTL Ringtone Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertRtttlConfigPacket(ringtone: ringtone, nodeNum: toUser.num, context: context) @@ -2474,7 +2462,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved MQTT Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved MQTT Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertMqttModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) return Int64(meshPacket.id) @@ -2504,7 +2492,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Range Test Module Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Range Test Module Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertRangeTestModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) @@ -2537,7 +2525,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Serial Module Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Serial Module Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertSerialModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) return Int64(meshPacket.id) @@ -2568,7 +2556,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Store & Forward Module Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Store & Forward Module Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertStoreForwardModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) return Int64(meshPacket.id) @@ -2599,7 +2587,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "Saved Telemetry Module Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "Saved Telemetry Module Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertTelemetryModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) return Int64(meshPacket.id) @@ -2629,7 +2617,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Sent a Get Channel \(channelIndex) Request Admin Message for node: \(toUser.longName ?? "unknown".localized))" + let messageDescription = "🛎️ Sent a Get Channel \(channelIndex) Request Admin Message for node: \(toUser.longName ?? "Unknown".localized))" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { @@ -2672,7 +2660,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected { connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse) - let logString = String.localizedStringWithFormat("mesh.log.cannedmessages.messages.get %@".localized, String(connectedPeripheral.num)) + let logString = String.localizedStringWithFormat("Requested Canned Messages Module Messages for node: %@".localized, String(connectedPeripheral.num)) Logger.mesh.info("🥫 \(logString, privacy: .public)") return true } @@ -2735,7 +2723,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Device Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Device Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true @@ -2765,7 +2753,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Display Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Display Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true @@ -2795,7 +2783,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested LoRa Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested LoRa Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { @@ -2826,7 +2814,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.wantResponse = true meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Network Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Network Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true @@ -2856,7 +2844,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Position Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Position Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -2885,7 +2873,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Power Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Power Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -2914,7 +2902,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Security Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Security Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -2943,7 +2931,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Ambient Lighting Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Ambient Lighting Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -2972,7 +2960,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Canned Messages Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Canned Messages Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -3001,7 +2989,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested External Notificaiton Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested External Notificaiton Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -3030,7 +3018,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested PAX Counter Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested PAX Counter Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -3059,7 +3047,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested RTTTL Ringtone Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested RTTTL Ringtone Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -3088,7 +3076,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Range Test Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Range Test Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -3146,7 +3134,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Detection Sensor Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Detection Sensor Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -3175,7 +3163,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Serial Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Serial Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -3204,7 +3192,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Store and Forward Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Store and Forward Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -3234,7 +3222,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Telemetry Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Telemetry Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -3448,7 +3436,7 @@ extension BLEManager: CBCentralManagerDelegate { case .unsupported: status = "BLE is unsupported" default: - status = "default" + status = "Default".localized } Logger.services.info("📜 [BLE] Bluetooth status: \(status, privacy: .public)") } diff --git a/Meshtastic/Helpers/Map/OfflineTileManager.swift b/Meshtastic/Helpers/Map/OfflineTileManager.swift deleted file mode 100644 index 66afa93c..00000000 --- a/Meshtastic/Helpers/Map/OfflineTileManager.swift +++ /dev/null @@ -1,74 +0,0 @@ -// -// OfflineTileManager.swift -// Meshtastic -// -// Copyright(c) Garth Vander Houwen 4/23/23. -// - -import Foundation -import MapKit -import OSLog - -class OfflineTileManager: ObservableObject { - static let shared = OfflineTileManager() - - // MARK: - Public properties - - @Published var status: DownloadStatus = .downloaded - - enum DownloadStatus { - case downloaded, downloading - } - - init() { - Logger.services.info("🗂️ Documents Directory = \(self.documentsDirectory.absoluteString, privacy: .public)") - createDirectoriesIfNecessary() - } - - // MARK: - Private properties - - private var overlay: MKTileOverlay { MKTileOverlay(urlTemplate: UserDefaults.mapTileServer.tileUrl.count > 1 ? UserDefaults.mapTileServer.tileUrl : MapTileServer.openStreetMap.tileUrl) } - private var documentsDirectory: URL { fileManager.urls(for: .documentDirectory, in: .userDomainMask).first! } - private let fileManager = FileManager.default - - // MARK: - Public methods - - func getAllDownloadedSize() -> String { - fileManager.allocatedSizeOfDirectory(at: documentsDirectory.appendingPathComponent("tiles")) - } - - func removeAll() { - try? fileManager.removeItem(at: documentsDirectory.appendingPathComponent("tiles")) - createDirectoriesIfNecessary() - } - - func loadAndCacheTileOverlay(for path: MKTileOverlayPath) throws -> Data { - guard UserDefaults.enableOfflineMaps, UserDefaults.mapTileServer.zoomRange.contains(path.z) else { - return try Data(contentsOf: Bundle.main.url(forResource: "alpha", withExtension: "png")!) - } - - let tilesUrl = documentsDirectory - .appendingPathComponent("tiles") - .appendingPathComponent("\(UserDefaults.mapTileServer.id)-z\(path.z)x\(path.x)y\(path.y)") - .appendingPathExtension("png") - - do { - return try Data(contentsOf: tilesUrl) - } catch let error as NSError where error.code == NSFileReadNoSuchFileError { - DispatchQueue.main.async { self.status = .downloading } - defer { - DispatchQueue.main.async { self.status = .downloaded } - } - let data = try Data(contentsOf: overlay.url(forTilePath: path)) - try data.write(to: tilesUrl) - return data - } - } - - // MARK: Private methods - - private func createDirectoriesIfNecessary() { - let tiles = documentsDirectory.appendingPathComponent("tiles") - try? fileManager.createDirectory(at: tiles, withIntermediateDirectories: true, attributes: [:]) - } -} diff --git a/Meshtastic/Helpers/Map/TileOverlay.swift b/Meshtastic/Helpers/Map/TileOverlay.swift deleted file mode 100644 index 754771df..00000000 --- a/Meshtastic/Helpers/Map/TileOverlay.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// TileOverlay.swift -// Meshtastic -// -// Copyright(c) Garth Vander Houwen 5/5/23. -// - -import Foundation -import MapKit - -class TileOverlay: MKTileOverlay { - override func loadTile(at path: MKTileOverlayPath) async throws -> Data { - return try OfflineTileManager.shared.loadAndCacheTileOverlay(for: path) - } -} diff --git a/Meshtastic/Helpers/MeshPackets.swift b/Meshtastic/Helpers/MeshPackets.swift index 83f0b8ef..f5a7bda9 100644 --- a/Meshtastic/Helpers/MeshPackets.swift +++ b/Meshtastic/Helpers/MeshPackets.swift @@ -103,7 +103,7 @@ func moduleConfig (config: ModuleConfig, context: NSManagedObjectContext, nodeNu func myInfoPacket (myInfo: MyNodeInfo, peripheralId: String, context: NSManagedObjectContext) -> MyInfoEntity? { - let logString = String.localizedStringWithFormat("mesh.log.myinfo %@".localized, String(myInfo.myNodeNum)) + let logString = String.localizedStringWithFormat("MyInfo received: %@".localized, String(myInfo.myNodeNum)) Logger.mesh.info("ℹ️ \(logString, privacy: .public)") let fetchMyInfoRequest = MyInfoEntity.fetchRequest() @@ -209,7 +209,7 @@ func channelPacket (channel: Channel, fromNum: Int64, context: NSManagedObjectCo func deviceMetadataPacket (metadata: DeviceMetadata, fromNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) { if metadata.isInitialized { - let logString = String.localizedStringWithFormat("mesh.log.device.metadata.received %@".localized, fromNum.toHex()) + let logString = String.localizedStringWithFormat("Device Metadata received from: %@".localized, fromNum.toHex()) Logger.mesh.info("🏷️ \(logString, privacy: .public)") let fetchedNodeRequest = NodeInfoEntity.fetchRequest() @@ -261,7 +261,7 @@ func deviceMetadataPacket (metadata: DeviceMetadata, fromNum: Int64, sessionPass func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObjectContext) -> NodeInfoEntity? { - let logString = String.localizedStringWithFormat("mesh.log.nodeinfo.received %@".localized, String(nodeInfo.num)) + let logString = String.localizedStringWithFormat("Node info received for: %@".localized, String(nodeInfo.num)) Logger.mesh.info("📟 \(logString, privacy: .public)") guard nodeInfo.num > 0 else { return nil } @@ -472,7 +472,7 @@ func adminAppPacket (packet: MeshPacket, context: NSManagedObjectContext) { if !cmmc.messages.isEmpty { - let logString = String.localizedStringWithFormat("mesh.log.cannedmessages.messages.received %@".localized, packet.from.toHex()) + let logString = String.localizedStringWithFormat("Canned Messages Messages Received For: %@".localized, packet.from.toHex()) Logger.mesh.info("🥫 \(logString, privacy: .public)") let fetchNodeRequest = NodeInfoEntity.fetchRequest() @@ -582,7 +582,7 @@ func adminResponseAck (packet: MeshPacket, context: NSManagedObjectContext) { } func paxCounterPacket (packet: MeshPacket, context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.paxcounter %@".localized, String(packet.from)) + let logString = String.localizedStringWithFormat("PAX Counter message received from: %@".localized, String(packet.from)) Logger.mesh.info("🧑‍🤝‍🧑 \(logString, privacy: .public)") let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest() @@ -625,8 +625,8 @@ func routingPacket (packet: MeshPacket, connectedNodeNum: Int64, context: NSMana let routingError = RoutingError(rawValue: routingMessage.errorReason.rawValue) - let routingErrorString = routingError?.display ?? "unknown".localized - let logString = String.localizedStringWithFormat("mesh.log.routing.message %@ %@".localized, String(packet.decoded.requestID), routingErrorString) + let routingErrorString = routingError?.display ?? "Unknown".localized + let logString = String.localizedStringWithFormat("Routing received for RequestID: %@ Ack Status: %@".localized, String(packet.decoded.requestID), routingErrorString) Logger.mesh.info("🕸️ \(logString, privacy: .public)") let fetchMessageRequest = MessageEntity.fetchRequest() @@ -686,20 +686,15 @@ func routingPacket (packet: MeshPacket, connectedNodeNum: Int64, context: NSMana func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManagedObjectContext) { if let telemetryMessage = try? Telemetry(serializedBytes: packet.decoded.payload) { - - let logString = String.localizedStringWithFormat("mesh.log.telemetry.received %@".localized, String(packet.from)) + let logString = String.localizedStringWithFormat("Telemetry received for: %@".localized, String(packet.from)) Logger.mesh.info("📈 \(logString, privacy: .public)") - if telemetryMessage.variant != Telemetry.OneOf_Variant.deviceMetrics(telemetryMessage.deviceMetrics) && telemetryMessage.variant != Telemetry.OneOf_Variant.environmentMetrics(telemetryMessage.environmentMetrics) && telemetryMessage.variant != Telemetry.OneOf_Variant.localStats(telemetryMessage.localStats) && telemetryMessage.variant != Telemetry.OneOf_Variant.powerMetrics(telemetryMessage.powerMetrics) { /// Other unhandled telemetry packets return } - let telemetry = TelemetryEntity(context: context) - let fetchNodeTelemetryRequest = NodeInfoEntity.fetchRequest() fetchNodeTelemetryRequest.predicate = NSPredicate(format: "num == %lld", Int64(packet.from)) - do { let fetchedNode = try context.fetch(fetchNodeTelemetryRequest) if fetchedNode.count == 1 { @@ -756,7 +751,6 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage Logger.statistics.info("📈 [Mesh Statistics] Channel Utilization: \(telemetryMessage.localStats.channelUtilization, privacy: .public) Airtime: \(telemetryMessage.localStats.airUtilTx, privacy: .public) Packets Sent: \(telemetryMessage.localStats.numPacketsTx, privacy: .public) Packets Received: \(telemetryMessage.localStats.numPacketsRx, privacy: .public) Bad Packets Received: \(telemetryMessage.localStats.numPacketsRxBad, privacy: .public) Nodes Online: \(telemetryMessage.localStats.numOnlineNodes, privacy: .public) of \(telemetryMessage.localStats.numTotalNodes, privacy: .public) nodes for Node: \(packet.from.toHex(), privacy: .public)") } else if telemetryMessage.variant == Telemetry.OneOf_Variant.powerMetrics(telemetryMessage.powerMetrics) { Logger.data.info("📈 [Power Metrics] Received for Node: \(packet.from.toHex(), privacy: .public)") - telemetry.powerCh1Voltage = telemetryMessage.powerMetrics.hasCh1Voltage.then(telemetryMessage.powerMetrics.ch1Voltage) telemetry.powerCh1Current = telemetryMessage.powerMetrics.hasCh1Current.then(telemetryMessage.powerMetrics.ch1Current) telemetry.powerCh2Voltage = telemetryMessage.powerMetrics.hasCh2Voltage.then(telemetryMessage.powerMetrics.ch2Voltage) @@ -764,7 +758,6 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage telemetry.powerCh3Voltage = telemetryMessage.powerMetrics.hasCh3Voltage.then(telemetryMessage.powerMetrics.ch3Voltage) telemetry.powerCh3Current = telemetryMessage.powerMetrics.hasCh3Current.then(telemetryMessage.powerMetrics.ch3Current) telemetry.metricsType = 2 - } telemetry.snr = packet.rxSnr telemetry.rssi = packet.rxRssi @@ -781,7 +774,6 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage fetchedNode[0].telemetries = mutableTelemetries.copy() as? NSOrderedSet } try context.save() - Logger.data.info("💾 [TelemetryEntity] of type \(MetricsTypes(rawValue: Int(telemetry.metricsType))?.name ?? "Unknown Metrics Type", privacy: .public) Saved for Node: \(packet.from.toHex(), privacy: .public)") if telemetry.metricsType == 0 { // Connected Device Metrics @@ -883,7 +875,7 @@ func textMessageAppPacket( } if messageText?.count ?? 0 > 0 { - Logger.mesh.info("💬 \("mesh.log.textmessage.received".localized, privacy: .public)") + Logger.mesh.info("💬 \("Message received from the text message app.".localized, privacy: .public)") let messageUsers = UserEntity.fetchRequest() messageUsers.predicate = NSPredicate(format: "num IN %@", [packet.to, packet.from]) do { @@ -980,7 +972,7 @@ func textMessageAppPacket( manager.notifications = [ Notification( id: ("notification.id.\(newMessage.messageId)"), - title: "\(newMessage.fromUser?.longName ?? "unknown".localized)", + title: "\(newMessage.fromUser?.longName ?? "Unknown".localized)", subtitle: "AKA \(newMessage.fromUser?.shortName ?? "?")", content: messageText!, target: "messages", @@ -992,7 +984,7 @@ func textMessageAppPacket( ) ] manager.schedule() - Logger.services.debug("iOS Notification Scheduled for text message from \(newMessage.fromUser?.longName ?? "unknown".localized, privacy: .public)") + Logger.services.debug("iOS Notification Scheduled for text message from \(newMessage.fromUser?.longName ?? "Unknown".localized, privacy: .public)") } } else if newMessage.fromUser != nil && newMessage.toUser == nil { let fetchMyInfoRequest = MyInfoEntity.fetchRequest() @@ -1011,7 +1003,7 @@ func textMessageAppPacket( manager.notifications = [ Notification( id: ("notification.id.\(newMessage.messageId)"), - title: "\(newMessage.fromUser?.longName ?? "unknown".localized)", + title: "\(newMessage.fromUser?.longName ?? "Unknown".localized)", subtitle: "AKA \(newMessage.fromUser?.shortName ?? "?")", content: messageText!, target: "messages", @@ -1023,7 +1015,7 @@ func textMessageAppPacket( ) ] manager.schedule() - Logger.services.debug("iOS Notification Scheduled for text message from \(newMessage.fromUser?.longName ?? "unknown".localized, privacy: .public)") + Logger.services.debug("iOS Notification Scheduled for text message from \(newMessage.fromUser?.longName ?? "Unknown".localized, privacy: .public)") } } } @@ -1045,7 +1037,7 @@ func textMessageAppPacket( func waypointPacket (packet: MeshPacket, context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.waypoint.received %@".localized, String(packet.from)) + let logString = String.localizedStringWithFormat("Waypoint Packet received from node: %@".localized, String(packet.from)) Logger.mesh.info("📍 \(logString, privacy: .public)") let fetchWaypointRequest = WaypointEntity.fetchRequest() diff --git a/Meshtastic/Helpers/Mqtt/MqttClientProxyManager.swift b/Meshtastic/Helpers/Mqtt/MqttClientProxyManager.swift index cac34de8..cf21d92e 100644 --- a/Meshtastic/Helpers/Mqtt/MqttClientProxyManager.swift +++ b/Meshtastic/Helpers/Mqtt/MqttClientProxyManager.swift @@ -8,6 +8,7 @@ import Foundation import CocoaMQTT import OSLog +import Security protocol MqttClientProxyManagerDelegate: AnyObject { func onMqttConnected() @@ -40,20 +41,20 @@ class MqttClientProxyManager { if let host = host { let port = defaultServerPort - var username = node.mqttConfig?.username - var password = node.mqttConfig?.password - // if host == defaultServerAddress { - //username = ProcessInfo.processInfo.environment["PUBLIC_MQTT_USERNAME"] - //password = ProcessInfo.processInfo.environment["PUBLIC_MQTT_PASSWORD"] - // } + let username = node.mqttConfig?.username + let password = node.mqttConfig?.password let root = node.mqttConfig?.root?.count ?? 0 > 0 ? node.mqttConfig?.root : "msh" let prefix = root! topic = prefix + "/2/e" + "/#" - let qos = CocoaMQTTQoS(rawValue: UInt8(1))! - connect(host: host, port: port, useSsl: useSsl, username: username, password: password, topic: topic, qos: qos, cleanSession: true) + // Require opt in to map report terms to connect + if node.mqttConfig?.mapReportingEnabled ?? false && UserDefaults.mapReportingOptIn || !(node.mqttConfig?.mapReportingEnabled ?? false) { + connect(host: host, port: port, useSsl: useSsl, username: username, password: password, topic: topic) + } else { + delegate?.onMqttError(message: "MQTT Map Reporting Terms need to be accepted.") + } } } - func connect(host: String, port: Int, useSsl: Bool, username: String?, password: String?, topic: String?, qos: CocoaMQTTQoS, cleanSession: Bool) { + func connect(host: String, port: Int, useSsl: Bool, username: String?, password: String?, topic: String?) { guard !host.isEmpty else { delegate?.onMqttDisconnected() return @@ -66,7 +67,7 @@ class MqttClientProxyManager { mqttClient.username = username mqttClient.password = password mqttClient.keepAlive = 60 - mqttClient.cleanSession = cleanSession + mqttClient.cleanSession = true if debugLog { mqttClient.logLevel = .debug } @@ -130,6 +131,16 @@ extension MqttClientProxyManager: CocoaMQTTDelegate { self.disconnect() } } + func mqtt(_ mqtt: CocoaMQTT, didReceive trust: SecTrust, completionHandler: @escaping (Bool) -> Void) { + let isValid = SecTrustEvaluateWithError(trust, nil) + if isValid { + Logger.mqtt.info("📲 [MQTT Client Proxy] TLS validation succeeded.") + completionHandler(true) + } else { + Logger.mqtt.warning("📲 [MQTT Client Proxy] TLS validation failed.") + completionHandler(true) + } + } func mqttDidDisconnect(_ mqtt: CocoaMQTT, withError err: Error?) { Logger.mqtt.debug("📲 [MQTT Client Proxy] disconnected: \(err?.localizedDescription ?? "", privacy: .public)") if let error = err { diff --git a/Meshtastic/Model/Metrics Visualization/MetricsChartSeries.swift b/Meshtastic/Model/Metrics Visualization/MetricsChartSeries.swift index ab68c4cc..42e35ce0 100644 --- a/Meshtastic/Model/Metrics Visualization/MetricsChartSeries.swift +++ b/Meshtastic/Model/Metrics Visualization/MetricsChartSeries.swift @@ -41,7 +41,6 @@ class MetricsChartSeries: ObservableObject { // Used for scaling the Y-axis let initialYAxisRange: ClosedRange? let minumumYAxisSpan: Float? - // Main initializer init( id: String, diff --git a/Meshtastic/Model/Metrics Visualization/MetricsSeriesList.swift b/Meshtastic/Model/Metrics Visualization/MetricsSeriesList.swift index fb68af92..1def5f47 100644 --- a/Meshtastic/Model/Metrics Visualization/MetricsSeriesList.swift +++ b/Meshtastic/Model/Metrics Visualization/MetricsSeriesList.swift @@ -67,12 +67,12 @@ class MetricsSeriesList: ObservableObject, RandomAccessCollection, RangeReplacea for aSeries in self.visible { var seriesUpper = range[aSeries]?.upperBound ?? -.infinity var seriesLower = range[aSeries]?.lowerBound ?? .infinity - + if let value = aSeries.valueFor(te) { // Update the global bounds if value > globalUpper {globalUpper = value} if value < globalLower {globalLower = value} - + // Update the series bounds if necessary if value > seriesUpper || value < seriesLower { if value > seriesUpper { diff --git a/Meshtastic/Persistence/Persistence.swift b/Meshtastic/Persistence/Persistence.swift index f18a8566..4b0fd147 100644 --- a/Meshtastic/Persistence/Persistence.swift +++ b/Meshtastic/Persistence/Persistence.swift @@ -45,6 +45,7 @@ class PersistenceController { // Merge policy that favors in memory data over data in the db self.container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy self.container.viewContext.automaticallyMergesChangesFromParent = true + self.container.viewContext.retainsRegisteredObjects = true if let error = error as NSError? { diff --git a/Meshtastic/Persistence/UpdateCoreData.swift b/Meshtastic/Persistence/UpdateCoreData.swift index e5e7bd87..00916edb 100644 --- a/Meshtastic/Persistence/UpdateCoreData.swift +++ b/Meshtastic/Persistence/UpdateCoreData.swift @@ -129,7 +129,7 @@ public func clearCoreDataDatabase(context: NSManagedObjectContext, includeRoutes func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.nodeinfo.received %@".localized, packet.from.toHex()) + let logString = String.localizedStringWithFormat("Node info received for: %@".localized, packet.from.toHex()) Logger.mesh.info("📟 \(logString, privacy: .public)") guard packet.from > 0 else { return } @@ -200,7 +200,7 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext) Notification( id: (UUID().uuidString), title: "New Node".localized, - subtitle: "\(newUser.longName ?? "unknown".localized)", + subtitle: "\(newUser.longName ?? "Unknown".localized)", content: "New Node has been discovered".localized, target: "nodes", path: "meshtastic:///nodes?nodenum=\(newUser.num)" @@ -227,6 +227,7 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext) let myInfoEntity = MyInfoEntity(context: context) myInfoEntity.myNodeNum = Int64(packet.from) myInfoEntity.rebootCount = 0 + newNode.myInfo = myInfoEntity do { try context.save() Logger.data.info("💾 [NodeInfo] Saved a NodeInfo for node number: \(packet.from.toHex(), privacy: .public)") @@ -236,7 +237,6 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext) let nsError = error as NSError Logger.data.error("💥 [MyInfoEntity] Error Inserting New Core Data: \(nsError, privacy: .public)") } - newNode.myInfo = myInfoEntity } else { // Update an existing node @@ -312,7 +312,7 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext) func upsertPositionPacket (packet: MeshPacket, context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.position.received %@".localized, String(packet.from)) + let logString = String.localizedStringWithFormat("Position Packet received from node: %@".localized, String(packet.from)) Logger.mesh.info("📍 \(logString, privacy: .public)") let fetchNodePositionRequest = NodeInfoEntity.fetchRequest() @@ -406,7 +406,7 @@ func upsertPositionPacket (packet: MeshPacket, context: NSManagedObjectContext) func upsertBluetoothConfigPacket(config: Config.BluetoothConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.bluetooth.config %@".localized, String(nodeNum)) + let logString = String.localizedStringWithFormat("Bluetooth config received: %@".localized, String(nodeNum)) Logger.mesh.info("📶 \(logString, privacy: .public)") let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest() @@ -450,7 +450,7 @@ func upsertBluetoothConfigPacket(config: Config.BluetoothConfig, nodeNum: Int64, func upsertDeviceConfigPacket(config: Config.DeviceConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.device.config %@".localized, String(nodeNum)) + let logString = String.localizedStringWithFormat("Device config received: %@".localized, String(nodeNum)) Logger.mesh.info("📟 \(logString, privacy: .public)") let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest() fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum)) @@ -505,7 +505,7 @@ func upsertDeviceConfigPacket(config: Config.DeviceConfig, nodeNum: Int64, sessi func upsertDisplayConfigPacket(config: Config.DisplayConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.display.config %@".localized, nodeNum.toHex()) + let logString = String.localizedStringWithFormat("Display config received: %@".localized, nodeNum.toHex()) Logger.data.info("🖥️ \(logString, privacy: .public)") let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest() @@ -567,7 +567,7 @@ func upsertDisplayConfigPacket(config: Config.DisplayConfig, nodeNum: Int64, ses func upsertLoRaConfigPacket(config: Config.LoRaConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.lora.config %@".localized, nodeNum.toHex()) + let logString = String.localizedStringWithFormat("LoRa config received: %@".localized, nodeNum.toHex()) Logger.data.info("📻 \(logString, privacy: .public)") let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest() @@ -638,7 +638,7 @@ func upsertLoRaConfigPacket(config: Config.LoRaConfig, nodeNum: Int64, sessionPa func upsertNetworkConfigPacket(config: Config.NetworkConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.network.config %@".localized, String(nodeNum)) + let logString = String.localizedStringWithFormat("Network config received: %@".localized, String(nodeNum)) Logger.data.info("🌐 \(logString, privacy: .public)") let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest() @@ -687,7 +687,7 @@ func upsertNetworkConfigPacket(config: Config.NetworkConfig, nodeNum: Int64, ses func upsertPositionConfigPacket(config: Config.PositionConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.position.config %@".localized, String(nodeNum)) + let logString = String.localizedStringWithFormat("Position config received: %@".localized, String(nodeNum)) Logger.data.info("🗺️ \(logString, privacy: .public)") let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest() @@ -750,7 +750,7 @@ func upsertPositionConfigPacket(config: Config.PositionConfig, nodeNum: Int64, s } func upsertPowerConfigPacket(config: Config.PowerConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.power.config %@".localized, String(nodeNum)) + let logString = String.localizedStringWithFormat("Power config received: %@".localized, String(nodeNum)) Logger.data.info("🗺️ \(logString, privacy: .public)") let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest() @@ -863,7 +863,7 @@ func upsertSecurityConfigPacket(config: Config.SecurityConfig, nodeNum: Int64, s func upsertAmbientLightingModuleConfigPacket(config: ModuleConfig.AmbientLightingConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.ambientlighting.config %@".localized, String(nodeNum)) + let logString = String.localizedStringWithFormat("Ambient Lighting module config received: %@".localized, String(nodeNum)) Logger.data.info("🏮 \(logString, privacy: .public)") let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest() @@ -916,7 +916,7 @@ func upsertAmbientLightingModuleConfigPacket(config: ModuleConfig.AmbientLightin func upsertCannedMessagesModuleConfigPacket(config: ModuleConfig.CannedMessageConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.cannedmessage.config %@".localized, String(nodeNum)) + let logString = String.localizedStringWithFormat("Canned Message module config received: %@".localized, String(nodeNum)) Logger.data.info("🥫 \(logString, privacy: .public)") let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest() @@ -975,7 +975,7 @@ func upsertCannedMessagesModuleConfigPacket(config: ModuleConfig.CannedMessageCo func upsertDetectionSensorModuleConfigPacket(config: ModuleConfig.DetectionSensorConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.detectionsensor.config %@".localized, String(nodeNum)) + let logString = String.localizedStringWithFormat("Detection Sensor module config received: %@".localized, String(nodeNum)) Logger.data.info("🕵️ \(logString, privacy: .public)") let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest() @@ -1032,7 +1032,7 @@ func upsertDetectionSensorModuleConfigPacket(config: ModuleConfig.DetectionSenso func upsertExternalNotificationModuleConfigPacket(config: ModuleConfig.ExternalNotificationConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.externalnotification.config %@".localized, String(nodeNum)) + let logString = String.localizedStringWithFormat("External Notification module config received: %@".localized, String(nodeNum)) Logger.data.info("📣 \(logString, privacy: .public)") let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest() @@ -1101,7 +1101,7 @@ func upsertExternalNotificationModuleConfigPacket(config: ModuleConfig.ExternalN func upsertPaxCounterModuleConfigPacket(config: ModuleConfig.PaxcounterConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.paxcounter.config %@".localized, String(nodeNum)) + let logString = String.localizedStringWithFormat("PAX Counter config received: %@".localized, String(nodeNum)) Logger.data.info("🧑‍🤝‍🧑 \(logString, privacy: .public)") let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest() @@ -1143,7 +1143,7 @@ func upsertPaxCounterModuleConfigPacket(config: ModuleConfig.PaxcounterConfig, n func upsertRtttlConfigPacket(ringtone: String, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.ringtone.config %@".localized, String(nodeNum)) + let logString = String.localizedStringWithFormat("RTTTL Ringtone config received: %@".localized, String(nodeNum)) Logger.data.info("⛰️ \(logString, privacy: .public)") let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest() @@ -1183,7 +1183,7 @@ func upsertRtttlConfigPacket(ringtone: String, nodeNum: Int64, sessionPasskey: D func upsertMqttModuleConfigPacket(config: ModuleConfig.MQTTConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.mqtt.config %@".localized, String(nodeNum)) + let logString = String.localizedStringWithFormat("MQTT module config received: %@".localized, String(nodeNum)) Logger.data.info("🌉 \(logString, privacy: .public)") let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest() @@ -1245,7 +1245,7 @@ func upsertMqttModuleConfigPacket(config: ModuleConfig.MQTTConfig, nodeNum: Int6 func upsertRangeTestModuleConfigPacket(config: ModuleConfig.RangeTestConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.rangetest.config %@".localized, String(nodeNum)) + let logString = String.localizedStringWithFormat("Range Test module config received: %@".localized, String(nodeNum)) Logger.data.info("⛰️ \(logString, privacy: .public)") let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest() @@ -1289,7 +1289,7 @@ func upsertRangeTestModuleConfigPacket(config: ModuleConfig.RangeTestConfig, nod func upsertSerialModuleConfigPacket(config: ModuleConfig.SerialConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.serial.config %@".localized, String(nodeNum)) + let logString = String.localizedStringWithFormat("Serial module config received: %@".localized, String(nodeNum)) Logger.data.info("🤖 \(logString, privacy: .public)") let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest() @@ -1344,7 +1344,7 @@ func upsertSerialModuleConfigPacket(config: ModuleConfig.SerialConfig, nodeNum: func upsertStoreForwardModuleConfigPacket(config: ModuleConfig.StoreForwardConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.storeforward.config %@".localized, String(nodeNum)) + let logString = String.localizedStringWithFormat("Store & Forward module config received: %@".localized, String(nodeNum)) Logger.data.info("📬 \(logString, privacy: .public)") let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest() @@ -1393,7 +1393,7 @@ func upsertStoreForwardModuleConfigPacket(config: ModuleConfig.StoreForwardConfi func upsertTelemetryModuleConfigPacket(config: ModuleConfig.TelemetryConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) { - let logString = String.localizedStringWithFormat("mesh.log.telemetry.config %@".localized, String(nodeNum)) + let logString = String.localizedStringWithFormat("Telemetry module config received: %@".localized, String(nodeNum)) Logger.data.info("📈 \(logString, privacy: .public)") let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest() diff --git a/Meshtastic/Resources/DeviceHardware.json b/Meshtastic/Resources/DeviceHardware.json index 00b80aea..bbe99f2a 100644 --- a/Meshtastic/Resources/DeviceHardware.json +++ b/Meshtastic/Resources/DeviceHardware.json @@ -543,7 +543,7 @@ "images": [ "t-watch-s3.svg" ], - "partitionScheme": "16MB" + "partitionScheme": "8MB" }, { "hwModel": 52, @@ -845,25 +845,32 @@ "hwModelSlug": "THINKNODE_M1", "platformioTarget": "thinknode_m1", "architecture": "nrf52840", - "activelySupported": false, + "activelySupported": true, "supportLevel": 1, "displayName": "ThinkNode M1", "tags": [ "Elecrow" ], - "requiresDfu": true + "requiresDfu": true, + "images": [ + "thinknode_m1.svg" + ], + "hasInkHud": true }, { "hwModel": 90, "hwModelSlug": "THINKNODE_M2", "platformioTarget": "thinknode_m2", "architecture": "esp32-s3", - "activelySupported": false, + "activelySupported": true, "supportLevel": 1, "displayName": "ThinkNode M2", "tags": [ "Elecrow" ], - "requiresDfu": false + "requiresDfu": false, + "images": [ + "thinknode_m2.svg" + ] } ] diff --git a/Meshtastic/Tips/ChannelTips.swift b/Meshtastic/Tips/ChannelTips.swift index 712a266e..f378c257 100644 --- a/Meshtastic/Tips/ChannelTips.swift +++ b/Meshtastic/Tips/ChannelTips.swift @@ -13,10 +13,10 @@ return "tip.channels.share" } var title: Text { - Text("tip.channels.share.title") + Text("Sharing Meshtastic Channels") } var message: Text? { - Text("tip.channels.share.message") + Text("A Meshtastic QR code contains the LoRa config and channel values needed for radios to communicate. You can share a complete channel configuration using the Replace Channels option, if you choose Add Channels your shared channels will be added to the channels on the receiving radio.") } var image: Image? { Image(systemName: "qrcode") @@ -29,10 +29,10 @@ struct CreateChannelsTip: Tip { return "tip.channels.create" } var title: Text { - Text("tip.channels.create.title") + Text("Manage Channels") } var message: Text? { - Text("tip.channels.create.message") + Text("Most data on your mesh is sent over the primary channel. You can set up secondary channels to create additional messaging groups secured by their own key. [Channel config tips](https://meshtastic.org/docs/configuration/tips/)") } var image: Image? { Image(systemName: "fibrechannel") @@ -45,10 +45,10 @@ struct AdminChannelTip: Tip { return "tip.channel.admin" } var title: Text { - Text("tip.channel.admin.title") + Text("Administration Enabled") } var message: Text? { - Text("tip.channel.admin.message") + Text("Select a node from the drop down to manage connected or remote devices.") } var image: Image? { Image(systemName: "fibrechannel") diff --git a/Meshtastic/Tips/MessagesTips.swift b/Meshtastic/Tips/MessagesTips.swift index ddbe9feb..1e5ac07c 100644 --- a/Meshtastic/Tips/MessagesTips.swift +++ b/Meshtastic/Tips/MessagesTips.swift @@ -13,10 +13,10 @@ struct MessagesTip: Tip { return "tip.messages" } var title: Text { - Text("tip.messages.title") + Text("Messages") } var message: Text? { - Text("tip.messages.message") + Text("You can send and receive channel (group chats) and direct messages. From any message you can long press to see available actions like copy, reply, tapback and delete as well as delivery details.") } var image: Image? { Image(systemName: "bubble.left.and.bubble.right") diff --git a/Meshtastic/Views/Bluetooth/Connect.swift b/Meshtastic/Views/Bluetooth/Connect.swift index 880faf8d..5e9dd834 100644 --- a/Meshtastic/Views/Bluetooth/Connect.swift +++ b/Meshtastic/Views/Bluetooth/Connect.swift @@ -46,7 +46,7 @@ struct Connect: View { VStack { List { if bleManager.isSwitchedOn { - Section(header: Text("connected.radio").font(.title)) { + Section(header: Text("Connected Radio").font(.title)) { if let connectedPeripheral = bleManager.connectedPeripheral, connectedPeripheral.peripheral.state == .connected { TipView(BluetoothConnectionTip(), arrowEdge: .bottom) VStack(alignment: .leading) { @@ -64,10 +64,10 @@ struct Connect: View { if node != nil { Text(connectedPeripheral.longName.addingVariationSelectors).font(.title2) } - Text("BLE Name").font(.callout)+Text(": \(bleManager.connectedPeripheral?.peripheral.name?.addingVariationSelectors ?? "unknown".localized)") + Text("BLE Name").font(.callout)+Text(": \(bleManager.connectedPeripheral?.peripheral.name?.addingVariationSelectors ?? "Unknown".localized)") .font(.callout).foregroundColor(Color.gray) if node != nil { - Text("firmware.version").font(.callout)+Text(": \(node?.metadata?.firmwareVersion ?? "unknown".localized)") + Text("Firmware Version").font(.callout)+Text(": \(node?.metadata?.firmwareVersion ?? "Unknown".localized)") .font(.callout).foregroundColor(Color.gray) } if bleManager.isSubscribed { @@ -116,12 +116,12 @@ struct Connect: View { #endif } } label: { - Label("mesh.live.activity", systemImage: liveActivityStarted ? "stop" : "play") + Label("Mesh Live Activity", systemImage: liveActivityStarted ? "stop" : "play") } #endif Text("Num: \(String(node!.num))") Text("Short Name: \(node?.user?.shortName ?? "?")") - Text("Long Name: \(node?.user?.longName?.addingVariationSelectors ?? "unknown".localized)") + Text("Long Name: \(node?.user?.longName?.addingVariationSelectors ?? "Unknown".localized)") Text("BLE RSSI: \(connectedPeripheral.rssi)") Button { @@ -139,7 +139,7 @@ struct Connect: View { NavigationLink { LoRaConfig(node: node) } label: { - Label("set.region", systemImage: "globe.americas.fill") + Label("Set LoRa Region", systemImage: "globe.americas.fill") .foregroundColor(.red) .font(.title) } @@ -156,7 +156,7 @@ struct Connect: View { .frame(width: 60, height: 60) .padding(.trailing) if bleManager.timeoutTimerCount == 0 { - Text("connecting") + Text("Connecting . .") .font(.title2) .foregroundColor(.orange) } else { @@ -189,7 +189,7 @@ struct Connect: View { .foregroundColor(.red) .frame(width: 60, height: 60) .padding(.trailing) - Text("not.connected").font(.title3) + Text("No device connected").font(.title3) } .padding() } diff --git a/Meshtastic/Views/Bluetooth/InvalidVersion.swift b/Meshtastic/Views/Bluetooth/InvalidVersion.swift index ba94e7c1..5d475756 100644 --- a/Meshtastic/Views/Bluetooth/InvalidVersion.swift +++ b/Meshtastic/Views/Bluetooth/InvalidVersion.swift @@ -17,7 +17,7 @@ struct InvalidVersion: View { VStack { - Text("update.firmware") + Text("Update Your Firmware") .font(.largeTitle) .foregroundColor(.orange) @@ -49,7 +49,7 @@ struct InvalidVersion: View { Button { dismiss() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) diff --git a/Meshtastic/Views/ContentView.swift b/Meshtastic/Views/ContentView.swift index d6b2fd6b..9eb1ce56 100644 --- a/Meshtastic/Views/ContentView.swift +++ b/Meshtastic/Views/ContentView.swift @@ -11,6 +11,12 @@ struct ContentView: View { @ObservedObject var router: Router + init(appState: AppState, router: Router) { + self.appState = appState + self.router = router + UITabBar.appearance().scrollEdgeAppearance = UITabBarAppearance(idiom: .unspecified) + } + var body: some View { TabView(selection: $appState.router.navigationState.selectedTab) { Messages( @@ -19,7 +25,7 @@ struct ContentView: View { unreadDirectMessages: $appState.unreadDirectMessages ) .tabItem { - Label("messages", systemImage: "message") + Label("Messages", systemImage: "message") } .tag(NavigationState.Tab.messages) .badge(appState.totalUnreadMessages) @@ -34,13 +40,13 @@ struct ContentView: View { router: appState.router ) .tabItem { - Label("nodes", systemImage: "flipphone") + Label("Nodes", systemImage: "flipphone") } .tag(NavigationState.Tab.nodes) MeshMap(router: appState.router) .tabItem { - Label("map", systemImage: "map") + Label("Mesh Map", systemImage: "map") } .tag(NavigationState.Tab.map) @@ -48,7 +54,7 @@ struct ContentView: View { router: appState.router ) .tabItem { - Label("settings", systemImage: "gear") + Label("Settings", systemImage: "gear") .font(.title) } .tag(NavigationState.Tab.settings) diff --git a/Meshtastic/Views/Helpers/CircleText.swift b/Meshtastic/Views/Helpers/CircleText.swift index b8f74842..f85decf4 100644 --- a/Meshtastic/Views/Helpers/CircleText.swift +++ b/Meshtastic/Views/Helpers/CircleText.swift @@ -4,29 +4,43 @@ A view draws a circle in the background of the shortName text */ import SwiftUI +import CoreData struct CircleText: View { - var text: String - var color: Color + var text: String + var color: Color var circleSize: CGFloat = 45 + var node: NodeInfoEntity? - var body: some View { + var body: some View { + if let node = node { + NavigationStack { + NavigationLink(destination: NodeDetail(node: node)) { + circleContent + } + } - ZStack { - Circle() - .fill(color) - .frame(width: circleSize, height: circleSize) - Text(text.addingVariationSelectors) + } else { + circleContent + } + } + + var circleContent: some View { + ZStack { + Circle() + .fill(color) + .frame(width: circleSize, height: circleSize) + Text(text) .frame(width: circleSize * 0.9, height: circleSize * 0.9, alignment: .center) .foregroundColor(color.isLight() ? .black : .white) .minimumScaleFactor(0.001) .font(.system(size: 1300)) - } - } + } + } } struct CircleText_Previews: PreviewProvider { - static var previews: some View { + static var previews: some View { VStack { HStack { CircleText(text: "N1", color: Color.yellow, circleSize: 80) @@ -75,5 +89,5 @@ struct CircleText_Previews: PreviewProvider { .previewLayout(.fixed(width: 300, height: 100)) } } - } + } } diff --git a/Meshtastic/Views/Helpers/Compact Widgets/CompactWidget.swift b/Meshtastic/Views/Helpers/Compact Widgets/CompactWidget.swift index 42411cc1..a999dae0 100644 --- a/Meshtastic/Views/Helpers/Compact Widgets/CompactWidget.swift +++ b/Meshtastic/Views/Helpers/Compact Widgets/CompactWidget.swift @@ -31,7 +31,7 @@ import SwiftUI WeightCompactWidget(weight: "123", unit: "kg") SoilTemperatureCompactWidget(temperature: "23", unit: "°C") SoilMoistureCompactWidget(moisture: "23", unit: "%") - + let rain: Float = 10.1 let locale = NSLocale.current as NSLocale let usesMetricSystem = locale.usesMetricSystem // Returns true for metric (mm), false for imperial (inches) diff --git a/Meshtastic/Views/Helpers/Compact Widgets/RadiationCompactWidget.swift b/Meshtastic/Views/Helpers/Compact Widgets/RadiationCompactWidget.swift index b5cd7232..582a1c26 100644 --- a/Meshtastic/Views/Helpers/Compact Widgets/RadiationCompactWidget.swift +++ b/Meshtastic/Views/Helpers/Compact Widgets/RadiationCompactWidget.swift @@ -16,7 +16,7 @@ struct RadiationCompactWidget: View { HStack(alignment: .firstTextBaseline) { Text(verbatim: "☢") .font(.system(size: 30, design: .monospaced)) - .foregroundColor(.accentColor) + .tint(.accentColor) Text("Radiation") .textCase(.uppercase) .font(.callout) diff --git a/Meshtastic/Views/Helpers/Compact Widgets/WeatherConditionsCompactWidget.swift b/Meshtastic/Views/Helpers/Compact Widgets/WeatherConditionsCompactWidget.swift index 4918c7b6..3cac48bf 100644 --- a/Meshtastic/Views/Helpers/Compact Widgets/WeatherConditionsCompactWidget.swift +++ b/Meshtastic/Views/Helpers/Compact Widgets/WeatherConditionsCompactWidget.swift @@ -39,4 +39,3 @@ struct WeatherConditionsCompactWidget: View { } } } - diff --git a/Meshtastic/Views/Helpers/DateTimeText.swift b/Meshtastic/Views/Helpers/DateTimeText.swift index 517772fe..38e386f3 100644 --- a/Meshtastic/Views/Helpers/DateTimeText.swift +++ b/Meshtastic/Views/Helpers/DateTimeText.swift @@ -24,7 +24,7 @@ struct DateTimeText: View { if dateTime != nil && dateTime! >= sixMonthsAgo! { Text(" \(dateTime!.formattedDate(format: dateFormatString))") } else { - Text("unknown.age") + Text("Unknown Age") } } } diff --git a/Meshtastic/Views/Helpers/Help/DirectMessagesHelp.swift b/Meshtastic/Views/Helpers/Help/DirectMessagesHelp.swift index fd0f0414..1b9263c5 100644 --- a/Meshtastic/Views/Helpers/Help/DirectMessagesHelp.swift +++ b/Meshtastic/Views/Helpers/Help/DirectMessagesHelp.swift @@ -50,7 +50,7 @@ struct DirectMessagesHelp: View { Button { dismiss() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) diff --git a/Meshtastic/Views/Helpers/LoRaSignalStrengthIndicator.swift b/Meshtastic/Views/Helpers/LoRaSignalStrengthIndicator.swift index 688dcc24..bc5fb605 100644 --- a/Meshtastic/Views/Helpers/LoRaSignalStrengthIndicator.swift +++ b/Meshtastic/Views/Helpers/LoRaSignalStrengthIndicator.swift @@ -47,13 +47,13 @@ enum LoRaSignalStrength: Int { var description: String { switch self { case .none: - return "lora.signal.strength.none".localized + return "None".localized case .bad: - return "lora.signal.strength.bad".localized + return "Bad".localized case .fair: - return "lora.signal.strength.fair".localized + return "Fair".localized case .good: - return "lora.signal.strength.good".localized + return "Good".localized } } } diff --git a/Meshtastic/Views/Helpers/MQTTIcon.swift b/Meshtastic/Views/Helpers/MQTTIcon.swift index 914c6043..7d6c653a 100644 --- a/Meshtastic/Views/Helpers/MQTTIcon.swift +++ b/Meshtastic/Views/Helpers/MQTTIcon.swift @@ -29,7 +29,7 @@ struct MQTTIcon: View { VStack(spacing: 0.5) { Text("Topic: \(topic)".localized) .padding(20) - Button("close", action: { self.isPopoverOpen = false }).padding([.bottom], 20) + Button("Close", action: { self.isPopoverOpen = false }).padding([.bottom], 20) } .presentationCompactAdaptation(.popover) }) diff --git a/Meshtastic/Views/Helpers/PowerMetrics.swift b/Meshtastic/Views/Helpers/PowerMetrics.swift index 7f9fdcdd..e85c0f6a 100644 --- a/Meshtastic/Views/Helpers/PowerMetrics.swift +++ b/Meshtastic/Views/Helpers/PowerMetrics.swift @@ -69,8 +69,8 @@ struct PowerMetrics: View { } enum PowerMetricType: String { - case current = "current" - case voltage = "voltage" + case current = "Current" + case voltage = "Voltage" } struct PowerMetricCompactWidget: View { diff --git a/Meshtastic/Views/Messages/ChannelList.swift b/Meshtastic/Views/Messages/ChannelList.swift index a4fd86bf..1123c4ab 100644 --- a/Meshtastic/Views/Messages/ChannelList.swift +++ b/Meshtastic/Views/Messages/ChannelList.swift @@ -24,7 +24,7 @@ struct ChannelList: View { @State private var isPresentingTraceRouteSentAlert = false - var restrictedChannels = ["gpio", "mqtt", "serial"] + var restrictedChannels = ["gpio", "mqtt", "serial", "admin"] @ViewBuilder private func makeChannelRow( @@ -144,7 +144,7 @@ struct ChannelList: View { context.refresh(myInfo, mergeChanges: true) channelSelection = nil } label: { - Text("delete") + Text("Delete") } } } @@ -154,6 +154,6 @@ struct ChannelList: View { .listStyle(.plain) } } - .navigationTitle("channels") + .navigationTitle("Channels") } } diff --git a/Meshtastic/Views/Messages/ChannelMessageList.swift b/Meshtastic/Views/Messages/ChannelMessageList.swift index bf5be325..c82cfb0b 100644 --- a/Meshtastic/Views/Messages/ChannelMessageList.swift +++ b/Meshtastic/Views/Messages/ChannelMessageList.swift @@ -14,136 +14,212 @@ struct ChannelMessageList: View { @EnvironmentObject var appState: AppState @Environment(\.managedObjectContext) var context @EnvironmentObject var bleManager: BLEManager - // Keyboard State @FocusState var messageFieldFocused: Bool - @ObservedObject var myInfo: MyInfoEntity @ObservedObject var channel: ChannelEntity @State private var replyMessageId: Int64 = 0 @AppStorage("preferredPeripheralNum") private var preferredPeripheralNum = -1 + // Scroll state + @State private var showScrollToBottomButton = false + @State private var hasReachedBottom = false + @State private var gotFirstUnreadMessage: Bool = false + + @State private var messageToHighlight: Int64 = 0 var body: some View { VStack { ScrollViewReader { scrollView in - ScrollView { - LazyVStack { - ForEach( channel.allPrivateMessages ) { (message: MessageEntity) in - let currentUser: Bool = (Int64(preferredPeripheralNum) == message.fromUser?.num ? true : false) - if message.replyID > 0 { - let messageReply = channel.allPrivateMessages.first(where: { $0.messageId == message.replyID }) - HStack { - Text(messageReply?.messagePayload ?? "EMPTY MESSAGE").foregroundColor(.accentColor).font(.caption2) - .padding(10) - .overlay( - RoundedRectangle(cornerRadius: 18) - .stroke(Color.blue, lineWidth: 0.5) - ) - Image(systemName: "arrowshape.turn.up.left.fill") - .symbolRenderingMode(.hierarchical) - .imageScale(.large).foregroundColor(.accentColor) - .padding(.trailing) - } - } - HStack(alignment: .bottom) { - if currentUser { Spacer(minLength: 50) } - if !currentUser { - CircleText(text: message.fromUser?.shortName ?? "?", color: Color(UIColor(hex: UInt32(message.fromUser?.num ?? 0))), circleSize: 44) - .padding(.all, 5) - .offset(y: -7) - } - - VStack(alignment: currentUser ? .trailing : .leading) { - let isDetectionSensorMessage = message.portNum == Int32(PortNum.detectionSensorApp.rawValue) - - if !currentUser && message.fromUser != nil { - Text("\(message.fromUser?.longName ?? "unknown".localized ) (\(message.fromUser?.userId ?? "?"))") - .font(.caption) - .foregroundColor(.gray) - .offset(y: 8) - } - + ZStack(alignment: .bottomTrailing) { + ScrollView { + LazyVStack { + ForEach(channel.allPrivateMessages) { (message: MessageEntity) in + let currentUser: Bool = (Int64(preferredPeripheralNum) == message.fromUser?.num ? true : false) + if message.replyID > 0 { + let messageReply = channel.allPrivateMessages.first(where: { $0.messageId == message.replyID }) HStack { - MessageText( - message: message, - tapBackDestination: .channel(channel), - isCurrentUser: currentUser - ) { - self.replyMessageId = message.messageId - self.messageFieldFocused = true - } + Button { + if let messageNum = messageReply?.messageId { + withAnimation(.easeInOut(duration: 0.5)) { + messageToHighlight = messageNum + } + scrollView.scrollTo(messageNum, anchor: .center) - if currentUser && message.canRetry { - RetryButton(message: message, destination: .channel(channel)) - } - } - - TapbackResponses(message: message) { - appState.unreadChannelMessages = myInfo.unreadMessages - context.refresh(myInfo, mergeChanges: true) - } - - HStack { - let ackErrorVal = RoutingError(rawValue: Int(message.ackError)) - if currentUser && message.receivedACK { - Text("\(ackErrorVal?.display ?? "Empty Ack Error")").fixedSize(horizontal: false, vertical: true) - .foregroundStyle(ackErrorVal?.color ?? Color.red) - .font(.caption2) - } else if currentUser && message.ackError == 0 { - // Empty Error - Text("Waiting to be acknowledged. . .").font( - .caption2) - .foregroundColor(.orange) - } else if currentUser && !isDetectionSensorMessage { - Text("\(ackErrorVal?.display ?? "Empty Ack Error")").fixedSize(horizontal: false, vertical: true) - .foregroundStyle(ackErrorVal?.color ?? Color.red) - .font(.caption2) + // Reset highlight after delay + Task { + try? await Task.sleep(nanoseconds: 1_000_000_000) // 1 second + withAnimation(.easeInOut(duration: 0.5)) { + messageToHighlight = -1 + } + } + } + } label: { + Text(messageReply?.messagePayload ?? "EMPTY MESSAGE").foregroundColor(.accentColor).font(.caption2) + .padding(10) + .overlay( + RoundedRectangle(cornerRadius: 18) + .stroke(Color.blue, lineWidth: 0.5) + ) + Image(systemName: "arrowshape.turn.up.left.fill") + .symbolRenderingMode(.hierarchical) + .imageScale(.large).foregroundColor(.accentColor) + .padding(.trailing) } } } - .padding(.bottom) - .id(channel.allPrivateMessages.firstIndex(of: message)) + HStack(alignment: .bottom) { + if currentUser { Spacer(minLength: 50) } + if !currentUser { + CircleText(text: message.fromUser?.shortName ?? "?", color: Color(UIColor(hex: UInt32(message.fromUser?.num ?? 0))), circleSize: 44, node: getNodeInfo(id: Int64(message.fromUser?.num ?? 0), context: context)) + .padding(.all, 5) + .offset(y: -7) + } - if !currentUser { - Spacer(minLength: 50) - } - } - .padding([.leading, .trailing]) - .frame(maxWidth: .infinity) - .id(message.messageId) - .onAppear { - if !message.read { - message.read = true - do { - for unreadMessage in channel.allPrivateMessages.filter({ !$0.read }) { - unreadMessage.read = true + VStack(alignment: currentUser ? .trailing : .leading) { + let isDetectionSensorMessage = message.portNum == Int32(PortNum.detectionSensorApp.rawValue) + + if !currentUser && message.fromUser != nil { + Text("\(message.fromUser?.longName ?? "Unknown".localized ) (\(message.fromUser?.userId ?? "?"))") + .font(.caption) + .foregroundColor(.gray) + .offset(y: 8) + } + + HStack { + MessageText( + message: message, + tapBackDestination: .channel(channel), + isCurrentUser: currentUser + ) { + self.replyMessageId = message.messageId + self.messageFieldFocused = true + } + + if currentUser && message.canRetry { + RetryButton(message: message, destination: .channel(channel)) + } + } + + TapbackResponses(message: message) { + appState.unreadChannelMessages = myInfo.unreadMessages + context.refresh(myInfo, mergeChanges: true) + } + + HStack { + let ackErrorVal = RoutingError(rawValue: Int(message.ackError)) + if currentUser && message.receivedACK { + Text("\(ackErrorVal?.display ?? "Empty Ack Error")").fixedSize(horizontal: false, vertical: true) + .foregroundStyle(ackErrorVal?.color ?? Color.red) + .font(.caption2) + } else if currentUser && message.ackError == 0 { + // Empty Error + Text("Waiting to be acknowledged. . .").font( + .caption2) + .foregroundColor(.orange) + } else if currentUser && !isDetectionSensorMessage { + Text("\(ackErrorVal?.display ?? "Empty Ack Error")").fixedSize(horizontal: false, vertical: true) + .foregroundStyle(ackErrorVal?.color ?? Color.red) + .font(.caption2) + } + } + } + .padding(.bottom) + .id(channel.allPrivateMessages.firstIndex(of: message)) + + if !currentUser { + Spacer(minLength: 50) + } + } + + .overlay { + RoundedRectangle(cornerRadius: 10) + .stroke(.blue, lineWidth: 2) + .opacity(((messageToHighlight == message.messageId) || (replyMessageId == message.messageId)) ? 1 : 0) + } + .padding([.leading, .trailing]) + .frame(maxWidth: .infinity) + .id(message.messageId) + .onAppear { + if gotFirstUnreadMessage { + if !message.read { + message.read = true + do { + for unreadMessage in channel.allPrivateMessages.filter({ !$0.read }) { + unreadMessage.read = true + } + try context.save() + Logger.data.info("📖 [App] Read message \(message.messageId, privacy: .public) ") + appState.unreadChannelMessages = myInfo.unreadMessages + context.refresh(myInfo, mergeChanges: true) + } catch { + Logger.data.error("Failed to read message \(message.messageId, privacy: .public): \(error.localizedDescription, privacy: .public)") + } + } + // Check if we've reached the bottom message + if message.messageId == channel.allPrivateMessages.last?.messageId { + hasReachedBottom = true + showScrollToBottomButton = false } - try context.save() - Logger.data.info("📖 [App] Read message \(message.messageId, privacy: .public) ") - appState.unreadChannelMessages = myInfo.unreadMessages - context.refresh(myInfo, mergeChanges: true) - } catch { - Logger.data.error("Failed to read message \(message.messageId, privacy: .public): \(error.localizedDescription, privacy: .public)") } } } + // Invisible spacer to detect reaching bottom + Color.clear + .frame(height: 1) + .id("bottomAnchor") + .onAppear { + hasReachedBottom = true + showScrollToBottomButton = false + } } } - } - .scrollDismissesKeyboard(.interactively) - .onFirstAppear { - withAnimation { - scrollView.scrollTo(channel.allPrivateMessages.last?.messageId ?? 0, anchor: .bottom) + .scrollDismissesKeyboard(.interactively) + .onFirstAppear { + // Find first unread message + if let firstUnreadMessageId = channel.allPrivateMessages.first(where: { !$0.read })?.messageId { + withAnimation { + scrollView.scrollTo(firstUnreadMessageId, anchor: .top) + showScrollToBottomButton = true + } + } else { + // If no unread messages, scroll to bottom + withAnimation { + scrollView.scrollTo(channel.allPrivateMessages.last?.messageId ?? 0, anchor: .bottom) + hasReachedBottom = true + } + } + gotFirstUnreadMessage = true } - } - .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardDidShowNotification)) { _ in - withAnimation { - scrollView.scrollTo(channel.allPrivateMessages.last?.messageId ?? 0, anchor: .bottom) + .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardDidShowNotification)) { _ in + withAnimation { + scrollView.scrollTo(channel.allPrivateMessages.last?.messageId ?? 0, anchor: .bottom) + hasReachedBottom = true + showScrollToBottomButton = false + } } - } - .onChange(of: channel.allPrivateMessages) { - withAnimation { - scrollView.scrollTo(channel.allPrivateMessages.last?.messageId ?? 0, anchor: .bottom) + .onChange(of: channel.allPrivateMessages) { + if hasReachedBottom { + withAnimation { + scrollView.scrollTo(channel.allPrivateMessages.last?.messageId ?? 0, anchor: .bottom) + } + } else { + showScrollToBottomButton = true + } + } + // Scroll to bottom button + if showScrollToBottomButton { + Button { + withAnimation { + scrollView.scrollTo("bottomAnchor", anchor: .bottom) + hasReachedBottom = true + showScrollToBottomButton = false + } + } label: { + ScrollToBottomButtonView() + } + .padding(.bottom, 8) + .padding(.trailing, 16) + .transition(.opacity) } } } @@ -161,7 +237,7 @@ struct ChannelMessageList: View { ToolbarItem(placement: .principal) { HStack { CircleText(text: String(channel.index), color: .accentColor, circleSize: 44).fixedSize() - Text(String(channel.name ?? "unknown".localized).camelCaseToWords()).font(.headline) + Text(String(channel.name ?? "Unknown".localized).camelCaseToWords()).font(.headline) } } ToolbarItem(placement: .navigationBarTrailing) { diff --git a/Meshtastic/Views/Messages/MessageContextMenuItems.swift b/Meshtastic/Views/Messages/MessageContextMenuItems.swift index 1d8642a0..ca80f80e 100644 --- a/Meshtastic/Views/Messages/MessageContextMenuItems.swift +++ b/Meshtastic/Views/Messages/MessageContextMenuItems.swift @@ -51,7 +51,7 @@ struct MessageContextMenuItems: View { Image(systemName: "doc.on.doc") } - Menu("message.details") { + Menu("Message Details") { VStack { let messageDate = Date(timeIntervalSince1970: TimeInterval(message.messageTimestamp)) Text("\(messageDate.formattedDate(format: MessageText.dateFormatString))").foregroundColor(.gray) @@ -69,8 +69,8 @@ struct MessageContextMenuItems: View { } if isCurrentUser && message.receivedACK { VStack { - Text("received.ack") + Text(": \(message.receivedACK ? "✔️" : "")") - Text("received.ack.real") + Text(": \(message.realACK ? "✔️" : "")") + Text("Received Ack") + Text(": \(message.receivedACK ? "✔️" : "")") + Text("Recipient Ack") + Text(": \(message.realACK ? "✔️" : "")") } } else if isCurrentUser && message.ackError == 0 { // Empty Error @@ -104,7 +104,7 @@ struct MessageContextMenuItems: View { Button(role: .destructive) { isShowingDeleteConfirmation = true } label: { - Text("delete") + Text("Delete") Image(systemName: "trash") } } diff --git a/Meshtastic/Views/Messages/MessageText.swift b/Meshtastic/Views/Messages/MessageText.swift index 002d2c4c..c8a994c3 100644 --- a/Meshtastic/Views/Messages/MessageText.swift +++ b/Meshtastic/Views/Messages/MessageText.swift @@ -73,7 +73,6 @@ struct MessageText: View { } else { EmptyView() } - } .contextMenu { MessageContextMenuItems( diff --git a/Meshtastic/Views/Messages/Messages.swift b/Meshtastic/Views/Messages/Messages.swift index 1267d3e2..cb6947c0 100644 --- a/Meshtastic/Views/Messages/Messages.swift +++ b/Meshtastic/Views/Messages/Messages.swift @@ -35,7 +35,7 @@ struct Messages: View { List(selection: $router.navigationState.messages) { NavigationLink(value: MessagesNavigationState.channels()) { Label { - Text("channels") + Text("Channels") .badge(unreadChannelMessages) .font(.title2) .padding() @@ -50,7 +50,7 @@ struct Messages: View { } NavigationLink(value: MessagesNavigationState.directMessages()) { Label { - Text("direct.messages") + Text("Direct Messages") .badge(unreadDirectMessages) .font(.title2) .padding() @@ -65,7 +65,7 @@ struct Messages: View { TipView(MessagesTip(), arrowEdge: .top) } - .navigationTitle("messages") + .navigationTitle("Messages") .navigationBarTitleDisplayMode(.large) .navigationBarItems(leading: MeshtasticLogo()) } content: { diff --git a/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift b/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift index c8def69b..d60a0381 100644 --- a/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift +++ b/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift @@ -15,78 +15,93 @@ struct TextMessageField: View { @State private var sendPositionWithMessage = false var body: some View { - #if targetEnvironment(macCatalyst) - HStack { - if destination.showAlertButton { + VStack { + #if targetEnvironment(macCatalyst) + HStack { + if destination.showAlertButton { + Spacer() + AlertButton { typingMessage += "🔔 Alert Bell! \u{7}" } + } Spacer() - AlertButton { typingMessage += "🔔 Alert Bell! \u{7}" } + RequestPositionButton(action: requestPosition) + TextMessageSize(maxbytes: Self.maxbytes, totalBytes: totalBytes).padding(.trailing) } - Spacer() - RequestPositionButton(action: requestPosition) - TextMessageSize(maxbytes: Self.maxbytes, totalBytes: totalBytes).padding(.trailing) - } - #endif + #endif - HStack(alignment: .top) { - ZStack { - TextField("message", text: $typingMessage, axis: .vertical) - .onChange(of: typingMessage) { _, value in - totalBytes = value.utf8.count - // Only mess with the value if it is too big - while totalBytes > Self.maxbytes { - typingMessage = String(typingMessage.dropLast()) - totalBytes = typingMessage.utf8.count - } - } - .keyboardType(.default) - .toolbar { - ToolbarItemGroup(placement: .keyboard) { - Button("Dismiss") { - isFocused = false + HStack(alignment: .top) { + if replyMessageId != 0 { + HStack { + Button { + withAnimation(.easeInOut(duration: 0.2)) { + replyMessageId = 0 } - .font(.subheadline) + isFocused = false + } label: { + Image(systemName: "x.circle.fill") + } + Text("Replying to a message") + } + } + + ZStack { + TextField("Message", text: $typingMessage, axis: .vertical) + .onChange(of: typingMessage) { _, value in + totalBytes = value.utf8.count + while totalBytes > Self.maxbytes { + typingMessage = String(typingMessage.dropLast()) + totalBytes = typingMessage.utf8.count + } + } + .keyboardType(.default) + .toolbar { + ToolbarItemGroup(placement: .keyboard) { + Button("Dismiss") { + isFocused = false + } + .font(.subheadline) + + if destination.showAlertButton { + Spacer() + AlertButton { typingMessage += "🔔 Alert Bell Character! \u{7}" } + } - if destination.showAlertButton { Spacer() - AlertButton { typingMessage += "🔔 Alert Bell Character! \u{7}" } + RequestPositionButton(action: requestPosition) + TextMessageSize(maxbytes: Self.maxbytes, totalBytes: totalBytes) } - - Spacer() - RequestPositionButton(action: requestPosition) - TextMessageSize(maxbytes: Self.maxbytes, totalBytes: totalBytes) } - } - .padding(.horizontal, 8) - .focused($isFocused) - .multilineTextAlignment(.leading) - .frame(minHeight: 50) - .keyboardShortcut(.defaultAction) - .onSubmit { - #if targetEnvironment(macCatalyst) - sendMessage() - #endif - } + .padding(.horizontal, 8) + .focused($isFocused) + .multilineTextAlignment(.leading) + .frame(minHeight: 50) + .keyboardShortcut(.defaultAction) + .onSubmit { + #if targetEnvironment(macCatalyst) + sendMessage() + #endif + } - Text(typingMessage) - .opacity(0) - .padding(.all, 0) - } - .overlay(RoundedRectangle(cornerRadius: 20).stroke(.tertiary, lineWidth: 1)) - .padding(.bottom, 15) + Text(typingMessage) + .opacity(0) + .padding(.all, 0) + } + .overlay(RoundedRectangle(cornerRadius: 20).stroke(.tertiary, lineWidth: 1)) + .padding(.bottom, 15) - Button(action: sendMessage) { - Image(systemName: "arrow.up.circle.fill") - .font(.largeTitle) - .foregroundColor(.accentColor) + Button(action: sendMessage) { + Image(systemName: "arrow.up.circle.fill") + .font(.largeTitle) + .foregroundColor(.accentColor) + } } + .padding(.all, 15) } - .padding(.all, 15) } private func requestPosition() { let userLongName = bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown" sendPositionWithMessage = true - typingMessage = "📍 " + userLongName + " \(destination.positionShareMessage)." + typingMessage = "📍 " + userLongName + " \(destination.positionShareMessage)." } private func sendMessage() { diff --git a/Meshtastic/Views/Messages/UserList.swift b/Meshtastic/Views/Messages/UserList.swift index b0602d5f..7e57ce8c 100644 --- a/Meshtastic/Views/Messages/UserList.swift +++ b/Meshtastic/Views/Messages/UserList.swift @@ -93,7 +93,7 @@ struct UserList: View { Image(systemName: "lock.open.fill") .foregroundColor(.yellow) } - Text(user.longName ?? "unknown".localized) + Text(user.longName ?? "Unknown".localized) .font(.headline) .allowsTightening(true) Spacer() @@ -187,14 +187,14 @@ struct UserList: View { deleteUserMessages(user: userSelection!, context: context) context.refresh(node!.user!, mergeChanges: true) } label: { - Text("delete") + Text("Delete") } } } } } .listStyle(.plain) - .navigationTitle(String.localizedStringWithFormat("contacts %@".localized, String(users.count == 0 ? 0 : users.count))) + .navigationTitle(String.localizedStringWithFormat("Contacts (%@)".localized, String(users.count == 0 ? 0 : users.count))) .sheet(isPresented: $editingFilters) { NodeListFilter(filterTitle: "Contact Filters", viaLora: $viaLora, viaMqtt: $viaMqtt, isOnline: $isOnline, isPkiEncrypted: $isPkiEncrypted, isFavorite: $isFavorite, isIgnored: $isIgnored, isEnvironment: $isEnvironment, distanceFilter: $distanceFilter, maximumDistance: $maxDistance, hopsAway: $hopsAway, roleFilter: $roleFilter, deviceRoles: $deviceRoles) } diff --git a/Meshtastic/Views/Messages/UserMessageList.swift b/Meshtastic/Views/Messages/UserMessageList.swift index dea4586f..f03811a5 100644 --- a/Meshtastic/Views/Messages/UserMessageList.swift +++ b/Meshtastic/Views/Messages/UserMessageList.swift @@ -20,115 +20,194 @@ struct UserMessageList: View { // View State Items @ObservedObject var user: UserEntity @State private var replyMessageId: Int64 = 0 + // Scroll state + @State private var showScrollToBottomButton = false + @State private var hasReachedBottom = false + @State private var gotFirstUnreadMessage: Bool = false + + @State private var messageToHighlight: Int64 = 0 var body: some View { VStack { ScrollViewReader { scrollView in - ScrollView { - LazyVStack { - ForEach( user.messageList ) { (message: MessageEntity) in - if user.num != bleManager.connectedPeripheral?.num ?? -1 { - let currentUser: Bool = (Int64(UserDefaults.preferredPeripheralNum) == message.fromUser?.num ?? -1 ? true : false) + ZStack(alignment: .bottomTrailing) { + ScrollView { + LazyVStack { + ForEach( user.messageList ) { (message: MessageEntity) in + if user.num != bleManager.connectedPeripheral?.num ?? -1 { + let currentUser: Bool = (Int64(UserDefaults.preferredPeripheralNum) == message.fromUser?.num ?? -1 ? true : false) - if message.replyID > 0 { - let messageReply = user.messageList.first(where: { $0.messageId == message.replyID }) - HStack { - Text(messageReply?.messagePayload ?? "EMPTY MESSAGE").foregroundColor(.accentColor).font(.caption2) - .padding(10) - .overlay( - RoundedRectangle(cornerRadius: 18) - .stroke(Color.blue, lineWidth: 0.5) - ) - Image(systemName: "arrowshape.turn.up.left.fill") - .symbolRenderingMode(.hierarchical) - .imageScale(.large).foregroundColor(.accentColor) - .padding(.trailing) - } - } - HStack(alignment: .top) { - if currentUser { Spacer(minLength: 50) } - VStack(alignment: currentUser ? .trailing : .leading) { + if message.replyID > 0 { + let messageReply = user.messageList.first(where: { $0.messageId == message.replyID }) HStack { - MessageText( - message: message, - tapBackDestination: .user(user), - isCurrentUser: currentUser - ) { - self.replyMessageId = message.messageId - self.messageFieldFocused = true - } + Button { + if let messageNum = messageReply?.messageId { + withAnimation(.easeInOut(duration: 0.5)) { + messageToHighlight = messageNum + } + scrollView.scrollTo(messageNum, anchor: .center) - if currentUser && message.canRetry || (message.receivedACK && !message.realACK) { - RetryButton(message: message, destination: .user(user)) - } - } - - TapbackResponses(message: message) { - appState.unreadDirectMessages = user.unreadMessages - } - - HStack { - let ackErrorVal = RoutingError(rawValue: Int(message.ackError)) - if currentUser && message.receivedACK { - // Ack Received - if message.realACK { - Text("\(ackErrorVal?.display ?? "Empty Ack Error")") - .font(.caption2) - .foregroundStyle(ackErrorVal?.color ?? Color.secondary) - } else { - Text("Acknowledged by another node").font(.caption2).foregroundColor(.orange) + // Reset highlight after delay + Task { + try? await Task.sleep(nanoseconds: 1_000_000_000) // 1 second + withAnimation(.easeInOut(duration: 0.5)) { + messageToHighlight = -1 + } + } } - } else if currentUser && message.ackError == 0 { - // Empty Error - Text("Waiting to be acknowledged. . .").font(.caption2).foregroundColor(.yellow) - } else if currentUser && message.ackError > 0 { - Text("\(ackErrorVal?.display ?? "Empty Ack Error")").fixedSize(horizontal: false, vertical: true) - .foregroundStyle(ackErrorVal?.color ?? Color.red) - .font(.caption2) + } label: { + Text(messageReply?.messagePayload ?? "EMPTY MESSAGE").foregroundColor(.accentColor).font(.caption2) + .padding(10) + .overlay( + RoundedRectangle(cornerRadius: 18) + .stroke(Color.blue, lineWidth: 0.5) + ) + Image(systemName: "arrowshape.turn.up.left.fill") + .symbolRenderingMode(.hierarchical) + .imageScale(.large).foregroundColor(.accentColor) + .padding(.trailing) } } } - .padding(.bottom) - .id(user.messageList.firstIndex(of: message)) + HStack(alignment: .top) { + if currentUser { Spacer(minLength: 50) } + VStack(alignment: currentUser ? .trailing : .leading) { + HStack { + MessageText( + message: message, + tapBackDestination: .user(user), + isCurrentUser: currentUser + ) { + self.replyMessageId = message.messageId + self.messageFieldFocused = true + } - if !currentUser { - Spacer(minLength: 50) + if currentUser && message.canRetry || (message.receivedACK && !message.realACK) { + RetryButton(message: message, destination: .user(user)) + } + } + + TapbackResponses(message: message) { + appState.unreadDirectMessages = user.unreadMessages + } + + HStack { + let ackErrorVal = RoutingError(rawValue: Int(message.ackError)) + if currentUser && message.receivedACK { + // Ack Received + if message.realACK { + Text("\(ackErrorVal?.display ?? "Empty Ack Error")") + .font(.caption2) + .foregroundStyle(ackErrorVal?.color ?? Color.secondary) + } else { + Text("Acknowledged by another node").font(.caption2).foregroundColor(.orange) + } + } else if currentUser && message.ackError == 0 { + // Empty Error + Text("Waiting to be acknowledged. . .").font(.caption2).foregroundColor(.yellow) + } else if currentUser && message.ackError > 0 { + Text("\(ackErrorVal?.display ?? "Empty Ack Error")").fixedSize(horizontal: false, vertical: true) + .foregroundStyle(ackErrorVal?.color ?? Color.red) + .font(.caption2) + } + } + } + .padding(.bottom) + .id(user.messageList.firstIndex(of: message)) + + if !currentUser { + Spacer(minLength: 50) + } } - } - .padding([.leading, .trailing]) - .frame(maxWidth: .infinity) - .id(message.messageId) - .onAppear { - if !message.read { - message.read = true - do { - try context.save() - Logger.data.info("📖 [App] Read message \(message.messageId, privacy: .public) ") - appState.unreadDirectMessages = user.unreadMessages - - } catch { - Logger.data.error("Failed to read message \(message.messageId, privacy: .public): \(error.localizedDescription, privacy: .public)") + .overlay { + RoundedRectangle(cornerRadius: 10) + .stroke(.blue, lineWidth: 2) + .opacity(((messageToHighlight == message.messageId) || (replyMessageId == message.messageId)) ? 1 : 0) + } + .padding([.leading, .trailing]) + .frame(maxWidth: .infinity) + .id(message.messageId) + .onAppear { + if gotFirstUnreadMessage { + if !message.read { + message.read = true + do { + for unreadMessage in user.messageList.filter({ !$0.read }) { + unreadMessage.read = true + } + try context.save() + Logger.data.info("📖 [App] Read message \(message.messageId, privacy: .public) ") + appState.unreadDirectMessages = user.unreadMessages + } catch { + Logger.data.error("Failed to read message \(message.messageId, privacy: .public): \(error.localizedDescription, privacy: .public)") + } + } + // Check if we've reached the bottom message + if message.messageId == user.messageList.last?.messageId { + hasReachedBottom = true + showScrollToBottomButton = false + } } } } } + // Invisible spacer to detect reaching bottom + Color.clear + .frame(height: 1) + .id("bottomAnchor") + .onAppear { + hasReachedBottom = true + showScrollToBottomButton = false + } } } - } - .scrollDismissesKeyboard(.interactively) - .onFirstAppear { - withAnimation { - scrollView.scrollTo(user.messageList.last?.messageId ?? 0, anchor: .bottom) + .scrollDismissesKeyboard(.interactively) + .onFirstAppear { + // Find first unread message + if let firstUnreadMessageId = user.messageList.first(where: { !$0.read })?.messageId { + withAnimation { + scrollView.scrollTo(firstUnreadMessageId, anchor: .top) + showScrollToBottomButton = true + } + } else { + // If no unread messages, scroll to bottom + withAnimation { + scrollView.scrollTo(user.messageList.last?.messageId ?? 0, anchor: .bottom) + hasReachedBottom = true + } + } + gotFirstUnreadMessage = true } - } - .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardDidShowNotification)) { _ in - withAnimation { - scrollView.scrollTo(user.messageList.last?.messageId ?? 0, anchor: .bottom) + .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardDidShowNotification)) { _ in + withAnimation { + scrollView.scrollTo(user.messageList.last?.messageId ?? 0, anchor: .bottom) + hasReachedBottom = true + showScrollToBottomButton = false + } } - } - .onChange(of: user.messageList) { - withAnimation { - scrollView.scrollTo(user.messageList.last?.messageId ?? 0, anchor: .bottom) + .onChange(of: user.messageList) { + if hasReachedBottom { + withAnimation { + scrollView.scrollTo(user.messageList.last?.messageId ?? 0, anchor: .bottom) + } + } else { + showScrollToBottomButton = true + } + } + // Scroll to bottom button + if showScrollToBottomButton { + Button { + withAnimation { + scrollView.scrollTo("bottomAnchor", anchor: .bottom) + hasReachedBottom = true + showScrollToBottomButton = false + } + } label: { + ScrollToBottomButtonView() + } + .padding(.bottom, 8) + .padding(.trailing, 16) + .transition(.opacity) } } } diff --git a/Meshtastic/Views/Nodes/DetectionSensorLog.swift b/Meshtastic/Views/Nodes/DetectionSensorLog.swift index 89c62be3..e4c22e0d 100644 --- a/Meshtastic/Views/Nodes/DetectionSensorLog.swift +++ b/Meshtastic/Views/Nodes/DetectionSensorLog.swift @@ -110,7 +110,7 @@ struct DetectionSensorLog: View { exportString = detectionsToCsv(detections: chartData) isExporting = true } label: { - Label("save", systemImage: "square.and.arrow.down") + Label("Save", systemImage: "square.and.arrow.down") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) @@ -118,7 +118,7 @@ struct DetectionSensorLog: View { .padding(.bottom) .padding(.trailing) } - .navigationTitle("detection.sensor.log") + .navigationTitle("Detection Sensor Log") .navigationBarTitleDisplayMode(.inline) .navigationBarItems(trailing: ZStack { @@ -128,7 +128,7 @@ struct DetectionSensorLog: View { isPresented: $isExporting, document: CsvDocument(emptyCsv: exportString), contentType: .commaSeparatedText, - defaultFilename: String("\(node.user?.longName ?? "Node") \("detection.sensor.log".localized)"), + defaultFilename: String("\(node.user?.longName ?? "Node") \("Detection Sensor Log".localized)"), onCompletion: { result in switch result { case .success: diff --git a/Meshtastic/Views/Nodes/DeviceMetricsLog.swift b/Meshtastic/Views/Nodes/DeviceMetricsLog.swift index 9ebce292..e7b4c952 100644 --- a/Meshtastic/Views/Nodes/DeviceMetricsLog.swift +++ b/Meshtastic/Views/Nodes/DeviceMetricsLog.swift @@ -121,7 +121,7 @@ struct DeviceMetricsLog: View { Table(deviceMetrics, selection: $selection, sortOrder: $sortOrder) { TableColumn("Battery Level") { dm in HStack { - Text(dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized) + Text(dm.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized) .font(.caption) .fontWeight(.semibold) Spacer() @@ -165,7 +165,7 @@ struct DeviceMetricsLog: View { // dm.voltage.map { Text("\(String(format: "%.2f", $0))") } ?? Text("--") Text("\(dm.voltage?.formatted(.number.precision(.fractionLength(2))) ?? Constants.nilValueIndicator)") } - TableColumn("channel.utilization") { dm in + TableColumn("Channel Utilization") { dm in dm.channelUtilization.map { channelUtilization in // Text("\(String(format: "%.2f", channelUtilization))%") Text("\(channelUtilization.formatted(.number.precision(.fractionLength(2))))%") @@ -188,7 +188,7 @@ struct DeviceMetricsLog: View { } .width(min: 100) TableColumn("Timestamp") { dm in - Text(dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized) + Text(dm.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized) } .width(min: 180) } @@ -209,7 +209,7 @@ struct DeviceMetricsLog: View { isPresented: $isPresentingClearLogConfirm, titleVisibility: .visible ) { - Button("device.metrics.delete", role: .destructive) { + Button("Delete all device metrics?", role: .destructive) { if clearTelemetry(destNum: node.num, metricsType: 0, context: context) { Logger.data.notice("Cleared Device Metrics for \(node.num, privacy: .public)") } else { @@ -222,7 +222,7 @@ struct DeviceMetricsLog: View { exportString = telemetryToCsvFile(telemetry: deviceMetrics, metricsType: 0) isExporting = true } label: { - Label("save", systemImage: "square.and.arrow.down") + Label("Save", systemImage: "square.and.arrow.down") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) @@ -240,7 +240,7 @@ struct DeviceMetricsLog: View { ContentUnavailableView("No Device Metrics", systemImage: "slash.circle") } } - .navigationTitle("device.metrics.log") + .navigationTitle("Device Metrics Log") .navigationBarTitleDisplayMode(.inline) .navigationBarItems(trailing: ZStack { @@ -250,7 +250,7 @@ struct DeviceMetricsLog: View { isPresented: $isExporting, document: CsvDocument(emptyCsv: exportString), contentType: .commaSeparatedText, - defaultFilename: String("\(node.user?.longName ?? "Node") \("device.metrics.log".localized)"), + defaultFilename: String("\(node.user?.longName ?? "Node") \("Device Metrics Log".localized)"), onCompletion: { result in switch result { case .success: diff --git a/Meshtastic/Views/Nodes/EnvironmentMetricsLog.swift b/Meshtastic/Views/Nodes/EnvironmentMetricsLog.swift index 7ae9bc50..160f3ef7 100644 --- a/Meshtastic/Views/Nodes/EnvironmentMetricsLog.swift +++ b/Meshtastic/Views/Nodes/EnvironmentMetricsLog.swift @@ -145,7 +145,7 @@ struct EnvironmentMetricsLog: View { exportString = telemetryToCsvFile(telemetry: environmentMetrics, metricsType: 1) isExporting = true } label: { - Label("save", systemImage: "square.and.arrow.down") + Label("Save", systemImage: "square.and.arrow.down") .imageScale(imageScale) } .buttonStyle(.bordered) diff --git a/Meshtastic/Views/Nodes/Helpers/Actions/DeleteNodeButton.swift b/Meshtastic/Views/Nodes/Helpers/Actions/DeleteNodeButton.swift index 127a31d7..c5495c10 100644 --- a/Meshtastic/Views/Nodes/Helpers/Actions/DeleteNodeButton.swift +++ b/Meshtastic/Views/Nodes/Helpers/Actions/DeleteNodeButton.swift @@ -49,7 +49,7 @@ struct DeleteNodeButton: View { connectedNodeNum: connectedNode.num ) if !success { - Logger.data.error("Failed to delete node \(deleteNode.user?.longName ?? "unknown".localized, privacy: .public)") + Logger.data.error("Failed to delete node \(deleteNode.user?.longName ?? "Unknown".localized, privacy: .public)") } else { dismiss() } diff --git a/Meshtastic/Views/Nodes/Helpers/Actions/NavigateToButton.swift b/Meshtastic/Views/Nodes/Helpers/Actions/NavigateToButton.swift index 78917082..403d1b98 100644 --- a/Meshtastic/Views/Nodes/Helpers/Actions/NavigateToButton.swift +++ b/Meshtastic/Views/Nodes/Helpers/Actions/NavigateToButton.swift @@ -14,45 +14,43 @@ struct NavigateToButton: View { var node: NodeInfoEntity var body: some View { - Button { - guard let userNum = node.user?.num else { - Logger.services.error("NavigateToAction: Selected node does not exist") + Button { + guard let userNum = node.user?.num else { + Logger.services.error("NavigateToAction: Selected node does not exist") + return + } + Logger.services.info("Fetching NodeInfoEntity for userNum: \(userNum, privacy: .public)") + + let fetchRequest: NSFetchRequest = NSFetchRequest(entityName: "NodeInfoEntity") + fetchRequest.predicate = NSPredicate(format: "num == %lld", Int64(userNum)) + + do { + let fetchedNodes = try PersistenceController.shared.container.viewContext.fetch(fetchRequest) + guard let nodeInfo = fetchedNodes.first else { + Logger.services.error("NavigateToAction: Node with userNum \(userNum, privacy: .public) not found in Core Data") return } - - Logger.services.info("Fetching NodeInfoEntity for userNum: \(userNum, privacy: .public)") - - let fetchRequest: NSFetchRequest = NSFetchRequest(entityName: "NodeInfoEntity") - fetchRequest.predicate = NSPredicate(format: "num == %lld", Int64(userNum)) - - do { - let fetchedNodes = try PersistenceController.shared.container.viewContext.fetch(fetchRequest) - - guard let nodeInfo = fetchedNodes.first else { - Logger.services.error("NavigateToAction: Node with userNum \(userNum, privacy: .public) not found in Core Data") - return - } - if let latitude = nodeInfo.latestPosition?.latitude, - let longitude = nodeInfo.latestPosition?.longitude { - if let url = URL(string: "maps://?saddr=&daddr=\(latitude),\(longitude)") { - UIApplication.shared.open(url, options: [:], completionHandler: nil) - } else { - Logger.services.error("Failed to create URL for navigation") - } + if let latitude = nodeInfo.latestPosition?.latitude, + let longitude = nodeInfo.latestPosition?.longitude { + if let url = URL(string: "maps://?saddr=&daddr=\(latitude),\(longitude)") { + UIApplication.shared.open(url, options: [:], completionHandler: nil) } else { - Logger.services.warning("NavigateToAction: Node \(userNum, privacy: .public) has invalid or missing coordinates") + Logger.services.error("Failed to create URL for navigation") } - } catch { - Logger.services.error("NavigateToAction: Failed to fetch node with userNum \(userNum, privacy: .public): \(error.localizedDescription, privacy: .public)") - } - } label: { - Label { - Text("Navigate to node") - } icon: { - Image(systemName: "map") - .symbolRenderingMode(.hierarchical) + } else { + Logger.services.warning("NavigateToAction: Node \(userNum, privacy: .public) has invalid or missing coordinates") } + } catch { + Logger.services.error("NavigateToAction: Failed to fetch node with userNum \(userNum, privacy: .public): \(error.localizedDescription, privacy: .public)") + } + } label: { + Label { + Text("Navigate to node") + } icon: { + Image(systemName: "map") + .symbolRenderingMode(.hierarchical) } } + } } diff --git a/Meshtastic/Views/Nodes/Helpers/Map/MapContent/MeshMapContent.swift b/Meshtastic/Views/Nodes/Helpers/Map/MapContent/MeshMapContent.swift index 6a0374f2..4bce572c 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/MapContent/MeshMapContent.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/MapContent/MeshMapContent.swift @@ -20,7 +20,7 @@ struct MeshMapContent: MapContent { @Binding var selectedMapLayer: MapLayer // Map Configuration @Binding var selectedPosition: PositionEntity? - @AppStorage("enableMapWaypoints") private var showWaypoints = false + @AppStorage("enableMapWaypoints") private var showWaypoints = true @Binding var selectedWaypoint: WaypointEntity? @FetchRequest(fetchRequest: PositionEntity.allPositionsFetchRequest(), animation: .easeIn) @@ -74,9 +74,9 @@ struct MeshMapContent: MapContent { } } } - .onTapGesture { _ in + .highPriorityGesture(TapGesture().onEnded { _ in selectedPosition = (selectedPosition == position ? nil : position) - } + }) } /// Node History and Route Lines for favorites if let nodePosition = position.nodePosition, @@ -186,7 +186,7 @@ struct MeshMapContent: MapContent { LazyVStack { ZStack { CircleText(text: String(UnicodeScalar(Int(waypoint.icon)) ?? "📍"), color: Color.orange, circleSize: 40) - .onTapGesture(perform: { _ in + .highPriorityGesture(TapGesture().onEnded { _ in selectedWaypoint = (selectedWaypoint == waypoint ? nil : waypoint) }) } diff --git a/Meshtastic/Views/Nodes/Helpers/Map/MapContent/NodeMapContent.swift b/Meshtastic/Views/Nodes/Helpers/Map/MapContent/NodeMapContent.swift index c9fbf95a..2d157979 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/MapContent/NodeMapContent.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/MapContent/NodeMapContent.swift @@ -16,7 +16,7 @@ struct NodeMapContent: MapContent { /// Map State User Defaults @AppStorage("meshMapShowNodeHistory") private var showNodeHistory = false @AppStorage("meshMapShowRouteLines") private var showRouteLines = false - @AppStorage("enableMapWaypoints") private var showWaypoints = false + @AppStorage("enableMapWaypoints") private var showWaypoints = true @AppStorage("enableMapConvexHull") private var showConvexHull = false @AppStorage("enableMapTraffic") private var showTraffic: Bool = false @AppStorage("enableMapPointsOfInterest") private var showPointsOfInterest: Bool = false diff --git a/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift b/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift index 088787b9..85db444a 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift @@ -111,7 +111,7 @@ Spacer() Button { dismiss() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) diff --git a/Meshtastic/Views/Nodes/Helpers/Map/NodeMapSwiftUI.swift b/Meshtastic/Views/Nodes/Helpers/Map/NodeMapSwiftUI.swift index 36d9a915..f5a2f84c 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/NodeMapSwiftUI.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/NodeMapSwiftUI.swift @@ -189,7 +189,7 @@ struct NodeMapSwiftUI: View { UIApplication.shared.isIdleTimerDisabled = false } }} - .navigationBarTitle(String((node.user?.shortName ?? "unknown".localized) + (" \(node.positions?.count ?? 0) points")), displayMode: .inline) + .navigationBarTitle(String((node.user?.shortName ?? "Unknown".localized) + (" \(node.positions?.count ?? 0) points")), displayMode: .inline) .navigationBarItems(trailing: ZStack { ConnectedDevice( diff --git a/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift b/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift index f68354c0..d3ef18a3 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift @@ -23,10 +23,10 @@ struct PositionPopover: View { var body: some View { // Node Color from node.num let nodeColor = UIColor(hex: UInt32(position.nodePosition?.num ?? 0)) + NavigationStack { VStack { HStack { ZStack { - if position.nodePosition?.isOnline ?? false { Circle() .fill(Color(nodeColor.lighter()).opacity(0.4).shadow(.drop(color: Color(nodeColor).isLight() ? .black : .white, radius: 5))) @@ -34,16 +34,15 @@ struct PositionPopover: View { .scaleEffect(scale) .animation( Animation.easeInOut(duration: 0.6) - .repeatForever().delay(delay), value: scale + .repeatForever().delay(delay), value: scale ) .onAppear { self.scale = 1 } .frame(width: 90, height: 90) } - CircleText(text: position.nodePosition?.user?.shortName ?? "?", color: Color(nodeColor), circleSize: 65) + CircleText(text: position.nodePosition?.user?.shortName ?? "?", color: Color(nodeColor), circleSize: 65, node: getNodeInfo(id: Int64(position.nodePosition?.user?.num ?? 0), context: context)) } - Text(position.nodePosition?.user?.longName ?? "Unknown") .font(.largeTitle) } @@ -53,7 +52,7 @@ struct PositionPopover: View { /// Time Label { if idiom != .phone { - Text("heard".localized + ":") + Text("Heard".localized + ":") } Text(position.time?.lastHeard ?? "unknown") .foregroundColor(.primary) @@ -106,7 +105,6 @@ struct PositionPopover: View { .foregroundColor(.primary) .font(idiom == .phone ? .callout : .body) } - } icon: { Image(systemName: "mountain.2.fill") .symbolRenderingMode(.hierarchical) @@ -147,9 +145,9 @@ struct PositionPopover: View { Text("Heading: \(heading.formatted(.measurement(width: .narrow, numberFormatStyle: .number.precision(.fractionLength(0)))))") } icon: { Image(systemName: "location.north") - .symbolRenderingMode(.hierarchical) - .frame(width: 35) - .rotationEffect(degrees) + .symbolRenderingMode(.hierarchical) + .frame(width: 35) + .rotationEffect(degrees) } .padding(.bottom, 5) /// Distance @@ -181,15 +179,14 @@ struct PositionPopover: View { } .padding(.bottom, 5) if position.nodePosition?.viaMqtt ?? false { - Label { Text("MQTT") .font(idiom == .phone ? .callout : .body) } icon: { Image(systemName: "network") - .symbolRenderingMode(.hierarchical) - .frame(width: 35) - .rotationEffect(degrees) + .symbolRenderingMode(.hierarchical) + .frame(width: 35) + .rotationEffect(degrees) } .padding(.bottom, 5) } @@ -235,7 +232,7 @@ struct PositionPopover: View { Button { dismiss() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) @@ -244,6 +241,7 @@ struct PositionPopover: View { #endif } } + } .presentationDetents([.fraction(0.65), .large]) .presentationContentInteraction(.scrolls) .presentationDragIndicator(.visible) diff --git a/Meshtastic/Views/Nodes/Helpers/Map/WaypointForm.swift b/Meshtastic/Views/Nodes/Helpers/Map/WaypointForm.swift index 8c8feb32..ad342cbc 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/WaypointForm.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/WaypointForm.swift @@ -134,40 +134,44 @@ struct WaypointForm: View { .scrollDismissesKeyboard(.immediately) HStack { Button { - /// Send a new or exiting waypoint - var newWaypoint = Waypoint() - if waypoint.id == 0 { - newWaypoint.id = UInt32.random(in: UInt32(UInt8.max).. 0 ? name : "Dropped Pin" - newWaypoint.description_p = description - // Unicode scalar value for the icon emoji string - let unicodeScalers = icon.unicodeScalars - // First element as an UInt32 - let unicode = unicodeScalers[unicodeScalers.startIndex].value - newWaypoint.icon = unicode - if locked { - if lockedTo == 0 { - newWaypoint.lockedTo = UInt32(bleManager.connectedPeripheral!.num) + if bleManager.isConnected { + /// Send a new or exiting waypoint + var newWaypoint = Waypoint() + if waypoint.id == 0 { + newWaypoint.id = UInt32.random(in: UInt32(UInt8.max).. 0 ? name : "Dropped Pin" + newWaypoint.description_p = description + // Unicode scalar value for the icon emoji string + let unicodeScalers = icon.unicodeScalars + // First element as an UInt32 + let unicode = unicodeScalers[unicodeScalers.startIndex].value + newWaypoint.icon = unicode + if locked { + if lockedTo == 0 { + newWaypoint.lockedTo = UInt32(bleManager.connectedPeripheral!.num) + } else { + newWaypoint.lockedTo = UInt32(lockedTo) + } + } + if expires { + newWaypoint.expire = UInt32(expire.timeIntervalSince1970) + } else { + newWaypoint.expire = 0 + } + if bleManager.sendWaypoint(waypoint: newWaypoint) { + dismiss() + } else { + dismiss() + Logger.mesh.warning("Send waypoint failed") } - } - if expires { - newWaypoint.expire = UInt32(expire.timeIntervalSince1970) } else { - newWaypoint.expire = 0 - } - if bleManager.sendWaypoint(waypoint: newWaypoint) { - dismiss() - } else { - dismiss() - Logger.mesh.warning("Send waypoint failed") + Logger.mesh.warning("Send waypoint failed, node not connected") } } label: { Label("Send", systemImage: "arrow.up") @@ -235,7 +239,7 @@ struct WaypointForm: View { }) } label: { - Label("delete", systemImage: "trash") + Label("Delete", systemImage: "trash") .foregroundColor(.red) } .buttonStyle(.bordered) @@ -338,7 +342,7 @@ struct WaypointForm: View { if LocationsHandler.currentLocation.distance(from: LocationsHandler.DefaultLocation) > 0.0 { let metersAway = waypoint.coordinate.distance(from: LocationsHandler.currentLocation) Label { - Text("distance".localized + ": \(distanceFormatter.string(fromDistance: Double(metersAway)))") + Text("Distance".localized + ": \(distanceFormatter.string(fromDistance: Double(metersAway)))") .foregroundColor(.primary) } icon: { Image(systemName: "lines.measurement.horizontal") @@ -354,7 +358,7 @@ struct WaypointForm: View { Button { dismiss() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) @@ -364,6 +368,18 @@ struct WaypointForm: View { } } } + .onDisappear { + if waypoint.id == 0 { + // New, unsent waypoint created by the user: delete it + bleManager.context.delete(waypoint) + do { + try bleManager.context.save() + } catch { + bleManager.context.rollback() + Logger.mesh.error("Failed to save context on waypoint deletion: \(error)") + } + } + } .onAppear { if waypoint.id > 0 { let waypoint = getWaypoint(id: Int64(waypoint.id), context: bleManager.context) diff --git a/Meshtastic/Views/Nodes/Helpers/Metrics Columns/EnvironmentDefaultColumns.swift b/Meshtastic/Views/Nodes/Helpers/Metrics Columns/EnvironmentDefaultColumns.swift index ffd86987..0f14331d 100644 --- a/Meshtastic/Views/Nodes/Helpers/Metrics Columns/EnvironmentDefaultColumns.swift +++ b/Meshtastic/Views/Nodes/Helpers/Metrics Columns/EnvironmentDefaultColumns.swift @@ -220,7 +220,6 @@ extension MetricsColumnList { ) } ?? Text(Constants.nilValueIndicator) }), - // Rainfall 24-hour MetricsTableColumn( id: "rainfall24H", @@ -334,7 +333,7 @@ extension MetricsColumnList { .replacingOccurrences(of: ",", with: "") Text( time?.formattedDate(format: dateFormatString) - ?? "unknown.age".localized + ?? "Unknown Age".localized ) }) ]) diff --git a/Meshtastic/Views/Nodes/Helpers/Metrics Columns/EnvironmentDefaultSeries.swift b/Meshtastic/Views/Nodes/Helpers/Metrics Columns/EnvironmentDefaultSeries.swift index d3762845..b2590b51 100644 --- a/Meshtastic/Views/Nodes/Helpers/Metrics Columns/EnvironmentDefaultSeries.swift +++ b/Meshtastic/Views/Nodes/Helpers/Metrics Columns/EnvironmentDefaultSeries.swift @@ -80,7 +80,7 @@ extension MetricsSeriesList { .alignsMarkStylesWithPlotArea() } }), - + // Barometric Pressure Series Configuration MetricsChartSeries( id: "barometricPressure", @@ -106,7 +106,7 @@ extension MetricsSeriesList { .alignsMarkStylesWithPlotArea() } }), - + // Indoor Air Quality Series Configuration MetricsChartSeries( id: "iaq", @@ -134,7 +134,7 @@ extension MetricsSeriesList { .alignsMarkStylesWithPlotArea() } }), - + // Lux MetricsChartSeries( id: "lux", @@ -460,7 +460,7 @@ extension MetricsSeriesList { .lineStyle(StrokeStyle(lineWidth: 4)) .alignsMarkStylesWithPlotArea() } - }), + }) ]) } } diff --git a/Meshtastic/Views/Nodes/Helpers/Metrics Columns/MetricsColumnDetail.swift b/Meshtastic/Views/Nodes/Helpers/Metrics Columns/MetricsColumnDetail.swift index 1f384cb2..24cc6f96 100644 --- a/Meshtastic/Views/Nodes/Helpers/Metrics Columns/MetricsColumnDetail.swift +++ b/Meshtastic/Views/Nodes/Helpers/Metrics Columns/MetricsColumnDetail.swift @@ -63,7 +63,7 @@ struct MetricsColumnDetail: View { Button { dismiss() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) diff --git a/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift b/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift index e48a9acc..081e7adc 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift @@ -120,14 +120,14 @@ struct NodeDetail: View { if let metadata = node.metadata { HStack { Label { - Text("firmware.version") + Text("Firmware Version") } icon: { Image(systemName: "memorychip") .symbolRenderingMode(.multicolor) } Spacer() - Text(metadata.firmwareVersion ?? "unknown".localized) + Text(metadata.firmwareVersion ?? "Unknown".localized) } } @@ -147,7 +147,7 @@ struct NodeDetail: View { if let dm = node.telemetries?.filtered(using: NSPredicate(format: "metricsType == 0")).lastObject as? TelemetryEntity, let uptimeSeconds = dm.uptimeSeconds { HStack { Label { - Text("\("uptime".localized)") + Text("\("Uptime".localized)") } icon: { Image(systemName: "checkmark.circle.fill") .foregroundColor(.green) @@ -195,7 +195,7 @@ struct NodeDetail: View { Spacer() if dateFormatRelative, let text = Self.relativeFormatter.string(for: lastHeard) { - if lastHeard.formatted() != "unknown.age".localized { + if lastHeard.formatted() != "Unknown Age".localized { Text(text) .textSelection(.enabled) } @@ -214,7 +214,7 @@ struct NodeDetail: View { // to use with WeatherKit, or has actual data in the most recent EnvironmentMetrics entity // that will be rendered in this section. if node.hasPositions && UserDefaults.environmentEnableWeatherKit - || node.hasDataForLatestEnvironmentMetrics(attributes: ["iaq", "temperature", "relativeHumidity", "barometricPressure", "windSpeed", "radiation", "weight", "distance", "soilTemperature", "soilMoisture"]) { + || node.hasDataForLatestEnvironmentMetrics(attributes: ["iaq", "temperature", "relativeHumidity", "barometricPressure", "windSpeed", "radiation", "weight", "Distance", "soilTemperature", "soilMoisture"]) { Section("Environment") { if !node.hasEnvironmentMetrics { LocalWeatherConditions(location: node.latestPosition?.nodeLocation) @@ -499,14 +499,14 @@ struct NodeDetail: View { showingRebootConfirm = true } label: { Label( - "reboot", + "Reboot", systemImage: "arrow.triangle.2.circlepath" ) }.confirmationDialog( "Are you sure?", isPresented: $showingRebootConfirm ) { - Button("reboot.node", role: .destructive) { + Button("Reboot node?", role: .destructive) { if !bleManager.sendReboot( fromUser: connectedNode.user!, toUser: node.user!, @@ -520,6 +520,7 @@ struct NodeDetail: View { } } .listStyle(.insetGrouped) + .navigationBarTitle(String(node.user?.longName?.addingVariationSelectors ?? "Unknown".localized), displayMode: .inline) } } } diff --git a/Meshtastic/Views/Nodes/Helpers/NodeInfoItem.swift b/Meshtastic/Views/Nodes/Helpers/NodeInfoItem.swift index 6a8f468a..07f3d92c 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeInfoItem.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeInfoItem.swift @@ -74,7 +74,7 @@ struct NodeInfoItem: View { } Spacer() if user.hwModel != "UNSET" { - Text(String(node.user?.hwDisplayName ?? (node.user?.hwModel ?? "unset".localized))) + Text(String(node.user?.hwDisplayName ?? (node.user?.hwModel ?? "Unset".localized))) } else { Text(String("incomplete".localized)) } diff --git a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift index a29a0749..063e073a 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift @@ -192,7 +192,7 @@ struct NodeListFilter: View { Button { dismiss() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) diff --git a/Meshtastic/Views/Nodes/Helpers/NodeListItem.swift b/Meshtastic/Views/Nodes/Helpers/NodeListItem.swift index cabfabc6..2978ceab 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeListItem.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeListItem.swift @@ -64,7 +64,7 @@ struct NodeListItem: View { let (image, color) = userKeyStatus IconAndText(systemName: image, imageColor: color, - text: node.user?.longName?.addingVariationSelectors ?? "unknown".localized, + text: node.user?.longName?.addingVariationSelectors ?? "Unknown".localized, textColor: .primary) if node.favorite { Spacer() @@ -75,16 +75,16 @@ struct NodeListItem: View { if connected { IconAndText(systemName: "antenna.radiowaves.left.and.right.circle.fill", imageColor: .green, - text: "connected".localized) + text: "Connected".localized) } - if node.lastHeard?.timeIntervalSince1970 ?? 0 > 0 && node.lastHeard! < Calendar.current.date(byAdding: .year, value: 1, to: Date())!{ + if node.lastHeard?.timeIntervalSince1970 ?? 0 > 0 && node.lastHeard! < Calendar.current.date(byAdding: .year, value: 1, to: Date())! { IconAndText(systemName: node.isOnline ? "checkmark.circle.fill" : "moon.circle.fill", imageColor: node.isOnline ? .green : .orange, - text: node.lastHeard?.formatted() ?? "unknown.age".localized) + text: node.lastHeard?.formatted() ?? "Unknown Age".localized) } let role = DeviceRoles(rawValue: Int(node.user?.role ?? 0)) IconAndText(systemName: role?.systemName ?? "figure", - text: "Role: \(role?.name ?? "unknown".localized)") + text: "Role: \(role?.name ?? "Unknown".localized)") if node.isStoreForwardRouter { IconAndText(systemName: "envelope.arrow.triangle.branch", renderingMode: .multicolor, diff --git a/Meshtastic/Views/Nodes/Helpers/ScrollToBottomButton.swift b/Meshtastic/Views/Nodes/Helpers/ScrollToBottomButton.swift new file mode 100644 index 00000000..da10d18a --- /dev/null +++ b/Meshtastic/Views/Nodes/Helpers/ScrollToBottomButton.swift @@ -0,0 +1,30 @@ +// +// ScrollToBottomButtonView.swift +// Meshtastic +// +// Created by Benjamin Faershtein on 4/2/25. +// + +import SwiftUI + +struct ScrollToBottomButtonView: View { + var body: some View { + HStack(spacing: 4) { + Text("Jump to present") + .font(.caption) + .padding(.horizontal, 8) + .padding(.vertical, 4) + .cornerRadius(12) + Image(systemName: "arrow.down") + .font(.title2) + .symbolRenderingMode(.hierarchical) + + } + .foregroundColor(.accentColor) + .shadow(radius: 2) + } +} + +#Preview { + ScrollToBottomButtonView() +} diff --git a/Meshtastic/Views/Nodes/NodeList.swift b/Meshtastic/Views/Nodes/NodeList.swift index 34dbd475..1e823020 100644 --- a/Meshtastic/Views/Nodes/NodeList.swift +++ b/Meshtastic/Views/Nodes/NodeList.swift @@ -65,10 +65,7 @@ struct NodeList: View { var nodes: FetchedResults var connectedNode: NodeInfoEntity? { - getNodeInfo( - id: bleManager.connectedPeripheral?.num ?? 0, - context: context - ) + getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0, context: context) } @ViewBuilder @@ -78,19 +75,11 @@ struct NodeList: View { ) -> some View { /// Allow users to mute notifications for a node even if they are not connected if let user = node.user { - NodeAlertsButton( - context: context, - node: node, - user: user - ) + NodeAlertsButton(context: context, node: node, user: user) } if let connectedNode { /// Favoriting a node requires being connected - FavoriteNodeButton( - bleManager: bleManager, - context: context, - node: node - ) + FavoriteNodeButton(bleManager: bleManager, context: context, node: node) /// Don't show message, trace route, position exchange or delete context menu items for the connected node if connectedNode.num != node.num { if !node.viaMqtt || node.viaMqtt && node.hopsAway == 0 { @@ -203,7 +192,7 @@ struct NodeList: View { .searchable(text: $searchText, placement: .automatic, prompt: "Find a node") .disableAutocorrection(true) .scrollDismissesKeyboard(.immediately) - .navigationTitle(String.localizedStringWithFormat("nodes %@".localized, String(nodes.count))) + .navigationTitle(String.localizedStringWithFormat("Nodes (%@)".localized, String(nodes.count))) .listStyle(.plain) .alert( "Position Exchange Requested", @@ -237,7 +226,7 @@ struct NodeList: View { if deleteNode != nil { let success = bleManager.removeNode(node: deleteNode!, connectedNodeNum: Int64(bleManager.connectedPeripheral?.num ?? -1)) if !success { - Logger.data.error("Failed to delete node \(deleteNode?.user?.longName ?? "unknown".localized, privacy: .public)") + Logger.data.error("Failed to delete node \(deleteNode?.user?.longName ?? "Unknown".localized, privacy: .public)") } } } @@ -264,7 +253,6 @@ struct NodeList: View { columnVisibility: columnVisibility ) .edgesIgnoringSafeArea([.leading, .trailing]) - .navigationBarTitle(String(node.user?.longName?.addingVariationSelectors ?? "unknown".localized), displayMode: .inline) .navigationBarItems( trailing: ZStack { if UIDevice.current.userInterfaceIdiom != .phone { @@ -284,7 +272,7 @@ struct NodeList: View { ) } } else { - ContentUnavailableView("select.node", systemImage: "flipphone") + ContentUnavailableView("Select Node", systemImage: "flipphone") } } detail: { ContentUnavailableView("", systemImage: "line.3.horizontal") diff --git a/Meshtastic/Views/Nodes/NodeMap.swift b/Meshtastic/Views/Nodes/NodeMap.swift deleted file mode 100644 index e81fc224..00000000 --- a/Meshtastic/Views/Nodes/NodeMap.swift +++ /dev/null @@ -1,233 +0,0 @@ -//// -//// NodeMap.swift -//// MeshtasticApple -//// -//// Created by Garth Vander Houwen on 8/7/21. -//// -// -//import SwiftUI -//import MapKit -//import CoreLocation -//import CoreData -// -//struct NodeMap: View { -// @Environment(\.managedObjectContext) var context -// @EnvironmentObject var bleManager: BLEManager -// -// @ObservedObject -// var router: Router -// @State var selectedMapLayer: MapLayer = UserDefaults.mapLayer -// @State var enableMapRecentering: Bool = UserDefaults.enableMapRecentering -// @State var enableMapRouteLines: Bool = UserDefaults.enableMapRouteLines -// @State var enableMapNodeHistoryPins: Bool = UserDefaults.enableMapNodeHistoryPins -// @State var enableOfflineMaps: Bool = UserDefaults.enableOfflineMaps -// @State var selectedTileServer: MapTileServer = UserDefaults.mapTileServer -// @State var enableOverlayServer: Bool = UserDefaults.enableOverlayServer -// @State var selectedOverlayServer: MapOverlayServer = UserDefaults.mapOverlayServer -// @State var mapTilesAboveLabels: Bool = UserDefaults.mapTilesAboveLabels -// let fromDate: NSDate = Calendar.current.date(byAdding: .month, value: -1, to: Date())! as NSDate -// @FetchRequest(sortDescriptors: [NSSortDescriptor(key: "time", ascending: true)], -// predicate: NSPredicate(format: "nodePosition != nil", Calendar.current.date(byAdding: .day, value: -7, to: Date())! as NSDate), animation: .none) -// private var positions: FetchedResults -// @FetchRequest(sortDescriptors: [NSSortDescriptor(key: "name", ascending: false)], -// predicate: NSPredicate( -// format: "expire == nil || expire >= %@", Date() as NSDate -// ), animation: .none) -// private var waypoints: FetchedResults -// @State var waypointCoordinate: WaypointCoordinate? -// @State var selectedTracking: UserTrackingModes = .none -// @State var isPresentingInfoSheet: Bool = false -// @State private var customMapOverlay: MapViewSwiftUI.CustomMapOverlay? = MapViewSwiftUI.CustomMapOverlay( -// mapName: "offlinemap", -// tileType: "png", -// canReplaceMapContent: true -// ) -// var body: some View { -// NavigationStack { -// ZStack { -// MapViewSwiftUI( -// onLongPress: { coord in -// waypointCoordinate = WaypointCoordinate(id: .init(), coordinate: coord, waypointId: 0) -// }, onWaypointEdit: { wpId in -// if wpId > 0 { -// waypointCoordinate = WaypointCoordinate(id: .init(), coordinate: nil, waypointId: Int64(wpId)) -// } -// }, -// selectedMapLayer: selectedMapLayer, -// positions: Array(positions), -// waypoints: Array(waypoints), -// userTrackingMode: selectedTracking.MKUserTrackingModeValue(), -// showNodeHistory: enableMapNodeHistoryPins, -// showRouteLines: enableMapRouteLines, -// customMapOverlay: self.customMapOverlay -// ) -// VStack(alignment: .trailing) { -// HStack(alignment: .top) { -// Spacer() -// MapButtons(tracking: $selectedTracking, isPresentingInfoSheet: $isPresentingInfoSheet) -// .padding(.trailing, 8) -// .padding(.top, 16) -// } -// Spacer() -// TileDownloadStatus() -// .padding(.trailing, 16) -// .padding(.bottom, 20) -// } -// } -// .ignoresSafeArea(.all, edges: [.top, .leading, .trailing]) -// .frame(maxHeight: .infinity) -// .sheet(item: $waypointCoordinate, content: { wpc in -// WaypointFormMapKit(coordinate: wpc) -// .presentationDetents([.medium, .large]) -// .presentationDragIndicator(.automatic) -// }) -// .sheet(isPresented: $isPresentingInfoSheet) { -// VStack { -// Form { -// Section(header: Text("Map Options")) { -// Picker(selection: $selectedMapLayer, label: Text("")) { -// ForEach(MapLayer.allCases, id: \.self) { layer in -// if layer == MapLayer.offline && enableOfflineMaps { -// Text(layer.localized) -// } else if layer != MapLayer.offline { -// Text(layer.localized) -// } -// } -// } -// .pickerStyle(SegmentedPickerStyle()) -// .onChange(of: selectedMapLayer) { _, newMapLayer in -// UserDefaults.mapLayer = newMapLayer -// } -// .padding(.top, 5) -// .padding(.bottom, 5) -// Toggle(isOn: $enableMapRecentering) { -// Label("map.recentering", systemImage: "camera.metering.center.weighted") -// } -// .toggleStyle(SwitchToggleStyle(tint: .accentColor)) -// .onTapGesture { -// self.enableMapRecentering.toggle() -// UserDefaults.enableMapRecentering = self.enableMapRecentering -// } -// Toggle(isOn: $enableMapNodeHistoryPins) { -// Label("Show Node History", systemImage: "building.columns.fill") -// } -// .toggleStyle(SwitchToggleStyle(tint: .accentColor)) -// .onTapGesture { -// self.enableMapNodeHistoryPins.toggle() -// UserDefaults.enableMapNodeHistoryPins = self.enableMapNodeHistoryPins -// } -// Toggle(isOn: $enableMapRouteLines) { -// Label("Show Route Lines", systemImage: "road.lanes") -// } -// .toggleStyle(SwitchToggleStyle(tint: .accentColor)) -// .onTapGesture { -// self.enableMapRouteLines.toggle() -// UserDefaults.enableMapRouteLines = self.enableMapRouteLines -// } -// let locale = Locale.current -// if locale.region?.identifier ?? "no locale" == "US" { -// Toggle(isOn: $enableOverlayServer) { -// Label("Show Weather", systemImage: "cloud.fill") -// } -// .toggleStyle(SwitchToggleStyle(tint: .accentColor)) -// .onTapGesture { -// self.enableOverlayServer.toggle() -// UserDefaults.enableOverlayServer = self.enableOverlayServer -// } -// if enableOverlayServer { -// Picker(selection: $selectedOverlayServer, -// label: Text("Radar")) { -// ForEach(MapOverlayServer.allCases, id: \.self) { mos in -// Text(mos.description) -// .font(.footnote) -// } -// } -// .pickerStyle(DefaultPickerStyle()) -// .onChange(of: (selectedOverlayServer)) { _, newSelectedOverlayServer in -// UserDefaults.mapOverlayServer = newSelectedOverlayServer -// } -// Text(LocalizedStringKey(selectedOverlayServer.attribution)) -// .font(.footnote) -// .foregroundColor(.gray) -// .padding(0) -// } -// } -// } -// Section(header: Text("Offline Maps")) { -// Toggle(isOn: $enableOfflineMaps) { -// Text("Enable Offline Maps") -// } -// .toggleStyle(SwitchToggleStyle(tint: .accentColor)) -// .onChange(of: enableOfflineMaps) { _, newEnableOfflineMaps in -// UserDefaults.enableOfflineMaps = newEnableOfflineMaps -// if !enableOfflineMaps { -// if self.selectedMapLayer == .offline { -// self.selectedMapLayer = .standard -// } -// } -// } -// if enableOfflineMaps { -// VStack(alignment: .leading) { -// Picker(selection: $selectedTileServer, -// label: Text("Tile Server")) { -// ForEach(MapTileServer.allCases, id: \.self) { tsl in -// Text(tsl.description) -// } -// } -// .pickerStyle(DefaultPickerStyle()) -// .onChange(of: (selectedTileServer)) { _, newSelectedTileServer in -// UserDefaults.mapTileServer = newSelectedTileServer -// } -// Text("Attribution:") -// .fontWeight(.semibold) -// .font(.footnote) -// Text(LocalizedStringKey(selectedTileServer.attribution)) -// .font(.footnote) -// .foregroundColor(.gray) -// .padding(0) -// Divider() -// Toggle(isOn: $mapTilesAboveLabels) { -// Text("Tiles above Labels") -// } -// .toggleStyle(SwitchToggleStyle(tint: .accentColor)) -// .onTapGesture { -// self.mapTilesAboveLabels.toggle() -// UserDefaults.mapTilesAboveLabels = self.mapTilesAboveLabels -// } -// } -// } -// } -// } -// #if targetEnvironment(macCatalyst) -// Button { -// isPresentingInfoSheet = false -// } label: { -// Label("close", systemImage: "xmark") -// } -// .buttonStyle(.bordered) -// .buttonBorderShape(.capsule) -// .controlSize(.large) -// .padding(.bottom) -// #endif -// } -// .presentationDetents([enableOfflineMaps || enableOverlayServer ? .large : .medium]) -// .presentationDragIndicator(.visible) -// } -// } -// .navigationBarItems(leading: -// MeshtasticLogo(), trailing: -// ZStack { -// ConnectedDevice( -// bluetoothOn: bleManager.isSwitchedOn, -// deviceConnected: bleManager.connectedPeripheral != nil, -// name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : -// "?") -// }) -// .onAppear(perform: { -// UIApplication.shared.isIdleTimerDisabled = true -// }) -// .onDisappear(perform: { -// UIApplication.shared.isIdleTimerDisabled = false -// }) -// } -//} diff --git a/Meshtastic/Views/Nodes/PaxCounterLog.swift b/Meshtastic/Views/Nodes/PaxCounterLog.swift index 37ca7c30..5be9db56 100644 --- a/Meshtastic/Views/Nodes/PaxCounterLog.swift +++ b/Meshtastic/Views/Nodes/PaxCounterLog.swift @@ -44,7 +44,7 @@ struct PaxCounterLog: View { y: .value("y", (point.wifi + point.ble)) ) } - .accessibilityLabel("paxcounter.total") + .accessibilityLabel("Total PAX") .accessibilityValue("X: \(point.time!), Y: \(point.wifi + point.ble)") .foregroundStyle(paxChartColor) .interpolationMethod(.cardinal) @@ -55,7 +55,7 @@ struct PaxCounterLog: View { y: .value("y", point.wifi) ) } - .accessibilityLabel("paxcounter.wifi") + .accessibilityLabel("WiFi") .accessibilityValue("X: \(point.time!), Y: \(point.wifi)") .foregroundStyle(wifiChartColor) @@ -65,7 +65,7 @@ struct PaxCounterLog: View { y: .value("y", point.ble) ) } - .accessibilityLabel("paxcounter.ble") + .accessibilityLabel("BLE") .accessibilityValue("X: \(point.time!), Y: \(point.ble)") .foregroundStyle(bleChartColor) } @@ -76,9 +76,9 @@ struct PaxCounterLog: View { .chartXAxis(.automatic) .chartYScale(domain: 0...maxValue) .chartForegroundStyleScale([ - "paxcounter.ble".localized: .blue, - "paxcounter.wifi".localized: .orange, - "paxcounter.total".localized: .green + "BLE".localized: .blue, + "WiFi".localized: .orange, + "Total PAX".localized: .green ]) .chartLegend(position: .automatic, alignment: .bottom) } @@ -89,23 +89,23 @@ struct PaxCounterLog: View { if UIScreen.main.bounds.size.width > 768 && (UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac) { // Add a table for mac and ipad Table(pax) { - TableColumn("paxcounter.ble") { pc in + TableColumn("BLE") { pc in Text("\(pc.ble)") } - TableColumn("paxcounter.wifi") { pc in + TableColumn("WiFi") { pc in Text("\(pc.wifi)") } - TableColumn("paxcounter.total") { pc in + TableColumn("Total PAX") { pc in Text("\(pc.wifi + pc.ble)") } - TableColumn("uptime") { pc in + TableColumn("Uptime") { pc in let now = Date.now let later = now + TimeInterval(pc.uptime) let components = (now..= 0 ? String(localized: "\(route.hopsBack) Hops") : String(localized: "unknown") + let hopBackString = route.hopsBack >= 0 ? String(localized: "\(route.hopsBack) Hops") : String(localized: "Unknown") Text("\(routeTime) - \(hopTowardsString) Towards \(hopBackString) Back") .font(.caption) } else if route.sent { @@ -67,7 +67,7 @@ struct TraceRouteLog: View { Logger.data.error("\(error.localizedDescription, privacy: .public)") } } label: { - Label("delete", systemImage: "trash") + Label("Delete", systemImage: "trash") } } } @@ -78,14 +78,14 @@ struct TraceRouteLog: View { if selectedRoute != nil { if selectedRoute?.response ?? false && selectedRoute?.hopsTowards ?? 0 >= 0 { Label { - Text("Route: \(selectedRoute?.routeText ?? "unknown".localized)") + Text("Route: \(selectedRoute?.routeText ?? "Unknown".localized)") } icon: { Image(systemName: "signpost.right") .symbolRenderingMode(.hierarchical) } .font(.title3) Label { - Text("Route Back: \(selectedRoute?.routeBackText ?? "unknown".localized)") + Text("Route Back: \(selectedRoute?.routeBackText ?? "Unknown".localized)") } icon: { Image(systemName: "signpost.left") .symbolRenderingMode(.hierarchical) @@ -94,7 +94,7 @@ struct TraceRouteLog: View { } else if !(selectedRoute?.sent ?? true) { Label { VStack { - Text("Trace route to \(selectedRoute?.node?.user?.longName ?? "unknown".localized) was not sent.") + Text("Trace route to \(selectedRoute?.node?.user?.longName ?? "Unknown".localized) was not sent.") .font(idiom == .phone ? .body : .largeTitle) .fontWeight(.semibold) Text("Trace Route was rate limited. You can send a trace route a maximum of once every thirty seconds.") @@ -109,7 +109,7 @@ struct TraceRouteLog: View { } else { Label { VStack { - Text("Trace route sent to \(selectedRoute?.node?.user?.longName ?? "unknown".localized)") + Text("Trace route sent to \(selectedRoute?.node?.user?.longName ?? "Unknown".localized)") .font(idiom == .phone ? .body : .largeTitle) .fontWeight(.semibold) Text("A Trace Route was sent, no response has been received.") diff --git a/Meshtastic/Views/Settings/About.swift b/Meshtastic/Views/Settings/About.swift index 84fa4b83..e65a4c64 100644 --- a/Meshtastic/Views/Settings/About.swift +++ b/Meshtastic/Views/Settings/About.swift @@ -14,7 +14,6 @@ struct AboutMeshtastic: View { var body: some View { VStack { - List { Section(header: Text("What is Meshtastic?")) { Text("An open source, off-grid, decentralized, mesh network that runs on affordable, low-power radios.") @@ -44,12 +43,12 @@ struct AboutMeshtastic: View { Button("Review the app") { if let scene = UIApplication.shared.connectedScenes .first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene { - SKStoreReviewController.requestReview(in: scene) + AppStore.requestReview(in: scene) } } .font(.title2) - Text("Version: \(Bundle.main.appVersionLong) (\(Bundle.main.appBuild)) ") + Text("Version: \(Bundle.main.appVersionLong) (\(Bundle.main.appBuild))") } Section(header: Text("Project information")) { diff --git a/Meshtastic/Views/Settings/AppData.swift b/Meshtastic/Views/Settings/AppData.swift index f1777989..e5ff252c 100644 --- a/Meshtastic/Views/Settings/AppData.swift +++ b/Meshtastic/Views/Settings/AppData.swift @@ -21,7 +21,7 @@ struct AppData: View { VStack { - Section(header: Text("phone.gps")) { + Section(header: Text("Phone GPS")) { GPSStatus() } Divider() @@ -41,7 +41,7 @@ struct AppData: View { Logger.services.error("🗑️ Delete file error: \(error, privacy: .public)") } } label: { - Label("delete", systemImage: "trash") + Label("Delete", systemImage: "trash") } } } icon: { @@ -61,7 +61,7 @@ struct AppData: View { Logger.services.error("🗑️ Delete file error: \(error, privacy: .public)") } } label: { - Label("delete", systemImage: "trash") + Label("Delete", systemImage: "trash") } } } icon: { diff --git a/Meshtastic/Views/Settings/AppLog.swift b/Meshtastic/Views/Settings/AppLog.swift index 53a32e07..7a0154b6 100644 --- a/Meshtastic/Views/Settings/AppLog.swift +++ b/Meshtastic/Views/Settings/AppLog.swift @@ -35,7 +35,7 @@ struct AppLog: View { if idiom == .phone { Table(logs, selection: $selection, sortOrder: $sortOrder) { - TableColumn("log.message", value: \.composedMessage) { value in + TableColumn("Message", value: \.composedMessage) { value in Text(value.composedMessage) .foregroundStyle(value.level.color) .font(.caption) @@ -75,18 +75,18 @@ struct AppLog: View { } } else { Table(logs, selection: $selection, sortOrder: $sortOrder) { - TableColumn("log.time") { value in + TableColumn("Time") { value in Text(value.date.formatted(dateFormatStyle)) } .width(min: 125, max: 150) - TableColumn("log.level") { value in + TableColumn("Level") { value in Text(value.level.description) .foregroundStyle(value.level.color) } .width(min: 85, max: 110) - TableColumn("log.category", value: \.category) + TableColumn("Category", value: \.category) .width(min: 80, max: 130) - TableColumn("log.message", value: \.composedMessage) { value in + TableColumn("Message", value: \.composedMessage) { value in Text(value.composedMessage) .foregroundStyle(value.level.color) .font(.body) @@ -270,4 +270,4 @@ extension AppLog { } } -extension OSLogEntry: Identifiable { } +extension OSLogEntry: @retroactive Identifiable { } diff --git a/Meshtastic/Views/Settings/AppSettings.swift b/Meshtastic/Views/Settings/AppSettings.swift index d8d1a1e8..e16fb31b 100644 --- a/Meshtastic/Views/Settings/AppSettings.swift +++ b/Meshtastic/Views/Settings/AppSettings.swift @@ -8,7 +8,6 @@ import OSLog struct AppSettings: View { @Environment(\.managedObjectContext) var context @EnvironmentObject var bleManager: BLEManager - @ObservedObject var tileManager = OfflineTileManager.shared @State var totalDownloadedTileSize = "" @State private var isPresentingCoreDataResetConfirm = false @State private var isPresentingDeleteMapTilesConfirm = false @@ -44,7 +43,7 @@ struct AppSettings: View { Button { isPresentingCoreDataResetConfirm = true } label: { - Label("clear.app.data", systemImage: "trash") + Label("Clear App Data", systemImage: "trash") .foregroundColor(.red) } .confirmationDialog( @@ -85,31 +84,7 @@ struct AppSettings: View { .foregroundColor(.red) } } - if totalDownloadedTileSize != "0MB" { - Section(header: Text("Map Tile Data")) { - Button { - isPresentingDeleteMapTilesConfirm = true - } label: { - Label("\("map.tiles.delete".localized) (\(totalDownloadedTileSize))", systemImage: "trash") - .foregroundColor(.red) - } - .confirmationDialog( - "Are you sure?", - isPresented: $isPresentingDeleteMapTilesConfirm, - titleVisibility: .visible - ) { - Button("Delete all map tiles?", role: .destructive) { - tileManager.removeAll() - totalDownloadedTileSize = tileManager.getAllDownloadedSize() - Logger.services.debug("delete all tiles") - } - } - } - } } - .onAppear(perform: { - totalDownloadedTileSize = tileManager.getAllDownloadedSize() - }) } .navigationTitle("App Settings") .navigationBarItems(trailing: diff --git a/Meshtastic/Views/Settings/Channels.swift b/Meshtastic/Views/Settings/Channels.swift index 551b9ab4..0a24c8c5 100644 --- a/Meshtastic/Views/Settings/Channels.swift +++ b/Meshtastic/Views/Settings/Channels.swift @@ -219,7 +219,7 @@ struct Channels: View { hasChanges = false } } label: { - Label("save", systemImage: "square.and.arrow.down") + Label("Save", systemImage: "square.and.arrow.down") } .disabled(bleManager.connectedPeripheral == nil)// || !hasChanges)// !hasValidKey) .buttonStyle(.bordered) @@ -230,7 +230,7 @@ struct Channels: View { Button { goBack() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) @@ -279,7 +279,7 @@ struct Channels: View { .padding() } } - .navigationTitle("channels") + .navigationTitle("Channels") .navigationBarItems(trailing: ZStack { ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?") @@ -379,6 +379,6 @@ enum PositionPrecision: Int, CaseIterable, Identifiable { var description: String { let distanceFormatter = MKDistanceFormatter() - return String.localizedStringWithFormat("position.precision %@".localized, String(distanceFormatter.string(fromDistance: precisionMeters))) + return String.localizedStringWithFormat("Within %@".localized, String(distanceFormatter.string(fromDistance: precisionMeters))) } } diff --git a/Meshtastic/Views/Settings/Channels/ChannelForm.swift b/Meshtastic/Views/Settings/Channels/ChannelForm.swift index 06a4a260..92f1b8e2 100644 --- a/Meshtastic/Views/Settings/Channels/ChannelForm.swift +++ b/Meshtastic/Views/Settings/Channels/ChannelForm.swift @@ -30,7 +30,7 @@ struct ChannelForm: View { Form { Section(header: Text("channel details")) { HStack { - Text("name") + Text("Name") Spacer() TextField( "Channel Name", @@ -128,7 +128,7 @@ struct ChannelForm: View { } } - Section(header: Text("position")) { + Section(header: Text("Position")) { VStack(alignment: .leading) { Toggle(isOn: $positionsEnabled) { Label(channelRole == 1 ? "Positions Enabled" : "Allow Position Requests", systemImage: positionsEnabled ? "mappin" : "mappin.slash") @@ -170,7 +170,7 @@ struct ChannelForm: View { } } } - Section(header: Text("mqtt")) { + Section(header: Text("MQTT")) { Toggle(isOn: $uplink) { Label("Uplink Enabled", systemImage: "arrowshape.up") } diff --git a/Meshtastic/Views/Settings/Config/BluetoothConfig.swift b/Meshtastic/Views/Settings/Config/BluetoothConfig.swift index 63fdf327..82b4f628 100644 --- a/Meshtastic/Views/Settings/Config/BluetoothConfig.swift +++ b/Meshtastic/Views/Settings/Config/BluetoothConfig.swift @@ -29,9 +29,9 @@ struct BluetoothConfig: View { Form { ConfigHeader(title: "Bluetooth", config: \.bluetoothConfig, node: node, onAppear: setBluetoothValues) - Section(header: Text("options")) { + Section(header: Text("Options")) { Toggle(isOn: $enabled) { - Label("enabled", systemImage: "antenna.radiowaves.left.and.right") + Label("Enabled", systemImage: "antenna.radiowaves.left.and.right") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) Picker("Pairing Mode", selection: $mode ) { diff --git a/Meshtastic/Views/Settings/Config/DeviceConfig.swift b/Meshtastic/Views/Settings/Config/DeviceConfig.swift index abce6e9a..6539848a 100644 --- a/Meshtastic/Views/Settings/Config/DeviceConfig.swift +++ b/Meshtastic/Views/Settings/Config/DeviceConfig.swift @@ -30,17 +30,15 @@ struct DeviceConfig: View { @State var ledHeartbeatEnabled = true @State var tripleClickAsAdHocPing = true @State var tzdef = "" - @State private var showRouterWarning = false @State private var confirmWarning = false - var body: some View { VStack { Form { ConfigHeader(title: "Device", config: \.deviceConfig, node: node, onAppear: setDeviceValues) - Section(header: Text("options")) { + Section(header: Text("Options")) { VStack(alignment: .leading) { Picker("Device Role", selection: $deviceRole ) { ForEach(DeviceRoles.allCases) { dr in @@ -149,7 +147,7 @@ struct DeviceConfig: View { Picker("Button GPIO", selection: $buttonGPIO) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -159,7 +157,7 @@ struct DeviceConfig: View { Picker("Buzzer GPIO", selection: $buzzerGPIO) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -249,7 +247,7 @@ struct DeviceConfig: View { } Spacer() } - .navigationTitle("device.config") + .navigationTitle("Device Config") .navigationBarItems( trailing: ZStack { ConnectedDevice( @@ -312,6 +310,9 @@ struct DeviceConfig: View { } } func setDeviceValues() { + if node?.deviceConfig?.role ?? 0 == 3 { + node?.deviceConfig?.role = 1 + } self.deviceRole = Int(node?.deviceConfig?.role ?? 0) self.buttonGPIO = Int(node?.deviceConfig?.buttonGpio ?? 0) self.buzzerGPIO = Int(node?.deviceConfig?.buzzerGpio ?? 0) diff --git a/Meshtastic/Views/Settings/Config/DisplayConfig.swift b/Meshtastic/Views/Settings/Config/DisplayConfig.swift index 88839956..d6f14135 100644 --- a/Meshtastic/Views/Settings/Config/DisplayConfig.swift +++ b/Meshtastic/Views/Settings/Config/DisplayConfig.swift @@ -153,7 +153,7 @@ struct DisplayConfig: View { } } - .navigationTitle("display.config") + .navigationTitle("Display Config") .navigationBarItems( trailing: ZStack { ConnectedDevice( diff --git a/Meshtastic/Views/Settings/Config/LoRaConfig.swift b/Meshtastic/Views/Settings/Config/LoRaConfig.swift index 20371f31..196f6ffb 100644 --- a/Meshtastic/Views/Settings/Config/LoRaConfig.swift +++ b/Meshtastic/Views/Settings/Config/LoRaConfig.swift @@ -228,7 +228,7 @@ struct LoRaConfig: View { } } } - .navigationTitle("lora.config") + .navigationTitle("LoRa Config") .navigationBarItems( trailing: ZStack { ConnectedDevice( @@ -304,6 +304,9 @@ struct LoRaConfig: View { } } func setLoRaValues() { + if node?.loRaConfig?.modemPreset ?? 0 == 2 { + node?.loRaConfig?.modemPreset = 0 + } self.hopLimit = Int(node?.loRaConfig?.hopLimit ?? 3) self.region = Int(node?.loRaConfig?.regionCode ?? 0) self.usePreset = node?.loRaConfig?.usePreset ?? true diff --git a/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift b/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift index 8e3a0f02..24c0ada3 100644 --- a/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift @@ -30,7 +30,7 @@ struct AmbientLightingConfig: View { Form { ConfigHeader(title: "Ambient Lighting", config: \.ambientLightingConfig, node: node, onAppear: setAmbientLightingConfigValue) - Section(header: Text("options")) { + Section(header: Text("Options")) { Toggle(isOn: $ledState) { Label("LED State", systemImage: ledState ? "lightbulb.led.fill" : "lightbulb.led") diff --git a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift index 99a28a32..20a62136 100644 --- a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift @@ -42,11 +42,11 @@ struct CannedMessagesConfig: View { Form { ConfigHeader(title: "Canned messages", config: \.cannedMessageConfig, node: node, onAppear: setCannedMessagesValues) - Section(header: Text("options")) { + Section(header: Text("Options")) { Toggle(isOn: $enabled) { - Label("enabled", systemImage: "list.bullet.rectangle.fill") + Label("Enabled", systemImage: "list.bullet.rectangle.fill") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) @@ -103,7 +103,7 @@ struct CannedMessagesConfig: View { Picker("Pin A", selection: $inputbrokerPinA) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -118,7 +118,7 @@ struct CannedMessagesConfig: View { Picker("Pin B", selection: $inputbrokerPinB) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -133,7 +133,7 @@ struct CannedMessagesConfig: View { Picker("Press Pin", selection: $inputbrokerPinPress) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } diff --git a/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift b/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift index 1c53b495..e042ca77 100644 --- a/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift @@ -47,10 +47,10 @@ struct DetectionSensorConfig: View { Form { ConfigHeader(title: "Detection Sensor", config: \.detectionSensorConfig, node: node, onAppear: setDetectionSensorValues) - Section(header: Text("options")) { + Section(header: Text("Options")) { Toggle(isOn: $enabled) { - Label("enabled", systemImage: "dot.radiowaves.right") + Label("Enabled", systemImage: "dot.radiowaves.right") Text("Enables the detection sensor module, it needs to be enabled on both the node with the sensor, and any nodes that you want to receive detection sensor text messages or view the detection sensor log and chart.") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) @@ -108,7 +108,7 @@ struct DetectionSensorConfig: View { Picker("GPIO Pin to monitor", selection: $monitorPin) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -130,7 +130,7 @@ struct DetectionSensorConfig: View { } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) } - Section(header: Text("update.interval")) { + Section(header: Text("Update Interval")) { Picker("Minimum time between detection broadcasts", selection: $minimumBroadcastSecs) { ForEach(UpdateIntervals.allCases) { ui in Text(ui.description).tag(ui.rawValue) @@ -181,7 +181,7 @@ struct DetectionSensorConfig: View { } } } - .navigationTitle("detection.sensor.config") + .navigationTitle("Detection Sensor Config") .navigationBarItems( trailing: ZStack { ConnectedDevice( diff --git a/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift b/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift index 9602c44b..e9959b41 100644 --- a/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift @@ -39,10 +39,10 @@ struct ExternalNotificationConfig: View { Form { ConfigHeader(title: "External notification", config: \.externalNotificationConfig, node: node, onAppear: setExternalNotificationValues) - Section(header: Text("options")) { + Section(header: Text("Options")) { Toggle(isOn: $enabled) { - Label("enabled", systemImage: "megaphone") + Label("Enabled", systemImage: "megaphone") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) @@ -82,7 +82,7 @@ struct ExternalNotificationConfig: View { Picker("Output pin GPIO", selection: $output) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -138,7 +138,7 @@ struct ExternalNotificationConfig: View { Picker("Output pin buzzer GPIO ", selection: $outputBuzzer) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -148,7 +148,7 @@ struct ExternalNotificationConfig: View { Picker("Output pin vibra GPIO", selection: $outputVibra) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -189,7 +189,7 @@ struct ExternalNotificationConfig: View { } } } - .navigationTitle("external.notification.config") + .navigationTitle("External Notification Config") .navigationBarItems( trailing: ZStack { ConnectedDevice( diff --git a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift index 29b06464..6967a2ab 100644 --- a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift @@ -31,6 +31,7 @@ struct MQTTConfig: View { @State var defaultTopic = "msh/US" @State var nearbyTopics = [String]() @State var mapReportingEnabled = false + @AppStorage("mapReportingOptIn") private var mapReportingOptIn: Bool = false @State var mapPublishIntervalSecs = 3600 @State var mapPositionPrecision: Double = 14.0 @@ -50,23 +51,23 @@ struct MQTTConfig: View { ConfigHeader(title: "MQTT", config: \.mqttConfig, node: node, onAppear: setMqttValues) - Section(header: Text("options")) { + Section(header: Text("Options")) { Toggle(isOn: $enabled) { - Label("enabled", systemImage: "dot.radiowaves.up.forward") + Label("Enabled", systemImage: "dot.radiowaves.up.forward") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) Toggle(isOn: $proxyToClientEnabled) { - Label("mqtt.clientproxy", systemImage: "iphone.radiowaves.left.and.right") + Label("MQTT Client Proxy", systemImage: "iphone.radiowaves.left.and.right") Text("Utilizes the network connection on your phone to connect to MQTT.") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) if enabled && proxyToClientEnabled && node?.mqttConfig?.proxyToClientEnabled ?? false == true { Toggle(isOn: $mqttConnected) { - Label(mqttConnected ? "mqtt.disconnect".localized : "mqtt.connect".localized, systemImage: "server.rack") + Label("Connect to MQTT via Proxy", systemImage: "server.rack") if bleManager.mqttError.count > 0 { Text(bleManager.mqttError) .fixedSize(horizontal: false, vertical: true) @@ -92,12 +93,30 @@ struct MQTTConfig: View { } Section(header: Text("Map Report")) { - Toggle(isOn: $mapReportingEnabled) { - Label("enabled", systemImage: "map") + Label("Enabled", systemImage: "map") + Text("Your node will periodically send an unencrypted map report packet to the configured MQTT server, this includes id, short and long name, approximate location, hardware model, role, firmware version, LoRa region, modem preset and primary channel name.") + .foregroundColor(.gray) + .font(.caption) } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) if mapReportingEnabled { + Text("Consent to Share Unencrypted Node Data via MQTT") + Text("By enabling this feature, you acknowledge and expressly consent to the transmission of your device’s real-time geographic location over the MQTT protocol without encryption. This location data may be used for purposes such as live map reporting, device tracking, and related telemetry functions.") + .foregroundColor(.gray) + .font(.caption) + Text("Please be advised that because the map report is not encrypted, your data may be stored and displayed permanently by third parties. Meshtastic does not assume responsibility for any such storage, display or disclosure of this data.") + .foregroundColor(.gray) + .font(.caption) + Toggle(isOn: $mapReportingOptIn) { + Label("I have read and understand the above. I voluntarily consent to the unencrypted transmission of my node data via MQTT.", systemImage: "hand.raised") + .foregroundColor(.gray) + .font(.callout) + + } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) + } + if mapReportingEnabled && mapReportingOptIn { Picker("Map Publish Interval", selection: $mapPublishIntervalSecs ) { ForEach(UpdateIntervals.allCases) { ui in if ui.rawValue >= 3600 { @@ -108,6 +127,9 @@ struct MQTTConfig: View { .pickerStyle(DefaultPickerStyle()) VStack(alignment: .leading) { Label("Approximate Location", systemImage: "location.slash.circle.fill") + Text("To comply with privacy laws like CCPA and GDPR, we avoid sharing exact location data. Instead, we use anonymized or approximate (imprecise) location information to protect your privacy.") + .foregroundColor(.gray) + .font(.callout) Slider(value: $mapPositionPrecision, in: 11...14, step: 1) { } minimumValueLabel: { Image(systemName: "minus") @@ -178,8 +200,8 @@ struct MQTTConfig: View { .autocorrectionDisabled() if address != "mqtt.meshtastic.org" { HStack { - Label("mqtt.username", systemImage: "person.text.rectangle") - TextField("mqtt.username", text: $username) + Label("Username", systemImage: "person.text.rectangle") + TextField("Username", text: $username) .foregroundColor(.gray) .autocapitalization(.none) .disableAutocorrection(true) @@ -197,8 +219,8 @@ struct MQTTConfig: View { .keyboardType(.default) .scrollDismissesKeyboard(.interactively) HStack { - Label("password", systemImage: "wallet.pass") - TextField("password", text: $password) + Label("Password", systemImage: "wallet.pass") + TextField("Password", text: $password) .foregroundColor(.gray) .autocapitalization(.none) .disableAutocorrection(true) @@ -266,6 +288,10 @@ struct MQTTConfig: View { if newProxyToClientEnabled != node?.mqttConfig?.proxyToClientEnabled { hasChanges = true } } .onChange(of: address) { _, newAddress in + if address.lowercased() == "mqtt.meshtastic.org" { + username = "meshdev" + password = "large4cats" + } if newAddress != node?.mqttConfig?.address ?? "" { hasChanges = true } } .onChange(of: username) { _, newUsername in @@ -314,7 +340,7 @@ struct MQTTConfig: View { if newMapPublishIntervalSecs != node?.mqttConfig?.mapPublishIntervalSecs ?? -1 { hasChanges = true } } } - .navigationTitle("mqtt.config") + .navigationTitle("MQTT Config") .navigationBarItems( trailing: ZStack { ConnectedDevice( @@ -362,7 +388,6 @@ struct MQTTConfig: View { } if let placemarks = placemarks, let placemark = placemarks.first { - let cc = locale.region?.identifier ?? "UNK" /// Country Topic unless your region is a country if !(region?.isCountry ?? false) { let countryTopic = defaultTopic + "/" + (placemark.isoCountryCode ?? "") diff --git a/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift b/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift index 24af3504..6d71f7a7 100644 --- a/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift @@ -22,17 +22,17 @@ struct PaxCounterConfig: View { var body: some View { Form { - ConfigHeader(title: "config.module.paxcounter.title", config: \.powerConfig, node: node, onAppear: setPaxValues) + ConfigHeader(title: "PAX Counter Config", config: \.powerConfig, node: node, onAppear: setPaxValues) Section { Toggle(isOn: $enabled) { - Label("enabled", systemImage: "figure.walk.motion") - Text("config.module.paxcounter.enabled.description") + Label("Enabled", systemImage: "figure.walk.motion") + Text("When enabled the PAX Counter module counts the number of people passing by using WiFi and Bluetooth. Both WiFI and Bluetooth must be disabled for PAX counter to work.") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) .listRowSeparator(.visible) if enabled { - Picker("config.module.paxcounter.updateinterval", selection: $paxcounterUpdateInterval) { + Picker("Update Interval", selection: $paxcounterUpdateInterval) { ForEach(UpdateIntervals.allCases) { at in if at.rawValue >= 300 { Text(at.description) @@ -41,16 +41,16 @@ struct PaxCounterConfig: View { } .pickerStyle(DefaultPickerStyle()) .listRowSeparator(.hidden) - Text("config.module.paxcounter.updateinterval.description") + Text("How often we can send a message to the mesh when people are detected.") .foregroundColor(.gray) .font(.callout) } } header: { - Text("options") + Text("Options") } } .disabled(self.bleManager.connectedPeripheral == nil || node?.powerConfig == nil) - .navigationTitle("config.module.paxcounter.title") + .navigationTitle("PAX Counter Config") .navigationBarItems(trailing: ZStack { ConnectedDevice( bluetoothOn: bleManager.isSwitchedOn, diff --git a/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift b/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift index 979eb736..cc323170 100644 --- a/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift @@ -27,9 +27,9 @@ struct RangeTestConfig: View { Form { ConfigHeader(title: "Range", config: \.rangeTestConfig, node: node, onAppear: setRangeTestValues) - Section(header: Text("options")) { + Section(header: Text("Options")) { Toggle(isOn: $enabled) { - Label("enabled", systemImage: "figure.walk") + Label("Enabled", systemImage: "figure.walk") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) .listRowSeparator(.visible) @@ -45,7 +45,7 @@ struct RangeTestConfig: View { .font(.callout) Toggle(isOn: $save) { - Label("save", systemImage: "square.and.arrow.down.fill") + Label("Save", systemImage: "square.and.arrow.down.fill") Text("Saves a CSV with the range test message details, currently only available on ESP32 devices with a web server.") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) @@ -71,7 +71,7 @@ struct RangeTestConfig: View { } } } - .navigationTitle("range.test.config") + .navigationTitle("Range Test Config") .navigationBarItems( trailing: ZStack { ConnectedDevice( diff --git a/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift b/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift index b81e2348..71452615 100644 --- a/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift @@ -22,12 +22,12 @@ struct RtttlConfig: View { var body: some View { VStack { Form { - ConfigHeader(title: "ringtone", config: \.rtttlConfig, node: node, onAppear: setRtttLConfigValue) + ConfigHeader(title: "Ringtone", config: \.rtttlConfig, node: node, onAppear: setRtttLConfigValue) - Section(header: Text("options")) { + Section(header: Text("Options")) { HStack { - Label("ringtone", systemImage: "music.quarternote.3") - TextField("config.ringtone.label", text: $ringtone, axis: .vertical) + Label("Ringtone", systemImage: "music.quarternote.3") + TextField("Ringtone Transfer Language", text: $ringtone, axis: .vertical) .foregroundColor(.gray) .autocapitalization(.none) .disableAutocorrection(true) @@ -43,7 +43,7 @@ struct RtttlConfig: View { } .keyboardType(.default) .listRowSeparator(.hidden) - Text("config.ringtone.description") + Text("Ringtone Transfer Language(RTTTL) Ringtone String used by supported buzzers in external notifications.") .foregroundColor(.gray) .font(.callout) } @@ -62,7 +62,7 @@ struct RtttlConfig: View { } } } - .navigationTitle("config.ringtone.title") + .navigationTitle("Ringtone Config") .navigationBarItems( trailing: ZStack { ConnectedDevice( diff --git a/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift b/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift index fd2c0c99..0bbe9fbc 100644 --- a/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift @@ -33,15 +33,15 @@ struct SerialConfig: View { Form { ConfigHeader(title: "Serial", config: \.serialConfig, node: node, onAppear: setSerialValues) - Section(header: Text("options")) { + Section(header: Text("Options")) { Toggle(isOn: $enabled) { - Label("enabled", systemImage: "terminal") + Label("Enabled", systemImage: "terminal") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) Toggle(isOn: $echo) { - Label("echo", systemImage: "repeat") + Label("Echo", systemImage: "repeat") Text("If set, any packets you send will be echoed back to your device.") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) @@ -53,7 +53,7 @@ struct SerialConfig: View { } .pickerStyle(DefaultPickerStyle()) .listRowSeparator(/*@START_MENU_TOKEN@*/.visible/*@END_MENU_TOKEN@*/) - Picker("timeout", selection: $timeout ) { + Picker("Timeout", selection: $timeout ) { ForEach(SerialTimeoutIntervals.allCases) { sti in Text(sti.description) } @@ -64,7 +64,7 @@ struct SerialConfig: View { .foregroundColor(.gray) .font(.callout) - Picker("mode", selection: $mode ) { + Picker("Mode", selection: $mode ) { ForEach(SerialModeTypes.allCases) { smt in Text(smt.description) } @@ -76,7 +76,7 @@ struct SerialConfig: View { Picker("Receive data (rxd) GPIO pin", selection: $rxd) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -88,7 +88,7 @@ struct SerialConfig: View { Picker("Transmit data (txd) GPIO pin", selection: $txd) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -126,7 +126,7 @@ struct SerialConfig: View { } } } - .navigationTitle("serial.config") + .navigationTitle("Serial Config") .navigationBarItems( trailing: ZStack { ConnectedDevice( diff --git a/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift b/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift index 0859f87f..78ad1343 100644 --- a/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift @@ -34,9 +34,9 @@ struct StoreForwardConfig: View { Form { ConfigHeader(title: "Store & Forward", config: \.storeForwardConfig, node: node, onAppear: setStoreAndForwardValues) - Section(header: Text("options")) { + Section(header: Text("Options")) { Toggle(isOn: $enabled) { - Label("enabled", systemImage: "envelope.arrow.triangle.branch") + Label("Enabled", systemImage: "envelope.arrow.triangle.branch") Text("Enables the store and forward module.") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) @@ -46,11 +46,11 @@ struct StoreForwardConfig: View { if enabled { Section(header: Text("settings")) { Toggle(isOn: $heartbeat) { - Label("storeforward.heartbeat", systemImage: "waveform.path.ecg") + Label("Send Heartbeat", systemImage: "waveform.path.ecg") Text("Send a heartbeat to advertise the server's presence.") } Picker("Number of records", selection: $records) { - Text("unset").tag(0) + Text("Unset").tag(0) Text("25").tag(25) Text("50").tag(50) Text("75").tag(75) @@ -58,7 +58,7 @@ struct StoreForwardConfig: View { } .pickerStyle(DefaultPickerStyle()) Picker("History Return Max", selection: $historyReturnMax) { - Text("unset").tag(0) + Text("Unset").tag(0) Text("25").tag(25) Text("50").tag(50) Text("75").tag(75) @@ -66,7 +66,7 @@ struct StoreForwardConfig: View { } .pickerStyle(DefaultPickerStyle()) Picker("History Return Window", selection: $historyReturnWindow) { - Text("unset").tag(0) + Text("Unset").tag(0) Text("One Minute").tag(60) Text("Five Minutes").tag(300) Text("Ten Minutes").tag(600) diff --git a/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift b/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift index ad173dae..0dfe7566 100644 --- a/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift @@ -32,7 +32,7 @@ struct TelemetryConfig: View { Form { ConfigHeader(title: "Telemetry", config: \.telemetryConfig, node: node, onAppear: setTelemetryValues) - Section(header: Text("update.interval")) { + Section(header: Text("Update Interval")) { Picker("Device Metrics", selection: $deviceUpdateInterval ) { ForEach(UpdateIntervals.allCases) { ui in if ui.rawValue >= 900 { @@ -46,7 +46,7 @@ struct TelemetryConfig: View { .foregroundColor(.gray) .font(.callout) .listRowSeparator(.visible) - Picker("Sensor Metrics", selection: $environmentUpdateInterval ) { + Picker("Environment Metrics", selection: $environmentUpdateInterval ) { ForEach(UpdateIntervals.allCases) { ui in if ui.rawValue >= 900 { Text(ui.description) @@ -55,7 +55,7 @@ struct TelemetryConfig: View { } .pickerStyle(DefaultPickerStyle()) .listRowSeparator(.hidden) - Text("How often sensor metrics are sent out over the mesh. Default is 30 minutes.") + Text("How often environment metrics are sent out over the mesh. Default is 30 minutes.") .foregroundColor(.gray) .font(.callout) } @@ -64,7 +64,7 @@ struct TelemetryConfig: View { .foregroundColor(.gray) .font(.callout) Toggle(isOn: $environmentMeasurementEnabled) { - Label("enabled", systemImage: "chart.xyaxis.line") + Label("Enabled", systemImage: "chart.xyaxis.line") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) Toggle(isOn: $environmentScreenEnabled) { @@ -78,7 +78,7 @@ struct TelemetryConfig: View { } Section(header: Text("Power Options")) { Toggle(isOn: $powerMeasurementEnabled) { - Label("enabled", systemImage: "bolt") + Label("Enabled", systemImage: "bolt") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) .listRowSeparator(.visible) @@ -124,7 +124,7 @@ struct TelemetryConfig: View { } } } - .navigationTitle("telemetry.config") + .navigationTitle("Telemetry Config") .navigationBarItems( trailing: ZStack { ConnectedDevice( diff --git a/Meshtastic/Views/Settings/Config/NetworkConfig.swift b/Meshtastic/Views/Settings/Config/NetworkConfig.swift index c63e95be..35e25660 100644 --- a/Meshtastic/Views/Settings/Config/NetworkConfig.swift +++ b/Meshtastic/Views/Settings/Config/NetworkConfig.swift @@ -36,14 +36,14 @@ struct NetworkConfig: View { Section(header: Text("WiFi Options")) { Toggle(isOn: $wifiEnabled) { - Label("enabled", systemImage: "wifi") + Label("Enabled", systemImage: "wifi") Text("Enabling WiFi will disable the bluetooth connection to the app.") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) HStack { - Label("ssid", systemImage: "network") - TextField("ssid", text: $wifiSsid) + Label("SSID", systemImage: "network") + TextField("SSID", text: $wifiSsid) .foregroundColor(.gray) .autocapitalization(.none) .disableAutocorrection(true) @@ -60,8 +60,8 @@ struct NetworkConfig: View { } .keyboardType(.default) HStack { - Label("password", systemImage: "wallet.pass") - TextField("password", text: $wifiPsk) + Label("Password", systemImage: "wallet.pass") + TextField("Password", text: $wifiPsk) .foregroundColor(.gray) .autocapitalization(.none) .disableAutocorrection(true) @@ -82,7 +82,7 @@ struct NetworkConfig: View { if node.metadata?.hasEthernet ?? false { Section(header: Text("Ethernet Options")) { Toggle(isOn: $ethEnabled) { - Label("enabled", systemImage: "network") + Label("Enabled", systemImage: "network") Text("Enabling Ethernet will disable the bluetooth connection to the app.") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) @@ -92,7 +92,7 @@ struct NetworkConfig: View { if node.metadata?.hasEthernet ?? false || node.metadata?.hasWifi ?? false { Section(header: Text("UDP Broadcast")) { Toggle(isOn: $udpEnabled) { - Label("enabled", systemImage: "point.3.connected.trianglepath.dotted") + Label("Enabled", systemImage: "point.3.connected.trianglepath.dotted") Text("Enable broadcasting packets via UDP over the local network.") } } @@ -123,7 +123,7 @@ struct NetworkConfig: View { } } } - .navigationTitle("network.config") + .navigationTitle("Network Config") .navigationBarItems( trailing: ZStack { ConnectedDevice( diff --git a/Meshtastic/Views/Settings/Config/PositionConfig.swift b/Meshtastic/Views/Settings/Config/PositionConfig.swift index db0574c7..8fbd9d14 100644 --- a/Meshtastic/Views/Settings/Config/PositionConfig.swift +++ b/Meshtastic/Views/Settings/Config/PositionConfig.swift @@ -114,7 +114,7 @@ struct PositionConfig: View { Picker("Minimum Distance", selection: $broadcastSmartMinimumDistance) { ForEach(10..<151) { if $0 == 0 { - Text("unset") + Text("Unset") } else { if $0.isMultiple(of: 5) { Text("\($0)") @@ -139,7 +139,6 @@ struct PositionConfig: View { ForEach(GpsMode.allCases, id: \.self) { at in Text(at.description) .tag(at.id) - } } .pickerStyle(SegmentedPickerStyle()) @@ -210,7 +209,7 @@ struct PositionConfig: View { } Toggle(isOn: $includeTimestamp) { // 128 - Label("timestamp", systemImage: "clock") + Label("Timestamp", systemImage: "clock") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) .onChange(of: includeTimestamp) { _, newIncludeTimestamp in @@ -283,7 +282,7 @@ struct PositionConfig: View { Picker("GPS Receive GPIO", selection: $rxGpio) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -293,7 +292,7 @@ struct PositionConfig: View { Picker("GPS Transmit GPIO", selection: $txGpio) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -303,7 +302,7 @@ struct PositionConfig: View { Picker("GPS EN GPIO", selection: $gpsEnGpio) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -314,7 +313,6 @@ struct PositionConfig: View { .font(.caption) } } - var saveButton: some View { SaveConfigButton(node: node, hasChanges: $hasChanges) { if fixedPosition && !supportedVersion { @@ -396,14 +394,10 @@ struct PositionConfig: View { } saveButton } - .navigationTitle("position.config") + .navigationTitle("Position Config") .navigationBarItems( trailing: ZStack { - ConnectedDevice( - bluetoothOn: bleManager.isSwitchedOn, - deviceConnected: bleManager.connectedPeripheral != nil, - name: bleManager.connectedPeripheral?.shortName ?? "?" - ) + ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: bleManager.connectedPeripheral?.shortName ?? "?") } ) .onFirstAppear { diff --git a/Meshtastic/Views/Settings/Config/PowerConfig.swift b/Meshtastic/Views/Settings/Config/PowerConfig.swift index abd2e30f..e3c26ffb 100644 --- a/Meshtastic/Views/Settings/Config/PowerConfig.swift +++ b/Meshtastic/Views/Settings/Config/PowerConfig.swift @@ -27,22 +27,22 @@ struct PowerConfig: View { var body: some View { Form { - ConfigHeader(title: "config.power.title", config: \.powerConfig, node: node, onAppear: setPowerValues) + ConfigHeader(title: "Power Config", config: \.powerConfig, node: node, onAppear: setPowerValues) Section { if (currentDevice?.architecture == .esp32 || currentDevice?.architecture == .esp32S3) || (currentDevice?.architecture == .nrf52840 && (node?.deviceConfig?.role ?? 0 == 5 || node?.deviceConfig?.role ?? 0 == 6)) { Toggle(isOn: $isPowerSaving) { - Label("config.power.saving", systemImage: "bolt") - Text("config.power.saving.description") + Label("Power Saving", systemImage: "bolt") + Text("Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio. Don't use this setting if you want to use your device with the phone apps or are using a device without a user button.") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) } Toggle(isOn: $shutdownOnPowerLoss) { - Label("config.power.shutdown.on.power.loss", systemImage: "power") + Label("Shutdown on Power Loss", systemImage: "power") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) if shutdownOnPowerLoss { - Picker("config.power.shutdown.after.secs", selection: $shutdownAfterSecs) { + Picker("After", selection: $shutdownAfterSecs) { ForEach(PowerIntervals.allCases) { at in Text(at.description) } @@ -50,20 +50,20 @@ struct PowerConfig: View { .pickerStyle(DefaultPickerStyle()) } } header: { - Text("config.power.settings") + Text("Power") } if currentDevice?.architecture == .esp32 || currentDevice?.architecture == .esp32S3 { Section { Toggle(isOn: $adcOverride) { - Text("config.power.adc.override") + Text("ADC Override") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) if adcOverride { HStack { - Text("config.power.adc.multiplier") + Text("Multiplier") Spacer() - FloatField(title: "config.power.adc.multiplier", number: $adcMultiplier) { + FloatField(title: "Multiplier", number: $adcMultiplier) { (2.0 ... 6.0).contains($0) } .focused($isFocused) @@ -71,7 +71,7 @@ struct PowerConfig: View { } } } header: { - Text("config.power.section.battery") + Text("Battery") } // Section { // Picker("config.power.wait.bluetooth.secs", selection: $waitBluetoothSecs) { @@ -101,7 +101,7 @@ struct PowerConfig: View { } } .disabled(self.bleManager.connectedPeripheral == nil || node?.powerConfig == nil) - .navigationTitle("config.power.title") + .navigationTitle("Power Config") .navigationBarItems(trailing: ZStack { ConnectedDevice( bluetoothOn: bleManager.isSwitchedOn, diff --git a/Meshtastic/Views/Settings/Config/SaveConfigButton.swift b/Meshtastic/Views/Settings/Config/SaveConfigButton.swift index 3b185129..8e0c8701 100644 --- a/Meshtastic/Views/Settings/Config/SaveConfigButton.swift +++ b/Meshtastic/Views/Settings/Config/SaveConfigButton.swift @@ -12,7 +12,7 @@ struct SaveConfigButton: View { Button { isPresentingSaveConfirm = true } label: { - Label("save", systemImage: "square.and.arrow.down") + Label("Save", systemImage: "square.and.arrow.down") } .disabled(bleManager.connectedPeripheral == nil || !hasChanges) .buttonStyle(.bordered) @@ -24,13 +24,13 @@ struct SaveConfigButton: View { isPresented: $isPresentingSaveConfirm, titleVisibility: .visible ) { - let nodeName = node?.user?.longName ?? "unknown".localized - let buttonText = String.localizedStringWithFormat("save.config %@".localized, nodeName) + let nodeName = node?.user?.longName ?? "Unknown".localized + let buttonText = String.localizedStringWithFormat("Save Config for %@".localized, nodeName) Button(buttonText) { onConfirmation() } } message: { - Text("config.save.confirm") + Text("After config values save the node will reboot.") } } } diff --git a/Meshtastic/Views/Settings/Firmware.swift b/Meshtastic/Views/Settings/Firmware.swift index b0c9c08f..ad885d86 100644 --- a/Meshtastic/Views/Settings/Firmware.swift +++ b/Meshtastic/Views/Settings/Firmware.swift @@ -77,7 +77,7 @@ struct Firmware: View { Text("Get the latest stable firmware") .fixedSize(horizontal: false, vertical: true) .font(.callout) - Link("\(latestStable?.title ?? "unknown".localized)", destination: URL(string: "\(latestStable?.zipURL ?? "https://meshtastic.org")")!) + Link("\(latestStable?.title ?? "Unknown".localized)", destination: URL(string: "\(latestStable?.zipURL ?? "https://meshtastic.org")")!) .font(.caption) Link("Release Notes", destination: URL(string: "\(latestStable?.pageURL ?? "https://meshtastic.org")")!) .font(.caption) @@ -86,7 +86,7 @@ struct Firmware: View { Text("Get the latest alpha firmware") .fixedSize(horizontal: false, vertical: true) .font(.callout) - Link("\(latestAlpha?.title ?? "unknown".localized)", destination: URL(string: "\(latestAlpha?.zipURL ?? "https://meshtastic.org")")!) + Link("\(latestAlpha?.title ?? "Unknown".localized)", destination: URL(string: "\(latestAlpha?.zipURL ?? "https://meshtastic.org")")!) .font(.caption) Link("Release Notes", destination: URL(string: "\(latestAlpha?.pageURL ?? "https://meshtastic.org")")!) .font(.caption) diff --git a/Meshtastic/Views/Settings/Logs/AppLogFilter.swift b/Meshtastic/Views/Settings/Logs/AppLogFilter.swift index e6371672..eadf8e41 100644 --- a/Meshtastic/Views/Settings/Logs/AppLogFilter.swift +++ b/Meshtastic/Views/Settings/Logs/AppLogFilter.swift @@ -136,7 +136,7 @@ struct AppLogFilter: View { Button { dismiss() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) diff --git a/Meshtastic/Views/Settings/Logs/LogDetail.swift b/Meshtastic/Views/Settings/Logs/LogDetail.swift index ca5d17d6..19e03029 100644 --- a/Meshtastic/Views/Settings/Logs/LogDetail.swift +++ b/Meshtastic/Views/Settings/Logs/LogDetail.swift @@ -38,7 +38,7 @@ struct LogDetail: View { /// Time Label { HStack { - Text("log.time".localized + ":") + Text("Time".localized + ":") .font(idiom == .phone ? .caption : .title) .frame(width: idiom == .phone ? 115 : 190, alignment: .trailing) Text(log.date.formatted(dateFormatStyle)) @@ -56,7 +56,7 @@ struct LogDetail: View { /// Subsystem Label { HStack { - Text("log.subsystem".localized + ":") + Text("Subsystem".localized + ":") .font(idiom == .phone ? .caption : .title) .frame(width: idiom == .phone ? 115 : 190, alignment: .trailing) Text(log.subsystem) @@ -73,7 +73,7 @@ struct LogDetail: View { /// Process Label { HStack { - Text("log.process".localized + ":") + Text("Process".localized + ":") .font(idiom == .phone ? .caption : .title) .frame(width: idiom == .phone ? 115 : 190, alignment: .trailing) Text(log.process) @@ -90,7 +90,7 @@ struct LogDetail: View { /// Level Label { HStack { - Text("log.level".localized + ":") + Text("Level".localized + ":") .font(idiom == .phone ? .caption : .title) .frame(width: idiom == .phone ? 115 : 190, alignment: .trailing) Text(log.level.description) @@ -107,7 +107,7 @@ struct LogDetail: View { /// Category Label { HStack { - Text("log.category".localized + ":") + Text("Category".localized + ":") .font(idiom == .phone ? .caption : .title) .frame(width: idiom == .phone ? 115 : 190, alignment: .trailing) Text(log.category) @@ -124,7 +124,7 @@ struct LogDetail: View { /// message Label { - Text("log.message".localized + ":") + Text("Message".localized + ":") .font(idiom == .phone ? .caption : .title) .frame(width: idiom == .phone ? 115 : 190, alignment: .trailing) Text(log.composedMessage) @@ -151,7 +151,7 @@ struct LogDetail: View { Button { dismiss() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) diff --git a/Meshtastic/Views/Settings/RouteRecorder.swift b/Meshtastic/Views/Settings/RouteRecorder.swift index 8cee2eeb..3c7bd81a 100644 --- a/Meshtastic/Views/Settings/RouteRecorder.swift +++ b/Meshtastic/Views/Settings/RouteRecorder.swift @@ -191,7 +191,7 @@ struct RouteRecorder: View { Logger.data.error("Error Saving RouteEntity from the Route Recorder \(nsError, privacy: .public)") } } label: { - Label("start", systemImage: "play") + Label("Start", systemImage: "play") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) @@ -204,7 +204,7 @@ struct RouteRecorder: View { locationsHandler.isRecording = false locationsHandler.isRecordingPaused = true } label: { - Label("pause", systemImage: "pause") + Label("Pause", systemImage: "pause") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) @@ -216,7 +216,7 @@ struct RouteRecorder: View { locationsHandler.isRecording = true locationsHandler.isRecordingPaused = false } label: { - Label("resume", systemImage: "playpause") + Label("Resume", systemImage: "playpause") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) @@ -250,7 +250,7 @@ struct RouteRecorder: View { } isShowingDetails = false } label: { - Label("finish", systemImage: "flag.checkered") + Label("Finish", systemImage: "flag.checkered") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) @@ -261,7 +261,7 @@ struct RouteRecorder: View { Button(role: .cancel) { isShowingDetails = false } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) diff --git a/Meshtastic/Views/Settings/Routes.swift b/Meshtastic/Views/Settings/Routes.swift index 52b00fa0..23c4fa18 100644 --- a/Meshtastic/Views/Settings/Routes.swift +++ b/Meshtastic/Views/Settings/Routes.swift @@ -154,7 +154,7 @@ struct Routes: View { Logger.data.error("\(error.localizedDescription, privacy: .public)") } } label: { - Label("delete", systemImage: "trash") + Label("Delete", systemImage: "trash") } } @@ -184,7 +184,7 @@ struct Routes: View { } Toggle(isOn: $enabled) { - Label("enabled", systemImage: "point.topleft.filled.down.to.point.bottomright.curvepath") + Label("Enabled", systemImage: "point.topleft.filled.down.to.point.bottomright.curvepath") Text("Show on the mesh map.") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) @@ -200,7 +200,7 @@ struct Routes: View { .foregroundColor(Color.gray) } .onAppear { - name = selectedRoute?.name ?? "unknown".localized + name = selectedRoute?.name ?? "Unknown".localized notes = selectedRoute?.notes ?? "" enabled = selectedRoute?.enabled ?? false color = Color(UIColor(hex: UInt32(selectedRoute?.color ?? 0))) @@ -215,7 +215,7 @@ struct Routes: View { .buttonBorderShape(.capsule) .controlSize(.large) - Button("save") { + Button("Save") { selectedRoute?.name = name selectedRoute?.notes = notes selectedRoute?.enabled = enabled @@ -279,7 +279,7 @@ struct Routes: View { exportString = routeToCsvFile(locations: selectedRoute!.locations!.array as? [LocationEntity] ?? []) isExporting = true } label: { - Label("export", systemImage: "square.and.arrow.down") + Label("Export", systemImage: "square.and.arrow.down") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) diff --git a/Meshtastic/Views/Settings/SaveChannelQRCode.swift b/Meshtastic/Views/Settings/SaveChannelQRCode.swift index 0e8e13f1..892df6eb 100644 --- a/Meshtastic/Views/Settings/SaveChannelQRCode.swift +++ b/Meshtastic/Views/Settings/SaveChannelQRCode.swift @@ -43,7 +43,7 @@ struct SaveChannelQRCode: View { showError = true } } label: { - Label("save", systemImage: "square.and.arrow.down") + Label("Save", systemImage: "square.and.arrow.down") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) diff --git a/Meshtastic/Views/Settings/Settings.swift b/Meshtastic/Views/Settings/Settings.swift index 8ebcfd83..2dec1530 100644 --- a/Meshtastic/Views/Settings/Settings.swift +++ b/Meshtastic/Views/Settings/Settings.swift @@ -44,7 +44,7 @@ struct Settings: View { // MARK: Views var radioConfigurationSection: some View { - Section("radio.configuration") { + Section("Radio Configuration") { let node = nodes.first(where: { $0.num == preferredNodeNum }) if let node, let loRaConfig = node.loRaConfig, @@ -69,7 +69,7 @@ struct Settings: View { NavigationLink(value: SettingsNavigationState.lora) { Label { - Text("lora") + Text("LoRa") } icon: { Image(systemName: "dot.radiowaves.left.and.right") .rotationEffect(.degrees(-90)) @@ -78,7 +78,7 @@ struct Settings: View { NavigationLink(value: SettingsNavigationState.channels) { Label { - Text("channels") + Text("Channels") } icon: { Image(systemName: "fibrechannel") } @@ -95,7 +95,7 @@ struct Settings: View { NavigationLink(value: SettingsNavigationState.shareQRCode) { Label { - Text("share.channels") + Text("Share QR Code") } icon: { Image(systemName: "qrcode") } @@ -105,10 +105,10 @@ struct Settings: View { } var deviceConfigurationSection: some View { - Section("device.configuration") { + Section("Device Configuration") { NavigationLink(value: SettingsNavigationState.user) { Label { - Text("user") + Text("User") } icon: { Image(systemName: "person.crop.rectangle.fill") } @@ -124,7 +124,7 @@ struct Settings: View { NavigationLink(value: SettingsNavigationState.device) { Label { - Text("device") + Text("Device") } icon: { Image(systemName: "flipphone") } @@ -140,7 +140,7 @@ struct Settings: View { NavigationLink(value: SettingsNavigationState.network) { Label { - Text("network") + Text("Network") } icon: { Image(systemName: "network") } @@ -148,7 +148,7 @@ struct Settings: View { NavigationLink(value: SettingsNavigationState.position) { Label { - Text("position") + Text("Position") } icon: { Image(systemName: "location") } @@ -156,7 +156,7 @@ struct Settings: View { NavigationLink(value: SettingsNavigationState.power) { Label { - Text("config.power.settings") + Text("Power") } icon: { Image(systemName: "bolt.fill") } @@ -189,7 +189,7 @@ struct Settings: View { if isModuleSupported(.detectionsensorConfig) { NavigationLink(value: SettingsNavigationState.detectionSensor) { Label { - Text("detection.sensor") + Text("Detection Sensor") } icon: { Image(systemName: "sensor") } @@ -199,7 +199,7 @@ struct Settings: View { if isModuleSupported(.extnotifConfig) { NavigationLink(value: SettingsNavigationState.externalNotification) { Label { - Text("external.notification") + Text("External Notification") } icon: { Image(systemName: "megaphone") } @@ -209,7 +209,7 @@ struct Settings: View { if isModuleSupported(.mqttConfig) { NavigationLink(value: SettingsNavigationState.mqtt) { Label { - Text("mqtt") + Text("MQTT") } icon: { Image(systemName: "dot.radiowaves.up.forward") } @@ -219,7 +219,7 @@ struct Settings: View { if isModuleSupported(.rangetestConfig) { NavigationLink(value: SettingsNavigationState.rangeTest) { Label { - Text("range.test") + Text("Range Test") } icon: { Image(systemName: "point.3.connected.trianglepath.dotted") } @@ -229,7 +229,7 @@ struct Settings: View { if isModuleSupported(.paxcounterConfig) { NavigationLink(value: SettingsNavigationState.paxCounter) { Label { - Text("config.module.paxcounter.settings") + Text("PAX Counter") } icon: { Image(systemName: "figure.walk.motion") } @@ -239,7 +239,7 @@ struct Settings: View { if isModuleSupported(.audioConfig) { NavigationLink(value: SettingsNavigationState.ringtone) { Label { - Text("ringtone") + Text("Ringtone") } icon: { Image(systemName: "music.note.list") } @@ -249,7 +249,7 @@ struct Settings: View { if isModuleSupported(.serialConfig) { NavigationLink(value: SettingsNavigationState.serial) { Label { - Text("serial") + Text("Serial") } icon: { Image(systemName: "terminal") } @@ -269,7 +269,7 @@ struct Settings: View { if isModuleSupported(.telemetryConfig) { NavigationLink(value: SettingsNavigationState.telemetry) { Label { - Text("telemetry") + Text("Telemetry") } icon: { Image(systemName: "chart.xyaxis.line") } @@ -286,7 +286,7 @@ struct Settings: View { Text("This node does not support any configurable modules.") } } header: { - Text("module.configuration") + Text("Module Configuration") } footer: { if moduleOverride { Text("Currently showing modules that may not be supported by this node.") @@ -295,7 +295,7 @@ struct Settings: View { } var loggingSection: some View { - Section(header: Text("logging")) { + Section(header: Text("Logging")) { NavigationLink(value: SettingsNavigationState.debugLogs) { Label { Text("Logs") @@ -388,14 +388,14 @@ struct Settings: View { /// Connected Node if node.num == bleManager.connectedPeripheral?.num ?? 0 { Label { - Text("BLE: \(node.user?.longName?.addingVariationSelectors ?? "unknown".localized)") + Text("BLE: \(node.user?.longName?.addingVariationSelectors ?? "Unknown".localized)") } icon: { Image(systemName: "antenna.radiowaves.left.and.right") } .tag(Int(node.num)) } else if node.canRemoteAdmin && UserDefaults.enableAdministration && node.sessionPasskey != nil { /// Nodes using the new PKI system Label { - Text("Remote PKI Admin: \(node.user?.longName ?? "unknown".localized)") + Text("Remote PKI Admin: \(node.user?.longName ?? "Unknown".localized)") } icon: { Image(systemName: "av.remote") } @@ -403,21 +403,21 @@ struct Settings: View { .tag(Int(node.num)) } else if !UserDefaults.enableAdministration && node.metadata != nil { /// Nodes using the old admin system Label { - Text("Remote Legacy Admin: \(node.user?.longName ?? "unknown".localized)") + Text("Remote Legacy Admin: \(node.user?.longName ?? "Unknown".localized)") } icon: { Image(systemName: "av.remote") } .tag(Int(node.num)) } else if UserDefaults.enableAdministration && node.user?.pkiEncrypted ?? false { Label { - Text("Request PKI Admin: \(node.user?.longName?.addingVariationSelectors ?? "unknown".localized)") + Text("Request PKI Admin: \(node.user?.longName?.addingVariationSelectors ?? "Unknown".localized)") } icon: { Image(systemName: "rectangle.and.hand.point.up.left") } .tag(Int(node.num)) } else if !UserDefaults.enableAdministration { Label { - Text("Request Legacy Admin: \(node.user?.longName?.addingVariationSelectors ?? "unknown".localized)") + Text("Request Legacy Admin: \(node.user?.longName?.addingVariationSelectors ?? "Unknown".localized)") } icon: { Image(systemName: "rectangle.and.hand.point.up.left") } @@ -442,7 +442,7 @@ struct Settings: View { TipView(AdminChannelTip(), arrowEdge: .top) } else { if bleManager.connectedPeripheral != nil { - Text("Connected Node \(node?.user?.longName?.addingVariationSelectors ?? "unknown".localized)") + Text("Connected Node \(node?.user?.longName?.addingVariationSelectors ?? "Unknown".localized)") } } } @@ -542,7 +542,7 @@ struct Settings: View { } } } - .navigationTitle("settings") + .navigationTitle("Settings") .navigationBarItems( leading: MeshtasticLogo().onLongPressGesture(minimumDuration: 1.0) { self.moduleOverride.toggle() diff --git a/Meshtastic/Views/Settings/ShareChannels.swift b/Meshtastic/Views/Settings/ShareChannels.swift index 7ea643ae..fa0e6370 100644 --- a/Meshtastic/Views/Settings/ShareChannels.swift +++ b/Meshtastic/Views/Settings/ShareChannels.swift @@ -62,7 +62,7 @@ struct ShareChannels: View { Grid { GridRow { Spacer() - Text("include") + Text("Include") .font(.caption) .fontWeight(.bold) .padding(.trailing) @@ -70,7 +70,7 @@ struct ShareChannels: View { .font(.caption) .fontWeight(.bold) .padding(.trailing) - Text("encrypted") + Text("Encrypted") .font(.caption) .fontWeight(.bold) } @@ -226,7 +226,7 @@ struct ShareChannels: View { } } } - .navigationTitle("generate.qr.code") + .navigationTitle("Generate QR Code") .navigationBarTitleDisplayMode(.inline) .navigationBarItems(trailing: ZStack { diff --git a/Meshtastic/Views/Settings/UserConfig.swift b/Meshtastic/Views/Settings/UserConfig.swift index 644c0077..4a47255c 100644 --- a/Meshtastic/Views/Settings/UserConfig.swift +++ b/Meshtastic/Views/Settings/UserConfig.swift @@ -141,7 +141,7 @@ struct UserConfig: View { Button { isPresentingSaveConfirm = true } label: { - Label("save", systemImage: "square.and.arrow.down") + Label("Save", systemImage: "square.and.arrow.down") } .disabled(bleManager.connectedPeripheral == nil || !hasChanges) .buttonStyle(.bordered) @@ -186,7 +186,7 @@ struct UserConfig: View { } } } message: { - Text("config.save.confirm") + Text("After config values save the node will reboot.") } } Spacer() diff --git a/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift index 5a9a75a5..e450d566 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/admin.proto @@ -25,7 +24,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// This message is handled by the Admin module and is responsible for all settings/channel read/write operations. /// This message is used to do settings operations to both remote AND local nodes. /// (Prior to 1.2 these operations were done via special ToRadio operations) -public struct AdminMessage: @unchecked Sendable { +public struct AdminMessage { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -564,7 +563,7 @@ public struct AdminMessage: @unchecked Sendable { /// /// TODO: REPLACE - public enum OneOf_PayloadVariant: Equatable, Sendable { + public enum OneOf_PayloadVariant: Equatable { /// /// Send the specified channel in the response to this message /// NOTE: This field is sent with the channel index + 1 (to ensure we never try to send 'zero' - which protobufs treats as not present) @@ -729,11 +728,225 @@ public struct AdminMessage: @unchecked Sendable { /// Tell the node to reset the nodedb. case nodedbReset(Int32) + #if !swift(>=4.1) + public static func ==(lhs: AdminMessage.OneOf_PayloadVariant, rhs: AdminMessage.OneOf_PayloadVariant) -> Bool { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch (lhs, rhs) { + case (.getChannelRequest, .getChannelRequest): return { + guard case .getChannelRequest(let l) = lhs, case .getChannelRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getChannelResponse, .getChannelResponse): return { + guard case .getChannelResponse(let l) = lhs, case .getChannelResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getOwnerRequest, .getOwnerRequest): return { + guard case .getOwnerRequest(let l) = lhs, case .getOwnerRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getOwnerResponse, .getOwnerResponse): return { + guard case .getOwnerResponse(let l) = lhs, case .getOwnerResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getConfigRequest, .getConfigRequest): return { + guard case .getConfigRequest(let l) = lhs, case .getConfigRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getConfigResponse, .getConfigResponse): return { + guard case .getConfigResponse(let l) = lhs, case .getConfigResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getModuleConfigRequest, .getModuleConfigRequest): return { + guard case .getModuleConfigRequest(let l) = lhs, case .getModuleConfigRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getModuleConfigResponse, .getModuleConfigResponse): return { + guard case .getModuleConfigResponse(let l) = lhs, case .getModuleConfigResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getCannedMessageModuleMessagesRequest, .getCannedMessageModuleMessagesRequest): return { + guard case .getCannedMessageModuleMessagesRequest(let l) = lhs, case .getCannedMessageModuleMessagesRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getCannedMessageModuleMessagesResponse, .getCannedMessageModuleMessagesResponse): return { + guard case .getCannedMessageModuleMessagesResponse(let l) = lhs, case .getCannedMessageModuleMessagesResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getDeviceMetadataRequest, .getDeviceMetadataRequest): return { + guard case .getDeviceMetadataRequest(let l) = lhs, case .getDeviceMetadataRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getDeviceMetadataResponse, .getDeviceMetadataResponse): return { + guard case .getDeviceMetadataResponse(let l) = lhs, case .getDeviceMetadataResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getRingtoneRequest, .getRingtoneRequest): return { + guard case .getRingtoneRequest(let l) = lhs, case .getRingtoneRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getRingtoneResponse, .getRingtoneResponse): return { + guard case .getRingtoneResponse(let l) = lhs, case .getRingtoneResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getDeviceConnectionStatusRequest, .getDeviceConnectionStatusRequest): return { + guard case .getDeviceConnectionStatusRequest(let l) = lhs, case .getDeviceConnectionStatusRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getDeviceConnectionStatusResponse, .getDeviceConnectionStatusResponse): return { + guard case .getDeviceConnectionStatusResponse(let l) = lhs, case .getDeviceConnectionStatusResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setHamMode, .setHamMode): return { + guard case .setHamMode(let l) = lhs, case .setHamMode(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getNodeRemoteHardwarePinsRequest, .getNodeRemoteHardwarePinsRequest): return { + guard case .getNodeRemoteHardwarePinsRequest(let l) = lhs, case .getNodeRemoteHardwarePinsRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getNodeRemoteHardwarePinsResponse, .getNodeRemoteHardwarePinsResponse): return { + guard case .getNodeRemoteHardwarePinsResponse(let l) = lhs, case .getNodeRemoteHardwarePinsResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.enterDfuModeRequest, .enterDfuModeRequest): return { + guard case .enterDfuModeRequest(let l) = lhs, case .enterDfuModeRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.deleteFileRequest, .deleteFileRequest): return { + guard case .deleteFileRequest(let l) = lhs, case .deleteFileRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setScale, .setScale): return { + guard case .setScale(let l) = lhs, case .setScale(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.backupPreferences, .backupPreferences): return { + guard case .backupPreferences(let l) = lhs, case .backupPreferences(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.restorePreferences, .restorePreferences): return { + guard case .restorePreferences(let l) = lhs, case .restorePreferences(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.removeBackupPreferences, .removeBackupPreferences): return { + guard case .removeBackupPreferences(let l) = lhs, case .removeBackupPreferences(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setOwner, .setOwner): return { + guard case .setOwner(let l) = lhs, case .setOwner(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setChannel, .setChannel): return { + guard case .setChannel(let l) = lhs, case .setChannel(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setConfig, .setConfig): return { + guard case .setConfig(let l) = lhs, case .setConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setModuleConfig, .setModuleConfig): return { + guard case .setModuleConfig(let l) = lhs, case .setModuleConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setCannedMessageModuleMessages, .setCannedMessageModuleMessages): return { + guard case .setCannedMessageModuleMessages(let l) = lhs, case .setCannedMessageModuleMessages(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setRingtoneMessage, .setRingtoneMessage): return { + guard case .setRingtoneMessage(let l) = lhs, case .setRingtoneMessage(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.removeByNodenum, .removeByNodenum): return { + guard case .removeByNodenum(let l) = lhs, case .removeByNodenum(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setFavoriteNode, .setFavoriteNode): return { + guard case .setFavoriteNode(let l) = lhs, case .setFavoriteNode(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.removeFavoriteNode, .removeFavoriteNode): return { + guard case .removeFavoriteNode(let l) = lhs, case .removeFavoriteNode(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setFixedPosition, .setFixedPosition): return { + guard case .setFixedPosition(let l) = lhs, case .setFixedPosition(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.removeFixedPosition, .removeFixedPosition): return { + guard case .removeFixedPosition(let l) = lhs, case .removeFixedPosition(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setTimeOnly, .setTimeOnly): return { + guard case .setTimeOnly(let l) = lhs, case .setTimeOnly(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getUiConfigRequest, .getUiConfigRequest): return { + guard case .getUiConfigRequest(let l) = lhs, case .getUiConfigRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getUiConfigResponse, .getUiConfigResponse): return { + guard case .getUiConfigResponse(let l) = lhs, case .getUiConfigResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.storeUiConfig, .storeUiConfig): return { + guard case .storeUiConfig(let l) = lhs, case .storeUiConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setIgnoredNode, .setIgnoredNode): return { + guard case .setIgnoredNode(let l) = lhs, case .setIgnoredNode(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.removeIgnoredNode, .removeIgnoredNode): return { + guard case .removeIgnoredNode(let l) = lhs, case .removeIgnoredNode(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.beginEditSettings, .beginEditSettings): return { + guard case .beginEditSettings(let l) = lhs, case .beginEditSettings(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.commitEditSettings, .commitEditSettings): return { + guard case .commitEditSettings(let l) = lhs, case .commitEditSettings(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.factoryResetDevice, .factoryResetDevice): return { + guard case .factoryResetDevice(let l) = lhs, case .factoryResetDevice(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.rebootOtaSeconds, .rebootOtaSeconds): return { + guard case .rebootOtaSeconds(let l) = lhs, case .rebootOtaSeconds(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.exitSimulator, .exitSimulator): return { + guard case .exitSimulator(let l) = lhs, case .exitSimulator(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.rebootSeconds, .rebootSeconds): return { + guard case .rebootSeconds(let l) = lhs, case .rebootSeconds(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.shutdownSeconds, .shutdownSeconds): return { + guard case .shutdownSeconds(let l) = lhs, case .shutdownSeconds(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.factoryResetConfig, .factoryResetConfig): return { + guard case .factoryResetConfig(let l) = lhs, case .factoryResetConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.nodedbReset, .nodedbReset): return { + guard case .nodedbReset(let l) = lhs, case .nodedbReset(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } /// /// TODO: REPLACE - public enum ConfigType: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum ConfigType: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -813,25 +1026,11 @@ public struct AdminMessage: @unchecked Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [AdminMessage.ConfigType] = [ - .deviceConfig, - .positionConfig, - .powerConfig, - .networkConfig, - .displayConfig, - .loraConfig, - .bluetoothConfig, - .securityConfig, - .sessionkeyConfig, - .deviceuiConfig, - ] - } /// /// TODO: REPLACE - public enum ModuleConfigType: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum ModuleConfigType: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -929,26 +1128,9 @@ public struct AdminMessage: @unchecked Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [AdminMessage.ModuleConfigType] = [ - .mqttConfig, - .serialConfig, - .extnotifConfig, - .storeforwardConfig, - .rangetestConfig, - .telemetryConfig, - .cannedmsgConfig, - .audioConfig, - .remotehardwareConfig, - .neighborinfoConfig, - .ambientlightingConfig, - .detectionsensorConfig, - .paxcounterConfig, - ] - } - public enum BackupLocation: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum BackupLocation: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -980,20 +1162,61 @@ public struct AdminMessage: @unchecked Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [AdminMessage.BackupLocation] = [ - .flash, - .sd, - ] - } public init() {} } +#if swift(>=4.2) + +extension AdminMessage.ConfigType: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [AdminMessage.ConfigType] = [ + .deviceConfig, + .positionConfig, + .powerConfig, + .networkConfig, + .displayConfig, + .loraConfig, + .bluetoothConfig, + .securityConfig, + .sessionkeyConfig, + .deviceuiConfig, + ] +} + +extension AdminMessage.ModuleConfigType: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [AdminMessage.ModuleConfigType] = [ + .mqttConfig, + .serialConfig, + .extnotifConfig, + .storeforwardConfig, + .rangetestConfig, + .telemetryConfig, + .cannedmsgConfig, + .audioConfig, + .remotehardwareConfig, + .neighborinfoConfig, + .ambientlightingConfig, + .detectionsensorConfig, + .paxcounterConfig, + ] +} + +extension AdminMessage.BackupLocation: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [AdminMessage.BackupLocation] = [ + .flash, + .sd, + ] +} + +#endif // swift(>=4.2) + /// /// Parameters for setting up Meshtastic for ameteur radio usage -public struct HamParameters: Sendable { +public struct HamParameters { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1023,7 +1246,7 @@ public struct HamParameters: Sendable { /// /// Response envelope for node_remote_hardware_pins -public struct NodeRemoteHardwarePinsResponse: Sendable { +public struct NodeRemoteHardwarePinsResponse { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1037,6 +1260,16 @@ public struct NodeRemoteHardwarePinsResponse: Sendable { public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension AdminMessage: @unchecked Sendable {} +extension AdminMessage.OneOf_PayloadVariant: @unchecked Sendable {} +extension AdminMessage.ConfigType: @unchecked Sendable {} +extension AdminMessage.ModuleConfigType: @unchecked Sendable {} +extension AdminMessage.BackupLocation: @unchecked Sendable {} +extension HamParameters: @unchecked Sendable {} +extension NodeRemoteHardwarePinsResponse: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" @@ -1890,7 +2123,7 @@ extension HamParameters: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa if self.txPower != 0 { try visitor.visitSingularInt32Field(value: self.txPower, fieldNumber: 2) } - if self.frequency.bitPattern != 0 { + if self.frequency != 0 { try visitor.visitSingularFloatField(value: self.frequency, fieldNumber: 3) } if !self.shortName.isEmpty { diff --git a/MeshtasticProtobufs/Sources/meshtastic/apponly.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/apponly.pb.swift index 52dac5ca..0457077c 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/apponly.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/apponly.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/apponly.proto @@ -8,6 +7,7 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ +import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -26,7 +26,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// any SECONDARY channels. /// No DISABLED channels are included. /// This abstraction is used only on the the 'app side' of the world (ie python, javascript and android etc) to show a group of Channels as a (long) URL -public struct ChannelSet: Sendable { +public struct ChannelSet { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -53,6 +53,10 @@ public struct ChannelSet: Sendable { fileprivate var _loraConfig: Config.LoRaConfig? = nil } +#if swift(>=5.5) && canImport(_Concurrency) +extension ChannelSet: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/atak.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/atak.pb.swift index 06d6af88..867648a9 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/atak.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/atak.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/atak.proto @@ -21,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public enum Team: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum Team: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -131,6 +130,11 @@ public enum Team: SwiftProtobuf.Enum, Swift.CaseIterable { } } +} + +#if swift(>=4.2) + +extension Team: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Team] = [ .unspecifedColor, @@ -149,12 +153,13 @@ public enum Team: SwiftProtobuf.Enum, Swift.CaseIterable { .darkGreen, .brown, ] - } +#endif // swift(>=4.2) + /// /// Role of the group member -public enum MemberRole: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum MemberRole: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -228,6 +233,11 @@ public enum MemberRole: SwiftProtobuf.Enum, Swift.CaseIterable { } } +} + +#if swift(>=4.2) + +extension MemberRole: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [MemberRole] = [ .unspecifed, @@ -240,12 +250,13 @@ public enum MemberRole: SwiftProtobuf.Enum, Swift.CaseIterable { .rto, .k9, ] - } +#endif // swift(>=4.2) + /// /// Packets for the official ATAK Plugin -public struct TAKPacket: @unchecked Sendable { +public struct TAKPacket { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -326,7 +337,7 @@ public struct TAKPacket: @unchecked Sendable { /// /// The payload of the packet - public enum OneOf_PayloadVariant: Equatable, @unchecked Sendable { + public enum OneOf_PayloadVariant: Equatable { /// /// TAK position report case pli(PLI) @@ -338,6 +349,28 @@ public struct TAKPacket: @unchecked Sendable { /// May be compressed / truncated by the sender (EUD) case detail(Data) + #if !swift(>=4.1) + public static func ==(lhs: TAKPacket.OneOf_PayloadVariant, rhs: TAKPacket.OneOf_PayloadVariant) -> Bool { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch (lhs, rhs) { + case (.pli, .pli): return { + guard case .pli(let l) = lhs, case .pli(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.chat, .chat): return { + guard case .chat(let l) = lhs, case .chat(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.detail, .detail): return { + guard case .detail(let l) = lhs, case .detail(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } public init() {} @@ -349,7 +382,7 @@ public struct TAKPacket: @unchecked Sendable { /// /// ATAK GeoChat message -public struct GeoChat: Sendable { +public struct GeoChat { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -391,7 +424,7 @@ public struct GeoChat: Sendable { /// /// ATAK Group /// <__group role='Team Member' name='Cyan'/> -public struct Group: Sendable { +public struct Group { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -413,7 +446,7 @@ public struct Group: Sendable { /// /// ATAK EUD Status /// -public struct Status: Sendable { +public struct Status { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -430,7 +463,7 @@ public struct Status: Sendable { /// /// ATAK Contact /// -public struct Contact: Sendable { +public struct Contact { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -450,7 +483,7 @@ public struct Contact: Sendable { /// /// Position Location Information from ATAK -public struct PLI: Sendable { +public struct PLI { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -482,6 +515,18 @@ public struct PLI: Sendable { public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension Team: @unchecked Sendable {} +extension MemberRole: @unchecked Sendable {} +extension TAKPacket: @unchecked Sendable {} +extension TAKPacket.OneOf_PayloadVariant: @unchecked Sendable {} +extension GeoChat: @unchecked Sendable {} +extension Group: @unchecked Sendable {} +extension Status: @unchecked Sendable {} +extension Contact: @unchecked Sendable {} +extension PLI: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/cannedmessages.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/cannedmessages.pb.swift index ce1f0503..1b8c84de 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/cannedmessages.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/cannedmessages.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/cannedmessages.proto @@ -8,6 +7,7 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ +import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -22,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// Canned message module configuration. -public struct CannedMessageModuleConfig: Sendable { +public struct CannedMessageModuleConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -36,6 +36,10 @@ public struct CannedMessageModuleConfig: Sendable { public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension CannedMessageModuleConfig: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/channel.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/channel.pb.swift index 180cd698..5b9c7e49 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/channel.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/channel.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/channel.proto @@ -37,15 +36,13 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// FIXME: Add description of multi-channel support and how primary vs secondary channels are used. /// FIXME: explain how apps use channels for security. /// explain how remote settings and remote gpio are managed as an example -public struct ChannelSettings: @unchecked Sendable { +public struct ChannelSettings { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. /// /// Deprecated in favor of LoraConfig.channel_num - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var channelNum: UInt32 = 0 /// @@ -114,7 +111,7 @@ public struct ChannelSettings: @unchecked Sendable { /// /// This message is specifically for modules to store per-channel configuration data. -public struct ModuleSettings: Sendable { +public struct ModuleSettings { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -135,7 +132,7 @@ public struct ModuleSettings: Sendable { /// /// A pair of a channel number, mode and the (sharable) settings for that channel -public struct Channel: Sendable { +public struct Channel { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -173,7 +170,7 @@ public struct Channel: Sendable { /// cross band routing as needed. /// If a device has only a single radio (the common case) only one channel can be PRIMARY at a time /// (but any number of SECONDARY channels can't be sent received on that common frequency) - public enum Role: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Role: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -212,13 +209,6 @@ public struct Channel: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Channel.Role] = [ - .disabled, - .primary, - .secondary, - ] - } public init() {} @@ -226,6 +216,26 @@ public struct Channel: Sendable { fileprivate var _settings: ChannelSettings? = nil } +#if swift(>=4.2) + +extension Channel.Role: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Channel.Role] = [ + .disabled, + .primary, + .secondary, + ] +} + +#endif // swift(>=4.2) + +#if swift(>=5.5) && canImport(_Concurrency) +extension ChannelSettings: @unchecked Sendable {} +extension ModuleSettings: @unchecked Sendable {} +extension Channel: @unchecked Sendable {} +extension Channel.Role: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/clientonly.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/clientonly.pb.swift index d72c0ae1..f89a8e3c 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/clientonly.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/clientonly.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/clientonly.proto @@ -8,6 +7,7 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ +import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -23,7 +23,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// This abstraction is used to contain any configuration for provisioning a node on any client. /// It is useful for importing and exporting configurations. -public struct DeviceProfile: Sendable { +public struct DeviceProfile { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -130,6 +130,10 @@ public struct DeviceProfile: Sendable { fileprivate var _cannedMessages: String? = nil } +#if swift(>=5.5) && canImport(_Concurrency) +extension DeviceProfile: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/config.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/config.pb.swift index b3988aaa..e0d45bcf 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/config.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/config.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/config.proto @@ -21,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public struct Config: Sendable { +public struct Config { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -114,7 +113,7 @@ public struct Config: Sendable { /// /// Payload Variant - public enum OneOf_PayloadVariant: Equatable, Sendable { + public enum OneOf_PayloadVariant: Equatable { case device(Config.DeviceConfig) case position(Config.PositionConfig) case power(Config.PowerConfig) @@ -126,11 +125,61 @@ public struct Config: Sendable { case sessionkey(Config.SessionkeyConfig) case deviceUi(DeviceUIConfig) + #if !swift(>=4.1) + public static func ==(lhs: Config.OneOf_PayloadVariant, rhs: Config.OneOf_PayloadVariant) -> Bool { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch (lhs, rhs) { + case (.device, .device): return { + guard case .device(let l) = lhs, case .device(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.position, .position): return { + guard case .position(let l) = lhs, case .position(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.power, .power): return { + guard case .power(let l) = lhs, case .power(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.network, .network): return { + guard case .network(let l) = lhs, case .network(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.display, .display): return { + guard case .display(let l) = lhs, case .display(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.lora, .lora): return { + guard case .lora(let l) = lhs, case .lora(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.bluetooth, .bluetooth): return { + guard case .bluetooth(let l) = lhs, case .bluetooth(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.security, .security): return { + guard case .security(let l) = lhs, case .security(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.sessionkey, .sessionkey): return { + guard case .sessionkey(let l) = lhs, case .sessionkey(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.deviceUi, .deviceUi): return { + guard case .deviceUi(let l) = lhs, case .deviceUi(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } /// /// Configuration - public struct DeviceConfig: Sendable { + public struct DeviceConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -142,8 +191,6 @@ public struct Config: Sendable { /// /// Disabling this will disable the SerialConsole by not initilizing the StreamAPI /// Moved to SecurityConfig - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var serialEnabled: Bool = false /// @@ -173,8 +220,6 @@ public struct Config: Sendable { /// If true, device is considered to be "managed" by a mesh administrator /// Clients should then limit available configuration and administrative options inside the user interface /// Moved to SecurityConfig - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var isManaged: Bool = false /// @@ -193,7 +238,7 @@ public struct Config: Sendable { /// /// Defines the device's role on the Mesh network - public enum Role: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Role: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -211,8 +256,6 @@ public struct Config: Sendable { /// The wifi radio and the oled screen will be put to sleep. /// This mode may still potentially have higher power usage due to it's preference in message rebroadcasting on the mesh. case router // = 2 - - /// NOTE: This enum value was marked as deprecated in the .proto file case routerClient // = 3 /// @@ -313,27 +356,11 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DeviceConfig.Role] = [ - .client, - .clientMute, - .router, - .routerClient, - .repeater, - .tracker, - .sensor, - .tak, - .clientHidden, - .lostAndFound, - .takTracker, - .routerLate, - ] - } /// /// Defines the device's behavior for how messages are rebroadcast - public enum RebroadcastMode: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum RebroadcastMode: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -394,16 +421,6 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DeviceConfig.RebroadcastMode] = [ - .all, - .allSkipDecoding, - .localOnly, - .knownOnly, - .none, - .corePortnumsOnly, - ] - } public init() {} @@ -411,7 +428,7 @@ public struct Config: Sendable { /// /// Position Config - public struct PositionConfig: Sendable { + public struct PositionConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -433,8 +450,6 @@ public struct Config: Sendable { /// /// Is GPS enabled for this node? - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var gpsEnabled: Bool = false /// @@ -445,8 +460,6 @@ public struct Config: Sendable { /// /// Deprecated in favor of using smart / regular broadcast intervals as implicit attempt time - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var gpsAttemptTime: UInt32 = 0 /// @@ -487,7 +500,7 @@ public struct Config: Sendable { /// are always included (also time if GPS-synced) /// NOTE: the more fields are included, the larger the message will be - /// leading to longer airtime and a higher risk of packet loss - public enum PositionFlags: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum PositionFlags: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -577,24 +590,9 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.PositionConfig.PositionFlags] = [ - .unset, - .altitude, - .altitudeMsl, - .geoidalSeparation, - .dop, - .hvdop, - .satinview, - .seqNo, - .timestamp, - .heading, - .speed, - ] - } - public enum GpsMode: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum GpsMode: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -632,13 +630,6 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.PositionConfig.GpsMode] = [ - .disabled, - .enabled, - .notPresent, - ] - } public init() {} @@ -647,7 +638,7 @@ public struct Config: Sendable { /// /// Power Config\ /// See [Power Config](/docs/settings/config/power) for additional power config details. - public struct PowerConfig: Sendable { + public struct PowerConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -707,7 +698,7 @@ public struct Config: Sendable { /// /// Network Config - public struct NetworkConfig: Sendable { + public struct NetworkConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -758,7 +749,7 @@ public struct Config: Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum AddressMode: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum AddressMode: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -790,17 +781,11 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.NetworkConfig.AddressMode] = [ - .dhcp, - .static, - ] - } /// /// Available flags auxiliary network protocols - public enum ProtocolFlags: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum ProtocolFlags: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -832,15 +817,9 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.NetworkConfig.ProtocolFlags] = [ - .noBroadcast, - .udpBroadcast, - ] - } - public struct IpV4Config: Sendable { + public struct IpV4Config { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -873,7 +852,7 @@ public struct Config: Sendable { /// /// Display Config - public struct DisplayConfig: Sendable { + public struct DisplayConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -934,7 +913,7 @@ public struct Config: Sendable { /// /// How the GPS coordinates are displayed on the OLED screen. - public enum GpsCoordinateFormat: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum GpsCoordinateFormat: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -997,21 +976,11 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DisplayConfig.GpsCoordinateFormat] = [ - .dec, - .dms, - .utm, - .mgrs, - .olc, - .osgr, - ] - } /// /// Unit display preference - public enum DisplayUnits: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum DisplayUnits: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1043,34 +1012,32 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DisplayConfig.DisplayUnits] = [ - .metric, - .imperial, - ] - } /// /// Override OLED outo detect with this if it fails. - public enum OledType: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum OledType: SwiftProtobuf.Enum { public typealias RawValue = Int /// - /// Default / Auto + /// Default / Autodetect case oledAuto // = 0 /// - /// Default / Auto + /// Default / Autodetect case oledSsd1306 // = 1 /// - /// Default / Auto + /// Default / Autodetect case oledSh1106 // = 2 /// /// Can not be auto detected but set by proto. Used for 128x128 screens case oledSh1107 // = 3 + + /// + /// Can not be auto detected but set by proto. Used for 128x64 screens + case oledSh110712864 // = 4 case UNRECOGNIZED(Int) public init() { @@ -1083,6 +1050,7 @@ public struct Config: Sendable { case 1: self = .oledSsd1306 case 2: self = .oledSh1106 case 3: self = .oledSh1107 + case 4: self = .oledSh110712864 default: self = .UNRECOGNIZED(rawValue) } } @@ -1093,21 +1061,14 @@ public struct Config: Sendable { case .oledSsd1306: return 1 case .oledSh1106: return 2 case .oledSh1107: return 3 + case .oledSh110712864: return 4 case .UNRECOGNIZED(let i): return i } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DisplayConfig.OledType] = [ - .oledAuto, - .oledSsd1306, - .oledSh1106, - .oledSh1107, - ] - } - public enum DisplayMode: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum DisplayMode: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1151,17 +1112,9 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DisplayConfig.DisplayMode] = [ - .default, - .twocolor, - .inverted, - .color, - ] - } - public enum CompassOrientation: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum CompassOrientation: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1229,18 +1182,6 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DisplayConfig.CompassOrientation] = [ - .degrees0, - .degrees90, - .degrees180, - .degrees270, - .degrees0Inverted, - .degrees90Inverted, - .degrees180Inverted, - .degrees270Inverted, - ] - } public init() {} @@ -1248,7 +1189,7 @@ public struct Config: Sendable { /// /// Lora Config - public struct LoRaConfig: @unchecked Sendable { + public struct LoRaConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1412,7 +1353,7 @@ public struct Config: Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum RegionCode: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum RegionCode: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1564,38 +1505,12 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.LoRaConfig.RegionCode] = [ - .unset, - .us, - .eu433, - .eu868, - .cn, - .jp, - .anz, - .kr, - .tw, - .ru, - .in, - .nz865, - .th, - .lora24, - .ua433, - .ua868, - .my433, - .my919, - .sg923, - .ph433, - .ph868, - .ph915, - ] - } /// /// Standard predefined channel settings /// Note: these mappings must match ModemPreset Choice in the device code. - public enum ModemPreset: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum ModemPreset: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1609,8 +1524,6 @@ public struct Config: Sendable { /// /// Very Long Range - Slow /// Deprecated in 2.5: Works only with txco and is unusably slow - /// - /// NOTE: This enum value was marked as deprecated in the .proto file case veryLongSlow // = 2 /// @@ -1674,19 +1587,6 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.LoRaConfig.ModemPreset] = [ - .longFast, - .longSlow, - .veryLongSlow, - .mediumSlow, - .mediumFast, - .shortSlow, - .shortFast, - .longModerate, - .shortTurbo, - ] - } public init() {} @@ -1694,7 +1594,7 @@ public struct Config: Sendable { fileprivate var _storage = _StorageClass.defaultInstance } - public struct BluetoothConfig: Sendable { + public struct BluetoothConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1713,7 +1613,7 @@ public struct Config: Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum PairingMode: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum PairingMode: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1751,19 +1651,12 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.BluetoothConfig.PairingMode] = [ - .randomPin, - .fixedPin, - .noPin, - ] - } public init() {} } - public struct SecurityConfig: @unchecked Sendable { + public struct SecurityConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1807,7 +1700,7 @@ public struct Config: Sendable { /// /// Blank config request, strictly for getting the session key - public struct SessionkeyConfig: Sendable { + public struct SessionkeyConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1820,6 +1713,218 @@ public struct Config: Sendable { public init() {} } +#if swift(>=4.2) + +extension Config.DeviceConfig.Role: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DeviceConfig.Role] = [ + .client, + .clientMute, + .router, + .routerClient, + .repeater, + .tracker, + .sensor, + .tak, + .clientHidden, + .lostAndFound, + .takTracker, + .routerLate, + ] +} + +extension Config.DeviceConfig.RebroadcastMode: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DeviceConfig.RebroadcastMode] = [ + .all, + .allSkipDecoding, + .localOnly, + .knownOnly, + .none, + .corePortnumsOnly, + ] +} + +extension Config.PositionConfig.PositionFlags: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.PositionConfig.PositionFlags] = [ + .unset, + .altitude, + .altitudeMsl, + .geoidalSeparation, + .dop, + .hvdop, + .satinview, + .seqNo, + .timestamp, + .heading, + .speed, + ] +} + +extension Config.PositionConfig.GpsMode: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.PositionConfig.GpsMode] = [ + .disabled, + .enabled, + .notPresent, + ] +} + +extension Config.NetworkConfig.AddressMode: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.NetworkConfig.AddressMode] = [ + .dhcp, + .static, + ] +} + +extension Config.NetworkConfig.ProtocolFlags: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.NetworkConfig.ProtocolFlags] = [ + .noBroadcast, + .udpBroadcast, + ] +} + +extension Config.DisplayConfig.GpsCoordinateFormat: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DisplayConfig.GpsCoordinateFormat] = [ + .dec, + .dms, + .utm, + .mgrs, + .olc, + .osgr, + ] +} + +extension Config.DisplayConfig.DisplayUnits: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DisplayConfig.DisplayUnits] = [ + .metric, + .imperial, + ] +} + +extension Config.DisplayConfig.OledType: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DisplayConfig.OledType] = [ + .oledAuto, + .oledSsd1306, + .oledSh1106, + .oledSh1107, + .oledSh110712864, + ] +} + +extension Config.DisplayConfig.DisplayMode: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DisplayConfig.DisplayMode] = [ + .default, + .twocolor, + .inverted, + .color, + ] +} + +extension Config.DisplayConfig.CompassOrientation: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DisplayConfig.CompassOrientation] = [ + .degrees0, + .degrees90, + .degrees180, + .degrees270, + .degrees0Inverted, + .degrees90Inverted, + .degrees180Inverted, + .degrees270Inverted, + ] +} + +extension Config.LoRaConfig.RegionCode: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.LoRaConfig.RegionCode] = [ + .unset, + .us, + .eu433, + .eu868, + .cn, + .jp, + .anz, + .kr, + .tw, + .ru, + .in, + .nz865, + .th, + .lora24, + .ua433, + .ua868, + .my433, + .my919, + .sg923, + .ph433, + .ph868, + .ph915, + ] +} + +extension Config.LoRaConfig.ModemPreset: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.LoRaConfig.ModemPreset] = [ + .longFast, + .longSlow, + .veryLongSlow, + .mediumSlow, + .mediumFast, + .shortSlow, + .shortFast, + .longModerate, + .shortTurbo, + ] +} + +extension Config.BluetoothConfig.PairingMode: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.BluetoothConfig.PairingMode] = [ + .randomPin, + .fixedPin, + .noPin, + ] +} + +#endif // swift(>=4.2) + +#if swift(>=5.5) && canImport(_Concurrency) +extension Config: @unchecked Sendable {} +extension Config.OneOf_PayloadVariant: @unchecked Sendable {} +extension Config.DeviceConfig: @unchecked Sendable {} +extension Config.DeviceConfig.Role: @unchecked Sendable {} +extension Config.DeviceConfig.RebroadcastMode: @unchecked Sendable {} +extension Config.PositionConfig: @unchecked Sendable {} +extension Config.PositionConfig.PositionFlags: @unchecked Sendable {} +extension Config.PositionConfig.GpsMode: @unchecked Sendable {} +extension Config.PowerConfig: @unchecked Sendable {} +extension Config.NetworkConfig: @unchecked Sendable {} +extension Config.NetworkConfig.AddressMode: @unchecked Sendable {} +extension Config.NetworkConfig.ProtocolFlags: @unchecked Sendable {} +extension Config.NetworkConfig.IpV4Config: @unchecked Sendable {} +extension Config.DisplayConfig: @unchecked Sendable {} +extension Config.DisplayConfig.GpsCoordinateFormat: @unchecked Sendable {} +extension Config.DisplayConfig.DisplayUnits: @unchecked Sendable {} +extension Config.DisplayConfig.OledType: @unchecked Sendable {} +extension Config.DisplayConfig.DisplayMode: @unchecked Sendable {} +extension Config.DisplayConfig.CompassOrientation: @unchecked Sendable {} +extension Config.LoRaConfig: @unchecked Sendable {} +extension Config.LoRaConfig.RegionCode: @unchecked Sendable {} +extension Config.LoRaConfig.ModemPreset: @unchecked Sendable {} +extension Config.BluetoothConfig: @unchecked Sendable {} +extension Config.BluetoothConfig.PairingMode: @unchecked Sendable {} +extension Config.SecurityConfig: @unchecked Sendable {} +extension Config.SessionkeyConfig: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" @@ -2327,7 +2432,7 @@ extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImple if self.onBatteryShutdownAfterSecs != 0 { try visitor.visitSingularUInt32Field(value: self.onBatteryShutdownAfterSecs, fieldNumber: 2) } - if self.adcMultiplierOverride.bitPattern != 0 { + if self.adcMultiplierOverride != 0 { try visitor.visitSingularFloatField(value: self.adcMultiplierOverride, fieldNumber: 3) } if self.waitBluetoothSecs != 0 { @@ -2636,6 +2741,7 @@ extension Config.DisplayConfig.OledType: SwiftProtobuf._ProtoNameProviding { 1: .same(proto: "OLED_SSD1306"), 2: .same(proto: "OLED_SH1106"), 3: .same(proto: "OLED_SH1107"), + 4: .same(proto: "OLED_SH1107_128_64"), ] } @@ -2794,7 +2900,7 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem if _storage._codingRate != 0 { try visitor.visitSingularUInt32Field(value: _storage._codingRate, fieldNumber: 5) } - if _storage._frequencyOffset.bitPattern != 0 { + if _storage._frequencyOffset != 0 { try visitor.visitSingularFloatField(value: _storage._frequencyOffset, fieldNumber: 6) } if _storage._region != .unset { @@ -2818,7 +2924,7 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem if _storage._sx126XRxBoostedGain != false { try visitor.visitSingularBoolField(value: _storage._sx126XRxBoostedGain, fieldNumber: 13) } - if _storage._overrideFrequency.bitPattern != 0 { + if _storage._overrideFrequency != 0 { try visitor.visitSingularFloatField(value: _storage._overrideFrequency, fieldNumber: 14) } if _storage._paFanDisabled != false { @@ -3035,8 +3141,8 @@ extension Config.SessionkeyConfig: SwiftProtobuf.Message, SwiftProtobuf._Message public static let _protobuf_nameMap = SwiftProtobuf._NameMap() public mutating func decodeMessage(decoder: inout D) throws { - // Load everything into unknown fields - while try decoder.nextFieldNumber() != nil {} + while let _ = try decoder.nextFieldNumber() { + } } public func traverse(visitor: inout V) throws { diff --git a/MeshtasticProtobufs/Sources/meshtastic/connection_status.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/connection_status.pb.swift index 6847c0e3..a2ec180e 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/connection_status.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/connection_status.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/connection_status.proto @@ -8,6 +7,7 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ +import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -20,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public struct DeviceConnectionStatus: Sendable { +public struct DeviceConnectionStatus { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -81,7 +81,7 @@ public struct DeviceConnectionStatus: Sendable { /// /// WiFi connection status -public struct WifiConnectionStatus: Sendable { +public struct WifiConnectionStatus { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -114,7 +114,7 @@ public struct WifiConnectionStatus: Sendable { /// /// Ethernet connection status -public struct EthernetConnectionStatus: Sendable { +public struct EthernetConnectionStatus { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -139,7 +139,7 @@ public struct EthernetConnectionStatus: Sendable { /// /// Ethernet or WiFi connection status -public struct NetworkConnectionStatus: Sendable { +public struct NetworkConnectionStatus { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -167,7 +167,7 @@ public struct NetworkConnectionStatus: Sendable { /// /// Bluetooth connection status -public struct BluetoothConnectionStatus: Sendable { +public struct BluetoothConnectionStatus { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -191,7 +191,7 @@ public struct BluetoothConnectionStatus: Sendable { /// /// Serial connection status -public struct SerialConnectionStatus: Sendable { +public struct SerialConnectionStatus { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -209,6 +209,15 @@ public struct SerialConnectionStatus: Sendable { public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension DeviceConnectionStatus: @unchecked Sendable {} +extension WifiConnectionStatus: @unchecked Sendable {} +extension EthernetConnectionStatus: @unchecked Sendable {} +extension NetworkConnectionStatus: @unchecked Sendable {} +extension BluetoothConnectionStatus: @unchecked Sendable {} +extension SerialConnectionStatus: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift index 0281d6c1..c3835518 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/device_ui.proto @@ -21,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public enum Theme: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum Theme: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -59,18 +58,24 @@ public enum Theme: SwiftProtobuf.Enum, Swift.CaseIterable { } } +} + +#if swift(>=4.2) + +extension Theme: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Theme] = [ .dark, .light, .red, ] - } +#endif // swift(>=4.2) + /// /// Localization -public enum Language: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum Language: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -137,6 +142,10 @@ public enum Language: SwiftProtobuf.Enum, Swift.CaseIterable { /// Slovenian case slovenian // = 15 + /// + /// Ukrainian + case ukrainian // = 16 + /// /// Simplified Chinese (experimental) case simplifiedChinese // = 30 @@ -168,6 +177,7 @@ public enum Language: SwiftProtobuf.Enum, Swift.CaseIterable { case 13: self = .greek case 14: self = .norwegian case 15: self = .slovenian + case 16: self = .ukrainian case 30: self = .simplifiedChinese case 31: self = .traditionalChinese default: self = .UNRECOGNIZED(rawValue) @@ -192,12 +202,18 @@ public enum Language: SwiftProtobuf.Enum, Swift.CaseIterable { case .greek: return 13 case .norwegian: return 14 case .slovenian: return 15 + case .ukrainian: return 16 case .simplifiedChinese: return 30 case .traditionalChinese: return 31 case .UNRECOGNIZED(let i): return i } } +} + +#if swift(>=4.2) + +extension Language: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Language] = [ .english, @@ -216,13 +232,15 @@ public enum Language: SwiftProtobuf.Enum, Swift.CaseIterable { .greek, .norwegian, .slovenian, + .ukrainian, .simplifiedChinese, .traditionalChinese, ] - } -public struct DeviceUIConfig: @unchecked Sendable { +#endif // swift(>=4.2) + +public struct DeviceUIConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -343,7 +361,7 @@ public struct DeviceUIConfig: @unchecked Sendable { fileprivate var _storage = _StorageClass.defaultInstance } -public struct NodeFilter: Sendable { +public struct NodeFilter { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -381,7 +399,7 @@ public struct NodeFilter: Sendable { public init() {} } -public struct NodeHighlight: Sendable { +public struct NodeHighlight { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -411,7 +429,7 @@ public struct NodeHighlight: Sendable { public init() {} } -public struct GeoPoint: Sendable { +public struct GeoPoint { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -433,7 +451,7 @@ public struct GeoPoint: Sendable { public init() {} } -public struct Map: Sendable { +public struct Map { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -464,6 +482,16 @@ public struct Map: Sendable { fileprivate var _home: GeoPoint? = nil } +#if swift(>=5.5) && canImport(_Concurrency) +extension Theme: @unchecked Sendable {} +extension Language: @unchecked Sendable {} +extension DeviceUIConfig: @unchecked Sendable {} +extension NodeFilter: @unchecked Sendable {} +extension NodeHighlight: @unchecked Sendable {} +extension GeoPoint: @unchecked Sendable {} +extension Map: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" @@ -494,6 +522,7 @@ extension Language: SwiftProtobuf._ProtoNameProviding { 13: .same(proto: "GREEK"), 14: .same(proto: "NORWEGIAN"), 15: .same(proto: "SLOVENIAN"), + 16: .same(proto: "UKRAINIAN"), 30: .same(proto: "SIMPLIFIED_CHINESE"), 31: .same(proto: "TRADITIONAL_CHINESE"), ] diff --git a/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift index 72248719..9a5dfe8f 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/deviceonly.proto @@ -23,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// Position with static location information only for NodeDBLite -public struct PositionLite: Sendable { +public struct PositionLite { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -58,15 +57,13 @@ public struct PositionLite: Sendable { public init() {} } -public struct UserLite: @unchecked Sendable { +public struct UserLite { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. /// /// This is the addr of the radio. - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var macaddr: Data = Data() /// @@ -105,7 +102,7 @@ public struct UserLite: @unchecked Sendable { public init() {} } -public struct NodeInfoLite: @unchecked Sendable { +public struct NodeInfoLite { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -227,7 +224,7 @@ public struct NodeInfoLite: @unchecked Sendable { /// FIXME, since we write this each time we enter deep sleep (and have infinite /// flash) it would be better to use some sort of append only data structure for /// the receive queue and use the preferences store for the other stuff -public struct DeviceState: @unchecked Sendable { +public struct DeviceState { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -287,8 +284,6 @@ public struct DeviceState: @unchecked Sendable { /// Used only during development. /// Indicates developer is testing and changes should never be saved to flash. /// Deprecated in 2.3.1 - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var noSave: Bool { get {return _storage._noSave} set {_uniqueStorage()._noSave = newValue} @@ -297,8 +292,6 @@ public struct DeviceState: @unchecked Sendable { /// /// Previously used to manage GPS factory resets. /// Deprecated in 2.5.23 - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var didGpsReset: Bool { get {return _storage._didGpsReset} set {_uniqueStorage()._didGpsReset = newValue} @@ -331,7 +324,7 @@ public struct DeviceState: @unchecked Sendable { fileprivate var _storage = _StorageClass.defaultInstance } -public struct NodeDatabase: Sendable { +public struct NodeDatabase { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -353,7 +346,7 @@ public struct NodeDatabase: Sendable { /// /// The on-disk saved channels -public struct ChannelFile: Sendable { +public struct ChannelFile { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -375,7 +368,7 @@ public struct ChannelFile: Sendable { /// /// The on-disk backup of the node's preferences -public struct BackupPreferences: Sendable { +public struct BackupPreferences { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -442,6 +435,16 @@ public struct BackupPreferences: Sendable { fileprivate var _owner: User? = nil } +#if swift(>=5.5) && canImport(_Concurrency) +extension PositionLite: @unchecked Sendable {} +extension UserLite: @unchecked Sendable {} +extension NodeInfoLite: @unchecked Sendable {} +extension DeviceState: @unchecked Sendable {} +extension NodeDatabase: @unchecked Sendable {} +extension ChannelFile: @unchecked Sendable {} +extension BackupPreferences: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" @@ -677,7 +680,7 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat try { if let v = _storage._position { try visitor.visitSingularMessageField(value: v, fieldNumber: 3) } }() - if _storage._snr.bitPattern != 0 { + if _storage._snr != 0 { try visitor.visitSingularFloatField(value: _storage._snr, fieldNumber: 4) } if _storage._lastHeard != 0 { diff --git a/MeshtasticProtobufs/Sources/meshtastic/interdevice.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/interdevice.pb.swift index 165ed685..92b72c15 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/interdevice.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/interdevice.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/interdevice.proto @@ -8,6 +7,7 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ +import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -20,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public enum MessageType: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum MessageType: SwiftProtobuf.Enum { public typealias RawValue = Int case ack // = 0 @@ -82,6 +82,11 @@ public enum MessageType: SwiftProtobuf.Enum, Swift.CaseIterable { } } +} + +#if swift(>=4.2) + +extension MessageType: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [MessageType] = [ .ack, @@ -97,10 +102,11 @@ public enum MessageType: SwiftProtobuf.Enum, Swift.CaseIterable { .aht20Humidity, .tvocIndex, ] - } -public struct SensorData: Sendable { +#endif // swift(>=4.2) + +public struct SensorData { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -130,16 +136,34 @@ public struct SensorData: Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() /// The sensor data, either as a float or an uint32 - public enum OneOf_Data: Equatable, Sendable { + public enum OneOf_Data: Equatable { case floatValue(Float) case uint32Value(UInt32) + #if !swift(>=4.1) + public static func ==(lhs: SensorData.OneOf_Data, rhs: SensorData.OneOf_Data) -> Bool { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch (lhs, rhs) { + case (.floatValue, .floatValue): return { + guard case .floatValue(let l) = lhs, case .floatValue(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.uint32Value, .uint32Value): return { + guard case .uint32Value(let l) = lhs, case .uint32Value(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } public init() {} } -public struct InterdeviceMessage: Sendable { +public struct InterdeviceMessage { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -166,15 +190,41 @@ public struct InterdeviceMessage: Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() /// The message data - public enum OneOf_Data: Equatable, Sendable { + public enum OneOf_Data: Equatable { case nmea(String) case sensor(SensorData) + #if !swift(>=4.1) + public static func ==(lhs: InterdeviceMessage.OneOf_Data, rhs: InterdeviceMessage.OneOf_Data) -> Bool { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch (lhs, rhs) { + case (.nmea, .nmea): return { + guard case .nmea(let l) = lhs, case .nmea(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.sensor, .sensor): return { + guard case .sensor(let l) = lhs, case .sensor(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension MessageType: @unchecked Sendable {} +extension SensorData: @unchecked Sendable {} +extension SensorData.OneOf_Data: @unchecked Sendable {} +extension InterdeviceMessage: @unchecked Sendable {} +extension InterdeviceMessage.OneOf_Data: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/localonly.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/localonly.pb.swift index c3356286..0af27466 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/localonly.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/localonly.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/localonly.proto @@ -8,6 +7,7 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ +import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -20,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public struct LocalConfig: @unchecked Sendable { +public struct LocalConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -129,7 +129,7 @@ public struct LocalConfig: @unchecked Sendable { fileprivate var _storage = _StorageClass.defaultInstance } -public struct LocalModuleConfig: @unchecked Sendable { +public struct LocalModuleConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -293,6 +293,11 @@ public struct LocalModuleConfig: @unchecked Sendable { fileprivate var _storage = _StorageClass.defaultInstance } +#if swift(>=5.5) && canImport(_Concurrency) +extension LocalConfig: @unchecked Sendable {} +extension LocalModuleConfig: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift index 8c869ba8..051f395f 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/mesh.proto @@ -26,7 +25,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// bin/build-all.sh script. /// Because they will be used to find firmware filenames in the android app for OTA updates. /// To match the old style filenames, _ is converted to -, p is converted to . -public enum HardwareModel: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum HardwareModel: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -407,6 +406,41 @@ public enum HardwareModel: SwiftProtobuf.Enum, Swift.CaseIterable { /// Seeed XIAO nRF52840 + Wio SX1262 kit case xiaoNrf52Kit // = 88 + /// + /// Elecrow ThinkNode M1 & M2 + /// https://www.elecrow.com/wiki/ThinkNode-M1_Transceiver_Device(Meshtastic)_Power_By_nRF52840.html + /// https://www.elecrow.com/wiki/ThinkNode-M2_Transceiver_Device(Meshtastic)_Power_By_NRF52840.html (this actually uses ESP32-S3) + case thinknodeM1 // = 89 + case thinknodeM2 // = 90 + + /// + /// Lilygo T-ETH-Elite + case tEthElite // = 91 + + /// + /// Heltec HRI-3621 industrial probe + case heltecSensorHub // = 92 + + /// + /// Reserved Fried Chicken ID for future use + case reservedFriedChicken // = 93 + + /// + /// Heltec Magnetic Power Bank with Meshtastic compatible + case heltecMeshPocket // = 94 + + /// + /// Seeed Solar Node + case seeedSolarNode // = 95 + + /// + /// NomadStar Meteor Pro https://nomadstar.ch/ + case nomadstarMeteorPro // = 96 + + /// + /// Elecrow CrowPanel Advance models, ESP32-S3 and TFT with SX1262 radio plugin + case crowpanel // = 97 + /// /// ------------------------------------------------------------------------------------------------------------------------------------------ /// Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. @@ -509,6 +543,15 @@ public enum HardwareModel: SwiftProtobuf.Enum, Swift.CaseIterable { case 86: self = .meshTab case 87: self = .meshlink case 88: self = .xiaoNrf52Kit + case 89: self = .thinknodeM1 + case 90: self = .thinknodeM2 + case 91: self = .tEthElite + case 92: self = .heltecSensorHub + case 93: self = .reservedFriedChicken + case 94: self = .heltecMeshPocket + case 95: self = .seeedSolarNode + case 96: self = .nomadstarMeteorPro + case 97: self = .crowpanel case 255: self = .privateHw default: self = .UNRECOGNIZED(rawValue) } @@ -605,11 +648,25 @@ public enum HardwareModel: SwiftProtobuf.Enum, Swift.CaseIterable { case .meshTab: return 86 case .meshlink: return 87 case .xiaoNrf52Kit: return 88 + case .thinknodeM1: return 89 + case .thinknodeM2: return 90 + case .tEthElite: return 91 + case .heltecSensorHub: return 92 + case .reservedFriedChicken: return 93 + case .heltecMeshPocket: return 94 + case .seeedSolarNode: return 95 + case .nomadstarMeteorPro: return 96 + case .crowpanel: return 97 case .privateHw: return 255 case .UNRECOGNIZED(let i): return i } } +} + +#if swift(>=4.2) + +extension HardwareModel: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [HardwareModel] = [ .unset, @@ -701,14 +758,24 @@ public enum HardwareModel: SwiftProtobuf.Enum, Swift.CaseIterable { .meshTab, .meshlink, .xiaoNrf52Kit, + .thinknodeM1, + .thinknodeM2, + .tEthElite, + .heltecSensorHub, + .reservedFriedChicken, + .heltecMeshPocket, + .seeedSolarNode, + .nomadstarMeteorPro, + .crowpanel, .privateHw, ] - } +#endif // swift(>=4.2) + /// /// Shared constants between device and phone -public enum Constants: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum Constants: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -743,20 +810,26 @@ public enum Constants: SwiftProtobuf.Enum, Swift.CaseIterable { } } +} + +#if swift(>=4.2) + +extension Constants: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Constants] = [ .zero, .dataPayloadLen, ] - } +#endif // swift(>=4.2) + /// /// Error codes for critical errors /// The device might report these fault codes on the screen. /// If you encounter a fault code, please post on the meshtastic.discourse.group /// and we'll try to help. -public enum CriticalErrorCode: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum CriticalErrorCode: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -865,6 +938,11 @@ public enum CriticalErrorCode: SwiftProtobuf.Enum, Swift.CaseIterable { } } +} + +#if swift(>=4.2) + +extension CriticalErrorCode: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [CriticalErrorCode] = [ .none, @@ -882,14 +960,15 @@ public enum CriticalErrorCode: SwiftProtobuf.Enum, Swift.CaseIterable { .flashCorruptionRecoverable, .flashCorruptionUnrecoverable, ] - } +#endif // swift(>=4.2) + /// /// Enum for modules excluded from a device's configuration. /// Each value represents a ModuleConfigType that can be toggled as excluded /// by setting its corresponding bit in the `excluded_modules` bitmask field. -public enum ExcludedModules: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum ExcludedModules: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -947,6 +1026,14 @@ public enum ExcludedModules: SwiftProtobuf.Enum, Swift.CaseIterable { /// /// Paxcounter module case paxcounterConfig // = 4096 + + /// + /// Bluetooth config (not technically a module, but used to indicate bluetooth capabilities) + case bluetoothConfig // = 8192 + + /// + /// Network config (not technically a module, but used to indicate network capabilities) + case networkConfig // = 16384 case UNRECOGNIZED(Int) public init() { @@ -969,6 +1056,8 @@ public enum ExcludedModules: SwiftProtobuf.Enum, Swift.CaseIterable { case 1024: self = .ambientlightingConfig case 2048: self = .detectionsensorConfig case 4096: self = .paxcounterConfig + case 8192: self = .bluetoothConfig + case 16384: self = .networkConfig default: self = .UNRECOGNIZED(rawValue) } } @@ -989,10 +1078,17 @@ public enum ExcludedModules: SwiftProtobuf.Enum, Swift.CaseIterable { case .ambientlightingConfig: return 1024 case .detectionsensorConfig: return 2048 case .paxcounterConfig: return 4096 + case .bluetoothConfig: return 8192 + case .networkConfig: return 16384 case .UNRECOGNIZED(let i): return i } } +} + +#if swift(>=4.2) + +extension ExcludedModules: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [ExcludedModules] = [ .excludedNone, @@ -1009,13 +1105,16 @@ public enum ExcludedModules: SwiftProtobuf.Enum, Swift.CaseIterable { .ambientlightingConfig, .detectionsensorConfig, .paxcounterConfig, + .bluetoothConfig, + .networkConfig, ] - } +#endif // swift(>=4.2) + /// /// A GPS Position -public struct Position: @unchecked Sendable { +public struct Position { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1232,7 +1331,7 @@ public struct Position: @unchecked Sendable { /// /// How the location was acquired: manual, onboard GPS, external (EUD) GPS - public enum LocSource: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum LocSource: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1276,20 +1375,12 @@ public struct Position: @unchecked Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Position.LocSource] = [ - .locUnset, - .locManual, - .locInternal, - .locExternal, - ] - } /// /// How the altitude was acquired: manual, GPS int/ext, etc /// Default: same as location_source if present - public enum AltSource: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum AltSource: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1339,15 +1430,6 @@ public struct Position: @unchecked Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Position.AltSource] = [ - .altUnset, - .altManual, - .altInternal, - .altExternal, - .altBarometric, - ] - } public init() {} @@ -1355,6 +1437,31 @@ public struct Position: @unchecked Sendable { fileprivate var _storage = _StorageClass.defaultInstance } +#if swift(>=4.2) + +extension Position.LocSource: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Position.LocSource] = [ + .locUnset, + .locManual, + .locInternal, + .locExternal, + ] +} + +extension Position.AltSource: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Position.AltSource] = [ + .altUnset, + .altManual, + .altInternal, + .altExternal, + .altBarometric, + ] +} + +#endif // swift(>=4.2) + /// /// Broadcast when a newly powered mesh node wants to find a node num it can use /// Sent from the phone over bluetooth to set the user id for the owner of this node. @@ -1376,7 +1483,7 @@ public struct Position: @unchecked Sendable { /// A few nodenums are reserved and will never be requested: /// 0xff - broadcast /// 0 through 3 - for future use -public struct User: @unchecked Sendable { +public struct User { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1401,8 +1508,6 @@ public struct User: @unchecked Sendable { /// Deprecated in Meshtastic 2.1.x /// This is the addr of the radio. /// Not populated by the phone, but added by the esp32 when broadcasting - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var macaddr: Data = Data() /// @@ -1434,7 +1539,7 @@ public struct User: @unchecked Sendable { /// /// A message used in a traceroute -public struct RouteDiscovery: Sendable { +public struct RouteDiscovery { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1462,7 +1567,7 @@ public struct RouteDiscovery: Sendable { /// /// A Routing control Data packet handled by the routing module -public struct Routing: Sendable { +public struct Routing { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1502,7 +1607,7 @@ public struct Routing: Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum OneOf_Variant: Equatable, Sendable { + public enum OneOf_Variant: Equatable { /// /// A route request going from the requester case routeRequest(RouteDiscovery) @@ -1514,12 +1619,34 @@ public struct Routing: Sendable { /// in addition to ack.fail_id to provide details on the type of failure). case errorReason(Routing.Error) + #if !swift(>=4.1) + public static func ==(lhs: Routing.OneOf_Variant, rhs: Routing.OneOf_Variant) -> Bool { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch (lhs, rhs) { + case (.routeRequest, .routeRequest): return { + guard case .routeRequest(let l) = lhs, case .routeRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.routeReply, .routeReply): return { + guard case .routeReply(let l) = lhs, case .routeReply(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.errorReason, .errorReason): return { + guard case .errorReason(let l) = lhs, case .errorReason(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } /// /// A failure in delivering a message (usually used for routing control messages, but might be provided in addition to ack.fail_id to provide /// details on the type of failure). - public enum Error: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Error: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1637,36 +1764,42 @@ public struct Routing: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Routing.Error] = [ - .none, - .noRoute, - .gotNak, - .timeout, - .noInterface, - .maxRetransmit, - .noChannel, - .tooLarge, - .noResponse, - .dutyCycleLimit, - .badRequest, - .notAuthorized, - .pkiFailed, - .pkiUnknownPubkey, - .adminBadSessionKey, - .adminPublicKeyUnauthorized, - ] - } public init() {} } +#if swift(>=4.2) + +extension Routing.Error: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Routing.Error] = [ + .none, + .noRoute, + .gotNak, + .timeout, + .noInterface, + .maxRetransmit, + .noChannel, + .tooLarge, + .noResponse, + .dutyCycleLimit, + .badRequest, + .notAuthorized, + .pkiFailed, + .pkiUnknownPubkey, + .adminBadSessionKey, + .adminPublicKeyUnauthorized, + ] +} + +#endif // swift(>=4.2) + /// /// (Formerly called SubPacket) /// The payload portion fo a packet, this is the actual bytes that are sent /// inside a radio packet (because from/to are broken out by the comms library) -public struct DataMessage: @unchecked Sendable { +public struct DataMessage { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1733,7 +1866,7 @@ public struct DataMessage: @unchecked Sendable { /// /// Waypoint message, used to share arbitrary locations across the mesh -public struct Waypoint: Sendable { +public struct Waypoint { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1795,7 +1928,7 @@ public struct Waypoint: Sendable { /// /// This message will be proxied over the PhoneAPI for the client to deliver to the MQTT server -public struct MqttClientProxyMessage: @unchecked Sendable { +public struct MqttClientProxyMessage { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1836,7 +1969,7 @@ public struct MqttClientProxyMessage: @unchecked Sendable { /// /// The actual service envelope payload or text for mqtt pub / sub - public enum OneOf_PayloadVariant: Equatable, @unchecked Sendable { + public enum OneOf_PayloadVariant: Equatable { /// /// Bytes case data(Data) @@ -1844,6 +1977,24 @@ public struct MqttClientProxyMessage: @unchecked Sendable { /// Text case text(String) + #if !swift(>=4.1) + public static func ==(lhs: MqttClientProxyMessage.OneOf_PayloadVariant, rhs: MqttClientProxyMessage.OneOf_PayloadVariant) -> Bool { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch (lhs, rhs) { + case (.data, .data): return { + guard case .data(let l) = lhs, case .data(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.text, .text): return { + guard case .text(let l) = lhs, case .text(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } public init() {} @@ -1853,7 +2004,7 @@ public struct MqttClientProxyMessage: @unchecked Sendable { /// A packet envelope sent/received over the mesh /// only payload_variant is sent in the payload portion of the LORA packet. /// The other fields are either not sent at all, or sent in the special 16 byte LORA header. -public struct MeshPacket: @unchecked Sendable { +public struct MeshPacket { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1987,8 +2138,6 @@ public struct MeshPacket: @unchecked Sendable { /// /// Describe if this message is delayed - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var delayed: MeshPacket.Delayed { get {return _storage._delayed} set {_uniqueStorage()._delayed = newValue} @@ -2050,7 +2199,7 @@ public struct MeshPacket: @unchecked Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum OneOf_PayloadVariant: Equatable, @unchecked Sendable { + public enum OneOf_PayloadVariant: Equatable { /// /// TODO: REPLACE case decoded(DataMessage) @@ -2058,6 +2207,24 @@ public struct MeshPacket: @unchecked Sendable { /// TODO: REPLACE case encrypted(Data) + #if !swift(>=4.1) + public static func ==(lhs: MeshPacket.OneOf_PayloadVariant, rhs: MeshPacket.OneOf_PayloadVariant) -> Bool { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch (lhs, rhs) { + case (.decoded, .decoded): return { + guard case .decoded(let l) = lhs, case .decoded(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.encrypted, .encrypted): return { + guard case .encrypted(let l) = lhs, case .encrypted(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } /// @@ -2079,7 +2246,7 @@ public struct MeshPacket: @unchecked Sendable { /// So I bit the bullet and implemented a new (internal - not sent over the air) /// field in MeshPacket called 'priority'. /// And the transmission queue in the router object is now a priority queue. - public enum Priority: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Priority: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -2163,25 +2330,11 @@ public struct MeshPacket: @unchecked Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [MeshPacket.Priority] = [ - .unset, - .min, - .background, - .default, - .reliable, - .response, - .high, - .alert, - .ack, - .max, - ] - } /// /// Identify if this is a delayed packet - public enum Delayed: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Delayed: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -2219,13 +2372,6 @@ public struct MeshPacket: @unchecked Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [MeshPacket.Delayed] = [ - .noDelay, - .broadcast, - .direct, - ] - } public init() {} @@ -2233,6 +2379,35 @@ public struct MeshPacket: @unchecked Sendable { fileprivate var _storage = _StorageClass.defaultInstance } +#if swift(>=4.2) + +extension MeshPacket.Priority: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [MeshPacket.Priority] = [ + .unset, + .min, + .background, + .default, + .reliable, + .response, + .high, + .alert, + .ack, + .max, + ] +} + +extension MeshPacket.Delayed: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [MeshPacket.Delayed] = [ + .noDelay, + .broadcast, + .direct, + ] +} + +#endif // swift(>=4.2) + /// /// The bluetooth to device link: /// Old BTLE protocol docs from TODO, merge in above and make real docs... @@ -2250,7 +2425,7 @@ public struct MeshPacket: @unchecked Sendable { /// level etc) SET_CONFIG (switches device to a new set of radio params and /// preshared key, drops all existing nodes, force our node to rejoin this new group) /// Full information about a node on the mesh -public struct NodeInfo: @unchecked Sendable { +public struct NodeInfo { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -2363,7 +2538,7 @@ public struct NodeInfo: @unchecked Sendable { /// Unique local debugging info for this node /// Note: we don't include position or the user info, because that will come in the /// Sent to the phone in response to WantNodes. -public struct MyNodeInfo: @unchecked Sendable { +public struct MyNodeInfo { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -2402,7 +2577,7 @@ public struct MyNodeInfo: @unchecked Sendable { /// on the message it is assumed to be a continuation of the previously sent message. /// This allows the device code to use fixed maxlen 64 byte strings for messages, /// and then extend as needed by emitting multiple records. -public struct LogRecord: Sendable { +public struct LogRecord { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -2427,7 +2602,7 @@ public struct LogRecord: Sendable { /// /// Log levels, chosen to match python logging conventions. - public enum Level: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Level: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -2489,23 +2664,29 @@ public struct LogRecord: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [LogRecord.Level] = [ - .unset, - .critical, - .error, - .warning, - .info, - .debug, - .trace, - ] - } public init() {} } -public struct QueueStatus: Sendable { +#if swift(>=4.2) + +extension LogRecord.Level: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [LogRecord.Level] = [ + .unset, + .critical, + .error, + .warning, + .info, + .debug, + .trace, + ] +} + +#endif // swift(>=4.2) + +public struct QueueStatus { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -2532,7 +2713,7 @@ public struct QueueStatus: Sendable { /// It will support READ and NOTIFY. When a new packet arrives the device will BLE notify? /// It will sit in that descriptor until consumed by the phone, /// at which point the next item in the FIFO will be populated. -public struct FromRadio: Sendable { +public struct FromRadio { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -2718,7 +2899,7 @@ public struct FromRadio: Sendable { /// /// Log levels, chosen to match python logging conventions. - public enum OneOf_PayloadVariant: Equatable, Sendable { + public enum OneOf_PayloadVariant: Equatable { /// /// Log levels, chosen to match python logging conventions. case packet(MeshPacket) @@ -2776,6 +2957,80 @@ public struct FromRadio: Sendable { /// Persistent data for device-ui case deviceuiConfig(DeviceUIConfig) + #if !swift(>=4.1) + public static func ==(lhs: FromRadio.OneOf_PayloadVariant, rhs: FromRadio.OneOf_PayloadVariant) -> Bool { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch (lhs, rhs) { + case (.packet, .packet): return { + guard case .packet(let l) = lhs, case .packet(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.myInfo, .myInfo): return { + guard case .myInfo(let l) = lhs, case .myInfo(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.nodeInfo, .nodeInfo): return { + guard case .nodeInfo(let l) = lhs, case .nodeInfo(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.config, .config): return { + guard case .config(let l) = lhs, case .config(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.logRecord, .logRecord): return { + guard case .logRecord(let l) = lhs, case .logRecord(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.configCompleteID, .configCompleteID): return { + guard case .configCompleteID(let l) = lhs, case .configCompleteID(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.rebooted, .rebooted): return { + guard case .rebooted(let l) = lhs, case .rebooted(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.moduleConfig, .moduleConfig): return { + guard case .moduleConfig(let l) = lhs, case .moduleConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.channel, .channel): return { + guard case .channel(let l) = lhs, case .channel(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.queueStatus, .queueStatus): return { + guard case .queueStatus(let l) = lhs, case .queueStatus(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.xmodemPacket, .xmodemPacket): return { + guard case .xmodemPacket(let l) = lhs, case .xmodemPacket(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.metadata, .metadata): return { + guard case .metadata(let l) = lhs, case .metadata(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.mqttClientProxyMessage, .mqttClientProxyMessage): return { + guard case .mqttClientProxyMessage(let l) = lhs, case .mqttClientProxyMessage(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.fileInfo, .fileInfo): return { + guard case .fileInfo(let l) = lhs, case .fileInfo(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.clientNotification, .clientNotification): return { + guard case .clientNotification(let l) = lhs, case .clientNotification(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.deviceuiConfig, .deviceuiConfig): return { + guard case .deviceuiConfig(let l) = lhs, case .deviceuiConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } public init() {} @@ -2786,7 +3041,7 @@ public struct FromRadio: Sendable { /// To be used for important messages that should to be displayed to the user /// in the form of push notifications or validation messages when saving /// invalid configuration. -public struct ClientNotification: Sendable { +public struct ClientNotification { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -2823,7 +3078,7 @@ public struct ClientNotification: Sendable { /// /// Individual File info for the device -public struct FileInfo: Sendable { +public struct FileInfo { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -2844,7 +3099,7 @@ public struct FileInfo: Sendable { /// /// Packets/commands to the radio will be written (reliably) to the toRadio characteristic. /// Once the write completes the phone can assume it is handled. -public struct ToRadio: Sendable { +public struct ToRadio { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -2924,7 +3179,7 @@ public struct ToRadio: Sendable { /// /// Log levels, chosen to match python logging conventions. - public enum OneOf_PayloadVariant: Equatable, Sendable { + public enum OneOf_PayloadVariant: Equatable { /// /// Send this packet on the mesh case packet(MeshPacket) @@ -2951,6 +3206,40 @@ public struct ToRadio: Sendable { /// Heartbeat message (used to keep the device connection awake on serial) case heartbeat(Heartbeat) + #if !swift(>=4.1) + public static func ==(lhs: ToRadio.OneOf_PayloadVariant, rhs: ToRadio.OneOf_PayloadVariant) -> Bool { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch (lhs, rhs) { + case (.packet, .packet): return { + guard case .packet(let l) = lhs, case .packet(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.wantConfigID, .wantConfigID): return { + guard case .wantConfigID(let l) = lhs, case .wantConfigID(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.disconnect, .disconnect): return { + guard case .disconnect(let l) = lhs, case .disconnect(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.xmodemPacket, .xmodemPacket): return { + guard case .xmodemPacket(let l) = lhs, case .xmodemPacket(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.mqttClientProxyMessage, .mqttClientProxyMessage): return { + guard case .mqttClientProxyMessage(let l) = lhs, case .mqttClientProxyMessage(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.heartbeat, .heartbeat): return { + guard case .heartbeat(let l) = lhs, case .heartbeat(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } public init() {} @@ -2958,7 +3247,7 @@ public struct ToRadio: Sendable { /// /// Compressed message payload -public struct Compressed: @unchecked Sendable { +public struct Compressed { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -2978,7 +3267,7 @@ public struct Compressed: @unchecked Sendable { /// /// Full info on edges for a single node -public struct NeighborInfo: Sendable { +public struct NeighborInfo { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -3006,7 +3295,7 @@ public struct NeighborInfo: Sendable { /// /// A single edge in the mesh -public struct Neighbor: Sendable { +public struct Neighbor { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -3036,7 +3325,7 @@ public struct Neighbor: Sendable { /// /// Device metadata response -public struct DeviceMetadata: Sendable { +public struct DeviceMetadata { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -3098,7 +3387,7 @@ public struct DeviceMetadata: Sendable { /// /// A heartbeat message is sent to the node from the client to keep the connection alive. /// This is currently only needed to keep serial connections alive, but can be used by any PhoneAPI. -public struct Heartbeat: Sendable { +public struct Heartbeat { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -3110,7 +3399,7 @@ public struct Heartbeat: Sendable { /// /// RemoteHardwarePins associated with a node -public struct NodeRemoteHardwarePin: Sendable { +public struct NodeRemoteHardwarePin { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -3137,7 +3426,7 @@ public struct NodeRemoteHardwarePin: Sendable { fileprivate var _pin: RemoteHardwarePin? = nil } -public struct ChunkedPayload: @unchecked Sendable { +public struct ChunkedPayload { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -3165,7 +3454,7 @@ public struct ChunkedPayload: @unchecked Sendable { /// /// Wrapper message for broken repeated oneof support -public struct resend_chunks: Sendable { +public struct resend_chunks { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -3179,7 +3468,7 @@ public struct resend_chunks: Sendable { /// /// Responses to a ChunkedPayload request -public struct ChunkedPayloadResponse: Sendable { +public struct ChunkedPayloadResponse { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -3222,7 +3511,7 @@ public struct ChunkedPayloadResponse: Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum OneOf_PayloadVariant: Equatable, Sendable { + public enum OneOf_PayloadVariant: Equatable { /// /// Request to transfer chunked payload case requestTransfer(Bool) @@ -3233,11 +3522,77 @@ public struct ChunkedPayloadResponse: Sendable { /// Request missing indexes in the chunked payload case resendChunks(resend_chunks) + #if !swift(>=4.1) + public static func ==(lhs: ChunkedPayloadResponse.OneOf_PayloadVariant, rhs: ChunkedPayloadResponse.OneOf_PayloadVariant) -> Bool { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch (lhs, rhs) { + case (.requestTransfer, .requestTransfer): return { + guard case .requestTransfer(let l) = lhs, case .requestTransfer(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.acceptTransfer, .acceptTransfer): return { + guard case .acceptTransfer(let l) = lhs, case .acceptTransfer(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.resendChunks, .resendChunks): return { + guard case .resendChunks(let l) = lhs, case .resendChunks(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension HardwareModel: @unchecked Sendable {} +extension Constants: @unchecked Sendable {} +extension CriticalErrorCode: @unchecked Sendable {} +extension ExcludedModules: @unchecked Sendable {} +extension Position: @unchecked Sendable {} +extension Position.LocSource: @unchecked Sendable {} +extension Position.AltSource: @unchecked Sendable {} +extension User: @unchecked Sendable {} +extension RouteDiscovery: @unchecked Sendable {} +extension Routing: @unchecked Sendable {} +extension Routing.OneOf_Variant: @unchecked Sendable {} +extension Routing.Error: @unchecked Sendable {} +extension DataMessage: @unchecked Sendable {} +extension Waypoint: @unchecked Sendable {} +extension MqttClientProxyMessage: @unchecked Sendable {} +extension MqttClientProxyMessage.OneOf_PayloadVariant: @unchecked Sendable {} +extension MeshPacket: @unchecked Sendable {} +extension MeshPacket.OneOf_PayloadVariant: @unchecked Sendable {} +extension MeshPacket.Priority: @unchecked Sendable {} +extension MeshPacket.Delayed: @unchecked Sendable {} +extension NodeInfo: @unchecked Sendable {} +extension MyNodeInfo: @unchecked Sendable {} +extension LogRecord: @unchecked Sendable {} +extension LogRecord.Level: @unchecked Sendable {} +extension QueueStatus: @unchecked Sendable {} +extension FromRadio: @unchecked Sendable {} +extension FromRadio.OneOf_PayloadVariant: @unchecked Sendable {} +extension ClientNotification: @unchecked Sendable {} +extension FileInfo: @unchecked Sendable {} +extension ToRadio: @unchecked Sendable {} +extension ToRadio.OneOf_PayloadVariant: @unchecked Sendable {} +extension Compressed: @unchecked Sendable {} +extension NeighborInfo: @unchecked Sendable {} +extension Neighbor: @unchecked Sendable {} +extension DeviceMetadata: @unchecked Sendable {} +extension Heartbeat: @unchecked Sendable {} +extension NodeRemoteHardwarePin: @unchecked Sendable {} +extension ChunkedPayload: @unchecked Sendable {} +extension resend_chunks: @unchecked Sendable {} +extension ChunkedPayloadResponse: @unchecked Sendable {} +extension ChunkedPayloadResponse.OneOf_PayloadVariant: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" @@ -3333,6 +3688,15 @@ extension HardwareModel: SwiftProtobuf._ProtoNameProviding { 86: .same(proto: "MESH_TAB"), 87: .same(proto: "MESHLINK"), 88: .same(proto: "XIAO_NRF52_KIT"), + 89: .same(proto: "THINKNODE_M1"), + 90: .same(proto: "THINKNODE_M2"), + 91: .same(proto: "T_ETH_ELITE"), + 92: .same(proto: "HELTEC_SENSOR_HUB"), + 93: .same(proto: "RESERVED_FRIED_CHICKEN"), + 94: .same(proto: "HELTEC_MESH_POCKET"), + 95: .same(proto: "SEEED_SOLAR_NODE"), + 96: .same(proto: "NOMADSTAR_METEOR_PRO"), + 97: .same(proto: "CROWPANEL"), 255: .same(proto: "PRIVATE_HW"), ] } @@ -3379,6 +3743,8 @@ extension ExcludedModules: SwiftProtobuf._ProtoNameProviding { 1024: .same(proto: "AMBIENTLIGHTING_CONFIG"), 2048: .same(proto: "DETECTIONSENSOR_CONFIG"), 4096: .same(proto: "PAXCOUNTER_CONFIG"), + 8192: .same(proto: "BLUETOOTH_CONFIG"), + 16384: .same(proto: "NETWORK_CONFIG"), ] } @@ -4288,7 +4654,7 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio if _storage._rxTime != 0 { try visitor.visitSingularFixed32Field(value: _storage._rxTime, fieldNumber: 7) } - if _storage._rxSnr.bitPattern != 0 { + if _storage._rxSnr != 0 { try visitor.visitSingularFloatField(value: _storage._rxSnr, fieldNumber: 8) } if _storage._hopLimit != 0 { @@ -4490,7 +4856,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB try { if let v = _storage._position { try visitor.visitSingularMessageField(value: v, fieldNumber: 3) } }() - if _storage._snr.bitPattern != 0 { + if _storage._snr != 0 { try visitor.visitSingularFloatField(value: _storage._snr, fieldNumber: 4) } if _storage._lastHeard != 0 { @@ -5369,7 +5735,7 @@ extension Neighbor: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB if self.nodeID != 0 { try visitor.visitSingularUInt32Field(value: self.nodeID, fieldNumber: 1) } - if self.snr.bitPattern != 0 { + if self.snr != 0 { try visitor.visitSingularFloatField(value: self.snr, fieldNumber: 2) } if self.lastRxTime != 0 { @@ -5494,8 +5860,8 @@ extension Heartbeat: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation public static let _protobuf_nameMap = SwiftProtobuf._NameMap() public mutating func decodeMessage(decoder: inout D) throws { - // Load everything into unknown fields - while try decoder.nextFieldNumber() != nil {} + while let _ = try decoder.nextFieldNumber() { + } } public func traverse(visitor: inout V) throws { diff --git a/MeshtasticProtobufs/Sources/meshtastic/module_config.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/module_config.pb.swift index 0138ccff..bcf4041c 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/module_config.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/module_config.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/module_config.proto @@ -8,6 +7,7 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ +import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -20,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public enum RemoteHardwarePinType: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum RemoteHardwarePinType: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -58,18 +58,24 @@ public enum RemoteHardwarePinType: SwiftProtobuf.Enum, Swift.CaseIterable { } } +} + +#if swift(>=4.2) + +extension RemoteHardwarePinType: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [RemoteHardwarePinType] = [ .unknown, .digitalRead, .digitalWrite, ] - } +#endif // swift(>=4.2) + /// /// Module Config -public struct ModuleConfig: Sendable { +public struct ModuleConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -212,7 +218,7 @@ public struct ModuleConfig: Sendable { /// /// TODO: REPLACE - public enum OneOf_PayloadVariant: Equatable, Sendable { + public enum OneOf_PayloadVariant: Equatable { /// /// TODO: REPLACE case mqtt(ModuleConfig.MQTTConfig) @@ -253,11 +259,73 @@ public struct ModuleConfig: Sendable { /// TODO: REPLACE case paxcounter(ModuleConfig.PaxcounterConfig) + #if !swift(>=4.1) + public static func ==(lhs: ModuleConfig.OneOf_PayloadVariant, rhs: ModuleConfig.OneOf_PayloadVariant) -> Bool { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch (lhs, rhs) { + case (.mqtt, .mqtt): return { + guard case .mqtt(let l) = lhs, case .mqtt(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.serial, .serial): return { + guard case .serial(let l) = lhs, case .serial(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.externalNotification, .externalNotification): return { + guard case .externalNotification(let l) = lhs, case .externalNotification(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.storeForward, .storeForward): return { + guard case .storeForward(let l) = lhs, case .storeForward(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.rangeTest, .rangeTest): return { + guard case .rangeTest(let l) = lhs, case .rangeTest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.telemetry, .telemetry): return { + guard case .telemetry(let l) = lhs, case .telemetry(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.cannedMessage, .cannedMessage): return { + guard case .cannedMessage(let l) = lhs, case .cannedMessage(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.audio, .audio): return { + guard case .audio(let l) = lhs, case .audio(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.remoteHardware, .remoteHardware): return { + guard case .remoteHardware(let l) = lhs, case .remoteHardware(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.neighborInfo, .neighborInfo): return { + guard case .neighborInfo(let l) = lhs, case .neighborInfo(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.ambientLighting, .ambientLighting): return { + guard case .ambientLighting(let l) = lhs, case .ambientLighting(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.detectionSensor, .detectionSensor): return { + guard case .detectionSensor(let l) = lhs, case .detectionSensor(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.paxcounter, .paxcounter): return { + guard case .paxcounter(let l) = lhs, case .paxcounter(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } /// /// MQTT Client Config - public struct MQTTConfig: Sendable { + public struct MQTTConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -332,7 +400,7 @@ public struct ModuleConfig: Sendable { /// /// Settings for reporting unencrypted information about our node to a map via MQTT - public struct MapReportSettings: Sendable { + public struct MapReportSettings { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -352,7 +420,7 @@ public struct ModuleConfig: Sendable { /// /// RemoteHardwareModule Config - public struct RemoteHardwareConfig: Sendable { + public struct RemoteHardwareConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -376,7 +444,7 @@ public struct ModuleConfig: Sendable { /// /// NeighborInfoModule Config - public struct NeighborInfoConfig: Sendable { + public struct NeighborInfoConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -402,7 +470,7 @@ public struct ModuleConfig: Sendable { /// /// Detection Sensor Module Config - public struct DetectionSensorConfig: Sendable { + public struct DetectionSensorConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -449,7 +517,7 @@ public struct ModuleConfig: Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum TriggerType: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum TriggerType: SwiftProtobuf.Enum { public typealias RawValue = Int /// Event is triggered if pin is low @@ -501,16 +569,6 @@ public struct ModuleConfig: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [ModuleConfig.DetectionSensorConfig.TriggerType] = [ - .logicLow, - .logicHigh, - .fallingEdge, - .risingEdge, - .eitherEdgeActiveLow, - .eitherEdgeActiveHigh, - ] - } public init() {} @@ -518,7 +576,7 @@ public struct ModuleConfig: Sendable { /// /// Audio Config for codec2 voice - public struct AudioConfig: Sendable { + public struct AudioConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -555,7 +613,7 @@ public struct ModuleConfig: Sendable { /// /// Baudrate for codec2 voice - public enum Audio_Baud: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Audio_Baud: SwiftProtobuf.Enum { public typealias RawValue = Int case codec2Default // = 0 case codec23200 // = 1 @@ -602,19 +660,6 @@ public struct ModuleConfig: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [ModuleConfig.AudioConfig.Audio_Baud] = [ - .codec2Default, - .codec23200, - .codec22400, - .codec21600, - .codec21400, - .codec21300, - .codec21200, - .codec2700, - .codec2700B, - ] - } public init() {} @@ -622,7 +667,7 @@ public struct ModuleConfig: Sendable { /// /// Config for the Paxcounter Module - public struct PaxcounterConfig: Sendable { + public struct PaxcounterConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -648,7 +693,7 @@ public struct ModuleConfig: Sendable { /// /// Serial Config - public struct SerialConfig: Sendable { + public struct SerialConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -691,7 +736,7 @@ public struct ModuleConfig: Sendable { /// /// TODO: REPLACE - public enum Serial_Baud: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Serial_Baud: SwiftProtobuf.Enum { public typealias RawValue = Int case baudDefault // = 0 case baud110 // = 1 @@ -759,31 +804,11 @@ public struct ModuleConfig: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [ModuleConfig.SerialConfig.Serial_Baud] = [ - .baudDefault, - .baud110, - .baud300, - .baud600, - .baud1200, - .baud2400, - .baud4800, - .baud9600, - .baud19200, - .baud38400, - .baud57600, - .baud115200, - .baud230400, - .baud460800, - .baud576000, - .baud921600, - ] - } /// /// TODO: REPLACE - public enum Serial_Mode: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Serial_Mode: SwiftProtobuf.Enum { public typealias RawValue = Int case `default` // = 0 case simple // = 1 @@ -828,17 +853,6 @@ public struct ModuleConfig: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [ModuleConfig.SerialConfig.Serial_Mode] = [ - .default, - .simple, - .proto, - .textmsg, - .nmea, - .caltopo, - .ws85, - ] - } public init() {} @@ -846,7 +860,7 @@ public struct ModuleConfig: Sendable { /// /// External Notifications Config - public struct ExternalNotificationConfig: Sendable { + public struct ExternalNotificationConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -929,7 +943,7 @@ public struct ModuleConfig: Sendable { /// /// Store and Forward Module Config - public struct StoreForwardConfig: Sendable { + public struct StoreForwardConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -965,7 +979,7 @@ public struct ModuleConfig: Sendable { /// /// Preferences for the RangeTestModule - public struct RangeTestConfig: Sendable { + public struct RangeTestConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -990,7 +1004,7 @@ public struct ModuleConfig: Sendable { /// /// Configuration for both device and environment metrics - public struct TelemetryConfig: Sendable { + public struct TelemetryConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1059,7 +1073,7 @@ public struct ModuleConfig: Sendable { /// /// Canned Messages Module Config - public struct CannedMessageConfig: Sendable { + public struct CannedMessageConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1114,7 +1128,7 @@ public struct ModuleConfig: Sendable { /// /// TODO: REPLACE - public enum InputEventChar: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum InputEventChar: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1182,18 +1196,6 @@ public struct ModuleConfig: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [ModuleConfig.CannedMessageConfig.InputEventChar] = [ - .none, - .up, - .down, - .left, - .right, - .select, - .back, - .cancel, - ] - } public init() {} @@ -1202,7 +1204,7 @@ public struct ModuleConfig: Sendable { /// ///Ambient Lighting Module - Settings for control of onboard LEDs to allow users to adjust the brightness levels and respective color levels. ///Initially created for the RAK14001 RGB LED module. - public struct AmbientLightingConfig: Sendable { + public struct AmbientLightingConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1235,9 +1237,89 @@ public struct ModuleConfig: Sendable { public init() {} } +#if swift(>=4.2) + +extension ModuleConfig.DetectionSensorConfig.TriggerType: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [ModuleConfig.DetectionSensorConfig.TriggerType] = [ + .logicLow, + .logicHigh, + .fallingEdge, + .risingEdge, + .eitherEdgeActiveLow, + .eitherEdgeActiveHigh, + ] +} + +extension ModuleConfig.AudioConfig.Audio_Baud: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [ModuleConfig.AudioConfig.Audio_Baud] = [ + .codec2Default, + .codec23200, + .codec22400, + .codec21600, + .codec21400, + .codec21300, + .codec21200, + .codec2700, + .codec2700B, + ] +} + +extension ModuleConfig.SerialConfig.Serial_Baud: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [ModuleConfig.SerialConfig.Serial_Baud] = [ + .baudDefault, + .baud110, + .baud300, + .baud600, + .baud1200, + .baud2400, + .baud4800, + .baud9600, + .baud19200, + .baud38400, + .baud57600, + .baud115200, + .baud230400, + .baud460800, + .baud576000, + .baud921600, + ] +} + +extension ModuleConfig.SerialConfig.Serial_Mode: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [ModuleConfig.SerialConfig.Serial_Mode] = [ + .default, + .simple, + .proto, + .textmsg, + .nmea, + .caltopo, + .ws85, + ] +} + +extension ModuleConfig.CannedMessageConfig.InputEventChar: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [ModuleConfig.CannedMessageConfig.InputEventChar] = [ + .none, + .up, + .down, + .left, + .right, + .select, + .back, + .cancel, + ] +} + +#endif // swift(>=4.2) + /// /// A GPIO pin definition for remote hardware module -public struct RemoteHardwarePin: Sendable { +public struct RemoteHardwarePin { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1259,6 +1341,32 @@ public struct RemoteHardwarePin: Sendable { public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension RemoteHardwarePinType: @unchecked Sendable {} +extension ModuleConfig: @unchecked Sendable {} +extension ModuleConfig.OneOf_PayloadVariant: @unchecked Sendable {} +extension ModuleConfig.MQTTConfig: @unchecked Sendable {} +extension ModuleConfig.MapReportSettings: @unchecked Sendable {} +extension ModuleConfig.RemoteHardwareConfig: @unchecked Sendable {} +extension ModuleConfig.NeighborInfoConfig: @unchecked Sendable {} +extension ModuleConfig.DetectionSensorConfig: @unchecked Sendable {} +extension ModuleConfig.DetectionSensorConfig.TriggerType: @unchecked Sendable {} +extension ModuleConfig.AudioConfig: @unchecked Sendable {} +extension ModuleConfig.AudioConfig.Audio_Baud: @unchecked Sendable {} +extension ModuleConfig.PaxcounterConfig: @unchecked Sendable {} +extension ModuleConfig.SerialConfig: @unchecked Sendable {} +extension ModuleConfig.SerialConfig.Serial_Baud: @unchecked Sendable {} +extension ModuleConfig.SerialConfig.Serial_Mode: @unchecked Sendable {} +extension ModuleConfig.ExternalNotificationConfig: @unchecked Sendable {} +extension ModuleConfig.StoreForwardConfig: @unchecked Sendable {} +extension ModuleConfig.RangeTestConfig: @unchecked Sendable {} +extension ModuleConfig.TelemetryConfig: @unchecked Sendable {} +extension ModuleConfig.CannedMessageConfig: @unchecked Sendable {} +extension ModuleConfig.CannedMessageConfig.InputEventChar: @unchecked Sendable {} +extension ModuleConfig.AmbientLightingConfig: @unchecked Sendable {} +extension RemoteHardwarePin: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/mqtt.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/mqtt.pb.swift index 006fd9c8..efe6cdd5 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/mqtt.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/mqtt.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/mqtt.proto @@ -8,6 +7,7 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ +import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -22,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// This message wraps a MeshPacket with extra metadata about the sender and how it arrived. -public struct ServiceEnvelope: Sendable { +public struct ServiceEnvelope { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -57,7 +57,7 @@ public struct ServiceEnvelope: Sendable { /// /// Information about a node intended to be reported unencrypted to a map using MQTT. -public struct MapReport: Sendable { +public struct MapReport { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -121,6 +121,11 @@ public struct MapReport: Sendable { public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension ServiceEnvelope: @unchecked Sendable {} +extension MapReport: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/paxcount.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/paxcount.pb.swift index e24ed371..cf8aa463 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/paxcount.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/paxcount.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/paxcount.proto @@ -8,6 +7,7 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ +import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -22,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// TODO: REPLACE -public struct Paxcount: Sendable { +public struct Paxcount { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -44,6 +44,10 @@ public struct Paxcount: Sendable { public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension Paxcount: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/portnums.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/portnums.pb.swift index cac96bc4..3b0efa08 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/portnums.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/portnums.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/portnums.proto @@ -8,6 +7,7 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ +import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -33,7 +33,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// Note: This was formerly a Type enum named 'typ' with the same id # /// We have change to this 'portnum' based scheme for specifying app handlers for particular payloads. /// This change is backwards compatible by treating the legacy OPAQUE/CLEAR_TEXT values identically. -public enum PortNum: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum PortNum: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -290,6 +290,11 @@ public enum PortNum: SwiftProtobuf.Enum, Swift.CaseIterable { } } +} + +#if swift(>=4.2) + +extension PortNum: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [PortNum] = [ .unknownApp, @@ -323,9 +328,14 @@ public enum PortNum: SwiftProtobuf.Enum, Swift.CaseIterable { .atakForwarder, .max, ] - } +#endif // swift(>=4.2) + +#if swift(>=5.5) && canImport(_Concurrency) +extension PortNum: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. extension PortNum: SwiftProtobuf._ProtoNameProviding { diff --git a/MeshtasticProtobufs/Sources/meshtastic/powermon.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/powermon.pb.swift index 58c21701..5f51e948 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/powermon.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/powermon.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/powermon.proto @@ -8,6 +7,7 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ +import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -22,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// Note: There are no 'PowerMon' messages normally in use (PowerMons are sent only as structured logs - slogs). ///But we wrap our State enum in this message to effectively nest a namespace (without our linter yelling at us) -public struct PowerMon: Sendable { +public struct PowerMon { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -31,7 +31,7 @@ public struct PowerMon: Sendable { /// Any significant power changing event in meshtastic should be tagged with a powermon state transition. ///If you are making new meshtastic features feel free to add new entries at the end of this definition. - public enum State: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum State: SwiftProtobuf.Enum { public typealias RawValue = Int case none // = 0 case cpuDeepSleep // = 1 @@ -104,31 +104,37 @@ public struct PowerMon: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [PowerMon.State] = [ - .none, - .cpuDeepSleep, - .cpuLightSleep, - .vext1On, - .loraRxon, - .loraTxon, - .loraRxactive, - .btOn, - .ledOn, - .screenOn, - .screenDrawing, - .wifiOn, - .gpsActive, - ] - } public init() {} } +#if swift(>=4.2) + +extension PowerMon.State: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [PowerMon.State] = [ + .none, + .cpuDeepSleep, + .cpuLightSleep, + .vext1On, + .loraRxon, + .loraTxon, + .loraRxactive, + .btOn, + .ledOn, + .screenOn, + .screenDrawing, + .wifiOn, + .gpsActive, + ] +} + +#endif // swift(>=4.2) + /// /// PowerStress testing support via the C++ PowerStress module -public struct PowerStressMessage: Sendable { +public struct PowerStressMessage { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -145,7 +151,7 @@ public struct PowerStressMessage: Sendable { /// What operation would we like the UUT to perform. ///note: senders should probably set want_response in their request packets, so that they can know when the state ///machine has started processing their request - public enum Opcode: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Opcode: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -266,35 +272,48 @@ public struct PowerStressMessage: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [PowerStressMessage.Opcode] = [ - .unset, - .printInfo, - .forceQuiet, - .endQuiet, - .screenOn, - .screenOff, - .cpuIdle, - .cpuDeepsleep, - .cpuFullon, - .ledOn, - .ledOff, - .loraOff, - .loraTx, - .loraRx, - .btOff, - .btOn, - .wifiOff, - .wifiOn, - .gpsOff, - .gpsOn, - ] - } public init() {} } +#if swift(>=4.2) + +extension PowerStressMessage.Opcode: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [PowerStressMessage.Opcode] = [ + .unset, + .printInfo, + .forceQuiet, + .endQuiet, + .screenOn, + .screenOff, + .cpuIdle, + .cpuDeepsleep, + .cpuFullon, + .ledOn, + .ledOff, + .loraOff, + .loraTx, + .loraRx, + .btOff, + .btOn, + .wifiOff, + .wifiOn, + .gpsOff, + .gpsOn, + ] +} + +#endif // swift(>=4.2) + +#if swift(>=5.5) && canImport(_Concurrency) +extension PowerMon: @unchecked Sendable {} +extension PowerMon.State: @unchecked Sendable {} +extension PowerStressMessage: @unchecked Sendable {} +extension PowerStressMessage.Opcode: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" @@ -304,8 +323,8 @@ extension PowerMon: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB public static let _protobuf_nameMap = SwiftProtobuf._NameMap() public mutating func decodeMessage(decoder: inout D) throws { - // Load everything into unknown fields - while try decoder.nextFieldNumber() != nil {} + while let _ = try decoder.nextFieldNumber() { + } } public func traverse(visitor: inout V) throws { @@ -360,7 +379,7 @@ extension PowerStressMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImple if self.cmd != .unset { try visitor.visitSingularEnumField(value: self.cmd, fieldNumber: 1) } - if self.numSeconds.bitPattern != 0 { + if self.numSeconds != 0 { try visitor.visitSingularFloatField(value: self.numSeconds, fieldNumber: 2) } try unknownFields.traverse(visitor: &visitor) diff --git a/MeshtasticProtobufs/Sources/meshtastic/remote_hardware.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/remote_hardware.pb.swift index d23dc07b..ac6eeb26 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/remote_hardware.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/remote_hardware.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/remote_hardware.proto @@ -8,6 +7,7 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ +import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -30,7 +30,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// because no security yet (beyond the channel mechanism). /// It should be off by default and then protected based on some TBD mechanism /// (a special channel once multichannel support is included?) -public struct HardwareMessage: Sendable { +public struct HardwareMessage { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -52,7 +52,7 @@ public struct HardwareMessage: Sendable { /// /// TODO: REPLACE - public enum TypeEnum: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum TypeEnum: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -110,21 +110,32 @@ public struct HardwareMessage: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [HardwareMessage.TypeEnum] = [ - .unset, - .writeGpios, - .watchGpios, - .gpiosChanged, - .readGpios, - .readGpiosReply, - ] - } public init() {} } +#if swift(>=4.2) + +extension HardwareMessage.TypeEnum: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [HardwareMessage.TypeEnum] = [ + .unset, + .writeGpios, + .watchGpios, + .gpiosChanged, + .readGpios, + .readGpiosReply, + ] +} + +#endif // swift(>=4.2) + +#if swift(>=5.5) && canImport(_Concurrency) +extension HardwareMessage: @unchecked Sendable {} +extension HardwareMessage.TypeEnum: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/rtttl.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/rtttl.pb.swift index 38d0c880..6fdf3208 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/rtttl.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/rtttl.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/rtttl.proto @@ -8,6 +7,7 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ +import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -22,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// Canned message module configuration. -public struct RTTTLConfig: Sendable { +public struct RTTTLConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -36,6 +36,10 @@ public struct RTTTLConfig: Sendable { public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension RTTTLConfig: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/storeforward.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/storeforward.pb.swift index deb96569..54efa77b 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/storeforward.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/storeforward.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/storeforward.proto @@ -23,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// TODO: REPLACE -public struct StoreAndForward: @unchecked Sendable { +public struct StoreAndForward { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -80,7 +79,7 @@ public struct StoreAndForward: @unchecked Sendable { /// /// TODO: REPLACE - public enum OneOf_Variant: Equatable, @unchecked Sendable { + public enum OneOf_Variant: Equatable { /// /// TODO: REPLACE case stats(StoreAndForward.Statistics) @@ -94,12 +93,38 @@ public struct StoreAndForward: @unchecked Sendable { /// Text from history message. case text(Data) + #if !swift(>=4.1) + public static func ==(lhs: StoreAndForward.OneOf_Variant, rhs: StoreAndForward.OneOf_Variant) -> Bool { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch (lhs, rhs) { + case (.stats, .stats): return { + guard case .stats(let l) = lhs, case .stats(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.history, .history): return { + guard case .history(let l) = lhs, case .history(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.heartbeat, .heartbeat): return { + guard case .heartbeat(let l) = lhs, case .heartbeat(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.text, .text): return { + guard case .text(let l) = lhs, case .text(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } /// /// 001 - 063 = From Router /// 064 - 127 = From Client - public enum RequestResponse: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum RequestResponse: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -217,31 +242,11 @@ public struct StoreAndForward: @unchecked Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [StoreAndForward.RequestResponse] = [ - .unset, - .routerError, - .routerHeartbeat, - .routerPing, - .routerPong, - .routerBusy, - .routerHistory, - .routerStats, - .routerTextDirect, - .routerTextBroadcast, - .clientError, - .clientHistory, - .clientStats, - .clientPing, - .clientPong, - .clientAbort, - ] - } /// /// TODO: REPLACE - public struct Statistics: Sendable { + public struct Statistics { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -289,7 +294,7 @@ public struct StoreAndForward: @unchecked Sendable { /// /// TODO: REPLACE - public struct History: Sendable { + public struct History { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -314,7 +319,7 @@ public struct StoreAndForward: @unchecked Sendable { /// /// TODO: REPLACE - public struct Heartbeat: Sendable { + public struct Heartbeat { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -335,6 +340,41 @@ public struct StoreAndForward: @unchecked Sendable { public init() {} } +#if swift(>=4.2) + +extension StoreAndForward.RequestResponse: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [StoreAndForward.RequestResponse] = [ + .unset, + .routerError, + .routerHeartbeat, + .routerPing, + .routerPong, + .routerBusy, + .routerHistory, + .routerStats, + .routerTextDirect, + .routerTextBroadcast, + .clientError, + .clientHistory, + .clientStats, + .clientPing, + .clientPong, + .clientAbort, + ] +} + +#endif // swift(>=4.2) + +#if swift(>=5.5) && canImport(_Concurrency) +extension StoreAndForward: @unchecked Sendable {} +extension StoreAndForward.OneOf_Variant: @unchecked Sendable {} +extension StoreAndForward.RequestResponse: @unchecked Sendable {} +extension StoreAndForward.Statistics: @unchecked Sendable {} +extension StoreAndForward.History: @unchecked Sendable {} +extension StoreAndForward.Heartbeat: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift index 4cd8e939..da282fe2 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/telemetry.proto @@ -8,6 +7,7 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ +import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -22,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// Supported I2C Sensors for telemetry in Meshtastic -public enum TelemetrySensorType: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum TelemetrySensorType: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -270,6 +270,11 @@ public enum TelemetrySensorType: SwiftProtobuf.Enum, Swift.CaseIterable { } } +} + +#if swift(>=4.2) + +extension TelemetrySensorType: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [TelemetrySensorType] = [ .sensorUnset, @@ -311,12 +316,13 @@ public enum TelemetrySensorType: SwiftProtobuf.Enum, Swift.CaseIterable { .dps310, .rak12035, ] - } +#endif // swift(>=4.2) + /// /// Key native device metrics such as battery level -public struct DeviceMetrics: Sendable { +public struct DeviceMetrics { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -389,7 +395,7 @@ public struct DeviceMetrics: Sendable { /// /// Weather station or other environmental metrics -public struct EnvironmentMetrics: @unchecked Sendable { +public struct EnvironmentMetrics { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -647,7 +653,7 @@ public struct EnvironmentMetrics: @unchecked Sendable { /// /// Power Metrics (voltage / current / etc) -public struct PowerMetrics: Sendable { +public struct PowerMetrics { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -732,7 +738,7 @@ public struct PowerMetrics: Sendable { /// /// Air quality metrics -public struct AirQualityMetrics: Sendable { +public struct AirQualityMetrics { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -870,7 +876,7 @@ public struct AirQualityMetrics: Sendable { public mutating func clearParticles100Um() {self._particles100Um = nil} /// - /// 10.0um Particle Count + /// CO2 concentration in ppm public var co2: UInt32 { get {return _co2 ?? 0} set {_co2 = newValue} @@ -901,7 +907,7 @@ public struct AirQualityMetrics: Sendable { /// /// Local device mesh statistics -public struct LocalStats: Sendable { +public struct LocalStats { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -959,7 +965,7 @@ public struct LocalStats: Sendable { /// /// Health telemetry metrics -public struct HealthMetrics: Sendable { +public struct HealthMetrics { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1008,7 +1014,7 @@ public struct HealthMetrics: Sendable { /// /// Types of Measurements the telemetry module is equipped to handle -public struct Telemetry: Sendable { +public struct Telemetry { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1081,7 +1087,7 @@ public struct Telemetry: Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum OneOf_Variant: Equatable, Sendable { + public enum OneOf_Variant: Equatable { /// /// Key native device metrics such as battery level case deviceMetrics(DeviceMetrics) @@ -1101,6 +1107,40 @@ public struct Telemetry: Sendable { /// Health telemetry metrics case healthMetrics(HealthMetrics) + #if !swift(>=4.1) + public static func ==(lhs: Telemetry.OneOf_Variant, rhs: Telemetry.OneOf_Variant) -> Bool { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch (lhs, rhs) { + case (.deviceMetrics, .deviceMetrics): return { + guard case .deviceMetrics(let l) = lhs, case .deviceMetrics(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.environmentMetrics, .environmentMetrics): return { + guard case .environmentMetrics(let l) = lhs, case .environmentMetrics(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.airQualityMetrics, .airQualityMetrics): return { + guard case .airQualityMetrics(let l) = lhs, case .airQualityMetrics(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.powerMetrics, .powerMetrics): return { + guard case .powerMetrics(let l) = lhs, case .powerMetrics(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.localStats, .localStats): return { + guard case .localStats(let l) = lhs, case .localStats(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.healthMetrics, .healthMetrics): return { + guard case .healthMetrics(let l) = lhs, case .healthMetrics(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } public init() {} @@ -1108,7 +1148,7 @@ public struct Telemetry: Sendable { /// /// NAU7802 Telemetry configuration, for saving to flash -public struct Nau7802Config: Sendable { +public struct Nau7802Config { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1126,6 +1166,19 @@ public struct Nau7802Config: Sendable { public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension TelemetrySensorType: @unchecked Sendable {} +extension DeviceMetrics: @unchecked Sendable {} +extension EnvironmentMetrics: @unchecked Sendable {} +extension PowerMetrics: @unchecked Sendable {} +extension AirQualityMetrics: @unchecked Sendable {} +extension LocalStats: @unchecked Sendable {} +extension HealthMetrics: @unchecked Sendable {} +extension Telemetry: @unchecked Sendable {} +extension Telemetry.OneOf_Variant: @unchecked Sendable {} +extension Nau7802Config: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" @@ -1693,10 +1746,10 @@ extension LocalStats: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio if self.uptimeSeconds != 0 { try visitor.visitSingularUInt32Field(value: self.uptimeSeconds, fieldNumber: 1) } - if self.channelUtilization.bitPattern != 0 { + if self.channelUtilization != 0 { try visitor.visitSingularFloatField(value: self.channelUtilization, fieldNumber: 2) } - if self.airUtilTx.bitPattern != 0 { + if self.airUtilTx != 0 { try visitor.visitSingularFloatField(value: self.airUtilTx, fieldNumber: 3) } if self.numPacketsTx != 0 { @@ -1963,7 +2016,7 @@ extension Nau7802Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa if self.zeroOffset != 0 { try visitor.visitSingularInt32Field(value: self.zeroOffset, fieldNumber: 1) } - if self.calibrationFactor.bitPattern != 0 { + if self.calibrationFactor != 0 { try visitor.visitSingularFloatField(value: self.calibrationFactor, fieldNumber: 2) } try unknownFields.traverse(visitor: &visitor) diff --git a/MeshtasticProtobufs/Sources/meshtastic/xmodem.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/xmodem.pb.swift index 46907a58..1f41fe0b 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/xmodem.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/xmodem.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/xmodem.proto @@ -21,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public struct XModem: @unchecked Sendable { +public struct XModem { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -36,7 +35,7 @@ public struct XModem: @unchecked Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum Control: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Control: SwiftProtobuf.Enum { public typealias RawValue = Int case nul // = 0 case soh // = 1 @@ -80,23 +79,34 @@ public struct XModem: @unchecked Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [XModem.Control] = [ - .nul, - .soh, - .stx, - .eot, - .ack, - .nak, - .can, - .ctrlz, - ] - } public init() {} } +#if swift(>=4.2) + +extension XModem.Control: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [XModem.Control] = [ + .nul, + .soh, + .stx, + .eot, + .ack, + .nak, + .can, + .ctrlz, + ] +} + +#endif // swift(>=4.2) + +#if swift(>=5.5) && canImport(_Concurrency) +extension XModem: @unchecked Sendable {} +extension XModem.Control: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/Widgets/WidgetsLiveActivity.swift b/Widgets/WidgetsLiveActivity.swift index 231efec2..656cc8a1 100644 --- a/Widgets/WidgetsLiveActivity.swift +++ b/Widgets/WidgetsLiveActivity.swift @@ -31,23 +31,21 @@ struct WidgetsLiveActivity: Widget { } dynamicIsland: { context in DynamicIsland { DynamicIslandExpandedRegion(.leading) { - if context.state.totalNodes >= 100 { - Text("100+ online") + if context.state.totalNodes > 0 { + Text(" \(context.state.nodesOnline) online") .font(.callout) .foregroundStyle(.secondary) .fixedSize() } else { - Text("\(context.state.nodesOnline) of \(context.state.totalNodes) online") + Text(" ") .font(.callout) .foregroundStyle(.secondary) .fixedSize() } - // Text("\(context.state.channelUtilization.map { String(format: "Ch. Util: %.2f", $0) } ?? "--")%") Text("Ch. Util: \(context.state.channelUtilization?.formatted(.number.precision(.fractionLength(2))) ?? Constants.nilValueIndicator)%") .font(.caption2) .foregroundStyle(.secondary) .fixedSize() - // Text("\(context.state.airtime.map { String(format: "Airtime: %.2f", $0) } ?? "--")%") Text("Airtime: \(context.state.airtime?.formatted(.number.precision(.fractionLength(2))) ?? Constants.nilValueIndicator)%") .font(.caption2) .foregroundStyle(.secondary) @@ -166,7 +164,7 @@ struct LiveActivityView: View { .frame(minWidth: 25, idealWidth: 45, maxWidth: 55) Spacer() NodeInfoView(isLuminanceReduced: _isLuminanceReduced, nodeName: nodeName, uptimeSeconds: uptimeSeconds, channelUtilization: channelUtilization, airtime: airtime, sentPackets: sentPackets, receivedPackets: receivedPackets, badReceivedPackets: badReceivedPackets, - dupeReceivedPackets: dupeReceivedPackets, packetsSentRelay: packetsSentRelay, packetsCanceledRelay: packetsCanceledRelay, nodesOnline: nodesOnline, totalNodes: totalNodes, timerRange: timerRange) + dupeReceivedPackets: dupeReceivedPackets, packetsSentRelay: packetsSentRelay, packetsCanceledRelay: packetsCanceledRelay, nodesOnline: nodesOnline, timerRange: timerRange) Spacer() } .tint(.primary) @@ -191,7 +189,6 @@ struct NodeInfoView: View { var packetsSentRelay: UInt32 var packetsCanceledRelay: UInt32 var nodesOnline: UInt32 - var totalNodes: UInt32 var timerRange: ClosedRange var body: some View { @@ -220,21 +217,14 @@ struct NodeInfoView: View { .foregroundStyle(.secondary) .opacity(isLuminanceReduced ? 0.8 : 1.0) .fixedSize() - if totalNodes >= 100 { - Text("Connected: \(nodesOnline) nodes online") - .font(.caption) - .fontWeight(.medium) - .foregroundStyle(.secondary) - .opacity(isLuminanceReduced ? 0.8 : 1.0) - .fixedSize() - } else { - Text("Connected: \(nodesOnline) of \(totalNodes) nodes online") - .font(.caption) - .fontWeight(.medium) - .foregroundStyle(.secondary) - .opacity(isLuminanceReduced ? 0.8 : 1.0) - .fixedSize() - } + + Text("Connected: \(nodesOnline) nodes online") + .font(.caption) + .fontWeight(.medium) + .foregroundStyle(.secondary) + .opacity(isLuminanceReduced ? 0.8 : 1.0) + .fixedSize() + let now = Date() Text("Last Heard: \(now.formatted())") .font(.caption)