@openmouse/protocol 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +167 -0
- package/README.md +89 -0
- package/dist/asus/index.d.ts +52 -0
- package/dist/asus/index.d.ts.map +1 -0
- package/dist/asus/index.js +248 -0
- package/dist/asus/index.js.map +1 -0
- package/dist/atk/index.d.ts +200 -0
- package/dist/atk/index.d.ts.map +1 -0
- package/dist/atk/index.js +480 -0
- package/dist/atk/index.js.map +1 -0
- package/dist/bitmouse/index.d.ts +284 -0
- package/dist/bitmouse/index.d.ts.map +1 -0
- package/dist/bitmouse/index.js +396 -0
- package/dist/bitmouse/index.js.map +1 -0
- package/dist/compx/codec.d.ts +31 -0
- package/dist/compx/codec.d.ts.map +1 -0
- package/dist/compx/codec.js +50 -0
- package/dist/compx/codec.js.map +1 -0
- package/dist/corsair/index.d.ts +147 -0
- package/dist/corsair/index.d.ts.map +1 -0
- package/dist/corsair/index.js +223 -0
- package/dist/corsair/index.js.map +1 -0
- package/dist/dareu/index.d.ts +136 -0
- package/dist/dareu/index.d.ts.map +1 -0
- package/dist/dareu/index.js +344 -0
- package/dist/dareu/index.js.map +1 -0
- package/dist/drivers/asus/hid.d.ts +29 -0
- package/dist/drivers/asus/hid.d.ts.map +1 -0
- package/dist/drivers/asus/hid.js +419 -0
- package/dist/drivers/asus/hid.js.map +1 -0
- package/dist/drivers/atk/bitmouse-hid.d.ts +80 -0
- package/dist/drivers/atk/bitmouse-hid.d.ts.map +1 -0
- package/dist/drivers/atk/bitmouse-hid.js +501 -0
- package/dist/drivers/atk/bitmouse-hid.js.map +1 -0
- package/dist/drivers/atk/hid.d.ts +163 -0
- package/dist/drivers/atk/hid.d.ts.map +1 -0
- package/dist/drivers/atk/hid.js +1368 -0
- package/dist/drivers/atk/hid.js.map +1 -0
- package/dist/drivers/atk/products.d.ts +13 -0
- package/dist/drivers/atk/products.d.ts.map +1 -0
- package/dist/drivers/atk/products.js +13 -0
- package/dist/drivers/atk/products.js.map +1 -0
- package/dist/drivers/attackshark/dpi.d.ts +41 -0
- package/dist/drivers/attackshark/dpi.d.ts.map +1 -0
- package/dist/drivers/attackshark/dpi.js +215 -0
- package/dist/drivers/attackshark/dpi.js.map +1 -0
- package/dist/drivers/attackshark/hid.d.ts +124 -0
- package/dist/drivers/attackshark/hid.d.ts.map +1 -0
- package/dist/drivers/attackshark/hid.js +728 -0
- package/dist/drivers/attackshark/hid.js.map +1 -0
- package/dist/drivers/corsair/hid.d.ts +70 -0
- package/dist/drivers/corsair/hid.d.ts.map +1 -0
- package/dist/drivers/corsair/hid.js +414 -0
- package/dist/drivers/corsair/hid.js.map +1 -0
- package/dist/drivers/dareu/hid.d.ts +59 -0
- package/dist/drivers/dareu/hid.d.ts.map +1 -0
- package/dist/drivers/dareu/hid.js +478 -0
- package/dist/drivers/dareu/hid.js.map +1 -0
- package/dist/drivers/endgame/egg-op1-hid.d.ts +107 -0
- package/dist/drivers/endgame/egg-op1-hid.d.ts.map +1 -0
- package/dist/drivers/endgame/egg-op1-hid.js +605 -0
- package/dist/drivers/endgame/egg-op1-hid.js.map +1 -0
- package/dist/drivers/endgame/egg-we-control.d.ts +42 -0
- package/dist/drivers/endgame/egg-we-control.d.ts.map +1 -0
- package/dist/drivers/endgame/egg-we-control.js +87 -0
- package/dist/drivers/endgame/egg-we-control.js.map +1 -0
- package/dist/drivers/endgame/egg-we-hid.d.ts +58 -0
- package/dist/drivers/endgame/egg-we-hid.d.ts.map +1 -0
- package/dist/drivers/endgame/egg-we-hid.js +514 -0
- package/dist/drivers/endgame/egg-we-hid.js.map +1 -0
- package/dist/drivers/fantech/hid.d.ts +106 -0
- package/dist/drivers/fantech/hid.d.ts.map +1 -0
- package/dist/drivers/fantech/hid.js +295 -0
- package/dist/drivers/fantech/hid.js.map +1 -0
- package/dist/drivers/finalmouse/hid.d.ts +31 -0
- package/dist/drivers/finalmouse/hid.d.ts.map +1 -0
- package/dist/drivers/finalmouse/hid.js +181 -0
- package/dist/drivers/finalmouse/hid.js.map +1 -0
- package/dist/drivers/gearhub/hid.d.ts +191 -0
- package/dist/drivers/gearhub/hid.d.ts.map +1 -0
- package/dist/drivers/gearhub/hid.js +542 -0
- package/dist/drivers/gearhub/hid.js.map +1 -0
- package/dist/drivers/glorious/classic-hid.d.ts +62 -0
- package/dist/drivers/glorious/classic-hid.d.ts.map +1 -0
- package/dist/drivers/glorious/classic-hid.js +326 -0
- package/dist/drivers/glorious/classic-hid.js.map +1 -0
- package/dist/drivers/glorious/hid.d.ts +39 -0
- package/dist/drivers/glorious/hid.d.ts.map +1 -0
- package/dist/drivers/glorious/hid.js +203 -0
- package/dist/drivers/glorious/hid.js.map +1 -0
- package/dist/drivers/gwolves/hid.d.ts +27 -0
- package/dist/drivers/gwolves/hid.d.ts.map +1 -0
- package/dist/drivers/gwolves/hid.js +225 -0
- package/dist/drivers/gwolves/hid.js.map +1 -0
- package/dist/drivers/gwolves/products.d.ts +17 -0
- package/dist/drivers/gwolves/products.d.ts.map +1 -0
- package/dist/drivers/gwolves/products.js +58 -0
- package/dist/drivers/gwolves/products.js.map +1 -0
- package/dist/drivers/hyperx/hid.d.ts +59 -0
- package/dist/drivers/hyperx/hid.d.ts.map +1 -0
- package/dist/drivers/hyperx/hid.js +229 -0
- package/dist/drivers/hyperx/hid.js.map +1 -0
- package/dist/drivers/incott/hid.d.ts +513 -0
- package/dist/drivers/incott/hid.d.ts.map +1 -0
- package/dist/drivers/incott/hid.js +1173 -0
- package/dist/drivers/incott/hid.js.map +1 -0
- package/dist/drivers/index.d.ts +5 -0
- package/dist/drivers/index.d.ts.map +1 -0
- package/dist/drivers/index.js +5 -0
- package/dist/drivers/index.js.map +1 -0
- package/dist/drivers/keychron/m6-hid.d.ts +81 -0
- package/dist/drivers/keychron/m6-hid.d.ts.map +1 -0
- package/dist/drivers/keychron/m6-hid.js +486 -0
- package/dist/drivers/keychron/m6-hid.js.map +1 -0
- package/dist/drivers/keychron/nape-hid.d.ts +60 -0
- package/dist/drivers/keychron/nape-hid.d.ts.map +1 -0
- package/dist/drivers/keychron/nape-hid.js +432 -0
- package/dist/drivers/keychron/nape-hid.js.map +1 -0
- package/dist/drivers/ksnake/hid.d.ts +74 -0
- package/dist/drivers/ksnake/hid.d.ts.map +1 -0
- package/dist/drivers/ksnake/hid.js +368 -0
- package/dist/drivers/ksnake/hid.js.map +1 -0
- package/dist/drivers/lamzu/hid.d.ts +58 -0
- package/dist/drivers/lamzu/hid.d.ts.map +1 -0
- package/dist/drivers/lamzu/hid.js +414 -0
- package/dist/drivers/lamzu/hid.js.map +1 -0
- package/dist/drivers/lamzu-atlantis/hid.d.ts +148 -0
- package/dist/drivers/lamzu-atlantis/hid.d.ts.map +1 -0
- package/dist/drivers/lamzu-atlantis/hid.js +587 -0
- package/dist/drivers/lamzu-atlantis/hid.js.map +1 -0
- package/dist/drivers/logitech/bolt.d.ts +41 -0
- package/dist/drivers/logitech/bolt.d.ts.map +1 -0
- package/dist/drivers/logitech/bolt.js +105 -0
- package/dist/drivers/logitech/bolt.js.map +1 -0
- package/dist/drivers/logitech/hidpp.d.ts +525 -0
- package/dist/drivers/logitech/hidpp.d.ts.map +1 -0
- package/dist/drivers/logitech/hidpp.js +2774 -0
- package/dist/drivers/logitech/hidpp.js.map +1 -0
- package/dist/drivers/logitech/mode-status.d.ts +53 -0
- package/dist/drivers/logitech/mode-status.d.ts.map +1 -0
- package/dist/drivers/logitech/mode-status.js +52 -0
- package/dist/drivers/logitech/mode-status.js.map +1 -0
- package/dist/drivers/logitech/onboard-profiles.d.ts +298 -0
- package/dist/drivers/logitech/onboard-profiles.d.ts.map +1 -0
- package/dist/drivers/logitech/onboard-profiles.js +965 -0
- package/dist/drivers/logitech/onboard-profiles.js.map +1 -0
- package/dist/drivers/logitech/rgb-effects.d.ts +20 -0
- package/dist/drivers/logitech/rgb-effects.d.ts.map +1 -0
- package/dist/drivers/logitech/rgb-effects.js +93 -0
- package/dist/drivers/logitech/rgb-effects.js.map +1 -0
- package/dist/drivers/mchose/a5-gen1-hid.d.ts +36 -0
- package/dist/drivers/mchose/a5-gen1-hid.d.ts.map +1 -0
- package/dist/drivers/mchose/a5-gen1-hid.js +219 -0
- package/dist/drivers/mchose/a5-gen1-hid.js.map +1 -0
- package/dist/drivers/mchose/dock-hid.d.ts +26 -0
- package/dist/drivers/mchose/dock-hid.d.ts.map +1 -0
- package/dist/drivers/mchose/dock-hid.js +176 -0
- package/dist/drivers/mchose/dock-hid.js.map +1 -0
- package/dist/drivers/mchose/hid.d.ts +118 -0
- package/dist/drivers/mchose/hid.d.ts.map +1 -0
- package/dist/drivers/mchose/hid.js +550 -0
- package/dist/drivers/mchose/hid.js.map +1 -0
- package/dist/drivers/mchose/v3-hid.d.ts +109 -0
- package/dist/drivers/mchose/v3-hid.d.ts.map +1 -0
- package/dist/drivers/mchose/v3-hid.js +572 -0
- package/dist/drivers/mchose/v3-hid.js.map +1 -0
- package/dist/drivers/microsoft/hid.d.ts +25 -0
- package/dist/drivers/microsoft/hid.d.ts.map +1 -0
- package/dist/drivers/microsoft/hid.js +247 -0
- package/dist/drivers/microsoft/hid.js.map +1 -0
- package/dist/drivers/moddo/hid.d.ts +31 -0
- package/dist/drivers/moddo/hid.d.ts.map +1 -0
- package/dist/drivers/moddo/hid.js +154 -0
- package/dist/drivers/moddo/hid.js.map +1 -0
- package/dist/drivers/mouse-types.d.ts +388 -0
- package/dist/drivers/mouse-types.d.ts.map +1 -0
- package/dist/drivers/mouse-types.js +2 -0
- package/dist/drivers/mouse-types.js.map +1 -0
- package/dist/drivers/ninjutso/hid.d.ts +62 -0
- package/dist/drivers/ninjutso/hid.d.ts.map +1 -0
- package/dist/drivers/ninjutso/hid.js +680 -0
- package/dist/drivers/ninjutso/hid.js.map +1 -0
- package/dist/drivers/orbital/hid.d.ts +24 -0
- package/dist/drivers/orbital/hid.d.ts.map +1 -0
- package/dist/drivers/orbital/hid.js +85 -0
- package/dist/drivers/orbital/hid.js.map +1 -0
- package/dist/drivers/orbital/host-protocol.d.ts +59 -0
- package/dist/drivers/orbital/host-protocol.d.ts.map +1 -0
- package/dist/drivers/orbital/host-protocol.js +884 -0
- package/dist/drivers/orbital/host-protocol.js.map +1 -0
- package/dist/drivers/pulsar/pulsar-hid.d.ts +63 -0
- package/dist/drivers/pulsar/pulsar-hid.d.ts.map +1 -0
- package/dist/drivers/pulsar/pulsar-hid.js +381 -0
- package/dist/drivers/pulsar/pulsar-hid.js.map +1 -0
- package/dist/drivers/pulsar/pulsar-pro-hid.d.ts +46 -0
- package/dist/drivers/pulsar/pulsar-pro-hid.d.ts.map +1 -0
- package/dist/drivers/pulsar/pulsar-pro-hid.js +343 -0
- package/dist/drivers/pulsar/pulsar-pro-hid.js.map +1 -0
- package/dist/drivers/pulsar/pulsar-xs1-hid.d.ts +40 -0
- package/dist/drivers/pulsar/pulsar-xs1-hid.d.ts.map +1 -0
- package/dist/drivers/pulsar/pulsar-xs1-hid.js +251 -0
- package/dist/drivers/pulsar/pulsar-xs1-hid.js.map +1 -0
- package/dist/drivers/rawm/hid.d.ts +29 -0
- package/dist/drivers/rawm/hid.d.ts.map +1 -0
- package/dist/drivers/rawm/hid.js +210 -0
- package/dist/drivers/rawm/hid.js.map +1 -0
- package/dist/drivers/razer/cobra-hid.d.ts +63 -0
- package/dist/drivers/razer/cobra-hid.d.ts.map +1 -0
- package/dist/drivers/razer/cobra-hid.js +282 -0
- package/dist/drivers/razer/cobra-hid.js.map +1 -0
- package/dist/drivers/razer/hid-open.d.ts +13 -0
- package/dist/drivers/razer/hid-open.d.ts.map +1 -0
- package/dist/drivers/razer/hid-open.js +29 -0
- package/dist/drivers/razer/hid-open.js.map +1 -0
- package/dist/drivers/razer/hid.d.ts +231 -0
- package/dist/drivers/razer/hid.d.ts.map +1 -0
- package/dist/drivers/razer/hid.js +772 -0
- package/dist/drivers/razer/hid.js.map +1 -0
- package/dist/drivers/razer/viper-hid.d.ts +33 -0
- package/dist/drivers/razer/viper-hid.d.ts.map +1 -0
- package/dist/drivers/razer/viper-hid.js +177 -0
- package/dist/drivers/razer/viper-hid.js.map +1 -0
- package/dist/drivers/razer/viper-mini-hid.d.ts +58 -0
- package/dist/drivers/razer/viper-mini-hid.d.ts.map +1 -0
- package/dist/drivers/razer/viper-mini-hid.js +273 -0
- package/dist/drivers/razer/viper-mini-hid.js.map +1 -0
- package/dist/drivers/razer/viper-v4-pro-hid.d.ts +26 -0
- package/dist/drivers/razer/viper-v4-pro-hid.d.ts.map +1 -0
- package/dist/drivers/razer/viper-v4-pro-hid.js +154 -0
- package/dist/drivers/razer/viper-v4-pro-hid.js.map +1 -0
- package/dist/drivers/registry.d.ts +70 -0
- package/dist/drivers/registry.d.ts.map +1 -0
- package/dist/drivers/registry.js +146 -0
- package/dist/drivers/registry.js.map +1 -0
- package/dist/drivers/steelseries/aerox3-hid.d.ts +53 -0
- package/dist/drivers/steelseries/aerox3-hid.d.ts.map +1 -0
- package/dist/drivers/steelseries/aerox3-hid.js +172 -0
- package/dist/drivers/steelseries/aerox3-hid.js.map +1 -0
- package/dist/drivers/steelseries/aerox5-hid.d.ts +54 -0
- package/dist/drivers/steelseries/aerox5-hid.d.ts.map +1 -0
- package/dist/drivers/steelseries/aerox5-hid.js +173 -0
- package/dist/drivers/steelseries/aerox5-hid.js.map +1 -0
- package/dist/drivers/steelseries/aerox5-wireless-hid.d.ts +69 -0
- package/dist/drivers/steelseries/aerox5-wireless-hid.d.ts.map +1 -0
- package/dist/drivers/steelseries/aerox5-wireless-hid.js +234 -0
- package/dist/drivers/steelseries/aerox5-wireless-hid.js.map +1 -0
- package/dist/drivers/steelseries/aerox9-wireless-hid.d.ts +70 -0
- package/dist/drivers/steelseries/aerox9-wireless-hid.d.ts.map +1 -0
- package/dist/drivers/steelseries/aerox9-wireless-hid.js +227 -0
- package/dist/drivers/steelseries/aerox9-wireless-hid.js.map +1 -0
- package/dist/drivers/steelseries/hid.d.ts +48 -0
- package/dist/drivers/steelseries/hid.d.ts.map +1 -0
- package/dist/drivers/steelseries/hid.js +157 -0
- package/dist/drivers/steelseries/hid.js.map +1 -0
- package/dist/drivers/steelseries/prime-mini-wireless-hid.d.ts +62 -0
- package/dist/drivers/steelseries/prime-mini-wireless-hid.d.ts.map +1 -0
- package/dist/drivers/steelseries/prime-mini-wireless-hid.js +215 -0
- package/dist/drivers/steelseries/prime-mini-wireless-hid.js.map +1 -0
- package/dist/drivers/steelseries/prime-plus-hid.d.ts +51 -0
- package/dist/drivers/steelseries/prime-plus-hid.d.ts.map +1 -0
- package/dist/drivers/steelseries/prime-plus-hid.js +150 -0
- package/dist/drivers/steelseries/prime-plus-hid.js.map +1 -0
- package/dist/drivers/steelseries/rival3-wireless-hid.d.ts +61 -0
- package/dist/drivers/steelseries/rival3-wireless-hid.d.ts.map +1 -0
- package/dist/drivers/steelseries/rival3-wireless-hid.js +185 -0
- package/dist/drivers/steelseries/rival3-wireless-hid.js.map +1 -0
- package/dist/drivers/steelseries/rival310-hid.d.ts +59 -0
- package/dist/drivers/steelseries/rival310-hid.d.ts.map +1 -0
- package/dist/drivers/steelseries/rival310-hid.js +182 -0
- package/dist/drivers/steelseries/rival310-hid.js.map +1 -0
- package/dist/drivers/steelseries/rival650-hid.d.ts +68 -0
- package/dist/drivers/steelseries/rival650-hid.d.ts.map +1 -0
- package/dist/drivers/steelseries/rival650-hid.js +209 -0
- package/dist/drivers/steelseries/rival650-hid.js.map +1 -0
- package/dist/drivers/steelseries/sensei-ten-hid.d.ts +62 -0
- package/dist/drivers/steelseries/sensei-ten-hid.d.ts.map +1 -0
- package/dist/drivers/steelseries/sensei-ten-hid.js +186 -0
- package/dist/drivers/steelseries/sensei-ten-hid.js.map +1 -0
- package/dist/drivers/teevolution/hid.d.ts +82 -0
- package/dist/drivers/teevolution/hid.d.ts.map +1 -0
- package/dist/drivers/teevolution/hid.js +607 -0
- package/dist/drivers/teevolution/hid.js.map +1 -0
- package/dist/drivers/vendors.d.ts +254 -0
- package/dist/drivers/vendors.d.ts.map +1 -0
- package/dist/drivers/vendors.js +587 -0
- package/dist/drivers/vendors.js.map +1 -0
- package/dist/drivers/vgn/hid.d.ts +33 -0
- package/dist/drivers/vgn/hid.d.ts.map +1 -0
- package/dist/drivers/vgn/hid.js +213 -0
- package/dist/drivers/vgn/hid.js.map +1 -0
- package/dist/drivers/wallhack/keyboard-hid.d.ts +28 -0
- package/dist/drivers/wallhack/keyboard-hid.d.ts.map +1 -0
- package/dist/drivers/wallhack/keyboard-hid.js +80 -0
- package/dist/drivers/wallhack/keyboard-hid.js.map +1 -0
- package/dist/drivers/wallhack/mouse-hid.d.ts +45 -0
- package/dist/drivers/wallhack/mouse-hid.d.ts.map +1 -0
- package/dist/drivers/wallhack/mouse-hid.js +288 -0
- package/dist/drivers/wallhack/mouse-hid.js.map +1 -0
- package/dist/drivers/webhid.d.ts +59 -0
- package/dist/drivers/webhid.d.ts.map +1 -0
- package/dist/drivers/webhid.js +2 -0
- package/dist/drivers/webhid.js.map +1 -0
- package/dist/drivers/wlmouse/hid.d.ts +81 -0
- package/dist/drivers/wlmouse/hid.d.ts.map +1 -0
- package/dist/drivers/wlmouse/hid.js +576 -0
- package/dist/drivers/wlmouse/hid.js.map +1 -0
- package/dist/drivers/wooting/hid.d.ts +86 -0
- package/dist/drivers/wooting/hid.d.ts.map +1 -0
- package/dist/drivers/wooting/hid.js +320 -0
- package/dist/drivers/wooting/hid.js.map +1 -0
- package/dist/drivers/zaunkoenig/hid.d.ts +31 -0
- package/dist/drivers/zaunkoenig/hid.d.ts.map +1 -0
- package/dist/drivers/zaunkoenig/hid.js +162 -0
- package/dist/drivers/zaunkoenig/hid.js.map +1 -0
- package/dist/endgame-gear/op1.d.ts +165 -0
- package/dist/endgame-gear/op1.d.ts.map +1 -0
- package/dist/endgame-gear/op1.js +384 -0
- package/dist/endgame-gear/op1.js.map +1 -0
- package/dist/endgame-gear/wireless.d.ts +93 -0
- package/dist/endgame-gear/wireless.d.ts.map +1 -0
- package/dist/endgame-gear/wireless.js +242 -0
- package/dist/endgame-gear/wireless.js.map +1 -0
- package/dist/fantech/index.d.ts +9 -0
- package/dist/fantech/index.d.ts.map +1 -0
- package/dist/fantech/index.js +11 -0
- package/dist/fantech/index.js.map +1 -0
- package/dist/finalmouse/index.d.ts +41 -0
- package/dist/finalmouse/index.d.ts.map +1 -0
- package/dist/finalmouse/index.js +106 -0
- package/dist/finalmouse/index.js.map +1 -0
- package/dist/gearhub/index.d.ts +210 -0
- package/dist/gearhub/index.d.ts.map +1 -0
- package/dist/gearhub/index.js +282 -0
- package/dist/gearhub/index.js.map +1 -0
- package/dist/glorious/index.d.ts +89 -0
- package/dist/glorious/index.d.ts.map +1 -0
- package/dist/glorious/index.js +236 -0
- package/dist/glorious/index.js.map +1 -0
- package/dist/glorious-classic/index.d.ts +103 -0
- package/dist/glorious-classic/index.d.ts.map +1 -0
- package/dist/glorious-classic/index.js +304 -0
- package/dist/glorious-classic/index.js.map +1 -0
- package/dist/gwolves/index.d.ts +82 -0
- package/dist/gwolves/index.d.ts.map +1 -0
- package/dist/gwolves/index.js +197 -0
- package/dist/gwolves/index.js.map +1 -0
- package/dist/hyperx/index.d.ts +181 -0
- package/dist/hyperx/index.d.ts.map +1 -0
- package/dist/hyperx/index.js +303 -0
- package/dist/hyperx/index.js.map +1 -0
- package/dist/incott/index.d.ts +1067 -0
- package/dist/incott/index.d.ts.map +1 -0
- package/dist/incott/index.js +1482 -0
- package/dist/incott/index.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/keychron/index.d.ts +194 -0
- package/dist/keychron/index.d.ts.map +1 -0
- package/dist/keychron/index.js +341 -0
- package/dist/keychron/index.js.map +1 -0
- package/dist/ksnake/index.d.ts +157 -0
- package/dist/ksnake/index.d.ts.map +1 -0
- package/dist/ksnake/index.js +314 -0
- package/dist/ksnake/index.js.map +1 -0
- package/dist/lamzu/atlantis.d.ts +237 -0
- package/dist/lamzu/atlantis.d.ts.map +1 -0
- package/dist/lamzu/atlantis.js +263 -0
- package/dist/lamzu/atlantis.js.map +1 -0
- package/dist/lamzu/index.d.ts +60 -0
- package/dist/lamzu/index.d.ts.map +1 -0
- package/dist/lamzu/index.js +86 -0
- package/dist/lamzu/index.js.map +1 -0
- package/dist/logitech/controls.d.ts +138 -0
- package/dist/logitech/controls.d.ts.map +1 -0
- package/dist/logitech/controls.js +184 -0
- package/dist/logitech/controls.js.map +1 -0
- package/dist/logitech/friendly-name.d.ts +50 -0
- package/dist/logitech/friendly-name.d.ts.map +1 -0
- package/dist/logitech/friendly-name.js +74 -0
- package/dist/logitech/friendly-name.js.map +1 -0
- package/dist/logitech/haptics.d.ts +97 -0
- package/dist/logitech/haptics.d.ts.map +1 -0
- package/dist/logitech/haptics.js +116 -0
- package/dist/logitech/haptics.js.map +1 -0
- package/dist/logitech/hosts.d.ts +55 -0
- package/dist/logitech/hosts.d.ts.map +1 -0
- package/dist/logitech/hosts.js +80 -0
- package/dist/logitech/hosts.js.map +1 -0
- package/dist/logitech/index.d.ts +127 -0
- package/dist/logitech/index.d.ts.map +1 -0
- package/dist/logitech/index.js +233 -0
- package/dist/logitech/index.js.map +1 -0
- package/dist/logitech/wheel.d.ts +117 -0
- package/dist/logitech/wheel.d.ts.map +1 -0
- package/dist/logitech/wheel.js +133 -0
- package/dist/logitech/wheel.js.map +1 -0
- package/dist/mchose/a5-gen1.d.ts +38 -0
- package/dist/mchose/a5-gen1.d.ts.map +1 -0
- package/dist/mchose/a5-gen1.js +60 -0
- package/dist/mchose/a5-gen1.js.map +1 -0
- package/dist/mchose/buttons.d.ts +66 -0
- package/dist/mchose/buttons.d.ts.map +1 -0
- package/dist/mchose/buttons.js +184 -0
- package/dist/mchose/buttons.js.map +1 -0
- package/dist/mchose/dock.d.ts +77 -0
- package/dist/mchose/dock.d.ts.map +1 -0
- package/dist/mchose/dock.js +133 -0
- package/dist/mchose/dock.js.map +1 -0
- package/dist/mchose/index.d.ts +299 -0
- package/dist/mchose/index.d.ts.map +1 -0
- package/dist/mchose/index.js +429 -0
- package/dist/mchose/index.js.map +1 -0
- package/dist/mchose/v3-buttons.d.ts +64 -0
- package/dist/mchose/v3-buttons.d.ts.map +1 -0
- package/dist/mchose/v3-buttons.js +258 -0
- package/dist/mchose/v3-buttons.js.map +1 -0
- package/dist/mchose/v3.d.ts +380 -0
- package/dist/mchose/v3.d.ts.map +1 -0
- package/dist/mchose/v3.js +608 -0
- package/dist/mchose/v3.js.map +1 -0
- package/dist/microsoft/index.d.ts +19 -0
- package/dist/microsoft/index.d.ts.map +1 -0
- package/dist/microsoft/index.js +22 -0
- package/dist/microsoft/index.js.map +1 -0
- package/dist/moddo/index.d.ts +72 -0
- package/dist/moddo/index.d.ts.map +1 -0
- package/dist/moddo/index.js +147 -0
- package/dist/moddo/index.js.map +1 -0
- package/dist/ninjutso/index.d.ts +74 -0
- package/dist/ninjutso/index.d.ts.map +1 -0
- package/dist/ninjutso/index.js +133 -0
- package/dist/ninjutso/index.js.map +1 -0
- package/dist/orbital/index.d.ts +14 -0
- package/dist/orbital/index.d.ts.map +1 -0
- package/dist/orbital/index.js +19 -0
- package/dist/orbital/index.js.map +1 -0
- package/dist/pulsar/index.d.ts +81 -0
- package/dist/pulsar/index.d.ts.map +1 -0
- package/dist/pulsar/index.js +185 -0
- package/dist/pulsar/index.js.map +1 -0
- package/dist/rawm/index.d.ts +55 -0
- package/dist/rawm/index.d.ts.map +1 -0
- package/dist/rawm/index.js +229 -0
- package/dist/rawm/index.js.map +1 -0
- package/dist/razer/codec.d.ts +504 -0
- package/dist/razer/codec.d.ts.map +1 -0
- package/dist/razer/codec.js +648 -0
- package/dist/razer/codec.js.map +1 -0
- package/dist/razer/devices.d.ts +156 -0
- package/dist/razer/devices.d.ts.map +1 -0
- package/dist/razer/devices.js +540 -0
- package/dist/razer/devices.js.map +1 -0
- package/dist/razer/index.d.ts +2 -0
- package/dist/razer/index.d.ts.map +1 -0
- package/dist/razer/index.js +2 -0
- package/dist/razer/index.js.map +1 -0
- package/dist/razer/v4.d.ts +19 -0
- package/dist/razer/v4.d.ts.map +1 -0
- package/dist/razer/v4.js +51 -0
- package/dist/razer/v4.js.map +1 -0
- package/dist/steelseries/aerox3.d.ts +236 -0
- package/dist/steelseries/aerox3.d.ts.map +1 -0
- package/dist/steelseries/aerox3.js +311 -0
- package/dist/steelseries/aerox3.js.map +1 -0
- package/dist/steelseries/aerox5-wireless.d.ts +300 -0
- package/dist/steelseries/aerox5-wireless.d.ts.map +1 -0
- package/dist/steelseries/aerox5-wireless.js +389 -0
- package/dist/steelseries/aerox5-wireless.js.map +1 -0
- package/dist/steelseries/aerox5.d.ts +228 -0
- package/dist/steelseries/aerox5.d.ts.map +1 -0
- package/dist/steelseries/aerox5.js +294 -0
- package/dist/steelseries/aerox5.js.map +1 -0
- package/dist/steelseries/aerox9-wireless.d.ts +213 -0
- package/dist/steelseries/aerox9-wireless.d.ts.map +1 -0
- package/dist/steelseries/aerox9-wireless.js +305 -0
- package/dist/steelseries/aerox9-wireless.js.map +1 -0
- package/dist/steelseries/devices.d.ts +82 -0
- package/dist/steelseries/devices.d.ts.map +1 -0
- package/dist/steelseries/devices.js +310 -0
- package/dist/steelseries/devices.js.map +1 -0
- package/dist/steelseries/index.d.ts +13 -0
- package/dist/steelseries/index.d.ts.map +1 -0
- package/dist/steelseries/index.js +13 -0
- package/dist/steelseries/index.js.map +1 -0
- package/dist/steelseries/prime-mini-wireless.d.ts +253 -0
- package/dist/steelseries/prime-mini-wireless.d.ts.map +1 -0
- package/dist/steelseries/prime-mini-wireless.js +351 -0
- package/dist/steelseries/prime-mini-wireless.js.map +1 -0
- package/dist/steelseries/prime-plus.d.ts +179 -0
- package/dist/steelseries/prime-plus.d.ts.map +1 -0
- package/dist/steelseries/prime-plus.js +275 -0
- package/dist/steelseries/prime-plus.js.map +1 -0
- package/dist/steelseries/rival3-wireless.d.ts +222 -0
- package/dist/steelseries/rival3-wireless.d.ts.map +1 -0
- package/dist/steelseries/rival3-wireless.js +308 -0
- package/dist/steelseries/rival3-wireless.js.map +1 -0
- package/dist/steelseries/rival3.d.ts +99 -0
- package/dist/steelseries/rival3.d.ts.map +1 -0
- package/dist/steelseries/rival3.js +147 -0
- package/dist/steelseries/rival3.js.map +1 -0
- package/dist/steelseries/rival310.d.ts +230 -0
- package/dist/steelseries/rival310.d.ts.map +1 -0
- package/dist/steelseries/rival310.js +322 -0
- package/dist/steelseries/rival310.js.map +1 -0
- package/dist/steelseries/rival650.d.ts +215 -0
- package/dist/steelseries/rival650.d.ts.map +1 -0
- package/dist/steelseries/rival650.js +284 -0
- package/dist/steelseries/rival650.js.map +1 -0
- package/dist/steelseries/sensei-ten.d.ts +283 -0
- package/dist/steelseries/sensei-ten.d.ts.map +1 -0
- package/dist/steelseries/sensei-ten.js +389 -0
- package/dist/steelseries/sensei-ten.js.map +1 -0
- package/dist/teevolution/index.d.ts +211 -0
- package/dist/teevolution/index.d.ts.map +1 -0
- package/dist/teevolution/index.js +458 -0
- package/dist/teevolution/index.js.map +1 -0
- package/dist/valkyrie/index.d.ts +19 -0
- package/dist/valkyrie/index.d.ts.map +1 -0
- package/dist/valkyrie/index.js +43 -0
- package/dist/valkyrie/index.js.map +1 -0
- package/dist/valkyrie/settings.d.ts +28 -0
- package/dist/valkyrie/settings.d.ts.map +1 -0
- package/dist/valkyrie/settings.js +84 -0
- package/dist/valkyrie/settings.js.map +1 -0
- package/dist/vgn/index.d.ts +59 -0
- package/dist/vgn/index.d.ts.map +1 -0
- package/dist/vgn/index.js +165 -0
- package/dist/vgn/index.js.map +1 -0
- package/dist/wallhack/index.d.ts +165 -0
- package/dist/wallhack/index.d.ts.map +1 -0
- package/dist/wallhack/index.js +226 -0
- package/dist/wallhack/index.js.map +1 -0
- package/dist/wlmouse/index.d.ts +4 -0
- package/dist/wlmouse/index.d.ts.map +1 -0
- package/dist/wlmouse/index.js +7 -0
- package/dist/wlmouse/index.js.map +1 -0
- package/dist/wooting/index.d.ts +225 -0
- package/dist/wooting/index.d.ts.map +1 -0
- package/dist/wooting/index.js +296 -0
- package/dist/wooting/index.js.map +1 -0
- package/dist/zaunkoenig/index.d.ts +49 -0
- package/dist/zaunkoenig/index.d.ts.map +1 -0
- package/dist/zaunkoenig/index.js +127 -0
- package/dist/zaunkoenig/index.js.map +1 -0
- package/package.json +193 -0
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
import { VENDOR_ID } from "../vendors.js";
|
|
2
|
+
import { TEEVOLUTION_BUTTON_OPTIONS, TEEVOLUTION_COMMAND, TEEVOLUTION_FLASH, TEEVOLUTION_PROFILE_COUNT, TEEVOLUTION_KEY_TABLE_LENGTH, TEEVOLUTION_LCD_REPORT_ID, TEEVOLUTION_LCD_USAGE, TEEVOLUTION_LCD_USAGE_PAGE, TEEVOLUTION_PRODUCT_IDS, TEEVOLUTION_REPORT_ID, TEEVOLUTION_TYPE_MAX_POLL, teevolutionBuildLcdTimePacket, teevolutionBuildOnlinePayload, teevolutionBuildReadPayload, teevolutionBuildSetCurrentProfile, teevolutionBuildSimplePayload, teevolutionBuildWritePayload, teevolutionDecodeButtonMappings, teevolutionDecodeCurrentProfile, teevolutionDecodeDpiLightBrightness, teevolutionDecodeDpiLightMode, teevolutionDecodeDpi, teevolutionDecodeFirmwareVersion, teevolutionDecodeLiftOff, teevolutionDecodePollingRate, teevolutionDecodeSensorModeStored, teevolutionDpiOptions, teevolutionEncodeDpiLightBrightness, teevolutionEncodeDpi, teevolutionEncodeKeyFunction, teevolutionEncodeLiftOff, teevolutionEncodePollingRate, teevolutionEncodeSensorMode, teevolutionFindButton, teevolutionFindButtonAction, teevolutionKeyFunctionAddress, teevolutionKeyFunctionLabel, teevolutionKeyTableHasLeftClick, teevolutionPacketChecksum, teevolutionParseBattery, teevolutionParseReadResponse, teevolutionProfileForCid, teevolutionSensorModeUi, } from "@openmouse/protocol/teevolution";
|
|
3
|
+
const PROFILE_SETTLE_MS = 100;
|
|
4
|
+
function delay(ms) {
|
|
5
|
+
return new Promise((resolve) => window.setTimeout(resolve, ms));
|
|
6
|
+
}
|
|
7
|
+
export class TeevolutionHidClient {
|
|
8
|
+
static RAPIDSYNC_OFFLINE_ERROR = "The RapidSync 8K dongle is connected, but the mouse is offline. Wake the mouse or pair it to this dongle, then retry.";
|
|
9
|
+
static MOUSE_OFFLINE_ERROR = "The Teevolution mouse is offline. Move it or click a button, then retry.";
|
|
10
|
+
static mouseOfflineMessage(rapidSyncDongle) {
|
|
11
|
+
return rapidSyncDongle
|
|
12
|
+
? TeevolutionHidClient.RAPIDSYNC_OFFLINE_ERROR
|
|
13
|
+
: TeevolutionHidClient.MOUSE_OFFLINE_ERROR;
|
|
14
|
+
}
|
|
15
|
+
deviceInfo = null;
|
|
16
|
+
lcdClockSynced = false;
|
|
17
|
+
lcdDevice = null;
|
|
18
|
+
responseWaiter = null;
|
|
19
|
+
onInputReport = (event) => {
|
|
20
|
+
const bytes = new Uint8Array(event.data.buffer.slice(event.data.byteOffset, event.data.byteOffset + event.data.byteLength));
|
|
21
|
+
if (event.reportId === TEEVOLUTION_REPORT_ID && bytes[0] === this.responseWaiter?.command) {
|
|
22
|
+
const waiter = this.responseWaiter;
|
|
23
|
+
this.responseWaiter = null;
|
|
24
|
+
waiter.resolve(bytes);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
device;
|
|
28
|
+
constructor(device) {
|
|
29
|
+
this.device = device;
|
|
30
|
+
}
|
|
31
|
+
static isSupported(device) {
|
|
32
|
+
return device.vendorId === VENDOR_ID.teevolution
|
|
33
|
+
&& TEEVOLUTION_PRODUCT_IDS.has(device.productId)
|
|
34
|
+
&& device.collections.some((collection) => collection.inputReports.length === 1
|
|
35
|
+
&& collection.outputReports.length === 1
|
|
36
|
+
&& collection.inputReports[0]?.reportId === TEEVOLUTION_REPORT_ID
|
|
37
|
+
&& collection.outputReports[0]?.reportId === TEEVOLUTION_REPORT_ID);
|
|
38
|
+
}
|
|
39
|
+
async open() {
|
|
40
|
+
if (!this.device.opened)
|
|
41
|
+
await this.device.open();
|
|
42
|
+
this.device.addEventListener("inputreport", this.onInputReport);
|
|
43
|
+
}
|
|
44
|
+
describeCollections() {
|
|
45
|
+
return this.device.collections.map((collection) => {
|
|
46
|
+
const inputIds = collection.inputReports.map((report) => report.reportId);
|
|
47
|
+
const outputIds = collection.outputReports.map((report) => report.reportId);
|
|
48
|
+
const featureIds = collection.featureReports.map((report) => report.reportId);
|
|
49
|
+
return [
|
|
50
|
+
`usage 0x${collection.usagePage.toString(16)}:${collection.usage.toString(16)}`,
|
|
51
|
+
`in [${inputIds.join(", ") || "none"}]`,
|
|
52
|
+
`out [${outputIds.join(", ") || "none"}]`,
|
|
53
|
+
`feature [${featureIds.join(", ") || "none"}]`,
|
|
54
|
+
].join(" · ");
|
|
55
|
+
}).join(" | ") || "No HID collections reported";
|
|
56
|
+
}
|
|
57
|
+
async readDeviceInfo() {
|
|
58
|
+
await this.open();
|
|
59
|
+
const challenge = new Uint8Array(8);
|
|
60
|
+
crypto.getRandomValues(challenge);
|
|
61
|
+
challenge.fill(0, 4);
|
|
62
|
+
const response = await this.query(TEEVOLUTION_COMMAND.encryptionData, challenge);
|
|
63
|
+
this.assertAccepted(response, "identification");
|
|
64
|
+
const cid = response[9] ?? 0;
|
|
65
|
+
const profile = teevolutionProfileForCid(cid);
|
|
66
|
+
if (!profile) {
|
|
67
|
+
throw new Error(`Unsupported Teevolution model (CID 0x${cid.toString(16).padStart(2, "0")}). No flash settings were read or written.`);
|
|
68
|
+
}
|
|
69
|
+
const type = response[11] ?? 0xff;
|
|
70
|
+
this.deviceInfo = {
|
|
71
|
+
cid,
|
|
72
|
+
mid: response[10] ?? 0,
|
|
73
|
+
type,
|
|
74
|
+
dongleType: response[12] ?? 0,
|
|
75
|
+
connection: type === 2 || type === 3 ? "Wired" : "Wireless",
|
|
76
|
+
maximumPollingRateHz: TEEVOLUTION_TYPE_MAX_POLL[type] ?? 1000,
|
|
77
|
+
profile,
|
|
78
|
+
};
|
|
79
|
+
await this.syncDongleClock().catch(() => undefined);
|
|
80
|
+
return this.deviceInfo;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Pushes host local time to a RapidSync LCD once per connection. Missing LCD
|
|
84
|
+
* collections (wired Terra, unauthorized sibling) are skipped.
|
|
85
|
+
*/
|
|
86
|
+
async syncDongleClock(now = new Date()) {
|
|
87
|
+
if (this.lcdClockSynced)
|
|
88
|
+
return true;
|
|
89
|
+
const lcd = await this.findLcdClockDevice();
|
|
90
|
+
if (!lcd)
|
|
91
|
+
return false;
|
|
92
|
+
const packet = teevolutionBuildLcdTimePacket(now);
|
|
93
|
+
const alreadyOpen = lcd.opened;
|
|
94
|
+
if (!alreadyOpen)
|
|
95
|
+
await lcd.open();
|
|
96
|
+
this.lcdDevice = lcd;
|
|
97
|
+
await lcd.sendReport(TEEVOLUTION_LCD_REPORT_ID, new Uint8Array(packet.subarray(1)));
|
|
98
|
+
this.lcdClockSynced = true;
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
async readStatus() {
|
|
102
|
+
const info = this.deviceInfo ?? await this.readDeviceInfo();
|
|
103
|
+
return await this.withDeviceControl(async () => {
|
|
104
|
+
const flash = await this.readFlash(TEEVOLUTION_FLASH.reportRate, TEEVOLUTION_FLASH.sensorMode + 2);
|
|
105
|
+
const batteryResponse = await this.query(TEEVOLUTION_COMMAND.batteryLevel);
|
|
106
|
+
const deviceVersion = await this.query(TEEVOLUTION_COMMAND.readVersionId);
|
|
107
|
+
const dongleVersion = await this.query(TEEVOLUTION_COMMAND.getDongleVersion).catch(() => null);
|
|
108
|
+
const profile = await this.query(TEEVOLUTION_COMMAND.getCurrentConfig).catch(() => null);
|
|
109
|
+
const rssi = await this.query(TEEVOLUTION_COMMAND.getRssi).catch(() => null);
|
|
110
|
+
const currentBank = profile ? teevolutionDecodeCurrentProfile(profile) : null;
|
|
111
|
+
const stageCount = this.decodeDpiStageCount(flash[TEEVOLUTION_FLASH.maxDpiStage], info.profile);
|
|
112
|
+
const activeDpiStage = Math.min(flash[TEEVOLUTION_FLASH.currentDpi] ?? 0, stageCount - 1);
|
|
113
|
+
const dpiStages = Array.from({ length: stageCount }, (_, stage) => {
|
|
114
|
+
const offset = TEEVOLUTION_FLASH.dpiValues + stage * 4;
|
|
115
|
+
return teevolutionDecodeDpi(flash.slice(offset, offset + 4));
|
|
116
|
+
});
|
|
117
|
+
const dpi = dpiStages[activeDpiStage] ?? dpiStages[0] ?? 0;
|
|
118
|
+
const battery = teevolutionParseBattery(batteryResponse);
|
|
119
|
+
const pollingRateHz = teevolutionDecodePollingRate(flash[TEEVOLUTION_FLASH.reportRate] ?? 1);
|
|
120
|
+
const sensorModeUi = teevolutionSensorModeUi({
|
|
121
|
+
storedMode: flash[TEEVOLUTION_FLASH.sensorMode] ?? 0,
|
|
122
|
+
pollingRateHz,
|
|
123
|
+
connection: info.connection,
|
|
124
|
+
});
|
|
125
|
+
return {
|
|
126
|
+
brand: "Teevolution",
|
|
127
|
+
name: this.displayName(info),
|
|
128
|
+
ui: {
|
|
129
|
+
defaultDisplayName: info.profile.name,
|
|
130
|
+
hideUnsupportedPollingRates: true,
|
|
131
|
+
hideSignalCard: true,
|
|
132
|
+
dpiStageEditor: {
|
|
133
|
+
maxStages: info.profile.dpiStageCount,
|
|
134
|
+
countEditable: true,
|
|
135
|
+
minDpi: info.profile.dpi.min,
|
|
136
|
+
maxDpi: info.profile.dpi.max,
|
|
137
|
+
stepDpi: info.profile.dpi.standardStep,
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
batteryPercent: battery?.percent ?? null,
|
|
141
|
+
batteryState: battery?.charging ? "Charging" : "Discharging",
|
|
142
|
+
dpi,
|
|
143
|
+
dpiStages,
|
|
144
|
+
activeDpiStage,
|
|
145
|
+
pollingRateHz,
|
|
146
|
+
supportedPollingRates: info.profile.pollingRates.filter((rate) => rate <= info.maximumPollingRateHz),
|
|
147
|
+
activeProfile: currentBank !== null ? currentBank + 1 : null,
|
|
148
|
+
profileCount: currentBank !== null ? TEEVOLUTION_PROFILE_COUNT : undefined,
|
|
149
|
+
connectionType: info.connection,
|
|
150
|
+
connectionDetail: `CID ${info.cid} · MID ${info.mid} · Type ${info.type}`,
|
|
151
|
+
signalStrength: rssi && rssi[1] === 0 ? Math.min(rssi[5] ?? 0, 4) : null,
|
|
152
|
+
dpiLedMode: teevolutionDecodeDpiLightMode(flash[TEEVOLUTION_FLASH.dpiLightMode] ?? 1, flash[TEEVOLUTION_FLASH.dpiLightState] ?? 0),
|
|
153
|
+
dpiLedBrightness: teevolutionDecodeDpiLightBrightness(flash[TEEVOLUTION_FLASH.dpiLightBrightness] ?? 0x80),
|
|
154
|
+
dpiLedSpeed: Math.min(Math.max(flash[TEEVOLUTION_FLASH.dpiLightSpeed] ?? 3, 1), 5),
|
|
155
|
+
debounceMs: flash[TEEVOLUTION_FLASH.debounceTime] ?? null,
|
|
156
|
+
motionSync: flash[TEEVOLUTION_FLASH.motionSync] === 1,
|
|
157
|
+
sleepTimeout: flash[TEEVOLUTION_FLASH.sleepTime] ?? null,
|
|
158
|
+
angleSnapping: flash[TEEVOLUTION_FLASH.angleSnapping] === 1,
|
|
159
|
+
rippleControl: flash[TEEVOLUTION_FLASH.rippleControl] === 1,
|
|
160
|
+
performanceMode: flash[TEEVOLUTION_FLASH.performanceState] === 1,
|
|
161
|
+
performanceDuration: flash[TEEVOLUTION_FLASH.performanceTime] ?? null,
|
|
162
|
+
sensorMode: sensorModeUi.mode,
|
|
163
|
+
sensorModeStored: sensorModeUi.storedValue,
|
|
164
|
+
sensorModeEditable: sensorModeUi.editable,
|
|
165
|
+
liftOffDistance: teevolutionDecodeLiftOff(flash[TEEVOLUTION_FLASH.liftOffDistance] ?? -1),
|
|
166
|
+
supportedLiftOffDistances: [...info.profile.liftOffDistances],
|
|
167
|
+
buttonMappings: teevolutionDecodeButtonMappings(flash),
|
|
168
|
+
buttonOptions: TEEVOLUTION_BUTTON_OPTIONS,
|
|
169
|
+
firmware: [
|
|
170
|
+
this.decodeVersionOptional("Mouse", deviceVersion) ?? "Mouse firmware unavailable",
|
|
171
|
+
this.decodeVersionOptional("Dongle", dongleVersion) ?? "Dongle firmware unavailable",
|
|
172
|
+
],
|
|
173
|
+
};
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
getDpiOptions() {
|
|
177
|
+
return teevolutionDpiOptions(this.profile());
|
|
178
|
+
}
|
|
179
|
+
getModelProfile() {
|
|
180
|
+
return this.profile();
|
|
181
|
+
}
|
|
182
|
+
getButtonOptions() {
|
|
183
|
+
return [...TEEVOLUTION_BUTTON_OPTIONS];
|
|
184
|
+
}
|
|
185
|
+
async setButtonMapping(button, action) {
|
|
186
|
+
const slot = teevolutionFindButton(button);
|
|
187
|
+
if (!slot)
|
|
188
|
+
throw new Error(`This mouse has no "${button}" button.`);
|
|
189
|
+
const assigned = teevolutionFindButtonAction(action);
|
|
190
|
+
if (!assigned)
|
|
191
|
+
throw new Error(`Unknown button action "${action}".`);
|
|
192
|
+
const payload = teevolutionEncodeKeyFunction(assigned.cls, assigned.param);
|
|
193
|
+
await this.open();
|
|
194
|
+
await this.withDeviceControl(async () => {
|
|
195
|
+
const table = await this.readFlash(TEEVOLUTION_FLASH.keyFunction, TEEVOLUTION_KEY_TABLE_LENGTH);
|
|
196
|
+
const next = new Uint8Array(table);
|
|
197
|
+
next.set(payload, slot.index * payload.length);
|
|
198
|
+
if (!teevolutionKeyTableHasLeftClick(next)) {
|
|
199
|
+
throw new Error("Keep at least one button as Left Click.");
|
|
200
|
+
}
|
|
201
|
+
const address = teevolutionKeyFunctionAddress(slot.index);
|
|
202
|
+
await this.writeFlash(address, payload);
|
|
203
|
+
const confirmed = await this.readFlash(address, payload.length);
|
|
204
|
+
if (teevolutionKeyFunctionLabel(confirmed) !== assigned.label) {
|
|
205
|
+
throw new Error("The mouse did not accept that button assignment.");
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Switch the active onboard bank. `profile` is 1-based to match the shell;
|
|
211
|
+
* TeevoLink / firmware use 0–3. DPI, buttons, and the rest of flash belong
|
|
212
|
+
* to that bank, so the panel re-reads status after this returns.
|
|
213
|
+
*/
|
|
214
|
+
async setProfile(profile) {
|
|
215
|
+
if (!Number.isInteger(profile) || profile < 1 || profile > TEEVOLUTION_PROFILE_COUNT) {
|
|
216
|
+
throw new Error(`Profile must be 1-${TEEVOLUTION_PROFILE_COUNT}.`);
|
|
217
|
+
}
|
|
218
|
+
await this.open();
|
|
219
|
+
await this.withDeviceControl(async () => {
|
|
220
|
+
this.assertAccepted(await this.exchange(teevolutionBuildSetCurrentProfile(profile - 1)), "profile switch");
|
|
221
|
+
await delay(PROFILE_SETTLE_MS);
|
|
222
|
+
const confirmed = teevolutionDecodeCurrentProfile(await this.query(TEEVOLUTION_COMMAND.getCurrentConfig));
|
|
223
|
+
if (confirmed !== profile - 1) {
|
|
224
|
+
throw new Error(confirmed === null
|
|
225
|
+
? "The mouse did not confirm the profile change."
|
|
226
|
+
: `The mouse kept profile ${confirmed + 1} instead of ${profile}.`);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
async setPollingRate(pollingRateHz) {
|
|
231
|
+
const info = this.deviceInfo ?? await this.readDeviceInfo();
|
|
232
|
+
if (!info.profile.pollingRates.includes(pollingRateHz)) {
|
|
233
|
+
throw new Error(`${pollingRateHz} Hz is not supported by the ${info.profile.name}.`);
|
|
234
|
+
}
|
|
235
|
+
const encoded = teevolutionEncodePollingRate(pollingRateHz);
|
|
236
|
+
if (pollingRateHz > info.maximumPollingRateHz) {
|
|
237
|
+
throw new Error(`This connection supports at most ${info.maximumPollingRateHz} Hz.`);
|
|
238
|
+
}
|
|
239
|
+
return await this.withDeviceControl(async () => {
|
|
240
|
+
await this.writeCheckedByte(TEEVOLUTION_FLASH.reportRate, encoded);
|
|
241
|
+
const confirmed = teevolutionDecodePollingRate((await this.readFlash(TEEVOLUTION_FLASH.reportRate, 2))[0] ?? 1);
|
|
242
|
+
if (confirmed !== pollingRateHz)
|
|
243
|
+
throw new Error(`The mouse kept ${confirmed} Hz instead of ${pollingRateHz} Hz.`);
|
|
244
|
+
return confirmed;
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
async setDpi(dpi) {
|
|
248
|
+
const info = this.deviceInfo ?? await this.readDeviceInfo();
|
|
249
|
+
if (!teevolutionDpiOptions(info.profile).includes(dpi)) {
|
|
250
|
+
throw new Error(`${dpi} DPI is not supported by the ${info.profile.name}.`);
|
|
251
|
+
}
|
|
252
|
+
return await this.withDeviceControl(async () => {
|
|
253
|
+
const stageCount = this.decodeDpiStageCount((await this.readFlash(TEEVOLUTION_FLASH.maxDpiStage, 2))[0], info.profile);
|
|
254
|
+
const currentDpi = Math.min((await this.readFlash(TEEVOLUTION_FLASH.currentDpi, 2))[0] ?? 0, stageCount - 1);
|
|
255
|
+
return await this.writeDpiStageValue(currentDpi, dpi);
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
/** Selects the active DPI stage index (0-based), matching Teevolink Set_MS_CurrentDPI. */
|
|
259
|
+
async setActiveDpiStage(stage) {
|
|
260
|
+
const info = this.deviceInfo ?? await this.readDeviceInfo();
|
|
261
|
+
if (!Number.isInteger(stage) || stage < 0 || stage >= info.profile.dpiStageCount) {
|
|
262
|
+
throw new Error(`DPI stage must be between 1 and ${info.profile.dpiStageCount}.`);
|
|
263
|
+
}
|
|
264
|
+
return await this.withDeviceControl(async () => {
|
|
265
|
+
const stageCount = this.decodeDpiStageCount((await this.readFlash(TEEVOLUTION_FLASH.maxDpiStage, 2))[0], info.profile);
|
|
266
|
+
if (stage >= stageCount) {
|
|
267
|
+
await this.writeCheckedByte(TEEVOLUTION_FLASH.maxDpiStage, stage + 1);
|
|
268
|
+
const enabled = this.decodeDpiStageCount((await this.readFlash(TEEVOLUTION_FLASH.maxDpiStage, 2))[0], info.profile);
|
|
269
|
+
if (enabled <= stage) {
|
|
270
|
+
throw new Error(`The mouse kept ${enabled} DPI stages; stage ${stage + 1} is unavailable.`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
await this.writeCheckedByte(TEEVOLUTION_FLASH.currentDpi, stage);
|
|
274
|
+
const confirmed = (await this.readFlash(TEEVOLUTION_FLASH.currentDpi, 2))[0] ?? 0;
|
|
275
|
+
if (confirmed !== stage)
|
|
276
|
+
throw new Error(`The mouse kept DPI stage ${confirmed + 1}.`);
|
|
277
|
+
return confirmed;
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
/** Writes one stage's DPI value without changing the active stage index. */
|
|
281
|
+
async setDpiStageValue(stage, dpi) {
|
|
282
|
+
const info = this.deviceInfo ?? await this.readDeviceInfo();
|
|
283
|
+
if (!teevolutionDpiOptions(info.profile).includes(dpi)) {
|
|
284
|
+
throw new Error(`${dpi} DPI is not supported by the ${info.profile.name}.`);
|
|
285
|
+
}
|
|
286
|
+
if (!Number.isInteger(stage) || stage < 0 || stage >= info.profile.dpiStageCount) {
|
|
287
|
+
throw new Error(`DPI stage must be between 1 and ${info.profile.dpiStageCount}.`);
|
|
288
|
+
}
|
|
289
|
+
return await this.withDeviceControl(async () => {
|
|
290
|
+
const stageCount = this.decodeDpiStageCount((await this.readFlash(TEEVOLUTION_FLASH.maxDpiStage, 2))[0], info.profile);
|
|
291
|
+
// A staged count increase may not have been flashed yet; enable the slot
|
|
292
|
+
// before writing it so the UI can edit newly added stages immediately.
|
|
293
|
+
if (stage >= stageCount) {
|
|
294
|
+
await this.writeCheckedByte(TEEVOLUTION_FLASH.maxDpiStage, stage + 1);
|
|
295
|
+
const enabled = this.decodeDpiStageCount((await this.readFlash(TEEVOLUTION_FLASH.maxDpiStage, 2))[0], info.profile);
|
|
296
|
+
if (enabled <= stage) {
|
|
297
|
+
throw new Error(`The mouse kept ${enabled} DPI stages; stage ${stage + 1} is unavailable.`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return await this.writeDpiStageValue(stage, dpi);
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
/** Sets how many DPI stages are enabled (1…dpiStageCount), matching Teevolink Set_MS_MaxDPI. */
|
|
304
|
+
async setDpiStageCount(count) {
|
|
305
|
+
const info = this.deviceInfo ?? await this.readDeviceInfo();
|
|
306
|
+
const max = info.profile.dpiStageCount;
|
|
307
|
+
if (!Number.isInteger(count) || count < 1 || count > max) {
|
|
308
|
+
throw new Error(`This Teevolution model supports 1–${max} DPI stages.`);
|
|
309
|
+
}
|
|
310
|
+
return await this.withDeviceControl(async () => {
|
|
311
|
+
await this.writeCheckedByte(TEEVOLUTION_FLASH.maxDpiStage, count);
|
|
312
|
+
const confirmed = this.decodeDpiStageCount((await this.readFlash(TEEVOLUTION_FLASH.maxDpiStage, 2))[0], info.profile);
|
|
313
|
+
if (confirmed !== count)
|
|
314
|
+
throw new Error(`The mouse kept ${confirmed} DPI stages instead of ${count}.`);
|
|
315
|
+
const active = (await this.readFlash(TEEVOLUTION_FLASH.currentDpi, 2))[0] ?? 0;
|
|
316
|
+
if (active >= confirmed) {
|
|
317
|
+
await this.writeCheckedByte(TEEVOLUTION_FLASH.currentDpi, confirmed - 1);
|
|
318
|
+
}
|
|
319
|
+
return confirmed;
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
async setLiftOffDistance(liftOffDistance) {
|
|
323
|
+
const profile = this.profile();
|
|
324
|
+
if (!profile.liftOffDistances.includes(liftOffDistance)) {
|
|
325
|
+
throw new Error(`${liftOffDistance} lift-off distance is not supported by the ${profile.name}.`);
|
|
326
|
+
}
|
|
327
|
+
const encoded = teevolutionEncodeLiftOff(liftOffDistance);
|
|
328
|
+
return await this.withDeviceControl(async () => {
|
|
329
|
+
await this.writeCheckedByte(TEEVOLUTION_FLASH.liftOffDistance, encoded);
|
|
330
|
+
const confirmed = teevolutionDecodeLiftOff((await this.readFlash(TEEVOLUTION_FLASH.liftOffDistance, 2))[0] ?? -1);
|
|
331
|
+
if (confirmed !== liftOffDistance)
|
|
332
|
+
throw new Error(`The mouse kept ${confirmed ?? "an unknown LOD"} instead of ${liftOffDistance}.`);
|
|
333
|
+
return confirmed;
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
async setMotionSync(enabled) {
|
|
337
|
+
return await this.setVerifiedBoolean(TEEVOLUTION_FLASH.motionSync, enabled, "Motion Sync");
|
|
338
|
+
}
|
|
339
|
+
async setAngleSnapping(enabled) {
|
|
340
|
+
return await this.setVerifiedBoolean(TEEVOLUTION_FLASH.angleSnapping, enabled, "angle snapping");
|
|
341
|
+
}
|
|
342
|
+
async setRippleControl(enabled) {
|
|
343
|
+
return await this.setVerifiedBoolean(TEEVOLUTION_FLASH.rippleControl, enabled, "ripple control");
|
|
344
|
+
}
|
|
345
|
+
getPerformanceDurationOptions() {
|
|
346
|
+
return [...this.profile().performanceTimeOptions];
|
|
347
|
+
}
|
|
348
|
+
async setSensorMode(mode) {
|
|
349
|
+
const info = this.deviceInfo ?? await this.readDeviceInfo();
|
|
350
|
+
if (mode === "Ultra" || !info.profile.sensorModes.includes(mode)) {
|
|
351
|
+
throw new Error(`${mode} sensor mode cannot be written on the ${info.profile.name}.`);
|
|
352
|
+
}
|
|
353
|
+
const pollingRateHz = teevolutionDecodePollingRate((await this.readFlash(TEEVOLUTION_FLASH.reportRate, 2))[0] ?? 1);
|
|
354
|
+
const ui = teevolutionSensorModeUi({
|
|
355
|
+
storedMode: teevolutionEncodeSensorMode(mode),
|
|
356
|
+
pollingRateHz,
|
|
357
|
+
connection: info.connection,
|
|
358
|
+
});
|
|
359
|
+
if (!ui.editable) {
|
|
360
|
+
throw new Error(`Sensor mode cannot be changed at ${pollingRateHz.toLocaleString()} Hz over ${info.connection.toLowerCase()}.`);
|
|
361
|
+
}
|
|
362
|
+
return await this.withDeviceControl(async () => {
|
|
363
|
+
const encoded = teevolutionEncodeSensorMode(mode);
|
|
364
|
+
await this.writeCheckedByte(TEEVOLUTION_FLASH.sensorMode, encoded);
|
|
365
|
+
const confirmed = teevolutionDecodeSensorModeStored((await this.readFlash(TEEVOLUTION_FLASH.sensorMode, 2))[0] ?? -1);
|
|
366
|
+
if (confirmed !== mode)
|
|
367
|
+
throw new Error(`The mouse kept ${confirmed} sensor mode instead of ${mode}.`);
|
|
368
|
+
return confirmed;
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
async setPerformanceDuration(duration) {
|
|
372
|
+
if (!this.profile().performanceTimeOptions.includes(duration)) {
|
|
373
|
+
throw new Error("Unsupported Teevolution highest-performance duration.");
|
|
374
|
+
}
|
|
375
|
+
return await this.setVerifiedByte(TEEVOLUTION_FLASH.performanceTime, duration, "highest-performance duration");
|
|
376
|
+
}
|
|
377
|
+
async setPerformanceMode(enabled) {
|
|
378
|
+
return await this.setVerifiedBoolean(TEEVOLUTION_FLASH.performanceState, enabled, "performance mode");
|
|
379
|
+
}
|
|
380
|
+
async setDpiLighting(mode, brightness, speed) {
|
|
381
|
+
const lighting = this.profile().dpiLighting;
|
|
382
|
+
if (!lighting.modes.includes(mode)) {
|
|
383
|
+
throw new Error("Unsupported Teevolution DPI light effect.");
|
|
384
|
+
}
|
|
385
|
+
if (brightness < lighting.brightness.min || brightness > lighting.brightness.max) {
|
|
386
|
+
throw new Error(`Teevolution DPI light brightness must be from ${lighting.brightness.min} to ${lighting.brightness.max}.`);
|
|
387
|
+
}
|
|
388
|
+
const encodedBrightness = teevolutionEncodeDpiLightBrightness(brightness);
|
|
389
|
+
if (!Number.isInteger(speed) || speed < lighting.speed.min || speed > lighting.speed.max) {
|
|
390
|
+
throw new Error(`Teevolution DPI light speed must be from ${lighting.speed.min} to ${lighting.speed.max}.`);
|
|
391
|
+
}
|
|
392
|
+
await this.withDeviceControl(async () => {
|
|
393
|
+
const current = await this.readFlash(TEEVOLUTION_FLASH.dpiLightMode, 8);
|
|
394
|
+
if (mode !== 0 && current[0] !== mode) {
|
|
395
|
+
await this.writeCheckedByte(TEEVOLUTION_FLASH.dpiLightMode, mode);
|
|
396
|
+
}
|
|
397
|
+
if (current[2] !== encodedBrightness) {
|
|
398
|
+
await this.writeCheckedByte(TEEVOLUTION_FLASH.dpiLightBrightness, encodedBrightness);
|
|
399
|
+
}
|
|
400
|
+
if (current[4] !== speed) {
|
|
401
|
+
await this.writeCheckedByte(TEEVOLUTION_FLASH.dpiLightSpeed, speed);
|
|
402
|
+
}
|
|
403
|
+
const state = mode === 0 ? 0 : 1;
|
|
404
|
+
if (current[6] !== state) {
|
|
405
|
+
await this.writeCheckedByte(TEEVOLUTION_FLASH.dpiLightState, state);
|
|
406
|
+
}
|
|
407
|
+
const confirmed = await this.readFlash(TEEVOLUTION_FLASH.dpiLightMode, 8);
|
|
408
|
+
const confirmedMode = teevolutionDecodeDpiLightMode(confirmed[0] ?? 1, confirmed[6] ?? 0);
|
|
409
|
+
const confirmedBrightness = teevolutionDecodeDpiLightBrightness(confirmed[2] ?? 0x80);
|
|
410
|
+
if (confirmedMode !== mode || confirmedBrightness !== brightness || confirmed[4] !== speed) {
|
|
411
|
+
throw new Error("The mouse did not confirm the requested DPI lighting settings.");
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
async setDebounceTime(debounceMs) {
|
|
416
|
+
const { min, max } = this.profile().debounce;
|
|
417
|
+
if (!Number.isInteger(debounceMs) || debounceMs < min || debounceMs > max) {
|
|
418
|
+
throw new Error(`This Teevolution model supports a debounce time from ${min} to ${max} ms.`);
|
|
419
|
+
}
|
|
420
|
+
return await this.setVerifiedByte(TEEVOLUTION_FLASH.debounceTime, debounceMs, "debounce time");
|
|
421
|
+
}
|
|
422
|
+
async setSleepTimeout(timeout) {
|
|
423
|
+
if (!this.profile().sleepOptions.includes(timeout)) {
|
|
424
|
+
throw new Error("Unsupported Teevolution sleep timeout.");
|
|
425
|
+
}
|
|
426
|
+
return await this.withDeviceControl(async () => {
|
|
427
|
+
await this.writeCheckedByte(TEEVOLUTION_FLASH.sleepTime, timeout);
|
|
428
|
+
const sleepConfirmed = (await this.readFlash(TEEVOLUTION_FLASH.sleepTime, 2))[0];
|
|
429
|
+
if (sleepConfirmed !== timeout) {
|
|
430
|
+
throw new Error("The mouse did not confirm the requested sleep timeout.");
|
|
431
|
+
}
|
|
432
|
+
return sleepConfirmed;
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
async close() {
|
|
436
|
+
this.device.removeEventListener("inputreport", this.onInputReport);
|
|
437
|
+
this.responseWaiter?.reject(new Error("The Teevolution device was closed."));
|
|
438
|
+
this.responseWaiter = null;
|
|
439
|
+
this.lcdClockSynced = false;
|
|
440
|
+
if (this.lcdDevice && this.lcdDevice !== this.device && this.lcdDevice.opened) {
|
|
441
|
+
await this.lcdDevice.close().catch(() => undefined);
|
|
442
|
+
}
|
|
443
|
+
this.lcdDevice = null;
|
|
444
|
+
if (this.device.opened)
|
|
445
|
+
await this.device.close();
|
|
446
|
+
}
|
|
447
|
+
displayName(info) {
|
|
448
|
+
return info.profile.name;
|
|
449
|
+
}
|
|
450
|
+
profile() {
|
|
451
|
+
if (!this.deviceInfo) {
|
|
452
|
+
throw new Error("Read the Teevolution device identity before requesting model capabilities.");
|
|
453
|
+
}
|
|
454
|
+
return this.deviceInfo.profile;
|
|
455
|
+
}
|
|
456
|
+
static isLcdClockInterface(device) {
|
|
457
|
+
return device.vendorId === VENDOR_ID.teevolution
|
|
458
|
+
&& TEEVOLUTION_PRODUCT_IDS.has(device.productId)
|
|
459
|
+
&& device.collections.some((collection) => collection.usagePage === TEEVOLUTION_LCD_USAGE_PAGE
|
|
460
|
+
&& collection.usage === TEEVOLUTION_LCD_USAGE
|
|
461
|
+
&& collection.outputReports.some((report) => report.reportId === TEEVOLUTION_LCD_REPORT_ID));
|
|
462
|
+
}
|
|
463
|
+
async findLcdClockDevice() {
|
|
464
|
+
if (TeevolutionHidClient.isLcdClockInterface(this.device))
|
|
465
|
+
return this.device;
|
|
466
|
+
const granted = typeof navigator !== "undefined" && navigator.hid
|
|
467
|
+
? await navigator.hid.getDevices()
|
|
468
|
+
: [];
|
|
469
|
+
return granted.find((candidate) => candidate !== this.device
|
|
470
|
+
&& candidate.vendorId === this.device.vendorId
|
|
471
|
+
&& candidate.productId === this.device.productId
|
|
472
|
+
&& TeevolutionHidClient.isLcdClockInterface(candidate)) ?? null;
|
|
473
|
+
}
|
|
474
|
+
decodeDpiStageCount(raw, profile) {
|
|
475
|
+
return Math.min(Math.max(raw ?? profile.dpiStageCount, 1), profile.dpiStageCount);
|
|
476
|
+
}
|
|
477
|
+
async writeDpiStageValue(stage, dpi) {
|
|
478
|
+
const address = TEEVOLUTION_FLASH.dpiValues + stage * 4;
|
|
479
|
+
await this.writeFlash(address, teevolutionEncodeDpi(dpi));
|
|
480
|
+
const confirmed = teevolutionDecodeDpi(await this.readFlash(address, 4));
|
|
481
|
+
if (confirmed !== dpi)
|
|
482
|
+
throw new Error(`The mouse kept ${confirmed} DPI instead of ${dpi} DPI.`);
|
|
483
|
+
return confirmed;
|
|
484
|
+
}
|
|
485
|
+
async withDeviceControl(operation) {
|
|
486
|
+
await this.setDeviceOnline(true);
|
|
487
|
+
try {
|
|
488
|
+
return await operation();
|
|
489
|
+
}
|
|
490
|
+
finally {
|
|
491
|
+
await this.setDeviceOnline(false).catch(() => undefined);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
async setDeviceOnline(enabled) {
|
|
495
|
+
let response = null;
|
|
496
|
+
for (let attempt = 0; attempt < 20; attempt += 1) {
|
|
497
|
+
response = await this.exchange(teevolutionBuildOnlinePayload(enabled));
|
|
498
|
+
this.assertAccepted(response, enabled ? "host-control entry" : "host-control exit");
|
|
499
|
+
if (response[9] !== 1)
|
|
500
|
+
break;
|
|
501
|
+
await new Promise((resolve) => window.setTimeout(resolve, 10));
|
|
502
|
+
}
|
|
503
|
+
if (!response || response[9] === 1)
|
|
504
|
+
throw new Error("The Teevolution receiver stayed busy.");
|
|
505
|
+
if (enabled && response[5] !== 1) {
|
|
506
|
+
throw new Error(TeevolutionHidClient.mouseOfflineMessage(this.usesRapidSyncDongle()));
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
usesRapidSyncDongle() {
|
|
510
|
+
if (this.device.productId === 0xf523)
|
|
511
|
+
return true;
|
|
512
|
+
if (this.lcdDevice || TeevolutionHidClient.isLcdClockInterface(this.device))
|
|
513
|
+
return true;
|
|
514
|
+
return this.deviceInfo?.connection === "Wireless"
|
|
515
|
+
&& this.deviceInfo.maximumPollingRateHz === 8000;
|
|
516
|
+
}
|
|
517
|
+
async readFlash(address, length) {
|
|
518
|
+
const result = new Uint8Array(length);
|
|
519
|
+
for (let offset = 0; offset < length; offset += 10) {
|
|
520
|
+
const count = Math.min(10, length - offset);
|
|
521
|
+
const response = await this.exchange(teevolutionBuildReadPayload(address + offset, count));
|
|
522
|
+
const chunk = teevolutionParseReadResponse(response, address + offset, count);
|
|
523
|
+
if (!chunk) {
|
|
524
|
+
this.assertAccepted(response, "configuration read");
|
|
525
|
+
throw new Error("The Teevolution configuration read response was corrupt.");
|
|
526
|
+
}
|
|
527
|
+
result.set(chunk, offset);
|
|
528
|
+
}
|
|
529
|
+
return result;
|
|
530
|
+
}
|
|
531
|
+
async writeCheckedByte(address, value) {
|
|
532
|
+
await this.writeFlash(address, new Uint8Array([value, (0x55 - value) & 0xff]));
|
|
533
|
+
}
|
|
534
|
+
async setVerifiedByte(address, value, label) {
|
|
535
|
+
return await this.withDeviceControl(async () => {
|
|
536
|
+
await this.writeCheckedByte(address, value);
|
|
537
|
+
const confirmed = (await this.readFlash(address, 2))[0];
|
|
538
|
+
if (confirmed !== value)
|
|
539
|
+
throw new Error(`The mouse did not confirm the requested ${label}.`);
|
|
540
|
+
return confirmed;
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
async setVerifiedBoolean(address, enabled, label) {
|
|
544
|
+
return (await this.setVerifiedByte(address, enabled ? 1 : 0, label)) === 1;
|
|
545
|
+
}
|
|
546
|
+
async writeFlash(address, data) {
|
|
547
|
+
for (let offset = 0; offset < data.length; offset += 10) {
|
|
548
|
+
const chunk = [...data.slice(offset, offset + 10)];
|
|
549
|
+
this.assertAccepted(await this.exchange(teevolutionBuildWritePayload(address + offset, chunk)), "configuration write");
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
async query(command, parameters = new Uint8Array()) {
|
|
553
|
+
if (parameters.length > 10)
|
|
554
|
+
throw new Error("Teevolution queries support at most 10 parameter bytes.");
|
|
555
|
+
const packet = teevolutionBuildSimplePayload(command);
|
|
556
|
+
packet[4] = parameters.length;
|
|
557
|
+
packet.set(parameters, 5);
|
|
558
|
+
packet[15] = teevolutionPacketChecksum(packet);
|
|
559
|
+
return await this.exchange(packet);
|
|
560
|
+
}
|
|
561
|
+
async exchange(packet) {
|
|
562
|
+
if (this.responseWaiter)
|
|
563
|
+
throw new Error("Another Teevolution request is already in progress.");
|
|
564
|
+
const command = packet[0];
|
|
565
|
+
let timeout = 0;
|
|
566
|
+
let rejectResponse = null;
|
|
567
|
+
const response = new Promise((resolve, reject) => {
|
|
568
|
+
rejectResponse = reject;
|
|
569
|
+
timeout = window.setTimeout(() => {
|
|
570
|
+
this.responseWaiter = null;
|
|
571
|
+
reject(new Error(`The Teevolution mouse did not answer command 0x${command.toString(16).padStart(2, "0")}.`));
|
|
572
|
+
}, 1200);
|
|
573
|
+
this.responseWaiter = {
|
|
574
|
+
command,
|
|
575
|
+
resolve: (bytes) => {
|
|
576
|
+
window.clearTimeout(timeout);
|
|
577
|
+
resolve(bytes);
|
|
578
|
+
},
|
|
579
|
+
reject: (reason) => {
|
|
580
|
+
window.clearTimeout(timeout);
|
|
581
|
+
reject(reason);
|
|
582
|
+
},
|
|
583
|
+
};
|
|
584
|
+
});
|
|
585
|
+
void response.catch(() => undefined);
|
|
586
|
+
try {
|
|
587
|
+
await this.device.sendReport(TEEVOLUTION_REPORT_ID, new Uint8Array(packet));
|
|
588
|
+
}
|
|
589
|
+
catch (error) {
|
|
590
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
591
|
+
rejectResponse?.(new Error(`Chrome could not write Teevolution report 8. ${detail}`));
|
|
592
|
+
this.responseWaiter = null;
|
|
593
|
+
}
|
|
594
|
+
return await response;
|
|
595
|
+
}
|
|
596
|
+
decodeVersionOptional(label, response) {
|
|
597
|
+
if (!response || response[1] !== 0)
|
|
598
|
+
return null;
|
|
599
|
+
this.assertAccepted(response, `${label.toLowerCase()} firmware read`);
|
|
600
|
+
return teevolutionDecodeFirmwareVersion(label, response);
|
|
601
|
+
}
|
|
602
|
+
assertAccepted(response, operation) {
|
|
603
|
+
if (response[1] !== 0)
|
|
604
|
+
throw new Error(`The Teevolution receiver rejected the ${operation} (status ${response[1]}).`);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
//# sourceMappingURL=hid.js.map
|