@benev/tact 0.4.0-0 → 0.4.0-10

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.
Files changed (518) hide show
  1. package/README.md +173 -61
  2. package/package.json +9 -7
  3. package/s/demo/main.bundle.ts +18 -3
  4. package/s/demo/main.css +41 -5
  5. package/s/demo/presets.ts +54 -0
  6. package/s/gamepad/gamepad-app/element.ts +11 -4
  7. package/s/gamepad/gamepad-app/style.css.ts +5 -1
  8. package/s/gamepad/index.html.ts +1 -1
  9. package/s/gamepad/main.css +10 -1
  10. package/s/index.html.ts +28 -15
  11. package/s/lib/index.ts +15 -4
  12. package/s/lib/input/{encoder.ts → controller.ts} +26 -15
  13. package/s/lib/input/data/endian.ts +3 -0
  14. package/s/lib/input/data/{decode.ts → intent/decode.ts} +6 -5
  15. package/s/lib/input/data/intent/encode.ts +25 -0
  16. package/s/lib/input/data/intent/minihash.ts +5 -0
  17. package/s/{_archive/lib3/input/data/params.ts → lib/input/data/intent/sizes.ts} +1 -2
  18. package/s/lib/input/data/intent/types.ts +6 -0
  19. package/s/lib/input/data/parcel/decode.ts +32 -0
  20. package/s/lib/input/data/parcel/encode.ts +30 -0
  21. package/s/lib/input/data/parcel/sizes.ts +5 -0
  22. package/s/lib/input/data/parcel/types.ts +8 -0
  23. package/s/lib/input/data/test.ts +23 -0
  24. package/s/lib/input/decoder.ts +18 -12
  25. package/s/lib/input/evaluate/context.ts +6 -3
  26. package/s/lib/input/evaluate/evaluate.ts +71 -28
  27. package/s/lib/input/expression.ts +5 -5
  28. package/s/lib/input/investigate/hash-bindings.ts +5 -3
  29. package/s/lib/input/investigate/investigate.ts +24 -9
  30. package/s/lib/input/investigate/is-expression.ts +1 -0
  31. package/s/lib/input/investigate/make-input.ts +1 -5
  32. package/s/lib/input/sources/gamepad.ts +3 -9
  33. package/s/lib/input/sources/pointer.ts +0 -18
  34. package/s/lib/input/test.ts +216 -0
  35. package/s/lib/input/testing/quickbind.ts +7 -6
  36. package/s/lib/input/types.ts +3 -7
  37. package/s/lib/input/utils/mouse-button.ts +1 -6
  38. package/s/lib/test.ts +3 -177
  39. package/s/lib/ui/deck/auto-gamepads.ts +30 -0
  40. package/s/lib/ui/deck/controls/controls.ts +76 -0
  41. package/s/lib/ui/deck/controls/internal/assignments.ts +24 -0
  42. package/s/lib/ui/deck/controls/internal/data.ts +53 -0
  43. package/s/lib/ui/deck/controls/internal/fns.ts +38 -0
  44. package/s/lib/ui/deck/controls/internal/profiles.ts +83 -0
  45. package/s/lib/ui/deck/controls/types.ts +23 -0
  46. package/s/lib/ui/deck/hub.ts +109 -0
  47. package/s/lib/ui/deck/players.ts +73 -0
  48. package/s/lib/ui/deck/setup/deck.ts +44 -0
  49. package/s/lib/ui/deck/setup/tact.ts +101 -0
  50. package/s/lib/ui/deck/setup/types.ts +13 -0
  51. package/s/lib/ui/deck/setup/utils/broadcast-channel.ts +17 -0
  52. package/s/lib/ui/deck/setup/utils/kv.ts +20 -0
  53. package/s/lib/ui/deck/types.ts +26 -0
  54. package/s/lib/ui/deck/utils/first-preset.ts +9 -0
  55. package/s/lib/ui/icons/akar/LICENSE +23 -0
  56. package/s/lib/ui/icons/akar/backspace.svg.ts +4 -0
  57. package/s/lib/ui/icons/akar/circle-plus.svg.ts +4 -0
  58. package/s/lib/ui/icons/akar/copy.svg.ts +4 -0
  59. package/s/lib/ui/icons/akar/cross.svg.ts +4 -0
  60. package/s/lib/ui/icons/akar/devices.svg.ts +4 -0
  61. package/s/lib/ui/icons/akar/drag-vertical-fill.svg.ts +4 -0
  62. package/s/lib/ui/icons/akar/game-controller.svg.ts +4 -0
  63. package/s/lib/ui/icons/akar/key-cap.svg.ts +4 -0
  64. package/s/lib/ui/icons/akar/people-group.svg.ts +4 -0
  65. package/s/lib/ui/icons/akar/person-add.svg.ts +4 -0
  66. package/s/lib/ui/icons/akar/settings-horizontal.svg.ts +4 -0
  67. package/s/lib/ui/icons/akar/trash-can.svg.ts +4 -0
  68. package/s/lib/ui/icons/akar/x-small.svg.ts +4 -0
  69. package/s/lib/ui/views/controllers/style.css.ts +158 -0
  70. package/s/lib/ui/views/controllers/subviews/controller.ts +53 -0
  71. package/s/lib/ui/views/controllers/subviews/dropcard.ts +31 -0
  72. package/s/lib/ui/views/controllers/subviews/player.ts +38 -0
  73. package/s/lib/ui/views/controllers/view.ts +73 -0
  74. package/s/lib/ui/views/customize/parts/capture-gamepad-chord.ts +59 -0
  75. package/s/lib/ui/views/customize/parts/capture-key-chord.ts +70 -0
  76. package/s/lib/ui/views/customize/parts/capture-pointer-chord.ts +55 -0
  77. package/s/lib/ui/views/customize/parts/render-bindings.ts +67 -0
  78. package/s/lib/ui/views/customize/style.css.ts +144 -0
  79. package/s/lib/ui/views/customize/subviews/expression.ts +88 -0
  80. package/s/lib/ui/views/customize/subviews/recorder.ts +76 -0
  81. package/s/lib/ui/views/customize/view.ts +105 -0
  82. package/s/lib/ui/views/deck/style.css.ts +69 -0
  83. package/s/lib/ui/views/deck/types.ts +15 -0
  84. package/s/lib/ui/views/deck/view.ts +55 -0
  85. package/s/lib/ui/views/profile-select/view.ts +44 -0
  86. package/s/lib/ui/views/theme.css.ts +115 -0
  87. package/s/lib/ui/views/visualizer/style.css.ts +25 -0
  88. package/s/lib/ui/views/visualizer/view.ts +17 -0
  89. package/s/lib/ui/views/visualizer/visualizer.ts +17 -0
  90. package/s/lib/utils/ellipsis.ts +7 -0
  91. package/s/lib/utils/hash.ts +47 -0
  92. package/s/lib/utils/hueify.ts +5 -0
  93. package/x/demo/main.bundle.js +16 -3
  94. package/x/demo/main.bundle.js.map +1 -1
  95. package/x/demo/main.bundle.min.js +814 -12
  96. package/x/demo/main.bundle.min.js.map +4 -4
  97. package/x/demo/main.css +41 -5
  98. package/x/demo/presets.d.ts +30 -0
  99. package/x/demo/presets.js +51 -0
  100. package/x/demo/presets.js.map +1 -0
  101. package/x/gamepad/gamepad-app/element.js +9 -4
  102. package/x/gamepad/gamepad-app/element.js.map +1 -1
  103. package/x/gamepad/gamepad-app/style.css.js +5 -1
  104. package/x/gamepad/gamepad-app/style.css.js.map +1 -1
  105. package/x/gamepad/index.html +4 -4
  106. package/x/gamepad/index.html.js +1 -1
  107. package/x/gamepad/main.bundle.min.js +25 -21
  108. package/x/gamepad/main.bundle.min.js.map +4 -4
  109. package/x/gamepad/main.css +10 -1
  110. package/x/index.html +30 -17
  111. package/x/index.html.js +28 -15
  112. package/x/index.html.js.map +1 -1
  113. package/x/lib/index.d.ts +14 -1
  114. package/x/lib/index.js +14 -1
  115. package/x/lib/index.js.map +1 -1
  116. package/x/lib/input/controller.d.ts +15 -0
  117. package/x/lib/input/{encoder.js → controller.js} +19 -13
  118. package/x/lib/input/controller.js.map +1 -0
  119. package/x/lib/input/data/endian.d.ts +1 -0
  120. package/x/lib/input/data/endian.js +2 -0
  121. package/x/lib/input/data/endian.js.map +1 -0
  122. package/x/lib/input/data/intent/decode.d.ts +5 -0
  123. package/x/lib/input/data/{decode.js → intent/decode.js} +5 -4
  124. package/x/lib/input/data/intent/decode.js.map +1 -0
  125. package/x/lib/input/data/intent/encode.d.ts +2 -0
  126. package/x/lib/input/data/intent/encode.js +18 -0
  127. package/x/lib/input/data/intent/encode.js.map +1 -0
  128. package/x/lib/input/data/intent/minihash.d.ts +1 -0
  129. package/x/lib/input/data/intent/minihash.js +4 -0
  130. package/x/lib/input/data/intent/minihash.js.map +1 -0
  131. package/x/lib/input/data/{params.d.ts → intent/sizes.d.ts} +1 -2
  132. package/x/lib/input/data/intent/sizes.js +5 -0
  133. package/x/lib/input/data/intent/sizes.js.map +1 -0
  134. package/x/lib/input/data/intent/types.d.ts +4 -0
  135. package/x/lib/input/data/intent/types.js +2 -0
  136. package/x/lib/input/data/intent/types.js.map +1 -0
  137. package/x/lib/input/data/parcel/decode.d.ts +2 -0
  138. package/x/lib/input/data/parcel/decode.js +22 -0
  139. package/x/lib/input/data/parcel/decode.js.map +1 -0
  140. package/x/lib/input/data/parcel/encode.d.ts +2 -0
  141. package/x/lib/input/data/parcel/encode.js +19 -0
  142. package/x/lib/input/data/parcel/encode.js.map +1 -0
  143. package/x/lib/input/data/parcel/sizes.d.ts +3 -0
  144. package/x/lib/input/data/parcel/sizes.js +4 -0
  145. package/x/lib/input/data/parcel/sizes.js.map +1 -0
  146. package/x/lib/input/data/parcel/types.d.ts +5 -0
  147. package/x/lib/input/data/parcel/types.js +2 -0
  148. package/x/lib/input/data/parcel/types.js.map +1 -0
  149. package/x/lib/input/data/test.d.ts +6 -0
  150. package/x/lib/input/data/test.js +19 -0
  151. package/x/lib/input/data/test.js.map +1 -0
  152. package/x/lib/input/decoder.d.ts +3 -3
  153. package/x/lib/input/decoder.js +14 -12
  154. package/x/lib/input/decoder.js.map +1 -1
  155. package/x/lib/input/evaluate/context.d.ts +5 -4
  156. package/x/lib/input/evaluate/context.js +2 -3
  157. package/x/lib/input/evaluate/context.js.map +1 -1
  158. package/x/lib/input/evaluate/evaluate.d.ts +1 -1
  159. package/x/lib/input/evaluate/evaluate.js +65 -24
  160. package/x/lib/input/evaluate/evaluate.js.map +1 -1
  161. package/x/lib/input/expression.d.ts +1 -1
  162. package/x/lib/input/investigate/hash-bindings.d.ts +1 -1
  163. package/x/lib/input/investigate/hash-bindings.js +5 -3
  164. package/x/lib/input/investigate/hash-bindings.js.map +1 -1
  165. package/x/lib/input/investigate/investigate.d.ts +2 -1
  166. package/x/lib/input/investigate/investigate.js +14 -9
  167. package/x/lib/input/investigate/investigate.js.map +1 -1
  168. package/x/lib/input/investigate/is-expression.js +2 -0
  169. package/x/lib/input/investigate/is-expression.js.map +1 -1
  170. package/x/lib/input/investigate/make-input.js +1 -5
  171. package/x/lib/input/investigate/make-input.js.map +1 -1
  172. package/x/lib/input/sources/gamepad.js +3 -9
  173. package/x/lib/input/sources/gamepad.js.map +1 -1
  174. package/x/lib/input/sources/pointer.js +0 -21
  175. package/x/lib/input/sources/pointer.js.map +1 -1
  176. package/x/lib/input/test.d.ts +20 -0
  177. package/x/lib/input/test.js +170 -0
  178. package/x/lib/input/test.js.map +1 -0
  179. package/x/lib/input/testing/quickbind.d.ts +6 -4
  180. package/x/lib/input/testing/quickbind.js +7 -6
  181. package/x/lib/input/testing/quickbind.js.map +1 -1
  182. package/x/lib/input/types.d.ts +3 -8
  183. package/x/lib/input/types.js.map +1 -1
  184. package/x/lib/input/utils/mouse-button.js +1 -6
  185. package/x/lib/input/utils/mouse-button.js.map +1 -1
  186. package/x/lib/test.js +3 -133
  187. package/x/lib/test.js.map +1 -1
  188. package/x/lib/ui/deck/auto-gamepads.d.ts +4 -0
  189. package/x/lib/ui/deck/auto-gamepads.js +20 -0
  190. package/x/lib/ui/deck/auto-gamepads.js.map +1 -0
  191. package/x/lib/ui/deck/controls/controls.d.ts +19 -0
  192. package/x/lib/ui/deck/controls/controls.js +56 -0
  193. package/x/lib/ui/deck/controls/controls.js.map +1 -0
  194. package/x/lib/ui/deck/controls/internal/assignments.d.ts +9 -0
  195. package/x/lib/ui/deck/controls/internal/assignments.js +16 -0
  196. package/x/lib/ui/deck/controls/internal/assignments.js.map +1 -0
  197. package/x/lib/ui/deck/controls/internal/data.d.ts +29 -0
  198. package/x/lib/ui/deck/controls/internal/data.js +32 -0
  199. package/x/lib/ui/deck/controls/internal/data.js.map +1 -0
  200. package/x/lib/ui/deck/controls/internal/fns.d.ts +6 -0
  201. package/x/lib/ui/deck/controls/internal/fns.js +19 -0
  202. package/x/lib/ui/deck/controls/internal/fns.js.map +1 -0
  203. package/x/lib/ui/deck/controls/internal/profiles.d.ts +18 -0
  204. package/x/lib/ui/deck/controls/internal/profiles.js +59 -0
  205. package/x/lib/ui/deck/controls/internal/profiles.js.map +1 -0
  206. package/x/lib/ui/deck/controls/types.d.ts +17 -0
  207. package/x/lib/ui/deck/controls/types.js +2 -0
  208. package/x/lib/ui/deck/controls/types.js.map +1 -0
  209. package/x/lib/ui/deck/hub.d.ts +21 -0
  210. package/x/lib/ui/deck/hub.js +86 -0
  211. package/x/lib/ui/deck/hub.js.map +1 -0
  212. package/x/lib/ui/deck/players.d.ts +16 -0
  213. package/x/lib/ui/deck/players.js +56 -0
  214. package/x/lib/ui/deck/players.js.map +1 -0
  215. package/x/lib/ui/deck/setup/deck.d.ts +3 -0
  216. package/x/lib/ui/deck/setup/deck.js +30 -0
  217. package/x/lib/ui/deck/setup/deck.js.map +1 -0
  218. package/x/lib/ui/deck/setup/tact.d.ts +20 -0
  219. package/x/lib/ui/deck/setup/tact.js +78 -0
  220. package/x/lib/ui/deck/setup/tact.js.map +1 -0
  221. package/x/lib/ui/deck/setup/types.d.ts +10 -0
  222. package/x/lib/ui/deck/setup/types.js +2 -0
  223. package/x/lib/ui/deck/setup/types.js.map +1 -0
  224. package/x/lib/ui/deck/setup/utils/broadcast-channel.d.ts +4 -0
  225. package/x/lib/ui/deck/setup/utils/broadcast-channel.js +10 -0
  226. package/x/lib/ui/deck/setup/utils/broadcast-channel.js.map +1 -0
  227. package/x/lib/ui/deck/setup/utils/kv.d.ts +5 -0
  228. package/x/lib/ui/deck/setup/utils/kv.js +12 -0
  229. package/x/lib/ui/deck/setup/utils/kv.js.map +1 -0
  230. package/x/lib/ui/deck/types.d.ts +19 -0
  231. package/x/lib/ui/deck/types.js +3 -0
  232. package/x/lib/ui/deck/types.js.map +1 -0
  233. package/x/lib/ui/deck/utils/first-preset.d.ts +6 -0
  234. package/x/lib/ui/deck/utils/first-preset.js +5 -0
  235. package/x/lib/ui/deck/utils/first-preset.js.map +1 -0
  236. package/x/lib/ui/icons/akar/backspace.svg.d.ts +2 -0
  237. package/x/lib/ui/icons/akar/backspace.svg.js +3 -0
  238. package/x/lib/ui/icons/akar/backspace.svg.js.map +1 -0
  239. package/x/lib/ui/icons/akar/circle-plus.svg.d.ts +2 -0
  240. package/x/lib/ui/icons/akar/circle-plus.svg.js +3 -0
  241. package/x/lib/ui/icons/akar/circle-plus.svg.js.map +1 -0
  242. package/x/lib/ui/icons/akar/copy.svg.d.ts +2 -0
  243. package/x/lib/ui/icons/akar/copy.svg.js +3 -0
  244. package/x/lib/ui/icons/akar/copy.svg.js.map +1 -0
  245. package/x/lib/ui/icons/akar/cross.svg.d.ts +2 -0
  246. package/x/lib/ui/icons/akar/cross.svg.js +3 -0
  247. package/x/lib/ui/icons/akar/cross.svg.js.map +1 -0
  248. package/x/lib/ui/icons/akar/devices.svg.d.ts +2 -0
  249. package/x/lib/ui/icons/akar/devices.svg.js +3 -0
  250. package/x/lib/ui/icons/akar/devices.svg.js.map +1 -0
  251. package/x/lib/ui/icons/akar/drag-vertical-fill.svg.d.ts +2 -0
  252. package/x/lib/ui/icons/akar/drag-vertical-fill.svg.js +3 -0
  253. package/x/lib/ui/icons/akar/drag-vertical-fill.svg.js.map +1 -0
  254. package/x/lib/ui/icons/akar/game-controller.svg.d.ts +2 -0
  255. package/x/lib/ui/icons/akar/game-controller.svg.js +3 -0
  256. package/x/lib/ui/icons/akar/game-controller.svg.js.map +1 -0
  257. package/x/lib/ui/icons/akar/key-cap.svg.d.ts +2 -0
  258. package/x/lib/ui/icons/akar/key-cap.svg.js +3 -0
  259. package/x/lib/ui/icons/akar/key-cap.svg.js.map +1 -0
  260. package/x/lib/ui/icons/akar/people-group.svg.d.ts +2 -0
  261. package/x/lib/ui/icons/akar/people-group.svg.js +3 -0
  262. package/x/lib/ui/icons/akar/people-group.svg.js.map +1 -0
  263. package/x/lib/ui/icons/akar/person-add.svg.d.ts +2 -0
  264. package/x/lib/ui/icons/akar/person-add.svg.js +3 -0
  265. package/x/lib/ui/icons/akar/person-add.svg.js.map +1 -0
  266. package/x/lib/ui/icons/akar/settings-horizontal.svg.d.ts +2 -0
  267. package/x/lib/ui/icons/akar/settings-horizontal.svg.js +3 -0
  268. package/x/lib/ui/icons/akar/settings-horizontal.svg.js.map +1 -0
  269. package/x/lib/ui/icons/akar/trash-can.svg.d.ts +2 -0
  270. package/x/lib/ui/icons/akar/trash-can.svg.js +3 -0
  271. package/x/lib/ui/icons/akar/trash-can.svg.js.map +1 -0
  272. package/x/lib/ui/icons/akar/x-small.svg.d.ts +2 -0
  273. package/x/lib/ui/icons/akar/x-small.svg.js +3 -0
  274. package/x/lib/ui/icons/akar/x-small.svg.js.map +1 -0
  275. package/x/lib/ui/views/controllers/style.css.js +157 -0
  276. package/x/lib/ui/views/controllers/style.css.js.map +1 -0
  277. package/x/lib/ui/views/controllers/subviews/controller.d.ts +3 -0
  278. package/x/lib/ui/views/controllers/subviews/controller.js +45 -0
  279. package/x/lib/ui/views/controllers/subviews/controller.js.map +1 -0
  280. package/x/lib/ui/views/controllers/subviews/dropcard.d.ts +9 -0
  281. package/x/lib/ui/views/controllers/subviews/dropcard.js +20 -0
  282. package/x/lib/ui/views/controllers/subviews/dropcard.js.map +1 -0
  283. package/x/lib/ui/views/controllers/subviews/player.d.ts +2 -0
  284. package/x/lib/ui/views/controllers/subviews/player.js +32 -0
  285. package/x/lib/ui/views/controllers/subviews/player.js.map +1 -0
  286. package/x/lib/ui/views/controllers/view.d.ts +2 -0
  287. package/x/lib/ui/views/controllers/view.js +65 -0
  288. package/x/lib/ui/views/controllers/view.js.map +1 -0
  289. package/x/lib/ui/views/customize/parts/capture-gamepad-chord.d.ts +2 -0
  290. package/x/lib/ui/views/customize/parts/capture-gamepad-chord.js +46 -0
  291. package/x/lib/ui/views/customize/parts/capture-gamepad-chord.js.map +1 -0
  292. package/x/lib/ui/views/customize/parts/capture-key-chord.d.ts +2 -0
  293. package/x/lib/ui/views/customize/parts/capture-key-chord.js +58 -0
  294. package/x/lib/ui/views/customize/parts/capture-key-chord.js.map +1 -0
  295. package/x/lib/ui/views/customize/parts/capture-pointer-chord.d.ts +2 -0
  296. package/x/lib/ui/views/customize/parts/capture-pointer-chord.js +42 -0
  297. package/x/lib/ui/views/customize/parts/capture-pointer-chord.js.map +1 -0
  298. package/x/lib/ui/views/customize/parts/render-bindings.d.ts +3 -0
  299. package/x/lib/ui/views/customize/parts/render-bindings.js +32 -0
  300. package/x/lib/ui/views/customize/parts/render-bindings.js.map +1 -0
  301. package/x/lib/ui/views/customize/style.css.d.ts +2 -0
  302. package/x/lib/ui/views/customize/style.css.js +143 -0
  303. package/x/lib/ui/views/customize/style.css.js.map +1 -0
  304. package/x/lib/ui/views/customize/subviews/expression.d.ts +2 -0
  305. package/x/lib/ui/views/customize/subviews/expression.js +75 -0
  306. package/x/lib/ui/views/customize/subviews/expression.js.map +1 -0
  307. package/x/lib/ui/views/customize/subviews/recorder.d.ts +3 -0
  308. package/x/lib/ui/views/customize/subviews/recorder.js +60 -0
  309. package/x/lib/ui/views/customize/subviews/recorder.js.map +1 -0
  310. package/x/lib/ui/views/customize/view.d.ts +6 -0
  311. package/x/lib/ui/views/customize/view.js +83 -0
  312. package/x/lib/ui/views/customize/view.js.map +1 -0
  313. package/x/lib/ui/views/deck/style.css.d.ts +2 -0
  314. package/x/lib/ui/views/deck/style.css.js +68 -0
  315. package/x/lib/ui/views/deck/style.css.js.map +1 -0
  316. package/x/lib/ui/views/deck/types.d.ts +14 -0
  317. package/x/lib/ui/views/deck/types.js +2 -0
  318. package/x/lib/ui/views/deck/types.js.map +1 -0
  319. package/x/lib/ui/views/deck/view.d.ts +2 -0
  320. package/x/lib/ui/views/deck/view.js +48 -0
  321. package/x/lib/ui/views/deck/view.js.map +1 -0
  322. package/x/lib/ui/views/profile-select/view.d.ts +4 -0
  323. package/x/lib/ui/views/profile-select/view.js +34 -0
  324. package/x/lib/ui/views/profile-select/view.js.map +1 -0
  325. package/x/lib/ui/views/theme.css.d.ts +2 -0
  326. package/x/lib/ui/views/theme.css.js +113 -0
  327. package/x/lib/ui/views/theme.css.js.map +1 -0
  328. package/x/lib/ui/views/visualizer/style.css.d.ts +2 -0
  329. package/x/lib/ui/views/visualizer/style.css.js +24 -0
  330. package/x/lib/ui/views/visualizer/style.css.js.map +1 -0
  331. package/x/lib/ui/views/visualizer/view.d.ts +2 -0
  332. package/x/lib/ui/views/visualizer/view.js +12 -0
  333. package/x/lib/ui/views/visualizer/view.js.map +1 -0
  334. package/x/lib/ui/views/visualizer/visualizer.d.ts +5 -0
  335. package/x/lib/ui/views/visualizer/visualizer.js +13 -0
  336. package/x/lib/ui/views/visualizer/visualizer.js.map +1 -0
  337. package/x/lib/utils/ellipsis.d.ts +1 -0
  338. package/x/lib/utils/ellipsis.js +6 -0
  339. package/x/lib/utils/ellipsis.js.map +1 -0
  340. package/x/lib/utils/hash.d.ts +1 -0
  341. package/x/lib/utils/hash.js +47 -0
  342. package/x/lib/utils/hash.js.map +1 -0
  343. package/x/lib/utils/hueify.d.ts +1 -0
  344. package/x/lib/utils/hueify.js +4 -0
  345. package/x/lib/utils/hueify.js.map +1 -0
  346. package/x/lib/utils/make-id.d.ts +1 -0
  347. package/x/lib/utils/make-id.js +5 -0
  348. package/x/lib/utils/make-id.js.map +1 -0
  349. package/s/_archive/core/atom/defaults.ts +0 -32
  350. package/s/_archive/core/atom/lens-algo.ts +0 -84
  351. package/s/_archive/core/atom/types.ts +0 -44
  352. package/s/_archive/core/bindings/normalize.ts +0 -27
  353. package/s/_archive/core/bindings/shape.ts +0 -15
  354. package/s/_archive/core/bindings/table.ts +0 -22
  355. package/s/_archive/core/intent/bucket.ts +0 -28
  356. package/s/_archive/core/intent/consts.ts +0 -4
  357. package/s/_archive/core/intent/decode.ts +0 -23
  358. package/s/_archive/core/intent/encode.ts +0 -20
  359. package/s/_archive/core/intent/merge.ts +0 -15
  360. package/s/_archive/core/parts/action.ts +0 -36
  361. package/s/_archive/core/parts/sample-map.ts +0 -24
  362. package/s/_archive/core/resolvers/actions.ts +0 -30
  363. package/s/_archive/core/resolvers/intents.ts +0 -106
  364. package/s/_archive/core/types.ts +0 -40
  365. package/s/_archive/deck/controller.ts +0 -35
  366. package/s/_archive/deck/deck.ts +0 -92
  367. package/s/_archive/deck/parts/profiles.ts +0 -39
  368. package/s/_archive/deck/parts/runtime.ts +0 -11
  369. package/s/_archive/deck/parts/settings.ts +0 -30
  370. package/s/_archive/deck/port.ts +0 -35
  371. package/s/_archive/deck/types.ts +0 -16
  372. package/s/_archive/demo/demo-app/element.ts +0 -17
  373. package/s/_archive/demo/demo-app/style.css.ts +0 -10
  374. package/s/_archive/demo/main.bundle.ts +0 -71
  375. package/s/_archive/demo/main.css +0 -83
  376. package/s/_archive/device/devices.ts +0 -24
  377. package/s/_archive/device/gamepad.ts +0 -42
  378. package/s/_archive/device/keyboard.ts +0 -33
  379. package/s/_archive/device/pad/on-pad.ts +0 -50
  380. package/s/_archive/device/pad/pad.ts +0 -10
  381. package/s/_archive/device/pointer.ts +0 -89
  382. package/s/_archive/device/sampler.ts +0 -25
  383. package/s/_archive/device/stick.ts +0 -24
  384. package/s/_archive/index-ui.ts +0 -3
  385. package/s/_archive/lib/bindings/resolver.ts +0 -61
  386. package/s/_archive/lib/bindings/types.ts +0 -67
  387. package/s/_archive/lib/bindings/utils/action-resolver.ts +0 -51
  388. package/s/_archive/lib/bindings/utils/evaluator.ts +0 -162
  389. package/s/_archive/lib/bindings/utils/hash-bindings.ts +0 -22
  390. package/s/_archive/lib/bindings/utils/intent-coding.ts +0 -50
  391. package/s/_archive/lib/bindings/utils/intent-resolver.ts +0 -52
  392. package/s/_archive/lib/bindings/utils/investigate.ts +0 -47
  393. package/s/_archive/lib/bindings/utils/is-down.ts +0 -5
  394. package/s/_archive/lib/bindings/utils/is-expression.ts +0 -11
  395. package/s/_archive/lib/index.ts +0 -12
  396. package/s/_archive/lib/sampling/sources/example.ts +0 -7
  397. package/s/_archive/lib/sampling/sources/gamepad.ts +0 -63
  398. package/s/_archive/lib/sampling/sources/keyboard.ts +0 -52
  399. package/s/_archive/lib/sampling/sources/pointer.ts +0 -56
  400. package/s/_archive/lib/sampling/sources/sources.ts +0 -13
  401. package/s/_archive/lib/sampling/sources/stick.ts +0 -27
  402. package/s/_archive/lib/sampling/types.ts +0 -11
  403. package/s/_archive/lib/sampling/utils/add-sample.ts +0 -12
  404. package/s/_archive/lib/test.ts +0 -57
  405. package/s/_archive/lib/utils/backwards.ts +0 -6
  406. package/s/_archive/lib/utils/evergreen.ts +0 -10
  407. package/s/_archive/lib/utils/mouse-button.ts +0 -10
  408. package/s/_archive/lib/utils/pad/on-pad.ts +0 -50
  409. package/s/_archive/lib/utils/pad/pad.ts +0 -10
  410. package/s/_archive/lib/utils/split-axis.ts +0 -15
  411. package/s/_archive/lib2/core/decoder/decoder.ts +0 -34
  412. package/s/_archive/lib2/core/decoder/utils/update-input.ts +0 -21
  413. package/s/_archive/lib2/core/encoder/encoder.ts +0 -60
  414. package/s/_archive/lib2/core/encoder/evaluate/context.ts +0 -22
  415. package/s/_archive/lib2/core/encoder/evaluate/evaluate.ts +0 -144
  416. package/s/_archive/lib2/core/encoder/parts/expression-index.ts +0 -27
  417. package/s/_archive/lib2/core/encoder/parts/hash-bindings.ts +0 -22
  418. package/s/_archive/lib2/core/encoder/parts/investigate.ts +0 -50
  419. package/s/_archive/lib2/core/encoder/parts/sampler.ts +0 -22
  420. package/s/_archive/lib2/core/sources/example.ts +0 -9
  421. package/s/_archive/lib2/core/sources/sources.ts +0 -16
  422. package/s/_archive/lib2/core/types.ts +0 -78
  423. package/s/_archive/lib2/core/utils/data.ts +0 -50
  424. package/s/_archive/lib2/core/utils/is-down.ts +0 -5
  425. package/s/_archive/lib2/core/utils/is-expression.ts +0 -11
  426. package/s/_archive/lib3/input/data/decode.ts +0 -25
  427. package/s/_archive/lib3/input/data/encode.ts +0 -24
  428. package/s/_archive/lib3/input/decoder.ts +0 -56
  429. package/s/_archive/lib3/input/encoder.ts +0 -99
  430. package/s/_archive/lib3/input/evaluate/context.ts +0 -15
  431. package/s/_archive/lib3/input/evaluate/evaluate.ts +0 -142
  432. package/s/_archive/lib3/input/evaluate/utils/clock.ts +0 -14
  433. package/s/_archive/lib3/input/investigate/hash-bindings.ts +0 -22
  434. package/s/_archive/lib3/input/investigate/investigate.ts +0 -42
  435. package/s/_archive/lib3/input/investigate/is-expression.ts +0 -11
  436. package/s/_archive/lib3/input/investigate/make-input.ts +0 -18
  437. package/s/_archive/lib3/input/investigate/root-index.ts +0 -26
  438. package/s/_archive/lib3/input/mixer.ts +0 -20
  439. package/s/_archive/lib3/input/sources/gamepad.ts +0 -58
  440. package/s/_archive/lib3/input/sources/keyboard.ts +0 -49
  441. package/s/_archive/lib3/input/sources/plain.ts +0 -9
  442. package/s/_archive/lib3/input/sources/pointer.ts +0 -58
  443. package/s/_archive/lib3/input/sources/sources.ts +0 -24
  444. package/s/_archive/lib3/input/sources/stick.ts +0 -29
  445. package/s/_archive/lib3/input/testing/quickbind.ts +0 -20
  446. package/s/_archive/lib3/input/types.ts +0 -96
  447. package/s/_archive/lib3/input/utils/evergreen.ts +0 -10
  448. package/s/_archive/lib3/input/utils/is-down.ts +0 -5
  449. package/s/_archive/lib3/input/utils/mouse-button.ts +0 -10
  450. package/s/_archive/lib3/input/utils/pad/on-pad.ts +0 -50
  451. package/s/_archive/lib3/input/utils/pad/pad.ts +0 -10
  452. package/s/_archive/lib3/input/utils/sampler.ts +0 -28
  453. package/s/_archive/lib3/input/utils/split-axis.ts +0 -15
  454. package/s/_archive/lib3/test.ts +0 -100
  455. package/s/_archive/lib4/input/data/decode.ts +0 -25
  456. package/s/_archive/lib4/input/data/encode.ts +0 -24
  457. package/s/_archive/lib4/input/data/params.ts +0 -7
  458. package/s/_archive/lib4/input/encoder.ts +0 -100
  459. package/s/_archive/lib4/input/evaluate/context.ts +0 -16
  460. package/s/_archive/lib4/input/evaluate/evaluate.ts +0 -157
  461. package/s/_archive/lib4/input/evaluate/utils/clock.ts +0 -14
  462. package/s/_archive/lib4/input/investigate/hash-bindings.ts +0 -22
  463. package/s/_archive/lib4/input/investigate/investigate.ts +0 -37
  464. package/s/_archive/lib4/input/investigate/is.ts +0 -19
  465. package/s/_archive/lib4/input/investigate/make-input.ts +0 -18
  466. package/s/_archive/lib4/input/investigate/root-index.ts +0 -26
  467. package/s/_archive/lib4/input/sources/gamepad.ts +0 -58
  468. package/s/_archive/lib4/input/sources/keyboard.ts +0 -46
  469. package/s/_archive/lib4/input/sources/plain.ts +0 -9
  470. package/s/_archive/lib4/input/sources/pointer.ts +0 -50
  471. package/s/_archive/lib4/input/sources/sources.ts +0 -24
  472. package/s/_archive/lib4/input/sources/stick.ts +0 -25
  473. package/s/_archive/lib4/input/types.ts +0 -102
  474. package/s/_archive/lib4/input/utils/evergreen.ts +0 -10
  475. package/s/_archive/lib4/input/utils/is-down.ts +0 -5
  476. package/s/_archive/lib4/input/utils/mouse-button.ts +0 -10
  477. package/s/_archive/lib4/input/utils/pad/on-pad.ts +0 -50
  478. package/s/_archive/lib4/input/utils/pad/pad.ts +0 -10
  479. package/s/_archive/lib4/input/utils/sampler.ts +0 -28
  480. package/s/_archive/lib4/input/utils/split-axis.ts +0 -15
  481. package/s/_archive/lib4/test.ts +0 -12
  482. package/s/_archive/test.ts +0 -339
  483. package/s/_archive/ui/views/desk/style.css.ts +0 -70
  484. package/s/_archive/ui/views/desk/view.ts +0 -122
  485. package/s/_archive/utils/circular-clamp.ts +0 -14
  486. package/s/_archive/utils/do-async.ts +0 -5
  487. package/s/_archive/utils/evergreen.ts +0 -10
  488. package/s/_archive/utils/freeze-clone.ts +0 -7
  489. package/s/_archive/utils/identifier.ts +0 -30
  490. package/s/_archive/utils/insert.ts +0 -6
  491. package/s/_archive/utils/is-down.ts +0 -5
  492. package/s/_archive/utils/remap.ts +0 -7
  493. package/s/_archive/utils/shift-limit.ts +0 -9
  494. package/s/_archive/utils/sort-by-key.ts +0 -7
  495. package/s/_archive/utils/split-axis.ts +0 -15
  496. package/s/_archive/utils/tmax.ts +0 -7
  497. package/s/_archive/utils/tmin.ts +0 -7
  498. package/s/demo/demo-app/element.ts +0 -15
  499. package/s/demo/demo-app/style.css.ts +0 -10
  500. package/s/lib/input/data/encode.ts +0 -24
  501. package/s/lib/input/data/params.ts +0 -7
  502. package/x/_archive/demo/main.css +0 -83
  503. package/x/demo/demo-app/element.d.ts +0 -1
  504. package/x/demo/demo-app/element.js +0 -12
  505. package/x/demo/demo-app/element.js.map +0 -1
  506. package/x/demo/demo-app/style.css.js +0 -9
  507. package/x/demo/demo-app/style.css.js.map +0 -1
  508. package/x/lib/input/data/decode.d.ts +0 -5
  509. package/x/lib/input/data/decode.js.map +0 -1
  510. package/x/lib/input/data/encode.d.ts +0 -2
  511. package/x/lib/input/data/encode.js +0 -17
  512. package/x/lib/input/data/encode.js.map +0 -1
  513. package/x/lib/input/data/params.js +0 -6
  514. package/x/lib/input/data/params.js.map +0 -1
  515. package/x/lib/input/encoder.d.ts +0 -10
  516. package/x/lib/input/encoder.js.map +0 -1
  517. /package/s/{_archive → lib}/utils/make-id.ts +0 -0
  518. /package/x/{demo/demo-app → lib/ui/views/controllers}/style.css.d.ts +0 -0
