43 Commits

Author SHA1 Message Date
László Monda
f3bd83af03 Bump version to 1.2.10, update changelog and package.json 2018-09-24 04:21:24 +02:00
László Monda
0b3fca63b7 Add History Back and History Forward scancodes. Resolves #776. 2018-09-24 03:56:29 +02:00
László Monda
cbd4460df0 Map Caps Lock without Ctrl on default keymaps. 2018-09-24 03:03:05 +02:00
László Monda
b941bd9a75 Set the decelerated scroll speed of the default configuration to 10. 2018-09-24 02:32:25 +02:00
László Monda
439b84affc Save decelerated mouse scroll speed properly instead of using the accelerated scroll speed by accident. Fixes https://github.com/UltimateHackingKeyboard/firmware/issues/178 2018-09-24 02:21:00 +02:00
László Monda
66d5302e6f Add play/pause icon. Improves #591. 2018-09-21 01:43:15 +02:00
László Monda
9e2e2b9c5c Add more exact instructions to the permission setup screen. Fixes #781. 2018-09-21 00:56:50 +02:00
Róbert Kiss
aa243ac7b0 feat: allow Layer Switcher secondary roles only on base layer (#790) 2018-09-21 00:20:46 +02:00
László Monda
eb421e0681 Revert "Remove unused mustache file."
This reverts commit 63aae8f578.
2018-09-20 02:31:06 +02:00
László Monda
63aae8f578 Remove unused mustache file. 2018-09-20 02:08:58 +02:00
László Monda
e577454a31 Make all SVGs non-executable. 2018-09-20 02:05:51 +02:00
László Monda
e802bb0052 Remove unused SVGs. 2018-09-20 02:05:15 +02:00
László Monda
b98e5df20a Add backspace and caps lock icons. Improves #83. 2018-09-20 01:42:05 +02:00
Róbert Kiss
7332105edb feat: remap on all keymap warning (#789) 2018-09-19 23:02:32 +02:00
László Monda
6a4feaf18d Merge branch 'master' of github.com:UltimateHackingKeyboard/agent 2018-09-16 21:30:58 +02:00
László Monda
ee637d7958 Rename Scroll Lock to ScrLk and Num Lock to NumLk on keys. Improves #83. 2018-09-16 21:28:54 +02:00
Róbert Kiss
8d161ce8ff chore: upgrade Node.js => 8.12.0 (#783)
it's fix appveyor build
2018-09-16 21:17:40 +02:00
László Monda
8010bd8195 In the scancode select2 display "Print Screen SysRq" and add SysRq above PrtScn when rendering the key. Fixes #784. 2018-09-16 21:09:54 +02:00
Jan Christoph Ebersbach
059f1d5505 Fix swapped direction title for mouse movements (#778) 2018-09-16 01:16:11 +02:00
László Monda
123cab5724 Bump Agent version to 1.2.9 2018-09-13 20:42:07 +02:00
Róbert Kiss
c16365a0e5 fix: Alt+Tab triggers "Remap on all layers" (#773) 2018-09-11 22:29:30 +02:00
Róbert Kiss
a21d278c0c fix: modifier button layout (#772) 2018-09-11 21:56:30 +02:00
Róbert Kiss
0466916be1 fix: key modifier reordering (#771) 2018-09-11 00:29:22 +02:00
László Monda
9a845d8f6a Fix eeprom.js 2018-09-10 19:29:58 +02:00
Róbert Kiss
9ae1673499 feat: secondary role visualisation (#767)
* feat: secondary role visualisation

* fix: recalculate the text position of the secondary role if changes

* fix: recalculate the text position of SvgKeystrokeKeyComponent

* fix: recalculate the text position when changes anything

* fix: two line text key position calculation

* fix: fix space positioning

* fix: visualize second character of complex key

* style: remove extra line
2018-09-08 12:09:16 +02:00
László Monda
2d5a5e7aef Exchange Alt and Super modifiers in the key action popover. 2018-09-03 03:58:03 +02:00
Róbert Kiss
3e4d439852 feat: display OS-specific modifiers (#764)
* chore: git ignore "out-tsc/" folder in uhk-web package

* feat: add OperationSystem calculation to the app reducer

* feat: create os specific key modifier

* feat: Os specific texts

* revert: KeyModifierValues and getKeyModifiers selector

* refactor: remove unnecessary return

* refactor: rename OperationSystem => OperatingSystem
2018-09-03 00:21:55 +02:00
László Monda
aba0b09109 Bump Agent to version 1.2.8 and update changelog. 2018-08-26 23:42:31 +02:00
László Monda
af608ee17d Downgrade to firmware 8.2.5 2018-08-26 23:35:54 +02:00
Róbert Kiss
df817e86d6 fix: use OnPush change detection on the keymap edit and add pages (#760)
* fix: use OnPush change detection on the keymap edit and add pages

* fix: font-size
2018-08-26 22:08:29 +02:00
Róbert Kiss
a7d3b62512 chore: upgrade many dependencies and restructure tsconfigs (#757)
* chore: upgrade many dependencies and restructure tsconfigs

Summary:
- upgrade many dependencies
- remove dev dependencies from test-serializer and uhk-common
- created root tsconfig.json and test-serializer and uhk-common
  tsconfigs extends it
- fixed e2e test

* chore: upgrade more dependencies
2018-08-22 00:34:16 +02:00
Róbert Kiss
b41f14192a chore: upgrade stylelint => 9.5.0 (#756)
it is fix "Unknown CSS word" error in IntelliJ
2018-08-21 20:43:18 +02:00
Róbert Kiss
475ec71983 fix: uncheck 'Remap on all keyboard' and 'Remap on all layer' checkbox by default (#754)
* fix: uncheck 'Remap on all keyboard' and 'Remap on all layer' checkbox by default

* fix: popover checkbox checked state
2018-08-21 20:41:54 +02:00
László Monda
b5cff2fa93 Fix the padding of the secondary role tooltip. 2018-08-14 04:10:30 +02:00
László Monda
80e8c014ec Bind left and right Shift on the Mouse layer of all keymaps in the default configuration. 2018-08-08 17:00:32 +02:00
László Monda
67d42f666c Simplify the output of get-debug-info.js 2018-08-04 02:29:39 +02:00
László Monda
fa32f95438 Add note to the LED brightness page saying that current UHK versions are not backlit. Also include spacing-bootstrap-3 2018-07-30 00:05:04 +02:00
László Monda
06878dd56a Remove the redundant scrollbar from the LED brightness page. 2018-07-29 00:28:34 +02:00
Róbert Kiss
374f6a3e6e chore: downgrade electron builder => 20.14.7 (#741)
* chore: downgrade electron builder => 20.14.7

* chore: downgrade electron builder => 20.8.1
2018-07-26 23:30:20 +02:00
László Monda
0b9c804a3d Bump Agent version to 1.2.7 and update changelog. 2018-07-26 22:20:28 +02:00
László Monda
365a459d61 Merge branch 'master' of github.com:UltimateHackingKeyboard/agent 2018-07-26 22:16:33 +02:00
László Monda
cec891a2c0 Change the shortcut which enables the USB stack test code, so that it can be triggered with the default Mac US keymap. 2018-07-26 22:15:21 +02:00
Róbert Kiss
8eb8aa3032 chore: upgrade electron builder => 20.26.0 (#740) 2018-07-26 22:06:32 +02:00
93 changed files with 17034 additions and 13973 deletions

2
.nvmrc
View File

@@ -1 +1 @@
8.11.2
8.12.0

View File

@@ -6,6 +6,47 @@ The format is loosely based on [Keep a Changelog](http://keepachangelog.com/en/1
Every Agent version includes the most recent firmware version. See the [firmware changelog](https://github.com/UltimateHackingKeyboard/firmware/blob/master/CHANGELOG.md).
## [1.2.10] - 2018-09-24
Firmware: 8.2.5 [[release](https://github.com/UltimateHackingKeyboard/firmware/releases/tag/v8.2.5)] | Device Protocol: 4.4.0 | User Config: 4.0.1 | Hardware Config: 1.0.0
- Add History Back and History Forward scancodes.
- Save the actual decelerated scroll speed instead of using the accelerated scroll speed by accident.
- Allow layer switcher secondary roles only on the base layer.
- When remapping modifiers, display a warning suggesting to remap them on all layers.
- Display more exact instructions on the permission setup screen.
- Set the decelerated scroll speed of the default configuration from 20 to 10.
- Map Caps Lock without Ctrl on default keymaps.
- Rename "Scroll Lock" to "ScrLk" and "Num Lock" to "NumLk" on keys to avoid text overlap.
- In the scancode select2, display "Print Screen SysRq" and add SysRq above PrtScn when rendering the key.
- Fix left and right direction titles for mouse movement macro actions.
## [1.2.9] - 2018-09-13
Firmware: 8.2.5 [[release](https://github.com/UltimateHackingKeyboard/firmware/releases/tag/v8.2.5)] | Device Protocol: 4.4.0 | User Config: 4.0.1 | Hardware Config: 1.0.0
- Display OS-specific modifiers.
- Display secondary roles.
- Don't trigger "Remap on all layers" after leaving Agent with Alt+Tab.
## [1.2.8] - 2018-08-26
Firmware: 8.**2.5** [[release](https://github.com/UltimateHackingKeyboard/firmware/releases/tag/v8.2.5)] | Device Protocol: 4.4.0 | User Config: 4.0.1 | Hardware Config: 1.0.0
- Uncheck the "Remap on all keymaps" and "Remap on all layers" checkboxes of the key action popover by default.
- Bind left and right Shift on the Mouse layer of all keymaps in the default configuration.
- Make ng2-select2 widgets faster.
- Add note to the LED brightness page saying that current UHK versions are not backlit.
- Fix the padding of the secondary role tooltip.
- Remove the redundant scrollbar from the LED brightness page.
## [1.2.7] - 2018-07-26
Firmware: 8.4.0 [[release](https://github.com/UltimateHackingKeyboard/firmware/releases/tag/v8.4.0)] | Device Protocol: 4.4.0 | User Config: 4.0.1 | Hardware Config: 1.0.0
- Fix Agent startup exception on Linux by upgrading Electron builder.
- Change the shortcut which enables the USB stack test code, so that it can be triggered with the default Mac US keymap.
## [1.2.6] - 2018-07-26
Firmware: 8.**4.0** [[release](https://github.com/UltimateHackingKeyboard/firmware/releases/tag/v8.4.0)] | Device Protocol: 4.**4.0** | User Config: 4.0.1 | Hardware Config: 1.0.0

13596
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,8 +3,8 @@
"private": true,
"author": "Ultimate Gadget Laboratories",
"main": "electron/dist/electron-main.js",
"version": "1.2.6",
"firmwareVersion": "8.4.0",
"version": "1.2.10",
"firmwareVersion": "8.2.5",
"deviceProtocolVersion": "4.4.0",
"userConfigVersion": "4.0.1",
"hardwareConfigVersion": "1.0.0",
@@ -15,14 +15,14 @@
},
"license": "GPL-3.0",
"engines": {
"node": ">=8.9.1 <9.0.0",
"npm": ">=5.6.0 <6.0.0"
"node": ">=8.12.0 <9.0.0",
"npm": ">=6.4.0 <7.0.0"
},
"devDependencies": {
"@types/electron-devtools-installer": "2.0.2",
"@types/electron-settings": "3.0.0",
"@types/fs-extra": "5.0.1",
"@types/jasmine": "2.6.0",
"@types/jasmine": "2.8.8",
"@types/jquery": "3.3.1",
"@types/jsonfile": "4.0.1",
"@types/lodash-es": "4.17.0",
@@ -40,35 +40,39 @@
"decompress": "4.2.0",
"decompress-tarbz2": "4.1.1",
"devtron": "1.4.0",
"electron": "1.8.4",
"electron-builder": "20.15.0",
"electron": "1.8.7",
"electron-builder": "20.8.1",
"electron-debug": "1.5.0",
"electron-devtools-installer": "2.2.3",
"electron-log": "2.2.16",
"electron-rebuild": "1.8.1",
"electron-rebuild": "1.8.2",
"electron-settings": "3.1.4",
"electron-updater": "2.21.4",
"exports-loader": "0.6.3",
"file-loader": "0.10.0",
"fs-extra": "5.0.0",
"gh-pages": "1.1.0",
"jasmine": "2.8.0",
"jasmine-core": "2.8.0",
"jasmine-node": "2.0.1",
"jasmine-ts": "0.2.1",
"jsonfile": "4.0.0",
"lerna": "2.9.0",
"lerna": "3.1.4",
"lodash-es": "4.17.4",
"mkdirp": "0.5.1",
"node-hid": "0.5.7",
"npm-run-all": "4.0.2",
"pre-commit": "1.2.2",
"request": "2.83.0",
"request": "2.88.0",
"rimraf": "2.6.1",
"standard-version": "4.2.0",
"stylelint": "7.13.0",
"svg-sprite": "1.3.7",
"stylelint": "9.5.0",
"svg-sprite": "1.4.0",
"ts-loader": "2.3.1",
"ts-node": "3.0.4",
"ts-node": "7.0.1",
"tslint": "5.9.1",
"typescript": "2.6.2",
"webpack": "3.10.0"
"webpack": "3.12.0"
},
"pre-commit": [
"precommit-msg"
@@ -88,6 +92,7 @@
"lint:ts:test-serializer": "tslint --project ./packages/test-serializer/tsconfig.json",
"lint:ts:uhk-usb": "tslint --project ./packages/uhk-usb/tsconfig.json",
"lint:style": "stylelint \"packages/uhk-agent/src/**/*.scss\" \"packages/uhk-web/src/**/*.scss\" --syntax scss",
"e2e": "lerna run e2e --scope uhk-web",
"prebuild": "check-node-version --package",
"build": "run-s build:common build:usb build:web build:electron",
"build:web": "lerna exec --scope uhk-web npm run build",

View File

@@ -201,11 +201,11 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"gaze": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz",
"integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=",
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
"integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
"requires": {
"globule": "0.1.0"
"globule": "1.2.1"
}
},
"get-caller-file": {
@@ -219,41 +219,37 @@
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
},
"glob": {
"version": "3.1.21",
"resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz",
"integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=",
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
"requires": {
"graceful-fs": "1.2.3",
"inherits": "1.0.2",
"minimatch": "0.2.14"
},
"dependencies": {
"inherits": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz",
"integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js="
}
"fs.realpath": "1.0.0",
"inflight": "1.0.6",
"inherits": "2.0.3",
"minimatch": "3.0.4",
"once": "1.4.0",
"path-is-absolute": "1.0.1"
}
},
"globule": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz",
"integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz",
"integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==",
"requires": {
"glob": "3.1.21",
"lodash": "1.0.2",
"minimatch": "0.2.14"
"glob": "7.1.2",
"lodash": "4.17.10",
"minimatch": "3.0.4"
}
},
"graceful-fs": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz",
"integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q="
},
"growl": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/growl/-/growl-1.7.0.tgz",
"integrity": "sha1-3i1mE20ALhErpw8/EMMc98NQsto="
"version": "1.10.5",
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
"integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA=="
},
"grunt-exec": {
"version": "0.4.7",
"resolved": "https://registry.npmjs.org/grunt-exec/-/grunt-exec-0.4.7.tgz",
"integrity": "sha1-QAUf+k6wyWV+BTuV6I1ENSocLCU="
},
"has-flag": {
"version": "2.0.0",
@@ -362,31 +358,34 @@
"integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4="
},
"jasmine-growl-reporter": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/jasmine-growl-reporter/-/jasmine-growl-reporter-0.2.1.tgz",
"integrity": "sha1-1fCje5L2qD/VxkgrgJSVyQqLVf4=",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/jasmine-growl-reporter/-/jasmine-growl-reporter-1.0.1.tgz",
"integrity": "sha512-dh7VjP3l0OLxL9+sw5vK6RrdH4gdHCNkTnUd9orViHDPr7Fe8LsXY+IObWauS2hX5khMFtjKRZCfTcDHKAjm/A==",
"requires": {
"growl": "1.7.0"
"growl": "1.10.5"
}
},
"jasmine-node": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/jasmine-node/-/jasmine-node-2.0.0.tgz",
"integrity": "sha1-gXUacjJfVJdJCxQYGlUIfxsDcf8=",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/jasmine-node/-/jasmine-node-2.0.1.tgz",
"integrity": "sha512-1S5Z4Mof5yxwqLIApzyo2pV5WN2kRpTSgICvEo3+rJmKve9P94kolzC9eS0u5cyiT+gxBY2mwOQdxLbkhwKzoA==",
"requires": {
"coffee-script": "1.7.1",
"gaze": "0.5.2",
"jasmine-growl-reporter": "0.2.1",
"minimist": "0.0.8",
"gaze": "1.1.3",
"grunt-exec": "0.4.7",
"jasmine-growl-reporter": "1.0.1",
"jasmine-reporters": "git://github.com/larrymyers/jasmine-reporters.git#2c7242dc11c15c2f156169bc704798568b8cb50d",
"minimist": "0.0.10",
"mkdirp": "0.3.5",
"underscore": "1.6.0",
"walkdir": "0.0.12"
"walkdir": "0.0.12",
"xml2js": "0.4.19"
},
"dependencies": {
"minimist": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
"integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
},
"mkdirp": {
"version": "0.3.5",
@@ -395,6 +394,19 @@
}
}
},
"jasmine-reporters": {
"version": "git://github.com/larrymyers/jasmine-reporters.git#2c7242dc11c15c2f156169bc704798568b8cb50d",
"requires": {
"mkdirp": "0.3.5"
},
"dependencies": {
"mkdirp": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz",
"integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc="
}
}
},
"jasmine-ts": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/jasmine-ts/-/jasmine-ts-0.2.1.tgz",
@@ -442,14 +454,9 @@
}
},
"lodash": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz",
"integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE="
},
"lru-cache": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz",
"integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI="
"version": "4.17.10",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
},
"make-error": {
"version": "1.3.0",
@@ -470,12 +477,11 @@
"integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg="
},
"minimatch": {
"version": "0.2.14",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz",
"integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=",
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"requires": {
"lru-cache": "2.7.3",
"sigmund": "1.0.1"
"brace-expansion": "1.1.8"
}
},
"minimist": {
@@ -633,6 +639,11 @@
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
},
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
},
"semver": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
@@ -656,11 +667,6 @@
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
},
"sigmund": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
"integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA="
},
"signal-exit": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
@@ -854,6 +860,20 @@
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"xml2js": {
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
"integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
"requires": {
"sax": "1.2.4",
"xmlbuilder": "9.0.7"
}
},
"xmlbuilder": {
"version": "9.0.7",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
},
"y18n": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",

View File

@@ -14,16 +14,9 @@
"npm": ">=5.1.0 <6.0.0"
},
"dependencies": {
"uhk-common": "1.0.0"
},
"devDependencies": {
"@types/jasmine": "2.6.0",
"@types/node": "8.0.30",
"jasmine": "2.8.0",
"jasmine-core": "2.8.0",
"jasmine-node": "2.0.0",
"jasmine-ts": "0.2.1",
"ts-node": "3.3.0",
"uhk-common": "1.0.0"
},
"scripts": {
"test": "jasmine-ts --config=jasmine.json"

View File

@@ -1,11 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"moduleResolution": "node",
"experimentalDecorators": true,
"typeRoots": [
"./node_modules/@types"
]
"experimentalDecorators": true
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -19,16 +19,6 @@
"coverage": "nyc jasmine-ts --config=jasmine.json"
},
"license": "GPL-3.0",
"devDependencies": {
"@types/jasmine": "2.6.0",
"@types/node": "8.0.30",
"jasmine": "2.8.0",
"jasmine-core": "2.8.0",
"jasmine-node": "2.0.0",
"jasmine-ts": "0.2.1",
"nyc": "11.2.1",
"ts-node": "3.3.0"
},
"nyc": {
"extension": [
".ts"

View File

@@ -259,7 +259,7 @@
},
{
"id": "70",
"text": "Print Screen"
"text": "Print Screen SysRq"
},
{
"id": "72",
@@ -509,6 +509,22 @@
"type": "media",
"scancode": 138
}
},
{
"id": "145",
"text": "History Back",
"additional": {
"type": "media",
"scancode": 548
}
},
{
"id": "146",
"text": "History Forward",
"additional": {
"type": "media",
"scancode": 549
}
}
]
},

View File

@@ -1,9 +1,11 @@
import { assertUInt8, assertUInt16 } from '../assert';
import { assertUInt16, assertUInt8 } from '../assert';
import { UhkBuffer } from '../uhk-buffer';
import { Keymap } from './keymap';
import { Macro } from './macro';
import { ModuleConfiguration } from './module-configuration';
import { ConfigSerializer } from '../config-serializer';
import { KeystrokeAction } from './key-action';
import { SecondaryRoleAction } from './secondary-role-action';
export class UserConfiguration {
@@ -90,7 +92,7 @@ export class UserConfiguration {
this.mouseMoveAcceleratedSpeed = jsonObject.mouseMoveAcceleratedSpeed;
this.mouseScrollInitialSpeed = jsonObject.mouseScrollInitialSpeed;
this.mouseScrollAcceleration = jsonObject.mouseScrollAcceleration;
this.mouseScrollDeceleratedSpeed = jsonObject.mouseScrollAcceleration;
this.mouseScrollDeceleratedSpeed = jsonObject.mouseScrollDeceleratedSpeed;
this.mouseScrollBaseSpeed = jsonObject.mouseScrollBaseSpeed;
this.mouseScrollAcceleratedSpeed = jsonObject.mouseScrollAcceleratedSpeed;
this.moduleConfigurations = jsonObject.moduleConfigurations.map((moduleConfiguration: any) => {
@@ -102,7 +104,9 @@ export class UserConfiguration {
return macro;
});
this.keymaps = jsonObject.keymaps.map((keymap: any) => new Keymap().fromJsonObject(keymap, this.macros));
this.clean();
this.recalculateConfigurationLength();
return this;
}
@@ -138,6 +142,8 @@ export class UserConfiguration {
this.keymaps = buffer.readArray<Keymap>(uhkBuffer => new Keymap().fromBinary(uhkBuffer, this.macros));
ConfigSerializer.resolveSwitchKeymapActions(this.keymaps);
this.clean();
if (this.userConfigurationLength === 0) {
this.recalculateConfigurationLength();
}
@@ -222,4 +228,30 @@ export class UserConfiguration {
this.deviceName = 'My UHK';
}
}
/* Remove not allowed settings/bugs
* 1. Layer Switcher secondary roles allowed only on base layers
*/
private clean(): void {
for (const keymap of this.keymaps) {
for (let layerId = 1; layerId < keymap.layers.length; layerId++) {
const layer = keymap.layers[layerId];
for (const module of layer.modules) {
for (let keyActionId = 0; keyActionId < module.keyActions.length; keyActionId++) {
const keyAction = module.keyActions[keyActionId];
if (!keyAction || !(keyAction instanceof KeystrokeAction)) {
continue;
}
if (keyAction.secondaryRoleAction === SecondaryRoleAction.fn ||
keyAction.secondaryRoleAction === SecondaryRoleAction.mod ||
keyAction.secondaryRoleAction === SecondaryRoleAction.mouse) {
(keyAction as any)._secondaryRoleAction = undefined;
}
}
}
}
}
}
}

View File

@@ -1,4 +1,5 @@
{
"extends": "../../tsconfig.json",
"compileOnSave": false,
"compilerOptions": {
"sourceMap": true,
@@ -9,9 +10,6 @@
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es5",
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2015.iterable",
"dom",

View File

@@ -1,11 +1,14 @@
{
"requires": true,
"name": "uhk-usb",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@types/node": {
"version": "8.0.28",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.28.tgz",
"integrity": "sha512-HupkFXEv3O3KSzcr3Ylfajg0kaerBg1DyaZzRBBQfrU3NN1mTBRE7sCveqHwXLS5Yrjvww8qFzkzYQQakG9FuQ=="
"integrity": "sha512-HupkFXEv3O3KSzcr3Ylfajg0kaerBg1DyaZzRBBQfrU3NN1mTBRE7sCveqHwXLS5Yrjvww8qFzkzYQQakG9FuQ==",
"dev": true
},
"ansi-regex": {
"version": "2.1.1",
@@ -22,8 +25,8 @@
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
"integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
"requires": {
"delegates": "1.0.0",
"readable-stream": "2.3.6"
"delegates": "^1.0.0",
"readable-stream": "^2.0.6"
}
},
"bindings": {
@@ -36,8 +39,8 @@
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
"integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
"requires": {
"readable-stream": "2.3.6",
"safe-buffer": "5.1.1"
"readable-stream": "^2.3.5",
"safe-buffer": "^5.1.1"
}
},
"chownr": {
@@ -65,7 +68,7 @@
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
"integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
"requires": {
"mimic-response": "1.0.0"
"mimic-response": "^1.0.0"
}
},
"deep-extend": {
@@ -88,7 +91,7 @@
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
"integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
"requires": {
"once": "1.4.0"
"once": "^1.4.0"
}
},
"expand-template": {
@@ -101,14 +104,14 @@
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
"requires": {
"aproba": "1.2.0",
"console-control-strings": "1.1.0",
"has-unicode": "2.0.1",
"object-assign": "4.1.1",
"signal-exit": "3.0.2",
"string-width": "1.0.2",
"strip-ansi": "3.0.1",
"wide-align": "1.1.2"
"aproba": "^1.0.3",
"console-control-strings": "^1.0.0",
"has-unicode": "^2.0.0",
"object-assign": "^4.1.0",
"signal-exit": "^3.0.0",
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1",
"wide-align": "^1.1.0"
}
},
"github-from-package": {
@@ -136,7 +139,7 @@
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"requires": {
"number-is-nan": "1.0.1"
"number-is-nan": "^1.0.0"
}
},
"isarray": {
@@ -179,7 +182,7 @@
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.3.0.tgz",
"integrity": "sha512-zwm6vU3SsVgw3e9fu48JBaRBCJGIvAgysDsqtf5+vEexFE71bEOtaMWb5zr/zODZNzTPtQlqUUpC79k68Hspow==",
"requires": {
"semver": "5.5.0"
"semver": "^5.4.1"
}
},
"node-hid": {
@@ -187,9 +190,9 @@
"resolved": "https://registry.npmjs.org/node-hid/-/node-hid-0.5.7.tgz",
"integrity": "sha512-dwwpOetL2+MGYgivbO22ML+45ieCGbueWv1rYxRgBoEc2QMp6UF6ZucEkYts1IA3YPWJNkmpGh6dqQ85n19szw==",
"requires": {
"bindings": "1.3.0",
"nan": "2.10.0",
"prebuild-install": "2.5.1"
"bindings": "^1.3.0",
"nan": "^2.6.2",
"prebuild-install": "^2.2.2"
}
},
"noop-logger": {
@@ -202,10 +205,10 @@
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
"requires": {
"are-we-there-yet": "1.1.4",
"console-control-strings": "1.1.0",
"gauge": "2.7.4",
"set-blocking": "2.0.0"
"are-we-there-yet": "~1.1.2",
"console-control-strings": "~1.1.0",
"gauge": "~2.7.3",
"set-blocking": "~2.0.0"
}
},
"number-is-nan": {
@@ -223,7 +226,7 @@
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"requires": {
"wrappy": "1.0.2"
"wrappy": "1"
}
},
"os-homedir": {
@@ -236,21 +239,21 @@
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.5.1.tgz",
"integrity": "sha512-3DX9L6pzwc1m1ksMkW3Ky2WLgPQUBiySOfXVl3WZyAeJSyJb4wtoH9OmeRGcubAWsMlLiL8BTHbwfm/jPQE9Ag==",
"requires": {
"detect-libc": "1.0.3",
"expand-template": "1.1.0",
"detect-libc": "^1.0.3",
"expand-template": "^1.0.2",
"github-from-package": "0.0.0",
"minimist": "1.2.0",
"mkdirp": "0.5.1",
"node-abi": "2.3.0",
"noop-logger": "0.1.1",
"npmlog": "4.1.2",
"os-homedir": "1.0.2",
"pump": "2.0.1",
"rc": "1.2.6",
"simple-get": "2.7.0",
"tar-fs": "1.16.0",
"tunnel-agent": "0.6.0",
"which-pm-runs": "1.0.0"
"minimist": "^1.2.0",
"mkdirp": "^0.5.1",
"node-abi": "^2.2.0",
"noop-logger": "^0.1.1",
"npmlog": "^4.0.1",
"os-homedir": "^1.0.1",
"pump": "^2.0.1",
"rc": "^1.1.6",
"simple-get": "^2.7.0",
"tar-fs": "^1.13.0",
"tunnel-agent": "^0.6.0",
"which-pm-runs": "^1.0.0"
}
},
"process-nextick-args": {
@@ -263,8 +266,8 @@
"resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
"integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
"requires": {
"end-of-stream": "1.4.1",
"once": "1.4.0"
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"rc": {
@@ -272,10 +275,10 @@
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.6.tgz",
"integrity": "sha1-6xiYnG1PTxYsOZ953dKfODVWgJI=",
"requires": {
"deep-extend": "0.4.2",
"ini": "1.3.5",
"minimist": "1.2.0",
"strip-json-comments": "2.0.1"
"deep-extend": "~0.4.0",
"ini": "~1.3.0",
"minimist": "^1.2.0",
"strip-json-comments": "~2.0.1"
}
},
"readable-stream": {
@@ -283,13 +286,13 @@
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "1.0.2",
"inherits": "2.0.3",
"isarray": "1.0.0",
"process-nextick-args": "2.0.0",
"safe-buffer": "5.1.1",
"string_decoder": "1.1.1",
"util-deprecate": "1.0.2"
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"safe-buffer": {
@@ -322,9 +325,9 @@
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.7.0.tgz",
"integrity": "sha512-RkE9rGPHcxYZ/baYmgJtOSM63vH0Vyq+ma5TijBcLla41SWlh8t6XYIGMR/oeZcmr+/G8k+zrClkkVrtnQ0esg==",
"requires": {
"decompress-response": "3.3.0",
"once": "1.4.0",
"simple-concat": "1.0.0"
"decompress-response": "^3.3.0",
"once": "^1.3.1",
"simple-concat": "^1.0.0"
}
},
"string-width": {
@@ -332,9 +335,9 @@
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"requires": {
"code-point-at": "1.1.0",
"is-fullwidth-code-point": "1.0.0",
"strip-ansi": "3.0.1"
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
"strip-ansi": "^3.0.0"
}
},
"string_decoder": {
@@ -342,7 +345,7 @@
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "5.1.1"
"safe-buffer": "~5.1.0"
}
},
"strip-ansi": {
@@ -350,7 +353,7 @@
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"requires": {
"ansi-regex": "2.1.1"
"ansi-regex": "^2.0.0"
}
},
"strip-json-comments": {
@@ -363,10 +366,10 @@
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.0.tgz",
"integrity": "sha512-I9rb6v7mjWLtOfCau9eH5L7sLJyU2BnxtEZRQ5Mt+eRKmf1F0ohXmT/Jc3fr52kDvjJ/HV5MH3soQfPL5bQ0Yg==",
"requires": {
"chownr": "1.0.1",
"mkdirp": "0.5.1",
"pump": "1.0.3",
"tar-stream": "1.5.5"
"chownr": "^1.0.1",
"mkdirp": "^0.5.1",
"pump": "^1.0.0",
"tar-stream": "^1.1.2"
},
"dependencies": {
"pump": {
@@ -374,8 +377,8 @@
"resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
"integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
"requires": {
"end-of-stream": "1.4.1",
"once": "1.4.0"
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
}
}
@@ -385,10 +388,10 @@
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz",
"integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==",
"requires": {
"bl": "1.2.2",
"end-of-stream": "1.4.1",
"readable-stream": "2.3.6",
"xtend": "4.0.1"
"bl": "^1.0.0",
"end-of-stream": "^1.0.0",
"readable-stream": "^2.0.0",
"xtend": "^4.0.0"
}
},
"tunnel-agent": {
@@ -396,7 +399,7 @@
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
"requires": {
"safe-buffer": "5.1.1"
"safe-buffer": "^5.0.1"
}
},
"util-deprecate": {
@@ -414,7 +417,7 @@
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
"integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
"requires": {
"string-width": "1.0.2"
"string-width": "^1.0.2"
}
},
"wrappy": {

1
packages/uhk-web/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
out-tsc/

View File

@@ -7,8 +7,8 @@ describe('web App', () => {
page = new WebPage();
});
it('should display welcome message', () => {
it('should display default device name', () => {
page.navigateTo();
expect(page.getParagraphText()).toEqual('Welcome to app!');
expect(page.getDeviceName()).toEqual('My UHK');
});
});

View File

@@ -5,7 +5,8 @@ export class WebPage {
return browser.get('/');
}
getParagraphText() {
return element(by.css('app-root h1')).getText();
getDeviceName() {
return element(by.css('body > main-app > side-menu > ul > li:nth-child(1) > div > auto-grow-input > input'))
.getAttribute('value');
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -36,8 +36,8 @@
"@types/electron-devtools-installer": "2.0.2",
"@types/electron-settings": "3.0.0",
"@types/file-saver": "0.0.1",
"@types/jasmine": "2.5.53",
"@types/jasminewd2": "2.0.2",
"@types/jasmine": "2.8.8",
"@types/jasminewd2": "2.0.3",
"@types/jquery": "3.2.9",
"@types/usb": "1.1.3",
"angular-confirmation-popover": "3.2.0",
@@ -50,23 +50,23 @@
"dragula": "3.7.2",
"font-awesome": "4.7.0",
"html-webpack-plugin": "^2.29.0",
"jasmine-core": "2.6.2",
"jasmine-spec-reporter": "4.1.0",
"jasmine-core": "3.2.1",
"jasmine-spec-reporter": "4.2.1",
"jquery": "3.2.1",
"jsonfile": "3.0.1",
"karma": "1.7.0",
"karma-chrome-launcher": "2.1.1",
"karma-coverage-istanbul-reporter": "1.2.1",
"karma-jasmine": "1.1.0",
"karma-jasmine-html-reporter": "0.2.2",
"karma": "3.0.0",
"karma-chrome-launcher": "2.2.0",
"karma-coverage-istanbul-reporter": "2.0.1",
"karma-jasmine": "1.1.2",
"karma-jasmine-html-reporter": "1.3.1",
"ng2-dragula": "1.5.0",
"ng2-nouislider": "^1.7.7",
"ngx-clipboard": "10.0.0",
"@ert78gb/ngx-select-ex": "3.7.0",
"@ert78gb/ngx-select-ex": "3.7.2",
"ngrx-store-freeze": "0.1.9",
"nouislider": "^11.1.0",
"postcss-url": "^7.1.2",
"protractor": "5.1.2",
"protractor": "5.4.0",
"reselect": "3.0.1",
"rxjs": "5.5.8",
"typescript": "2.6.2",
@@ -78,6 +78,7 @@
},
"dependencies": {
"classlist.js": "1.1.20150312",
"file-saver": "1.3.3"
"file-saver": "1.3.3",
"spacing-bootstrap-3": "^1.0.0"
}
}

View File

@@ -12,7 +12,7 @@ exports.config = {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
baseUrl: 'http://localhost:8080/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,

View File

@@ -68,7 +68,6 @@ export class MainAppComponent implements OnDestroy {
if (event.shiftKey &&
event.ctrlKey &&
event.altKey &&
event.metaKey &&
event.key === '|' &&
!event.defaultPrevented) {

View File

@@ -29,7 +29,7 @@
<div class="row led-setting">
<div class="col-xs-12 col-md-6">
<slider-wrapper
label="Key backlight brightness"
label="Key backlight brightness <span class='text-muted pl-1'>Please note that current UHK versions are not backlit.</span>"
[min]="0"
[max]="255"
[step]="1"

View File

@@ -1,5 +1,4 @@
:host {
overflow-y: auto;
display: block;
height: 100%;
width: 100%;

View File

@@ -1,4 +1,4 @@
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { Keymap } from 'uhk-common';
@@ -14,6 +14,7 @@ import { KeymapActions } from '../../../store/actions';
selector: 'keymap-add',
templateUrl: './keymap-add.component.html',
styleUrls: ['./keymap-add.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
'class': 'container-fluid'
}

View File

@@ -1,4 +1,4 @@
import { Component, HostListener } from '@angular/core';
import { ChangeDetectionStrategy, Component, HostListener } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Store } from '@ngrx/store';
import { Keymap } from 'uhk-common';
@@ -24,6 +24,7 @@ import { ChangeKeymapDescription } from '../../../models/ChangeKeymapDescription
selector: 'keymap-edit',
templateUrl: './keymap-edit.component.html',
styleUrls: ['./keymap-edit.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
'class': 'container-fluid'
}

View File

@@ -176,7 +176,7 @@ export class MacroItemComponent implements OnInit, OnChanges {
let needAnd: boolean;
if (Math.abs(typedAction.x) !== 0) {
this.title += ` by ${Math.abs(typedAction.x)}px ${typedAction.x > 0 ? 'leftward' : 'rightward'}`;
this.title += ` by ${Math.abs(typedAction.x)}px ${typedAction.x > 0 ? 'rightward' : 'leftward'}`;
needAnd = true;
}
if (Math.abs(typedAction.y) !== 0) {

View File

@@ -47,10 +47,14 @@
</ul>
</div>
<div [ngSwitch]="activeTab">
<keypress-tab #tab *ngSwitchCase="tabName.Keypress" class="popover-content"
[defaultKeyAction]="defaultKeyAction"
<keypress-tab #tab *ngSwitchCase="tabName.Keypress" class="popover-content pr-10"
[defaultKeyAction]="shadowKeyAction"
[secondaryRoleEnabled]="true"
[allowRemapOnAllKeymapWarning]="true"
[remapInfo]="remapInfo"
[showLayerSwitcherInSecondaryRoles]="currentLayer === 0"
(validAction)="keyActionValid=$event"
(keyActionChange)="keystrokeActionChange($event)"
></keypress-tab>
<layer-tab #tab *ngSwitchCase="tabName.Layer" class="popover-content"
[defaultKeyAction]="defaultKeyAction"
@@ -81,14 +85,16 @@
<label>
<input type="checkbox"
name="remapOnAllKeymap"
[(ngModel)]="remapOnAllKeymap"> Remap on all keymaps
[(ngModel)]="remapInfo.remapOnAllKeymap"> Remap on all keymaps
</label>
</div>
<div class="checkbox">
<label>
<label [ngClass]="{ disabled: disableRemapOnAllLayer }">
<input type="checkbox"
name="remapOnAllLayer"
[(ngModel)]="remapOnAllLayer"> Remap on all layers
[(ngModel)]="remapInfo.remapOnAllLayer"
[disabled]="disableRemapOnAllLayer"
(ngModelChange)="remapInfoChange()"> Remap on all layers
</label>
</div>
<div class="d-inline-block">

View File

@@ -99,6 +99,10 @@
padding: 10px 24px;
}
.pr-10 {
padding-right: 10px;
}
.popover-overlay {
position: fixed;
width: 100%;
@@ -121,5 +125,10 @@
label {
margin-right: 5px;
&.disabled {
cursor: not-allowed;
color: #959595;
}
}
}

View File

@@ -1,4 +1,6 @@
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ElementRef,
EventEmitter,
@@ -23,6 +25,7 @@ import {
KeystrokeAction,
MouseAction,
PlayMacroAction,
SecondaryRoleAction,
SwitchKeymapAction,
SwitchLayerAction
} from 'uhk-common';
@@ -32,6 +35,7 @@ import { Tab } from './tab';
import { AppState } from '../../store';
import { getKeymaps } from '../../store/reducers/user-configuration';
import { KeyActionRemap } from '../../models/key-action-remap';
import { RemapInfo } from '../../models/remap-info';
enum TabName {
Keypress,
@@ -46,6 +50,7 @@ enum TabName {
selector: 'popover',
templateUrl: './popover.component.html',
styleUrls: ['./popover.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
animations: [
trigger('popover', [
state('closed', style({
@@ -84,8 +89,7 @@ export class PopoverComponent implements OnChanges {
@Input() wrapPosition: any;
@Input() visible: boolean;
@Input() allowLayerDoubleTap: boolean;
@Input() remapOnAllKeymap: boolean;
@Input() remapOnAllLayer: boolean;
@Input() remapInfo: RemapInfo;
@Output() cancel = new EventEmitter<any>();
@Output() remap = new EventEmitter<KeyActionRemap>();
@@ -102,10 +106,13 @@ export class PopoverComponent implements OnChanges {
topPosition: number = 0;
leftPosition: number = 0;
animationState: string;
shadowKeyAction: KeyAction;
disableRemapOnAllLayer = false;
private readonly currentKeymap$ = new BehaviorSubject<Keymap>(undefined);
constructor(store: Store<AppState>) {
constructor(private store: Store<AppState>,
private cdRef: ChangeDetectorRef) {
this.animationState = 'closed';
this.keymaps$ = store.let(getKeymaps())
.combineLatest(this.currentKeymap$)
@@ -121,8 +128,10 @@ export class PopoverComponent implements OnChanges {
if (change['defaultKeyAction']) {
let tab: TabName;
this.disableRemapOnAllLayer = false;
if (this.defaultKeyAction instanceof KeystrokeAction) {
this.keystrokeActionChange(this.defaultKeyAction);
tab = TabName.Keypress;
} else if (this.defaultKeyAction instanceof SwitchLayerAction) {
tab = TabName.Layer;
@@ -160,8 +169,8 @@ export class PopoverComponent implements OnChanges {
if (this.keyActionValid) {
try {
this.remap.emit({
remapOnAllKeymap: this.remapOnAllKeymap,
remapOnAllLayer: this.remapOnAllLayer,
remapOnAllKeymap: this.remapInfo.remapOnAllKeymap,
remapOnAllLayer: this.remapInfo.remapOnAllLayer,
action: this.selectedTab.toKeyAction()
});
} catch (e) {
@@ -186,12 +195,39 @@ export class PopoverComponent implements OnChanges {
selectTab(tab: TabName): void {
this.activeTab = tab;
if (tab === TabName.Keypress) {
this.keystrokeActionChange(this.defaultKeyAction as KeystrokeAction);
}
}
onOverlay() {
this.cancel.emit(undefined);
}
remapInfoChange(): void {
this.selectedTab.remapInfoChanged(this.remapInfo);
}
keystrokeActionChange(keystrokeAction: KeystrokeAction): void {
this.shadowKeyAction = keystrokeAction;
const disableRemapOnAllLayer =
keystrokeAction &&
this.currentLayer === 0 &&
(keystrokeAction.secondaryRoleAction === SecondaryRoleAction.fn ||
keystrokeAction.secondaryRoleAction === SecondaryRoleAction.mod ||
keystrokeAction.secondaryRoleAction === SecondaryRoleAction.mouse);
if (this.disableRemapOnAllLayer !== disableRemapOnAllLayer) {
this.disableRemapOnAllLayer = disableRemapOnAllLayer;
if (disableRemapOnAllLayer) {
this.remapInfo.remapOnAllLayer = false;
}
this.cdRef.markForCheck();
}
}
private calculatePosition() {
const offsetLeft: number = this.wrapPosition.left + 265; // 265 is a width of the side menu with a margin
const popover: HTMLElement = this.popoverHost.nativeElement;

View File

@@ -36,20 +36,20 @@
<div class="btn-toolbar modifiers">
<div class="btn-group btn-group-sm modifiers__left">
<button type="button" class="btn btn-default"
*ngFor="let modifier of leftModifiers; let index = index"
[class.btn-primary]="leftModifierSelects[index]"
(click)="toggleModifier(false, index)"
*ngFor="let modifier of leftModifiers; trackBy:modifiersTrackBy"
[class.btn-primary]="modifier.checked"
(click)="toggleModifier(modifier)"
>
{{modifier}}
{{ modifier.text }}
</button>
</div>
<div class="btn-group btn-group-sm modifiers__right">
<button type="button" class="btn btn-default"
*ngFor="let modifier of rightModifiers; let index = index"
[class.btn-primary]="rightModifierSelects[index]"
(click)="toggleModifier(true, index)"
*ngFor="let modifier of rightModifiers; trackBy:modifiersTrackBy"
[class.btn-primary]="modifier.checked"
(click)="toggleModifier(modifier)"
>
{{modifier}}
{{ modifier.text }}
</button>
</div>
</div>
@@ -88,10 +88,15 @@
<li>Tap this key to trigger Escape. <i>(Primary role)</i></li>
<li>Hold this key and press another key to activate the relevant key of the Mouse layer. <i>(Secondary role)</i></li>
</ul>
<p class='text-left pt-3'>The secondary role can be any layer or modifier.</p>"
<p class='text-left'>The secondary role can be any layer or modifier.</p>"
data-placement="bottom"></icon>
</div>
<div *ngIf="warningVisible" class="alert alert-warning remap-warning" role="alert">
You're about to remap a modifier key only on this layer. You probably want to remap it on all layers. If so, check
the <strong>Remap on all layers</strong> checkbox below.
</div>
<div class="disabled-state--text">
<i class="fa fa-info-circle"></i>
When a key is configured as layer switcher key, you can't assign other functions to it.

View File

@@ -89,4 +89,11 @@
display: inline-block;
width: 140px;
}
.remap-warning {
margin-top: 10px;
margin-bottom: 0;
padding-top: 5px;
padding-bottom: 5px;
}
}

View File

@@ -1,9 +1,31 @@
import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
EventEmitter,
Input,
OnChanges,
Output,
SimpleChanges
} from '@angular/core';
import { KeyAction, KeystrokeAction, KeystrokeType, SCANCODES, SECONDARY_ROLES } from 'uhk-common';
import { Tab } from '../tab';
import { MapperService } from '../../../../services/mapper.service';
import { SelectOptionData } from '../../../../models/select-option-data';
import { KeyModifierModel } from '../../../../models/key-modifier-model';
import { mapLeftRigthModifierToKeyActionModifier } from '../../../../util';
import { RemapInfo } from '../../../../models/remap-info';
export const secondaryRoleFilter = (showLayerSwitchers: boolean) => {
return (data): boolean => {
if (showLayerSwitchers) {
return data;
}
return data.text !== 'Layer switcher';
};
};
@Component({
selector: 'keypress-tab',
@@ -14,38 +36,43 @@ import { SelectOptionData } from '../../../../models/select-option-data';
export class KeypressTabComponent extends Tab implements OnChanges {
@Input() defaultKeyAction: KeyAction;
@Input() secondaryRoleEnabled: boolean;
@Input() allowRemapOnAllKeymapWarning: boolean;
@Input() remapInfo: RemapInfo;
@Input() showLayerSwitcherInSecondaryRoles: boolean;
leftModifiers: string[];
rightModifiers: string[];
@Output() keyActionChange = new EventEmitter<KeystrokeAction>();
leftModifierSelects: boolean[];
rightModifierSelects: boolean[];
leftModifiers: KeyModifierModel[];
rightModifiers: KeyModifierModel[];
scanCodeGroups: Array<SelectOptionData>;
secondaryRoleGroups: Array<SelectOptionData>;
secondaryRoleGroups: Array<SelectOptionData> = [];
selectedScancodeOption: SelectOptionData;
selectedSecondaryRoleIndex: number;
warningVisible: boolean;
constructor(private mapper: MapperService) {
constructor(private mapper: MapperService,
private cdRef: ChangeDetectorRef) {
super();
this.leftModifiers = ['LShift', 'LCtrl', 'LSuper', 'LAlt'];
this.rightModifiers = ['RShift', 'RCtrl', 'RSuper', 'RAlt'];
this.leftModifiers = mapper.getLeftKeyModifiers();
this.rightModifiers = mapper.getRightKeyModifiers();
this.scanCodeGroups = [{
id: '0',
text: 'None'
}];
this.scanCodeGroups = this.scanCodeGroups.concat(SCANCODES);
this.secondaryRoleGroups = SECONDARY_ROLES;
this.leftModifierSelects = Array(this.leftModifiers.length).fill(false);
this.rightModifierSelects = Array(this.rightModifiers.length).fill(false);
this.selectedScancodeOption = this.scanCodeGroups[0];
this.selectedSecondaryRoleIndex = -1;
}
ngOnChanges() {
ngOnChanges(changes: SimpleChanges) {
if (changes.showLayerSwitcherInSecondaryRoles) {
this.fillSecondaryRoles();
}
this.fromKeyAction(this.defaultKeyAction);
this.validAction.emit(this.keyActionValid());
this.keyActionChanged(false);
}
keyActionValid(keystrokeAction?: KeystrokeAction): boolean {
@@ -56,16 +83,16 @@ export class KeypressTabComponent extends Tab implements OnChanges {
return (keystrokeAction) ? (keystrokeAction.scancode > 0 || keystrokeAction.modifierMask > 0) : false;
}
onKeysCapture(event: { code: number, left: boolean[], right: boolean[] }) {
onKeysCapture(event: { code: number, left: KeyModifierModel[], right: KeyModifierModel[] }) {
if (event.code) {
this.selectedScancodeOption = this.findScancodeOptionByScancode(event.code, KeystrokeType.basic);
} else {
this.selectedScancodeOption = this.scanCodeGroups[0];
}
this.leftModifierSelects = event.left;
this.rightModifierSelects = event.right;
this.validAction.emit(this.keyActionValid());
this.leftModifiers = event.left;
this.rightModifiers = event.right;
this.keyActionChanged();
}
fromKeyAction(keyAction: KeyAction): boolean {
@@ -76,16 +103,12 @@ export class KeypressTabComponent extends Tab implements OnChanges {
// Restore selectedScancodeOption
this.selectedScancodeOption = this.findScancodeOptionByScancode(keystrokeAction.scancode || 0, keystrokeAction.type);
const leftModifiersLength: number = this.leftModifiers.length;
// Restore modifiers
for (let i = 0; i < leftModifiersLength; ++i) {
this.leftModifierSelects[this.mapper.modifierMapper(i)] = ((keystrokeAction.modifierMask >> i) & 1) === 1;
for (const modifier of this.leftModifiers) {
modifier.checked = (keystrokeAction.modifierMask & modifier.value) > 0;
}
for (let i = leftModifiersLength; i < leftModifiersLength + this.rightModifierSelects.length; ++i) {
const index: number = this.mapper.modifierMapper(i) - leftModifiersLength;
this.rightModifierSelects[index] = ((keystrokeAction.modifierMask >> i) & 1) === 1;
for (const modifier of this.rightModifiers) {
modifier.checked = (keystrokeAction.modifierMask & modifier.value) > 0;
}
// Restore secondaryRoleAction
@@ -107,11 +130,7 @@ export class KeypressTabComponent extends Tab implements OnChanges {
} else {
keystrokeAction.type = KeystrokeType[scTypePair[1]];
}
keystrokeAction.modifierMask = 0;
const modifiers = this.leftModifierSelects.concat(this.rightModifierSelects).map(x => x ? 1 : 0);
for (let i = 0; i < modifiers.length; ++i) {
keystrokeAction.modifierMask |= modifiers[i] << this.mapper.modifierMapper(i);
}
keystrokeAction.modifierMask = mapLeftRigthModifierToKeyActionModifier(this.leftModifiers, this.rightModifiers);
keystrokeAction.secondaryRoleAction = this.selectedSecondaryRoleIndex === -1
? undefined
@@ -122,21 +141,31 @@ export class KeypressTabComponent extends Tab implements OnChanges {
}
}
toggleModifier(right: boolean, index: number) {
const modifierSelects: boolean[] = right ? this.rightModifierSelects : this.leftModifierSelects;
modifierSelects[index] = !modifierSelects[index];
this.validAction.emit(this.keyActionValid());
toggleModifier(modifier: KeyModifierModel): void {
modifier.checked = !modifier.checked;
this.keyActionChanged();
}
onSecondaryRoleChange(id: string) {
this.selectedSecondaryRoleIndex = +id;
this.keyActionChanged();
}
onScancodeChange(id: string) {
this.selectedScancodeOption = this.findScancodeOptionById(id);
this.validAction.emit(this.keyActionValid());
this.keyActionChanged();
}
modifiersTrackBy(index: number, modifier: KeyModifierModel): string {
return `${modifier.value}${modifier.checked}`;
}
remapInfoChanged(remapInfo: RemapInfo): void {
this.remapInfo = remapInfo;
const keystrokeAction = this.toKeyAction();
this.calculateRemapOnAllLayerWarningVisibility(keystrokeAction);
this.cdRef.markForCheck();
}
private findScancodeOptionBy(predicate: (option: SelectOptionData) => boolean): SelectOptionData {
@@ -196,4 +225,27 @@ export class KeypressTabComponent extends Tab implements OnChanges {
return [scanCode, type];
}
private keyActionChanged(dispatch = true): void {
const keystrokeAction = this.toKeyAction();
this.validAction.emit(this.keyActionValid(keystrokeAction));
this.calculateRemapOnAllLayerWarningVisibility(keystrokeAction);
if (dispatch) {
this.keyActionChange.emit(keystrokeAction);
}
}
private calculateRemapOnAllLayerWarningVisibility(keystrokeAction: KeystrokeAction): void {
this.warningVisible = this.allowRemapOnAllKeymapWarning &&
this.remapInfo &&
!this.remapInfo.remapOnAllLayer &&
keystrokeAction &&
!keystrokeAction.hasScancode() &&
keystrokeAction.hasOnlyOneActiveModifier();
}
private fillSecondaryRoles(): void {
this.secondaryRoleGroups = SECONDARY_ROLES
.filter(secondaryRoleFilter(this.showLayerSwitcherInSecondaryRoles));
}
}

View File

@@ -1,10 +1,13 @@
import { EventEmitter, Output } from '@angular/core';
import { KeyAction } from 'uhk-common';
import { RemapInfo } from '../../../models/remap-info';
export abstract class Tab {
@Output() validAction = new EventEmitter<boolean>();
abstract keyActionValid(): boolean;
abstract fromKeyAction(keyAction: KeyAction): boolean;
abstract toKeyAction(): KeyAction;
remapInfoChanged(remapInfo: RemapInfo): void {}
}

View File

@@ -1,10 +1,12 @@
import { Component, EventEmitter, HostListener, Output, Input } from '@angular/core';
import { ChangeDetectionStrategy, Component, EventEmitter, HostListener, Input, Output } from '@angular/core';
import { CaptureService } from '../../../../services/capture.service';
import { KeyModifierModel } from '../../../../models/key-modifier-model';
@Component({
selector: 'capture-keystroke-button',
templateUrl: './capture-keystroke-button.component.html',
styleUrls: ['./capture-keystroke-button.component.scss']
styleUrls: ['./capture-keystroke-button.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CaptureKeystrokeButtonComponent {
@Input() isLink = false;
@@ -67,8 +69,8 @@ export class CaptureKeystrokeButtonComponent {
private saveScanCode(code?: number) {
this.record = false;
const left: boolean[] = this.captureService.getModifiers(true);
const right: boolean[] = this.captureService.getModifiers(false);
const left: KeyModifierModel[] = this.captureService.getModifiers(true);
const right: KeyModifierModel[] = this.captureService.getModifiers(false);
this.capture.emit({
code,

View File

@@ -1,9 +1,10 @@
import { Component, Input, OnInit } from '@angular/core';
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'icon',
templateUrl: './icon.component.html',
styleUrls: ['./icon.component.scss']
styleUrls: ['./icon.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class IconComponent implements OnInit {

View File

@@ -21,9 +21,13 @@
</p>
<div *ngIf="state.showWhatWillThisDoContent">
Agent uses the following script to set up permissions. You can run it manually as root, then
<a class="link-inline"
(click)="retry()">retry</a>.
If you want to set up permissions manually:
<ol>
<li>Open a terminal.</li>
<li>Run <code>su</code> to become root.</li>
<li>Paste the following script, and <a class="link-inline" (click)="retry()">retry</a>.</li>
</ol>
<div class="copy-container">
<span class="fa fa-2x fa-copy"
ngxClipboard

View File

@@ -1,5 +1,5 @@
<label *ngIf="label">
<span>{{label}}</span>
<span [innerHtml]="label"></span>
<icon name="question-circle"
data-toggle="tooltip"
[title]="tooltip"

View File

@@ -0,0 +1 @@
export const SECONDARY_ROLE_BOTTOM_MARGIN = 1;

View File

@@ -11,3 +11,4 @@ export { SvgSingleIconKeyComponent } from './svg-single-icon-key';
export { SvgSwitchKeymapKeyComponent } from './svg-switch-keymap-key';
export { SvgTextIconKeyComponent } from './svg-text-icon-key';
export { SvgTwoLineTextKeyComponent } from './svg-two-line-text-key';
export { SvgSecondaryRoleComponent } from './svg-secondary-role';

View File

@@ -11,3 +11,10 @@
[attr.font-size]="11">
<tspan [attr.x]="spanX">{{ text }}</tspan>
</svg:text>
<svg:g svg-secondary-role
*ngIf="secondaryText"
[height]="20"
[width]="width"
[y]="secondaryTextY"
[text]="secondaryText">
</svg:g>

Before

Width:  |  Height:  |  Size: 331 B

After

Width:  |  Height:  |  Size: 499 B

View File

@@ -1,15 +1,19 @@
import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core';
import { Component, Input, ChangeDetectionStrategy, OnChanges, SimpleChanges } from '@angular/core';
import { isRectangleAsSecondaryRoleKey } from '../util';
import { SECONDARY_ROLE_BOTTOM_MARGIN } from '../../constants';
@Component({
selector: 'g[svg-icon-text-key]',
templateUrl: './svg-icon-text-key.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SvgIconTextKeyComponent implements OnInit {
export class SvgIconTextKeyComponent implements OnChanges {
@Input() width: number;
@Input() height: number;
@Input() icon: string;
@Input() text: string;
@Input() secondaryText: string;
useWidth: number;
useHeight: number;
@@ -17,16 +21,33 @@ export class SvgIconTextKeyComponent implements OnInit {
useY: number;
textY: number;
spanX: number;
secondaryTextY: number;
secondaryHeight: number;
constructor() {
}
ngOnInit() {
ngOnChanges(changes: SimpleChanges): void {
this.calculatePositions();
}
private calculatePositions(): void {
let textYModifier = 0;
let secondaryYModifier = 0;
if (this.secondaryText && isRectangleAsSecondaryRoleKey(this.width, this.height)) {
textYModifier = this.height / 5;
secondaryYModifier = 5;
}
this.useWidth = this.width / 3;
this.useHeight = this.height / 3;
this.useX = (this.width > 2 * this.height) ? 0 : this.width / 3;
this.useY = (this.width > 2 * this.height) ? this.height / 3 : this.height / 10;
this.textY = (this.width > 2 * this.height) ? this.height / 2 : this.height * 0.6;
this.spanX = (this.width > 2 * this.height) ? this.width * 0.6 : this.width / 2;
this.secondaryHeight = this.height / 4;
this.secondaryTextY = this.height - this.secondaryHeight - SECONDARY_ROLE_BOTTOM_MARGIN - secondaryYModifier;
}
}

View File

@@ -25,34 +25,40 @@
<svg:g svg-keystroke-key *ngSwitchCase="enumLabelTypes.KeystrokeKey"
[height]="height"
[width]="width"
[keystrokeAction]="labelSource">
[keystrokeAction]="labelSource"
[secondaryText]="secondaryText">
</svg:g>
<svg:g svg-one-line-text-key *ngSwitchCase="enumLabelTypes.OneLineText"
[height]="height"
[width]="width"
[text]="labelSource">
[text]="labelSource"
[secondaryText]="secondaryText">
</svg:g>
<svg:g svg-two-line-text-key *ngSwitchCase="enumLabelTypes.TwoLineText"
[height]="height"
[width]="width"
[texts]="labelSource">
[texts]="labelSource"
[secondaryText]="secondaryText">
</svg:g>
<svg:g svg-text-icon-key *ngSwitchCase="enumLabelTypes.TextIcon"
[height]="height"
[width]="width"
[text]="labelSource.text"
[icon]="labelSource.icon">
[icon]="labelSource.icon"
[secondaryText]="secondaryText">
</svg:g>
<svg:g svg-icon-text-key *ngSwitchCase="enumLabelTypes.IconText"
[height]="height"
[width]="width"
[icon]="labelSource.icon"
[text]="labelSource.text">
[text]="labelSource.text"
[secondaryText]="secondaryText">
</svg:g>
<svg:g svg-single-icon-key *ngSwitchCase="enumLabelTypes.SingleIcon"
[height]="height"
[width]="width"
[icon]="labelSource">
[icon]="labelSource"
[secondaryText]="secondaryText">
</svg:g>
<svg:g svg-switch-keymap-key *ngSwitchCase="enumLabelTypes.SwitchKeymap"
[height]="height"

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -27,6 +27,8 @@ import { MapperService } from '../../../../services/mapper.service';
import { AppState } from '../../../../store';
import { getMacros } from '../../../../store/reducers/user-configuration';
import { SvgKeyCaptureEvent, SvgKeyClickEvent } from '../../../../models/svg-key-events';
import { OperatingSystem } from '../../../../models/operating-system';
import { KeyModifierModel } from '../../../../models/key-modifier-model';
enum LabelTypes {
KeystrokeKey,
@@ -94,6 +96,7 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
labelType: LabelTypes;
labelSource: any;
secondaryText: string;
macros: Macro[];
private subscription: Subscription;
private scanCodePressed: boolean;
@@ -117,14 +120,16 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
this.scanCodePressed = false;
}
@HostListener('click')
onClick() {
@HostListener('click', ['$event'])
onClick(e: MouseEvent) {
this.reset();
this.keyClick.emit({
keyTarget: this.element.nativeElement,
shiftPressed: this.pressedShiftLocation > -1,
altPressed: this.pressedAltLocation > -1
shiftPressed: e.shiftKey,
altPressed: e.altKey
});
this.pressedShiftLocation = -1;
this.pressedAltLocation = -1;
}
@HostListener('mousedown', ['$event'])
@@ -138,14 +143,8 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
} else {
this.recording = true;
this.recordAnimation = 'active';
if (this.pressedShiftLocation > -1) {
this.shiftPressed = true;
}
if (this.pressedAltLocation > -1) {
this.altPressed = true;
}
this.shiftPressed = e.shiftKey;
this.altPressed = e.altKey;
}
}
}
@@ -246,8 +245,8 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
}
private saveScanCode(code = 0) {
const left: boolean[] = this.captureService.getModifiers(true);
const right: boolean[] = this.captureService.getModifiers(false);
const left: KeyModifierModel[] = this.captureService.getModifiers(true);
const right: KeyModifierModel[] = this.captureService.getModifiers(false);
this.capture.emit({
captured: {
@@ -263,17 +262,18 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
}
private setLabels(): void {
if (!this.keyAction) {
this.labelSource = undefined;
this.labelType = LabelTypes.OneLineText;
this.labelSource = undefined;
this.secondaryText = undefined;
if (!this.keyAction) {
return;
}
this.labelType = LabelTypes.OneLineText;
if (this.keyAction instanceof KeystrokeAction) {
const keyAction: KeystrokeAction = this.keyAction as KeystrokeAction;
let newLabelSource: string[];
this.secondaryText = this.mapper.getSecondaryRoleText(keyAction.secondaryRoleAction);
if (!keyAction.hasActiveModifier() && keyAction.hasScancode()) {
const scancode: number = keyAction.scancode;
@@ -291,29 +291,32 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
}
}
} else if (keyAction.hasOnlyOneActiveModifier() && !keyAction.hasScancode()) {
newLabelSource = [];
switch (keyAction.modifierMask) {
case KeyModifiers.leftCtrl:
case KeyModifiers.rightCtrl:
newLabelSource.push('Ctrl');
this.labelSource = ['Ctrl'];
break;
case KeyModifiers.leftShift:
case KeyModifiers.rightShift:
newLabelSource.push('Shift');
this.labelSource = ['Shift'];
break;
case KeyModifiers.leftAlt:
case KeyModifiers.rightAlt:
newLabelSource.push('Alt');
this.labelSource = [this.mapper.getOsSpecificText('Alt')];
break;
case KeyModifiers.leftGui:
case KeyModifiers.rightGui:
newLabelSource.push('Super');
if (this.mapper.getOperatingSystem() === OperatingSystem.Windows) {
this.labelSource = this.mapper.getIcon('command');
this.labelType = LabelTypes.SingleIcon;
} else {
this.labelSource = [this.mapper.getOsSpecificText('Super')];
}
break;
default:
newLabelSource.push('Undefined');
this.labelSource = ['Undefined'];
break;
}
this.labelSource = newLabelSource;
} else {
this.labelType = LabelTypes.KeystrokeKey;
this.labelSource = this.keyAction;

View File

@@ -13,7 +13,8 @@
<svg:g svg-two-line-text-key *ngSwitchCase="'two-line'"
[height]="height"
[width]="width"
[texts]="labelSource">
[texts]="labelSource"
[secondaryText]="subComponentSecondaryRoleText">
</svg:g>
</svg>
<svg [attr.viewBox]="viewBox" [attr.width]="modifierContainer.width" [attr.height]="modifierContainer.height" [attr.x]="modifierContainer.x"
@@ -28,10 +29,19 @@
</svg>
<svg viewBox="0 0 100 100" [attr.width]="option.width" [attr.height]="option.height" [attr.x]="option.x" [attr.y]="option.y"
preserveAspectRatio="none" [class.disabled]="option.disabled">
<svg:use [attr.xlink:href]="modifierIconNames.option" />
<svg:use *ngIf="modifierIconNames.option" [attr.xlink:href]="modifierIconNames.option" />
<svg:text *ngIf="!modifierIconNames.option" [attr.text-anchor]="'middle'" [attr.x]="50" [attr.y]="50">A</svg:text>
</svg>
<svg viewBox="0 0 100 100" [attr.width]="command.width" [attr.height]="command.height" [attr.x]="command.x" [attr.y]="command.y"
preserveAspectRatio="none" [class.disabled]="command.disabled">
<svg:use [attr.xlink:href]="modifierIconNames.command" />
<svg:use *ngIf="modifierIconNames.command" [attr.xlink:href]="modifierIconNames.command" />
<svg:text *ngIf="!modifierIconNames.command" [attr.text-anchor]="'middle'" [attr.x]="50" [attr.y]="50">S</svg:text>
</svg>
</svg>
<svg:g svg-secondary-role
*ngIf="thisSecondaryRoleText"
[height]="20"
[width]="secondaryTextWidth"
[y]="secondaryTextY"
[text]="thisSecondaryRoleText">
</svg:g>

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -1,7 +1,9 @@
import { Component, Input, OnChanges, OnInit, ChangeDetectionStrategy } from '@angular/core';
import { Component, Input, OnChanges, ChangeDetectionStrategy } from '@angular/core';
import { KeyModifiers, KeystrokeAction } from 'uhk-common';
import { MapperService } from '../../../../services/mapper.service';
import { isRectangleAsSecondaryRoleKey } from '../util';
import { SECONDARY_ROLE_BOTTOM_MARGIN } from '../../constants';
class SvgAttributes {
width: number;
@@ -25,10 +27,11 @@ class SvgAttributes {
styleUrls: ['./svg-keystroke-key.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SvgKeystrokeKeyComponent implements OnInit, OnChanges {
export class SvgKeystrokeKeyComponent implements OnChanges {
@Input() height: number;
@Input() width: number;
@Input() keystrokeAction: KeystrokeAction;
@Input() secondaryText: string;
viewBox: string;
textContainer: SvgAttributes;
@@ -46,6 +49,11 @@ export class SvgKeystrokeKeyComponent implements OnInit, OnChanges {
option?: string,
command?: string
};
secondaryTextY: number;
secondaryTextWidth: number;
secondaryHeight: number;
thisSecondaryRoleText: string;
subComponentSecondaryRoleText: string;
constructor(private mapper: MapperService) {
this.modifierIconNames = {};
@@ -57,15 +65,75 @@ export class SvgKeystrokeKeyComponent implements OnInit, OnChanges {
this.command = new SvgAttributes();
}
ngOnInit() {
ngOnChanges() {
this.calculatePositions();
}
private calculatePositions(): void {
let textYModifier = 0;
let secondaryYModifier = 0;
this.thisSecondaryRoleText = this.secondaryText;
this.subComponentSecondaryRoleText = null;
const bottomSideMode: boolean = this.width < this.height * 1.8;
const isRectangleAsSecondaryRole = isRectangleAsSecondaryRoleKey(this.width, this.height);
if (this.secondaryText && isRectangleAsSecondaryRole) {
textYModifier = this.height / 5;
secondaryYModifier = 5;
}
if (this.keystrokeAction.hasScancode()) {
const scancode: number = this.keystrokeAction.scancode;
this.labelSource = this.mapper.scanCodeToSvgImagePath(scancode, this.keystrokeAction.type);
if (this.labelSource) {
this.labelType = 'icon';
} else {
let newLabelSource: string[];
newLabelSource = this.mapper.scanCodeToText(scancode, this.keystrokeAction.type);
if (newLabelSource) {
if (this.secondaryText && newLabelSource.length === 2) {
if (isRectangleAsSecondaryRole || bottomSideMode) {
this.labelSource = newLabelSource[0];
this.labelType = 'one-line';
} else {
this.labelSource = newLabelSource;
this.labelType = 'two-line';
this.thisSecondaryRoleText = null;
this.subComponentSecondaryRoleText = this.secondaryText;
}
}
else {
if (newLabelSource.length === 1) {
this.labelSource = newLabelSource[0];
this.labelType = 'one-line';
} else {
this.labelSource = newLabelSource;
this.labelType = 'two-line';
}
}
}
}
} else {
this.labelType = 'empty';
}
this.shift.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftShift | KeyModifiers.rightShift);
this.control.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftCtrl | KeyModifiers.rightCtrl);
this.option.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftAlt | KeyModifiers.rightAlt);
this.command.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftGui | KeyModifiers.rightGui);
this.secondaryHeight = this.secondaryText ? this.height / 4 : 0;
this.secondaryTextY = this.height - this.secondaryHeight - SECONDARY_ROLE_BOTTOM_MARGIN - secondaryYModifier;
this.viewBox = [0, 0, this.width, this.height].join(' ');
this.modifierIconNames.shift = this.mapper.getIcon('shift');
this.modifierIconNames.option = this.mapper.getIcon('option');
this.modifierIconNames.command = this.mapper.getIcon('command');
const bottomSideMode: boolean = this.width < this.height * 1.8;
this.textContainer.y = 0;
const heightWidthRatio = this.height / this.width;
this.secondaryTextWidth = this.width;
if (bottomSideMode) {
const maxIconWidth = this.width / 4;
@@ -75,7 +143,7 @@ export class SvgKeystrokeKeyComponent implements OnInit, OnChanges {
const iconHeight = iconScalingFactor * maxIconHeight;
this.modifierContainer.width = this.width;
this.modifierContainer.height = this.height / 5;
this.modifierContainer.y = this.height - this.modifierContainer.height;
this.modifierContainer.y = this.height - this.modifierContainer.height - this.secondaryHeight;
this.shift.width = iconWidth;
this.shift.height = iconHeight;
this.shift.x = (maxIconWidth - iconWidth) / 2;
@@ -92,7 +160,7 @@ export class SvgKeystrokeKeyComponent implements OnInit, OnChanges {
this.command.height = iconHeight;
this.command.x = this.option.x + maxIconWidth;
this.command.y = this.shift.y;
this.textContainer.y = -this.modifierContainer.height / 2;
this.textContainer.y = -this.modifierContainer.height / 2 - this.secondaryHeight / 2;
} else {
this.modifierContainer.width = this.width / 4;
this.modifierContainer.height = this.height;
@@ -120,40 +188,11 @@ export class SvgKeystrokeKeyComponent implements OnInit, OnChanges {
this.command.x = this.option.x + this.width / 2;
this.command.y = this.option.y;
this.textContainer.x = -this.modifierContainer.width / 2;
this.secondaryTextWidth = this.width - this.modifierContainer.width;
}
this.textContainer.y -= textYModifier;
this.textContainer.width = this.width;
this.textContainer.height = this.height;
}
ngOnChanges() {
if (this.keystrokeAction.hasScancode()) {
const scancode: number = this.keystrokeAction.scancode;
this.labelSource = this.mapper.scanCodeToSvgImagePath(scancode, this.keystrokeAction.type);
if (this.labelSource) {
this.labelType = 'icon';
} else {
let newLabelSource: string[];
newLabelSource = this.mapper.scanCodeToText(scancode, this.keystrokeAction.type);
if (newLabelSource) {
if (newLabelSource.length === 1) {
this.labelSource = newLabelSource[0];
this.labelType = 'one-line';
} else {
this.labelSource = newLabelSource;
this.labelType = 'two-line';
}
}
}
} else {
this.labelType = 'empty';
}
this.shift.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftShift | KeyModifiers.rightShift);
this.control.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftCtrl | KeyModifiers.rightCtrl);
this.option.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftAlt | KeyModifiers.rightAlt);
this.command.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftGui | KeyModifiers.rightGui);
}
}

View File

@@ -4,3 +4,10 @@
[attr.text-anchor]="'middle'">
<tspan [attr.x]="spanX" dy="0">{{ text }}</tspan>
</svg:text>
<svg:g svg-secondary-role
*ngIf="secondaryText"
[height]="20"
[width]="width"
[y]="secondaryTextY"
[text]="secondaryText">
</svg:g>

Before

Width:  |  Height:  |  Size: 154 B

After

Width:  |  Height:  |  Size: 316 B

View File

@@ -1,22 +1,43 @@
import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core';
import { Component, Input, ChangeDetectionStrategy, OnChanges, SimpleChanges } from '@angular/core';
import { isRectangleAsSecondaryRoleKey } from '../util';
import { SECONDARY_ROLE_BOTTOM_MARGIN } from '../../constants';
@Component({
selector: 'g[svg-one-line-text-key]',
templateUrl: './svg-one-line-text-key.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SvgOneLineTextKeyComponent implements OnInit {
export class SvgOneLineTextKeyComponent implements OnChanges {
@Input() height: number;
@Input() width: number;
@Input() text: string;
@Input() secondaryText: string;
textY: number;
spanX: number;
secondaryTextY: number;
secondaryHeight: number;
constructor() { }
ngOnInit() {
this.textY = this.height / 2;
ngOnChanges(changes: SimpleChanges): void {
this.calculatePositions();
}
calculatePositions() {
let textYModifier = 0;
let secondaryYModifier = 0;
if (this.secondaryText && isRectangleAsSecondaryRoleKey(this.width, this.height)) {
textYModifier = this.height / 5;
secondaryYModifier = 5;
}
this.textY = this.height / 2 - textYModifier;
this.spanX = this.width / 2;
this.secondaryHeight = this.height / 4;
this.secondaryTextY = this.height - this.secondaryHeight - SECONDARY_ROLE_BOTTOM_MARGIN - secondaryYModifier;
}
}

View File

@@ -0,0 +1 @@
export * from './svg-secondary-role.component';

View File

@@ -0,0 +1,15 @@
<svg [attr.viewBox]="viewBox" [attr.width]="width" [attr.height]="height" [attr.y]="y">
<g id="secondaryContent" [attr.transform]="transform">
<svg viewBox="0 0 14 14" width="12" height="12" x="2" [attr.y]="textY / 3.5">
<ellipse stroke="#fff" rx="6.5" ry="6.5" cy="7" cx="7" stroke-width="1" fill-opacity="0"/>
<text text-anchor="start" font-family="Helvetica" font-size="12" y="7.8" x="4" stroke-width="0">2
</text>
</svg>
<text [attr.y]="textY"
[attr.x]="textIndent"
font-size="12"
text-anchor="start">
{{ text }}
</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 667 B

View File

@@ -0,0 +1,52 @@
import {
ChangeDetectionStrategy,
Component,
ElementRef,
Input,
OnChanges,
OnInit,
SimpleChanges,
ViewChild
} from '@angular/core';
import { getContentWidth } from '../../../../util';
const SECONDARY_STYLE: CSSStyleDeclaration = {
font: '12px Helvetica'
} as any;
@Component({
selector: 'g[svg-secondary-role]',
templateUrl: './svg-secondary-role.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SvgSecondaryRoleComponent implements OnInit, OnChanges {
@Input() height: number;
@Input() width: number;
@Input() y: number;
@Input() text: string;
@ViewChild('secondary') svgElement: ElementRef;
viewBox: string;
textY: number;
transform: string;
textIndent = 16;
ngOnInit(): void {
this.viewBox = [0, 0, this.width, this.height].join(' ');
this.textY = this.height / 2 - 2;
}
ngOnChanges(changes: SimpleChanges): void {
if (changes.text) {
this.calculateTextPosition();
}
}
private calculateTextPosition(): void {
const textWidth = getContentWidth(SECONDARY_STYLE, this.text) + this.textIndent;
const translateValue = Math.max(0, (this.width - textWidth) / 2);
this.transform = `translate(${ translateValue },0)`;
}
}

View File

@@ -4,3 +4,10 @@
[attr.x]="svgWidth"
[attr.y]="svgHeight">
</svg:use>
<svg:g svg-secondary-role
*ngIf="secondaryText"
[height]="20"
[width]="width"
[y]="secondaryTextY"
[text]="secondaryText">
</svg:g>

Before

Width:  |  Height:  |  Size: 173 B

After

Width:  |  Height:  |  Size: 340 B

View File

@@ -1,22 +1,42 @@
import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core';
import { Component, Input, ChangeDetectionStrategy, OnChanges, SimpleChanges } from '@angular/core';
import { isRectangleAsSecondaryRoleKey } from '../util';
import { SECONDARY_ROLE_BOTTOM_MARGIN } from '../../constants';
@Component({
selector: 'g[svg-single-icon-key]',
templateUrl: './svg-single-icon-key.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SvgSingleIconKeyComponent implements OnInit {
export class SvgSingleIconKeyComponent implements OnChanges {
@Input() width: number;
@Input() height: number;
@Input() icon: string;
@Input() secondaryText: string;
svgHeight: number;
svgWidth: number;
secondaryTextY: number;
secondaryHeight: number;
constructor() { }
ngOnInit() {
ngOnChanges(changes: SimpleChanges): void {
this.calculatePositions();
}
calculatePositions(): void {
let textYModifier = 0;
let secondaryYModifier = 0;
if (this.secondaryText && isRectangleAsSecondaryRoleKey(this.width, this.height)) {
textYModifier = this.height / 5;
secondaryYModifier = 5;
}
this.svgWidth = this.width / 3;
this.svgHeight = this.height / 3;
this.secondaryHeight = this.height / 4;
this.secondaryTextY = this.height - this.secondaryHeight - SECONDARY_ROLE_BOTTOM_MARGIN - secondaryYModifier;
}
}

View File

@@ -10,3 +10,10 @@
[attr.x]="useX"
[attr.y]="useY">
</svg:use>
<svg:g svg-secondary-role
*ngIf="secondaryText"
[height]="20"
[width]="width"
[y]="secondaryTextY"
[text]="secondaryText">
</svg:g>

Before

Width:  |  Height:  |  Size: 309 B

After

Width:  |  Height:  |  Size: 484 B

View File

@@ -1,15 +1,19 @@
import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core';
import { Component, Input, ChangeDetectionStrategy, OnChanges, SimpleChanges } from '@angular/core';
import { isRectangleAsSecondaryRoleKey } from '../util';
import { SECONDARY_ROLE_BOTTOM_MARGIN } from '../../constants';
@Component({
selector: 'g[svg-text-icon-key]',
templateUrl: './svg-text-icon-key.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SvgTextIconKeyComponent implements OnInit {
export class SvgTextIconKeyComponent implements OnChanges {
@Input() width: number;
@Input() height: number;
@Input() text: string;
@Input() icon: string;
@Input() secondaryText: string;
useWidth: number;
useHeight: number;
@@ -18,16 +22,33 @@ export class SvgTextIconKeyComponent implements OnInit {
textY: number;
textAnchor: string;
spanX: number;
secondaryTextY: number;
secondaryHeight: number;
constructor() { }
ngOnInit() {
ngOnChanges(changes: SimpleChanges): void {
this.calculatePositions();
}
calculatePositions(): void {
let textYModifier = 0;
let secondaryYModifier = 0;
if (this.secondaryText && isRectangleAsSecondaryRoleKey(this.width, this.height)) {
textYModifier = this.height / 5;
secondaryYModifier = 5;
}
this.useWidth = this.width / 3;
this.useHeight = this.height / 3;
this.useX = (this.width > 2 * this.height) ? this.width * 0.6 : this.width / 3;
this.useY = (this.width > 2 * this.height) ? this.height / 3 : this.height / 2;
this.textY = (this.width > 2 * this.height) ? this.height / 2 : this.height / 3;
this.textY = ((this.width > 2 * this.height) ? this.height / 2 : this.height / 3) - textYModifier;
this.textAnchor = (this.width > 2 * this.height) ? 'end' : 'middle';
this.spanX = (this.width > 2 * this.height) ? 0.6 * this.width : this.width / 2;
this.secondaryHeight = this.height / 4;
this.secondaryTextY = this.height - this.secondaryHeight - SECONDARY_ROLE_BOTTOM_MARGIN - secondaryYModifier;
}
}

View File

@@ -9,3 +9,10 @@
dy="0"
>{{ text }}</tspan>
</svg:text>
<svg:g svg-secondary-role
*ngIf="secondaryText"
[height]="20"
[width]="width"
[y]="secondaryTextY"
[text]="secondaryText">
</svg:g>

Before

Width:  |  Height:  |  Size: 306 B

After

Width:  |  Height:  |  Size: 474 B

View File

@@ -1,28 +1,51 @@
import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core';
import { Component, Input, ChangeDetectionStrategy, SimpleChanges, OnChanges } from '@angular/core';
import { SECONDARY_ROLE_BOTTOM_MARGIN } from '../../constants';
@Component({
selector: 'g[svg-two-line-text-key]',
templateUrl: './svg-two-line-text-key.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SvgTwoLineTextKeyComponent implements OnInit {
export class SvgTwoLineTextKeyComponent implements OnChanges {
@Input() height: number;
@Input() width: number;
@Input() texts: string[];
@Input() secondaryText: string;
textY: number;
spanX: number;
spanYs: number[];
secondaryTextY: number;
secondaryHeight: number;
constructor() {
this.spanYs = [];
}
ngOnInit() {
this.textY = this.height / 2;
ngOnChanges(changes: SimpleChanges): void {
this.calculatePositions();
}
calculatePositions(): void {
let textYModifier = 0;
let secondaryYModifier = 0;
this.secondaryHeight = 0;
let textContainerHeight = this.height;
if (this.secondaryText) {
textYModifier = this.height / 5;
secondaryYModifier = 0;
this.secondaryHeight = this.height / 4;
textContainerHeight -= this.secondaryHeight;
}
this.textY = textContainerHeight / 2;
this.spanX = this.width / 2;
this.spanYs = [];
for (let i = 0; i < this.texts.length; ++i) {
this.spanYs.push((0.75 - i * 0.5) * this.height);
}
this.spanYs.push((0.75 - i * 0.5) * textContainerHeight);
}
this.secondaryTextY = this.height - this.secondaryHeight - SECONDARY_ROLE_BOTTOM_MARGIN - secondaryYModifier;
}
}

View File

@@ -0,0 +1,3 @@
export const isRectangleAsSecondaryRoleKey = (width: number, height: number): boolean => {
return width > height * 2.4;
};

View File

@@ -22,8 +22,7 @@
[currentKeymap]="keymap"
[currentLayer]="currentLayer"
[allowLayerDoubleTap]="allowLayerDoubleTap"
[remapOnAllKeymap]="remapOnAllKeymap"
[remapOnAllLayer]="remapOnAllLayer"
[remapInfo]="remapInfo"
(cancel)="hidePopover()"
(remap)="onRemap($event)"></popover>

View File

@@ -48,6 +48,8 @@ import {
SvgKeyboardKeyClickEvent,
SvgKeyHoverEvent
} from '../../../models/svg-key-events';
import { RemapInfo } from '../../../models/remap-info';
import { mapLeftRigthModifierToKeyActionModifier } from '../../../util';
interface NameValuePair {
name: string;
@@ -87,8 +89,10 @@ export class SvgKeyboardWrapComponent implements OnInit, OnChanges {
layers: Layer[];
keyPosition: ClientRect;
wrapPosition: ClientRect;
remapOnAllKeymap: boolean;
remapOnAllLayer: boolean;
remapInfo: RemapInfo = {
remapOnAllKeymap: false,
remapOnAllLayer: false
};
private wrapHost: HTMLElement;
private keyElement: HTMLElement;
@@ -156,8 +160,10 @@ export class SvgKeyboardWrapComponent implements OnInit, OnChanges {
this.selectedKey = {layerId: this.currentLayer, moduleId: event.moduleId, keyId: event.keyId};
const keyActionToEdit: KeyAction = this.layers[this.currentLayer].modules[event.moduleId].keyActions[event.keyId];
this.keyElement = event.keyTarget;
this.remapOnAllKeymap = event.shiftPressed;
this.remapOnAllLayer = event.altPressed;
this.remapInfo = {
remapOnAllKeymap: event.shiftPressed,
remapOnAllLayer: event.altPressed
};
this.showPopover(keyActionToEdit);
}
}
@@ -176,14 +182,9 @@ export class SvgKeyboardWrapComponent implements OnInit, OnChanges {
onCapture(event: SvgKeyboardCaptureEvent): void {
const keystrokeAction: KeystrokeAction = new KeystrokeAction();
const modifiers = event.captured.left.concat(event.captured.right).map(x => x ? 1 : 0);
keystrokeAction.scancode = event.captured.code;
keystrokeAction.modifierMask = 0;
for (let i = 0; i < modifiers.length; ++i) {
keystrokeAction.modifierMask |= modifiers[i] << this.mapper.modifierMapper(i);
}
keystrokeAction.modifierMask = mapLeftRigthModifierToKeyActionModifier(event.captured.left, event.captured.right);
this.store.dispatch(
KeymapActions.saveKey(

View File

@@ -0,0 +1,7 @@
import { KeyModifiers } from 'uhk-common';
export interface KeyModifierModel {
text: string;
value: KeyModifiers;
checked: boolean;
}

View File

@@ -0,0 +1,5 @@
export enum OperatingSystem {
Linux,
Mac,
Windows
}

View File

@@ -0,0 +1,4 @@
export interface RemapInfo {
remapOnAllKeymap: boolean;
remapOnAllLayer: boolean;
}

View File

@@ -1,3 +1,5 @@
import { KeyModifierModel } from './key-modifier-model';
export interface SvgKeyClickEvent {
keyTarget: HTMLElement;
shiftPressed?: boolean;
@@ -14,8 +16,8 @@ export interface SvgKeyboardKeyClickEvent extends SvgModuleKeyClickEvent {
export interface KeyCaptureData {
code: number;
left: boolean[];
right: boolean[];
left: KeyModifierModel[];
right: KeyModifierModel[];
}
export interface SvgKeyCaptureEvent {

View File

@@ -1,14 +1,18 @@
import { Injectable } from '@angular/core';
import { MapperService } from './mapper.service';
import { KeyModifiers } from 'uhk-common';
import { KeyModifierModel } from '../models/key-modifier-model';
@Injectable()
export class CaptureService {
private mapping: Map<number, number>;
private leftModifiers: Map<number, boolean>;
private rightModifiers: Map<number, boolean>;
private readonly leftModifiers: Map<number, KeyModifierModel>;
private readonly rightModifiers: Map<number, KeyModifierModel>;
constructor() {
this.leftModifiers = new Map<number, boolean>();
this.rightModifiers = new Map<number, boolean>();
constructor(private mapper: MapperService) {
this.leftModifiers = new Map<number, KeyModifierModel>();
this.rightModifiers = new Map<number, KeyModifierModel>();
this.mapping = new Map<number, number>();
}
@@ -21,23 +25,58 @@ export class CaptureService {
}
public setModifier(left: boolean, code: number) {
return left ? this.leftModifiers.set(code, true) : this.rightModifiers.set(code, true);
const map = left ? this.leftModifiers : this.rightModifiers;
map.get(code).checked = true;
}
public getModifiers(left: boolean) {
return left ? this.reMap(this.leftModifiers) : this.reMap(this.rightModifiers);
const map = left ? this.leftModifiers : this.rightModifiers;
return Array.from(map.values());
}
public initModifiers() {
this.leftModifiers.set(16, false); // Shift
this.leftModifiers.set(17, false); // Ctrl
this.leftModifiers.set(18, false); // Alt
this.leftModifiers.set(91, false); // Super
this.leftModifiers.set(16, {
text: 'LShift',
value: KeyModifiers.leftShift,
checked: false
});
this.leftModifiers.set(17, {
text: 'LCtrl',
value: KeyModifiers.leftCtrl,
checked: false
});
this.leftModifiers.set(18, {
text: this.mapper.getOsSpecificText('LAlt'),
value: KeyModifiers.leftAlt,
checked: false
});
this.leftModifiers.set(91, {
text: this.mapper.getOsSpecificText('LSuper'),
value: KeyModifiers.leftGui,
checked: false
});
this.rightModifiers.set(16, false); // Shift
this.rightModifiers.set(17, false); // Ctrl
this.rightModifiers.set(18, false); // Alt
this.rightModifiers.set(91, false); // Super
this.rightModifiers.set(16, {
text: 'RShift',
value: KeyModifiers.rightShift,
checked: false
});
this.rightModifiers.set(17, {
text: 'RCtrl',
value: KeyModifiers.rightCtrl,
checked: false
});
this.rightModifiers.set(18, {
text: this.mapper.getOsSpecificText('RAlt'),
value: KeyModifiers.rightAlt,
checked: false
});
this.rightModifiers.set(91, {
text: this.mapper.getOsSpecificText('RSuper'),
value: KeyModifiers.rightGui,
checked: false
});
}
public populateMapping() {
@@ -136,8 +175,4 @@ export class CaptureService {
this.mapping.set(221, 48); // Close bracket
this.mapping.set(222, 52); // Single quote
}
private reMap(value: Map<number, boolean>): boolean[] {
return [value.get(16), value.get(17), value.get(91), value.get(18)];
}
}

View File

@@ -1,22 +1,40 @@
import { Injectable } from '@angular/core';
import { KeystrokeType } from 'uhk-common';
import { Store } from '@ngrx/store';
import { KeyModifiers, KeystrokeType, SecondaryRoleAction } from 'uhk-common';
import { Subscription } from 'rxjs/Subscription';
import { AppState, getOperatingSystem } from '../store';
import { OperatingSystem } from '../models/operating-system';
import { KeyModifierModel } from '../models/key-modifier-model';
@Injectable()
export class MapperService {
private basicScanCodeTextMap: Map<number, string[]>;
private mediaScanCodeTextMap: Map<number, string[]>;
private sytemScanCodeTextMap: Map<number, string[]>;
private systemScanCodeTextMap: Map<number, string[]>;
private basicScancodeIcons: Map<number, string>;
private mediaScancodeIcons: Map<number, string>;
private systemScancodeIcons: Map<number, string>;
private nameToFileName: Map<string, string>;
private osSpecificTexts: Map<string, string>;
private secondaryRoleTexts: Map<number, string>;
constructor() {
private operatingSystem: OperatingSystem;
private osSubscription: Subscription;
constructor(private store: Store<AppState>) {
this.osSubscription = store
.select(getOperatingSystem)
.subscribe(os => {
this.operatingSystem = os;
this.initOsSpecificText();
this.initScanCodeTextMap();
this.initScancodeIcons();
this.initNameToFileNames();
this.initSecondaryRoleTexts();
});
}
public scanCodeToText(scanCode: number, type: KeystrokeType = KeystrokeType.basic): string[] {
@@ -27,7 +45,7 @@ export class MapperService {
map = this.mediaScanCodeTextMap;
break;
case KeystrokeType.system:
map = this.sytemScanCodeTextMap;
map = this.systemScanCodeTextMap;
break;
default:
map = this.basicScanCodeTextMap;
@@ -79,7 +97,10 @@ export class MapperService {
}
public getIcon(iconName: string): string {
return 'assets/compiled_sprite.svg#' + this.nameToFileName.get(iconName);
const mappedIconName = this.nameToFileName.get(iconName);
if (mappedIconName) {
return 'assets/compiled_sprite.svg#' + mappedIconName;
}
}
public modifierMapper(x: number) {
@@ -90,6 +111,87 @@ export class MapperService {
}
}
public getOperatingSystem(): OperatingSystem {
return this.operatingSystem;
}
public getOsSpecificText(key: string): string {
const text = this.osSpecificTexts.get(key);
return text ? text : key;
}
public getSecondaryRoleText(secondaryRoleAction: SecondaryRoleAction): string {
return this.secondaryRoleTexts.get(secondaryRoleAction);
}
public getLeftKeyModifiers(): KeyModifierModel[] {
return [
{
text: 'LShift',
value: KeyModifiers.leftShift,
checked: false
},
{
text: 'LCtrl',
value: KeyModifiers.leftCtrl,
checked: false
},
{
text: this.getOsSpecificText('LAlt'),
value: KeyModifiers.leftAlt,
checked: false
},
{
text: this.getOsSpecificText('LSuper'),
value: KeyModifiers.leftGui,
checked: false
}
];
}
public getRightKeyModifiers(): KeyModifierModel[] {
return [
{
text: 'RShift',
value: KeyModifiers.rightShift,
checked: false
},
{
text: 'RCtrl',
value: KeyModifiers.rightCtrl,
checked: false
},
{
text: this.getOsSpecificText('RAlt'),
value: KeyModifiers.rightAlt,
checked: false
},
{
text: this.getOsSpecificText('RSuper'),
value: KeyModifiers.rightGui,
checked: false
}
];
}
private initOsSpecificText(): void {
this.osSpecificTexts = new Map<string, string>();
if (this.operatingSystem === OperatingSystem.Mac) {
this.osSpecificTexts.set('Enter', 'Return');
this.osSpecificTexts.set('Alt', 'Option');
this.osSpecificTexts.set('Super', 'Cmd');
this.osSpecificTexts.set('LSuper', 'LCmd');
this.osSpecificTexts.set('RSuper', 'RCmd');
this.osSpecificTexts.set('LAlt', 'LOption');
this.osSpecificTexts.set('RAlt', 'ROption');
} else if (this.operatingSystem === OperatingSystem.Windows) {
this.osSpecificTexts.set('LSuper', 'LWindows');
this.osSpecificTexts.set('RSuper', 'RWindows');
}
}
// TODO: read the mapping from JSON
private initScanCodeTextMap(): void {
this.basicScanCodeTextMap = new Map<number, string[]>();
@@ -129,7 +231,7 @@ export class MapperService {
this.basicScanCodeTextMap.set(37, ['8', '*']);
this.basicScanCodeTextMap.set(38, ['9', '(']);
this.basicScanCodeTextMap.set(39, ['0', ')']);
this.basicScanCodeTextMap.set(40, ['Enter']);
this.basicScanCodeTextMap.set(40, [this.getOsSpecificText('Enter')]);
this.basicScanCodeTextMap.set(41, ['Esc']);
this.basicScanCodeTextMap.set(42, ['Backspace']);
this.basicScanCodeTextMap.set(43, ['Tab']);
@@ -159,8 +261,8 @@ export class MapperService {
this.basicScanCodeTextMap.set(67, ['F10']);
this.basicScanCodeTextMap.set(68, ['F11']);
this.basicScanCodeTextMap.set(69, ['F12']);
this.basicScanCodeTextMap.set(70, ['PrtScn']);
this.basicScanCodeTextMap.set(71, ['Scroll Lock']);
this.basicScanCodeTextMap.set(70, ['PrtScn', 'SysRq']);
this.basicScanCodeTextMap.set(71, ['ScrLk']);
this.basicScanCodeTextMap.set(72, ['Pause']);
this.basicScanCodeTextMap.set(73, ['Insert']);
this.basicScanCodeTextMap.set(74, ['Home']);
@@ -172,12 +274,12 @@ export class MapperService {
this.basicScanCodeTextMap.set(80, ['Left Arrow']);
this.basicScanCodeTextMap.set(81, ['Down Arrow']);
this.basicScanCodeTextMap.set(82, ['Up Arrow']);
this.basicScanCodeTextMap.set(83, ['Num Lock']);
this.basicScanCodeTextMap.set(83, ['NumLk']);
this.basicScanCodeTextMap.set(84, ['/']);
this.basicScanCodeTextMap.set(85, ['*']);
this.basicScanCodeTextMap.set(86, ['-']);
this.basicScanCodeTextMap.set(87, ['+']);
this.basicScanCodeTextMap.set(88, ['Enter']);
this.basicScanCodeTextMap.set(88, [this.getOsSpecificText('Enter')]);
this.basicScanCodeTextMap.set(89, ['end', '1']);
this.basicScanCodeTextMap.set(90, ['2']);
this.basicScanCodeTextMap.set(91, ['pgdn', '3']);
@@ -224,10 +326,13 @@ export class MapperService {
this.mediaScanCodeTextMap.set(394, ['Launch Email Client']);
this.mediaScanCodeTextMap.set(402, ['Launch Calculator']);
this.sytemScanCodeTextMap = new Map<number, string[]>();
this.sytemScanCodeTextMap.set(129, ['Power Down']);
this.sytemScanCodeTextMap.set(130, ['Sleep']);
this.sytemScanCodeTextMap.set(131, ['Wake Up']);
this.mediaScanCodeTextMap.set(548, ['Hist -']);
this.mediaScanCodeTextMap.set(549, ['Hist +']);
this.systemScanCodeTextMap = new Map<number, string[]>();
this.systemScanCodeTextMap.set(129, ['Power Down']);
this.systemScanCodeTextMap.set(130, ['Sleep']);
this.systemScanCodeTextMap.set(131, ['Wake Up']);
}
private initScancodeIcons(): void {
@@ -266,8 +371,12 @@ export class MapperService {
this.nameToFileName.set('switch-keymap', 'icon-kbd__mod--switch-keymap');
this.nameToFileName.set('macro', 'icon-icon__macro');
this.nameToFileName.set('shift', 'icon-kbd__default--modifier-shift');
if (this.operatingSystem === OperatingSystem.Mac) {
this.nameToFileName.set('option', 'icon-kbd__default--modifier-option');
this.nameToFileName.set('command', 'icon-kbd__default--modifier-command');
} else if (this.operatingSystem === OperatingSystem.Windows) {
this.nameToFileName.set('command', 'icon-kbd__default--modifier-windows');
}
this.nameToFileName.set('mouse', 'icon-kbd__mouse');
this.nameToFileName.set('left-arrow', 'icon-kbd__mod--arrow-left');
this.nameToFileName.set('right-arrow', 'icon-kbd__mod--arrow-right');
@@ -279,4 +388,18 @@ export class MapperService {
this.nameToFileName.set('scroll-up', 'icon-kbd__mouse--scroll-up');
}
private initSecondaryRoleTexts(): void {
this.secondaryRoleTexts = new Map<number, string>();
this.secondaryRoleTexts.set(0, 'LCtrl');
this.secondaryRoleTexts.set(1, 'LShift');
this.secondaryRoleTexts.set(2, 'LAlt');
this.secondaryRoleTexts.set(3, 'LSuper');
this.secondaryRoleTexts.set(4, 'RCtrl');
this.secondaryRoleTexts.set(5, 'RShift');
this.secondaryRoleTexts.set(6, 'RAlt');
this.secondaryRoleTexts.set(7, 'RSuper');
this.secondaryRoleTexts.set(8, 'Mod');
this.secondaryRoleTexts.set(9, 'Fn');
this.secondaryRoleTexts.set(10, 'Mouse');
}
}

View File

@@ -14,7 +14,7 @@
"mouseMoveAcceleratedSpeed": 64,
"mouseScrollInitialSpeed": 20,
"mouseScrollAcceleration": 20,
"mouseScrollDeceleratedSpeed": 20,
"mouseScrollDeceleratedSpeed": 10,
"mouseScrollBaseSpeed": 20,
"mouseScrollAcceleratedSpeed": 50,
"moduleConfigurations": [],
@@ -595,8 +595,7 @@
{
"keyActionType": "keystroke",
"type": "basic",
"scancode": 57,
"modifierMask": 1
"scancode": 57
},
{
"keyActionType": "keystroke",
@@ -888,7 +887,11 @@
null,
null,
null,
null,
{
"keyActionType": "keystroke",
"type": "basic",
"modifierMask": 32
},
null,
{
"keyActionType": "mouse",
@@ -959,7 +962,11 @@
},
null,
null,
null,
{
"keyActionType": "keystroke",
"type": "basic",
"modifierMask": 2
},
null,
null,
null,
@@ -1573,8 +1580,7 @@
{
"keyActionType": "keystroke",
"type": "basic",
"scancode": 57,
"modifierMask": 1
"scancode": 57
},
{
"keyActionType": "keystroke",
@@ -1875,7 +1881,11 @@
null,
null,
null,
null,
{
"keyActionType": "keystroke",
"type": "basic",
"modifierMask": 32
},
null,
{
"keyActionType": "mouse",
@@ -1946,7 +1956,11 @@
},
null,
null,
null,
{
"keyActionType": "keystroke",
"type": "basic",
"modifierMask": 2
},
null,
null,
null,
@@ -2560,8 +2574,7 @@
{
"keyActionType": "keystroke",
"type": "basic",
"scancode": 57,
"modifierMask": 1
"scancode": 57
},
{
"keyActionType": "keystroke",
@@ -2856,7 +2869,11 @@
null,
null,
null,
null,
{
"keyActionType": "keystroke",
"type": "basic",
"modifierMask": 32
},
null,
{
"keyActionType": "mouse",
@@ -2921,7 +2938,11 @@
},
null,
null,
null,
{
"keyActionType": "keystroke",
"type": "basic",
"modifierMask": 2
},
null,
null,
null,
@@ -3535,8 +3556,7 @@
{
"keyActionType": "keystroke",
"type": "basic",
"scancode": 57,
"modifierMask": 1
"scancode": 57
},
{
"keyActionType": "keystroke",
@@ -3840,7 +3860,11 @@
null,
null,
null,
null,
{
"keyActionType": "keystroke",
"type": "basic",
"modifierMask": 32
},
null,
{
"keyActionType": "mouse",
@@ -3905,7 +3929,11 @@
},
null,
null,
null,
{
"keyActionType": "keystroke",
"type": "basic",
"modifierMask": 2
},
null,
null,
null,
@@ -4519,8 +4547,7 @@
{
"keyActionType": "keystroke",
"type": "basic",
"scancode": 57,
"modifierMask": 1
"scancode": 57
},
{
"keyActionType": "keystroke",
@@ -4809,7 +4836,11 @@
null,
null,
null,
null,
{
"keyActionType": "keystroke",
"type": "basic",
"modifierMask": 32
},
null,
{
"keyActionType": "mouse",
@@ -4874,7 +4905,11 @@
},
null,
null,
null,
{
"keyActionType": "keystroke",
"type": "basic",
"modifierMask": 2
},
null,
null,
null,
@@ -5488,8 +5523,7 @@
{
"keyActionType": "keystroke",
"type": "basic",
"scancode": 57,
"modifierMask": 1
"scancode": 57
},
{
"keyActionType": "keystroke",
@@ -5790,7 +5824,11 @@
null,
null,
null,
null,
{
"keyActionType": "keystroke",
"type": "basic",
"modifierMask": 32
},
null,
{
"keyActionType": "mouse",
@@ -5855,7 +5893,11 @@
},
null,
null,
null,
{
"keyActionType": "keystroke",
"type": "basic",
"modifierMask": 2
},
null,
null,
null,
@@ -6465,8 +6507,7 @@
{
"keyActionType": "keystroke",
"type": "basic",
"scancode": 57,
"modifierMask": 1
"scancode": 57
},
{
"keyActionType": "keystroke",
@@ -6755,7 +6796,11 @@
null,
null,
null,
null,
{
"keyActionType": "keystroke",
"type": "basic",
"modifierMask": 32
},
null,
{
"keyActionType": "mouse",
@@ -6816,7 +6861,11 @@
},
null,
null,
null,
{
"keyActionType": "keystroke",
"type": "basic",
"modifierMask": 2
},
null,
null,
null,

View File

@@ -59,6 +59,7 @@ import {
SvgMouseScrollKeyComponent,
SvgMouseSpeedKeyComponent,
SvgOneLineTextKeyComponent,
SvgSecondaryRoleComponent,
SvgSingleIconKeyComponent,
SvgSwitchKeymapKeyComponent,
SvgTextIconKeyComponent,
@@ -186,7 +187,8 @@ import { HelpPageComponent } from './components/agent/help-page/help-page.compon
FileUploadComponent,
AutoGrowInputComponent,
HelpPageComponent,
ExternalUrlDirective
ExternalUrlDirective,
SvgSecondaryRoleComponent
],
imports: [
CommonModule,

View File

@@ -10,6 +10,7 @@ import * as fromAppUpdate from './reducers/app-update.reducer';
import * as autoUpdateSettings from './reducers/auto-update-settings';
import * as fromApp from './reducers/app.reducer';
import * as fromDevice from './reducers/device';
import * as fromSelectors from './reducers/selectors';
import { initProgressButtonState } from './reducers/progress-button-state';
import { environment } from '../../environments/environment';
import { RouterStateUrl } from './router-util';
@@ -52,6 +53,7 @@ export const getKeyboardLayout = createSelector(appState, fromApp.getKeyboardLay
export const deviceConfigurationLoaded = createSelector(appState, fromApp.deviceConfigurationLoaded);
export const getAgentVersionInfo = createSelector(appState, fromApp.getAgentVersionInfo);
export const getPrivilegePageState = createSelector(appState, fromApp.getPrivilagePageState);
export const getOperatingSystem = createSelector(appState, fromSelectors.getOperatingSystem);
export const runningOnNotSupportedWindows = createSelector(appState, fromApp.runningOnNotSupportedWindows);
export const firmwareUpgradeAllowed = createSelector(runningOnNotSupportedWindows, notSupportedOs => !notSupportedOs);

View File

@@ -0,0 +1,29 @@
import { OperatingSystem } from '../../models/operating-system';
import { State } from './app.reducer';
export const getOperatingSystem = (state: State): OperatingSystem => {
if (state.runningInElectron) {
switch (state.platform) {
case 'darwin':
return OperatingSystem.Mac;
case 'win32':
return OperatingSystem.Windows;
default:
return OperatingSystem.Linux;
}
}
const platform = navigator.platform.toLowerCase();
if (platform.indexOf('mac') > -1) {
return OperatingSystem.Mac;
}
if (platform.indexOf('win') > -1) {
return OperatingSystem.Windows;
}
return OperatingSystem.Linux;
};

View File

@@ -0,0 +1 @@
export * from './get-operating-system.selector';

View File

@@ -1,4 +1,5 @@
export * from './find-new-item';
export * from './html-helper';
export * from './key-modifier-model-mapper';
export * from './validators';
export * from './version-helper';

View File

@@ -0,0 +1,13 @@
import { KeyModifierModel } from '../models/key-modifier-model';
export const mapLeftRigthModifierToKeyActionModifier = (left: KeyModifierModel[], right: KeyModifierModel[]): number => {
const modifiers = [...left, ...right];
let result = 0;
for (const modifier of modifiers) {
if (modifier.checked) {
result |= modifier.value;
}
}
return result;
};

View File

@@ -1,4 +1,8 @@
/* You can add global styles to this file, and also import other style files */
$grid-gutter-width: 30px;
$zindex-navbar-fixed: 1030;
@import '~spacing-bootstrap-3/spacing';
@import './styles/variables';
@import '~angular-notifier/styles';
@import '~font-awesome/scss/font-awesome';

View File

@@ -4,6 +4,10 @@ ngx-select,
font-size: 14px;
}
input.input-sm {
font-size: 14px;
}
.dropdown-header {
font-weight: bold;
font-size: 1em;

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 17 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 36 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 43 KiB

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M576 64H205.26A63.97 63.97 0 0 0 160 82.75L9.37 233.37c-12.5 12.5-12.5 32.76 0 45.25L160 429.25c12 12 28.28 18.75 45.25 18.75H576c35.35 0 64-28.65 64-64V128c0-35.35-28.65-64-64-64zm-84.69 254.06c6.25 6.25 6.25 16.38 0 22.63l-22.62 22.62c-6.25 6.25-16.38 6.25-22.63 0L384 301.25l-62.06 62.06c-6.25 6.25-16.38 6.25-22.63 0l-22.62-22.62c-6.25-6.25-6.25-16.38 0-22.63L338.75 256l-62.06-62.06c-6.25-6.25-6.25-16.38 0-22.63l22.62-22.62c6.25-6.25 16.38-6.25 22.63 0L384 210.75l62.06-62.06c6.25-6.25 16.38-6.25 22.63 0l22.62 22.62c6.25 6.25 6.25 16.38 0 22.63L429.25 256l62.06 62.06z"/></svg>
<!--
Font Awesome Free 5.3.1 by @fontawesome - https://fontawesome.com
License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
-->

After

Width:  |  Height:  |  Size: 890 B

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path d="M 224 0 C 140.2 0 72 68.2 72 152 L 72 224 L 48 224 C 21.5 224 0 245.5 0 272 L 0 464 C 0 490.5 21.5 512 48 512 L 400 512 C 426.5 512 448 490.5 448 464 L 448 272 C 448 245.5 426.5 224 400 224 L 376 224 L 376 152 C 376 68.2 307.8 0 224 0 z M 224 80 C 263.7 80 296 112.3 296 152 L 296 224 L 152 224 L 152 152 C 152 112.3 184.3 80 224 80 z M 211.47656 290.19141 L 236.63477 290.19141 L 299.14648 454.2168 L 276.07422 454.2168 L 261.13281 412.13867 L 187.19531 412.13867 L 172.25391 454.2168 L 148.85352 454.2168 L 211.47656 290.19141 z M 224 312.05469 L 193.89844 393.68164 L 254.21289 393.68164 L 224 312.05469 z " />
</svg>
<!--
Based on Font Awesome Free 5.3.1 by @fontawesome - https://fontawesome.com
License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
-->

After

Width:  |  Height:  |  Size: 939 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 522 B

After

Width:  |  Height:  |  Size: 522 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 988.74573 512.02081">
<path d="M 49.021484 0.013671875 C 24.637109 -0.54414061 3.5527137e-15 16.517187 0 47.867188 L 0 463.96875 C 0 501.46875 40.700391 524.06758 72.400391 505.26758 L 424.40039 297.26758 C 455.80039 278.76758 455.90039 233.16797 424.40039 214.66797 L 72.400391 6.5683594 C 65.250391 2.3433594 57.149609 0.19960937 49.021484 0.013671875 z M 588.74609 33.052734 C 562.24609 33.052734 540.74609 54.552734 540.74609 81.052734 L 540.74609 433.05273 C 540.74609 459.55273 562.24609 481.05273 588.74609 481.05273 L 684.74609 481.05273 C 711.24609 481.05273 732.74609 459.55273 732.74609 433.05273 L 732.74609 81.052734 C 732.74609 54.552734 711.24609 33.052734 684.74609 33.052734 L 588.74609 33.052734 z M 844.74609 33.052734 C 818.24609 33.052734 796.74609 54.552734 796.74609 81.052734 L 796.74609 433.05273 C 796.74609 459.55273 818.24609 481.05273 844.74609 481.05273 L 940.74609 481.05273 C 967.24604 481.05273 988.74609 459.55273 988.74609 433.05273 L 988.74609 81.052734 C 988.74609 54.552734 967.24604 33.052734 940.74609 33.052734 L 844.74609 33.052734 z " />
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 716 B

After

Width:  |  Height:  |  Size: 716 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1,176 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="31.177315mm"
height="14.907915mm"
viewBox="0 0 110.4708 52.823321"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="segments_dvr.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="12.310946"
inkscape:cx="55.235392"
inkscape:cy="26.411669"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showguides="true"
inkscape:guide-bbox="true"
inkscape:snap-bbox="true"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:object-paths="false"
inkscape:object-nodes="true"
inkscape:window-width="1920"
inkscape:window-height="1144"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(967.89459,-355.26718)">
<rect
style="opacity:1;fill:#000000;fill-opacity:1"
id="rect4658"
width="110.4708"
height="52.823322"
x="-967.89459"
y="355.26718"
ry="2.2743988" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -926.64583,399.89017 -0.9734,-0.97353 0,-7.48741 0,-7.48737 0.9733,-0.97384 0.9734,-0.97384 0.9736,0.9735 0.9736,0.9735 0,7.4955 0,7.49553 -0.9658,0.96575 c -0.5313,0.53114 -0.9693,0.96571 -0.9736,0.96571 0,0 -0.4457,-0.43807 -0.9811,-0.9735 z"
id="path3399"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -923.27903,396.77639 0,-2.02518 3.2037,-5.3394 3.2036,-5.33941 0.9135,0 0.9134,0 0,2.02331 0,2.02331 -3.2051,5.34097 -3.2052,5.34093 -0.9119,0 -0.912,0 0,-2.0252 z"
id="path3393"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -926.64593,380.38988 -0.9733,-0.97384 0,-7.48747 0,-7.4875 0.9773,-0.97724 0.9773,-0.97724 0.9697,0.96955 0.9696,0.96955 0,7.4955 0,7.49553 -0.9736,0.9735 -0.9736,0.9735 -0.9734,-0.97384 z"
id="path3385"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -910.27363,377.26274 0,-2.02282 3.2052,-5.3417 3.2052,-5.34171 0.9119,-6e-5 0.9119,-6e-5 0,2.02518 0,2.02521 -3.2036,5.3394 -3.2036,5.33941 -0.9135,0 -0.9135,0 0,-2.02282 z"
id="path3377"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -958.32118,402.15653 -0.9695,-0.96964 0.9695,-0.96961 0.9695,-0.96964 4.2481,0 4.24795,0 0.9695,0.96964 0.9696,0.96961 -0.9696,0.96964 -0.9695,0.96964 -4.24795,0 -4.2481,0 -0.9695,-0.96964 z"
id="path3371"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -945.31583,402.15653 -0.9695,-0.96964 0.9695,-0.96961 0.9696,-0.96964 4.248,0 4.248,0 0.9695,0.96964 0.96951,0.96961 -0.96951,0.96964 -0.9695,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z"
id="path3369"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -947.57453,399.89817 -0.9657,-0.96584 0,-7.50313 0,-7.5031 0.9696,-0.96955 0.9696,-0.96954 0.9697,0.96954 0.9696,0.96955 0,7.50319 0,7.50322 -0.9658,0.96575 c -0.5312,0.53114 -0.96929,0.96572 -0.97349,0.96572 -0.01,0 -0.44231,-0.43461 -0.9735,-0.96581 z"
id="path3365"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -934.56913,399.89817 -0.9657,-0.96584 0,-7.49544 0,-7.4954 0.9736,-0.9735 0.9736,-0.97351 0.9733,0.97384 0.9734,0.97384 0,7.48747 0,7.4875 -0.9735,0.97344 c -0.53539,0.53537 -0.97699,0.97341 -0.98119,0.97341 -0.01,0 -0.44231,-0.43461 -0.9735,-0.96581 z"
id="path3363"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -947.57453,380.39788 -0.9657,-0.96584 0,-7.5031 0,-7.50312 0.9696,-0.96955 0.9696,-0.96955 0.9697,0.96955 0.9696,0.96955 0,7.50322 0,7.50319 -0.9658,0.96574 c -0.5312,0.53114 -0.96929,0.96575 -0.97349,0.96575 -0.01,0 -0.44231,-0.43464 -0.9735,-0.96584 z"
id="path3351"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -934.56133,380.38988 -0.9735,-0.97359 0,-7.49544 0,-7.49541 0.9696,-0.96954 0.9697,-0.96955 0.9773,0.97724 0.9773,0.97724 0,7.48753 0,7.4875 -0.9735,0.97381 -0.97339,0.9738 -0.9735,-0.97359 z"
id="path3349"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -958.32118,363.14038 -0.9695,-0.96961 0.9695,-0.96964 0.9695,-0.96964 4.2481,0 4.24795,0 0.9695,0.96964 0.9696,0.96964 -0.9696,0.96961 -0.9695,0.96964 -4.24795,0 -4.2481,0 -0.9695,-0.96964 z"
id="path3343"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -945.31583,363.14038 -0.9695,-0.96961 0.9695,-0.96964 0.9696,-0.96964 4.248,0 4.248,0 0.9695,0.96964 0.96951,0.96964 -0.96951,0.96961 -0.9695,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z"
id="path4610-4-6"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -892.70413,399.89017 -0.9734,-0.97353 0,-7.48741 0,-7.48737 0.9734,-0.97384 0.9734,-0.97384 0.9735,0.9735 0.9736,0.9735 0,7.4955 0,7.49553 -0.9658,0.96575 c -0.5312,0.53114 -0.9693,0.96571 -0.9735,0.96571 0,0 -0.4458,-0.43807 -0.9812,-0.9735 z"
id="path3431"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -873.12673,393.45965 -3.2051,-5.34195 0,-2.02266 0,-2.02264 0.9134,0 0.9135,0 3.2036,5.33941 3.2037,5.3394 0,2.02518 0,2.02521 -0.912,0 -0.9119,0 -3.20519,-5.34195 z"
id="path3423"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -890.44163,382.65253 -0.9734,-0.97354 0.9735,-0.9734 0.9735,-0.97344 4.2479,0 4.248,0 0.9734,0.97353 0.9734,0.9735 -0.9735,0.97344 -0.9735,0.97344 -4.2479,0 -4.248,0 -0.9734,-0.97353 z"
id="path3421"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -877.43623,382.65253 -0.9734,-0.97354 0.9735,-0.9734 0.9735,-0.97344 4.248,0 4.2479,0 0.9734,0.97353 0.9734,0.9735 -0.9735,0.97344 -0.9735,0.97344 -4.2479,0 -4.2479,0 -0.97349,-0.97353 z"
id="path3419"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -892.70413,380.38988 -0.9734,-0.97384 0,-7.48747 0,-7.4875 0.9773,-0.97724 0.9774,-0.97724 0.9696,0.96955 0.9696,0.96955 0,7.4955 0,7.49553 -0.9736,0.9735 -0.9735,0.9735 -0.9734,-0.97384 z"
id="path3417"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -866.67783,380.38988 -0.9735,-0.97359 0,-7.49544 0,-7.49541 0.9696,-0.96954 0.9697,-0.96955 0.9773,0.97724 0.9773,0.97724 0,7.48753 0,7.4875 -0.97349,0.97381 -0.9734,0.9738 -0.9735,-0.97359 z"
id="path3413"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -890.43773,363.14038 -0.9695,-0.96961 0.9695,-0.96964 0.9695,-0.96964 4.2481,0 4.248,0 0.96951,0.96964 0.9696,0.96964 -0.9696,0.96961 -0.96951,0.96964 -4.248,0 -4.2481,0 -0.9695,-0.96964 z"
id="path3407"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -877.43233,363.14038 -0.9695,-0.96961 0.9695,-0.96964 0.9696,-0.96964 4.248,0 4.248,0 0.96951,0.96964 0.9695,0.96964 -0.9695,0.96961 -0.96951,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z"
id="path4610-1-5"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.6 KiB

View File

@@ -1,186 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="31.177315mm"
height="14.907915mm"
viewBox="0 0 110.4708 52.823321"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="segments_qwe.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="12.310946"
inkscape:cx="55.23539"
inkscape:cy="26.411671"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showguides="true"
inkscape:guide-bbox="true"
inkscape:snap-bbox="true"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:object-paths="false"
inkscape:object-nodes="true"
inkscape:window-width="1920"
inkscape:window-height="1144"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(967.89459,-355.26718)">
<rect
style="opacity:1;fill:#000000;fill-opacity:1"
id="rect4658"
width="110.4708"
height="52.823322"
x="-967.89459"
y="355.26718"
ry="2.2743988" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -926.64583,399.89017 -0.9734,-0.97353 0,-7.48741 0,-7.48737 0.9733,-0.97384 0.9734,-0.97384 0.9736,0.9735 0.9736,0.9735 0,7.4955 0,7.49553 -0.9658,0.96575 c -0.5313,0.53114 -0.9693,0.96571 -0.9736,0.96571 0,0 -0.4457,-0.43807 -0.9811,-0.9735 z"
id="path4765"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -900.62733,399.89817 -0.9657,-0.96584 0,-7.49544 0,-7.4954 0.9735,-0.9735 0.9736,-0.97351 0.9734,0.97384 0.9734,0.97384 0,7.48747 0,7.4875 -0.9735,0.97344 c -0.5355,0.53537 -0.977,0.97341 -0.9813,0.97341 -0.01,0 -0.4422,-0.43461 -0.9734,-0.96581 z"
id="path4761"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -923.27903,396.77639 0,-2.02518 3.2037,-5.3394 3.2036,-5.33941 0.9135,0 0.9134,0 0,2.02331 0,2.02331 -3.2051,5.34097 -3.2052,5.34093 -0.9119,0 -0.912,0 0,-2.0252 z"
id="path4759"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -907.06843,393.45965 -3.2052,-5.34195 0,-2.02266 0,-2.02264 0.9135,0 0.9135,0 3.2036,5.33941 3.2036,5.3394 0,2.02518 0,2.02521 -0.9119,0 -0.91189,0 -3.2052,-5.34195 z"
id="path4757"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -926.64593,380.38988 -0.9733,-0.97384 0,-7.48747 0,-7.4875 0.9773,-0.97724 0.9773,-0.97724 0.9697,0.96955 0.9696,0.96955 0,7.4955 0,7.49553 -0.9736,0.9735 -0.9736,0.9735 -0.9734,-0.97384 z"
id="path4751"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -900.61953,380.38988 -0.9735,-0.97359 0,-7.49544 0,-7.49541 0.9696,-0.96954 0.9696,-0.96955 0.9774,0.97724 0.9773,0.97724 0,7.48753 0,7.4875 -0.9735,0.97381 -0.9735,0.9738 -0.97339,-0.97359 z"
id="path4747"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -958.32118,402.15653 -0.9695,-0.96964 0.9695,-0.96961 0.9695,-0.96964 4.2481,0 4.24795,0 0.9695,0.96964 0.9696,0.96961 -0.9696,0.96964 -0.9695,0.96964 -4.24795,0 -4.2481,0 -0.9695,-0.96964 z"
id="path4737"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -945.31583,402.15653 -0.9695,-0.96964 0.9695,-0.96961 0.9696,-0.96964 4.248,0 4.248,0 0.9695,0.96964 0.96951,0.96961 -0.96951,0.96964 -0.9695,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z"
id="path4735"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -960.58758,399.89017 -0.9734,-0.97353 0,-7.48741 0,-7.48737 0.9734,-0.97384 0.9734,-0.97384 0.9735,0.9735 0.9736,0.9735 0,7.4955 0,7.49553 -0.9658,0.96575 c -0.5312,0.53114 -0.9693,0.96571 -0.9735,0.96571 0,0 -0.4458,-0.43807 -0.9812,-0.9735 z"
id="path4733"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -934.56913,399.89817 -0.9657,-0.96584 0,-7.49544 0,-7.4954 0.9736,-0.9735 0.9736,-0.97351 0.9733,0.97384 0.9734,0.97384 0,7.48747 0,7.4875 -0.9735,0.97344 c -0.53539,0.53537 -0.97699,0.97341 -0.98119,0.97341 -0.01,0 -0.44231,-0.43461 -0.9735,-0.96581 z"
id="path4729"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -941.01023,393.45965 -3.2051,-5.34195 0,-2.02266 0,-2.02264 0.9134,0 0.9135,0 3.2036,5.33941 3.2037,5.3394 0,2.02518 0,2.02521 -0.912,0 -0.9119,0 -3.2052,-5.34195 z"
id="path4725"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -960.58758,380.38988 -0.9734,-0.97384 0,-7.48747 0,-7.4875 0.9773,-0.97724 0.9774,-0.97724 0.9696,0.96955 0.9696,0.96955 0,7.4955 0,7.49553 -0.9736,0.9735 -0.9735,0.9735 -0.9734,-0.97384 z"
id="path4719"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -934.56133,380.38988 -0.9735,-0.97359 0,-7.49544 0,-7.49541 0.9696,-0.96954 0.9697,-0.96955 0.9773,0.97724 0.9773,0.97724 0,7.48753 0,7.4875 -0.9735,0.97381 -0.97339,0.9738 -0.9735,-0.97359 z"
id="path4715"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -958.32118,363.14038 -0.9695,-0.96961 0.9695,-0.96964 0.9695,-0.96964 4.2481,0 4.24795,0 0.9695,0.96964 0.9696,0.96964 -0.9696,0.96961 -0.9695,0.96964 -4.24795,0 -4.2481,0 -0.9695,-0.96964 z"
id="path4709"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -945.31583,363.14038 -0.9695,-0.96961 0.9695,-0.96964 0.9696,-0.96964 4.248,0 4.248,0 0.9695,0.96964 0.96951,0.96964 -0.96951,0.96961 -0.9695,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z"
id="path4610-4-6"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -890.43773,402.15653 -0.9695,-0.96964 0.9695,-0.96961 0.9695,-0.96964 4.2481,0 4.248,0 0.96951,0.96964 0.9696,0.96961 -0.9696,0.96964 -0.96951,0.96964 -4.248,0 -4.2481,0 -0.9695,-0.96964 z"
id="path4801"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -877.43233,402.15653 -0.9695,-0.96964 0.9695,-0.96961 0.9696,-0.96964 4.248,0 4.248,0 0.96951,0.96964 0.9695,0.96961 -0.9695,0.96964 -0.96951,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z"
id="path4799"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -892.70413,399.89017 -0.9734,-0.97353 0,-7.48741 0,-7.48737 0.9734,-0.97384 0.9734,-0.97384 0.9735,0.9735 0.9736,0.9735 0,7.4955 0,7.49553 -0.9658,0.96575 c -0.5312,0.53114 -0.9693,0.96571 -0.9735,0.96571 0,0 -0.4458,-0.43807 -0.9812,-0.9735 z"
id="path4797"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -890.44163,382.65253 -0.9734,-0.97354 0.9735,-0.9734 0.9735,-0.97344 4.2479,0 4.248,0 0.9734,0.97353 0.9734,0.9735 -0.9735,0.97344 -0.9735,0.97344 -4.2479,0 -4.248,0 -0.9734,-0.97353 z"
id="path4787"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -892.70413,380.38988 -0.9734,-0.97384 0,-7.48747 0,-7.4875 0.9773,-0.97724 0.9774,-0.97724 0.9696,0.96955 0.9696,0.96955 0,7.4955 0,7.49553 -0.9736,0.9735 -0.9735,0.9735 -0.9734,-0.97384 z"
id="path4783"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -890.43773,363.14038 -0.9695,-0.96961 0.9695,-0.96964 0.9695,-0.96964 4.2481,0 4.248,0 0.96951,0.96964 0.9696,0.96964 -0.9696,0.96961 -0.96951,0.96964 -4.248,0 -4.2481,0 -0.9695,-0.96964 z"
id="path4773"
inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;fill-opacity:1"
d="m -877.43233,363.14038 -0.9695,-0.96961 0.9695,-0.96964 0.9696,-0.96964 4.248,0 4.248,0 0.96951,0.96964 0.9695,0.96964 -0.9695,0.96961 -0.96951,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z"
id="path4610-1-5"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -1,95 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="31.177315mm"
height="14.907915mm"
viewBox="0 0 110.4708 52.823321"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="segments_template.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="12.310946"
inkscape:cx="55.235392"
inkscape:cy="26.411669"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showguides="true"
inkscape:guide-bbox="true"
inkscape:snap-bbox="true"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:object-paths="false"
inkscape:object-nodes="true"
inkscape:window-width="1920"
inkscape:window-height="1144"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(967.89459,-355.26718)">
<rect
style="opacity:1;fill:#000000;fill-opacity:1"
id="rect4658"
width="110.4708"
height="52.823322"
x="-967.89459"
y="355.26718"
ry="2.2743988" />
<g
id="g4660"
transform="translate(0.78135242,3.819203)">
<path
inkscape:connector-curvature="0"
id="path4610-2"
d="m -925.16078,398.33733 -0.9696,-0.96964 0.9696,-0.96961 0.9695,-0.96964 4.248,0 4.248,0 0.9696,0.96964 0.9695,0.96961 -0.9695,0.96964 -0.9696,0.96964 -4.248,0 -4.248,0 -0.9695,-0.96964 z m 13.0054,0 -0.9696,-0.96964 0.9696,-0.96961 0.9695,-0.96964 4.248,0 4.2481,0 0.9695,0.96964 0.9695,0.96961 -0.9695,0.96964 -0.9695,0.96964 -4.2481,0 -4.248,0 -0.9695,-0.96964 z m -15.2718,-2.26636 -0.9734,-0.97353 0,-7.48741 0,-7.48737 0.9733,-0.97384 0.9734,-0.97384 0.9736,0.9735 0.9736,0.9735 0,7.4955 0,7.49553 -0.9658,0.96575 c -0.5313,0.53114 -0.9693,0.96571 -0.9736,0.96571 0,0 -0.4457,-0.43807 -0.9811,-0.9735 z m 13.0131,0.008 -0.9657,-0.96584 0,-7.50313 0,-7.5031 0.9696,-0.96955 0.9696,-0.96954 0.9697,0.96954 0.9696,0.96955 0,7.50319 0,7.50322 -0.9658,0.96575 c -0.5312,0.53114 -0.9693,0.96572 -0.9736,0.96572 -0.01,0 -0.4422,-0.43461 -0.9734,-0.96581 z m 13.0054,0 -0.9657,-0.96584 0,-7.49544 0,-7.4954 0.9735,-0.9735 0.9736,-0.97351 0.9734,0.97384 0.9734,0.97384 0,7.48747 0,7.4875 -0.9735,0.97344 c -0.5355,0.53537 -0.977,0.97341 -0.9813,0.97341 -0.01,0 -0.4422,-0.43461 -0.9734,-0.96581 z m -22.6517,-3.12178 0,-2.02518 3.2037,-5.3394 3.2036,-5.33941 0.9135,0 0.9134,0 0,2.02331 0,2.02331 -3.2051,5.34097 -3.2052,5.34093 -0.9119,0 -0.912,0 0,-2.0252 z m 16.2106,-3.31674 -3.2052,-5.34195 0,-2.02266 0,-2.02264 0.9135,0 0.9135,0 3.2036,5.33941 3.2036,5.3394 0,2.02518 0,2.02521 -0.9119,0 -0.91189,0 -3.2052,-5.34195 z m -17.3149,-10.80712 -0.9735,-0.97354 0.9736,-0.9734 0.9735,-0.97344 4.2479,0 4.2479,0 0.9735,0.97353 0.9734,0.9735 -0.9735,0.97344 -0.9735,0.97344 -4.248,0 -4.2479,0 -0.9734,-0.97353 z m 13.0054,0 -0.9735,-0.97354 0.9736,-0.9734 0.9735,-0.97344 4.2479,0 4.248,0 0.9734,0.97353 0.9734,0.9735 -0.9735,0.97344 -0.9735,0.97344 -4.248,0 -4.2479,0 -0.9734,-0.97353 z m -15.268,-2.26265 -0.9733,-0.97384 0,-7.48747 0,-7.4875 0.9773,-0.97724 0.9773,-0.97724 0.9697,0.96955 0.9696,0.96955 0,7.4955 0,7.49553 -0.9736,0.9735 -0.9736,0.9735 -0.9734,-0.97384 z m 13.0132,0.008 -0.9657,-0.96584 0,-7.5031 0,-7.50312 0.9696,-0.96955 0.9696,-0.96955 0.9697,0.96955 0.9696,0.96955 0,7.50322 0,7.50319 -0.9658,0.96574 c -0.5312,0.53114 -0.9693,0.96575 -0.9736,0.96575 -0.01,0 -0.4422,-0.43464 -0.9734,-0.96584 z m 13.0132,-0.008 -0.9735,-0.97359 0,-7.49544 0,-7.49541 0.9696,-0.96954 0.9696,-0.96955 0.9774,0.97724 0.9773,0.97724 0,7.48753 0,7.4875 -0.9735,0.97381 -0.9735,0.9738 -0.97339,-0.97359 z m -19.4558,-6.44373 -3.2037,-5.33941 0,-2.02517 0,-2.02521 0.912,0 0.9119,0 3.2052,5.34054 3.2051,5.34057 0,2.02343 0,2.02346 -0.9134,0 -0.9135,0 -3.2036,-5.3394 z m 9.8017,3.31659 0,-2.02282 3.2052,-5.3417 3.2052,-5.34171 0.9119,-6e-5 0.9119,-6e-5 0,2.02518 0,2.02521 -3.2036,5.3394 -3.2036,5.33941 -0.9135,0 -0.9135,0 0,-2.02282 z m -14.1058,-14.12236 -0.9696,-0.96961 0.9696,-0.96964 0.9695,-0.96964 4.248,0 4.248,0 0.9696,0.96964 0.9695,0.96964 -0.9695,0.96961 -0.9696,0.96964 -4.248,0 -4.248,0 -0.9695,-0.96964 z m 13.0054,0 -0.9696,-0.96961 0.9696,-0.96964 0.9695,-0.96964 4.248,0 4.2481,0 0.9695,0.96964 0.9695,0.96964 -0.9695,0.96961 -0.9695,0.96964 -4.2481,0 -4.248,0 -0.9695,-0.96964 z"
style="fill:#ff0000;fill-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path4610-4-6"
d="m -959.10253,398.33733 -0.9695,-0.96964 0.9695,-0.96961 0.9695,-0.96964 4.2481,0 4.24795,0 0.9695,0.96964 0.9696,0.96961 -0.9696,0.96964 -0.9695,0.96964 -4.24795,0 -4.2481,0 -0.9695,-0.96964 z m 13.00535,0 -0.9695,-0.96964 0.9695,-0.96961 0.9696,-0.96964 4.248,0 4.248,0 0.9695,0.96964 0.96951,0.96961 -0.96951,0.96964 -0.9695,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z m -15.27175,-2.26636 -0.9734,-0.97353 0,-7.48741 0,-7.48737 0.9734,-0.97384 0.9734,-0.97384 0.9735,0.9735 0.9736,0.9735 0,7.4955 0,7.49553 -0.9658,0.96575 c -0.5312,0.53114 -0.9693,0.96571 -0.9735,0.96571 0,0 -0.4458,-0.43807 -0.9812,-0.9735 z m 13.01305,0.008 -0.9657,-0.96584 0,-7.50313 0,-7.5031 0.9696,-0.96955 0.9696,-0.96954 0.9697,0.96954 0.9696,0.96955 0,7.50319 0,7.50322 -0.9658,0.96575 c -0.5312,0.53114 -0.96929,0.96572 -0.97349,0.96572 -0.01,0 -0.44231,-0.43461 -0.9735,-0.96581 z m 13.0054,0 -0.9657,-0.96584 0,-7.49544 0,-7.4954 0.9736,-0.9735 0.9736,-0.97351 0.9733,0.97384 0.9734,0.97384 0,7.48747 0,7.4875 -0.9735,0.97344 c -0.53539,0.53537 -0.97699,0.97341 -0.98119,0.97341 -0.01,0 -0.44231,-0.43461 -0.9735,-0.96581 z m -22.65155,-3.12178 0,-2.02518 3.2036,-5.3394 3.20355,-5.33941 0.9135,0 0.9135,0 0,2.02331 0,2.02331 -3.20515,5.34097 -3.2052,5.34093 -0.9119,0 -0.9119,0 0,-2.0252 z m 16.21045,-3.31674 -3.2051,-5.34195 0,-2.02266 0,-2.02264 0.9134,0 0.9135,0 3.2036,5.33941 3.2037,5.3394 0,2.02518 0,2.02521 -0.912,0 -0.9119,0 -3.2052,-5.34195 z m -17.31485,-10.80712 -0.9734,-0.97354 0.9735,-0.9734 0.9735,-0.97344 4.2479,0 4.24795,0 0.9734,0.97353 0.9734,0.9735 -0.9735,0.97344 -0.9735,0.97344 -4.24785,0 -4.248,0 -0.9734,-0.97353 z m 13.00535,0 -0.9734,-0.97354 0.9735,-0.9734 0.9735,-0.97344 4.248,0 4.2479,0 0.9734,0.97353 0.9734,0.9735 -0.9735,0.97344 -0.9735,0.97344 -4.2479,0 -4.2479,0 -0.97349,-0.97353 z m -15.26785,-2.26265 -0.9734,-0.97384 0,-7.48747 0,-7.4875 0.9773,-0.97724 0.9774,-0.97724 0.9696,0.96955 0.9696,0.96955 0,7.4955 0,7.49553 -0.9736,0.9735 -0.9735,0.9735 -0.9734,-0.97384 z m 13.01305,0.008 -0.9657,-0.96584 0,-7.5031 0,-7.50312 0.9696,-0.96955 0.9696,-0.96955 0.9697,0.96955 0.9696,0.96955 0,7.50322 0,7.50319 -0.9658,0.96574 c -0.5312,0.53114 -0.96929,0.96575 -0.97349,0.96575 -0.01,0 -0.44231,-0.43464 -0.9735,-0.96584 z m 13.0132,-0.008 -0.9735,-0.97359 0,-7.49544 0,-7.49541 0.9696,-0.96954 0.9697,-0.96955 0.9773,0.97724 0.9773,0.97724 0,7.48753 0,7.4875 -0.9735,0.97381 -0.97339,0.9738 -0.9735,-0.97359 z m -19.45575,-6.44373 -3.2036,-5.33941 0,-2.02517 0,-2.02521 0.9119,0 0.9119,0 3.2052,5.34054 3.20515,5.34057 0,2.02343 0,2.02346 -0.9135,0 -0.9135,0 -3.20355,-5.3394 z m 9.80175,3.31659 0,-2.02282 3.2051,-5.3417 3.2052,-5.34171 0.9119,-6e-5 0.912,-6e-5 0,2.02518 0,2.02521 -3.2037,5.3394 -3.2036,5.33941 -0.9135,0 -0.9134,0 0,-2.02282 z m -14.10585,-14.12236 -0.9695,-0.96961 0.9695,-0.96964 0.9695,-0.96964 4.2481,0 4.24795,0 0.9695,0.96964 0.9696,0.96964 -0.9696,0.96961 -0.9695,0.96964 -4.24795,0 -4.2481,0 -0.9695,-0.96964 z m 13.00535,0 -0.9695,-0.96961 0.9695,-0.96964 0.9696,-0.96964 4.248,0 4.248,0 0.9695,0.96964 0.96951,0.96964 -0.96951,0.96961 -0.9695,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z"
style="fill:#ff0000;fill-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path4610-1-5"
d="m -891.21908,398.33733 -0.9695,-0.96964 0.9695,-0.96961 0.9695,-0.96964 4.2481,0 4.248,0 0.96951,0.96964 0.9696,0.96961 -0.9696,0.96964 -0.96951,0.96964 -4.248,0 -4.2481,0 -0.9695,-0.96964 z m 13.0054,0 -0.9695,-0.96964 0.9695,-0.96961 0.9696,-0.96964 4.248,0 4.248,0 0.96951,0.96964 0.9695,0.96961 -0.9695,0.96964 -0.96951,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z m -15.2718,-2.26636 -0.9734,-0.97353 0,-7.48741 0,-7.48737 0.9734,-0.97384 0.9734,-0.97384 0.9735,0.9735 0.9736,0.9735 0,7.4955 0,7.49553 -0.9658,0.96575 c -0.5312,0.53114 -0.9693,0.96571 -0.9735,0.96571 0,0 -0.4458,-0.43807 -0.9812,-0.9735 z m 13.0131,0.008 -0.9657,-0.96584 0,-7.50313 0,-7.5031 0.9696,-0.96955 0.9696,-0.96954 0.9697,0.96954 0.9696,0.96955 0,7.50319 0,7.50322 -0.96579,0.96575 c -0.53121,0.53114 -0.9693,0.96572 -0.9735,0.96572 -0.01,0 -0.4423,-0.43461 -0.9735,-0.96581 z m 13.0054,0 -0.9657,-0.96584 0,-7.49544 0,-7.4954 0.9736,-0.9735 0.9736,-0.97351 0.9733,0.97384 0.9734,0.97384 0,7.48747 0,7.4875 -0.97349,0.97344 c -0.5354,0.53537 -0.977,0.97341 -0.9812,0.97341 -0.01,0 -0.4423,-0.43461 -0.9735,-0.96581 z m -22.6516,-3.12178 0,-2.02518 3.2036,-5.3394 3.2036,-5.33941 0.9135,0 0.9135,0 0,2.02331 0,2.02331 -3.2052,5.34097 -3.2052,5.34093 -0.91189,0 -0.9119,0 0,-2.0252 z m 16.2105,-3.31674 -3.2051,-5.34195 0,-2.02266 0,-2.02264 0.9134,0 0.9135,0 3.2036,5.33941 3.2037,5.3394 0,2.02518 0,2.02521 -0.912,0 -0.9119,0 -3.20519,-5.34195 z m -17.3149,-10.80712 -0.9734,-0.97354 0.9735,-0.9734 0.9735,-0.97344 4.2479,0 4.248,0 0.9734,0.97353 0.9734,0.9735 -0.9735,0.97344 -0.9735,0.97344 -4.2479,0 -4.248,0 -0.9734,-0.97353 z m 13.0054,0 -0.9734,-0.97354 0.9735,-0.9734 0.9735,-0.97344 4.248,0 4.2479,0 0.9734,0.97353 0.9734,0.9735 -0.9735,0.97344 -0.9735,0.97344 -4.2479,0 -4.2479,0 -0.97349,-0.97353 z m -15.2679,-2.26265 -0.9734,-0.97384 0,-7.48747 0,-7.4875 0.9773,-0.97724 0.9774,-0.97724 0.9696,0.96955 0.9696,0.96955 0,7.4955 0,7.49553 -0.9736,0.9735 -0.9735,0.9735 -0.9734,-0.97384 z m 13.0131,0.008 -0.9657,-0.96584 0,-7.5031 0,-7.50312 0.9696,-0.96955 0.9696,-0.96955 0.9697,0.96955 0.9696,0.96955 0,7.50322 0,7.50319 -0.96579,0.96574 c -0.53121,0.53114 -0.9693,0.96575 -0.9735,0.96575 -0.01,0 -0.4423,-0.43464 -0.9735,-0.96584 z m 13.0132,-0.008 -0.9735,-0.97359 0,-7.49544 0,-7.49541 0.9696,-0.96954 0.9697,-0.96955 0.9773,0.97724 0.9773,0.97724 0,7.48753 0,7.4875 -0.97349,0.97381 -0.9734,0.9738 -0.9735,-0.97359 z m -19.4558,-6.44373 -3.2036,-5.33941 0,-2.02517 0,-2.02521 0.9119,0 0.9119,0 3.2052,5.34054 3.2052,5.34057 0,2.02343 0,2.02346 -0.9135,0 -0.9135,0 -3.2036,-5.3394 z m 9.8018,3.31659 0,-2.02282 3.2051,-5.3417 3.2052,-5.34171 0.9119,-6e-5 0.912,-6e-5 0,2.02518 0,2.02521 -3.2037,5.3394 -3.2036,5.33941 -0.9135,0 -0.9134,0 0,-2.02282 z m -14.1059,-14.12236 -0.9695,-0.96961 0.9695,-0.96964 0.9695,-0.96964 4.2481,0 4.248,0 0.96951,0.96964 0.9696,0.96964 -0.9696,0.96961 -0.96951,0.96964 -4.248,0 -4.2481,0 -0.9695,-0.96964 z m 13.0054,0 -0.9695,-0.96961 0.9695,-0.96964 0.9696,-0.96964 4.248,0 4.248,0 0.96951,0.96964 0.9695,0.96964 -0.9695,0.96961 -0.96951,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z"
style="fill:#ff0000;fill-opacity:1" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,13 +1,21 @@
#!/usr/bin/env node
const uhk = require('./uhk');
const device = uhk.getUhkDevice();
const eepromTransferType = process.argv[2];
const eepromTransfer = uhk.eepromTransfer[eepromTransferType];
if (eepromTransfer === undefined) {
console.error(`Gotta provide one of ${Object.keys(uhk.eepromTransfer).join(', ')}`);
(async function() {
const operationArg = process.argv[2];
const operation = uhk.eepromOperations[operationArg];
if (operation === undefined) {
console.error(`Invalid operation: Gotta provide one of ${Object.keys(uhk.eepromOperations).join(', ')}`);
process.exit(1);
}
// const buffer = await uhk.writeDevice(device, [uhk.usbCommands.launchEepromTransfer, eepromTransfer.operation, eepromTransfer.configBuffer]);
const bufferIdArg = process.argv[3];
const bufferId = uhk.configBufferIds[bufferIdArg]
if (bufferId === undefined) {
console.error(`Invalid bufferId: Gotta provide one of ${Object.keys(uhk.configBufferIds).join(', ')}`);
process.exit(1);
}
const buffer = await uhk.launchEepromTransfer(device, operation, bufferId);
})();

View File

@@ -14,11 +14,11 @@ let prevGeneric, prevBasic, prevMedia, prevSystem, prevMouse;
function getDebugInfo() {
const payload = new Buffer([uhk.usbCommands.getDebugBuffer]);
console.log(payload)
console.log('Sending ', uhk.bufferToString(payload));
// console.log(payload)
// console.log('Sending ', uhk.bufferToString(payload));
device.write(uhk.getTransferData(payload));
const rxBuffer = Buffer.from(device.readSync());
console.log('Received', uhk.bufferToString(rxBuffer));
// console.log('Received', uhk.bufferToString(rxBuffer));
const I2C_Watchdog = getUint32(rxBuffer, 1);
const I2cSlaveScheduler_Counter = getUint32(rxBuffer, 5);
@@ -33,25 +33,25 @@ function getDebugInfo() {
const UsbSystemKeyboardActionCounter = getUint32(rxBuffer, 41);
const UsbMouseActionCounter = getUint32(rxBuffer, 45);
process.stdout.write(`I2C_Watchdog:${I2C_Watchdog} | `);
process.stdout.write(`I2cSlaveScheduler_Counter:${I2cSlaveScheduler_Counter} | `);
process.stdout.write(`I2cWatchdog_WatchCounter:${I2cWatchdog_WatchCounter} | `);
process.stdout.write(`I2cWatchdog_RecoveryCounter:${I2cWatchdog_RecoveryCounter} | `);
process.stdout.write(`KeyScannerCounter:${KeyScannerCounter} | `);
process.stdout.write(`UsbReportUpdateCounter:${UsbReportUpdateCounter} | `);
process.stdout.write(`CurrentTime:${CurrentTime} | `);
process.stdout.write(`UsbGenericHidActionCounter:${UsbGenericHidActionCounter} | `);
process.stdout.write(`UsbBasicKeyboardActionCounter:${UsbBasicKeyboardActionCounter} | `);
process.stdout.write(`UsbMediaKeyboardActionCounter:${UsbMediaKeyboardActionCounter} | `);
process.stdout.write(`UsbSystemKeyboardActionCounter:${UsbSystemKeyboardActionCounter} | `);
process.stdout.write(`UsbMouseActionCounter:${UsbMouseActionCounter} | `);
process.stdout.write(`I2cWatchdog:${I2C_Watchdog} | `);
process.stdout.write(`I2cSlave:${I2cSlaveScheduler_Counter} | `);
process.stdout.write(`I2cWatch:${I2cWatchdog_WatchCounter} | `);
process.stdout.write(`I2cRecovery:${I2cWatchdog_RecoveryCounter} | `);
process.stdout.write(`KeyMatrix:${KeyScannerCounter} | `);
process.stdout.write(`UsbReport:${UsbReportUpdateCounter} | `);
process.stdout.write(`Time:${CurrentTime} | `);
process.stdout.write(`UsbGeneric:${UsbGenericHidActionCounter} | `);
process.stdout.write(`UsbBasic:${UsbBasicKeyboardActionCounter} | `);
process.stdout.write(`UsbMedia:${UsbMediaKeyboardActionCounter} | `);
process.stdout.write(`UsbSystem:${UsbSystemKeyboardActionCounter} | `);
process.stdout.write(`UsbMouse:${UsbMouseActionCounter}`);
process.stdout.write('\n');
process.stdout.write(`generic:${UsbGenericHidActionCounter - prevGeneric} `)
process.stdout.write(`basic:${UsbBasicKeyboardActionCounter - prevBasic} `)
process.stdout.write(`basic:${UsbMediaKeyboardActionCounter - prevMedia} `)
process.stdout.write(`basic:${UsbSystemKeyboardActionCounter - prevSystem} `)
process.stdout.write(`basic:${UsbMouseActionCounter - prevMouse} `)
// process.stdout.write(`generic:${UsbGenericHidActionCounter - prevGeneric} `)
// process.stdout.write(`basic:${UsbBasicKeyboardActionCounter - prevBasic} `)
// process.stdout.write(`basic:${UsbMediaKeyboardActionCounter - prevMedia} `)
// process.stdout.write(`basic:${UsbSystemKeyboardActionCounter - prevSystem} `)
// process.stdout.write(`basic:${UsbMouseActionCounter - prevMouse} `)
prevGeneric = UsbGenericHidActionCounter;
prevBasic = UsbBasicKeyboardActionCounter;

File diff suppressed because it is too large Load Diff

12
tsconfig.json Normal file
View File

@@ -0,0 +1,12 @@
{
"compileOnSave": false,
"compilerOptions": {
"sourceMap": true,
"declaration": true,
"module": "commonjs",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es5"
}
}