mirror of
https://github.com/CharaChorder/DeviceManager.git
synced 2025-12-10 12:56:14 +00:00
feat: cookbook
This commit is contained in:
@@ -47,9 +47,11 @@ const config = {
|
||||
"step_over",
|
||||
"step_into",
|
||||
"step_out",
|
||||
"timer_play",
|
||||
"settings_backup_restore",
|
||||
"sound_detection_loud_sound",
|
||||
"ring_volume",
|
||||
"skillet",
|
||||
"wifi",
|
||||
"power_settings_circle",
|
||||
"graphic_eq",
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[c, p]]
|
||||
output: [CAPITALIZE]
|
||||
- input: [[a, b]]
|
||||
output: [a, b, c]
|
||||
idle: true
|
||||
|
||||
- press: [c, p]
|
||||
keys: [c, p]
|
||||
- release: [c, p]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
keys: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,35 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[c, p]]
|
||||
output: [CAPITALIZE, KSC_00]
|
||||
- input: [[a, b]]
|
||||
output: [JOIN, a, b, c, KSC_00]
|
||||
idle: true
|
||||
|
||||
- press: [c, p]
|
||||
keys: [c, p]
|
||||
- release: [c, p]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
keys: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,33 +0,0 @@
|
||||
test:
|
||||
- remap:
|
||||
A1:
|
||||
- [d, DUP]
|
||||
idle: true
|
||||
|
||||
- press: [a]
|
||||
keys: [a]
|
||||
- release: [a]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- press: [d]
|
||||
keys: [a]
|
||||
- release: [d]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- press: [c]
|
||||
keys: [c]
|
||||
- release: [c]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- press: [d]
|
||||
keys: [c]
|
||||
- release: [d]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
@@ -1,24 +0,0 @@
|
||||
test:
|
||||
- remap:
|
||||
A1:
|
||||
- [d, DUP]
|
||||
idle: true
|
||||
|
||||
- press: [a]
|
||||
keys: [a]
|
||||
- release: [a]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- press: [LEFT_SHIFT]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- press: [d]
|
||||
keys: [a]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- release: [LEFT_SHIFT, d]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
@@ -1,25 +0,0 @@
|
||||
test:
|
||||
- remap:
|
||||
A1:
|
||||
- [d, DUP]
|
||||
idle: true
|
||||
|
||||
- press: [a]
|
||||
keys: [a]
|
||||
- release: [a]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [a]
|
||||
keys: [a]
|
||||
- press: [d]
|
||||
keys: []
|
||||
- keys: [a]
|
||||
- release: [a, d]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
@@ -1,81 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
remap:
|
||||
A1:
|
||||
- [q, QUICKFIX]
|
||||
addChords:
|
||||
- input: [[t, s, e]]
|
||||
output: [t, e, s, t]
|
||||
- input: [[t, s]]
|
||||
output: [s, e, t]
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [s, t]
|
||||
keys: [s, t]
|
||||
- release: [s, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [s]
|
||||
- keys: [e]
|
||||
- keys: [t]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [q]
|
||||
keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- release: [q]
|
||||
step: 16
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,83 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
remap:
|
||||
A1:
|
||||
- [q, QUICKFIX]
|
||||
addChords:
|
||||
- input: [[t, s, e]]
|
||||
output: [t, e, s, t]
|
||||
- input: [[t, s]]
|
||||
output: [s, e, t]
|
||||
settings:
|
||||
chording:
|
||||
concatenation style: prepended
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [s, t]
|
||||
keys: [s, t]
|
||||
- release: [s, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [SPACE]
|
||||
- keys: [s]
|
||||
- keys: [e]
|
||||
- keys: [t]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [q]
|
||||
keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- release: [q]
|
||||
step: 16
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [SPACE]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,65 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
remap:
|
||||
A1:
|
||||
- [q, QUICKFIX]
|
||||
addChords:
|
||||
- input: [[t, s, e]]
|
||||
output: [t, e, s, t]
|
||||
- input: [[t, s]]
|
||||
output: [s, e, t]
|
||||
settings:
|
||||
chording:
|
||||
detection method: smart
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [s, t]
|
||||
- release: [s, t]
|
||||
- step: 16
|
||||
keys: [s]
|
||||
- keys: [e]
|
||||
- keys: [t]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [q]
|
||||
- release: [q]
|
||||
step: 16
|
||||
keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,65 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
remap:
|
||||
A1:
|
||||
- [q, QUICKFIX]
|
||||
addChords:
|
||||
- input: [[t, s, e]]
|
||||
output: [t, e, s, t]
|
||||
- input: [[t, s]]
|
||||
output: [s, e, t]
|
||||
settings:
|
||||
chording:
|
||||
detection method: smart
|
||||
concatenation style: prepended
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [s, t]
|
||||
- release: [s, t]
|
||||
- step: 16
|
||||
keys: [SPACE]
|
||||
- keys: [s]
|
||||
- keys: [e]
|
||||
- keys: [t]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [q]
|
||||
- release: [q]
|
||||
step: 16
|
||||
keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: [SPACE]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,79 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[a, b]]
|
||||
output: [a, b, c]
|
||||
settings:
|
||||
arpeggiates:
|
||||
enable: 1
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
keys: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
keys: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [LEFT_SHIFT]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- release: [LEFT_SHIFT]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [x]
|
||||
keys: [x]
|
||||
- release: [x]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- press: [LEFT_SHIFT]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- release: [LEFT_SHIFT]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
@@ -1,74 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[a, b]]
|
||||
output: [a, b, c, KSC_00]
|
||||
settings:
|
||||
arpeggiates:
|
||||
enable: 1
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
keys: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
keys: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [LEFT_SHIFT]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- release: [LEFT_SHIFT]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [x]
|
||||
keys: [x]
|
||||
- release: [x]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- press: [LEFT_SHIFT]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- release: [LEFT_SHIFT]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
@@ -1,65 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[a, b]]
|
||||
output: [a, b, c]
|
||||
- input: [[ARPEGGIATE, .]]
|
||||
output: [JOIN, ., CAPITALIZE, JOIN]
|
||||
settings:
|
||||
arpeggiates:
|
||||
enable: 1
|
||||
autocorrect:
|
||||
maximum attempts: 0
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
keys: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
keys: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
keys: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [.]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
keys: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,80 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[a, b]]
|
||||
output: [a, b, c]
|
||||
settings:
|
||||
arpeggiates:
|
||||
enable: 1
|
||||
chording:
|
||||
concatenation style: prepended
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
keys: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
keys: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [SPACE]
|
||||
- keys: [a]
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [LEFT_SHIFT]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- release: [LEFT_SHIFT]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [SPACE]
|
||||
- keys: [a]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [x]
|
||||
keys: [x]
|
||||
- release: [x]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- press: [LEFT_SHIFT]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- release: [LEFT_SHIFT]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
@@ -1,76 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[a, b]]
|
||||
output: [a, b, c, KSC_00]
|
||||
settings:
|
||||
arpeggiates:
|
||||
enable: 1
|
||||
chording:
|
||||
concatenation style: prepended
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
keys: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
keys: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [LEFT_SHIFT]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- release: [LEFT_SHIFT]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [x]
|
||||
keys: [x]
|
||||
- release: [x]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- press: [LEFT_SHIFT]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- release: [LEFT_SHIFT]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
@@ -1,63 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[a, b]]
|
||||
output: [a, b, c]
|
||||
- input: [[ARPEGGIATE, .]]
|
||||
output: [JOIN, ., CAPITALIZE, JOIN]
|
||||
settings:
|
||||
arpeggiates:
|
||||
enable: 1
|
||||
chording:
|
||||
concatenation style: prepended
|
||||
autocorrect:
|
||||
maximum attempts: 0
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
keys: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
keys: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
keys: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [.]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
keys: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [SPACE]
|
||||
- keys: [a]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,55 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[a, b]]
|
||||
output: [a, b, c]
|
||||
settings:
|
||||
chording:
|
||||
detection method: smart
|
||||
arpeggiates:
|
||||
enable: 1
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: [a]
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [LEFT_SHIFT]
|
||||
- release: [LEFT_SHIFT]
|
||||
- step: 16
|
||||
keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [x]
|
||||
- release: [x]
|
||||
- step: 16
|
||||
keys: [x]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [LEFT_SHIFT]
|
||||
- release: [LEFT_SHIFT]
|
||||
- step: 16
|
||||
modifiers:
|
||||
lshift: true
|
||||
- modifiers: {}
|
||||
idle: true
|
||||
@@ -1,51 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[a, b]]
|
||||
output: [a, b, c, KSC_00]
|
||||
settings:
|
||||
chording:
|
||||
detection method: smart
|
||||
arpeggiates:
|
||||
enable: 1
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: [a]
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [LEFT_SHIFT]
|
||||
- release: [LEFT_SHIFT]
|
||||
- step: 16
|
||||
keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [x]
|
||||
- release: [x]
|
||||
- step: 16
|
||||
keys: [x]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [LEFT_SHIFT]
|
||||
- release: [LEFT_SHIFT]
|
||||
- step: 16
|
||||
modifiers:
|
||||
lshift: true
|
||||
- modifiers: {}
|
||||
idle: true
|
||||
@@ -1,59 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[a, b]]
|
||||
output: [a, b, c]
|
||||
- input: [[ARPEGGIATE, .]]
|
||||
output: [JOIN, ., CAPITALIZE, JOIN]
|
||||
settings:
|
||||
chording:
|
||||
detection method: smart
|
||||
arpeggiates:
|
||||
enable: 1
|
||||
autocorrect:
|
||||
maximum attempts: 0
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: [.]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: [a]
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: [BKSP]
|
||||
- keys: [.]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: [a]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,51 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[a, b]]
|
||||
output: [a, b, c]
|
||||
- input: [[ARPEGGIATE, .]]
|
||||
output: [JOIN, ., CAPITALIZE, JOIN]
|
||||
settings:
|
||||
arpeggiates:
|
||||
enable: 1
|
||||
chording:
|
||||
detection method: smart
|
||||
concatenation style: prepended
|
||||
autocorrect:
|
||||
maximum attempts: 0
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: [.]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: [a]
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: [.]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [a, b]
|
||||
- release: [a, b]
|
||||
- step: 16
|
||||
keys: [SPACE]
|
||||
- keys: [a]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,76 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
remap:
|
||||
A1:
|
||||
- [d, DUP]
|
||||
addChords:
|
||||
- input: [[h, z]]
|
||||
output: [t, h, e]
|
||||
- input: [[m, o, h, DUP, a, y]]
|
||||
output: [m, o, t, i, v, a, t, i, o, n]
|
||||
settings:
|
||||
chording:
|
||||
detection method: smart
|
||||
concatenation style: prepended
|
||||
idle: true
|
||||
|
||||
- press: [x]
|
||||
- release: [x]
|
||||
- step: 16
|
||||
keys: [x]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [h, z]
|
||||
- release: [h, z]
|
||||
- step: 16
|
||||
keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [h]
|
||||
- keys: [e]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [d]
|
||||
- press: [m, h, a, y]
|
||||
- release: [d, m, h, a, y]
|
||||
- step: 16
|
||||
keys: [e, a, h, m, y]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [d]
|
||||
- press: [m, o, h, a, y]
|
||||
- release: [d, m, o, h, a, y]
|
||||
- step: 16
|
||||
keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [SPACE]
|
||||
- keys: [m]
|
||||
- keys: [o]
|
||||
- keys: [t]
|
||||
- keys: [i]
|
||||
- keys: [v]
|
||||
- keys: [a]
|
||||
- keys: [t]
|
||||
- keys: [i]
|
||||
- keys: [o]
|
||||
- keys: [n]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,67 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
remap:
|
||||
A1:
|
||||
- [d, DUP]
|
||||
addChords:
|
||||
- input: [[h, z]]
|
||||
output: [t, h, e]
|
||||
- input: [[m, o, h, DUP, a, y]]
|
||||
output: [m, o, t, i, v, a, t, i, o, n]
|
||||
settings:
|
||||
chording:
|
||||
detection method: smart
|
||||
concatenation style: prepended
|
||||
autocorrect:
|
||||
maximum attempts: 0
|
||||
idle: true
|
||||
|
||||
- press: [x]
|
||||
- release: [x]
|
||||
- step: 16
|
||||
keys: [x]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [h, z]
|
||||
- release: [h, z]
|
||||
- step: 16
|
||||
keys: [t]
|
||||
- keys: [h]
|
||||
- keys: [e]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [d]
|
||||
- press: [m, h, a, y]
|
||||
- release: [d, m, h, a, y]
|
||||
- step: 16
|
||||
keys: [e, a, h, m, y]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [d]
|
||||
- press: [m, o, h, a, y]
|
||||
- release: [d, m, o, h, a, y]
|
||||
- step: 16
|
||||
keys: [m]
|
||||
- keys: [o]
|
||||
- keys: [t]
|
||||
- keys: [i]
|
||||
- keys: [v]
|
||||
- keys: [a]
|
||||
- keys: [t]
|
||||
- keys: [i]
|
||||
- keys: [o]
|
||||
- keys: [n]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,24 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[t, s, e]]
|
||||
output: [t, e, s, t]
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,23 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[t, s, e]]
|
||||
output: [t, e, s, t, KSC_00]
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,78 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[i, n, g]]
|
||||
output: [t, h, i, n, g]
|
||||
- input: [[t, s, e]]
|
||||
output: [t, e, s, t]
|
||||
- input: [[i, n, g], [t, s, e]]
|
||||
output: [t, e, s, t, i, n, g]
|
||||
idle: true
|
||||
|
||||
- press: [i, n, g]
|
||||
keys: [g, i, n]
|
||||
- release: [i, n, g]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [h]
|
||||
- keys: [i]
|
||||
- keys: [n]
|
||||
- keys: [g]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [i, n, g]
|
||||
keys: [g, i, n]
|
||||
- release: [i, n, g]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: [i]
|
||||
- keys: [n]
|
||||
- keys: [g]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,45 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
remap:
|
||||
A1:
|
||||
- [d, DUP]
|
||||
addChords:
|
||||
- input: [[DUP, s, e]]
|
||||
output: [t, e, s, t]
|
||||
settings:
|
||||
autocorrect:
|
||||
maximum attempts: 0
|
||||
idle: true
|
||||
|
||||
- press: [s]
|
||||
keys: [s]
|
||||
- release: [s]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [s]
|
||||
keys: [s]
|
||||
- press: [d]
|
||||
keys: []
|
||||
- keys: [s]
|
||||
- press: [e]
|
||||
keys: [s, e]
|
||||
- release: [d, e, s]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,27 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[t]]
|
||||
output: [t, e, s, t]
|
||||
idle: true
|
||||
|
||||
- press: [t]
|
||||
keys: [t]
|
||||
- release: [t]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [t]
|
||||
keys: [t]
|
||||
- press: [LEFT_SHIFT]
|
||||
keys: [t]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- release: [LEFT_SHIFT, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
@@ -1,58 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[SPACE, s]]
|
||||
output: [a, b]
|
||||
idle: true
|
||||
|
||||
- press: [a]
|
||||
keys: [a]
|
||||
- release: [a]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- press: [SPACE]
|
||||
keys: [SPACE]
|
||||
- release: [SPACE]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [SPACE]
|
||||
keys: [SPACE]
|
||||
- press: [s]
|
||||
keys: [SPACE, s]
|
||||
- release: [SPACE, s]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
- keys: [b]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [s]
|
||||
keys: [s]
|
||||
- press: [SPACE]
|
||||
keys: [s, SPACE]
|
||||
- release: [SPACE, s]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
- keys: [b]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,28 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[t, h, e]]
|
||||
output: [t, h, e]
|
||||
settings:
|
||||
keyboard:
|
||||
debounce press: 4
|
||||
debounce release: 5
|
||||
idle: true
|
||||
|
||||
- press: [t]
|
||||
keys: [t]
|
||||
- release: [t]
|
||||
- press: [a]
|
||||
keys: [t, a]
|
||||
- release: [a]
|
||||
- keys: [a]
|
||||
- press: [t]
|
||||
- keys: []
|
||||
- step: 1
|
||||
- step: 1
|
||||
- keys: [t]
|
||||
- release: [t]
|
||||
- step: 1
|
||||
- step: 1
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,34 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
remap:
|
||||
A1:
|
||||
- [l, KM_3_L]
|
||||
- [r, KM_3_R]
|
||||
- [a, a]
|
||||
A2:
|
||||
- [l, KM_3_L]
|
||||
- [r, KM_3_R]
|
||||
- [a, b]
|
||||
A3:
|
||||
- [l, KM_3_L]
|
||||
- [r, KM_3_R]
|
||||
- [a, c]
|
||||
idle: true
|
||||
|
||||
- press: [a]
|
||||
keys: [a]
|
||||
- release: [a]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [l]
|
||||
- press: [a]
|
||||
keys: [c]
|
||||
- release: [l, a]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
@@ -1,82 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[h, y]]
|
||||
output: [CAPTURE, CAPITALIZE, CAPTURE]
|
||||
- input: [[t, s, e]]
|
||||
output: [t, e, s, t]
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [h, y]
|
||||
keys: [h, y]
|
||||
- release: [h, y]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,83 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[h, y]]
|
||||
output: [CAPTURE, "-", CAPTURE]
|
||||
- input: [[t, s, e]]
|
||||
output: [t, e, s, t]
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [h, y]
|
||||
keys: [h, y]
|
||||
- release: [h, y]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: ["-"]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: ["-"]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: ["-"]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,85 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[h, y]]
|
||||
output: [CAPTURE, CAPITALIZE, CAPTURE]
|
||||
- input: [[t, s, e]]
|
||||
output: [t, e, s, t]
|
||||
settings:
|
||||
chording:
|
||||
concatenation style: prepended
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [h, y]
|
||||
keys: [h, y]
|
||||
- release: [h, y]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,85 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[h, y]]
|
||||
output: [CAPTURE, "-", CAPTURE]
|
||||
- input: [[t, s, e]]
|
||||
output: [t, e, s, t]
|
||||
settings:
|
||||
chording:
|
||||
concatenation style: prepended
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [h, y]
|
||||
keys: [h, y]
|
||||
- release: [h, y]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: ["-"]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: ["-"]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,28 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[a, b]]
|
||||
output: [a, b, c]
|
||||
idle: true
|
||||
|
||||
- press: [LEFT_SHIFT]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- press: [LEFT_SHIFT, a, b]
|
||||
modifiers:
|
||||
lshift: true
|
||||
keys: [a, b]
|
||||
- release: [LEFT_SHIFT, a, b]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,80 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[i, n, g]]
|
||||
output: [t, h, i, n, g]
|
||||
- input: [[t, s, e]]
|
||||
output: [t, e, s, t]
|
||||
- input: [[i, n, g], [t, s, e]]
|
||||
output: [t, e, s, t, i, n, g]
|
||||
settings:
|
||||
chording:
|
||||
concatenation style: prepended
|
||||
idle: true
|
||||
|
||||
- press: [i, n, g]
|
||||
keys: [g, i, n]
|
||||
- release: [i, n, g]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [h]
|
||||
- keys: [i]
|
||||
- keys: [n]
|
||||
- keys: [g]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [s, e, t]
|
||||
keys: [e, s, t]
|
||||
- release: [s, e, t]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [SPACE]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [i, n, g]
|
||||
keys: [g, i, n]
|
||||
- release: [i, n, g]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [SPACE]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: [i]
|
||||
- keys: [n]
|
||||
- keys: [g]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,45 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[h, z]]
|
||||
output: [t, h, e]
|
||||
settings:
|
||||
chording:
|
||||
detection method: smart
|
||||
concatenation style: prepended
|
||||
autocorrect:
|
||||
maximum attempts: 0
|
||||
idle: true
|
||||
|
||||
- press: [x]
|
||||
- release: [x]
|
||||
- step: 16
|
||||
keys: [x]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [h, z]
|
||||
- release: [h, z]
|
||||
- step: 16
|
||||
keys: [t]
|
||||
- keys: [h]
|
||||
- keys: [e]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [x]
|
||||
- release: [x]
|
||||
- step: 16
|
||||
keys: [x]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [x]
|
||||
- step: 120
|
||||
keys: [x]
|
||||
- release: [x]
|
||||
keys: []
|
||||
idle: true
|
||||
@@ -1,49 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[h, z]]
|
||||
output: [t, h, e]
|
||||
settings:
|
||||
chording:
|
||||
detection method: smart
|
||||
idle: true
|
||||
|
||||
- press: [ENTER]
|
||||
- release: [ENTER]
|
||||
- step: 16
|
||||
keys: [ENTER]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [h, z]
|
||||
- release: [h, z]
|
||||
- step: 16
|
||||
keys: [t]
|
||||
- keys: [h]
|
||||
- keys: [e]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- press: [ENTER]
|
||||
- release: [ENTER]
|
||||
- step: 16
|
||||
keys: [ENTER]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [h, z]
|
||||
- release: [h, z]
|
||||
- step: 16
|
||||
keys: [t]
|
||||
- keys: [h]
|
||||
- keys: [e]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,109 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[t, s]]
|
||||
output: [t, e, s, t]
|
||||
- input: [[ARPEGGIATE, .]]
|
||||
output: [JOIN, ., CAPITALIZE, JOIN]
|
||||
- input: [[., .]]
|
||||
output: [JOIN, ., KSC_00]
|
||||
- input: [[., ., .]]
|
||||
output: [JOIN, ., ., ., CAPITALIZE, JOIN]
|
||||
settings:
|
||||
chording:
|
||||
tap dance tolerance: 175
|
||||
autocorrect:
|
||||
maximum attempts: 0
|
||||
arpeggiates:
|
||||
enable: 1
|
||||
idle: true
|
||||
|
||||
- press: [t, s]
|
||||
keys: [s, t]
|
||||
- release: [t, s]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
keys: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [.]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
keys: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [.]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
keys: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [.]
|
||||
- keys: []
|
||||
- keys: [.]
|
||||
- keys: []
|
||||
- keys: [.]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [t, s]
|
||||
keys: [s, t]
|
||||
- release: [t, s]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,102 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[t, s]]
|
||||
output: [t, e, s, t]
|
||||
- input: [[., .]]
|
||||
output: [JOIN, ., CAPITALIZE, JOIN]
|
||||
- input: [[., ., .]]
|
||||
output: [JOIN, ., ., ., CAPITALIZE, JOIN]
|
||||
settings:
|
||||
chording:
|
||||
tap dance tolerance: 175
|
||||
autocorrect:
|
||||
maximum attempts: 0
|
||||
idle: true
|
||||
|
||||
- press: [t, s]
|
||||
keys: [s, t]
|
||||
- release: [t, s]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
keys: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
keys: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [.]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
keys: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [.]
|
||||
- keys: []
|
||||
- keys: [.]
|
||||
- keys: []
|
||||
- keys: [.]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [t, s]
|
||||
keys: [s, t]
|
||||
- release: [t, s]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [t]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,103 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[a, a]]
|
||||
output: [b, c]
|
||||
- input: [[a, a, a, a, a]]
|
||||
output: [d, e]
|
||||
settings:
|
||||
chording:
|
||||
tap dance tolerance: 175
|
||||
autocorrect:
|
||||
maximum attempts: 0
|
||||
idle: true
|
||||
|
||||
- press: [a]
|
||||
keys: [a]
|
||||
- release: [a]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- step: 180
|
||||
idle: true
|
||||
|
||||
- press: [a]
|
||||
keys: [a]
|
||||
- release: [a]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [a]
|
||||
keys: [a]
|
||||
- release: [a]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [a]
|
||||
keys: [a]
|
||||
- release: [a]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
- keys: []
|
||||
- keys: [a]
|
||||
- keys: []
|
||||
- keys: [a]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [a]
|
||||
keys: [a]
|
||||
- release: [a]
|
||||
- step: 16
|
||||
keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [a]
|
||||
keys: [a]
|
||||
- release: [a]
|
||||
- step: 16
|
||||
keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [d]
|
||||
- keys: [e]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,88 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[t, s]]
|
||||
output: [t, e, s, t]
|
||||
- input: [[ARPEGGIATE, .]]
|
||||
output: [JOIN, ., CAPITALIZE, JOIN]
|
||||
- input: [[., .]]
|
||||
output: [JOIN, ., KSC_00]
|
||||
- input: [[., ., .]]
|
||||
output: [JOIN, ., ., ., CAPITALIZE, JOIN]
|
||||
settings:
|
||||
chording:
|
||||
tap dance tolerance: 175
|
||||
detection method: smart
|
||||
autocorrect:
|
||||
maximum attempts: 0
|
||||
arpeggiates:
|
||||
enable: 1
|
||||
idle: true
|
||||
|
||||
- press: [t, s]
|
||||
- release: [t, s]
|
||||
- step: 16
|
||||
keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: [BKSP]
|
||||
- keys: [.]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [.]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: [BKSP]
|
||||
- keys: [.]
|
||||
- keys: []
|
||||
- keys: [.]
|
||||
- keys: []
|
||||
- keys: [.]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [t, s]
|
||||
- release: [t, s]
|
||||
- step: 16
|
||||
keys: [t]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,85 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[t, s]]
|
||||
output: [t, e, s, t]
|
||||
- input: [[., .]]
|
||||
output: [JOIN, ., CAPITALIZE, JOIN]
|
||||
- input: [[., ., .]]
|
||||
output: [JOIN, ., ., ., CAPITALIZE, JOIN]
|
||||
settings:
|
||||
chording:
|
||||
tap dance tolerance: 175
|
||||
detection method: smart
|
||||
autocorrect:
|
||||
maximum attempts: 0
|
||||
idle: true
|
||||
|
||||
- press: [t, s]
|
||||
- release: [t, s]
|
||||
- step: 16
|
||||
keys: [t]
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: [.]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [.]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [.]
|
||||
- release: [.]
|
||||
- step: 16
|
||||
keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [.]
|
||||
- keys: []
|
||||
- keys: [.]
|
||||
- keys: []
|
||||
- keys: [.]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [t, s]
|
||||
- release: [t, s]
|
||||
- step: 16
|
||||
keys: [t]
|
||||
modifiers:
|
||||
lshift: true
|
||||
- keys: [e]
|
||||
- keys: [s]
|
||||
- keys: [t]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -1,92 +0,0 @@
|
||||
test:
|
||||
- clearChords: true
|
||||
addChords:
|
||||
- input: [[a, a]]
|
||||
output: [b, c]
|
||||
- input: [[a, a, a, a, a]]
|
||||
output: [d, e]
|
||||
settings:
|
||||
chording:
|
||||
tap dance tolerance: 175
|
||||
detection method: smart
|
||||
autocorrect:
|
||||
maximum attempts: 0
|
||||
idle: true
|
||||
|
||||
- press: [a]
|
||||
- release: [a]
|
||||
- step: 16
|
||||
keys: [a]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 180
|
||||
idle: true
|
||||
|
||||
- press: [a]
|
||||
- release: [a]
|
||||
- step: 16
|
||||
keys: [a]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [a]
|
||||
- release: [a]
|
||||
- step: 16
|
||||
keys: [BKSP]
|
||||
- keys: [b]
|
||||
- keys: [c]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [a]
|
||||
- release: [a]
|
||||
- step: 16
|
||||
keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [a]
|
||||
- keys: []
|
||||
- keys: [a]
|
||||
- keys: []
|
||||
- keys: [a]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [a]
|
||||
- release: [a]
|
||||
- step: 16
|
||||
keys: [a]
|
||||
- keys: []
|
||||
idle: true
|
||||
|
||||
- step: 16
|
||||
idle: true
|
||||
|
||||
- press: [a]
|
||||
- release: [a]
|
||||
- step: 16
|
||||
keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: []
|
||||
- keys: [BKSP]
|
||||
- keys: [d]
|
||||
- keys: [e]
|
||||
- keys: [SPACE]
|
||||
- keys: []
|
||||
idle: true
|
||||
@@ -10,14 +10,18 @@
|
||||
replay,
|
||||
cursor = false,
|
||||
keys = false,
|
||||
paused = false,
|
||||
children,
|
||||
ondone,
|
||||
ontick,
|
||||
}: {
|
||||
replay: ReplayPlayer | Replay;
|
||||
cursor?: boolean;
|
||||
keys?: boolean;
|
||||
paused?: boolean;
|
||||
children?: Snippet;
|
||||
ondone?: () => void;
|
||||
ontick?: (time: number) => void;
|
||||
} = $props();
|
||||
|
||||
let replayPlayer: ReplayPlayer | undefined = $state();
|
||||
@@ -45,6 +49,10 @@
|
||||
|
||||
$effect(() => {
|
||||
if (!svg || !text) return;
|
||||
if (paused) {
|
||||
text.textContent = finalText ?? "";
|
||||
return;
|
||||
}
|
||||
const player =
|
||||
replay instanceof ReplayPlayer ? replay : new ReplayPlayer(replay);
|
||||
replayPlayer = player;
|
||||
@@ -63,6 +71,7 @@
|
||||
const unsubscribePlayer = player.subscribe(apply);
|
||||
textRenderer = renderer;
|
||||
|
||||
player.onTick = ontick;
|
||||
player.onDone = ondone;
|
||||
player.start();
|
||||
apply();
|
||||
@@ -70,8 +79,11 @@
|
||||
renderer.animated = true;
|
||||
});
|
||||
return () => {
|
||||
textRenderer = undefined;
|
||||
replayPlayer = undefined;
|
||||
unsubscribePlayer();
|
||||
player?.destroy();
|
||||
player.destroy();
|
||||
renderer.destroy();
|
||||
};
|
||||
});
|
||||
|
||||
@@ -88,7 +100,7 @@
|
||||
{#key replay}
|
||||
<svg bind:this={svg}></svg>
|
||||
{#if browser}
|
||||
<span use:innerText={text}></span>
|
||||
<span use:innerText={text} style:opacity={paused ? 1 : 0}></span>
|
||||
{:else if !(replay instanceof ReplayPlayer)}
|
||||
{finalText}
|
||||
{/if}
|
||||
@@ -104,7 +116,6 @@
|
||||
}
|
||||
|
||||
span {
|
||||
opacity: 0;
|
||||
white-space: pre-wrap;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,10 @@ export class ReplayPlayer {
|
||||
|
||||
startTime = performance.now();
|
||||
|
||||
private animationFrameId: number | null = null;
|
||||
private animationFrameId: ReturnType<typeof requestAnimationFrame> | null =
|
||||
null;
|
||||
|
||||
private timeoutId: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
timescale = 1;
|
||||
|
||||
@@ -20,6 +23,8 @@ export class ReplayPlayer {
|
||||
|
||||
onDone?: () => void;
|
||||
|
||||
onTick?: (time: number) => void;
|
||||
|
||||
constructor(
|
||||
readonly replay: Replay,
|
||||
plugins: ReplayPlugin[] = [],
|
||||
@@ -47,6 +52,7 @@ export class ReplayPlayer {
|
||||
}
|
||||
|
||||
const now = performance.now() - this.startTime;
|
||||
this.onTick?.(now);
|
||||
|
||||
while (
|
||||
this.replayCursor < this.replay.keys.length &&
|
||||
@@ -131,7 +137,7 @@ export class ReplayPlayer {
|
||||
}
|
||||
return this;
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.timeoutId = setTimeout(() => {
|
||||
this.startTime = performance.now();
|
||||
this.animationFrameId = requestAnimationFrame(this.updateLoop.bind(this));
|
||||
}, delay);
|
||||
@@ -139,6 +145,9 @@ export class ReplayPlayer {
|
||||
}
|
||||
|
||||
destroy() {
|
||||
if (this.timeoutId) {
|
||||
clearTimeout(this.timeoutId);
|
||||
}
|
||||
if (this.animationFrameId) {
|
||||
cancelAnimationFrame(this.animationFrameId);
|
||||
}
|
||||
|
||||
@@ -279,6 +279,18 @@ export class TextRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.cursorNode.remove();
|
||||
for (const node of this.nodes.values()) {
|
||||
node.remove();
|
||||
}
|
||||
for (const node of this.heldNodes.values()) {
|
||||
node.remove();
|
||||
}
|
||||
this.nodes.clear();
|
||||
this.heldNodes.clear();
|
||||
}
|
||||
|
||||
private isShiny(char: TextToken, index: number) {
|
||||
return (
|
||||
this.shiny?.includes(index) ||
|
||||
|
||||
367
src/lib/components/ChordPhraseDisplay.svelte
Normal file
367
src/lib/components/ChordPhraseDisplay.svelte
Normal file
@@ -0,0 +1,367 @@
|
||||
<script lang="ts">
|
||||
import { KEYMAP_CODES } from "$lib/serial/keymap-codes";
|
||||
import { onMount, tick } from "svelte";
|
||||
import { scale } from "svelte/transition";
|
||||
import ActionString from "$lib/components/ActionString.svelte";
|
||||
import { deviceMeta, serialPort } from "$lib/serial/connection";
|
||||
import { get } from "svelte/store";
|
||||
import { action } from "$lib/title";
|
||||
import semverGte from "semver/functions/gte";
|
||||
import { inputToAction } from "../../routes/(app)/config/chords/input-converter";
|
||||
import { selectAction } from "../../routes/(app)/config/chords/action-selector";
|
||||
|
||||
interface InteractiveProps {
|
||||
interactive: true;
|
||||
ondeleteaction: (at: number, count?: number) => void;
|
||||
oninsertaction: (at: number, action: number) => void;
|
||||
}
|
||||
|
||||
interface NonInteractiveProps {
|
||||
interactive: false;
|
||||
ondeleteaction?: never;
|
||||
oninsertaction?: never;
|
||||
}
|
||||
|
||||
let {
|
||||
phrase,
|
||||
edited,
|
||||
interactive,
|
||||
oninsertaction,
|
||||
ondeleteaction,
|
||||
}: { phrase: number[]; edited: boolean } & (
|
||||
| NonInteractiveProps
|
||||
| InteractiveProps
|
||||
) = $props();
|
||||
|
||||
const JOIN_ACTION = 574;
|
||||
const NO_CONCATENATOR_ACTION = 256;
|
||||
|
||||
onMount(() => {
|
||||
if (interactive && phrase.length === 0) {
|
||||
box?.focus();
|
||||
}
|
||||
});
|
||||
|
||||
function keypress(event: KeyboardEvent) {
|
||||
if (!event.shiftKey && event.key === "ArrowUp") {
|
||||
addSpecial(event);
|
||||
} else if (!event.shiftKey && event.key === "ArrowLeft") {
|
||||
moveCursor(cursorPosition - 1);
|
||||
} else if (!event.shiftKey && event.key === "ArrowRight") {
|
||||
moveCursor(cursorPosition + 1);
|
||||
} else if (event.key === "Backspace") {
|
||||
if (interactive) {
|
||||
ondeleteaction!(cursorPosition - 1);
|
||||
}
|
||||
moveCursor(cursorPosition - 1);
|
||||
} else if (event.key === "Delete") {
|
||||
if (interactive) {
|
||||
ondeleteaction!(cursorPosition);
|
||||
}
|
||||
} else {
|
||||
if (event.key === "Shift") return;
|
||||
const action = inputToAction(event, get(serialPort)?.device === "X");
|
||||
if (action !== undefined) {
|
||||
oninsertaction!(cursorPosition, action);
|
||||
tick().then(() => moveCursor(cursorPosition + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function moveCursor(to: number) {
|
||||
if (!box) return;
|
||||
cursorPosition = Math.max(0, Math.min(to, phrase.length));
|
||||
const item = box.children.item(cursorPosition) as HTMLElement;
|
||||
cursorOffset = item.offsetLeft + item.offsetWidth;
|
||||
}
|
||||
|
||||
function clickCursor(event: MouseEvent) {
|
||||
if (box === undefined || event.target === button) return;
|
||||
const distance = (event as unknown as { layerX: number }).layerX;
|
||||
|
||||
let i = 0;
|
||||
for (const child of box.children) {
|
||||
const { offsetLeft, offsetWidth } = child as HTMLElement;
|
||||
if (distance < offsetLeft + offsetWidth / 2) {
|
||||
moveCursor(i - 1);
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
moveCursor(i - 1);
|
||||
}
|
||||
|
||||
function addSpecial(event: MouseEvent | KeyboardEvent) {
|
||||
selectAction(
|
||||
event,
|
||||
(action) => {
|
||||
oninsertaction!(cursorPosition, action);
|
||||
tick().then(() => moveCursor(cursorPosition + 1));
|
||||
},
|
||||
() => box?.focus(),
|
||||
);
|
||||
}
|
||||
|
||||
function resolveAutospace(autospace: boolean) {
|
||||
if (autospace) {
|
||||
if (phrase.at(-1) === JOIN_ACTION) {
|
||||
if (
|
||||
phrase.every(
|
||||
(action, i, arr) =>
|
||||
$KEYMAP_CODES.get(action)?.printable || i === arr.length - 1,
|
||||
)
|
||||
) {
|
||||
ondeleteaction!(phrase.length - 1);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (isPrintable) {
|
||||
return;
|
||||
} else if (phrase.at(-1) === NO_CONCATENATOR_ACTION) {
|
||||
ondeleteaction!(phrase.length - 1);
|
||||
} else {
|
||||
oninsertaction!(phrase.length, JOIN_ACTION);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (phrase.at(-1) === JOIN_ACTION) {
|
||||
ondeleteaction!(phrase.length - 1);
|
||||
} else {
|
||||
if (phrase.at(-1) === NO_CONCATENATOR_ACTION) {
|
||||
if (
|
||||
phrase.every(
|
||||
(action, i, arr) =>
|
||||
$KEYMAP_CODES.get(action)?.printable || i === arr.length - 1,
|
||||
)
|
||||
) {
|
||||
return;
|
||||
} else {
|
||||
ondeleteaction!(phrase.length - 1);
|
||||
}
|
||||
} else {
|
||||
oninsertaction!(phrase.length, NO_CONCATENATOR_ACTION);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let button: HTMLButtonElement | undefined = $state();
|
||||
let box: HTMLDivElement | undefined = $state();
|
||||
let cursorPosition = 0;
|
||||
let cursorOffset = $state(0);
|
||||
|
||||
let hasFocus = $state(false);
|
||||
|
||||
let isPrintable = $derived(
|
||||
phrase.every((action) => $KEYMAP_CODES.get(action)?.printable === true),
|
||||
);
|
||||
let supportsAutospace = $derived(
|
||||
semverGte($deviceMeta?.version ?? "0.0.0", "2.1.0"),
|
||||
);
|
||||
let hasAutospace = $derived(isPrintable || phrase.at(-1) === JOIN_ACTION);
|
||||
|
||||
let displayPhrase = $derived(
|
||||
phrase.filter(
|
||||
(it, i, arr) =>
|
||||
!(
|
||||
(i === 0 && it === JOIN_ACTION) ||
|
||||
(i === arr.length - 1 &&
|
||||
(it === JOIN_ACTION || it === NO_CONCATENATOR_ACTION))
|
||||
),
|
||||
),
|
||||
);
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="wrapper"
|
||||
class:edited
|
||||
onclick={interactive
|
||||
? () => {
|
||||
box.focus();
|
||||
}
|
||||
: undefined}
|
||||
>
|
||||
{#if supportsAutospace}
|
||||
<label
|
||||
class="auto-space-edit"
|
||||
use:action={{ title: "Remove previous concatenator" }}
|
||||
><span class="icon">join_inner</span><input
|
||||
checked={phrase[0] === JOIN_ACTION}
|
||||
disabled={!interactive}
|
||||
onchange={interactive
|
||||
? (event) => {
|
||||
const autospace = hasAutospace;
|
||||
if ((event.target as HTMLInputElement).checked) {
|
||||
if (phrase[0] !== JOIN_ACTION) {
|
||||
oninsertaction!(0, JOIN_ACTION);
|
||||
}
|
||||
} else {
|
||||
if (phrase[0] === JOIN_ACTION) {
|
||||
ondeleteaction!(0, 1);
|
||||
}
|
||||
}
|
||||
tick().then(() => resolveAutospace(autospace));
|
||||
}
|
||||
: undefined}
|
||||
type="checkbox"
|
||||
/></label
|
||||
>
|
||||
{/if}
|
||||
<div
|
||||
onkeydown={interactive ? keypress : undefined}
|
||||
onmousedown={interactive ? clickCursor : undefined}
|
||||
role="textbox"
|
||||
tabindex="0"
|
||||
bind:this={box}
|
||||
onfocusin={interactive ? () => (hasFocus = true) : undefined}
|
||||
onfocusout={interactive
|
||||
? (event) => {
|
||||
if (event.relatedTarget !== button) hasFocus = false;
|
||||
}
|
||||
: undefined}
|
||||
>
|
||||
{#if hasFocus}
|
||||
<div transition:scale class="cursor" style:translate="{cursorOffset}px 0">
|
||||
<button class="icon" bind:this={button} onclick={addSpecial}>add</button
|
||||
>
|
||||
</div>
|
||||
{:else}
|
||||
<div></div>
|
||||
<!-- placeholder for cursor placement -->
|
||||
{/if}
|
||||
<ActionString actions={displayPhrase} />
|
||||
</div>
|
||||
{#if supportsAutospace}
|
||||
<label class="auto-space-edit" use:action={{ title: "Add concatenator" }}
|
||||
><span class="icon">space_bar</span><input
|
||||
checked={hasAutospace}
|
||||
disabled={!interactive}
|
||||
onchange={interactive
|
||||
? (event) =>
|
||||
resolveAutospace((event.target as HTMLInputElement).checked)
|
||||
: undefined}
|
||||
type="checkbox"
|
||||
/></label
|
||||
>
|
||||
{/if}
|
||||
<sup>•</sup>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
sup {
|
||||
translate: 0 -40%;
|
||||
opacity: 0;
|
||||
transition: opacity 250ms ease;
|
||||
}
|
||||
|
||||
.cursor {
|
||||
position: absolute;
|
||||
transform: translateX(-50%);
|
||||
translate: 0 0;
|
||||
|
||||
transition: translate 50ms ease;
|
||||
|
||||
background: var(--md-sys-color-on-secondary-container);
|
||||
|
||||
width: 2px;
|
||||
height: 100%;
|
||||
|
||||
button {
|
||||
position: absolute;
|
||||
top: -24px;
|
||||
left: 0;
|
||||
border: 2px solid currentcolor;
|
||||
border-radius: 12px 12px 12px 0;
|
||||
|
||||
background: var(--md-sys-color-secondary-container);
|
||||
padding: 0;
|
||||
|
||||
height: 24px;
|
||||
|
||||
color: var(--md-sys-color-on-secondary-container);
|
||||
}
|
||||
}
|
||||
|
||||
.edited {
|
||||
color: var(--md-sys-color-primary);
|
||||
|
||||
sup {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.auto-space-edit {
|
||||
margin-inline: 8px;
|
||||
border-radius: 4px;
|
||||
background: var(--md-sys-color-tertiary-container);
|
||||
padding-inline: 0;
|
||||
height: 1em;
|
||||
color: var(--md-sys-color-on-tertiary-container);
|
||||
font-size: 1.3em;
|
||||
|
||||
&:first-of-type:not(:has(:checked)),
|
||||
&:last-of-type:has(:checked) {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.wrapper:hover .auto-space-edit {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
display: flex;
|
||||
|
||||
position: relative;
|
||||
align-items: center;
|
||||
|
||||
padding-block: 4px;
|
||||
|
||||
height: 1em;
|
||||
|
||||
&::after,
|
||||
&::before {
|
||||
position: absolute;
|
||||
bottom: -4px;
|
||||
|
||||
opacity: 0;
|
||||
|
||||
transition:
|
||||
opacity 150ms ease,
|
||||
scale 250ms ease;
|
||||
background: currentcolor;
|
||||
|
||||
width: calc(100% - 8px);
|
||||
height: 1px;
|
||||
content: "";
|
||||
}
|
||||
|
||||
&::after {
|
||||
scale: 0 1;
|
||||
transition-duration: 250ms;
|
||||
}
|
||||
|
||||
&:hover::before {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
&:has(> :focus-within)::after {
|
||||
scale: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
[role="textbox"] {
|
||||
display: flex;
|
||||
|
||||
position: relative;
|
||||
align-items: center;
|
||||
cursor: text;
|
||||
white-space: pre;
|
||||
|
||||
&:focus-within {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -133,14 +133,16 @@
|
||||
/></label
|
||||
>
|
||||
{#each $KEYMAP_CATEGORIES as category}
|
||||
<label
|
||||
>{category.name}<input
|
||||
name="category"
|
||||
type="radio"
|
||||
value={new Set(Object.keys(category.actions).map(Number))}
|
||||
bind:group={filter}
|
||||
/></label
|
||||
>
|
||||
{#if category.name !== "Internal"}
|
||||
<label
|
||||
>{category.name}<input
|
||||
name="category"
|
||||
type="radio"
|
||||
value={new Set(Object.keys(category.actions).map(Number))}
|
||||
bind:group={filter}
|
||||
/></label
|
||||
>
|
||||
{/if}
|
||||
{/each}
|
||||
</fieldset>
|
||||
{#if currentAction !== undefined}
|
||||
|
||||
@@ -17,7 +17,7 @@ export async function getMeta(
|
||||
try {
|
||||
if (!browser) return fetchMeta(device, version, fetch);
|
||||
|
||||
const dbRequest = indexedDB.open("version-meta", 5);
|
||||
const dbRequest = indexedDB.open("version-meta", 6);
|
||||
const db = await new Promise<IDBDatabase>((resolve, reject) => {
|
||||
dbRequest.onsuccess = () => resolve(dbRequest.result);
|
||||
dbRequest.onerror = () => reject(dbRequest.error);
|
||||
@@ -130,6 +130,9 @@ async function fetchMeta(
|
||||
async (load) => load().then((it) => (it as any).default),
|
||||
),
|
||||
)),
|
||||
recipes: await (meta?.recipes
|
||||
? fetch(`${path}/${meta.recipes}`).then((it) => it.json())
|
||||
: undefined),
|
||||
update: {
|
||||
uf2:
|
||||
meta?.update?.uf2 ??
|
||||
|
||||
@@ -13,6 +13,7 @@ export interface SettingsMeta {
|
||||
|
||||
export interface SettingsItemMeta {
|
||||
id: number;
|
||||
name?: string;
|
||||
description?: string;
|
||||
enum?: string[];
|
||||
range: [number, number];
|
||||
@@ -43,6 +44,7 @@ export interface RawVersionMeta {
|
||||
actions: string;
|
||||
settings: string;
|
||||
changelog: string;
|
||||
recipes: string;
|
||||
factory_defaults: {
|
||||
layout: string;
|
||||
settings: string;
|
||||
@@ -61,6 +63,38 @@ export interface RawVersionMeta {
|
||||
spi_flash: SPIFlashInfo | null;
|
||||
}
|
||||
|
||||
export interface E2eAddChord {
|
||||
input: string[][];
|
||||
output: string[];
|
||||
}
|
||||
|
||||
export interface E2eTestItem {
|
||||
keys?: string[];
|
||||
modifiers?: Record<string, boolean>;
|
||||
press?: string[];
|
||||
release?: string[];
|
||||
step?: number;
|
||||
idle?: boolean;
|
||||
clearChords?: boolean;
|
||||
addChords?: E2eAddChord[];
|
||||
settings: Record<string, Record<string, string | number>>;
|
||||
}
|
||||
|
||||
export interface E2eTest {
|
||||
matrix?: string[];
|
||||
test: E2eTestItem[];
|
||||
}
|
||||
|
||||
export interface E2eDemo {
|
||||
demo?: {
|
||||
id?: string;
|
||||
title?: string;
|
||||
description?: string;
|
||||
};
|
||||
matrix?: string[];
|
||||
tests: E2eTest[];
|
||||
}
|
||||
|
||||
export interface VersionMeta {
|
||||
version: string;
|
||||
device: string;
|
||||
@@ -73,6 +107,7 @@ export interface VersionMeta {
|
||||
actions: KeymapCategory[];
|
||||
settings: SettingsMeta[];
|
||||
changelog: Changelog;
|
||||
recipes?: E2eTest[];
|
||||
factoryDefaults?: {
|
||||
layout: CharaLayoutFile;
|
||||
settings: CharaSettingsFile;
|
||||
|
||||
@@ -11,6 +11,7 @@ async function updateLayout() {
|
||||
layout.size !== currentLayout.size ||
|
||||
[...layout.keys()].some((key) => layout.get(key) !== currentLayout.get(key))
|
||||
) {
|
||||
console.log(layout);
|
||||
osLayout.set(layout);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,5 +29,10 @@ export async function fromBase64(
|
||||
.replaceAll(".", "+")
|
||||
.replaceAll("_", "/")
|
||||
.replaceAll("-", "=")}`,
|
||||
).then((it) => it.blob());
|
||||
)
|
||||
.then((it) => {
|
||||
console.log(it);
|
||||
return it;
|
||||
})
|
||||
.then((it) => it.blob());
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { page } from "$app/stores";
|
||||
import { deviceMeta } from "$lib/serial/connection";
|
||||
|
||||
const routes = [
|
||||
let routes = $derived([
|
||||
[
|
||||
{
|
||||
href: "/config/settings/",
|
||||
@@ -11,6 +12,9 @@
|
||||
},
|
||||
{ href: "/config/chords/", icon: "dictionary", title: "Library" },
|
||||
{ href: "/config/layout/", icon: "keyboard", title: "Layout" },
|
||||
...($deviceMeta?.recipes
|
||||
? [{ href: "/recipes", icon: "skillet", title: "Cookbook" }]
|
||||
: []),
|
||||
],
|
||||
[
|
||||
{
|
||||
@@ -47,7 +51,7 @@
|
||||
wip?: boolean;
|
||||
external?: boolean;
|
||||
primary?: boolean;
|
||||
}[][];
|
||||
}[][]);
|
||||
|
||||
let connectButton: HTMLButtonElement;
|
||||
</script>
|
||||
|
||||
@@ -19,12 +19,7 @@
|
||||
{#each data.versions as version}
|
||||
{@const isPrerelease = version.name.includes("-")}
|
||||
<li class:pre-release={isPrerelease}>
|
||||
<a href="./{version.name}/"
|
||||
>{version.name}
|
||||
<time datetime={version.mtime}
|
||||
>{new Date(version.mtime).toLocaleDateString()}</time
|
||||
></a
|
||||
>
|
||||
<a href="./{version.name}/">{version.name}</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
@@ -70,14 +65,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
time {
|
||||
opacity: 0.5;
|
||||
&:before {
|
||||
padding-inline: 0.4ch;
|
||||
content: "•";
|
||||
}
|
||||
}
|
||||
|
||||
div.title:has(input:not(:checked)) ~ ul .pre-release {
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
|
||||
@@ -344,6 +344,15 @@
|
||||
|
||||
<section class="changelog">
|
||||
<h2>Changelog</h2>
|
||||
|
||||
<time datetime={data.meta.date.toISOString()}
|
||||
>Published {data.meta.date.toLocaleDateString()}</time
|
||||
>
|
||||
|
||||
{#if data.meta.recipes}
|
||||
<p>Includes {data.meta.recipes.length} recipes</p>
|
||||
{/if}
|
||||
|
||||
{#if data.meta.changelog.features}
|
||||
<h3>Features</h3>
|
||||
<ul>
|
||||
|
||||
@@ -1,232 +0,0 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
compileLayout,
|
||||
type VisualLayout,
|
||||
} from "$lib/serialization/visual-layout";
|
||||
import ccxLayout from "$lib/assets/layouts/generic/103-key.yml";
|
||||
import keycodes from "./keycodes.json";
|
||||
|
||||
let width = $state(16);
|
||||
let height = $state(16);
|
||||
|
||||
let layout = $state(compileLayout(ccxLayout as VisualLayout));
|
||||
let layoutMargin = $state(0.2);
|
||||
|
||||
let timelineCanvas = $state<HTMLCanvasElement | undefined>(undefined);
|
||||
|
||||
interface Report {
|
||||
modifiers?: number;
|
||||
keys?: number[];
|
||||
}
|
||||
|
||||
interface Tick {
|
||||
ms?: number;
|
||||
reports?: Report[];
|
||||
keys?: number[];
|
||||
}
|
||||
|
||||
let test: Tick[] = $state([
|
||||
{ ms: 1, reports: [{ keys: [4] }], keys: [4] },
|
||||
{ ms: 2, reports: [{ keys: [4, 2] }], keys: [4, 12] },
|
||||
]);
|
||||
|
||||
function timelineData<T extends { ms: number }>(
|
||||
ticks: T[],
|
||||
value: (tick: T) => number[],
|
||||
) {
|
||||
let totalTicks = 0;
|
||||
const result = new Map<number, [number, number][]>();
|
||||
for (const tick of ticks) {
|
||||
const key = value(tick);
|
||||
}
|
||||
}
|
||||
|
||||
let timelineData = $derived.by(() => {
|
||||
const result = new Map<number, [number, number][]>();
|
||||
for (const tick of test) {
|
||||
if (!tick.keys) continue;
|
||||
if (Array.isArray(action)) {
|
||||
if (typeof action[0] === "number") {
|
||||
ticks.push([action[0]]);
|
||||
totalTicks++;
|
||||
} else if (action.length === 0) {
|
||||
ticks.push([1]);
|
||||
totalTicks++;
|
||||
}
|
||||
}
|
||||
if (typeof action !== "number") continue;
|
||||
if (action >= 0) {
|
||||
if (!result.has(action)) {
|
||||
result.set(action, []);
|
||||
}
|
||||
result.get(action)!.push([totalTicks, test.length - 1]);
|
||||
} else {
|
||||
const value = result.get(~action)?.at(-1);
|
||||
if (!value || value[1] !== test.length - 1) continue;
|
||||
value[1] = totalTicks;
|
||||
}
|
||||
}
|
||||
return {
|
||||
totalTicks,
|
||||
ticks,
|
||||
presses: [...result.entries()].sort(([a], [b]) => a - b),
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<h1>E2E Testing</h1>
|
||||
|
||||
{#snippet Layout(keys: Set<number>)}
|
||||
<svg viewBox="0 0 {layout.size[0]} {layout.size[1]}">
|
||||
{#each layout.keys as key}
|
||||
{#if key.shape === "square"}
|
||||
<rect
|
||||
x={key.pos[0] + layoutMargin / 2}
|
||||
y={key.pos[1] + layoutMargin / 2}
|
||||
rx={0.5 - layoutMargin / 2}
|
||||
width={key.size[0] - layoutMargin}
|
||||
height={key.size[1] - layoutMargin}
|
||||
fill={keys.has(key.id)
|
||||
? "var(--md-sys-color-primary)"
|
||||
: "var(--md-sys-color-on-surface)"}
|
||||
opacity={keys.has(key.id) ? 1 : 0.1}
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
</svg>
|
||||
{/snippet}
|
||||
|
||||
<canvas bind:this={timelineCanvas}></canvas>
|
||||
|
||||
<div class="t">
|
||||
{#each test as { ms, reports, keys }}
|
||||
<div class="tick">
|
||||
{ms}ms
|
||||
<div class="keys">
|
||||
{#each keys ?? [] as key}
|
||||
<kbd>{keycodes[key] ?? key}</kbd>
|
||||
{/each}
|
||||
<button class="icon">+</button>
|
||||
</div>
|
||||
{@render Layout(new Set(keys))}
|
||||
{#each reports ?? [] as report}
|
||||
<div class="report">
|
||||
<div class="modifiers">{report.modifiers}</div>
|
||||
<div class="keys">
|
||||
{#each report.keys ?? [] as key}
|
||||
<kbd>{keycodes[key] ?? key}</kbd>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
{#each test as action, i}
|
||||
{@const isActionTick = Array.isArray(action)}
|
||||
{@const isActionPress = typeof action === "number" && action >= 0}
|
||||
{@const isActionRelease = typeof action === "number" && action < 0}
|
||||
{#if isActionTick}
|
||||
<div class="tick">
|
||||
<span class="icon">step_over</span>
|
||||
{action[0]}ms
|
||||
</div>
|
||||
{#if action[1]}
|
||||
<div class="report">
|
||||
{#each Array.from({ length: 8 }) as _, j}
|
||||
<div class="modifier">{j}</div>
|
||||
{/each}
|
||||
{#each action[1][1] as key}
|
||||
<div class="key">
|
||||
{key}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{:else if typeof action === "string"}
|
||||
<div>Command: {action}</div>
|
||||
{:else if isActionPress}
|
||||
<button class="release" onclick={() => (test[i] = ~action)}
|
||||
>{action}</button
|
||||
>
|
||||
{:else if isActionRelease}
|
||||
<button class="press" onclick={() => (test[i] = ~action)}
|
||||
>{~action}</button
|
||||
>
|
||||
{:else}
|
||||
<div>Unsupported {action}</div>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
svg {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
$shadow-inset: 1px;
|
||||
|
||||
.timeline {
|
||||
display: grid;
|
||||
grid-template-rows: auto repeat(auto-fit, minmax(var(--height), 1fr));
|
||||
}
|
||||
|
||||
.timeline-press {
|
||||
margin-inline: calc(var(--width) / 2);
|
||||
border-radius: calc(var(--height) / 2);
|
||||
background-color: var(--md-sys-color-surface-variant);
|
||||
height: var(--height);
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.tick {
|
||||
display: flex;
|
||||
position: relative;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
cursor: ew-resize;
|
||||
padding: 0.5rem;
|
||||
user-select: none;
|
||||
|
||||
span.icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
border: none;
|
||||
padding: 8px;
|
||||
aspect-ratio: 1;
|
||||
user-select: none;
|
||||
|
||||
&.release {
|
||||
box-shadow:
|
||||
inset #{$shadow-inset} #{$shadow-inset} #{$shadow-inset * 2}
|
||||
rgba(0, 0, 0, 0.6),
|
||||
inset -#{$shadow-inset} -#{$shadow-inset} #{$shadow-inset * 2}
|
||||
rgba(255, 255, 255, 0.2);
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
&.press {
|
||||
box-shadow:
|
||||
#{$shadow-inset} #{$shadow-inset} #{$shadow-inset * 2}
|
||||
rgba(0, 0, 0, 0.6),
|
||||
-#{$shadow-inset} -#{$shadow-inset} #{$shadow-inset * 2}
|
||||
rgba(255, 255, 255, 0.2);
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,251 +0,0 @@
|
||||
[
|
||||
"reserved",
|
||||
"esc",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"0",
|
||||
"-",
|
||||
"=",
|
||||
"bksp",
|
||||
"tab",
|
||||
"q",
|
||||
"w",
|
||||
"e",
|
||||
"r",
|
||||
"t",
|
||||
"y",
|
||||
"u",
|
||||
"i",
|
||||
"o",
|
||||
"p",
|
||||
"[",
|
||||
"]",
|
||||
"enter",
|
||||
"lctrl",
|
||||
"a",
|
||||
"s",
|
||||
"d",
|
||||
"f",
|
||||
"g",
|
||||
"h",
|
||||
"j",
|
||||
"k",
|
||||
"l",
|
||||
";",
|
||||
"'",
|
||||
"`",
|
||||
"lshift",
|
||||
"\\",
|
||||
"z",
|
||||
"x",
|
||||
"c",
|
||||
"v",
|
||||
"b",
|
||||
"n",
|
||||
"m",
|
||||
",",
|
||||
".",
|
||||
"/",
|
||||
"rshift",
|
||||
"kp*",
|
||||
"lalt",
|
||||
"_",
|
||||
"capslock",
|
||||
"f1",
|
||||
"f2",
|
||||
"f3",
|
||||
"f4",
|
||||
"f5",
|
||||
"f6",
|
||||
"f7",
|
||||
"f8",
|
||||
"f9",
|
||||
"f10",
|
||||
"numlock",
|
||||
"scrolllock",
|
||||
"kp7",
|
||||
"kp8",
|
||||
"kp9",
|
||||
"kp-",
|
||||
"kp4",
|
||||
"kp5",
|
||||
"kp6",
|
||||
"kp+",
|
||||
"kp1",
|
||||
"kp2",
|
||||
"kp3",
|
||||
"kp0",
|
||||
"kp.",
|
||||
"ksc_84",
|
||||
"zenkaku_hankaku",
|
||||
"102nd",
|
||||
"f11",
|
||||
"f12",
|
||||
"ro",
|
||||
"katakana",
|
||||
"hiragana",
|
||||
"henkan",
|
||||
"katakana_hiragana",
|
||||
"muhenkan",
|
||||
"kp,",
|
||||
"kp_enter",
|
||||
"rctrl",
|
||||
"kp/",
|
||||
"sysrq",
|
||||
"ralt",
|
||||
"linefeed",
|
||||
"home",
|
||||
"up",
|
||||
"pageup",
|
||||
"left",
|
||||
"right",
|
||||
"end",
|
||||
"down",
|
||||
"pagedown",
|
||||
"insert",
|
||||
"delete",
|
||||
"macro",
|
||||
"mute",
|
||||
"volume_down",
|
||||
"volume_up",
|
||||
"power",
|
||||
"kp=",
|
||||
"kp+-",
|
||||
"pause",
|
||||
"scale",
|
||||
"kp,",
|
||||
"hangeul",
|
||||
"hanja",
|
||||
"yen",
|
||||
"lmeta",
|
||||
"rmeta",
|
||||
"compose",
|
||||
"stop",
|
||||
"again",
|
||||
"props",
|
||||
"undo",
|
||||
"front",
|
||||
"copy",
|
||||
"open",
|
||||
"paste",
|
||||
"find",
|
||||
"cut",
|
||||
"help",
|
||||
"menu",
|
||||
"calc",
|
||||
"setup",
|
||||
"sleep",
|
||||
"wakeup",
|
||||
"file",
|
||||
"sendfile",
|
||||
"deletefile",
|
||||
"xfer",
|
||||
"prog1",
|
||||
"prog2",
|
||||
"www",
|
||||
"msdos",
|
||||
"coffee",
|
||||
"rotate_display",
|
||||
"cyclewindows",
|
||||
"mail",
|
||||
"bookmarks",
|
||||
"computer",
|
||||
"back",
|
||||
"forward",
|
||||
"close_cd",
|
||||
"eject_cd",
|
||||
"eject_close_cd",
|
||||
"next_song",
|
||||
"play_pause",
|
||||
"prev_song",
|
||||
"stop_cd",
|
||||
"record",
|
||||
"rewind",
|
||||
"phone",
|
||||
"iso",
|
||||
"config",
|
||||
"homepage",
|
||||
"refresh",
|
||||
"exit",
|
||||
"move",
|
||||
"edit",
|
||||
"scroll_up",
|
||||
"scroll_down",
|
||||
"kp_left_paren",
|
||||
"kp_right_paren",
|
||||
"new",
|
||||
"redo",
|
||||
"f13",
|
||||
"f14",
|
||||
"f15",
|
||||
"f16",
|
||||
"f17",
|
||||
"f18",
|
||||
"f19",
|
||||
"f20",
|
||||
"f21",
|
||||
"f22",
|
||||
"f23",
|
||||
"f24",
|
||||
"sc_195",
|
||||
"sc_196",
|
||||
"sc_197",
|
||||
"sc_198",
|
||||
"sc_199",
|
||||
"play_cd",
|
||||
"pause_cd",
|
||||
"prog3",
|
||||
"prog4",
|
||||
"all_applications",
|
||||
"suspend",
|
||||
"close",
|
||||
"play",
|
||||
"fastforward",
|
||||
"bass_boost",
|
||||
"print",
|
||||
"hp",
|
||||
"camera",
|
||||
"sound",
|
||||
"question",
|
||||
"email",
|
||||
"chat",
|
||||
"search",
|
||||
"connect",
|
||||
"finance",
|
||||
"sport",
|
||||
"shop",
|
||||
"alterase",
|
||||
"cancel",
|
||||
"brightness_down",
|
||||
"brightness_up",
|
||||
"media",
|
||||
"switch_video_mode",
|
||||
"kbd_illum_toggle",
|
||||
"kbd_illum_down",
|
||||
"kbd_illum_up",
|
||||
"send",
|
||||
"reply",
|
||||
"forward_mail",
|
||||
"save",
|
||||
"documents",
|
||||
"battery",
|
||||
"bluetooth",
|
||||
"wlan",
|
||||
"uwb",
|
||||
"unknown",
|
||||
"video_next",
|
||||
"video_prev",
|
||||
"brightness_cycle",
|
||||
"brightness_auto",
|
||||
"display_off",
|
||||
"wwan",
|
||||
"rfkill",
|
||||
"mic_mute"
|
||||
]
|
||||
85
src/routes/(app)/e2e/replay/+page.svelte
Normal file
85
src/routes/(app)/e2e/replay/+page.svelte
Normal file
@@ -0,0 +1,85 @@
|
||||
<script lang="ts">
|
||||
import type { PageData } from "./$types";
|
||||
|
||||
let { data }: { data: PageData } = $props();
|
||||
|
||||
$effect(() => {
|
||||
console.log(data);
|
||||
});
|
||||
</script>
|
||||
|
||||
<details>
|
||||
<summary>Full Log</summary>
|
||||
{#each data.data as item, i}
|
||||
{#if "press" in item}
|
||||
<div class="press">{item.press}</div>
|
||||
{:else if "release" in item}
|
||||
<div class="release">{item.release}</div>
|
||||
{:else if "keys" in item}
|
||||
<div class="report">
|
||||
<span class="icon">keyboard</span>
|
||||
<div class="modifiers">
|
||||
{item.modifiers.toString(2)}
|
||||
</div>
|
||||
<div class="keys">{item.keys.join(", ")}</div>
|
||||
</div>
|
||||
{:else if "out" in item}
|
||||
<pre class="out">{item.out}</pre>
|
||||
{:else if "in" in item}
|
||||
<pre class="in">{item.in}</pre>
|
||||
{:else if "tick" in item}
|
||||
<div class="tick"><span class="icon">timer_play</span>{item.tick}ms</div>
|
||||
{:else}
|
||||
<div>Unknown log item at index {i}</div>
|
||||
{/if}
|
||||
{/each}
|
||||
</details>
|
||||
|
||||
<style lang="scss">
|
||||
details {
|
||||
margin-top: 1rem;
|
||||
border: 1px solid var(--md-sys-color-outline);
|
||||
border-radius: 0.5rem;
|
||||
background-color: var(--md-sys-color-surface-variant);
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.report {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
margin-bottom: 0.5rem;
|
||||
border-radius: 0.25rem;
|
||||
background-color: var(--md-sys-color-primary-container);
|
||||
padding: 0.5rem;
|
||||
color: var(--md-sys-color-on-primary-container);
|
||||
}
|
||||
|
||||
.out {
|
||||
color: var(--md-sys-color-primary);
|
||||
}
|
||||
|
||||
.in {
|
||||
color: var(--md-sys-color-secondary);
|
||||
}
|
||||
|
||||
.tick {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.2rem 0.5rem;
|
||||
width: fit-content;
|
||||
color: var(--md-sys-color-tertiary);
|
||||
font-size: 0.6rem;
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
input[type="range"] {
|
||||
margin-bottom: 1rem;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
49
src/routes/(app)/e2e/replay/+page.ts
Normal file
49
src/routes/(app)/e2e/replay/+page.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import type { PageLoad } from "./$types";
|
||||
import { browser } from "$app/environment";
|
||||
import { fromBase64 } from "$lib/serialization/base64";
|
||||
|
||||
export interface ReplaySerialIn {
|
||||
in: string;
|
||||
}
|
||||
|
||||
export interface ReplaySerialOut {
|
||||
out: string;
|
||||
}
|
||||
|
||||
export interface ReplaySerialReport {
|
||||
modifiers: number;
|
||||
keys: number[];
|
||||
}
|
||||
|
||||
export interface ReplaySerialPress {
|
||||
press: number;
|
||||
}
|
||||
|
||||
export interface ReplaySerialRelease {
|
||||
release: number;
|
||||
}
|
||||
|
||||
export interface ReplayTick {
|
||||
tick: number;
|
||||
}
|
||||
|
||||
export type ReplayDataItem =
|
||||
| ReplayTick
|
||||
| ReplaySerialIn
|
||||
| ReplaySerialOut
|
||||
| ReplaySerialReport
|
||||
| ReplaySerialPress
|
||||
| ReplaySerialRelease;
|
||||
|
||||
export const load = (async ({ url, fetch }) => {
|
||||
const replay = browser && new URLSearchParams(url.search).get("data");
|
||||
if (!replay) {
|
||||
return undefined;
|
||||
}
|
||||
const stream = (await fromBase64(replay, fetch))
|
||||
.stream()
|
||||
.pipeThrough(new DecompressionStream("deflate"));
|
||||
return {
|
||||
data: JSON.parse(await new Response(stream).text()) as ReplayDataItem[],
|
||||
};
|
||||
}) satisfies PageLoad;
|
||||
64
src/routes/(app)/recipes/+page.svelte
Normal file
64
src/routes/(app)/recipes/+page.svelte
Normal file
@@ -0,0 +1,64 @@
|
||||
<script lang="ts">
|
||||
import { deviceMeta } from "$lib/serial/connection";
|
||||
import Demo from "./Demo.svelte";
|
||||
|
||||
let recipes = $derived(
|
||||
$deviceMeta?.recipes?.toSorted((a, b) => {
|
||||
if (a.demo == null) return 1;
|
||||
if (b.demo == null) return -1;
|
||||
return a.demo.title.localeCompare(b.demo.title);
|
||||
}),
|
||||
);
|
||||
</script>
|
||||
|
||||
<div class="page">
|
||||
<nav>
|
||||
{#each recipes as demo, i}
|
||||
{#if demo.demo?.title}
|
||||
<a href="#demo-{i}">
|
||||
{demo.demo?.title}
|
||||
</a>
|
||||
{/if}
|
||||
{/each}
|
||||
</nav>
|
||||
|
||||
<div class="recipes">
|
||||
<h1>Cookbook</h1>
|
||||
{#if recipes}
|
||||
{#each recipes as demo, i}
|
||||
<Demo {demo} {i} />
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.page {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 2rem;
|
||||
padding: 1rem;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.recipes {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 60px;
|
||||
overflow-y: auto;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
nav {
|
||||
display: flex;
|
||||
position: sticky;
|
||||
top: 1rem;
|
||||
flex-direction: column;
|
||||
align-self: flex-start;
|
||||
gap: 0.5rem;
|
||||
padding: 1rem;
|
||||
min-width: 200px;
|
||||
max-height: calc(100vh - 2rem);
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
86
src/routes/(app)/recipes/Demo.svelte
Normal file
86
src/routes/(app)/recipes/Demo.svelte
Normal file
@@ -0,0 +1,86 @@
|
||||
<script lang="ts">
|
||||
import type { E2eDemo } from "$lib/meta/types/meta";
|
||||
import Recipe from "./Recipe.svelte";
|
||||
|
||||
let {
|
||||
demo,
|
||||
i,
|
||||
}: {
|
||||
demo: E2eDemo;
|
||||
i: number;
|
||||
} = $props();
|
||||
|
||||
let paused = $state(true);
|
||||
|
||||
let config: boolean[] = $state([]);
|
||||
|
||||
let test = $derived.by(() => {
|
||||
if (!demo.matrix) return demo.tests[0];
|
||||
|
||||
const configuration = demo.matrix?.filter((_, i) => config[i]);
|
||||
return demo.tests.find(
|
||||
(test) => test && test.matrix?.toString() === configuration?.toString(),
|
||||
);
|
||||
});
|
||||
</script>
|
||||
|
||||
<section
|
||||
id={"demo-" + i}
|
||||
onmouseenter={() => (paused = false)}
|
||||
onmouseleave={() => (paused = true)}
|
||||
>
|
||||
{#if demo.demo}
|
||||
<h2>{demo.demo?.title}</h2>
|
||||
<p>{demo.demo?.description}</p>
|
||||
{/if}
|
||||
{#if demo.matrix}
|
||||
<div class="configuration">
|
||||
{#each demo.matrix as item, i}
|
||||
<label><input type="checkbox" bind:checked={config[i]} />{item}</label>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{#if test}
|
||||
<Recipe {test} {paused} />
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
<style lang="scss">
|
||||
section:target h2 {
|
||||
color: var(--md-sys-color-primary);
|
||||
}
|
||||
|
||||
section {
|
||||
max-width: 20cm;
|
||||
scroll-margin-top: 80px;
|
||||
}
|
||||
|
||||
section > :global(:not(h2)) {
|
||||
margin-inline-start: 24px;
|
||||
}
|
||||
|
||||
.configuration {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
margin-block: 8px;
|
||||
|
||||
label {
|
||||
background-color: var(--md-sys-color-surface-variant);
|
||||
padding-inline: 8px;
|
||||
padding-block: 4px;
|
||||
height: auto;
|
||||
color: var(--md-sys-color-on-surface-variant);
|
||||
|
||||
&:has(:checked) {
|
||||
background-color: var(--md-sys-color-primary);
|
||||
color: var(--md-sys-color-on-primary);
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
331
src/routes/(app)/recipes/Recipe.svelte
Normal file
331
src/routes/(app)/recipes/Recipe.svelte
Normal file
@@ -0,0 +1,331 @@
|
||||
<script lang="ts">
|
||||
import CharRecorder from "$lib/charrecorder/CharRecorder.svelte";
|
||||
import { ReplayPlayer } from "$lib/charrecorder/core/player";
|
||||
import type { Replay } from "$lib/charrecorder/core/types";
|
||||
import ActionString from "$lib/components/ActionString.svelte";
|
||||
import ChordPhraseDisplay from "$lib/components/ChordPhraseDisplay.svelte";
|
||||
import type { E2eTest, E2eTestItem } from "$lib/meta/types/meta";
|
||||
import { osLayout } from "$lib/os-layout";
|
||||
import { deviceMeta } from "$lib/serial/connection";
|
||||
import { KEYMAP_IDS } from "$lib/serial/keymap-codes";
|
||||
import type { ChordInfo } from "$lib/undo-redo";
|
||||
|
||||
let { test, paused = false }: { test: E2eTest; paused?: boolean } = $props();
|
||||
|
||||
let timescale = $state(10);
|
||||
let idleHold = $state(500);
|
||||
let pressHold = $state(250);
|
||||
let replayDelay = $state(1000);
|
||||
|
||||
let time = $state(0);
|
||||
|
||||
function getKeyRaw(key: string): string {
|
||||
return $KEYMAP_IDS.get(key)?.keyCode ?? key;
|
||||
}
|
||||
|
||||
const keyMap = new Map<string, string>(
|
||||
Object.entries({
|
||||
ENTER: "\n",
|
||||
SPACE: " ",
|
||||
TAB: "\t",
|
||||
BKSP: "Backspace",
|
||||
}),
|
||||
);
|
||||
|
||||
function getKeyMapped(key: string, shift: boolean): string {
|
||||
let value = $osLayout.get(getKeyRaw(key)) ?? key;
|
||||
value = keyMap.get(value) ?? value;
|
||||
return shift ? value.toUpperCase() : value;
|
||||
}
|
||||
|
||||
function advanceTime(
|
||||
step: E2eTestItem,
|
||||
timescale: number,
|
||||
idleHold: number,
|
||||
): number {
|
||||
return (
|
||||
(step.skip ?? step.step ?? 1) * timescale +
|
||||
(step.idle ? idleHold : 0) +
|
||||
(step.press ? pressHold : 0)
|
||||
);
|
||||
}
|
||||
|
||||
let replay: Replay = $derived.by(() => {
|
||||
const replay: Replay = {
|
||||
start: 0,
|
||||
finish: 0,
|
||||
keys: [],
|
||||
};
|
||||
let timeIndex = 0;
|
||||
let held = new Map<string, any>();
|
||||
for (const it of test.test) {
|
||||
if (it.keys) {
|
||||
for (const key of it.keys) {
|
||||
if (held.has(key)) continue;
|
||||
const raw = getKeyRaw(key);
|
||||
const mapped = getKeyMapped(key, it.modifiers?.["lshift"] == true);
|
||||
held.set(key, [mapped, raw, timeIndex, 0]);
|
||||
replay.keys.push(held.get(key));
|
||||
}
|
||||
for (const [key, value] of held) {
|
||||
if (!it.keys.includes(key)) {
|
||||
value[3] = timeIndex - value[2];
|
||||
held.delete(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
timeIndex += advanceTime(it, timescale, idleHold);
|
||||
}
|
||||
|
||||
replay.finish = timeIndex;
|
||||
return replay;
|
||||
});
|
||||
|
||||
let graph = $derived.by(() => {
|
||||
const rows: string[][] = [[]];
|
||||
for (const it of test.test) {
|
||||
if (it.keys?.includes("BKSP")) {
|
||||
if (rows.at(-1)!.at(-1) === " ") {
|
||||
rows.at(-1)!.pop();
|
||||
} else {
|
||||
rows.push(Array.from({ length: rows.at(-1)!.length - 1 }, () => " "));
|
||||
}
|
||||
} else {
|
||||
for (const key of it.keys ?? []) {
|
||||
if (key === "SPACE") {
|
||||
rows.at(-1)!.push("␣");
|
||||
} else if (key === "ENTER") {
|
||||
rows.at(-1)!.push("↵");
|
||||
} else {
|
||||
rows
|
||||
.at(-1)!
|
||||
.push(getKeyMapped(key, it.modifiers?.["lshift"] == true));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rows;
|
||||
});
|
||||
|
||||
let chords = $derived(
|
||||
test.test
|
||||
.flatMap((step) => step.addChords ?? [])
|
||||
.map(({ input, output }) => ({
|
||||
input: input.map((chord) =>
|
||||
chord.map((it) => $KEYMAP_IDS.get(it)?.code ?? 0),
|
||||
),
|
||||
output: output.map((it) => $KEYMAP_IDS.get(it)?.code ?? 0),
|
||||
})),
|
||||
);
|
||||
|
||||
let settings = $derived(
|
||||
test.test
|
||||
.flatMap((step) => (step.settings ? Object.entries(step.settings) : []))
|
||||
.flatMap(([key, value]) => {
|
||||
const category = $deviceMeta?.settings.find((it) => it.name === key);
|
||||
return Object.entries(value).map(([subkey, subvalue]) => [
|
||||
category?.items.find((it) => it.name === subkey),
|
||||
subvalue,
|
||||
]);
|
||||
}),
|
||||
);
|
||||
|
||||
let keysUsed = $derived.by(() => {
|
||||
const keys = new Map<number, number[]>();
|
||||
let time = 0;
|
||||
for (const step of test.test) {
|
||||
for (const key of step.press ?? []) {
|
||||
const keyCode = $KEYMAP_IDS.get(key)?.code ?? 0;
|
||||
if (!keys.has(keyCode)) {
|
||||
keys.set(keyCode, []);
|
||||
}
|
||||
keys.get(keyCode)!.push(time);
|
||||
}
|
||||
|
||||
for (const key of step.release ?? []) {
|
||||
const keyCode = $KEYMAP_IDS.get(key)?.code ?? 0;
|
||||
keys.get(keyCode)!.push(time);
|
||||
}
|
||||
|
||||
time += advanceTime(step, timescale, idleHold);
|
||||
}
|
||||
|
||||
return keys;
|
||||
});
|
||||
|
||||
function isKeyPressed(times: number[], time: number): boolean {
|
||||
return (
|
||||
times.findIndex(
|
||||
(t, i, arr) => time >= t && (arr[i + 1] ?? Infinity) > time,
|
||||
) %
|
||||
2 ===
|
||||
0
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="replay">
|
||||
<CharRecorder
|
||||
{replay}
|
||||
{paused}
|
||||
cursor={true}
|
||||
keys={false}
|
||||
ondone={() => setTimeout(() => (replay = { ...replay }), replayDelay)}
|
||||
ontick={(t) => (time = t)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="keystaff">
|
||||
{#each keysUsed as [action, times]}
|
||||
<div class="keystaff-item" class:active={isKeyPressed(times, time)}>
|
||||
<ActionString actions={[action]} />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<details>
|
||||
<div class="graph">
|
||||
{#each graph as row, i}
|
||||
{#each row as char, j}
|
||||
{#if char !== " "}
|
||||
<div
|
||||
class:deleted={(graph[i + 1]?.findIndex((it) => it !== " ") ??
|
||||
Infinity) <= j}
|
||||
style:grid-row={i + 1}
|
||||
style:grid-column={j + 1}
|
||||
>
|
||||
{char}
|
||||
</div>
|
||||
{/if}
|
||||
{/each}
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
{#if chords.length > 0}
|
||||
<h3>Chords Used</h3>
|
||||
<div class="chords">
|
||||
{#each chords as { input, output }}
|
||||
<div class="input">
|
||||
{#each input as actions}
|
||||
<div class="compound">
|
||||
<ActionString display="keys" {actions} />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<div class="output">
|
||||
<ActionString actions={output} />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{#if settings.length > 0}
|
||||
<h3>Settings Changed</h3>
|
||||
<ul>
|
||||
{#each settings as [item, value]}
|
||||
<li>
|
||||
{item?.name ?? "Unknown Setting"}: {value?.toString()}
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
{/if}
|
||||
</details>
|
||||
|
||||
<style lang="scss">
|
||||
.chords {
|
||||
display: grid;
|
||||
column-gap: 1rem;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
width: fit-content;
|
||||
|
||||
.compound {
|
||||
display: inline-flex;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.input {
|
||||
display: flex;
|
||||
grid-column: 1;
|
||||
align-items: center;
|
||||
justify-self: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.output {
|
||||
grid-column: 2;
|
||||
justify-self: start;
|
||||
}
|
||||
}
|
||||
|
||||
.keystaff {
|
||||
$expo-out: cubic-bezier(0.16, 1, 0.3, 1);
|
||||
$time: 1s;
|
||||
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
width: fit-content;
|
||||
|
||||
.keystaff-item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
translate: 0 -8px;
|
||||
opacity: 0;
|
||||
transition:
|
||||
opacity $time $expo-out,
|
||||
translate $time $expo-out;
|
||||
border-radius: 4px;
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
|
||||
&.active {
|
||||
translate: 0;
|
||||
opacity: 1;
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.details {
|
||||
position: absolute;
|
||||
transform-origin: top;
|
||||
scale: 1 0.5;
|
||||
z-index: 1;
|
||||
margin-left: -17px;
|
||||
border: 1px solid var(--md-sys-color-outline);
|
||||
border-top: none;
|
||||
background-color: var(--md-sys-color-surface);
|
||||
padding: 16px;
|
||||
width: calc(100% + 2px);
|
||||
}
|
||||
|
||||
summary {
|
||||
cursor: pointer;
|
||||
margin-top: 0.5rem;
|
||||
font-weight: bold;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.replay {
|
||||
border-radius: 0.4rem;
|
||||
background: var(--md-sys-color-surface-variant);
|
||||
padding: 0.6rem;
|
||||
width: fit-content;
|
||||
color: var(--md-sys-color-on-surface-variant);
|
||||
font-weight: bold;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.graph {
|
||||
display: grid;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
width: min-content;
|
||||
}
|
||||
|
||||
.deleted {
|
||||
opacity: 0.6;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
</style>
|
||||
@@ -1,28 +0,0 @@
|
||||
<script lang="ts">
|
||||
import Recipe from "./Recipe.svelte";
|
||||
|
||||
const tests = import.meta.glob("$lib/assets/tests/**/*.yml");
|
||||
</script>
|
||||
|
||||
<h1>Recipes</h1>
|
||||
|
||||
<p>These are example uses, taken directly from our E2E testing library.</p>
|
||||
|
||||
<div class="recipes">
|
||||
{#each Object.entries(tests) as [path, resolver]}
|
||||
{#await resolver() then module}
|
||||
<section>
|
||||
<Recipe test={module.default} />
|
||||
</section>
|
||||
{/await}
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.recipes {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -1,148 +0,0 @@
|
||||
<script lang="ts">
|
||||
import CharRecorder from "$lib/charrecorder/CharRecorder.svelte";
|
||||
import type { Replay } from "$lib/charrecorder/core/types";
|
||||
import type { E2eTest } from "./test-types";
|
||||
|
||||
let { test }: { test: E2eTest } = $props();
|
||||
|
||||
const replace = new Map<string, string>([
|
||||
["SPACE", "Space"],
|
||||
["ENTER", "Enter"],
|
||||
["BKSP", "Backspace"],
|
||||
["e", "KeyE"],
|
||||
["t", "KeyT"],
|
||||
]);
|
||||
|
||||
const replaceOut = new Map<string, string>([
|
||||
["SPACE", " "],
|
||||
["ENTER", "\n"],
|
||||
["BKSP", "Backspace"],
|
||||
]);
|
||||
|
||||
let timescale = $state(10);
|
||||
let idleHold = $state(500);
|
||||
let replayDelay = $state(1000);
|
||||
|
||||
let replay: Replay = $derived.by(() => {
|
||||
const replay: Replay = {
|
||||
start: 0,
|
||||
finish: 0,
|
||||
keys: [],
|
||||
};
|
||||
let timeIndex = 0;
|
||||
let held = new Map<string, any>();
|
||||
for (const it of test.test) {
|
||||
if (it.keys) {
|
||||
for (const key of it.keys) {
|
||||
if (held.has(key)) continue;
|
||||
held.set(key, [
|
||||
replaceOut.get(key) ?? key,
|
||||
replace.get(key) ?? key,
|
||||
timeIndex,
|
||||
0,
|
||||
]);
|
||||
replay.keys.push(held.get(key));
|
||||
}
|
||||
for (const [key, value] of held) {
|
||||
if (!it.keys.includes(key)) {
|
||||
value[3] = timeIndex - value[2];
|
||||
held.delete(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
timeIndex += timescale * (it.step ?? 1);
|
||||
if (it.idle) {
|
||||
timeIndex += idleHold;
|
||||
}
|
||||
}
|
||||
|
||||
replay.finish = timeIndex;
|
||||
return replay;
|
||||
});
|
||||
|
||||
let graph = $derived.by(() => {
|
||||
const rows: string[][] = [[]];
|
||||
for (const it of test.test) {
|
||||
if (it.keys?.includes("BKSP")) {
|
||||
if (rows.at(-1)!.at(-1) === " ") {
|
||||
rows.at(-1)!.pop();
|
||||
} else {
|
||||
rows.push(Array.from({ length: rows.at(-1)!.length - 1 }, () => " "));
|
||||
}
|
||||
} else {
|
||||
for (const key of it.keys ?? []) {
|
||||
if (key === "SPACE") {
|
||||
rows.at(-1)!.push("␣");
|
||||
} else if (key === "ENTER") {
|
||||
rows.at(-1)!.push("↵");
|
||||
} else {
|
||||
rows.at(-1)!.push(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rows;
|
||||
});
|
||||
</script>
|
||||
|
||||
<section>
|
||||
<div class="replay">
|
||||
<CharRecorder
|
||||
{replay}
|
||||
cursor={true}
|
||||
ondone={() => setTimeout(() => (replay = { ...replay }), replayDelay)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<details>
|
||||
<summary>Breakdown</summary>
|
||||
<div class="graph">
|
||||
{#each graph as row, i}
|
||||
{#each row as char, j}
|
||||
{#if char !== " "}
|
||||
<div
|
||||
class:deleted={(graph[i + 1]?.findIndex((it) => it !== " ") ??
|
||||
Infinity) <= j}
|
||||
style:grid-row={i + 1}
|
||||
style:grid-column={j + 1}
|
||||
>
|
||||
{char}
|
||||
</div>
|
||||
{/if}
|
||||
{/each}
|
||||
{/each}
|
||||
</div>
|
||||
</details>
|
||||
</section>
|
||||
|
||||
<style lang="scss">
|
||||
section {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
summary {
|
||||
cursor: pointer;
|
||||
margin-top: 0.5rem;
|
||||
font-weight: bold;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.replay {
|
||||
background: #f0f0f0;
|
||||
padding: 0.6rem;
|
||||
font-weight: bold;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.graph {
|
||||
display: grid;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
width: min-content;
|
||||
}
|
||||
|
||||
.deleted {
|
||||
opacity: 0.6;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
</style>
|
||||
@@ -1,20 +0,0 @@
|
||||
export interface E2eAddChord {
|
||||
input: string[][];
|
||||
output: string[];
|
||||
}
|
||||
|
||||
export interface E2eTestItem {
|
||||
keys?: string[];
|
||||
modifiers?: Record<string, boolean>;
|
||||
press?: string[];
|
||||
release?: string[];
|
||||
step?: number;
|
||||
idle?: boolean;
|
||||
clearChords?: boolean;
|
||||
addChords?: E2eAddChord[];
|
||||
settings: Record<string, Record<string, string | number>>;
|
||||
}
|
||||
|
||||
export interface E2eTest {
|
||||
test: E2eTestItem[];
|
||||
}
|
||||
Reference in New Issue
Block a user