package/README.md CHANGED
@@ -2,104 +2,216 @@
2
2
  # 🎮 @benev/tact
3
3
  > *from keypress to couch co-op.*
4
4
 
5
- **tact is a tiny input toolkit for web games.**
6
- keyboards, mice, gamepads. expressive bindings json dsl.
7
- binary messages for efficient networking and web worker multithreading.
5
+ ### tact is a user-input toolkit for web games.
8
6
 
9
- ```ts
10
- npm install @benev/tact@next
11
- ```
7
+ 🌐 👉 ***https://tact.benev.gg/*** 👈 *try now*
8
+ 🖱 keyboards, mice, gamepads.
9
+ 🔥 powerful enough for multiplayer games, simple enough for any app.
10
+ 🎸 users can customize keybinds with the ready-to-rock ui.
11
+ 🧬 expressive bindings json dsl.
12
+ 📡 binary streaming for multiplayer and multithreading.
13
+ ✍️ handcrafted by a human being.
14
+
15
+ user input isn't as simple as you'd think.
16
+ after many design iterations, tact has evolved into an elegant system that handles hard problems for you like customizability, multiplayer, and multithreading. i'm trying to give you the *"it just works"* experience.
17
+
18
+ i care about the little things. all input types are boiled down to simple numbers, and packed up into efficient binary packets for streaming across networks and web workers. mouse movement precision and accuracy is holy, so there's careful design to make it resilient in the face of encoder/decoder sampling frequency mismatches. the bindings language is an infinitely capable recursive dsl so you can remap values from funky gamepads and make ridiculously complex logical hotkey combinations.
19
+
20
+
21
+
22
+ ![](https://i.imgur.com/dCAlD14.png)
23
+
24
+ ![](https://i.imgur.com/IBW5Kkd.png)
12
25
 
13
26
 
14
27
 
15
28
  <br/>
16
29
 
17
- ## 🕹️ sources emit samples.
30
+ ## 🎮 let's play.
31
+ > *here's the fully-featured, batteries-included, ready-for-anything web game starter pack.*
18
32
 
19
- - **samples look like** `{code: "KeyW", value: 1}`
33
+ - 🍏 **install tact into your typescript project.**
34
+ ```sh
35
+ npm install @benev/tact@next
36
+ ```
37
+ - 🍏 **establish your app's standard bindings.**
38
+ ```ts
39
+ import {asBindings} from "@benev/tact"
40
+
41
+ const bindings = asBindings({
42
+ jump: "Space",
43
+ forward: "KeyW",
44
+ look: ["accumulate", "pointer.x"],
45
+ })
46
+ ```
47
+ - 🍏 **let's have two presets available to the user, with one for gamepads.**
48
+ ```ts
49
+ import {asPresets} from "@benev/tact"
50
+
51
+ const presets = asPresets<typeof bindings>({
52
+ standard: {label: "⌨️standard", bindings},
53
+ gamepad: {label: "🎮gamer", bindings: {
54
+ jump: "gamepad.1",
55
+ forward: ["remap", 0, -1, 0, 1, "gamepad.axis.2"],
56
+ look: ["*", ["dt"], "gamepad.axis.3", 100],
57
+ }},
58
+ })
59
+ ```
60
+ - ⚙️ **setup tact.**
20
61
  ```ts
21
- import {Sources, KeyboardSource, PointerSource} from "@benev/tact"
62
+ import {setupTact} from "@benev/tact"
63
+
64
+ const tact = await setupTact({presets, maxPlayers: 4})
65
+ tact.mouseKeyboard()
66
+ tact.gamepads("gamepad")
67
+ tact.registerElements()
22
68
  ```
69
+ - 💡 *you can set `{maxPlayers: 1}` for a single player game.*
70
+ - 💡 *you can pass `{namespace: "falrysk"}` if you need to run multiple games on one website.*
71
+ - 💡 *you can register elements manually like `customElements.define("tact-deck-falrysk", tact.elements.TactDeck)`.*
72
+ - 💡 *you can call `tact.dispose()` to release resources.*
73
+ - 🍏 **encoding, decoding, and your game logic.**
23
74
  ```ts
24
- const source = new Sources(
25
- new KeyboardSource(),
26
- new PointerSource(),
27
- )
75
+ import {Players} from "@benev/tact"
76
+
77
+ const players = new Players(bindings)
78
+
79
+ setInterval(() => {
80
+ const buffer = tact.encodeAll()
81
+ players.decodeAll(buffer)
82
+ for (const [playerId, inputs] of players) {
83
+
84
+ // your game logic can read these handy input values.
85
+ inputs.jump.value // button-like values are numbers 0 to 1.
86
+ inputs.jump.was // previous value (to detect up/down).
87
+ inputs.jump.sum // sum of values reported since last frame.
88
+
89
+ inputs.forward.value
90
+ inputs.look.value
91
+ }
92
+ }, 16.67)
93
+ ```
94
+ - 💡 *maybe you'd like to stream the buffers over a network with [renraku](https://github.com/e280/renraku).*
95
+ - 💡 *maybe you'd like the tact deck on the clientside and the players on the serverside.*
96
+ - 🍏 **put the `<tact-deck>` element in your html page.**
97
+ ```html
98
+ <tact-deck></tact-deck>
28
99
  ```
29
- - proper sources: [GamepadSource](./s/lib/input/sources/gamepad.ts), [KeyboardSource](./s/lib/input/sources/keyboard.ts), [PointerSource](./s/lib/input/sources/pointer.ts), [StickSource](./s/lib/input/sources/stick.ts).
30
- - utility sources: [Sources](./s/lib/input/sources/sources.ts) *(consolidates sources)*, [PlainSource](./s/lib/input/sources/plain.ts) *(handy base class)*.
100
+ - 💡 *or just use the sub-panels directly, `<tact-controllers>` and `<tact-customize>`.*
101
+ - 💡 *you can customize the colors with css.*
102
+ ```html
103
+ <style>
104
+ html {
105
+ --tact-prime: aqua;
106
+ }
107
+ </style>
108
+ ```
109
+ - 🎉 **you're done! your users can manage controllers and customize bindings!**
31
110
 
32
111
 
33
112
 
34
113
  <br/>
35
114
 
36
- ## 🕹️ bindings describe controls.
115
+ ## 🎮 get down to brass tacks.
116
+ > *for simpler apps, you can use tact's composable parts more directly.*
37
117
 
38
- - **bindings are tiny programs,** a dsl in js data.
118
+ - ⚙️ **pov: your app isn't a game, no multiplayer, no gamepads.**
39
119
  ```ts
40
- import {asBindings} from "@benev/tact"
120
+ import {setupTact, Decoder} from "@benev/tact"
121
+
122
+ const tact = await setupTact({presets, maxPlayers: 1})
123
+ const controller = tact.mouseKeyboard()
124
+ const decoder = new Decoder(bindings)
125
+ tact.registerElements()
126
+
127
+ setInterval(() => {
128
+ const inputs = decoder.decode(controller.encode())
129
+
130
+ // 🧙‍♂️ handle your inputs.
131
+ inputs.jump.value
132
+
133
+ }, 16.67)
41
134
  ```
135
+ - 💡 *then the only ui you need is the `<tact-customize>` panel (also available as a sly view `CustomizeView`).*
136
+ - ⚙️ **pov: your app doesn't even want any ui, or persistence.**
42
137
  ```ts
43
- const bindings = asBindings({
44
- forward: ["max", "KeyW", "ArrowUp"],
45
- jump: ["down", "Space"],
46
- look: ["accumulate", ["sum", "pointer.x"]],
47
- })
138
+ import {Controller, Decoder, KeyboardSource, PointerSource, Sources} from "@benev/tact"
139
+
140
+ const source = new Sources(new KeyboardSource(), new PointerSource())
141
+ const controller = new Controller({bindings, source})
142
+ const decoder = new Decoder(bindings)
143
+
144
+ setInterval(() => {
145
+ const inputs = decoder.decode(controller.encode())
146
+
147
+ // 🧙‍♂️ handle your inputs.
148
+ inputs.jump.value
149
+
150
+ }, 16.67)
48
151
  ```
49
- - see [expression.ts](./s/lib/input/expression.ts) to learn what's possible.
50
152
 
51
153
 
52
154
 
53
155
  <br/>
54
156
 
55
- ## 🕹️ encode and decode.
157
+ ## 🎮 bindings.
158
+ > *bindings are a little json programming language.*
56
159
 
57
- - **the data is binary for efficient networking.**
160
+ - 🧬 **see [expression.ts](./s/lib/input/expression.ts) to get an idea of what's possible.**
161
+ - 🧬 **arbitrary nesting is valid.**
58
162
  ```ts
59
- import {InputEncoder, InputDecoder} from "@benev/tact"
163
+ asBindings("KeyW")
164
+
165
+ inputs.value // 1
60
166
  ```
61
167
  ```ts
62
- const encoder = new InputEncoder(source, bindings)
63
- const decoder = new InputDecoder(bindings)
168
+ asBindings({
169
+ special: {
170
+ magic: {
171
+ castSpell: ["*", ["mod", "shift", "alt"], "KeyR"],
172
+ }
173
+ }
174
+ })
175
+
176
+ inputs.special.magic.castSpell.value // 1
64
177
  ```
178
+ - 🧬 **you can differentiate taps versus holds on the same key.**
65
179
  ```ts
66
- function frame() {
67
-
68
- // data is an ArrayBuffer (you could stream it over the network).
69
- const data = encoder.encode()
70
-
71
- // decoding interprets the data as handy input objects.
72
- const inputs = decoder.decode(data)
180
+ asBindings({
73
181
 
74
- // your game logic can read these handy input values.
75
- inputs.forward.value // current held state.
76
- inputs.jump.value // down-presses this frame.
77
- inputs.look.value // total accumulated mouse movement.
182
+ // tapping E yoinks a weapon into your inventory.
183
+ grab: ["taps", 1, 250, "KeyE"],
78
184
 
79
- // this was so cool, let's do this forever.
80
- requestAnimationFrame(frame)
81
- }
185
+ // holding E equips the weapon as your primary.
186
+ equip: ["held", 250, "KeyE"],
187
+ })
188
+ ```
189
+ - 🧬 **you can "accumulate" mouse inputs accurately,** to avoid losses in sampling frequency mismatches.
190
+ ```ts
191
+ asBindings({
192
+ lookX: ["accumulate", "pointer.x"],
193
+ })
82
194
 
83
- requestAnimationFrame(frame)
195
+ inputs.lookX.sum // use sum instead of value.
84
196
  ```
85
- - **understanding networking situations.**
86
- - the encoder could be on your clientside.
87
- - the decoder could be on your serverside.
88
- - thus, clients are streaming their input data to the serverside, which is decoding it and using it in game logic.
89
- - don't worry, it's not a keylogger -- the encoded data is more like `jump: 1`, `look: 5`, etc.
90
- - the decoder can accept multiple data packets at once, `decoder.decode(...datas)`.
91
- - **understanding multithreaded worker situations.**
92
- - the encoder would be on the main thread, where javascript events are accessible.
93
- - you can then send the encoded input data to the thread where you're simulating the game.
94
- - you can have multiple encoders -- one encoder sending data to a worker thread -- another encoder sending data to the serverside.
95
- - **update the encoder's bindings anytime.**
197
+ - 🧬 **gamepads thumbstick inputs are best done with some math.**
96
198
  ```ts
97
- // the new bindings must be schema-compatible or an error is thrown.
98
- encoder.bindings = {
99
- forward: "KeyE",
100
- jump: "Space",
101
- look: "gamepad.axis.2"
102
- }
199
+ asBindings({
200
+ forward: ["*",
201
+
202
+ // user-customizable sensitivity,
203
+ // equivalent with pointer-pixels-per-second.
204
+ 1234,
205
+
206
+ // delta time factor,
207
+ // to ensure sensitivity is framerate-independent.
208
+ ["dt"],
209
+
210
+ // remapping the ranges,
211
+ // because different gamepads represent the values differently.
212
+ ["remap", 0, -1, 0, 1, "gamepad.axis.1"],
213
+ ],
214
+ })
103
215
  ```
104
216
 
105
217
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@benev/tact",
3
- "version": "0.4.0-0",
4
- "description": "🎮 keybindings and couch co-op",
3
+ "version": "0.4.0-10",
4
+ "description": "🎮 from keypress to couch co-op",
5
5
  "license": "MIT",
6
6
  "author": "Chase Moskal <chasemoskal@gmail.com>",
7
7
  "type": "module",
@@ -21,20 +21,22 @@
21
21
  "count": "find s -path '*/_archive' -prune -o -name '*.ts' -exec wc -l {} +"
22
22
  },
23
23
  "peerDependencies": {
24
- "@e280/sly": "^0.4.9",
25
- "@e280/strata": "^0.5.6",
24
+ "@e280/sly": "^0.4.14",
25
+ "@e280/strata": "^0.5.7",
26
26
  "lit": "^3.3.3"
27
27
  },
28
28
  "dependencies": {
29
+ "@awasm/noble": "^0.1.4",
29
30
  "@benev/math": "0.4.0-9",
30
- "@e280/kv": "^0.2.4",
31
- "@e280/stz": "^0.4.11"
31
+ "@e280/kv": "^0.2.6",
32
+ "@e280/shiny": "^0.1.1",
33
+ "@e280/stz": "^0.4.16"
32
34
  },
33
35
  "devDependencies": {
34
36
  "@e280/hottie": "^0.1.7",
35
37
  "@e280/octo": "^0.1.7",
36
38
  "@e280/science": "^0.1.14",
37
- "@e280/scute": "^0.5.3",
39
+ "@e280/scute": "^0.5.5",
38
40
  "http-server": "^14.1.1",
39
41
  "npm-run-all": "^4.1.5",
40
42
  "typescript": "^7.0.2"
@@ -1,8 +1,23 @@
1
1
 
2
2
  import {dom} from "@e280/sly"
3
- import {setupDemoApp} from "./demo-app/element.js"
3
+ import {cycle, nap} from "@e280/stz"
4
+ import {presets} from "./presets.js"
5
+ import {setupTact} from "../lib/ui/deck/setup/tact.js"
4
6
 
5
- dom.register({
6
- DemoApp: setupDemoApp(),
7
+ const tact = await setupTact({presets, maxPlayers: 4})
8
+ tact.mouseKeyboard()
9
+ tact.gamepads("gamer")
10
+ tact.registerElements()
11
+
12
+ cycle(async() => {
13
+ const data = tact.deck.hub.encodeAll()
14
+ tact.visualizer.update(data)
15
+ await nap(1000 / 60)
7
16
  })
8
17
 
18
+ {
19
+ const input = dom<HTMLInputElement>('input[type="color"]')
20
+ input.value = "#ffbb00"
21
+ input.oninput = () => document.body.style.setProperty("--tact-prime", input.value)
22
+ }
23
+
package/s/demo/main.css CHANGED
@@ -53,23 +53,52 @@
53
53
  background: var(--bg);
54
54
  }
55
55
 
56
+ html {
57
+ scrollbar-gutter: stable;
58
+ }
59
+
56
60
  body {
57
61
  display: flex;
58
62
  flex-direction: column;
59
63
  align-items: center;
60
64
 
61
65
  gap: 1em;
62
- padding: 2em;
66
+ padding: 0.5em;
67
+ padding-bottom: 8em;
63
68
 
64
69
  > * {
65
- width: 100%;
66
- max-width: 42em;
70
+ width: min(100%, 50em);
67
71
  }
68
72
 
69
73
  > header {
74
+ display: flex;
75
+ flex-wrap: wrap;
76
+ justify-content: space-between;
77
+ align-items: end;
78
+ gap: 1em;
70
79
  padding: 0 2em;
71
- h1 small { font-size: 0.6em; font-weight: normal; }
72
- * + * { margin-top: 0.5em; }
80
+
81
+ h1 small {
82
+ font-size: 0.6em;
83
+ font-weight: normal;
84
+ }
85
+
86
+ blockquote {
87
+ opacity: 0.5;
88
+ font-style: italic;
89
+ padding-left: 1em;
90
+ }
91
+
92
+ label {
93
+ display: flex;
94
+ flex-direction: column;
95
+ align-items: end;
96
+ gap: 0.1em;
97
+ }
98
+
99
+ .links span {
100
+ opacity: 0.5;
101
+ }
73
102
  }
74
103
 
75
104
  > section {
@@ -78,6 +107,13 @@
78
107
  padding-left: 1em;
79
108
  }
80
109
  }
110
+
111
+ > footer {
112
+ padding: 1em 2em;
113
+ p {
114
+ opacity: 0.5;
115
+ }
116
+ }
81
117
  }
82
118
  }
83
119
 
@@ -0,0 +1,54 @@
1
+
2
+ import {asBindings} from "../lib/input/types.js"
3
+ import {asPresets} from "../lib/ui/deck/types.js"
4
+
5
+ export const bindings = asBindings({
6
+ looking: {
7
+ horizontal: ["accumulate", "pointer.x"],
8
+ vertical: ["accumulate", "pointer.y"],
9
+ },
10
+ moving: {
11
+ forward: "KeyW",
12
+ backward: "KeyS",
13
+ leftward: "KeyA",
14
+ rightward: "KeyD",
15
+ },
16
+ interactions: {
17
+ use: "KeyE",
18
+ },
19
+ })
20
+
21
+ export const presets = asPresets<typeof bindings>({
22
+ standard: {label: "⌨️standard", bindings},
23
+ gamer: {label: "🎮gamer", bindings: {
24
+ looking: {
25
+ horizontal: ["*", ["dt"], "gamepad.axis.3", 100],
26
+ vertical: ["*", ["dt"], "gamepad.axis.4", 100],
27
+ },
28
+ moving: {
29
+ forward: ["remap", 0, -1, 0, 1, "gamepad.axis.2"],
30
+ backward: ["remap", 0, 1, 0, 1, "gamepad.axis.2"],
31
+ leftward: ["remap", 0, -1, 0, 1, "gamepad.axis.1"],
32
+ rightward: ["remap", 0, 1, 0, 1, "gamepad.axis.1"],
33
+ },
34
+ interactions: {
35
+ use: "gamepad.1",
36
+ },
37
+ }},
38
+ micro: {label: "🦠micro", bindings: {
39
+ looking: {
40
+ horizontal: ["*", ["dt"], ["+", "gamepad.1", ["-", "gamepad.4"]], 100],
41
+ vertical: ["*", ["dt"], ["+", "gamepad.2", ["-", "gamepad.3"]], 100],
42
+ },
43
+ moving: {
44
+ forward: ["remap", 0, -1, 0, 1, "gamepad.axis.2"],
45
+ backward: ["remap", 0, 1, 0, 1, "gamepad.axis.2"],
46
+ leftward: ["remap", 0, -1, 0, 1, "gamepad.axis.1"],
47
+ rightward: ["remap", 0, 1, 0, 1, "gamepad.axis.1"],
48
+ },
49
+ interactions: {
50
+ use: ["*", "gamepad.5", "gamepad.6"],
51
+ },
52
+ }},
53
+ })
54
+
@@ -35,12 +35,15 @@ export const GamepadApp = shadowElement(() => {
35
35
  }))
