Started work on improved device guest sharing.
Ylian Saint-Hilaire committed
Apr 9, 2021 at 00:28 UTC
9bf2e211ab85a29be0bbb03ff404184da02ed57c
77 files changed
+2740
-132
emails/translations/account-check-min_cs.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Ověření e-mailem</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Ověření</b></table><p>Ahoj [[[USERNAME]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> požaduje ověření e-mailem a dokončete proces kliknutím na následující odkaz.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">Kliknutím sem ověřte svou e-mailovou adresu.</a></p>Pokud jste tento požadavek nezačali, ignorujte tento e-mail.</div>
\ No newline at end of file
emails/translations/account-check-min_de.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - E-Mail-Überprüfung</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Überprüfung</b></table><p>Hallo [[[USERNAME]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> Wenn Sie eine E-Mail-Bestätigung anfordern, klicken Sie auf den folgenden Link, um den Vorgang abzuschließen.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">Klicken Sie hier, um Ihre E-Mail-Adresse zu bestätigen.</a></p>Wenn Sie diese Anfrage nicht initiiert haben, ignorieren Sie diese Mail bitte.</div>
\ No newline at end of file
emails/translations/account-check-min_es.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Verificación de Correo Electrónico</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Verificación</b></table><p>Hola [[[USERNAME]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> solicita la verificación por correo electrónico, haga clic en el siguiente enlace para completar el proceso.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">Haga clic aquí para verificar su dirección de correo electrónico.</a></p>Si Ud. no inicio este requerimiento, por favor ignore este correo.</div>
\ No newline at end of file
emails/translations/account-check-min_fi.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Sähköpostivarmistus</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Todentaminen</b></table><p>Moi [[[USERNAME]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> pyytää sähköpostitse vahvistusta, suorita prosessi napsauttamalla seuraavaa linkkiä.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">Napsauta tätä vahvistaaksesi sähköpostiosoitteesi.</a></p>Jos et suorittanut tätä pyyntöä, voit ohitaa tämän sähköpostin.</div>
\ No newline at end of file
emails/translations/account-check-min_fr.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Vérification E-mail</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Vérification</b></table><p>Bonjour [[[USERNAME]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> demande une vérification par e-mail, cliquez sur le lien suivant pour terminer le processus.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">Cliquez ici pour vérifier votre adresse e-mail.</a></p>Si vous n'avez pas initié cette demande, veuillez ignorer ce courrier.</div>
\ No newline at end of file
emails/translations/account-check-min_hi.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - ईमेल सत्यापन</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - सत्यापन</b></table><p>हाय [[[USERNAME]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> ईमेल सत्यापन का अनुरोध कर रहा है, प्रक्रिया को पूरा करने के लिए निम्न लिंक पर क्लिक करें।<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">अपना ई-मेल पता सत्यापित करने के लिए यहां क्लिक करें।</a></p>यदि आपने यह अनुरोध आरंभ नहीं किया है, तो कृपया इस मेल को अनदेखा करें।</div>
\ No newline at end of file
emails/translations/account-check-min_ja.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - メールの確認</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - 確認</b></table><p>[[[USERNAME]]]様 <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> がメールの確認をリクエストしている場合は、次のリンクをクリックしてプロセスを完了してください。<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">ここをクリックして、電子メールアドレスを確認してください。</a></p>このリクエストを開始していない場合は、このメールを無視してください。</div>
\ No newline at end of file
emails/translations/account-check-min_ko.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Email 인증</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - 인증</b></table><p>안녕하세요, [[[USERNAME]]]님. <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> 이메일 검증을 요구하는 경우, 다음 링크를 클릭하여 과정을 완료하십시오.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">이메일 주소를 검증하려면 여기를 클릭하십시오.</a></p>이 요청을 시작하지 않은 경우, 이 메일을 무시하십시오.</div>
\ No newline at end of file
emails/translations/account-check-min_nl.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - E-mail Verificatie</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Verificatie</b></table><p>Hallo [[[USERNAME]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> vraagt om e-mailverificatie, klik op de volgende link om het proces te voltooien.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">Klik hier om uw e-mailadres te verifiëren.</a></p>Als u dit verzoek niet heeft ingediend, dan kunt u deze e-mail negeren.</div>
\ No newline at end of file
emails/translations/account-check-min_pt.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Verificação de Email</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Verificação</b></table><p>Olá [[[NOME DE USUÁRIO]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> está solicitando verificação de e-mail, clique no link a seguir para concluir o processo.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">Clique aqui para verificar seu endereço de e-mail.</a></p>Se você não iniciou esta solicitação, ignore este e-mail.</div>
\ No newline at end of file
emails/translations/account-check-min_ru.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - подтверждение по электронной почте</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Подтверждение</b></table><p>Привет [[[USERNAME]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> запрашивает подтверждение по электронной почте, нажмите на следующую ссылку, чтобы завершить процесс.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">Нажмите здесь, чтобы подтвердить свой адрес электронной почты.</a></p>Если вы не инициировали этот запрос, игнорируйте это письмо.</div>
\ No newline at end of file
emails/translations/account-check-min_tr.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - E-posta Doğrulaması</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Doğrulama</b></table><p>Merhaba [[[USERNAME]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> e-posta doğrulaması istiyorsa, işlemi tamamlamak için aşağıdaki bağlantıya tıklayın.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">E-posta adresinizi doğrulamak için burayı tıklayın.</a></p>Bu isteği siz başlatmadıysanız, lütfen bu postayı dikkate almayın.</div>
\ No newline at end of file
emails/translations/account-check-min_zh-chs.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]]-电邮验证</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]]-验证</b></table><p>[[[USERNAME]],你好, <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> 正在请求电邮验证,请单击以下连结以完成该过程。<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">单击此处以验证您的电邮地址。</a></p>如果您没有发起此请求,请不理此邮件。</div>
\ No newline at end of file
emails/translations/account-check-min_zh-cht.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]]-電郵驗證</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]]-驗證</b></table><p>[[[USERNAME]],你好, <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]</a> 正在請求電郵驗證,請單擊以下鏈結以完成該過程。<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">單擊此處以驗證你的電郵地址。</a></p>如果你沒有發起此請求,請不理此電郵。</div>
\ No newline at end of file
emails/translations/account-invite-min_cs.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Pozvánka na účet</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Pozvánka na účet</b></table><p>Účet byl pro vás vytvořen na serveru <a href=[[[SERVERURL]]][[[URLARGS1]]] notrans=1>[[[SERVERNAME]]]</a>, nyní k němu máte přístup:<p> Uživatelské jméno: <b notrans=1>[[[ACCOUNTNAME]]]</b><br> Heslo: <b notrans=1>[[[PASSWORD]]]</b></p>S pozdravem,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/account-invite-min_de.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Kontoeinladung</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Kontoeinladung</b></table><p>Auf dem Server wurde ein Konto für Sie erstellt <a href=[[[SERVERURL]]][[[URLARGS1]]] notrans=1>[[[SERVERNAME]]]</a>können Sie jetzt darauf zugreifen mit:<p> Benutzername: <b notrans=1>[[[ACCOUNTNAME]]]</b><br> Passwort: <b notrans=1>[[[PASSWORD]]]</b></p>Freundliche Grüße,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/account-invite-min_es.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Invitación de Cuenta</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Invitación de Cuenta</b></table><p>Una cuenta ha sido creada en su servidor <a href=[[[SERVERURL]]][[[URLARGS1]]] notrans=1>[[[SERVERNAME]]]</a>, ahora puede acceder con:<p> Nombre de usuario: <b notrans=1>[[[ACCOUNTNAME]]]</b><br> Contraseña: <b notrans=1>[[[PASSWORD]]]</b></p>Atentamente,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/account-invite-min_fi.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Tili kutsu</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Tili kutsu</b></table><p>Sinulle on luotu tili palvelimelle <a href=[[[SERVERURL]]][[[URLARGS1]]] notrans=1>[[[SERVERNAME]]]</a>, voit käyttää sitä nyt:<p> Käyttäjätunnus: <b notrans=1>[[[ACCOUNTNAME]]]</b><br> Salasana: <b notrans=1>[[[PASSWORD]]]</b></p>Ystävällisin terveisin,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/account-invite-min_fr.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Invitation au compte</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Invitation au compte</b></table><p>Un compte a été créé pour vous sur le serveur <a href=[[[SERVERURL]]][[[URLARGS1]]] notrans=1>[[[SERVERNAME]]]</a>, vous pouvez y accéder maintenant avec :<p> Nom d'utilisateur: <b notrans=1>[[[ACCOUNTNAME]]]</b><br> Mot de passe: <b notrans=1>[[[PASSWORD]]]</b></p>Meilleures salutations,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/account-invite-min_hi.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - खाता निमंत्रण</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - खाता निमंत्रण</b></table><p>सर्वर पर आपके लिए एक खाता बनाया गया था <a href=[[[SERVERURL]]][[[URLARGS1]]] notrans=1>[[[SERVERNAME]]]</a>, आप इसे अभी एक्सेस कर सकते हैं:<p> उपयोगकर्ता नाम: <b notrans=1>[[[ACCOUNTNAME]]]</b><br> कुंजिका: <b notrans=1>[[[PASSWORD]]]</b></p>सादर,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/account-invite-min_ja.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - アカウントの招待</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - アカウントの招待</b></table><p>サーバー上にアカウントが作成されました <a href=[[[SERVERURL]]][[[URLARGS1]]] notrans=1>[[[SERVERNAME]]]</a>、あなたは今それを使ってそれにアクセスできます:<p> ユーザー名: <b notrans=1>[[[ACCOUNTNAME]]]</b><br> パスワード: <b notrans=1>[[[PASSWORD]]]</b></p>宜しくお願いします、<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/account-invite-min_ko.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - 계정 초대</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - 계정 초대</b></table><p>당신을 위해 서버에서 한 계정이 생성되었습니다. <a href=[[[SERVERURL]]][[[URLARGS1]]] notrans=1>[[[SERVERNAME]]]</a>이제 당신은 다음으로 접근 가능합니다:<p> 사용자 이름: <b notrans=1>[[[ACCOUNTNAME]]]</b><br> 암호: <b notrans=1>[[[PASSWORD]]]</b></p>최고의 안부를 전합니다,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/account-invite-min_nl.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Account uitnodiging</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Account uitnodiging</b></table><p>Er is een account voor je aangemaakt op de server <a href=[[[SERVERURL]]][[[URLARGS1]]] notrans=1>[[[SERVERNAME]]]</a>, je hebt er nu toegang toe met:<p> Gebruikersnaam: <b notrans=1>[[[ACCOUNTNAME]]]</b><br> Wachtwoord: <b notrans=1>[[[PASSWORD]]]</b></p>Vriendelijke groeten,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/account-invite-min_pt.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Convite para conta</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Convite para conta</b></table><p>Uma conta foi criada para você no servidor <a href=[[[SERVERURL]]][[[URLARGS1]]] notrans=1>[[[SERVERNAME]]]</a>, você pode acessá-lo agora com:<p> Nome de usuário: <b notrans=1>[[[ACCOUNTNAME]]]</b><br> Senha: <b notrans=1>[[[PASSWORD]]]</b></p>Cumprimentos,<br>[[[NOME DO USUÁRIO]]]<br></div>
\ No newline at end of file
emails/translations/account-invite-min_ru.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - приглашение в аккаунт</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - приглашение в аккаунт</b></table><p>Учетная запись была создана для вас на сервере <a href=[[[SERVERURL]]][[[URLARGS1]]] notrans=1>[[[SERVERNAME]]]</a>Вы можете получить к нему доступ сейчас:<p> Имя пользователя: <b notrans=1>[[[ACCOUNTNAME]]]</b><br> Пароль: <b notrans=1>[[[PASSWORD]]]</b></p>С уважением,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/account-invite-min_tr.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Hesap Davetiyesi</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Hesap Davetiyesi</b></table><p>Sunucuda sizin için bir hesap oluşturuldu <a href=[[[SERVERURL]]][[[URLARGS1]]] notrans=1>[[[SERVERNAME]]]</a>, şimdi şununla erişebilirsiniz:<p> Kullanıcı adı: <b notrans=1>[[[ACCOUNTNAME]]]</b><br> Parola: <b notrans=1>[[[PASSWORD]]]</b></p>Saygılarımla,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/account-invite-min_zh-chs.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]]-帐户邀请</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]]-帐户邀请</b></table><p>在服务器上为您创建了一个帐户 <a href=[[[SERVERURL]]][[[URLARGS1]]] notrans=1>[[[SERVERNAME]]]</a>,您现在可以通过以下方式访问它:<p> 用户名: <b notrans=1>[[[ACCOUNTNAME]]]</b><br> 密码: <b notrans=1>[[[PASSWORD]]]</b></p>最好的祝福,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/account-invite-min_zh-cht.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]]-帳戶邀請</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]]-帳戶邀請</b></table><p>在伺服器上為你創建了一個帳戶 <a href=[[[SERVERURL]]][[[URLARGS1]]] notrans=1>[[[SERVERNAME]]]</a>,你現在可以通過以下方式訪問它:<p> 用戶名: <b notrans=1>[[[ACCOUNTNAME]]]</b><br> 密碼: <b notrans=1>[[[PASSWORD]]]</b></p>最好的祝福,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/account-login-min_cs.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Přihlášení k účtu</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Přihlášení k účtu</b></table><p>Váš přihlašovací token je: [[[TOKEN]]]<p>Tento token lze použít pouze jednou a je platný po dobu 5 minut.</div>
\ No newline at end of file
emails/translations/account-login-min_de.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Konto-Login</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Konto-Login</b></table><p>Ihr Login-Token lautet: [[[TOKEN]]]<p>Dieser Token kann nur einmal verwendet werden und ist 5 Minuten gültig.</div>
\ No newline at end of file
emails/translations/account-login-min_es.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Inicio de Sesión</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Inicio de Sesión</b></table><p>Su token de inicio de sesión es: [[[TOKEN]]]<p>Este token sólo se puede usar una vez y es válido durante 5 minutos.</div>
\ No newline at end of file
emails/translations/account-login-min_fi.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Tilille Kirjautuminen</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Tilille Kirjautuminen</b></table><p>Kirjautumistunnuksesi on: [[[TOKEN]]]<p>Tätä tunnusta voidaan käyttää vain kerran ja se on voimassa 5 minuuttia.</div>
\ No newline at end of file
emails/translations/account-login-min_fr.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Connexion au compte</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Connexion au compte</b></table><p>Votre jeton de connexion est: [[[TOKEN]]]<p>Ce jeton ne peut être utilisé qu'une seule fois et est valide pendant 5 minutes.</div>
\ No newline at end of file
emails/translations/account-login-min_hi.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - खाता लॉगिन</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - खाता लॉगिन</b></table><p>आपका लॉगिन टोकन है: [[[TOKEN]]]<p>यह टोकन केवल एक बार उपयोग किया जा सकता है और 5 मिनट के लिए वैध है।</div>
\ No newline at end of file
emails/translations/account-login-min_ja.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - アカウントログイン</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - アカウントログイン</b></table><p>ログイントークンは次のとおりです:[[[TOKEN]]]<p>このトークンは1回だけ使用でき、5分間有効です。</div>
\ No newline at end of file
emails/translations/account-login-min_ko.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - 계정 로그인</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - 계정 로그인</b></table><p>당신이 로그인한 토큰은 다음과 같습니다 : [[[TOKEN]]]<p>이 토큰은 오직 한 번만 사용될 수 있으며, 5분 동안만 유효합니다.</div>
\ No newline at end of file
emails/translations/account-login-min_nl.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Inloggen account</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Inloggen account</b></table><p>Uw login token is: [[[TOKEN]]]<p>Dit token kan maar één keer worden gebruikt en is 5 minuten geldig.</div>
\ No newline at end of file
emails/translations/account-login-min_pt.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Login da conta</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Login da conta</b></table><p>Seu token de login é: [[[TOKEN]]]<p>Este token só pode ser usado uma vez e é válido por 5 minutos.</div>
\ No newline at end of file
emails/translations/account-login-min_ru.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Вход в аккаунт</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Вход в аккаунт</b></table><p>Ваш токен для входа: [[[TOKEN]]]<p>Этот токен может быть использован только один раз и действителен в течение 5 минут.</div>
\ No newline at end of file
emails/translations/account-login-min_tr.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Hesap Girişi</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Hesap Girişi</b></table><p>Giriş jetonunuz: [[[TOKEN]]]<p>Bu simge yalnızca bir kez kullanılabilir ve 5 dakika geçerlidir.</div>
\ No newline at end of file
emails/translations/account-login-min_zh-chs.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]]-帐户登录</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]]-帐户登录</b></table><p>您的登录保安编码为:[[[TOKEN]]]<p>此保安编码只能使用一次,有效期为5分钟。</div>
\ No newline at end of file
emails/translations/account-login-min_zh-cht.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]]-帳戶登入</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]]-帳戶登入</b></table><p>你的登入保安編碼為:[[[TOKEN]]]<p>該保安編碼只能使用一次,有效期為5分鐘。</div>
\ No newline at end of file
emails/translations/account-reset-min_cs.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Reset účtu</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Ověření</b></table><p>Ahoj [[[USERNAME]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> požaduje obnovení hesla k účtu, dokončete proces kliknutím na následující odkaz.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">Kliknutím sem obnovíte heslo svého účtu.</a></p>Pokud jste tento požadavek nezačali, ignorujte tento e-mail.</div>
\ No newline at end of file
emails/translations/account-reset-min_de.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Zurücksetzen des Kontos</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Überprüfung</b></table><p>Hallo [[[USERNAME]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> Wenn Sie ein Zurücksetzen des Kontokennworts anfordern, klicken Sie auf den folgenden Link, um den Vorgang abzuschließen.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">Klicken Sie hier, um Ihr Kontopasswort zurückzusetzen.</a></p>Wenn Sie diese Anfrage nicht initiiert haben, ignorieren Sie diese Mail bitte.</div>
\ No newline at end of file
emails/translations/account-reset-min_es.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Restablecimiento de Cuenta</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Verificación</b></table><p>Hola [[[USERNAME]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> solicita restablecer la contraseña de la cuenta, haga clic en el siguiente enlace para completar el proceso.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">Haga clic aquí para restablecer la contraseña de su cuenta.</a></p>Si Ud. no inicio este requerimiento, por favor ignore este correo.</div>
\ No newline at end of file
emails/translations/account-reset-min_fi.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Tili nollattu</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Todentaminen</b></table><p>Moi [[[USERNAME]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> pyytää tilin salasanan palauttamista, suorita prosessi napsauttamalla seuraavaa linkkiä.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">Palauta tilisi salasana napsauttamalla tätä.</a></p>Jos et suorittanut tätä pyyntöä, voit ohitaa tämän sähköpostin.</div>
\ No newline at end of file
emails/translations/account-reset-min_fr.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Réinitialisation du compte</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Vérification</b></table><p>Bonjour [[[USERNAME]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> demande une réinitialisation du mot de passe du compte, cliquez sur le lien suivant pour terminer le processus.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">Cliquez ici pour réinitialiser le mot de passe de votre compte.</a></p>Si vous n'avez pas initié cette demande, veuillez ignorer ce courrier.</div>
\ No newline at end of file
emails/translations/account-reset-min_hi.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - खाता रीसेट</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - सत्यापन</b></table><p>हाय [[[USERNAME]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> खाता पासवर्ड रीसेट का अनुरोध कर रहा है, प्रक्रिया पूरी करने के लिए निम्न लिंक पर क्लिक करें।<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">अपना खाता पासवर्ड रीसेट करने के लिए यहां क्लिक करें।</a></p>यदि आपने यह अनुरोध आरंभ नहीं किया है, तो कृपया इस मेल को अनदेखा करें।</div>
\ No newline at end of file
emails/translations/account-reset-min_ja.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - アカウントのリセット</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - 確認</b></table><p>[[[USERNAME]]]様 <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> がアカウントパスワードのリセットを要求している場合は、次のリンクをクリックしてプロセスを完了します。<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">ここをクリックしてアカウントのパスワードをリセットしてください。</a></p>このリクエストを開始していない場合は、このメールを無視してください。</div>
\ No newline at end of file
emails/translations/account-reset-min_ko.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - 계정 재설정</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - 인증</b></table><p>안녕하세요, [[[USERNAME]]]님. <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> 계정 비밀번호 재설정을 요청하는 경우, 다음 링크를 클릭하여 과정을 완료하십시오.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">당신의 계정 암호를 초기화하려면 여기를 클릭하십시오.</a></p>이 요청을 시작하지 않은 경우, 이 메일을 무시하십시오.</div>
\ No newline at end of file
emails/translations/account-reset-min_nl.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Account Reset</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Verificatie</b></table><p>Hallo [[[USERNAME]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> vraagt om het opnieuw instellen van het wachtwoord van een account, klik op de volgende link om het proces te voltooien.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">Klik hier om je wachtwoord opnieuw in te stellen.</a></p>Als u dit verzoek niet heeft ingediend, dan kunt u deze e-mail negeren.</div>
\ No newline at end of file
emails/translations/account-reset-min_pt.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Redefinição de conta</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Verificação</b></table><p>Olá [[[NOME DE USUÁRIO]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> está solicitando a redefinição da senha da conta, clique no link a seguir para concluir o processo.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">Clique aqui para redefinir a senha da sua conta.</a></p>Se você não iniciou esta solicitação, ignore este e-mail.</div>
\ No newline at end of file
emails/translations/account-reset-min_ru.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Сброс учетной записи</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Подтверждение</b></table><p>Привет [[[USERNAME]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> запрашивает сброс пароля учетной записи, нажмите на следующую ссылку, чтобы завершить процесс.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">Нажмите здесь, чтобы сбросить пароль учетной записи.</a></p>Если вы не инициировали этот запрос, игнорируйте это письмо.</div>
\ No newline at end of file
emails/translations/account-reset-min_tr.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Hesabı Sıfırlama</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Doğrulama</b></table><p>Merhaba [[[USERNAME]]], <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> bir hesap şifresi sıfırlama talep ediyor, işlemi tamamlamak için aşağıdaki bağlantıya tıklayın.<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">Hesap şifrenizi sıfırlamak için burayı tıklayın.</a></p>Bu isteği siz başlatmadıysanız, lütfen bu postayı dikkate almayın.</div>
\ No newline at end of file
emails/translations/account-reset-min_zh-chs.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]]-帐户重置</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]]-验证</b></table><p>[[[USERNAME]],你好, <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> 正在要求重置帐户密码,请单击以下连结以完成该过程。<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">单击此处重置您的帐户密码。</a></p>如果您没有发起此请求,请不理此邮件。</div>
\ No newline at end of file
emails/translations/account-reset-min_zh-cht.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]]-帳戶重置</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]]-驗證</b></table><p>[[[USERNAME]],你好, <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]</a> 正在要求重置帳戶密碼,請單擊以下鏈結以完成該過程。<p style=margin-left:30px><a href="[[[SERVERURL]]]/checkmail?c=[[[COOKIE]]][[[URLARGS2]]]">單擊此處重置你的帳戶密碼。</a></p>如果你沒有發起此請求,請不理此電郵。</div>
\ No newline at end of file
emails/translations/mesh-invite-min_cs.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Pozvánka</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Instalace agenta</b></table><area-name><p>Dobrý den, [[[NAME]]],</p></area-name><p>Uživatel [[[USERNAME]]] na serveru <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> vás žádá o instalaci softwaru pro spuštění relace dálkového ovládání.</p><area-msg><p>Zpráva: <b notrans=1>[[[MSG]]]</b></p></area-msg><area-windows><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshagents?id=4&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Kliknutím sem stáhnete MeshAgent pro Windows.</a></p></area-windows><area-osx><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshosxagent?id=16&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Kliknutím sem stáhnete MeshAgent pro Apple OSX.</a></p></area-osx><area-linux><p>V případě systému Linux vyjměte a vložte do terminálu a nainstalujte agenta:<br><pre style=margin-left:30px notrans=1>wget -q "[[[SERVERURL]]]/meshagents?script=1" --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh [[[SERVERURL]]] \'[[[MESHIDHEX]]]\'</pre><p></p></area-linux><area-link><p>Chcete-li nainstalovat software, <a href=[[[SERVERURL]]][[[LINKURL]]][[[URLARGS2]]]>klikněte zde</a> a postupujte podle pokynů.</p></area-link><p>Pokud jste tento požadavek nezačali, ignorujte tento e-mail.</p>S pozdravem,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/mesh-invite-min_de.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Einladung</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Agenteninstallation</b></table><area-name><p>Hallo [[[NAME]]],</p></area-name><p>Benutzer [[[USERNAME]]] auf dem Server <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> fordert Sie auf, Software zu installieren, um eine Fernsteuerungssitzung zu starten.</p><area-msg><p>Botschaft: <b notrans=1>[[[MSG]]]</b></p></area-msg><area-windows><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshagents?id=4&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Klicken Sie hier, um den MeshAgent für Windows herunterzuladen.</a></p></area-windows><area-osx><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshosxagent?id=16&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Klicken Sie hier, um den MeshAgent für Apple OSX herunterzuladen.</a></p></area-osx><area-linux><p>Schneiden Sie unter Linux Folgendes aus und fügen Sie es in ein Terminal ein, um den Agenten zu installieren:<br><pre style=margin-left:30px notrans=1>wget -q "[[[SERVERURL]]]/meshagents?script=1" --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh [[[SERVERURL]]] \'[[[MESHIDHEX]]]\'</pre><p></p></area-linux><area-link><p>Um die Software zu installieren, <a href=[[[SERVERURL]]][[[LINKURL]]][[[URLARGS2]]]>hier klicken</a> und folgen Sie den Anweisungen.</p></area-link><p>Wenn Sie diese Anfrage nicht initiiert haben, ignorieren Sie diese Mail bitte.</p>Freundliche Grüße,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/mesh-invite-min_es.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Invitación</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Instalación de Agente</b></table><area-name><p>Hola [[[NAME]]],</p></area-name><p>Usuario [[[USERNAME]]] en servidor <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> le solicita que instale software para iniciar una sesión de control remoto.</p><area-msg><p>Mensaje: <b notrans=1>[[[MSG]]]</b></p></area-msg><area-windows><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshagents?id=4&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Haga clic aquí para descargar el Agente Mesh para Windows.</a></p></area-windows><area-osx><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshosxagent?id=16&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Haga clic aquí para descargar el Agente Mesh para Apple OSX.</a></p></area-osx><area-linux><p>Para Linux, copie y pegue lo siguiente en la terminal para instalar el agente:<br><pre style=margin-left:30px notrans=1>wget -q "[[[SERVERURL]]]/meshagents?script=1" --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh [[[SERVERURL]]] \'[[[MESHIDHEX]]]\'</pre><p></p></area-linux><area-link><p>Para instalar el software, <a href=[[[SERVERURL]]][[[LINKURL]]][[[URLARGS2]]]>haga clic aquí</a> y siga las instrucciones.</p></area-link><p>Si Ud. no inicio este requerimiento, por favor ignore este correo.</p>Atentamente,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/mesh-invite-min_fi.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Kutsu</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Agentin asennus</b></table><area-name><p>Hei [[[NAME]]],</p></area-name><p>Käyttäjä [[[USERNAME]]] palvelimella <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> pyytää sinua asentamaan ohjelmiston etäohjausistunnon aloittamiseksi.</p><area-msg><p>Viesti: <b notrans=1>[[[MSG]]]</b></p></area-msg><area-windows><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshagents?id=4&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Napsauta tätä ladataksesi MeshAgent Windows:lle.</a></p></area-windows><area-osx><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshosxagent?id=16&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Napsauta tätä ladataksesi MeshAgent Apple OSX:lle.</a></p></area-osx><area-linux><p>Linux: leikkaa ja liitä seuraava päätelaitteeseen agentin asentamiseksi:<br><pre style=margin-left:30px notrans=1>wget -q "[[[SERVERURL]]]/meshagents?script=1" --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh [[[SERVERURL]]] \'[[[MESHIDHEX]]]\'</pre><p></p></area-linux><area-link><p>Asentaaksesi ohjelman, <a href=[[[SERVERURL]]][[[LINKURL]]][[[URLARGS2]]]>klikkaa tästä</a> ja seuraa ohjeita.</p></area-link><p>Jos et suorittanut tätä pyyntöä, voit ohitaa tämän sähköpostin.</p>Ystävällisin terveisin,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/mesh-invite-min_fr.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Invitation</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Installation de l'agent</b></table><area-name><p>Bonjour [[[NAME]]],</p></area-name><p>Utilisateur [[[USERNAME]]] sur le serveur <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> vous demande d'installer un logiciel pour démarrer une session de contrôle à distance.</p><area-msg><p>Message: <b notrans=1>[[[MSG]]]</b></p></area-msg><area-windows><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshagents?id=4&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Cliquez ici pour télécharger le MeshAgent pour Windows.</a></p></area-windows><area-osx><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshosxagent?id=16&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Cliquez ici pour télécharger le MeshAgent pour Apple OSX.</a></p></area-osx><area-linux><p>Pour Linux, copiez et collez les éléments suivants dans un terminal pour installer l'agent:<br><pre style=margin-left:30px notrans=1>wget -q "[[[SERVERURL]]]/meshagents?script=1" --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh [[[SERVERURL]]] \'[[[MESHIDHEX]]]\'</pre><p></p></area-linux><area-link><p>Pour installer le logiciel, <a href=[[[SERVERURL]]][[[LINKURL]]][[[URLARGS2]]]>cliquez ici</a> et suivez les instructions.</p></area-link><p>Si vous n'avez pas initié cette demande, veuillez ignorer ce courrier.</p>Meilleures salutations,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/mesh-invite-min_hi.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - निमंत्रण</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - एजेंट स्थापना</b></table><area-name><p>नमस्कार [[[NAME]]],</p></area-name><p>उपयोगकर्ता [[[USERNAME]]] सर्वर पर <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> रिमोट कंट्रोल सेशन शुरू करने के लिए आपको सॉफ्टवेयर इंस्टॉल करने का अनुरोध कर रहा है।</p><area-msg><p>संदेश: <b notrans=1>[[[MSG]]]</b></p></area-msg><area-windows><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshagents?id=4&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">विंडोज के लिए मेशजेंट को डाउनलोड करने के लिए यहां क्लिक करें।</a></p></area-windows><area-osx><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshosxagent?id=16&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Apple OSX के लिए मेशजेंट को डाउनलोड करने के लिए यहां क्लिक करें।</a></p></area-osx><area-linux><p>लिनक्स में, एजेंट को स्थापित करने के लिए टर्मिनल में निम्नलिखित को काटें और चिपकाएँ:<br><pre style=margin-left:30px notrans=1>wget -q "[[[SERVERURL]]]/meshagents?script=1" --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh [[[SERVERURL]]] \'[[[MESHIDHEX]]]\'</pre><p></p></area-linux><area-link><p>सॉफ़्टवेयर स्थापित करने के लिए, <a href=[[[SERVERURL]]][[[LINKURL]]][[[URLARGS2]]]>यहाँ क्लिक करें</a> और निर्देशों का पालन करें।</p></area-link><p>यदि आपने यह अनुरोध आरंभ नहीं किया है, तो कृपया इस मेल को अनदेखा करें।</p>सादर,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/mesh-invite-min_ja.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - 招待</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - エージェントのインストール</b></table><area-name><p>[[[NAME]]]様</p></area-name><p>サーバー上のユーザー[[[USERNAME]]] <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> リモートコントロールセッションを開始するソフトウェアをインストールするように要求しています。</p><area-msg><p>メッセージ: <b notrans=1>[[[MSG]]]</b></p></area-msg><area-windows><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshagents?id=4&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Windows用のMeshAgentをダウンロードするには、ここをクリックしてください。</a></p></area-windows><area-osx><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshosxagent?id=16&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">ここをクリックして、Apple OSX用のMeshAgentをダウンロードしてください。</a></p></area-osx><area-linux><p>Linuxの場合は、ターミナルで以下をカットアンドペーストしてエージェントをインストールします。<br><pre style=margin-left:30px notrans=1>wget -q "[[[SERVERURL]]]/meshagents?script=1" --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh [[[SERVERURL]]] \'[[[MESHIDHEX]]]\'</pre><p></p></area-linux><area-link><p>ソフトウェアをインストールするには、 <a href=[[[SERVERURL]]][[[LINKURL]]][[[URLARGS2]]]>ここをクリック</a> 指示に従ってください。</p></area-link><p>このリクエストを開始していない場合は、このメールを無視してください。</p>宜しくお願いします、<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/mesh-invite-min_ko.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - 초대</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - 에이전트 설치</b></table><area-name><p>안녕하세요, [[[NAME]]]님.</p></area-name><p>서버의 [[[USERNAME]]] 사용자 <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> 원격 제어 세션을 시작하기 위해 소프트웨어 설치를 요청하고 있습니다.</p><area-msg><p>메시지: <b notrans=1>[[[MSG]]]</b></p></area-msg><area-windows><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshagents?id=4&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Windows를 위한 MeshAgent를 다운로드 하려면 여기를 클릭하십시오.</a></p></area-windows><area-osx><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshosxagent?id=16&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Apple OSX를 위한 MeshAgent를 다운로드 하려면 여기를 클릭하십시오.</a></p></area-osx><area-linux><p>Linux의 경우, 다음을 잘라내어 터미널에 붙여 넣어 에이전트를 설치하십시오.<br><pre style=margin-left:30px notrans=1>wget -q "[[[SERVERURL]]]/meshagents?script=1" --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh [[[SERVERURL]]] \'[[[MESHIDHEX]]]\'</pre><p></p></area-linux><area-link><p>소프트웨어를 설치하려면, <a href=[[[SERVERURL]]][[[LINKURL]]][[[URLARGS2]]]>여기를 클릭하십시오.</a> 그리고 다음 지시들을 따르십시오.</p></area-link><p>이 요청을 시작하지 않은 경우, 이 메일을 무시하십시오.</p>최고의 안부를 전합니다,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/mesh-invite-min_nl.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Uitnodiging</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Agent installatie</b></table><area-name><p>Hallo [[[NAME]]],</p></area-name><p>Gebruiker [[[USERNAME]]] op server <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> vraagt u om de software te installeren om een ondersteunings sessie te starten.</p><area-msg><p>Bericht: <b notrans=1>[[[MSG]]]</b></p></area-msg><area-windows><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshagents?id=4&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Klik hier om de MeshAgent te downloaden voor Windows.</a></p></area-windows><area-osx><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshosxagent?id=16&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Klik hier om de MeshAgent te downloaden voor Apple OSX.</a></p></area-osx><area-linux><p>Voor Linux, knip het volgende en plak dit in een terminal om de agent te installeren:<br><pre style=margin-left:30px notrans=1>wget -q "[[[SERVERURL]]]/meshagents?script=1" --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh [[[SERVERURL]]] \'[[[MESHIDHEX]]]\'</pre><p></p></area-linux><area-link><p>Om de software te installeren, <a href=[[[SERVERURL]]][[[LINKURL]]][[[URLARGS2]]]>Klik hier</a> en volg de instructies.</p></area-link><p>Als u dit verzoek niet heeft ingediend, dan kunt u deze e-mail negeren.</p>Vriendelijke groeten,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/mesh-invite-min_pt.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Convite</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Instalação do Agente</b></table><area-name><p>Olá [[[NAME]]],</p></area-name><p>Usuário [[[USERNAME]]] no servidor <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> está solicitando a instalação de um software para iniciar uma sessão de controle remoto.</p><area-msg><p>Mensagem: <b notrans=1>[[[MSG]]]</b></p></area-msg><area-windows><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshagents?id=4&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Clique aqui para baixar o MeshAgent para Windows.</a></p></area-windows><area-osx><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshosxagent?id=16&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Clique aqui para baixar o MeshAgent para Apple OSX.</a></p></area-osx><area-linux><p>Para Linux, recorte e cole o seguinte em um terminal para instalar o agente:<br><pre style=margin-left:30px notrans=1>wget -q "[[[SERVERURL]]]/meshagents?script=1" --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh [[[SERVERURL]]] \'[[[MESHIDHEX]]]\'</pre><p></p></area-linux><area-link><p>Para instalar o software, <a href=[[[SERVERURL]]][[[LINKURL]]][[[URLARGS2]]]>Clique aqui</a> e siga as instruções.</p></area-link><p>Se você não iniciou esta solicitação, ignore este e-mail.</p>Cumprimentos,<br>[[[NOME DO USUÁRIO]]]<br></div>
\ No newline at end of file
emails/translations/mesh-invite-min_ru.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Приглашение</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Установка агента</b></table><area-name><p>Здравствуйте, [[[NAME]]],</p></area-name><p>Пользователь [[[USERNAME]]] на сервере <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> просит вас установить программное обеспечение, чтобы начать сеанс удаленного управления.</p><area-msg><p>Сообщение: <b notrans=1>[[[MSG]]]</b></p></area-msg><area-windows><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshagents?id=4&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Нажмите здесь, чтобы загрузить MeshAgent для Windows.</a></p></area-windows><area-osx><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshosxagent?id=16&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Нажмите здесь, чтобы загрузить MeshAgent для Apple OSX.</a></p></area-osx><area-linux><p>Для Linux вырезайте и вставляйте в терминал следующее, чтобы установить агент:<br><pre style=margin-left:30px notrans=1>wget -q "[[[SERVERURL]]]/meshagents?script=1" --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh [[[SERVERURL]]] \'[[[MESHIDHEX]]]\'</pre><p></p></area-linux><area-link><p>Чтобы установить программное обеспечение, <a href=[[[SERVERURL]]][[[LINKURL]]][[[URLARGS2]]]>кликните сюда</a> и следуйте инструкциям.</p></area-link><p>Если вы не инициировали этот запрос, игнорируйте это письмо.</p>С уважением,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/mesh-invite-min_tr.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]] - Davet</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]] - Aracı Kurulumu</b></table><area-name><p>Merhaba [[[NAME]]],</p></area-name><p>Sunucudaki kullanıcı [[[USERNAME]]] <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> bir uzaktan kontrol oturumu başlatmak için yazılım yüklemenizi istiyor.</p><area-msg><p>İleti: <b notrans=1>[[[MSG]]]</b></p></area-msg><area-windows><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshagents?id=4&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Windows için MeshAgent'ı indirmek için buraya tıklayın.</a></p></area-windows><area-osx><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshosxagent?id=16&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">Apple OSX için MeshAgent'ı indirmek için burayı tıklayın.</a></p></area-osx><area-linux><p>Linux için, aracıyı yüklemek için aşağıdakileri kesip bir terminale yapıştırın:<br><pre style=margin-left:30px notrans=1>wget -q "[[[SERVERURL]]]/meshagents?script=1" --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh [[[SERVERURL]]] \'[[[MESHIDHEX]]]\'</pre><p></p></area-linux><area-link><p>Yazılımı kurmak için, <a href=[[[SERVERURL]]][[[LINKURL]]][[[URLARGS2]]]>buraya Tıkla</a> ve talimatları izleyin.</p></area-link><p>Bu isteği siz başlatmadıysanız, lütfen bu postayı dikkate almayın.</p>Saygılarımla,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/mesh-invite-min_zh-chs.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]]-邀请</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]]-代理程序安装</b></table><area-name><p>您好[[[NAME]]],</p></area-name><p>服务器上的使用者[[[USERNAME]]] <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]]</a> 正在要求您安装软件以启动远程控制会话。</p><area-msg><p>消息: <b notrans=1>[[[MSG]]]</b></p></area-msg><area-windows><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshagents?id=4&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">单击此处下载适用于Windows的MeshAgent。</a></p></area-windows><area-osx><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshosxagent?id=16&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">单击此处下载适用于Apple OSX的MeshAgent。</a></p></area-osx><area-linux><p>对于Linux,将以下内容剪切并粘贴到终端中以安装代理软件:<br><pre style=margin-left:30px notrans=1>wget -q "[[[SERVERURL]]]/meshagents?script=1" --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh [[[SERVERURL]]] \'[[[MESHIDHEX]]]\'</pre><p></p></area-linux><area-link><p>要安装软件, <a href=[[[SERVERURL]]][[[LINKURL]]][[[URLARGS2]]]>点击这里</a> 并按照说明进行操作。</p></area-link><p>如果您没有发起此请求,请不理此邮件。</p>最好的祝福,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
emails/translations/mesh-invite-min_zh-cht.html
new
+1
@@ -0,0 +1 @@
1
+<div>[[[SERVERNAME]]]-邀請</div><div style=font-family:Arial,Helvetica,sans-serif><table style=background-color:#036;color:#d3d3d3;width:100% cellpadding=8><tr><td><b style=font-size:20px;font-family:Arial,Helvetica,sans-serif>[[[SERVERNAME]]]-代理程序安裝</b></table><area-name><p>你好[[[NAME]]],</p></area-name><p>伺服器上的使用者[[[USERNAME]]] <a href=[[[SERVERURL]]][[[URLARGS1]]]>[[[SERVERNAME]]</a> 正在要求你安裝軟體以啟動遠程控制會話。</p><area-msg><p>訊息: <b notrans=1>[[[MSG]]]</b></p></area-msg><area-windows><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshagents?id=4&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">單擊此處下載適用於Windows的MeshAgent。</a></p></area-windows><area-osx><p style=margin-left:30px><a href="[[[SERVERURL]]]/meshosxagent?id=16&meshid=[[[MESHIDHEX]]]&tag=mailto:[[[EMAIL]]]&installflags=[[[INSTALLFLAGS]]]">單擊此處下載適用於Apple OSX的MeshAgent。</a></p></area-osx><area-linux><p>對於Linux,將以下內容剪切並粘貼到終端中以安裝代理軟體:<br><pre style=margin-left:30px notrans=1>wget -q "[[[SERVERURL]]]/meshagents?script=1" --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh [[[SERVERURL]]] \'[[[MESHIDHEX]]]\'</pre><p></p></area-linux><area-link><p>要安裝軟體, <a href=[[[SERVERURL]]][[[LINKURL]]][[[URLARGS2]]]>點擊這裡</a> 並按照說明進行操作。</p></area-link><p>如果你沒有發起此請求,請不理此電郵。</p>最好的祝福,<br>[[[USERNAME]]]<br></div>
\ No newline at end of file
public/images/sharing-32.png
Binary files /dev/null and b/public/images/sharing-32.png differ
public/images/sharing-64.png
Binary files /dev/null and b/public/images/sharing-64.png differ
public/styles/style-sharing.css
new
+65
@@ -0,0 +1,65 @@
1
+.slbbutton {
2
+ width: 44px;
3
+ height: 44px;
4
+ border-radius: 5px;
5
+ background-color: #BBB;
6
+ margin-left: 4px;
7
+ margin-top: 8px;
8
+ position: relative;
9
+ cursor: pointer;
10
+ opacity: 0.5;
11
+}
12
+
13
+ .night .slbbutton {
14
+ background-color: black;
15
+ }
16
+
17
+ .slbbutton:hover {
18
+ opacity: 1;
19
+ }
20
+
21
+.slbbuttonsel {
22
+ opacity: 0.9;
23
+}
24
+
25
+.slbbuttonsel2 {
26
+ width: 70px;
27
+ border-radius: 5px 0px 0px 5px;
28
+ opacity: 1;
29
+}
30
+
31
+.slb1 {
32
+ background: url(../images/sharing-32.png) 0px 0px;
33
+ background-image: image-set(url(../images/sharing-32.png) 1x, url(../images/sharing-64.png) 2x);
34
+ height: 32px;
35
+ width: 32px;
36
+ cursor: pointer;
37
+ border: none;
38
+ position: absolute;
39
+ top: 3px;
40
+ left: 3px;
41
+}
42
+
43
+.slb2 {
44
+ background: url(../images/sharing-32.png) -32px 0px;
45
+ background-image: image-set(url(../images/sharing-32.png) 1x, url(../images/sharing-64.png) 2x);
46
+ height: 32px;
47
+ width: 32px;
48
+ cursor: pointer;
49
+ border: none;
50
+ position: absolute;
51
+ top: 3px;
52
+ left: 3px;
53
+}
54
+
55
+.slb3 {
56
+ background: url(../images/sharing-32.png) -64px 0px;
57
+ background-image: image-set(url(../images/sharing-32.png) 1x, url(../images/sharing-64.png) 2x);
58
+ height: 32px;
59
+ width: 32px;
60
+ cursor: pointer;
61
+ border: none;
62
+ position: absolute;
63
+ top: 3px;
64
+ left: 3px;
65
+}
\ No newline at end of file
translate/translate.js
+2
@@ -38,6 +38,7 @@ var meshCentralSourceFiles = [
38
"../views/player.handlebars",
39
"../views/desktop.handlebars",
40
"../views/terminal.handlebars",
41
+ "../views/sharing.handlebars",
42
"../views/mstsc.handlebars",
43
"../emails/account-check.html",
44
"../emails/account-invite.html",
@@ -75,6 +76,7 @@ var minifyMeshCentralSourceFiles = [
76
"../views/player.handlebars",
77
"../views/desktop.handlebars",
78
"../views/terminal.handlebars",
79
+ "../views/sharing.handlebars",
80
"../views/mstsc.handlebars",
81
"../public/scripts/agent-desktop-0.0.2.js",
82
"../public/scripts/agent-redir-rtc-0.1.0.js",
translate/translate.json
+340
-125
@@ -600,7 +600,8 @@
600
"zh-cht": ",軟體KVM",
601
"xloc": [
602
"default.handlebars->31->938",
603
- "desktop.handlebars->3->12"
603
+ "desktop.handlebars->3->12",
604
+ "sharing.handlebars->11->12"
605
]
606
},
607
{
@@ -644,6 +645,9 @@
645
"default.handlebars->31->1019",
646
"default.handlebars->31->945",
647
"desktop.handlebars->3->19",
648
+ "sharing.handlebars->11->19",
649
+ "sharing.handlebars->11->27",
650
+ "sharing.handlebars->11->44",
651
"terminal.handlebars->3->9",
652
"xterm.handlebars->9->6"
653
]
@@ -667,6 +671,7 @@
671
"xloc": [
672
"default.handlebars->container->column_l->p11->p11warning->3->p11warninga",
673
"default.handlebars->container->column_l->p12->p12warning->3->p12warninga",
674
+ "sharing.handlebars->p12->p12warning->3->p12warninga",
675
"terminal.handlebars->p12->p12warning->3->p12warninga"
676
]
677
},
@@ -766,7 +771,8 @@
771
"zh-cht": ",{0}觀看",
772
"xloc": [
773
"default.handlebars->31->939",
769
- "desktop.handlebars->3->13"
774
+ "desktop.handlebars->3->13",
775
+ "sharing.handlebars->11->13"
776
]
777
},
778
{
@@ -832,7 +838,8 @@
838
"default-mobile.handlebars->11->376",
839
"default.handlebars->31->1025",
840
"default.handlebars->31->1706",
835
- "default.handlebars->31->2229"
841
+ "default.handlebars->31->2229",
842
+ "sharing.handlebars->11->50"
843
]
844
},
845
{
@@ -913,7 +920,8 @@
920
"default-mobile.handlebars->11->626",
921
"default.handlebars->31->1730",
922
"download.handlebars->3->1",
916
- "download2.handlebars->5->1"
923
+ "download2.handlebars->5->1",
924
+ "sharing.handlebars->11->96"
925
]
926
},
927
{
@@ -934,7 +942,8 @@
942
"zh-cht": "1位聯絡文",
943
"xloc": [
944
"default.handlebars->31->941",
937
- "desktop.handlebars->3->15"
945
+ "desktop.handlebars->3->15",
946
+ "sharing.handlebars->11->15"
947
]
948
},
949
{
@@ -1300,7 +1309,8 @@
1309
"xloc": [
1310
"default-mobile.handlebars->dialog->3->dialog7->d7meshkvm->3->1->2->3->d7bitmapscaling->1",
1311
"default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->1",
1303
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->1"
1312
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->1",
1313
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->1"
1314
]
1315
},
1316
{
@@ -1321,6 +1331,7 @@
1331
"zh-cht": "100x30",
1332
"xloc": [
1333
"default.handlebars->container->column_l->p12->termTable->1->1->6->1->1->terminalSizeDropDown->termSizeList->1",
1334
+ "sharing.handlebars->p12->9->1->terminalSizeDropDown->termSizeList->1",
1335
"terminal.handlebars->p12->9->1->terminalSizeDropDown->termSizeList->1"
1336
]
1337
},
@@ -1383,7 +1394,8 @@
1394
"xloc": [
1395
"default-mobile.handlebars->dialog->3->dialog7->d7meshkvm->3->1->2->3->d7bitmapscaling->15",
1396
"default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->15",
1386
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->15"
1397
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->15",
1398
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->15"
1399
]
1400
},
1401
{
@@ -1589,7 +1601,8 @@
1601
"xloc": [
1602
"default-mobile.handlebars->dialog->3->dialog7->d7meshkvm->3->1->2->3->d7bitmapscaling->13",
1603
"default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->13",
1592
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->13"
1604
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->13",
1605
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->13"
1606
]
1607
},
1608
{
@@ -1812,7 +1825,8 @@
1825
"xloc": [
1826
"default-mobile.handlebars->dialog->3->dialog7->d7meshkvm->3->1->2->3->d7bitmapscaling->11",
1827
"default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->11",
1815
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->11"
1828
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->11",
1829
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->11"
1830
]
1831
},
1832
{
@@ -2039,7 +2053,8 @@
2053
"xloc": [
2054
"default-mobile.handlebars->dialog->3->dialog7->d7meshkvm->3->1->2->3->d7bitmapscaling->9",
2055
"default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->9",
2042
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->9"
2056
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->9",
2057
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->9"
2058
]
2059
},
2060
{
@@ -2123,7 +2138,8 @@
2138
"xloc": [
2139
"default-mobile.handlebars->dialog->3->dialog7->d7meshkvm->3->1->2->3->d7bitmapscaling->7",
2140
"default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->7",
2126
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->7"
2141
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->7",
2142
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->7"
2143
]
2144
},
2145
{
@@ -2264,7 +2280,8 @@
2280
"xloc": [
2281
"default-mobile.handlebars->dialog->3->dialog7->d7meshkvm->3->1->2->3->d7bitmapscaling->5",
2282
"default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->5",
2267
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->5"
2283
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->5",
2284
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->5"
2285
]
2286
},
2287
{
@@ -2307,6 +2324,7 @@
2324
"zh-cht": "80x25",
2325
"xloc": [
2326
"default.handlebars->container->column_l->p12->termTable->1->1->6->1->1->terminalSizeDropDown->termSizeList->0",
2327
+ "sharing.handlebars->p12->9->1->terminalSizeDropDown->termSizeList->0",
2328
"terminal.handlebars->p12->9->1->terminalSizeDropDown->termSizeList->0"
2329
]
2330
},
@@ -2329,7 +2347,8 @@
2347
"xloc": [
2348
"default-mobile.handlebars->dialog->3->dialog7->d7meshkvm->3->1->2->3->d7bitmapscaling->3",
2349
"default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->3",
2332
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->3"
2350
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->3",
2351
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->3"
2352
]
2353
},
2354
{
@@ -4551,7 +4570,8 @@
4570
"xloc": [
4571
"default-mobile.handlebars->dialog->3->dialog7->d7meshkvm->1",
4572
"default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->1",
4554
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->1"
4573
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->1",
4574
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7meshkvm->1"
4575
]
4576
},
4577
{
@@ -4986,7 +5006,8 @@
5006
"zh-cht": "Alt-F4",
5007
"xloc": [
5008
"default-mobile.handlebars->dialog->3->dialog3->deskkeys->19",
4989
- "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->17"
5009
+ "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->17",
5010
+ "sharing.handlebars->p11->deskarea0->deskarea4->3->deskkeys->17"
5011
]
5012
},
5013
{
@@ -5007,7 +5028,8 @@
5028
"zh-cht": "Alt-Tab",
5029
"xloc": [
5030
"default-mobile.handlebars->dialog->3->dialog3->deskkeys->23",
5010
- "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->21"
5031
+ "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->21",
5032
+ "sharing.handlebars->p11->deskarea0->deskarea4->3->deskkeys->21"
5033
]
5034
},
5035
{
@@ -5028,6 +5050,7 @@
5050
"zh-cht": "備用(F10 = ESC + 0)",
5051
"xloc": [
5052
"default.handlebars->31->1012",
5053
+ "sharing.handlebars->11->37",
5054
"terminal.handlebars->3->19"
5055
]
5056
},
@@ -6138,7 +6161,8 @@
6161
"default.handlebars->container->column_l->p11->deskarea0->deskarea1->3",
6162
"default.handlebars->container->column_l->p12->termTable->1->1->0->1->3",
6163
"default.handlebars->container->column_l->p13->p13toolbar->1->0->1->3",
6141
- "desktop.handlebars->p11->deskarea0->deskarea1->3"
6164
+ "desktop.handlebars->p11->deskarea0->deskarea1->3",
6165
+ "sharing.handlebars->p11->deskarea0->deskarea1->3"
6166
]
6167
},
6168
{
@@ -6426,6 +6450,7 @@
6450
"zh-cht": "退格鍵",
6451
"xloc": [
6452
"default.handlebars->container->column_l->p12->termTable->1->1->6->1->3",
6453
+ "sharing.handlebars->p12->9->3",
6454
"terminal.handlebars->p12->9->3"
6455
]
6456
},
@@ -7036,6 +7061,9 @@
7061
"default.handlebars->31->1005",
7062
"default.handlebars->31->1014",
7063
"default.handlebars->container->column_l->p12->termTable->1->1->6->1->1->terminalSettingsButtons",
7064
+ "sharing.handlebars->11->25",
7065
+ "sharing.handlebars->11->39",
7066
+ "sharing.handlebars->p12->9->1->terminalSettingsButtons",
7067
"terminal.handlebars->3->21",
7068
"terminal.handlebars->3->7",
7069
"terminal.handlebars->p12->9->1->terminalSettingsButtons"
@@ -7148,6 +7176,7 @@
7176
"login.handlebars->dialog->idx_dlgButtonBar",
7177
"login2.handlebars->dialog->idx_dlgButtonBar",
7178
"player.handlebars->p11->dialog->idx_dlgButtonBar",
7179
+ "sharing.handlebars->dialog->idx_dlgButtonBar",
7180
"terminal.handlebars->p12->dialog->idx_dlgButtonBar",
7181
"xterm.handlebars->p11->dialog->idx_dlgButtonBar"
7182
]
@@ -8064,7 +8093,11 @@
8093
"default.handlebars->31->1745",
8094
"default.handlebars->container->column_l->p15->consoleTable->1->6->1->1->1->0->7",
8095
"default.handlebars->container->column_l->p41->3->1",
8067
- "messenger.handlebars->xbottom->1->1->0->5"
8096
+ "messenger.handlebars->xbottom->1->1->0->5",
8097
+ "sharing.handlebars->11->75",
8098
+ "sharing.handlebars->11->77",
8099
+ "sharing.handlebars->11->79",
8100
+ "sharing.handlebars->11->81"
8101
]
8102
},
8103
{
@@ -8523,7 +8556,8 @@
8556
"zh-cht": "剪貼板",
8557
"xloc": [
8558
"default.handlebars->container->column_l->p11->deskarea0->deskarea4->3",
8526
- "desktop.handlebars->p11->deskarea0->deskarea4->3"
8559
+ "desktop.handlebars->p11->deskarea0->deskarea4->3",
8560
+ "sharing.handlebars->p11->deskarea0->deskarea4->3"
8561
]
8562
},
8563
{
@@ -8548,7 +8582,8 @@
8582
"default.handlebars->31->152",
8583
"default.handlebars->31->160",
8584
"default.handlebars->31->2343",
8551
- "default.handlebars->31->994"
8585
+ "default.handlebars->31->994",
8586
+ "sharing.handlebars->11->52"
8587
]
8588
},
8589
{
@@ -8765,7 +8800,8 @@
8800
"zh-chs": "压缩档案...",
8801
"zh-cht": "壓縮檔案...",
8802
"xloc": [
8768
- "default.handlebars->31->1022"
8803
+ "default.handlebars->31->1022",
8804
+ "sharing.handlebars->11->47"
8805
]
8806
},
8807
{
@@ -8815,7 +8851,8 @@
8851
"zh-cht": "確認將1個副本複製到此位置?",
8852
"xloc": [
8853
"default-mobile.handlebars->11->390",
8818
- "default.handlebars->31->1045"
8854
+ "default.handlebars->31->1045",
8855
+ "sharing.handlebars->11->70"
8856
]
8857
},
8858
{
@@ -8835,7 +8872,8 @@
8872
"zh-chs": "确认{0}个条目的复制到此位置?",
8873
"zh-cht": "確認{0}個條目的複製到此位置?",
8874
"xloc": [
8838
- "default.handlebars->31->1044"
8875
+ "default.handlebars->31->1044",
8876
+ "sharing.handlebars->11->69"
8877
]
8878
},
8879
{
@@ -8996,7 +9034,8 @@
9034
"zh-cht": "確認將1個條目移動到此位置?",
9035
"xloc": [
9036
"default-mobile.handlebars->11->392",
8999
- "default.handlebars->31->1047"
9037
+ "default.handlebars->31->1047",
9038
+ "sharing.handlebars->11->72"
9039
]
9040
},
9041
{
@@ -9016,7 +9055,8 @@
9055
"zh-chs": "确认将{0}个条目移到此位置?",
9056
"zh-cht": "確認將{0}個條目移到該位置?",
9057
"xloc": [
9019
- "default.handlebars->31->1046"
9058
+ "default.handlebars->31->1046",
9059
+ "sharing.handlebars->11->71"
9060
]
9061
},
9062
{
@@ -9381,6 +9421,10 @@
9421
"default.handlebars->container->column_l->p13->p13toolbar->1->0->1->3",
9422
"desktop.handlebars->p11->deskarea0->deskarea1->3->connectbutton1span",
9423
"mstsc.handlebars->main->1->3->1->8->1->0",
9424
+ "sharing.handlebars->11->42",
9425
+ "sharing.handlebars->p11->deskarea0->deskarea1->3->connectbutton1span",
9426
+ "sharing.handlebars->p12->5->3->connectbutton2span",
9427
+ "sharing.handlebars->p13->p13toolbar->1->3",
9428
"terminal.handlebars->p12->5->3->connectbutton2span",
9429
"xterm.handlebars->p11->deskarea0->deskarea1->3"
9430
]
@@ -9463,7 +9507,8 @@
9507
"zh-chs": "使用Intel AMT硬件KVM连接",
9508
"zh-cht": "使用Intel AMT硬件KVM連接",
9509
"xloc": [
9466
- "desktop.handlebars->p11->deskarea0->deskarea1->3->connectbutton1hspan"
9510
+ "desktop.handlebars->p11->deskarea0->deskarea1->3->connectbutton1hspan",
9511
+ "sharing.handlebars->p11->deskarea0->deskarea1->3->connectbutton1hspan"
9512
]
9513
},
9514
{
@@ -9524,6 +9569,7 @@
9569
"default-mobile.handlebars->11->4",
9570
"default.handlebars->31->11",
9571
"desktop.handlebars->3->4",
9572
+ "sharing.handlebars->11->4",
9573
"terminal.handlebars->3->4",
9574
"xterm.handlebars->9->4"
9575
]
@@ -9635,6 +9681,8 @@
9681
"default.handlebars->31->310",
9682
"default.handlebars->31->9",
9683
"desktop.handlebars->3->2",
9684
+ "sharing.handlebars->11->2",
9685
+ "sharing.handlebars->11->93",
9686
"terminal.handlebars->3->2",
9687
"xterm.handlebars->9->2"
9688
]
@@ -9850,7 +9898,8 @@
9898
"default-mobile.handlebars->container->page_content->column_l->p10->p10files->p13toolbar->1->2->1->3",
9899
"default-mobile.handlebars->container->page_content->column_l->p5->p5myfiles->p5toolbar->1->0->1->3",
9900
"default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3",
9853
- "default.handlebars->container->column_l->p5->p5toolbar->1->0->p5filehead->3"
9901
+ "default.handlebars->container->column_l->p5->p5toolbar->1->0->p5filehead->3",
9902
+ "sharing.handlebars->p13->p13toolbar->fileArea2->3"
9903
]
9904
},
9905
{
@@ -10699,6 +10748,7 @@
10748
"zh-cht": "Ctl-C",
10749
"xloc": [
10750
"default.handlebars->container->column_l->p12->termTable->1->1->6->1->3",
10751
+ "sharing.handlebars->p12->9->3",
10752
"terminal.handlebars->p12->9->3"
10753
]
10754
},
@@ -10720,6 +10770,7 @@
10770
"zh-cht": "Ctl-X",
10771
"xloc": [
10772
"default.handlebars->container->column_l->p12->termTable->1->1->6->1->3",
10773
+ "sharing.handlebars->p12->9->3",
10774
"terminal.handlebars->p12->9->3"
10775
]
10776
},
@@ -10745,6 +10796,7 @@
10796
"default.handlebars->31->57",
10797
"default.handlebars->31->970",
10798
"default.handlebars->31->974",
10799
+ "sharing.handlebars->11->24",
10800
"terminal.handlebars->3->6"
10801
]
10802
},
@@ -10772,7 +10824,8 @@
10824
"zh-cht": "Ctrl + Alt + Del",
10825
"xloc": [
10826
"default-mobile.handlebars->dialog->3->dialog3->deskkeys->1",
10775
- "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->1"
10827
+ "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->1",
10828
+ "sharing.handlebars->p11->deskarea0->deskarea4->3->deskkeys->1"
10829
]
10830
},
10831
{
@@ -10810,7 +10863,8 @@
10863
"zh-cht": "Ctrl-W",
10864
"xloc": [
10865
"default-mobile.handlebars->dialog->3->dialog3->deskkeys->21",
10813
- "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->19"
10866
+ "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->19",
10867
+ "sharing.handlebars->p11->deskarea0->deskarea4->3->deskkeys->19"
10868
]
10869
},
10870
{
@@ -10901,7 +10955,8 @@
10955
"default-mobile.handlebars->container->page_content->column_l->p10->p10files->p13toolbar->1->2->1->3",
10956
"default-mobile.handlebars->container->page_content->column_l->p5->p5myfiles->p5toolbar->1->0->1->3",
10957
"default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3",
10904
- "default.handlebars->container->column_l->p5->p5toolbar->1->0->p5filehead->3"
10958
+ "default.handlebars->container->column_l->p5->p5toolbar->1->0->p5filehead->3",
10959
+ "sharing.handlebars->p13->p13toolbar->fileArea2->3"
10960
]
10961
},
10962
{
@@ -10992,7 +11047,8 @@
11047
"zh-cht": "數據通道",
11048
"xloc": [
11049
"default.handlebars->31->937",
10995
- "desktop.handlebars->3->11"
11050
+ "desktop.handlebars->3->11",
11051
+ "sharing.handlebars->11->11"
11052
]
11053
},
11054
{
@@ -11178,6 +11234,9 @@
11234
"default.handlebars->filesContextMenu->5",
11235
"desktop.handlebars->p11->dialog->idx_dlgButtonBar->5",
11236
"player.handlebars->p11->dialog->idx_dlgButtonBar->5",
11237
+ "sharing.handlebars->11->61",
11238
+ "sharing.handlebars->dialog->idx_dlgButtonBar->5",
11239
+ "sharing.handlebars->p13->p13toolbar->fileArea2->3",
11240
"terminal.handlebars->p12->dialog->idx_dlgButtonBar->5",
11241
"xterm.handlebars->p11->dialog->idx_dlgButtonBar->5"
11242
]
@@ -11511,7 +11570,8 @@
11570
"default-mobile.handlebars->11->147",
11571
"default-mobile.handlebars->11->384",
11572
"default.handlebars->31->1038",
11514
- "default.handlebars->31->1736"
11573
+ "default.handlebars->31->1736",
11574
+ "sharing.handlebars->11->63"
11575
]
11576
},
11577
{
@@ -11554,7 +11614,8 @@
11614
"default-mobile.handlebars->11->146",
11615
"default-mobile.handlebars->11->383",
11616
"default.handlebars->31->1037",
11557
- "default.handlebars->31->1735"
11617
+ "default.handlebars->31->1735",
11618
+ "sharing.handlebars->11->62"
11619
]
11620
},
11621
{
@@ -11637,6 +11698,8 @@
11698
"default-mobile.handlebars->11->334",
11699
"default.handlebars->31->933",
11700
"desktop.handlebars->3->7",
11701
+ "sharing.handlebars->11->29",
11702
+ "sharing.handlebars->11->7",
11703
"terminal.handlebars->3->11"
11704
]
11705
},
@@ -11660,7 +11723,8 @@
11723
"default-mobile.handlebars->container->page_content->column_l->p10->p10files->p13toolbar->1->4->1->1->1->0->3->p13sortdropdown->11",
11724
"default-mobile.handlebars->container->page_content->column_l->p5->p5myfiles->p5toolbar->1->2->1->1->1->0->3->p5sortdropdown->11",
11725
"default.handlebars->container->column_l->p13->p13toolbar->1->4->1->1->p13sortdropdown->11",
11663
- "default.handlebars->container->column_l->p5->p5toolbar->1->2->p5filesubhead->1->p5sortdropdown->11"
11726
+ "default.handlebars->container->column_l->p5->p5toolbar->1->2->p5filesubhead->1->p5sortdropdown->11",
11727
+ "sharing.handlebars->p13->p13toolbar->5->1->p13sortdropdown->11"
11728
]
11729
},
11730
{
@@ -11683,7 +11747,8 @@
11747
"default-mobile.handlebars->container->page_content->column_l->p10->p10files->p13toolbar->1->4->1->1->1->0->3->p13sortdropdown->7",
11748
"default-mobile.handlebars->container->page_content->column_l->p5->p5myfiles->p5toolbar->1->2->1->1->1->0->3->p5sortdropdown->7",
11749
"default.handlebars->container->column_l->p13->p13toolbar->1->4->1->1->p13sortdropdown->7",
11686
- "default.handlebars->container->column_l->p5->p5toolbar->1->2->p5filesubhead->1->p5sortdropdown->7"
11750
+ "default.handlebars->container->column_l->p5->p5toolbar->1->2->p5filesubhead->1->p5sortdropdown->7",
11751
+ "sharing.handlebars->p13->p13toolbar->5->1->p13sortdropdown->7"
11752
]
11753
},
11754
{
@@ -11706,7 +11771,8 @@
11771
"default-mobile.handlebars->container->page_content->column_l->p10->p10files->p13toolbar->1->4->1->1->1->0->3->p13sortdropdown->9",
11772
"default-mobile.handlebars->container->page_content->column_l->p5->p5myfiles->p5toolbar->1->2->1->1->1->0->3->p5sortdropdown->9",
11773
"default.handlebars->container->column_l->p13->p13toolbar->1->4->1->1->p13sortdropdown->9",
11709
- "default.handlebars->container->column_l->p5->p5toolbar->1->2->p5filesubhead->1->p5sortdropdown->9"
11774
+ "default.handlebars->container->column_l->p5->p5toolbar->1->2->p5filesubhead->1->p5sortdropdown->9",
11775
+ "sharing.handlebars->p13->p13toolbar->5->1->p13sortdropdown->9"
11776
]
11777
},
11778
{
@@ -11792,7 +11858,9 @@
11858
"default.handlebars->31->805",
11859
"default.handlebars->container->topbar->1->1->MainSubMenuSpan->MainSubMenu->1->0->MainDevDesktop",
11860
"default.handlebars->contextMenu->cxdesktop",
11795
- "desktop.handlebars->3->23"
11861
+ "desktop.handlebars->3->23",
11862
+ "sharing.handlebars->11->23",
11863
+ "sharing.handlebars->LeftSideToolBar"
11864
]
11865
},
11866
{
@@ -11902,7 +11970,8 @@
11970
"zh-cht": "桌面會話延遲",
11971
"xloc": [
11972
"default.handlebars->container->column_l->p11->deskarea0->deskarea4->1",
11905
- "desktop.handlebars->p11->deskarea0->deskarea4->1"
11973
+ "desktop.handlebars->p11->deskarea0->deskarea4->1",
11974
+ "sharing.handlebars->p11->deskarea0->deskarea4->1"
11975
]
11976
},
11977
{
@@ -13044,6 +13113,9 @@
13113
"default.handlebars->container->column_l->p11->deskarea0->deskarea1->3->disconnectbutton1span",
13114
"default.handlebars->container->column_l->p12->termTable->1->1->0->1->3->disconnectbutton2span",
13115
"desktop.handlebars->p11->deskarea0->deskarea1->3->disconnectbutton1span",
13116
+ "sharing.handlebars->11->43",
13117
+ "sharing.handlebars->p11->deskarea0->deskarea1->3->disconnectbutton1span",
13118
+ "sharing.handlebars->p12->5->3->disconnectbutton2span",
13119
"terminal.handlebars->p12->5->3->disconnectbutton2span",
13120
"xterm.handlebars->p11->deskarea0->deskarea1->3"
13121
]
@@ -13099,6 +13171,10 @@
13171
"default.handlebars->container->column_l->p13->p13toolbar->1->0->1->3->p13Status",
13172
"desktop.handlebars->3->1",
13173
"desktop.handlebars->p11->deskarea0->deskarea1->3->deskstatus",
13174
+ "sharing.handlebars->11->1",
13175
+ "sharing.handlebars->p11->deskarea0->deskarea1->3->deskstatus",
13176
+ "sharing.handlebars->p12->5->3->termstatus",
13177
+ "sharing.handlebars->p13->p13toolbar->1->3->p13Status",
13178
"terminal.handlebars->3->1",
13179
"terminal.handlebars->p12->5->3->termstatus",
13180
"xterm.handlebars->9->1"
@@ -13522,7 +13598,8 @@
13598
"zh-cht": "下載檔案",
13599
"xloc": [
13600
"default-mobile.handlebars->11->403",
13525
- "default.handlebars->31->1057"
13601
+ "default.handlebars->31->1057",
13602
+ "sharing.handlebars->11->82"
13603
]
13604
},
13605
{
@@ -14365,6 +14442,7 @@
14442
"xloc": [
14443
"default.handlebars->container->column_l->p11->deskarea0->deskarea4->3",
14444
"default.handlebars->container->column_l->p12->termTable->1->1->6->1->3",
14445
+ "sharing.handlebars->p12->9->3",
14446
"terminal.handlebars->p12->9->3"
14447
]
14448
},
@@ -14386,7 +14464,8 @@
14464
"zh-cht": "編輯",
14465
"xloc": [
14466
"default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3",
14389
- "default.handlebars->filesContextMenu->3"
14467
+ "default.handlebars->filesContextMenu->3",
14468
+ "sharing.handlebars->p13->p13toolbar->fileArea2->3"
14469
]
14470
},
14471
{
@@ -14785,7 +14864,8 @@
14864
"zh-cht": "編輯遠程桌面設置",
14865
"xloc": [
14866
"default.handlebars->container->column_l->p11->deskarea0->deskarea1->1",
14788
- "desktop.handlebars->p11->deskarea0->deskarea1->1"
14867
+ "desktop.handlebars->p11->deskarea0->deskarea1->1",
14868
+ "sharing.handlebars->p11->deskarea0->deskarea1->1"
14869
]
14870
},
14871
{
@@ -15717,7 +15797,8 @@
15797
"default.handlebars->31->1030",
15798
"default.handlebars->31->1439",
15799
"default.handlebars->31->1440",
15720
- "default.handlebars->31->954"
15800
+ "default.handlebars->31->954",
15801
+ "sharing.handlebars->11->55"
15802
]
15803
},
15804
{
@@ -15777,7 +15858,8 @@
15858
"zh-chs": "输入文本,然后单击“确定”以使用美式英语键盘远程输入文本。在继续操作之前,请确保将远程鼠标放置在正确的位置。",
15859
"zh-cht": "輸入文本,然後單擊“確定”以使用美式英語鍵盤遠程輸入文本。在繼續操作之前,請確保將遠程光標放置在正確的位置。",
15860
"xloc": [
15780
- "desktop.handlebars->3->21"
15861
+ "desktop.handlebars->3->21",
15862
+ "sharing.handlebars->11->21"
15863
]
15864
},
15865
{
@@ -16155,6 +16237,7 @@
16237
"zh-cht": "於{0}到期",
16238
"xloc": [
16239
"desktop.handlebars->3->26",
16240
+ "sharing.handlebars->11->94",
16241
"terminal.handlebars->3->24"
16242
]
16243
},
@@ -16176,6 +16259,7 @@
16259
"zh-cht": "過期{0}",
16260
"xloc": [
16261
"desktop.handlebars->3->27",
16262
+ "sharing.handlebars->11->95",
16263
"terminal.handlebars->3->25"
16264
]
16265
},
@@ -16217,6 +16301,7 @@
16301
"zh-cht": "擴充式ASCII",
16302
"xloc": [
16303
"default.handlebars->31->1009",
16304
+ "sharing.handlebars->11->34",
16305
"terminal.handlebars->3->16"
16306
]
16307
},
@@ -16238,6 +16323,7 @@
16323
"zh-cht": "擴充式ASCII",
16324
"xloc": [
16325
"default.handlebars->container->column_l->p12->termTable->1->1->6->1->1->terminalSettingsButtons",
16326
+ "sharing.handlebars->p12->9->1->terminalSettingsButtons",
16327
"terminal.handlebars->p12->9->1->terminalSettingsButtons"
16328
]
16329
},
@@ -16411,6 +16497,8 @@
16497
"default-mobile.handlebars->11->335",
16498
"default.handlebars->31->934",
16499
"desktop.handlebars->3->8",
16500
+ "sharing.handlebars->11->30",
16501
+ "sharing.handlebars->11->8",
16502
"terminal.handlebars->3->12"
16503
]
16504
},
@@ -16453,7 +16541,8 @@
16541
"xloc": [
16542
"default-mobile.handlebars->dialog->3->dialog7->d7meshkvm->3->1->4->3->d7framelimiter->1",
16543
"default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->7->d7framelimiter->1",
16456
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->7->d7framelimiter->1"
16544
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->7->d7framelimiter->1",
16545
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7meshkvm->7->d7framelimiter->1"
16546
]
16547
},
16548
{
@@ -16535,7 +16624,8 @@
16624
"xloc": [
16625
"default-mobile.handlebars->11->387",
16626
"default.handlebars->31->1041",
16538
- "default.handlebars->31->571"
16627
+ "default.handlebars->31->571",
16628
+ "sharing.handlebars->11->66"
16629
]
16630
},
16631
{
@@ -16572,7 +16662,9 @@
16662
"zh-cht": "檔案操作",
16663
"xloc": [
16664
"default.handlebars->31->1021",
16575
- "default.handlebars->31->1023"
16665
+ "default.handlebars->31->1023",
16666
+ "sharing.handlebars->11->46",
16667
+ "sharing.handlebars->11->48"
16668
]
16669
},
16670
{
@@ -16638,7 +16730,8 @@
16730
"default.handlebars->31->2211",
16731
"default.handlebars->31->295",
16732
"default.handlebars->container->topbar->1->1->MainSubMenuSpan->MainSubMenu->1->0->MainDevFiles",
16641
- "default.handlebars->contextMenu->cxfiles"
16733
+ "default.handlebars->contextMenu->cxfiles",
16734
+ "sharing.handlebars->LeftSideToolBar"
16735
]
16736
},
16737
{
@@ -16728,7 +16821,8 @@
16821
"default.handlebars->31->1026",
16822
"default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->devListToolbar",
16823
"default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->kvmListToolbar",
16731
- "default.handlebars->container->column_l->p4->3->1->0->3->3"
16824
+ "default.handlebars->container->column_l->p4->3->1->0->3->3",
16825
+ "sharing.handlebars->11->51"
16826
]
16827
},
16828
{
@@ -16748,7 +16842,8 @@
16842
"zh-chs": "找",
16843
"zh-cht": "找",
16844
"xloc": [
16751
- "default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3"
16845
+ "default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3",
16846
+ "sharing.handlebars->p13->p13toolbar->fileArea2->3"
16847
]
16848
},
16849
{
@@ -16768,7 +16863,8 @@
16863
"zh-chs": "查找文件",
16864
"zh-cht": "查找文件",
16865
"xloc": [
16771
- "default.handlebars->31->1029"
16866
+ "default.handlebars->31->1029",
16867
+ "sharing.handlebars->11->54"
16868
]
16869
},
16870
{
@@ -17127,7 +17223,8 @@
17223
"zh-cht": "框速率",
17224
"xloc": [
17225
"default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->7->1",
17130
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->7->1"
17226
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->7->1",
17227
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7meshkvm->7->1"
17228
]
17229
},
17230
{
@@ -18409,7 +18506,8 @@
18506
"default-mobile.handlebars->container->page_content->column_l->p10->p10desktop->deskarea1->1->3",
18507
"default.handlebars->container->column_l->p11->deskarea0->deskarea1->3->connectbutton1hspan",
18508
"default.handlebars->container->column_l->p12->termTable->1->1->0->1->3->connectbutton2hspan",
18412
- "desktop.handlebars->p11->deskarea0->deskarea1->3->connectbutton1hspan"
18509
+ "desktop.handlebars->p11->deskarea0->deskarea1->3->connectbutton1hspan",
18510
+ "sharing.handlebars->p11->deskarea0->deskarea1->3->connectbutton1hspan"
18511
]
18512
},
18513
{
@@ -18794,7 +18892,8 @@
18892
"zh-cht": "保存1個項目進行複製",
18893
"xloc": [
18894
"default-mobile.handlebars->11->396",
18797
- "default.handlebars->31->1051"
18895
+ "default.handlebars->31->1051",
18896
+ "sharing.handlebars->11->76"
18897
]
18898
},
18899
{
@@ -18815,7 +18914,8 @@
18914
"zh-cht": "保存1個項目進行移動",
18915
"xloc": [
18916
"default-mobile.handlebars->11->400",
18818
- "default.handlebars->31->1055"
18917
+ "default.handlebars->31->1055",
18918
+ "sharing.handlebars->11->80"
18919
]
18920
},
18921
{
@@ -18836,7 +18936,8 @@
18936
"zh-cht": "保留{0}個項目進行複製",
18937
"xloc": [
18938
"default-mobile.handlebars->11->394",
18839
- "default.handlebars->31->1049"
18939
+ "default.handlebars->31->1049",
18940
+ "sharing.handlebars->11->74"
18941
]
18942
},
18943
{
@@ -18857,7 +18958,8 @@
18958
"zh-cht": "保存{0}個項目以進行移動",
18959
"xloc": [
18960
"default-mobile.handlebars->11->398",
18860
- "default.handlebars->31->1053"
18961
+ "default.handlebars->31->1053",
18962
+ "sharing.handlebars->11->78"
18963
]
18964
},
18965
{
@@ -19403,7 +19505,8 @@
19505
"zh-cht": "影像編碼",
19506
"xloc": [
19507
"default.handlebars->container->dialog->dialogBody->dialog7->d7amtkvm->3->1",
19406
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->3->1"
19508
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->3->1",
19509
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7amtkvm->3->1"
19510
]
19511
},
19512
{
@@ -19534,7 +19637,8 @@
19637
"xloc": [
19638
"default-mobile.handlebars->container->page_content->column_l->p10->p10desktop->deskarea4->1->3->11->DeskControlSpan",
19639
"default.handlebars->container->column_l->p11->deskarea0->deskarea4->3->11->DeskControlSpan",
19537
- "desktop.handlebars->p11->deskarea0->deskarea4->3->9->DeskControlSpan"
19640
+ "desktop.handlebars->p11->deskarea0->deskarea4->3->9->DeskControlSpan",
19641
+ "sharing.handlebars->p11->deskarea0->deskarea4->3->9->DeskControlSpan"
19642
]
19643
},
19644
{
@@ -19702,6 +19806,8 @@
19806
"xloc": [
19807
"default.handlebars->31->1011",
19808
"default.handlebars->container->column_l->p12->termTable->1->1->6->1->1->terminalSettingsButtons",
19809
+ "sharing.handlebars->11->36",
19810
+ "sharing.handlebars->p12->9->1->terminalSettingsButtons",
19811
"terminal.handlebars->3->18",
19812
"terminal.handlebars->p12->9->1->terminalSettingsButtons"
19813
]
@@ -19752,6 +19858,7 @@
19858
"zh-cht": "Intel ASCII",
19859
"xloc": [
19860
"default.handlebars->31->1010",
19861
+ "sharing.handlebars->11->35",
19862
"terminal.handlebars->3->17"
19863
]
19864
},
@@ -19908,6 +20015,7 @@
20015
"default-mobile.handlebars->11->5",
20016
"default.handlebars->31->12",
20017
"desktop.handlebars->3->5",
20018
+ "sharing.handlebars->11->5",
20019
"terminal.handlebars->3->5",
20020
"xterm.handlebars->9->5"
20021
]
@@ -20532,7 +20640,8 @@
20640
"xloc": [
20641
"default-mobile.handlebars->dialog->3->dialog7->d7amtkvm->1",
20642
"default.handlebars->container->dialog->dialogBody->dialog7->d7amtkvm->1",
20535
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->1"
20643
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->1",
20644
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7amtkvm->1"
20645
]
20646
},
20647
{
@@ -20554,6 +20663,7 @@
20663
"xloc": [
20664
"default.handlebars->container->column_l->p11->p11warning->3",
20665
"default.handlebars->container->column_l->p12->p12warning->3",
20666
+ "sharing.handlebars->p12->p12warning->3",
20667
"terminal.handlebars->p12->p12warning->3"
20668
]
20669
},
@@ -21704,6 +21814,8 @@
21814
"xloc": [
21815
"default.handlebars->31->1006",
21816
"default.handlebars->31->1015",
21817
+ "sharing.handlebars->11->26",
21818
+ "sharing.handlebars->11->40",
21819
"terminal.handlebars->3->22",
21820
"terminal.handlebars->3->8"
21821
]
@@ -23109,7 +23221,8 @@
23221
"zh-cht": "本地鍵盤圖",
23222
"xloc": [
23223
"default.handlebars->container->dialog->dialogBody->dialog7->d7amtkvm->5->d7otherset->5",
23112
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->5->d7otherset->5"
23224
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->5->d7otherset->5",
23225
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7amtkvm->5->d7otherset->5"
23226
]
23227
},
23228
{
@@ -24568,7 +24681,8 @@
24681
"default-mobile.handlebars->dialog->3->dialog7->d7meshkvm->3->1->4->3->d7framelimiter->3",
24682
"default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->9->devListToolbarSize->sizeselect->3",
24683
"default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->7->d7framelimiter->3",
24571
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->7->d7framelimiter->3"
24684
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->7->d7framelimiter->3",
24685
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7meshkvm->7->d7framelimiter->3"
24686
]
24687
},
24688
{
@@ -26416,7 +26530,9 @@
26530
"default.handlebars->31->1034",
26531
"default.handlebars->31->1732",
26532
"default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3",
26419
- "default.handlebars->container->column_l->p5->p5toolbar->1->0->p5filehead->3"
26533
+ "default.handlebars->container->column_l->p5->p5toolbar->1->0->p5filehead->3",
26534
+ "sharing.handlebars->11->59",
26535
+ "sharing.handlebars->p13->p13toolbar->fileArea2->3"
26536
]
26537
},
26538
{
@@ -27274,7 +27390,8 @@
27390
"zh-chs": "找不到文件",
27391
"zh-cht": "找不到文件",
27392
"xloc": [
27277
- "default.handlebars->31->1020"
27393
+ "default.handlebars->31->1020",
27394
+ "sharing.handlebars->11->45"
27395
]
27396
},
27397
{
@@ -28139,6 +28256,7 @@
28256
"login.handlebars->dialog->idx_dlgButtonBar",
28257
"login2.handlebars->dialog->idx_dlgButtonBar",
28258
"player.handlebars->p11->dialog->idx_dlgButtonBar",
28259
+ "sharing.handlebars->dialog->idx_dlgButtonBar",
28260
"terminal.handlebars->p12->dialog->idx_dlgButtonBar",
28261
"xterm.handlebars->p11->dialog->idx_dlgButtonBar"
28262
]
@@ -28389,7 +28507,8 @@
28507
"xloc": [
28508
"default-mobile.handlebars->11->388",
28509
"default.handlebars->31->1042",
28392
- "default.handlebars->31->572"
28510
+ "default.handlebars->31->572",
28511
+ "sharing.handlebars->11->67"
28512
]
28513
},
28514
{
@@ -28698,7 +28817,8 @@
28817
"xloc": [
28818
"default.handlebars->container->dialog->dialogBody->dialog7->d7amtkvm->5->1",
28819
"default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->d7desktopOtherSettings->1",
28701
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->5->1"
28820
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->5->1",
28821
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7amtkvm->5->1"
28822
]
28823
},
28824
{
@@ -29271,6 +29391,10 @@
29391
"default.handlebars->container->column_l->p12->termTable->1->1->6->1->3",
29392
"default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3",
29393
"default.handlebars->container->column_l->p5->p5toolbar->1->0->p5filehead->3",
29394
+ "sharing.handlebars->11->41",
29395
+ "sharing.handlebars->11->73",
29396
+ "sharing.handlebars->p12->9->3",
29397
+ "sharing.handlebars->p13->p13toolbar->fileArea2->3",
29398
"terminal.handlebars->3->23",
29399
"terminal.handlebars->p12->9->3"
29400
]
@@ -29293,6 +29417,7 @@
29417
"zh-cht": "將文本黏貼到終端中",
29418
"xloc": [
29419
"default.handlebars->container->column_l->p12->termTable->1->1->6->1->3",
29420
+ "sharing.handlebars->p12->9->3",
29421
"terminal.handlebars->p12->9->3"
29422
]
29423
},
@@ -30768,7 +30893,8 @@
30893
"xloc": [
30894
"default-mobile.handlebars->dialog->3->dialog7->d7meshkvm->3->1->0->1",
30895
"default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->3->1",
30771
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->3->1"
30896
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->3->1",
30897
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7meshkvm->3->1"
30898
]
30899
},
30900
{
@@ -30810,7 +30936,8 @@
30936
"xloc": [
30937
"default-mobile.handlebars->dialog->3->dialog7->d7amtkvm->3->1->0->3->d7desktopmode->7",
30938
"default.handlebars->container->dialog->dialogBody->dialog7->d7amtkvm->3->d7desktopmode->7",
30813
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->3->d7desktopmode->7"
30939
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->3->d7desktopmode->7",
30940
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7amtkvm->3->d7desktopmode->7"
30941
]
30942
},
30943
{
@@ -30832,7 +30959,8 @@
30959
"xloc": [
30960
"default-mobile.handlebars->dialog->3->dialog7->d7amtkvm->3->1->0->3->d7desktopmode->5",
30961
"default.handlebars->container->dialog->dialogBody->dialog7->d7amtkvm->3->d7desktopmode->5",
30835
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->3->d7desktopmode->5"
30962
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->3->d7desktopmode->5",
30963
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7amtkvm->3->d7desktopmode->5"
30964
]
30965
},
30966
{
@@ -30932,7 +31060,8 @@
31060
"xloc": [
31061
"default-mobile.handlebars->dialog->3->dialog7->d7amtkvm->3->1->0->3->d7desktopmode->3",
31062
"default.handlebars->container->dialog->dialogBody->dialog7->d7amtkvm->3->d7desktopmode->3",
30935
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->3->d7desktopmode->3"
31063
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->3->d7desktopmode->3",
31064
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7amtkvm->3->d7desktopmode->3"
31065
]
31066
},
31067
{
@@ -30954,7 +31083,8 @@
31083
"xloc": [
31084
"default-mobile.handlebars->dialog->3->dialog7->d7amtkvm->3->1->0->3->d7desktopmode->1",
31085
"default.handlebars->container->dialog->dialogBody->dialog7->d7amtkvm->3->d7desktopmode->1",
30957
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->3->d7desktopmode->1"
31086
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->3->d7desktopmode->1",
31087
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7amtkvm->3->d7desktopmode->1"
31088
]
31089
},
31090
{
@@ -31136,6 +31266,8 @@
31266
"default-mobile.handlebars->11->337",
31267
"default.handlebars->31->936",
31268
"desktop.handlebars->3->10",
31269
+ "sharing.handlebars->11->10",
31270
+ "sharing.handlebars->11->32",
31271
"terminal.handlebars->3->14"
31272
]
31273
},
@@ -31259,7 +31391,8 @@
31391
"default-mobile.handlebars->11->144",
31392
"default-mobile.handlebars->11->381",
31393
"default.handlebars->31->1035",
31262
- "default.handlebars->31->1733"
31394
+ "default.handlebars->31->1733",
31395
+ "sharing.handlebars->11->60"
31396
]
31397
},
31398
{
@@ -31308,7 +31441,8 @@
31441
"default.handlebars->container->column_l->p11->deskarea0->deskarea3x->DeskTools->deskToolsAreaTop->DeskToolsRefreshButton",
31442
"default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3",
31443
"default.handlebars->container->column_l->p40->3->3",
31311
- "default.handlebars->container->column_l->p52->3->1->0->3->3"
31444
+ "default.handlebars->container->column_l->p52->3->1->0->3->3",
31445
+ "sharing.handlebars->p13->p13toolbar->fileArea2->3"
31446
]
31447
},
31448
{
@@ -31761,7 +31895,8 @@
31895
"default-mobile.handlebars->11->339",
31896
"default.handlebars->31->312",
31897
"default.handlebars->31->947",
31764
- "desktop.handlebars->3->20"
31898
+ "desktop.handlebars->3->20",
31899
+ "sharing.handlebars->11->20"
31900
]
31901
},
31902
{
@@ -31782,7 +31917,8 @@
31917
"zh-cht": "遠程鍵盤輸入",
31918
"xloc": [
31919
"default.handlebars->31->980",
31785
- "desktop.handlebars->3->22"
31920
+ "desktop.handlebars->3->22",
31921
+ "sharing.handlebars->11->22"
31922
]
31923
},
31924
{
@@ -31904,6 +32040,7 @@
32040
"xloc": [
32041
"default.handlebars->container->column_l->p11->p11warning2->3",
32042
"default.handlebars->container->column_l->p12->p12warning2->3",
32043
+ "sharing.handlebars->p12->p12warning2->3",
32044
"terminal.handlebars->p12->p12warning2->3"
32045
]
32046
},
@@ -32617,7 +32754,9 @@
32754
"default.handlebars->31->570",
32755
"default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3",
32756
"default.handlebars->container->column_l->p5->p5toolbar->1->0->p5filehead->3",
32620
- "default.handlebars->filesContextMenu->1"
32757
+ "default.handlebars->filesContextMenu->1",
32758
+ "sharing.handlebars->11->64",
32759
+ "sharing.handlebars->p13->p13toolbar->fileArea2->3"
32760
]
32761
},
32762
{
@@ -33170,7 +33309,8 @@
33309
"default-mobile.handlebars->11->130",
33310
"default-mobile.handlebars->11->375",
33311
"default.handlebars->31->1024",
33173
- "default.handlebars->31->1705"
33312
+ "default.handlebars->31->1705",
33313
+ "sharing.handlebars->11->49"
33314
]
33315
},
33316
{
@@ -33246,7 +33386,8 @@
33386
"zh-cht": "向左旋轉",
33387
"xloc": [
33388
"default.handlebars->container->column_l->p11->deskarea0->deskarea1->1",
33249
- "desktop.handlebars->p11->deskarea0->deskarea1->1"
33389
+ "desktop.handlebars->p11->deskarea0->deskarea1->1",
33390
+ "sharing.handlebars->p11->deskarea0->deskarea1->1"
33391
]
33392
},
33393
{
@@ -33267,7 +33408,8 @@
33408
"zh-cht": "向右旋轉",
33409
"xloc": [
33410
"default.handlebars->container->column_l->p11->deskarea0->deskarea1->1",
33270
- "desktop.handlebars->p11->deskarea0->deskarea1->1"
33411
+ "desktop.handlebars->p11->deskarea0->deskarea1->1",
33412
+ "sharing.handlebars->p11->deskarea0->deskarea1->1"
33413
]
33414
},
33415
{
@@ -33834,7 +33976,8 @@
33976
"zh-cht": "保存遠程桌面的屏幕截圖",
33977
"xloc": [
33978
"default.handlebars->container->column_l->p11->deskarea0->deskarea4->1",
33837
- "desktop.handlebars->p11->deskarea0->deskarea4->1"
33979
+ "desktop.handlebars->p11->deskarea0->deskarea4->1",
33980
+ "sharing.handlebars->p11->deskarea0->deskarea4->1"
33981
]
33982
},
33983
{
@@ -33913,7 +34056,8 @@
34056
"xloc": [
34057
"default-mobile.handlebars->dialog->3->dialog7->d7meshkvm->3->1->2->1",
34058
"default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->5->1",
33916
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->5->1"
34059
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->5->1",
34060
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7meshkvm->5->1"
34061
]
34062
},
34063
{
@@ -34096,7 +34240,8 @@
34240
"xloc": [
34241
"default.handlebars->31->1028",
34242
"default.handlebars->31->590",
34099
- "default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->devMapToolbar"
34243
+ "default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->devMapToolbar",
34244
+ "sharing.handlebars->11->53"
34245
]
34246
},
34247
{
@@ -34290,7 +34435,10 @@
34435
"default.handlebars->container->column_l->p4->3->1->0->3->3",
34436
"default.handlebars->container->column_l->p5->p5toolbar->1->0->p5filehead->3",
34437
"default.handlebars->container->column_l->p50->3->1->0->3->3",
34293
- "default.handlebars->meshContextMenu->cxselectall"
34438
+ "default.handlebars->meshContextMenu->cxselectall",
34439
+ "sharing.handlebars->11->56",
34440
+ "sharing.handlebars->11->58",
34441
+ "sharing.handlebars->p13->p13toolbar->fileArea2->3"
34442
]
34443
},
34444
{
@@ -34315,7 +34463,8 @@
34463
"default.handlebars->31->1910",
34464
"default.handlebars->31->1993",
34465
"default.handlebars->31->475",
34318
- "default.handlebars->meshContextMenu->cxselectnone"
34466
+ "default.handlebars->meshContextMenu->cxselectnone",
34467
+ "sharing.handlebars->11->57"
34468
]
34469
},
34470
{
@@ -34523,6 +34672,8 @@
34672
"default.handlebars->container->column_l->p12->termTable->1->1->6->1->1->specialKeyDropDown",
34673
"desktop.handlebars->p11->deskarea0->deskarea4->3",
34674
"messenger.handlebars->xbottom->1->1->0->3",
34675
+ "sharing.handlebars->p11->deskarea0->deskarea4->3",
34676
+ "sharing.handlebars->p12->9->1->specialKeyDropDown",
34677
"terminal.handlebars->p12->9->1->specialKeyDropDown"
34678
]
34679
},
@@ -34765,6 +34916,7 @@
34916
"zh-cht": "發送選擇的特殊鍵",
34917
"xloc": [
34918
"default.handlebars->container->column_l->p12->termTable->1->1->6->1->1->specialKeyDropDown",
34919
+ "sharing.handlebars->p12->9->1->specialKeyDropDown",
34920
"terminal.handlebars->p12->9->1->specialKeyDropDown"
34921
]
34922
},
@@ -35382,6 +35534,8 @@
35534
"default.handlebars->container->column_l->p11->deskarea0->deskarea1->1",
35535
"default.handlebars->container->column_l->p12->termTable->1->1->0->1->1",
35536
"default.handlebars->container->column_l->p13->p13toolbar->1->0->1->1",
35537
+ "sharing.handlebars->p12->5->1",
35538
+ "sharing.handlebars->p13->p13toolbar->1->1",
35539
"terminal.handlebars->p12->5->1"
35540
]
35541
},
@@ -35504,7 +35658,8 @@
35658
"zh-cht": "會議訊息",
35659
"xloc": [
35660
"default.handlebars->31->944",
35507
- "desktop.handlebars->3->18"
35661
+ "desktop.handlebars->3->18",
35662
+ "sharing.handlebars->11->18"
35663
]
35664
},
35665
{
@@ -35527,6 +35682,8 @@
35682
"default.handlebars->container->column_l->p11->deskarea0->deskarea4->1",
35683
"default.handlebars->container->column_l->p12->termTable->1->1->6->1->1",
35684
"desktop.handlebars->p11->deskarea0->deskarea4->1",
35685
+ "sharing.handlebars->p11->deskarea0->deskarea4->1",
35686
+ "sharing.handlebars->p12->9->1",
35687
"terminal.handlebars->p12->9->1"
35688
]
35689
},
@@ -35680,7 +35837,8 @@
35837
"zh-cht": "設定...",
35838
"xloc": [
35839
"default.handlebars->container->column_l->p11->deskarea0->deskarea1->1",
35683
- "desktop.handlebars->p11->deskarea0->deskarea1->1"
35840
+ "desktop.handlebars->p11->deskarea0->deskarea1->1",
35841
+ "sharing.handlebars->p11->deskarea0->deskarea1->1"
35842
]
35843
},
35844
{
@@ -35782,6 +35940,7 @@
35940
"default.handlebars->31->264",
35941
"default.handlebars->31->311",
35942
"desktop.handlebars->3->3",
35943
+ "sharing.handlebars->11->3",
35944
"terminal.handlebars->3->3",
35945
"xterm.handlebars->9->3"
35946
]
@@ -35972,7 +36131,8 @@
36131
"zh-cht": "Shift + Win + M",
36132
"xloc": [
36133
"default-mobile.handlebars->dialog->3->dialog3->deskkeys->15",
35975
- "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->13"
36134
+ "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->13",
36135
+ "sharing.handlebars->p11->deskarea0->deskarea4->3->deskkeys->13"
36136
]
36137
},
36138
{
@@ -36036,7 +36196,8 @@
36196
"zh-cht": "顯示焦點工具",
36197
"xloc": [
36198
"default.handlebars->container->dialog->dialogBody->dialog7->d7amtkvm->5->d7otherset->1",
36039
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->5->d7otherset->1"
36199
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->5->d7otherset->1",
36200
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7amtkvm->5->d7otherset->1"
36201
]
36202
},
36203
{
@@ -36079,7 +36240,8 @@
36240
"zh-cht": "顯示本地鼠標光標",
36241
"xloc": [
36242
"default.handlebars->container->dialog->dialogBody->dialog7->d7amtkvm->5->d7otherset->3",
36082
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->5->d7otherset->3"
36243
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7amtkvm->5->d7otherset->3",
36244
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7amtkvm->5->d7otherset->3"
36245
]
36246
},
36247
{
@@ -36604,7 +36766,8 @@
36766
"zh-chs": "缩放:100%",
36767
"zh-cht": "縮放:100%",
36768
"xloc": [
36607
- "default.handlebars->31->1060"
36769
+ "default.handlebars->31->1060",
36770
+ "sharing.handlebars->11->85"
36771
]
36772
},
36773
{
@@ -36624,7 +36787,8 @@
36787
"zh-chs": "缩放:125%",
36788
"zh-cht": "縮放:125%",
36789
"xloc": [
36627
- "default.handlebars->31->1061"
36790
+ "default.handlebars->31->1061",
36791
+ "sharing.handlebars->11->86"
36792
]
36793
},
36794
{
@@ -36644,7 +36808,8 @@
36808
"zh-chs": "缩放:150%",
36809
"zh-cht": "縮放:150%",
36810
"xloc": [
36647
- "default.handlebars->31->1062"
36811
+ "default.handlebars->31->1062",
36812
+ "sharing.handlebars->11->87"
36813
]
36814
},
36815
{
@@ -36664,7 +36829,8 @@
36829
"zh-chs": "缩放:200%",
36830
"zh-cht": "縮放:200%",
36831
"xloc": [
36667
- "default.handlebars->31->1063"
36832
+ "default.handlebars->31->1063",
36833
+ "sharing.handlebars->11->88"
36834
]
36835
},
36836
{
@@ -36796,7 +36962,8 @@
36962
"xloc": [
36963
"default-mobile.handlebars->dialog->3->dialog7->d7meshkvm->3->1->4->3->d7framelimiter->5",
36964
"default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->7->d7framelimiter->5",
36799
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->7->d7framelimiter->5"
36965
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->7->d7framelimiter->5",
36966
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7meshkvm->7->d7framelimiter->5"
36967
]
36968
},
36969
{
@@ -36982,7 +37149,8 @@
37149
"default-mobile.handlebars->container->page_content->column_l->p10->p10files->p13toolbar->1->4->1->1->1->0->3->p13sortdropdown->5",
37150
"default-mobile.handlebars->container->page_content->column_l->p5->p5myfiles->p5toolbar->1->2->1->1->1->0->3->p5sortdropdown->5",
37151
"default.handlebars->container->column_l->p13->p13toolbar->1->4->1->1->p13sortdropdown->5",
36985
- "default.handlebars->container->column_l->p5->p5toolbar->1->2->p5filesubhead->1->p5sortdropdown->5"
37152
+ "default.handlebars->container->column_l->p5->p5toolbar->1->2->p5filesubhead->1->p5sortdropdown->5",
37153
+ "sharing.handlebars->p13->p13toolbar->5->1->p13sortdropdown->5"
37154
]
37155
},
37156
{
@@ -37007,7 +37175,8 @@
37175
"default.handlebars->container->column_l->p11->deskarea0->deskarea3x->DeskTools->deskToolsArea->DeskToolsProcessTab->deskToolsHeader",
37176
"default.handlebars->container->column_l->p11->deskarea0->deskarea3x->DeskTools->deskToolsArea->DeskToolsServiceTab->deskToolsServiceHeader",
37177
"default.handlebars->container->column_l->p13->p13toolbar->1->4->1->1->p13sortdropdown->1",
37010
- "default.handlebars->container->column_l->p5->p5toolbar->1->2->p5filesubhead->1->p5sortdropdown->1"
37178
+ "default.handlebars->container->column_l->p5->p5toolbar->1->2->p5filesubhead->1->p5sortdropdown->1",
37179
+ "sharing.handlebars->p13->p13toolbar->5->1->p13sortdropdown->1"
37180
]
37181
},
37182
{
@@ -37050,7 +37219,8 @@
37219
"default-mobile.handlebars->container->page_content->column_l->p10->p10files->p13toolbar->1->4->1->1->1->0->3->p13sortdropdown->3",
37220
"default-mobile.handlebars->container->page_content->column_l->p5->p5myfiles->p5toolbar->1->2->1->1->1->0->3->p5sortdropdown->3",
37221
"default.handlebars->container->column_l->p13->p13toolbar->1->4->1->1->p13sortdropdown->3",
37053
- "default.handlebars->container->column_l->p5->p5toolbar->1->2->p5filesubhead->1->p5sortdropdown->3"
37222
+ "default.handlebars->container->column_l->p5->p5toolbar->1->2->p5filesubhead->1->p5sortdropdown->3",
37223
+ "sharing.handlebars->p13->p13toolbar->5->1->p13sortdropdown->3"
37224
]
37225
},
37226
{
@@ -37591,7 +37761,8 @@
37761
"default.handlebars->31->2203",
37762
"default.handlebars->31->2222",
37763
"default.handlebars->31->940",
37594
- "desktop.handlebars->3->14"
37764
+ "desktop.handlebars->3->14",
37765
+ "sharing.handlebars->11->14"
37766
]
37767
},
37768
{
@@ -38735,7 +38906,8 @@
38906
"default.handlebars->31->748",
38907
"default.handlebars->31->806",
38908
"default.handlebars->container->topbar->1->1->MainSubMenuSpan->MainSubMenu->1->0->MainDevTerminal",
38738
- "default.handlebars->contextMenu->cxterminal"
38909
+ "default.handlebars->contextMenu->cxterminal",
38910
+ "sharing.handlebars->LeftSideToolBar"
38911
]
38912
},
38913
{
@@ -38821,6 +38993,7 @@
38993
"zh-chs": "终端会话延迟",
38994
"zh-cht": "終端會話延遲",
38995
"xloc": [
38996
+ "sharing.handlebars->p12->9->1",
38997
"terminal.handlebars->p12->9->1"
38998
]
38999
},
@@ -39519,6 +39692,8 @@
39692
"default-mobile.handlebars->11->336",
39693
"default.handlebars->31->935",
39694
"desktop.handlebars->3->9",
39695
+ "sharing.handlebars->11->31",
39696
+ "sharing.handlebars->11->9",
39697
"terminal.handlebars->3->13"
39698
]
39699
},
@@ -39860,6 +40035,7 @@
40035
"zh-cht": "切換F1至F10鍵仿真類型",
40036
"xloc": [
40037
"default.handlebars->container->column_l->p12->termTable->1->1->6->1->1->terminalSettingsButtons",
40038
+ "sharing.handlebars->p12->9->1->terminalSettingsButtons",
40039
"terminal.handlebars->p12->9->1->terminalSettingsButtons"
40040
]
40041
},
@@ -39902,7 +40078,8 @@
40078
"xloc": [
40079
"default.handlebars->container->column_l->p11->deskarea0->deskarea1->1",
40080
"desktop.handlebars->p11->deskarea0->deskarea1->1",
39905
- "player.handlebars->p11->deskarea0->deskarea1->1"
40081
+ "player.handlebars->p11->deskarea0->deskarea1->1",
40082
+ "sharing.handlebars->p11->deskarea0->deskarea1->1"
40083
]
40084
},
40085
{
@@ -39963,7 +40140,8 @@
40140
"zh-cht": "切換鼠標和鍵盤輸入",
40141
"xloc": [
40142
"default.handlebars->container->column_l->p11->deskarea0->deskarea4->3->11",
39966
- "desktop.handlebars->p11->deskarea0->deskarea4->3->9"
40143
+ "desktop.handlebars->p11->deskarea0->deskarea4->3->9",
40144
+ "sharing.handlebars->p11->deskarea0->deskarea4->3->9"
40145
]
40146
},
40147
{
@@ -40029,6 +40207,7 @@
40207
"zh-cht": "切換終端仿真類型",
40208
"xloc": [
40209
"default.handlebars->container->column_l->p12->termTable->1->1->6->1->1->terminalSettingsButtons",
40210
+ "sharing.handlebars->p12->9->1->terminalSettingsButtons",
40211
"terminal.handlebars->p12->9->1->terminalSettingsButtons"
40212
]
40213
},
@@ -40070,6 +40249,7 @@
40249
"zh-cht": "切換返回鍵將發送的內容",
40250
"xloc": [
40251
"default.handlebars->container->column_l->p12->termTable->1->1->6->1->1->terminalSettingsButtons",
40252
+ "sharing.handlebars->p12->9->1->terminalSettingsButtons",
40253
"terminal.handlebars->p12->9->1->terminalSettingsButtons"
40254
]
40255
},
@@ -40396,7 +40576,8 @@
40576
"default.handlebars->31->807",
40577
"default.handlebars->31->993",
40578
"default.handlebars->container->column_l->p11->deskarea0->deskarea4->3",
40399
- "desktop.handlebars->p11->deskarea0->deskarea4->3"
40579
+ "desktop.handlebars->p11->deskarea0->deskarea4->3",
40580
+ "sharing.handlebars->p11->deskarea0->deskarea4->3"
40581
]
40582
},
40583
{
@@ -40478,6 +40659,7 @@
40659
"zh-cht": "UTF8終端",
40660
"xloc": [
40661
"default.handlebars->31->1008",
40662
+ "sharing.handlebars->11->33",
40663
"terminal.handlebars->3->15"
40664
]
40665
},
@@ -41144,7 +41326,8 @@
41326
"default.handlebars->31->964",
41327
"default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3",
41328
"default.handlebars->container->column_l->p5->p5toolbar->1->0->p5filehead->3",
41147
- "default.handlebars->container->dialog->dialogBody->dialog3->d3servermode->d3serveraction"
41329
+ "default.handlebars->container->dialog->dialogBody->dialog3->d3servermode->d3serveraction",
41330
+ "sharing.handlebars->p13->p13toolbar->fileArea2->3"
41331
]
41332
},
41333
{
@@ -41212,7 +41395,8 @@
41395
"default-mobile.handlebars->container->page_content->column_l->p5->p5myfiles->p5toolbar->1->0->1->3",
41396
"default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3",
41397
"default.handlebars->container->column_l->p5->p5toolbar->1->0->p5filehead->3",
41215
- "messenger.handlebars->remoteImage->3->10"
41398
+ "messenger.handlebars->remoteImage->3->10",
41399
+ "sharing.handlebars->p13->p13toolbar->fileArea2->3"
41400
]
41401
},
41402
{
@@ -41241,7 +41425,10 @@
41425
"default.handlebars->31->1067",
41426
"default.handlebars->31->1738",
41427
"default.handlebars->31->1746",
41244
- "default.handlebars->container->dialog->dialogBody->dialog3->d3localmode->1"
41428
+ "default.handlebars->container->dialog->dialogBody->dialog3->d3localmode->1",
41429
+ "sharing.handlebars->11->65",
41430
+ "sharing.handlebars->11->89",
41431
+ "sharing.handlebars->11->92"
41432
]
41433
},
41434
{
@@ -41428,7 +41615,8 @@
41615
"xloc": [
41616
"default-mobile.handlebars->11->405",
41617
"default.handlebars->31->1065",
41431
- "default.handlebars->31->1747"
41618
+ "default.handlebars->31->1747",
41619
+ "sharing.handlebars->11->90"
41620
]
41621
},
41622
{
@@ -41450,7 +41638,8 @@
41638
"xloc": [
41639
"default-mobile.handlebars->11->406",
41640
"default.handlebars->31->1066",
41453
- "default.handlebars->31->1748"
41641
+ "default.handlebars->31->1748",
41642
+ "sharing.handlebars->11->91"
41643
]
41644
},
41645
{
@@ -42103,7 +42292,8 @@
42292
"zh-cht": "用戶“{0}”",
42293
"xloc": [
42294
"default.handlebars->31->943",
42106
- "desktop.handlebars->3->17"
42295
+ "desktop.handlebars->3->17",
42296
+ "sharing.handlebars->11->17"
42297
]
42298
},
42299
{
@@ -42416,6 +42606,7 @@
42606
"zh-cht": "VT100 +(F10 = ESC + [OY)",
42607
"xloc": [
42608
"default.handlebars->31->1013",
42609
+ "sharing.handlebars->11->38",
42610
"terminal.handlebars->3->20"
42611
]
42612
},
@@ -42734,7 +42925,8 @@
42925
"xloc": [
42926
"default-mobile.handlebars->dialog->3->dialog7->d7meshkvm->3->1->4->3->d7framelimiter->7",
42927
"default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->7->d7framelimiter->7",
42737
- "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->7->d7framelimiter->7"
42928
+ "desktop.handlebars->p11->dialog->dialogBody->dialog7->d7meshkvm->7->d7framelimiter->7",
42929
+ "sharing.handlebars->dialog->dialogBody->dialog7->d7meshkvm->7->d7framelimiter->7"
42930
]
42931
},
42932
{
@@ -43062,6 +43254,8 @@
43254
"default-mobile.handlebars->11->333",
43255
"default.handlebars->31->932",
43256
"desktop.handlebars->3->6",
43257
+ "sharing.handlebars->11->28",
43258
+ "sharing.handlebars->11->6",
43259
"terminal.handlebars->3->10"
43260
]
43261
},
@@ -43506,7 +43700,8 @@
43700
"default-mobile.handlebars->dialog->3->dialog3->deskkeys->5",
43701
"default.handlebars->31->971",
43702
"default.handlebars->31->975",
43509
- "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->3"
43703
+ "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->3",
43704
+ "sharing.handlebars->p11->deskarea0->deskarea4->3->deskkeys->3"
43705
]
43706
},
43707
{
@@ -43527,7 +43722,8 @@
43722
"zh-cht": "Win+向下",
43723
"xloc": [
43724
"default-mobile.handlebars->dialog->3->dialog3->deskkeys->7",
43530
- "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->5"
43725
+ "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->5",
43726
+ "sharing.handlebars->p11->deskarea0->deskarea4->3->deskkeys->5"
43727
]
43728
},
43729
{
@@ -43548,7 +43744,8 @@
43744
"zh-cht": "Win+L",
43745
"xloc": [
43746
"default-mobile.handlebars->dialog->3->dialog3->deskkeys->11",
43551
- "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->9"
43747
+ "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->9",
43748
+ "sharing.handlebars->p11->deskarea0->deskarea4->3->deskkeys->9"
43749
]
43750
},
43751
{
@@ -43568,7 +43765,8 @@
43765
"zh-chs": "Win+向左",
43766
"zh-cht": "Win+向左",
43767
"xloc": [
43571
- "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->23"
43768
+ "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->23",
43769
+ "sharing.handlebars->p11->deskarea0->deskarea4->3->deskkeys->23"
43770
]
43771
},
43772
{
@@ -43589,7 +43787,8 @@
43787
"zh-cht": "Win+M",
43788
"xloc": [
43789
"default-mobile.handlebars->dialog->3->dialog3->deskkeys->13",
43592
- "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->11"
43790
+ "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->11",
43791
+ "sharing.handlebars->p11->deskarea0->deskarea4->3->deskkeys->11"
43792
]
43793
},
43794
{
@@ -43610,7 +43809,8 @@
43809
"zh-cht": "Win+R",
43810
"xloc": [
43811
"default-mobile.handlebars->dialog->3->dialog3->deskkeys->17",
43613
- "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->15"
43812
+ "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->15",
43813
+ "sharing.handlebars->p11->deskarea0->deskarea4->3->deskkeys->15"
43814
]
43815
},
43816
{
@@ -43630,7 +43830,8 @@
43830
"zh-chs": "Win+向右",
43831
"zh-cht": "Win+向右",
43832
"xloc": [
43633
- "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->25"
43833
+ "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->25",
43834
+ "sharing.handlebars->p11->deskarea0->deskarea4->3->deskkeys->25"
43835
]
43836
},
43837
{
@@ -43651,7 +43852,8 @@
43852
"zh-cht": "Win+向上",
43853
"xloc": [
43854
"default-mobile.handlebars->dialog->3->dialog3->deskkeys->9",
43654
- "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->7"
43855
+ "desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->7",
43856
+ "sharing.handlebars->p11->deskarea0->deskarea4->3->deskkeys->7"
43857
]
43858
},
43859
{
@@ -44108,7 +44310,8 @@
44310
"zh-chs": "换行:关",
44311
"zh-cht": "换行:關",
44312
"xloc": [
44111
- "default.handlebars->31->1059"
44313
+ "default.handlebars->31->1059",
44314
+ "sharing.handlebars->11->84"
44315
]
44316
},
44317
{
@@ -44128,7 +44331,8 @@
44331
"zh-chs": "换行:开",
44332
"zh-cht": "换行:開",
44333
"xloc": [
44131
- "default.handlebars->31->1058"
44334
+ "default.handlebars->31->1058",
44335
+ "sharing.handlebars->11->83"
44336
]
44337
},
44338
{
@@ -44407,7 +44611,8 @@
44611
"zh-chs": "Zip",
44612
"zh-cht": "Zip",
44613
"xloc": [
44410
- "default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3"
44614
+ "default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3",
44615
+ "sharing.handlebars->p13->p13toolbar->fileArea2->3"
44616
]
44617
},
44618
{
@@ -44427,7 +44632,8 @@
44632
"zh-chs": "邮编档案名",
44633
"zh-cht": "郵編檔案名",
44634
"xloc": [
44430
- "default.handlebars->31->1043"
44635
+ "default.handlebars->31->1043",
44636
+ "sharing.handlebars->11->68"
44637
]
44638
},
44639
{
@@ -46372,7 +46578,8 @@
46578
"default.handlebars->31->1731",
46579
"default.handlebars->31->2221",
46580
"download.handlebars->3->2",
46375
- "download2.handlebars->5->2"
46581
+ "download2.handlebars->5->2",
46582
+ "sharing.handlebars->11->97"
46583
]
46584
},
46585
{
@@ -46413,7 +46620,8 @@
46620
"zh-cht": "{0}個連接",
46621
"xloc": [
46622
"default.handlebars->31->942",
46416
- "desktop.handlebars->3->16"
46623
+ "desktop.handlebars->3->16",
46624
+ "sharing.handlebars->11->16"
46625
]
46626
},
46627
{
@@ -47019,7 +47227,8 @@
47227
"ru": "↺",
47228
"xloc": [
47229
"default.handlebars->container->column_l->p11->deskarea0->deskarea1->1->5",
47022
- "desktop.handlebars->p11->deskarea0->deskarea1->1->5"
47230
+ "desktop.handlebars->p11->deskarea0->deskarea1->1->5",
47231
+ "sharing.handlebars->p11->deskarea0->deskarea1->1->5"
47232
]
47233
},
47234
{
@@ -47036,7 +47245,8 @@
47245
"ru": "↻",
47246
"xloc": [
47247
"default.handlebars->container->column_l->p11->deskarea0->deskarea1->1->7",
47039
- "desktop.handlebars->p11->deskarea0->deskarea1->1->7"
47248
+ "desktop.handlebars->p11->deskarea0->deskarea1->1->7",
47249
+ "sharing.handlebars->p11->deskarea0->deskarea1->1->7"
47250
]
47251
},
47252
{
@@ -47054,7 +47264,8 @@
47264
"xloc": [
47265
"default.handlebars->container->column_l->p11->deskarea0->deskarea1->1->3",
47266
"desktop.handlebars->p11->deskarea0->deskarea1->1->3",
47057
- "player.handlebars->p11->deskarea0->deskarea1->1->1"
47267
+ "player.handlebars->p11->deskarea0->deskarea1->1->1",
47268
+ "sharing.handlebars->p11->deskarea0->deskarea1->1->3"
47269
]
47270
},
47271
{
@@ -47127,6 +47338,7 @@
47338
"default.handlebars->container->column_l->p6->p6info->p2ServerActions->3->p2ServerActionsRestore->0->0->0",
47339
"default.handlebars->container->column_l->p6->p6info->p2ServerActions->3->p2ServerActionsVersion->0->0->0",
47340
"player.handlebars->p11->deskarea0->deskarea3x->bigok->0",
47341
+ "sharing.handlebars->p13->p13toolbar->fileArea4->p13filetable->p13bigok->0",
47342
"xterm.handlebars->p11->deskarea0->deskarea3x->bigok->0"
47343
]
47344
},
@@ -47149,6 +47361,8 @@
47361
"desktop.handlebars->p11->deskarea0->deskarea1->3->idx_deskFullBtn2",
47362
"desktop.handlebars->p11->dialog->dialogHeader->id_dialogclose",
47363
"player.handlebars->p11->dialog->dialogHeader->id_dialogclose",
47364
+ "sharing.handlebars->dialog->dialogHeader->id_dialogclose",
47365
+ "sharing.handlebars->p11->deskarea0->deskarea1->3->idx_deskFullBtn2",
47366
"terminal.handlebars->p12->5->3->idx_termFullBtn2",
47367
"terminal.handlebars->p12->dialog->dialogHeader->id_dialogclose",
47368
"xterm.handlebars->p11->dialog->dialogHeader->id_dialogclose"
@@ -47170,6 +47384,7 @@
47384
"default.handlebars->container->column_l->p13->p13filetable->p13bigfail->0",
47385
"default.handlebars->container->column_l->p5->p5filetable->bigfail->0",
47386
"player.handlebars->p11->deskarea0->deskarea3x->bigfail->0",
47387
+ "sharing.handlebars->p13->p13toolbar->fileArea4->p13filetable->p13bigfail->0",
47388
"xterm.handlebars->p11->deskarea0->deskarea3x->bigfail->0"
47389
]
47390
}
views/sharing.handlebars
new
+2209
@@ -0,0 +1,2209 @@
1
+<!DOCTYPE html>
2
+<html lang="en" dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
3
+<head>
4
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
5
+ <meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
6
+ <meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0" />
7
+ <meta name="apple-mobile-web-app-capable" content="yes" />
8
+ <meta name="format-detection" content="telephone=no" />
9
+ <meta name="robots" content="noindex,nofollow">
10
+ <link type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS" />
11
+ <link type="text/css" href="styles/style-sharing.css" media="screen" rel="stylesheet" title="CSS" />
12
+ <link type="text/css" href="styles/xterm.css" media="screen" rel="stylesheet" title="CSS" />
13
+ <link rel="apple-touch-icon" href="/favicon-303x303.png" />
14
+ <script type="text/javascript" src="scripts/common-0.0.1{{min}}.js"></script>
15
+ <script type="text/javascript" src="scripts/amt-redir-ws-0.1.0{{{min}}}.js"></script>
16
+ <script type="text/javascript" src="scripts/amt-wsman-ws-0.2.0{{{min}}}.js"></script>
17
+ <script type="text/javascript" src="scripts/agent-redir-ws-0.1.1{{{min}}}.js"></script>
18
+ <script type="text/javascript" src="scripts/agent-redir-rtc-0.1.0{{{min}}}.js"></script>
19
+ <script type="text/javascript" src="scripts/agent-desktop-0.0.2{{min}}.js"></script>
20
+ <script type="text/javascript" src="scripts/amt-desktop-0.0.2{{min}}.js"></script>
21
+ <script type="text/javascript" src="scripts/amt-terminal-0.0.2{{min}}.js"></script>
22
+ <script type="text/javascript" src="scripts/zlib{{min}}.js"></script>
23
+ <script type="text/javascript" src="scripts/zlib-inflate{{min}}.js"></script>
24
+ <script type="text/javascript" src="scripts/zlib-adler32{{min}}.js"></script>
25
+ <script type="text/javascript" src="scripts/zlib-crc32{{min}}.js"></script>
26
+ <script type="text/javascript" src="scripts/amt-terminal-0.0.2{{min}}.js"></script>
27
+ <script type="text/javascript" src="scripts/xterm{{{min}}}.js"></script>
28
+ <script type="text/javascript" src="scripts/xterm-addon-fit{{{min}}}.js"></script>
29
+ <script keeplink=1 type="text/javascript" src="scripts/filesaver.min.js"></script>
30
+ <title>{{{title}}}</title>
31
+</head>
32
+<body style="overflow:hidden;background-color:black">
33
+ <div id=LeftSideToolBar style="position:absolute;left:0;bottom:0;width:52px;top:0;background:#113962;background:linear-gradient(to bottom, #104893 0%,#113962 100%);color:white;border-right: 5px solid #BBB;">
34
+ <div id=LeftMenuDesktop class="slbbutton slbbuttonsel2" title="Desktop" onclick=go(11)>
35
+ <div class="slb1" style="position:absolute;top:6px;left:6px"></div>
36
+ </div>
37
+ <div id=LeftMenuTerminal class="slbbutton" title="Terminal" onclick=go(12)>
38
+ <div class="slb2" style="position:absolute;top:6px;left:6px"></div>
39
+ </div>
40
+ <div id=LeftMenuFiles class="slbbutton" title="Files" onclick=go(13)>
41
+ <div class="slb3" style="position:absolute;top:6px;left:6px"></div>
42
+ </div>
43
+ </div>
44
+ <div id=p11 class="noselect" style="overflow:hidden;position:absolute;left:54px;top:0;right:0;bottom:0;display:none">
45
+ <div id=deskarea0>
46
+ <div id=deskarea1 class="areaHead">
47
+ <div class="toright2">
48
+ <span id="p11power"></span>
49
+ <div class='deskareaicon' title="Toggle View Mode" onclick="toggleAspectRatio(1)">⇲</div>
50
+ <div class='deskareaicon' title="Rotate Left" onclick="drotate(-1)">↺</div>
51
+ <div class='deskareaicon' title="Rotate Right" onclick="drotate(1)">↻</div>
52
+ <input id="deskActionsSettings" type="button" value="Settings..." title="Edit remote desktop settings" onkeypress="return false" onkeydown="return false" onclick="showDesktopSettings()" class="mR" />
53
+ <div id="desktopCustomUiButtons" style="float:left"></div>
54
+ </div>
55
+ <div>
56
+ <div id="idx_deskFullBtn2" onclick=deskToggleFull(event)> ✖</div>
57
+ <input type="button" id="autoconnectbutton1" value="AutoConnect" onclick=autoConnectDesktop(event) onkeypress="return false" onkeydown="return false" style="display:none" />
58
+ <span id=connectbutton1span><input type=button id=connectbutton1 cmenu="deskConnectButton" value="Connect" onclick=connectDesktop(event,3) onkeypress="return false" onkeydown="return false" disabled="disabled" /></span>
59
+ <span id=connectbutton1hspan> <input type=button id=connectbutton1h value="HW Connect" title="Connect using Intel AMT hardware KVM" onclick=connectDesktop(event,2) onkeypress="return false" onkeydown="return false" disabled="disabled" /></span>
60
+ <span id=disconnectbutton1span> <input type=button id=disconnectbutton1 value="Disconnect" onclick=connectDesktop(event,0) onkeypress="return false" onkeydown="return false" /></span>
61
+ <span id="deskstatus">Disconnected</span><span id="deskmetadata"></span>
62
+ </div>
63
+ </div>
64
+ <div id=deskarea3x style="max-height:calc(100vh - 52px);height:calc(100vh - 56px);">
65
+ <div id=DeskFocus oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event)></div>
66
+ <div id=DeskParent>
67
+ <canvas id=Desk width=640 height=480 oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event) onmousewheel=dmousewheel(event)></canvas>
68
+ </div>
69
+ <div id=p11DeskConsoleMsg style="display:none;cursor:pointer;position:absolute;left:30px;top:17px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick=clearConsoleMsg()></div>
70
+ </div>
71
+ <div id=deskarea4 class="areaFoot" style="min-height:24px">
72
+ <div class="toright2">
73
+ <span id="DeskLatency" title="Desktop Session Latency"></span>
74
+ <span id="DeskTimer" style="display:none" title="Session time"></span>
75
+ <select id=termdisplays style="display:none" onchange=deskSetDisplay(event) onkeypress="return false" onkeydown="return false"></select>
76
+ <span id=DeskSaveImageButton title="Save a screenshot of the remote desktop"><img src='images/icon-camera.png' onclick=deskSaveImage() height=16 width=16 style=padding-top:2px /></span>
77
+ </div>
78
+ <div style="height:22px">
79
+ <select id="deskkeys">
80
+ <option value=10>Ctrl+Alt+Del</option>
81
+ <option value=5>Win</option>
82
+ <option value=0>Win+Down</option>
83
+ <option value=1>Win+Up</option>
84
+ <option value=2>Win+L</option>
85
+ <option value=3>Win+M</option>
86
+ <option value=4>Shift+Win+M</option>
87
+ <option value=6>Win+R</option>
88
+ <option value=7>Alt-F4</option>
89
+ <option value=8>Ctrl-W</option>
90
+ <option value=9>Alt-Tab</option>
91
+ <option value=11>Win+Left</option>
92
+ <option value=12>Win+Right</option>
93
+ </select>
94
+ <input id="DeskWD" type=button value="Send" onkeypress="return false" onkeydown="return false" onclick="deskSendKeys()" />
95
+ <input id="DeskClip" style="" type="button" value="Clipboard" onkeypress="return false" onkeydown="return false" onclick="showDeskClip()" />
96
+ <input id="DeskType" style="" type="button" value="Type" onkeypress="return false" onkeydown="return false" onclick="showDeskType()" />
97
+ <label><span id="DeskControlSpan" title="Toggle mouse and keyboard input"><input id="DeskControl" type="checkbox" onkeypress="return false" onkeydown="return false" onclick="toggleKvmControl()" />Input</span></label>
98
+ </div>
99
+ </div>
100
+ </div>
101
+ </div>
102
+ <div id=p12 class="noselect" style="overflow:hidden;position:absolute;left:54px;top:0;right:0;bottom:0;display:none;background-color:black">
103
+ <div id="p12warning" onclick=showFeaturesDlg()>
104
+ <div class="icon2"></div>
105
+ <div class="warningbox">Intel® AMT Redirection port or KVM feature is disabled<span id="p12warninga">, click here to enable it.</span></div>
106
+ </div>
107
+ <div id="p12warning2" onclick=showPowerActionDlg()>
108
+ <div class="icon2"></div>
109
+ <div class="warningbox">Remote computer is not powered on, click here to issue a power command.</div>
110
+ </div>
111
+ <div class="areaHead" style="position:absolute;top:0;left:0;right:0;height:24px">
112
+ <div class="toright2">
113
+ <div id="p12power" style="margin-top:3px;margin-right:4px"></div>
114
+ <div id="termRecordIcon" class='deskareaicon' title="Server is recording this session" style="display:none;background-color:red;width:12px;height:12px;border-radius:6px;margin-top:5px;margin-left:5px"></div>
115
+ </div>
116
+ <div>
117
+ <span id="connectbutton2span"><input type="button" id="connectbutton2" cmenu="termConnectButton" value="Connect" onclick=connectTerminal(event,1) onkeypress="return false" onkeydown="return false" disabled="disabled" /></span>
118
+ <span id="disconnectbutton2span"> <input type="button" id="disconnectbutton2" value="Disconnect" onclick=connectTerminal(event,0) onkeypress="return false" onkeydown="return false" /></span>
119
+ <span id="termstatus">Disconnected</span><span id="termtitle"></span>
120
+ </div>
121
+ </div>
122
+ <div id="termarea3xdiv" style="position:absolute;top:28px;bottom:28px;left:0;right:0"></div>
123
+ <div class="areaFoot" style="position:absolute;bottom:0;left:0;right:0;height:24px">
124
+ <div class="toright2">
125
+ <span id="TermLatency" title="Terminal Session Latency"></span>
126
+ <span id="TermTimer" title="Session time"></span>
127
+ <span id="terminalSettingsButtons" style="display:none">
128
+ <input id="id_tcrbutton" type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" value="CR+LF" title="Toggle what the return key will send" onclick="termToggleCr()" />
129
+ <input id="id_tfxkeysbutton" type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" value="Intel (F10 = ESC+[OM)" title="Toggle F1 to F10 keys emulation type" onclick="termToggleFx()" />
130
+ <input id="id_ttypebutton" type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" value="Extended Ascii" title="Toggle terminal emulation type" onclick="termToggleType()" />
131
+ </span>
132
+ <span id="terminalSizeDropDown" style="display:none">
133
+ <select id="termSizeList" onkeypress="return false"><option value="1">80x25</option><option value="2">100x30</option></select>
134
+ </span>
135
+ <span id="specialKeyDropDown">
136
+ <select id="specialkeylist" onkeypress="return false"></select>
137
+ <input id="specialkeylistinput" type="button" onkeypress="return false" class="bottombutton" value="Send" title="Send the selected special key" onclick="sendSpecialKey()" />
138
+ </span>
139
+ </div>
140
+ <div>
141
+
142
+ <input type=button onkeypress="return false" onkeydown="return false" class="bottombutton" id="ctrlcbutton" value="Ctl-C" onclick="termSendKey(3,'ctrlcbutton')" />
143
+ <input type=button onkeypress="return false" onkeydown="return false" class="bottombutton" id="ctrlxbutton" value="Ctl-X" onclick="termSendKey(24,'ctrlxbutton')" />
144
+ <input type=button onkeypress="return false" onkeydown="return false" class="bottombutton" id="escbutton" value="ESC" onclick="termSendKey(27,'escbutton')" />
145
+ <input type=button onkeypress="return false" onkeydown="return false" class="bottombutton" id="bsbutton" value="Backspace" onclick="termSendKey(8,'bsbutton')" style="display:none" />
146
+ <input type=button onkeypress="return false" onkeydown="return false" class="bottombutton" id="pastebutton" value="Paste" title="Paste text into the terminal" onclick="showTermPasteDialog()" style="display:none" />
147
+ </div>
148
+ </div>
149
+ <div id=p12TermConsoleMsg style="display:none;cursor:pointer;position:absolute;left:30px;top:45px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick=p12clearConsoleMsg()></div>
150
+ </div>
151
+ <div id=p13 class="noselect" style="overflow:hidden;position:absolute;left:54px;top:0;right:0;bottom:0;display:none;background-color:white">
152
+ <div id="p13toolbar" style="position:absolute;left:0;top:0;right:0;bottom:28px">
153
+ <div class="areaHead">
154
+ <div class="toright2">
155
+ <div id="p13power" style="margin-top:3px;margin-right:4px"></div>
156
+ <div id="filesRecordIcon" class='deskareaicon' title="Server is recording this session" style="display:none;background-color:red;width:12px;height:12px;border-radius:6px;margin-top:5px;margin-left:5px"></div>
157
+ </div>
158
+ <div>
159
+ <input id=p13Connect value="Connect" onclick=connectFiles(event) type="button" />
160
+ <span id=p13Status>Disconnected</span>
161
+ </div>
162
+ </div>
163
+ <div id="fileArea2" class="areaHead2" valign=bottom>
164
+ <div id="p13rightOfButtons" class="toright2"></div>
165
+ <div>
166
+ <input type=button id=p13FolderUp disabled="disabled" onclick="p13folderup()" value="Up" />
167
+ <input type=button id=p13SelectAllButton disabled="disabled" onclick="p13selectallfile()" value="Select All" />
168
+ <input type=button id=p13RenameFileButton disabled="disabled" value="Rename" onclick="p13renamefile()" />
169
+ <input type=button id=p13DeleteFileButton disabled="disabled" value="Delete" onclick="p13deletefile()" />
170
+ <input type=button id=p13ViewFileButton disabled="disabled" value="Edit" onclick="p13viewfile()" />
171
+ <input type=button id=p13NewFolderButton disabled="disabled" value="New Folder" onclick="p13createfolder()" />
172
+ <input type=button id=p13UploadButton disabled="disabled" value="Upload" onclick="p13uploadFile()" />
173
+ <input type=button id=p13CutButton disabled="disabled" value="Cut" onclick="p13copyFile(1)" />
174
+ <input type=button id=p13CopyButton disabled="disabled" value="Copy" onclick="p13copyFile(0)" />
175
+ <input type=button id=p13PasteButton disabled="disabled" value="Paste" onclick="p13pasteFile()" />
176
+ <input type=button id=p13ZipButton disabled="disabled" value="Zip" onclick="p13zipFiles()" />
177
+ <input type=button id=p13RefreshButton disabled="disabled" value="Refresh" onclick="p13folderup(9999)" />
178
+ <input type=button id=p13FindButton disabled="disabled" value="Find" onclick="p13findfile()" />
179
+ </div>
180
+ </div>
181
+ <div class="areaHead3" style="line-height:28px">
182
+ <div class="toright2">
183
+ <select id=p13sortdropdown onchange=p13updateFiles()>
184
+ <option value=1 selected="selected">Sort by name</option>
185
+ <option value=2>Sort by size</option>
186
+ <option value=3>Sort by date</option>
187
+ <option value=4>Descend by name</option>
188
+ <option value=5>Descend by size</option>
189
+ <option value=6>Descend by date</option>
190
+ </select>
191
+ </div>
192
+ <div> <span id="p13currentpath"></span></div>
193
+ </div>
194
+ <div id="fileArea4" style="height:calc(100vh - 146px)">
195
+ <div id=p13FilesConsoleMsg style="display:none;cursor:pointer;position:absolute;left:30px;top:165px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick=p13clearConsoleMsg()></div>
196
+ <div id="p13filetable" style="width:100%;height:100%">
197
+ <div id="p13bigok" style="display:none"><b>✓</b></div>
198
+ <div id="p13bigfail" style="display:none"><b>✗</b></div>
199
+ <span id="p13files"></span>
200
+ </div>
201
+ </div>
202
+ </div>
203
+ <div class="areaFoot" style="position:absolute;left:0;right:0;bottom:0;height:28px">
204
+ <span id="p13bottomstatus"></span>
205
+ </div>
206
+ </div>
207
+ <div id=dialog class="noselect" style="display:none">
208
+ <div id=dialogHeader>
209
+ <div tabindex=0 id=id_dialogclose onclick=setDialogMode() onkeypress="if (event.key == 'Enter') setDialogMode()">✖</div>
210
+ <div id=id_dialogtitle></div>
211
+ </div>
212
+ <div id=dialogBody>
213
+ <div id=dialog1>
214
+ <div id=id_dialogMessage style=""></div>
215
+ </div>
216
+ <div id=dialog2 style="">
217
+ <div id=id_dialogOptions></div>
218
+ </div>
219
+ <div id=dialog7 style="">
220
+ <div id="d7meshkvm">
221
+ <h4>Agent Remote Desktop</h4>
222
+ <div>
223
+ <div>Quality</div>
224
+ <select id="d7bitmapquality" dir="rtl"></select>
225
+ </div>
226
+ <div>
227
+ <div>Scaling</div>
228
+ <select id="d7bitmapscaling" style="" dir="rtl">
229
+ <option selected=selected value=1024>100%</option>
230
+ <option value=896>87.5%</option>
231
+ <option value=768>75%</option>
232
+ <option value=640>62.5%</option>
233
+ <option value=512>50%</option>
234
+ <option value=384>37.5%</option>
235
+ <option value=256>25%</option>
236
+ <option value=128>12.5%</option>
237
+ </select>
238
+ </div>
239
+ <div>
240
+ <div>Frame rate</div>
241
+ <select id="d7framelimiter" dir="rtl">
242
+ <option selected=selected value=50>Fast</option>
243
+ <option value=100>Medium</option>
244
+ <option value=400>Slow</option>
245
+ <option value=1000>Very slow</option>
246
+ </select>
247
+ </div>
248
+ </div>
249
+ <div id="d7amtkvm">
250
+ <h4>Intel® AMT Hardware KVM</h4>
251
+ <div>
252
+ <div>Image Encoding</div>
253
+ <select id="d7desktopmode">
254
+ <option value="1">RLE8, Fastest</option>
255
+ <option value="2">RLE16, Recommended</option>
256
+ <option value="3">RAW8, Slow</option>
257
+ <option value="4">RAW16, Very Slow</option>
258
+ </select>
259
+ </div>
260
+ <div>
261
+ <div>Other Settings</div>
262
+ <div id="d7otherset" style="display:block">
263
+ <label style="display:block"><input type="checkbox" id="d7showfocus" />Show Focus Tool</label>
264
+ <label style="display:block"><input type="checkbox" id="d7showcursor" />Show Local Mouse Cursor</label>
265
+ <label style="display:block"><input type="checkbox" id="d7localKeyMap" />Local Keyboard Map</label>
266
+ </div>
267
+ </div>
268
+ </div>
269
+ </div>
270
+ </div>
271
+ <div id="idx_dlgButtonBar">
272
+ <input id="idx_dlgCancelButton" type="button" value="Cancel" style="" onclick="dialogclose(0)">
273
+ <input id="idx_dlgOkButton" type="button" value="OK" style="" onclick="dialogclose(1)">
274
+ <div><input id="idx_dlgDeleteButton" type="button" value="Delete" style="display:none" onclick="dialogclose(2)"></div>
275
+ </div>
276
+ </div>
277
+ <script>
278
+ var sessionActivity = null;
279
+ var desktop = null;
280
+ var agentPresent = true;
281
+ var intelAmtPresent = false;
282
+ var deskAspectRatio = 0;
283
+ var desktopsettings = { encoding: 2, showfocus: false, showmouse: true, showcad: true, quality: 40, scaling: 1024, framerate: 100, localkeymap: false };
284
+ var serverPublicNamePort = '{{{serverDnsName}}}:{{{serverPublicPort}}}';
285
+ var domain = '{{{domain}}}';
286
+ var domainUrl = '{{{domainurl}}}';
287
+ var authCookie = '{{{authCookie}}}';
288
+ var nodeid = '{{{nodeid}}}';
289
+ var viewOnly = parseInt('{{{viewOnly}}}');
290
+ var urlargs = parseUriArgs();
291
+ var debugmode = urlargs.debug;
292
+ var attemptWebRTC = false;
293
+ var updateSessionTimer = null;
294
+ var StatusStrs = ["Disconnected", "Connecting...", "Setup...", "Connected", "Intel® AMT Connected"];
295
+ var nodeName = decodeURIComponent('{{{nodeName}}}');
296
+ var webPageFullScreen = false;
297
+ var expire = '{{{expire}}}';
298
+ if (expire != '') {
299
+ QH('p11power', printFlexDateTime(new Date(parseInt(expire))));
300
+ QH('p12power', printFlexDateTime(new Date(parseInt(expire))));
301
+ QH('p13power', printFlexDateTime(new Date(parseInt(expire))));
302
+ }
303
+
304
+ // Terminal
305
+ var terminal = null;
306
+ var xterm = null;
307
+ var xtermfit = null;
308
+ var xtermResizeTimer = null;
309
+
310
+ // Files
311
+ var files = null
312
+
313
+ // Console messages timers
314
+ var p11DeskConsoleMsgTimer = null;
315
+ var p12TermConsoleMsgTimer = null;
316
+ var p13FilesConsoleMsgTimer = null;
317
+
318
+ function start() {
319
+ window.onresize = deskAdjust;
320
+ document.onkeypress = ondockeypress;
321
+ document.onkeydown = ondockeydown;
322
+ document.onkeyup = ondockeyup;
323
+ setupDesktop();
324
+ setupTerminal();
325
+ setupFiles();
326
+
327
+ // Set the document title
328
+ if (nodeName.length > 0) { document.title += ' - ' + nodeName; }
329
+
330
+ // View only mode
331
+ if (viewOnly == 1) {
332
+ QV('deskkeys', false);
333
+ QV('DeskWD', false);
334
+ QV('DeskClip', false);
335
+ QV('DeskType', false);
336
+ QV('DeskControlSpan', false);
337
+ }
338
+
339
+ // Setup upload drag & drop
340
+ Q('p13filetable').addEventListener('drop', p13fileDragDrop, false);
341
+ Q('p13filetable').addEventListener('dragover', p13fileDragOver, false);
342
+ Q('p13filetable').addEventListener('dragleave', p13fileDragLeave, false);
343
+
344
+ go(11); // Go to desktop
345
+ deskAdjust();
346
+ }
347
+
348
+
349
+ //
350
+ // Desktop
351
+ //
352
+
353
+ function isInputAllowed() { return (viewOnly != 1) && (Q('DeskControl').checked == true); }
354
+ function clearConsoleMsg() { QH('p11DeskConsoleMsg', ''); }
355
+
356
+ // Toggle the web page to full screen
357
+ function toggleAspectRatio(toggle) {
358
+ if (toggle === 1) { deskAspectRatio = ((deskAspectRatio + 1) % 3); }
359
+ deskAdjust();
360
+ }
361
+
362
+ function deskAdjust() {
363
+ if ((xxcurrentView == 12) && (terminal != null) && (xtermfit != null)) { xtermfit.fit(); } // Terminal
364
+ QS('fileArea4')['height'] = 'calc(100vh - ' + (90 + Q('fileArea2').clientHeight) + 'px)'; // Files
365
+ var parentH = Q('DeskParent').clientHeight, parentW = Q('DeskParent').clientWidth;
366
+ var deskH = Q('Desk').height, deskW = Q('Desk').width;
367
+
368
+ if (deskAspectRatio == 2) {
369
+ // Scale mode
370
+ QS('Desk')['margin-top'] = null;
371
+ QS('Desk').height = '100%';
372
+ QS('Desk').width = '100%';
373
+ QS('DeskParent').overflow = 'hidden';
374
+ } else if (deskAspectRatio == 1) {
375
+ // Zoomed mode
376
+ QS('Desk')['margin-top'] = '0px';
377
+ //QS('Desk')['margin-left'] = '0px';
378
+ QS('Desk').height = deskH + 'px';
379
+ QS('Desk').width = deskW + 'px';
380
+ QS('DeskParent').overflow = 'scroll';
381
+ } else {
382
+ // Fixed aspect ratio
383
+ if ((parentH / parentW) > (deskH / deskW)) {
384
+ var hNew = ((deskH * parentW) / deskW) + 'px';
385
+ //if (webPageFullScreen || fullscreen) {
386
+ //QS('deskarea3x').height = null;
387
+ //} else {
388
+ // QS('deskarea3x').height = hNew;
389
+ //QS('deskarea3x').height = null;
390
+ //}
391
+ QS('Desk').height = hNew;
392
+ QS('Desk').width = '100%';
393
+ } else {
394
+ var wNew = ((deskW * parentH) / deskH) + 'px';
395
+ //if (webPageFullScreen || fullscreen) {
396
+ //QS('Desk').height = null;
397
+ //} else {
398
+ QS('Desk').height = '100%';
399
+ //}
400
+ QS('Desk').width = wNew;
401
+ }
402
+ QS('Desk')['margin-top'] = null;
403
+ QS('DeskParent').overflow = 'hidden';
404
+ }
405
+ }
406
+
407
+ function setupDesktop() {
408
+ // Setup the remote desktop
409
+ if (desktop != null) { desktop.Stop(); desktop = null; }
410
+
411
+ // If the device desktop is already connected in multi-desktop, use that.
412
+ if (desktop == null) {
413
+ // Device is not already connected, just setup a blank canvas
414
+ QH('DeskParent', '<canvas id=Desk oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event)></canvas>');
415
+
416
+ // Setup the mouse wheel
417
+ Q('Desk').addEventListener('DOMMouseScroll', function (e) { return dmousewheel(e); });
418
+ Q('Desk').addEventListener('mousewheel', function (e) { return dmousewheel(e); });
419
+ }
420
+ updateDesktopButtons();
421
+ deskAdjust();
422
+ updateMetadata(desktop, 'deskmetadata');
423
+ }
424
+
425
+ // Show and enable the right buttons
426
+ function updateDesktopButtons() {
427
+ var deskState = 0;
428
+ if (desktop != null) { deskState = desktop.State; }
429
+
430
+ // Show the right buttons
431
+ QV('disconnectbutton1span', (deskState != 0));
432
+ QV('connectbutton1span', (deskState == 0) && (agentPresent));
433
+ QV('connectbutton1hspan', (deskState == 0) && (intelAmtPresent));
434
+
435
+ // Show the right settings
436
+ QV('d7meshkvm', agentPresent && ((deskState == 0) || (desktop.contype == 1)));
437
+ QV('d7amtkvm', intelAmtPresent && ((deskState == 0) || (desktop.contype == 2)));
438
+
439
+ // Enable buttons
440
+ QE('connectbutton1', agentPresent);
441
+ QE('connectbutton1h', intelAmtPresent);
442
+ //QV('DeskClip', agentPresent && ((desktop == null) || (desktop.contype != 2))); // Clipboard not supported on macOS
443
+ QV('DeskClip', false); // Clipboard not supported on this page
444
+ QE('DeskClip', deskState == 3);
445
+ QE('DeskType', deskState == 3);
446
+ QV('DeskWD', viewOnly != 1);
447
+ QE('DeskWD', deskState == 3);
448
+ QV('deskkeys', viewOnly != 1);
449
+ QE('deskkeys', deskState == 3);
450
+
451
+ // Display this only if we have Chat & Notify permissions
452
+ QV('DeskSaveImageButton', (deskState == 3) && (Q('Desk')['toBlob'] != null));
453
+ QV('DeskControlSpan', viewOnly != 1);
454
+ QV('deskActionsBtn', (browserfullscreen == false));
455
+ QV('deskActionsSettings', (browserfullscreen == false));
456
+ Q('DeskControl').checked = true;
457
+ QS('DeskControlSpan').color = Q('DeskControl').checked ? null : 'red';
458
+ }
459
+
460
+ // Debug
461
+ var autoConnectDesktopTimer = null;
462
+ function autoConnectDesktop(e) { if (autoConnectDesktopTimer == null) { autoConnectDesktopTimer = setInterval(function () { connectDesktop(null, 1) }, 1000); } else { clearInterval(autoConnectDesktopTimer); autoConnectDesktopTimer = null; } }
463
+
464
+ // Used to translate incoming agent console messages
465
+ var agentConsoleMessages = ['', "Waiting for user to grant access...", "Denied", "Failed to start remote terminal session, {0} ({1})", "Timeout", "Received invalid network data"];
466
+ function formatAgentConsoleMessage(msg, msgid, msgargs) {
467
+ var r;
468
+ if (msgargs == null) { msgargs = []; }
469
+ while (msgargs.length < 3) { msgargs.push(''); } // We need to call the format function in a way that works with older browsers and minifier, can't use apply() or ...
470
+ if (msgid && (msgid < agentConsoleMessages.length)) { r = EscapeHtml(format(agentConsoleMessages[msgid], (msgargs[0]), (msgargs[1]), (msgargs[2]))); } else { r = EscapeHtml(msg); }
471
+ return r.split('\n').join('<br />') + '<br /><br />';
472
+ }
473
+
474
+ function connectDesktop(e, contype, tsid, consent) {
475
+ if (xxdialogMode) return;
476
+ if ((e != null) && (e.shiftKey != false) && (contype == 3)) { contype = 1; } // If the shift key is not pressed, don't try to ask for session list.
477
+ QV('p11DeskSessionSelector', false);
478
+ p11clearConsoleMsg();
479
+ if (desktop == null) {
480
+ if (contype == 2) {
481
+ // Setup the Intel AMT remote desktop
482
+ //if ((desktopNode.intelamt.user == null) || (desktopNode.intelamt.user == '')) { editDeviceAmtSettings(desktopNode._id, connectDesktop, 2); return; }
483
+ desktop = CreateAmtRedirect(CreateAmtRemoteDesktop('Desk'), authCookie);
484
+ desktop.debugmode = debugmode;
485
+ desktop.onStateChanged = onDesktopStateChange;
486
+ desktop.m.stopInput = (viewOnly == 1);
487
+ desktop.m.bpp = (desktopsettings.encoding == 1 || desktopsettings.encoding == 3) ? 1 : 2;
488
+ desktop.m.useZRLE = (desktopsettings.encoding < 3);
489
+ desktop.m.localKeyMap = desktopsettings.localkeymap;
490
+ desktop.m.showmouse = desktopsettings.showmouse;
491
+ desktop.m.onScreenSizeChange = deskAdjust;
492
+ desktop.m.onKvmData = function (x) {
493
+ //console.log('onKvmData (' + x.length + '): ' + x);
494
+ // Send the presense probe only once if needed.
495
+ if (x.length == 0) { if (!desktop.m._sentPresence) { desktop.m._sentPresence = true; desktop.m.sendKvmData(JSON.stringify({ action: 'present', ver: 1 })); } return; }
496
+ var data = null;
497
+ try { data = JSON.parse(x); } catch (e) { }
498
+ if ((data != null) && (data.action != null)) {
499
+ if (data.action == 'restart') {
500
+ // Clear WebRTC channel
501
+ webRtcDesktopReset();
502
+ desktop.m.sendKvmData(JSON.stringify({ action: 'present', ver: 1 }));
503
+ } else if ((data.action == 'present') && (webRtcDesktop == null)) {
504
+ // Setup WebRTC channel
505
+ webRtcDesktop = { platform: data.platform };
506
+ var configuration = null; //{ "iceServers": [ { 'urls': 'stun:stun.services.mozilla.com' }, { 'urls': 'stun:stun.l.google.com:19302' } ] };
507
+ if (typeof RTCPeerConnection !== 'undefined') { webRtcDesktop.webrtc = new RTCPeerConnection(configuration); }
508
+ else if (typeof webkitRTCPeerConnection !== 'undefined') { webRtcDesktop.webrtc = new webkitRTCPeerConnection(configuration); }
509
+
510
+ webRtcDesktop.webchannel = webRtcDesktop.webrtc.createDataChannel("DataChannel", {}); // { ordered: false, maxRetransmits: 2 }
511
+ webRtcDesktop.webchannel.onopen = function () {
512
+ // Switch to software KVM
513
+ //if (urlvars && urlvars['kvmdatatrace']) { console.log('WebRTC Data Channel Open'); }
514
+ console.log('WebRTC Data Channel Open');
515
+ Q('deskstatus').textContent = StatusStrs[desktop.State] + ", Soft-KVM";
516
+ desktop.m.hold(true);
517
+ webRtcDesktop.webRtcActive = true;
518
+ webRtcDesktop.softdesktop = CreateKvmDataChannel(webRtcDesktop.webchannel, CreateAgentRemoteDesktop('Desk', Q('id_mainarea')), desktop.m);
519
+ webRtcDesktop.softdesktop.m.setRotation(desktop.m.rotation);
520
+ webRtcDesktop.softdesktop.m.onScreenSizeChange = deskAdjust;
521
+ if (desktopsettings.quality) { webRtcDesktop.softdesktop.m.CompressionLevel = desktopsettings.quality; } // Number from 1 to 100. 50 or less is best.
522
+ if (desktopsettings.scaling) { webRtcDesktop.softdesktop.m.ScalingLevel = desktopsettings.scaling; }
523
+ webRtcDesktop.softdesktop.Start();
524
+
525
+ // Check if we can get remote file access
526
+ // ###BEGIN###{DesktopInbandFiles}
527
+ /*
528
+ QV('go24', true); // Files
529
+ downloadFile = null;
530
+ p24files = webRtcDesktop.softdesktop;
531
+ p24targetpath = '';
532
+ webRtcDesktop.softdesktop.onControlMsg = onFilesControlData;
533
+ webRtcDesktop.softdesktop.sendCtrlMsg(JSON.stringify({ action: 'ls', reqid: 1, path: '' })); // Ask for the root folder
534
+ */
535
+ // ###END###{DesktopInbandFiles}
536
+ }
537
+ webRtcDesktop.webchannel.onclose = function (event) {
538
+ //if (urlvars['kvmdatatrace']) { console.log('WebRTC Data Channel Closed'); }
539
+ console.log('WebRTC Data Channel Closed');
540
+ webRtcDesktopReset();
541
+ }
542
+ webRtcDesktop.webrtc.onicecandidate = function (e) {
543
+ if (e.candidate == null) {
544
+ desktop.m.sendKvmData(JSON.stringify({ action: 'offer', ver: 1, sdp: webRtcDesktop.webrtcoffer.sdp }));
545
+ } else {
546
+ webRtcDesktop.webrtcoffer.sdp += ('a=' + e.candidate.candidate + '\r\n'); // New candidate, add it to the SDP
547
+ }
548
+ }
549
+ webRtcDesktop.webrtc.oniceconnectionstatechange = function () {
550
+ if ((webRtcDesktop != null) && (webRtcDesktop.webrtc != null) && ((webRtcDesktop.webrtc.iceConnectionState == 'disconnected') || (webRtcDesktop.webrtc.iceConnectionState == 'failed'))) { /*console.log('WebRTC ICE Failed');*/ webRtcDesktopReset(); }
551
+ }
552
+ webRtcDesktop.webrtc.createOffer(function (offer) {
553
+ // Got the offer
554
+ webRtcDesktop.webrtcoffer = offer;
555
+ webRtcDesktop.webrtc.setLocalDescription(offer, function () { }, webRtcDesktopReset);
556
+ }, webRtcDesktopReset, { mandatory: { OfferToReceiveAudio: false, OfferToReceiveVideo: false } });
557
+ } else if ((data.action == 'answer') && (webRtcDesktop != null)) {
558
+ // Complete the WebRTC channel
559
+ webRtcDesktop.webrtc.setRemoteDescription(new RTCSessionDescription({ type: 'answer', sdp: data.sdp }), function () { }, webRtcDesktopReset);
560
+ }
561
+ }
562
+ };
563
+ desktop.Start(null, 16994, '*', '*', 0);
564
+ desktop.contype = 2;
565
+ } else if ((contype == null) || (contype == 1) || (contype == 3)) {
566
+ // Setup the Mesh Agent remote desktop
567
+ desktop = CreateAgentRedirect(null, CreateAgentRemoteDesktop('Desk'), serverPublicNamePort, authCookie, null, domainUrl);
568
+ desktop.m.stopInput = (viewOnly == 1);
569
+ desktop.m.mouseCursorActive(true);
570
+ desktop.debugmode = debugmode;
571
+ desktop.m.debugmode = debugmode;
572
+ desktop.attemptWebRTC = attemptWebRTC;
573
+ desktop.options = {};
574
+ if (tsid != null) { desktop.options.tsid = tsid; }
575
+ if (consent != null) { desktop.options.consent = consent; }
576
+ desktop.onStateChanged = onDesktopStateChange;
577
+ desktop.onConsoleMessageChange = function () {
578
+ if (desktop.consoleMessage) {
579
+ Q('p11DeskConsoleMsg').innerHTML += formatAgentConsoleMessage(desktop.consoleMessage, desktop.consoleMessageId, desktop.consoleMessageArgs);
580
+ QV('p11DeskConsoleMsg', true);
581
+ if (p11DeskConsoleMsgTimer != null) { clearTimeout(p11DeskConsoleMsgTimer); }
582
+ if (desktop.consoleMessageTimeout) { p11DeskConsoleMsgTimer = setTimeout(p11clearConsoleMsg, desktop.consoleMessageTimeout * 1000); }
583
+ } else {
584
+ p11clearConsoleMsg();
585
+ }
586
+ }
587
+ desktop.onMetadataChange = function (metadata) { updateMetadata(desktop, 'deskmetadata'); }
588
+ desktop.m.CompressionLevel = desktopsettings.quality; // Number from 1 to 100. 50 or less is best.
589
+ desktop.m.ScalingLevel = desktopsettings.scaling;
590
+ if (desktopsettings.framerate) { desktop.m.FrameRateTimer = desktopsettings.framerate; }
591
+ desktop.m.onDisplayinfo = deskDisplayInfo;
592
+ desktop.m.onScreenSizeChange = deskAdjust;
593
+ desktop.Start(null);
594
+ desktop.latency.callback = function (ms) { console.log('latency', ms); updateSessionTime(); };
595
+ desktop.contype = 1;
596
+ }
597
+ } else {
598
+ // Disconnect and clean up the remote desktop
599
+ desktop.Stop();
600
+ webRtcDesktopReset();
601
+ desktop = null;
602
+ //if (pluginHandler != null) { pluginHandler.callHook('onDesktopDisconnect'); }
603
+ }
604
+ }
605
+
606
+ function updateMetadata(conn, elementid) {
607
+ var str = '', viewerCount = 0;
608
+ if (conn && (conn.State == 3)) {
609
+ if (conn.metadata && conn.metadata.users) { for (var i in conn.metadata.users) { viewerCount += conn.metadata.users[i]; } }
610
+ if (viewerCount > 1) { str = '<span onclick=showSessionMetadata(1) style=cursor:pointer>' + format(", {0} watching", viewerCount) + '</span>'; }
611
+ }
612
+ QH('deskmetadata', str);
613
+ if ((conn == desktop) && (xxdialogTag == ('sessionMetadata1'))) { showSessionMetadata(1); }
614
+ }
615
+
616
+ function showSessionMetadata(cid) {
617
+ if (xxdialogMode && (xxdialogTag != ('sessionMetadata' + cid))) return;
618
+ if (xxdialogMode) { setDialogMode(0); }
619
+ var conn = null;
620
+ if (cid == 1) { conn = desktop; }
621
+ if (conn && conn.metadata) {
622
+ var x = '';
623
+ if (conn.metadata.startTime) { x += addHtmlValue4("Start Time", printDateTime(new Date(conn.metadata.startTime))); }
624
+ if (conn.metadata.users) {
625
+ for (var i in conn.metadata.users) {
626
+ var val = (conn.metadata.users[i] == 1) ? "1 connection" : format("{0} connections", conn.metadata.users[i]);
627
+ var username = i.split('/')[2];
628
+ if ((users != null) && (users[i] != null)) { username = users[i].name; }
629
+ x += addHtmlValue4(format("User \"{0}\"", username), val);
630
+ }
631
+ }
632
+ setDialogMode(2, "Session Information", 1, null, x, 'sessionMetadata' + cid);
633
+ }
634
+ }
635
+
636
+ function p11clearConsoleMsg() { QH('p11DeskConsoleMsg', ''); QV('p11DeskConsoleMsg', false); if (p11DeskConsoleMsgTimer) { clearTimeout(p11DeskConsoleMsgTimer); p11DeskConsoleMsgTimer = null; } }
637
+ function p12clearConsoleMsg() { QH('p12TermConsoleMsg', ''); QV('p12TermConsoleMsg', false); if (p12TermConsoleMsgTimer) { clearTimeout(p12TermConsoleMsgTimer); p12TermConsoleMsgTimer = null; } }
638
+ function p13clearConsoleMsg() { QH('p13FilesConsoleMsg', ''); QV('p13FilesConsoleMsg', false); if (p13FilesConsoleMsgTimer) { clearTimeout(p13FilesConsoleMsgTimer); p13FilesConsoleMsgTimer = null; } }
639
+
640
+ var webRtcDesktop = null;
641
+ function webRtcDesktopReset() {
642
+ if (webRtcDesktop == null) return;
643
+ if (webRtcDesktop.softdesktop != null) { webRtcDesktop.softdesktop.Stop(); webRtcDesktop.softdesktop = null; }
644
+ if (webRtcDesktop.webchannel != null) { try { webRtcDesktop.webchannel.close(); } catch (e) { } webRtcDesktop.webchannel = null; }
645
+ if (webRtcDesktop.webrtc != null) { try { webRtcDesktop.webrtc.close(); } catch (e) { } webRtcDesktop.webrtc = null; }
646
+ webRtcDesktop = null;
647
+ // Switch back to hardware KVM
648
+ if (desktop && desktop.m) {
649
+ desktop.m.hold(false);
650
+ Q('deskstatus').textContent = StatusStrs[desktop.State];
651
+ }
652
+ // ###BEGIN###{DesktopInbandFiles}
653
+ /*
654
+ p24files = null;
655
+ p24downloadFileCancel() // If any downloads are in process, cancel them.
656
+ p24uploadFileCancel(); // If any uploads are in process, cancel them.
657
+ QV('go24', false); // Files
658
+ if (currentView == 24) { go(14); }
659
+ */
660
+ // ###END###{DesktopInbandFiles}
661
+ }
662
+
663
+ function onDesktopStateChange(xdesktop, state) {
664
+ var xstate = state;
665
+ if ((xstate == 3) && (xdesktop.contype == 2)) { xstate++; }
666
+ var str = StatusStrs[xstate];
667
+ if ((desktop != null) && (desktop.webRtcActive == true)) { str += ", WebRTC"; }
668
+ //if (desktop.m.stopInput == true) { str += ', Loopback'; }
669
+ QH('deskstatus', str);
670
+ switch (state) {
671
+ case 0:
672
+ // Stop recording
673
+ if (desktop.m.recordedData != null) { deskRecordSession(); }
674
+
675
+ // Disconnect and clean up the remote desktop
676
+ desktop.Stop();
677
+ desktop = null;
678
+ QV('DeskFocus', false);
679
+ QV('termdisplays', false);
680
+ QV('deskRecordIcon', false);
681
+ if (fullscreen == true) { deskToggleFull(); }
682
+ webRtcDesktopReset();
683
+ deskPreferedStickyDisplay = 0;
684
+ break;
685
+ case 2:
686
+ break;
687
+ case 3:
688
+ if (desktop && (desktop.serverIsRecording == true)) { QV('deskRecordIcon', true); }
689
+ desktop.startTime = new Date();
690
+ if (updateSessionTimer == null) { updateSessionTimer = setInterval(updateSessionTime, 1000); }
691
+ break;
692
+ default:
693
+ //console.log('Unknown onDesktopStateChange state', state);
694
+ break;
695
+ }
696
+ updateDesktopButtons();
697
+ deskAdjust();
698
+ setTimeout(deskAdjust, 50);
699
+ updateMetadata(desktop, 'deskmetadata');
700
+ }
701
+
702
+ function updateSessionTime() {
703
+ // Desktop
704
+ var latencyStr = '', seconds = 0;
705
+ if (desktop && desktop.startTime) {
706
+ if (desktop.latency && (desktop.latency.current >= 0)) { latencyStr = format('{0} ms, ', desktop.latency.current); }
707
+ seconds = Math.floor((new Date() - desktop.startTime) / 1000);
708
+ QH('DeskTimer', latencyStr + zeroPad(Math.floor(seconds / 3600), 2) + ':' + zeroPad((Math.floor(seconds / 60) % 60), 2) + ':' + zeroPad((seconds % 60), 2));
709
+ } else {
710
+ QH('DeskTimer', '');
711
+ }
712
+
713
+ if (desktop == null) { clearInterval(updateSessionTimer); updateSessionTimer = null; }
714
+ }
715
+
716
+ function showDesktopSettings() {
717
+ if (xxdialogMode) return;
718
+ applyDesktopSettings();
719
+ updateDesktopButtons();
720
+ setDialogMode(7, "Remote Desktop Settings", 3, showDesktopSettingsChanged);
721
+ }
722
+
723
+ function showDesktopSettingsChanged() {
724
+ desktopsettings.encoding = d7desktopmode.value;
725
+ desktopsettings.showfocus = d7showfocus.checked;
726
+ desktopsettings.showmouse = d7showcursor.checked;
727
+ desktopsettings.quality = d7bitmapquality.value;
728
+ desktopsettings.scaling = d7bitmapscaling.value;
729
+ desktopsettings.framerate = d7framelimiter.value;
730
+ desktopsettings.localkeymap = d7localKeyMap.checked;
731
+ localStorage.setItem('desktopsettings', JSON.stringify(desktopsettings));
732
+ applyDesktopSettings();
733
+ if (desktop) {
734
+ if (desktop.contype == 1) {
735
+ if (desktop.State != 0) {
736
+ desktop.m.SendCompressionLevel(1, desktopsettings.quality, desktopsettings.scaling, desktopsettings.framerate);
737
+ }
738
+ }
739
+ if (desktop.contype == 2) {
740
+ if (desktop.State != 0) { desktop.Stop(); setTimeout(function () { connectDesktop(null, 2); }, 50); }
741
+ }
742
+ }
743
+ }
744
+
745
+ function applyDesktopSettings() {
746
+ var r = '', ops = [60, 50, 40, 30, 20, 10, 5, 1];
747
+ for (var i in ops) { r += '<option value=' + ops[i] + '>' + ops[i] + '%</option>'; }
748
+ QH('d7bitmapquality', r);
749
+ d7desktopmode.value = desktopsettings.encoding;
750
+ d7showfocus.checked = desktopsettings.showfocus;
751
+ d7showcursor.checked = desktopsettings.showmouse;
752
+ d7bitmapquality.value = 40; // Default value
753
+ if (ops.indexOf(parseInt(desktopsettings.quality)) >= 0) { d7bitmapquality.value = desktopsettings.quality; }
754
+ d7bitmapscaling.value = desktopsettings.scaling;
755
+ if (desktopsettings.framerate) { d7framelimiter.value = desktopsettings.framerate; } else { d7framelimiter.value = 100; }
756
+ if (desktopsettings.localkeymap) { d7localKeyMap.checked = desktopsettings.localkeymap; }
757
+ }
758
+
759
+ // Enter browser fullscreen
760
+ function enterBrowserFullscreen(elem) {
761
+ if (elem.requestFullscreen) { elem.requestFullscreen(); }
762
+ else if (elem.msRequestFullscreen) { elem.msRequestFullscreen(); }
763
+ else if (elem.mozRequestFullScreen) { elem.mozRequestFullScreen(); }
764
+ else if (elem.webkitRequestFullscreen) { elem.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); }
765
+ }
766
+
767
+ // Exit browser fullscreen
768
+ function exitBrowserFullscreen() {
769
+ if (document.exitFullscreen) { document.exitFullscreen(); }
770
+ else if (document.msExitFullscreen) { document.msExitFullscreen(); }
771
+ else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); }
772
+ else if (document.webkitExitFullscreen) { document.webkitExitFullscreen(); }
773
+ }
774
+
775
+ // Return true if the browser is fullscreen. This is a delayed method that will return true/false late. Not very useful.
776
+ function isBrowserFullscreen() {
777
+ if (!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) { return false; } else { return true; }
778
+ }
779
+
780
+ var fullscreen = false;
781
+ var browserfullscreen = false;
782
+ function deskToggleFull(e) {
783
+ var xtermActive = !((urlargs.xterm === 0) || ((terminal != null) && (xterm == null)));
784
+ fullscreen = !fullscreen;
785
+ if (fullscreen) {
786
+ QC('body').add('fulldesk');
787
+ QS('deskarea3x')['height'] = '100%';
788
+ QS('deskarea3x')['max-height'] = '100%';
789
+ if (xtermActive) {
790
+ // XTerm terminal
791
+ QS('termTable')['position'] = 'absolute';
792
+ QS('termTable')['top'] = QS('termTable')['bottom'] = QS('termTable')['left'] = QS('termTable')['right'] = '0';
793
+ } else {
794
+ // Legacy terminal
795
+ QS('termTable')['height'] = '100%';
796
+ QS('termTable')['max-height'] = '100%';
797
+ }
798
+
799
+ // If shift is pressed, enter browser full screen.
800
+ if (e.shiftKey == true) {
801
+ enterBrowserFullscreen(Q('container'));
802
+ browserfullscreen = true;
803
+ }
804
+ } else {
805
+ QC('body').remove('fulldesk');
806
+ var hide = urlargs.hide;
807
+ if (footerBar == false) { hide |= 4; }
808
+ var xh = (((hide & 1) ? 0 : 66) + ((hide & 2) ? 0 : 24) + ((hide & 4) ? 0 : 45) + ((hide & 8) ? 0 : 60)); // 0 to 195
809
+ QS('deskarea3x')['height'] = 'calc(100vh - ' + (75 + xh) + 'px)';
810
+ QS('deskarea3x')['max-height'] = 'calc(100vh - ' + (75 + xh) + 'px)';
811
+ if (xtermActive) {
812
+ // XTerm terminal
813
+ QS('termTable')['position'] = null;
814
+ QS('termTable')['top'] = QS('termTable')['bottom'] = QS('termTable')['left'] = QS('termTable')['right'] = null;
815
+ } else {
816
+ // Legacy terminal
817
+ QS('termTable')['height'] = 'calc(100vh - ' + (75 + xh) + 'px)';
818
+ QS('termTable')['max-height'] = 'calc(100vh - ' + (75 + xh) + 'px)';
819
+ }
820
+ if (browserfullscreen == true) { exitBrowserFullscreen(); browserfullscreen = false; }
821
+ }
822
+ deskAdjust();
823
+ updateDesktopButtons();
824
+ adjustPanels();
825
+ //setTimeout(adjustPanels, 10);
826
+ //setTimeout(function() { xtermfit.fit(); }, 10);
827
+ if (xterm != null) { if (xxcurrentView == 12) { xtermfit.fit(); xterm.focus(); } }
828
+ }
829
+
830
+ function mdeskAdjust(mod, sw, sh, cv) {
831
+ if (!mod || !sw || !sh || !cv) return;
832
+
833
+ // Check if we are in single desktop mode
834
+ if (cv.id == 'Desk') { deskAdjust(); return; }
835
+
836
+ // Figure out and adjust the size to fill the width of the div
837
+ var vsize = [{ x: 180, y: 101 }, { x: 302, y: 169 }, { x: 454, y: 255 }][Q('sizeselect').selectedIndex];
838
+ var realw = vsize.x + 2, tw = Q('xdevices').clientWidth - 30, xw = Math.floor(tw / realw);
839
+ xw = realw + Math.floor((tw - (xw * realw)) / xw);
840
+ vsize.y = vsize.y * (xw / vsize.x);
841
+ vsize.x = xw;
842
+ var mh = vsize.y, mw = vsize.x;
843
+ if (mod.State != 0) { mh = vsize.y; mw = (sw / sh) * vsize.y; }
844
+ QS(cv.id)['max-height'] = mh + 'px';
845
+ QS(cv.id)['max-width'] = mw + 'px';
846
+ QS(cv.id)['margin-top'] = '0';
847
+ QS(cv.id)['margin-bottom'] = '0';
848
+ }
849
+
850
+ // Remote desktop special key combos for Windows
851
+ function deskSendKeys() {
852
+ if (xxdialogMode || desktop == null || desktop.State != 3) return;
853
+ var ks = Q('deskkeys').value;
854
+ if (ks == 0) { // WIN+Down arrow
855
+ if (desktop.contype == 2) {
856
+ desktop.m.sendkey([[0xffe7, 1], [0xff54, 1], [0xff54, 0], [0xffe7, 0]]); // Intel AMT: Meta-left down, Down arrow press, Down arrow release, Meta-left release
857
+ } else {
858
+ desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.DOWN, 40], [desktop.m.KeyAction.UP, 40], [desktop.m.KeyAction.EXUP, 0x5B]]); // Agent: L-Winkey press, Down arrow press, Down arrow release, L-Winkey release
859
+ }
860
+ } else if (ks == 1) { // WIN+Up arrow
861
+ if (desktop.contype == 2) {
862
+ desktop.m.sendkey([[0xffe7, 1], [0xff52, 1], [0xff52, 0], [0xffe7, 0]]); // Intel AMT: Meta-left down, Up arrow press, Up arrow release, Meta-left release
863
+ } else {
864
+ desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.DOWN, 38], [desktop.m.KeyAction.UP, 38], [desktop.m.KeyAction.EXUP, 0x5B]]); // MeshAgent: L-Winkey press, Up arrow press, Up arrow release, L-Winkey release
865
+ }
866
+ } else if (ks == 2) { // WIN+L arrow
867
+ if (desktop.contype == 2) {
868
+ desktop.m.sendkey([[0xffe7, 1], [0x6c, 1], [0x6c, 0], [0xffe7, 0]]); // Intel AMT: Meta-left down, 'l' press, 'l' release, Meta-left release
869
+ } else {
870
+ desktop.sendCtrlMsg('{"action":"lock"}');
871
+ //desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN,0x5B],[desktop.m.KeyAction.DOWN,76],[desktop.m.KeyAction.UP,76],[desktop.m.KeyAction.EXUP,0x5B]]); // MeshAgent: L-Winkey press, 'L' press, 'L' release, L-Winkey release
872
+ //desktop.m.SendKeyMsgKC(desktop.m.KeyAction.EXDOWN, 0x5B);
873
+ //desktop.m.SendKeyMsgKC(desktop.m.KeyAction.DOWN, 76);
874
+ //desktop.m.SendKeyMsgKC(desktop.m.KeyAction.UP, 76);
875
+ //desktop.m.SendKeyMsgKC(desktop.m.KeyAction.EXUP, 0x5B);
876
+ }
877
+ } else if (ks == 3) { // WIN+M arrow
878
+ if (desktop.contype == 2) {
879
+ desktop.m.sendkey([[0xffe7, 1], [0x6d, 1], [0x6d, 0], [0xffe7, 0]]); // Intel AMT: Meta-left down, 'm' press, 'm' release, Meta-left release
880
+ } else {
881
+ desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.DOWN, 77], [desktop.m.KeyAction.UP, 77], [desktop.m.KeyAction.EXUP, 0x5B]]); // MeshAgent: L-Winkey press, 'M' press, 'M' release, L-Winkey release
882
+ }
883
+ } else if (ks == 4) { // Shift+WIN+M arrow
884
+ if (desktop.contype == 2) {
885
+ desktop.m.sendkey([[0xffe1, 1], [0xffe7, 1], [0x6d, 1], [0x6d, 0], [0xffe7, 0], [0xffe1, 0]]); // Intel AMT: Shift-left down, Meta-left down, 'm' press, 'm' release, Meta-left release, Shift-left release
886
+ } else {
887
+ desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.DOWN, 16], [desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.DOWN, 77], [desktop.m.KeyAction.UP, 77], [desktop.m.KeyAction.EXUP, 0x5B], [desktop.m.KeyAction.UP, 16]]); // MeshAgent: L-shift press, L-Winkey press, 'M' press, 'M' release, L-Winkey release, L-shift release
888
+ }
889
+ } else if (ks == 5) { // WIN
890
+ if (desktop.contype == 2) {
891
+ desktop.m.sendkey([[0xffe7, 1], [0xffe7, 0]]); // Intel AMT: Meta-left down, Meta-left release
892
+ } else {
893
+ desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.EXUP, 0x5B]]); // MeshAgent: L-Winkey press, L-Winkey release
894
+ }
895
+ } else if (ks == 6) { // WIN+R
896
+ if (desktop.contype == 2) {
897
+ desktop.m.sendkey([[0xffe7, 1], [0x72, 1], [0x72, 0], [0xffe7, 0]]); // Intel AMT: Meta-left down, 'r' press, 'r' release, Meta-left release
898
+ } else {
899
+ desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.DOWN, 82], [desktop.m.KeyAction.UP, 82], [desktop.m.KeyAction.EXUP, 0x5B]]); // MeshAgent: L-Winkey press, 'R' press, 'R' release, L-Winkey release
900
+ }
901
+ } else if (ks == 7) { // ALT-F4
902
+ if (desktop.contype == 2) {
903
+ desktop.m.sendkey([[0xffe9, 1], [0xffc1, 1], [0xffc1, 0], [0xffe9, 0]]); // Intel AMT: Alt down, 'F4' press, 'F4' release, Alt release
904
+ } else {
905
+ desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 18], [desktop.m.KeyAction.DOWN, 115], [desktop.m.KeyAction.UP, 115], [desktop.m.KeyAction.EXUP, 18]]); // MeshAgent: Alt press, 'F4' press, 'F4' release, Alt release
906
+ }
907
+ } else if (ks == 8) { // CTRL-W
908
+ if (desktop.contype == 2) {
909
+ desktop.m.sendkey([[0xffe3, 1], [0x77, 1], [0x77, 0], [0xffe3, 0]]); // Intel AMT: Ctrl down, 'w' press, 'w' release, Ctrl release
910
+ } else {
911
+ desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 17], [desktop.m.KeyAction.DOWN, 87], [desktop.m.KeyAction.UP, 87], [desktop.m.KeyAction.EXUP, 17]]); // MeshAgent: Ctrl press, 'W' press, 'W' release, Ctrl release
912
+ }
913
+ } else if (ks == 9) { // ALT-TAB
914
+ if (desktop.contype == 2) {
915
+ desktop.m.sendkey([[0xffe9, 1], [0xff09, 1], [0xff09, 0], [0xffe9, 0]]); // Intel AMT: Alt down, 'TAB' press, 'TAB' release, Alt release
916
+ } else {
917
+ desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 18], [desktop.m.KeyAction.DOWN, 9], [desktop.m.KeyAction.UP, 9], [desktop.m.KeyAction.EXUP, 18]]); // MeshAgent: Alt press, 'TAB' press, 'TAB' release, Alt release
918
+ }
919
+ } else if (ks == 10) { // CTRL-ALT-DEL
920
+ desktop.m.sendcad();
921
+ } else if (ks == 11) { // WIN-LEFT
922
+ if (desktop.contype == 2) {
923
+ desktop.m.sendkey([[0xffe7, 1], [0xff51, 1], [0xff51, 0], [0xffe7, 0]]); // Intel AMT: Meta-left down, Left arrow press, Left arrow release, Meta-left release
924
+ } else {
925
+ desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.DOWN, 37], [desktop.m.KeyAction.UP, 37], [desktop.m.KeyAction.EXUP, 0x5B]]);
926
+ }
927
+ } else if (ks == 12) { // WIN-RIGHT
928
+ if (desktop.contype == 2) {
929
+ desktop.m.sendkey([[0xffe7, 1], [0xff53, 1], [0xff53, 0], [0xffe7, 0]]); // Intel AMT: Meta-left down, Right arrow press, Right arrow release, Meta-left release
930
+ } else {
931
+ desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.DOWN, 39], [desktop.m.KeyAction.UP, 39], [desktop.m.KeyAction.EXUP, 0x5B]]);
932
+ }
933
+ }
934
+ }
935
+
936
+ function ondockeypress(e) {
937
+ setSessionActivity();
938
+ if (!xxdialogMode && desktop && isInputAllowed()) {
939
+ // Check what keys we are allows to send
940
+ /*
941
+ if (currentNode != null) {
942
+ var meshrights = GetNodeRights(currentNode);
943
+ var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
944
+ if (inputAllowed == false) return false;
945
+ var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
946
+ if (limitedInputAllowed == true) { if ((e.altKey == true) || (e.ctrlKey == true) || ((e.keyCode < 32) && (e.keyCode != 8) && (e.keyCode != 13)) || (e.keyCode > 90)) return false; }
947
+ }
948
+ */
949
+ return desktop.m.handleKeys(e);
950
+ }
951
+ }
952
+
953
+ function ondockeydown(e) {
954
+ setSessionActivity();
955
+ if (!xxdialogMode && desktop && isInputAllowed()) {
956
+ // Check what keys we are allows to send
957
+ /*
958
+ if (currentNode != null) {
959
+ var meshrights = GetNodeRights(currentNode);
960
+ var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
961
+ if (inputAllowed == false) return false;
962
+ var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
963
+ if (limitedInputAllowed == true) { if ((e.altKey == true) || (e.ctrlKey == true) || ((e.keyCode < 32) && (e.keyCode != 8) && (e.keyCode != 13)) || (e.keyCode > 90)) return false; }
964
+ }
965
+ */
966
+ return desktop.m.handleKeyDown(e);
967
+ }
968
+ }
969
+
970
+ function ondockeyup(e) {
971
+ setSessionActivity();
972
+ if (!xxdialogMode && desktop && isInputAllowed()) {
973
+ // Check what keys we are allows to send
974
+ /*
975
+ if (currentNode != null) {
976
+ var meshrights = GetNodeRights(currentNode);
977
+ var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
978
+ if (inputAllowed == false) return false;
979
+ var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
980
+ if (limitedInputAllowed == true) { if ((e.altKey == true) || (e.ctrlKey == true) || ((e.keyCode < 32) && (e.keyCode != 8) && (e.keyCode != 13)) || (e.keyCode > 90)) return false; }
981
+ }
982
+ */
983
+ return desktop.m.handleKeyUp(e);
984
+ }
985
+ }
986
+
987
+ // Remote desktop typing
988
+ function showDeskType() {
989
+ if (xxdialogMode || desktop == null || desktop.State != 3) return;
990
+ Q('DeskType').blur();
991
+ var x = '<div>' + "Enter text and click OK to remotely type it using a US english keyboard. Make sure to place the remote cursor at the correct position before proceeding." + '<div>';
992
+ x += '<textarea id=d2typeText style="margin-top:5px;width:100%;height:184px;resize:none" maxlength=2000></textarea>';
993
+ setDialogMode(2, "Remote Keyboard Entry", 3, showDeskTypeEx, x);
994
+ Q('d2typeText').focus();
995
+ }
996
+
997
+ var AmtDeskTypeTimer = null;
998
+ var AmtDeskTypeContent = null;
999
+ var DeskTypeTranslate = { 39: 222, 42: 106, 43: 107, 44: 188, 45: 189, 46: 190, 47: 191, 59: 186, 61: 187, 91: 219, 92: 220, 93: 221, 96: 192, 191: 111 };
1000
+ var DeskTypeShiftTranslate = { 33: 49, 34: 222, 35: 51, 36: 52, 37: 53, 38: 55, 40: 57, 41: 48, 58: 186, 60: 188, 62: 190, 63: 191, 64: 50, 94: 54, 95: 189, 106: 56, 107: 187, 123: 219, 124: 220, 125: 221, 126: 192 };
1001
+ function showDeskTypeEx() {
1002
+ var txt = Q('d2typeText').value, ltxt = Q('d2typeText').value.toUpperCase(), x = [], shift = false;
1003
+ if (desktop.contype == 2) {
1004
+ // Intel AMT
1005
+ for (var i in txt) { var a = txt.charCodeAt(i); x.push([a, 1], [a, 0]); }
1006
+ AmtDeskTypeContent = x;
1007
+ AmtDeskTypeTimer = setInterval(function () {
1008
+ var key = AmtDeskTypeContent.shift();
1009
+ if (desktop) { desktop.m.sendkey(key[0], key[1]); }
1010
+ if ((desktop == null) || (AmtDeskTypeContent.length == 0)) { clearInterval(AmtDeskTypeTimer); AmtDeskTypeContent = null; }
1011
+ }, 10);
1012
+ } else {
1013
+ // MeshAgent
1014
+ for (var i in txt) {
1015
+ var a = txt.charCodeAt(i), b = ltxt.charCodeAt(i);
1016
+ if (((a >= 65) && (a <= 90)) || ((a >= 97) && (a <= 122))) {
1017
+ if ((a == b) && (shift == false)) { x.push([desktop.m.KeyAction.DOWN, 16]); shift = true; } // LShift down
1018
+ if ((a != b) && (shift == true)) { x.push([desktop.m.KeyAction.UP, 16]); shift = false; } // LShift up
1019
+ } else if ((a >= 48) && (a <= 57)) {
1020
+ if (shift == true) { x.push([desktop.m.KeyAction.UP, 16]); shift = false; } // Shift up
1021
+ } else if (DeskTypeTranslate[a]) {
1022
+ if (shift == true) { x.push([desktop.m.KeyAction.UP, 16]); shift = false; } // Shift up
1023
+ b = DeskTypeTranslate[a];
1024
+ } else if (DeskTypeShiftTranslate[a]) {
1025
+ if (shift == false) { x.push([desktop.m.KeyAction.DOWN, 16]); shift = true; } // LShift down
1026
+ b = DeskTypeShiftTranslate[a];
1027
+ }
1028
+ x.push([desktop.m.KeyAction.DOWN, b], [desktop.m.KeyAction.UP, b]);
1029
+ }
1030
+ if (shift == true) { x.push([desktop.m.KeyAction.UP, 16]); shift = false; } // Shift up
1031
+ desktop.m.SendKeyMsgKC(x);
1032
+ }
1033
+ }
1034
+
1035
+ /*
1036
+ // Show clipboard dialog
1037
+ function showDeskClip() {
1038
+ if (xxdialogMode || desktop == null || desktop.State != 3) return;
1039
+ Q('DeskClip').blur();
1040
+ var x = '';
1041
+ x += '<input id=dlgClipGet type=button value="Get Clipboard" style=width:120px onclick=showDeskClipGet()>';
1042
+ x += '<input id=dlgClipSet type=button value="Set Clipboard" style=width:120px onclick=showDeskClipSet()>';
1043
+ x += '<div id=dlgClipStatus style="display:inline-block;margin-left:8px" ></div>';
1044
+ x += '<textarea id=d2clipText style="width:100%;height:184px;resize:none" maxlength=65535></textarea>';
1045
+ x += '<input type=button value="Close" style=width:80px;float:right onclick=dialogclose(0)><div style=height:26px;margin-top:3px><span id=linuxClipWarn style=display:none>' + "Remote clipboard is valid for 60 seconds." + '</span> </div><div></div>';
1046
+ setDialogMode(2, "Remote Clipboard", 8, null, x, 'clipboard');
1047
+ Q('d2clipText').focus();
1048
+ }
1049
+
1050
+ function showDeskClipGet() {
1051
+ if (desktop == null || desktop.State != 3) return;
1052
+ meshserver.send({ action: 'msg', type: 'getclip', nodeid: currentNode._id });
1053
+ }
1054
+
1055
+ function showDeskClipSet() {
1056
+ if (desktop == null || desktop.State != 3) return;
1057
+ meshserver.send({ action: 'msg', type: 'setclip', nodeid: currentNode._id, data: Q('d2clipText').value });
1058
+ //QV('linuxClipWarn', currentNode && currentNode.agent && (currentNode.agent.id > 4) && (currentNode.agent.id != 21) && (currentNode.agent.id != 22));
1059
+ }
1060
+ */
1061
+
1062
+ // Send CTRL-ALT-DEL
1063
+ function sendCAD() {
1064
+ if (xxdialogMode || desktop == null || desktop.State != 3) return;
1065
+ desktop.m.sendcad();
1066
+ }
1067
+
1068
+ /*
1069
+ // Show process dialogs
1070
+ function toggleDeskTools() {
1071
+ if (xxdialogMode) return;
1072
+ if (QS('DeskTools').display == 'none') {
1073
+ QV('DeskTools', true);
1074
+ Q('DeskTools').nodeid = currentNode._id;
1075
+ QH('DeskToolsProcesses', '');
1076
+ QH('DeskToolsServices', '');
1077
+ QV('deskToolsTopTabService', false);
1078
+ changeDeskToolTab(0)
1079
+ refreshDeskTools(0);
1080
+ refreshDeskTools(1);
1081
+ } else {
1082
+ QV('DeskTools', false);
1083
+ }
1084
+ }
1085
+
1086
+ var deskToolTabSelection = 0;
1087
+ function changeDeskToolTab(tabnum) {
1088
+ deskToolTabSelection = tabnum;
1089
+ QV('DeskToolsProcessTab', tabnum == 0);
1090
+ QV('DeskToolsServiceTab', tabnum == 1);
1091
+ QS('deskToolsTopTabProcess')['bottom'] = (tabnum == 0) ? '0px' : '3px';
1092
+ QS('deskToolsTopTabService')['bottom'] = (tabnum == 1) ? '0px' : '3px';
1093
+ QS('deskToolsTopTabProcess')['color'] = (tabnum == 0) ? 'black' : 'gray';
1094
+ QS('deskToolsTopTabService')['color'] = (tabnum == 1) ? 'black' : 'gray';
1095
+ }
1096
+
1097
+ // Refresh all of the desktop tool panels
1098
+ function refreshDeskTools(x) {
1099
+ var sel = (x == null) ? deskToolTabSelection : x;
1100
+ QV('DeskToolsRefreshButton', false);
1101
+ setTimeout(refreshDeskToolsEx, 500);
1102
+ if (sel == 0) meshserver.send({ action: 'msg', type: 'ps', nodeid: currentNode._id });
1103
+ if (sel == 1) meshserver.send({ action: 'msg', type: 'services', nodeid: currentNode._id });
1104
+ }
1105
+ function refreshDeskToolsEx() { QV('DeskToolsRefreshButton', true); }
1106
+ var deskTools = { sort: 1, ssort: 1, msg: null, smsg: null };
1107
+ function sortProcess(sort) { deskTools.sort = sort; showDeskToolsProcesses(deskTools.msg); }
1108
+ function sortService(sort) { deskTools.ssort = sort; showDeskToolsServices(deskTools.smsg); }
1109
+ function sortProcessPid(a, b) { if (a.p > b.p) return 1; if (a.p < b.p) return (-1); return sortProcessName(a, b); }
1110
+ function sortProcessName(a, b) { if (a.d > b.d) return 1; if (a.d < b.d) return (-1); return 0; }
1111
+ function showDeskToolsProcesses(message) {
1112
+ deskTools.msg = message;
1113
+ if (message == null) { QH('DeskToolsProcesses', ''); return; }
1114
+ if (Q('DeskTools').nodeid != message.nodeid) return;
1115
+ var p = [], processes = null;
1116
+ try { processes = JSON.parse(message.value); } catch (e) { }
1117
+ if (processes != null) {
1118
+ for (var pid in processes) { p.push({ p: parseInt(pid), c: processes[pid].cmd, d: processes[pid].cmd.toLowerCase(), u: processes[pid].user }); }
1119
+ if (deskTools.sort == 0) { p.sort(sortProcessPid); } else if (deskTools.sort == 1) { p.sort(sortProcessName); }
1120
+ var x = '';
1121
+ for (var i in p) {
1122
+ if (p[i].p != 0) {
1123
+ var c = p[i].c;
1124
+ if (c.length > 30) { c = '<span title="' + EscapeHtml(c) + '">' + EscapeHtml(c.substring(0, 30)) + '...</span>' } else { c = EscapeHtml(c); }
1125
+ x += '<div class=deskToolsBar><div style=width:50px;float:left;text-align:right;padding-right:5px>' + EscapeHtml(p[i].p) + '</div><a href=# style=float:right;padding-right:5px;cursor:pointer title="' + "Stop process" + '" onclick=\'return stopProcess(' + EscapeHtml(p[i].p) + ',"' + EscapeHtml(p[i].c) + '")\'><img width=10 height=10 src="images/trash.png"></a><div style=float:right;padding-right:5px>' + (p[i].u ? EscapeHtml(p[i].u) : '') + '</div><div>' + c + '</div></div>';
1126
+ }
1127
+ }
1128
+ QH('DeskToolsProcesses', x);
1129
+ }
1130
+ }
1131
+ function showDeskToolsServices(message) {
1132
+ deskTools.smsg = message;
1133
+ if (message == null) { QH('DeskToolsProcesses', ''); return; }
1134
+ if (Q('DeskTools').nodeid != message.nodeid) return;
1135
+ QV('deskToolsTopTabService', true);
1136
+ var s = [], services = null;
1137
+ try { services = JSON.parse(message.value); } catch (e) { }
1138
+ deskTools.services = services;
1139
+ if (services != null) {
1140
+ for (var i in services) {
1141
+ if (services[i].status) {
1142
+ // Windows
1143
+ s.push({ p: capitalizeFirstLetter(services[i].status.state.toLowerCase()), d: services[i].displayName, i: i });
1144
+ } else if (services[i].serviceType) {
1145
+ // Linux (TODO: This the service status is not displayed, not sure start/stop/restart will work).
1146
+ s.push({ p: services[i].serviceType, d: services[i].name, i: i });
1147
+ }
1148
+ }
1149
+ if (deskTools.ssort == 0) { s.sort(sortProcessPid); } else if (deskTools.ssort == 1) { s.sort(sortProcessName); }
1150
+ var x = '';
1151
+ for (var i in s) {
1152
+ if (s[i].p != 0) {
1153
+ var c = s[i].d;
1154
+ if (c.length > 30) { c = '<span title="' + c + '">' + c.substring(0, 30) + '...</span>' } else { c = EscapeHtml(c); }
1155
+ x += '<div onclick=showServiceDetailsDialog(' + s[i].i + ') class=deskToolsBar><div style=width:70px;float:left;padding-right:5px>' + EscapeHtml(s[i].p) + '</div><div>' + c + '</div></div>';
1156
+ }
1157
+ }
1158
+ QH('DeskToolsServices', x);
1159
+ }
1160
+ }
1161
+
1162
+ function showServiceDetailsDialog(index) {
1163
+ if (xxdialogMode) return;
1164
+ var service = deskTools.services[index];
1165
+ if (service != null) {
1166
+ var x = '';
1167
+ if (service.name) { x += addHtmlValue("Name", service.name); }
1168
+ if (service.displayName) { x += addHtmlValue("Display name", service.displayName); }
1169
+ if (service.status) {
1170
+ if (service.status.state) { x += addHtmlValue("State", capitalizeFirstLetter(service.status.state.toLowerCase())); }
1171
+ if (service.status.pid) { x += addHtmlValue("PID", service.status.pid); }
1172
+ var serviceTypes = [];
1173
+ if (service.status.isFileSystemDriver === true) { serviceTypes.push("FileSystemDriver"); }
1174
+ if (service.status.isInteractive === true) { serviceTypes.push("Interactive"); }
1175
+ if (service.status.isKernelDriver === true) { serviceTypes.push("KernelDriver"); }
1176
+ if (service.status.isOwnProcess === true) { serviceTypes.push("OwnProcess"); }
1177
+ if (service.status.isSharedProcess === true) { serviceTypes.push("SharedProcess"); }
1178
+ if (serviceTypes.length > 0) { x += addHtmlValue("Type", serviceTypes.join(', ')); }
1179
+ }
1180
+ x += '<br/><div style=float:right;margin-bottom:12px><input type=button value="' + "Close" + '" onclick=showServiceDetailsDialogEx(0,' + index + ')></div><div style=margin-bottom:12px><input type=button value="' + "Start" + '" onclick=showServiceDetailsDialogEx(1,' + index + ')><input type=button value="' + "Stop" + '" onclick=showServiceDetailsDialogEx(2,' + index + ')><input type=button value="' + "Restart" + '" onclick=showServiceDetailsDialogEx(3,' + index + ')></div>';
1181
+ setDialogMode(2, "Service Details", 8, null, x, name);
1182
+ }
1183
+ }
1184
+
1185
+ function showServiceDetailsDialogEx(action, index) {
1186
+ setDialogMode(0);
1187
+ if (action == 0) return;
1188
+ var service = deskTools.services[index];
1189
+ if (service != null) {
1190
+ if (action == 1) { meshserver.send({ action: 'msg', type: 'serviceStart', nodeid: currentNode._id, serviceName: service.name }); }
1191
+ if (action == 2) { meshserver.send({ action: 'msg', type: 'serviceStop', nodeid: currentNode._id, serviceName: service.name }); }
1192
+ if (action == 3) { meshserver.send({ action: 'msg', type: 'serviceRestart', nodeid: currentNode._id, serviceName: service.name }); }
1193
+ setTimeout(function () { refreshDeskTools(1) }, 1000);
1194
+ }
1195
+ }
1196
+ */
1197
+
1198
+ // Toggle mouse and keyboard input
1199
+ function toggleKvmControl() { QS('DeskControlSpan').color = Q('DeskControl').checked ? null : 'red'; }
1200
+
1201
+ // Save the desktop image to file
1202
+ function deskSaveImage() {
1203
+ if (xxdialogMode || desktop == null || desktop.State != 3) return;
1204
+ var d = new Date(), n = "Desktop" + '-' + d.getFullYear() + '-' + ('0' + (d.getMonth() + 1)).slice(-2) + '-' + ('0' + d.getDate()).slice(-2) + '-' + ('0' + d.getHours()).slice(-2) + '-' + ('0' + d.getMinutes()).slice(-2);
1205
+ Q('Desk')['toBlob'](function (blob) { saveAs(blob, n + '.png'); });
1206
+ }
1207
+
1208
+ function deskDisplayInfo(sender, displays, selDisplay) {
1209
+ var displayCount = 0, displaySelector = '';
1210
+ for (var i in displays) {
1211
+ displayCount++;
1212
+ displaySelector += '<option' + ((selDisplay == i) ? ' selected' : '') + ' value=' + i + '>' + displays[i] + '</option>';
1213
+ if ((deskPreferedStickyDisplay == i) && (selDisplay != deskPreferedStickyDisplay)) { desktop.m.SetDisplay(i); }
1214
+ deskPreferedStickyDisplay = -1;
1215
+ }
1216
+ QH('termdisplays', displaySelector);
1217
+ QV('termdisplays', displayCount > 1);
1218
+ }
1219
+
1220
+ function deskGetDisplayNumbers(e) { desktop.m.GetDisplayNumbers(); }
1221
+ var deskPreferedStickyDisplay = -1;
1222
+ function deskSetDisplay(e) { desktop.m.SetDisplay(deskPreferedStickyDisplay = parseInt(Q('termdisplays').value)); Q('termdisplays').blur(); }
1223
+
1224
+ // Double click detection. This is important for macOS.
1225
+ var dblClickDetectArgs = { t: 0, x: 0, y: 0 };
1226
+ function dblClickDetect(e) {
1227
+ if (e.buttons != 1) return;
1228
+ var t = Date.now();
1229
+ if (((t - dblClickDetectArgs.t) < 250) && (Math.abs(e.clientX - dblClickDetectArgs.x) < 2) && (Math.abs(e.clientY - dblClickDetectArgs.y) < 2)) {
1230
+ if (!xxdialogMode && desktop != null && isInputAllowed()) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousedblclick(e); desktop.m.sendKeepAlive(); } else { desktop.m.mousedblclick(e); } }
1231
+ }
1232
+ dblClickDetectArgs.t = t;
1233
+ dblClickDetectArgs.x = e.clientX;
1234
+ dblClickDetectArgs.y = e.clientY;
1235
+ }
1236
+
1237
+ function dmousedown(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && isInputAllowed()) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousedown(e); desktop.m.sendKeepAlive(); } else { desktop.m.mousedown(e); } } dblClickDetect(e); }
1238
+ function dmouseup(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && isInputAllowed()) if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mouseup(e); desktop.m.sendKeepAlive(); } else { desktop.m.mouseup(e); } }
1239
+ function dmousemove(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && isInputAllowed()) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousemove(e); desktop.m.sendKeepAlive(); } else { desktop.m.mousemove(e); } } }
1240
+ function dmousewheel(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && isInputAllowed()) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousewheel(e); desktop.m.sendKeepAlive(); } else { if (desktop.m.mousewheel) { desktop.m.mousewheel(e); } } haltEvent(e); return true; } return false; }
1241
+ function drotate(x) { if (!xxdialogMode && desktop != null) { desktop.m.setRotation(desktop.m.rotation + x); deskAdjust(); deskAdjust(); } }
1242
+
1243
+
1244
+ //
1245
+ // Terminal
1246
+ //
1247
+
1248
+ function setupTerminal() {
1249
+ // Setup the terminal
1250
+ if (terminal != null) { terminal.Stop(); terminal = null; }
1251
+ updateTerminalButtons();
1252
+
1253
+ // Terminal special keys
1254
+ var x = '';
1255
+ for (var c = 1; c < 27; c++) x += '<option value=\'' + c + '\'>' + "Ctrl" + '-' + String.fromCharCode(64 + c) + ' (' + c + ')</option>';
1256
+ QH('specialkeylist', x);
1257
+ }
1258
+
1259
+ // Show and enable the right buttons
1260
+ function updateTerminalButtons() {
1261
+ var termState = ((terminal != null) && (terminal.state != 0));
1262
+
1263
+ // Show the right buttons
1264
+ QV('disconnectbutton2span', termState == true);
1265
+ QV('connectbutton2span', termState == false);
1266
+ //QV('terminalSizeDropDown', termState == false);
1267
+
1268
+ // Enable buttons
1269
+ QE('connectbutton2', true);
1270
+
1271
+ // Key buttons
1272
+ QE('ctrlcbutton', termState);
1273
+ QE('ctrlxbutton', termState);
1274
+ QE('escbutton', termState);
1275
+ QE('bsbutton', termState);
1276
+ QE('pastebutton', termState);
1277
+ QE('specialkeylist', termState);
1278
+ QE('specialkeylistinput', termState);
1279
+
1280
+ // Terminal settings
1281
+ QV('terminalSettingsButtons', (terminal) && (terminal.contype == 2));
1282
+ if (terminal) {
1283
+ Q('id_ttypebutton').value = terminalEmulations[terminal.m.terminalEmulation];
1284
+ Q('id_tfxkeysbutton').value = fxEmulations[terminal.m.fxEmulation];
1285
+ Q('id_tcrbutton').value = (terminal.m.lineFeed == '\r\n') ? "CR+LF" : "LF";
1286
+ }
1287
+
1288
+ // Display extra buttons on legacy terminal
1289
+ var xtermActive = true;
1290
+ QV('termarea3xdiv', xtermActive);
1291
+ QV('bsbutton', !xtermActive);
1292
+ QV('pastebutton', !xtermActive);
1293
+ QV('devListToolbarViewIcons2', xtermActive);
1294
+ QE('termSizeList', terminal == null);
1295
+ }
1296
+
1297
+ // Called when the terminal state changes
1298
+ function onTerminalStateChange(xterminal, state) {
1299
+ var xstate = state;
1300
+ if ((xstate == 3) && (xterminal.contype == 2)) { xstate++; }
1301
+ var str = StatusStrs[xstate];
1302
+ if (terminal.webRtcActive == true) { str += ", WebRTC"; }
1303
+ QH('termstatus', str);
1304
+ switch (state) {
1305
+ case 0:
1306
+ // Disconnected, clear the terminal
1307
+ QH('termtitle', '');
1308
+ QV('termRecordIcon', false);
1309
+ if (xterm == null) {
1310
+ xterminal.m.TermResetScreen();
1311
+ xterminal.m.TermDraw();
1312
+ } else {
1313
+ xterm.dispose();
1314
+ xterm = xtermfit = null;
1315
+ }
1316
+ if (terminal != null) { terminal.Stop(); terminal = null; }
1317
+ break;
1318
+ case 3:
1319
+ if (xterminal && (xterminal.serverIsRecording == true)) { QV('termRecordIcon', true); }
1320
+ terminal.startTime = new Date();
1321
+ if (updateSessionTimer == null) { updateSessionTimer = setInterval(updateSessionTime, 1000); }
1322
+ if (xterm != null) { xterm.focus(); }
1323
+ break;
1324
+ default:
1325
+ //console.log('Unhandled onTerminalStateChange state', state);
1326
+ break;
1327
+ }
1328
+ updateTerminalButtons();
1329
+ }
1330
+
1331
+ function updateSessionTime() {
1332
+ // Terminal
1333
+ var latencyStr = '', seconds = 0;
1334
+ if (terminal && terminal.startTime) {
1335
+ if (terminal.latency && (terminal.latency.current >= 0)) { latencyStr = format('{0} ms, ', terminal.latency.current); }
1336
+ seconds = Math.floor((new Date() - terminal.startTime) / 1000);
1337
+ QH('TermTimer', latencyStr + zeroPad(Math.floor(seconds / 3600), 2) + ':' + zeroPad((Math.floor(seconds / 60) % 60), 2) + ':' + zeroPad((seconds % 60), 2));
1338
+ } else {
1339
+ QH('TermTimer', '');
1340
+ }
1341
+
1342
+ if (terminal == null) { clearInterval(updateSessionTimer); updateSessionTimer = null; }
1343
+ }
1344
+
1345
+ // DEBUG
1346
+ var autoConnectTerminalTimer = null;
1347
+ function autoConnectTerminal(e) { if (autoConnectTerminalTimer == null) { autoConnectTerminalTimer = setInterval(connectTerminal, 100); } else { clearInterval(autoConnectTerminalTimer); autoConnectTerminalTimer = null; } }
1348
+
1349
+ // Handles a tunnel to a remote shell
1350
+ function CreateRemoteTunnel(onTunnelUpdate, options) {
1351
+ var obj = { protocol: 1 };
1352
+ if ((options != null) && (typeof options.protocol == 'number')) { obj.protocol = options.protocol; }
1353
+ obj.onTunnelUpdate = onTunnelUpdate;
1354
+ obj.xxStateChange = function (state) { }
1355
+ obj.ProcessBinaryData = function (data) { obj.onTunnelUpdate(data); }
1356
+ obj.ProcessData = function (data) { obj.onTunnelUpdate(data); }
1357
+ obj.terminalEmulation = 1;
1358
+ obj.fxEmulation = 0;
1359
+ obj.lineFeed = '\r\n';
1360
+ return obj;
1361
+ }
1362
+
1363
+ function tunnelUpdate(data) { if (typeof data == 'string') { xterm.writeUtf8(data); } else { xterm.writeUtf8(new Uint8Array(data)); } }
1364
+
1365
+ // Send the new terminal size to the agent
1366
+ function xTermSendResize() {
1367
+ xtermResizeTimer = null;
1368
+ if ((xterm != null) && (terminal != null) && (terminal.sendCtrlMsg != null)) { terminal.sendCtrlMsg(JSON.stringify({ ctrlChannel: '102938', type: 'termsize', cols: xterm.cols, rows: xterm.rows })); }
1369
+ }
1370
+
1371
+ // Used to translate incoming agent console messages
1372
+ var agentConsoleMessages = ['', "Waiting for user to grant access...", "Denied", "Failed to start remote terminal session, {0} ({1})", "Timeout", "Received invalid network data"];
1373
+ function formatAgentConsoleMessage(msg, msgid, msgargs) {
1374
+ var r;
1375
+ if (msgargs == null) { msgargs = []; }
1376
+ while (msgargs.length < 3) { msgargs.push(''); } // We need to call the format function in a way that works with older browsers and minifier, can't use apply() or ...
1377
+ if (msgid && (msgid < agentConsoleMessages.length)) { r = EscapeHtml(format(agentConsoleMessages[msgid], (msgargs[0]), (msgargs[1]), (msgargs[2]))); } else { r = EscapeHtml(msg); }
1378
+ return r.split('\n').join('<br />') + '<br /><br />';
1379
+ }
1380
+
1381
+ function connectTerminal(e, contype, options) {
1382
+ p12clearConsoleMsg();
1383
+ if (!terminal) {
1384
+ // Terminal setup
1385
+ var termoptions = { protocol: ((options != null) && (typeof options.protocol == 'number')) ? options.protocol : 1 };
1386
+ if (options && options.requireLogin) { termoptions.requireLogin = true; }
1387
+ /*
1388
+ if ([1, 2, 3, 4, 21, 22].indexOf(currentNode.agent.id) == -1) {
1389
+ if (Q('termSizeList').value == 1) { termoptions.cols = 80; termoptions.rows = 25; termoptions.xterm = true; }
1390
+ else if (Q('termSizeList').value == 2) { termoptions.cols = 100; termoptions.rows = 30; termoptions.xterm = true; }
1391
+ else if (Q('termSizeList').value == 3) {
1392
+ // TODO: Try to improve terminal auto-size.
1393
+ termoptions.cols = Math.floor((Q('column_l').clientWidth - 60) / 10);
1394
+ termoptions.rows = Math.floor((Q('column_l').clientHeight - 120) / 20);
1395
+ termoptions.xterm = true;
1396
+ }
1397
+ }
1398
+ */
1399
+
1400
+ /*
1401
+ // If shift is pressed
1402
+ if ((e && (e.shiftKey == true))) {
1403
+ if (currentNode.agent.id > 4) {
1404
+ if (termoptions.protocol == 1) { termoptions.protocol = 7; } // Switch to user shell
1405
+ } else {
1406
+ if (termoptions.protocol == 1) { termoptions.protocol = 6; } // Switch to Powershell
1407
+ }
1408
+ }
1409
+ */
1410
+
1411
+ // Setup a mesh agent xterm terminal
1412
+ QV('termarea3xdiv', true);
1413
+
1414
+ // Setup the terminal with auto-fit
1415
+ if (xterm != null) { xterm.dispose(); }
1416
+ xtermfit = new FitAddon.FitAddon();
1417
+ xterm = new Terminal();
1418
+ if (xtermfit) { xterm.loadAddon(xtermfit); }
1419
+ xterm.open(Q('termarea3xdiv')); // termarea3x
1420
+ xterm.onData(function (data) { if (terminal != null) { terminal.sendText(data); } })
1421
+ if (xtermfit) { xtermfit.fit(); }
1422
+ xterm.onTitleChange(function (title) { QH('termtitle', ' - ' + EscapeHtml(title)); });
1423
+ xterm.onResize(function (size) {
1424
+ // Despam resize
1425
+ if (xtermResizeTimer) clearTimeout(xtermResizeTimer);
1426
+ xtermResizeTimer = setTimeout(xTermSendResize, 200);
1427
+ });
1428
+
1429
+ // Setup a terminal tunnel to the agent
1430
+ terminal = CreateAgentRedirect(null, CreateRemoteTunnel(tunnelUpdate, options), serverPublicNamePort, authCookie, null, domainUrl);
1431
+ terminal.debugmode = debugmode;
1432
+ terminal.m.debugmode = debugmode;
1433
+ terminal.options = { cols: xterm.cols, rows: xterm.rows };
1434
+ if (options && options.requireLogin) { terminal.options.requireLogin = true; }
1435
+ terminal.Start(null);
1436
+ terminal.onStateChanged = onTerminalStateChange;
1437
+ terminal.contype = 1;
1438
+ terminal.attemptWebRTC = false; // Never do WebRTC on terminal, because of a race condition we can't do it.
1439
+ terminal.onConsoleMessageChange = function (server, msg) {
1440
+ if (terminal.consoleMessage) {
1441
+ Q('p12TermConsoleMsg').innerHTML += formatAgentConsoleMessage(terminal.consoleMessage, terminal.consoleMessageId, terminal.consoleMessageArgs);
1442
+ QV('p12TermConsoleMsg', true);
1443
+ if (p12TermConsoleMsgTimer != null) { clearTimeout(p12TermConsoleMsgTimer); }
1444
+ if (terminal.consoleMessageTimeout) { p12TermConsoleMsgTimer = setTimeout(p12clearConsoleMsg, terminal.consoleMessageTimeout * 1000); }
1445
+ } else {
1446
+ p12clearConsoleMsg();
1447
+ }
1448
+ };
1449
+ } else {
1450
+ terminal.Stop();
1451
+ terminal = null;
1452
+ }
1453
+ Q('connectbutton2').blur(); // Deselect the connect button so the button does not get key presses.
1454
+ }
1455
+
1456
+ var terminalEmulations = ["UTF8 Terminal", "Extended ASCII", "Intel ASCII"];
1457
+ function termToggleType() {
1458
+ if (!terminal || xxdialogMode) return;
1459
+ terminal.m.terminalEmulation = (terminal.m.terminalEmulation + 1) % 3;
1460
+ Q('id_ttypebutton').value = terminalEmulations[terminal.m.terminalEmulation];
1461
+ Q('id_ttypebutton').blur(); // Deselect the connect button so the button does not get key presses.
1462
+ }
1463
+
1464
+ var fxEmulations = ["Intel (F10 = ESC+[OM)", "Alternate (F10 = ESC+0)", "VT100+ (F10 = ESC+[OY)"];
1465
+ function termToggleFx() {
1466
+ if (!terminal || xxdialogMode) return;
1467
+ terminal.m.fxEmulation = (terminal.m.fxEmulation + 1) % 3;
1468
+ Q('id_tfxkeysbutton').value = fxEmulations[terminal.m.fxEmulation];
1469
+ Q('id_tfxkeysbutton').blur(); // Deselect the connect button so the button does not get key presses.
1470
+ }
1471
+
1472
+ function termToggleCr() {
1473
+ if (!terminal || xxdialogMode) return;
1474
+ if (terminal.m.lineFeed == '\n') { terminal.m.lineFeed = '\r\n'; } else { terminal.m.lineFeed = '\n'; }
1475
+ Q('id_tcrbutton').value = (terminal.m.lineFeed == '\r\n') ? "CR+LF" : "LF";
1476
+ }
1477
+
1478
+ function termSendKey(key, id) {
1479
+ if (!terminal || xxdialogMode) return;
1480
+ if (xterm != null) {
1481
+ if (terminal.sendText) {
1482
+ // MeshAgent
1483
+ terminal.sendText(String.fromCharCode(key));
1484
+ } else {
1485
+ // CIRA
1486
+ terminal.send(String.fromCharCode(key));
1487
+ }
1488
+ xterm.focus();
1489
+ } else if (terminal != null) {
1490
+ terminal.m.TermSendKey(key);
1491
+ Q(id).blur(); // Deselect the connect button so the button does not get key presses.
1492
+ }
1493
+ }
1494
+
1495
+ function showTermPasteDialog() {
1496
+ if (!terminal || xxdialogMode) return;
1497
+ Q('pastebutton').blur();
1498
+ setDialogMode(2, "Paste", 3, showTermPasteDialogEx, '<textarea id=d2pasteText style="width:100%;height:184px;resize:none"></textarea>');
1499
+ Q('d2pasteText').focus();
1500
+ }
1501
+
1502
+ function showTermPasteDialogEx() {
1503
+ if (!terminal) return;
1504
+ terminal.m.TermSendKeys(Q('d2pasteText').value);
1505
+ }
1506
+
1507
+ // Send special key
1508
+ function sendSpecialKey() {
1509
+ if (xterm != null) {
1510
+ terminal.sendText(String.fromCharCode(Q('specialkeylist').value));
1511
+ xterm.focus();
1512
+ } else if (terminal != null) {
1513
+ terminal.m.TermSendKey(Q('specialkeylist').value);
1514
+ Q('specialkeylist').blur();
1515
+ Q('specialkeylistinput').blur();
1516
+ }
1517
+ }
1518
+
1519
+ function p12clearConsoleMsg() { QH('p12TermConsoleMsg', ''); QV('p12TermConsoleMsg', false); if (p12TermConsoleMsgTimer) { clearTimeout(p12TermConsoleMsgTimer); p12TermConsoleMsgTimer = null; } }
1520
+
1521
+
1522
+
1523
+ //
1524
+ // Files
1525
+ //
1526
+
1527
+ function setupFiles() {
1528
+ // Setup the files tab
1529
+ if (files != null) { files.Stop(); files = null; }
1530
+ }
1531
+
1532
+ function onFilesStateChange(xfiles, state) {
1533
+ p13Connect.value = (state == 0) ? "Connect" : "Disconnect";
1534
+ var str = StatusStrs[state];
1535
+ if (files.webRtcActive == true) { str += ", WebRTC"; }
1536
+ Q('p13Status').textContent = str;
1537
+ switch (state) {
1538
+ case 0:
1539
+ // Disconnected, clear the files
1540
+ QH('p13files', '');
1541
+ p13filetree = null;
1542
+ p13filetreelocation = [];
1543
+ QH('p13currentpath', '');
1544
+ QE('p13FolderUp', false);
1545
+ QV('filesRecordIcon', false);
1546
+ p13setActions();
1547
+ if (files != null) { files.Stop(); files = null; }
1548
+ if (xxdialogTag == 'fileMsgDialog') { setDialogMode(0); }
1549
+ break;
1550
+ case 3:
1551
+ p13targetpath = '';
1552
+ if (files) {
1553
+ files.sendText({ action: 'ls', reqid: 1, path: '' });
1554
+ if (files.serverIsRecording == true) { QV('filesRecordIcon', true); }
1555
+ }
1556
+ break;
1557
+ default:
1558
+ //console.log('Unknown onFilesStateChange state', state);
1559
+ break;
1560
+ }
1561
+ }
1562
+
1563
+ function CreateRemoteFiles(onFileUpdate) {
1564
+ var obj = { protocol: 5 };
1565
+ obj.onFileUpdate = onFileUpdate;
1566
+ obj.xxStateChange = function (state) { }
1567
+ obj.ProcessData = function (data) { obj.onFileUpdate(data); }
1568
+ return obj;
1569
+ }
1570
+
1571
+ function connectFiles(e) {
1572
+ p13clearConsoleMsg();
1573
+ if (!files) {
1574
+ // Setup a mesh agent files
1575
+ files = CreateAgentRedirect(null, CreateRemoteFiles(p13gotFiles), serverPublicNamePort, authCookie, null, domainUrl);
1576
+ files.attemptWebRTC = attemptWebRTC;
1577
+ files.onStateChanged = onFilesStateChange;
1578
+ files.onConsoleMessageChange = function () {
1579
+ if (files.consoleMessage) {
1580
+ Q('p13FilesConsoleMsg').innerHTML += formatAgentConsoleMessage(files.consoleMessage, files.consoleMessageId, files.consoleMessageArgs);
1581
+ QV('p13FilesConsoleMsg', true);
1582
+ if (p13FilesConsoleMsgTimer != null) { clearTimeout(p13FilesConsoleMsgTimer); }
1583
+ if (files.consoleMessageTimeout) { p13FilesConsoleMsgTimer = setTimeout(p13clearConsoleMsg, files.consoleMessageTimeout * 1000); }
1584
+ } else {
1585
+ p13clearConsoleMsg();
1586
+ }
1587
+ }
1588
+ files.Start(null);
1589
+ } else {
1590
+ //QH('Term', '');
1591
+ files.Stop();
1592
+ files = null;
1593
+ }
1594
+ p13clipboard = p13clipboardFolder = null;
1595
+ p13clipboardCut = 0;
1596
+ p13updateClipview();
1597
+ }
1598
+
1599
+ var p13filetree = null;
1600
+ var p13targetpath = null;
1601
+ var p13filetreelocation = [];
1602
+
1603
+ function p13fileOperationDialogEx(b) { if ((b == 0) && (files != null)) { files.sendText({ action: 'cancel' }); } }
1604
+
1605
+ function p13gotFiles(data) {
1606
+ if ((data.length > 0) && (data.charCodeAt(0) != 123)) { p13gotDownloadBinaryData(data); return; } // This is ok because 4 first bytes is a control value.
1607
+ //console.log('p13gotFiles', data);
1608
+ try { data = JSON.parse(decode_utf8(data)); } catch (ex) { data = JSON.parse(data); }
1609
+ if (data.action == 'download') { p13gotDownloadCommand(data); return; }
1610
+
1611
+ // Find file result
1612
+ if (data.action == 'findfile') {
1613
+ if (xxdialogTag == data.reqid) {
1614
+ if (data.r == null) {
1615
+ QE('d2findFilter', true);
1616
+ QE('filefind_dlgOkButton', true);
1617
+ xxdialogTag = null;
1618
+ if (Q('d2findResults').innerHTML == '') { QH('d2findResults', '<div style=text-align:center;margin:10px><i>' + "No files found" + '</i></div>'); }
1619
+ } else {
1620
+ QA('d2findResults', '<div style=white-space:nowrap>' + EscapeHtml(data.r) + '</div>');
1621
+ }
1622
+ }
1623
+ return;
1624
+ }
1625
+
1626
+ // Process file upload commands
1627
+ if ((data.action != null) && (data.action.startsWith('upload'))) { p13gotUploadData(data); return; }
1628
+
1629
+ // Display a dialog message
1630
+ if (data.action == 'dialogmessage') {
1631
+ if ((data.msg == null) && (xxdialogTag == 'fileMsgDialog')) {
1632
+ setDialogMode(0); // Close the dialog box
1633
+ } else if ((data.msg == 'zipping') && ((!xxdialogMode) || (xxdialogTag == 'fileMsgDialog'))) {
1634
+ // Show the dialog box message
1635
+ setDialogMode(2, "File Operation", 10, p13fileOperationDialogEx, '<div style=margin:10px>' + "Compressing files..." + '<div>', 'fileMsgDialog');
1636
+ } else if ((data.msg == 'zippingFile') && ((!xxdialogMode) || (xxdialogTag == 'fileMsgDialog'))) {
1637
+ // Show the dialog box message
1638
+ setDialogMode(2, "File Operation", 10, p13fileOperationDialogEx, '<div style=margin:10px>' + EscapeHtml(data.file) + '<div><br /><progress value=' + EscapeHtml(data.progress) + ' style=width:100% max=100 />', 'fileMsgDialog');
1639
+ }
1640
+ return;
1641
+ }
1642
+
1643
+ // Refresh file folder
1644
+ if (data.action == 'refresh') { p13folderup(9999); return; }
1645
+
1646
+ if (data.path != null) {
1647
+ data.path = data.path.replace(/\//g, '\\');
1648
+ if ((p13filetree != null) && (data.path == p13filetree.path)) {
1649
+ // This is an update to the same folder
1650
+ var checkedNames = p13getCheckedNames();
1651
+ p13filetree = data;
1652
+ p13updateFiles(checkedNames);
1653
+ } else {
1654
+ // Make both paths use the same seperator not start with /
1655
+ var x1 = data.path.replace(/\//g, '\\'), x2 = p13targetpath.replace(/\//g, '\\');
1656
+ while ((x1.length > 0) && (x1[0] == '\\')) { x1 = x1.substring(1); }
1657
+ while ((x2.length > 0) && (x2[0] == '\\')) { x2 = x2.substring(1); }
1658
+ if ((x1 == x2) || ((data.path == '\\') && (p13targetpath == ''))) {
1659
+ // This is a different folder
1660
+ p13filetree = data;
1661
+ p13updateFiles();
1662
+ }
1663
+ }
1664
+ }
1665
+ }
1666
+
1667
+ function p13getCheckedNames() {
1668
+ // Save all existing checked boxes
1669
+ var checkedNames = [], checkboxes = document.getElementsByName('fd');
1670
+ for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { checkedNames.push(p13filetree.dir[checkboxes[i].value].n) }; }
1671
+ return checkedNames;
1672
+ }
1673
+
1674
+ function p13updateFiles(checkedNames) {
1675
+ var html1 = '', html2 = '', displayPath = '<a href=# style=cursor:pointer onclick="return p13folderup(0)">' + "Root" + '</a>', fullPath = 'Root';
1676
+
1677
+ // Work on parsing the file path
1678
+ var x = p13filetree.path.split('\\');
1679
+ p13filetreelocation = [];
1680
+ for (var i in x) { if (x[i] != '') { p13filetreelocation.push(x[i]); } } // Remove empty spaces
1681
+ for (var i in p13filetreelocation) { displayPath += ' / <a href=# style=cursor:pointer onclick="return p13folderup(' + (parseInt(i) + 1) + ')">' + EscapeHtml(p13filetreelocation[i]) + '</a>' } // Setup the path we display
1682
+ var newlinkpath = p13filetreelocation.join('/');
1683
+
1684
+ // Sort the files
1685
+ var filetreexx = p13sort_files(p13filetree.dir);
1686
+
1687
+ // Display all files and folders at this location
1688
+ for (var i in filetreexx) {
1689
+ // Figure out the name and shortname
1690
+ var f = filetreexx[i], name = f.n, shortname;
1691
+ shortname = name;
1692
+ if (name.length > 70) { shortname = '<span title="' + EscapeHtml(name) + '">' + EscapeHtml(name.substring(0, 70)) + ("..." + '</span>'); } else { shortname = EscapeHtml(name); }
1693
+ name = EscapeHtml(name);
1694
+
1695
+ // Figure out the date
1696
+ var fdatestr = '';
1697
+ if (f.d != null) {
1698
+ var fdate = new Date(f.d);
1699
+ if (typeof f.d == 'number') { fdate = new Date(f.d * 1000); }
1700
+ var fdatestr = printDateTime(fdate) + ' ';
1701
+ }
1702
+
1703
+ // Figure out the size
1704
+ var fsize = '';
1705
+ if (f.s != null) { fsize = getFileSizeStr(f.s); }
1706
+
1707
+ var h = '';
1708
+ if (f.t < 3) {
1709
+ var right = '', title = '';
1710
+ h = '<div class=filelist file=999><input file=999 style=float:left name=fd class=fcb type=checkbox onchange=p13setActions() value=\'' + f.nx + '\'> <span style=float:right title="' + title + '">' + right + '</span><span><div class=fileIcon' + f.t + ' onclick=p13folderset("' + encodeURIComponentEx(f.nx) + '")></div><a href=# style=cursor:pointer onclick=\'return p13folderset("' + encodeURIComponentEx(f.nx) + '")\'>' + shortname + '</a></span></div>';
1711
+ } else {
1712
+ var link = shortname;
1713
+ if (f.s > 0) {
1714
+ // Local link
1715
+ //link = '<a href=# style=cursor:pointer onclick="return p13downloadfile(\'' + encodeURIComponentEx(newlinkpath + '/' + name) + '\',\'' + encodeURIComponentEx(name) + '\',' + f.s + ')">' + shortname + '</a>';
1716
+ // Server link
1717
+ //link = '<a href="devicefile.ashx?c=' + authCookie + '&m=' + currentNode.meshid.split('/')[2] + '&n=' + currentNode._id.split('/')[2] + '&f=' + encodeURIComponentEx(newlinkpath + '/' + name) + '" download="' + name + '" style=cursor:pointer>' + shortname + '</a>';
1718
+ // Server link
1719
+ //link = '<a onclick=downloadFile("devicefile.ashx?c=' + authCookie + '&m=' + currentNode.meshid.split('/')[2] + '&n=' + currentNode._id.split('/')[2] + '&f=' + encodeURIComponentEx(newlinkpath + '/' + name) + '","' + encodeURIComponentEx(name) + '") style=cursor:pointer>' + shortname + '</a>';
1720
+ link = '<a onclick=downloadFile("devicefile.ashx?c=' + authCookie + '&n=' + nodeid.split('/')[2] + '&f=' + encodeURIComponentEx(newlinkpath + '/' + name) + '","' + encodeURIComponentEx(name) + '") style=cursor:pointer>' + shortname + '</a>';
1721
+ }
1722
+ h = '<div id=fileEntry cmenu=filesContextMenu fileIndex=' + i + ' class=filelist file=3><input file=3 style=float:left name=fd class=fcb type=checkbox onchange=p13setActions() value=\'' + f.nx + '\'> <span class=fsize>' + fdatestr + '</span><span style=float:right>' + EscapeHtml(fsize) + '</span><span><div class=fileIcon' + f.t + '></div>' + link + '</span></div>';
1723
+ }
1724
+
1725
+ if (f.t < 3) { html1 += h; } else { html2 += h; }
1726
+ }
1727
+
1728
+ // Display the files and path
1729
+ QH('p13files', html1 + html2);
1730
+ QH('p13currentpath', displayPath);
1731
+ QE('p13FolderUp', p13filetreelocation.length != 0);
1732
+
1733
+ // Re-check all boxes if needed using names
1734
+ if (checkedNames != null) { var checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { if (checkedNames.indexOf(p13filetree.dir[checkboxes[i].value].n) >= 0) { checkboxes[i].checked = true; } } }
1735
+
1736
+ // Update the actions buttons
1737
+ p13setActions();
1738
+ }
1739
+
1740
+ function p13folderset(x) {
1741
+ p13targetpath = joinPaths(p13filetree.path, p13filetree.dir[x].n).split('\\').join('/');
1742
+ files.sendText({ action: 'ls', reqid: 1, path: p13targetpath });
1743
+ }
1744
+
1745
+ function p13folderup(x) {
1746
+ if (x == null) { p13filetreelocation.pop(); } else { while (p13filetreelocation.length > x) { p13filetreelocation.pop(); } }
1747
+ p13targetpath = p13filetreelocation.join('/');
1748
+ files.sendText({ action: 'ls', reqid: 1, path: p13targetpath });
1749
+ return false;
1750
+ }
1751
+
1752
+ function p13findfile() {
1753
+ if (xxdialogMode) return;
1754
+ var x = addHtmlValue("Filter", '<input id=d2findFilter style="width:230px" onkeyup=p13findfileValidate() onkeydown=p13findfileDown(event) placeholder="*.txt"></input>');
1755
+ x += '<div id=d2findResults style="width:100%;height:184px;background-color:white;border:1px solid black;padding:3px;overflow:scroll;margin-top:8px"></div>';
1756
+ x += '<div style=margin-top:8px><input id=filefind_dlgCancelButton type=button value=' + "Close" + ' style=float:right;width:80px;margin-left:5px onclick=p13findfileCancel()>';
1757
+ x += '<input id=filefind_dlgOkButton type=submit value=' + "Search" + ' style=float:right;width:80px onclick=p13findfileEx()><br /><br /></div>';
1758
+ setDialogMode(2, "Find Files", 0, null, x);
1759
+ p13findfileValidate();
1760
+ Q('d2findFilter').focus();
1761
+ }
1762
+
1763
+ function p13findfileDown(e) { if (e.code == "Enter") { p13findfileEx(); } }
1764
+ function p13findfileValidate() { QE('filefind_dlgOkButton', Q('d2findFilter').value.length > 0); }
1765
+ function p13findfileCancel() { if (xxdialogTag != null) { files.sendText({ action: 'cancelfindfile', reqid: xxdialogTag }); } dialogclose(0) }
1766
+
1767
+ function p13findfileEx(b, t) {
1768
+ if (Q('d2findFilter').value.length == 0) return;
1769
+ var winagent = true;//((currentNode.agent.id > 0) && (currentNode.agent.id < 5));
1770
+ var slash = winagent ? '\\' : '/';
1771
+ var path = p13filetreelocation.join(slash) + slash;
1772
+ if (!winagent) { path = slash + path; }
1773
+ xxdialogTag = 'find:' + Math.random();
1774
+ files.sendText({ action: 'findfile', reqid: xxdialogTag, path: path, filter: Q('d2findFilter').value });
1775
+ QH('d2findResults', '');
1776
+ QE('d2findFilter', false);
1777
+ QE('filefind_dlgOkButton', false);
1778
+ }
1779
+
1780
+ var p13sortorder;
1781
+ function p13sort_filename(a, b) { if (a.ln > b.ln) return (1 * p13sortorder); if (a.ln < b.ln) return (-1 * p13sortorder); return 0; }
1782
+ function p13sort_timestamp(a, b) { if (a.d > b.d) return (1 * p13sortorder); if (a.d < b.d) return (-1 * p13sortorder); return 0; }
1783
+ function p13sort_bysize(a, b) { if (a.s == b.s) return p13sort_filename(a, b); return (((a.s - b.s)) * p13sortorder); }
1784
+
1785
+ function p13sort_files(files) {
1786
+ var r = [], sortselection = Q('p13sortdropdown').value;
1787
+ for (var i in files) { files[i].nx = i; if (files[i].s == null) { files[i].s = 0; } if (files[i].n == null) { files[i].n = i; } files[i].ln = files[i].n.toLowerCase(); r.push(files[i]); }
1788
+ p13sortorder = 1;
1789
+ if (sortselection > 3) { p13sortorder = -1; sortselection -= 3; }
1790
+ if (sortselection == 1) { r.sort(p13sort_filename); }
1791
+ else if (sortselection == 2) { r.sort(p13sort_bysize); }
1792
+ else if (sortselection == 3) { r.sort(p13sort_timestamp); }
1793
+ return r;
1794
+ }
1795
+
1796
+ function p13setActions() {
1797
+ var advancedFeatures = true; //(currentNode.agent.id != 14); // Reduct file feature on some devices.
1798
+ if (p13filetree == null) {
1799
+ QE('p13DeleteFileButton', false);
1800
+ QE('p13NewFolderButton', false);
1801
+ QE('p13UploadButton', false);
1802
+ QE('p13RenameFileButton', false);
1803
+ QE('p13ViewFileButton', false);
1804
+ QE('p13SelectAllButton', false);
1805
+ Q('p13SelectAllButton').value = "Select All";
1806
+ QE('p13RefreshButton', false);
1807
+ QE('p13FindButton', false);
1808
+ QE('p13CutButton', false);
1809
+ QE('p13CopyButton', false);
1810
+ QE('p13ZipButton', false);
1811
+ QE('p13PasteButton', false);
1812
+ } else {
1813
+ var cc = p13getFileSelCount(), tc = p13getFileCount(), sfc = p13getFileSelCount(false); // In order: number of entires selected, number of total entries, number of selected entires that are files (not folders)
1814
+ var winAgent = true; //((currentNode.agent.id > 0) && (currentNode.agent.id < 5)) || (currentNode.agent.id == 14);
1815
+ QE('p13DeleteFileButton', (cc > 0) && ((p13filetreelocation.length > 0) || (winAgent == false)));
1816
+ QE('p13NewFolderButton', advancedFeatures && ((p13filetreelocation.length > 0) || (winAgent == false)));
1817
+ QE('p13UploadButton', ((p13filetreelocation.length > 0) || (winAgent == false) /*|| (currentNode.agent.id == 14)*/));
1818
+ QE('p13RenameFileButton', advancedFeatures && (cc == 1) && ((p13filetreelocation.length > 0) || (winAgent == false)));
1819
+ QE('p13ViewFileButton', advancedFeatures && (cc == 1) && (sfc == 1) && ((p13filetreelocation.length > 0) || (winAgent == false)));
1820
+ QE('p13SelectAllButton', tc > 0);
1821
+ Q('p13SelectAllButton').value = (cc > 0 ? "Select None" : "Select All");
1822
+ QE('p13RefreshButton', true);
1823
+ QE('p13FindButton', advancedFeatures && ((p13filetreelocation.length > 0) || (winAgent == false)));
1824
+ QE('p13CutButton', advancedFeatures && (cc > 0) && (cc == sfc) && ((p13filetreelocation.length > 0) || (winAgent == false)));
1825
+ QE('p13CopyButton', advancedFeatures && (cc > 0) && (cc == sfc) && ((p13filetreelocation.length > 0) || (winAgent == false)));
1826
+ QE('p13ZipButton', advancedFeatures && (cc > 0) && ((p13filetreelocation.length > 0) || (winAgent == false)));
1827
+ QE('p13PasteButton', advancedFeatures && ((p13filetreelocation.length > 0) || (winAgent == false)) && ((p13clipboard != null) && (p13clipboard.length > 0)));
1828
+ }
1829
+ }
1830
+
1831
+ function p13getFileSelCount(includeDirs) { var cc = 0; var checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { if ((checkboxes[i].checked) && ((includeDirs != false) || (checkboxes[i].attributes.file.value == '3'))) cc++; } return cc; }
1832
+ function p13getFileSelDirCount() { var cc = 0, checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { if ((checkboxes[i].checked) && (checkboxes[i].attributes.file.value == '999')) cc++; } return cc; }
1833
+ function p13getFileCount() { var cc = 0; var checkboxes = document.getElementsByName('fd'); return checkboxes.length; }
1834
+ function p13selectallfile() { var nv = (p13getFileSelCount() == 0), checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { checkboxes[i].checked = nv; } p13setActions(); }
1835
+ function p13createfolder() { setDialogMode(2, "New Folder", 3, p13createfolderEx, '<input type=text id=p13renameinput maxlength=64 onkeyup=p13fileNameCheck(event) style=width:100% />'); focusTextBox('p13renameinput'); p13fileNameCheck(); }
1836
+ function p13createfolderEx() { files.sendText({ action: 'mkdir', reqid: 1, path: p13filetreelocation.join('/') + '/' + Q('p13renameinput').value }); p13folderup(999); }
1837
+ function p13deletefile() { var cc = p13getFileSelCount(), rec = (p13getFileSelDirCount() > 0) ? '<br /><br /><label><input type=checkbox id=p13recdeleteinput>' + "Recursive delete" + '</label><br>' : '<input type=checkbox id=p13recdeleteinput style=\'display:none\'>'; setDialogMode(2, "Delete", 3, p13deletefileEx, (cc > 1) ? (format("Delete {0} selected items?", cc) + rec) : ("Delete selected item?" + rec)); }
1838
+ function p13deletefileEx() { var delfiles = [], checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { delfiles.push(p13filetree.dir[checkboxes[i].value].n); } } files.sendText({ action: 'rm', reqid: 1, path: p13filetreelocation.join('/'), delfiles: delfiles, rec: Q('p13recdeleteinput').checked }); p13folderup(999); }
1839
+ function p13renamefile() { var renamefile, checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { renamefile = p13filetree.dir[checkboxes[i].value].n; } } setDialogMode(2, "Rename", 3, p13renamefileEx, '<input type=text id=p13renameinput maxlength=64 onkeyup=p13fileNameCheck(event) style=width:100% value="' + renamefile + '" />', { action: 'rename', path: p13filetreelocation.join('/'), oldname: renamefile }); focusTextBox('p13renameinput'); p13fileNameCheck(); }
1840
+ function p13renamefileEx(b, t) { t.newname = Q('p13renameinput').value; files.sendText(t); p13folderup(999); }
1841
+ function p13fileNameCheck(e) { var x = isFilenameValid(Q('p13renameinput').value); QE('idx_dlgOkButton', x); if ((x == true) && (e != null) && (e.keyCode == 13)) { dialogclose(1); } }
1842
+ function p13uploadFile() { setDialogMode(2, "Upload File", 3, p13uploadFileEx, '<input type=file name=files id=p13uploadinput style=width:100% multiple=multiple onchange="updateUploadDialogOk(\'p13uploadinput\')" />'); updateUploadDialogOk('p13uploadinput'); }
1843
+ function updateUploadDialogOk(x) { QE('idx_dlgOkButton', Q('p13uploadinput').files.length > 0); }
1844
+ function p13uploadFileEx() { p13doUploadFiles(Q('p13uploadinput').files); }
1845
+ function p13viewfile() {
1846
+ var checkboxes = document.getElementsByName('fd');
1847
+ for (var i = 0; i < checkboxes.length; i++) {
1848
+ if (checkboxes[i].checked) {
1849
+ if (p13filetree.dir[checkboxes[i].value].s <= 204800) {
1850
+ p13downloadfile(encodeURIComponentEx(p13filetreelocation.join('/') + '/' + p13filetree.dir[checkboxes[i].value].n), encodeURIComponentEx(p13filetree.dir[checkboxes[i].value].n), p13filetree.dir[checkboxes[i].value].s, 'viewer');
1851
+ } else { messagebox("File Editor", "Only files less than 200k can be edited."); }
1852
+ break;
1853
+ }
1854
+ }
1855
+ }
1856
+
1857
+ function p13zipFiles() {
1858
+ var inputFiles = [], checkboxes = document.getElementsByName('fd');
1859
+ for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { inputFiles.push(p13filetree.dir[checkboxes[i].value].n); } }
1860
+ setDialogMode(2, "Zip Filename", 3, p13zipFilesEx, '<input type=text id=p13renameinput maxlength=64 onkeyup=p13fileNameCheck(event) style=width:100% value="" />', { action: 'zip', path: p13filetreelocation.join('/'), files: inputFiles });
1861
+ focusTextBox('p13renameinput');
1862
+ p13fileNameCheck();
1863
+ }
1864
+
1865
+ function p13zipFilesEx(b, tag) {
1866
+ tag.output = Q('p13renameinput').value;
1867
+ if (!tag.output.toLowerCase().endsWith('.zip')) { tag.output += '.zip'; }
1868
+ files.sendText(tag);
1869
+ }
1870
+
1871
+ var p13clipboard = null, p13clipboardFolder = null, p13clipboardCut = 0;
1872
+ function p13copyFile(cut) { var checkboxes = document.getElementsByName('fd'); p13clipboard = []; p13clipboardCut = cut, p13clipboardFolder = p13targetpath; for (var i = 0; i < checkboxes.length; i++) { if ((checkboxes[i].checked) && (checkboxes[i].attributes.file.value == '3')) { p13clipboard.push(p13filetree.dir[checkboxes[i].value].n); } } p13updateClipview(); }
1873
+ function p13pasteFile() {
1874
+ var x = '';
1875
+ if ((p13clipboard != null) && (p13clipboard.length > 0)) {
1876
+ if (p13clipboardCut == 0) {
1877
+ if (p13clipboard.length > 1) { x = format("Confirm copy of {0} entries to this location?", p13clipboard.length); } else { x = format("Confirm copy of 1 entrie to this location?"); }
1878
+ } else {
1879
+ if (p13clipboard.length > 1) { x = format("Confirm move of {0} entries to this location?", p13clipboard.length); } else { x = format("Confirm move of 1 entrie to this location?"); }
1880
+ }
1881
+ }
1882
+ setDialogMode(2, "Paste", 3, p13pasteFileEx, x);
1883
+ }
1884
+ function p13pasteFileEx() { files.sendText({ action: (p13clipboardCut == 0 ? 'copy' : 'move'), reqid: 1, scpath: p13clipboardFolder, dspath: p13targetpath, names: p13clipboard }); p13folderup(999); if (p13clipboardCut == 1) { p13clipboard = null, p13clipboardFolder = null, p13clipboardCut = 0; p13updateClipview(); } }
1885
+ function p13updateClipview() {
1886
+ var x = '';
1887
+ if ((p13clipboard != null) && (p13clipboard.length > 0)) {
1888
+ if (p13clipboardCut == 0) {
1889
+ if (p13clipboard.length > 1) {
1890
+ x = format("Holding {0} entries for copy" + ', <a href=# onclick="return p13clearClip()" style=cursor:pointer>' + "Clear" + '</a>.', p13clipboard.length);
1891
+ } else {
1892
+ x = format("Holding 1 entrie for copy" + ', <a href=# onclick="return p13clearClip()" style=cursor:pointer>' + "Clear" + '</a>.');
1893
+ }
1894
+ } else {
1895
+ if (p13clipboard.length > 1) {
1896
+ x = format("Holding {0} entries for move" + ', <a href=# onclick="return p13clearClip()" style=cursor:pointer>' + "Clear" + '</a>.', p13clipboard.length);
1897
+ } else {
1898
+ x = format("Holding 1 entrie for move" + ', <a href=# onclick="return p13clearClip()" style=cursor:pointer>' + "Clear" + '</a>.');
1899
+ }
1900
+ }
1901
+ }
1902
+ QH('p13bottomstatus', x);
1903
+ p13setActions();
1904
+ }
1905
+ function p13clearClip() { p13clipboard = null; p13clipboardFolder = null; p13clipboardCut = 0; p13updateClipview(); return false; }
1906
+
1907
+ function p13fileDragDrop(e) {
1908
+ haltEvent(e);
1909
+ QV('p13bigfail', false);
1910
+ QV('p13bigok', false);
1911
+ if ((e.dataTransfer == null) || (e.dataTransfer.files.length == 0) || (p13filetree == null)) return;
1912
+
1913
+ // Check if these are files we can upload, remove all folders.
1914
+ var files = [];
1915
+ for (var i in e.dataTransfer.files) { if ((e.dataTransfer.files[i].size != null) && (e.dataTransfer.files[i].size != 0)) { files.push(e.dataTransfer.files[i]); } }
1916
+ if (files.length == 0) return;
1917
+
1918
+ p13doUploadFiles(files);
1919
+ }
1920
+
1921
+ var p13dragtimer = null;
1922
+ function p13fileDragOver(e) {
1923
+ haltEvent(e);
1924
+ if (p13dragtimer != null) { clearTimeout(p13dragtimer); p13dragtimer = null; }
1925
+ var ac = (p13filetree != null); // Set to true if we can accept the file
1926
+ QV('p13bigok', ac);
1927
+ QV('p13bigfail', !ac);
1928
+ }
1929
+
1930
+ function p13fileDragLeave(e) {
1931
+ haltEvent(e);
1932
+ if (e.target.id != 'p13filetable') {
1933
+ QV('p13bigfail', false);
1934
+ QV('p13bigok', false);
1935
+ } else {
1936
+ p13dragtimer = setTimeout(function () { QV('p13bigfail', false); QV('p13bigok', false); p13dragtimer = null; }, 10);
1937
+ }
1938
+ }
1939
+
1940
+ //
1941
+ // FILES DOWNLOAD
1942
+ //
1943
+
1944
+ var gdownloadFile; // Global state for file download
1945
+
1946
+ // Called by the html page to start a download, arguments are: path, file name and file size.
1947
+ function p13downloadfile(x, y, z, tag) {
1948
+ if (xxdialogMode || !files) return;
1949
+ gdownloadFile = { path: decodeURIComponent(x), file: decodeURIComponent(y), size: z, tsize: 0, data: '', state: 0, id: Math.random(), tag: tag }
1950
+ //console.log('p13downloadFileCancel', gdownloadFile);
1951
+ files.sendText({ action: 'download', sub: 'start', id: gdownloadFile.id, path: gdownloadFile.path });
1952
+ setDialogMode(2, "Download File", 10, p13downloadFileCancel, '<div>' + gdownloadFile.file + '</div><br /><progress id=d2progressBar style=width:100% value=0 max=' + z + ' />');
1953
+ }
1954
+
1955
+ // Called by the html page to cancel the download
1956
+ function p13downloadFileCancel() { setDialogMode(0); files.sendText({ action: 'download', sub: 'cancel', id: gdownloadFile.id }); gdownloadFile = null; }
1957
+
1958
+ // Called by the transport when download control command is received
1959
+ function p13gotDownloadCommand(cmd) {
1960
+ //console.log('p13gotDownloadCommand', cmd);
1961
+ if ((gdownloadFile == null) || (cmd.id != gdownloadFile.id)) return;
1962
+ if (cmd.sub == 'start') { gdownloadFile.state = 1; files.sendText({ action: 'download', sub: 'startack', id: gdownloadFile.id }); }
1963
+ else if (cmd.sub == 'cancel') { gdownloadFile = null; setDialogMode(0); }
1964
+ }
1965
+
1966
+ // Called by the transport when binary data is received
1967
+ function p13gotDownloadBinaryData(data) {
1968
+ if (!gdownloadFile || gdownloadFile.state == 0) return;
1969
+ if (data.length > 4) {
1970
+ gdownloadFile.tsize += (data.length - 4); // Add to the total bytes received
1971
+ gdownloadFile.data += data.substring(4); // Append the data
1972
+ Q('d2progressBar').value = gdownloadFile.tsize; // Change the progress bar
1973
+ }
1974
+ if ((ReadInt(data, 0) & 1) != 0) { // Check end flag
1975
+ if (gdownloadFile.tag == 'viewer') {
1976
+ // View the file in the dialog box
1977
+ setDialogMode(4, EscapeHtml(gdownloadFile.file), 3, p13editSaveBack, null, gdownloadFile.file);
1978
+ QS('dialog').width = 'auto';
1979
+ QS('dialog').bottom = '80px';
1980
+ QS('dialog').top = QS('dialog').left = QS('dialog').right = '100px';
1981
+ Q('d4editorarea').value = gdownloadFile.data;
1982
+ gdownloadFile = null;
1983
+ } else {
1984
+ // Save the file to disk
1985
+ saveAs(data2blob(gdownloadFile.data), gdownloadFile.file); gdownloadFile = null; setDialogMode(0); // Save the file
1986
+ }
1987
+ } else {
1988
+ files.sendText({ action: 'download', sub: 'ack', id: gdownloadFile.id }); // Send the ACK
1989
+ }
1990
+ }
1991
+
1992
+ var d4EditWrapVal = 0;
1993
+ var d4EditSizeVal = 0;
1994
+ function d4ToggleWrap(update) {
1995
+ if (!update) { d4EditWrapVal = ++d4EditWrapVal % 2; }
1996
+ Q('d4WrapButton').value = ["Wrap: ON", "Wrap: OFF"][d4EditWrapVal];
1997
+ QS('d4editorarea').overflow = (d4EditWrapVal == 0) ? 'auto' : 'scroll';
1998
+ QS('d4editorarea')['white-space'] = (d4EditWrapVal == 0) ? null : 'pre';
1999
+ putstore('editorWrap', d4EditWrapVal);
2000
+ }
2001
+
2002
+ function d4ToggleSize(update) {
2003
+ if (!update) { d4EditSizeVal = ++d4EditSizeVal % 4; }
2004
+ QS('d4editorarea')['font-size'] = ['100%', '125%', '150%', '200%'][d4EditSizeVal];
2005
+ Q('d4SizeButton').value = ["Size: 100%", "Size: 125%", "Size: 150%", "Size: 200%"][d4EditSizeVal];
2006
+ putstore('editorSize', d4EditSizeVal);
2007
+ }
2008
+
2009
+ function p13editSaveBack(b, tag) {
2010
+ var data = new TextEncoder().encode(Q('d4editorarea').value);
2011
+ p13uploadFileContinue(1, [{ name: tag, size: data.byteLength, type: 'text/plain', xdata: data }]);
2012
+ }
2013
+
2014
+ //
2015
+ // FILES UPLOAD
2016
+ //
2017
+
2018
+ var uploadFile;
2019
+ function p13doUploadFiles(files) {
2020
+ if (xxdialogMode) return;
2021
+
2022
+ // Check if we are going to overwrite any files
2023
+ var winAgent = true;//((currentNode.agent.id > 0) && (currentNode.agent.id < 5));
2024
+ var targetFiles = [], overWriteCount = 0;
2025
+ for (var i in p13filetree.dir) { if (winAgent) { targetFiles.push(p13filetree.dir[i].n.toLowerCase()); } else { targetFiles.push(p13filetree.dir[i].n); } }
2026
+ for (var i = 0; i < files.length; i++) {
2027
+ if (winAgent) {
2028
+ if (targetFiles.indexOf(files[i].name.toLowerCase()) >= 0) { overWriteCount++; }
2029
+ } else {
2030
+ if (targetFiles.indexOf(files[i].name) >= 0) { overWriteCount++; }
2031
+ }
2032
+ }
2033
+
2034
+ if (overWriteCount == 0) {
2035
+ // If no overwrite, go ahead with upload
2036
+ p13uploadFileContinue(1, files);
2037
+ } else {
2038
+ // Otherwise, prompt for confirmation
2039
+ setDialogMode(2, "Upload File", 3, p13uploadFileContinue, format((overWriteCount == 1) ? "Upload will overwrite 1 file. Continue?" : "Upload will overwrite {0} files. Continue?", overWriteCount), files);
2040
+ }
2041
+ }
2042
+
2043
+ function p13uploadFileContinue(b, files) {
2044
+ uploadFile = {};
2045
+ uploadFile.xpath = p13filetreelocation.join('/');
2046
+ uploadFile.xfiles = files;
2047
+ uploadFile.xfilePtr = -1;
2048
+ setDialogMode(2, "Upload File", 10, p13uploadFileCancel, '<div id=p13dfileName>' + "Connecting..." + '</div><br /><progress id=d2progressBar style=width:100% value=0 max=0 />');
2049
+ p13uploadNextFile();
2050
+ }
2051
+
2052
+ // Push the next file
2053
+ function p13uploadNextFile() {
2054
+ uploadFile.xfilePtr++;
2055
+ if (uploadFile.xfiles.length > uploadFile.xfilePtr) {
2056
+ uploadFile.xptr = 0;
2057
+ var file = uploadFile.xfiles[uploadFile.xfilePtr];
2058
+ QH('p13dfileName', file.name);
2059
+ Q('d2progressBar').max = file.size;
2060
+ Q('d2progressBar').value = 0;
2061
+ if (file.xdata == null) {
2062
+ // Load the data
2063
+ uploadFile.xreader = new FileReader();
2064
+ uploadFile.xreader.onload = function () {
2065
+ uploadFile.xdata = uploadFile.xreader.result;
2066
+ files.sendText(JSON.stringify({ action: 'upload', reqid: uploadFile.xfilePtr, path: uploadFile.xpath, name: file.name, size: uploadFile.xdata.byteLength }));
2067
+ };
2068
+ uploadFile.xreader.readAsArrayBuffer(file);
2069
+ } else {
2070
+ // Data already loaded
2071
+ uploadFile.xdata = file.xdata;
2072
+ files.sendText(JSON.stringify({ action: 'upload', reqid: uploadFile.xfilePtr, path: uploadFile.xpath, name: file.name, size: uploadFile.xdata.byteLength }));
2073
+ }
2074
+ } else {
2075
+ p13uploadFileTransferDone();
2076
+ }
2077
+ }
2078
+
2079
+ // Used to cancel the entire transfer.
2080
+ function p13uploadFileCancel(button, tag) {
2081
+ if (uploadFile != null) { files.sendText(JSON.stringify({ action: 'uploadcancel', reqid: uploadFile.xfilePtr })); uploadFile = null; }
2082
+ p13uploadFileTransferDone();
2083
+ }
2084
+
2085
+ // Used to cancel the entire transfer.
2086
+ function p13uploadFileTransferDone() {
2087
+ uploadFile = null; // No more files to upload, clean up.
2088
+ setDialogMode(0); // Close the dialog box
2089
+ p13folderup(9999); // Refresh the current folder
2090
+ }
2091
+
2092
+ // Receive upload ack from the mesh agent, use this to keep sending more data
2093
+ function p13gotUploadData(cmd) {
2094
+ if ((uploadFile == null) || (parseInt(uploadFile.xfilePtr) != parseInt(cmd.reqid))) { return; }
2095
+ switch (cmd.action) {
2096
+ case 'uploadstart': { p13uploadNextPart(false); for (var i = 0; i < 8; i++) { p13uploadNextPart(true); } break; } // Send 8 more blocks of 16k to fill the websocket.
2097
+ case 'uploadack': { p13uploadNextPart(false); break; }
2098
+ case 'uploaddone': { if (uploadFile.xfiles.length > uploadFile.xfilePtr + 1) { p13uploadNextFile(); } else { p13uploadFileTransferDone(); } break; }
2099
+ case 'uploaderror': { p13uploadFileCancel(); break; }
2100
+ }
2101
+ }
2102
+
2103
+ // Push the next part of the file into the websocket. If dataPriming is true, push more data only if it's not the last block of the file.
2104
+ function p13uploadNextPart(dataPriming) {
2105
+ var data = uploadFile.xdata, start = uploadFile.xptr;
2106
+ if (start >= data.byteLength) {
2107
+ files.sendText(JSON.stringify({ action: 'uploaddone', reqid: uploadFile.xfilePtr }));
2108
+ } else {
2109
+ var end = uploadFile.xptr + 16384;
2110
+ if (end > data.byteLength) { if (dataPriming == true) { return; } end = data.byteLength; }
2111
+ var dataslice = new Uint8Array(data.slice(start, end))
2112
+ if ((dataslice[0] == 123) || (dataslice[0] == 0)) {
2113
+ var datapart = new Uint8Array(end - start + 1);
2114
+ datapart.set(dataslice, 1); // Add a zero char at the start of the send, this will indicate that it's not a JSON command.
2115
+ files.send(datapart);
2116
+ } else {
2117
+ files.send(dataslice); // The data does not start with 0 or 123 "{" so it can't be confused for JSON.
2118
+ }
2119
+ uploadFile.xptr = end;
2120
+ Q('d2progressBar').value = end;
2121
+ }
2122
+ }
2123
+
2124
+
2125
+
2126
+ //
2127
+ // POPUP DIALOG
2128
+ //
2129
+
2130
+ // null = Hidden, 1 = Generic Message
2131
+ var xxdialogMode;
2132
+ var xxdialogFunc;
2133
+ var xxdialogButtons;
2134
+ var xxdialogTag;
2135
+ var xxcurrentView = -1;
2136
+
2137
+ // Display a dialog box
2138
+ // Parameters: Dialog Mode (0 = none), Dialog Title, Buttons (1 = OK, 2 = Cancel, 3 = OK & Cancel), Call back function(0 = Cancel, 1 = OK), Dialog Content (Mode 2 only)
2139
+ function setDialogMode(x, y, b, f, c, tag) {
2140
+ xxdialogMode = x;
2141
+ xxdialogFunc = f;
2142
+ xxdialogButtons = b;
2143
+ xxdialogTag = tag;
2144
+ QE('idx_dlgOkButton', true);
2145
+ QV('idx_dlgOkButton', b & 1);
2146
+ QV('idx_dlgCancelButton', b & 2);
2147
+ QV('id_dialogclose', (b & 2) || (b & 8));
2148
+ QV('idx_dlgDeleteButton', b & 4);
2149
+ QV('idx_dlgButtonBar', b & 7);
2150
+ if (y) QH('id_dialogtitle', y);
2151
+ for (var i = 1; i < 8; i++) { QV('dialog' + i, i == x); } // Edit this line when more dialogs are added
2152
+ QV('dialog', x);
2153
+ if (c) { if (x == 2) { QH('id_dialogOptions', c); } else { QH('id_dialogMessage', c); } }
2154
+ }
2155
+
2156
+ function dialogclose(x) {
2157
+ var f = xxdialogFunc, b = xxdialogButtons, t = xxdialogTag;
2158
+ setDialogMode();
2159
+ if (((b & 8) || x) && f) f(x, t);
2160
+ }
2161
+
2162
+ function go(x) {
2163
+ if (xxdialogMode) return;
2164
+ QV('p11', x == 11);
2165
+ QV('p12', x == 12);
2166
+ QV('p13', x == 13);
2167
+
2168
+ var leftBarItems = ['LeftMenuDesktop', 'LeftMenuTerminal', 'LeftMenuFiles'];
2169
+ for (var i in leftBarItems) { Q(leftBarItems[i]).classList.remove('slbbuttonsel'); Q(leftBarItems[i]).classList.remove('slbbuttonsel2'); }
2170
+ if (x == 11) { Q('LeftMenuDesktop').classList.add('slbbuttonsel2'); }
2171
+ if (x == 12) { Q('LeftMenuTerminal').classList.add('slbbuttonsel2'); }
2172
+ if (x == 13) { Q('LeftMenuFiles').classList.add('slbbuttonsel2'); }
2173
+ xxcurrentView = x;
2174
+ }
2175
+
2176
+ function messagebox(t, m) { setSessionActivity(); QH('id_dialogMessage', m); setDialogMode(1, t, 1); }
2177
+ function statusbox(t, m) { setSessionActivity(); QH('id_dialogMessage', m); setDialogMode(1, t); }
2178
+ function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
2179
+ function pad2(num) { var s = '00' + num; return s.substr(s.length - 2); }
2180
+ function format(format) { var args = Array.prototype.slice.call(arguments, 1); return format.replace(/{(\d+)}/g, function (match, number) { return typeof args[number] != 'undefined' ? args[number] : match; }); };
2181
+ function setSessionActivity() { sessionActivity = Date.now(); /*QH('idleTimeoutNotify', '');*/ }
2182
+ function printDate(d) { return d.toLocaleDateString(urlargs.locale); }
2183
+ function printTime(d) { return d.toLocaleTimeString(urlargs.locale); }
2184
+ function printDateTime(d) { return d.toLocaleString(urlargs.locale); }
2185
+ function printFlexDateTime(d) { if (printDate(new Date()) == printDate(d)) { return format("Expires at {0}", printTime(d)); } else { return format("Expires {0}", printDateTime(d)); } }
2186
+ function getFileSizeStr(size) { if (typeof size != 'number') { size = 0; } if (size == 1) return "1 byte"; return format("{0} bytes", size); }
2187
+ function encodeURIComponentEx(txt) { return encodeURIComponent(txt).replace(/'/g, '%27'); };
2188
+ function joinPaths() { var x = []; for (var i in arguments) { var w = arguments[i]; if ((w != null) && (w != '')) { while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); } while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); } x.push(w); } } return x.join('/'); }
2189
+ function focusTextBox(x) { setTimeout(function () { Q(x).selectionStart = Q(x).selectionEnd = 65535; Q(x).focus(); }, 0); }
2190
+ var isFilenameValid = (function () { var x1 = /^[^\\/:\*\?"<>\|]+$/, x2 = /^\./, x3 = /^(nul|prn|con|lpt[0-9]|com[0-9])(\.|$)/i; return function isFilenameValid(fname) { return x1.test(fname) && !x2.test(fname) && !x3.test(fname) && (fname[0] != '.'); } })();
2191
+
2192
+ // Webkit seems to have a problem with "download" tag causing "network error", but openning the download in a hidden frame fixes it.
2193
+ // So we do that for all browsers except FireFox
2194
+ function downloadFile(link, name, closeDialog) {
2195
+ var element = document.createElement('a');
2196
+ element.setAttribute('href', link);
2197
+ element.setAttribute('rel', 'noreferrer noopener');
2198
+ element.setAttribute('target', 'fileDownloadFrame');
2199
+ if (navigator.userAgent.indexOf('Firefox') >= 0) { element.setAttribute('download', decodeURIComponent(name ? name : '')); }
2200
+ document.body.appendChild(element);
2201
+ element.click();
2202
+ document.body.removeChild(element);
2203
+ if (closeDialog) { setDialogMode(0); }
2204
+ }
2205
+
2206
+ start();
2207
+ </script>
2208
+</body>
2209
+</html>
\ No newline at end of file
webserver.js
+54
-7
@@ -2992,7 +2992,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2992
function handleDeviceFile(req, res) {
2993
const domain = checkUserIpAddress(req, res);
2994
if (domain == null) { return; }
2995
- if ((req.query.c == null) || (req.query.m == null) || (req.query.n == null) || (req.query.f == null)) { res.sendStatus(404); return; }
2995
+ if ((req.query.c == null) || (req.query.n == null) || (req.query.f == null)) { res.sendStatus(404); return; }
2996
2997
// Check the inbound desktop sharing cookie
2998
var c = obj.parent.decodeCookie(req.query.c, obj.parent.loginCookieEncryptionKey, 60); // 60 minute timeout
@@ -3003,13 +3003,13 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3003
if ((c == user)) { res.sendStatus(404); return; }
3004
3005
// Check if this user has permission to manage this computer
3006
- const meshid = 'mesh/' + domain.id + '/' + req.query.m;
3007
- const nodeid = 'node/' + domain.id + '/' + req.query.n;
3008
- if ((obj.GetNodeRights(c.userid, meshid, nodeid) & MESHRIGHT_REMOTECONTROL) == 0) { res.sendStatus(404); return; }
3006
+ obj.GetNodeWithRights(domain, user, 'node/' + domain.id + '/' + req.query.n, function (node, rights, visible) {
3007
+ if ((node == null) || ((rights & MESHRIGHT_REMOTECONTROL) == 0) || (visible == false)) { res.sendStatus(404); return; } // We don't have remote control rights to this device
3008
3010
- // All good, start the file transfer
3011
- req.query.id = getRandomLowerCase(12);
3012
- obj.meshDeviceFileHandler.CreateMeshDeviceFile(obj, null, res, req, domain, user, meshid, nodeid);
3009
+ // All good, start the file transfer
3010
+ req.query.id = getRandomLowerCase(12);
3011
+ obj.meshDeviceFileHandler.CreateMeshDeviceFile(obj, null, res, req, domain, user, node.meshid, node._id);
3012
+ });
3013
}
3014
3015
// Handle download of a server file by an agent
@@ -3301,6 +3301,52 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3301
});
3302
}
3303
3304
+ // Serve the guest sharing page
3305
+ function handleSharingRequest(req, res) {
3306
+ const domain = getDomain(req, res);
3307
+ if (domain == null) { return; }
3308
+ if (req.query.c == null) { res.sendStatus(404); return; }
3309
+ if (domain.guestdevicesharing === false) { res.sendStatus(404); return; } // This feature is not allowed.
3310
+
3311
+ // Check the inbound desktop sharing cookie
3312
+ var c = obj.parent.decodeCookie(req.query.c, obj.parent.invitationLinkEncryptionKey, 60); // 60 minute timeout
3313
+ if ((c == null) || (c.a !== 5) || ((c.p !== 2) && (c.p != null)) || (typeof c.uid != 'string') || (typeof c.nid != 'string') || (typeof c.gn != 'string') || (typeof c.cf != 'number') || (typeof c.start != 'number') || (typeof c.expire != 'number') || (typeof c.pid != 'string')) { res.sendStatus(404); return; }
3314
+
3315
+ // Check the expired time, expire message.
3316
+ if (c.expire <= Date.now()) { render(req, res, getRenderPage((domain.sitestyle == 2) ? 'message2' : 'message', req, domain), getRenderArgs({ titleid: 2, msgid: 12, domainurl: encodeURIComponent(domain.url).replace(/'/g, '%27') }, req, domain)); return; }
3317
+
3318
+ // Check the public id
3319
+ obj.db.GetAllTypeNodeFiltered([c.nid], domain.id, 'deviceshare', null, function (err, docs) {
3320
+ // Check if any desktop sharing links are present, expire message.
3321
+ if ((err != null) || (docs.length == 0)) { render(req, res, getRenderPage((domain.sitestyle == 2) ? 'message2' : 'message', req, domain), getRenderArgs({ titleid: 2, msgid: 12, domainurl: encodeURIComponent(domain.url).replace(/'/g, '%27') }, req, domain)); return; }
3322
+
3323
+ // Search for the device share public identifier, expire message.
3324
+ var found = false;
3325
+ for (var i = 0; i < docs.length; i++) { if (docs[i].publicid == c.pid) { found = true; } }
3326
+ if (found == false) { render(req, res, getRenderPage((domain.sitestyle == 2) ? 'message2' : 'message', req, domain), getRenderArgs({ titleid: 2, msgid: 12, domainurl: encodeURIComponent(domain.url).replace(/'/g, '%27') }, req, domain)); return; }
3327
+
3328
+ // Get information about this node
3329
+ obj.db.Get(c.nid, function (err, nodes) {
3330
+ if ((err != null) || (nodes == null) || (nodes.length != 1)) { res.sendStatus(404); return; }
3331
+ var node = nodes[0];
3332
+
3333
+ // Check the start time, not yet valid message.
3334
+ if ((c.start > Date.now()) || (c.start > c.expire)) { render(req, res, getRenderPage((domain.sitestyle == 2) ? 'message2' : 'message', req, domain), getRenderArgs({ titleid: 2, msgid: 11, domainurl: encodeURIComponent(domain.url).replace(/'/g, '%27') }, req, domain)); return; }
3335
+
3336
+ // Looks good, let's create the outbound session cookies.
3337
+ // Consent flags are 1 = Notify, 8 = Prompt, 64 = Privacy Bar.
3338
+ const authCookie = obj.parent.encodeCookie({ userid: c.uid, domainid: domain.id, nid: c.nid, ip: req.clientIp, p: 2, gn: c.gn, cf: 65 | c.cf, r: 8, expire: c.expire, pid: c.pid, vo: c.vo }, obj.parent.loginCookieEncryptionKey);
3339
+
3340
+ // Lets respond by sending out the desktop viewer.
3341
+ var httpsPort = ((obj.args.aliasport == null) ? obj.args.port : obj.args.aliasport); // Use HTTPS alias port is specified
3342
+ parent.debug('web', 'handleDesktopRequest: Sending guest sharing page for \"' + c.uid + '\", guest \"' + c.gn + '\".');
3343
+ res.set({ 'Cache-Control': 'no-store' });
3344
+ render(req, res, getRenderPage('sharing', req, domain), getRenderArgs({ authCookie: authCookie, authRelayCookie: '', domainurl: encodeURIComponent(domain.url).replace(/'/g, '%27'), nodeid: c.nid, serverDnsName: obj.getWebServerName(domain), serverRedirPort: args.redirport, serverPublicPort: httpsPort, expire: c.expire, viewOnly: (c.vo == 1) ? 1 : 0, nodeName: encodeURIComponent(node.name) }, req, domain));
3345
+ });
3346
+ });
3347
+ }
3348
+
3349
+
3350
// Handle domain redirection
3351
obj.handleDomainRedirect = function (req, res) {
3352
const domain = checkUserIpAddress(req, res);
@@ -5286,6 +5332,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
5332
obj.app.get(url + 'player', handlePlayerRequest);
5333
obj.app.get(url + 'desktop', handleDesktopRequest);
5334
obj.app.get(url + 'terminal', handleTerminalRequest);
5335
+ obj.app.get(url + 'sharing', handleSharingRequest);
5336
obj.app.ws(url + 'agenttransfer.ashx', handleAgentFileTransfer); // Setup agent to/from server file transfer handler
5337
obj.app.ws(url + 'meshrelay.ashx', function (ws, req) {
5338
PerformWSSessionAuth(ws, req, true, function (ws1, req1, domain, user, cookie) {