初步整合:

1. python 内置服务器
2. 将配置文件统一目录
This commit is contained in:
mofeng-git
2025-01-01 14:26:22 +00:00
parent 5db37797ea
commit d5a0b1a8b3
411 changed files with 7387 additions and 7263 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
extends ../base.pug
append vars
- title = "One-KVM Session"
- main_js = "kvm/main"
- body_class = "body-no-select"
- css_list = css_list.concat(["navbar", "window", "modal", "led", "slider", "switch", "radio", "progress", "keypad", "tabs"])
- css_list = css_list.concat(["kvm/stream", "kvm/hid", "kvm/msd", "kvm/system", "kvm/keyboard", "kvm/about"])
block body
include navbar.pug
include windows.pug
ul(class="navbar-bg-tips")
li(class="left")
pre(id="kvmd-meta-tips-left")
li(class="right")
pre(id="kvmd-meta-tips-right")
ul(class="footer")
li(class="left")
span(id="kvmd-meta-server-host" title="Server name (see System/About)")
|   |  
span(id="kvmd-version-kvmd" title="KVMD version")
|   |  
span(id="kvmd-version-streamer" title="Streamer version")
li(class="right")
a(target="_blank" href="https://pikvm.org" i18n="index_text_10") PiKVM Project
|   |  
a(target="_blank" href="https://docs.pikvm.org" i18n="index_text_11") Documentation
|   |  
a(target="_blank" href="https://github.com/mofeng-git/One-KVM" i18n="index_text_12") One-KVM Project
|   |  
a(target="_blank" href="https://one-kvm.mofeng.run" i18n="index_text_13") One-KVM Documentation

View File

@@ -0,0 +1,17 @@
li(id="atx-dropdown" class="right feature-disabled")
a(class="menu-button" href="#")
+navbar_led("atx-power-led", "led-atx-power")
+navbar_led("atx-hdd-led", "led-atx-hdd")
span ATX
div(class="menu")
div(class="text")
b Control the server's power#[br]
sub Use the short click for ACPI shutdown
hr
+menu_switch("atx-ask-switch", "Ask click confirmation", true, true,"atx-ask-switch")
hr
div(class="buttons")
button(disabled data-force-hide-menu id="atx-power-button") • Click Power #[sup #[i short]]
button(disabled data-force-hide-menu id="atx-power-button-long") • Click Power #[sup #[i long]]
hr
button(disabled data-force-hide-menu id="atx-reset-button") • Click Reset

View File

@@ -0,0 +1,4 @@
li(id="gpio-dropdown" class="right feature-disabled")
a(class="menu-button" id="gpio-menu-button" href="#")
span GPIO
div(id="gpio-menu" class="menu")

View File

@@ -0,0 +1,32 @@
div(id="hw-health-dropdown" class="hidden")
li(class="left")
a(class="menu-button" href="#")
+navbar_led("hw-health-undervoltage-led", "led-undervoltage", "hidden")
+navbar_led("hw-health-overheating-led", "led-overheating", "hidden")
div(class="menu")
+menu_message("warning", "Raspberry Pi's health is at risk")
| This is not a drill! A red icon indicates a current issue,#[br]
| a yellow one that was observed since the device booted up
div(id="hw-health-message-undervoltage" class="hidden")
hr
+menu_message("led-undervoltage", "Undervoltage detected", "led-gray")
| Make sure your power supply and cabling are providing#[br]
| enough power to the Raspberry Pi (3A minimum)
div(id="hw-health-message-overheating" class="hidden")
hr
+menu_message("led-overheating", "Overheating detected", "led-gray")
| Frequency capping due to overheating,#[br]
| please improve cooling of the Raspberry Pi
div(id="fan-health-dropdown" class="hidden")
li(class="left")
a(class="menu-button" href="#")
+navbar_led("fan-health-led", "led-fan", "hidden")
div(class="menu")
+menu_message("warning", "Raspberry Pi's health is at risk")
| This is not a drill! A red icon indicates a current issue,#[br]
| a yellow one that was observed in the past
div(id="fan-health-message-fail")
hr
+menu_message("led-fan", "Fan failed", "led-gray")
| A fan error occured, please #[a(href="/api/log?seek=3600&follow=1" target="_blank") check the log]

View File

@@ -0,0 +1,30 @@
li(id="macro-dropdown" class="right")
a(class="menu-button" href="#")
+navbar_led("hid-recorder-led", "led-gear")
span(i18n="kvm_text32") Macro
div(class="menu")
div(class="text")
b(i18n="kvm_text33") Record and play HID/ATX/GPIO actions#[br]
sub(i18n="kvm_text34") For security reasons, the record will not be saved on the PiKVM
hr
div(class="buttons buttons-row")
button(disabled data-force-hide-menu id="hid-recorder-record" class="row25" i18n="kvm_text35") • Rec
button(disabled id="hid-recorder-stop" class="row25" i18n="kvm_text36") Stop
button(disabled id="hid-recorder-play" class="row25" i18n="kvm_text37") Play
button(disabled id="hid-recorder-clear" class="row25" i18n="kvm_text38") Clear
hr
table(class="kv")
tr
td(i18n="kvm_text39") Script time:
td(colspan="2" id="hid-recorder-time" class="value") 00:00:00.0
tr
td(i18n="kvm_text40") Scripted events:
td(id="hid-recorder-events-count" class="value") 0
td #[sup #[i(i18n="kvm_text41") include delays]]
hr
+menu_switch("hid-recorder-loop-switch", "Infinite loop playback", false, false, "hid-recorder-loop-switch")
hr
input(type="file" id="hid-recorder-new-script-file")
div(class="buttons buttons-row")
button(disabled id="hid-recorder-upload" class="row50" i18n="kvm_text42") Upload script
button(disabled id="hid-recorder-download" class="row50" i18n="kvm_text43") Download script

View File

