From 55f5e76f9e067d93ed47428f61733d22b8c756a2 Mon Sep 17 00:00:00 2001 From: SeungYongShim Date: Sat, 2 Mar 2024 20:08:56 +0900 Subject: [PATCH] . --- src/Sample.Tests/Sample.Tests.csproj | 21 - src/Sample.Tests/UnitTest1.cs | 14 - src/Sample/Class1.cs | 7 - src/VncApp/Components/App.razor | 20 + src/VncApp/Components/Layout/MainLayout.razor | 23 + .../Components/Layout/MainLayout.razor.css | 96 + src/VncApp/Components/Layout/NavMenu.razor | 30 + .../Components/Layout/NavMenu.razor.css | 105 + src/VncApp/Components/Pages/Counter.razor | 19 + src/VncApp/Components/Pages/Error.razor | 36 + src/VncApp/Components/Pages/Home.razor | 7 + src/VncApp/Components/Pages/Weather.razor | 64 + src/VncApp/Components/Routes.razor | 6 + src/VncApp/Components/_Imports.razor | 10 + src/VncApp/Middleware/WebsockifyMiddleware.cs | 146 + src/VncApp/Program.cs | 23 + src/VncApp/Properties/launchSettings.json | 29 + .../Sample.csproj => VncApp/VncApp.csproj} | 7 +- src/VncApp/appsettings.Development.json | 8 + src/VncApp/appsettings.json | 9 + src/VncApp/wwwroot/app.css | 51 + src/VncApp/wwwroot/app/error-handler.js | 79 + src/VncApp/wwwroot/app/images/alt.svg | 92 + src/VncApp/wwwroot/app/images/clipboard.svg | 106 + src/VncApp/wwwroot/app/images/connect.svg | 96 + src/VncApp/wwwroot/app/images/ctrl.svg | 96 + src/VncApp/wwwroot/app/images/ctrlaltdel.svg | 100 + src/VncApp/wwwroot/app/images/disconnect.svg | 94 + src/VncApp/wwwroot/app/images/drag.svg | 76 + src/VncApp/wwwroot/app/images/error.svg | 81 + src/VncApp/wwwroot/app/images/esc.svg | 92 + src/VncApp/wwwroot/app/images/expander.svg | 69 + src/VncApp/wwwroot/app/images/fullscreen.svg | 93 + src/VncApp/wwwroot/app/images/handle.svg | 82 + src/VncApp/wwwroot/app/images/handle_bg.svg | 172 + src/VncApp/wwwroot/app/images/icons/Makefile | 42 + .../app/images/icons/novnc-icon-sm.svg | 163 + .../wwwroot/app/images/icons/novnc-icon.svg | 163 + .../app/images/icons/novnc-ios-120.png | Bin 0 -> 3215 bytes .../app/images/icons/novnc-ios-152.png | Bin 0 -> 4190 bytes .../app/images/icons/novnc-ios-167.png | Bin 0 -> 4574 bytes .../app/images/icons/novnc-ios-180.png | Bin 0 -> 4730 bytes .../wwwroot/app/images/icons/novnc-ios-40.png | Bin 0 -> 1245 bytes .../wwwroot/app/images/icons/novnc-ios-58.png | Bin 0 -> 1602 bytes .../wwwroot/app/images/icons/novnc-ios-60.png | Bin 0 -> 1595 bytes .../wwwroot/app/images/icons/novnc-ios-80.png | Bin 0 -> 1825 bytes .../wwwroot/app/images/icons/novnc-ios-87.png | Bin 0 -> 2708 bytes .../app/images/icons/novnc-ios-icon.svg | 183 + src/VncApp/wwwroot/app/images/icons/novnc.ico | Bin 0 -> 310566 bytes src/VncApp/wwwroot/app/images/info.svg | 81 + src/VncApp/wwwroot/app/images/keyboard.svg | 88 + src/VncApp/wwwroot/app/images/power.svg | 87 + src/VncApp/wwwroot/app/images/settings.svg | 76 + src/VncApp/wwwroot/app/images/tab.svg | 86 + .../wwwroot/app/images/toggleextrakeys.svg | 90 + src/VncApp/wwwroot/app/images/warning.svg | 81 + src/VncApp/wwwroot/app/images/windows.svg | 65 + src/VncApp/wwwroot/app/locale/README | 1 + src/VncApp/wwwroot/app/locale/cs.json | 71 + src/VncApp/wwwroot/app/locale/de.json | 69 + src/VncApp/wwwroot/app/locale/el.json | 69 + src/VncApp/wwwroot/app/locale/es.json | 68 + src/VncApp/wwwroot/app/locale/fr.json | 78 + src/VncApp/wwwroot/app/locale/it.json | 72 + src/VncApp/wwwroot/app/locale/ja.json | 72 + src/VncApp/wwwroot/app/locale/ko.json | 70 + src/VncApp/wwwroot/app/locale/nl.json | 73 + src/VncApp/wwwroot/app/locale/pl.json | 69 + src/VncApp/wwwroot/app/locale/pt_BR.json | 72 + src/VncApp/wwwroot/app/locale/ru.json | 72 + src/VncApp/wwwroot/app/locale/sv.json | 80 + src/VncApp/wwwroot/app/locale/tr.json | 69 + src/VncApp/wwwroot/app/locale/zh_CN.json | 69 + src/VncApp/wwwroot/app/locale/zh_TW.json | 69 + src/VncApp/wwwroot/app/localization.js | 179 + src/VncApp/wwwroot/app/sounds/CREDITS | 4 + src/VncApp/wwwroot/app/sounds/bell.mp3 | Bin 0 -> 4531 bytes src/VncApp/wwwroot/app/sounds/bell.oga | Bin 0 -> 8495 bytes src/VncApp/wwwroot/app/styles/Orbitron700.ttf | Bin 0 -> 38580 bytes .../wwwroot/app/styles/Orbitron700.woff | Bin 0 -> 17472 bytes src/VncApp/wwwroot/app/styles/base.css | 922 +++++ src/VncApp/wwwroot/app/styles/input.css | 281 ++ src/VncApp/wwwroot/app/ui.js | 1782 +++++++++ src/VncApp/wwwroot/app/webutil.js | 186 + .../wwwroot/bootstrap/bootstrap.min.css | 7 + .../wwwroot/bootstrap/bootstrap.min.css.map | 1 + src/VncApp/wwwroot/core/base64.js | 104 + src/VncApp/wwwroot/core/decoders/copyrect.js | 27 + src/VncApp/wwwroot/core/decoders/hextile.js | 191 + src/VncApp/wwwroot/core/decoders/jpeg.js | 141 + src/VncApp/wwwroot/core/decoders/raw.js | 66 + src/VncApp/wwwroot/core/decoders/rre.js | 44 + src/VncApp/wwwroot/core/decoders/tight.js | 331 ++ src/VncApp/wwwroot/core/decoders/tightpng.js | 27 + src/VncApp/wwwroot/core/decoders/zrle.js | 185 + src/VncApp/wwwroot/core/deflator.js | 85 + src/VncApp/wwwroot/core/des.js | 266 ++ src/VncApp/wwwroot/core/display.js | 525 +++ src/VncApp/wwwroot/core/encodings.js | 48 + src/VncApp/wwwroot/core/inflator.js | 66 + src/VncApp/wwwroot/core/input/domkeytable.js | 311 ++ src/VncApp/wwwroot/core/input/fixedkeys.js | 129 + .../wwwroot/core/input/gesturehandler.js | 567 +++ src/VncApp/wwwroot/core/input/keyboard.js | 283 ++ src/VncApp/wwwroot/core/input/keysym.js | 616 +++ src/VncApp/wwwroot/core/input/keysymdef.js | 688 ++++ src/VncApp/wwwroot/core/input/util.js | 191 + src/VncApp/wwwroot/core/input/vkeys.js | 116 + src/VncApp/wwwroot/core/input/xtscancodes.js | 173 + src/VncApp/wwwroot/core/ra2.js | 567 +++ src/VncApp/wwwroot/core/rfb.js | 3373 +++++++++++++++++ src/VncApp/wwwroot/core/util/browser.js | 152 + src/VncApp/wwwroot/core/util/cursor.js | 247 ++ src/VncApp/wwwroot/core/util/element.js | 32 + src/VncApp/wwwroot/core/util/events.js | 138 + src/VncApp/wwwroot/core/util/eventtarget.js | 35 + src/VncApp/wwwroot/core/util/int.js | 15 + src/VncApp/wwwroot/core/util/logging.js | 56 + src/VncApp/wwwroot/core/util/md5.js | 79 + src/VncApp/wwwroot/core/util/strings.js | 28 + src/VncApp/wwwroot/core/websock.js | 353 ++ src/VncApp/wwwroot/favicon.png | Bin 0 -> 1148 bytes src/VncApp/wwwroot/vendor/pako/LICENSE | 21 + src/VncApp/wwwroot/vendor/pako/README.md | 6 + .../wwwroot/vendor/pako/lib/utils/common.js | 45 + .../wwwroot/vendor/pako/lib/zlib/adler32.js | 27 + .../wwwroot/vendor/pako/lib/zlib/constants.js | 47 + .../wwwroot/vendor/pako/lib/zlib/crc32.js | 36 + .../wwwroot/vendor/pako/lib/zlib/deflate.js | 1846 +++++++++ .../wwwroot/vendor/pako/lib/zlib/gzheader.js | 35 + .../wwwroot/vendor/pako/lib/zlib/inffast.js | 324 ++ .../wwwroot/vendor/pako/lib/zlib/inflate.js | 1527 ++++++++ .../wwwroot/vendor/pako/lib/zlib/inftrees.js | 322 ++ .../wwwroot/vendor/pako/lib/zlib/messages.js | 11 + .../wwwroot/vendor/pako/lib/zlib/trees.js | 1195 ++++++ .../wwwroot/vendor/pako/lib/zlib/zstream.js | 24 + src/VncApp/wwwroot/vnc.html | 341 ++ src/poc-novnc-blazor-wasm-8.sln | 25 + src/src.sln | 56 - 139 files changed, 23811 insertions(+), 101 deletions(-) delete mode 100644 src/Sample.Tests/Sample.Tests.csproj delete mode 100644 src/Sample.Tests/UnitTest1.cs delete mode 100644 src/Sample/Class1.cs create mode 100644 src/VncApp/Components/App.razor create mode 100644 src/VncApp/Components/Layout/MainLayout.razor create mode 100644 src/VncApp/Components/Layout/MainLayout.razor.css create mode 100644 src/VncApp/Components/Layout/NavMenu.razor create mode 100644 src/VncApp/Components/Layout/NavMenu.razor.css create mode 100644 src/VncApp/Components/Pages/Counter.razor create mode 100644 src/VncApp/Components/Pages/Error.razor create mode 100644 src/VncApp/Components/Pages/Home.razor create mode 100644 src/VncApp/Components/Pages/Weather.razor create mode 100644 src/VncApp/Components/Routes.razor create mode 100644 src/VncApp/Components/_Imports.razor create mode 100644 src/VncApp/Middleware/WebsockifyMiddleware.cs create mode 100644 src/VncApp/Program.cs create mode 100644 src/VncApp/Properties/launchSettings.json rename src/{Sample/Sample.csproj => VncApp/VncApp.csproj} (59%) create mode 100644 src/VncApp/appsettings.Development.json create mode 100644 src/VncApp/appsettings.json create mode 100644 src/VncApp/wwwroot/app.css create mode 100644 src/VncApp/wwwroot/app/error-handler.js create mode 100644 src/VncApp/wwwroot/app/images/alt.svg create mode 100644 src/VncApp/wwwroot/app/images/clipboard.svg create mode 100644 src/VncApp/wwwroot/app/images/connect.svg create mode 100644 src/VncApp/wwwroot/app/images/ctrl.svg create mode 100644 src/VncApp/wwwroot/app/images/ctrlaltdel.svg create mode 100644 src/VncApp/wwwroot/app/images/disconnect.svg create mode 100644 src/VncApp/wwwroot/app/images/drag.svg create mode 100644 src/VncApp/wwwroot/app/images/error.svg create mode 100644 src/VncApp/wwwroot/app/images/esc.svg create mode 100644 src/VncApp/wwwroot/app/images/expander.svg create mode 100644 src/VncApp/wwwroot/app/images/fullscreen.svg create mode 100644 src/VncApp/wwwroot/app/images/handle.svg create mode 100644 src/VncApp/wwwroot/app/images/handle_bg.svg create mode 100644 src/VncApp/wwwroot/app/images/icons/Makefile create mode 100644 src/VncApp/wwwroot/app/images/icons/novnc-icon-sm.svg create mode 100644 src/VncApp/wwwroot/app/images/icons/novnc-icon.svg create mode 100644 src/VncApp/wwwroot/app/images/icons/novnc-ios-120.png create mode 100644 src/VncApp/wwwroot/app/images/icons/novnc-ios-152.png create mode 100644 src/VncApp/wwwroot/app/images/icons/novnc-ios-167.png create mode 100644 src/VncApp/wwwroot/app/images/icons/novnc-ios-180.png create mode 100644 src/VncApp/wwwroot/app/images/icons/novnc-ios-40.png create mode 100644 src/VncApp/wwwroot/app/images/icons/novnc-ios-58.png create mode 100644 src/VncApp/wwwroot/app/images/icons/novnc-ios-60.png create mode 100644 src/VncApp/wwwroot/app/images/icons/novnc-ios-80.png create mode 100644 src/VncApp/wwwroot/app/images/icons/novnc-ios-87.png create mode 100644 src/VncApp/wwwroot/app/images/icons/novnc-ios-icon.svg create mode 100644 src/VncApp/wwwroot/app/images/icons/novnc.ico create mode 100644 src/VncApp/wwwroot/app/images/info.svg create mode 100644 src/VncApp/wwwroot/app/images/keyboard.svg create mode 100644 src/VncApp/wwwroot/app/images/power.svg create mode 100644 src/VncApp/wwwroot/app/images/settings.svg create mode 100644 src/VncApp/wwwroot/app/images/tab.svg create mode 100644 src/VncApp/wwwroot/app/images/toggleextrakeys.svg create mode 100644 src/VncApp/wwwroot/app/images/warning.svg create mode 100644 src/VncApp/wwwroot/app/images/windows.svg create mode 100644 src/VncApp/wwwroot/app/locale/README create mode 100644 src/VncApp/wwwroot/app/locale/cs.json create mode 100644 src/VncApp/wwwroot/app/locale/de.json create mode 100644 src/VncApp/wwwroot/app/locale/el.json create mode 100644 src/VncApp/wwwroot/app/locale/es.json create mode 100644 src/VncApp/wwwroot/app/locale/fr.json create mode 100644 src/VncApp/wwwroot/app/locale/it.json create mode 100644 src/VncApp/wwwroot/app/locale/ja.json create mode 100644 src/VncApp/wwwroot/app/locale/ko.json create mode 100644 src/VncApp/wwwroot/app/locale/nl.json create mode 100644 src/VncApp/wwwroot/app/locale/pl.json create mode 100644 src/VncApp/wwwroot/app/locale/pt_BR.json create mode 100644 src/VncApp/wwwroot/app/locale/ru.json create mode 100644 src/VncApp/wwwroot/app/locale/sv.json create mode 100644 src/VncApp/wwwroot/app/locale/tr.json create mode 100644 src/VncApp/wwwroot/app/locale/zh_CN.json create mode 100644 src/VncApp/wwwroot/app/locale/zh_TW.json create mode 100644 src/VncApp/wwwroot/app/localization.js create mode 100644 src/VncApp/wwwroot/app/sounds/CREDITS create mode 100644 src/VncApp/wwwroot/app/sounds/bell.mp3 create mode 100644 src/VncApp/wwwroot/app/sounds/bell.oga create mode 100644 src/VncApp/wwwroot/app/styles/Orbitron700.ttf create mode 100644 src/VncApp/wwwroot/app/styles/Orbitron700.woff create mode 100644 src/VncApp/wwwroot/app/styles/base.css create mode 100644 src/VncApp/wwwroot/app/styles/input.css create mode 100644 src/VncApp/wwwroot/app/ui.js create mode 100644 src/VncApp/wwwroot/app/webutil.js create mode 100644 src/VncApp/wwwroot/bootstrap/bootstrap.min.css create mode 100644 src/VncApp/wwwroot/bootstrap/bootstrap.min.css.map create mode 100644 src/VncApp/wwwroot/core/base64.js create mode 100644 src/VncApp/wwwroot/core/decoders/copyrect.js create mode 100644 src/VncApp/wwwroot/core/decoders/hextile.js create mode 100644 src/VncApp/wwwroot/core/decoders/jpeg.js create mode 100644 src/VncApp/wwwroot/core/decoders/raw.js create mode 100644 src/VncApp/wwwroot/core/decoders/rre.js create mode 100644 src/VncApp/wwwroot/core/decoders/tight.js create mode 100644 src/VncApp/wwwroot/core/decoders/tightpng.js create mode 100644 src/VncApp/wwwroot/core/decoders/zrle.js create mode 100644 src/VncApp/wwwroot/core/deflator.js create mode 100644 src/VncApp/wwwroot/core/des.js create mode 100644 src/VncApp/wwwroot/core/display.js create mode 100644 src/VncApp/wwwroot/core/encodings.js create mode 100644 src/VncApp/wwwroot/core/inflator.js create mode 100644 src/VncApp/wwwroot/core/input/domkeytable.js create mode 100644 src/VncApp/wwwroot/core/input/fixedkeys.js create mode 100644 src/VncApp/wwwroot/core/input/gesturehandler.js create mode 100644 src/VncApp/wwwroot/core/input/keyboard.js create mode 100644 src/VncApp/wwwroot/core/input/keysym.js create mode 100644 src/VncApp/wwwroot/core/input/keysymdef.js create mode 100644 src/VncApp/wwwroot/core/input/util.js create mode 100644 src/VncApp/wwwroot/core/input/vkeys.js create mode 100644 src/VncApp/wwwroot/core/input/xtscancodes.js create mode 100644 src/VncApp/wwwroot/core/ra2.js create mode 100644 src/VncApp/wwwroot/core/rfb.js create mode 100644 src/VncApp/wwwroot/core/util/browser.js create mode 100644 src/VncApp/wwwroot/core/util/cursor.js create mode 100644 src/VncApp/wwwroot/core/util/element.js create mode 100644 src/VncApp/wwwroot/core/util/events.js create mode 100644 src/VncApp/wwwroot/core/util/eventtarget.js create mode 100644 src/VncApp/wwwroot/core/util/int.js create mode 100644 src/VncApp/wwwroot/core/util/logging.js create mode 100644 src/VncApp/wwwroot/core/util/md5.js create mode 100644 src/VncApp/wwwroot/core/util/strings.js create mode 100644 src/VncApp/wwwroot/core/websock.js create mode 100644 src/VncApp/wwwroot/favicon.png create mode 100644 src/VncApp/wwwroot/vendor/pako/LICENSE create mode 100644 src/VncApp/wwwroot/vendor/pako/README.md create mode 100644 src/VncApp/wwwroot/vendor/pako/lib/utils/common.js create mode 100644 src/VncApp/wwwroot/vendor/pako/lib/zlib/adler32.js create mode 100644 src/VncApp/wwwroot/vendor/pako/lib/zlib/constants.js create mode 100644 src/VncApp/wwwroot/vendor/pako/lib/zlib/crc32.js create mode 100644 src/VncApp/wwwroot/vendor/pako/lib/zlib/deflate.js create mode 100644 src/VncApp/wwwroot/vendor/pako/lib/zlib/gzheader.js create mode 100644 src/VncApp/wwwroot/vendor/pako/lib/zlib/inffast.js create mode 100644 src/VncApp/wwwroot/vendor/pako/lib/zlib/inflate.js create mode 100644 src/VncApp/wwwroot/vendor/pako/lib/zlib/inftrees.js create mode 100644 src/VncApp/wwwroot/vendor/pako/lib/zlib/messages.js create mode 100644 src/VncApp/wwwroot/vendor/pako/lib/zlib/trees.js create mode 100644 src/VncApp/wwwroot/vendor/pako/lib/zlib/zstream.js create mode 100644 src/VncApp/wwwroot/vnc.html create mode 100644 src/poc-novnc-blazor-wasm-8.sln delete mode 100644 src/src.sln diff --git a/src/Sample.Tests/Sample.Tests.csproj b/src/Sample.Tests/Sample.Tests.csproj deleted file mode 100644 index 96fd276..0000000 --- a/src/Sample.Tests/Sample.Tests.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - net7 - false - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - diff --git a/src/Sample.Tests/UnitTest1.cs b/src/Sample.Tests/UnitTest1.cs deleted file mode 100644 index 3e3de9b..0000000 --- a/src/Sample.Tests/UnitTest1.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using Xunit; -using static Sample.Prelude; - -namespace Sample.Tests; - -public class PreludeSpec -{ - [Fact] - public void AddSuccess() - { - Assert.Equal(3, add(1)(2)); - } -} diff --git a/src/Sample/Class1.cs b/src/Sample/Class1.cs deleted file mode 100644 index 8528249..0000000 --- a/src/Sample/Class1.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Sample; - -public static class Prelude -{ - public static Func> add => - x => y => x + y; -} diff --git a/src/VncApp/Components/App.razor b/src/VncApp/Components/App.razor new file mode 100644 index 0000000..c81c4c7 --- /dev/null +++ b/src/VncApp/Components/App.razor @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/VncApp/Components/Layout/MainLayout.razor b/src/VncApp/Components/Layout/MainLayout.razor new file mode 100644 index 0000000..5a24bb1 --- /dev/null +++ b/src/VncApp/Components/Layout/MainLayout.razor @@ -0,0 +1,23 @@ +@inherits LayoutComponentBase + +
+ + +
+
+ About +
+ +
+ @Body +
+
+
+ +
+ An unhandled error has occurred. + Reload + 🗙 +
diff --git a/src/VncApp/Components/Layout/MainLayout.razor.css b/src/VncApp/Components/Layout/MainLayout.razor.css new file mode 100644 index 0000000..038baf1 --- /dev/null +++ b/src/VncApp/Components/Layout/MainLayout.razor.css @@ -0,0 +1,96 @@ +.page { + position: relative; + display: flex; + flex-direction: column; +} + +main { + flex: 1; +} + +.sidebar { + background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); +} + +.top-row { + background-color: #f7f7f7; + border-bottom: 1px solid #d6d5d5; + justify-content: flex-end; + height: 3.5rem; + display: flex; + align-items: center; +} + + .top-row ::deep a, .top-row ::deep .btn-link { + white-space: nowrap; + margin-left: 1.5rem; + text-decoration: none; + } + + .top-row ::deep a:hover, .top-row ::deep .btn-link:hover { + text-decoration: underline; + } + + .top-row ::deep a:first-child { + overflow: hidden; + text-overflow: ellipsis; + } + +@media (max-width: 640.98px) { + .top-row { + justify-content: space-between; + } + + .top-row ::deep a, .top-row ::deep .btn-link { + margin-left: 0; + } +} + +@media (min-width: 641px) { + .page { + flex-direction: row; + } + + .sidebar { + width: 250px; + height: 100vh; + position: sticky; + top: 0; + } + + .top-row { + position: sticky; + top: 0; + z-index: 1; + } + + .top-row.auth ::deep a:first-child { + flex: 1; + text-align: right; + width: 0; + } + + .top-row, article { + padding-left: 2rem !important; + padding-right: 1.5rem !important; + } +} + +#blazor-error-ui { + background: lightyellow; + bottom: 0; + box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); + display: none; + left: 0; + padding: 0.6rem 1.25rem 0.7rem 1.25rem; + position: fixed; + width: 100%; + z-index: 1000; +} + + #blazor-error-ui .dismiss { + cursor: pointer; + position: absolute; + right: 0.75rem; + top: 0.5rem; + } diff --git a/src/VncApp/Components/Layout/NavMenu.razor b/src/VncApp/Components/Layout/NavMenu.razor new file mode 100644 index 0000000..a2f8985 --- /dev/null +++ b/src/VncApp/Components/Layout/NavMenu.razor @@ -0,0 +1,30 @@ + + + + + + diff --git a/src/VncApp/Components/Layout/NavMenu.razor.css b/src/VncApp/Components/Layout/NavMenu.razor.css new file mode 100644 index 0000000..4e15395 --- /dev/null +++ b/src/VncApp/Components/Layout/NavMenu.razor.css @@ -0,0 +1,105 @@ +.navbar-toggler { + appearance: none; + cursor: pointer; + width: 3.5rem; + height: 2.5rem; + color: white; + position: absolute; + top: 0.5rem; + right: 1rem; + border: 1px solid rgba(255, 255, 255, 0.1); + background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1); +} + +.navbar-toggler:checked { + background-color: rgba(255, 255, 255, 0.5); +} + +.top-row { + height: 3.5rem; + background-color: rgba(0,0,0,0.4); +} + +.navbar-brand { + font-size: 1.1rem; +} + +.bi { + display: inline-block; + position: relative; + width: 1.25rem; + height: 1.25rem; + margin-right: 0.75rem; + top: -1px; + background-size: cover; +} + +.bi-house-door-fill-nav-menu { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E"); +} + +.bi-plus-square-fill-nav-menu { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E"); +} + +.bi-list-nested-nav-menu { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E"); +} + +.nav-item { + font-size: 0.9rem; + padding-bottom: 0.5rem; +} + + .nav-item:first-of-type { + padding-top: 1rem; + } + + .nav-item:last-of-type { + padding-bottom: 1rem; + } + + .nav-item ::deep .nav-link { + color: #d7d7d7; + background: none; + border: none; + border-radius: 4px; + height: 3rem; + display: flex; + align-items: center; + line-height: 3rem; + width: 100%; + } + +.nav-item ::deep a.active { + background-color: rgba(255,255,255,0.37); + color: white; +} + +.nav-item ::deep .nav-link:hover { + background-color: rgba(255,255,255,0.1); + color: white; +} + +.nav-scrollable { + display: none; +} + +.navbar-toggler:checked ~ .nav-scrollable { + display: block; +} + +@media (min-width: 641px) { + .navbar-toggler { + display: none; + } + + .nav-scrollable { + /* Never collapse the sidebar for wide screens */ + display: block; + + /* Allow sidebar to scroll for tall menus */ + height: calc(100vh - 3.5rem); + overflow-y: auto; + } +} diff --git a/src/VncApp/Components/Pages/Counter.razor b/src/VncApp/Components/Pages/Counter.razor new file mode 100644 index 0000000..1a4f8e7 --- /dev/null +++ b/src/VncApp/Components/Pages/Counter.razor @@ -0,0 +1,19 @@ +@page "/counter" +@rendermode InteractiveServer + +Counter + +

Counter

+ +

Current count: @currentCount

+ + + +@code { + private int currentCount = 0; + + private void IncrementCount() + { + currentCount++; + } +} diff --git a/src/VncApp/Components/Pages/Error.razor b/src/VncApp/Components/Pages/Error.razor new file mode 100644 index 0000000..576cc2d --- /dev/null +++ b/src/VncApp/Components/Pages/Error.razor @@ -0,0 +1,36 @@ +@page "/Error" +@using System.Diagnostics + +Error + +

Error.

+

An error occurred while processing your request.

+ +@if (ShowRequestId) +{ +

+ Request ID: @RequestId +

+} + +

Development Mode

+

+ Swapping to Development environment will display more detailed information about the error that occurred. +

+

+ The Development environment shouldn't be enabled for deployed applications. + It can result in displaying sensitive information from exceptions to end users. + For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development + and restarting the app. +

+ +@code{ + [CascadingParameter] + private HttpContext? HttpContext { get; set; } + + private string? RequestId { get; set; } + private bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + + protected override void OnInitialized() => + RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier; +} diff --git a/src/VncApp/Components/Pages/Home.razor b/src/VncApp/Components/Pages/Home.razor new file mode 100644 index 0000000..9001e0b --- /dev/null +++ b/src/VncApp/Components/Pages/Home.razor @@ -0,0 +1,7 @@ +@page "/" + +Home + +

Hello, world!

+ +Welcome to your new app. diff --git a/src/VncApp/Components/Pages/Weather.razor b/src/VncApp/Components/Pages/Weather.razor new file mode 100644 index 0000000..43a1ecb --- /dev/null +++ b/src/VncApp/Components/Pages/Weather.razor @@ -0,0 +1,64 @@ +@page "/weather" +@attribute [StreamRendering] + +Weather + +

Weather

+ +

This component demonstrates showing data.

+ +@if (forecasts == null) +{ +

Loading...

+} +else +{ + + + + + + + + + + + @foreach (var forecast in forecasts) + { + + + + + + + } + +
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
+} + +@code { + private WeatherForecast[]? forecasts; + + protected override async Task OnInitializedAsync() + { + // Simulate asynchronous loading to demonstrate streaming rendering + await Task.Delay(500); + + var startDate = DateOnly.FromDateTime(DateTime.Now); + var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; + forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = startDate.AddDays(index), + TemperatureC = Random.Shared.Next(-20, 55), + Summary = summaries[Random.Shared.Next(summaries.Length)] + }).ToArray(); + } + + private class WeatherForecast + { + public DateOnly Date { get; set; } + public int TemperatureC { get; set; } + public string? Summary { get; set; } + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + } +} diff --git a/src/VncApp/Components/Routes.razor b/src/VncApp/Components/Routes.razor new file mode 100644 index 0000000..f756e19 --- /dev/null +++ b/src/VncApp/Components/Routes.razor @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/VncApp/Components/_Imports.razor b/src/VncApp/Components/_Imports.razor new file mode 100644 index 0000000..7abe934 --- /dev/null +++ b/src/VncApp/Components/_Imports.razor @@ -0,0 +1,10 @@ +@using System.Net.Http +@using System.Net.Http.Json +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using static Microsoft.AspNetCore.Components.Web.RenderMode +@using Microsoft.AspNetCore.Components.Web.Virtualization +@using Microsoft.JSInterop +@using VncApp +@using VncApp.Components diff --git a/src/VncApp/Middleware/WebsockifyMiddleware.cs b/src/VncApp/Middleware/WebsockifyMiddleware.cs new file mode 100644 index 0000000..93e2153 --- /dev/null +++ b/src/VncApp/Middleware/WebsockifyMiddleware.cs @@ -0,0 +1,146 @@ +namespace VncApp.Middleware; + +using System; +using System.Net.Sockets; +using System.Net.WebSockets; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; + + +public class WebsockifyMiddleware +{ + private readonly RequestDelegate _next; + private readonly string _hostname; + private readonly int _port; + + public WebsockifyMiddleware( + RequestDelegate next, + string hostname, + int port) + { + if (next == null) + { + throw new ArgumentNullException(nameof(next)); + } + + if (hostname == null) + { + throw new ArgumentNullException(nameof(hostname)); + } + + _next = next; + _hostname = hostname; + _port = port; + } + + public async Task InvokeAsync(HttpContext context) + { + if (context.WebSockets.IsWebSocketRequest) + { + WebSocket webSocket = + await context.WebSockets.AcceptWebSocketAsync(); + + TcpClient tcpClient = new TcpClient(); + + tcpClient.Connect(_hostname, _port); + + NetworkStream networkStream = tcpClient.GetStream(); + + Task receiveTask = Task.Run(async () => + { + byte[] buffer = new byte[1024 * 1024]; + + try + { + for (; ; ) + { + int size = await networkStream.ReadAsync( + buffer, + CancellationToken.None); + + await webSocket.SendAsync( + new ArraySegment(buffer, 0, size), + WebSocketMessageType.Binary, + true, + CancellationToken.None); + } + } + catch (Exception) + { + + } + }); + + Task sendTask = Task.Run(async () => + { + WebSocketReceiveResult result = null; + byte[] buffer = new byte[1024 * 1024]; + + try + { + for (; ; ) + { + result = await webSocket.ReceiveAsync( + new ArraySegment(buffer), + CancellationToken.None); + if (result.CloseStatus.HasValue) + { + break; + } + + await networkStream.WriteAsync( + buffer, + 0, + result.Count, + CancellationToken.None); + } + } + catch (Exception) + { + + } + + networkStream.Close(); + + tcpClient.Close(); + + await webSocket.CloseAsync( + result.CloseStatus.Value, + result.CloseStatusDescription, + CancellationToken.None); + }); + + Task.WaitAll(receiveTask, sendTask); + } + else + { + context.Response.StatusCode = 400; + } + + // Call the next delegate/middleware in the pipeline. + await _next(context); + } +} + +public static class WebsockifyMiddlewareExtensions +{ + public static IApplicationBuilder UseWebsockify + ( + this IApplicationBuilder app, + PathString pathMatch, + string hostname = "", + int port = 0 + ) + { + ArgumentNullException.ThrowIfNull(app); + ArgumentNullException.ThrowIfNull(pathMatch); + ArgumentNullException.ThrowIfNull(hostname); + + return app.UseWebSockets().Map + ( + pathMatch, + a => a.UseMiddleware(hostname, port) + ); + } +} diff --git a/src/VncApp/Program.cs b/src/VncApp/Program.cs new file mode 100644 index 0000000..67c0574 --- /dev/null +++ b/src/VncApp/Program.cs @@ -0,0 +1,23 @@ +using VncApp.Components; +using VncApp.Middleware; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (!app.Environment.IsDevelopment()) +{ + app.UseExceptionHandler("/Error", createScopeForErrors: true); +} + +app.UseWebsockify("/websockify"); +app.UseStaticFiles(); +app.UseAntiforgery(); + +app.MapRazorComponents() .AddInteractiveServerRenderMode(); + +app.Run(); diff --git a/src/VncApp/Properties/launchSettings.json b/src/VncApp/Properties/launchSettings.json new file mode 100644 index 0000000..78de610 --- /dev/null +++ b/src/VncApp/Properties/launchSettings.json @@ -0,0 +1,29 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:20205", + "sslPort": 0 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5227", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } + } diff --git a/src/Sample/Sample.csproj b/src/VncApp/VncApp.csproj similarity index 59% rename from src/Sample/Sample.csproj rename to src/VncApp/VncApp.csproj index 0d1c2ba..1b28a01 100644 --- a/src/Sample/Sample.csproj +++ b/src/VncApp/VncApp.csproj @@ -1,8 +1,9 @@ - + - net7 - enable + net8.0 enable + enable + diff --git a/src/VncApp/appsettings.Development.json b/src/VncApp/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/src/VncApp/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/src/VncApp/appsettings.json b/src/VncApp/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/src/VncApp/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/src/VncApp/wwwroot/app.css b/src/VncApp/wwwroot/app.css new file mode 100644 index 0000000..2bd9b78 --- /dev/null +++ b/src/VncApp/wwwroot/app.css @@ -0,0 +1,51 @@ +html, body { + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; +} + +a, .btn-link { + color: #006bb7; +} + +.btn-primary { + color: #fff; + background-color: #1b6ec2; + border-color: #1861ac; +} + +.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus { + box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb; +} + +.content { + padding-top: 1.1rem; +} + +h1:focus { + outline: none; +} + +.valid.modified:not([type=checkbox]) { + outline: 1px solid #26b050; +} + +.invalid { + outline: 1px solid #e50000; +} + +.validation-message { + color: #e50000; +} + +.blazor-error-boundary { + background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121; + padding: 1rem 1rem 1rem 3.7rem; + color: white; +} + + .blazor-error-boundary::after { + content: "An error has occurred." + } + +.darker-border-checkbox.form-check-input { + border-color: #929292; +} diff --git a/src/VncApp/wwwroot/app/error-handler.js b/src/VncApp/wwwroot/app/error-handler.js new file mode 100644 index 0000000..67b6372 --- /dev/null +++ b/src/VncApp/wwwroot/app/error-handler.js @@ -0,0 +1,79 @@ +/* + * noVNC: HTML5 VNC client + * Copyright (C) 2019 The noVNC Authors + * Licensed under MPL 2.0 (see LICENSE.txt) + * + * See README.md for usage and integration instructions. + */ + +// Fallback for all uncought errors +function handleError(event, err) { + try { + const msg = document.getElementById('noVNC_fallback_errormsg'); + + // Work around Firefox bug: + // https://bugzilla.mozilla.org/show_bug.cgi?id=1685038 + if (event.message === "ResizeObserver loop completed with undelivered notifications.") { + return false; + } + + // Only show the initial error + if (msg.hasChildNodes()) { + return false; + } + + let div = document.createElement("div"); + div.classList.add('noVNC_message'); + div.appendChild(document.createTextNode(event.message)); + msg.appendChild(div); + + if (event.filename) { + div = document.createElement("div"); + div.className = 'noVNC_location'; + let text = event.filename; + if (event.lineno !== undefined) { + text += ":" + event.lineno; + if (event.colno !== undefined) { + text += ":" + event.colno; + } + } + div.appendChild(document.createTextNode(text)); + msg.appendChild(div); + } + + if (err && err.stack) { + div = document.createElement("div"); + div.className = 'noVNC_stack'; + div.appendChild(document.createTextNode(err.stack)); + msg.appendChild(div); + } + + document.getElementById('noVNC_fallback_error') + .classList.add("noVNC_open"); + + } catch (exc) { + document.write("noVNC encountered an error."); + } + + // Try to disable keyboard interaction, best effort + try { + // Remove focus from the currently focused element in order to + // prevent keyboard interaction from continuing + if (document.activeElement) { document.activeElement.blur(); } + + // Don't let any element be focusable when showing the error + let keyboardFocusable = 'a[href], button, input, textarea, select, details, [tabindex]'; + document.querySelectorAll(keyboardFocusable).forEach((elem) => { + elem.setAttribute("tabindex", "-1"); + }); + } catch (exc) { + // Do nothing + } + + // Don't return true since this would prevent the error + // from being printed to the browser console. + return false; +} + +window.addEventListener('error', evt => handleError(evt, evt.error)); +window.addEventListener('unhandledrejection', evt => handleError(evt.reason, evt.reason)); diff --git a/src/VncApp/wwwroot/app/images/alt.svg b/src/VncApp/wwwroot/app/images/alt.svg new file mode 100644 index 0000000..e5bb461 --- /dev/null +++ b/src/VncApp/wwwroot/app/images/alt.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/clipboard.svg b/src/VncApp/wwwroot/app/images/clipboard.svg new file mode 100644 index 0000000..79af275 --- /dev/null +++ b/src/VncApp/wwwroot/app/images/clipboard.svg @@ -0,0 +1,106 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/connect.svg b/src/VncApp/wwwroot/app/images/connect.svg new file mode 100644 index 0000000..56cde41 --- /dev/null +++ b/src/VncApp/wwwroot/app/images/connect.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/ctrl.svg b/src/VncApp/wwwroot/app/images/ctrl.svg new file mode 100644 index 0000000..856e939 --- /dev/null +++ b/src/VncApp/wwwroot/app/images/ctrl.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/ctrlaltdel.svg b/src/VncApp/wwwroot/app/images/ctrlaltdel.svg new file mode 100644 index 0000000..d7744ea --- /dev/null +++ b/src/VncApp/wwwroot/app/images/ctrlaltdel.svg @@ -0,0 +1,100 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/disconnect.svg b/src/VncApp/wwwroot/app/images/disconnect.svg new file mode 100644 index 0000000..6be7d18 --- /dev/null +++ b/src/VncApp/wwwroot/app/images/disconnect.svg @@ -0,0 +1,94 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/drag.svg b/src/VncApp/wwwroot/app/images/drag.svg new file mode 100644 index 0000000..139caf9 --- /dev/null +++ b/src/VncApp/wwwroot/app/images/drag.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/error.svg b/src/VncApp/wwwroot/app/images/error.svg new file mode 100644 index 0000000..8356d3f --- /dev/null +++ b/src/VncApp/wwwroot/app/images/error.svg @@ -0,0 +1,81 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/esc.svg b/src/VncApp/wwwroot/app/images/esc.svg new file mode 100644 index 0000000..830152b --- /dev/null +++ b/src/VncApp/wwwroot/app/images/esc.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/expander.svg b/src/VncApp/wwwroot/app/images/expander.svg new file mode 100644 index 0000000..e163535 --- /dev/null +++ b/src/VncApp/wwwroot/app/images/expander.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/fullscreen.svg b/src/VncApp/wwwroot/app/images/fullscreen.svg new file mode 100644 index 0000000..29bd05d --- /dev/null +++ b/src/VncApp/wwwroot/app/images/fullscreen.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/handle.svg b/src/VncApp/wwwroot/app/images/handle.svg new file mode 100644 index 0000000..4a7a126 --- /dev/null +++ b/src/VncApp/wwwroot/app/images/handle.svg @@ -0,0 +1,82 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/handle_bg.svg b/src/VncApp/wwwroot/app/images/handle_bg.svg new file mode 100644 index 0000000..7579c42 --- /dev/null +++ b/src/VncApp/wwwroot/app/images/handle_bg.svg @@ -0,0 +1,172 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/icons/Makefile b/src/VncApp/wwwroot/app/images/icons/Makefile new file mode 100644 index 0000000..03eaed0 --- /dev/null +++ b/src/VncApp/wwwroot/app/images/icons/Makefile @@ -0,0 +1,42 @@ +BROWSER_SIZES := 16 24 32 48 64 +#ANDROID_SIZES := 72 96 144 192 +# FIXME: The ICO is limited to 8 icons due to a Chrome bug: +# https://bugs.chromium.org/p/chromium/issues/detail?id=1381393 +ANDROID_SIZES := 96 144 192 +WEB_ICON_SIZES := $(BROWSER_SIZES) $(ANDROID_SIZES) + +#IOS_1X_SIZES := 20 29 40 76 # No such devices exist anymore +IOS_2X_SIZES := 40 58 80 120 152 167 +IOS_3X_SIZES := 60 87 120 180 +ALL_IOS_SIZES := $(IOS_1X_SIZES) $(IOS_2X_SIZES) $(IOS_3X_SIZES) + +ALL_ICONS := \ + $(ALL_IOS_SIZES:%=novnc-ios-%.png) \ + novnc.ico + +all: $(ALL_ICONS) + +# Our testing shows that the ICO file need to be sorted in largest to +# smallest to get the apporpriate behviour +WEB_ICON_SIZES_REVERSE := $(shell echo $(WEB_ICON_SIZES) | tr ' ' '\n' | sort -nr | tr '\n' ' ') +WEB_BASE_ICONS := $(WEB_ICON_SIZES_REVERSE:%=novnc-%.png) +.INTERMEDIATE: $(WEB_BASE_ICONS) + +novnc.ico: $(WEB_BASE_ICONS) + convert $(WEB_BASE_ICONS) "$@" + +# General conversion +novnc-%.png: novnc-icon.svg + convert -depth 8 -background transparent \ + -size $*x$* "$(lastword $^)" "$@" + +# iOS icons use their own SVG +novnc-ios-%.png: novnc-ios-icon.svg + convert -depth 8 -background transparent \ + -size $*x$* "$(lastword $^)" "$@" + +# The smallest sizes are generated using a different SVG +novnc-16.png novnc-24.png novnc-32.png: novnc-icon-sm.svg + +clean: + rm -f *.png diff --git a/src/VncApp/wwwroot/app/images/icons/novnc-icon-sm.svg b/src/VncApp/wwwroot/app/images/icons/novnc-icon-sm.svg new file mode 100644 index 0000000..aa1c6f1 --- /dev/null +++ b/src/VncApp/wwwroot/app/images/icons/novnc-icon-sm.svg @@ -0,0 +1,163 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/icons/novnc-icon.svg b/src/VncApp/wwwroot/app/images/icons/novnc-icon.svg new file mode 100644 index 0000000..1efff91 --- /dev/null +++ b/src/VncApp/wwwroot/app/images/icons/novnc-icon.svg @@ -0,0 +1,163 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/icons/novnc-ios-120.png b/src/VncApp/wwwroot/app/images/icons/novnc-ios-120.png new file mode 100644 index 0000000000000000000000000000000000000000..8da7bab3d0f0ff810af3073b14b52b557f91ada7 GIT binary patch literal 3215 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 literal 0 HcmV?d00001 diff --git a/src/VncApp/wwwroot/app/images/icons/novnc-ios-152.png b/src/VncApp/wwwroot/app/images/icons/novnc-ios-152.png new file mode 100644 index 0000000000000000000000000000000000000000..60b2bcef533e2030e2bb8d92bbbdf010d89f2d4f GIT binary patch literal 4190 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 JT=lypi-cL*%GNG~DMq5={U(y<`j@sI-2B}*(J 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 literal 0 HcmV?d00001 diff --git a/src/VncApp/wwwroot/app/images/icons/novnc-ios-40.png b/src/VncApp/wwwroot/app/images/icons/novnc-ios-40.png new file mode 100644 index 0000000000000000000000000000000000000000..cf14894daf12da14c536b26101fac933d47ddffe GIT binary patch literal 1245 zcmZ{iYfMuI6vxl)6G|}`ETyG9N?i+WX}N7Fr7b9ZT-x%oXj@QVwx#8v4nZpswndqA zgQ9_D(I9BFjx2*QhmYZ=(TwSIb2C#y6eQ6&l!-Vs(`7nQceii*un+(9JO7jXb3UBY zWiPcvGZGj85N)%XR}oDAM-gPAp5|NE5unr=N(=x;d!iOSRKoLXtgA`@+C%_5IspD6 zMmz2SY{dZXy8(240P#)xPnG2Ykm&Ye2d+>klu9M7i3U4>+)Nf|1Tu{*vM~~Q8(~>k zDwT@5i3+U%P5>8>>?EFp2h{+Z0k(liB+AOlg7qK}2;_1(%fUiLXp}oDDJe;#(FldY zn6wzChnbj|sMTt7b93VyaZ9vI(hO;gdIoHV{QP{rnGZF<=kswKk132H=}C-I1_>j{ zWHOeHMJ^yCI6}%Jp*$4BFss#Sv)Ps}Uw-IN?CaOy^Rb(o1$*~K1_CJ;E>P8K`HdU2 z>(|M0x%lka=*2~lNF-*ndBqC(!-vS!6kwP%D+`;Mp*?y8%a)-nEvX|TRD}YYo~BMt zg4fHtcoBw&VfSw6?q1r`64lw6xNRFUI}1HMjK)T8RTW*M$()@fEi8aqEz;}d3k&2s zcOW^L<@M6X$0==XXmxc&TN}5hhko!N+v7p<@}yH!NKQ_UN~O4ZmHhlU7!1ipMbc-_ zkckOMN=mR;MDz2=lP6%erEV=x%>dcDPBF&d4;lel|ar34Ufk;Obx?*F};Fp*8xHCqT4 z{i}th!qr4W57Wsr9^9NCJ7`a~N-?Qd z;t;sP%8)Ux)~Qyjw?=0$)Mc#o?eG3P^7+modwlWz`JJo;P6BtJufM;4U!|M&vGBv& zvJLp4aYLt(SE-Mx z_lCb4`||SG8S>%Y@bS-1)5D|J8Mai@y6vw!x|sGL^CQvB`zwzg&_y#psT4@}D~@m9 zORY*hw{hmNc1!AbJx|^}((AeTj<%^!UJ)@TU;AMGq)!}?QQ5frFdARs@%!;z-|lgp z7iSz7l!hNjeqjkFZzLMc-!9f~X+rqZdhr5L8eFnzVK@;`yMHu)NA WTmL^$2nT*80${^S%}0#x_x=V(2bBr{ literal 0 HcmV?d00001 diff --git a/src/VncApp/wwwroot/app/images/icons/novnc-ios-58.png b/src/VncApp/wwwroot/app/images/icons/novnc-ios-58.png new file mode 100644 index 0000000000000000000000000000000000000000..f6dfbebd2e233bfec83a4d557187eec9e660d0ed GIT binary patch literal 1602 zcmZ{iX;hO}8pofPm_(LLXtNxNq{$D$z~STV6>%ZT?hz_xL{C%D2t_a zX^T@p#!j(NK|w4>+)yhmgM=bic1554C+_jjLrp8q}f zKKFkxEyYOlVtD}o&1}-A6U6@)i%G;hl6{p$V9{nxvId~D+IxN@naG2)OzFu0C7}T2 z?*YsbTjfsxico;38wl;+00OpucGao|@Mug+vKeGD8HQnO8=JL;#a_)8Xa#}<0ecOb zujfZbMk0Fv7>;WhQ9*?I`C_n`a z1|uLKz&p_!ih#vpk&DQ%68!!BX*wE{$&8AMl1L@ z`Tch=7!1wLw7EIZY6Gp-@VPnU=ux2)>Tm>wg!snA#nsgKuU@^>Zs(Vm69t^QIyiNT{PD+LD_5>msiaSyApQLy z7K<=UHazS#F+sGHQd>)0EVQR*k<;l{S-C7X*Qc~JC^r{^gM)EAVra<2ZfDBn=$$(x zmkXp)epHlne4Kpe4*2GfeQ7m|{)e8-NUvNGZ*memS28+Ux1ct}WJA7yHa=sCyj z_W1sLqTV+rhci5k%*-I`*YnhBq_~(~SQw<$`XnWVXJ+D;FMD=$Kury8)vD06G+{)9 z$LZ6H8ykJBR<_wpR;wv*y|qFjp$LUSrBa%f=ELVx;^OEQ3nej;YBEvze11$!j8?1F zXf!I7O0U-w?)^Joqphch85WGY1nml;7INS|9g}HCG;3%rGAIjt%%??0NvTBcJgl@x5JN za9_mkklx!f**)EwX`{bp)+qCI{!;^U$ENEi_w1c@-d-!=H>-aYrVhwV=e34y+HlXq zeQzFrx8<}%VL8vLOYf$%Wh6dry7;oS*LdUU0nZaf&xY$uNTcZ54?f*{!K!aQ@~!-| zSzf>jd6iT9?bCti_=^Y5$9#0C`lR@sL*0xP8Gb<#e{pIRJ3e`!u^{*EuIE*b#-xj2w!!(OgH>JEe?4KRoZD-e`~Co)Ac_(2;NI2K|C6+^x*yFmv_t?+(_uhVnj(N#t4j8;mc=3PzOK z+-rEa^oq|~&uMF+BH-ta_EzzcPuQ28&y+9j@%LF?WItNi5BWLavrEQE&f1P$gIHA!W=Ff(b`n!%H^4ARs;>kK{XF_r>b=o-d za>2DQf9vko`*xOf{ZdB1+AW-)dDcY{>zZT7nj~BEv#t&G73VE|)WWx?$t895%(_}l z+F!~eA{7f8Kdff*vAFy->(6bGKbB^xhivoJoxyGYu=fiuT}jVqoAHbAWwqR-r~gP8 zmG3aT?XYijWaC+d*#rPXF-$DO#299i$#FCik5r0K6h~3jI)3IK1O?mdc{$EM7g(U- PF(Cl6Aw}Pz-B9^oj2c9P literal 0 HcmV?d00001 diff --git a/src/VncApp/wwwroot/app/images/icons/novnc-ios-60.png b/src/VncApp/wwwroot/app/images/icons/novnc-ios-60.png new file mode 100644 index 0000000000000000000000000000000000000000..8cda29530c8fc0a3ee7499be716f90e22b2c4fc8 GIT binary patch literal 1595 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 literal 0 HcmV?d00001 diff --git a/src/VncApp/wwwroot/app/images/icons/novnc-ios-87.png b/src/VncApp/wwwroot/app/images/icons/novnc-ios-87.png new file mode 100644 index 0000000000000000000000000000000000000000..4377d874b18d965cb430f80dc1f97d3e8f0daff0 GIT binary patch literal 2708 zcmbW3c{tQv8^?cx3`Ptg)mUQ;M#k93q=?57GM19D%!Dk-HWV_9EsQ5>2qB)3p0rq| zgh_Tv?^vG59!AK%3|X?g)BE51$NSHFU)Oy;=RW6r&$+I1|8d_bwl-!*1x^Y80C3d8 z+{BKd8&9+Y2)!*VuwuU#}V;gDlH7Z@=d@CTV+C2?5%A5Us5bK*?Ep%&Jr;2A*) zA#Q~yztp@q$Kowaj2yy;m-6rU!1|>-8oa+*+)~Q(q>o^SOI=6ah}82&emQmV;ljCG z6;THhsF8}f>6?4dsbZg})Hm|-tva%n#kTjqn)S;cc`$e`0blE4J}#aSkjpHF`&JDx z7w@ddEG#cxcc;@e8P*1c4Iy0x`lJ~Ky@CB}ze`_kX=w>3`Gd=G88q4{$(m1=d!6=w z!Uk$A7`z!*gg{xIjC?6=VgXvn!BH~wR^1GzIz%vB7MW0@d<5ef8JS@EWYqb&@q?Pv zQm6UolW_*+xn*%vF+x2c3~siXG3kF>zBNf~tEGEAXm0@I#u9h84+zzTd~T>FMjsd|OCB@G0dh@0-)! z$hSWAbxy1S^wQ#o{JVDbpDXx=Jut7+CtTI>J{Q}0-q}^F4t>kLSL^0>Z6q=I#c46q z6Ri2fwVB^PZ_^Wsl-F+U2W5GI5dTv1IU4FwJ`*vatGT9;)rTBBsEFN8u1i%1dFH=N{(%gTuv9s-;5{iB zLUB=~{3BS(Ga*PR2jww&)21w6IKlnPcUykCJ-2F(M)F3gPE(*A3s9xcnFmMc6XbD82cw0 zUfvvu3*YQd1^ViJ*=%;QiTq$K$@v&DcF^zRUX-7^U`vTrm?$j?VD zoK?aJBh|INL&}H#F^5vy^QzxnF5X%H1TBc155dKShB3v%$c8*}wW z%AJ*aUYDu^j$knPdUtNoSs+^nF~;p@a6h*gsR}2*^}BED>qX&8W~&S33yx=_NOb@4 zOZk9XglYZ#6It9i9PYv8E4C7z1cDmIKs|o%vGm}(?j$LL861v?3nky)LN3=_u*|$v zz!SZbNMO(0eLo<|1;f@*9vdhH9YlFF#VO=HIi(AvcVw{#Xz95pcLLL%q@a#q^#y+mw@_{xV5(4yXkb+@fW`WNNp(Fxh0HTk2Av4YK9 zAF&^E&zpPhV|yPl8yg$7osa>{R%HohYgnxw%;0h!0*`DYbz8%K#(Onihp^_Jl`D19 zcos*%gG)c(?+g*3gN)n9x(Xg94G;2dY^76X6*Es6LC@nJc{zwbA^*I3Y&2lU`|XV@ zJaGG;;)%!I^Us?mVj)o*A}H-Pm97vqHH{y0zHQqzQQg(m2q9Pv7gfdIzVNGqqodcp z)x#P#TaXt#&6nsE`|aCR9wI;7>h61ZyU?t-PPQAd5;@D#%G}kty$Ys@ z!7xQ)K&9t;Y&Lr;JuG)j9VX-v9^?_!a;6Sdea`kE2H^A7nXvIFkG9+6J5YhdiVEAo{ohGxh8PX{+oxEKwek?? zZT`!5R^Aph#E89m1yNRRFE-)NjIym$9AiR;Az2(u@r6r`yx=uux;dTW3vp3!Auz|Hvs=mlctO zP^v(rU@*P03R(8zMe2MDRF^ve>V(WH8W<7`*0i;^FCOlKlh`sSgj@nNx#;hq z<*+HHb+fI=uSfiEfhF*GmLmWx MOl?eF8x!LG4f?<8TL1t6 literal 0 HcmV?d00001 diff --git a/src/VncApp/wwwroot/app/images/icons/novnc-ios-icon.svg b/src/VncApp/wwwroot/app/images/icons/novnc-ios-icon.svg new file mode 100644 index 0000000..009452a --- /dev/null +++ b/src/VncApp/wwwroot/app/images/icons/novnc-ios-icon.svg @@ -0,0 +1,183 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/icons/novnc.ico b/src/VncApp/wwwroot/app/images/icons/novnc.ico new file mode 100644 index 0000000000000000000000000000000000000000..c3bc58e389396b7beb0fb0a97386e2af3604b386 GIT binary patch literal 310566 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 + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/keyboard.svg b/src/VncApp/wwwroot/app/images/keyboard.svg new file mode 100644 index 0000000..137b350 --- /dev/null +++ b/src/VncApp/wwwroot/app/images/keyboard.svg @@ -0,0 +1,88 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/power.svg b/src/VncApp/wwwroot/app/images/power.svg new file mode 100644 index 0000000..4925d3e --- /dev/null +++ b/src/VncApp/wwwroot/app/images/power.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/settings.svg b/src/VncApp/wwwroot/app/images/settings.svg new file mode 100644 index 0000000..dbb2e80 --- /dev/null +++ b/src/VncApp/wwwroot/app/images/settings.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/tab.svg b/src/VncApp/wwwroot/app/images/tab.svg new file mode 100644 index 0000000..1ccb322 --- /dev/null +++ b/src/VncApp/wwwroot/app/images/tab.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/toggleextrakeys.svg b/src/VncApp/wwwroot/app/images/toggleextrakeys.svg new file mode 100644 index 0000000..b578c0d --- /dev/null +++ b/src/VncApp/wwwroot/app/images/toggleextrakeys.svg @@ -0,0 +1,90 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/warning.svg b/src/VncApp/wwwroot/app/images/warning.svg new file mode 100644 index 0000000..7114f9b --- /dev/null +++ b/src/VncApp/wwwroot/app/images/warning.svg @@ -0,0 +1,81 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/src/VncApp/wwwroot/app/images/windows.svg b/src/VncApp/wwwroot/app/images/windows.svg new file mode 100644 index 0000000..ad5eec3 --- /dev/null +++ b/src/VncApp/wwwroot/app/images/windows.svg @@ -0,0 +1,65 @@ + + + +image/svg+xml + + + \ No newline at end of file diff --git a/src/VncApp/wwwroot/app/locale/README b/src/VncApp/wwwroot/app/locale/README new file mode 100644 index 0000000..ca4f548 --- /dev/null +++ b/src/VncApp/wwwroot/app/locale/README @@ -0,0 +1 @@ +DO NOT MODIFY THE FILES IN THIS FOLDER, THEY ARE AUTOMATICALLY GENERATED FROM THE PO-FILES. diff --git a/src/VncApp/wwwroot/app/locale/cs.json b/src/VncApp/wwwroot/app/locale/cs.json new file mode 100644 index 0000000..589145e --- /dev/null +++ b/src/VncApp/wwwroot/app/locale/cs.json @@ -0,0 +1,71 @@ +{ + "Connecting...": "Připojení...", + "Disconnecting...": "Odpojení...", + "Reconnecting...": "Obnova připojení...", + "Internal error": "Vnitřní chyba", + "Must set host": "Hostitel musí být nastavení", + "Connected (encrypted) to ": "Připojení (šifrované) k ", + "Connected (unencrypted) to ": "Připojení (nešifrované) k ", + "Something went wrong, connection is closed": "Něco se pokazilo, odpojeno", + "Failed to connect to server": "Chyba připojení k serveru", + "Disconnected": "Odpojeno", + "New connection has been rejected with reason: ": "Nové připojení bylo odmítnuto s odůvodněním: ", + "New connection has been rejected": "Nové připojení bylo odmítnuto", + "Password is required": "Je vyžadováno heslo", + "noVNC encountered an error:": "noVNC narazilo na chybu:", + "Hide/Show the control bar": "Skrýt/zobrazit ovládací panel", + "Move/Drag Viewport": "Přesunout/přetáhnout výřez", + "viewport drag": "přesun výřezu", + "Active Mouse Button": "Aktivní tlačítka myši", + "No mousebutton": "Žádné", + "Left mousebutton": "Levé tlačítko myši", + "Middle mousebutton": "Prostřední tlačítko myši", + "Right mousebutton": "Pravé tlačítko myši", + "Keyboard": "Klávesnice", + "Show Keyboard": "Zobrazit klávesnici", + "Extra keys": "Extra klávesy", + "Show Extra Keys": "Zobrazit extra klávesy", + "Ctrl": "Ctrl", + "Toggle Ctrl": "Přepnout Ctrl", + "Alt": "Alt", + "Toggle Alt": "Přepnout Alt", + "Send Tab": "Odeslat tabulátor", + "Tab": "Tab", + "Esc": "Esc", + "Send Escape": "Odeslat Esc", + "Ctrl+Alt+Del": "Ctrl+Alt+Del", + "Send Ctrl-Alt-Del": "Poslat Ctrl-Alt-Del", + "Shutdown/Reboot": "Vypnutí/Restart", + "Shutdown/Reboot...": "Vypnutí/Restart...", + "Power": "Napájení", + "Shutdown": "Vypnout", + "Reboot": "Restart", + "Reset": "Reset", + "Clipboard": "Schránka", + "Clear": "Vymazat", + "Fullscreen": "Celá obrazovka", + "Settings": "Nastavení", + "Shared Mode": "Sdílený režim", + "View Only": "Pouze prohlížení", + "Clip to Window": "Přizpůsobit oknu", + "Scaling Mode:": "Přizpůsobení velikosti", + "None": "Žádné", + "Local Scaling": "Místní", + "Remote Resizing": "Vzdálené", + "Advanced": "Pokročilé", + "Repeater ID:": "ID opakovače", + "WebSocket": "WebSocket", + "Encrypt": "Šifrování:", + "Host:": "Hostitel:", + "Port:": "Port:", + "Path:": "Cesta", + "Automatic Reconnect": "Automatická obnova připojení", + "Reconnect Delay (ms):": "Zpoždění připojení (ms)", + "Show Dot when No Cursor": "Tečka místo chybějícího kurzoru myši", + "Logging:": "Logování:", + "Disconnect": "Odpojit", + "Connect": "Připojit", + "Password:": "Heslo", + "Send Password": "Odeslat heslo", + "Cancel": "Zrušit" +} \ No newline at end of file diff --git a/src/VncApp/wwwroot/app/locale/de.json b/src/VncApp/wwwroot/app/locale/de.json new file mode 100644 index 0000000..62e7336 --- /dev/null +++ b/src/VncApp/wwwroot/app/locale/de.json @@ -0,0 +1,69 @@ +{ + "Connecting...": "Verbinden...", + "Disconnecting...": "Verbindung trennen...", + "Reconnecting...": "Verbindung wiederherstellen...", + "Internal error": "Interner Fehler", + "Must set host": "Richten Sie den Server ein", + "Connected (encrypted) to ": "Verbunden mit (verschlüsselt) ", + "Connected (unencrypted) to ": "Verbunden mit (unverschlüsselt) ", + "Something went wrong, connection is closed": "Etwas lief schief, Verbindung wurde getrennt", + "Disconnected": "Verbindung zum Server getrennt", + "New connection has been rejected with reason: ": "Verbindung wurde aus folgendem Grund abgelehnt: ", + "New connection has been rejected": "Verbindung wurde abgelehnt", + "Password is required": "Passwort ist erforderlich", + "noVNC encountered an error:": "Ein Fehler ist aufgetreten:", + "Hide/Show the control bar": "Kontrollleiste verstecken/anzeigen", + "Move/Drag Viewport": "Ansichtsfenster verschieben/ziehen", + "viewport drag": "Ansichtsfenster ziehen", + "Active Mouse Button": "Aktive Maustaste", + "No mousebutton": "Keine Maustaste", + "Left mousebutton": "Linke Maustaste", + "Middle mousebutton": "Mittlere Maustaste", + "Right mousebutton": "Rechte Maustaste", + "Keyboard": "Tastatur", + "Show Keyboard": "Tastatur anzeigen", + "Extra keys": "Zusatztasten", + "Show Extra Keys": "Zusatztasten anzeigen", + "Ctrl": "Strg", + "Toggle Ctrl": "Strg umschalten", + "Alt": "Alt", + "Toggle Alt": "Alt umschalten", + "Send Tab": "Tab senden", + "Tab": "Tab", + "Esc": "Esc", + "Send Escape": "Escape senden", + "Ctrl+Alt+Del": "Strg+Alt+Entf", + "Send Ctrl-Alt-Del": "Strg+Alt+Entf senden", + "Shutdown/Reboot": "Herunterfahren/Neustarten", + "Shutdown/Reboot...": "Herunterfahren/Neustarten...", + "Power": "Energie", + "Shutdown": "Herunterfahren", + "Reboot": "Neustarten", + "Reset": "Zurücksetzen", + "Clipboard": "Zwischenablage", + "Clear": "Löschen", + "Fullscreen": "Vollbild", + "Settings": "Einstellungen", + "Shared Mode": "Geteilter Modus", + "View Only": "Nur betrachten", + "Clip to Window": "Auf Fenster begrenzen", + "Scaling Mode:": "Skalierungsmodus:", + "None": "Keiner", + "Local Scaling": "Lokales skalieren", + "Remote Resizing": "Serverseitiges skalieren", + "Advanced": "Erweitert", + "Repeater ID:": "Repeater ID:", + "WebSocket": "WebSocket", + "Encrypt": "Verschlüsselt", + "Host:": "Server:", + "Port:": "Port:", + "Path:": "Pfad:", + "Automatic Reconnect": "Automatisch wiederverbinden", + "Reconnect Delay (ms):": "Wiederverbindungsverzögerung (ms):", + "Logging:": "Protokollierung:", + "Disconnect": "Verbindung trennen", + "Connect": "Verbinden", + "Password:": "Passwort:", + "Cancel": "Abbrechen", + "Canvas not supported.": "Canvas nicht unterstützt." +} \ No newline at end of file diff --git a/src/VncApp/wwwroot/app/locale/el.json b/src/VncApp/wwwroot/app/locale/el.json new file mode 100644 index 0000000..f801251 --- /dev/null +++ b/src/VncApp/wwwroot/app/locale/el.json @@ -0,0 +1,69 @@ +{ + "Connecting...": "Συνδέεται...", + "Disconnecting...": "Aποσυνδέεται...", + "Reconnecting...": "Επανασυνδέεται...", + "Internal error": "Εσωτερικό σφάλμα", + "Must set host": "Πρέπει να οριστεί ο διακομιστής", + "Connected (encrypted) to ": "Συνδέθηκε (κρυπτογραφημένα) με το ", + "Connected (unencrypted) to ": "Συνδέθηκε (μη κρυπτογραφημένα) με το ", + "Something went wrong, connection is closed": "Κάτι πήγε στραβά, η σύνδεση διακόπηκε", + "Disconnected": "Αποσυνδέθηκε", + "New connection has been rejected with reason: ": "Η νέα σύνδεση απορρίφθηκε διότι: ", + "New connection has been rejected": "Η νέα σύνδεση απορρίφθηκε ", + "Password is required": "Απαιτείται ο κωδικός πρόσβασης", + "noVNC encountered an error:": "το noVNC αντιμετώπισε ένα σφάλμα:", + "Hide/Show the control bar": "Απόκρυψη/Εμφάνιση γραμμής ελέγχου", + "Move/Drag Viewport": "Μετακίνηση/Σύρσιμο Θεατού πεδίου", + "viewport drag": "σύρσιμο θεατού πεδίου", + "Active Mouse Button": "Ενεργό Πλήκτρο Ποντικιού", + "No mousebutton": "Χωρίς Πλήκτρο Ποντικιού", + "Left mousebutton": "Αριστερό Πλήκτρο Ποντικιού", + "Middle mousebutton": "Μεσαίο Πλήκτρο Ποντικιού", + "Right mousebutton": "Δεξί Πλήκτρο Ποντικιού", + "Keyboard": "Πληκτρολόγιο", + "Show Keyboard": "Εμφάνιση Πληκτρολογίου", + "Extra keys": "Επιπλέον πλήκτρα", + "Show Extra Keys": "Εμφάνιση Επιπλέον Πλήκτρων", + "Ctrl": "Ctrl", + "Toggle Ctrl": "Εναλλαγή Ctrl", + "Alt": "Alt", + "Toggle Alt": "Εναλλαγή Alt", + "Send Tab": "Αποστολή Tab", + "Tab": "Tab", + "Esc": "Esc", + "Send Escape": "Αποστολή Escape", + "Ctrl+Alt+Del": "Ctrl+Alt+Del", + "Send Ctrl-Alt-Del": "Αποστολή Ctrl-Alt-Del", + "Shutdown/Reboot": "Κλείσιμο/Επανεκκίνηση", + "Shutdown/Reboot...": "Κλείσιμο/Επανεκκίνηση...", + "Power": "Απενεργοποίηση", + "Shutdown": "Κλείσιμο", + "Reboot": "Επανεκκίνηση", + "Reset": "Επαναφορά", + "Clipboard": "Πρόχειρο", + "Clear": "Καθάρισμα", + "Fullscreen": "Πλήρης Οθόνη", + "Settings": "Ρυθμίσεις", + "Shared Mode": "Κοινόχρηστη Λειτουργία", + "View Only": "Μόνο Θέαση", + "Clip to Window": "Αποκοπή στο όριο του Παράθυρου", + "Scaling Mode:": "Λειτουργία Κλιμάκωσης:", + "None": "Καμία", + "Local Scaling": "Τοπική Κλιμάκωση", + "Remote Resizing": "Απομακρυσμένη Αλλαγή μεγέθους", + "Advanced": "Για προχωρημένους", + "Repeater ID:": "Repeater ID:", + "WebSocket": "WebSocket", + "Encrypt": "Κρυπτογράφηση", + "Host:": "Όνομα διακομιστή:", + "Port:": "Πόρτα διακομιστή:", + "Path:": "Διαδρομή:", + "Automatic Reconnect": "Αυτόματη επανασύνδεση", + "Reconnect Delay (ms):": "Καθυστέρηση επανασύνδεσης (ms):", + "Logging:": "Καταγραφή:", + "Disconnect": "Αποσύνδεση", + "Connect": "Σύνδεση", + "Password:": "Κωδικός Πρόσβασης:", + "Cancel": "Ακύρωση", + "Canvas not supported.": "Δεν υποστηρίζεται το στοιχείο Canvas" +} \ No newline at end of file diff --git a/src/VncApp/wwwroot/app/locale/es.json b/src/VncApp/wwwroot/app/locale/es.json new file mode 100644 index 0000000..b9e663a --- /dev/null +++ b/src/VncApp/wwwroot/app/locale/es.json @@ -0,0 +1,68 @@ +{ + "Connecting...": "Conectando...", + "Connected (encrypted) to ": "Conectado (con encriptación) a", + "Connected (unencrypted) to ": "Conectado (sin encriptación) a", + "Disconnecting...": "Desconectando...", + "Disconnected": "Desconectado", + "Must set host": "Se debe configurar el host", + "Reconnecting...": "Reconectando...", + "Password is required": "La contraseña es obligatoria", + "Disconnect timeout": "Tiempo de desconexión agotado", + "noVNC encountered an error:": "noVNC ha encontrado un error:", + "Hide/Show the control bar": "Ocultar/Mostrar la barra de control", + "Move/Drag Viewport": "Mover/Arrastrar la ventana", + "viewport drag": "Arrastrar la ventana", + "Active Mouse Button": "Botón activo del ratón", + "No mousebutton": "Ningún botón del ratón", + "Left mousebutton": "Botón izquierdo del ratón", + "Middle mousebutton": "Botón central del ratón", + "Right mousebutton": "Botón derecho del ratón", + "Keyboard": "Teclado", + "Show Keyboard": "Mostrar teclado", + "Extra keys": "Teclas adicionales", + "Show Extra Keys": "Mostrar Teclas Adicionales", + "Ctrl": "Ctrl", + "Toggle Ctrl": "Pulsar/Soltar Ctrl", + "Alt": "Alt", + "Toggle Alt": "Pulsar/Soltar Alt", + "Send Tab": "Enviar Tabulación", + "Tab": "Tabulación", + "Esc": "Esc", + "Send Escape": "Enviar Escape", + "Ctrl+Alt+Del": "Ctrl+Alt+Del", + "Send Ctrl-Alt-Del": "Enviar Ctrl+Alt+Del", + "Shutdown/Reboot": "Apagar/Reiniciar", + "Shutdown/Reboot...": "Apagar/Reiniciar...", + "Power": "Encender", + "Shutdown": "Apagar", + "Reboot": "Reiniciar", + "Reset": "Restablecer", + "Clipboard": "Portapapeles", + "Clear": "Vaciar", + "Fullscreen": "Pantalla Completa", + "Settings": "Configuraciones", + "Encrypt": "Encriptar", + "Shared Mode": "Modo Compartido", + "View Only": "Solo visualización", + "Clip to Window": "Recortar al tamaño de la ventana", + "Scaling Mode:": "Modo de escalado:", + "None": "Ninguno", + "Local Scaling": "Escalado Local", + "Local Downscaling": "Reducción de escala local", + "Remote Resizing": "Cambio de tamaño remoto", + "Advanced": "Avanzado", + "Local Cursor": "Cursor Local", + "Repeater ID:": "ID del Repetidor:", + "WebSocket": "WebSocket", + "Host:": "Host:", + "Port:": "Puerto:", + "Path:": "Ruta:", + "Automatic Reconnect": "Reconexión automática", + "Reconnect Delay (ms):": "Retraso en la reconexión (ms):", + "Logging:": "Registrando:", + "Disconnect": "Desconectar", + "Connect": "Conectar", + "Password:": "Contraseña:", + "Cancel": "Cancelar", + "Canvas not supported.": "Canvas no soportado." +} \ No newline at end of file diff --git a/src/VncApp/wwwroot/app/locale/fr.json b/src/VncApp/wwwroot/app/locale/fr.json new file mode 100644 index 0000000..22531f7 --- /dev/null +++ b/src/VncApp/wwwroot/app/locale/fr.json @@ -0,0 +1,78 @@ +{ + "HTTPS is required for full functionality": "", + "Connecting...": "En cours de connexion...", + "Disconnecting...": "Déconnexion en cours...", + "Reconnecting...": "Reconnexion en cours...", + "Internal error": "Erreur interne", + "Must set host": "Doit définir l'hôte", + "Connected (encrypted) to ": "Connecté (chiffré) à ", + "Connected (unencrypted) to ": "Connecté (non chiffré) à ", + "Something went wrong, connection is closed": "Quelque chose s'est mal passé, la connexion a été fermée", + "Failed to connect to server": "Échec de connexion au serveur", + "Disconnected": "Déconnecté", + "New connection has been rejected with reason: ": "Une nouvelle connexion a été rejetée avec motif : ", + "New connection has been rejected": "Une nouvelle connexion a été rejetée", + "Credentials are required": "Les identifiants sont requis", + "noVNC encountered an error:": "noVNC a rencontré une erreur :", + "Hide/Show the control bar": "Masquer/Afficher la barre de contrôle", + "Drag": "Faire glisser", + "Move/Drag Viewport": "Déplacer/faire glisser le Viewport", + "Keyboard": "Clavier", + "Show Keyboard": "Afficher le clavier", + "Extra keys": "Touches supplémentaires", + "Show Extra Keys": "Afficher les touches supplémentaires", + "Ctrl": "Ctrl", + "Toggle Ctrl": "Basculer Ctrl", + "Alt": "Alt", + "Toggle Alt": "Basculer Alt", + "Toggle Windows": "Basculer Windows", + "Windows": "Windows", + "Send Tab": "Envoyer l'onglet", + "Tab": "l'onglet", + "Esc": "Esc", + "Send Escape": "Envoyer Escape", + "Ctrl+Alt+Del": "Ctrl+Alt+Del", + "Send Ctrl-Alt-Del": "Envoyer Ctrl-Alt-Del", + "Shutdown/Reboot": "Arrêter/Redémarrer", + "Shutdown/Reboot...": "Arrêter/Redémarrer...", + "Power": "Alimentation", + "Shutdown": "Arrêter", + "Reboot": "Redémarrer", + "Reset": "Réinitialiser", + "Clipboard": "Presse-papiers", + "Edit clipboard content in the textarea below.": "", + "Settings": "Paramètres", + "Shared Mode": "Mode partagé", + "View Only": "Afficher uniquement", + "Clip to Window": "Clip à fenêtre", + "Scaling Mode:": "Mode mise à l'échelle :", + "None": "Aucun", + "Local Scaling": "Mise à l'échelle locale", + "Remote Resizing": "Redimensionnement à distance", + "Advanced": "Avancé", + "Quality:": "Qualité :", + "Compression level:": "Niveau de compression :", + "Repeater ID:": "ID Répéteur :", + "WebSocket": "WebSocket", + "Encrypt": "Chiffrer", + "Host:": "Hôte :", + "Port:": "Port :", + "Path:": "Chemin :", + "Automatic Reconnect": "Reconnecter automatiquemen", + "Reconnect Delay (ms):": "Délai de reconnexion (ms) :", + "Show Dot when No Cursor": "Afficher le point lorsqu'il n'y a pas de curseur", + "Logging:": "Se connecter :", + "Version:": "Version :", + "Disconnect": "Déconnecter", + "Connect": "Connecter", + "Server identity": "", + "The server has provided the following identifying information:": "", + "Fingerprint:": "", + "Please verify that the information is correct and press \"Approve\". Otherwise press \"Reject\".": "", + "Approve": "", + "Reject": "", + "Username:": "Nom d'utilisateur :", + "Password:": "Mot de passe :", + "Send Credentials": "Envoyer les identifiants", + "Cancel": "Annuler" +} \ No newline at end of file diff --git a/src/VncApp/wwwroot/app/locale/it.json b/src/VncApp/wwwroot/app/locale/it.json new file mode 100644 index 0000000..6fd2570 --- /dev/null +++ b/src/VncApp/wwwroot/app/locale/it.json @@ -0,0 +1,72 @@ +{ + "Connecting...": "Connessione in corso...", + "Disconnecting...": "Disconnessione...", + "Reconnecting...": "Riconnessione...", + "Internal error": "Errore interno", + "Must set host": "Devi impostare l'host", + "Connected (encrypted) to ": "Connesso (crittografato) a ", + "Connected (unencrypted) to ": "Connesso (non crittografato) a", + "Something went wrong, connection is closed": "Qualcosa è andato storto, la connessione è stata chiusa", + "Failed to connect to server": "Impossibile connettersi al server", + "Disconnected": "Disconnesso", + "New connection has been rejected with reason: ": "La nuova connessione è stata rifiutata con motivo: ", + "New connection has been rejected": "La nuova connessione è stata rifiutata", + "Credentials are required": "Le credenziali sono obbligatorie", + "noVNC encountered an error:": "noVNC ha riscontrato un errore:", + "Hide/Show the control bar": "Nascondi/Mostra la barra di controllo", + "Drag": "", + "Move/Drag Viewport": "", + "Keyboard": "Tastiera", + "Show Keyboard": "Mostra tastiera", + "Extra keys": "Tasti Aggiuntivi", + "Show Extra Keys": "Mostra Tasti Aggiuntivi", + "Ctrl": "Ctrl", + "Toggle Ctrl": "Tieni premuto Ctrl", + "Alt": "Alt", + "Toggle Alt": "Tieni premuto Alt", + "Toggle Windows": "Tieni premuto Windows", + "Windows": "Windows", + "Send Tab": "Invia Tab", + "Tab": "Tab", + "Esc": "Esc", + "Send Escape": "Invia Esc", + "Ctrl+Alt+Del": "Ctrl+Alt+Canc", + "Send Ctrl-Alt-Del": "Invia Ctrl-Alt-Canc", + "Shutdown/Reboot": "Spegnimento/Riavvio", + "Shutdown/Reboot...": "Spegnimento/Riavvio...", + "Power": "Alimentazione", + "Shutdown": "Spegnimento", + "Reboot": "Riavvio", + "Reset": "Reset", + "Clipboard": "Clipboard", + "Clear": "Pulisci", + "Fullscreen": "Schermo intero", + "Settings": "Impostazioni", + "Shared Mode": "Modalità condivisa", + "View Only": "Sola Visualizzazione", + "Clip to Window": "", + "Scaling Mode:": "Modalità di ridimensionamento:", + "None": "Nessuna", + "Local Scaling": "Ridimensionamento Locale", + "Remote Resizing": "Ridimensionamento Remoto", + "Advanced": "Avanzate", + "Quality:": "Qualità:", + "Compression level:": "Livello Compressione:", + "Repeater ID:": "ID Ripetitore:", + "WebSocket": "WebSocket", + "Encrypt": "Crittografa", + "Host:": "Host:", + "Port:": "Porta:", + "Path:": "Percorso:", + "Automatic Reconnect": "Riconnessione Automatica", + "Reconnect Delay (ms):": "Ritardo Riconnessione (ms):", + "Show Dot when No Cursor": "Mostra Punto quando Nessun Cursore", + "Logging:": "", + "Version:": "Versione:", + "Disconnect": "Disconnetti", + "Connect": "Connetti", + "Username:": "Utente:", + "Password:": "Password:", + "Send Credentials": "Invia Credenziale", + "Cancel": "Annulla" +} \ No newline at end of file diff --git a/src/VncApp/wwwroot/app/locale/ja.json b/src/VncApp/wwwroot/app/locale/ja.json new file mode 100644 index 0000000..43fc5bf --- /dev/null +++ b/src/VncApp/wwwroot/app/locale/ja.json @@ -0,0 +1,72 @@ +{ + "Connecting...": "接続しています...", + "Disconnecting...": "切断しています...", + "Reconnecting...": "再接続しています...", + "Internal error": "内部エラー", + "Must set host": "ホストを設定する必要があります", + "Connected (encrypted) to ": "接続しました (暗号化済み): ", + "Connected (unencrypted) to ": "接続しました (暗号化されていません): ", + "Something went wrong, connection is closed": "何らかの問題で、接続が閉じられました", + "Failed to connect to server": "サーバーへの接続に失敗しました", + "Disconnected": "切断しました", + "New connection has been rejected with reason: ": "新規接続は次の理由で拒否されました: ", + "New connection has been rejected": "新規接続は拒否されました", + "Credentials are required": "資格情報が必要です", + "noVNC encountered an error:": "noVNC でエラーが発生しました:", + "Hide/Show the control bar": "コントロールバーを隠す/表示する", + "Drag": "ドラッグ", + "Move/Drag Viewport": "ビューポートを移動/ドラッグ", + "Keyboard": "キーボード", + "Show Keyboard": "キーボードを表示", + "Extra keys": "追加キー", + "Show Extra Keys": "追加キーを表示", + "Ctrl": "Ctrl", + "Toggle Ctrl": "Ctrl キーを切り替え", + "Alt": "Alt", + "Toggle Alt": "Alt キーを切り替え", + "Toggle Windows": "Windows キーを切り替え", + "Windows": "Windows", + "Send Tab": "Tab キーを送信", + "Tab": "Tab", + "Esc": "Esc", + "Send Escape": "Escape キーを送信", + "Ctrl+Alt+Del": "Ctrl+Alt+Del", + "Send Ctrl-Alt-Del": "Ctrl-Alt-Del を送信", + "Shutdown/Reboot": "シャットダウン/再起動", + "Shutdown/Reboot...": "シャットダウン/再起動...", + "Power": "電源", + "Shutdown": "シャットダウン", + "Reboot": "再起動", + "Reset": "リセット", + "Clipboard": "クリップボード", + "Clear": "クリア", + "Fullscreen": "全画面表示", + "Settings": "設定", + "Shared Mode": "共有モード", + "View Only": "表示のみ", + "Clip to Window": "ウィンドウにクリップ", + "Scaling Mode:": "スケーリングモード:", + "None": "なし", + "Local Scaling": "ローカルスケーリング", + "Remote Resizing": "リモートでリサイズ", + "Advanced": "高度", + "Quality:": "品質:", + "Compression level:": "圧縮レベル:", + "Repeater ID:": "リピーター ID:", + "WebSocket": "WebSocket", + "Encrypt": "暗号化", + "Host:": "ホスト:", + "Port:": "ポート:", + "Path:": "パス:", + "Automatic Reconnect": "自動再接続", + "Reconnect Delay (ms):": "再接続する遅延 (ミリ秒):", + "Show Dot when No Cursor": "カーソルがないときにドットを表示", + "Logging:": "ロギング:", + "Version:": "バージョン:", + "Disconnect": "切断", + "Connect": "接続", + "Username:": "ユーザー名:", + "Password:": "パスワード:", + "Send Credentials": "資格情報を送信", + "Cancel": "キャンセル" +} \ No newline at end of file diff --git a/src/VncApp/wwwroot/app/locale/ko.json b/src/VncApp/wwwroot/app/locale/ko.json new file mode 100644 index 0000000..e4ecddc --- /dev/null +++ b/src/VncApp/wwwroot/app/locale/ko.json @@ -0,0 +1,70 @@ +{ + "Connecting...": "연결중...", + "Disconnecting...": "연결 해제중...", + "Reconnecting...": "재연결중...", + "Internal error": "내부 오류", + "Must set host": "호스트는 설정되어야 합니다.", + "Connected (encrypted) to ": "다음과 (암호화되어) 연결되었습니다:", + "Connected (unencrypted) to ": "다음과 (암호화 없이) 연결되었습니다:", + "Something went wrong, connection is closed": "무언가 잘못되었습니다, 연결이 닫혔습니다.", + "Failed to connect to server": "서버에 연결하지 못했습니다.", + "Disconnected": "연결이 해제되었습니다.", + "New connection has been rejected with reason: ": "새 연결이 다음 이유로 거부되었습니다:", + "New connection has been rejected": "새 연결이 거부되었습니다.", + "Password is required": "비밀번호가 필요합니다.", + "noVNC encountered an error:": "noVNC에 오류가 발생했습니다:", + "Hide/Show the control bar": "컨트롤 바 숨기기/보이기", + "Move/Drag Viewport": "움직이기/드래그 뷰포트", + "viewport drag": "뷰포트 드래그", + "Active Mouse Button": "마우스 버튼 활성화", + "No mousebutton": "마우스 버튼 없음", + "Left mousebutton": "왼쪽 마우스 버튼", + "Middle mousebutton": "중간 마우스 버튼", + "Right mousebutton": "오른쪽 마우스 버튼", + "Keyboard": "키보드", + "Show Keyboard": "키보드 보이기", + "Extra keys": "기타 키들", + "Show Extra Keys": "기타 키들 보이기", + "Ctrl": "Ctrl", + "Toggle Ctrl": "Ctrl 켜기/끄기", + "Alt": "Alt", + "Toggle Alt": "Alt 켜기/끄기", + "Send Tab": "Tab 보내기", + "Tab": "Tab", + "Esc": "Esc", + "Send Escape": "Esc 보내기", + "Ctrl+Alt+Del": "Ctrl+Alt+Del", + "Send Ctrl-Alt-Del": "Ctrl+Alt+Del 보내기", + "Shutdown/Reboot": "셧다운/리붓", + "Shutdown/Reboot...": "셧다운/리붓...", + "Power": "전원", + "Shutdown": "셧다운", + "Reboot": "리붓", + "Reset": "리셋", + "Clipboard": "클립보드", + "Clear": "지우기", + "Fullscreen": "전체화면", + "Settings": "설정", + "Shared Mode": "공유 모드", + "View Only": "보기 전용", + "Clip to Window": "창에 클립", + "Scaling Mode:": "스케일링 모드:", + "None": "없음", + "Local Scaling": "로컬 스케일링", + "Remote Resizing": "원격 크기 조절", + "Advanced": "고급", + "Repeater ID:": "중계 ID", + "WebSocket": "웹소켓", + "Encrypt": "암호화", + "Host:": "호스트:", + "Port:": "포트:", + "Path:": "위치:", + "Automatic Reconnect": "자동 재연결", + "Reconnect Delay (ms):": "재연결 지연 시간 (ms)", + "Logging:": "로깅", + "Disconnect": "연결 해제", + "Connect": "연결", + "Password:": "비밀번호:", + "Send Password": "비밀번호 전송", + "Cancel": "취소" +} \ No newline at end of file diff --git a/src/VncApp/wwwroot/app/locale/nl.json b/src/VncApp/wwwroot/app/locale/nl.json new file mode 100644 index 0000000..0cdcc92 --- /dev/null +++ b/src/VncApp/wwwroot/app/locale/nl.json @@ -0,0 +1,73 @@ +{ + "Connecting...": "Verbinden...", + "Disconnecting...": "Verbinding verbreken...", + "Reconnecting...": "Opnieuw verbinding maken...", + "Internal error": "Interne fout", + "Must set host": "Host moeten worden ingesteld", + "Connected (encrypted) to ": "Verbonden (versleuteld) met ", + "Connected (unencrypted) to ": "Verbonden (onversleuteld) met ", + "Something went wrong, connection is closed": "Er iets fout gelopen, verbinding werd verbroken", + "Failed to connect to server": "Verbinding maken met server is mislukt", + "Disconnected": "Verbinding verbroken", + "New connection has been rejected with reason: ": "Nieuwe verbinding is geweigerd omwille van de volgende reden: ", + "New connection has been rejected": "Nieuwe verbinding is geweigerd", + "Password is required": "Wachtwoord is vereist", + "noVNC encountered an error:": "noVNC heeft een fout bemerkt:", + "Hide/Show the control bar": "Verberg/Toon de bedieningsbalk", + "Move/Drag Viewport": "Verplaats/Versleep Kijkvenster", + "viewport drag": "kijkvenster slepen", + "Active Mouse Button": "Actieve Muisknop", + "No mousebutton": "Geen muisknop", + "Left mousebutton": "Linker muisknop", + "Middle mousebutton": "Middelste muisknop", + "Right mousebutton": "Rechter muisknop", + "Keyboard": "Toetsenbord", + "Show Keyboard": "Toon Toetsenbord", + "Extra keys": "Extra toetsen", + "Show Extra Keys": "Toon Extra Toetsen", + "Ctrl": "Ctrl", + "Toggle Ctrl": "Ctrl omschakelen", + "Alt": "Alt", + "Toggle Alt": "Alt omschakelen", + "Toggle Windows": "Windows omschakelen", + "Windows": "Windows", + "Send Tab": "Tab Sturen", + "Tab": "Tab", + "Esc": "Esc", + "Send Escape": "Escape Sturen", + "Ctrl+Alt+Del": "Ctrl-Alt-Del", + "Send Ctrl-Alt-Del": "Ctrl-Alt-Del Sturen", + "Shutdown/Reboot": "Uitschakelen/Herstarten", + "Shutdown/Reboot...": "Uitschakelen/Herstarten...", + "Power": "Systeem", + "Shutdown": "Uitschakelen", + "Reboot": "Herstarten", + "Reset": "Resetten", + "Clipboard": "Klembord", + "Clear": "Wissen", + "Fullscreen": "Volledig Scherm", + "Settings": "Instellingen", + "Shared Mode": "Gedeelde Modus", + "View Only": "Alleen Kijken", + "Clip to Window": "Randen buiten venster afsnijden", + "Scaling Mode:": "Schaalmodus:", + "None": "Geen", + "Local Scaling": "Lokaal Schalen", + "Remote Resizing": "Op Afstand Formaat Wijzigen", + "Advanced": "Geavanceerd", + "Repeater ID:": "Repeater ID:", + "WebSocket": "WebSocket", + "Encrypt": "Versleutelen", + "Host:": "Host:", + "Port:": "Poort:", + "Path:": "Pad:", + "Automatic Reconnect": "Automatisch Opnieuw Verbinden", + "Reconnect Delay (ms):": "Vertraging voor Opnieuw Verbinden (ms):", + "Show Dot when No Cursor": "Geef stip weer indien geen cursor", + "Logging:": "Logmeldingen:", + "Disconnect": "Verbinding verbreken", + "Connect": "Verbinden", + "Password:": "Wachtwoord:", + "Send Password": "Verzend Wachtwoord:", + "Cancel": "Annuleren" +} \ No newline at end of file diff --git a/src/VncApp/wwwroot/app/locale/pl.json b/src/VncApp/wwwroot/app/locale/pl.json new file mode 100644 index 0000000..006ac7a --- /dev/null +++ b/src/VncApp/wwwroot/app/locale/pl.json @@ -0,0 +1,69 @@ +{ + "Connecting...": "Łączenie...", + "Disconnecting...": "Rozłączanie...", + "Reconnecting...": "Łączenie...", + "Internal error": "Błąd wewnętrzny", + "Must set host": "Host i port są wymagane", + "Connected (encrypted) to ": "Połączenie (szyfrowane) z ", + "Connected (unencrypted) to ": "Połączenie (nieszyfrowane) z ", + "Something went wrong, connection is closed": "Coś poszło źle, połączenie zostało zamknięte", + "Disconnected": "Rozłączony", + "New connection has been rejected with reason: ": "Nowe połączenie zostało odrzucone z powodu: ", + "New connection has been rejected": "Nowe połączenie zostało odrzucone", + "Password is required": "Hasło jest wymagane", + "noVNC encountered an error:": "noVNC napotkało błąd:", + "Hide/Show the control bar": "Pokaż/Ukryj pasek ustawień", + "Move/Drag Viewport": "Ruszaj/Przeciągaj Viewport", + "viewport drag": "przeciągnij viewport", + "Active Mouse Button": "Aktywny Przycisk Myszy", + "No mousebutton": "Brak przycisku myszy", + "Left mousebutton": "Lewy przycisk myszy", + "Middle mousebutton": "Środkowy przycisk myszy", + "Right mousebutton": "Prawy przycisk myszy", + "Keyboard": "Klawiatura", + "Show Keyboard": "Pokaż klawiaturę", + "Extra keys": "Przyciski dodatkowe", + "Show Extra Keys": "Pokaż przyciski dodatkowe", + "Ctrl": "Ctrl", + "Toggle Ctrl": "Przełącz Ctrl", + "Alt": "Alt", + "Toggle Alt": "Przełącz Alt", + "Send Tab": "Wyślij Tab", + "Tab": "Tab", + "Esc": "Esc", + "Send Escape": "Wyślij Escape", + "Ctrl+Alt+Del": "Ctrl+Alt+Del", + "Send Ctrl-Alt-Del": "Wyślij Ctrl-Alt-Del", + "Shutdown/Reboot": "Wyłącz/Uruchom ponownie", + "Shutdown/Reboot...": "Wyłącz/Uruchom ponownie...", + "Power": "Włączony", + "Shutdown": "Wyłącz", + "Reboot": "Uruchom ponownie", + "Reset": "Resetuj", + "Clipboard": "Schowek", + "Clear": "Wyczyść", + "Fullscreen": "Pełny ekran", + "Settings": "Ustawienia", + "Shared Mode": "Tryb Współdzielenia", + "View Only": "Tylko Podgląd", + "Clip to Window": "Przytnij do Okna", + "Scaling Mode:": "Tryb Skalowania:", + "None": "Brak", + "Local Scaling": "Skalowanie lokalne", + "Remote Resizing": "Skalowanie zdalne", + "Advanced": "Zaawansowane", + "Repeater ID:": "ID Repeatera:", + "WebSocket": "WebSocket", + "Encrypt": "Szyfrowanie", + "Host:": "Host:", + "Port:": "Port:", + "Path:": "Ścieżka:", + "Automatic Reconnect": "Automatycznie wznawiaj połączenie", + "Reconnect Delay (ms):": "Opóźnienie wznawiania (ms):", + "Logging:": "Poziom logowania:", + "Disconnect": "Rozłącz", + "Connect": "Połącz", + "Password:": "Hasło:", + "Cancel": "Anuluj", + "Canvas not supported.": "Element Canvas nie jest wspierany." +} \ No newline at end of file diff --git a/src/VncApp/wwwroot/app/locale/pt_BR.json b/src/VncApp/wwwroot/app/locale/pt_BR.json new file mode 100644 index 0000000..aa130f7 --- /dev/null +++ b/src/VncApp/wwwroot/app/locale/pt_BR.json @@ -0,0 +1,72 @@ +{ + "Connecting...": "Conectando...", + "Disconnecting...": "Desconectando...", + "Reconnecting...": "Reconectando...", + "Internal error": "Erro interno", + "Must set host": "É necessário definir o host", + "Connected (encrypted) to ": "Conectado (com criptografia) a ", + "Connected (unencrypted) to ": "Conectado (sem criptografia) a ", + "Something went wrong, connection is closed": "Algo deu errado. A conexão foi encerrada.", + "Failed to connect to server": "Falha ao conectar-se ao servidor", + "Disconnected": "Desconectado", + "New connection has been rejected with reason: ": "A nova conexão foi rejeitada pelo motivo: ", + "New connection has been rejected": "A nova conexão foi rejeitada", + "Credentials are required": "Credenciais são obrigatórias", + "noVNC encountered an error:": "O noVNC encontrou um erro:", + "Hide/Show the control bar": "Esconder/mostrar a barra de controles", + "Drag": "Arrastar", + "Move/Drag Viewport": "Mover/arrastar a janela", + "Keyboard": "Teclado", + "Show Keyboard": "Mostrar teclado", + "Extra keys": "Teclas adicionais", + "Show Extra Keys": "Mostar teclas adicionais", + "Ctrl": "Ctrl", + "Toggle Ctrl": "Pressionar/soltar Ctrl", + "Alt": "Alt", + "Toggle Alt": "Pressionar/soltar Alt", + "Toggle Windows": "Pressionar/soltar Windows", + "Windows": "Windows", + "Send Tab": "Enviar Tab", + "Tab": "Tab", + "Esc": "Esc", + "Send Escape": "Enviar Esc", + "Ctrl+Alt+Del": "Ctrl+Alt+Del", + "Send Ctrl-Alt-Del": "Enviar Ctrl-Alt-Del", + "Shutdown/Reboot": "Desligar/reiniciar", + "Shutdown/Reboot...": "Desligar/reiniciar...", + "Power": "Ligar", + "Shutdown": "Desligar", + "Reboot": "Reiniciar", + "Reset": "Reiniciar (forçado)", + "Clipboard": "Área de transferência", + "Clear": "Limpar", + "Fullscreen": "Tela cheia", + "Settings": "Configurações", + "Shared Mode": "Modo compartilhado", + "View Only": "Apenas visualizar", + "Clip to Window": "Recortar à janela", + "Scaling Mode:": "Modo de dimensionamento:", + "None": "Nenhum", + "Local Scaling": "Local", + "Remote Resizing": "Remoto", + "Advanced": "Avançado", + "Quality:": "Qualidade:", + "Compression level:": "Nível de compressão:", + "Repeater ID:": "ID do repetidor:", + "WebSocket": "WebSocket", + "Encrypt": "Criptografar", + "Host:": "Host:", + "Port:": "Porta:", + "Path:": "Caminho:", + "Automatic Reconnect": "Reconexão automática", + "Reconnect Delay (ms):": "Atraso da reconexão (ms)", + "Show Dot when No Cursor": "Mostrar ponto quando não há cursor", + "Logging:": "Registros:", + "Version:": "Versão:", + "Disconnect": "Desconectar", + "Connect": "Conectar", + "Username:": "Nome de usuário:", + "Password:": "Senha:", + "Send Credentials": "Enviar credenciais", + "Cancel": "Cancelar" +} \ No newline at end of file diff --git a/src/VncApp/wwwroot/app/locale/ru.json b/src/VncApp/wwwroot/app/locale/ru.json new file mode 100644 index 0000000..cab9739 --- /dev/null +++ b/src/VncApp/wwwroot/app/locale/ru.json @@ -0,0 +1,72 @@ +{ + "Connecting...": "Подключение...", + "Disconnecting...": "Отключение...", + "Reconnecting...": "Переподключение...", + "Internal error": "Внутренняя ошибка", + "Must set host": "Задайте имя сервера или IP", + "Connected (encrypted) to ": "Подключено (с шифрованием) к ", + "Connected (unencrypted) to ": "Подключено (без шифрования) к ", + "Something went wrong, connection is closed": "Что-то пошло не так, подключение разорвано", + "Failed to connect to server": "Ошибка подключения к серверу", + "Disconnected": "Отключено", + "New connection has been rejected with reason: ": "Новое соединение отклонено по причине: ", + "New connection has been rejected": "Новое соединение отклонено", + "Credentials are required": "Требуются учетные данные", + "noVNC encountered an error:": "Ошибка noVNC: ", + "Hide/Show the control bar": "Скрыть/Показать контрольную панель", + "Drag": "Переместить", + "Move/Drag Viewport": "Переместить окно", + "Keyboard": "Клавиатура", + "Show Keyboard": "Показать клавиатуру", + "Extra keys": "Дополнительные Кнопки", + "Show Extra Keys": "Показать Дополнительные Кнопки", + "Ctrl": "Ctrl", + "Toggle Ctrl": "Переключение нажатия Ctrl", + "Alt": "Alt", + "Toggle Alt": "Переключение нажатия Alt", + "Toggle Windows": "Переключение вкладок", + "Windows": "Вкладка", + "Send Tab": "Передать нажатие Tab", + "Tab": "Tab", + "Esc": "Esc", + "Send Escape": "Передать нажатие Escape", + "Ctrl+Alt+Del": "Ctrl+Alt+Del", + "Send Ctrl-Alt-Del": "Передать нажатие Ctrl-Alt-Del", + "Shutdown/Reboot": "Выключить/Перезагрузить", + "Shutdown/Reboot...": "Выключить/Перезагрузить...", + "Power": "Питание", + "Shutdown": "Выключить", + "Reboot": "Перезагрузить", + "Reset": "Сброс", + "Clipboard": "Буфер обмена", + "Clear": "Очистить", + "Fullscreen": "Во весь экран", + "Settings": "Настройки", + "Shared Mode": "Общий режим", + "View Only": "Только Просмотр", + "Clip to Window": "В окно", + "Scaling Mode:": "Масштаб:", + "None": "Нет", + "Local Scaling": "Локльный масштаб", + "Remote Resizing": "Удаленная перенастройка размера", + "Advanced": "Дополнительно", + "Quality:": "Качество", + "Compression level:": "Уровень Сжатия", + "Repeater ID:": "Идентификатор ID:", + "WebSocket": "WebSocket", + "Encrypt": "Шифрование", + "Host:": "Сервер:", + "Port:": "Порт:", + "Path:": "Путь:", + "Automatic Reconnect": "Автоматическое переподключение", + "Reconnect Delay (ms):": "Задержка переподключения (мс):", + "Show Dot when No Cursor": "Показать точку вместо курсора", + "Logging:": "Лог:", + "Version:": "Версия", + "Disconnect": "Отключение", + "Connect": "Подключение", + "Username:": "Имя Пользователя", + "Password:": "Пароль:", + "Send Credentials": "Передача Учетных Данных", + "Cancel": "Выход" +} \ No newline at end of file diff --git a/src/VncApp/wwwroot/app/locale/sv.json b/src/VncApp/wwwroot/app/locale/sv.json new file mode 100644 index 0000000..077ef42 --- /dev/null +++ b/src/VncApp/wwwroot/app/locale/sv.json @@ -0,0 +1,80 @@ +{ + "HTTPS is required for full functionality": "HTTPS krävs för full funktionalitet", + "Connecting...": "Ansluter...", + "Disconnecting...": "Kopplar ner...", + "Reconnecting...": "Återansluter...", + "Internal error": "Internt fel", + "Must set host": "Du måste specifiera en värd", + "Connected (encrypted) to ": "Ansluten (krypterat) till ", + "Connected (unencrypted) to ": "Ansluten (okrypterat) till ", + "Something went wrong, connection is closed": "Något gick fel, anslutningen avslutades", + "Failed to connect to server": "Misslyckades att ansluta till servern", + "Disconnected": "Frånkopplad", + "New connection has been rejected with reason: ": "Ny anslutning har blivit nekad med följande skäl: ", + "New connection has been rejected": "Ny anslutning har blivit nekad", + "Credentials are required": "Användaruppgifter krävs", + "noVNC encountered an error:": "noVNC stötte på ett problem:", + "Hide/Show the control bar": "Göm/Visa kontrollbaren", + "Drag": "Dra", + "Move/Drag Viewport": "Flytta/Dra Vyn", + "Keyboard": "Tangentbord", + "Show Keyboard": "Visa Tangentbord", + "Extra keys": "Extraknappar", + "Show Extra Keys": "Visa Extraknappar", + "Ctrl": "Ctrl", + "Toggle Ctrl": "Växla Ctrl", + "Alt": "Alt", + "Toggle Alt": "Växla Alt", + "Toggle Windows": "Växla Windows", + "Windows": "Windows", + "Send Tab": "Skicka Tab", + "Tab": "Tab", + "Esc": "Esc", + "Send Escape": "Skicka Escape", + "Ctrl+Alt+Del": "Ctrl+Alt+Del", + "Send Ctrl-Alt-Del": "Skicka Ctrl-Alt-Del", + "Shutdown/Reboot": "Stäng av/Boota om", + "Shutdown/Reboot...": "Stäng av/Boota om...", + "Power": "Ström", + "Shutdown": "Stäng av", + "Reboot": "Boota om", + "Reset": "Återställ", + "Clipboard": "Urklipp", + "Edit clipboard content in the textarea below.": "Redigera urklippets innehåll i fältet nedan.", + "Full Screen": "Fullskärm", + "Settings": "Inställningar", + "Shared Mode": "Delat Läge", + "View Only": "Endast Visning", + "Clip to Window": "Begränsa till Fönster", + "Scaling Mode:": "Skalningsläge:", + "None": "Ingen", + "Local Scaling": "Lokal Skalning", + "Remote Resizing": "Ändra Storlek", + "Advanced": "Avancerat", + "Quality:": "Kvalitet:", + "Compression level:": "Kompressionsnivå:", + "Repeater ID:": "Repeater-ID:", + "WebSocket": "WebSocket", + "Encrypt": "Kryptera", + "Host:": "Värd:", + "Port:": "Port:", + "Path:": "Sökväg:", + "Automatic Reconnect": "Automatisk Återanslutning", + "Reconnect Delay (ms):": "Fördröjning (ms):", + "Show Dot when No Cursor": "Visa prick när ingen muspekare finns", + "Logging:": "Loggning:", + "Version:": "Version:", + "Disconnect": "Koppla från", + "Connect": "Anslut", + "Server identity": "Server-identitet", + "The server has provided the following identifying information:": "Servern har gett följande identifierande information:", + "Fingerprint:": "Fingeravtryck:", + "Please verify that the information is correct and press \"Approve\". Otherwise press \"Reject\".": "Kontrollera att informationen är korrekt och tryck sedan \"Godkänn\". Tryck annars \"Neka\".", + "Approve": "Godkänn", + "Reject": "Neka", + "Credentials": "Användaruppgifter", + "Username:": "Användarnamn:", + "Password:": "Lösenord:", + "Send Credentials": "Skicka Användaruppgifter", + "Cancel": "Avbryt" +} \ No newline at end of file diff --git a/src/VncApp/wwwroot/app/locale/tr.json b/src/VncApp/wwwroot/app/locale/tr.json new file mode 100644 index 0000000..451c1b8 --- /dev/null +++ b/src/VncApp/wwwroot/app/locale/tr.json @@ -0,0 +1,69 @@ +{ + "Connecting...": "Bağlanıyor...", + "Disconnecting...": "Bağlantı kesiliyor...", + "Reconnecting...": "Yeniden bağlantı kuruluyor...", + "Internal error": "İç hata", + "Must set host": "Sunucuyu kur", + "Connected (encrypted) to ": "Bağlı (şifrelenmiş)", + "Connected (unencrypted) to ": "Bağlandı (şifrelenmemiş)", + "Something went wrong, connection is closed": "Bir şeyler ters gitti, bağlantı kesildi", + "Disconnected": "Bağlantı kesildi", + "New connection has been rejected with reason: ": "Bağlantı aşağıdaki nedenlerden dolayı reddedildi: ", + "New connection has been rejected": "Bağlantı reddedildi", + "Password is required": "Şifre gerekli", + "noVNC encountered an error:": "Bir hata oluştu:", + "Hide/Show the control bar": "Denetim masasını Gizle/Göster", + "Move/Drag Viewport": "Görünümü Taşı/Sürükle", + "viewport drag": "Görüntü penceresini sürükle", + "Active Mouse Button": "Aktif Fare Düğmesi", + "No mousebutton": "Fare düğmesi yok", + "Left mousebutton": "Farenin sol düğmesi", + "Middle mousebutton": "Farenin orta düğmesi", + "Right mousebutton": "Farenin sağ düğmesi", + "Keyboard": "Klavye", + "Show Keyboard": "Klavye Düzenini Göster", + "Extra keys": "Ekstra tuşlar", + "Show Extra Keys": "Ekstra tuşları göster", + "Ctrl": "Ctrl", + "Toggle Ctrl": "Ctrl Değiştir ", + "Alt": "Alt", + "Toggle Alt": "Alt Değiştir", + "Send Tab": "Sekme Gönder", + "Tab": "Sekme", + "Esc": "Esc", + "Send Escape": "Boşluk Gönder", + "Ctrl+Alt+Del": "Ctrl + Alt + Del", + "Send Ctrl-Alt-Del": "Ctrl-Alt-Del Gönder", + "Shutdown/Reboot": "Kapat/Yeniden Başlat", + "Shutdown/Reboot...": "Kapat/Yeniden Başlat...", + "Power": "Güç", + "Shutdown": "Kapat", + "Reboot": "Yeniden Başlat", + "Reset": "Sıfırla", + "Clipboard": "Pano", + "Clear": "Temizle", + "Fullscreen": "Tam Ekran", + "Settings": "Ayarlar", + "Shared Mode": "Paylaşım Modu", + "View Only": "Sadece Görüntüle", + "Clip to Window": "Pencereye Tıkla", + "Scaling Mode:": "Ölçekleme Modu:", + "None": "Bilinmeyen", + "Local Scaling": "Yerel Ölçeklendirme", + "Remote Resizing": "Uzaktan Yeniden Boyutlandırma", + "Advanced": "Gelişmiş", + "Repeater ID:": "Tekralayıcı ID:", + "WebSocket": "WebSocket", + "Encrypt": "Şifrele", + "Host:": "Ana makine:", + "Port:": "Port:", + "Path:": "Yol:", + "Automatic Reconnect": "Otomatik Yeniden Bağlan", + "Reconnect Delay (ms):": "Yeniden Bağlanma Süreci (ms):", + "Logging:": "Giriş yapılıyor:", + "Disconnect": "Bağlantıyı Kes", + "Connect": "Bağlan", + "Password:": "Parola:", + "Cancel": "Vazgeç", + "Canvas not supported.": "Tuval desteklenmiyor." +} \ No newline at end of file diff --git a/src/VncApp/wwwroot/app/locale/zh_CN.json b/src/VncApp/wwwroot/app/locale/zh_CN.json new file mode 100644 index 0000000..f0aea9a --- /dev/null +++ b/src/VncApp/wwwroot/app/locale/zh_CN.json @@ -0,0 +1,69 @@ +{ + "Connecting...": "连接中...", + "Disconnecting...": "正在断开连接...", + "Reconnecting...": "重新连接中...", + "Internal error": "内部错误", + "Must set host": "请提供主机名", + "Connected (encrypted) to ": "已连接到(加密)", + "Connected (unencrypted) to ": "已连接到(未加密)", + "Something went wrong, connection is closed": "发生错误,连接已关闭", + "Failed to connect to server": "无法连接到服务器", + "Disconnected": "已断开连接", + "New connection has been rejected with reason: ": "连接被拒绝,原因:", + "New connection has been rejected": "连接被拒绝", + "Password is required": "请提供密码", + "noVNC encountered an error:": "noVNC 遇到一个错误:", + "Hide/Show the control bar": "显示/隐藏控制栏", + "Move/Drag Viewport": "拖放显示范围", + "viewport drag": "显示范围拖放", + "Active Mouse Button": "启动鼠标按鍵", + "No mousebutton": "禁用鼠标按鍵", + "Left mousebutton": "鼠标左鍵", + "Middle mousebutton": "鼠标中鍵", + "Right mousebutton": "鼠标右鍵", + "Keyboard": "键盘", + "Show Keyboard": "显示键盘", + "Extra keys": "额外按键", + "Show Extra Keys": "显示额外按键", + "Ctrl": "Ctrl", + "Toggle Ctrl": "切换 Ctrl", + "Alt": "Alt", + "Toggle Alt": "切换 Alt", + "Send Tab": "发送 Tab 键", + "Tab": "Tab", + "Esc": "Esc", + "Send Escape": "发送 Escape 键", + "Ctrl+Alt+Del": "Ctrl-Alt-Del", + "Send Ctrl-Alt-Del": "发送 Ctrl-Alt-Del 键", + "Shutdown/Reboot": "关机/重新启动", + "Shutdown/Reboot...": "关机/重新启动...", + "Power": "电源", + "Shutdown": "关机", + "Reboot": "重新启动", + "Reset": "重置", + "Clipboard": "剪贴板", + "Clear": "清除", + "Fullscreen": "全屏", + "Settings": "设置", + "Shared Mode": "分享模式", + "View Only": "仅查看", + "Clip to Window": "限制/裁切窗口大小", + "Scaling Mode:": "缩放模式:", + "None": "无", + "Local Scaling": "本地缩放", + "Remote Resizing": "远程调整大小", + "Advanced": "高级", + "Repeater ID:": "中继站 ID", + "WebSocket": "WebSocket", + "Encrypt": "加密", + "Host:": "主机:", + "Port:": "端口:", + "Path:": "路径:", + "Automatic Reconnect": "自动重新连接", + "Reconnect Delay (ms):": "重新连接间隔 (ms):", + "Logging:": "日志级别:", + "Disconnect": "中断连接", + "Connect": "连接", + "Password:": "密码:", + "Cancel": "取消" +} \ No newline at end of file diff --git a/src/VncApp/wwwroot/app/locale/zh_TW.json b/src/VncApp/wwwroot/app/locale/zh_TW.json new file mode 100644 index 0000000..8ddf813 --- /dev/null +++ b/src/VncApp/wwwroot/app/locale/zh_TW.json @@ -0,0 +1,69 @@ +{ + "Connecting...": "連線中...", + "Disconnecting...": "正在中斷連線...", + "Reconnecting...": "重新連線中...", + "Internal error": "內部錯誤", + "Must set host": "請提供主機資訊", + "Connected (encrypted) to ": "已加密連線到", + "Connected (unencrypted) to ": "未加密連線到", + "Something went wrong, connection is closed": "發生錯誤,連線已關閉", + "Failed to connect to server": "無法連線到伺服器", + "Disconnected": "連線已中斷", + "New connection has been rejected with reason: ": "連線被拒絕,原因:", + "New connection has been rejected": "連線被拒絕", + "Password is required": "請提供密碼", + "noVNC encountered an error:": "noVNC 遇到一個錯誤:", + "Hide/Show the control bar": "顯示/隱藏控制列", + "Move/Drag Viewport": "拖放顯示範圍", + "viewport drag": "顯示範圍拖放", + "Active Mouse Button": "啟用滑鼠按鍵", + "No mousebutton": "無滑鼠按鍵", + "Left mousebutton": "滑鼠左鍵", + "Middle mousebutton": "滑鼠中鍵", + "Right mousebutton": "滑鼠右鍵", + "Keyboard": "鍵盤", + "Show Keyboard": "顯示鍵盤", + "Extra keys": "額外按鍵", + "Show Extra Keys": "顯示額外按鍵", + "Ctrl": "Ctrl", + "Toggle Ctrl": "切換 Ctrl", + "Alt": "Alt", + "Toggle Alt": "切換 Alt", + "Send Tab": "送出 Tab 鍵", + "Tab": "Tab", + "Esc": "Esc", + "Send Escape": "送出 Escape 鍵", + "Ctrl+Alt+Del": "Ctrl-Alt-Del", + "Send Ctrl-Alt-Del": "送出 Ctrl-Alt-Del 快捷鍵", + "Shutdown/Reboot": "關機/重新啟動", + "Shutdown/Reboot...": "關機/重新啟動...", + "Power": "電源", + "Shutdown": "關機", + "Reboot": "重新啟動", + "Reset": "重設", + "Clipboard": "剪貼簿", + "Clear": "清除", + "Fullscreen": "全螢幕", + "Settings": "設定", + "Shared Mode": "分享模式", + "View Only": "僅檢視", + "Clip to Window": "限制/裁切視窗大小", + "Scaling Mode:": "縮放模式:", + "None": "無", + "Local Scaling": "本機縮放", + "Remote Resizing": "遠端調整大小", + "Advanced": "進階", + "Repeater ID:": "中繼站 ID", + "WebSocket": "WebSocket", + "Encrypt": "加密", + "Host:": "主機:", + "Port:": "連接埠:", + "Path:": "路徑:", + "Automatic Reconnect": "自動重新連線", + "Reconnect Delay (ms):": "重新連線間隔 (ms):", + "Logging:": "日誌級別:", + "Disconnect": "中斷連線", + "Connect": "連線", + "Password:": "密碼:", + "Cancel": "取消" +} \ No newline at end of file diff --git a/src/VncApp/wwwroot/app/localization.js b/src/VncApp/wwwroot/app/localization.js new file mode 100644 index 0000000..84341da --- /dev/null +++ b/src/VncApp/wwwroot/app/localization.js @@ -0,0 +1,179 @@ +/* + * noVNC: HTML5 VNC client + * Copyright (C) 2018 The noVNC Authors + * Licensed under MPL 2.0 (see LICENSE.txt) + * + * See README.md for usage and integration instructions. + */ + +/* + * Localization Utilities + */ + +export class Localizer { + constructor() { + // Currently configured language + this.language = 'en'; + + // Current dictionary of translations + this.dictionary = undefined; + } + + // Configure suitable language based on user preferences + setup(supportedLanguages) { + this.language = 'en'; // Default: US English + + /* + * Navigator.languages only available in Chrome (32+) and FireFox (32+) + * Fall back to navigator.language for other browsers + */ + let userLanguages; + if (typeof window.navigator.languages == 'object') { + userLanguages = window.navigator.languages; + } else { + userLanguages = [navigator.language || navigator.userLanguage]; + } + + for (let i = 0;i < userLanguages.length;i++) { + const userLang = userLanguages[i] + .toLowerCase() + .replace("_", "-") + .split("-"); + + // Built-in default? + if ((userLang[0] === 'en') && + ((userLang[1] === undefined) || (userLang[1] === 'us'))) { + return; + } + + // First pass: perfect match + for (let j = 0; j < supportedLanguages.length; j++) { + const supLang = supportedLanguages[j] + .toLowerCase() + .replace("_", "-") + .split("-"); + + if (userLang[0] !== supLang[0]) { + continue; + } + if (userLang[1] !== supLang[1]) { + continue; + } + + this.language = supportedLanguages[j]; + return; + } + + // Second pass: fallback + for (let j = 0;j < supportedLanguages.length;j++) { + const supLang = supportedLanguages[j] + .toLowerCase() + .replace("_", "-") + .split("-"); + + if (userLang[0] !== supLang[0]) { + continue; + } + if (supLang[1] !== undefined) { + continue; + } + + this.language = supportedLanguages[j]; + return; + } + } + } + + // Retrieve localised text + get(id) { + if (typeof this.dictionary !== 'undefined' && this.dictionary[id]) { + return this.dictionary[id]; + } else { + return id; + } + } + + // Traverses the DOM and translates relevant fields + // See https://html.spec.whatwg.org/multipage/dom.html#attr-translate + translateDOM() { + const self = this; + + function process(elem, enabled) { + function isAnyOf(searchElement, items) { + return items.indexOf(searchElement) !== -1; + } + + function translateString(str) { + // We assume surrounding whitespace, and whitespace around line + // breaks is just for source formatting + str = str.split("\n").map(s => s.trim()).join(" ").trim(); + return self.get(str); + } + + function translateAttribute(elem, attr) { + const str = translateString(elem.getAttribute(attr)); + elem.setAttribute(attr, str); + } + + function translateTextNode(node) { + const str = translateString(node.data); + node.data = str; + } + + if (elem.hasAttribute("translate")) { + if (isAnyOf(elem.getAttribute("translate"), ["", "yes"])) { + enabled = true; + } else if (isAnyOf(elem.getAttribute("translate"), ["no"])) { + enabled = false; + } + } + + if (enabled) { + if (elem.hasAttribute("abbr") && + elem.tagName === "TH") { + translateAttribute(elem, "abbr"); + } + if (elem.hasAttribute("alt") && + isAnyOf(elem.tagName, ["AREA", "IMG", "INPUT"])) { + translateAttribute(elem, "alt"); + } + if (elem.hasAttribute("download") && + isAnyOf(elem.tagName, ["A", "AREA"])) { + translateAttribute(elem, "download"); + } + if (elem.hasAttribute("label") && + isAnyOf(elem.tagName, ["MENUITEM", "MENU", "OPTGROUP", + "OPTION", "TRACK"])) { + translateAttribute(elem, "label"); + } + // FIXME: Should update "lang" + if (elem.hasAttribute("placeholder") && + isAnyOf(elem.tagName, ["INPUT", "TEXTAREA"])) { + translateAttribute(elem, "placeholder"); + } + if (elem.hasAttribute("title")) { + translateAttribute(elem, "title"); + } + if (elem.hasAttribute("value") && + elem.tagName === "INPUT" && + isAnyOf(elem.getAttribute("type"), ["reset", "button", "submit"])) { + translateAttribute(elem, "value"); + } + } + + for (let i = 0; i < elem.childNodes.length; i++) { + const node = elem.childNodes[i]; + if (node.nodeType === node.ELEMENT_NODE) { + process(node, enabled); + } else if (node.nodeType === node.TEXT_NODE && enabled) { + translateTextNode(node); + } + } + } + + process(document.body, true); + } +} + +export const l10n = new Localizer(); +export default l10n.get.bind(l10n); diff --git a/src/VncApp/wwwroot/app/sounds/CREDITS b/src/VncApp/wwwroot/app/sounds/CREDITS new file mode 100644 index 0000000..ec1fb55 --- /dev/null +++ b/src/VncApp/wwwroot/app/sounds/CREDITS @@ -0,0 +1,4 @@ +bell + Copyright: Dr. Richard Boulanger et al + URL: http://www.archive.org/details/Berklee44v12 + License: CC-BY Attribution 3.0 Unported diff --git a/src/VncApp/wwwroot/app/sounds/bell.mp3 b/src/VncApp/wwwroot/app/sounds/bell.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..fdbf149a1e9e58aa6a39adb6c681b910347d161a GIT binary patch literal 4531 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 DLJX+- literal 0 HcmV?d00001 diff --git a/src/VncApp/wwwroot/app/sounds/bell.oga b/src/VncApp/wwwroot/app/sounds/bell.oga new file mode 100644 index 0000000000000000000000000000000000000000..144d2b3670e8e294ee7cfe343355bf90123cb687 GIT binary patch literal 8495 zcmbVx2{@G9+xSCei6qHVvV<7>TF73uK{AYe$)2?sOSY(FU&7e8EJI^WS+e&gJ43di zFhxwVOb9WS?-}0S-}1k%@4K%5xsEgEzR!K`=iJ-5&pGs*oD2YR;O`=+JrhXkQsTa^ zkg=2b-uJR~MvxHXx5`OBU|BsTeoLlDn)y#5%_IXM+bZGH^umY#Q9Mr^GrA0pn>atX zC!*)&#Oda2Yjnh(Q;SnVOzgVYH3WKT4_@ z80x~o;$vy->wxw3!TJW9rav=(8*KXanfb&s%k5`2Ea89G-@&+TQauu#lMHylEt@(A zDY$a6U{Z6-ZK{RoBJ;m-W)5X;49L=D&c8r2W{vz6Wthd+fKJakvY;D= zbq=&8q&K7EMaEDj0;5Hni8}82Gh|U#poc*mD?Xd9lhp>Ka~{s5L{FN4b4`ab7hX0n zg1snY7GG_H;W59z-2!cujrmLVD>x(SQzbmlza z434L;W#lU6N@n*?pi6!s-VG^YkBe7_qMzP@vGSq3pBzcf2>@aAM_&A=IdbJ=FD^=o z7U<=F(=X8{L~6?0F>*_<+Ual7ii2J(Bn^6TTzm72t+&V_$dEG@sA) z&nzc=aM)lRHqM$k{J$ORpU45gpb0yQNu+J8cvtq*+p5&Z2L2N{o{U|IY(0rQ+OK(Z zhlK{#rSvwWKAu<8m(n%3VEOTa&j^!)!8OYfX@?QG!;E$h`iRacz;xSFS>YwTqm5I*CT|^h0{;$Zn7hRGbT@o3M zkBsM!N_CFPENv)o>#baB{6FhIk)z?o16D9{)Vz59Eppz8v)u%v>9vsV#<7eFA3=qB zt1#ijrNE4URxIx@rVB&pnn zE~`0ra#B`M%tOLhk|$yo(^b3m?+Dn_vVK$U85Iww->|hSVN~spSwkUWRYW`A!c_VH zq5`+QlYl+|P-tDz;?Y`{D$xAJGr%1!e=d|KKt2JlmD|1XkR8xs^k*MTzLkhylLxa0 z86Eh?q?*qqNFFLf2E_3Avumx(Cw=pm(q-g|PAZPNGAOB=>lm$L0M9S|8_eX(JOXq1 zO9jAfvUIW0{&Ss8-``;Ik4Cr2I=*N)1Rw6}YIvc?Trne?YVYtQ z_z#$5X&Nqc0sw||MpB~+mKoHr4w;oS*fAZ0x~Kxd^M8XE;A5%iVqpWg=|bacT2m%C zye^~E?GH!+uKuWmzAUZNg*#-p^h#h;9J*is4WdD?76btxl#CJx1gDNBo zS(8*yZC%wuy61J{?MyQrqj|JO>!1(FON1OG`_Kq>j;` zJAsTzq@|^eBB1?1*8*{t%$W=RB+4I+l{E5tjJgJJORNv+;P4*>+?Uy8z&(#eg^v}^ zWK&4Z%pUs3p+dzY#XHjVPpd+BrJyR*yvWn4&gdefmS#omxC8_ZZdkminpCsC7e(V{ zt{GuqQvm?4PEdk>H2Ftzu>-)9SXitqo=sXE(wU8jzgWmk_J-V)$xt71SFZx5ck z%xD1Rdk+BM#w#12u;ha3cc8h*0e>*tt3pYqGI}l)i(S8X#B&(wkY*Sy-pOW12QD2v zvr%$^4Di`c=}G)BDpWa$cyO&@L$Y1z2zpg~wq3t0RX!qCd?6b=l#r7g{F2%=J{D>L zl8p4=mci1Vj);||$O${mh3E99Qx!lPQpr;0Bj}-8=!bN25H2u(33PxUbv_blCMXgP zgYu(_Mq!EKVPIkdrHvLZ4toxRqHB#}#q+}qL1dk6Y#c}e`pyMAHzD2>k{5w%b%oS2 z*_DG@u+T=MSX_lVS>^&=ggZ^_K$-H)T_D94G=P}@10WRo$}>Er=*|0&Uyk(90G?z? zdPoQTh2%(DC>D})afXr3gGeYS8Umw2$pwP^B(FQ_fjRFE>_<9+j+FgKbg0okGe8hD z2dJv!fiNWOPYtFa{_UZxIr9nluA~3WKSF2WQZ0P{=z_NInu2 z9`qko{v(i=l<#>-IiD9C1qYB&{(KT03Q0ny91Xyr)F2G%jD!L^$L$dcf&xDTB9BlE zP|^t<20h~ZhYot0go2uR5I#&Pa z6VYtPe2=D*8q!LR8U2I${{zY1O*7MlDxUw3_yVsFV&S04yfCsTForshWaq?rqPn_c21KPm}EP^i5FbAfcu z1ZwlX88&lm!Ov(5KsrAK5M=9D~z+Hx~Kf8BA!$$(IBUjWFAUJ1UbaVdO@PHz7G^c|n~2S@vElwtq3TSMH^qqe*g`4^_X zoVrWO2>^J<`k-Gf-DxFg%MzC4B6LP2Rwb&zp_6}}XJH)tQnHCbHxkxw8qMpi15t+* zGpKeVi$KqZcn_Ol6zUD3G+>tD1l}o!^`9g^b>}X)4bjmv6ak^{$!~T&I7k0nyPIE( zpY1$GtK*UC+l{9Dsz>wP6vF7kvP;w7{S*2yPA1Ab z%H(vn-+qm{F8`H+?>l3P9C+6Q3l;DXOug4aBkwsb$jHenDy!a7*M#caz5_D^a|BrE z0Yv~vy1;oQGeb6>F5&ER`owcd49Vw_jNmCo8NAGpXp{kR^5bhO2_`2$zPc(ik_G{Q zbaf?-Iwj1tu%)FK8ymngGmt6C@Z^}Z!)+4_TiAwU4pMDX>8jeM~7U zQ_HlcHuKZcv_GTm>NnB^52M`uT!m0x*LhQCHmCg>+o7#rvnw(F##182vkrFlh0FmO zd4Zi-wYT*R#+)#_D@s0-RZA|-zrUZ5dUZ0EOf7rKZL8V!9piJceC#)v+*6(EH-^9B zV@9J*BT)f&i9(n``|Gn#)=j23JA~)^5u#38Q*7H@_R!MZ={4?I-Rum?-+tLPX^M}K zA&8Jq<`KEO^yJ=~zvP)sY+zqrWk}^;J)Zz&cpSABvM2nKG^wV9?p_(vH7-NcdWx+ z`WNzhq#HVJldbQR>{YDb71CC_4=jVV(w7}Zn&~bZBSLv^>|=R_^Q6At7sBwk@jK{I zem=lbOlFd0?~7^i0A$8z1*5N4%VpT0UVatF331nf=8 z>v+ewCVY*0GO@N?TpjISc`0z4Al@J^g z{a8<4-#(ER6703p9XtEg0lv3)us^@QX)}Jv=eZZ?*}szKv3bn}-+Q?!_aJ=9ApXYp zGihQc)my|S;sy`8yELG`qa`JF(mI`)-F7YvDixE)&sp&`{x;;OOF; z&|f&*oRFYt{0`2syzpjyqt{=wO~&;ZPdobIYFSqvyo^pM#qe`5@yZ9q@Ur@}n}^2O z)(=WK8d)xbSIoA{#@!LM!!w6&bkz&^z1q|R+Q5o{h5K|jMjj|(*7r;3%r4UajAm+C zCd`L1Um9afzc4r+UOc1rr2_l%rJMDN>G$F9(A#e|wiLU9sy-ru6NvZ~wz)d9R$HB| z!O{zXsA|?z9e*WB?KcARmy}>SBa!Atz5sxM3_Ualcd{i&= zc^^I1X3_R=`@5_xGjpW0ld;ZWo+x3T&hl%08bNw9m`6-NvHtL9gceX^v&qeT#eV0b zwKa!Pqs5CZ#kh!Ezt!uCK-_|AKZfAcxvM4VWW&TAuIpx!I6Wfx;4&{dEvK?p z-2$iJd%G;zMv4$a+gP_Qh*~g>tS;vE6rmp>|i{+ z>4%?Iv+8cMfe+W~k<$mQ*0`Q%!9H6L0(<>RbL%5TGGI?_lPfLWjoG4>d2_;|$7OY# zD&@iOt;yoX3Mz@0B@gpH+`vVlto?F`%U{=L_8H&6XZAk#&f*UfWbnf*gjN@JfyvR> zdOg*juOlTL*NA-;wO4_YFi*PoK^L{oWCp^k`T7ZR5|JyFR>nAK1=a83fzycQeQ0Eg zwNuDjCp#Hq$Akqo1CtC-^Sp+wV!;{?U)+uRkIeEWA5R55e^Bk!E%K3i!vw)KEvFrQG0YA*^4+i_TWjhg{twaF83;)ew?Zy;FD9fz9 zD&Sx|^Rb83p-<$}wej+AGN_Q%`gIGO_4L7>QmZaU?Lf@_gM**afiTUI^jIF<= zulO&|08{cEKFor=8=t@jk_4|RwyxOn#%3A9`>bb<>x8BXe^kVW{O$VnxroZL>y&mo zZ_|U_Z-nfPF0nRDun+pZRdC3>X>LAp@?42%V}yaRtn}xK2P=A}R@#@|+~@t?XobV( z?FY96;vI;c2JY`IMXq zP1|fK-dLSj^=N3s#ARVTE4L#`-(spZmIUJlg4VM!*!F`v)16}ngbdZoLB)}J-AP{N zgw=OeXRj9=_JUsc3wqZzNfncOptY1^0j;yP!G zoH^69oW!OHv@BDPd3Ga0T=#8!nj~A$2VNo6?_9rU;@4Jl2Y7E9-?mu9NikcNrphsL zctigB9DwM#ch%{wPS8xKC&iW|MU~fi8Nge*Du*F3UWvW4*<~lQ_VJU*I)QHeFZFxV z+tC$5WBgB;)z?Z^*tRQP7gSZ8C^n!8%E(@SLGUcdaQ2`rvz8%5IAK1&E=qGm`Es9hYELovSkJgqaqi7#Xe5u$n>Tl(Ic#~pNJzsFpXQ#*s#=umX6~82?_;dcz z@_p^t;K{nC-?~?8p|Q!gGc&2@u2=IOcn`i(Gjhu+(I77p5Ba(N3L&%buIEA(&2AwF z`&_j4$)DD1R@~Dxzdl5~)H?k}#4GjE1aim8vFypT<)K^}hPczF$icgoEpfnP>XAhZ z7UB35w>kIvoVFJ1(VC*D3cGG>kf_rY#b3>2+4|OpYvDlw-vi&rmbGpL7EM`9(Cs|h zTx~kIYE))h+t7K@RiTQ=g5NQ(gkN{4(Sn3@4W-Z47+atp@|ImR_&T<2p|po++w0RdeD zLaT|3OQ{FBGx_^(^b*_=i)kK~Ut7qF^sR|>fke-rV-?pH%WxF_J0|CFJ`2gLcnv|5 zzgn(2N7NGHCf2CMbKM2?%MbyTLBj~?5v#zhOKb2u_D`#QgeNe5wBlYNtc=4Ug#911 zBUiTjIti0wXW@gW>jCJ81SMgd{ne*6Z8_>}w-P0dWx$f-~DZ)(3IyK{YiW&3%{K>JUlc6{1{kq;3=Ri6jAPeroK zxP0Hka(P+mZPsGrS+)*#S6-L+TkgKQ)KIWFx_sA}e4%nCwDA|YSU{zqR`s*XS+|k^ z3}J<8$Mma}cpRM(^PsTb%uG4U#WIxy;yp;@b;miwK*ZP%)2GSds?^|81?o?RQV~x(PvkUWEHi!nRt>PwWJwLCiN>hYoRQqP3 z?~?Ys*HuiLuw$c)WE^_>N2!_ml_hOd476&#mc2)AbHj7H_i7NfF1lfSy35eVF z;8?kJo5gIVnd0Uxroa{A^PI$vZhJHP{oTe8z4OK8PucqS%XEy>d@S$*Qi?l^*)bxJ zn(dhKx?T?Hww!H)HjzukdOGTzj>vs3>bZv%*xqQh{aNcz4@8)@gD)_--@qX|49NwT z53)J8spr_5j=+2(MzFtcK{<>c=dy? z*E#S#Yb>>W^pn8^|7UGkOv@qV6B&0(VbgOhcw^{%q2AA0slm?f(8~(RrT#qUN8?{i zjFyWV)Tfs_ zHNIptN`UE!LhlBwm0LECz}e&3-dbmsW8LqwUSqCTUqtb}b|3ZKvAF8`bi?C;z@|>{ z47LxSga|>mL>`ZOrR&&E;5`mq=mE2IVGeaj{Z3J&kIu(S{b33S= zi3!RJo^g^02#>IyI=$I85OZqFU*jhZk@uafSQoM0+RSg)95_zfa-%0&+JG7S2gT95 z!AVM%qi2JocLVSd7TBGZnI=D6P?QeC8|0ngwM_mfg4LJ)Fo-42BIL+dho{43zHa8h z%dvTfO8CeY-=VH1yDB^i|A{8e(&*`#7qbEDWG*_*(2nn&;@}f5phK-dFiyoSCKGb) ztLEACpur!8mcH!a@2)6n`@MdawK`%b64IJSSdwem+x@lU@#D+Z&Z3Dw|1PShB_Bon zJh&ZjgR!xpp)#@k_rBuL2(ej-@P;rL?Ad&f)R*SRmtE!w;TWoQQV?8B(#|OIp8U&x zg?s0##*FD@T@%rH0b7lYwJgFQ$}nvSW%pNh@YTw+rFr?!YdG-?+iK@OgXBGM^R&#nJ@o3@Ke(I~Z@U~ox5&6TE$BzC3 q4pSv@4Tp8LC~{y18P49-RO96847`*l^Ef%*L!-C1?mgOf>VE*{SErW% literal 0 HcmV?d00001 diff --git a/src/VncApp/wwwroot/app/styles/Orbitron700.ttf b/src/VncApp/wwwroot/app/styles/Orbitron700.ttf new file mode 100644 index 0000000000000000000000000000000000000000..e28729dc56b0662b5d2506ddfde5a368784f5755 GIT binary patch literal 38580 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 YaN=?Mu0Qj~2_>(2Mry;V1-x;lBPyVI3Q(tVP1 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 aYg+X)x}OQee;ks?lK=p?0sn=t1dRYj;d3$o literal 0 HcmV?d00001 diff --git a/src/VncApp/wwwroot/app/styles/base.css b/src/VncApp/wwwroot/app/styles/base.css new file mode 100644 index 0000000..06e736a --- /dev/null +++ b/src/VncApp/wwwroot/app/styles/base.css @@ -0,0 +1,922 @@ +/* + * noVNC base CSS + * Copyright (C) 2019 The noVNC Authors + * noVNC is licensed under the MPL 2.0 (see LICENSE.txt) + * This file is licensed under the 2-Clause BSD license (see LICENSE.txt). + */ + +/* + * Z index layers: + * + * 0: Main screen + * 10: Control bar + * 50: Transition blocker + * 60: Connection popups + * 100: Status bar + * ... + * 1000: Javascript crash + * ... + * 10000: Max (used for polyfills) + */ + +/* + * State variables (set on :root): + * + * noVNC_loading: Page is still loading + * noVNC_connecting: Connecting to server + * noVNC_reconnecting: Re-establishing a connection + * noVNC_connected: Connected to server (most common state) + * noVNC_disconnecting: Disconnecting from server + */ + +:root { + font-family: sans-serif; +} + +body { + margin:0; + padding:0; + /*Background image with light grey curve.*/ + background-color:#494949; + background-repeat:no-repeat; + background-position:right bottom; + height:100%; + touch-action: none; +} + +html { + height:100%; +} + +.noVNC_only_touch.noVNC_hidden { + display: none; +} + +.noVNC_disabled { + color: rgb(128, 128, 128); +} + +/* ---------------------------------------- + * Spinner + * ---------------------------------------- + */ + +.noVNC_spinner { + position: relative; +} +.noVNC_spinner, .noVNC_spinner::before, .noVNC_spinner::after { + width: 10px; + height: 10px; + border-radius: 2px; + box-shadow: -60px 10px 0 rgba(255, 255, 255, 0); + animation: noVNC_spinner 1.0s linear infinite; +} +.noVNC_spinner::before { + content: ""; + position: absolute; + left: 0px; + top: 0px; + animation-delay: -0.1s; +} +.noVNC_spinner::after { + content: ""; + position: absolute; + top: 0px; + left: 0px; + animation-delay: 0.1s; +} +@keyframes noVNC_spinner { + 0% { box-shadow: -60px 10px 0 rgba(255, 255, 255, 0); width: 20px; } + 25% { box-shadow: 20px 10px 0 rgba(255, 255, 255, 1); width: 10px; } + 50% { box-shadow: 60px 10px 0 rgba(255, 255, 255, 0); width: 10px; } +} + +/* ---------------------------------------- + * WebKit centering hacks + * ---------------------------------------- + */ + +.noVNC_center { + /* + * This is a workaround because webkit misrenders transforms and + * uses non-integer coordinates, resulting in blurry content. + * Ideally we'd use "top: 50%; transform: translateY(-50%);" on + * the objects instead. + */ + display: flex; + align-items: center; + justify-content: center; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; +} +.noVNC_center > * { + pointer-events: auto; +} +.noVNC_vcenter { + display: flex !important; + flex-direction: column; + justify-content: center; + position: fixed; + top: 0; + left: 0; + height: 100%; + margin: 0 !important; + padding: 0 !important; + pointer-events: none; +} +.noVNC_vcenter > * { + pointer-events: auto; +} + +/* ---------------------------------------- + * Layering + * ---------------------------------------- + */ + +.noVNC_connect_layer { + z-index: 60; +} + +/* ---------------------------------------- + * Fallback error + * ---------------------------------------- + */ + +#noVNC_fallback_error { + z-index: 1000; + visibility: hidden; + /* Put a dark background in front of everything but the error, + and don't let mouse events pass through */ + background: rgba(0, 0, 0, 0.8); + pointer-events: all; +} +#noVNC_fallback_error.noVNC_open { + visibility: visible; +} + +#noVNC_fallback_error > div { + max-width: calc(100vw - 30px - 30px); + max-height: calc(100vh - 30px - 30px); + overflow: auto; + + padding: 15px; + + transition: 0.5s ease-in-out; + + transform: translateY(-50px); + opacity: 0; + + text-align: center; + font-weight: bold; + color: #fff; + + border-radius: 10px; + box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); + background: rgba(200,55,55,0.8); +} +#noVNC_fallback_error.noVNC_open > div { + transform: translateY(0); + opacity: 1; +} + +#noVNC_fallback_errormsg { + font-weight: normal; +} + +#noVNC_fallback_errormsg .noVNC_message { + display: inline-block; + text-align: left; + font-family: monospace; + white-space: pre-wrap; +} + +#noVNC_fallback_error .noVNC_location { + font-style: italic; + font-size: 0.8em; + color: rgba(255, 255, 255, 0.8); +} + +#noVNC_fallback_error .noVNC_stack { + padding: 10px; + margin: 10px; + font-size: 0.8em; + text-align: left; + font-family: monospace; + white-space: pre; + border: 1px solid rgba(0, 0, 0, 0.5); + background: rgba(0, 0, 0, 0.2); + overflow: auto; +} + +/* ---------------------------------------- + * Control Bar + * ---------------------------------------- + */ + +#noVNC_control_bar_anchor { + /* The anchor is needed to get z-stacking to work */ + position: fixed; + z-index: 10; + + transition: 0.5s ease-in-out; + + /* Edge misrenders animations wihthout this */ + transform: translateX(0); +} +:root.noVNC_connected #noVNC_control_bar_anchor.noVNC_idle { + opacity: 0.8; +} +#noVNC_control_bar_anchor.noVNC_right { + left: auto; + right: 0; +} + +#noVNC_control_bar { + position: relative; + left: -100%; + + transition: 0.5s ease-in-out; + + background-color: rgb(110, 132, 163); + border-radius: 0 10px 10px 0; + + user-select: none; + -webkit-user-select: none; + -webkit-touch-callout: none; /* Disable iOS image long-press popup */ +} +#noVNC_control_bar.noVNC_open { + box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); + left: 0; +} +#noVNC_control_bar::before { + /* This extra element is to get a proper shadow */ + content: ""; + position: absolute; + z-index: -1; + height: 100%; + width: 30px; + left: -30px; + transition: box-shadow 0.5s ease-in-out; +} +#noVNC_control_bar.noVNC_open::before { + box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); +} +.noVNC_right #noVNC_control_bar { + left: 100%; + border-radius: 10px 0 0 10px; +} +.noVNC_right #noVNC_control_bar.noVNC_open { + left: 0; +} +.noVNC_right #noVNC_control_bar::before { + visibility: hidden; +} + +#noVNC_control_bar_handle { + position: absolute; + left: -15px; + top: 0; + transform: translateY(35px); + width: calc(100% + 30px); + height: 50px; + z-index: -1; + cursor: pointer; + border-radius: 5px; + background-color: rgb(83, 99, 122); + background-image: url("../images/handle_bg.svg"); + background-repeat: no-repeat; + background-position: right; + box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.5); +} +#noVNC_control_bar_handle:after { + content: ""; + transition: transform 0.5s ease-in-out; + background: url("../images/handle.svg"); + position: absolute; + top: 22px; /* (50px-6px)/2 */ + right: 5px; + width: 5px; + height: 6px; +} +#noVNC_control_bar.noVNC_open #noVNC_control_bar_handle:after { + transform: translateX(1px) rotate(180deg); +} +:root:not(.noVNC_connected) #noVNC_control_bar_handle { + display: none; +} +.noVNC_right #noVNC_control_bar_handle { + background-position: left; +} +.noVNC_right #noVNC_control_bar_handle:after { + left: 5px; + right: 0; + transform: translateX(1px) rotate(180deg); +} +.noVNC_right #noVNC_control_bar.noVNC_open #noVNC_control_bar_handle:after { + transform: none; +} +/* Larger touch area for the handle, used when a touch screen is available */ +#noVNC_control_bar_handle div { + position: absolute; + right: -35px; + top: 0; + width: 50px; + height: 100%; + display: none; +} +@media (any-pointer: coarse) { + #noVNC_control_bar_handle div { + display: initial; + } +} +.noVNC_right #noVNC_control_bar_handle div { + left: -35px; + right: auto; +} + +#noVNC_control_bar > .noVNC_scroll { + max-height: 100vh; /* Chrome is buggy with 100% */ + overflow-x: hidden; + overflow-y: auto; + padding: 0 10px; +} + +#noVNC_control_bar > .noVNC_scroll > * { + display: block; + margin: 10px auto; +} + +/* Control bar hint */ +#noVNC_hint_anchor { + position: fixed; + right: -50px; + left: auto; +} +#noVNC_control_bar_anchor.noVNC_right + #noVNC_hint_anchor { + left: -50px; + right: auto; +} +#noVNC_control_bar_hint { + position: relative; + transform: scale(0); + width: 100px; + height: 50%; + max-height: 600px; + + visibility: hidden; + opacity: 0; + transition: 0.2s ease-in-out; + background: transparent; + box-shadow: 0 0 10px black, inset 0 0 10px 10px rgba(110, 132, 163, 0.8); + border-radius: 10px; + transition-delay: 0s; +} +#noVNC_control_bar_hint.noVNC_active { + visibility: visible; + opacity: 1; + transition-delay: 0.2s; + transform: scale(1); +} +#noVNC_control_bar_hint.noVNC_notransition { + transition: none !important; +} + +/* Control bar buttons */ +#noVNC_control_bar .noVNC_button { + padding: 4px 4px; + vertical-align: middle; + border:1px solid rgba(255, 255, 255, 0.2); + border-radius: 6px; + background-color: transparent; + background-image: unset; /* we don't want the gradiant from input.css */ +} +#noVNC_control_bar .noVNC_button.noVNC_selected { + border-color: rgba(0, 0, 0, 0.8); + background-color: rgba(0, 0, 0, 0.5); +} +#noVNC_control_bar .noVNC_button.noVNC_selected:not(:disabled):hover { + border-color: rgba(0, 0, 0, 0.4); + background-color: rgba(0, 0, 0, 0.2); +} +#noVNC_control_bar .noVNC_button:not(:disabled):hover { + background-color: rgba(255, 255, 255, 0.2); +} +#noVNC_control_bar .noVNC_button:not(:disabled):active { + padding-top: 5px; + padding-bottom: 3px; +} +#noVNC_control_bar .noVNC_button.noVNC_hidden { + display: none !important; +} + +/* Android browsers don't properly update hover state if touch events are + * intercepted, like they are when clicking on the remote screen. */ +@media (any-pointer: coarse) { + #noVNC_control_bar .noVNC_button:not(:disabled):hover { + background-color: transparent; + } + #noVNC_control_bar .noVNC_button.noVNC_selected:not(:disabled):hover { + border-color: rgba(0, 0, 0, 0.8); + background-color: rgba(0, 0, 0, 0.5); + } +} + + +/* Panels */ +.noVNC_panel { + transform: translateX(25px); + + transition: 0.5s ease-in-out; + + box-sizing: border-box; /* so max-width don't have to care about padding */ + max-width: calc(100vw - 75px - 25px); /* minus left and right margins */ + max-height: 100vh; /* Chrome is buggy with 100% */ + overflow-x: hidden; + overflow-y: auto; + + visibility: hidden; + opacity: 0; + + padding: 15px; + + background: #fff; + border-radius: 10px; + color: #000; + border: 2px solid #E0E0E0; + box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); +} +.noVNC_panel.noVNC_open { + visibility: visible; + opacity: 1; + transform: translateX(75px); +} +.noVNC_right .noVNC_vcenter { + left: auto; + right: 0; +} +.noVNC_right .noVNC_panel { + transform: translateX(-25px); +} +.noVNC_right .noVNC_panel.noVNC_open { + transform: translateX(-75px); +} + +.noVNC_panel > * { + display: block; + margin: 10px auto; +} +.noVNC_panel > *:first-child { + margin-top: 0 !important; +} +.noVNC_panel > *:last-child { + margin-bottom: 0 !important; +} + +.noVNC_panel hr { + border: none; + border-top: 1px solid rgb(192, 192, 192); +} + +.noVNC_panel label { + display: block; + white-space: nowrap; + margin: 5px; +} + +.noVNC_panel li { + margin: 5px; +} + +.noVNC_panel .noVNC_heading { + background-color: rgb(110, 132, 163); + border-radius: 5px; + padding: 5px; + /* Compensate for padding in image */ + padding-right: 8px; + color: white; + font-size: 20px; + white-space: nowrap; +} +.noVNC_panel .noVNC_heading img { + vertical-align: bottom; +} + +.noVNC_submit { + float: right; +} + +/* Expanders */ +.noVNC_expander { + cursor: pointer; +} +.noVNC_expander::before { + content: url("../images/expander.svg"); + display: inline-block; + margin-right: 5px; + transition: 0.2s ease-in-out; +} +.noVNC_expander.noVNC_open::before { + transform: rotateZ(90deg); +} +.noVNC_expander ~ * { + margin: 5px; + margin-left: 10px; + padding: 5px; + background: rgba(0, 0, 0, 0.05); + border-radius: 5px; +} +.noVNC_expander:not(.noVNC_open) ~ * { + display: none; +} + +/* Control bar content */ + +#noVNC_control_bar .noVNC_logo { + font-size: 13px; +} + +.noVNC_logo + hr { + /* Remove all but top border */ + border: none; + border-top: 1px solid rgba(255, 255, 255, 0.2); +} + +:root:not(.noVNC_connected) #noVNC_view_drag_button { + display: none; +} + +/* noVNC Touch Device only buttons */ +:root:not(.noVNC_connected) #noVNC_mobile_buttons { + display: none; +} +@media not all and (any-pointer: coarse) { + /* FIXME: The button for the virtual keyboard is the only button in this + group of "mobile buttons". It is bad to assume that no touch + devices have physical keyboards available. Hopefully we can get + a media query for this: + https://github.com/w3c/csswg-drafts/issues/3871 */ + :root.noVNC_connected #noVNC_mobile_buttons { + display: none; + } +} + +/* Extra manual keys */ +:root:not(.noVNC_connected) #noVNC_toggle_extra_keys_button { + display: none; +} + +#noVNC_modifiers { + background-color: rgb(92, 92, 92); + border: none; + padding: 10px; +} + +/* Shutdown/Reboot */ +:root:not(.noVNC_connected) #noVNC_power_button { + display: none; +} +#noVNC_power { +} +#noVNC_power_buttons { + display: none; +} + +#noVNC_power input[type=button] { + width: 100%; +} + +/* Clipboard */ +:root:not(.noVNC_connected) #noVNC_clipboard_button { + display: none; +} +#noVNC_clipboard_text { + width: 360px; + min-width: 150px; + height: 160px; + min-height: 70px; + + box-sizing: border-box; + max-width: 100%; + /* minus approximate height of title, height of subtitle, and margin */ + max-height: calc(100vh - 10em - 25px); +} + +/* Settings */ +#noVNC_settings { +} +#noVNC_settings ul { + list-style: none; + padding: 0px; +} +#noVNC_setting_port { + width: 80px; +} +#noVNC_setting_path { + width: 100px; +} + +/* Version */ + +.noVNC_version_wrapper { + font-size: small; +} + +.noVNC_version { + margin-left: 1rem; +} + +/* Connection Controls */ +:root:not(.noVNC_connected) #noVNC_disconnect_button { + display: none; +} + +/* ---------------------------------------- + * Status Dialog + * ---------------------------------------- + */ + +#noVNC_status { + position: fixed; + top: 0; + left: 0; + width: 100%; + z-index: 100; + transform: translateY(-100%); + + cursor: pointer; + + transition: 0.5s ease-in-out; + + visibility: hidden; + opacity: 0; + + padding: 5px; + + display: flex; + flex-direction: row; + justify-content: center; + align-content: center; + + line-height: 25px; + word-wrap: break-word; + color: #fff; + + border-bottom: 1px solid rgba(0, 0, 0, 0.9); +} +#noVNC_status.noVNC_open { + transform: translateY(0); + visibility: visible; + opacity: 1; +} + +#noVNC_status::before { + content: ""; + display: inline-block; + width: 25px; + height: 25px; + margin-right: 5px; +} + +#noVNC_status.noVNC_status_normal { + background: rgba(128,128,128,0.9); +} +#noVNC_status.noVNC_status_normal::before { + content: url("../images/info.svg") " "; +} +#noVNC_status.noVNC_status_error { + background: rgba(200,55,55,0.9); +} +#noVNC_status.noVNC_status_error::before { + content: url("../images/error.svg") " "; +} +#noVNC_status.noVNC_status_warn { + background: rgba(180,180,30,0.9); +} +#noVNC_status.noVNC_status_warn::before { + content: url("../images/warning.svg") " "; +} + +/* ---------------------------------------- + * Connect Dialog + * ---------------------------------------- + */ + +#noVNC_connect_dlg { + transition: 0.5s ease-in-out; + + transform: scale(0, 0); + visibility: hidden; + opacity: 0; +} +#noVNC_connect_dlg.noVNC_open { + transform: scale(1, 1); + visibility: visible; + opacity: 1; +} +#noVNC_connect_dlg .noVNC_logo { + transition: 0.5s ease-in-out; + padding: 10px; + margin-bottom: 10px; + + font-size: 80px; + text-align: center; + + border-radius: 5px; +} +@media (max-width: 440px) { + #noVNC_connect_dlg { + max-width: calc(100vw - 100px); + } + #noVNC_connect_dlg .noVNC_logo { + font-size: calc(25vw - 30px); + } +} +#noVNC_connect_dlg div { + padding: 12px; + + background-color: rgb(110, 132, 163); + border-radius: 12px; + text-align: center; + font-size: 20px; + + box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); +} +#noVNC_connect_button { + width: 100%; + padding: 5px 30px; + + cursor: pointer; + + border-color: rgb(83, 99, 122); + border-radius: 5px; + + background: linear-gradient(to top, rgb(110, 132, 163), rgb(99, 119, 147)); + color: white; + + /* This avoids it jumping around when :active */ + vertical-align: middle; +} +#noVNC_connect_button:hover { + background: linear-gradient(to top, rgb(110, 132, 163), rgb(105, 125, 155)); +} + +#noVNC_connect_button img { + vertical-align: bottom; + height: 1.3em; +} + +/* ---------------------------------------- + * Server verification Dialog + * ---------------------------------------- + */ + +#noVNC_verify_server_dlg { + position: relative; + + transform: translateY(-50px); +} +#noVNC_verify_server_dlg.noVNC_open { + transform: translateY(0); +} +#noVNC_fingerprint_block { + margin: 10px; +} + +/* ---------------------------------------- + * Password Dialog + * ---------------------------------------- + */ + +#noVNC_credentials_dlg { + position: relative; + + transform: translateY(-50px); +} +#noVNC_credentials_dlg.noVNC_open { + transform: translateY(0); +} +#noVNC_username_block.noVNC_hidden, +#noVNC_password_block.noVNC_hidden { + display: none; +} + + +/* ---------------------------------------- + * Main Area + * ---------------------------------------- + */ + +/* Transition screen */ +#noVNC_transition { + transition: 0.5s ease-in-out; + + display: flex; + opacity: 0; + visibility: hidden; + + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; + + color: white; + background: rgba(0, 0, 0, 0.5); + z-index: 50; + + /*display: flex;*/ + align-items: center; + justify-content: center; + flex-direction: column; +} +:root.noVNC_loading #noVNC_transition, +:root.noVNC_connecting #noVNC_transition, +:root.noVNC_disconnecting #noVNC_transition, +:root.noVNC_reconnecting #noVNC_transition { + opacity: 1; + visibility: visible; +} +:root:not(.noVNC_reconnecting) #noVNC_cancel_reconnect_button { + display: none; +} +#noVNC_transition_text { + font-size: 1.5em; +} + +/* Main container */ +#noVNC_container { + width: 100%; + height: 100%; + background-color: #313131; + border-bottom-right-radius: 800px 600px; + /*border-top-left-radius: 800px 600px;*/ + + /* If selection isn't disabled, long-pressing stuff in the sidebar + can accidentally select the container or the canvas. This can + happen when attempting to move the handle. */ + user-select: none; + -webkit-user-select: none; +} + +#noVNC_keyboardinput { + width: 1px; + height: 1px; + background-color: #fff; + color: #fff; + border: 0; + position: absolute; + left: -40px; + z-index: -1; + ime-mode: disabled; +} + +/*Default noVNC logo.*/ +/* From: http://fonts.googleapis.com/css?family=Orbitron:700 */ +@font-face { + font-family: 'Orbitron'; + font-style: normal; + font-weight: 700; + src: local('?'), url('Orbitron700.woff') format('woff'), + url('Orbitron700.ttf') format('truetype'); +} + +.noVNC_logo { + color:yellow; + font-family: 'Orbitron', 'OrbitronTTF', sans-serif; + line-height:90%; + text-shadow: 0.1em 0.1em 0 black; +} +.noVNC_logo span{ + color:green; +} + +#noVNC_bell { + display: none; +} + +/* ---------------------------------------- + * Media sizing + * ---------------------------------------- + */ + +@media screen and (max-width: 640px){ + #noVNC_logo { + font-size: 150px; + } +} + +@media screen and (min-width: 321px) and (max-width: 480px) { + #noVNC_logo { + font-size: 110px; + } +} + +@media screen and (max-width: 320px) { + #noVNC_logo { + font-size: 90px; + } +} diff --git a/src/VncApp/wwwroot/app/styles/input.css b/src/VncApp/wwwroot/app/styles/input.css new file mode 100644 index 0000000..eaf083c --- /dev/null +++ b/src/VncApp/wwwroot/app/styles/input.css @@ -0,0 +1,281 @@ +/* + * noVNC general input element CSS + * Copyright (C) 2022 The noVNC Authors + * noVNC is licensed under the MPL 2.0 (see LICENSE.txt) + * This file is licensed under the 2-Clause BSD license (see LICENSE.txt). + */ + +/* + * Common for all inputs + */ +input, input::file-selector-button, button, select, textarea { + /* Respect standard font settings */ + font: inherit; + + /* Disable default rendering */ + appearance: none; + background: none; + + padding: 5px; + border: 1px solid rgb(192, 192, 192); + border-radius: 5px; + color: black; + --bg-gradient: linear-gradient(to top, rgb(255, 255, 255) 80%, rgb(240, 240, 240)); + background-image: var(--bg-gradient); +} + +/* + * Buttons + */ +input[type=button], +input[type=color], +input[type=image], +input[type=reset], +input[type=submit], +input::file-selector-button, +button, +select { + border-bottom-width: 2px; + + /* This avoids it jumping around when :active */ + vertical-align: middle; + margin-top: 0; + + padding-left: 20px; + padding-right: 20px; + + /* Disable Chrome's touch tap highlight */ + -webkit-tap-highlight-color: transparent; +} + +/* + * Select dropdowns + */ +select { + --select-arrow: url('data:image/svg+xml;utf8, \ + \ + \ + '); + background-image: var(--select-arrow), var(--bg-gradient); + background-position: calc(100% - 7px), left top; + background-repeat: no-repeat; + padding-right: calc(2*7px + 8px); + padding-left: 7px; +} +/* FIXME: :active isn't set when the s in some browsers, due to the limited stylability of ` + + +
+ +
+ + + +
+
+ + + + + + +
+
+ + + +
+
+
+ Power +
+ + + +
+
+ + + +
+
+
+ Clipboard +
+

+ Edit clipboard content in the textarea below. +

+ +
+
+ + + + + + +
+
+
+ Settings +
+
    +
  • + +
  • +
  • + +
  • +

  • +
  • + +
  • +
  • + + +
  • +

  • +
  • +
    Advanced
    +
      +
    • + + +
    • +
    • + + +
    • +

    • +
    • + + +
    • +
    • +
      WebSocket
      +
        +
      • + +
      • +
      • + + +
      • +
      • + + +
      • +
      • + + +
      • +
      +
    • +

    • +
    • + +
    • +
    • + + +
    • +

    • +
    • + +
    • +

    • + +
    • + +
    • +
    +
  • +

  • +
  • + Version: + +
  • +
+
+
+ + + + + + + + + +
+
+
+
+ + +
+ + +
+
+ +
+ +
+
+
+ + +
+
+
+ Server identity +
+
+ The server has provided the following identifying information: +
+
+ Fingerprint: + +
+
+ Please verify that the information is correct and press + "Approve". Otherwise press "Reject". +
+
+ + +
+
+
+ + +
+
+
+ Credentials +
+
+ + +
+
+ + +
+
+ +
+
+
+ + +
+
+
+ +
+
+
+ + +
+ + +
+ + + + diff --git a/src/poc-novnc-blazor-wasm-8.sln b/src/poc-novnc-blazor-wasm-8.sln new file mode 100644 index 0000000..0b447be --- /dev/null +++ b/src/poc-novnc-blazor-wasm-8.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VncApp", "VncApp\VncApp.csproj", "{D31F6A54-622F-4D7F-A889-51FAB7FDBF94}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D31F6A54-622F-4D7F-A889-51FAB7FDBF94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D31F6A54-622F-4D7F-A889-51FAB7FDBF94}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D31F6A54-622F-4D7F-A889-51FAB7FDBF94}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D31F6A54-622F-4D7F-A889-51FAB7FDBF94}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {3D6BCB49-6740-47AF-8A62-74CA8738C7F4} + EndGlobalSection +EndGlobal diff --git a/src/src.sln b/src/src.sln deleted file mode 100644 index 988b205..0000000 --- a/src/src.sln +++ /dev/null @@ -1,56 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31717.71 -MinimumVisualStudioVersion = 15.0.26124.0 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Tests", "Sample.Tests\Sample.Tests.csproj", "{447D1077-4FB1-48C6-9AED-B821E2655FDC}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{29C81B48-7ADA-4C89-B454-45B623039C09}" - ProjectSection(SolutionItems) = preProject - ..\.editorconfig = ..\.editorconfig - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample", "Sample\Sample.csproj", "{47C488C7-6FF9-4B80-8C3A-DA98B0499E4D}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {447D1077-4FB1-48C6-9AED-B821E2655FDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {447D1077-4FB1-48C6-9AED-B821E2655FDC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {447D1077-4FB1-48C6-9AED-B821E2655FDC}.Debug|x64.ActiveCfg = Debug|Any CPU - {447D1077-4FB1-48C6-9AED-B821E2655FDC}.Debug|x64.Build.0 = Debug|Any CPU - {447D1077-4FB1-48C6-9AED-B821E2655FDC}.Debug|x86.ActiveCfg = Debug|Any CPU - {447D1077-4FB1-48C6-9AED-B821E2655FDC}.Debug|x86.Build.0 = Debug|Any CPU - {447D1077-4FB1-48C6-9AED-B821E2655FDC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {447D1077-4FB1-48C6-9AED-B821E2655FDC}.Release|Any CPU.Build.0 = Release|Any CPU - {447D1077-4FB1-48C6-9AED-B821E2655FDC}.Release|x64.ActiveCfg = Release|Any CPU - {447D1077-4FB1-48C6-9AED-B821E2655FDC}.Release|x64.Build.0 = Release|Any CPU - {447D1077-4FB1-48C6-9AED-B821E2655FDC}.Release|x86.ActiveCfg = Release|Any CPU - {447D1077-4FB1-48C6-9AED-B821E2655FDC}.Release|x86.Build.0 = Release|Any CPU - {47C488C7-6FF9-4B80-8C3A-DA98B0499E4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {47C488C7-6FF9-4B80-8C3A-DA98B0499E4D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {47C488C7-6FF9-4B80-8C3A-DA98B0499E4D}.Debug|x64.ActiveCfg = Debug|Any CPU - {47C488C7-6FF9-4B80-8C3A-DA98B0499E4D}.Debug|x64.Build.0 = Debug|Any CPU - {47C488C7-6FF9-4B80-8C3A-DA98B0499E4D}.Debug|x86.ActiveCfg = Debug|Any CPU - {47C488C7-6FF9-4B80-8C3A-DA98B0499E4D}.Debug|x86.Build.0 = Debug|Any CPU - {47C488C7-6FF9-4B80-8C3A-DA98B0499E4D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {47C488C7-6FF9-4B80-8C3A-DA98B0499E4D}.Release|Any CPU.Build.0 = Release|Any CPU - {47C488C7-6FF9-4B80-8C3A-DA98B0499E4D}.Release|x64.ActiveCfg = Release|Any CPU - {47C488C7-6FF9-4B80-8C3A-DA98B0499E4D}.Release|x64.Build.0 = Release|Any CPU - {47C488C7-6FF9-4B80-8C3A-DA98B0499E4D}.Release|x86.ActiveCfg = Release|Any CPU - {47C488C7-6FF9-4B80-8C3A-DA98B0499E4D}.Release|x86.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {EBF86A4A-E639-4F62-AAEE-EAD045707B45} - EndGlobalSection -EndGlobal