From 5618e984b6cf833eee3fb1d7ef32bccc0d2de5a7 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Fri, 7 Aug 2026 13:45:53 +0800 Subject: [PATCH] add enable-webrtc option; gate test_ipv6 under forced relay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OPTION_ENABLE_WEBRTC (hbb_common 48c2d4d) follows the udp/ipv6 punch options end to end: default on against the public server, off against private ones, same settings UI placement on desktop and mobile, and the same bool2option local-option handling. Gates: - controller: should_create_webrtc_offerer checks it first — no pc, no STUN/TURN gathering, no offer in the request; - controlled: unlike the udp/ipv6 legs, which deliberately follow the request, answering builds a pc that gathers ICE from this host, so the answerer honors this machine's own switch too. Translations for "Enable WebRTC P2P connection" added to all 50 lang files next to the IPv6 entry (IPv6 and WebRTC are invariant terms in the same grammatical slot in every one of them). Also stop probing v6 reachability (test_ipv6) under any forced relay: the v6 punch socket is never bound there, so the probe was wasted work on every ws/proxy/relay connection. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01ExUfAkYbq8UC9pQCiLy8TQ --- flutter/lib/common.dart | 3 ++- flutter/lib/consts.dart | 1 + .../lib/desktop/pages/desktop_setting_page.dart | 6 ++++++ flutter/lib/mobile/pages/settings_page.dart | 14 ++++++++++++++ src/client.rs | 10 +++++++++- src/common.rs | 12 +++++++++++- src/lang/ar.rs | 1 + src/lang/be.rs | 1 + src/lang/bg.rs | 1 + src/lang/ca.rs | 1 + src/lang/cn.rs | 1 + src/lang/cs.rs | 1 + src/lang/da.rs | 1 + src/lang/de.rs | 1 + src/lang/el.rs | 1 + src/lang/eo.rs | 1 + src/lang/es.rs | 1 + src/lang/et.rs | 1 + src/lang/eu.rs | 1 + src/lang/fa.rs | 1 + src/lang/fi.rs | 1 + src/lang/fr.rs | 1 + src/lang/ge.rs | 1 + src/lang/gu.rs | 1 + src/lang/he.rs | 1 + src/lang/hi.rs | 1 + src/lang/hr.rs | 1 + src/lang/hu.rs | 1 + src/lang/id.rs | 1 + src/lang/it.rs | 1 + src/lang/ja.rs | 1 + src/lang/ko.rs | 1 + src/lang/kz.rs | 1 + src/lang/lt.rs | 1 + src/lang/lv.rs | 1 + src/lang/ml.rs | 1 + src/lang/nb.rs | 1 + src/lang/nl.rs | 1 + src/lang/pl.rs | 1 + src/lang/pt_PT.rs | 1 + src/lang/ptbr.rs | 1 + src/lang/ro.rs | 1 + src/lang/ru.rs | 1 + src/lang/sc.rs | 1 + src/lang/sk.rs | 1 + src/lang/sl.rs | 1 + src/lang/sq.rs | 1 + src/lang/sr.rs | 1 + src/lang/sv.rs | 1 + src/lang/ta.rs | 1 + src/lang/template.rs | 1 + src/lang/th.rs | 1 + src/lang/tr.rs | 1 + src/lang/tw.rs | 1 + src/lang/uk.rs | 1 + src/lang/vi.rs | 1 + src/rendezvous_mediator.rs | 4 ++++ 57 files changed, 97 insertions(+), 3 deletions(-) diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 25eed4259..b80e0b5f9 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -1633,7 +1633,8 @@ String bool2option(String option, bool b) { String res; if (option.startsWith('enable-') && option != kOptionEnableUdpPunch && - option != kOptionEnableIpv6Punch) { + option != kOptionEnableIpv6Punch && + option != kOptionEnableWebrtc) { res = b ? defaultOptionYes : 'N'; } else if (option.startsWith('allow-') || option == kOptionStopService || diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart index 2b4ada7c7..97cee8c76 100644 --- a/flutter/lib/consts.dart +++ b/flutter/lib/consts.dart @@ -176,6 +176,7 @@ const String kOptionEnableUdpPunch = "enable-udp-punch"; const String kOptionEnableIpv6Punch = "enable-ipv6-punch"; const String kOptionAllowSyncClipboardBetweenSessions = "allow-sync-clipboard-between-sessions"; +const String kOptionEnableWebrtc = "enable-webrtc"; const String kOptionEnableTrustedDevices = "enable-trusted-devices"; const String kOptionShowVirtualMouse = "show-virtual-mouse"; const String kOptionVirtualMouseScale = "virtual-mouse-scale"; diff --git a/flutter/lib/desktop/pages/desktop_setting_page.dart b/flutter/lib/desktop/pages/desktop_setting_page.dart index b8dd80ba7..ce7499cdc 100644 --- a/flutter/lib/desktop/pages/desktop_setting_page.dart +++ b/flutter/lib/desktop/pages/desktop_setting_page.dart @@ -584,6 +584,12 @@ class _GeneralState extends State<_General> { kOptionEnableIpv6Punch, isServer: false, ), + _OptionCheckBox( + context, + 'Enable WebRTC P2P connection', + kOptionEnableWebrtc, + isServer: false, + ), Tooltip( message: translate('sync-clipboard-between-sessions-tip'), child: _OptionCheckBox( diff --git a/flutter/lib/mobile/pages/settings_page.dart b/flutter/lib/mobile/pages/settings_page.dart index 434cff501..f9b4ed2a0 100644 --- a/flutter/lib/mobile/pages/settings_page.dart +++ b/flutter/lib/mobile/pages/settings_page.dart @@ -101,6 +101,7 @@ class _SettingsState extends State with WidgetsBindingObserver { var _allowInsecureTlsFallback = false; var _disableUdp = false; var _enableIpv6Punch = false; + var _enableWebrtc = false; var _isUsingPublicServer = false; var _allowAskForNoteAtEndOfConnection = false; var _preventSleepWhileConnected = true; @@ -143,6 +144,7 @@ class _SettingsState extends State with WidgetsBindingObserver { _enableTrustedDevices = mainGetBoolOptionSync(kOptionEnableTrustedDevices); _enableUdpPunch = mainGetLocalBoolOptionSync(kOptionEnableUdpPunch); _enableIpv6Punch = mainGetLocalBoolOptionSync(kOptionEnableIpv6Punch); + _enableWebrtc = mainGetLocalBoolOptionSync(kOptionEnableWebrtc); _allowAskForNoteAtEndOfConnection = mainGetLocalBoolOptionSync(kOptionAllowAskForNoteAtEndOfConnection); _preventSleepWhileConnected = @@ -841,6 +843,18 @@ class _SettingsState extends State with WidgetsBindingObserver { }); }, ), + if (!incomingOnly) + SettingsTile.switchTile( + title: Text(translate('Enable WebRTC P2P connection')), + initialValue: _enableWebrtc, + onToggle: (v) async { + await mainSetLocalBoolOption(kOptionEnableWebrtc, v); + final newValue = mainGetLocalBoolOptionSync(kOptionEnableWebrtc); + setState(() { + _enableWebrtc = newValue; + }); + }, + ), SettingsTile( title: Text(translate('Language')), leading: Icon(Icons.translate), diff --git a/src/client.rs b/src/client.rs index 9a1808b38..e0688f4f7 100644 --- a/src/client.rs +++ b/src/client.rs @@ -464,7 +464,9 @@ impl Client { } }; - if crate::get_ipv6_punch_enabled() { + // Same relay gate as the v6 socket below: under any forced relay the v6 punch cannot + // be used, so probing v6 reachability is wasted work on every such connection. + if crate::get_ipv6_punch_enabled() && !interface.is_force_relay() { crate::test_ipv6().await; } @@ -600,6 +602,9 @@ impl Client { /// Whether to build a WebRTC offerer for this connection. /// + /// Off by default against a private rendezvous server, like the UDP/IPv6 punch options: + /// a self-hosted deployment opts in once its server (and TURN, if any) is ready. + /// /// Skips it when a SOCKS proxy is configured: WebRTC's ICE binds its own UDP sockets and /// speaks STUN directly, which would bypass the proxy policy and can leak the real IP. /// WebSocket mode does NOT skip it: ws only tunnels the signaling/relay legs to the server @@ -620,6 +625,9 @@ impl Client { /// keeps its rendezvous socket for trickle signaling and never reuses it for TCP punching; a /// separate offer-less request provides the TCP fallback when force-relay is not requested. fn should_create_webrtc_offerer(interface: &impl Interface) -> bool { + if !crate::get_webrtc_enabled() { + return false; + } if Config::is_proxy() { return false; } diff --git a/src/common.rs b/src/common.rs index 6dee71837..d289f8c8f 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1167,9 +1167,19 @@ pub fn get_ipv6_punch_enabled() -> bool { ) } +pub fn get_webrtc_enabled() -> bool { + config::option2bool( + keys::OPTION_ENABLE_WEBRTC, + &get_local_option(keys::OPTION_ENABLE_WEBRTC), + ) +} + pub fn get_local_option(key: &str) -> String { let v = LocalConfig::get_option(key); - if key == keys::OPTION_ENABLE_UDP_PUNCH || key == keys::OPTION_ENABLE_IPV6_PUNCH { + if key == keys::OPTION_ENABLE_UDP_PUNCH + || key == keys::OPTION_ENABLE_IPV6_PUNCH + || key == keys::OPTION_ENABLE_WEBRTC + { if v.is_empty() { if !is_public(&Config::get_rendezvous_server()) { return "N".to_owned(); diff --git a/src/lang/ar.rs b/src/lang/ar.rs index 47e93d5c5..589b76465 100644 --- a/src/lang/ar.rs +++ b/src/lang/ar.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "سرعة لوحة التتبع الافتراضية"), ("Numeric one-time password", "كلمة مرور رقمية لمرة واحدة"), ("Enable IPv6 P2P connection", "تمكين اتصال نظير إلى نظير عبر IPv6"), + ("Enable WebRTC P2P connection", "تمكين اتصال نظير إلى نظير عبر WebRTC"), ("Enable UDP hole punching", "تمكين تقنية حفر الثغرات عبر UDP"), ("View camera", "عرض الكاميرا"), ("Enable camera", "تمكين الكاميرا"), diff --git a/src/lang/be.rs b/src/lang/be.rs index 78cc5f455..1acb10846 100644 --- a/src/lang/be.rs +++ b/src/lang/be.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Стандартная хуткасць трэкпада"), ("Numeric one-time password", "Лічбавы аднаразовы пароль"), ("Enable IPv6 P2P connection", "Выкарыстоўваць падключэнне IPv6 P2P"), + ("Enable WebRTC P2P connection", "Выкарыстоўваць падключэнне WebRTC P2P"), ("Enable UDP hole punching", "Выкарыстоўваць UDP hole punching"), ("View camera", "Рэжым камеры"), ("Enable camera", "Уключыць камеру"), diff --git a/src/lang/bg.rs b/src/lang/bg.rs index effb91514..b836f04ef 100644 --- a/src/lang/bg.rs +++ b/src/lang/bg.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Скорост на тъчпада по подразбиране"), ("Numeric one-time password", "Цифрова еднократна парола"), ("Enable IPv6 P2P connection", "Позволяване на IPv6 P2P връзка"), + ("Enable WebRTC P2P connection", "Позволяване на WebRTC P2P връзка"), ("Enable UDP hole punching", "Позволяване на UDP hole punching"), ("View camera", "Преглед на камерата"), ("Enable camera", "Позволяване на камерата"), diff --git a/src/lang/ca.rs b/src/lang/ca.rs index 9ac80dd8c..2352aa4fa 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Velocitat per defecte del trackpad"), ("Numeric one-time password", "Contrasenya numèrica d'un sol ús"), ("Enable IPv6 P2P connection", "Habilita la connexió IPv6 P2P"), + ("Enable WebRTC P2P connection", "Habilita la connexió WebRTC P2P"), ("Enable UDP hole punching", "Activa la perforació UDP"), ("View camera", "Mostra la càmera"), ("Enable camera", "Habilita la càmera"), diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 9e2e3f991..e230f9088 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "默认触控板速度"), ("Numeric one-time password", "一次性密码为数字"), ("Enable IPv6 P2P connection", "启用 IPv6 P2P 连接"), + ("Enable WebRTC P2P connection", "启用 WebRTC P2P 连接"), ("Enable UDP hole punching", "启用 UDP 打洞"), ("View camera", "查看摄像头"), ("Enable camera", "允许查看摄像头"), diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 5a7dabcb4..604461454 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Výchozí rychlost trackpadu"), ("Numeric one-time password", "Číselné jednorázové heslo"), ("Enable IPv6 P2P connection", "Povolit připojení IPv6 P2P"), + ("Enable WebRTC P2P connection", "Povolit připojení WebRTC P2P"), ("Enable UDP hole punching", "Povolit UDP hole punching"), ("View camera", "Zobrazit kameru"), ("Enable camera", "Povolit kameru"), diff --git a/src/lang/da.rs b/src/lang/da.rs index 1b96ead6b..49d43de9a 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Standard pegefeltshastighed"), ("Numeric one-time password", "Numerisk engangskode"), ("Enable IPv6 P2P connection", "Aktivér IPv6 P2P-forbindelse"), + ("Enable WebRTC P2P connection", "Aktivér WebRTC P2P-forbindelse"), ("Enable UDP hole punching", "Aktivér UDP hole punching"), ("View camera", "Se kamera"), ("Enable camera", "Aktivér kamera"), diff --git a/src/lang/de.rs b/src/lang/de.rs index 06d8eac45..cf99105aa 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Standardgeschwindigkeit des Trackpads"), ("Numeric one-time password", "Numerisches Einmalpasswort"), ("Enable IPv6 P2P connection", "IPv6-P2P-Verbindung aktivieren"), + ("Enable WebRTC P2P connection", "WebRTC-P2P-Verbindung aktivieren"), ("Enable UDP hole punching", "UDP-Hole-Punching aktivieren"), ("View camera", "Kamera anzeigen"), ("Enable camera", "Kamera zulassen"), diff --git a/src/lang/el.rs b/src/lang/el.rs index 87a097898..a2f368251 100644 --- a/src/lang/el.rs +++ b/src/lang/el.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Προεπιλεγμένη ταχύτητα trackpad"), ("Numeric one-time password", "Αριθμητικός κωδικός πρόσβασης μίας χρήσης"), ("Enable IPv6 P2P connection", "Ενεργοποίηση σύνδεσης IPv6 P2P"), + ("Enable WebRTC P2P connection", "Ενεργοποίηση σύνδεσης WebRTC P2P"), ("Enable UDP hole punching", "Ενεργοποίηση διάτρησης οπών UDP"), ("View camera", "Προβολή κάμερας"), ("Enable camera", "Ενεργοποίηση κάμερας"), diff --git a/src/lang/eo.rs b/src/lang/eo.rs index dbd4e5d0c..9fd244218 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Implicita rapideco de tuŝplato"), ("Numeric one-time password", "Numera unufoja pasvorto"), ("Enable IPv6 P2P connection", "Ebligi IPv6 P2P-konekton"), + ("Enable WebRTC P2P connection", "Ebligi WebRTC P2P-konekton"), ("Enable UDP hole punching", "Ebligi UDP-trapikadon"), ("View camera", "Rigardi kameron"), ("Enable camera", "Ebligi kameron"), diff --git a/src/lang/es.rs b/src/lang/es.rs index d36ee2281..7c7da0431 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Velocidad predeterminada de trackpad"), ("Numeric one-time password", "Contraseña numérica de un solo uso"), ("Enable IPv6 P2P connection", "Habilitar conexión IPv6 P2P"), + ("Enable WebRTC P2P connection", "Habilitar conexión WebRTC P2P"), ("Enable UDP hole punching", "Habilitar perforación de agujero UDP"), ("View camera", "Ver cámara"), ("Enable camera", "Habilitar cámara"), diff --git a/src/lang/et.rs b/src/lang/et.rs index 792457cb3..a75f4798e 100644 --- a/src/lang/et.rs +++ b/src/lang/et.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Vaikimisi puuteplaadi kiirus"), ("Numeric one-time password", "Numbriline ühekordne parool"), ("Enable IPv6 P2P connection", "Luba IPv6 P2P-ühendus"), + ("Enable WebRTC P2P connection", "Luba WebRTC P2P-ühendus"), ("Enable UDP hole punching", "Luba UDP-augustamine"), ("View camera", "Vaata kaamerat"), ("Enable camera", "Luba kaamera"), diff --git a/src/lang/eu.rs b/src/lang/eu.rs index 322f2822d..37edaba34 100644 --- a/src/lang/eu.rs +++ b/src/lang/eu.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Trackpad-aren abiadura lehenetsia"), ("Numeric one-time password", "Behin-behineko pasahitz numerikoa"), ("Enable IPv6 P2P connection", "Gaitu IPv6 P2P konexioa"), + ("Enable WebRTC P2P connection", "Gaitu WebRTC P2P konexioa"), ("Enable UDP hole punching", "Gaitu UDP zulo-egitea"), ("View camera", "Ikusi kamera"), ("Enable camera", "Gaitu kamera"), diff --git a/src/lang/fa.rs b/src/lang/fa.rs index 5c46c5de3..a97e1eb09 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "سرعت پیش‌فرض ترک‌پد"), ("Numeric one-time password", "رمز عبور یک‌بار مصرف عددی"), ("Enable IPv6 P2P connection", "فعال‌سازی اتصال همتا‌به‌همتای IPv6"), + ("Enable WebRTC P2P connection", "فعال‌سازی اتصال همتا‌به‌همتای WebRTC"), ("Enable UDP hole punching", "فعال‌سازی تکنیک UDP hole punching"), ("View camera", "نمایش دوربین"), ("Enable camera", "فعال کردن دوربین"), diff --git a/src/lang/fi.rs b/src/lang/fi.rs index 96616fad3..c53549bf1 100644 --- a/src/lang/fi.rs +++ b/src/lang/fi.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Oletusnopeus kosketuslevylle"), ("Numeric one-time password", "Numeerinen kertakäyttösalasana"), ("Enable IPv6 P2P connection", "Ota IPv6 P2P yhteys käyttöön"), + ("Enable WebRTC P2P connection", "Ota WebRTC P2P yhteys käyttöön"), ("Enable UDP hole punching", "Ota käyttöön UDP hole punching tekniikka"), ("View camera", "Näytä kamera"), ("Enable camera", "Ota kamera käyttöön"), diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 55872b320..4e539ab00 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Vitesse par défaut du pavé tactile"), ("Numeric one-time password", "Mot de passe à usage unique numérique"), ("Enable IPv6 P2P connection", "Activer la connexion P2P IPv6"), + ("Enable WebRTC P2P connection", "Activer la connexion P2P WebRTC"), ("Enable UDP hole punching", "Activer le « hole punching » UDP"), ("View camera", "Afficher la caméra"), ("Enable camera", "Activer la caméra"), diff --git a/src/lang/ge.rs b/src/lang/ge.rs index 4f0e77606..e7fc9d3f0 100644 --- a/src/lang/ge.rs +++ b/src/lang/ge.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "ტაჩპადის ნაგულისხმევი სიჩქარე"), ("Numeric one-time password", "ციფრული ერთჯერადი პაროლი"), ("Enable IPv6 P2P connection", "IPv6 P2P კავშირის ჩართვა"), + ("Enable WebRTC P2P connection", "WebRTC P2P კავშირის ჩართვა"), ("Enable UDP hole punching", "UDP hole punching-ის ჩართვა"), ("View camera", "კამერის ნახვა"), ("Enable camera", "კამერის ჩართვა"), diff --git a/src/lang/gu.rs b/src/lang/gu.rs index 6f9282bb9..577c873ae 100644 --- a/src/lang/gu.rs +++ b/src/lang/gu.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "ડિફોલ્ટ ટ્રેકપેડ સ્પીડ"), ("Numeric one-time password", "ન્યુમેરિક OTP"), ("Enable IPv6 P2P connection", "IPv6 P2P કનેક્શન સક્ષમ કરો"), + ("Enable WebRTC P2P connection", "WebRTC P2P કનેક્શન સક્ષમ કરો"), ("Enable UDP hole punching", "UDP હોલ પંચિંગ સક્ષમ કરો"), ("View camera", "કેમેરા જુઓ"), ("Enable camera", "કેમેરા સક્ષમ કરો"), diff --git a/src/lang/he.rs b/src/lang/he.rs index a69b49c82..84400377b 100644 --- a/src/lang/he.rs +++ b/src/lang/he.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "מהירות ברירת מחדל של משטח מגע"), ("Numeric one-time password", "סיסמה חד-פעמית מספרית"), ("Enable IPv6 P2P connection", "אפשר חיבור IPv6 P2P"), + ("Enable WebRTC P2P connection", "אפשר חיבור WebRTC P2P"), ("Enable UDP hole punching", "אפשר UDP hole punching"), ("View camera", "הצג מצלמה"), ("Enable camera", "הפעל מצלמה"), diff --git a/src/lang/hi.rs b/src/lang/hi.rs index cd7f46b0b..f3c3889d6 100644 --- a/src/lang/hi.rs +++ b/src/lang/hi.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "डिफ़ॉल्ट ट्रैकपैड गति"), ("Numeric one-time password", "संख्यात्मक वन-टाइम पासवर्ड"), ("Enable IPv6 P2P connection", "IPv6 P2P कनेक्शन सक्षम करें"), + ("Enable WebRTC P2P connection", "WebRTC P2P कनेक्शन सक्षम करें"), ("Enable UDP hole punching", "UDP होल पंचिंग सक्षम करें"), ("View camera", "कैमरा देखें"), ("Enable camera", "कैमरा सक्षम करें"), diff --git a/src/lang/hr.rs b/src/lang/hr.rs index a1118a1c3..991826d26 100644 --- a/src/lang/hr.rs +++ b/src/lang/hr.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Zadana brzina dodirne ploče"), ("Numeric one-time password", "Numerička jednokratna lozinka"), ("Enable IPv6 P2P connection", "Omogući IPv6 P2P vezu"), + ("Enable WebRTC P2P connection", "Omogući WebRTC P2P vezu"), ("Enable UDP hole punching", "Omogući UDP hole punching"), ("View camera", "Pregled kamere"), ("Enable camera", "Omogući kameru"), diff --git a/src/lang/hu.rs b/src/lang/hu.rs index 1fff7804d..141f14201 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Alapértelmezett érintőpad sebessége"), ("Numeric one-time password", "Numerikus, egyszer használatos jelszó"), ("Enable IPv6 P2P connection", "IPv6 P2P kapcsolat engedélyezése"), + ("Enable WebRTC P2P connection", "WebRTC P2P kapcsolat engedélyezése"), ("Enable UDP hole punching", "UDP résszűrés engedélyezése"), ("View camera", "Kamera nézet"), ("Enable camera", "Kamera engedélyezése"), diff --git a/src/lang/id.rs b/src/lang/id.rs index e45b87472..a1a557847 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Kecepatan default trackpad"), ("Numeric one-time password", "Kata sandi sekali pakai numerik"), ("Enable IPv6 P2P connection", "Aktifkan koneksi P2P IPv6"), + ("Enable WebRTC P2P connection", "Aktifkan koneksi P2P WebRTC"), ("Enable UDP hole punching", "Aktifkan UDP hole punching"), ("View camera", "Lihat Kamera"), ("Enable camera", "Aktifkan kamera"), diff --git a/src/lang/it.rs b/src/lang/it.rs index a0017ce06..f215bf21b 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Velocità predefinita trackpad"), ("Numeric one-time password", "Password numerica monouso"), ("Enable IPv6 P2P connection", "Abilita connessione P2P IPv6"), + ("Enable WebRTC P2P connection", "Abilita connessione P2P WebRTC"), ("Enable UDP hole punching", "Abilita hole punching UDP"), ("View camera", "Visualizza telecamera"), ("Enable camera", "Abilita camera"), diff --git a/src/lang/ja.rs b/src/lang/ja.rs index 0d41f3f85..2215888d2 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "既定のトラックパッドの速度"), ("Numeric one-time password", "数字のワンタイムパスワード"), ("Enable IPv6 P2P connection", "IPv6 P2P 接続を有効化する"), + ("Enable WebRTC P2P connection", "WebRTC P2P 接続を有効化する"), ("Enable UDP hole punching", "UDP ホールパンチを有効化する"), ("View camera", "カメラを表示"), ("Enable camera", "カメラを有効化する"), diff --git a/src/lang/ko.rs b/src/lang/ko.rs index 98b76cc6f..336c282ca 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "기본 트랙패드 속도"), ("Numeric one-time password", "숫자 일회용 비밀번호"), ("Enable IPv6 P2P connection", "IPv6 P2P 연결 사용"), + ("Enable WebRTC P2P connection", "WebRTC P2P 연결 사용"), ("Enable UDP hole punching", "UDP 홀 펀칭 사용"), ("View camera", "카메라 보기"), ("Enable camera", "카메라 허용"), diff --git a/src/lang/kz.rs b/src/lang/kz.rs index 1ca770788..85b684349 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Әдепкі трекпад жылдамдығы"), ("Numeric one-time password", "Сандық бір-реттік құпия сөз"), ("Enable IPv6 P2P connection", "IPv6 P2P қосылымын іске қосу"), + ("Enable WebRTC P2P connection", "WebRTC P2P қосылымын іске қосу"), ("Enable UDP hole punching", "UDP hole punching'ті іске қосу"), ("View camera", "Камераны Көру"), ("Enable camera", "Камераны қосу"), diff --git a/src/lang/lt.rs b/src/lang/lt.rs index 1f3e0c83e..904240cd3 100644 --- a/src/lang/lt.rs +++ b/src/lang/lt.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Numatytasis jutiklinės dalies greitis"), ("Numeric one-time password", "Skaitmeninis vienkartinis slaptažodis"), ("Enable IPv6 P2P connection", "Įgalinti IPv6 P2P ryšį"), + ("Enable WebRTC P2P connection", "Įgalinti WebRTC P2P ryšį"), ("Enable UDP hole punching", "Įgalinti UDP gręžimą (hole punching)"), ("View camera", "Peržiūrėti kamerą"), ("Enable camera", "Įgalinti kamerą"), diff --git a/src/lang/lv.rs b/src/lang/lv.rs index 895957d2d..524df6595 100644 --- a/src/lang/lv.rs +++ b/src/lang/lv.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Noklusējuma skārienpaliktņa ātrums"), ("Numeric one-time password", "Vienreiz lietojama ciparu parole"), ("Enable IPv6 P2P connection", "Iespējot IPv6 P2P savienojumu"), + ("Enable WebRTC P2P connection", "Iespējot WebRTC P2P savienojumu"), ("Enable UDP hole punching", "Iespējot UDP caurumu veidošanu"), ("View camera", "Skatīt kameru"), ("Enable camera", "Iespējot kameru"), diff --git a/src/lang/ml.rs b/src/lang/ml.rs index 1c7a72790..d88ce9af0 100644 --- a/src/lang/ml.rs +++ b/src/lang/ml.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "സാധാരണ ട്രാക്ക്പാഡ് വേഗത"), ("Numeric one-time password", "അക്കങ്ങൾ മാത്രമുള്ള OTP"), ("Enable IPv6 P2P connection", "IPv6 P2P കണക്ഷൻ അനുവദിക്കുക"), + ("Enable WebRTC P2P connection", "WebRTC P2P കണക്ഷൻ അനുവദിക്കുക"), ("Enable UDP hole punching", "UDP ഹോൾ പഞ്ചിംഗ് അനുവദിക്കുക"), ("View camera", "ക്യാമറ കാണുക"), ("Enable camera", "ക്യാമറ ഓൺ ചെയ്യുക"), diff --git a/src/lang/nb.rs b/src/lang/nb.rs index 74e7c4202..4036ba226 100644 --- a/src/lang/nb.rs +++ b/src/lang/nb.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Standard styreplatehastighet"), ("Numeric one-time password", "Numerisk engangspassord"), ("Enable IPv6 P2P connection", "Aktiver IPv6 P2P-tilkobling"), + ("Enable WebRTC P2P connection", "Aktiver WebRTC P2P-tilkobling"), ("Enable UDP hole punching", "Aktiver UDP hole punching"), ("View camera", "Vis kamera"), ("Enable camera", "Aktiver kamera"), diff --git a/src/lang/nl.rs b/src/lang/nl.rs index de1197127..f8de33800 100644 --- a/src/lang/nl.rs +++ b/src/lang/nl.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Standaardsnelheid Trackpad"), ("Numeric one-time password", "Eenmalig numeriek wachtwoord"), ("Enable IPv6 P2P connection", "IPv6 P2P-verbinding inschakelen"), + ("Enable WebRTC P2P connection", "WebRTC P2P-verbinding inschakelen"), ("Enable UDP hole punching", "UDP-hole punching inschakelen"), ("View camera", "Camera weergeven"), ("Enable camera", "Camera inschakelen"), diff --git a/src/lang/pl.rs b/src/lang/pl.rs index 3960f3f55..b9d91fc00 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Domyślna szybkość gładzika"), ("Numeric one-time password", "Jednorazowe hasło cyfrowe"), ("Enable IPv6 P2P connection", "Włącz połączenie P2P IPv6"), + ("Enable WebRTC P2P connection", "Włącz połączenie P2P WebRTC"), ("Enable UDP hole punching", "Włącz tworzenie tunelu UDP"), ("View camera", "Podgląd kamery"), ("Enable camera", "Włącz kamerę"), diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index ab4b8d805..2950dea51 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Velocidade predefinida do trackpad"), ("Numeric one-time password", "Palavra-passe de uso único numérica"), ("Enable IPv6 P2P connection", "Ativar ligação P2P por IPv6"), + ("Enable WebRTC P2P connection", "Ativar ligação P2P por WebRTC"), ("Enable UDP hole punching", "Ativar UDP hole punching"), ("View camera", "Ver câmara"), ("Enable camera", "Ativar câmara"), diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index aa97c5d57..4bf26d81d 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Velocidade padrão do trackpad"), ("Numeric one-time password", "Senha numérica de uso único"), ("Enable IPv6 P2P connection", "Habilitar conexão IPv6 P2P"), + ("Enable WebRTC P2P connection", "Habilitar conexão WebRTC P2P"), ("Enable UDP hole punching", "Habilitar UDP hole punching"), ("View camera", "Visualizar câmera"), ("Enable camera", "Habilitar câmera"), diff --git a/src/lang/ro.rs b/src/lang/ro.rs index 5d377ab35..f96a537ab 100644 --- a/src/lang/ro.rs +++ b/src/lang/ro.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Viteza implicită a touchpad-ului"), ("Numeric one-time password", "Parolă unică numerică"), ("Enable IPv6 P2P connection", "Activează conexiunea P2P prin IPv6"), + ("Enable WebRTC P2P connection", "Activează conexiunea P2P prin WebRTC"), ("Enable UDP hole punching", "Activează traversarea UDP (hole punching)"), ("View camera", "Vezi camera"), ("Enable camera", "Activează camera"), diff --git a/src/lang/ru.rs b/src/lang/ru.rs index ecc9a78f8..d27ebcf5d 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Скорость трекпада по умолчанию"), ("Numeric one-time password", "Цифровой одноразовый пароль"), ("Enable IPv6 P2P connection", "Использовать подключение IPv6 P2P"), + ("Enable WebRTC P2P connection", "Использовать подключение WebRTC P2P"), ("Enable UDP hole punching", "Использовать UDP hole punching"), ("View camera", "Просмотр камеры"), ("Enable camera", "Включить камеру"), diff --git a/src/lang/sc.rs b/src/lang/sc.rs index 62b248b8a..df90353a7 100644 --- a/src/lang/sc.rs +++ b/src/lang/sc.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Velotzidade predefinida de su pannellu tàtile"), ("Numeric one-time password", "Crae numèrica monoimpreu"), ("Enable IPv6 P2P connection", "Abìlita connessione P2P IPv6"), + ("Enable WebRTC P2P connection", "Abìlita connessione P2P WebRTC"), ("Enable UDP hole punching", "Abìlita s'istampadura UDP"), ("View camera", "Mustra sa càmera"), ("Enable camera", "Abìlita sa càmera"), diff --git a/src/lang/sk.rs b/src/lang/sk.rs index 80674b5fb..bae86c99d 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Predvolená rýchlosť touchpadu"), ("Numeric one-time password", "Číselné jednorazové heslo"), ("Enable IPv6 P2P connection", "Povoliť pripojenie IPv6 P2P"), + ("Enable WebRTC P2P connection", "Povoliť pripojenie WebRTC P2P"), ("Enable UDP hole punching", "Povoliť UDP hole punching"), ("View camera", "Zobraziť kameru"), ("Enable camera", "Povoliť kameru"), diff --git a/src/lang/sl.rs b/src/lang/sl.rs index ec62c9cec..a1a48d7da 100644 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Privzeta hitrost sledilne ploščice"), ("Numeric one-time password", "Numerično enkratno geslo"), ("Enable IPv6 P2P connection", "Omogoči povezavo IPv6 P2P"), + ("Enable WebRTC P2P connection", "Omogoči povezavo WebRTC P2P"), ("Enable UDP hole punching", "Omogoči preboj lukenj UDP"), ("View camera", "Pogled kamere"), ("Enable camera", "Omogoči kamero"), diff --git a/src/lang/sq.rs b/src/lang/sq.rs index c3e2a97be..e30965500 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Shpejtësia e parazgjedhur e trackpad-it"), ("Numeric one-time password", "Fjalëkalim numerik një-herë"), ("Enable IPv6 P2P connection", "Aktivizo lidhjen IPv6 P2P"), + ("Enable WebRTC P2P connection", "Aktivizo lidhjen WebRTC P2P"), ("Enable UDP hole punching", "Aktivizo UDP hole punching"), ("View camera", "Shiko kamerën"), ("Enable camera", "Aktivizo kamerën"), diff --git a/src/lang/sr.rs b/src/lang/sr.rs index 0429c34f9..7ac20ca39 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Podrazumevana brzina dodirne table"), ("Numeric one-time password", "Numerička jednokratna lozinka"), ("Enable IPv6 P2P connection", "Omogući IPv6 P2P konekciju"), + ("Enable WebRTC P2P connection", "Omogući WebRTC P2P konekciju"), ("Enable UDP hole punching", "Omogući UDP hole punching"), ("View camera", "Pregled kamere"), ("Enable camera", "Omogući kameru"), diff --git a/src/lang/sv.rs b/src/lang/sv.rs index 0018572b2..444deb9ec 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Standardhastighet för styrplattan"), ("Numeric one-time password", "Numeriskt engångslösenord"), ("Enable IPv6 P2P connection", "Aktivera IPv6 P2P anslutning"), + ("Enable WebRTC P2P connection", "Aktivera WebRTC P2P anslutning"), ("Enable UDP hole punching", "Aktivera UDP hålslagning"), ("View camera", "Visa kamera"), ("Enable camera", "Aktivera kamera"), diff --git a/src/lang/ta.rs b/src/lang/ta.rs index e2903f0e8..c65ac31db 100644 --- a/src/lang/ta.rs +++ b/src/lang/ta.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "இயல்புநிலை டிராக்பேட் வேகம்"), ("Numeric one-time password", "எண் ஒருமுறை கடவுச்சொல்"), ("Enable IPv6 P2P connection", "IPv6 P2P இணைப்பு இயக்கு"), + ("Enable WebRTC P2P connection", "WebRTC P2P இணைப்பு இயக்கு"), ("Enable UDP hole punching", "UDP hole punching இயக்கு"), ("View camera", "கேமரா பார்"), ("Enable camera", "கேமரா இயக்கு"), diff --git a/src/lang/template.rs b/src/lang/template.rs index 6daa1f306..3809abc26 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", ""), ("Numeric one-time password", ""), ("Enable IPv6 P2P connection", ""), + ("Enable WebRTC P2P connection", ""), ("Enable UDP hole punching", ""), ("View camera", ""), ("Enable camera", ""), diff --git a/src/lang/th.rs b/src/lang/th.rs index a067ba050..9761931ed 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "ความเร็วแทร็กแพดเริ่มต้น"), ("Numeric one-time password", "รหัสผ่านครั้งเดียวแบบตัวเลข"), ("Enable IPv6 P2P connection", "เปิดใช้งานการเชื่อมต่อ P2P แบบ IPv6"), + ("Enable WebRTC P2P connection", "เปิดใช้งานการเชื่อมต่อ P2P แบบ WebRTC"), ("Enable UDP hole punching", "เปิดใช้งาน UDP hole punching"), ("View camera", "ดูกล้อง"), ("Enable camera", "เปิดใช้งานกล้อง"), diff --git a/src/lang/tr.rs b/src/lang/tr.rs index 63c8f6a40..ee9487934 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Varsayılan izleme paneli hızı"), ("Numeric one-time password", "Sayısal tek seferlik parola"), ("Enable IPv6 P2P connection", "IPv6 P2P bağlantısını etkinleştir"), + ("Enable WebRTC P2P connection", "WebRTC P2P bağlantısını etkinleştir"), ("Enable UDP hole punching", "UDP delik açmayı etkinleştir"), ("View camera", "Kamerayı görüntüle"), ("Enable camera", "Kamerayı etkinleştir"), diff --git a/src/lang/tw.rs b/src/lang/tw.rs index cdfe85fbc..98d1052ee 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "預設觸控板速度"), ("Numeric one-time password", "數字一次性密碼"), ("Enable IPv6 P2P connection", "啟用 IPv6 P2P 連線"), + ("Enable WebRTC P2P connection", "啟用 WebRTC P2P 連線"), ("Enable UDP hole punching", "啟用 UDP 打洞"), ("View camera", "檢視相機"), ("Enable camera", "允許查看鏡頭"), diff --git a/src/lang/uk.rs b/src/lang/uk.rs index 9bb94d002..bf843680e 100644 --- a/src/lang/uk.rs +++ b/src/lang/uk.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Швидкість тачпада за замовчуванням"), ("Numeric one-time password", "Числовий одноразовий пароль"), ("Enable IPv6 P2P connection", "Увімкнути P2P-підключення через IPv6"), + ("Enable WebRTC P2P connection", "Увімкнути P2P-підключення через WebRTC"), ("Enable UDP hole punching", "Увімкнути UDP hole punching"), ("View camera", "Перегляд камери"), ("Enable camera", "Увімкнути камеру"), diff --git a/src/lang/vi.rs b/src/lang/vi.rs index 59c94830e..6c9ba8304 100644 --- a/src/lang/vi.rs +++ b/src/lang/vi.rs @@ -676,6 +676,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Default trackpad speed", "Tốc độ Trackpad mặc định"), ("Numeric one-time password", "Mật khẩu số dùng một lần"), ("Enable IPv6 P2P connection", "Cho phép kết nối IPv6 P2P"), + ("Enable WebRTC P2P connection", "Cho phép kết nối WebRTC P2P"), ("Enable UDP hole punching", "Bật UDP Hole Punching"), ("View camera", "Xem Camera"), ("Enable camera", "Bật Camera"), diff --git a/src/rendezvous_mediator.rs b/src/rendezvous_mediator.rs index 4adafc2f1..3994d73d4 100644 --- a/src/rendezvous_mediator.rs +++ b/src/rendezvous_mediator.rs @@ -856,7 +856,11 @@ impl RendezvousMediator { // policy, viable (and answerable) only through TURN. let webrtc_relay_only = ph.force_relay && !WebRTCStream::endpoint_declares_all_ice(&ph.webrtc_sdp_offer); + // Unlike the udp/ipv6 legs - which deliberately just follow the request - WebRTC is + // gated on this machine's own option too: answering builds a pc that gathers ICE + // from this host, so a machine with WebRTC off must not be pulled into it. let webrtc_viable = !ph.webrtc_sdp_offer.is_empty() + && crate::get_webrtc_enabled() && !Config::is_proxy() && (!webrtc_relay_only || WebRTCStream::has_turn_server()); let webrtc_sdp_answer = if webrtc_viable {