@@ -0,0 +1,124 @@
li(id="msd-dropdown" class="right feature-disabled")
a(class="menu-button" href="#")
+navbar_led("msd-led", "led-msd")
span(i18n="kvm_text60") Drive
div(id="msd-menu" class="menu")
div(class="text")
b(i18n="kvm_text61") Mass Storage Drive:
span(id="msd-status")
br
hr
div(id="msd-message-offline" class="hidden")
+menu_message("warning", "Mass Storage Drive is offline", "msd-message-offline")
hr
div(id="msd-message-image-broken" class="hidden")
+menu_message("warning", "Current image is broken!", "msd-message-image-broken")
| Perhaps uploading was interrupted#[br]
hr
div(id="msd-message-too-big-for-cdrom" class="hidden")
+menu_message("warning", "Current image is too big for CD-ROM!", "msd-message-too-big-for-cdrom")
| The device filesystem will be truncated to 2.2GiB
hr
div(id="msd-message-out-of-storage" class="hidden")
+menu_message("warning", "Current image is out of storage", "msd-message-out-of-storage")
| This image was connected manually using #[b kvmd-otgmsd]
hr
div(id="msd-message-rw-enabled" class="hidden")
+menu_message("warning", "Read-write mode is enabled", "msd-message-rw-enabled")
| Do not turn off PiKVM while this is active to prevent#[br]
| filesystem corruption. Use read-only mode where possible,#[br]
| as writing to SD card often can reduce its lifespan.
hr
div(id="msd-message-downloads" class="hidden")
+menu_message("info", "The image is being downloaded from PiKVM", "msd-message-downloads")
| Please wait
hr
table(class="kv")
tr
td(i18n="kvm_text62") Image:
td(width="100%") #[select(disabled id="msd-image-selector")]
td #[button(disabled id="msd-download-button" title="Download image") #[b   ⇩  ]]
td #[button(disabled id="msd-remove-button" title="Remove image") #[b   ×  ]]
table(class="kv")
tr
td(i18n="kvm_text63") Drive #[a(target="_blank" href="https://docs.pikvm.org/msd") mode]:
td
div(class="radio-box")
input(checked type="radio" id="msd-mode-radio-cdrom" name="msd-mode-radio" value="1")
label(for="msd-mode-radio-cdrom") CD-ROM
input(type="radio" id="msd-mode-radio-flash" name="msd-mode-radio" value="0")
label(for="msd-mode-radio-flash") Flash
td  
+menu_switch_notable("msd-rw-switch", "Writable", false, false, "msd-rw-switch")
tr
td(i18n="kvm_text84") 文件内容:
td
div(class="radio-box")
input(checked type="radio" id="msd-mode-radio-image" name="file-mode-radio" value="1")
label(for="msd-mode-radio-image" i18n="kvm_text90") ImageFiles
input(type="radio" id="msd-mode-radio-file" name="file-mode-radio" value="0")
label(for="msd-mode-radio-file" i18n="kvm_text91") NormalFiles
div(id="msd-storages")
hr
div(class="buttons buttons-row")
button(disabled id="msd-select-new-button" class="row50" i18n="kvm_text64") Select image to upload
button(disabled id="msd-upload-new-button" class="row25" i18n="kvm_text65") Upload
button(disabled id="msd-abort-new-button" class="row25" i18n="kvm_text66") Abort
div(id="msd-message-another-user-uploads" class="hidden")
hr
+menu_message("info", "Another user uploads an image", "msd-message-another-user-uploads")
div(id="msd-new-sub" class="hidden")
hr
table(class="kv")
tr
td(i18n="kvm_text68") Specify a local file:
td #[input(type="file" id="msd-new-file")]
tr
td(i18n="kvm_text69") #[b Or] paste a URL:
td #[input(type="text" id="msd-new-url" style="width: 100%")]
tr(id="msd-new-part" class="hidden")
td(i18n="kvm_text70") Upload partition:
td(width="100%") #[select(id="msd-new-part-selector")]
div(id="msd-uploading-sub" class="hidden")
hr
table(class="kv")
tr
td(i18n="kvm_text74") New image:
td(id="msd-uploading-name" class="value")
tr
td(i18n="kvm_text75") Upload size:
td(id="msd-uploading-size" class="value")
div(class="text")
div(id="msd-uploading-progress" class="progress")
span(id="msd-uploading-progress-value" class="progress-value")
div(id="msd-new-tips" class="hidden")
hr
table(class="kv")
tr
td(class="value" i18n="kvm_text71") Note:
td(i18n="kvm_text72") • Don't close the browser page until the upload is complete.
tr
td
td(i18n="kvm_text73") • To speed up the upload, close the stream window.
hr
div(class="buttons buttons-row")
button(disabled id="msd-connect-button" class="row50" i18n="kvm_text76") Connect drive to Server
button(disabled id="msd-disconnect-button" class="row25" i18n="kvm_text77") Disconnect
button(disabled id="msd-reset-button" class="row25" i18n="kvm_text78") Reset
hr
div(class="text")
b(i18n="kvm_text85") Quick file transfer:
br
sub(i18n="kvm_text86") • Select NormalFiles tab to upload, package them and mount image
br
sub(i18n="kvm_text87") • Disconnect MSD, unpackage it, select tab to download
br
hr
div(class="buttons buttons-row")
button(id="msd-file-image-update-button" class="row50" i18n="kvm_text88") Package files into image
button(id="msd-file-image-unzip-button" class="row50" i18n="kvm_text89") Unpackage files from image
hr

View File

@@ -0,0 +1,68 @@
li(id="shortcuts-dropdown" class="right")
a(class="menu-button" href="#" i18n="kvm_text56") Shortcuts
div(id="shortcuts-menu" class="menu")
div(class="text")
b(i18n="kvm_text57") Quick keyboard shortcuts#[br]
sub(i18n="kvm_text58") Also see #[i System → Show keyboard]
hr
div(class="buttons")
div(class="buttons-row")
button(data-force-hide-menu data-shortcut="CapsLock" class="row50")
| • Caps Lock  
img(class="inline-lamp hid-keyboard-caps-led led-gray" src=`${svg_dir}/led-square.svg`)
button(data-force-hide-menu data-shortcut="MetaLeft" class="row50") • Left Win
hr
div(class="buttons-row")
button(data-force-hide-menu data-shortcut="AltLeft ShiftLeft" class="row50") • Alt+Shift
button(data-force-hide-menu data-shortcut="ControlLeft KeyW" class="row50") • Ctrl+W
div(class="buttons-row")
button(data-force-hide-menu data-shortcut="ControlLeft ShiftLeft" class="row50") • Ctrl+Shift
button(data-force-hide-menu data-shortcut="AltLeft Tab" class="row50") • Alt+Tab
div(class="buttons-row")
button(data-force-hide-menu data-shortcut="ShiftLeft ShiftRight" class="row50") • Shift+Shift
button(data-force-hide-menu data-shortcut="AltLeft Enter" class="row50") • Alt+Enter
div(class="buttons-row")
button(data-force-hide-menu data-shortcut="MetaLeft Space" class="row50") • Win+Space
button(data-force-hide-menu data-shortcut="AltLeft F4" class="row50") • Alt+F4
hr
div(class="buttons-row")
button(data-force-hide-menu data-shortcut="ControlLeft AltLeft F1" class="row50") • Ctrl+Alt+F1
button(data-force-hide-menu data-shortcut="MetaLeft KeyL" class="row50") • Win+L
div(class="buttons-row")
button(data-force-hide-menu data-shortcut="ControlLeft AltLeft F2" class="row50") • Ctrl+Alt+F2
button(data-force-hide-menu data-shortcut="PrintScreen" class="row50") • Print Screen
hr
div(class="buttons-row")
button(data-force-hide-menu data-shortcut="ControlLeft AltLeft Delete" class="row50") • Ctrl+Alt+Del
button(data-force-hide-menu data-shortcut="Power" class="row50") • Power
hr
div(class="text")
| &darr; &bull; Alt+SysRq+... <sup><i>linux magic
| #[a(target="_blank" href="https://www.kernel.org/doc/html/latest/admin-guide/sysrq.html" i18n="kvm_text59") help]</i></sup>
hr
div(class="buttons")
div(class="buttons-row")
-
let sysrq = {
"F": "Call the OOM killer to kill a memory hog process",
"M": "Dump current memory info to the console",
"D": "Show all locks that are held",
"T": "Dump a list of current tasks and their information to the console",
}
each title, key in sysrq
button(data-shortcut=`AltLeft PrintScreen Key${key}` data-shortcut-confirm="hid-sysrq-ask-switch" class="row25" style="text-align: center;" title=`${title}`) #{key}
hr
div(class="buttons-row")
-
sysrq = {
"R": "Turn off keyboard raw mode, set it to XLATE",
"E": "Send a SIGTERM to all processes, except for init",
"I": "Send a SIGKILL to all processes, except for init",
"S": "Attempt to sync all mounted filesystems",
"U": "Attempt to remount all mounted filesystems read-only",
"B": "Immediately reboot the system without syncing or unmounting disks",
}
each title, key in sysrq
button(data-shortcut=`AltLeft PrintScreen Key${key}` data-shortcut-confirm="hid-sysrq-ask-switch" class="row16" style="text-align: center;" title=`${title}`) #{key}
hr
+menu_switch("hid-sysrq-ask-switch", "Ask the magic confirmation", true, true,"hid-sysrq-ask-switch")