36
36
 
37
37
  const renderSample = ([code, value]: [string, number]) => html`
38
- <li style="${`--percent: ${value * 100}%;`}">
38
+ <li ?data-neg="${value < 0}" style="${`--percent: ${Math.abs(value) * 100}%;`}">
39
39
  <span>${code}</span>
40
40
  <span>${value.toFixed(3)}</span>
41
41
  </li>
42
42
  `
43
43
 
44
+ const sortSamples = (a: [string, number], b: [string, number]) =>
45
+ a[0].localeCompare(b[0])
46
+
44
47
  return html`
45
48
  <div class=plate>
46
49
  ${connected.size > 0 ? [...connected].map(({samples, source: {gamepad}}) => html`
@@ -49,14 +52,18 @@ export const GamepadApp = shadowElement(() => {
49
52
  <div class=stats>
50
53
  <span>index ${gamepad.index}</span>
51
54
  <span>connected ${gamepad.connected ? "yes" : "no"}</span>
52
- <span>mapping ${gamepad.mapping}</span>
55
+ <span>mapping "${gamepad.mapping}"</span>
53
56
  <span>vibrationActuator ${gamepad.vibrationActuator ? "yes" : "no"}</span>
54
57
  </div>
55
58
  <ul>
56
- ${[...samples].filter(([code]) => code.startsWith("gamepad.button")).map(renderSample)}
59
+ ${[...samples]
60
+ .sort(sortSamples)
61
+ .filter(([code]) => !code.startsWith("gamepad.axis")).map(renderSample)}
57
62
  </ul>
58
63
  <ul>
59
- ${[...samples].filter(([code]) => code.startsWith("gamepad.axis")).map(renderSample)}
64
+ ${[...samples]
65
+ .sort(sortSamples)
66
+ .filter(([code]) => code.startsWith("gamepad.axis")).map(renderSample)}
60
67
  </ul>
61
68
  </div>
62
69
  `) : html`
@@ -57,10 +57,14 @@ export default css`
57
57
  display: block;
58
58
  content: "";
59
59
  inset: 0;
60
- background: #f004;
60
+ background: #08f4;
61
61
  width: var(--percent);
62
62
  }
63
63
 
64
+ &[data-neg]::before {
65
+ background: #f004;
66
+ }
67
+
64
68
  > span {
65
69
  position: relative;
66
70
  z-index: 2;
@@ -15,7 +15,7 @@ export default template(import.meta.url, async orb => html`
15
15
  <meta charset="utf-8"/>
16
16
  <meta name="viewport" content="width=device-width,initial-scale=1"/>
17
17
  <meta name="darkreader-lock"/>
18
- <style>@layer base{html{background:#000}}</style>
18
+ <style>@layer base{html{background:#111}}</style>
19
19
 
20
20
  <link rel="icon" href="${dataSvgEmoji("🎮")}"/>
21
21
  <link rel="stylesheet" href="${orb.hashurl("main.css")}"/>
@@ -54,7 +54,16 @@
54
54
  }
55
55
 
56
56
  body {
57
- padding: 1em;
57
+ display: flex;
58
+ flex-direction: column;
59
+ align-items: center;
60
+
61
+ gap: 1em;
62
+ padding: 0.5em;
63
+
64
+ > * {
65
+ width: min(100%, 50em);
66
+ }
58
67
  }
59
68
  }
60
69
 
package/s/index.html.ts CHANGED
@@ -4,7 +4,7 @@ import {template, html, dataSvgEmoji, socialCard} from "@e280/scute"
4
4
  const title = "@benev/tact"
5
5
  const domain = "tact.benev.gg"
6
6
  const favicon = "/assets/b.png"
7
- const description = "🎮 keybindings and couch co-op"
7
+ const description = "🎮 from keypress to couch co-op"
8
8
 
9
9
  export default template(import.meta.url, async orb => html`
10
10
  <!doctype html>
@@ -15,7 +15,7 @@ export default template(import.meta.url, async orb => html`
15
15
  <meta charset="utf-8"/>
16
16
  <meta name="viewport" content="width=device-width,initial-scale=1"/>
17
17
  <meta name="darkreader-lock"/>
18
- <style>@layer base{html{background:#000}}</style>
18
+ <style>@layer base{html{background:#111}}</style>
19
19
 
20
20
  <link rel="icon" href="${dataSvgEmoji("🎮")}"/>
21
21
  <link rel="stylesheet" href="${orb.hashurl("demo/main.css")}"/>
@@ -31,23 +31,36 @@ export default template(import.meta.url, async orb => html`
31
31
  </head>
32
32
  <body>
33
33
  <header>
34
- <h1>
35
- <strong>@benev/tact</strong>
36
- <small>v${orb.packageVersion()}</small>
37
- </h1>
38
34
  <div>
39
- <blockquote>"from keypress to couch co-op"</blockquote>
40
- <p>
41
- <a href="./gamepad/">gamepad visualizer</a>.
42
- </p>
43
- <p>
44
- <a href="https://github.com/benev-gg/tact">github</a>.
45
- <a href="https://benev.gg/">benev.gg</a>.
46
- </p>
35
+ <h1>
36
+ <strong>@benev/tact</strong>
37
+ <small>v${orb.packageVersion()}</small>
38
+ </h1>
39
+ <div>
40
+ <blockquote>"from keypress to couch co-op"</blockquote>
41
+ <p class=links>
42
+ <a href="./gamepad/">gamepad visualizer</a>
43
+ <span>—</span>
44
+ <a href="https://github.com/benev-gg/tact">github</a>
45
+ <span>—</span>
46
+ <a href="https://benev.gg/">benev.gg</a>
47
+ </p>
48
+ </div>
49
+ </div>
50
+ <div>
51
+ <label>
52
+ <input type="color"/>
53
+ <span>choose your color ☝️</span>
54
+ </label>
47
55
  </div>
48
56
  </header>
49
57
 
50
- <demo-app></demo-app>
58
+ <tact-deck></tact-deck>
59
+
60
+ <footer>
61
+ <p>binary data visualizer</p>
62
+ <tact-visualizer></tact-visualizer>
63
+ </footer>
51
64
  </body>
52
65
  </html>
53
66
  `)
package/s/lib/index.ts CHANGED
@@ -1,18 +1,29 @@
1
1
 
2
2
  export * from "./input/investigate/is-compatible.js"
3
-
4
3
  export * from "./input/sources/gamepad.js"
5
4
  export * from "./input/sources/keyboard.js"
6
5
  export * from "./input/sources/plain.js"
7
6
  export * from "./input/sources/pointer.js"
8
7
  export * from "./input/sources/sources.js"
9
8
  export * from "./input/sources/stick.js"
10
-
11
9
  export * from "./input/utils/pad/on-pad.js"
12
10
  export * from "./input/utils/pad/pad.js"
13
11
  export * from "./input/utils/is-down.js"
14
-
15
- export * from "./input/encoder.js"
12
+ export * from "./input/controller.js"
16
13
  export * from "./input/decoder.js"
14
+ export * from "./input/expression.js"
17
15
  export * from "./input/types.js"
18
16
 
17
+ export * from "./ui/deck/controls/controls.js"
18
+ export * from "./ui/deck/controls/types.js"
19
+ export * from "./ui/deck/setup/deck.js"
20
+ export * from "./ui/deck/setup/tact.js"
21
+ export * from "./ui/deck/auto-gamepads.js"
22
+ export * from "./ui/deck/players.js"
23
+ export * from "./ui/deck/hub.js"
24
+ export * from "./ui/deck/types.js"
25
+ export * from "./ui/views/customize/view.js"
26
+ export * from "./ui/views/deck/view.js"
27
+ export * from "./ui/views/controllers/view.js"
28
+ export * from "./ui/views/visualizer/view.js"
29
+