mirror of https://github.com/jetkvm/kvm.git
Compare commits
31 Commits
da92c2138d
...
ec753b8493
Author | SHA1 | Date |
---|---|---|
|
ec753b8493 | |
|
29241ec3a5 | |
|
9ee905820c | |
|
2f2a21984a | |
|
b3fbf9391e | |
|
bd6a49b579 | |
|
47a54c6519 | |
|
ff84a9a848 | |
|
2f452582ff | |
|
c02ba8c343 | |
|
8bb0f54073 | |
|
65207b78e9 | |
|
c1a9c7d663 | |
|
6fbb7a66fc | |
|
286fb457f5 | |
|
50fe23af56 | |
|
66baa007aa | |
|
cdc7d749ae | |
|
6e58dfa956 | |
|
04f2ddec70 | |
|
6f37933e45 | |
|
d2ae8564b2 | |
|
226e01d5b7 | |
|
1f88ec183a | |
|
336745a666 | |
|
dcdcd9bbf2 | |
|
0a4a1af80e | |
|
fc3dbcd820 | |
|
17baf1647f | |
|
840743fcf7 | |
|
3ec1bdf388 |
|
@ -38,7 +38,7 @@ jobs:
|
|||
- name: Golang Test Report
|
||||
uses: becheran/go-testreport@v0.3.2
|
||||
with:
|
||||
output: "testreport.json"
|
||||
input: "testreport.json"
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
|
|
19
Makefile
19
Makefile
|
@ -15,6 +15,8 @@ GO_LDFLAGS := \
|
|||
-X $(PROMETHEUS_TAG).Revision=$(REVISION) \
|
||||
-X $(KVM_PKG_NAME).builtTimestamp=$(BUILDTS)
|
||||
|
||||
TEST_DIRS := $(shell find . -name "*_test.go" -type f -exec dirname {} \; | sort -u)
|
||||
|
||||
hash_resource:
|
||||
@shasum -a 256 resource/jetkvm_native | cut -d ' ' -f 1 > resource/jetkvm_native.sha256
|
||||
|
||||
|
@ -29,16 +31,17 @@ build_dev_test: build_test2json
|
|||
# collect all directories that contain tests
|
||||
@echo "Building tests for devices ..."
|
||||
@rm -rf bin/tests && mkdir -p bin/tests
|
||||
GOOS=linux GOARCH=arm GOARM=7 \
|
||||
go test -v \
|
||||
-ldflags="$(GO_LDFLAGS) -X $(KVM_PKG_NAME).builtAppVersion=$(VERSION_DEV)" \
|
||||
-c -o bin/tests ./...; \
|
||||
|
||||
@cat resource/dev_test.sh > bin/tests/run_all_tests
|
||||
@for test in bin/tests/*.test; do \
|
||||
chmod +x $$test; \
|
||||
base_name=$$(basename $$test); \
|
||||
echo "runTest ./$$base_name" >> bin/tests/run_all_tests; \
|
||||
@for test in $(TEST_DIRS); do \
|
||||
test_pkg_name=$$(echo $$test | sed 's/^.\///g'); \
|
||||
test_pkg_full_name=$(KVM_PKG_NAME)/$$(echo $$test | sed 's/^.\///g'); \
|
||||
test_filename=$$(echo $$test_pkg_name | sed 's/\//__/g')_test; \
|
||||
GOOS=linux GOARCH=arm GOARM=7 \
|
||||
go test -v \
|
||||
-ldflags="$(GO_LDFLAGS) -X $(KVM_PKG_NAME).builtAppVersion=$(VERSION_DEV)" \
|
||||
-c -o bin/tests/$$test_filename $$test; \
|
||||
echo "runTest ./$$test_filename $$test_pkg_full_name" >> bin/tests/run_all_tests; \
|
||||
done; \
|
||||
chmod +x bin/tests/run_all_tests; \
|
||||
cp bin/test2json bin/tests/; \
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
[](https://twitter.com/jetkvm)
|
||||
|
||||
[](https://goreportcard.com/report/github.com/jetkvm/kvm)
|
||||
|
||||
</div>
|
||||
|
||||
JetKVM is a high-performance, open-source KVM over IP (Keyboard, Video, Mouse) solution designed for efficient remote management of computers, servers, and workstations. Whether you're dealing with boot failures, installing a new operating system, adjusting BIOS settings, or simply taking control of a machine from afar, JetKVM provides the tools to get it done effectively.
|
||||
|
|
|
@ -87,6 +87,7 @@ type Config struct {
|
|||
LocalAuthMode string `json:"localAuthMode"` //TODO: fix it with migration
|
||||
WakeOnLanDevices []WakeOnLanDevice `json:"wake_on_lan_devices"`
|
||||
KeyboardMacros []KeyboardMacro `json:"keyboard_macros"`
|
||||
KeyboardLayout string `json:"keyboard_layout"`
|
||||
EdidString string `json:"hdmi_edid_string"`
|
||||
ActiveExtension string `json:"active_extension"`
|
||||
DisplayRotation string `json:"display_rotation"`
|
||||
|
@ -109,6 +110,7 @@ var defaultConfig = &Config{
|
|||
ActiveExtension: "",
|
||||
KeyboardMacros: []KeyboardMacro{},
|
||||
DisplayRotation: "270",
|
||||
KeyboardLayout: "en-US",
|
||||
DisplayMaxBrightness: 64,
|
||||
DisplayDimAfterSec: 120, // 2 minutes
|
||||
DisplayOffAfterSec: 1800, // 30 minutes
|
||||
|
|
|
@ -41,7 +41,7 @@ SKIP_UI_BUILD=false
|
|||
RESET_USB_HID_DEVICE=false
|
||||
LOG_TRACE_SCOPES="${LOG_TRACE_SCOPES:-jetkvm,cloud,websocket,native,jsonrpc}"
|
||||
RUN_GO_TESTS=false
|
||||
|
||||
RUN_GO_TESTS_JSON=false
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
|
@ -65,6 +65,10 @@ while [[ $# -gt 0 ]]; do
|
|||
RUN_GO_TESTS=true
|
||||
shift
|
||||
;;
|
||||
--run-go-tests-json)
|
||||
RUN_GO_TESTS_JSON=true
|
||||
shift
|
||||
;;
|
||||
--help)
|
||||
show_help
|
||||
exit 0
|
||||
|
@ -77,6 +81,10 @@ while [[ $# -gt 0 ]]; do
|
|||
esac
|
||||
done
|
||||
|
||||
if [ "$RUN_GO_TESTS_JSON" = true ]; then
|
||||
RUN_GO_TESTS=true
|
||||
fi
|
||||
|
||||
# Verify required parameters
|
||||
if [ -z "$REMOTE_HOST" ]; then
|
||||
msg_err "Error: Remote IP is a required parameter"
|
||||
|
@ -101,11 +109,15 @@ if [ "$RUN_GO_TESTS" = true ]; then
|
|||
ssh "${REMOTE_USER}@${REMOTE_HOST}" "cat > ${REMOTE_PATH}/device-tests.tar.gz" < device-tests.tar.gz
|
||||
|
||||
msg_info "▶ Running go tests"
|
||||
TEST_ARGS=""
|
||||
if [ "$RUN_GO_TESTS_JSON" = true ]; then
|
||||
TEST_ARGS="-json"
|
||||
fi
|
||||
ssh "${REMOTE_USER}@${REMOTE_HOST}" ash << EOF
|
||||
set -e
|
||||
cd ${REMOTE_PATH}
|
||||
tar zxvf device-tests.tar.gz
|
||||
./run_all_tests -test.v
|
||||
./run_all_tests $TEST_ARGS
|
||||
EOF
|
||||
fi
|
||||
|
||||
|
@ -113,7 +125,7 @@ fi
|
|||
ssh "${REMOTE_USER}@${REMOTE_HOST}" "killall jetkvm_app_debug || true"
|
||||
|
||||
# Copy the binary to the remote host
|
||||
ssh "${REMOTE_USER}@${REMOTE_HOST}" "cat > ${REMOTE_PATH}/jetkvm_app_debug" < jetkvm_app_debug
|
||||
ssh "${REMOTE_USER}@${REMOTE_HOST}" "cat > ${REMOTE_PATH}/jetkvm_app_debug" < bin/jetkvm_app
|
||||
|
||||
if [ "$RESET_USB_HID_DEVICE" = true ]; then
|
||||
# Remove the old USB gadget configuration
|
||||
|
|
|
@ -74,7 +74,7 @@ func (u *UsbGadget) keyboardWriteHidFile(data []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (u *UsbGadget) KeyboardReport(modifier uint8, keys []uint8) error {
|
||||
func (u *UsbGadget) KeyboardReport(modifier uint8, keys []uint8, hold bool) error {
|
||||
u.keyboardLock.Lock()
|
||||
defer u.keyboardLock.Unlock()
|
||||
|
||||
|
@ -90,6 +90,13 @@ func (u *UsbGadget) KeyboardReport(modifier uint8, keys []uint8) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if !hold {
|
||||
err := u.keyboardWriteHidFile(make([]uint8, 8))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
u.resetUserInputTime()
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -107,24 +107,16 @@ func (u *UsbGadget) AbsMouseWheelReport(wheelY int8) error {
|
|||
u.absMouseLock.Lock()
|
||||
defer u.absMouseLock.Unlock()
|
||||
|
||||
// Accumulate the wheelY value
|
||||
u.absMouseAccumulatedWheelY += float64(wheelY) / 8.0
|
||||
|
||||
// Only send a report if the accumulated value is significant
|
||||
if abs(u.absMouseAccumulatedWheelY) < 1.0 {
|
||||
// Only send a report if the value is non-zero
|
||||
if wheelY == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
scaledWheelY := int8(u.absMouseAccumulatedWheelY)
|
||||
|
||||
err := u.absMouseWriteHidFile([]byte{
|
||||
2, // Report ID 2
|
||||
byte(scaledWheelY), // Scaled Wheel Y (signed)
|
||||
2, // Report ID 2
|
||||
byte(wheelY), // Wheel Y (signed)
|
||||
})
|
||||
|
||||
// Reset the accumulator, keeping any remainder
|
||||
u.absMouseAccumulatedWheelY -= float64(scaledWheelY)
|
||||
|
||||
u.resetUserInputTime()
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -7,14 +7,6 @@ import (
|
|||
"path/filepath"
|
||||
)
|
||||
|
||||
// Helper function to get absolute value of float64
|
||||
func abs(x float64) float64 {
|
||||
if x < 0 {
|
||||
return -x
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
func joinPath(basePath string, paths []string) string {
|
||||
pathArr := append([]string{basePath}, paths...)
|
||||
return filepath.Join(pathArr...)
|
||||
|
|
16
jsonrpc.go
16
jsonrpc.go
|
@ -888,6 +888,18 @@ func rpcSetScrollSensitivity(sensitivity string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func rpcGetKeyboardLayout() (string, error) {
|
||||
return config.KeyboardLayout, nil
|
||||
}
|
||||
|
||||
func rpcSetKeyboardLayout(layout string) error {
|
||||
config.KeyboardLayout = layout
|
||||
if err := SaveConfig(); err != nil {
|
||||
return fmt.Errorf("failed to save config: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getKeyboardMacros() (interface{}, error) {
|
||||
macros := make([]KeyboardMacro, len(config.KeyboardMacros))
|
||||
copy(macros, config.KeyboardMacros)
|
||||
|
@ -991,7 +1003,7 @@ var rpcHandlers = map[string]RPCHandler{
|
|||
"getNetworkSettings": {Func: rpcGetNetworkSettings},
|
||||
"setNetworkSettings": {Func: rpcSetNetworkSettings, Params: []string{"settings"}},
|
||||
"renewDHCPLease": {Func: rpcRenewDHCPLease},
|
||||
"keyboardReport": {Func: rpcKeyboardReport, Params: []string{"modifier", "keys"}},
|
||||
"keyboardReport": {Func: rpcKeyboardReport, Params: []string{"modifier", "keys", "hold"}},
|
||||
"absMouseReport": {Func: rpcAbsMouseReport, Params: []string{"x", "y", "buttons"}},
|
||||
"relMouseReport": {Func: rpcRelMouseReport, Params: []string{"dx", "dy", "buttons"}},
|
||||
"wheelReport": {Func: rpcWheelReport, Params: []string{"wheelY"}},
|
||||
|
@ -1055,6 +1067,8 @@ var rpcHandlers = map[string]RPCHandler{
|
|||
"setCloudUrl": {Func: rpcSetCloudUrl, Params: []string{"apiUrl", "appUrl"}},
|
||||
"getScrollSensitivity": {Func: rpcGetScrollSensitivity},
|
||||
"setScrollSensitivity": {Func: rpcSetScrollSensitivity, Params: []string{"sensitivity"}},
|
||||
"getKeyboardLayout": {Func: rpcGetKeyboardLayout},
|
||||
"setKeyboardLayout": {Func: rpcSetKeyboardLayout, Params: []string{"layout"}},
|
||||
"getKeyboardMacros": {Func: getKeyboardMacros},
|
||||
"setKeyboardMacros": {Func: setKeyboardMacros, Params: []string{"params"}},
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#!/bin/sh
|
||||
JSON_OUTPUT=false
|
||||
GET_COMMANDS=false
|
||||
if [ "$1" = "-json" ]; then
|
||||
JSON_OUTPUT=true
|
||||
shift
|
||||
|
@ -8,8 +9,12 @@ ADDITIONAL_ARGS=$@
|
|||
EXIT_CODE=0
|
||||
|
||||
runTest() {
|
||||
PKG_ARGS=""
|
||||
if [ "$2" != "" ]; then
|
||||
PKG_ARGS="-p $2"
|
||||
fi
|
||||
if [ "$JSON_OUTPUT" = true ]; then
|
||||
./test2json $1 -test.v $ADDITIONAL_ARGS | tee $1.result.json
|
||||
./test2json $PKG_ARGS -t $1 -test.v $ADDITIONAL_ARGS | tee $1.result.json
|
||||
if [ $? -ne 0 ]; then
|
||||
EXIT_CODE=1
|
||||
fi
|
||||
|
@ -21,7 +26,6 @@ runTest() {
|
|||
fi
|
||||
}
|
||||
|
||||
|
||||
function exit_with_code() {
|
||||
if [ $EXIT_CODE -ne 0 ]; then
|
||||
printf "\e[0;31m❌ Test failed\e[0m\n"
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
"dayjs": "^1.11.13",
|
||||
"eslint-import-resolver-alias": "^1.1.2",
|
||||
"focus-trap-react": "^11.0.3",
|
||||
"framer-motion": "^12.11.0",
|
||||
"framer-motion": "^12.11.4",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"mini-svg-data-uri": "^1.4.4",
|
||||
"react": "^19.1.0",
|
||||
|
@ -45,9 +45,9 @@
|
|||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@eslint/js": "^9.26.0",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@tailwindcss/postcss": "^4.1.6",
|
||||
"@tailwindcss/postcss": "^4.1.7",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"@tailwindcss/vite": "^4.1.6",
|
||||
"@tailwindcss/vite": "^4.1.7",
|
||||
"@types/react": "^19.1.4",
|
||||
"@types/react-dom": "^19.1.5",
|
||||
"@types/semver": "^7.7.0",
|
||||
|
@ -66,7 +66,7 @@
|
|||
"postcss": "^8.5.3",
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-tailwindcss": "^0.6.11",
|
||||
"tailwindcss": "^4.1.6",
|
||||
"tailwindcss": "^4.1.7",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.5",
|
||||
"vite-tsconfig-paths": "^5.1.4"
|
||||
|
@ -879,14 +879,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@modelcontextprotocol/sdk": {
|
||||
"version": "1.11.2",
|
||||
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.11.2.tgz",
|
||||
"integrity": "sha512-H9vwztj5OAqHg9GockCQC06k1natgcxWQSRpQcPJf6i5+MWBzfKkRtxGbjQf0X2ihii0ffLZCRGbYV2f2bjNCQ==",
|
||||
"version": "1.11.3",
|
||||
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.11.3.tgz",
|
||||
"integrity": "sha512-rmOWVRUbUJD7iSvJugjUbFZshTAuJ48MXoZ80Osx1GM0K/H1w7rSEvmw8m6vdWxNASgtaHIhAgre4H/E9GJiYQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"content-type": "^1.0.5",
|
||||
"cors": "^2.8.5",
|
||||
"cross-spawn": "^7.0.3",
|
||||
"cross-spawn": "^7.0.5",
|
||||
"eventsource": "^3.0.2",
|
||||
"express": "^5.0.1",
|
||||
"express-rate-limit": "^7.5.0",
|
||||
|
@ -1558,25 +1558,25 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/node": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.6.tgz",
|
||||
"integrity": "sha512-ed6zQbgmKsjsVvodAS1q1Ld2BolEuxJOSyyNc+vhkjdmfNUDCmQnlXBfQkHrlzNmslxHsQU/bFmzcEbv4xXsLg==",
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.7.tgz",
|
||||
"integrity": "sha512-9rsOpdY9idRI2NH6CL4wORFY0+Q6fnx9XP9Ju+iq/0wJwGD5IByIgFmwVbyy4ymuyprj8Qh4ErxMKTUL4uNh3g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ampproject/remapping": "^2.3.0",
|
||||
"enhanced-resolve": "^5.18.1",
|
||||
"jiti": "^2.4.2",
|
||||
"lightningcss": "1.29.2",
|
||||
"lightningcss": "1.30.1",
|
||||
"magic-string": "^0.30.17",
|
||||
"source-map-js": "^1.2.1",
|
||||
"tailwindcss": "4.1.6"
|
||||
"tailwindcss": "4.1.7"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.6.tgz",
|
||||
"integrity": "sha512-0bpEBQiGx+227fW4G0fLQ8vuvyy5rsB1YIYNapTq3aRsJ9taF3f5cCaovDjN5pUGKKzcpMrZst/mhNaKAPOHOA==",
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.7.tgz",
|
||||
"integrity": "sha512-5SF95Ctm9DFiUyjUPnDGkoKItPX/k+xifcQhcqX5RA85m50jw1pT/KzjdvlqxRja45Y52nR4MR9fD1JYd7f8NQ==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
|
@ -1588,24 +1588,24 @@
|
|||
"node": ">= 10"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@tailwindcss/oxide-android-arm64": "4.1.6",
|
||||
"@tailwindcss/oxide-darwin-arm64": "4.1.6",
|
||||
"@tailwindcss/oxide-darwin-x64": "4.1.6",
|
||||
"@tailwindcss/oxide-freebsd-x64": "4.1.6",
|
||||
"@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.6",
|
||||
"@tailwindcss/oxide-linux-arm64-gnu": "4.1.6",
|
||||
"@tailwindcss/oxide-linux-arm64-musl": "4.1.6",
|
||||
"@tailwindcss/oxide-linux-x64-gnu": "4.1.6",
|
||||
"@tailwindcss/oxide-linux-x64-musl": "4.1.6",
|
||||
"@tailwindcss/oxide-wasm32-wasi": "4.1.6",
|
||||
"@tailwindcss/oxide-win32-arm64-msvc": "4.1.6",
|
||||
"@tailwindcss/oxide-win32-x64-msvc": "4.1.6"
|
||||
"@tailwindcss/oxide-android-arm64": "4.1.7",
|
||||
"@tailwindcss/oxide-darwin-arm64": "4.1.7",
|
||||
"@tailwindcss/oxide-darwin-x64": "4.1.7",
|
||||
"@tailwindcss/oxide-freebsd-x64": "4.1.7",
|
||||
"@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.7",
|
||||
"@tailwindcss/oxide-linux-arm64-gnu": "4.1.7",
|
||||
"@tailwindcss/oxide-linux-arm64-musl": "4.1.7",
|
||||
"@tailwindcss/oxide-linux-x64-gnu": "4.1.7",
|
||||
"@tailwindcss/oxide-linux-x64-musl": "4.1.7",
|
||||
"@tailwindcss/oxide-wasm32-wasi": "4.1.7",
|
||||
"@tailwindcss/oxide-win32-arm64-msvc": "4.1.7",
|
||||
"@tailwindcss/oxide-win32-x64-msvc": "4.1.7"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-android-arm64": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.6.tgz",
|
||||
"integrity": "sha512-VHwwPiwXtdIvOvqT/0/FLH/pizTVu78FOnI9jQo64kSAikFSZT7K4pjyzoDpSMaveJTGyAKvDjuhxJxKfmvjiQ==",
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.7.tgz",
|
||||
"integrity": "sha512-IWA410JZ8fF7kACus6BrUwY2Z1t1hm0+ZWNEzykKmMNM09wQooOcN/VXr0p/WJdtHZ90PvJf2AIBS/Ceqx1emg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -1620,9 +1620,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-darwin-arm64": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.6.tgz",
|
||||
"integrity": "sha512-weINOCcqv1HVBIGptNrk7c6lWgSFFiQMcCpKM4tnVi5x8OY2v1FrV76jwLukfT6pL1hyajc06tyVmZFYXoxvhQ==",
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.7.tgz",
|
||||
"integrity": "sha512-81jUw9To7fimGGkuJ2W5h3/oGonTOZKZ8C2ghm/TTxbwvfSiFSDPd6/A/KE2N7Jp4mv3Ps9OFqg2fEKgZFfsvg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -1637,9 +1637,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-darwin-x64": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.6.tgz",
|
||||
"integrity": "sha512-3FzekhHG0ww1zQjQ1lPoq0wPrAIVXAbUkWdWM8u5BnYFZgb9ja5ejBqyTgjpo5mfy0hFOoMnMuVDI+7CXhXZaQ==",
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.7.tgz",
|
||||
"integrity": "sha512-q77rWjEyGHV4PdDBtrzO0tgBBPlQWKY7wZK0cUok/HaGgbNKecegNxCGikuPJn5wFAlIywC3v+WMBt0PEBtwGw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -1654,9 +1654,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-freebsd-x64": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.6.tgz",
|
||||
"integrity": "sha512-4m5F5lpkBZhVQJq53oe5XgJ+aFYWdrgkMwViHjRsES3KEu2m1udR21B1I77RUqie0ZYNscFzY1v9aDssMBZ/1w==",
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.7.tgz",
|
||||
"integrity": "sha512-RfmdbbK6G6ptgF4qqbzoxmH+PKfP4KSVs7SRlTwcbRgBwezJkAO3Qta/7gDy10Q2DcUVkKxFLXUQO6J3CRvBGw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -1671,9 +1671,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.6.tgz",
|
||||
"integrity": "sha512-qU0rHnA9P/ZoaDKouU1oGPxPWzDKtIfX7eOGi5jOWJKdxieUJdVV+CxWZOpDWlYTd4N3sFQvcnVLJWJ1cLP5TA==",
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.7.tgz",
|
||||
"integrity": "sha512-OZqsGvpwOa13lVd1z6JVwQXadEobmesxQ4AxhrwRiPuE04quvZHWn/LnihMg7/XkN+dTioXp/VMu/p6A5eZP3g==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
|
@ -1688,9 +1688,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.6.tgz",
|
||||
"integrity": "sha512-jXy3TSTrbfgyd3UxPQeXC3wm8DAgmigzar99Km9Sf6L2OFfn/k+u3VqmpgHQw5QNfCpPe43em6Q7V76Wx7ogIQ==",
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.7.tgz",
|
||||
"integrity": "sha512-voMvBTnJSfKecJxGkoeAyW/2XRToLZ227LxswLAwKY7YslG/Xkw9/tJNH+3IVh5bdYzYE7DfiaPbRkSHFxY1xA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -1705,9 +1705,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-linux-arm64-musl": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.6.tgz",
|
||||
"integrity": "sha512-8kjivE5xW0qAQ9HX9reVFmZj3t+VmljDLVRJpVBEoTR+3bKMnvC7iLcoSGNIUJGOZy1mLVq7x/gerVg0T+IsYw==",
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.7.tgz",
|
||||
"integrity": "sha512-PjGuNNmJeKHnP58M7XyjJyla8LPo+RmwHQpBI+W/OxqrwojyuCQ+GUtygu7jUqTEexejZHr/z3nBc/gTiXBj4A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -1722,9 +1722,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-linux-x64-gnu": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.6.tgz",
|
||||
"integrity": "sha512-A4spQhwnWVpjWDLXnOW9PSinO2PTKJQNRmL/aIl2U/O+RARls8doDfs6R41+DAXK0ccacvRyDpR46aVQJJCoCg==",
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.7.tgz",
|
||||
"integrity": "sha512-HMs+Va+ZR3gC3mLZE00gXxtBo3JoSQxtu9lobbZd+DmfkIxR54NO7Z+UQNPsa0P/ITn1TevtFxXTpsRU7qEvWg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -1739,9 +1739,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-linux-x64-musl": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.6.tgz",
|
||||
"integrity": "sha512-YRee+6ZqdzgiQAHVSLfl3RYmqeeaWVCk796MhXhLQu2kJu2COHBkqlqsqKYx3p8Hmk5pGCQd2jTAoMWWFeyG2A==",
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.7.tgz",
|
||||
"integrity": "sha512-MHZ6jyNlutdHH8rd+YTdr3QbXrHXqwIhHw9e7yXEBcQdluGwhpQY2Eku8UZK6ReLaWtQ4gijIv5QoM5eE+qlsA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -1756,9 +1756,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.6.tgz",
|
||||
"integrity": "sha512-qAp4ooTYrBQ5pk5jgg54/U1rCJ/9FLYOkkQ/nTE+bVMseMfB6O7J8zb19YTpWuu4UdfRf5zzOrNKfl6T64MNrQ==",
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.7.tgz",
|
||||
"integrity": "sha512-ANaSKt74ZRzE2TvJmUcbFQ8zS201cIPxUDm5qez5rLEwWkie2SkGtA4P+GPTj+u8N6JbPrC8MtY8RmJA35Oo+A==",
|
||||
"bundleDependencies": [
|
||||
"@napi-rs/wasm-runtime",
|
||||
"@emnapi/core",
|
||||
|
@ -1786,9 +1786,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.6.tgz",
|
||||
"integrity": "sha512-nqpDWk0Xr8ELO/nfRUDjk1pc9wDJ3ObeDdNMHLaymc4PJBWj11gdPCWZFKSK2AVKjJQC7J2EfmSmf47GN7OuLg==",
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.7.tgz",
|
||||
"integrity": "sha512-HUiSiXQ9gLJBAPCMVRk2RT1ZrBjto7WvqsPBwUrNK2BcdSxMnk19h4pjZjI7zgPhDxlAbJSumTC4ljeA9y0tEw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -1803,9 +1803,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-win32-x64-msvc": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.6.tgz",
|
||||
"integrity": "sha512-5k9xF33xkfKpo9wCvYcegQ21VwIBU1/qEbYlVukfEIyQbEA47uK8AAwS7NVjNE3vHzcmxMYwd0l6L4pPjjm1rQ==",
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.7.tgz",
|
||||
"integrity": "sha512-rYHGmvoHiLJ8hWucSfSOEmdCBIGZIq7SpkPRSqLsH2Ab2YUNgKeAPT1Fi2cx3+hnYOrAb0jp9cRyode3bBW4mQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -1820,17 +1820,17 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/postcss": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.6.tgz",
|
||||
"integrity": "sha512-ELq+gDMBuRXPJlpE3PEen+1MhnHAQQrh2zF0dI1NXOlEWfr2qWf2CQdr5jl9yANv8RErQaQ2l6nIFO9OSCVq/g==",
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.7.tgz",
|
||||
"integrity": "sha512-88g3qmNZn7jDgrrcp3ZXEQfp9CVox7xjP1HN2TFKI03CltPVd/c61ydn5qJJL8FYunn0OqBaW5HNUga0kmPVvw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@alloc/quick-lru": "^5.2.0",
|
||||
"@tailwindcss/node": "4.1.6",
|
||||
"@tailwindcss/oxide": "4.1.6",
|
||||
"@tailwindcss/node": "4.1.7",
|
||||
"@tailwindcss/oxide": "4.1.7",
|
||||
"postcss": "^8.4.41",
|
||||
"tailwindcss": "4.1.6"
|
||||
"tailwindcss": "4.1.7"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/typography": {
|
||||
|
@ -1850,15 +1850,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/vite": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.6.tgz",
|
||||
"integrity": "sha512-zjtqjDeY1w3g2beYQtrMAf51n5G7o+UwmyOjtsDMP7t6XyoRMOidcoKP32ps7AkNOHIXEOK0bhIC05dj8oJp4w==",
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.7.tgz",
|
||||
"integrity": "sha512-tYa2fO3zDe41I7WqijyVbRd8oWT0aEID1Eokz5hMT6wShLIHj3yvwj9XbfuloHP9glZ6H+aG2AN/+ZrxJ1Y5RQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tailwindcss/node": "4.1.6",
|
||||
"@tailwindcss/oxide": "4.1.6",
|
||||
"tailwindcss": "4.1.6"
|
||||
"@tailwindcss/node": "4.1.7",
|
||||
"@tailwindcss/oxide": "4.1.7",
|
||||
"tailwindcss": "4.1.7"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vite": "^5.2.0 || ^6"
|
||||
|
@ -3232,9 +3232,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.152",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.152.tgz",
|
||||
"integrity": "sha512-xBOfg/EBaIlVsHipHl2VdTPJRSvErNUaqW8ejTq5OlOlIYx1wOllCHsAvAIrr55jD1IYEfdR86miUEt8H5IeJg==",
|
||||
"version": "1.5.155",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.155.tgz",
|
||||
"integrity": "sha512-ps5KcGGmwL8VaeJlvlDlu4fORQpv3+GIcF5I3f9tUKUlJ/wsysh6HU8P5L1XWRYeXfA0oJd4PyM8ds8zTFf6Ng==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
|
@ -3906,9 +3906,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/eventsource-parser": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.1.tgz",
|
||||
"integrity": "sha512-VARTJ9CYeuQYb0pZEPbzi740OWFgpHe7AYJ2WFZVnUDUQp5Dk2yJUgF36YsZ81cOyxT0QxmXD2EQpapAouzWVA==",
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.2.tgz",
|
||||
"integrity": "sha512-6RxOBZ/cYgd8usLwsEl+EC09Au/9BcmCKYF2/xbml6DNczf7nv0MQb+7BA2F+li6//I+28VNlQR37XfQtcAJuA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
|
@ -4179,12 +4179,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/framer-motion": {
|
||||
"version": "12.11.1",
|
||||
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.11.1.tgz",
|
||||
"integrity": "sha512-k8SlrjoDesLTBklizQ2BSW7Pb99cHDoZe51Tff9ZjmWHQ/N5DLly949veBnwNfeH4d0E/h02RKuul/6D+5u9Bg==",
|
||||
"version": "12.11.4",
|
||||
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.11.4.tgz",
|
||||
"integrity": "sha512-kyE5oWZCUxhDb7LtpEyyadNThJJvoE8a6bfUTBqz++zw3XxDOosPAvw1lqNhYbjOgy57YuAlJ5qG/Cx5BigiEQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"motion-dom": "^12.11.0",
|
||||
"motion-dom": "^12.11.4",
|
||||
"motion-utils": "^12.9.4",
|
||||
"tslib": "^2.4.0"
|
||||
},
|
||||
|
@ -5084,9 +5084,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/lightningcss": {
|
||||
"version": "1.29.2",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.2.tgz",
|
||||
"integrity": "sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==",
|
||||
"version": "1.30.1",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz",
|
||||
"integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==",
|
||||
"devOptional": true,
|
||||
"license": "MPL-2.0",
|
||||
"dependencies": {
|
||||
|
@ -5100,22 +5100,22 @@
|
|||
"url": "https://opencollective.com/parcel"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"lightningcss-darwin-arm64": "1.29.2",
|
||||
"lightningcss-darwin-x64": "1.29.2",
|
||||
"lightningcss-freebsd-x64": "1.29.2",
|
||||
"lightningcss-linux-arm-gnueabihf": "1.29.2",
|
||||
"lightningcss-linux-arm64-gnu": "1.29.2",
|
||||
"lightningcss-linux-arm64-musl": "1.29.2",
|
||||
"lightningcss-linux-x64-gnu": "1.29.2",
|
||||
"lightningcss-linux-x64-musl": "1.29.2",
|
||||
"lightningcss-win32-arm64-msvc": "1.29.2",
|
||||
"lightningcss-win32-x64-msvc": "1.29.2"
|
||||
"lightningcss-darwin-arm64": "1.30.1",
|
||||
"lightningcss-darwin-x64": "1.30.1",
|
||||
"lightningcss-freebsd-x64": "1.30.1",
|
||||
"lightningcss-linux-arm-gnueabihf": "1.30.1",
|
||||
"lightningcss-linux-arm64-gnu": "1.30.1",
|
||||
"lightningcss-linux-arm64-musl": "1.30.1",
|
||||
"lightningcss-linux-x64-gnu": "1.30.1",
|
||||
"lightningcss-linux-x64-musl": "1.30.1",
|
||||
"lightningcss-win32-arm64-msvc": "1.30.1",
|
||||
"lightningcss-win32-x64-msvc": "1.30.1"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-darwin-arm64": {
|
||||
"version": "1.29.2",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.2.tgz",
|
||||
"integrity": "sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==",
|
||||
"version": "1.30.1",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz",
|
||||
"integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -5133,9 +5133,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/lightningcss-darwin-x64": {
|
||||
"version": "1.29.2",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.2.tgz",
|
||||
"integrity": "sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==",
|
||||
"version": "1.30.1",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz",
|
||||
"integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -5153,9 +5153,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/lightningcss-freebsd-x64": {
|
||||
"version": "1.29.2",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.2.tgz",
|
||||
"integrity": "sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==",
|
||||
"version": "1.30.1",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz",
|
||||
"integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -5173,9 +5173,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/lightningcss-linux-arm-gnueabihf": {
|
||||
"version": "1.29.2",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.2.tgz",
|
||||
"integrity": "sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==",
|
||||
"version": "1.30.1",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz",
|
||||
"integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
|
@ -5193,9 +5193,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/lightningcss-linux-arm64-gnu": {
|
||||
"version": "1.29.2",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.2.tgz",
|
||||
"integrity": "sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==",
|
||||
"version": "1.30.1",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz",
|
||||
"integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -5213,9 +5213,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/lightningcss-linux-arm64-musl": {
|
||||
"version": "1.29.2",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.2.tgz",
|
||||
"integrity": "sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==",
|
||||
"version": "1.30.1",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz",
|
||||
"integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -5233,9 +5233,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/lightningcss-linux-x64-gnu": {
|
||||
"version": "1.29.2",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.2.tgz",
|
||||
"integrity": "sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==",
|
||||
"version": "1.30.1",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz",
|
||||
"integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -5253,9 +5253,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/lightningcss-linux-x64-musl": {
|
||||
"version": "1.29.2",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.2.tgz",
|
||||
"integrity": "sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==",
|
||||
"version": "1.30.1",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz",
|
||||
"integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -5273,9 +5273,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/lightningcss-win32-arm64-msvc": {
|
||||
"version": "1.29.2",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.2.tgz",
|
||||
"integrity": "sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==",
|
||||
"version": "1.30.1",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz",
|
||||
"integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -5293,9 +5293,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/lightningcss-win32-x64-msvc": {
|
||||
"version": "1.29.2",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.2.tgz",
|
||||
"integrity": "sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==",
|
||||
"version": "1.30.1",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz",
|
||||
"integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -5532,9 +5532,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/motion-dom": {
|
||||
"version": "12.11.0",
|
||||
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.11.0.tgz",
|
||||
"integrity": "sha512-CItkGYJenn5ZsbzTX0D9mE0UWdjdd9r535FrxEXhzR8Kwa9I2dLr1uhEJgQPWbgaIJ6i0sNFnf2T9NvVDWQVBw==",
|
||||
"version": "12.11.4",
|
||||
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.11.4.tgz",
|
||||
"integrity": "sha512-1z/qYsrDjSx5QjOH8GfJ2RfFBvEzI2gdAEt2zNW+f7QkLlqjM3sQieESJr5+QtVmvD81qPANM7t97ROixKIt9Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"motion-utils": "^12.9.4"
|
||||
|
@ -6947,9 +6947,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/tailwindcss": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.6.tgz",
|
||||
"integrity": "sha512-j0cGLTreM6u4OWzBeLBpycK0WIh8w7kSwcUsQZoGLHZ7xDTdM69lN64AgoIEEwFi0tnhs4wSykUa5YWxAzgFYg==",
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.7.tgz",
|
||||
"integrity": "sha512-kr1o/ErIdNhTz8uzAYL7TpaUuzKIE6QPQ4qmSdxnoX/lo+5wmUHQA6h3L5yIqEImSRnAAURDirLu/BgiXGPAhg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tapable": {
|
||||
|
@ -7630,9 +7630,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/zustand": {
|
||||
"version": "4.5.6",
|
||||
"resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.6.tgz",
|
||||
"integrity": "sha512-ibr/n1hBzLLj5Y+yUcU7dYw8p6WnIVzdJbnX+1YpaScvZVF2ziugqHs+LAmHw4lWO9c/zRj+K1ncgWDQuthEdQ==",
|
||||
"version": "4.5.7",
|
||||
"resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz",
|
||||
"integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"use-sync-external-store": "^1.2.2"
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
"dayjs": "^1.11.13",
|
||||
"eslint-import-resolver-alias": "^1.1.2",
|
||||
"focus-trap-react": "^11.0.3",
|
||||
"framer-motion": "^12.11.0",
|
||||
"framer-motion": "^12.11.4",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"mini-svg-data-uri": "^1.4.4",
|
||||
"react": "^19.1.0",
|
||||
|
@ -56,9 +56,9 @@
|
|||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@eslint/js": "^9.26.0",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@tailwindcss/postcss": "^4.1.6",
|
||||
"@tailwindcss/postcss": "^4.1.7",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"@tailwindcss/vite": "^4.1.6",
|
||||
"@tailwindcss/vite": "^4.1.7",
|
||||
"@types/react": "^19.1.4",
|
||||
"@types/react-dom": "^19.1.5",
|
||||
"@types/semver": "^7.7.0",
|
||||
|
@ -77,7 +77,7 @@
|
|||
"postcss": "^8.5.3",
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-tailwindcss": "^0.6.11",
|
||||
"tailwindcss": "^4.1.6",
|
||||
"tailwindcss": "^4.1.7",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.5",
|
||||
"vite-tsconfig-paths": "^5.1.4"
|
||||
|
|
|
@ -89,8 +89,8 @@ export default function Actionbar({
|
|||
anchor="bottom start"
|
||||
transition
|
||||
className={cx(
|
||||
"z-10 flex w-[420px] origin-top flex-col !overflow-visible",
|
||||
"flex origin-top flex-col transition duration-300 ease-out data-[closed]:translate-y-8 data-[closed]:opacity-0",
|
||||
"z-10 flex w-[420px] origin-top flex-col overflow-visible!",
|
||||
"flex origin-top flex-col transition duration-300 ease-out data-closed:translate-y-8 data-closed:opacity-0",
|
||||
)}
|
||||
>
|
||||
{({ open }) => {
|
||||
|
@ -131,8 +131,8 @@ export default function Actionbar({
|
|||
anchor="bottom start"
|
||||
transition
|
||||
className={cx(
|
||||
"z-10 flex w-[420px] origin-top flex-col !overflow-visible",
|
||||
"flex origin-top flex-col transition duration-300 ease-out data-[closed]:translate-y-8 data-[closed]:opacity-0",
|
||||
"z-10 flex w-[420px] origin-top flex-col overflow-visible!",
|
||||
"flex origin-top flex-col transition duration-300 ease-out data-closed:translate-y-8 data-closed:opacity-0",
|
||||
)}
|
||||
>
|
||||
{({ open }) => {
|
||||
|
@ -183,8 +183,8 @@ export default function Actionbar({
|
|||
transitionProperty: "opacity",
|
||||
}}
|
||||
className={cx(
|
||||
"z-10 flex w-[420px] origin-top flex-col !overflow-visible",
|
||||
"flex origin-top flex-col transition duration-300 ease-out data-[closed]:translate-y-8 data-[closed]:opacity-0",
|
||||
"z-10 flex w-[420px] origin-top flex-col overflow-visible!",
|
||||
"flex origin-top flex-col transition duration-300 ease-out data-closed:translate-y-8 data-closed:opacity-0",
|
||||
)}
|
||||
>
|
||||
{({ open }) => {
|
||||
|
@ -226,8 +226,8 @@ export default function Actionbar({
|
|||
anchor="bottom start"
|
||||
transition
|
||||
className={cx(
|
||||
"z-10 flex w-[420px] flex-col !overflow-visible",
|
||||
"flex origin-top flex-col transition duration-300 ease-out data-[closed]:translate-y-8 data-[closed]:opacity-0",
|
||||
"z-10 flex w-[420px] flex-col overflow-visible!",
|
||||
"flex origin-top flex-col transition duration-300 ease-out data-closed:translate-y-8 data-closed:opacity-0",
|
||||
)}
|
||||
>
|
||||
{({ open }) => {
|
||||
|
@ -274,7 +274,7 @@ export default function Actionbar({
|
|||
</div>
|
||||
|
||||
<div className="hidden items-center gap-x-2 lg:flex">
|
||||
<div className="h-4 w-[1px] bg-slate-300 dark:bg-slate-600" />
|
||||
<div className="h-4 w-px bg-slate-300 dark:bg-slate-600" />
|
||||
<Button
|
||||
size="XS"
|
||||
theme="light"
|
||||
|
|
|
@ -126,9 +126,9 @@ function ButtonContent(props: ButtonContentPropsType) {
|
|||
<div
|
||||
className={cx(
|
||||
"flex w-full min-w-0 items-center gap-x-1.5 text-center",
|
||||
textAlign === "left" ? "!text-left" : "",
|
||||
textAlign === "center" ? "!text-center" : "",
|
||||
textAlign === "right" ? "!text-right" : "",
|
||||
textAlign === "left" ? "text-left!" : "",
|
||||
textAlign === "center" ? "text-center!" : "",
|
||||
textAlign === "right" ? "text-right!" : "",
|
||||
)}
|
||||
>
|
||||
{loading ? (
|
||||
|
@ -216,7 +216,7 @@ type LinkPropsType = Pick<LinkProps, "to"> &
|
|||
export const LinkButton = ({ to, ...props }: LinkPropsType) => {
|
||||
const classes = cx(
|
||||
"group outline-hidden",
|
||||
props.disabled ? "pointer-events-none !opacity-70" : "",
|
||||
props.disabled ? "pointer-events-none opacity-70!" : "",
|
||||
props.fullWidth ? "w-full" : "",
|
||||
props.loading ? "pointer-events-none" : "",
|
||||
props.className,
|
||||
|
@ -242,7 +242,7 @@ type LabelPropsType = Pick<HTMLLabelElement, "htmlFor"> &
|
|||
export const LabelButton = ({ htmlFor, ...props }: LabelPropsType) => {
|
||||
const classes = cx(
|
||||
"group outline-hidden block cursor-pointer",
|
||||
props.disabled ? "pointer-events-none !opacity-70" : "",
|
||||
props.disabled ? "pointer-events-none opacity-70!" : "",
|
||||
props.fullWidth ? "w-full" : "",
|
||||
props.loading ? "pointer-events-none" : "",
|
||||
props.className,
|
||||
|
|
|
@ -17,8 +17,8 @@ export const GridCard = ({
|
|||
return (
|
||||
<Card className={cx("overflow-hidden", cardClassName)}>
|
||||
<div className="relative h-full">
|
||||
<div className="absolute inset-0 z-0 h-full w-full bg-gradient-to-tr from-blue-50/30 to-blue-50/20 transition-colors duration-300 ease-in-out dark:from-slate-800/30 dark:to-slate-800/20" />
|
||||
<div className="absolute inset-0 z-0 h-full w-full rotate-0 bg-grid-blue-100/[25%] dark:bg-grid-slate-700/[7%]" />
|
||||
<div className="absolute inset-0 z-0 h-full w-full bg-linear-to-tr from-blue-50/30 to-blue-50/20 transition-colors duration-300 ease-in-out dark:from-slate-800/30 dark:to-slate-800/20" />
|
||||
<div className="absolute inset-0 z-0 h-full w-full rotate-0 bg-grid-blue-100/25 dark:bg-grid-slate-700/7" />
|
||||
<div className="isolate h-full">{children}</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
|
|
@ -58,7 +58,7 @@ export function Combobox({
|
|||
<HeadlessCombobox onChange={onChange} {...otherProps}>
|
||||
{() => (
|
||||
<>
|
||||
<Card className="w-auto !border border-solid !border-slate-800/30 shadow-xs outline-0 dark:!border-slate-300/30">
|
||||
<Card className="w-auto border! border-solid border-slate-800/30! shadow-xs outline-0 dark:border-slate-300/30!">
|
||||
<ComboboxInput
|
||||
ref={inputRef}
|
||||
className={clsx(
|
||||
|
@ -88,7 +88,7 @@ export function Combobox({
|
|||
</Card>
|
||||
|
||||
{options().length > 0 && (
|
||||
<ComboboxOptions className="hide-scrollbar absolute left-0 z-[100] mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-sm shadow-lg ring-1 ring-black/5 dark:bg-slate-800 dark:ring-slate-700">
|
||||
<ComboboxOptions className="hide-scrollbar absolute left-0 z-100 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-sm shadow-lg ring-1 ring-black/5 dark:bg-slate-800 dark:ring-slate-700">
|
||||
{options().map(option => (
|
||||
<ComboboxOption
|
||||
key={option.value}
|
||||
|
@ -111,7 +111,7 @@ export function Combobox({
|
|||
)}
|
||||
|
||||
{options().length === 0 && inputRef.current?.value && (
|
||||
<div className="absolute left-0 z-[100] mt-1 w-full rounded-md bg-white px-4 py-2 text-sm shadow-lg ring-1 ring-black/5 dark:bg-slate-800 dark:ring-slate-700">
|
||||
<div className="absolute left-0 z-100 mt-1 w-full rounded-md bg-white px-4 py-2 text-sm shadow-lg ring-1 ring-black/5 dark:bg-slate-800 dark:ring-slate-700">
|
||||
<div className="text-slate-500 dark:text-slate-400">{emptyMessage}</div>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -100,7 +100,7 @@ export default function DashboardNavbar({
|
|||
)}
|
||||
{isLoggedIn ? (
|
||||
<>
|
||||
<hr className="h-[20px] w-[1px] self-center border-none bg-slate-800/20 dark:bg-slate-300/20" />
|
||||
<hr className="h-[20px] w-px self-center border-none bg-slate-800/20 dark:bg-slate-300/20" />
|
||||
<div className="relative inline-block text-left">
|
||||
<Menu>
|
||||
<MenuButton className="h-full">
|
||||
|
|
|
@ -78,7 +78,7 @@ export default function KvmCard({
|
|||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-[1px] bg-slate-800/20 dark:bg-slate-300/20" />
|
||||
<div className="h-px bg-slate-800/20 dark:bg-slate-300/20" />
|
||||
<div className="flex justify-between">
|
||||
<div>
|
||||
{online ? (
|
||||
|
@ -111,7 +111,7 @@ export default function KvmCard({
|
|||
|
||||
<MenuItems
|
||||
transition
|
||||
className="data-[closed]:scale-95 data-[closed]:transform data-[closed]:opacity-0 data-[enter]:duration-100 data-[leave]:duration-75 data-[enter]:ease-out data-[leave]:ease-in"
|
||||
className="data-closed:scale-95 data-closed:transform data-closed:opacity-0 data-enter:duration-100 data-leave:duration-75 data-enter:ease-out data-leave:ease-in"
|
||||
>
|
||||
<Card className="absolute right-0 z-10 w-56 px-1 mt-2 transition origin-top-right ring-1 ring-black/50 focus:outline-hidden">
|
||||
<div className="divide-y divide-slate-800/20 dark:divide-slate-300/20">
|
||||
|
|
|
@ -18,7 +18,7 @@ const Modal = React.memo(function Modal({
|
|||
<Dialog open={open} onClose={onClose} className="relative z-20">
|
||||
<DialogBackdrop
|
||||
transition
|
||||
className="fixed inset-0 bg-gray-500/75 transition-opacity data-[closed]:opacity-0 data-[enter]:duration-500 data-[leave]:duration-200 data-[enter]:ease-out data-[leave]:ease-in dark:bg-slate-900/90"
|
||||
className="fixed inset-0 bg-gray-500/75 transition-opacity data-closed:opacity-0 data-enter:duration-500 data-leave:duration-200 data-enter:ease-out data-leave:ease-in dark:bg-slate-900/90"
|
||||
/>
|
||||
<div className="fixed inset-0 z-20 w-screen overflow-y-auto">
|
||||
{/* TODO: This doesn't work well with other-sessions */}
|
||||
|
@ -26,8 +26,8 @@ const Modal = React.memo(function Modal({
|
|||
<DialogPanel
|
||||
transition
|
||||
className={cx(
|
||||
"pointer-events-none relative w-full md:my-8 md:!mt-[10vh]",
|
||||
"transform transition-all data-[closed]:translate-y-8 data-[closed]:opacity-0 data-[enter]:duration-500 data-[leave]:duration-200 data-[enter]:ease-out data-[leave]:ease-in",
|
||||
"pointer-events-none relative w-full md:my-8 md:mt-[10vh]!",
|
||||
"transform transition-all data-closed:translate-y-8 data-closed:opacity-0 data-enter:duration-500 data-leave:duration-200 data-enter:ease-out data-leave:ease-in",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
|
|
|
@ -63,7 +63,7 @@ export const SelectMenuBasic = React.forwardRef<HTMLSelectElement, SelectMenuPro
|
|||
)}
|
||||
>
|
||||
{label && <FieldLabel label={label} id={id} as="span" />}
|
||||
<Card className="w-auto !border border-solid !border-slate-800/30 shadow-xs outline-0 dark:!border-slate-300/30">
|
||||
<Card className="w-auto border! border-solid border-slate-800/30! shadow-xs outline-0 dark:border-slate-300/30!">
|
||||
<select
|
||||
ref={ref}
|
||||
name={name}
|
||||
|
|
|
@ -23,7 +23,7 @@ const variants = cva({
|
|||
export default function StepCounter({ nSteps, currStepIdx, size = "MD" }: Props) {
|
||||
const textStyle = variants({ size });
|
||||
return (
|
||||
<Card className="!inline-flex w-auto select-none items-center justify-center gap-x-2 rounded-lg p-1">
|
||||
<Card className="inline-flex! w-auto select-none items-center justify-center gap-x-2 rounded-lg p-1">
|
||||
{[...Array(nSteps).keys()].map(i => {
|
||||
if (i < currStepIdx) {
|
||||
return (
|
||||
|
@ -57,7 +57,7 @@ export default function StepCounter({ nSteps, currStepIdx, size = "MD" }: Props)
|
|||
return (
|
||||
<Card
|
||||
className={cx(
|
||||
"flex items-center justify-center !rounded-full text-slate-600 dark:text-slate-400",
|
||||
"flex items-center justify-center rounded-full! text-slate-600 dark:text-slate-400",
|
||||
textStyle,
|
||||
size === "SM" ? "h-5 w-5" : "h-6 w-6",
|
||||
)}
|
||||
|
|
|
@ -171,12 +171,12 @@ function Terminal({
|
|||
[
|
||||
// Base styles
|
||||
"fixed bottom-0 w-full transform transition duration-500 ease-in-out",
|
||||
"translate-y-[0px]",
|
||||
"-translate-y-[0px]",
|
||||
],
|
||||
{
|
||||
"pointer-events-none translate-y-[500px] opacity-100 transition duration-300":
|
||||
!enableTerminal,
|
||||
"pointer-events-auto translate-y-[0px] opacity-100 transition duration-300":
|
||||
"pointer-events-auto -translate-y-[0px] opacity-100 transition duration-300":
|
||||
enableTerminal,
|
||||
},
|
||||
)}
|
||||
|
|
|
@ -11,7 +11,7 @@ export default function UpdateInProgressStatusCard() {
|
|||
|
||||
return (
|
||||
<div className="w-full select-none opacity-100 transition-all duration-300 ease-in-out">
|
||||
<GridCard cardClassName="!shadow-xl">
|
||||
<GridCard cardClassName="shadow-xl!">
|
||||
<div className="flex items-center justify-between gap-x-3 px-2.5 py-2.5 text-black dark:text-white">
|
||||
<div className="flex items-center gap-x-3">
|
||||
<LoadingSpinner className={cx("h-5 w-5", "shrink-0 text-blue-700")} />
|
||||
|
|
|
@ -150,7 +150,7 @@ export function UsbDeviceSetting() {
|
|||
|
||||
return (
|
||||
<Fieldset disabled={loading} className="space-y-4">
|
||||
<div className="h-[1px] w-full bg-slate-800/10 dark:bg-slate-300/20" />
|
||||
<div className="h-px w-full bg-slate-800/10 dark:bg-slate-300/20" />
|
||||
|
||||
<SettingsSectionHeader
|
||||
title="USB Device"
|
||||
|
|
|
@ -14,7 +14,7 @@ interface OverlayContentProps {
|
|||
}
|
||||
function OverlayContent({ children }: OverlayContentProps) {
|
||||
return (
|
||||
<GridCard cardClassName="h-full pointer-events-auto !outline-hidden">
|
||||
<GridCard cardClassName="h-full pointer-events-auto outline-hidden!">
|
||||
<div className="flex h-full w-full flex-col items-center justify-center rounded-md border border-slate-800/30 dark:border-slate-300/20">
|
||||
{children}
|
||||
</div>
|
||||
|
@ -376,7 +376,7 @@ export function PointerLockBar({ show }: PointerLockBarProps) {
|
|||
transition={{ duration: 0.5, ease: "easeInOut", delay: 0.5 }}
|
||||
>
|
||||
<div>
|
||||
<Card className="rounded-b-none shadow-none !outline-0">
|
||||
<Card className="rounded-b-none shadow-none outline-0!">
|
||||
<div className="flex items-center justify-between border border-slate-800/50 px-4 py-2 outline-0 backdrop-blur-xs dark:border-slate-300/20 dark:bg-slate-800">
|
||||
<div className="flex items-center space-x-2">
|
||||
<BsMouseFill className="h-4 w-4 text-blue-700 dark:text-blue-500" />
|
||||
|
|
|
@ -259,25 +259,25 @@ export default function WebRTCVideo() {
|
|||
(e: WheelEvent) => {
|
||||
if (blockWheelEvent) return;
|
||||
|
||||
// Determine if the wheel event is from a trackpad or a mouse wheel
|
||||
const isTrackpad = Math.abs(e.deltaY) < trackpadThreshold;
|
||||
// Determine if the wheel event is an accel scroll value
|
||||
const isAccel = Math.abs(e.deltaY) >= 100;
|
||||
|
||||
// Apply appropriate sensitivity based on input device
|
||||
const scrollSensitivity = isTrackpad ? trackpadSensitivity : mouseSensitivity;
|
||||
// Calculate the accel scroll value
|
||||
const accelScrollValue = e.deltaY / 100;
|
||||
|
||||
// Calculate the scroll value
|
||||
const scroll = e.deltaY * scrollSensitivity;
|
||||
// Calculate the no accel scroll value
|
||||
const noAccelScrollValue = e.deltaY > 0 ? 1 : (e.deltaY < 0 ? -1 : 0);
|
||||
|
||||
// Apply clamping
|
||||
const clampedScroll = Math.max(clampMin, Math.min(clampMax, scroll));
|
||||
// Get scroll value
|
||||
const scrollValue = isAccel ? accelScrollValue : noAccelScrollValue;
|
||||
|
||||
// Round to the nearest integer
|
||||
const roundedScroll = Math.round(clampedScroll);
|
||||
// Apply clamping (i.e. min and max mouse wheel hardware value)
|
||||
const clampedScrollValue = Math.max(-127, Math.min(127, scrollValue));
|
||||
|
||||
// Invert the scroll value to match expected behavior
|
||||
const invertedScroll = -roundedScroll;
|
||||
// Invert the clamped scroll value to match expected behavior
|
||||
const invertedScrollValue = -clampedScrollValue;
|
||||
|
||||
send("wheelReport", { wheelY: invertedScroll });
|
||||
send("wheelReport", { wheelY : invertedScrollValue });
|
||||
|
||||
// Apply blocking delay
|
||||
setBlockWheelEvent(true);
|
||||
|
@ -691,15 +691,15 @@ export default function WebRTCVideo() {
|
|||
<div
|
||||
className={cx(
|
||||
"absolute inset-0 -z-0 bg-blue-50/40 opacity-80 dark:bg-slate-800/40",
|
||||
"[background-image:radial-gradient(theme(colors.blue.300)_0.5px,transparent_0.5px),radial-gradient(theme(colors.blue.300)_0.5px,transparent_0.5px)] dark:[background-image:radial-gradient(theme(colors.slate.700)_0.5px,transparent_0.5px),radial-gradient(theme(colors.slate.700)_0.5px,transparent_0.5px)]",
|
||||
"[background-position:0_0,10px_10px]",
|
||||
"[background-size:20px_20px]",
|
||||
"bg-[radial-gradient(var(--color-blue-300)_0.5px,transparent_0.5px),radial-gradient(var(--color-blue-300)_0.5px,transparent_0.5px)] dark:bg-[radial-gradient(var(--color-slate-700)_0.5px,transparent_0.5px),radial-gradient(var(--color-slate-700)_0.5px,transparent_0.5px)]",
|
||||
"bg-position-[0_0,10px_10px]",
|
||||
"bg-size-[20px_20px]",
|
||||
)}
|
||||
/>
|
||||
<div className="flex h-full flex-col">
|
||||
<div className="relative flex-grow overflow-hidden">
|
||||
<div className="relative grow overflow-hidden">
|
||||
<div className="flex h-full flex-col">
|
||||
<div className="grid flex-grow grid-rows-(--grid-bodyFooter) overflow-hidden">
|
||||
<div className="grid grow grid-rows-(--grid-bodyFooter) overflow-hidden">
|
||||
<div className="relative mx-4 my-2 flex items-center justify-center overflow-hidden">
|
||||
<div className="relative flex h-full w-full items-center justify-center">
|
||||
<div className="relative inline-block">
|
||||
|
@ -723,7 +723,7 @@ export default function WebRTCVideo() {
|
|||
isVideoLoading ||
|
||||
hdmiError ||
|
||||
peerConnectionState !== "connected",
|
||||
"!opacity-60": showPointerLockBar,
|
||||
"opacity-60!": showPointerLockBar,
|
||||
"animate-slideUpFade border border-slate-800/30 shadow-xs dark:border-slate-300/20":
|
||||
isPlaying,
|
||||
},
|
||||
|
|
|
@ -8,14 +8,21 @@ import { GridCard } from "@components/Card";
|
|||
import { TextAreaWithLabel } from "@components/TextArea";
|
||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
||||
import { useHidStore, useRTCStore, useUiStore } from "@/hooks/stores";
|
||||
import { chars, keys, modifiers } from "@/keyboardMappings";
|
||||
import { useHidStore, useRTCStore, useUiStore, useDeviceSettingsStore } from "@/hooks/stores";
|
||||
import { keys, modifiers } from "@/keyboardMappings";
|
||||
import { layouts, chars } from "@/keyboardLayouts";
|
||||
import notifications from "@/notifications";
|
||||
|
||||
const hidKeyboardPayload = (keys: number[], modifier: number) => {
|
||||
return { keys, modifier };
|
||||
const hidKeyboardPayload = (keys: number[], modifier: number, hold: boolean) => {
|
||||
return { keys, modifier, hold };
|
||||
};
|
||||
|
||||
const modifierCode = (shift?: boolean, altRight?: boolean) => {
|
||||
return (shift ? modifiers["ShiftLeft"] : 0)
|
||||
| (altRight ? modifiers["AltRight"] : 0)
|
||||
}
|
||||
const noModifier = 0
|
||||
|
||||
export default function PasteModal() {
|
||||
const TextAreaRef = useRef<HTMLTextAreaElement>(null);
|
||||
const setPasteMode = useHidStore(state => state.setPasteModeEnabled);
|
||||
|
@ -27,6 +34,18 @@ export default function PasteModal() {
|
|||
const [invalidChars, setInvalidChars] = useState<string[]>([]);
|
||||
const close = useClose();
|
||||
|
||||
const keyboardLayout = useDeviceSettingsStore(state => state.keyboardLayout);
|
||||
const setKeyboardLayout = useDeviceSettingsStore(
|
||||
state => state.setKeyboardLayout,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
send("getKeyboardLayout", {}, resp => {
|
||||
if ("error" in resp) return;
|
||||
setKeyboardLayout(resp.result as string);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const onCancelPasteMode = useCallback(() => {
|
||||
setPasteMode(false);
|
||||
setDisableVideoFocusTrap(false);
|
||||
|
@ -37,27 +56,40 @@ export default function PasteModal() {
|
|||
setPasteMode(false);
|
||||
setDisableVideoFocusTrap(false);
|
||||
if (rpcDataChannel?.readyState !== "open" || !TextAreaRef.current) return;
|
||||
if (!keyboardLayout) return;
|
||||
if (!chars[keyboardLayout]) return;
|
||||
|
||||
const text = TextAreaRef.current.value;
|
||||
|
||||
try {
|
||||
for (const char of text) {
|
||||
const { key, shift } = chars[char] ?? {};
|
||||
const { key, shift, altRight, deadKey, accentKey } = chars[keyboardLayout][char]
|
||||
if (!key) continue;
|
||||
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
send(
|
||||
"keyboardReport",
|
||||
hidKeyboardPayload([keys[key]], shift ? modifiers["ShiftLeft"] : 0),
|
||||
params => {
|
||||
if ("error" in params) return reject(params.error);
|
||||
send("keyboardReport", hidKeyboardPayload([], 0), params => {
|
||||
const keyz = [ keys[key] ];
|
||||
const modz = [ modifierCode(shift, altRight) ];
|
||||
|
||||
if (deadKey) {
|
||||
keyz.push(keys["Space"]);
|
||||
modz.push(noModifier);
|
||||
}
|
||||
if (accentKey) {
|
||||
keyz.unshift(keys[accentKey.key])
|
||||
modz.unshift(modifierCode(accentKey.shift, accentKey.altRight))
|
||||
}
|
||||
|
||||
for (const [index, kei] of keyz.entries()) {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
send(
|
||||
"keyboardReport",
|
||||
hidKeyboardPayload([kei], modz[index], false),
|
||||
params => {
|
||||
if ("error" in params) return reject(params.error);
|
||||
resolve();
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
@ -113,7 +145,7 @@ export default function PasteModal() {
|
|||
// @ts-expect-error TS doesn't recognize Intl.Segmenter in some environments
|
||||
[...new Intl.Segmenter().segment(value)]
|
||||
.map(x => x.segment)
|
||||
.filter(char => !chars[char]),
|
||||
.filter(char => !chars[keyboardLayout][char]),
|
||||
),
|
||||
];
|
||||
|
||||
|
@ -132,6 +164,11 @@ export default function PasteModal() {
|
|||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<p className="text-xs text-slate-600 dark:text-slate-400">
|
||||
Sending key codes using keyboard layout {layouts[keyboardLayout]}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -348,6 +348,8 @@ export interface DeviceSettingsState {
|
|||
trackpadThreshold: number;
|
||||
scrollSensitivity: "low" | "default" | "high";
|
||||
setScrollSensitivity: (sensitivity: DeviceSettingsState["scrollSensitivity"]) => void;
|
||||
keyboardLayout: string;
|
||||
setKeyboardLayout: (layout: string) => void;
|
||||
}
|
||||
|
||||
export const useDeviceSettingsStore = create<DeviceSettingsState>(set => ({
|
||||
|
@ -409,6 +411,9 @@ export const useDeviceSettingsStore = create<DeviceSettingsState>(set => ({
|
|||
scrollSensitivity: sensitivity,
|
||||
});
|
||||
},
|
||||
|
||||
keyboardLayout: "en_US",
|
||||
setKeyboardLayout: layout => set({ keyboardLayout: layout }),
|
||||
}));
|
||||
|
||||
export interface RemoteVirtualMediaState {
|
||||
|
@ -941,4 +946,5 @@ export const useMacrosStore = create<MacrosState>((set, get) => ({
|
|||
set({ loading: false });
|
||||
}
|
||||
},
|
||||
}
|
||||
}));
|
||||
|
|
|
@ -4,6 +4,10 @@ import { useHidStore, useRTCStore } from "@/hooks/stores";
|
|||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
||||
import { keys, modifiers } from "@/keyboardMappings";
|
||||
|
||||
const hidKeyboardPayload = (keys: number[], modifier: number, hold: boolean) => {
|
||||
return { keys, modifier, hold };
|
||||
};
|
||||
|
||||
export default function useKeyboard() {
|
||||
const [send] = useJsonRpc();
|
||||
|
||||
|
@ -17,7 +21,7 @@ export default function useKeyboard() {
|
|||
if (rpcDataChannel?.readyState !== "open") return;
|
||||
const accModifier = modifiers.reduce((acc, val) => acc + val, 0);
|
||||
|
||||
send("keyboardReport", { keys, modifier: accModifier });
|
||||
send("keyboardReport", hidKeyboardPayload(keys, accModifier, true));
|
||||
|
||||
// We do this for the info bar to display the currently pressed keys for the user
|
||||
updateActiveKeysAndModifiers({ keys: keys, modifiers: modifiers });
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
@import "tailwindcss";
|
||||
@import 'tailwindcss';
|
||||
|
||||
@config "../tailwind.config.js";
|
||||
|
||||
@plugin "@tailwindcss/typography";
|
||||
@plugin "@tailwindcss/forms";
|
||||
@plugin "@headlessui/tailwindcss";
|
||||
|
@ -7,22 +9,11 @@
|
|||
/* Dark mode uses CSS selector instead of prefers-color-scheme */
|
||||
@custom-variant dark (&:where(.dark, .dark *));
|
||||
|
||||
html {
|
||||
@apply scroll-smooth;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
@theme {
|
||||
--font-sans: "Circular", sans-serif;
|
||||
--font-display: "Circular", sans-serif;
|
||||
--font-serif: "Circular", serif;
|
||||
--font-mono: "Source Code Pro Variable", monospace;
|
||||
--font-sans: 'Circular', sans-serif;
|
||||
--font-display: 'Circular', sans-serif;
|
||||
--font-serif: 'Circular', serif;
|
||||
--font-mono: 'Source Code Pro Variable', monospace;
|
||||
|
||||
--grid-layout: auto 1fr auto;
|
||||
--grid-headerBody: auto 1fr;
|
||||
|
@ -140,15 +131,26 @@ body {
|
|||
animation-delay: --value(integer) ms;
|
||||
}
|
||||
|
||||
html {
|
||||
@apply scroll-smooth;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
@property --grid-color-start {
|
||||
syntax: "<color>";
|
||||
initial-value: theme("colors.blue.50/10");
|
||||
initial-value: var(--color-blue-50/10);
|
||||
inherits: false;
|
||||
}
|
||||
|
||||
@property --grid-color-end {
|
||||
syntax: "<color>";
|
||||
initial-value: theme("colors.blue.50/100");
|
||||
initial-value: var(--color-blue-50/100);
|
||||
inherits: false;
|
||||
}
|
||||
|
||||
|
@ -164,8 +166,8 @@ body {
|
|||
}
|
||||
|
||||
.group:hover .grid-card {
|
||||
--grid-color-start: theme("colors.blue.100/50");
|
||||
--grid-color-end: theme("colors.blue.50/50");
|
||||
--grid-color-start: var(--color-blue-100/50);
|
||||
--grid-color-end: var(--color-blue-50/50);
|
||||
}
|
||||
|
||||
video::-webkit-media-controls {
|
||||
|
@ -173,11 +175,11 @@ video::-webkit-media-controls {
|
|||
}
|
||||
|
||||
.hg-theme-default {
|
||||
@apply !font-display font-normal;
|
||||
@apply font-display! font-normal;
|
||||
}
|
||||
|
||||
.hg-theme-default .hg-button {
|
||||
@apply border !border-b border-slate-800/25 !border-b-slate-800/25 !shadow-xs;
|
||||
@apply border border-b! border-slate-800/25 border-b-slate-800/25! shadow-xs!;
|
||||
}
|
||||
|
||||
.hg-theme-default .hg-button span {
|
||||
|
@ -249,7 +251,7 @@ video::-webkit-media-controls {
|
|||
}
|
||||
|
||||
.hg-button {
|
||||
@apply dark:!bg-slate-800 dark:text-white;
|
||||
@apply dark:bg-slate-800! dark:text-white;
|
||||
}
|
||||
|
||||
.simple-keyboard-control .hg-button {
|
||||
|
@ -297,25 +299,21 @@ video::-webkit-media-controls {
|
|||
}
|
||||
|
||||
.hg-button.hg-standardBtn[data-skbtn="Space"] {
|
||||
@apply md:!w-[350px];
|
||||
@apply md:w-[350px]!;
|
||||
}
|
||||
|
||||
.hg-theme-default .hg-row .combination-key {
|
||||
@apply inline-flex !h-auto !w-auto grow-0 py-1 text-xs;
|
||||
}
|
||||
|
||||
.hg-theme-default .hg-row:has(.combination-key) {
|
||||
/*margin-bottom: 100px !important;*/
|
||||
@apply inline-flex h-auto! w-auto! grow-0 py-1 text-xs;
|
||||
}
|
||||
|
||||
.hg-theme-default .hg-row .hg-button-container,
|
||||
.hg-theme-default .hg-row .hg-button:not(:last-child) {
|
||||
@apply !mr-[2px] md:!mr-[5px];
|
||||
@apply mr-[2px]! md:mr-[5px]!;
|
||||
}
|
||||
|
||||
/* Hide the scrollbar by setting the scrollbar color to the background color */
|
||||
.xterm .xterm-viewport {
|
||||
scrollbar-color: theme("colors.gray.900") #002b36;
|
||||
scrollbar-color: var(--color-gray-900) #002b36;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
import { chars as chars_cs_CZ, name as name_cs_CZ } from "@/keyboardLayouts/cs_CZ"
|
||||
import { chars as chars_en_UK, name as name_en_UK } from "@/keyboardLayouts/en_UK"
|
||||
import { chars as chars_en_US, name as name_en_US } from "@/keyboardLayouts/en_US"
|
||||
import { chars as chars_fr_FR, name as name_fr_FR } from "@/keyboardLayouts/fr_FR"
|
||||
import { chars as chars_de_DE, name as name_de_DE } from "@/keyboardLayouts/de_DE"
|
||||
import { chars as chars_it_IT, name as name_it_IT } from "@/keyboardLayouts/it_IT"
|
||||
import { chars as chars_nb_NO, name as name_nb_NO } from "@/keyboardLayouts/nb_NO"
|
||||
import { chars as chars_es_ES, name as name_es_ES } from "@/keyboardLayouts/es_ES"
|
||||
import { chars as chars_sv_SE, name as name_sv_SE } from "@/keyboardLayouts/sv_SE"
|
||||
import { chars as chars_fr_CH, name as name_fr_CH } from "@/keyboardLayouts/fr_CH"
|
||||
import { chars as chars_de_CH, name as name_de_CH } from "@/keyboardLayouts/de_CH"
|
||||
|
||||
type KeyInfo = { key: string | number; shift?: boolean, altRight?: boolean }
|
||||
export type KeyCombo = KeyInfo & { deadKey?: boolean, accentKey?: KeyInfo }
|
||||
|
||||
export const layouts: Record<string, string> = {
|
||||
cs_CZ: name_cs_CZ,
|
||||
en_UK: name_en_UK,
|
||||
en_US: name_en_US,
|
||||
fr_FR: name_fr_FR,
|
||||
de_DE: name_de_DE,
|
||||
it_IT: name_it_IT,
|
||||
nb_NO: name_nb_NO,
|
||||
es_ES: name_es_ES,
|
||||
sv_SE: name_sv_SE,
|
||||
fr_CH: name_fr_CH,
|
||||
de_CH: name_de_CH,
|
||||
}
|
||||
|
||||
export const chars: Record<string, Record<string, KeyCombo>> = {
|
||||
cs_CZ: chars_cs_CZ,
|
||||
en_UK: chars_en_UK,
|
||||
en_US: chars_en_US,
|
||||
fr_FR: chars_fr_FR,
|
||||
de_DE: chars_de_DE,
|
||||
it_IT: chars_it_IT,
|
||||
nb_NO: chars_nb_NO,
|
||||
es_ES: chars_es_ES,
|
||||
sv_SE: chars_sv_SE,
|
||||
fr_CH: chars_fr_CH,
|
||||
de_CH: chars_de_CH,
|
||||
};
|
|
@ -0,0 +1,244 @@
|
|||
import { KeyCombo } from "../keyboardLayouts"
|
||||
|
||||
export const name = "Čeština";
|
||||
|
||||
const keyTrema = { key: "Backslash" } // tréma (umlaut), two dots placed above a vowel
|
||||
const keyAcute = { key: "Equal" } // accent aigu (acute accent), mark ´ placed above the letter
|
||||
const keyHat = { key: "Digit3", shift: true, altRight: true } // accent circonflexe (accent hat), mark ^ placed above the letter
|
||||
const keyCaron = { key: "Equal", shift: true } // caron or haček (inverted hat), mark ˇ placed above the letter
|
||||
const keyGrave = { key: "Digit7", shift: true, altRight: true } // accent grave, mark ` placed above the letter
|
||||
const keyTilde = { key: "Digit1", shift: true, altRight: true } // tilde, mark ~ placed above the letter
|
||||
const keyRing = { key: "Backquote", shift: true } // kroužek (little ring), mark ° placed above the letter
|
||||
const keyOverdot = { key: "Digit8", shift: true, altRight: true } // overdot (dot above), mark ˙ placed above the letter
|
||||
const keyHook = { key: "Digit6", shift: true, altRight: true } // ogonoek (little hook), mark ˛ placed beneath a letter
|
||||
const keyCedille = { key: "Equal", shift: true, altRight: true } // accent cedille (cedilla), mark ¸ placed beneath a letter
|
||||
|
||||
export const chars = {
|
||||
A: { key: "KeyA", shift: true },
|
||||
"Ä": { key: "KeyA", shift: true, accentKey: keyTrema },
|
||||
"Á": { key: "KeyA", shift: true, accentKey: keyAcute },
|
||||
"Â": { key: "KeyA", shift: true, accentKey: keyHat },
|
||||
"À": { key: "KeyA", shift: true, accentKey: keyGrave },
|
||||
"Ã": { key: "KeyA", shift: true, accentKey: keyTilde },
|
||||
"Ȧ": { key: "KeyA", shift: true, accentKey: keyOverdot },
|
||||
"Ą": { key: "KeyA", shift: true, accentKey: keyHook },
|
||||
B: { key: "KeyB", shift: true },
|
||||
"Ḃ": { key: "KeyB", shift: true, accentKEy: keyOverdot },
|
||||
C: { key: "KeyC", shift: true },
|
||||
"Č": { key: "KeyC", shift: true, accentKey: keyCaron },
|
||||
"Ċ": { key: "KeyC", shift: true, accentKey: keyOverdot },
|
||||
"Ç": { key: "KeyC", shift: true, accentKey: keyCedille },
|
||||
D: { key: "KeyD", shift: true },
|
||||
"Ď": { key: "KeyD", shift: true, accentKey: keyCaron },
|
||||
"Ḋ": { key: "KeyD", shift: true, accentKey: keyOverdot },
|
||||
E: { key: "KeyE", shift: true },
|
||||
"Ë": { key: "KeyE", shift: true, accentKey: keyTrema },
|
||||
"É": { key: "KeyE", shift: true, accentKey: keyAcute },
|
||||
"Ê": { key: "KeyE", shift: true, accentKey: keyHat },
|
||||
"Ě": { key: "KeyE", shift: true, accentKey: keyCaron },
|
||||
"È": { key: "KeyE", shift: true, accentKey: keyGrave },
|
||||
"Ẽ": { key: "KeyE", shift: true, accentKey: keyTilde },
|
||||
"Ė": { key: "KeyE", shift: true, accentKEy: keyOverdot },
|
||||
"Ę": { key: "KeyE", shift: true, accentKey: keyHook },
|
||||
F: { key: "KeyF", shift: true },
|
||||
"Ḟ": { key: "KeyF", shift: true, accentKey: keyOverdot },
|
||||
G: { key: "KeyG", shift: true },
|
||||
"Ġ": { key: "KeyG", shift: true, accentKey: keyOverdot },
|
||||
H: { key: "KeyH", shift: true },
|
||||
"Ḣ": { key: "KeyH", shift: true, accentKey: keyOverdot },
|
||||
I: { key: "KeyI", shift: true },
|
||||
"Ï": { key: "KeyI", shift: true, accentKey: keyTrema },
|
||||
"Í": { key: "KeyI", shift: true, accentKey: keyAcute },
|
||||
"Î": { key: "KeyI", shift: true, accentKey: keyHat },
|
||||
"Ì": { key: "KeyI", shift: true, accentKey: keyGrave },
|
||||
"Ĩ": { key: "KeyI", shift: true, accentKey: keyTilde },
|
||||
"İ": { key: "KeyI", shift: true, accentKey: keyOverdot },
|
||||
"Į": { key: "KeyI", shift: true, accentKey: keyHook },
|
||||
J: { key: "KeyJ", shift: true },
|
||||
K: { key: "KeyK", shift: true },
|
||||
L: { key: "KeyL", shift: true },
|
||||
"Ŀ": { key: "KeyL", shift: true },
|
||||
M: { key: "KeyM", shift: true },
|
||||
"Ṁ": { key: "KeyM", shift: true },
|
||||
N: { key: "KeyN", shift: true },
|
||||
"Ň": { key: "KeyN", shift: true, accentKey: keyCaron },
|
||||
"Ñ": { key: "KeyN", shift: true, accentKey: keyTilde },
|
||||
"Ṅ": { key: "KeyN", shift: true, accentKEy: keyOverdot },
|
||||
O: { key: "KeyO", shift: true },
|
||||
"Ö": { key: "KeyO", shift: true, accentKey: keyTrema },
|
||||
"Ó": { key: "KeyO", shift: true, accentKey: keyAcute },
|
||||
"Ô": { key: "KeyO", shift: true, accentKey: keyHat },
|
||||
"Ò": { key: "KeyO", shift: true, accentKey: keyGrave },
|
||||
"Õ": { key: "KeyO", shift: true, accentKey: keyTilde },
|
||||
"Ȯ": { key: "KeyO", shift: true, accentKey: keyOverdot },
|
||||
"Ǫ": { key: "KeyO", shift: true, accentKey: keyHook },
|
||||
P: { key: "KeyP", shift: true },
|
||||
"Ṗ": { key: "KeyP", shift: true, accentKey: keyOverdot },
|
||||
Q: { key: "KeyQ", shift: true },
|
||||
R: { key: "KeyR", shift: true },
|
||||
"Ř": { key: "KeyR", shift: true, accentKey: keyCaron },
|
||||
"Ṙ": { key: "KeyR", shift: true, accentKey: keyOverdot },
|
||||
S: { key: "KeyS", shift: true },
|
||||
"Š": { key: "KeyS", shift: true, accentKey: keyCaron },
|
||||
"Ṡ": { key: "KeyS", shift: true, accentKey: keyOverdot },
|
||||
T: { key: "KeyT", shift: true },
|
||||
"Ť": { key: "KeyT", shift: true, accentKey: keyCaron },
|
||||
"Ṫ": { key: "KeyT", shift: true, accentKey: keyOverdot },
|
||||
U: { key: "KeyU", shift: true },
|
||||
"Ü": { key: "KeyU", shift: true, accentKey: keyTrema },
|
||||
"Ú": { key: "KeyU", shift: true, accentKey: keyAcute },
|
||||
"Û": { key: "KeyU", shift: true, accentKey: keyHat },
|
||||
"Ù": { key: "KeyU", shift: true, accentKey: keyGrave },
|
||||
"Ũ": { key: "KeyU", shift: true, accentKey: keyTilde },
|
||||
"Ů": { key: "KeyU", shift: true, accentKey: keyRing },
|
||||
"Ų": { key: "KeyU", shift: true, accentKey: keyHook },
|
||||
V: { key: "KeyV", shift: true },
|
||||
W: { key: "KeyW", shift: true },
|
||||
"Ẇ": { key: "KeyW", shift: true, accentKey: keyOverdot },
|
||||
X: { key: "KeyX", shift: true },
|
||||
"Ẋ": { key: "KeyX", shift: true, accentKey: keyOverdot },
|
||||
Y: { key: "KeyY", shift: true },
|
||||
"Ý": { key: "KeyY", shift: true, accentKey: keyAcute },
|
||||
"Ẏ": { key: "KeyY", shift: true, accentKey: keyOverdot },
|
||||
Z: { key: "KeyZ", shift: true },
|
||||
"Ż": { key: "KeyZ", shift: true, accentKey: keyOverdot },
|
||||
a: { key: "KeyA" },
|
||||
"ä": { key: "KeyA", accentKey: keyTrema },
|
||||
"â": { key: "KeyA", accentKey: keyHat },
|
||||
"à": { key: "KeyA", accentKey: keyGrave },
|
||||
"ã": { key: "KeyA", accentKey: keyTilde },
|
||||
"ȧ": { key: "KeyA", accentKey: keyOverdot },
|
||||
"ą": { key: "KeyA", accentKey: keyHook },
|
||||
b: { key: "KeyB" },
|
||||
"{": { key: "KeyB", altRight: true },
|
||||
"ḃ": { key: "KeyB", accentKey: keyOverdot },
|
||||
c: { key: "KeyC" },
|
||||
"&": { key: "KeyC", altRight: true },
|
||||
"ç": { key: "KeyC", accentKey: keyCedille },
|
||||
"ċ": { key: "KeyC", accentKey: keyOverdot },
|
||||
d: { key: "KeyD" },
|
||||
"ď": { key: "KeyD", accentKey: keyCaron },
|
||||
"ḋ": { key: "KeyD", accentKey: keyOverdot },
|
||||
"Đ": { key: "KeyD", altRight: true },
|
||||
e: { key: "KeyE" },
|
||||
"ë": { key: "KeyE", accentKey: keyTrema },
|
||||
"ê": { key: "KeyE", accentKey: keyHat },
|
||||
"ẽ": { key: "KeyE", accentKey: keyTilde },
|
||||
"è": { key: "KeyE", accentKey: keyGrave },
|
||||
"ė": { key: "KeyE", accentKey: keyOverdot },
|
||||
"ę": { key: "KeyE", accentKey: keyHook },
|
||||
"€": { key: "KeyE", altRight: true },
|
||||
f: { key: "KeyF" },
|
||||
"ḟ": { key: "KeyF", accentKey: keyOverdot },
|
||||
"[": { key: "KeyF", altRight: true },
|
||||
g: { key: "KeyG" },
|
||||
"ġ": { key: "KeyG", accentKey: keyOverdot },
|
||||
"]": { key: "KeyF", altRight: true },
|
||||
h: { key: "KeyH" },
|
||||
"ḣ": { key: "KeyH", accentKey: keyOverdot },
|
||||
i: { key: "KeyI" },
|
||||
"ï": { key: "KeyI", accentKey: keyTrema },
|
||||
"î": { key: "KeyI", accentKey: keyHat },
|
||||
"ì": { key: "KeyI", accentKey: keyGrave },
|
||||
"ĩ": { key: "KeyI", accentKey: keyTilde },
|
||||
"ı": { key: "KeyI", accentKey: keyOverdot },
|
||||
"į": { key: "KeyI", accentKey: keyHook },
|
||||
j: { key: "KeyJ" },
|
||||
"ȷ": { key: "KeyJ", accentKey: keyOverdot },
|
||||
k: { key: "KeyK" },
|
||||
"ł": { key: "KeyK", altRight: true },
|
||||
l: { key: "KeyL" },
|
||||
"ŀ": { key: "KeyL", accentKey: keyOverdot },
|
||||
"Ł": { key: "KeyL", altRight: true },
|
||||
m: { key: "KeyM" },
|
||||
"ṁ": { key: "KeyM", accentKey: keyOverdot },
|
||||
n: { key: "KeyN" },
|
||||
"}": { key: "KeyN", altRight: true },
|
||||
"ň": { key: "KeyN", accentKey: keyCaron },
|
||||
"ñ": { key: "KeyN", accentKey: keyTilde },
|
||||
"ṅ": { key: "KeyN", accentKey: keyOverdot },
|
||||
o: { key: "KeyO" },
|
||||
"ö": { key: "Key0", accentKey: keyTrema },
|
||||
"ó": { key: "KeyO", accentKey: keyAcute },
|
||||
"ô": { key: "KeyO", accentKey: keyHat },
|
||||
"ò": { key: "KeyO", accentKey: keyGrave },
|
||||
"õ": { key: "KeyO", accentKey: keyTilde },
|
||||
"ȯ": { key: "KeyO", accentKey: keyOverdot },
|
||||
"ǫ": { key: "KeyO", accentKey: keyHook },
|
||||
p: { key: "KeyP" },
|
||||
"ṗ": { key: "KeyP", accentKey: keyOverdot },
|
||||
q: { key: "KeyQ" },
|
||||
r: { key: "KeyR" },
|
||||
"ṙ": { key: "KeyR", accentKey: keyOverdot },
|
||||
s: { key: "KeyS" },
|
||||
"ṡ": { key: "KeyS", accentKey: keyOverdot },
|
||||
"đ": { key: "KeyS", altRight: true },
|
||||
t: { key: "KeyT" },
|
||||
"ť": { key: "KeyT", accentKey: keyCaron },
|
||||
"ṫ": { key: "KeyT", accentKey: keyOverdot },
|
||||
u: { key: "KeyU" },
|
||||
"ü": { key: "KeyU", accentKey: keyTrema },
|
||||
"û": { key: "KeyU", accentKey: keyHat },
|
||||
"ù": { key: "KeyU", accentKey: keyGrave },
|
||||
"ũ": { key: "KeyU", accentKey: keyTilde },
|
||||
"ų": { key: "KeyU", accentKey: keyHook },
|
||||
v: { key: "KeyV" },
|
||||
"@": { key: "KeyV", altRight: true },
|
||||
w: { key: "KeyW" },
|
||||
"ẇ": { key: "KeyW", accentKey: keyOverdot },
|
||||
x: { key: "KeyX" },
|
||||
"#": { key: "KeyX", altRight: true },
|
||||
"ẋ": { key: "KeyX", accentKey: keyOverdot },
|
||||
y: { key: "KeyY" },
|
||||
"ẏ": { key: "KeyY", accentKey: keyOverdot },
|
||||
z: { key: "KeyZ" },
|
||||
"ż": { key: "KeyZ", accentKey: keyOverdot },
|
||||
";": { key: "Backquote" },
|
||||
"°": { key: "Backquote", shift: true, deadKey: true },
|
||||
"+": { key: "Digit1" },
|
||||
1: { key: "Digit1", shift: true },
|
||||
"ě": { key: "Digit2" },
|
||||
2: { key: "Digit2", shift: true },
|
||||
"š": { key: "Digit3" },
|
||||
3: { key: "Digit3", shift: true },
|
||||
"č": { key: "Digit4" },
|
||||
4: { key: "Digit4", shift: true },
|
||||
"ř": { key: "Digit5" },
|
||||
5: { key: "Digit5", shift: true },
|
||||
"ž": { key: "Digit6" },
|
||||
6: { key: "Digit6", shift: true },
|
||||
"ý": { key: "Digit7" },
|
||||
7: { key: "Digit7", shift: true },
|
||||
"á": { key: "Digit8" },
|
||||
8: { key: "Digit8", shift: true },
|
||||
"í": { key: "Digit9" },
|
||||
9: { key: "Digit9", shift: true },
|
||||
"é": { key: "Digit0" },
|
||||
0: { key: "Digit0", shift: true },
|
||||
"=": { key: "Minus" },
|
||||
"%": { key: "Minus", shift: true },
|
||||
"ú": { key: "BracketLeft" },
|
||||
"/": { key: "BracketLeft", shift: true },
|
||||
")": { key: "BracketRight" },
|
||||
"(": { key: "BracketRight", shift: true },
|
||||
"ů": { key: "Semicolon" },
|
||||
"\"": { key: "Semicolon", shift: true },
|
||||
"§": { key: "Quote" },
|
||||
"!": { key: "Quote", shift: true },
|
||||
"'": { key: "Backslash", shift: true },
|
||||
",": { key: "Comma" },
|
||||
"?": { key: "Comma", shift: true },
|
||||
"<": { key: "Comma", altRight: true },
|
||||
".": { key: "Period" },
|
||||
":": { key: "Period", shift: true },
|
||||
">": { key: "Period", altRight: true },
|
||||
"-": { key: "Slash" },
|
||||
"_": { key: "Slash", shift: true },
|
||||
"*": { key: "Slash", altRight: true },
|
||||
"\\": { key: "IntlBackslash" },
|
||||
"|": { key: "IntlBackslash", shift: true },
|
||||
" ": { key: "Space" },
|
||||
"\n": { key: "Enter" },
|
||||
Enter: { key: "Enter" },
|
||||
Tab: { key: "Tab" },
|
||||
} as Record<string, KeyCombo>;
|
|
@ -0,0 +1,165 @@
|
|||
import { KeyCombo } from "../keyboardLayouts"
|
||||
|
||||
export const name = "Schwiizerdütsch";
|
||||
|
||||
const keyTrema = { key: "BracketRight" } // tréma (umlaut), two dots placed above a vowel
|
||||
const keyAcute = { key: "Minus", altRight: true } // accent aigu (acute accent), mark ´ placed above the letter
|
||||
const keyHat = { key: "Equal" } // accent circonflexe (accent hat), mark ^ placed above the letter
|
||||
const keyGrave = { key: "Equal", shift: true } // accent grave, mark ` placed above the letter
|
||||
const keyTilde = { key: "Equal", altRight: true } // tilde, mark ~ placed above the letter
|
||||
|
||||
export const chars = {
|
||||
A: { key: "KeyA", shift: true },
|
||||
"Ä": { key: "KeyA", shift: true, accentKey: keyTrema },
|
||||
"Á": { key: "KeyA", shift: true, accentKey: keyAcute },
|
||||
"Â": { key: "KeyA", shift: true, accentKey: keyHat },
|
||||
"À": { key: "KeyA", shift: true, accentKey: keyGrave },
|
||||
"Ã": { key: "KeyA", shift: true, accentKey: keyTilde },
|
||||
B: { key: "KeyB", shift: true },
|
||||
C: { key: "KeyC", shift: true },
|
||||
D: { key: "KeyD", shift: true },
|
||||
E: { key: "KeyE", shift: true },
|
||||
"Ë": { key: "KeyE", shift: true, accentKey: keyTrema },
|
||||
"É": { key: "KeyE", shift: true, accentKey: keyAcute },
|
||||
"Ê": { key: "KeyE", shift: true, accentKey: keyHat },
|
||||
"È": { key: "KeyE", shift: true, accentKey: keyGrave },
|
||||
"Ẽ": { key: "KeyE", shift: true, accentKey: keyTilde },
|
||||
F: { key: "KeyF", shift: true },
|
||||
G: { key: "KeyG", shift: true },
|
||||
H: { key: "KeyH", shift: true },
|
||||
I: { key: "KeyI", shift: true },
|
||||
"Ï": { key: "KeyI", shift: true, accentKey: keyTrema },
|
||||
"Í": { key: "KeyI", shift: true, accentKey: keyAcute },
|
||||
"Î": { key: "KeyI", shift: true, accentKey: keyHat },
|
||||
"Ì": { key: "KeyI", shift: true, accentKey: keyGrave },
|
||||
"Ĩ": { key: "KeyI", shift: true, accentKey: keyTilde },
|
||||
J: { key: "KeyJ", shift: true },
|
||||
K: { key: "KeyK", shift: true },
|
||||
L: { key: "KeyL", shift: true },
|
||||
M: { key: "KeyM", shift: true },
|
||||
N: { key: "KeyN", shift: true },
|
||||
O: { key: "KeyO", shift: true },
|
||||
"Ö": { key: "KeyO", shift: true, accentKey: keyTrema },
|
||||
"Ó": { key: "KeyO", shift: true, accentKey: keyAcute },
|
||||
"Ô": { key: "KeyO", shift: true, accentKey: keyHat },
|
||||
"Ò": { key: "KeyO", shift: true, accentKey: keyGrave },
|
||||
"Õ": { key: "KeyO", shift: true, accentKey: keyTilde },
|
||||
P: { key: "KeyP", shift: true },
|
||||
Q: { key: "KeyQ", shift: true },
|
||||
R: { key: "KeyR", shift: true },
|
||||
S: { key: "KeyS", shift: true },
|
||||
T: { key: "KeyT", shift: true },
|
||||
U: { key: "KeyU", shift: true },
|
||||
"Ü": { key: "KeyU", shift: true, accentKey: keyTrema },
|
||||
"Ú": { key: "KeyU", shift: true, accentKey: keyAcute },
|
||||
"Û": { key: "KeyU", shift: true, accentKey: keyHat },
|
||||
"Ù": { key: "KeyU", shift: true, accentKey: keyGrave },
|
||||
"Ũ": { key: "KeyU", shift: true, accentKey: keyTilde },
|
||||
V: { key: "KeyV", shift: true },
|
||||
W: { key: "KeyW", shift: true },
|
||||
X: { key: "KeyX", shift: true },
|
||||
Y: { key: "KeyZ", shift: true },
|
||||
Z: { key: "KeyY", shift: true },
|
||||
a: { key: "KeyA" },
|
||||
"á": { key: "KeyA", accentKey: keyAcute },
|
||||
"â": { key: "KeyA", accentKey: keyHat },
|
||||
"ã": { key: "KeyA", accentKey: keyTilde },
|
||||
b: { key: "KeyB" },
|
||||
c: { key: "KeyC" },
|
||||
d: { key: "KeyD" },
|
||||
e: { key: "KeyE" },
|
||||
"ë": { key: "KeyE", accentKey: keyTrema },
|
||||
"ê": { key: "KeyE", accentKey: keyHat },
|
||||
"ẽ": { key: "KeyE", accentKey: keyTilde },
|
||||
"€": { key: "KeyE", altRight: true },
|
||||
f: { key: "KeyF" },
|
||||
g: { key: "KeyG" },
|
||||
h: { key: "KeyH" },
|
||||
i: { key: "KeyI" },
|
||||
"ï": { key: "KeyI", accentKey: keyTrema },
|
||||
"í": { key: "KeyI", accentKey: keyAcute },
|
||||
"î": { key: "KeyI", accentKey: keyHat },
|
||||
"ì": { key: "KeyI", accentKey: keyGrave },
|
||||
"ĩ": { key: "KeyI", accentKey: keyTilde },
|
||||
j: { key: "KeyJ" },
|
||||
k: { key: "KeyK" },
|
||||
l: { key: "KeyL" },
|
||||
m: { key: "KeyM" },
|
||||
n: { key: "KeyN" },
|
||||
o: { key: "KeyO" },
|
||||
"ó": { key: "KeyO", accentKey: keyAcute },
|
||||
"ô": { key: "KeyO", accentKey: keyHat },
|
||||
"ò": { key: "KeyO", accentKey: keyGrave },
|
||||
"õ": { key: "KeyO", accentKey: keyTilde },
|
||||
p: { key: "KeyP" },
|
||||
q: { key: "KeyQ" },
|
||||
r: { key: "KeyR" },
|
||||
s: { key: "KeyS" },
|
||||
t: { key: "KeyT" },
|
||||
u: { key: "KeyU" },
|
||||
"ú": { key: "KeyU", accentKey: keyAcute },
|
||||
"û": { key: "KeyU", accentKey: keyHat },
|
||||
"ù": { key: "KeyU", accentKey: keyGrave },
|
||||
"ũ": { key: "KeyU", accentKey: keyTilde },
|
||||
v: { key: "KeyV" },
|
||||
w: { key: "KeyW" },
|
||||
x: { key: "KeyX" },
|
||||
y: { key: "KeyZ" },
|
||||
z: { key: "KeyY" },
|
||||
"§": { key: "Backquote" },
|
||||
"°": { key: "Backquote", shift: true },
|
||||
1: { key: "Digit1" },
|
||||
"+": { key: "Digit1", shift: true },
|
||||
"|": { key: "Digit1", altRight: true },
|
||||
2: { key: "Digit2" },
|
||||
"\"": { key: "Digit2", shift: true },
|
||||
"@": { key: "Digit2", altRight: true },
|
||||
3: { key: "Digit3" },
|
||||
"*": { key: "Digit3", shift: true },
|
||||
"#": { key: "Digit3", altRight: true },
|
||||
4: { key: "Digit4" },
|
||||
"ç": { key: "Digit4", shift: true },
|
||||
5: { key: "Digit5" },
|
||||
"%": { key: "Digit5", shift: true },
|
||||
6: { key: "Digit6" },
|
||||
"&": { key: "Digit6", shift: true },
|
||||
7: { key: "Digit7" },
|
||||
"/": { key: "Digit7", shift: true },
|
||||
8: { key: "Digit8" },
|
||||
"(": { key: "Digit8", shift: true },
|
||||
9: { key: "Digit9" },
|
||||
")": { key: "Digit9", shift: true },
|
||||
0: { key: "Digit0" },
|
||||
"=": { key: "Digit0", shift: true },
|
||||
"'": { key: "Minus" },
|
||||
"?": { key: "Minus", shift: true },
|
||||
"^": { key: "Equal", deadKey: true },
|
||||
"`": { key: "Equal", shift: true },
|
||||
"~": { key: "Equal", altRight: true, deadKey: true },
|
||||
"ü": { key: "BracketLeft" },
|
||||
"è": { key: "BracketLeft", shift: true },
|
||||
"[": { key: "BracketLeft", altRight: true },
|
||||
"!": { key: "BracketRight", shift: true },
|
||||
"]": { key: "BracketRight", altRight: true },
|
||||
"ö": { key: "Semicolon" },
|
||||
"é": { key: "Semicolon", shift: true },
|
||||
"ä": { key: "Quote" },
|
||||
"à": { key: "Quote", shift: true },
|
||||
"{": { key: "Quote", altRight: true },
|
||||
"$": { key: "Backslash" },
|
||||
"£": { key: "Backslash", shift: true },
|
||||
"}": { key: "Backslash", altRight: true },
|
||||
",": { key: "Comma" },
|
||||
";": { key: "Comma", shift: true },
|
||||
".": { key: "Period" },
|
||||
":": { key: "Period", shift: true },
|
||||
"-": { key: "Slash" },
|
||||
"_": { key: "Slash", shift: true },
|
||||
"<": { key: "IntlBackslash" },
|
||||
">": { key: "IntlBackslash", shift: true },
|
||||
"\\": { key: "IntlBackslash", altRight: true },
|
||||
" ": { key: "Space" },
|
||||
"\n": { key: "Enter" },
|
||||
Enter: { key: "Enter" },
|
||||
Tab: { key: "Tab" },
|
||||
} as Record<string, KeyCombo>;
|
|
@ -0,0 +1,152 @@
|
|||
import { KeyCombo } from "../keyboardLayouts"
|
||||
|
||||
export const name = "Deutsch";
|
||||
|
||||
const keyAcute = { key: "Equal" } // accent aigu (acute accent), mark ´ placed above the letter
|
||||
const keyHat = { key: "Backquote" } // accent circonflexe (accent hat), mark ^ placed above the letter
|
||||
const keyGrave = { key: "Equal", shift: true } // accent grave, mark ` placed above the letter
|
||||
|
||||
export const chars = {
|
||||
A: { key: "KeyA", shift: true },
|
||||
"Á": { key: "KeyA", shift: true, accentKey: keyAcute },
|
||||
"Â": { key: "KeyA", shift: true, accentKey: keyHat },
|
||||
"À": { key: "KeyA", shift: true, accentKey: keyGrave },
|
||||
B: { key: "KeyB", shift: true },
|
||||
C: { key: "KeyC", shift: true },
|
||||
D: { key: "KeyD", shift: true },
|
||||
E: { key: "KeyE", shift: true },
|
||||
"É": { key: "KeyE", shift: true, accentKey: keyAcute },
|
||||
"Ê": { key: "KeyE", shift: true, accentKey: keyHat },
|
||||
"È": { key: "KeyE", shift: true, accentKey: keyGrave },
|
||||
F: { key: "KeyF", shift: true },
|
||||
G: { key: "KeyG", shift: true },
|
||||
H: { key: "KeyH", shift: true },
|
||||
I: { key: "KeyI", shift: true },
|
||||
"Í": { key: "KeyI", shift: true, accentKey: keyAcute },
|
||||
"Î": { key: "KeyI", shift: true, accentKey: keyHat },
|
||||
"Ì": { key: "KeyI", shift: true, accentKey: keyGrave },
|
||||
J: { key: "KeyJ", shift: true },
|
||||
K: { key: "KeyK", shift: true },
|
||||
L: { key: "KeyL", shift: true },
|
||||
M: { key: "KeyM", shift: true },
|
||||
N: { key: "KeyN", shift: true },
|
||||
O: { key: "KeyO", shift: true },
|
||||
"Ó": { key: "KeyO", shift: true, accentKey: keyAcute },
|
||||
"Ô": { key: "KeyO", shift: true, accentKey: keyHat },
|
||||
"Ò": { key: "KeyO", shift: true, accentKey: keyGrave },
|
||||
P: { key: "KeyP", shift: true },
|
||||
Q: { key: "KeyQ", shift: true },
|
||||
R: { key: "KeyR", shift: true },
|
||||
S: { key: "KeyS", shift: true },
|
||||
T: { key: "KeyT", shift: true },
|
||||
U: { key: "KeyU", shift: true },
|
||||
"Ú": { key: "KeyU", shift: true, accentKey: keyAcute },
|
||||
"Û": { key: "KeyU", shift: true, accentKey: keyHat },
|
||||
"Ù": { key: "KeyU", shift: true, accentKey: keyGrave },
|
||||
V: { key: "KeyV", shift: true },
|
||||
W: { key: "KeyW", shift: true },
|
||||
X: { key: "KeyX", shift: true },
|
||||
Y: { key: "KeyZ", shift: true },
|
||||
Z: { key: "KeyY", shift: true },
|
||||
a: { key: "KeyA" },
|
||||
"á": { key: "KeyA", accentKey: keyAcute },
|
||||
"â": { key: "KeyA", accentKey: keyHat },
|
||||
"à": { key: "KeyA", accentKey: keyGrave},
|
||||
b: { key: "KeyB" },
|
||||
c: { key: "KeyC" },
|
||||
d: { key: "KeyD" },
|
||||
e: { key: "KeyE" },
|
||||
"é": { key: "KeyE", accentKey: keyAcute},
|
||||
"ê": { key: "KeyE", accentKey: keyHat },
|
||||
"è": { key: "KeyE", accentKey: keyGrave },
|
||||
"€": { key: "KeyE", altRight: true },
|
||||
f: { key: "KeyF" },
|
||||
g: { key: "KeyG" },
|
||||
h: { key: "KeyH" },
|
||||
i: { key: "KeyI" },
|
||||
"í": { key: "KeyI", accentKey: keyAcute },
|
||||
"î": { key: "KeyI", accentKey: keyHat },
|
||||
"ì": { key: "KeyI", accentKey: keyGrave },
|
||||
j: { key: "KeyJ" },
|
||||
k: { key: "KeyK" },
|
||||
l: { key: "KeyL" },
|
||||
m: { key: "KeyM" },
|
||||
"µ": { key: "KeyM", altRight: true },
|
||||
n: { key: "KeyN" },
|
||||
o: { key: "KeyO" },
|
||||
"ó": { key: "KeyO", accentKey: keyAcute },
|
||||
"ô": { key: "KeyO", accentKey: keyHat },
|
||||
"ò": { key: "KeyO", accentKey: keyGrave },
|
||||
p: { key: "KeyP" },
|
||||
q: { key: "KeyQ" },
|
||||
"@": { key: "KeyQ", altRight: true },
|
||||
r: { key: "KeyR" },
|
||||
s: { key: "KeyS" },
|
||||
t: { key: "KeyT" },
|
||||
u: { key: "KeyU" },
|
||||
"ú": { key: "KeyU", accentKey: keyAcute },
|
||||
"û": { key: "KeyU", accentKey: keyHat },
|
||||
"ù": { key: "KeyU", accentKey: keyGrave },
|
||||
v: { key: "KeyV" },
|
||||
w: { key: "KeyW" },
|
||||
x: { key: "KeyX" },
|
||||
y: { key: "KeyZ" },
|
||||
z: { key: "KeyY" },
|
||||
"°": { key: "Backquote", shift: true },
|
||||
"^": { key: "Backquote", deadKey: true },
|
||||
1: { key: "Digit1" },
|
||||
"!": { key: "Digit1", shift: true },
|
||||
2: { key: "Digit2" },
|
||||
"\"": { key: "Digit2", shift: true },
|
||||
"²": { key: "Digit2", altRight: true },
|
||||
3: { key: "Digit3" },
|
||||
"§": { key: "Digit3", shift: true },
|
||||
"³": { key: "Digit3", altRight: true },
|
||||
4: { key: "Digit4" },
|
||||
"$": { key: "Digit4", shift: true },
|
||||
5: { key: "Digit5" },
|
||||
"%": { key: "Digit5", shift: true },
|
||||
6: { key: "Digit6" },
|
||||
"&": { key: "Digit6", shift: true },
|
||||
7: { key: "Digit7" },
|
||||
"/": { key: "Digit7", shift: true },
|
||||
"{": { key: "Digit7", altRight: true },
|
||||
8: { key: "Digit8" },
|
||||
"(": { key: "Digit8", shift: true },
|
||||
"[": { key: "Digit8", altRight: true },
|
||||
9: { key: "Digit9" },
|
||||
")": { key: "Digit9", shift: true },
|
||||
"]": { key: "Digit9", altRight: true },
|
||||
0: { key: "Digit0" },
|
||||
"=": { key: "Digit0", shift: true },
|
||||
"}": { key: "Digit0", altRight: true },
|
||||
"ß": { key: "Minus" },
|
||||
"?": { key: "Minus", shift: true },
|
||||
"\\": { key: "Minus", altRight: true },
|
||||
"´": { key: "Equal", deadKey: true },
|
||||
"`": { key: "Equal", shift: true, deadKey: true },
|
||||
"ü": { key: "BracketLeft" },
|
||||
"Ü": { key: "BracketLeft", shift: true },
|
||||
"+": { key: "BracketRight" },
|
||||
"*": { key: "BracketRight", shift: true },
|
||||
"~": { key: "BracketRight", altRight: true },
|
||||
"ö": { key: "Semicolon" },
|
||||
"Ö": { key: "Semicolon", shift: true },
|
||||
"ä": { key: "Quote" },
|
||||
"Ä": { key: "Quote", shift: true },
|
||||
"#": { key: "Backslash" },
|
||||
"'": { key: "Backslash", shift: true },
|
||||
",": { key: "Comma" },
|
||||
";": { key: "Comma", shift: true },
|
||||
".": { key: "Period" },
|
||||
":": { key: "Period", shift: true },
|
||||
"-": { key: "Slash" },
|
||||
"_": { key: "Slash", shift: true },
|
||||
"<": { key: "IntlBackslash" },
|
||||
">": { key: "IntlBackslash", shift: true },
|
||||
"|": { key: "IntlBackslash", altRight: true },
|
||||
" ": { key: "Space" },
|
||||
"\n": { key: "Enter" },
|
||||
Enter: { key: "Enter" },
|
||||
Tab: { key: "Tab" },
|
||||
} as Record<string, KeyCombo>;
|
|
@ -0,0 +1,107 @@
|
|||
import { KeyCombo } from "../keyboardLayouts"
|
||||
|
||||
export const name = "English (UK)";
|
||||
|
||||
export const chars = {
|
||||
A: { key: "KeyA", shift: true },
|
||||
B: { key: "KeyB", shift: true },
|
||||
C: { key: "KeyC", shift: true },
|
||||
D: { key: "KeyD", shift: true },
|
||||
E: { key: "KeyE", shift: true },
|
||||
F: { key: "KeyF", shift: true },
|
||||
G: { key: "KeyG", shift: true },
|
||||
H: { key: "KeyH", shift: true },
|
||||
I: { key: "KeyI", shift: true },
|
||||
J: { key: "KeyJ", shift: true },
|
||||
K: { key: "KeyK", shift: true },
|
||||
L: { key: "KeyL", shift: true },
|
||||
M: { key: "KeyM", shift: true },
|
||||
N: { key: "KeyN", shift: true },
|
||||
O: { key: "KeyO", shift: true },
|
||||
P: { key: "KeyP", shift: true },
|
||||
Q: { key: "KeyQ", shift: true },
|
||||
R: { key: "KeyR", shift: true },
|
||||
S: { key: "KeyS", shift: true },
|
||||
T: { key: "KeyT", shift: true },
|
||||
U: { key: "KeyU", shift: true },
|
||||
V: { key: "KeyV", shift: true },
|
||||
W: { key: "KeyW", shift: true },
|
||||
X: { key: "KeyX", shift: true },
|
||||
Y: { key: "KeyY", shift: true },
|
||||
Z: { key: "KeyZ", shift: true },
|
||||
a: { key: "KeyA" },
|
||||
b: { key: "KeyB" },
|
||||
c: { key: "KeyC" },
|
||||
d: { key: "KeyD" },
|
||||
e: { key: "KeyE" },
|
||||
f: { key: "KeyF" },
|
||||
g: { key: "KeyG" },
|
||||
h: { key: "KeyH" },
|
||||
i: { key: "KeyI" },
|
||||
j: { key: "KeyJ" },
|
||||
k: { key: "KeyK" },
|
||||
l: { key: "KeyL" },
|
||||
m: { key: "KeyM" },
|
||||
n: { key: "KeyN" },
|
||||
o: { key: "KeyO" },
|
||||
p: { key: "KeyP" },
|
||||
q: { key: "KeyQ" },
|
||||
r: { key: "KeyR" },
|
||||
s: { key: "KeyS" },
|
||||
t: { key: "KeyT" },
|
||||
u: { key: "KeyU" },
|
||||
v: { key: "KeyV" },
|
||||
w: { key: "KeyW" },
|
||||
x: { key: "KeyX" },
|
||||
y: { key: "KeyY" },
|
||||
z: { key: "KeyZ" },
|
||||
1: { key: "Digit1" },
|
||||
"!": { key: "Digit1", shift: true },
|
||||
2: { key: "Digit2" },
|
||||
"\"": { key: "Digit2", shift: true },
|
||||
3: { key: "Digit3" },
|
||||
"£": { key: "Digit3", shift: true },
|
||||
4: { key: "Digit4" },
|
||||
$: { key: "Digit4", shift: true },
|
||||
"€": { key: "Digit4", altRight: true },
|
||||
5: { key: "Digit5" },
|
||||
"%": { key: "Digit5", shift: true },
|
||||
6: { key: "Digit6" },
|
||||
"^": { key: "Digit6", shift: true },
|
||||
7: { key: "Digit7" },
|
||||
"&": { key: "Digit7", shift: true },
|
||||
8: { key: "Digit8" },
|
||||
"*": { key: "Digit8", shift: true },
|
||||
9: { key: "Digit9" },
|
||||
"(": { key: "Digit9", shift: true },
|
||||
0: { key: "Digit0" },
|
||||
")": { key: "Digit0", shift: true },
|
||||
"-": { key: "Minus" },
|
||||
_: { key: "Minus", shift: true },
|
||||
"=": { key: "Equal" },
|
||||
"+": { key: "Equal", shift: true },
|
||||
"'": { key: "Quote" },
|
||||
'@': { key: "Quote", shift: true },
|
||||
",": { key: "Comma" },
|
||||
"<": { key: "Comma", shift: true },
|
||||
"/": { key: "Slash" },
|
||||
"?": { key: "Slash", shift: true },
|
||||
".": { key: "Period" },
|
||||
">": { key: "Period", shift: true },
|
||||
";": { key: "Semicolon" },
|
||||
":": { key: "Semicolon", shift: true },
|
||||
"[": { key: "BracketLeft" },
|
||||
"{": { key: "BracketLeft", shift: true },
|
||||
"]": { key: "BracketRight" },
|
||||
"}": { key: "BracketRight", shift: true },
|
||||
"#": { key: "Backslash" },
|
||||
"~": { key: "Backslash", shift: true },
|
||||
"`": { key: "Backquote" },
|
||||
"¬": { key: "Backquote", shift: true },
|
||||
"\\": { key: "IntlBackslash" },
|
||||
"|": { key: "IntlBackslash", shift: true },
|
||||
" ": { key: "Space" },
|
||||
"\n": { key: "Enter" },
|
||||
Enter: { key: "Enter" },
|
||||
Tab: { key: "Tab" },
|
||||
} as Record<string, KeyCombo>
|
|
@ -0,0 +1,113 @@
|
|||
import { KeyCombo } from "../keyboardLayouts"
|
||||
|
||||
export const name = "English (US)";
|
||||
|
||||
export const chars = {
|
||||
A: { key: "KeyA", shift: true },
|
||||
B: { key: "KeyB", shift: true },
|
||||
C: { key: "KeyC", shift: true },
|
||||
D: { key: "KeyD", shift: true },
|
||||
E: { key: "KeyE", shift: true },
|
||||
F: { key: "KeyF", shift: true },
|
||||
G: { key: "KeyG", shift: true },
|
||||
H: { key: "KeyH", shift: true },
|
||||
I: { key: "KeyI", shift: true },
|
||||
J: { key: "KeyJ", shift: true },
|
||||
K: { key: "KeyK", shift: true },
|
||||
L: { key: "KeyL", shift: true },
|
||||
M: { key: "KeyM", shift: true },
|
||||
N: { key: "KeyN", shift: true },
|
||||
O: { key: "KeyO", shift: true },
|
||||
P: { key: "KeyP", shift: true },
|
||||
Q: { key: "KeyQ", shift: true },
|
||||
R: { key: "KeyR", shift: true },
|
||||
S: { key: "KeyS", shift: true },
|
||||
T: { key: "KeyT", shift: true },
|
||||
U: { key: "KeyU", shift: true },
|
||||
V: { key: "KeyV", shift: true },
|
||||
W: { key: "KeyW", shift: true },
|
||||
X: { key: "KeyX", shift: true },
|
||||
Y: { key: "KeyY", shift: true },
|
||||
Z: { key: "KeyZ", shift: true },
|
||||
a: { key: "KeyA" },
|
||||
b: { key: "KeyB" },
|
||||
c: { key: "KeyC" },
|
||||
d: { key: "KeyD" },
|
||||
e: { key: "KeyE" },
|
||||
f: { key: "KeyF" },
|
||||
g: { key: "KeyG" },
|
||||
h: { key: "KeyH" },
|
||||
i: { key: "KeyI" },
|
||||
j: { key: "KeyJ" },
|
||||
k: { key: "KeyK" },
|
||||
l: { key: "KeyL" },
|
||||
m: { key: "KeyM" },
|
||||
n: { key: "KeyN" },
|
||||
o: { key: "KeyO" },
|
||||
p: { key: "KeyP" },
|
||||
q: { key: "KeyQ" },
|
||||
r: { key: "KeyR" },
|
||||
s: { key: "KeyS" },
|
||||
t: { key: "KeyT" },
|
||||
u: { key: "KeyU" },
|
||||
v: { key: "KeyV" },
|
||||
w: { key: "KeyW" },
|
||||
x: { key: "KeyX" },
|
||||
y: { key: "KeyY" },
|
||||
z: { key: "KeyZ" },
|
||||
1: { key: "Digit1" },
|
||||
"!": { key: "Digit1", shift: true },
|
||||
2: { key: "Digit2" },
|
||||
"@": { key: "Digit2", shift: true },
|
||||
3: { key: "Digit3" },
|
||||
"#": { key: "Digit3", shift: true },
|
||||
4: { key: "Digit4" },
|
||||
$: { key: "Digit4", shift: true },
|
||||
"%": { key: "Digit5", shift: true },
|
||||
5: { key: "Digit5" },
|
||||
"^": { key: "Digit6", shift: true },
|
||||
6: { key: "Digit6" },
|
||||
"&": { key: "Digit7", shift: true },
|
||||
7: { key: "Digit7" },
|
||||
"*": { key: "Digit8", shift: true },
|
||||
8: { key: "Digit8" },
|
||||
"(": { key: "Digit9", shift: true },
|
||||
9: { key: "Digit9" },
|
||||
")": { key: "Digit0", shift: true },
|
||||
0: { key: "Digit0" },
|
||||
"-": { key: "Minus" },
|
||||
_: { key: "Minus", shift: true },
|
||||
"=": { key: "Equal" },
|
||||
"+": { key: "Equal", shift: true },
|
||||
"'": { key: "Quote" },
|
||||
'"': { key: "Quote", shift: true },
|
||||
",": { key: "Comma" },
|
||||
"<": { key: "Comma", shift: true },
|
||||
"/": { key: "Slash" },
|
||||
"?": { key: "Slash", shift: true },
|
||||
".": { key: "Period" },
|
||||
">": { key: "Period", shift: true },
|
||||
";": { key: "Semicolon" },
|
||||
":": { key: "Semicolon", shift: true },
|
||||
"[": { key: "BracketLeft" },
|
||||
"{": { key: "BracketLeft", shift: true },
|
||||
"]": { key: "BracketRight" },
|
||||
"}": { key: "BracketRight", shift: true },
|
||||
"\\": { key: "Backslash" },
|
||||
"|": { key: "Backslash", shift: true },
|
||||
"`": { key: "Backquote" },
|
||||
"~": { key: "Backquote", shift: true },
|
||||
"§": { key: "IntlBackslash" },
|
||||
"±": { key: "IntlBackslash", shift: true },
|
||||
" ": { key: "Space", shift: false },
|
||||
"\n": { key: "Enter", shift: false },
|
||||
Enter: { key: "Enter", shift: false },
|
||||
Tab: { key: "Tab", shift: false },
|
||||
PrintScreen: { key: "Prt Sc", shift: false },
|
||||
SystemRequest: { key: "Prt Sc", shift: true },
|
||||
ScrollLock: { key: "ScrollLock", shift: false},
|
||||
Pause: { key: "Pause", shift: false },
|
||||
Break: { key: "Pause", shift: true },
|
||||
Insert: { key: "Insert", shift: false },
|
||||
Delete: { key: "Delete", shift: false },
|
||||
} as Record<string, KeyCombo>
|
|
@ -0,0 +1,168 @@
|
|||
import { KeyCombo } from "../keyboardLayouts"
|
||||
|
||||
export const name = "Español";
|
||||
|
||||
const keyTrema = { key: "Quote", shift: true } // tréma (umlaut), two dots placed above a vowel
|
||||
const keyAcute = { key: "Quote" } // accent aigu (acute accent), mark ´ placed above the letter
|
||||
const keyHat = { key: "BracketRight", shift: true } // accent circonflexe (accent hat), mark ^ placed above the letter
|
||||
const keyGrave = { key: "BracketRight" } // accent grave, mark ` placed above the letter
|
||||
const keyTilde = { key: "Key4", altRight: true } // tilde, mark ~ placed above the letter
|
||||
|
||||
export const chars = {
|
||||
A: { key: "KeyA", shift: true },
|
||||
"Ä": { key: "KeyA", shift: true, accentKey: keyTrema },
|
||||
"Á": { key: "KeyA", shift: true, accentKey: keyAcute },
|
||||
"Â": { key: "KeyA", shift: true, accentKey: keyHat },
|
||||
"À": { key: "KeyA", shift: true, accentKey: keyGrave },
|
||||
"Ã": { key: "KeyA", shift: true, accentKey: keyTilde },
|
||||
B: { key: "KeyB", shift: true },
|
||||
C: { key: "KeyC", shift: true },
|
||||
D: { key: "KeyD", shift: true },
|
||||
E: { key: "KeyE", shift: true },
|
||||
"Ë": { key: "KeyE", shift: true, accentKey: keyTrema },
|
||||
"É": { key: "KeyE", shift: true, accentKey: keyAcute },
|
||||
"Ê": { key: "KeyE", shift: true, accentKey: keyHat },
|
||||
"È": { key: "KeyE", shift: true, accentKey: keyGrave },
|
||||
"Ẽ": { key: "KeyE", shift: true, accentKey: keyTilde },
|
||||
F: { key: "KeyF", shift: true },
|
||||
G: { key: "KeyG", shift: true },
|
||||
H: { key: "KeyH", shift: true },
|
||||
I: { key: "KeyI", shift: true },
|
||||
"Ï": { key: "KeyI", shift: true, accentKey: keyTrema },
|
||||
"Í": { key: "KeyI", shift: true, accentKey: keyAcute },
|
||||
"Î": { key: "KeyI", shift: true, accentKey: keyHat },
|
||||
"Ì": { key: "KeyI", shift: true, accentKey: keyGrave },
|
||||
"Ĩ": { key: "KeyI", shift: true, accentKey: keyTilde },
|
||||
J: { key: "KeyJ", shift: true },
|
||||
K: { key: "KeyK", shift: true },
|
||||
L: { key: "KeyL", shift: true },
|
||||
M: { key: "KeyM", shift: true },
|
||||
N: { key: "KeyN", shift: true },
|
||||
O: { key: "KeyO", shift: true },
|
||||
"Ö": { key: "KeyO", shift: true, accentKey: keyTrema },
|
||||
"Ó": { key: "KeyO", shift: true, accentKey: keyAcute },
|
||||
"Ô": { key: "KeyO", shift: true, accentKey: keyHat },
|
||||
"Ò": { key: "KeyO", shift: true, accentKey: keyGrave },
|
||||
"Õ": { key: "KeyO", shift: true, accentKey: keyTilde },
|
||||
P: { key: "KeyP", shift: true },
|
||||
Q: { key: "KeyQ", shift: true },
|
||||
R: { key: "KeyR", shift: true },
|
||||
S: { key: "KeyS", shift: true },
|
||||
T: { key: "KeyT", shift: true },
|
||||
U: { key: "KeyU", shift: true },
|
||||
"Ü": { key: "KeyU", shift: true, accentKey: keyTrema },
|
||||
"Ú": { key: "KeyU", shift: true, accentKey: keyAcute },
|
||||
"Û": { key: "KeyU", shift: true, accentKey: keyHat },
|
||||
"Ù": { key: "KeyU", shift: true, accentKey: keyGrave },
|
||||
"Ũ": { key: "KeyU", shift: true, accentKey: keyTilde },
|
||||
V: { key: "KeyV", shift: true },
|
||||
W: { key: "KeyW", shift: true },
|
||||
X: { key: "KeyX", shift: true },
|
||||
Y: { key: "KeyY", shift: true },
|
||||
Z: { key: "KeyZ", shift: true },
|
||||
a: { key: "KeyA" },
|
||||
"ä": { key: "KeyA", accentKey: keyTrema },
|
||||
"á": { key: "KeyA", accentKey: keyAcute },
|
||||
"â": { key: "KeyA", accentKey: keyHat },
|
||||
"à": { key: "KeyA", accentKey: keyGrave },
|
||||
"ã": { key: "KeyA", accentKey: keyTilde },
|
||||
b: { key: "KeyB" },
|
||||
c: { key: "KeyC" },
|
||||
d: { key: "KeyD" },
|
||||
e: { key: "KeyE" },
|
||||
"ë": { key: "KeyE", accentKey: keyTrema },
|
||||
"é": { key: "KeyE", accentKey: keyAcute },
|
||||
"ê": { key: "KeyE", accentKey: keyHat },
|
||||
"è": { key: "KeyE", accentKey: keyGrave },
|
||||
"ẽ": { key: "KeyE", accentKey: keyTilde },
|
||||
"€": { key: "KeyE", altRight: true },
|
||||
f: { key: "KeyF" },
|
||||
g: { key: "KeyG" },
|
||||
h: { key: "KeyH" },
|
||||
i: { key: "KeyI" },
|
||||
"ï": { key: "KeyI", accentKey: keyTrema },
|
||||
"í": { key: "KeyI", accentKey: keyAcute },
|
||||
"î": { key: "KeyI", accentKey: keyHat },
|
||||
"ì": { key: "KeyI", accentKey: keyGrave },
|
||||
"ĩ": { key: "KeyI", accentKey: keyTilde },
|
||||
j: { key: "KeyJ" },
|
||||
k: { key: "KeyK" },
|
||||
l: { key: "KeyL" },
|
||||
m: { key: "KeyM" },
|
||||
n: { key: "KeyN" },
|
||||
o: { key: "KeyO" },
|
||||
"ö": { key: "KeyO", accentKey: keyTrema },
|
||||
"ó": { key: "KeyO", accentKey: keyAcute },
|
||||
"ô": { key: "KeyO", accentKey: keyHat },
|
||||
"ò": { key: "KeyO", accentKey: keyGrave },
|
||||
"õ": { key: "KeyO", accentKey: keyTilde },
|
||||
p: { key: "KeyP" },
|
||||
q: { key: "KeyQ" },
|
||||
r: { key: "KeyR" },
|
||||
s: { key: "KeyS" },
|
||||
t: { key: "KeyT" },
|
||||
u: { key: "KeyU" },
|
||||
"ü": { key: "KeyU", accentKey: keyTrema },
|
||||
"ú": { key: "KeyU", accentKey: keyAcute },
|
||||
"û": { key: "KeyU", accentKey: keyHat },
|
||||
"ù": { key: "KeyU", accentKey: keyGrave },
|
||||
"ũ": { key: "KeyU", accentKey: keyTilde },
|
||||
v: { key: "KeyV" },
|
||||
w: { key: "KeyW" },
|
||||
x: { key: "KeyX" },
|
||||
y: { key: "KeyY" },
|
||||
z: { key: "KeyZ" },
|
||||
"º": { key: "Backquote" },
|
||||
"ª": { key: "Backquote", shift: true },
|
||||
"\\": { key: "Backquote", altRight: true },
|
||||
1: { key: "Digit1" },
|
||||
"!": { key: "Digit1", shift: true },
|
||||
"|": { key: "Digit1", altRight: true },
|
||||
2: { key: "Digit2" },
|
||||
"\"": { key: "Digit2", shift: true },
|
||||
"@": { key: "Digit2", altRight: true },
|
||||
3: { key: "Digit3" },
|
||||
"·": { key: "Digit3", shift: true },
|
||||
"#": { key: "Digit3", altRight: true },
|
||||
4: { key: "Digit4" },
|
||||
"$": { key: "Digit4", shift: true },
|
||||
5: { key: "Digit5" },
|
||||
"%": { key: "Digit5", shift: true },
|
||||
6: { key: "Digit6" },
|
||||
"&": { key: "Digit6", shift: true },
|
||||
"¬": { key: "Digit6", altRight: true },
|
||||
7: { key: "Digit7" },
|
||||
"/": { key: "Digit7", shift: true },
|
||||
8: { key: "Digit8" },
|
||||
"(": { key: "Digit8", shift: true },
|
||||
9: { key: "Digit9" },
|
||||
")": { key: "Digit9", shift: true },
|
||||
0: { key: "Digit0" },
|
||||
"=": { key: "Digit0", shift: true },
|
||||
"'": { key: "Minus" },
|
||||
"?": { key: "Minus", shift: true },
|
||||
"¡": { key: "Equal", deadKey: true },
|
||||
"¿": { key: "Equal", shift: true },
|
||||
"[": { key: "BracketLeft", altRight: true },
|
||||
"+": { key: "BracketRight" },
|
||||
"*": { key: "BracketRight", shift: true },
|
||||
"]": { key: "BracketRight", altRight: true },
|
||||
"ñ": { key: "Semicolon" },
|
||||
"Ñ": { key: "Semicolon", shift: true },
|
||||
"{": { key: "Quote", altRight: true },
|
||||
"ç": { key: "Backslash" },
|
||||
"Ç": { key: "Backslash", shift: true },
|
||||
"}": { key: "Backslash", altRight: true },
|
||||
",": { key: "Comma" },
|
||||
";": { key: "Comma", shift: true },
|
||||
".": { key: "Period" },
|
||||
":": { key: "Period", shift: true },
|
||||
"-": { key: "Slash" },
|
||||
"_": { key: "Slash", shift: true },
|
||||
"<": { key: "IntlBackslash" },
|
||||
">": { key: "IntlBackslash", shift: true },
|
||||
" ": { key: "Space" },
|
||||
"\n": { key: "Enter" },
|
||||
Enter: { key: "Enter" },
|
||||
Tab: { key: "Tab" },
|
||||
} as Record<string, KeyCombo>;
|
|
@ -0,0 +1,14 @@
|
|||
import { KeyCombo } from "../keyboardLayouts"
|
||||
import { chars as chars_de_CH } from "./de_CH"
|
||||
|
||||
export const name = "Français de Suisse";
|
||||
|
||||
export const chars = {
|
||||
...chars_de_CH,
|
||||
"è": { key: "BracketLeft" },
|
||||
"ü": { key: "BracketLeft", shift: true },
|
||||
"é": { key: "Semicolon" },
|
||||
"ö": { key: "Semicolon", shift: true },
|
||||
"à": { key: "Quote" },
|
||||
"ä": { key: "Quote", shift: true },
|
||||
} as Record<string, KeyCombo>;
|
|
@ -0,0 +1,139 @@
|
|||
import { KeyCombo } from "../keyboardLayouts"
|
||||
|
||||
export const name = "Français";
|
||||
|
||||
const keyTrema = { key: "BracketLeft", shift: true } // tréma (umlaut), two dots placed above a vowel
|
||||
const keyHat = { key: "BracketLeft" } // accent circonflexe (accent hat), mark ^ placed above the letter
|
||||
|
||||
export const chars = {
|
||||
A: { key: "KeyQ", shift: true },
|
||||
"Ä": { key: "KeyQ", shift: true, accentKey: keyTrema },
|
||||
"Â": { key: "KeyQ", shift: true, accentKey: keyHat },
|
||||
B: { key: "KeyB", shift: true },
|
||||
C: { key: "KeyC", shift: true },
|
||||
D: { key: "KeyD", shift: true },
|
||||
E: { key: "KeyE", shift: true },
|
||||
"Ë": { key: "KeyE", shift: true, accentKey: keyTrema },
|
||||
"Ê": { key: "KeyE", shift: true, accentKey: keyHat },
|
||||
F: { key: "KeyF", shift: true },
|
||||
G: { key: "KeyG", shift: true },
|
||||
H: { key: "KeyH", shift: true },
|
||||
I: { key: "KeyI", shift: true },
|
||||
"Ï": { key: "KeyI", shift: true, accentKey: keyTrema },
|
||||
"Î": { key: "KeyI", shift: true, accentKey: keyHat },
|
||||
J: { key: "KeyJ", shift: true },
|
||||
K: { key: "KeyK", shift: true },
|
||||
L: { key: "KeyL", shift: true },
|
||||
M: { key: "Semicolon", shift: true },
|
||||
N: { key: "KeyN", shift: true },
|
||||
O: { key: "KeyO", shift: true },
|
||||
"Ö": { key: "KeyO", shift: true, accentKey: keyTrema },
|
||||
"Ô": { key: "KeyO", shift: true, accentKey: keyHat },
|
||||
P: { key: "KeyP", shift: true },
|
||||
Q: { key: "KeyA", shift: true },
|
||||
R: { key: "KeyR", shift: true },
|
||||
S: { key: "KeyS", shift: true },
|
||||
T: { key: "KeyT", shift: true },
|
||||
U: { key: "KeyU", shift: true },
|
||||
"Ü": { key: "KeyU", shift: true, accentKey: keyTrema },
|
||||
"Û": { key: "KeyU", shift: true, accentKey: keyHat },
|
||||
V: { key: "KeyV", shift: true },
|
||||
W: { key: "KeyZ", shift: true },
|
||||
X: { key: "KeyX", shift: true },
|
||||
Y: { key: "KeyY", shift: true },
|
||||
Z: { key: "KeyW", shift: true },
|
||||
a: { key: "KeyQ" },
|
||||
"ä": { key: "KeyQ", accentKey: keyTrema },
|
||||
"â": { key: "KeyQ", accentKey: keyHat },
|
||||
b: { key: "KeyB" },
|
||||
c: { key: "KeyC" },
|
||||
d: { key: "KeyD" },
|
||||
e: { key: "KeyE" },
|
||||
"ë": { key: "KeyE", accentKey: keyTrema },
|
||||
"ê": { key: "KeyE", accentKey: keyHat },
|
||||
"€": { key: "KeyE", altRight: true },
|
||||
f: { key: "KeyF" },
|
||||
g: { key: "KeyG" },
|
||||
h: { key: "KeyH" },
|
||||
i: { key: "KeyI" },
|
||||
"ï": { key: "KeyI", accentKey: keyTrema },
|
||||
"î": { key: "KeyI", accentKey: keyHat },
|
||||
j: { key: "KeyJ" },
|
||||
k: { key: "KeyK" },
|
||||
l: { key: "KeyL" },
|
||||
m: { key: "Semicolon" },
|
||||
n: { key: "KeyN" },
|
||||
o: { key: "KeyO" },
|
||||
"ö": { key: "KeyO", accentKey: keyTrema },
|
||||
"ô": { key: "KeyO", accentKey: keyHat },
|
||||
p: { key: "KeyP" },
|
||||
q: { key: "KeyA" },
|
||||
r: { key: "KeyR" },
|
||||
s: { key: "KeyS" },
|
||||
t: { key: "KeyT" },
|
||||
u: { key: "KeyU" },
|
||||
"ü": { key: "KeyU", accentKey: keyTrema },
|
||||
"û": { key: "KeyU", accentKey: keyHat },
|
||||
v: { key: "KeyV" },
|
||||
w: { key: "KeyZ" },
|
||||
x: { key: "KeyX" },
|
||||
y: { key: "KeyY" },
|
||||
z: { key: "KeyW" },
|
||||
"²": { key: "Backquote" },
|
||||
"&": { key: "Digit1" },
|
||||
1: { key: "Digit1", shift: true },
|
||||
"é": { key: "Digit2" },
|
||||
2: { key: "Digit2", shift: true },
|
||||
"~": { key: "Digit2", altRight: true },
|
||||
"\"": { key: "Digit3" },
|
||||
3: { key: "Digit3", shift: true },
|
||||
"#": { key: "Digit3", altRight: true },
|
||||
"'": { key: "Digit4" },
|
||||
4: { key: "Digit4", shift: true },
|
||||
"{": { key: "Digit4", altRight: true },
|
||||
"(": { key: "Digit5" },
|
||||
5: { key: "Digit5", shift: true },
|
||||
"[": { key: "Digit5", altRight: true },
|
||||
"-": { key: "Digit6" },
|
||||
6: { key: "Digit6", shift: true },
|
||||
"|": { key: "Digit6", altRight: true },
|
||||
"è": { key: "Digit7" },
|
||||
7: { key: "Digit7", shift: true },
|
||||
"`": { key: "Digit7", altRight: true },
|
||||
"_": { key: "Digit8" },
|
||||
8: { key: "Digit8", shift: true },
|
||||
"\\": { key: "Digit8", altRight: true },
|
||||
"ç": { key: "Digit9" },
|
||||
9: { key: "Digit9", shift: true },
|
||||
"^": { key: "Digit9", altRight: true },
|
||||
"à": { key: "Digit0" },
|
||||
0: { key: "Digit0", shift: true },
|
||||
"@": { key: "Digit0", altRight: true },
|
||||
")": { key: "Minus" },
|
||||
"°": { key: "Minus", shift: true },
|
||||
"]": { key: "Minus", altRight: true },
|
||||
"=": { key: "Equal" },
|
||||
"+": { key: "Equal", shift: true },
|
||||
"}": { key: "Equal", altRight: true },
|
||||
"$": { key: "BracketRight" },
|
||||
"£": { key: "BracketRight", shift: true },
|
||||
"¤": { key: "BracketRight", altRight: true },
|
||||
"ù": { key: "Quote" },
|
||||
"%": { key: "Quote", shift: true },
|
||||
"*": { key: "Backslash" },
|
||||
"µ": { key: "Backslash", shift: true },
|
||||
",": { key: "KeyM" },
|
||||
"?": { key: "KeyM", shift: true },
|
||||
";": { key: "Comma" },
|
||||
".": { key: "Comma", shift: true },
|
||||
":": { key: "Period" },
|
||||
"/": { key: "Period", shift: true },
|
||||
"!": { key: "Slash" },
|
||||
"§": { key: "Slash", shift: true },
|
||||
"<": { key: "IntlBackslash" },
|
||||
">": { key: "IntlBackslash", shift: true },
|
||||
" ": { key: "Space" },
|
||||
"\n": { key: "Enter" },
|
||||
Enter: { key: "Enter" },
|
||||
Tab: { key: "Tab" },
|
||||
} as Record<string, KeyCombo>;
|
|
@ -0,0 +1,113 @@
|
|||
import { KeyCombo } from "../keyboardLayouts"
|
||||
|
||||
export const name = "Italiano";
|
||||
|
||||
export const chars = {
|
||||
A: { key: "KeyA", shift: true },
|
||||
B: { key: "KeyB", shift: true },
|
||||
C: { key: "KeyC", shift: true },
|
||||
D: { key: "KeyD", shift: true },
|
||||
E: { key: "KeyE", shift: true },
|
||||
F: { key: "KeyF", shift: true },
|
||||
G: { key: "KeyG", shift: true },
|
||||
H: { key: "KeyH", shift: true },
|
||||
I: { key: "KeyI", shift: true },
|
||||
J: { key: "KeyJ", shift: true },
|
||||
K: { key: "KeyK", shift: true },
|
||||
L: { key: "KeyL", shift: true },
|
||||
M: { key: "KeyM", shift: true },
|
||||
N: { key: "KeyN", shift: true },
|
||||
O: { key: "KeyO", shift: true },
|
||||
P: { key: "KeyP", shift: true },
|
||||
Q: { key: "KeyQ", shift: true },
|
||||
R: { key: "KeyR", shift: true },
|
||||
S: { key: "KeyS", shift: true },
|
||||
T: { key: "KeyT", shift: true },
|
||||
U: { key: "KeyU", shift: true },
|
||||
V: { key: "KeyV", shift: true },
|
||||
W: { key: "KeyW", shift: true },
|
||||
X: { key: "KeyX", shift: true },
|
||||
Y: { key: "KeyY", shift: true },
|
||||
Z: { key: "KeyZ", shift: true },
|
||||
a: { key: "KeyA" },
|
||||
b: { key: "KeyB" },
|
||||
c: { key: "KeyC" },
|
||||
d: { key: "KeyD" },
|
||||
e: { key: "KeyE" },
|
||||
"€": { key: "KeyE", altRight: true },
|
||||
f: { key: "KeyF" },
|
||||
g: { key: "KeyG" },
|
||||
h: { key: "KeyH" },
|
||||
i: { key: "KeyI" },
|
||||
j: { key: "KeyJ" },
|
||||
k: { key: "KeyK" },
|
||||
l: { key: "KeyL" },
|
||||
m: { key: "KeyM" },
|
||||
n: { key: "KeyN" },
|
||||
o: { key: "KeyO" },
|
||||
p: { key: "KeyP" },
|
||||
q: { key: "KeyQ" },
|
||||
r: { key: "KeyR" },
|
||||
s: { key: "KeyS" },
|
||||
t: { key: "KeyT" },
|
||||
u: { key: "KeyU" },
|
||||
v: { key: "KeyV" },
|
||||
w: { key: "KeyW" },
|
||||
x: { key: "KeyX" },
|
||||
y: { key: "KeyY" },
|
||||
z: { key: "KeyZ" },
|
||||
"\\": { key: "Backquote" },
|
||||
"|": { key: "Backquote", shift: true },
|
||||
1: { key: "Digit1" },
|
||||
"!": { key: "Digit1", shift: true },
|
||||
2: { key: "Digit2" },
|
||||
"\"": { key: "Digit2", shift: true },
|
||||
3: { key: "Digit3" },
|
||||
"£": { key: "Digit3", shift: true },
|
||||
4: { key: "Digit4" },
|
||||
"$": { key: "Digit4", shift: true },
|
||||
5: { key: "Digit5" },
|
||||
"%": { key: "Digit5", shift: true },
|
||||
6: { key: "Digit6" },
|
||||
"&": { key: "Digit6", shift: true },
|
||||
7: { key: "Digit7" },
|
||||
"/": { key: "Digit7", shift: true },
|
||||
8: { key: "Digit8" },
|
||||
"(": { key: "Digit8", shift: true },
|
||||
9: { key: "Digit9" },
|
||||
")": { key: "Digit9", shift: true },
|
||||
0: { key: "Digit0" },
|
||||
"=": { key: "Digit0", shift: true },
|
||||
"'": { key: "Minus" },
|
||||
"?": { key: "Minus", shift: true },
|
||||
"ì": { key: "Equal" },
|
||||
"^": { key: "Equal", shift: true },
|
||||
"è": { key: "BracketLeft" },
|
||||
"é": { key: "BracketLeft", shift: true },
|
||||
"[": { key: "BracketLeft", altRight: true },
|
||||
"{": { key: "BracketLeft", shift: true, altRight: true },
|
||||
"+": { key: "BracketRight" },
|
||||
"*": { key: "BracketRight", shift: true },
|
||||
"]": { key: "BracketRight", altRight: true },
|
||||
"}": { key: "BracketRight", shift: true, altRight: true },
|
||||
"ò": { key: "Semicolon" },
|
||||
"ç": { key: "Semicolon", shift: true },
|
||||
"@": { key: "Semicolon", altRight: true },
|
||||
"à": { key: "Quote" },
|
||||
"°": { key: "Quote", shift: true },
|
||||
"#": { key: "Quote", altRight: true },
|
||||
"ù": { key: "Backslash" },
|
||||
"§": { key: "Backslash", shift: true },
|
||||
",": { key: "Comma" },
|
||||
";": { key: "Comma", shift: true },
|
||||
".": { key: "Period" },
|
||||
":": { key: "Period", shift: true },
|
||||
"-": { key: "Slash" },
|
||||
"_": { key: "Slash", shift: true },
|
||||
"<": { key: "IntlBackslash" },
|
||||
">": { key: "IntlBackslash", shift: true },
|
||||
" ": { key: "Space" },
|
||||
"\n": { key: "Enter" },
|
||||
Enter: { key: "Enter" },
|
||||
Tab: { key: "Tab" },
|
||||
} as Record<string, KeyCombo>;
|
|
@ -0,0 +1,167 @@
|
|||
import { KeyCombo } from "../keyboardLayouts"
|
||||
|
||||
export const name = "Norsk bokmål";
|
||||
|
||||
const keyTrema = { key: "BracketRight" } // tréma (umlaut), two dots placed above a vowel
|
||||
const keyAcute = { key: "Equal", altRight: true } // accent aigu (acute accent), mark ´ placed above the letter
|
||||
const keyHat = { key: "BracketRight", shift: true } // accent circonflexe (accent hat), mark ^ placed above the letter
|
||||
const keyGrave = { key: "Equal", shift: true } // accent grave, mark ` placed above the letter
|
||||
const keyTilde = { key: "BracketRight", altRight: true } // tilde, mark ~ placed above the letter
|
||||
|
||||
export const chars = {
|
||||
A: { key: "KeyA", shift: true },
|
||||
"Ä": { key: "KeyA", shift: true, accentKey: keyTrema },
|
||||
"Á": { key: "KeyA", shift: true, accentKey: keyAcute },
|
||||
"Â": { key: "KeyA", shift: true, accentKey: keyHat },
|
||||
"À": { key: "KeyA", shift: true, accentKey: keyGrave },
|
||||
"Ã": { key: "KeyA", shift: true, accentKey: keyTilde },
|
||||
B: { key: "KeyB", shift: true },
|
||||
C: { key: "KeyC", shift: true },
|
||||
D: { key: "KeyD", shift: true },
|
||||
E: { key: "KeyE", shift: true },
|
||||
"Ë": { key: "KeyE", shift: true, accentKey: keyTrema },
|
||||
"É": { key: "KeyE", shift: true, accentKey: keyAcute },
|
||||
"Ê": { key: "KeyE", shift: true, accentKey: keyHat },
|
||||
"È": { key: "KeyE", shift: true, accentKey: keyGrave },
|
||||
"Ẽ": { key: "KeyE", shift: true, accentKey: keyTilde },
|
||||
F: { key: "KeyF", shift: true },
|
||||
G: { key: "KeyG", shift: true },
|
||||
H: { key: "KeyH", shift: true },
|
||||
I: { key: "KeyI", shift: true },
|
||||
"Ï": { key: "KeyI", shift: true, accentKey: keyTrema },
|
||||
"Í": { key: "KeyI", shift: true, accentKey: keyAcute },
|
||||
"Î": { key: "KeyI", shift: true, accentKey: keyHat },
|
||||
"Ì": { key: "KeyI", shift: true, accentKey: keyGrave },
|
||||
"Ĩ": { key: "KeyI", shift: true, accentKey: keyTilde },
|
||||
J: { key: "KeyJ", shift: true },
|
||||
K: { key: "KeyK", shift: true },
|
||||
L: { key: "KeyL", shift: true },
|
||||
M: { key: "KeyM", shift: true },
|
||||
N: { key: "KeyN", shift: true },
|
||||
O: { key: "KeyO", shift: true },
|
||||
"Ö": { key: "KeyO", shift: true, accentKey: keyTrema },
|
||||
"Ó": { key: "KeyO", shift: true, accentKey: keyAcute },
|
||||
"Ô": { key: "KeyO", shift: true, accentKey: keyHat },
|
||||
"Ò": { key: "KeyO", shift: true, accentKey: keyGrave },
|
||||
"Õ": { key: "KeyO", shift: true, accentKey: keyTilde },
|
||||
P: { key: "KeyP", shift: true },
|
||||
Q: { key: "KeyQ", shift: true },
|
||||
R: { key: "KeyR", shift: true },
|
||||
S: { key: "KeyS", shift: true },
|
||||
T: { key: "KeyT", shift: true },
|
||||
U: { key: "KeyU", shift: true },
|
||||
"Ü": { key: "KeyU", shift: true, accentKey: keyTrema },
|
||||
"Ú": { key: "KeyU", shift: true, accentKey: keyAcute },
|
||||
"Û": { key: "KeyU", shift: true, accentKey: keyHat },
|
||||
"Ù": { key: "KeyU", shift: true, accentKey: keyGrave },
|
||||
"Ũ": { key: "KeyU", shift: true, accentKey: keyTilde },
|
||||
V: { key: "KeyV", shift: true },
|
||||
W: { key: "KeyW", shift: true },
|
||||
X: { key: "KeyX", shift: true },
|
||||
Y: { key: "KeyZ", shift: true },
|
||||
Z: { key: "KeyY", shift: true },
|
||||
a: { key: "KeyA" },
|
||||
"ä": { key: "KeyA", accentKey: keyTrema },
|
||||
"á": { key: "KeyA", accentKey: keyAcute },
|
||||
"â": { key: "KeyA", accentKey: keyHat },
|
||||
"à": { key: "KeyA", accentKey: keyGrave },
|
||||
"ã": { key: "KeyA", accentKey: keyTilde },
|
||||
b: { key: "KeyB" },
|
||||
c: { key: "KeyC" },
|
||||
d: { key: "KeyD" },
|
||||
e: { key: "KeyE" },
|
||||
"ë": { key: "KeyE", accentKey: keyTrema },
|
||||
"é": { key: "KeyE", accentKey: keyAcute },
|
||||
"ê": { key: "KeyE", accentKey: keyHat },
|
||||
"è": { key: "KeyE", accentKey: keyGrave },
|
||||
"ẽ": { key: "KeyE", accentKey: keyTilde },
|
||||
"€": { key: "KeyE", altRight: true },
|
||||
f: { key: "KeyF" },
|
||||
g: { key: "KeyG" },
|
||||
h: { key: "KeyH" },
|
||||
i: { key: "KeyI" },
|
||||
"ï": { key: "KeyI", accentKey: keyTrema },
|
||||
"í": { key: "KeyI", accentKey: keyAcute },
|
||||
"î": { key: "KeyI", accentKey: keyHat },
|
||||
"ì": { key: "KeyI", accentKey: keyGrave },
|
||||
"ĩ": { key: "KeyI", accentKey: keyTilde },
|
||||
j: { key: "KeyJ" },
|
||||
k: { key: "KeyK" },
|
||||
l: { key: "KeyL" },
|
||||
m: { key: "KeyM" },
|
||||
n: { key: "KeyN" },
|
||||
o: { key: "KeyO" },
|
||||
"ö": { key: "KeyO", accentKey: keyTrema },
|
||||
"ó": { key: "KeyO", accentKey: keyAcute },
|
||||
"ô": { key: "KeyO", accentKey: keyHat },
|
||||
"ò": { key: "KeyO", accentKey: keyGrave },
|
||||
"õ": { key: "KeyO", accentKey: keyTilde },
|
||||
p: { key: "KeyP" },
|
||||
q: { key: "KeyQ" },
|
||||
r: { key: "KeyR" },
|
||||
s: { key: "KeyS" },
|
||||
t: { key: "KeyT" },
|
||||
u: { key: "KeyU" },
|
||||
"ü": { key: "KeyU", accentKey: keyTrema },
|
||||
"ú": { key: "KeyU", accentKey: keyAcute },
|
||||
"û": { key: "KeyU", accentKey: keyHat },
|
||||
"ù": { key: "KeyU", accentKey: keyGrave },
|
||||
"ũ": { key: "KeyU", accentKey: keyTilde },
|
||||
v: { key: "KeyV" },
|
||||
w: { key: "KeyW" },
|
||||
x: { key: "KeyX" },
|
||||
y: { key: "KeyZ" },
|
||||
z: { key: "KeyY" },
|
||||
"|": { key: "Backquote" },
|
||||
"§": { key: "Backquote", shift: true },
|
||||
1: { key: "Digit1" },
|
||||
"!": { key: "Digit1", shift: true },
|
||||
2: { key: "Digit2" },
|
||||
"\"": { key: "Digit2", shift: true },
|
||||
"@": { key: "Digit2", altRight: true },
|
||||
3: { key: "Digit3" },
|
||||
"#": { key: "Digit3", shift: true },
|
||||
"£": { key: "Digit3", altRight: true },
|
||||
4: { key: "Digit4" },
|
||||
"¤": { key: "Digit4", shift: true },
|
||||
"$": { key: "Digit4", altRight: true },
|
||||
5: { key: "Digit5" },
|
||||
"%": { key: "Digit5", shift: true },
|
||||
6: { key: "Digit6" },
|
||||
"&": { key: "Digit6", shift: true },
|
||||
7: { key: "Digit7" },
|
||||
"/": { key: "Digit7", shift: true },
|
||||
"{": { key: "Digit7", altRight: true },
|
||||
8: { key: "Digit8" },
|
||||
"(": { key: "Digit8", shift: true },
|
||||
"[": { key: "Digit8", altRight: true },
|
||||
9: { key: "Digit9" },
|
||||
")": { key: "Digit9", shift: true },
|
||||
"]": { key: "Digit9", altRight: true },
|
||||
0: { key: "Digit0" },
|
||||
"=": { key: "Digit0", shift: true },
|
||||
"}": { key: "Digit0", altRight: true },
|
||||
"+": { key: "Minus" },
|
||||
"?": { key: "Minus", shift: true },
|
||||
"\\": { key: "Equal" },
|
||||
"å": { key: "BracketLeft" },
|
||||
"Å": { key: "BracketLeft", shift: true },
|
||||
"ø": { key: "Semicolon" },
|
||||
"Ø": { key: "Semicolon", shift: true },
|
||||
"æ": { key: "Quote" },
|
||||
"Æ": { key: "Quote", shift: true },
|
||||
"'": { key: "Backslash" },
|
||||
"*": { key: "Backslash", shift: true },
|
||||
",": { key: "Comma" },
|
||||
";": { key: "Comma", shift: true },
|
||||
".": { key: "Period" },
|
||||
":": { key: "Period", shift: true },
|
||||
"-": { key: "Slash" },
|
||||
"_": { key: "Slash", shift: true },
|
||||
"<": { key: "IntlBackslash" },
|
||||
">": { key: "IntlBackslash", shift: true },
|
||||
" ": { key: "Space" },
|
||||
"\n": { key: "Enter" },
|
||||
Enter: { key: "Enter" },
|
||||
Tab: { key: "Tab" },
|
||||
} as Record<string, KeyCombo>;
|
|
@ -0,0 +1,164 @@
|
|||
import { KeyCombo } from "../keyboardLayouts"
|
||||
|
||||
export const name = "Svenska";
|
||||
|
||||
const keyTrema = { key: "BracketRight" } // tréma (umlaut), two dots placed above a vowel
|
||||
const keyAcute = { key: "Equal" } // accent aigu (acute accent), mark ´ placed above the letter
|
||||
const keyHat = { key: "BracketRight", shift: true } // accent circonflexe (accent hat), mark ^ placed above the letter
|
||||
const keyGrave = { key: "Equal", shift: true } // accent grave, mark ` placed above the letter
|
||||
const keyTilde = { key: "BracketRight", altRight: true } // tilde, mark ~ placed above the letter
|
||||
|
||||
export const chars = {
|
||||
A: { key: "KeyA", shift: true },
|
||||
"Á": { key: "KeyA", shift: true, accentKey: keyAcute },
|
||||
"Â": { key: "KeyA", shift: true, accentKey: keyHat },
|
||||
"À": { key: "KeyA", shift: true, accentKey: keyGrave },
|
||||
"Ã": { key: "KeyA", shift: true, accentKey: keyTilde },
|
||||
B: { key: "KeyB", shift: true },
|
||||
C: { key: "KeyC", shift: true },
|
||||
D: { key: "KeyD", shift: true },
|
||||
E: { key: "KeyE", shift: true },
|
||||
"Ë": { key: "KeyE", shift: true, accentKey: keyTrema },
|
||||
"É": { key: "KeyE", shift: true, accentKey: keyAcute },
|
||||
"Ê": { key: "KeyE", shift: true, accentKey: keyHat },
|
||||
"È": { key: "KeyE", shift: true, accentKey: keyGrave },
|
||||
"Ẽ": { key: "KeyE", shift: true, accentKey: keyTilde },
|
||||
F: { key: "KeyF", shift: true },
|
||||
G: { key: "KeyG", shift: true },
|
||||
H: { key: "KeyH", shift: true },
|
||||
I: { key: "KeyI", shift: true },
|
||||
"Ï": { key: "KeyI", shift: true, accentKey: keyTrema },
|
||||
"Í": { key: "KeyI", shift: true, accentKey: keyAcute },
|
||||
"Î": { key: "KeyI", shift: true, accentKey: keyHat },
|
||||
"Ì": { key: "KeyI", shift: true, accentKey: keyGrave },
|
||||
"Ĩ": { key: "KeyI", shift: true, accentKey: keyTilde },
|
||||
J: { key: "KeyJ", shift: true },
|
||||
K: { key: "KeyK", shift: true },
|
||||
L: { key: "KeyL", shift: true },
|
||||
M: { key: "KeyM", shift: true },
|
||||
N: { key: "KeyN", shift: true },
|
||||
O: { key: "KeyO", shift: true },
|
||||
"Ó": { key: "KeyO", shift: true, accentKey: keyAcute },
|
||||
"Ô": { key: "KeyO", shift: true, accentKey: keyHat },
|
||||
"Ò": { key: "KeyO", shift: true, accentKey: keyGrave },
|
||||
"Õ": { key: "KeyO", shift: true, accentKey: keyTilde },
|
||||
P: { key: "KeyP", shift: true },
|
||||
Q: { key: "KeyQ", shift: true },
|
||||
R: { key: "KeyR", shift: true },
|
||||
S: { key: "KeyS", shift: true },
|
||||
T: { key: "KeyT", shift: true },
|
||||
U: { key: "KeyU", shift: true },
|
||||
"Ü": { key: "KeyU", shift: true, accentKey: keyTrema },
|
||||
"Ú": { key: "KeyU", shift: true, accentKey: keyAcute },
|
||||
"Û": { key: "KeyU", shift: true, accentKey: keyHat },
|
||||
"Ù": { key: "KeyU", shift: true, accentKey: keyGrave },
|
||||
"Ũ": { key: "KeyU", shift: true, accentKey: keyTilde },
|
||||
V: { key: "KeyV", shift: true },
|
||||
W: { key: "KeyW", shift: true },
|
||||
X: { key: "KeyX", shift: true },
|
||||
Y: { key: "KeyZ", shift: true },
|
||||
Z: { key: "KeyY", shift: true },
|
||||
a: { key: "KeyA" },
|
||||
"á": { key: "KeyA", accentKey: keyAcute },
|
||||
"â": { key: "KeyA", accentKey: keyHat },
|
||||
"à": { key: "KeyA", accentKey: keyGrave },
|
||||
"ã": { key: "KeyA", accentKey: keyTilde },
|
||||
b: { key: "KeyB" },
|
||||
c: { key: "KeyC" },
|
||||
d: { key: "KeyD" },
|
||||
e: { key: "KeyE" },
|
||||
"ë": { key: "KeyE", accentKey: keyTrema },
|
||||
"é": { key: "KeyE", accentKey: keyAcute },
|
||||
"ê": { key: "KeyE", accentKey: keyHat },
|
||||
"è": { key: "KeyE", accentKey: keyGrave },
|
||||
"ẽ": { key: "KeyE", accentKey: keyTilde },
|
||||
"€": { key: "KeyE", altRight: true },
|
||||
f: { key: "KeyF" },
|
||||
g: { key: "KeyG" },
|
||||
h: { key: "KeyH" },
|
||||
i: { key: "KeyI" },
|
||||
"ï": { key: "KeyI", accentKey: keyTrema },
|
||||
"í": { key: "KeyI", accentKey: keyAcute },
|
||||
"î": { key: "KeyI", accentKey: keyHat },
|
||||
"ì": { key: "KeyI", accentKey: keyGrave },
|
||||
"ĩ": { key: "KeyI", accentKey: keyTilde },
|
||||
j: { key: "KeyJ" },
|
||||
k: { key: "KeyK" },
|
||||
l: { key: "KeyL" },
|
||||
m: { key: "KeyM" },
|
||||
n: { key: "KeyN" },
|
||||
o: { key: "KeyO" },
|
||||
"ó": { key: "KeyO", accentKey: keyAcute },
|
||||
"ô": { key: "KeyO", accentKey: keyHat },
|
||||
"ò": { key: "KeyO", accentKey: keyGrave },
|
||||
"õ": { key: "KeyO", accentKey: keyTilde },
|
||||
p: { key: "KeyP" },
|
||||
q: { key: "KeyQ" },
|
||||
r: { key: "KeyR" },
|
||||
s: { key: "KeyS" },
|
||||
t: { key: "KeyT" },
|
||||
u: { key: "KeyU" },
|
||||
"ü": { key: "KeyU", accentKey: keyTrema },
|
||||
"ú": { key: "KeyU", accentKey: keyAcute },
|
||||
"û": { key: "KeyU", accentKey: keyHat },
|
||||
"ù": { key: "KeyU", accentKey: keyGrave },
|
||||
"ũ": { key: "KeyU", accentKey: keyTilde },
|
||||
v: { key: "KeyV" },
|
||||
w: { key: "KeyW" },
|
||||
x: { key: "KeyX" },
|
||||
y: { key: "KeyZ" },
|
||||
z: { key: "KeyY" },
|
||||
"§": { key: "Backquote" },
|
||||
"½": { key: "Backquote", shift: true },
|
||||
1: { key: "Digit1" },
|
||||
"!": { key: "Digit1", shift: true },
|
||||
2: { key: "Digit2" },
|
||||
"\"": { key: "Digit2", shift: true },
|
||||
"@": { key: "Digit2", altRight: true },
|
||||
3: { key: "Digit3" },
|
||||
"#": { key: "Digit3", shift: true },
|
||||
"£": { key: "Digit3", altRight: true },
|
||||
4: { key: "Digit4" },
|
||||
"¤": { key: "Digit4", shift: true },
|
||||
"$": { key: "Digit4", altRight: true },
|
||||
5: { key: "Digit5" },
|
||||
"%": { key: "Digit5", shift: true },
|
||||
6: { key: "Digit6" },
|
||||
"&": { key: "Digit6", shift: true },
|
||||
7: { key: "Digit7" },
|
||||
"/": { key: "Digit7", shift: true },
|
||||
"{": { key: "Digit7", altRight: true },
|
||||
8: { key: "Digit8" },
|
||||
"(": { key: "Digit8", shift: true },
|
||||
"[": { key: "Digit8", altRight: true },
|
||||
9: { key: "Digit9" },
|
||||
")": { key: "Digit9", shift: true },
|
||||
"]": { key: "Digit9", altRight: true },
|
||||
0: { key: "Digit0" },
|
||||
"=": { key: "Digit0", shift: true },
|
||||
"}": { key: "Digit0", altRight: true },
|
||||
"+": { key: "Minus" },
|
||||
"?": { key: "Minus", shift: true },
|
||||
"\\": { key: "Minus", altRight: true },
|
||||
"å": { key: "BracketLeft" },
|
||||
"Å": { key: "BracketLeft", shift: true },
|
||||
"ö": { key: "Semicolon" },
|
||||
"Ö": { key: "Semicolon", shift: true },
|
||||
"ä": { key: "Quote" },
|
||||
"Ä": { key: "Quote", shift: true },
|
||||
"'": { key: "Backslash" },
|
||||
"*": { key: "Backslash", shift: true },
|
||||
",": { key: "Comma" },
|
||||
";": { key: "Comma", shift: true },
|
||||
".": { key: "Period" },
|
||||
":": { key: "Period", shift: true },
|
||||
"-": { key: "Slash" },
|
||||
"_": { key: "Slash", shift: true },
|
||||
"<": { key: "IntlBackslash" },
|
||||
">": { key: "IntlBackslash", shift: true },
|
||||
"|": { key: "IntlBackslash", altRight: true },
|
||||
" ": { key: "Space" },
|
||||
"\n": { key: "Enter" },
|
||||
Enter: { key: "Enter" },
|
||||
Tab: { key: "Tab" },
|
||||
} as Record<string, KeyCombo>;
|
|
@ -43,7 +43,7 @@ export const keys = {
|
|||
F13: 0x68,
|
||||
Home: 0x4a,
|
||||
Insert: 0x49,
|
||||
IntlBackslash: 0x31,
|
||||
IntlBackslash: 0x64,
|
||||
KeyA: 0x04,
|
||||
KeyB: 0x05,
|
||||
KeyC: 0x06,
|
||||
|
@ -104,116 +104,6 @@ export const keys = {
|
|||
Tab: 0x2b,
|
||||
} as Record<string, number>;
|
||||
|
||||
export const chars = {
|
||||
A: { key: "KeyA", shift: true },
|
||||
B: { key: "KeyB", shift: true },
|
||||
C: { key: "KeyC", shift: true },
|
||||
D: { key: "KeyD", shift: true },
|
||||
E: { key: "KeyE", shift: true },
|
||||
F: { key: "KeyF", shift: true },
|
||||
G: { key: "KeyG", shift: true },
|
||||
H: { key: "KeyH", shift: true },
|
||||
I: { key: "KeyI", shift: true },
|
||||
J: { key: "KeyJ", shift: true },
|
||||
K: { key: "KeyK", shift: true },
|
||||
L: { key: "KeyL", shift: true },
|
||||
M: { key: "KeyM", shift: true },
|
||||
N: { key: "KeyN", shift: true },
|
||||
O: { key: "KeyO", shift: true },
|
||||
P: { key: "KeyP", shift: true },
|
||||
Q: { key: "KeyQ", shift: true },
|
||||
R: { key: "KeyR", shift: true },
|
||||
S: { key: "KeyS", shift: true },
|
||||
T: { key: "KeyT", shift: true },
|
||||
U: { key: "KeyU", shift: true },
|
||||
V: { key: "KeyV", shift: true },
|
||||
W: { key: "KeyW", shift: true },
|
||||
X: { key: "KeyX", shift: true },
|
||||
Y: { key: "KeyY", shift: true },
|
||||
Z: { key: "KeyZ", shift: true },
|
||||
a: { key: "KeyA", shift: false },
|
||||
b: { key: "KeyB", shift: false },
|
||||
c: { key: "KeyC", shift: false },
|
||||
d: { key: "KeyD", shift: false },
|
||||
e: { key: "KeyE", shift: false },
|
||||
f: { key: "KeyF", shift: false },
|
||||
g: { key: "KeyG", shift: false },
|
||||
h: { key: "KeyH", shift: false },
|
||||
i: { key: "KeyI", shift: false },
|
||||
j: { key: "KeyJ", shift: false },
|
||||
k: { key: "KeyK", shift: false },
|
||||
l: { key: "KeyL", shift: false },
|
||||
m: { key: "KeyM", shift: false },
|
||||
n: { key: "KeyN", shift: false },
|
||||
o: { key: "KeyO", shift: false },
|
||||
p: { key: "KeyP", shift: false },
|
||||
q: { key: "KeyQ", shift: false },
|
||||
r: { key: "KeyR", shift: false },
|
||||
s: { key: "KeyS", shift: false },
|
||||
t: { key: "KeyT", shift: false },
|
||||
u: { key: "KeyU", shift: false },
|
||||
v: { key: "KeyV", shift: false },
|
||||
w: { key: "KeyW", shift: false },
|
||||
x: { key: "KeyX", shift: false },
|
||||
y: { key: "KeyY", shift: false },
|
||||
z: { key: "KeyZ", shift: false },
|
||||
1: { key: "Digit1", shift: false },
|
||||
"!": { key: "Digit1", shift: true },
|
||||
2: { key: "Digit2", shift: false },
|
||||
"@": { key: "Digit2", shift: true },
|
||||
3: { key: "Digit3", shift: false },
|
||||
"#": { key: "Digit3", shift: true },
|
||||
4: { key: "Digit4", shift: false },
|
||||
$: { key: "Digit4", shift: true },
|
||||
"%": { key: "Digit5", shift: true },
|
||||
5: { key: "Digit5", shift: false },
|
||||
"^": { key: "Digit6", shift: true },
|
||||
6: { key: "Digit6", shift: false },
|
||||
"&": { key: "Digit7", shift: true },
|
||||
7: { key: "Digit7", shift: false },
|
||||
"*": { key: "Digit8", shift: true },
|
||||
8: { key: "Digit8", shift: false },
|
||||
"(": { key: "Digit9", shift: true },
|
||||
9: { key: "Digit9", shift: false },
|
||||
")": { key: "Digit0", shift: true },
|
||||
0: { key: "Digit0", shift: false },
|
||||
"-": { key: "Minus", shift: false },
|
||||
_: { key: "Minus", shift: true },
|
||||
"=": { key: "Equal", shift: false },
|
||||
"+": { key: "Equal", shift: true },
|
||||
"'": { key: "Quote", shift: false },
|
||||
'"': { key: "Quote", shift: true },
|
||||
",": { key: "Comma", shift: false },
|
||||
"<": { key: "Comma", shift: true },
|
||||
"/": { key: "Slash", shift: false },
|
||||
"?": { key: "Slash", shift: true },
|
||||
".": { key: "Period", shift: false },
|
||||
">": { key: "Period", shift: true },
|
||||
";": { key: "Semicolon", shift: false },
|
||||
":": { key: "Semicolon", shift: true },
|
||||
"[": { key: "BracketLeft", shift: false },
|
||||
"{": { key: "BracketLeft", shift: true },
|
||||
"]": { key: "BracketRight", shift: false },
|
||||
"}": { key: "BracketRight", shift: true },
|
||||
"\\": { key: "Backslash", shift: false },
|
||||
"|": { key: "Backslash", shift: true },
|
||||
"`": { key: "Backquote", shift: false },
|
||||
"~": { key: "Backquote", shift: true },
|
||||
"§": { key: "IntlBackslash", shift: false },
|
||||
"±": { key: "IntlBackslash", shift: true },
|
||||
" ": { key: "Space", shift: false },
|
||||
"\n": { key: "Enter", shift: false },
|
||||
Enter: { key: "Enter", shift: false },
|
||||
Tab: { key: "Tab", shift: false },
|
||||
PrintScreen: { key: "Prt Sc", shift: false },
|
||||
SystemRequest: { key: "Prt Sc", shift: true },
|
||||
ScrollLock: { key: "ScrollLock", shift: false},
|
||||
Pause: { key: "Pause", shift: false },
|
||||
Break: { key: "Pause", shift: true },
|
||||
Insert: { key: "Insert", shift: false },
|
||||
Delete: { key: "Delete", shift: false },
|
||||
} as Record<string, { key: string | number; shift: boolean }>;
|
||||
|
||||
export const modifiers = {
|
||||
ControlLeft: 0x01,
|
||||
ControlRight: 0x10,
|
||||
|
|
|
@ -32,7 +32,8 @@ import { CLOUD_API, DEVICE_API } from "./ui.config";
|
|||
import OtherSessionRoute from "./routes/devices.$id.other-session";
|
||||
import MountRoute from "./routes/devices.$id.mount";
|
||||
import * as SettingsRoute from "./routes/devices.$id.settings";
|
||||
import SettingsKeyboardMouseRoute from "./routes/devices.$id.settings.mouse";
|
||||
import SettingsMouseRoute from "./routes/devices.$id.settings.mouse";
|
||||
import SettingsKeyboardRoute from "./routes/devices.$id.settings.keyboard";
|
||||
import api from "./api";
|
||||
import * as SettingsIndexRoute from "./routes/devices.$id.settings._index";
|
||||
import SettingsAdvancedRoute from "./routes/devices.$id.settings.advanced";
|
||||
|
@ -147,7 +148,11 @@ if (isOnDevice) {
|
|||
},
|
||||
{
|
||||
path: "mouse",
|
||||
element: <SettingsKeyboardMouseRoute />,
|
||||
element: <SettingsMouseRoute />,
|
||||
},
|
||||
{
|
||||
path: "keyboard",
|
||||
element: <SettingsKeyboardRoute />,
|
||||
},
|
||||
{
|
||||
path: "advanced",
|
||||
|
@ -276,7 +281,11 @@ if (isOnDevice) {
|
|||
},
|
||||
{
|
||||
path: "mouse",
|
||||
element: <SettingsKeyboardMouseRoute />,
|
||||
element: <SettingsMouseRoute />,
|
||||
},
|
||||
{
|
||||
path: "keyboard",
|
||||
element: <SettingsKeyboardRoute />,
|
||||
},
|
||||
{
|
||||
path: "advanced",
|
||||
|
|
|
@ -22,7 +22,7 @@ const ToastContent = ({
|
|||
<Card
|
||||
className={`${
|
||||
t.visible ? "animate-enter" : "animate-leave"
|
||||
} pointer-events-auto z-30 w-full max-w-sm !shadow-xl`}
|
||||
} pointer-events-auto z-30 w-full max-w-sm shadow-xl!`}
|
||||
>
|
||||
<div className="flex items-center gap-x-2 p-2.5 px-2">
|
||||
{icon}
|
||||
|
|
|
@ -185,7 +185,7 @@ export function Dialog({ onClose }: { onClose: () => void }) {
|
|||
<img
|
||||
src={LogoWhiteIcon}
|
||||
alt="JetKVM Logo"
|
||||
className="hidden h-[24px] dark:!mt-0 dark:block"
|
||||
className="hidden h-[24px] dark:mt-0! dark:block"
|
||||
/>
|
||||
{modalView === "mode" && (
|
||||
<ModeSelectionView
|
||||
|
@ -332,7 +332,7 @@ function ModeSelectionView({
|
|||
{
|
||||
"ring-2 ring-blue-700": selectedMode === mode,
|
||||
"hover:ring-2 hover:ring-blue-500": selectedMode !== mode && !disabled,
|
||||
"!cursor-not-allowed": disabled,
|
||||
"cursor-not-allowed!": disabled,
|
||||
},
|
||||
)}
|
||||
>
|
||||
|
@ -1489,7 +1489,7 @@ function PreUploadedImageItem({
|
|||
<div className="flex items-center gap-x-1 text-slate-600 dark:text-slate-400">
|
||||
{formatters.date(new Date(uploadedAt), { month: "short" })}
|
||||
</div>
|
||||
<div className="mx-1 h-[10px] w-[1px] bg-slate-300 text-slate-300 dark:bg-slate-600"></div>
|
||||
<div className="mx-1 h-[10px] w-px bg-slate-300 text-slate-300 dark:bg-slate-600"></div>
|
||||
<div className="text-gray-600 dark:text-slate-400">{size}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
import { useCallback, useEffect } from "react";
|
||||
|
||||
import { useDeviceSettingsStore } from "@/hooks/stores";
|
||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
||||
import notifications from "@/notifications";
|
||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||
import { layouts } from "@/keyboardLayouts";
|
||||
|
||||
import { FeatureFlag } from "../components/FeatureFlag";
|
||||
import { SelectMenuBasic } from "../components/SelectMenuBasic";
|
||||
|
||||
import { SettingsItem } from "./devices.$id.settings";
|
||||
|
||||
export default function SettingsKeyboardRoute() {
|
||||
const keyboardLayout = useDeviceSettingsStore(state => state.keyboardLayout);
|
||||
const setKeyboardLayout = useDeviceSettingsStore(
|
||||
state => state.setKeyboardLayout,
|
||||
);
|
||||
|
||||
const layoutOptions = Object.entries(layouts).map(([code, language]) => { return { value: code, label: language } })
|
||||
|
||||
const [send] = useJsonRpc();
|
||||
|
||||
useEffect(() => {
|
||||
send("getKeyboardLayout", {}, resp => {
|
||||
if ("error" in resp) return;
|
||||
setKeyboardLayout(resp.result as string);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const onKeyboardLayoutChange = useCallback(
|
||||
(e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const layout = e.target.value;
|
||||
send("setKeyboardLayout", { layout }, resp => {
|
||||
if ("error" in resp) {
|
||||
notifications.error(
|
||||
`Failed to set keyboard layout: ${resp.error.data || "Unknown error"}`,
|
||||
);
|
||||
}
|
||||
notifications.success("Keyboard layout set successfully");
|
||||
setKeyboardLayout(layout);
|
||||
});
|
||||
},
|
||||
[send, setKeyboardLayout],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<SettingsPageHeader
|
||||
title="Keyboard"
|
||||
description="Configure keyboard layout settings for your device"
|
||||
/>
|
||||
|
||||
<div className="space-y-4">
|
||||
<FeatureFlag minAppVersion="0.4.0" name="Paste text">
|
||||
{ /* this menu item could be renamed to plain "Keyboard layout" in the future, when also the virtual keyboard layout mappings are being implemented */ }
|
||||
<SettingsItem
|
||||
title="Paste text"
|
||||
description="Keyboard layout of target operating system"
|
||||
>
|
||||
<SelectMenuBasic
|
||||
size="SM"
|
||||
label=""
|
||||
fullWidth
|
||||
value={keyboardLayout}
|
||||
onChange={onKeyboardLayoutChange}
|
||||
options={layoutOptions}
|
||||
/>
|
||||
</SettingsItem>
|
||||
<p className="text-xs text-slate-600 dark:text-slate-400">
|
||||
Pasting text sends individual key strokes to the target device. The keyboard layout determines which key codes are being sent. Ensure that the keyboard layout in JetKVM matches the settings in the operating system.
|
||||
</p>
|
||||
</FeatureFlag>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -18,7 +18,7 @@ import { SettingsItem } from "./devices.$id.settings";
|
|||
|
||||
type ScrollSensitivity = "low" | "default" | "high";
|
||||
|
||||
export default function SettingsKeyboardMouseRoute() {
|
||||
export default function SettingsMouseRoute() {
|
||||
const hideCursor = useSettingsStore(state => state.isCursorHidden);
|
||||
const setHideCursor = useSettingsStore(state => state.setCursorVisibility);
|
||||
|
||||
|
|
|
@ -345,7 +345,7 @@ export default function SettingsNetworkRoute() {
|
|||
/>
|
||||
</div>
|
||||
|
||||
<div className="h-[1px] w-full bg-slate-800/10 dark:bg-slate-300/20" />
|
||||
<div className="h-px w-full bg-slate-800/10 dark:bg-slate-300/20" />
|
||||
|
||||
<div className="space-y-4">
|
||||
<SettingsItem title="IPv4 Mode" description="Configure the IPv4 mode">
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { NavLink, Outlet, useLocation } from "react-router-dom";
|
||||
import {
|
||||
LuSettings,
|
||||
LuMouse,
|
||||
LuKeyboard,
|
||||
LuVideo,
|
||||
LuCpu,
|
||||
|
@ -111,7 +112,7 @@ export default function SettingsRoute() {
|
|||
{/* Gradient overlay for left side - only visible on mobile when scrolled */}
|
||||
<div
|
||||
className={cx(
|
||||
"pointer-events-none absolute inset-y-0 left-0 z-10 w-8 bg-gradient-to-r from-white to-transparent transition-opacity duration-300 ease-in-out md:hidden dark:from-slate-900",
|
||||
"pointer-events-none absolute inset-y-0 left-0 z-10 w-8 bg-linear-to-r from-white to-transparent transition-opacity duration-300 ease-in-out md:hidden dark:from-slate-900",
|
||||
{
|
||||
"opacity-0": !showLeftGradient,
|
||||
"opacity-100": showLeftGradient,
|
||||
|
@ -121,7 +122,7 @@ export default function SettingsRoute() {
|
|||
{/* Gradient overlay for right side - only visible on mobile when there's more content */}
|
||||
<div
|
||||
className={cx(
|
||||
"pointer-events-none absolute inset-y-0 right-0 z-10 w-8 bg-gradient-to-l from-white to-transparent transition duration-300 ease-in-out md:hidden dark:from-slate-900",
|
||||
"pointer-events-none absolute inset-y-0 right-0 z-10 w-8 bg-linear-to-l from-white to-transparent transition duration-300 ease-in-out md:hidden dark:from-slate-900",
|
||||
{
|
||||
"opacity-0": !showRightGradient,
|
||||
"opacity-100": showRightGradient,
|
||||
|
@ -137,7 +138,7 @@ export default function SettingsRoute() {
|
|||
to="general"
|
||||
className={({ isActive }) => (isActive ? "active" : "")}
|
||||
>
|
||||
<div className="flex items-center gap-x-2 rounded-md px-2.5 py-2.5 text-sm transition-colors hover:bg-slate-100 dark:hover:bg-slate-700 [.active_&]:bg-blue-50 [.active_&]:!text-blue-700 md:[.active_&]:bg-transparent dark:[.active_&]:bg-blue-900 dark:[.active_&]:!text-blue-200 dark:md:[.active_&]:bg-transparent">
|
||||
<div className="flex items-center gap-x-2 rounded-md px-2.5 py-2.5 text-sm transition-colors hover:bg-slate-100 dark:hover:bg-slate-700 in-[.active]:bg-blue-50 in-[.active]:text-blue-700! md:in-[.active]:bg-transparent dark:in-[.active]:bg-blue-900 dark:in-[.active]:text-blue-200! dark:md:in-[.active]:bg-transparent">
|
||||
<LuSettings className="h-4 w-4 shrink-0" />
|
||||
<h1>General</h1>
|
||||
</div>
|
||||
|
@ -147,10 +148,22 @@ export default function SettingsRoute() {
|
|||
<NavLink
|
||||
to="mouse"
|
||||
className={({ isActive }) => (isActive ? "active" : "")}
|
||||
>
|
||||
<div className="flex items-center gap-x-2 rounded-md px-2.5 py-2.5 text-sm transition-colors hover:bg-slate-100 dark:hover:bg-slate-700 in-[.active]:bg-blue-50 in-[.active]:text-blue-700! md:in-[.active]:bg-transparent dark:in-[.active]:bg-blue-900 dark:in-[.active]:text-blue-200! dark:md:in-[.active]:bg-transparent">
|
||||
|
||||
<LuMouse className="h-4 w-4 shrink-0" />
|
||||
<h1>Mouse</h1>
|
||||
</div>
|
||||
</NavLink>
|
||||
</div>
|
||||
<div className="shrink-0">
|
||||
<NavLink
|
||||
to="keyboard"
|
||||
className={({ isActive }) => (isActive ? "active" : "")}
|
||||
>
|
||||
<div className="flex items-center gap-x-2 rounded-md px-2.5 py-2.5 text-sm transition-colors hover:bg-slate-100 dark:hover:bg-slate-700 [.active_&]:bg-blue-50 [.active_&]:!text-blue-700 md:[.active_&]:bg-transparent dark:[.active_&]:bg-blue-900 dark:[.active_&]:!text-blue-200 dark:md:[.active_&]:bg-transparent">
|
||||
<LuKeyboard className="h-4 w-4 shrink-0" />
|
||||
<h1>Mouse</h1>
|
||||
<h1>Keyboard</h1>
|
||||
</div>
|
||||
</NavLink>
|
||||
</div>
|
||||
|
@ -159,7 +172,7 @@ export default function SettingsRoute() {
|
|||
to="video"
|
||||
className={({ isActive }) => (isActive ? "active" : "")}
|
||||
>
|
||||
<div className="flex items-center gap-x-2 rounded-md px-2.5 py-2.5 text-sm transition-colors hover:bg-slate-100 dark:hover:bg-slate-700 [.active_&]:bg-blue-50 [.active_&]:!text-blue-700 md:[.active_&]:bg-transparent dark:[.active_&]:bg-blue-900 dark:[.active_&]:!text-blue-200 dark:md:[.active_&]:bg-transparent">
|
||||
<div className="flex items-center gap-x-2 rounded-md px-2.5 py-2.5 text-sm transition-colors hover:bg-slate-100 dark:hover:bg-slate-700 in-[.active]:bg-blue-50 in-[.active]:text-blue-700! md:in-[.active]:bg-transparent dark:in-[.active]:bg-blue-900 dark:in-[.active]:text-blue-200! dark:md:in-[.active]:bg-transparent">
|
||||
<LuVideo className="h-4 w-4 shrink-0" />
|
||||
<h1>Video</h1>
|
||||
</div>
|
||||
|
@ -170,7 +183,7 @@ export default function SettingsRoute() {
|
|||
to="hardware"
|
||||
className={({ isActive }) => (isActive ? "active" : "")}
|
||||
>
|
||||
<div className="flex items-center gap-x-2 rounded-md px-2.5 py-2.5 text-sm transition-colors hover:bg-slate-100 dark:hover:bg-slate-700 [.active_&]:bg-blue-50 [.active_&]:!text-blue-700 md:[.active_&]:bg-transparent dark:[.active_&]:bg-blue-900 dark:[.active_&]:!text-blue-200 dark:md:[.active_&]:bg-transparent">
|
||||
<div className="flex items-center gap-x-2 rounded-md px-2.5 py-2.5 text-sm transition-colors hover:bg-slate-100 dark:hover:bg-slate-700 in-[.active]:bg-blue-50 in-[.active]:text-blue-700! md:in-[.active]:bg-transparent dark:in-[.active]:bg-blue-900 dark:in-[.active]:text-blue-200! dark:md:in-[.active]:bg-transparent">
|
||||
<LuCpu className="h-4 w-4 shrink-0" />
|
||||
<h1>Hardware</h1>
|
||||
</div>
|
||||
|
@ -181,7 +194,7 @@ export default function SettingsRoute() {
|
|||
to="access"
|
||||
className={({ isActive }) => (isActive ? "active" : "")}
|
||||
>
|
||||
<div className="flex items-center gap-x-2 rounded-md px-2.5 py-2.5 text-sm transition-colors hover:bg-slate-100 dark:hover:bg-slate-700 [.active_&]:bg-blue-50 [.active_&]:!text-blue-700 md:[.active_&]:bg-transparent dark:[.active_&]:bg-blue-900 dark:[.active_&]:!text-blue-200 dark:md:[.active_&]:bg-transparent">
|
||||
<div className="flex items-center gap-x-2 rounded-md px-2.5 py-2.5 text-sm transition-colors hover:bg-slate-100 dark:hover:bg-slate-700 in-[.active]:bg-blue-50 in-[.active]:text-blue-700! md:in-[.active]:bg-transparent dark:in-[.active]:bg-blue-900 dark:in-[.active]:text-blue-200! dark:md:in-[.active]:bg-transparent">
|
||||
<LuShieldCheck className="h-4 w-4 shrink-0" />
|
||||
<h1>Access</h1>
|
||||
</div>
|
||||
|
@ -192,7 +205,7 @@ export default function SettingsRoute() {
|
|||
to="appearance"
|
||||
className={({ isActive }) => (isActive ? "active" : "")}
|
||||
>
|
||||
<div className="flex items-center gap-x-2 rounded-md px-2.5 py-2.5 text-sm transition-colors hover:bg-slate-100 dark:hover:bg-slate-700 [.active_&]:bg-blue-50 [.active_&]:!text-blue-700 md:[.active_&]:bg-transparent dark:[.active_&]:bg-blue-900 dark:[.active_&]:!text-blue-200 dark:md:[.active_&]:bg-transparent">
|
||||
<div className="flex items-center gap-x-2 rounded-md px-2.5 py-2.5 text-sm transition-colors hover:bg-slate-100 dark:hover:bg-slate-700 in-[.active]:bg-blue-50 in-[.active]:text-blue-700! md:in-[.active]:bg-transparent dark:in-[.active]:bg-blue-900 dark:in-[.active]:text-blue-200! dark:md:in-[.active]:bg-transparent">
|
||||
<LuPalette className="h-4 w-4 shrink-0" />
|
||||
<h1>Appearance</h1>
|
||||
</div>
|
||||
|
@ -203,7 +216,7 @@ export default function SettingsRoute() {
|
|||
to="macros"
|
||||
className={({ isActive }) => (isActive ? "active" : "")}
|
||||
>
|
||||
<div className="flex items-center gap-x-2 rounded-md px-2.5 py-2.5 text-sm transition-colors hover:bg-slate-100 dark:hover:bg-slate-700 [.active_&]:bg-blue-50 [.active_&]:!text-blue-700 md:[.active_&]:bg-transparent dark:[.active_&]:bg-blue-900 dark:[.active_&]:!text-blue-200 dark:md:[.active_&]:bg-transparent">
|
||||
<div className="flex items-center gap-x-2 rounded-md px-2.5 py-2.5 text-sm transition-colors hover:bg-slate-100 dark:hover:bg-slate-700 in-[.active]:bg-blue-50 in-[.active]:text-blue-700! md:in-[.active]:bg-transparent dark:in-[.active]:bg-blue-900 dark:in-[.active]:text-blue-200! dark:md:in-[.active]:bg-transparent">
|
||||
<LuCommand className="h-4 w-4 shrink-0" />
|
||||
<h1>Keyboard Macros</h1>
|
||||
</div>
|
||||
|
@ -214,7 +227,7 @@ export default function SettingsRoute() {
|
|||
to="network"
|
||||
className={({ isActive }) => (isActive ? "active" : "")}
|
||||
>
|
||||
<div className="flex items-center gap-x-2 rounded-md px-2.5 py-2.5 text-sm transition-colors hover:bg-slate-100 dark:hover:bg-slate-700 [.active_&]:bg-blue-50 [.active_&]:!text-blue-700 md:[.active_&]:bg-transparent dark:[.active_&]:bg-blue-900 dark:[.active_&]:!text-blue-200 dark:md:[.active_&]:bg-transparent">
|
||||
<div className="flex items-center gap-x-2 rounded-md px-2.5 py-2.5 text-sm transition-colors hover:bg-slate-100 dark:hover:bg-slate-700 in-[.active]:bg-blue-50 in-[.active]:text-blue-700! md:in-[.active]:bg-transparent dark:in-[.active]:bg-blue-900 dark:in-[.active]:text-blue-200! dark:md:in-[.active]:bg-transparent">
|
||||
<LuNetwork className="h-4 w-4 shrink-0" />
|
||||
<h1>Network</h1>
|
||||
</div>
|
||||
|
@ -225,7 +238,7 @@ export default function SettingsRoute() {
|
|||
to="advanced"
|
||||
className={({ isActive }) => (isActive ? "active" : "")}
|
||||
>
|
||||
<div className="flex items-center gap-x-2 rounded-md px-2.5 py-2.5 text-sm transition-colors hover:bg-slate-100 dark:hover:bg-slate-700 [.active_&]:bg-blue-50 [.active_&]:!text-blue-700 md:[.active_&]:bg-transparent dark:[.active_&]:bg-blue-900 dark:[.active_&]:!text-blue-200 dark:md:[.active_&]:bg-transparent">
|
||||
<div className="flex items-center gap-x-2 rounded-md px-2.5 py-2.5 text-sm transition-colors hover:bg-slate-100 dark:hover:bg-slate-700 in-[.active]:bg-blue-50 in-[.active]:text-blue-700! md:in-[.active]:bg-transparent dark:in-[.active]:bg-blue-900 dark:in-[.active]:text-blue-200! dark:md:in-[.active]:bg-transparent">
|
||||
<LuWrench className="h-4 w-4 shrink-0" />
|
||||
<h1>Advanced</h1>
|
||||
</div>
|
||||
|
|
|
@ -90,8 +90,8 @@ export default function WelcomeLocalModeRoute() {
|
|||
<GridCard
|
||||
key={mode}
|
||||
cardClassName={cx("transition-all duration-100", {
|
||||
"!outline-blue-700 !outline-2": selectedMode === mode,
|
||||
"hover:!outline-blue-700": selectedMode !== mode,
|
||||
"outline-blue-700! outline-2!": selectedMode === mode,
|
||||
"hover:outline-blue-700!": selectedMode !== mode,
|
||||
})}
|
||||
>
|
||||
<div
|
||||
|
|
|
@ -68,7 +68,7 @@ export default function WelcomeRoute() {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="!-mt-2 -ml-6 flex items-center justify-center">
|
||||
<div className="-mt-2! -ml-6 flex items-center justify-center">
|
||||
<img
|
||||
src={DeviceImage}
|
||||
alt="JetKVM Device"
|
||||
|
@ -90,7 +90,7 @@ export default function WelcomeRoute() {
|
|||
theme="light"
|
||||
text="Set up your JetKVM"
|
||||
LeadingIcon={({ className }) => (
|
||||
<img src={LogoMark} className={cx(className, "mr-1.5 !h-5")} />
|
||||
<img src={LogoMark} className={cx(className, "mr-1.5 h-5!")} />
|
||||
)}
|
||||
textAlign="center"
|
||||
to="/welcome/mode"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import defaultTheme from "tailwindcss/defaultTheme";
|
||||
import flattenColorPalette from "tailwindcss/lib/util/flattenColorPalette";
|
||||
import svgToDataUri from "mini-svg-data-uri";
|
||||
import plugin from "tailwindcss/plugin";
|
||||
|
|
4
usb.go
4
usb.go
|
@ -26,8 +26,8 @@ func initUsbGadget() {
|
|||
}()
|
||||
}
|
||||
|
||||
func rpcKeyboardReport(modifier uint8, keys []uint8) error {
|
||||
return gadget.KeyboardReport(modifier, keys)
|
||||
func rpcKeyboardReport(modifier uint8, keys []uint8, hold bool) error {
|
||||
return gadget.KeyboardReport(modifier, keys, hold)
|
||||
}
|
||||
|
||||
func rpcAbsMouseReport(x, y int, buttons uint8) error {
|
||||
|
|
Loading…
Reference in New Issue