View File

@@ -0,0 +1,145 @@
li(id="system-dropdown" class="right")
a(class="menu-button" href="#")
+navbar_led("link-led", "led-link")
+navbar_led("stream-led", "led-stream")
+navbar_led("hid-keyboard-led", "led-hid-keyboard")
+navbar_led("hid-mouse-led", "led-hid-mouse")
span(i18n="kvm_text3") System
div(id="system-menu" class="menu")
table(class="kv")
tr
td(class="value" i18n="kvm_text4") Runtime settings &amp; tools
td(id="system-tool-webterm" class="feature-disabled") #[button(data-force-hide-menu data-show-window="webterm-window" class="small" i18n="kvm_text5") &bull; Term]
td(id="system-tool-about") #[button(data-force-hide-menu data-show-window="about-window" class="small" i18n="kvm_text6") &bull; About]
td(id="system-tool-log") #[button(data-force-hide-menu id="open-log-button" class="small" i18n="kvm_text7") &bull; Log]
td(id="system-tool-wol" class="feature-disabled")
button(data-force-hide-menu class="__gpio-button-__wol__ __gpio-button small" data-channel="__wol__"
data-confirm="Are you sure to send Wake-on-LAN packet to the server?" i18n="kvm_text8") &bull; WoL
hr
div(id="stream-message-no-webrtc" class="hidden")
+menu_message("warning", "WebRTC is not supported by this browser", "stream-message-no-webrtc")
hr
div(id="stream-message-no-h264" class="hidden")
+menu_message("warning", "H.264 is not supported by this browser", "stream-message-no-h264")
hr
table(class="kv")
tr(id="stream-resolution" class="feature-disabled")
td(i18n="kvm_text9") Resolution:
td #[select(disabled id="stream-resolution-selector")]
tr(id="stream-quality" class="feature-disabled")
td(i18n="kvm_text10") JPEG quality:
td(class="value-slider") #[input(disabled type="range" id="stream-quality-slider" class="slider")]
td(id="stream-quality-value" class="value-number")
tr
td(i18n="kvm_text11") JPEG max fps:
td(class="value-slider") #[input(disabled type="range" id="stream-desired-fps-slider" class="slider")]
td(id="stream-desired-fps-value" class="value-number")
tr(id="stream-h264-bitrate" class="feature-disabled")
td(i18n="kvm_text12") H.264 kbps:
td(class="value-slider") #[input(disabled type="range" id="stream-h264-bitrate-slider" class="slider")]
td(id="stream-h264-bitrate-value" class="value-number")
tr(id="stream-h264-gop" class="feature-disabled")
td(i18n="kvm_text13") H.264 #[a(target="_blank" href="https://docs.pikvm.org/webrtc") gop]:
td(class="value-slider") #[input(disabled type="range" id="stream-h264-gop-slider" class="slider")]
td(id="stream-h264-gop-value" class="value-number")
tr(id="stream-mode" class="feature-disabled")
td(i18n="kvm_text14") Video #[a(target="_blank" href="https://docs.pikvm.org/webrtc") mode]:
td
div(class="radio-box")
input(checked type="radio" id="stream-mode-radio-mjpeg" name="stream-mode-radio" value="mjpeg")
label(for="stream-mode-radio-mjpeg") MJPEG / HTTP
input(type="radio" id="stream-mode-radio-janus" name="stream-mode-radio" value="janus")
label(for="stream-mode-radio-janus") H.264 / WebRTC
tr(id="stream-orient" class="feature-disabled")
td(i18n="kvm_text17") Orientation:
td
div(class="radio-box")
input(checked type="radio" id="stream-orient-radio-0" name="stream-orient-radio" value="0")
label(for="stream-orient-radio-0" i18n="kvm_text18") Default
input(type="radio" id="stream-orient-radio-90" name="stream-orient-radio" value="90")
label(for="stream-orient-radio-90") 90&deg;
input(type="radio" id="stream-orient-radio-180" name="stream-orient-radio" value="180")
label(for="stream-orient-radio-180") 180&deg;
input(type="radio" id="stream-orient-radio-270" name="stream-orient-radio" value="270")
label(for="stream-orient-radio-270") 270&deg;
tr(id="stream-audio", class="feature-disabled")
td(i18n="kvm_text19") Audio volume:
td(class="value-slider") #[input(type="range" id="stream-audio-volume-slider" class="slider")]
td(id="stream-audio-volume-value" class="value-number")
hr
div(class="buttons buttons-row")
button(data-force-hide-menu data-show-window="stream-window" class="row33" i18n="kvm_text20") &bull; Show stream
button(data-force-hide-menu id="stream-screenshot-button" class="row33" i18n="kvm_text21") &bull; Screenshot
button(id="stream-reset-button" class="row33" i18n="kvm_text22") Reset stream
div(class="text")
b(i18n="kvm_text79") Video Record#[br]
sub(i18n="kvm_text80") Record video using the browser API, and will be downloaded automatically
div(class="buttons buttons-row")
button(data-force-hide-menu id="stream-record-start-button" class="row50" i18n="kvm_text81") &bull; Start recording
button(data-force-hide-menu id="stream-record-stop-button" class="row50" i18n="kvm_text82") &bull; End recording
hr
table(class="kv")
tr(id="hid-outputs-keyboard", class="feature-disabled")
td(i18n="kvm_text23") Keyboard mode:
td #[div(id="hid-outputs-keyboard-box" class="radio-box")]
tr(id="hid-outputs-mouse", class="feature-disabled")
td(i18n="kvm_text24") Mouse #[a(target="_blank" href="https://docs.pikvm.org/mouse") mode]:
td #[div(id="hid-outputs-mouse-box" class="radio-box")]
details
summary(i18n="kvm_text25") Keyboard &amp; Mouse (HID) settings
div(class="spoiler")
table(class="kv")
tr
+menu_switch_notable("hid-keyboard-swap-cc-switch", "Swap Left Ctrl and Caps keys", true, false, "hid-keyboard-swap-cc-switch")
hr
table(class="kv")
tr
td(i18n="kvm_text26") Mouse polling:
td(class="value-slider") #[input(type="range" id="hid-mouse-rate-slider" class="slider")]
td(id="hid-mouse-rate-value" class="value-number")
tr(id="hid-mouse-sens" class="feature-disabled")
td(i18n="kvm_text27") Relative sensitivity:
td(class="value-slider") #[input(disabled type="range" id="hid-mouse-sens-slider" class="slider")]
td(id="hid-mouse-sens-value" class="value-number")
tr(id="hid-mouse-squash" class="feature-disabled")
+menu_switch_notable("hid-mouse-squash-switch", "Squash relative moves", true, true, "hid-mouse-squash-switch")
tr
td(i18n="kvm_text28") Reverse scrolling:
td
table
tr
+menu_switch_notable("hid-mouse-reverse-scrolling-switch", "Y", true, false)
td &nbsp;&nbsp;
+menu_switch_notable("hid-mouse-reverse-panning-switch", "X", true, false)
tr
+menu_switch_notable("hid-mouse-cumulative-scrolling-switch", "Cumulative scrolling", true, false,"hid-mouse-cumulative-scrolling-switch")
tr
td(i18n="kvm_text29") Scroll rate:
td(class="value-slider") #[input(type="range" id="hid-mouse-scroll-slider" class="slider")]
td(id="hid-mouse-scroll-value" class="value-number")
tr
+menu_switch_notable("hid-mouse-dot-switch", "Show the blue dot", true, true, "hid-mouse-dot-switch")
details
summary(i18n="kvm_text83") Web UI settings
div(class="spoiler")
table(class="kv")
tr
+menu_switch_notable("page-close-ask-switch", "Ask page close confirmation", true, true, "page-close-ask-switch")
tr
+menu_switch_notable("page-full-tab-stream-switch", "Expand for the entire tab by default", true, false,"page-full-tab-stream-switch")
table(class="kv")
tr(id="hid-connect" class="feature-disabled")
+menu_switch_notable("hid-connect-switch", "Connect HID to Server", true, true, "hid-connect-switch")
tr(id="hid-jiggler" class="feature-disabled")
+menu_switch_notable("hid-jiggler-switch", "<a href=\"https://docs.pikvm.org/mouse_jiggler\" target=\"_blank\">Mouse jiggler</a>", false, false,"hid-jiggler-switch")
tr
+menu_switch_notable("hid-mute-switch", "Mute HID input events", true, false, "hid-mute-switch")
tr(id="v3-usb-breaker" class="feature-disabled")
+menu_switch_notable_gpio("__v3_usb_breaker__", "Connect main USB to Server",
"Turning off this switch will disconnect the main USB<br>from the server. Are you sure you want to continue?")
tr(id="v4-locator" class="feature-disabled")
+menu_switch_notable_gpio("__v4_locator__", "Enable locator LED")
hr
div(class="buttons buttons-row")
button(data-force-hide-menu data-show-window="keyboard-window" class="row50" i18n="kvm_text30") &bull; Show keyboard
button(disabled id="hid-reset-button" class="row50" i18n="kvm_text31") Reset HID

View File

@@ -0,0 +1,46 @@
li(id="text-dropdown" class="right")
a(class="menu-button" href="#")
+navbar_led("stream-ocr-led", "led-gear", "feature-disabled")
span(i18n="kvm_text44") Text
div(id="text-menu" class="menu")
div(class="text")
b(i18n="kvm_text45") Paste text as keypress sequence#[br]
sub(i18n="kvm_text46") Please note that PiKVM cannot switch the keyboard layout
hr
div(class="text" style="margin-right: 20px")
textarea(id="hid-pak-text" data-focus placeholder="Enter your text here")
table(class="kv")
tr
td
button(disabled data-force-hide-menu id="hid-pak-button" i18n="kvm_text47") &bull; Paste
td(i18n="kvm_text48") using host keymap
td
select(id="hid-pak-keymap-selector")
table(class="kv")
tr
+menu_switch_notable("hid-pak-ask-switch", "Ask paste confirmation", true, true, "hid-pak-ask-switch")
tr(id="hid-pak-secure" class="feature-disabled")
+menu_switch_notable("hid-pak-secure-switch", "Hide input text", true, false,"hid-pak-secure-switch")
div(id="stream-ocr" class="feature-disabled")
hr
br
hr
div(class="text")
b(i18n="kvm_text49") Text recognition <sup><i>&beta;</i></sup>#[br]
sub(i18n="kvm_text50") #[a(target="_blank" href="https://docs.pikvm.org/ocr") OCR] works locally on PiKVM
hr
table(class="kv")
tr
td
button(data-force-hide-menu id="stream-ocr-button" i18n="kvm_text51") &bull; Select area
td(i18n="kvm_text52") for
td
select(id="stream-ocr-lang-selector")
td(i18n="kvm_text53") text recognition
table(class="kv")
tr
td(colspan="4" i18n="kvm_text54") &bull; Press #[b Enter] to recognize and copy text to clipboard
tr
td(colspan="4" i18n="kvm_text55") &bull; Press #[b Esc] to cancel selection
tr
td

View File

@@ -0,0 +1,53 @@
mixin navbar_led(id, icon, cls="led-gray")
img(id=id, class=cls src=`${svg_dir}/${icon}.svg`)
mixin menu_message(icon, short, classes="", i18nid)
div(class="text")
table
tr
td(rowspan="2") #[img(class=`sign ${classes}` src=`${svg_dir}/${icon}.svg`)]
td(style="line-height:1.5") #[b(i18n=i18nid) #{short}]
if block
tr
td
sup(style="line-height:1")
block
mixin menu_switch_notable_gpio(channel, title, confirm_off="")
td !{title}:
td(align="right")
div(class="switch-box")
input(disabled type="checkbox" id=`__gpio-switch-${channel}` class=`__gpio-switch-${channel} gpio-switch`
data-channel=channel data-confirm-off=confirm_off)
label(for=`__gpio-switch-${channel}`)
span(class="switch-inner")
span(class="switch")
mixin menu_switch_notable(id, title, enabled, checked, i18nid)
td(i18n=i18nid) !{title}:
td(align="right")
div(class="switch-box")
input(checked=checked disabled=!enabled type="checkbox" id=id)
label(for=id)
span(class="switch-inner")
span(class="switch")
mixin menu_switch(id, title, enabled, checked, i18nid)
table(class="kv")
tr
+menu_switch_notable(id, title, enabled, checked, i18nid)
ul(id="navbar")
li(class="left")
a(id="logo" href="/") &larr;&nbsp;&nbsp;
img(class="svg-gray" src=`${svg_dir}/logo.svg` alt="&pi;-kvm")
include navbar-health.pug
include navbar-system.pug
include navbar-atx.pug
include navbar-msd.pug
include navbar-macro.pug
include navbar-text.pug
include navbar-shortcuts.pug
include navbar-gpio.pug

View File

@@ -0,0 +1,692 @@
mixin about_tab(name, title, i18nid, checked=false)
- let button_id = `about-tab-${name}-button`
input(checked=checked type="radio" name="about-tab-button", id=button_id)
label(for=button_id i18n=i18nid) #{title}
div(class="tab")
div(id=`about-${name}` class="code")
if block
block
else
span(class="code-comment") No data
div(id="about-window" class="window")
div(class="window-header")
div(class="window-grab" i18n="kvm_text1") About
button(class="window-button-close") #[b &times;]
div(id="about")
table
tr
td(class="logo")
a(href="https://pikvm.org" target="_blank")
img(class="svg-gray" src=`${svg_dir}/logo.svg` alt="PiKVM" height="40")
td
table
tr #[td(colspan="2" class="title" i18n="index_title") The Open Source KVM over IP]
tr
td(colspan="2" class="copyright" i18n="copyright")
| Copyright &copy; 2018-2024 #[a(target="_blank" href="mailto:mdevaev@gmail.com") Maxim Devaev]
br
div(class="tabs-box")
+about_tab("meta", "Meta", "meta", true)
div
span(class="code-comment")
| // You can get this JSON using handle #[a(target="_blank" href="/api/info?fields=meta") /api/info?fields=meta]#[br]
| // In the standard configuration this data#[br]
| // is specified in the file /etc/kvmd/meta.yaml
br
pre(id="kvmd-meta-json")
| No data
+about_tab("hardware", "Hardware", "hardware")
+about_tab("version", "Version", "version")
+about_tab("thanks", "Thanks", "thanks")
span(class="code-comment" i18n="kvm_text2")
| // These kind people donated money to the PiKVM project#[br]
| // and supported the work on it. We are very grateful#[br]
| // for their help, and memorializing their names#[br]
| // is the least we can do in gratitude.#[br]
| // If you also want to support this project,#[br]
| // you can donate on #[a(target="_blank" href="https://www.patreon.com/pikvm") Patreon]
| or #[a(target="_blank" href="https://paypal.me/pikvm") Paypal].
ul
li A. Isenring
li Aaron Graubert
li Aaron Heise
li Aaron Stein
li Accalia
li Adam Goodbar
li Adam S
li Adam Stuart
li AdamBomb
li adipisicing
li Adrian Basham
li Adrian Popescu
li Ahmed Syed
li Alberto Bassi
li alejandro
li Aleksei Brusianskii
li Alessio Curri
li Alex T
li Alex Z
li Alexander Karmanov
li Alexander Lahuerta
li Alexander Martin
li Alexander Pankov
li Alexandre Jablonski
li Alexey Kamenskiy
li alm0241
li Alok Anand
li Alucard
li Ananthaneshan Elampoornan
li Andreas Marufke
li Andreas Schmid
li Andrew Brant
li Andrew Melton
li Andrew Reusch
li Andrew Ruan
li Andrzej V
li Andy
li Andy Keys
li Anish Patel
li Anix
li Anonymous
li Anthony Junk
li Anton Kovalenko
li Armen
li Aron Green
li Aron Perelman
li Artem Simonov
li Arthur Mayer
li Arthur Woimbée
li Ashlesh Chaudhari
li Asim Shakour
li Augusto Becciu
li AVS Computer
li awkspace
li Badal Patel
li baddog
li Bao Tin Hoang
li Bean Co.
li Bela Bargel
li Belf Igor
li Ben Gordon
li Ben Scott
li Benedikt Heine
li Benedikt Meier
li Benjamin Frewert
li Benjamin Melancon
li Benjamin Schwartz
li Benjamin Stegmann
li Benni Stauder
li Bernhard Fitzke
li Beu
li bikmaek
li bitjoe
li Bits and Bytes Computers LLC
li Bjoern Petsch
li Blair Hasler
li Blindside
li Blue Frog LLC
li Bootstrapper - Programmierung erklärt
li Bosco
li Bradford King
li Brainspore Networks
li Branden Shaulis
li Brandon Daniels
li Brian
li Brian Moses
li Brian T Mulcahy
li Brian Vecchiarelli
li Brian White
li Bruno Gomes
li Bryan Adams
li Bryan Montgomery
li Buzzer
li C P ELSE
li Calanish
li Cameron Hatcher
li Cameron Tacklind
li Carl Mercier
li Carl-Fredrik Johansson
li Carlos Eduardo Porter Herrera
li Carlos Garcia
li Carlos Manuel Torres
li cbad536
li César Nascimento
li CHINATERA LIMITED
li Chris Blackmon
li Chris Burton
li Chris Campbell
li Chris Jackson
li Chris Lewis
li Chris Rizio
li Christi King
li Christian Schlögl
li Christian Svensson
li Christof Maluck
li Christoph Dette
li Christoffer Lund
li Christopher Bulla
li Christopher Gelatt
li Christopher Hearn
li Christopher Mandlbaur
li Christopher Mendoza
li Christopher Simms
li Chucktastic
li Cihan VURAL
li clauskj3r
li Clifford Coleman
li Clinton Lee Taylor
li Cole Imhoff
li Colin Goodman
li Corey Layton
li Corey Lista
li Craig Keenan
li Crossfactor
li Cruzzer
li ctag
li Curt Sammer
li CyB0rgg
li DeMentor
li Desmond Whitt
li Daegara
li DailyAneurism
li Damon Meledones
li Dan Berkowitz
li Dan Brakeley
li Daniel Bowder
li Daniel Cabrera
li Daniel Davila
li Danilo Saft
li Danne
li Dariusz Techmański
li David
li David Brausewetter
li David Davis
li David Godibadze
li David Howell
li David Irvine
li David Klinkman
li David Niemann
li David Shay
li David Ye
li David York
li Denis
li Denis Andreev
li Denis Yatsenko
li Dennis Becker
li Dennis Joslin
li Dennis Lomet
li Derek Jarvis
li Derek Yap
li Didrik
li digitalbaconbits
li Dimitrij Jedich
li dixon wong
li dizztrukshin
li Dmitry Shilov
li DogeLabs
li Dominic Phoon
li Dominik Klonowski
li Donald Hays
li Edmon Abdul Nur
li Edward Wang
li Egan Ford
li Elani Ferri
li Elliot Woo
li Entt
li Eric Phenix
li Ethan Shold
li Eugene Sukhodolin
li ewook
li eye-catcher.com
li Fabian Druschke
li Fabiano Sidler
li Far Pin Solutions, LLC
li Felyx Gabryel
li Fergus McKay
li Finn Ebenritter
li floppy
li fo0bar
li Foad Yousef
li Foamy
li Foli Ayivoh
li Folkert Weistra
li Francisco Pavon
li Frank
li Frank Sander
li Frederick Czajka
li Fredrik Idréus
li Garrett Dangerfield
li Ge Men
li Geekworm
li Genkinger Andreas
li Geijer
li Geoffrey Wright
li George Becker
li Georgy Brodsky
li Gerald
li Gerardus Vernimmen
li Gernot Neuschröer
li Giovanni Fulco
li GK
li Glen Dragon
li Greg Winterstein
li Gregory Smith
li Gregory Treantos
li grewil
li Grey Cynic
li Guenter Honisch
li Guido Bernacchi
li Gustin Johnson
li György Tamás Vizi
li Haiberg GmbH
li Haven Zheng
li Heibunny
li Heikki Tiittanen
li Helio Leonardo Pinheiro e Mota
li Henrik Ählström
li Henry Hood
li HimKo
li HouseFPV
li Howard Simons
li HyunohRyu
li Icculus
li iks
li INFO TRX INC
li Invader Monks
li Ioannis Karageorgos
li Isaac
li IT Lifesaver
li Ivan Ganev
li Ivan Josiah Lapis
li Ivan Shapovalov
li iwbjhbweriuhf
li J
li J L
li Jaanus
li Jackson Wyatt
li Jacob Karaffa
li Jacob Morgan
li James Cadd
li James Cobb
li James Edwards
li James Kocher
li James Mayhugh
li James Noonan
li James Ye
li Jamie Murphy
li Jamie Scott
li Jan Niehusmann
li Jannick Oursin
li Jari Hiltunen
li Jason Crossley
li Jason Downey
li Jason Toland
li Jasper Backer
li Jay Davis
li Jay Isaacs
li Jazereel Goh
li Jean-Daniel Croteau
li Jean-Philippe Guilbault
li Jeff
li Jeff Bowman
li Jeff Urlwin
li Jennifer Herting
li Jennifer Rowlett
li Jeremy Abel
li Jeremy Combs
li Jeremy Hines
li Jerremy Holland
li Jerry Nall
li Jerry Y. Chen
li Jim Bailey
li Jim Harbin
li Jimmy Burgett
li Jimmy Stanley
li Joachim Bruening
li Joe Hanson
li Joe Hinteregger
li Joe Ventura
li Joel Jacobs
li Johannes Heigermose
li John Andersen
li John Copeland
li John F Glenn
li John Holmes
li John Kelley
li John McGovern
li Johnny Henson
li Jon Ferguy
li Jon-Eric
li Joni Ruuskanen
li Jonas Fischer
li Jonathan Slenders
li Jonathan Vaughn
li Joost Backer
li Jordan Blake
li Jordi Pakey-Rodriguez
li Joris van Embden
li Joseph Swift
li Josh Nethery
li Josh Ricker
li Josh VanDeraa
li Joshua Futterer
li Jozef Riha
li Jörgen Fredriksson
li Julian Forero
li Julian Schneider
li Julien Angelier
li Justin
li Justin Waters
li Kai Hadler
li Kamil Chyba
li Kari Matti Korpi
li Karl Dunne
li Karl Moos
li Keith Muggleton
li Ken Lee
li Kenneth Younger III
li Kenny Hui
li KeonWoo PARK
li Kevin Bajohr
li Kevin Schwartz
li Kevin Sherwood
li Kiera Kujisawa
li Kiran Schuler
li Koloman
li Konrad Neitzel
li Krzysztof Żelaśkiewicz
li Lance Ward
li Larry Meaney
li Lars
li Lars Reinhardt
li Lee Wilkinson
li LeeNX
li Leon Siegl
li Leonard Feineis
li Lewis Wild
li Liran
li Liviu Dimitriu
li Lizardo Hernandez
li LoCascio
li Lordbob75
li Lothar Schweikle-Droll
li Louis Müller
li LSDTripp
li Ľubor Slušný
li Luca Di Diomede
li Lucio De Carli
li Luiz Bizzio
li Lukas Bischof
li Lukas Kammerer
li Lukas Söder
li Maksim Terehin
li Malcolm Cameron
li Manfred Radeschnig
li Marc Khouri
li Marcin Wilk
li Marcio Zimbres
li Marco Rossi
li Marcos Wolf
li Marek Marczykowski-Górecki
li Marius
li Mar. Balske
li Mark Farrell
li Mark Gilbert
li Mark Knam
li Mark Robinson
li Markrosoft
li Markus Halm
li Markus Schicker
li Markus Sobczack
li Marshall Bjerke
li Marten Hermans
li Martin Gasser
li Martin Hofbauer
li Martin Raine
li Martin Suelmann
li Martin Wilhelmi
li Marvin Honderboom
li Mateusz Grabowski
li Mathias Uhl
li Matt Kane
li Matthew Cameron
li Mauricio Allende
li Max Evans
li Mecky
li Mehmet Aydoğdu
li Michael Bartholomew
li Michael Bell
li Michael Bombe
li Michael Collins
li Michael Copeland
li Michael Ho
li Michael Kovacs
li Michael Lynch
li Michael Pennington
li Michael Sage
li Michael Stella
li Michael Thalmann
li Michael Wu
li MichaelZ
li Michel Bissonnette
li Mikael Wikström
li Mike Mason
li Mikhael Mariano
li Milan Múčka
li Miles Davis
li Minh Tang
li Moez Tharani
li Morgan Helton
li Myron Weber
li Murad Khasawneh
li N Patel
li Nathaniel Griswold
li Nelson Lee
li nezu
li Nicholas Jeppson
li Nicholas Kopas
li Nicholas Walczak
li Nick Leffler
li Nick Roethemeier
li Nico Baumgartner
li Nicolai Kragh-Hansen
li Nigel Smith
li Nihal Fernando
li Nils Orbat
li Nis Wechselberg
li Nithin Philips
li Nod Swal
li Nolan Haynes
li nubbn
li nybble
li Oh Be
li Oliver Schwarz
li Oliver Zimmer
li Omar El-Domeiri
li Omar Siam
li Oscar
li Patrick
li Patrick Fortin-Ducharme
li Patrick McDowell
li Patrick Wagstrom
li Paul Bishop
li Paul De La Rosa
li Paul Pietkiewicz
li Paul Tan
li Pawel Trofimiuk
li Peder Madsen
li Peter
li Peter Drayton
li Peter Farrelly
li Peter Okelmann
li Petra Lohmann
li Petri Heiskanen
li Phil Wu
li Philip Edwards
li Philip Merricks
li Pierre Brassart
li Pierre Peine
li posicat
li pozitron03
li Przemysław Szypowicz
li P_Dmitrij
li Qteal
li Quattro Uno
li Quentin Peten
li Ralph Borchers
li Ranc1d
li Randall D Bilbrey
li RandomJerk
li Raphael Schitz
li Ref Chowdhury
li René Rathenau
li ReysDad
li Ricardo Marques
li Richard
li Richard Bernarts
li Richard Fancher
li Richard Freemantle
li Richard Michael
li Rico Cantrell
li Rob
li Rob Holden
li Rob Tongue
li Robert Klauco
li Robert Weemhoff
li Robin Gfatter
li Rodion DENISYUK
li Rohit Priyadarshi
li Rolfs 3D UG
li Ronald LeBaron
li Ronald Wells
li Ronny Haldorsen
li rotx
li Rufo Sanchez
li Russell Scott
li Ryan
li Ryan Peacock
li Samed Ozoglu
li Sameul Davies
li Samuel Cote
li Samuel Vetsch
li Samuel Walker
li Sarah Foster
li Sarten X
li Satish Alwani
li Scott
li Scott Gagon
li Scott Spicola
li Scott Tusing
li Scott Worthington
li Scuba
li Sean
li Sean Akers
li SEAT
li Sebastian
li Seonwoo Lee
li Sergey Lukjanov
li Seth Jennings
li Shane Selling
li Shawn Butts
li Sheran Gunasekera
li Shichun Chen
li Shin Guey Wong
li Simon Evans
li Simon Sundgaard
li Simplistic Realities
li Sirmo
li Snowy Maslov
li Solve Technology
li srepac
li Stefan Bautz
li Stefan Müller
li Stefan Stemmer
li Stefan Vaillant
li Stephan Schmidt
li Stephen
li Stephen Hocking
li Steve Jones
li Steve Kerr
li Steve Ovens
li Steve Stringham
li Steven Richter
li Stratagem Solutions Ltd
li Sven Breckler
li sudo34
li SuperHiTech
li Tango_Echo_Alpha
li Tarlak Desaydrone
li TechBear
li techlobo
li Ted
li Tejun Heo
li TheSnowedOne
li TheTechGiant
li Thomas Charisoulis
li Thomas Gitlin
li Thomas Hagenmaier
li Thomas Hedberg Jensen
li Thomas Price
li Thomas Søfteland
li Tim Lenz
li Tim Wilkinson
li Timo Brinkmann
li Timothee Besset
li TitomusPrime
li Tobias Schafferhans
li Tom Lawson
li Tom York
li Tomas Kuchta
li Tomáš hrubý
li Torsten Droste
li Torsten Knoll
li Tracy Fitch
li Tristan Schoening
li Truman Kilen
li turbochris
li tutanak
li Tyler
li Udo Schroeter
li Uli Fahrer
li Vasily Lazarev
li Vidru Eduard
li Vicente Salvador Cubedo
li Viktor Aschenbrenner
li Viktor Ekmark
li Vincent Chov
li Vlad Sterescu
li Volker Gropp
li Walli
li Walter_Ego
li William Wenzel
li Will Froning
li William Hooper
li William Perrin
li William Stearns
li Woojin Son
li xMdb
li Yanko Kaneti
li Yaroslav Kulikovskikh
li Yethal
li Yevgeniy Kuksenko
li Yew Kay Yan
li Yigal Dar
li Yogi
li YURI LEE
li Yurii Ostapchuk
li Zeljko
li zgen
li Zoltan Magyari
li Zsombor Vari
br
p(class="text credits")
a(target="_blank" href="https://pikvm.org" i18n="index_text_10") PiKVM Project
| &nbsp; | &nbsp;
a(target="_blank" href="https://docs.pikvm.org" i18n="index_text_11") Documentation
| &nbsp; | &nbsp;
a(target="_blank" href="https://github.com/mofeng-git/One-KVM" i18n="index_text_12") One-KVM Project
| &nbsp; | &nbsp;
a(target="_blank" href="https://one-kvm.mofeng.run" i18n="index_text_13") One-KVM Documentation

View File

@@ -0,0 +1,232 @@
mixin key(spacer, code, classes="", width=0)
div(data-code=code, class=`key ${classes}`, style=(width ? `width:${width}px` : ""))
div(class="label")
block
if spacer == 1
div(class="spacer")
else if spacer == 2
div(class="spacer-fixed")
mixin modifier(spacer, code, classes="", width=0)
div(data-code=code class=`modifier ${classes}` style=(width ? `width:${width}px` : ""))
div(class="label")
| #[b &bull;]#[br]
block
if spacer == 1
div(class="spacer")
else if spacer == 2
div(class="spacer-fixed")
mixin empty(spacer, classes="", width=0)
div(class=`empty ${classes}` style=(width ? `width:${width}px` : ""))
div(class="label") &nbsp;
if spacer == 1
div(class="spacer")
else if spacer == 2
div(class="spacer-fixed")
mixin lamp(cls)
img(class=`inline-lamp ${cls} led-gray` src=`${svg_dir}/led-square.svg`)
div(id="keyboard-window" class="window")
div(id="keyboard-window-header" class="window-header")
div(class="window-grab" i18n="kvm_text15") Virtual Keyboard
button(class="window-button-close") #[b &times;]
div(id="keyboard-desktop" class="keypad" align="center")
div(class="keypad-block")
div(class="keypad-row")
+key(2, "Escape", "small") Esc
+empty(1, "", 24)
each key in ["F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12"]
+key((key != "F12" ? 1 : 0), key, "small") #{key}
if key == "F4" || key == "F8"
+empty(1, "", 10)
hr
div(class="keypad-row")
+key(1, "Backquote") ~#[br]`
each key, index in ["!", "@", "#", "$", "%", "^", "&", "*", "("]
+key(1, `Digit${index + 1}`) #{key}#[br]#{index + 1}
+key(1, "Digit0") )#[br]0
+key(1, "Minus") _#[br]-
+key(1, "Equal") +#[br]=
+key(0, "Backspace", "wide-1 right") &#8612;
div(class="keypad-row")
+key(1, "Tab", "wide-1 left") &#8676;#[br]&#8677;
each key in ["Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P"]
+key(1, `Key${key}`, "single") #{key}
+key(1, "BracketLeft") {#[br][
+key(1, "BracketRight") }#[br]]
+key(0, "Backslash") |#[br]&bsol;
div(class="keypad-row")
+key(1, "CapsLock", "wide-2 left small")
+lamp("hid-keyboard-caps-led")
| #[br] Caps Lock
each key in ["A", "S", "D", "F", "G", "H", "J", "K", "L"]
+key(1, `Key${key}`, "single") #{key}
+key(1, "Semicolon") :#[br];
+key(1, "Quote") "#[br]'
+key(0, "Enter", "wide-2 right small") Enter#[br]&crarr;
div(class="keypad-row")
+modifier(1, "ShiftLeft", "wide-3 left small") Shift
each key in ["Z", "X", "C", "V", "B", "N", "M"]
+key(1, `Key${key}`, "single") #{key}
+key(1, "Comma") &lt;#[br],
+key(1, "Period") &gt;#[br].
+key(1, "Slash") ?#[br]/
+modifier(0, "ShiftRight", "wide-3 right small") Shift
div(class="keypad-row")
+modifier(2, "ControlLeft", "wide-1 left small") Ctrl
+modifier(2, "MetaLeft", "wide-1 left small") Win
+modifier(2, "AltLeft", "wide-1 left small") Alt
+key(2, "Space", "wide-4")
+modifier(2, "AltRight", "wide-1 right small") Alt
+modifier(2, "MetaRight", "wide-1 right small") Win
+key(2, "ContextMenu", "small") #[br]Menu
+modifier(0, "ControlRight", "wide-1 right small") Ctrl
div(class="keypad-block")
div(class="keypad-row")
+modifier(2, "PrintScreen", "small") Pt/Sq
+key(2, "ScrollLock", "small")
+lamp("hid-keyboard-scroll-led")
| #[br] ScrLk
+key(0, "Pause", "small") P/Brk
hr
div(class="keypad-row")
+key(2, "Insert", "small") Ins
+key(2, "Home", "small") Home
+key(0, "PageUp", "small") PgUp
div(class="keypad-row")
+key(2, "Delete", "small") Del
+key(2, "End", "small") End
+key(0, "PageDown", "small") PgDn
div(class="keypad-row")
div(class="keypad-row")
+empty(1, "")
+key(2, "ArrowUp") &uarr;
+empty(0, "")
div(class="keypad-row")
+key(2, "ArrowLeft") &larr;
+key(2, "ArrowDown") &darr;
+key(0, "ArrowRight") &rarr;
div(class="keypad-block")
div(class="keypad-row")
+empty(2, "small")
+empty(2, "small")
+empty(2, "small")
+key(0, "Power", "small") PWR
hr
div(class="keypad-row")
+key(2, "NumLock", "small")
+lamp("hid-keyboard-num-led")
| #[br] NmLk
+key(2, "NumpadDivide") /
+key(2, "NumpadMultiply") *
+key(0, "NumpadSubtract") -
div(class="keypad-row")
+key(2, "Numpad7", "small") 7#[br]Home
+key(2, "Numpad8", "small") 8#[br]&uarr;
+key(2, "Numpad9", "small") 9#[br]PgUp
+empty(0, "")
div(class="keypad-row")
+key(2, "Numpad4", "small") 4#[br]&larr;
+key(2, "Numpad5", "small") 5#[br]#[br]
+key(2, "Numpad6", "small") 6#[br]&rarr;
+key(0, "NumpadAdd") +
div(class="keypad-row")
+key(2, "Numpad1", "small") 1#[br]End
+key(2, "Numpad2", "small") 2#[br]&darr;
+key(2, "Numpad3", "small") 3#[br]PgDn
+empty(0, "")
div(class="keypad-row")
+key(2, "Numpad0", "small") 0#[br]Ins
+empty(2, "")
+key(2, "NumpadDecimal", "small") .#[br]Del
+key(0, "NumpadEnter", "small") Ent
div(class="keypad-block")
div(class="keypad-row")
+key(0, "IntlBackslash", "small") &bsol;#[br]|
hr
div(class="keypad-row")
+key(0, "IntlYen", "small") ¥#[br]_
div(class="keypad-row")
+key(0, "IntlRo", "small") &bsol;#[br]ろ
div(class="keypad-row")
+modifier(0, "KanaMode", "small") Kana
div(class="keypad-row")
+modifier(0, "NonConvert", "small") N/Cnv
div(class="keypad-row")
+modifier(0, "Convert", "small") Cnv
div(id="keyboard-mobile" class="keypad" align="center")
div(class="keypad-block")
div(class="keypad-row")
+key(1, "Escape", "small") Esc
+key(0, "F1", "wide-0 small rounded-left") F1
+key(0, "F2", "wide-0 small rounded-none") F2
+key(0, "F3", "wide-0 small rounded-none") F3
+key(2, "F4", "wide-0 small rounded-right") F4
+key(0, "F5", "wide-0 small rounded-left") F5
+key(0, "F6", "wide-0 small rounded-none") F6
+key(0, "F7", "wide-0 small rounded-none") F7
+key(2, "F8", "wide-0 small rounded-right") F8
+key(0, "F9", "wide-0 small rounded-left") F9
+key(0, "F10", "wide-0 small rounded-none") F10
+key(0, "F11", "wide-0 small rounded-none") F11
+key(2, "F12", "wide-0 small rounded-right") F12
+modifier(1, "PrintScreen", "small") Pt/Sq
+key(1, "ScrollLock", "small")
+lamp("hid-keyboard-scroll-led")
| #[br] ScrLk
+key(1, "Pause", "small") P/Brk
+key(1, "Insert", "small") Ins
+key(1, "Home", "small") Home
+key(1, "End", "small") End
+key(0, "Delete", "small") Del
div(class="keypad-row")
+key(1, "Backquote") ~#[br]`
each key, index in ["!", "@", "#", "$", "%", "^", "&", "*", "("]
+key(1, `Digit${index + 1}`) #{key}#[br]#{index + 1}
+key(1, "Digit0") )#[br]0
+key(1, "Minus") _#[br]-
+key(1, "Equal") +#[br]=
+key(0, "Backspace", "wide-2 right", 101) &#8612;
div(class="keypad-row")
+key(1, "Tab", "wide-1 left") &#8676;<br>&#8677;
each key in ["Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P"]
+key(1, `Key${key}`, "single") #{key}
+key(1, "BracketLeft") {#[br][
+key(1, "BracketRight") }#[br]]
+key(0, "Backslash", "wide-1 left", 78) |#[br]&bsol;
div(class="keypad-row")
+key(1, "CapsLock", "wide-2 left small")
+lamp("hid-keyboard-caps-led")
| #[br] Caps Lock
each key in ["A", "S", "D", "F", "G", "H", "J", "K", "L"]
+key(1, `Key${key}`, "single") #{key}
+key(1, "Semicolon") :#[br];
+key(1, "Quote") `#[br]'
+key(0, "Enter", "wide-3 right small", 116) Enter#[br]&crarr;
div(class="keypad-row")
+modifier(1, "ShiftLeft", "wide-3 left small") Shift
each key in ["Z", "X", "C", "V", "B", "N", "M"]
+key(1, `Key${key}`, "single") #{key}
+key(1, "Comma") &lt;#[br],
+key(1, "Period") &gt;#[br].
+key(1, "Slash") ?#[br]/
+key(2, "PageUp", "small") PgUp
+key(2, "ArrowUp") &uarr;
+key(0, "PageDown", "small") PgDn
div(class="keypad-row")
+modifier(1, "ControlLeft", "wide-1 left small") Ctrl
+modifier(1, "MetaLeft", "wide-1 left small") Win
+modifier(1, "AltLeft", "wide-1 left small") Alt
+key(1, "Space", "", 190)
+modifier(1, "AltRight", "right small") Alt
+modifier(1, "MetaRight", "right small") Win
+key(1, "ContextMenu", "small") #[br]Menu
+modifier(1, "ShiftRight", "right small") Shift
+modifier(1, "ControlRight", "right small") Ctrl
+key(2, "ArrowLeft") &larr;
+key(2, "ArrowDown") &darr;
+key(0, "ArrowRight") &rarr;

View File

@@ -0,0 +1,49 @@
div(id="stream-ocr-window" class="window")
div(id="stream-ocr-selection" class="hidden")
div(id="stream-window" class="window window-resizable")
div(id="stream-window-header" class="window-header")
div(class="window-grab") MJPEG
button(class="window-button-close") #[b &times;]
button(class="window-button-maximize") &#9744;
button(class="window-button-original") &bull;
button(class="window-button-enter-full-tab") &#9650;
button(class="window-button-full-screen") &#10530;
div(id="stream-info")
button(class="window-button-exit-full-tab") &#9660;
div(id="stream-box" class="stream-box-offline")
img(id="stream-image" src=`${png_dir}/blank-stream.png`)
video(id="stream-video" class="hidden" disablePictureInPicture="true" autoplay playsinline muted)
div(id="stream-fullscreen-active")
div(id="stream-mouse-buttons" class="keypad" align="center")
div(class="keypad-block")
div(class="keypad-row")
div(data-code="left" class="key wide-3 left rounded-left")
div(class="label") Left
div(data-code="left" class="modifier left small rounded-right")
div(class="label") #[b &bull;]#[br]Hold
div(class="empty" style="width:15px")
div(data-code="middle" class="key wide-1 left rounded-left")
div(class="label") Mid
div(data-code="middle" class="modifier left small rounded-right")
div(class="label") #[b &bull;]#[br]Hold
div(class="empty" style="width:15px")
div(data-code="right" class="modifier right small rounded-left")
div(class="label") #[b &bull;]#[br]Hold
div(data-code="right" class="key wide-3 right rounded-right")
div(class="label") Right
div(class="empty" style="width:30px")
div(data-code="up" class="key small rounded-left")
div(class="label") Up
div(data-code="down" class="key small rounded-right")
div(class="label") Down
canvas(id="stream-mjpeg-canvas" class="hidden")

View File

@@ -0,0 +1,8 @@
div(id="webterm-window" class="window window-resizable" style="width: 640px; height: 480px")
div(class="window-header")
div(class="window-grab" i18n="kvm_text16") Terminal
button(class="window-button-close") #[b &times;]
button(class="window-button-maximize") &#9744;
// Терминал глючит из-за зажимаемой клавиши ESC для выхода
// button(class="window-button-full-screen") &#10530;
iframe(id="webterm-iframe" src="" style="width: 100%; height: 100%")

View File

@@ -0,0 +1,4 @@
include window-stream.pug
include window-keyboard.pug
include window-about.pug
include window-webterm.pug