From 4c7e126fb6808625b00c727c15bad8b1aa0b358a Mon Sep 17 00:00:00 2001 From: numachang Date: Mon, 25 May 2026 21:07:05 +0900 Subject: [PATCH 1/2] test: Add Vitest and snapshot baselines for HID labels and ZMK names Lock in the current behaviour of the picker label pipeline (hid_usage_get_metadata / hid_usage_get_label) and the keymap-parser canonical table before consolidating them into a single source of truth. Any drift introduced by the upcoming SSOT refactor will trip the snapshots loudly. - Add Vitest as a devDependency with `npm test` / `npm run test:watch`. - src/hid-usages.test.ts snapshots every (page, usage) pair that surfaces a label today, plus the page list. - src/keymap-parser.test.ts snapshots the full canonical name table and asserts forward/reverse name<->code round-trip plus modifier wrapper round-trip. Co-Authored-By: Claude --- package-lock.json | 975 +- package.json | 7 +- src/__snapshots__/hid-usages.test.ts.snap | 8562 ++++++++++++++++++ src/__snapshots__/keymap-parser.test.ts.snap | 530 ++ src/hid-usages.test.ts | 74 + src/keymap-parser.test.ts | 52 + 6 files changed, 10173 insertions(+), 27 deletions(-) create mode 100644 src/__snapshots__/hid-usages.test.ts.snap create mode 100644 src/__snapshots__/keymap-parser.test.ts.snap create mode 100644 src/hid-usages.test.ts create mode 100644 src/keymap-parser.test.ts diff --git a/package-lock.json b/package-lock.json index 77d0645a..cb8514b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,7 +52,8 @@ "storybook": "^8.0.10", "tailwindcss": "^3.4.4", "typescript": "^5.4.5", - "vite": "^5.4.8" + "vite": "^5.4.8", + "vitest": "^3.2.4" }, "optionalDependencies": { "@esbuild/darwin-arm64": "0.23.0", @@ -1336,7 +1337,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { @@ -4675,6 +4678,27 @@ "@types/node": "*" } }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/chai/node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/@types/connect": { "version": "3.4.38", "dev": true, @@ -4683,6 +4707,13 @@ "@types/node": "*" } }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/doctrine": { "version": "0.0.3", "dev": true, @@ -5144,6 +5175,131 @@ "dev": true, "license": "MIT" }, + "node_modules/@vitest/mocker": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.2.4", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/mocker/node_modules/@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/@vitest/mocker/node_modules/tinyspy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", + "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.2.4", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner/node_modules/@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner/node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitest/snapshot": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", + "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, "node_modules/@vitest/spy": { "version": "1.6.0", "dev": true, @@ -5624,6 +5780,16 @@ "node": ">= 0.8" } }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind": { "version": "1.0.7", "dev": true, @@ -5901,11 +6067,13 @@ "license": "MIT" }, "node_modules/debug": { - "version": "4.3.4", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -6668,6 +6836,16 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/express": { "version": "4.21.1", "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", @@ -8113,11 +8291,13 @@ } }, "node_modules/magic-string": { - "version": "0.30.10", + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@jridgewell/sourcemap-codec": "^1.5.5" } }, "node_modules/make-dir": { @@ -8293,7 +8473,9 @@ } }, "node_modules/ms": { - "version": "2.1.2", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, "license": "MIT" }, @@ -8654,6 +8836,13 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, "node_modules/pathval": { "version": "1.1.1", "dev": true, @@ -9605,12 +9794,6 @@ "node": ">= 0.8" } }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, "node_modules/serve-static": { "version": "1.16.2", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", @@ -9696,6 +9879,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, "node_modules/signal-exit": { "version": "3.0.7", "dev": true, @@ -9735,6 +9925,13 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -9744,6 +9941,13 @@ "node": ">= 0.8" } }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, "node_modules/stop-iteration-iterator": { "version": "1.0.0", "dev": true, @@ -9860,6 +10064,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strip-literal": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", + "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/strip-literal/node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, "node_modules/sucrase": { "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", @@ -10074,6 +10298,88 @@ "dev": true, "license": "MIT" }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/tinyspy": { "version": "2.2.1", "dev": true, @@ -10480,6 +10786,36 @@ } } }, + "node_modules/vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-node/node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, "node_modules/vite/node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -10886,6 +11222,211 @@ "@esbuild/win32-x64": "0.21.5" } }, + "node_modules/vitest": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", + "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@vitest/pretty-format": "^3.2.4", + "@vitest/runner": "3.2.4", + "@vitest/snapshot": "3.2.4", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "debug": "^4.4.1", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.2.4", + "@vitest/ui": "3.2.4", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/@vitest/expect": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest/node_modules/@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest/node_modules/@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest/node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/vitest/node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/vitest/node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/vitest/node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/vitest/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vitest/node_modules/tinyspy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "dev": true, @@ -10976,6 +11517,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "dev": true, @@ -11869,7 +12427,9 @@ "version": "1.2.1" }, "@jridgewell/sourcemap-codec": { - "version": "1.4.15" + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==" }, "@jridgewell/trace-mapping": { "version": "0.3.25", @@ -14173,6 +14733,24 @@ "@types/node": "*" } }, + "@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "requires": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + }, + "dependencies": { + "assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true + } + } + }, "@types/connect": { "version": "3.4.38", "dev": true, @@ -14180,6 +14758,12 @@ "@types/node": "*" } }, + "@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true + }, "@types/doctrine": { "version": "0.0.3", "dev": true @@ -14493,6 +15077,93 @@ } } }, + "@vitest/mocker": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", + "dev": true, + "requires": { + "@vitest/spy": "3.2.4", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "dependencies": { + "@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "requires": { + "tinyspy": "^4.0.3" + } + }, + "estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "requires": { + "@types/estree": "^1.0.0" + } + }, + "tinyspy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "dev": true + } + } + }, + "@vitest/pretty-format": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", + "dev": true, + "requires": { + "tinyrainbow": "^2.0.0" + } + }, + "@vitest/runner": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", + "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", + "dev": true, + "requires": { + "@vitest/utils": "3.2.4", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" + }, + "dependencies": { + "@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "dev": true, + "requires": { + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + } + }, + "loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true + } + } + }, + "@vitest/snapshot": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", + "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", + "dev": true, + "requires": { + "@vitest/pretty-format": "3.2.4", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + } + }, "@vitest/spy": { "version": "1.6.0", "dev": true, @@ -14807,6 +15478,12 @@ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true }, + "cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true + }, "call-bind": { "version": "1.0.7", "dev": true, @@ -14971,10 +15648,12 @@ "dev": true }, "debug": { - "version": "4.3.4", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "requires": { - "ms": "2.1.2" + "ms": "^2.1.3" } }, "deep-eql": { @@ -15453,6 +16132,12 @@ "strip-final-newline": "^2.0.0" } }, + "expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true + }, "express": { "version": "4.21.1", "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", @@ -16350,10 +17035,12 @@ "dev": true }, "magic-string": { - "version": "0.30.10", + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "dev": true, "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@jridgewell/sourcemap-codec": "^1.5.5" } }, "make-dir": { @@ -16458,7 +17145,9 @@ "version": "5.0.0" }, "ms": { - "version": "2.1.2", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "mz": { @@ -16667,6 +17356,12 @@ "version": "4.0.0", "dev": true }, + "pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true + }, "pathval": { "version": "1.1.1", "dev": true @@ -17290,12 +17985,6 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true } } }, @@ -17358,6 +18047,12 @@ "object-inspect": "^1.13.1" } }, + "siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true + }, "signal-exit": { "version": "3.0.7", "dev": true @@ -17381,12 +18076,24 @@ "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", "dev": true }, + "stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true + }, "statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true }, + "std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true + }, "stop-iteration-iterator": { "version": "1.0.0", "dev": true, @@ -17450,6 +18157,23 @@ "version": "3.1.1", "dev": true }, + "strip-literal": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", + "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", + "dev": true, + "requires": { + "js-tokens": "^9.0.1" + }, + "dependencies": { + "js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true + } + } + }, "sucrase": { "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", @@ -17594,6 +18318,55 @@ "version": "1.3.3", "dev": true }, + "tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true + }, + "tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true + }, + "tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, + "requires": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "dependencies": { + "fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "requires": {} + }, + "picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true + } + } + }, + "tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true + }, + "tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true + }, "tinyspy": { "version": "2.2.1", "dev": true @@ -18007,6 +18780,148 @@ } } }, + "vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "dev": true, + "requires": { + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "dependencies": { + "es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true + } + } + }, + "vitest": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", + "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", + "dev": true, + "requires": { + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@vitest/pretty-format": "^3.2.4", + "@vitest/runner": "3.2.4", + "@vitest/snapshot": "3.2.4", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "debug": "^4.4.1", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.4", + "why-is-node-running": "^2.3.0" + }, + "dependencies": { + "@vitest/expect": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", + "dev": true, + "requires": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + } + }, + "@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "requires": { + "tinyspy": "^4.0.3" + } + }, + "@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "dev": true, + "requires": { + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + } + }, + "assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true + }, + "chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "requires": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + } + }, + "check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "dev": true + }, + "deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true + }, + "loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true + }, + "pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true + }, + "picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true + }, + "tinyspy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "dev": true + } + } + }, "webidl-conversions": { "version": "3.0.1", "dev": true @@ -18065,6 +18980,16 @@ "has-tostringtag": "^1.0.2" } }, + "why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "requires": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + } + }, "word-wrap": { "version": "1.2.5", "dev": true diff --git a/package.json b/package.json index 1505bcaf..d2637caa 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,8 @@ "dev": "npm run generate-data && vite", "build": "npm run generate-data && tsc && vite build", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "test": "vitest run", + "test:watch": "vitest", "preview": "vite preview", "tauri": "tauri", "storybook": "storybook dev -p 6006", @@ -58,10 +60,11 @@ "storybook": "^8.0.10", "tailwindcss": "^3.4.4", "typescript": "^5.4.5", - "vite": "^5.4.8" + "vite": "^5.4.8", + "vitest": "^3.2.4" }, "optionalDependencies": { "@esbuild/darwin-arm64": "0.23.0", "@rollup/rollup-darwin-arm64": "^4.18.1" } -} \ No newline at end of file +} diff --git a/src/__snapshots__/hid-usages.test.ts.snap b/src/__snapshots__/hid-usages.test.ts.snap new file mode 100644 index 00000000..29ffe5c6 --- /dev/null +++ b/src/__snapshots__/hid-usages.test.ts.snap @@ -0,0 +1,8562 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`hid_usage_get_label > captures the compact-label baseline (pre-SSOT snapshot) 1`] = ` +[ + { + "label": "ErrorRollOver", + "page": 7, + "usage": 1, + }, + { + "label": "POSTFail", + "page": 7, + "usage": 2, + }, + { + "label": "ErrorUndefined", + "page": 7, + "usage": 3, + }, + { + "label": "Keyboard A", + "page": 7, + "usage": 4, + }, + { + "label": "Keyboard B", + "page": 7, + "usage": 5, + }, + { + "label": "Keyboard C", + "page": 7, + "usage": 6, + }, + { + "label": "Keyboard D", + "page": 7, + "usage": 7, + }, + { + "label": "Keyboard E", + "page": 7, + "usage": 8, + }, + { + "label": "Keyboard F", + "page": 7, + "usage": 9, + }, + { + "label": "Keyboard G", + "page": 7, + "usage": 10, + }, + { + "label": "Keyboard H", + "page": 7, + "usage": 11, + }, + { + "label": "Keyboard I", + "page": 7, + "usage": 12, + }, + { + "label": "Keyboard J", + "page": 7, + "usage": 13, + }, + { + "label": "Keyboard K", + "page": 7, + "usage": 14, + }, + { + "label": "Keyboard L", + "page": 7, + "usage": 15, + }, + { + "label": "Keyboard M", + "page": 7, + "usage": 16, + }, + { + "label": "Keyboard N", + "page": 7, + "usage": 17, + }, + { + "label": "Keyboard O", + "page": 7, + "usage": 18, + }, + { + "label": "Keyboard P", + "page": 7, + "usage": 19, + }, + { + "label": "Keyboard Q", + "page": 7, + "usage": 20, + }, + { + "label": "Keyboard R", + "page": 7, + "usage": 21, + }, + { + "label": "Keyboard S", + "page": 7, + "usage": 22, + }, + { + "label": "Keyboard T", + "page": 7, + "usage": 23, + }, + { + "label": "Keyboard U", + "page": 7, + "usage": 24, + }, + { + "label": "Keyboard V", + "page": 7, + "usage": 25, + }, + { + "label": "Keyboard W", + "page": 7, + "usage": 26, + }, + { + "label": "Keyboard X", + "page": 7, + "usage": 27, + }, + { + "label": "Keyboard Y", + "page": 7, + "usage": 28, + }, + { + "label": "Keyboard Z", + "page": 7, + "usage": 29, + }, + { + "label": "1 !", + "page": 7, + "usage": 30, + }, + { + "label": "2 @", + "page": 7, + "usage": 31, + }, + { + "label": "3 #", + "page": 7, + "usage": 32, + }, + { + "label": "4 $", + "page": 7, + "usage": 33, + }, + { + "label": "5 %", + "page": 7, + "usage": 34, + }, + { + "label": "6 ^", + "page": 7, + "usage": 35, + }, + { + "label": "7 &", + "page": 7, + "usage": 36, + }, + { + "label": "8 *", + "page": 7, + "usage": 37, + }, + { + "label": "9 (", + "page": 7, + "usage": 38, + }, + { + "label": "0 )", + "page": 7, + "usage": 39, + }, + { + "label": "Ret", + "page": 7, + "usage": 40, + }, + { + "label": "Esc", + "page": 7, + "usage": 41, + }, + { + "label": "BkSp", + "page": 7, + "usage": 42, + }, + { + "label": "Keyboard Tab", + "page": 7, + "usage": 43, + }, + { + "label": "␣", + "page": 7, + "usage": 44, + }, + { + "label": "- _", + "page": 7, + "usage": 45, + }, + { + "label": "= +", + "page": 7, + "usage": 46, + }, + { + "label": "[ {", + "page": 7, + "usage": 47, + }, + { + "label": "] }", + "page": 7, + "usage": 48, + }, + { + "label": "\\ |", + "page": 7, + "usage": 49, + }, + { + "label": "NUHS", + "page": 7, + "usage": 50, + }, + { + "label": "; :", + "page": 7, + "usage": 51, + }, + { + "label": "' "", + "page": 7, + "usage": 52, + }, + { + "label": "\` ~", + "page": 7, + "usage": 53, + }, + { + "label": ", <", + "page": 7, + "usage": 54, + }, + { + "label": ". >", + "page": 7, + "usage": 55, + }, + { + "label": "/ ?", + "page": 7, + "usage": 56, + }, + { + "label": "Cap", + "page": 7, + "usage": 57, + }, + { + "label": "Keyboard F1", + "page": 7, + "usage": 58, + }, + { + "label": "Keyboard F2", + "page": 7, + "usage": 59, + }, + { + "label": "Keyboard F3", + "page": 7, + "usage": 60, + }, + { + "label": "Keyboard F4", + "page": 7, + "usage": 61, + }, + { + "label": "Keyboard F5", + "page": 7, + "usage": 62, + }, + { + "label": "Keyboard F6", + "page": 7, + "usage": 63, + }, + { + "label": "Keyboard F7", + "page": 7, + "usage": 64, + }, + { + "label": "Keyboard F8", + "page": 7, + "usage": 65, + }, + { + "label": "Keyboard F9", + "page": 7, + "usage": 66, + }, + { + "label": "Keyboard F10", + "page": 7, + "usage": 67, + }, + { + "label": "Keyboard F11", + "page": 7, + "usage": 68, + }, + { + "label": "Keyboard F12", + "page": 7, + "usage": 69, + }, + { + "label": "PrSc", + "page": 7, + "usage": 70, + }, + { + "label": "ScLk", + "page": 7, + "usage": 71, + }, + { + "label": "Paus", + "page": 7, + "usage": 72, + }, + { + "label": "Ins", + "page": 7, + "usage": 73, + }, + { + "label": "Keyboard Home", + "page": 7, + "usage": 74, + }, + { + "label": "PgUp", + "page": 7, + "usage": 75, + }, + { + "label": "Del", + "page": 7, + "usage": 76, + }, + { + "label": "Keyboard End", + "page": 7, + "usage": 77, + }, + { + "label": "PgDn", + "page": 7, + "usage": 78, + }, + { + "label": "→", + "page": 7, + "usage": 79, + }, + { + "label": "←", + "page": 7, + "usage": 80, + }, + { + "label": "↓", + "page": 7, + "usage": 81, + }, + { + "label": "↑", + "page": 7, + "usage": 82, + }, + { + "label": "Num", + "page": 7, + "usage": 83, + }, + { + "label": "/", + "page": 7, + "usage": 84, + }, + { + "label": "*", + "page": 7, + "usage": 85, + }, + { + "label": "-", + "page": 7, + "usage": 86, + }, + { + "label": "+", + "page": 7, + "usage": 87, + }, + { + "label": "Ent", + "page": 7, + "usage": 88, + }, + { + "label": "1 En", + "page": 7, + "usage": 89, + }, + { + "label": "2 ↓", + "page": 7, + "usage": 90, + }, + { + "label": "3 PD", + "page": 7, + "usage": 91, + }, + { + "label": "4 ←", + "page": 7, + "usage": 92, + }, + { + "label": "5", + "page": 7, + "usage": 93, + }, + { + "label": "6 →", + "page": 7, + "usage": 94, + }, + { + "label": "7 Hm", + "page": 7, + "usage": 95, + }, + { + "label": "8 ↑", + "page": 7, + "usage": 96, + }, + { + "label": "9 PU", + "page": 7, + "usage": 97, + }, + { + "label": "0 In", + "page": 7, + "usage": 98, + }, + { + "label": ". Dl", + "page": 7, + "usage": 99, + }, + { + "label": "NUBS", + "page": 7, + "usage": 100, + }, + { + "label": "Menu", + "page": 7, + "usage": 101, + }, + { + "label": "Power", + "page": 7, + "usage": 102, + }, + { + "label": "=", + "page": 7, + "usage": 103, + }, + { + "label": "Keyboard F13", + "page": 7, + "usage": 104, + }, + { + "label": "Keyboard F14", + "page": 7, + "usage": 105, + }, + { + "label": "Keyboard F15", + "page": 7, + "usage": 106, + }, + { + "label": "Keyboard F16", + "page": 7, + "usage": 107, + }, + { + "label": "Keyboard F17", + "page": 7, + "usage": 108, + }, + { + "label": "Keyboard F18", + "page": 7, + "usage": 109, + }, + { + "label": "Keyboard F19", + "page": 7, + "usage": 110, + }, + { + "label": "Keyboard F20", + "page": 7, + "usage": 111, + }, + { + "label": "Keyboard F21", + "page": 7, + "usage": 112, + }, + { + "label": "Keyboard F22", + "page": 7, + "usage": 113, + }, + { + "label": "Keyboard F23", + "page": 7, + "usage": 114, + }, + { + "label": "Keyboard F24", + "page": 7, + "usage": 115, + }, + { + "label": "Keyboard Execute", + "page": 7, + "usage": 116, + }, + { + "label": "Keyboard Help", + "page": 7, + "usage": 117, + }, + { + "label": "Keyboard Menu", + "page": 7, + "usage": 118, + }, + { + "label": "Keyboard Select", + "page": 7, + "usage": 119, + }, + { + "label": "Keyboard Stop", + "page": 7, + "usage": 120, + }, + { + "label": "Keyboard Again", + "page": 7, + "usage": 121, + }, + { + "label": "Keyboard Undo", + "page": 7, + "usage": 122, + }, + { + "label": "Keyboard Cut", + "page": 7, + "usage": 123, + }, + { + "label": "Keyboard Copy", + "page": 7, + "usage": 124, + }, + { + "label": "Keyboard Paste", + "page": 7, + "usage": 125, + }, + { + "label": "Keyboard Find", + "page": 7, + "usage": 126, + }, + { + "label": "Keyboard Mute", + "page": 7, + "usage": 127, + }, + { + "label": "Keyboard Volume Up", + "page": 7, + "usage": 128, + }, + { + "label": "Keyboard Volume Down", + "page": 7, + "usage": 129, + }, + { + "label": "Keyboard Locking Caps Lock", + "page": 7, + "usage": 130, + }, + { + "label": "Keyboard Locking Num Lock", + "page": 7, + "usage": 131, + }, + { + "label": "Keyboard Locking Scroll Lock", + "page": 7, + "usage": 132, + }, + { + "label": ",", + "page": 7, + "usage": 133, + }, + { + "label": "Keypad Equal Sign", + "page": 7, + "usage": 134, + }, + { + "label": "Intl1", + "page": 7, + "usage": 135, + }, + { + "label": "Intl2", + "page": 7, + "usage": 136, + }, + { + "label": "Intl3", + "page": 7, + "usage": 137, + }, + { + "label": "Intl4", + "page": 7, + "usage": 138, + }, + { + "label": "Intl5", + "page": 7, + "usage": 139, + }, + { + "label": "Intl6", + "page": 7, + "usage": 140, + }, + { + "label": "Intl7", + "page": 7, + "usage": 141, + }, + { + "label": "Intl8", + "page": 7, + "usage": 142, + }, + { + "label": "Intl9", + "page": 7, + "usage": 143, + }, + { + "label": "Lang1", + "page": 7, + "usage": 144, + }, + { + "label": "Lang2", + "page": 7, + "usage": 145, + }, + { + "label": "Lang3", + "page": 7, + "usage": 146, + }, + { + "label": "Lang4", + "page": 7, + "usage": 147, + }, + { + "label": "Lang5", + "page": 7, + "usage": 148, + }, + { + "label": "Lang6", + "page": 7, + "usage": 149, + }, + { + "label": "Lang7", + "page": 7, + "usage": 150, + }, + { + "label": "Lang8", + "page": 7, + "usage": 151, + }, + { + "label": "Lang9", + "page": 7, + "usage": 152, + }, + { + "label": "Keyboard Alternate Erase", + "page": 7, + "usage": 153, + }, + { + "label": "Keyboard SysReq Attention", + "page": 7, + "usage": 154, + }, + { + "label": "Keyboard Cancel", + "page": 7, + "usage": 155, + }, + { + "label": "Keyboard Clear", + "page": 7, + "usage": 156, + }, + { + "label": "Keyboard Prior", + "page": 7, + "usage": 157, + }, + { + "label": "Keyboard Return", + "page": 7, + "usage": 158, + }, + { + "label": "Keyboard Separator", + "page": 7, + "usage": 159, + }, + { + "label": "Keyboard Out", + "page": 7, + "usage": 160, + }, + { + "label": "Keyboard Oper", + "page": 7, + "usage": 161, + }, + { + "label": "Keyboard Clear Again", + "page": 7, + "usage": 162, + }, + { + "label": "Keyboard CrSel Props", + "page": 7, + "usage": 163, + }, + { + "label": "Keyboard ExSel", + "page": 7, + "usage": 164, + }, + { + "label": "00", + "page": 7, + "usage": 176, + }, + { + "label": "000", + "page": 7, + "usage": 177, + }, + { + "label": "Thousands Separator", + "page": 7, + "usage": 178, + }, + { + "label": "Decimal Separator", + "page": 7, + "usage": 179, + }, + { + "label": "Currency Unit", + "page": 7, + "usage": 180, + }, + { + "label": "Currency Sub-unit", + "page": 7, + "usage": 181, + }, + { + "label": "Keypad Left Bracket", + "page": 7, + "usage": 182, + }, + { + "label": "Keypad Right Bracket", + "page": 7, + "usage": 183, + }, + { + "label": "Keypad Left Brace", + "page": 7, + "usage": 184, + }, + { + "label": "Keypad Right Brace", + "page": 7, + "usage": 185, + }, + { + "label": "Keypad Tab", + "page": 7, + "usage": 186, + }, + { + "label": "Keypad Backspace", + "page": 7, + "usage": 187, + }, + { + "label": "Keypad A", + "page": 7, + "usage": 188, + }, + { + "label": "Keypad B", + "page": 7, + "usage": 189, + }, + { + "label": "Keypad C", + "page": 7, + "usage": 190, + }, + { + "label": "Keypad D", + "page": 7, + "usage": 191, + }, + { + "label": "Keypad E", + "page": 7, + "usage": 192, + }, + { + "label": "Keypad F", + "page": 7, + "usage": 193, + }, + { + "label": "Keypad XOR", + "page": 7, + "usage": 194, + }, + { + "label": "Keypad Caret", + "page": 7, + "usage": 195, + }, + { + "label": "Keypad Percentage", + "page": 7, + "usage": 196, + }, + { + "label": "Keypad Less", + "page": 7, + "usage": 197, + }, + { + "label": "Keypad Greater", + "page": 7, + "usage": 198, + }, + { + "label": "Keypad Ampersand", + "page": 7, + "usage": 199, + }, + { + "label": "Keypad Double Ampersand", + "page": 7, + "usage": 200, + }, + { + "label": "Keypad Bar", + "page": 7, + "usage": 201, + }, + { + "label": "Keypad Double Bar", + "page": 7, + "usage": 202, + }, + { + "label": "Keypad Colon", + "page": 7, + "usage": 203, + }, + { + "label": "Keypad Hash", + "page": 7, + "usage": 204, + }, + { + "label": "Keypad Space", + "page": 7, + "usage": 205, + }, + { + "label": "Keypad At", + "page": 7, + "usage": 206, + }, + { + "label": "Keypad Bang", + "page": 7, + "usage": 207, + }, + { + "label": "Keypad Memory Store", + "page": 7, + "usage": 208, + }, + { + "label": "Keypad Memory Recall", + "page": 7, + "usage": 209, + }, + { + "label": "Keypad Memory Clear", + "page": 7, + "usage": 210, + }, + { + "label": "Keypad Memory Add", + "page": 7, + "usage": 211, + }, + { + "label": "Keypad Memory Subtract", + "page": 7, + "usage": 212, + }, + { + "label": "Keypad Memory Multiply", + "page": 7, + "usage": 213, + }, + { + "label": "Keypad Memory Divide", + "page": 7, + "usage": 214, + }, + { + "label": "Keypad Plus Minus", + "page": 7, + "usage": 215, + }, + { + "label": "Keypad Clear", + "page": 7, + "usage": 216, + }, + { + "label": "Keypad Clear Entry", + "page": 7, + "usage": 217, + }, + { + "label": "Keypad Binary", + "page": 7, + "usage": 218, + }, + { + "label": "Keypad Octal", + "page": 7, + "usage": 219, + }, + { + "label": "Keypad Decimal", + "page": 7, + "usage": 220, + }, + { + "label": "Keypad Hexadecimal", + "page": 7, + "usage": 221, + }, + { + "label": "Ctrl", + "page": 7, + "usage": 224, + }, + { + "label": "Shft", + "page": 7, + "usage": 225, + }, + { + "label": "Alt", + "page": 7, + "usage": 226, + }, + { + "label": "GUI", + "page": 7, + "usage": 227, + }, + { + "label": "Ctrl", + "page": 7, + "usage": 228, + }, + { + "label": "Shft", + "page": 7, + "usage": 229, + }, + { + "label": "AltG", + "page": 7, + "usage": 230, + }, + { + "label": "GUI", + "page": 7, + "usage": 231, + }, + { + "label": "Consumer Control", + "page": 12, + "usage": 1, + }, + { + "label": "Numeric Key Pad", + "page": 12, + "usage": 2, + }, + { + "label": "Programmable Buttons", + "page": 12, + "usage": 3, + }, + { + "label": "Microphone", + "page": 12, + "usage": 4, + }, + { + "label": "Headphone", + "page": 12, + "usage": 5, + }, + { + "label": "Graphic Equalizer", + "page": 12, + "usage": 6, + }, + { + "label": "+10", + "page": 12, + "usage": 32, + }, + { + "label": "+100", + "page": 12, + "usage": 33, + }, + { + "label": "AM/PM", + "page": 12, + "usage": 34, + }, + { + "label": "Power", + "page": 12, + "usage": 48, + }, + { + "label": "Reset", + "page": 12, + "usage": 49, + }, + { + "label": "Sleep", + "page": 12, + "usage": 50, + }, + { + "label": "Sleep After", + "page": 12, + "usage": 51, + }, + { + "label": "Sleep Mode", + "page": 12, + "usage": 52, + }, + { + "label": "Illumination", + "page": 12, + "usage": 53, + }, + { + "label": "Function Buttons", + "page": 12, + "usage": 54, + }, + { + "label": "Menu", + "page": 12, + "usage": 64, + }, + { + "label": "Menu Pick", + "page": 12, + "usage": 65, + }, + { + "label": "Menu Up", + "page": 12, + "usage": 66, + }, + { + "label": "Menu Down", + "page": 12, + "usage": 67, + }, + { + "label": "Menu Left", + "page": 12, + "usage": 68, + }, + { + "label": "Menu Right", + "page": 12, + "usage": 69, + }, + { + "label": "Menu Escape", + "page": 12, + "usage": 70, + }, + { + "label": "Menu Value Increase", + "page": 12, + "usage": 71, + }, + { + "label": "Menu Value Decrease", + "page": 12, + "usage": 72, + }, + { + "label": "Data On Screen", + "page": 12, + "usage": 96, + }, + { + "label": "Closed Caption", + "page": 12, + "usage": 97, + }, + { + "label": "Closed Caption Select", + "page": 12, + "usage": 98, + }, + { + "label": "VCR/TV", + "page": 12, + "usage": 99, + }, + { + "label": "Broadcast Mode", + "page": 12, + "usage": 100, + }, + { + "label": "Snapshot", + "page": 12, + "usage": 101, + }, + { + "label": "Still", + "page": 12, + "usage": 102, + }, + { + "label": "Picture-in-Picture Toggle", + "page": 12, + "usage": 103, + }, + { + "label": "Picture-in-Picture Swap", + "page": 12, + "usage": 104, + }, + { + "label": "Red Menu Button", + "page": 12, + "usage": 105, + }, + { + "label": "Green Menu Button", + "page": 12, + "usage": 106, + }, + { + "label": "Blue Menu Button", + "page": 12, + "usage": 107, + }, + { + "label": "Yellow Menu Button", + "page": 12, + "usage": 108, + }, + { + "label": "Aspect", + "page": 12, + "usage": 109, + }, + { + "label": "3D Mode Select", + "page": 12, + "usage": 110, + }, + { + "label": "🔆", + "page": 12, + "usage": 111, + }, + { + "label": "🔅", + "page": 12, + "usage": 112, + }, + { + "label": "Display Brightness", + "page": 12, + "usage": 113, + }, + { + "label": "Display Backlight Toggle", + "page": 12, + "usage": 114, + }, + { + "label": "Display Set Brightness to Minimum", + "page": 12, + "usage": 115, + }, + { + "label": "Display Set Brightness to Maximum", + "page": 12, + "usage": 116, + }, + { + "label": "Display Set Auto Brightness", + "page": 12, + "usage": 117, + }, + { + "label": "Camera Access Enabled", + "page": 12, + "usage": 118, + }, + { + "label": "Camera Access Disabled", + "page": 12, + "usage": 119, + }, + { + "label": "Camera Access Toggle", + "page": 12, + "usage": 120, + }, + { + "label": "Keyboard Brightness Increment", + "page": 12, + "usage": 121, + }, + { + "label": "Keyboard Brightness Decrement", + "page": 12, + "usage": 122, + }, + { + "label": "Keyboard Backlight Set Level", + "page": 12, + "usage": 123, + }, + { + "label": "Keyboard Backlight OOC", + "page": 12, + "usage": 124, + }, + { + "label": "Keyboard Backlight Set Minimum", + "page": 12, + "usage": 125, + }, + { + "label": "Keyboard Backlight Set Maximum", + "page": 12, + "usage": 126, + }, + { + "label": "Keyboard Backlight Auto", + "page": 12, + "usage": 127, + }, + { + "label": "Selection", + "page": 12, + "usage": 128, + }, + { + "label": "Assign Selection", + "page": 12, + "usage": 129, + }, + { + "label": "Mode Step", + "page": 12, + "usage": 130, + }, + { + "label": "Recall Last", + "page": 12, + "usage": 131, + }, + { + "label": "Enter Channel", + "page": 12, + "usage": 132, + }, + { + "label": "Order Movie", + "page": 12, + "usage": 133, + }, + { + "label": "Channel", + "page": 12, + "usage": 134, + }, + { + "label": "Media Selection", + "page": 12, + "usage": 135, + }, + { + "label": "Media Select Computer", + "page": 12, + "usage": 136, + }, + { + "label": "Media Select TV", + "page": 12, + "usage": 137, + }, + { + "label": "Media Select WWW", + "page": 12, + "usage": 138, + }, + { + "label": "Media Select DVD", + "page": 12, + "usage": 139, + }, + { + "label": "Media Select Telephone", + "page": 12, + "usage": 140, + }, + { + "label": "Media Select Program Guide", + "page": 12, + "usage": 141, + }, + { + "label": "Media Select Video Phone", + "page": 12, + "usage": 142, + }, + { + "label": "Media Select Games", + "page": 12, + "usage": 143, + }, + { + "label": "Media Select Messages", + "page": 12, + "usage": 144, + }, + { + "label": "Media Select CD", + "page": 12, + "usage": 145, + }, + { + "label": "Media Select VCR", + "page": 12, + "usage": 146, + }, + { + "label": "Media Select Tuner", + "page": 12, + "usage": 147, + }, + { + "label": "Quit", + "page": 12, + "usage": 148, + }, + { + "label": "Help", + "page": 12, + "usage": 149, + }, + { + "label": "Media Select Tape", + "page": 12, + "usage": 150, + }, + { + "label": "Media Select Cable", + "page": 12, + "usage": 151, + }, + { + "label": "Media Select Satellite", + "page": 12, + "usage": 152, + }, + { + "label": "Media Select Security", + "page": 12, + "usage": 153, + }, + { + "label": "Media Select Home", + "page": 12, + "usage": 154, + }, + { + "label": "Media Select Call", + "page": 12, + "usage": 155, + }, + { + "label": "Channel Increment", + "page": 12, + "usage": 156, + }, + { + "label": "Channel Decrement", + "page": 12, + "usage": 157, + }, + { + "label": "Media Select SAP", + "page": 12, + "usage": 158, + }, + { + "label": "VCR Plus", + "page": 12, + "usage": 160, + }, + { + "label": "Once", + "page": 12, + "usage": 161, + }, + { + "label": "Daily", + "page": 12, + "usage": 162, + }, + { + "label": "Weekly", + "page": 12, + "usage": 163, + }, + { + "label": "Monthly", + "page": 12, + "usage": 164, + }, + { + "label": "Play", + "page": 12, + "usage": 176, + }, + { + "label": "Pause", + "page": 12, + "usage": 177, + }, + { + "label": "Record", + "page": 12, + "usage": 178, + }, + { + "label": "Fast Forward", + "page": 12, + "usage": 179, + }, + { + "label": "Rewind", + "page": 12, + "usage": 180, + }, + { + "label": "⇥", + "page": 12, + "usage": 181, + }, + { + "label": "⇤", + "page": 12, + "usage": 182, + }, + { + "label": "Stop", + "page": 12, + "usage": 183, + }, + { + "label": "Eject", + "page": 12, + "usage": 184, + }, + { + "label": "Random Play", + "page": 12, + "usage": 185, + }, + { + "label": "Select Disc", + "page": 12, + "usage": 186, + }, + { + "label": "Enter Disc", + "page": 12, + "usage": 187, + }, + { + "label": "Repeat", + "page": 12, + "usage": 188, + }, + { + "label": "Tracking", + "page": 12, + "usage": 189, + }, + { + "label": "Track Normal", + "page": 12, + "usage": 190, + }, + { + "label": "Slow Tracking", + "page": 12, + "usage": 191, + }, + { + "label": "Frame Forward", + "page": 12, + "usage": 192, + }, + { + "label": "Frame Back", + "page": 12, + "usage": 193, + }, + { + "label": "Mark", + "page": 12, + "usage": 194, + }, + { + "label": "Clear Mark", + "page": 12, + "usage": 195, + }, + { + "label": "Repeat From Mark", + "page": 12, + "usage": 196, + }, + { + "label": "Return To Mark", + "page": 12, + "usage": 197, + }, + { + "label": "Search Mark Forward", + "page": 12, + "usage": 198, + }, + { + "label": "Search Mark Backwards", + "page": 12, + "usage": 199, + }, + { + "label": "Counter Reset", + "page": 12, + "usage": 200, + }, + { + "label": "Show Counter", + "page": 12, + "usage": 201, + }, + { + "label": "Tracking Increment", + "page": 12, + "usage": 202, + }, + { + "label": "Tracking Decrement", + "page": 12, + "usage": 203, + }, + { + "label": "Stop/Eject", + "page": 12, + "usage": 204, + }, + { + "label": "⏯️", + "page": 12, + "usage": 205, + }, + { + "label": "Play/Skip", + "page": 12, + "usage": 206, + }, + { + "label": "Voice Command", + "page": 12, + "usage": 207, + }, + { + "label": "Invoke Capture Interface", + "page": 12, + "usage": 208, + }, + { + "label": "Start or Stop Game Recording", + "page": 12, + "usage": 209, + }, + { + "label": "Historical Game Capture", + "page": 12, + "usage": 210, + }, + { + "label": "Capture Game Screenshot", + "page": 12, + "usage": 211, + }, + { + "label": "Show or Hide Recording Indicator", + "page": 12, + "usage": 212, + }, + { + "label": "Start or Stop Microphone Capture", + "page": 12, + "usage": 213, + }, + { + "label": "Start or Stop Camera Capture", + "page": 12, + "usage": 214, + }, + { + "label": "Start or Stop Game Broadcast", + "page": 12, + "usage": 215, + }, + { + "label": "Start or Stop Voice Dictation Session", + "page": 12, + "usage": 216, + }, + { + "label": "Invoke/Dismiss Emoji Picker", + "page": 12, + "usage": 217, + }, + { + "label": "Volume", + "page": 12, + "usage": 224, + }, + { + "label": "Balance", + "page": 12, + "usage": 225, + }, + { + "label": "🔇", + "page": 12, + "usage": 226, + }, + { + "label": "Bass", + "page": 12, + "usage": 227, + }, + { + "label": "Treble", + "page": 12, + "usage": 228, + }, + { + "label": "Bass Boost", + "page": 12, + "usage": 229, + }, + { + "label": "Surround Mode", + "page": 12, + "usage": 230, + }, + { + "label": "Loudness", + "page": 12, + "usage": 231, + }, + { + "label": "MPX", + "page": 12, + "usage": 232, + }, + { + "label": "🔊", + "page": 12, + "usage": 233, + }, + { + "label": "🔉", + "page": 12, + "usage": 234, + }, + { + "label": "Speed Select", + "page": 12, + "usage": 240, + }, + { + "label": "Playback Speed", + "page": 12, + "usage": 241, + }, + { + "label": "Standard Play", + "page": 12, + "usage": 242, + }, + { + "label": "Long Play", + "page": 12, + "usage": 243, + }, + { + "label": "Extended Play", + "page": 12, + "usage": 244, + }, + { + "label": "Slow", + "page": 12, + "usage": 245, + }, + { + "label": "Fan Enable", + "page": 12, + "usage": 256, + }, + { + "label": "Fan Speed", + "page": 12, + "usage": 257, + }, + { + "label": "Light Enable", + "page": 12, + "usage": 258, + }, + { + "label": "Light Illumination Level", + "page": 12, + "usage": 259, + }, + { + "label": "Climate Control Enable", + "page": 12, + "usage": 260, + }, + { + "label": "Room Temperature", + "page": 12, + "usage": 261, + }, + { + "label": "Security Enable", + "page": 12, + "usage": 262, + }, + { + "label": "Fire Alarm", + "page": 12, + "usage": 263, + }, + { + "label": "Police Alarm", + "page": 12, + "usage": 264, + }, + { + "label": "Proximity", + "page": 12, + "usage": 265, + }, + { + "label": "Motion", + "page": 12, + "usage": 266, + }, + { + "label": "Duress Alarm", + "page": 12, + "usage": 267, + }, + { + "label": "Holdup Alarm", + "page": 12, + "usage": 268, + }, + { + "label": "Medical Alarm", + "page": 12, + "usage": 269, + }, + { + "label": "Balance Right", + "page": 12, + "usage": 336, + }, + { + "label": "Balance Left", + "page": 12, + "usage": 337, + }, + { + "label": "Bass Increment", + "page": 12, + "usage": 338, + }, + { + "label": "Bass Decrement", + "page": 12, + "usage": 339, + }, + { + "label": "Treble Increment", + "page": 12, + "usage": 340, + }, + { + "label": "Treble Decrement", + "page": 12, + "usage": 341, + }, + { + "label": "Speaker System", + "page": 12, + "usage": 352, + }, + { + "label": "Channel Left", + "page": 12, + "usage": 353, + }, + { + "label": "Channel Right", + "page": 12, + "usage": 354, + }, + { + "label": "Channel Center", + "page": 12, + "usage": 355, + }, + { + "label": "Channel Front", + "page": 12, + "usage": 356, + }, + { + "label": "Channel Center Front", + "page": 12, + "usage": 357, + }, + { + "label": "Channel Side", + "page": 12, + "usage": 358, + }, + { + "label": "Channel Surround", + "page": 12, + "usage": 359, + }, + { + "label": "Channel Low Frequency Enhancement", + "page": 12, + "usage": 360, + }, + { + "label": "Channel Top", + "page": 12, + "usage": 361, + }, + { + "label": "Channel Unknown", + "page": 12, + "usage": 362, + }, + { + "label": "Sub-channel", + "page": 12, + "usage": 368, + }, + { + "label": "Sub-channel Increment", + "page": 12, + "usage": 369, + }, + { + "label": "Sub-channel Decrement", + "page": 12, + "usage": 370, + }, + { + "label": "Alternate Audio Increment", + "page": 12, + "usage": 371, + }, + { + "label": "Alternate Audio Decrement", + "page": 12, + "usage": 372, + }, + { + "label": "Application Launch Buttons", + "page": 12, + "usage": 384, + }, + { + "label": "AL Launch Button Configuration Tool", + "page": 12, + "usage": 385, + }, + { + "label": "AL Programmable Button Configuration", + "page": 12, + "usage": 386, + }, + { + "label": "AL Consumer Control Configuration", + "page": 12, + "usage": 387, + }, + { + "label": "AL Word Processor", + "page": 12, + "usage": 388, + }, + { + "label": "AL Text Editor", + "page": 12, + "usage": 389, + }, + { + "label": "AL Spreadsheet", + "page": 12, + "usage": 390, + }, + { + "label": "AL Graphics Editor", + "page": 12, + "usage": 391, + }, + { + "label": "AL Presentation App", + "page": 12, + "usage": 392, + }, + { + "label": "AL Database App", + "page": 12, + "usage": 393, + }, + { + "label": "AL Email Reader", + "page": 12, + "usage": 394, + }, + { + "label": "AL Newsreader", + "page": 12, + "usage": 395, + }, + { + "label": "AL Voicemail", + "page": 12, + "usage": 396, + }, + { + "label": "AL Contacts/Address Book", + "page": 12, + "usage": 397, + }, + { + "label": "AL Calendar/Schedule", + "page": 12, + "usage": 398, + }, + { + "label": "AL Task/Project Manager", + "page": 12, + "usage": 399, + }, + { + "label": "AL Log/Journal/Timecard", + "page": 12, + "usage": 400, + }, + { + "label": "AL Checkbook/Finance", + "page": 12, + "usage": 401, + }, + { + "label": "AL Calculator", + "page": 12, + "usage": 402, + }, + { + "label": "AL A/V Capture/Playback", + "page": 12, + "usage": 403, + }, + { + "label": "AL Local Machine Browser", + "page": 12, + "usage": 404, + }, + { + "label": "AL LAN/WAN Browser", + "page": 12, + "usage": 405, + }, + { + "label": "AL Internet Browser", + "page": 12, + "usage": 406, + }, + { + "label": "AL Remote Networking/ISP Connect", + "page": 12, + "usage": 407, + }, + { + "label": "AL Network Conference", + "page": 12, + "usage": 408, + }, + { + "label": "AL Network Chat", + "page": 12, + "usage": 409, + }, + { + "label": "AL Telephony/Dialer", + "page": 12, + "usage": 410, + }, + { + "label": "AL Logon", + "page": 12, + "usage": 411, + }, + { + "label": "AL Logoff", + "page": 12, + "usage": 412, + }, + { + "label": "AL Logon/Logoff", + "page": 12, + "usage": 413, + }, + { + "label": "AL Terminal Lock/Screensaver", + "page": 12, + "usage": 414, + }, + { + "label": "AL Control Panel", + "page": 12, + "usage": 415, + }, + { + "label": "AL Command Line Processor/Run", + "page": 12, + "usage": 416, + }, + { + "label": "AL Process/Task Manager", + "page": 12, + "usage": 417, + }, + { + "label": "AL Select Task/Application", + "page": 12, + "usage": 418, + }, + { + "label": "AL Next Task/Application", + "page": 12, + "usage": 419, + }, + { + "label": "AL Previous Task/Application", + "page": 12, + "usage": 420, + }, + { + "label": "AL Preemptive Halt Task/Application", + "page": 12, + "usage": 421, + }, + { + "label": "AL Integrated Help Center", + "page": 12, + "usage": 422, + }, + { + "label": "AL Documents", + "page": 12, + "usage": 423, + }, + { + "label": "AL Thesaurus", + "page": 12, + "usage": 424, + }, + { + "label": "AL Dictionary", + "page": 12, + "usage": 425, + }, + { + "label": "AL Desktop", + "page": 12, + "usage": 426, + }, + { + "label": "AL Spell Check", + "page": 12, + "usage": 427, + }, + { + "label": "AL Grammar Check", + "page": 12, + "usage": 428, + }, + { + "label": "AL Wireless Status", + "page": 12, + "usage": 429, + }, + { + "label": "AL Keyboard Layout", + "page": 12, + "usage": 430, + }, + { + "label": "AL Virus Protection", + "page": 12, + "usage": 431, + }, + { + "label": "AL Encryption", + "page": 12, + "usage": 432, + }, + { + "label": "AL Screen Saver", + "page": 12, + "usage": 433, + }, + { + "label": "AL Alarms", + "page": 12, + "usage": 434, + }, + { + "label": "AL Clock", + "page": 12, + "usage": 435, + }, + { + "label": "AL File Browser", + "page": 12, + "usage": 436, + }, + { + "label": "AL Power Status", + "page": 12, + "usage": 437, + }, + { + "label": "AL Image Browser", + "page": 12, + "usage": 438, + }, + { + "label": "AL Audio Browser", + "page": 12, + "usage": 439, + }, + { + "label": "AL Movie Browser", + "page": 12, + "usage": 440, + }, + { + "label": "AL Digital Rights Manager", + "page": 12, + "usage": 441, + }, + { + "label": "AL Digital Wallet", + "page": 12, + "usage": 442, + }, + { + "label": "AL Instant Messaging", + "page": 12, + "usage": 444, + }, + { + "label": "AL OEM Features/ Tips/Tutorial Browser", + "page": 12, + "usage": 445, + }, + { + "label": "AL OEM Help", + "page": 12, + "usage": 446, + }, + { + "label": "AL Online Community", + "page": 12, + "usage": 447, + }, + { + "label": "AL Entertainment Content Browser", + "page": 12, + "usage": 448, + }, + { + "label": "AL Online Shopping Browser", + "page": 12, + "usage": 449, + }, + { + "label": "AL SmartCard Information/Help", + "page": 12, + "usage": 450, + }, + { + "label": "AL Market Monitor/Finance Browser", + "page": 12, + "usage": 451, + }, + { + "label": "AL Customized Corporate News Browser", + "page": 12, + "usage": 452, + }, + { + "label": "AL Online Activity Browser", + "page": 12, + "usage": 453, + }, + { + "label": "AL Research/Search Browser", + "page": 12, + "usage": 454, + }, + { + "label": "AL Audio Player", + "page": 12, + "usage": 455, + }, + { + "label": "AL Message Status", + "page": 12, + "usage": 456, + }, + { + "label": "AL Contact Sync", + "page": 12, + "usage": 457, + }, + { + "label": "AL Navigation", + "page": 12, + "usage": 458, + }, + { + "label": "AL Context‐aware Desktop Assistant", + "page": 12, + "usage": 459, + }, + { + "label": "Generic GUI Application Controls", + "page": 12, + "usage": 512, + }, + { + "label": "AC New", + "page": 12, + "usage": 513, + }, + { + "label": "AC Open", + "page": 12, + "usage": 514, + }, + { + "label": "AC Close", + "page": 12, + "usage": 515, + }, + { + "label": "AC Exit", + "page": 12, + "usage": 516, + }, + { + "label": "AC Maximize", + "page": 12, + "usage": 517, + }, + { + "label": "AC Minimize", + "page": 12, + "usage": 518, + }, + { + "label": "AC Save", + "page": 12, + "usage": 519, + }, + { + "label": "AC Print", + "page": 12, + "usage": 520, + }, + { + "label": "AC Properties", + "page": 12, + "usage": 521, + }, + { + "label": "AC Undo", + "page": 12, + "usage": 538, + }, + { + "label": "AC Copy", + "page": 12, + "usage": 539, + }, + { + "label": "AC Cut", + "page": 12, + "usage": 540, + }, + { + "label": "AC Paste", + "page": 12, + "usage": 541, + }, + { + "label": "AC Select All", + "page": 12, + "usage": 542, + }, + { + "label": "AC Find", + "page": 12, + "usage": 543, + }, + { + "label": "AC Find and Replace", + "page": 12, + "usage": 544, + }, + { + "label": "AC Search", + "page": 12, + "usage": 545, + }, + { + "label": "AC Go To", + "page": 12, + "usage": 546, + }, + { + "label": "AC Home", + "page": 12, + "usage": 547, + }, + { + "label": "AC Back", + "page": 12, + "usage": 548, + }, + { + "label": "AC Forward", + "page": 12, + "usage": 549, + }, + { + "label": "AC Stop", + "page": 12, + "usage": 550, + }, + { + "label": "AC Refresh", + "page": 12, + "usage": 551, + }, + { + "label": "AC Previous Link", + "page": 12, + "usage": 552, + }, + { + "label": "AC Next Link", + "page": 12, + "usage": 553, + }, + { + "label": "AC Bookmarks", + "page": 12, + "usage": 554, + }, + { + "label": "AC History", + "page": 12, + "usage": 555, + }, + { + "label": "AC Subscriptions", + "page": 12, + "usage": 556, + }, + { + "label": "AC Zoom In", + "page": 12, + "usage": 557, + }, + { + "label": "AC Zoom Out", + "page": 12, + "usage": 558, + }, + { + "label": "AC Zoom", + "page": 12, + "usage": 559, + }, + { + "label": "AC Full Screen View", + "page": 12, + "usage": 560, + }, + { + "label": "AC Normal View", + "page": 12, + "usage": 561, + }, + { + "label": "AC View Toggle", + "page": 12, + "usage": 562, + }, + { + "label": "AC Scroll Up", + "page": 12, + "usage": 563, + }, + { + "label": "AC Scroll Down", + "page": 12, + "usage": 564, + }, + { + "label": "AC Scroll", + "page": 12, + "usage": 565, + }, + { + "label": "AC Pan Left", + "page": 12, + "usage": 566, + }, + { + "label": "AC Pan Right", + "page": 12, + "usage": 567, + }, + { + "label": "AC Pan", + "page": 12, + "usage": 568, + }, + { + "label": "AC New Window", + "page": 12, + "usage": 569, + }, + { + "label": "AC Tile Horizontally", + "page": 12, + "usage": 570, + }, + { + "label": "AC Tile Vertically", + "page": 12, + "usage": 571, + }, + { + "label": "AC Format", + "page": 12, + "usage": 572, + }, + { + "label": "AC Edit", + "page": 12, + "usage": 573, + }, + { + "label": "AC Bold", + "page": 12, + "usage": 574, + }, + { + "label": "AC Italics", + "page": 12, + "usage": 575, + }, + { + "label": "AC Underline", + "page": 12, + "usage": 576, + }, + { + "label": "AC Strikethrough", + "page": 12, + "usage": 577, + }, + { + "label": "AC Subscript", + "page": 12, + "usage": 578, + }, + { + "label": "AC Superscript", + "page": 12, + "usage": 579, + }, + { + "label": "AC All Caps", + "page": 12, + "usage": 580, + }, + { + "label": "AC Rotate", + "page": 12, + "usage": 581, + }, + { + "label": "AC Resize", + "page": 12, + "usage": 582, + }, + { + "label": "AC Flip Horizontal", + "page": 12, + "usage": 583, + }, + { + "label": "AC Flip Vertical", + "page": 12, + "usage": 584, + }, + { + "label": "AC Mirror Horizontal", + "page": 12, + "usage": 585, + }, + { + "label": "AC Mirror Vertical", + "page": 12, + "usage": 586, + }, + { + "label": "AC Font Select", + "page": 12, + "usage": 587, + }, + { + "label": "AC Font Color", + "page": 12, + "usage": 588, + }, + { + "label": "AC Font Size", + "page": 12, + "usage": 589, + }, + { + "label": "AC Justify Left", + "page": 12, + "usage": 590, + }, + { + "label": "AC Justify Center H", + "page": 12, + "usage": 591, + }, + { + "label": "AC Justify Right", + "page": 12, + "usage": 592, + }, + { + "label": "AC Justify Block H", + "page": 12, + "usage": 593, + }, + { + "label": "AC Justify Top", + "page": 12, + "usage": 594, + }, + { + "label": "AC Justify Center V", + "page": 12, + "usage": 595, + }, + { + "label": "AC Justify Bottom", + "page": 12, + "usage": 596, + }, + { + "label": "AC Justify Block V", + "page": 12, + "usage": 597, + }, + { + "label": "AC Indent Decrease", + "page": 12, + "usage": 598, + }, + { + "label": "AC Indent Increase", + "page": 12, + "usage": 599, + }, + { + "label": "AC Numbered List", + "page": 12, + "usage": 600, + }, + { + "label": "AC Restart Numbering", + "page": 12, + "usage": 601, + }, + { + "label": "AC Bulleted List", + "page": 12, + "usage": 602, + }, + { + "label": "AC Promote", + "page": 12, + "usage": 603, + }, + { + "label": "AC Demote", + "page": 12, + "usage": 604, + }, + { + "label": "AC Yes", + "page": 12, + "usage": 605, + }, + { + "label": "AC No", + "page": 12, + "usage": 606, + }, + { + "label": "AC Cancel", + "page": 12, + "usage": 607, + }, + { + "label": "AC Catalog", + "page": 12, + "usage": 608, + }, + { + "label": "AC Buy/Checkout", + "page": 12, + "usage": 609, + }, + { + "label": "AC Add to Cart", + "page": 12, + "usage": 610, + }, + { + "label": "AC Expand", + "page": 12, + "usage": 611, + }, + { + "label": "AC Expand All", + "page": 12, + "usage": 612, + }, + { + "label": "AC Collapse", + "page": 12, + "usage": 613, + }, + { + "label": "AC Collapse All", + "page": 12, + "usage": 614, + }, + { + "label": "AC Print Preview", + "page": 12, + "usage": 615, + }, + { + "label": "AC Paste Special", + "page": 12, + "usage": 616, + }, + { + "label": "AC Insert Mode", + "page": 12, + "usage": 617, + }, + { + "label": "AC Delete", + "page": 12, + "usage": 618, + }, + { + "label": "AC Lock", + "page": 12, + "usage": 619, + }, + { + "label": "AC Unlock", + "page": 12, + "usage": 620, + }, + { + "label": "AC Protect", + "page": 12, + "usage": 621, + }, + { + "label": "AC Unprotect", + "page": 12, + "usage": 622, + }, + { + "label": "AC Attach Comment", + "page": 12, + "usage": 623, + }, + { + "label": "AC Delete Comment", + "page": 12, + "usage": 624, + }, + { + "label": "AC View Comment", + "page": 12, + "usage": 625, + }, + { + "label": "AC Select Word", + "page": 12, + "usage": 626, + }, + { + "label": "AC Select Sentence", + "page": 12, + "usage": 627, + }, + { + "label": "AC Select Paragraph", + "page": 12, + "usage": 628, + }, + { + "label": "AC Select Column", + "page": 12, + "usage": 629, + }, + { + "label": "AC Select Row", + "page": 12, + "usage": 630, + }, + { + "label": "AC Select Table", + "page": 12, + "usage": 631, + }, + { + "label": "AC Select Object", + "page": 12, + "usage": 632, + }, + { + "label": "AC Redo/Repeat", + "page": 12, + "usage": 633, + }, + { + "label": "AC Sort", + "page": 12, + "usage": 634, + }, + { + "label": "AC Sort Ascending", + "page": 12, + "usage": 635, + }, + { + "label": "AC Sort Descending", + "page": 12, + "usage": 636, + }, + { + "label": "AC Filter", + "page": 12, + "usage": 637, + }, + { + "label": "AC Set Clock", + "page": 12, + "usage": 638, + }, + { + "label": "AC View Clock", + "page": 12, + "usage": 639, + }, + { + "label": "AC Select Time Zone", + "page": 12, + "usage": 640, + }, + { + "label": "AC Edit Time Zones", + "page": 12, + "usage": 641, + }, + { + "label": "AC Set Alarm", + "page": 12, + "usage": 642, + }, + { + "label": "AC Clear Alarm", + "page": 12, + "usage": 643, + }, + { + "label": "AC Snooze Alarm", + "page": 12, + "usage": 644, + }, + { + "label": "AC Reset Alarm", + "page": 12, + "usage": 645, + }, + { + "label": "AC Synchronize", + "page": 12, + "usage": 646, + }, + { + "label": "AC Send/Receive", + "page": 12, + "usage": 647, + }, + { + "label": "AC Send To", + "page": 12, + "usage": 648, + }, + { + "label": "AC Reply", + "page": 12, + "usage": 649, + }, + { + "label": "AC Reply All", + "page": 12, + "usage": 650, + }, + { + "label": "AC Forward Msg", + "page": 12, + "usage": 651, + }, + { + "label": "AC Send", + "page": 12, + "usage": 652, + }, + { + "label": "AC Attach File", + "page": 12, + "usage": 653, + }, + { + "label": "AC Upload", + "page": 12, + "usage": 654, + }, + { + "label": "AC Download (Save Target As)", + "page": 12, + "usage": 655, + }, + { + "label": "AC Set Borders", + "page": 12, + "usage": 656, + }, + { + "label": "AC Insert Row", + "page": 12, + "usage": 657, + }, + { + "label": "AC Insert Column", + "page": 12, + "usage": 658, + }, + { + "label": "AC Insert File", + "page": 12, + "usage": 659, + }, + { + "label": "AC Insert Picture", + "page": 12, + "usage": 660, + }, + { + "label": "AC Insert Object", + "page": 12, + "usage": 661, + }, + { + "label": "AC Insert Symbol", + "page": 12, + "usage": 662, + }, + { + "label": "AC Save and Close", + "page": 12, + "usage": 663, + }, + { + "label": "AC Rename", + "page": 12, + "usage": 664, + }, + { + "label": "AC Merge", + "page": 12, + "usage": 665, + }, + { + "label": "AC Split", + "page": 12, + "usage": 666, + }, + { + "label": "AC Disribute Horizontally", + "page": 12, + "usage": 667, + }, + { + "label": "AC Distribute Vertically", + "page": 12, + "usage": 668, + }, + { + "label": "AC Next Keyboard Layout Select", + "page": 12, + "usage": 669, + }, + { + "label": "AC Navigation Guidance", + "page": 12, + "usage": 670, + }, + { + "label": "AC Desktop Show All Windows", + "page": 12, + "usage": 671, + }, + { + "label": "AC Soft Key Left", + "page": 12, + "usage": 672, + }, + { + "label": "AC Soft Key Right", + "page": 12, + "usage": 673, + }, + { + "label": "AC Desktop Show All Applications", + "page": 12, + "usage": 674, + }, + { + "label": "AC Idle Keep Alive", + "page": 12, + "usage": 688, + }, + { + "label": "Extended Keyboard Attributes Collection", + "page": 12, + "usage": 704, + }, + { + "label": "Keyboard Form Factor", + "page": 12, + "usage": 705, + }, + { + "label": "Keyboard Key Type", + "page": 12, + "usage": 706, + }, + { + "label": "Keyboard Physical Layout", + "page": 12, + "usage": 707, + }, + { + "label": "Vendor‐Specific Keyboard Physical Layout", + "page": 12, + "usage": 708, + }, + { + "label": "Keyboard IETF Language Tag Index", + "page": 12, + "usage": 709, + }, + { + "label": "Implemented Keyboard Input Assist Controls", + "page": 12, + "usage": 710, + }, + { + "label": "Keyboard Input Assist Previous", + "page": 12, + "usage": 711, + }, + { + "label": "Keyboard Input Assist Next", + "page": 12, + "usage": 712, + }, + { + "label": "Keyboard Input Assist Previous Group", + "page": 12, + "usage": 713, + }, + { + "label": "Keyboard Input Assist Next Group", + "page": 12, + "usage": 714, + }, + { + "label": "Keyboard Input Assist Accept", + "page": 12, + "usage": 715, + }, + { + "label": "Keyboard Input Assist Cancel", + "page": 12, + "usage": 716, + }, + { + "label": "Privacy Screen Toggle", + "page": 12, + "usage": 720, + }, + { + "label": "Privacy Screen Level Decrement", + "page": 12, + "usage": 721, + }, + { + "label": "Privacy Screen Level Increment", + "page": 12, + "usage": 722, + }, + { + "label": "Privacy Screen Level Minimum", + "page": 12, + "usage": 723, + }, + { + "label": "Privacy Screen Level Maximum", + "page": 12, + "usage": 724, + }, + { + "label": "Contact Edited", + "page": 12, + "usage": 1280, + }, + { + "label": "Contact Added", + "page": 12, + "usage": 1281, + }, + { + "label": "Contact Record Active", + "page": 12, + "usage": 1282, + }, + { + "label": "Contact Index", + "page": 12, + "usage": 1283, + }, + { + "label": "Contact Nickname", + "page": 12, + "usage": 1284, + }, + { + "label": "Contact First Name", + "page": 12, + "usage": 1285, + }, + { + "label": "Contact Last Name", + "page": 12, + "usage": 1286, + }, + { + "label": "Contact Full Name", + "page": 12, + "usage": 1287, + }, + { + "label": "Contact Phone Number Personal", + "page": 12, + "usage": 1288, + }, + { + "label": "Contact Phone Number Business", + "page": 12, + "usage": 1289, + }, + { + "label": "Contact Phone Number Mobile", + "page": 12, + "usage": 1290, + }, + { + "label": "Contact Phone Number Pager", + "page": 12, + "usage": 1291, + }, + { + "label": "Contact Phone Number Fax", + "page": 12, + "usage": 1292, + }, + { + "label": "Contact Phone Number Other", + "page": 12, + "usage": 1293, + }, + { + "label": "Contact Email Personal", + "page": 12, + "usage": 1294, + }, + { + "label": "Contact Email Business", + "page": 12, + "usage": 1295, + }, + { + "label": "Contact Email Other", + "page": 12, + "usage": 1296, + }, + { + "label": "Contact Email Main", + "page": 12, + "usage": 1297, + }, + { + "label": "Contact Speed Dial Number", + "page": 12, + "usage": 1298, + }, + { + "label": "Contact Status Flag", + "page": 12, + "usage": 1299, + }, + { + "label": "Contact Misc.", + "page": 12, + "usage": 1300, + }, +] +`; + +exports[`hid_usage_get_metadata > captures the full picker-label baseline (pre-SSOT snapshot) 1`] = ` +[ + { + "category": "Other", + "long": "ErrorRollOver", + "med": "ErrorRollOver", + "page": 7, + "short": "ErrorRollOver", + "usage": 1, + }, + { + "category": "Other", + "long": "POSTFail", + "med": "POSTFail", + "page": 7, + "short": "POSTFail", + "usage": 2, + }, + { + "category": "Other", + "long": "ErrorUndefined", + "med": "ErrorUndefined", + "page": 7, + "short": "ErrorUndefined", + "usage": 3, + }, + { + "category": "Letters", + "long": "Keyboard A", + "med": "A", + "page": 7, + "short": "A", + "usage": 4, + }, + { + "category": "Letters", + "long": "Keyboard B", + "med": "B", + "page": 7, + "short": "B", + "usage": 5, + }, + { + "category": "Letters", + "long": "Keyboard C", + "med": "C", + "page": 7, + "short": "C", + "usage": 6, + }, + { + "category": "Letters", + "long": "Keyboard D", + "med": "D", + "page": 7, + "short": "D", + "usage": 7, + }, + { + "category": "Letters", + "long": "Keyboard E", + "med": "E", + "page": 7, + "short": "E", + "usage": 8, + }, + { + "category": "Letters", + "long": "Keyboard F", + "med": "F", + "page": 7, + "short": "F", + "usage": 9, + }, + { + "category": "Letters", + "long": "Keyboard G", + "med": "G", + "page": 7, + "short": "G", + "usage": 10, + }, + { + "category": "Letters", + "long": "Keyboard H", + "med": "H", + "page": 7, + "short": "H", + "usage": 11, + }, + { + "category": "Letters", + "long": "Keyboard I", + "med": "I", + "page": 7, + "short": "I", + "usage": 12, + }, + { + "category": "Letters", + "long": "Keyboard J", + "med": "J", + "page": 7, + "short": "J", + "usage": 13, + }, + { + "category": "Letters", + "long": "Keyboard K", + "med": "K", + "page": 7, + "short": "K", + "usage": 14, + }, + { + "category": "Letters", + "long": "Keyboard L", + "med": "L", + "page": 7, + "short": "L", + "usage": 15, + }, + { + "category": "Letters", + "long": "Keyboard M", + "med": "M", + "page": 7, + "short": "M", + "usage": 16, + }, + { + "category": "Letters", + "long": "Keyboard N", + "med": "N", + "page": 7, + "short": "N", + "usage": 17, + }, + { + "category": "Letters", + "long": "Keyboard O", + "med": "O", + "page": 7, + "short": "O", + "usage": 18, + }, + { + "category": "Letters", + "long": "Keyboard P", + "med": "P", + "page": 7, + "short": "P", + "usage": 19, + }, + { + "category": "Letters", + "long": "Keyboard Q", + "med": "Q", + "page": 7, + "short": "Q", + "usage": 20, + }, + { + "category": "Letters", + "long": "Keyboard R", + "med": "R", + "page": 7, + "short": "R", + "usage": 21, + }, + { + "category": "Letters", + "long": "Keyboard S", + "med": "S", + "page": 7, + "short": "S", + "usage": 22, + }, + { + "category": "Letters", + "long": "Keyboard T", + "med": "T", + "page": 7, + "short": "T", + "usage": 23, + }, + { + "category": "Letters", + "long": "Keyboard U", + "med": "U", + "page": 7, + "short": "U", + "usage": 24, + }, + { + "category": "Letters", + "long": "Keyboard V", + "med": "V", + "page": 7, + "short": "V", + "usage": 25, + }, + { + "category": "Letters", + "long": "Keyboard W", + "med": "W", + "page": 7, + "short": "W", + "usage": 26, + }, + { + "category": "Letters", + "long": "Keyboard X", + "med": "X", + "page": 7, + "short": "X", + "usage": 27, + }, + { + "category": "Letters", + "long": "Keyboard Y", + "med": "Y", + "page": 7, + "short": "Y", + "usage": 28, + }, + { + "category": "Letters", + "long": "Keyboard Z", + "med": "Z", + "page": 7, + "short": "Z", + "usage": 29, + }, + { + "category": "Numbers + Punctuation", + "page": 7, + "short": "1 !", + "usage": 30, + }, + { + "category": "Numbers + Punctuation", + "page": 7, + "short": "2 @", + "usage": 31, + }, + { + "category": "Numbers + Punctuation", + "page": 7, + "short": "3 #", + "usage": 32, + }, + { + "category": "Numbers + Punctuation", + "page": 7, + "short": "4 $", + "usage": 33, + }, + { + "category": "Numbers + Punctuation", + "page": 7, + "short": "5 %", + "usage": 34, + }, + { + "category": "Numbers + Punctuation", + "page": 7, + "short": "6 ^", + "usage": 35, + }, + { + "category": "Numbers + Punctuation", + "page": 7, + "short": "7 &", + "usage": 36, + }, + { + "category": "Numbers + Punctuation", + "page": 7, + "short": "8 *", + "usage": 37, + }, + { + "category": "Numbers + Punctuation", + "page": 7, + "short": "9 (", + "usage": 38, + }, + { + "category": "Numbers + Punctuation", + "page": 7, + "short": "0 )", + "usage": 39, + }, + { + "category": "Function + Navigation", + "med": "Return", + "page": 7, + "short": "Ret", + "usage": 40, + }, + { + "category": "Function + Navigation", + "long": "Escape", + "page": 7, + "short": "Esc", + "usage": 41, + }, + { + "category": "Function + Navigation", + "long": "Backspace", + "med": "BkSpc", + "page": 7, + "short": "BkSp", + "usage": 42, + }, + { + "category": "Function + Navigation", + "long": "Keyboard Tab", + "med": "Tab", + "page": 7, + "short": "Tab", + "usage": 43, + }, + { + "category": "Function + Navigation", + "med": "Space", + "page": 7, + "short": "␣", + "usage": 44, + }, + { + "category": "Numbers + Punctuation", + "med": "Dash", + "page": 7, + "short": "- _", + "usage": 45, + }, + { + "category": "Numbers + Punctuation", + "med": "Equals", + "page": 7, + "short": "= +", + "usage": 46, + }, + { + "category": "Numbers + Punctuation", + "page": 7, + "short": "[ {", + "usage": 47, + }, + { + "category": "Numbers + Punctuation", + "page": 7, + "short": "] }", + "usage": 48, + }, + { + "category": "Numbers + Punctuation", + "page": 7, + "short": "\\ |", + "usage": 49, + }, + { + "category": "International", + "long": "NonUS Hash", + "page": 7, + "short": "NUHS", + "usage": 50, + }, + { + "category": "Numbers + Punctuation", + "page": 7, + "short": "; :", + "usage": 51, + }, + { + "category": "Numbers + Punctuation", + "page": 7, + "short": "' "", + "usage": 52, + }, + { + "category": "Numbers + Punctuation", + "page": 7, + "short": "\` ~", + "usage": 53, + }, + { + "category": "Numbers + Punctuation", + "page": 7, + "short": ", <", + "usage": 54, + }, + { + "category": "Numbers + Punctuation", + "page": 7, + "short": ". >", + "usage": 55, + }, + { + "category": "Numbers + Punctuation", + "page": 7, + "short": "/ ?", + "usage": 56, + }, + { + "category": "Function + Navigation", + "long": "Caps Lock", + "med": "CapsLk", + "page": 7, + "short": "Cap", + "usage": 57, + }, + { + "category": "Function + Navigation", + "long": "Keyboard F1", + "med": "F1", + "page": 7, + "short": "F1", + "usage": 58, + }, + { + "category": "Function + Navigation", + "long": "Keyboard F2", + "med": "F2", + "page": 7, + "short": "F2", + "usage": 59, + }, + { + "category": "Function + Navigation", + "long": "Keyboard F3", + "med": "F3", + "page": 7, + "short": "F3", + "usage": 60, + }, + { + "category": "Function + Navigation", + "long": "Keyboard F4", + "med": "F4", + "page": 7, + "short": "F4", + "usage": 61, + }, + { + "category": "Function + Navigation", + "long": "Keyboard F5", + "med": "F5", + "page": 7, + "short": "F5", + "usage": 62, + }, + { + "category": "Function + Navigation", + "long": "Keyboard F6", + "med": "F6", + "page": 7, + "short": "F6", + "usage": 63, + }, + { + "category": "Function + Navigation", + "long": "Keyboard F7", + "med": "F7", + "page": 7, + "short": "F7", + "usage": 64, + }, + { + "category": "Function + Navigation", + "long": "Keyboard F8", + "med": "F8", + "page": 7, + "short": "F8", + "usage": 65, + }, + { + "category": "Function + Navigation", + "long": "Keyboard F9", + "med": "F9", + "page": 7, + "short": "F9", + "usage": 66, + }, + { + "category": "Function + Navigation", + "long": "Keyboard F10", + "med": "F10", + "page": 7, + "short": "F10", + "usage": 67, + }, + { + "category": "Function + Navigation", + "long": "Keyboard F11", + "med": "F11", + "page": 7, + "short": "F11", + "usage": 68, + }, + { + "category": "Function + Navigation", + "long": "Keyboard F12", + "med": "F12", + "page": 7, + "short": "F12", + "usage": 69, + }, + { + "category": "Function + Navigation", + "long": "Print Scr", + "page": 7, + "short": "PrSc", + "usage": 70, + }, + { + "category": "Function + Navigation", + "long": "ScrollLock", + "page": 7, + "short": "ScLk", + "usage": 71, + }, + { + "category": "Function + Navigation", + "med": "Pause", + "page": 7, + "short": "Paus", + "usage": 72, + }, + { + "category": "Function + Navigation", + "med": "Insert", + "page": 7, + "short": "Ins", + "usage": 73, + }, + { + "category": "Function + Navigation", + "long": "Keyboard Home", + "med": "Home", + "page": 7, + "short": "Home", + "usage": 74, + }, + { + "category": "Function + Navigation", + "long": "Page Up", + "med": "PageUp", + "page": 7, + "short": "PgUp", + "usage": 75, + }, + { + "category": "Function + Navigation", + "med": "Delete", + "page": 7, + "short": "Del", + "usage": 76, + }, + { + "category": "Function + Navigation", + "long": "Keyboard End", + "med": "End", + "page": 7, + "short": "End", + "usage": 77, + }, + { + "category": "Function + Navigation", + "long": "Page Down", + "med": "PageDn", + "page": 7, + "short": "PgDn", + "usage": 78, + }, + { + "category": "Function + Navigation", + "page": 7, + "short": "→", + "usage": 79, + }, + { + "category": "Function + Navigation", + "page": 7, + "short": "←", + "usage": 80, + }, + { + "category": "Function + Navigation", + "page": 7, + "short": "↓", + "usage": 81, + }, + { + "category": "Function + Navigation", + "page": 7, + "short": "↑", + "usage": 82, + }, + { + "category": "Numpad", + "long": "Num Lock", + "med": "NumLck", + "page": 7, + "short": "Num", + "usage": 83, + }, + { + "category": "Numpad", + "page": 7, + "short": "/", + "usage": 84, + }, + { + "category": "Numpad", + "page": 7, + "short": "*", + "usage": 85, + }, + { + "category": "Numpad", + "page": 7, + "short": "-", + "usage": 86, + }, + { + "category": "Numpad", + "page": 7, + "short": "+", + "usage": 87, + }, + { + "category": "Numpad", + "long": "KP Enter", + "med": "KP Ent", + "page": 7, + "short": "Ent", + "usage": 88, + }, + { + "category": "Numpad", + "med": "1 End", + "page": 7, + "short": "1 En", + "usage": 89, + }, + { + "category": "Numpad", + "page": 7, + "short": "2 ↓", + "usage": 90, + }, + { + "category": "Numpad", + "med": "3 PgDn", + "page": 7, + "short": "3 PD", + "usage": 91, + }, + { + "category": "Numpad", + "page": 7, + "short": "4 ←", + "usage": 92, + }, + { + "category": "Numpad", + "page": 7, + "short": "5", + "usage": 93, + }, + { + "category": "Numpad", + "page": 7, + "short": "6 →", + "usage": 94, + }, + { + "category": "Numpad", + "med": "7 Home", + "page": 7, + "short": "7 Hm", + "usage": 95, + }, + { + "category": "Numpad", + "page": 7, + "short": "8 ↑", + "usage": 96, + }, + { + "category": "Numpad", + "med": "9 PgUp", + "page": 7, + "short": "9 PU", + "usage": 97, + }, + { + "category": "Numpad", + "long": "0 Insert", + "med": "0 Ins", + "page": 7, + "short": "0 In", + "usage": 98, + }, + { + "category": "Numpad", + "long": ". Delete", + "med": ". Del", + "page": 7, + "short": ". Dl", + "usage": 99, + }, + { + "category": "International", + "page": 7, + "short": "NUBS", + "usage": 100, + }, + { + "category": "Function + Navigation", + "long": "Applicat'n (Menu)", + "med": "Menu", + "page": 7, + "short": "Menu", + "usage": 101, + }, + { + "category": "Apps/Media/Special", + "med": "Power", + "page": 7, + "short": "Power", + "usage": 102, + }, + { + "category": "Numpad", + "page": 7, + "short": "=", + "usage": 103, + }, + { + "category": "Apps/Media/Special", + "long": "Keyboard F13", + "med": "F13", + "page": 7, + "short": "F13", + "usage": 104, + }, + { + "category": "Apps/Media/Special", + "long": "Keyboard F14", + "med": "F14", + "page": 7, + "short": "F14", + "usage": 105, + }, + { + "category": "Apps/Media/Special", + "long": "Keyboard F15", + "med": "F15", + "page": 7, + "short": "F15", + "usage": 106, + }, + { + "category": "Apps/Media/Special", + "long": "Keyboard F16", + "med": "F16", + "page": 7, + "short": "F16", + "usage": 107, + }, + { + "category": "Apps/Media/Special", + "long": "Keyboard F17", + "med": "F17", + "page": 7, + "short": "F17", + "usage": 108, + }, + { + "category": "Apps/Media/Special", + "long": "Keyboard F18", + "med": "F18", + "page": 7, + "short": "F18", + "usage": 109, + }, + { + "category": "Apps/Media/Special", + "long": "Keyboard F19", + "med": "F19", + "page": 7, + "short": "F19", + "usage": 110, + }, + { + "category": "Apps/Media/Special", + "long": "Keyboard F20", + "med": "F20", + "page": 7, + "short": "F20", + "usage": 111, + }, + { + "category": "Apps/Media/Special", + "long": "Keyboard F21", + "med": "F21", + "page": 7, + "short": "F21", + "usage": 112, + }, + { + "category": "Apps/Media/Special", + "long": "Keyboard F22", + "med": "F22", + "page": 7, + "short": "F22", + "usage": 113, + }, + { + "category": "Apps/Media/Special", + "long": "Keyboard F23", + "med": "F23", + "page": 7, + "short": "F23", + "usage": 114, + }, + { + "category": "Apps/Media/Special", + "long": "Keyboard F24", + "med": "F24", + "page": 7, + "short": "F24", + "usage": 115, + }, + { + "category": "Other", + "long": "Keyboard Execute", + "med": "Execute", + "page": 7, + "short": "Execute", + "usage": 116, + }, + { + "category": "Other", + "long": "Keyboard Help", + "med": "Help", + "page": 7, + "short": "Help", + "usage": 117, + }, + { + "category": "Apps/Media/Special", + "long": "Keyboard Menu", + "med": "Menu", + "page": 7, + "short": "Menu", + "usage": 118, + }, + { + "category": "Other", + "long": "Keyboard Select", + "med": "Select", + "page": 7, + "short": "Select", + "usage": 119, + }, + { + "category": "Other", + "long": "Keyboard Stop", + "med": "Stop", + "page": 7, + "short": "Stop", + "usage": 120, + }, + { + "category": "Other", + "long": "Keyboard Again", + "med": "Again", + "page": 7, + "short": "Again", + "usage": 121, + }, + { + "category": "Other", + "long": "Keyboard Undo", + "med": "Undo", + "page": 7, + "short": "Undo", + "usage": 122, + }, + { + "category": "Other", + "long": "Keyboard Cut", + "med": "Cut", + "page": 7, + "short": "Cut", + "usage": 123, + }, + { + "category": "Other", + "long": "Keyboard Copy", + "med": "Copy", + "page": 7, + "short": "Copy", + "usage": 124, + }, + { + "category": "Other", + "long": "Keyboard Paste", + "med": "Paste", + "page": 7, + "short": "Paste", + "usage": 125, + }, + { + "category": "Other", + "long": "Keyboard Find", + "med": "Find", + "page": 7, + "short": "Find", + "usage": 126, + }, + { + "category": "Other", + "long": "Keyboard Mute", + "med": "Mute", + "page": 7, + "short": "Mute", + "usage": 127, + }, + { + "category": "Other", + "long": "Keyboard Volume Up", + "med": "Volume Up", + "page": 7, + "short": "Volume Up", + "usage": 128, + }, + { + "category": "Other", + "long": "Keyboard Volume Down", + "med": "Volume Down", + "page": 7, + "short": "Volume Down", + "usage": 129, + }, + { + "category": "Other", + "long": "Keyboard Locking Caps Lock", + "med": "Locking Caps Lock", + "page": 7, + "short": "Locking Caps Lock", + "usage": 130, + }, + { + "category": "Other", + "long": "Keyboard Locking Num Lock", + "med": "Locking Num Lock", + "page": 7, + "short": "Locking Num Lock", + "usage": 131, + }, + { + "category": "Other", + "long": "Keyboard Locking Scroll Lock", + "med": "Locking Scroll Lock", + "page": 7, + "short": "Locking Scroll Lock", + "usage": 132, + }, + { + "category": "Numpad", + "page": 7, + "short": ",", + "usage": 133, + }, + { + "category": "Other", + "long": "Keypad Equal Sign", + "med": "Keypad Equal Sign", + "page": 7, + "short": "Keypad Equal Sign", + "usage": 134, + }, + { + "category": "International", + "page": 7, + "short": "Intl1", + "usage": 135, + }, + { + "category": "International", + "page": 7, + "short": "Intl2", + "usage": 136, + }, + { + "category": "International", + "page": 7, + "short": "Intl3", + "usage": 137, + }, + { + "category": "International", + "page": 7, + "short": "Intl4", + "usage": 138, + }, + { + "category": "International", + "page": 7, + "short": "Intl5", + "usage": 139, + }, + { + "category": "International", + "page": 7, + "short": "Intl6", + "usage": 140, + }, + { + "category": "International", + "page": 7, + "short": "Intl7", + "usage": 141, + }, + { + "category": "International", + "page": 7, + "short": "Intl8", + "usage": 142, + }, + { + "category": "International", + "page": 7, + "short": "Intl9", + "usage": 143, + }, + { + "category": "International", + "page": 7, + "short": "Lang1", + "usage": 144, + }, + { + "category": "International", + "page": 7, + "short": "Lang2", + "usage": 145, + }, + { + "category": "International", + "page": 7, + "short": "Lang3", + "usage": 146, + }, + { + "category": "International", + "page": 7, + "short": "Lang4", + "usage": 147, + }, + { + "category": "International", + "page": 7, + "short": "Lang5", + "usage": 148, + }, + { + "category": "International", + "page": 7, + "short": "Lang6", + "usage": 149, + }, + { + "category": "International", + "page": 7, + "short": "Lang7", + "usage": 150, + }, + { + "category": "International", + "page": 7, + "short": "Lang8", + "usage": 151, + }, + { + "category": "International", + "page": 7, + "short": "Lang9", + "usage": 152, + }, + { + "category": "Other", + "long": "Keyboard Alternate Erase", + "med": "Alternate Erase", + "page": 7, + "short": "Alternate Erase", + "usage": 153, + }, + { + "category": "Other", + "long": "Keyboard SysReq Attention", + "med": "SysReq Attention", + "page": 7, + "short": "SysReq Attention", + "usage": 154, + }, + { + "category": "Other", + "long": "Keyboard Cancel", + "med": "Cancel", + "page": 7, + "short": "Cancel", + "usage": 155, + }, + { + "category": "Other", + "long": "Keyboard Clear", + "med": "Clear", + "page": 7, + "short": "Clear", + "usage": 156, + }, + { + "category": "Other", + "long": "Keyboard Prior", + "med": "Prior", + "page": 7, + "short": "Prior", + "usage": 157, + }, + { + "category": "Other", + "long": "Keyboard Return", + "med": "Return", + "page": 7, + "short": "Return", + "usage": 158, + }, + { + "category": "Other", + "long": "Keyboard Separator", + "med": "Separator", + "page": 7, + "short": "Separator", + "usage": 159, + }, + { + "category": "Other", + "long": "Keyboard Out", + "med": "Out", + "page": 7, + "short": "Out", + "usage": 160, + }, + { + "category": "Other", + "long": "Keyboard Oper", + "med": "Oper", + "page": 7, + "short": "Oper", + "usage": 161, + }, + { + "category": "Other", + "long": "Keyboard Clear Again", + "med": "Clear Again", + "page": 7, + "short": "Clear Again", + "usage": 162, + }, + { + "category": "Other", + "long": "Keyboard CrSel Props", + "med": "CrSel Props", + "page": 7, + "short": "CrSel Props", + "usage": 163, + }, + { + "category": "Other", + "long": "Keyboard ExSel", + "med": "ExSel", + "page": 7, + "short": "ExSel", + "usage": 164, + }, + { + "category": "Numpad", + "page": 7, + "short": "00", + "usage": 176, + }, + { + "page": 7, + "short": "000", + "usage": 177, + }, + { + "category": "Other", + "long": "Thousands Separator", + "med": "Thousands Separator", + "page": 7, + "short": "Thousands Separator", + "usage": 178, + }, + { + "category": "Other", + "long": "Decimal Separator", + "med": "Decimal Separator", + "page": 7, + "short": "Decimal Separator", + "usage": 179, + }, + { + "category": "Other", + "long": "Currency Unit", + "med": "Currency Unit", + "page": 7, + "short": "Currency Unit", + "usage": 180, + }, + { + "category": "Other", + "long": "Currency Sub-unit", + "med": "Currency Sub-unit", + "page": 7, + "short": "Currency Sub-unit", + "usage": 181, + }, + { + "category": "Other", + "long": "Keypad Left Bracket", + "med": "Keypad Left Bracket", + "page": 7, + "short": "Keypad Left Bracket", + "usage": 182, + }, + { + "category": "Other", + "long": "Keypad Right Bracket", + "med": "Keypad Right Bracket", + "page": 7, + "short": "Keypad Right Bracket", + "usage": 183, + }, + { + "category": "Other", + "long": "Keypad Left Brace", + "med": "Keypad Left Brace", + "page": 7, + "short": "Keypad Left Brace", + "usage": 184, + }, + { + "category": "Other", + "long": "Keypad Right Brace", + "med": "Keypad Right Brace", + "page": 7, + "short": "Keypad Right Brace", + "usage": 185, + }, + { + "category": "Other", + "long": "Keypad Tab", + "med": "Keypad Tab", + "page": 7, + "short": "Keypad Tab", + "usage": 186, + }, + { + "category": "Other", + "long": "Keypad Backspace", + "med": "Keypad Backspace", + "page": 7, + "short": "Keypad Backspace", + "usage": 187, + }, + { + "category": "Other", + "long": "Keypad A", + "med": "Keypad A", + "page": 7, + "short": "Keypad A", + "usage": 188, + }, + { + "category": "Other", + "long": "Keypad B", + "med": "Keypad B", + "page": 7, + "short": "Keypad B", + "usage": 189, + }, + { + "category": "Other", + "long": "Keypad C", + "med": "Keypad C", + "page": 7, + "short": "Keypad C", + "usage": 190, + }, + { + "category": "Other", + "long": "Keypad D", + "med": "Keypad D", + "page": 7, + "short": "Keypad D", + "usage": 191, + }, + { + "category": "Other", + "long": "Keypad E", + "med": "Keypad E", + "page": 7, + "short": "Keypad E", + "usage": 192, + }, + { + "category": "Other", + "long": "Keypad F", + "med": "Keypad F", + "page": 7, + "short": "Keypad F", + "usage": 193, + }, + { + "category": "Other", + "long": "Keypad XOR", + "med": "Keypad XOR", + "page": 7, + "short": "Keypad XOR", + "usage": 194, + }, + { + "category": "Other", + "long": "Keypad Caret", + "med": "Keypad Caret", + "page": 7, + "short": "Keypad Caret", + "usage": 195, + }, + { + "category": "Other", + "long": "Keypad Percentage", + "med": "Keypad Percentage", + "page": 7, + "short": "Keypad Percentage", + "usage": 196, + }, + { + "category": "Other", + "long": "Keypad Less", + "med": "Keypad Less", + "page": 7, + "short": "Keypad Less", + "usage": 197, + }, + { + "category": "Other", + "long": "Keypad Greater", + "med": "Keypad Greater", + "page": 7, + "short": "Keypad Greater", + "usage": 198, + }, + { + "category": "Other", + "long": "Keypad Ampersand", + "med": "Keypad Ampersand", + "page": 7, + "short": "Keypad Ampersand", + "usage": 199, + }, + { + "category": "Other", + "long": "Keypad Double Ampersand", + "med": "Keypad Double Ampersand", + "page": 7, + "short": "Keypad Double Ampersand", + "usage": 200, + }, + { + "category": "Other", + "long": "Keypad Bar", + "med": "Keypad Bar", + "page": 7, + "short": "Keypad Bar", + "usage": 201, + }, + { + "category": "Other", + "long": "Keypad Double Bar", + "med": "Keypad Double Bar", + "page": 7, + "short": "Keypad Double Bar", + "usage": 202, + }, + { + "category": "Other", + "long": "Keypad Colon", + "med": "Keypad Colon", + "page": 7, + "short": "Keypad Colon", + "usage": 203, + }, + { + "category": "Other", + "long": "Keypad Hash", + "med": "Keypad Hash", + "page": 7, + "short": "Keypad Hash", + "usage": 204, + }, + { + "category": "Other", + "long": "Keypad Space", + "med": "Keypad Space", + "page": 7, + "short": "Keypad Space", + "usage": 205, + }, + { + "category": "Other", + "long": "Keypad At", + "med": "Keypad At", + "page": 7, + "short": "Keypad At", + "usage": 206, + }, + { + "category": "Other", + "long": "Keypad Bang", + "med": "Keypad Bang", + "page": 7, + "short": "Keypad Bang", + "usage": 207, + }, + { + "category": "Other", + "long": "Keypad Memory Store", + "med": "Keypad Memory Store", + "page": 7, + "short": "Keypad Memory Store", + "usage": 208, + }, + { + "category": "Other", + "long": "Keypad Memory Recall", + "med": "Keypad Memory Recall", + "page": 7, + "short": "Keypad Memory Recall", + "usage": 209, + }, + { + "category": "Other", + "long": "Keypad Memory Clear", + "med": "Keypad Memory Clear", + "page": 7, + "short": "Keypad Memory Clear", + "usage": 210, + }, + { + "category": "Other", + "long": "Keypad Memory Add", + "med": "Keypad Memory Add", + "page": 7, + "short": "Keypad Memory Add", + "usage": 211, + }, + { + "category": "Other", + "long": "Keypad Memory Subtract", + "med": "Keypad Memory Subtract", + "page": 7, + "short": "Keypad Memory Subtract", + "usage": 212, + }, + { + "category": "Other", + "long": "Keypad Memory Multiply", + "med": "Keypad Memory Multiply", + "page": 7, + "short": "Keypad Memory Multiply", + "usage": 213, + }, + { + "category": "Other", + "long": "Keypad Memory Divide", + "med": "Keypad Memory Divide", + "page": 7, + "short": "Keypad Memory Divide", + "usage": 214, + }, + { + "category": "Other", + "long": "Keypad Plus Minus", + "med": "Keypad Plus Minus", + "page": 7, + "short": "Keypad Plus Minus", + "usage": 215, + }, + { + "category": "Other", + "long": "Keypad Clear", + "med": "Keypad Clear", + "page": 7, + "short": "Keypad Clear", + "usage": 216, + }, + { + "category": "Other", + "long": "Keypad Clear Entry", + "med": "Keypad Clear Entry", + "page": 7, + "short": "Keypad Clear Entry", + "usage": 217, + }, + { + "category": "Other", + "long": "Keypad Binary", + "med": "Keypad Binary", + "page": 7, + "short": "Keypad Binary", + "usage": 218, + }, + { + "category": "Other", + "long": "Keypad Octal", + "med": "Keypad Octal", + "page": 7, + "short": "Keypad Octal", + "usage": 219, + }, + { + "category": "Other", + "long": "Keypad Decimal", + "med": "Keypad Decimal", + "page": 7, + "short": "Keypad Decimal", + "usage": 220, + }, + { + "category": "Other", + "long": "Keypad Hexadecimal", + "med": "Keypad Hexadecimal", + "page": 7, + "short": "Keypad Hexadecimal", + "usage": 221, + }, + { + "category": "Function + Navigation", + "med": "L Ctrl", + "page": 7, + "short": "Ctrl", + "usage": 224, + }, + { + "category": "Function + Navigation", + "long": "L Shift", + "med": "L Shft", + "page": 7, + "short": "Shft", + "usage": 225, + }, + { + "category": "Function + Navigation", + "long": "Left Alt", + "med": "L Alt", + "page": 7, + "short": "Alt", + "usage": 226, + }, + { + "category": "Function + Navigation", + "long": "Left GUI", + "med": "L GUI", + "page": 7, + "short": "GUI", + "usage": 227, + }, + { + "category": "Function + Navigation", + "med": "R Ctrl", + "page": 7, + "short": "Ctrl", + "usage": 228, + }, + { + "category": "Function + Navigation", + "long": "R Shift", + "med": "R Shft", + "page": 7, + "short": "Shft", + "usage": 229, + }, + { + "category": "Function + Navigation", + "med": "AltGr", + "page": 7, + "short": "AltG", + "usage": 230, + }, + { + "category": "Function + Navigation", + "long": "Right GUI", + "med": "R GUI", + "page": 7, + "short": "GUI", + "usage": 231, + }, + { + "category": "Other", + "long": "Consumer Control", + "med": "Consumer Control", + "page": 12, + "short": "Consumer Control", + "usage": 1, + }, + { + "category": "Other", + "long": "Numeric Key Pad", + "med": "Numeric Key Pad", + "page": 12, + "short": "Numeric Key Pad", + "usage": 2, + }, + { + "category": "Other", + "long": "Programmable Buttons", + "med": "Programmable Buttons", + "page": 12, + "short": "Programmable Buttons", + "usage": 3, + }, + { + "category": "Other", + "long": "Microphone", + "med": "Microphone", + "page": 12, + "short": "Microphone", + "usage": 4, + }, + { + "category": "Other", + "long": "Headphone", + "med": "Headphone", + "page": 12, + "short": "Headphone", + "usage": 5, + }, + { + "category": "Other", + "long": "Graphic Equalizer", + "med": "Graphic Equalizer", + "page": 12, + "short": "Graphic Equalizer", + "usage": 6, + }, + { + "category": "Other", + "long": "+10", + "med": "+10", + "page": 12, + "short": "+10", + "usage": 32, + }, + { + "category": "Other", + "long": "+100", + "med": "+100", + "page": 12, + "short": "+100", + "usage": 33, + }, + { + "category": "Other", + "long": "AM/PM", + "med": "AM/PM", + "page": 12, + "short": "AM/PM", + "usage": 34, + }, + { + "category": "Other", + "long": "Power", + "med": "Power", + "page": 12, + "short": "Power", + "usage": 48, + }, + { + "category": "Other", + "long": "Reset", + "med": "Reset", + "page": 12, + "short": "Reset", + "usage": 49, + }, + { + "category": "Other", + "long": "Sleep", + "med": "Sleep", + "page": 12, + "short": "Sleep", + "usage": 50, + }, + { + "category": "Other", + "long": "Sleep After", + "med": "Sleep After", + "page": 12, + "short": "Sleep After", + "usage": 51, + }, + { + "category": "Other", + "long": "Sleep Mode", + "med": "Sleep Mode", + "page": 12, + "short": "Sleep Mode", + "usage": 52, + }, + { + "category": "Other", + "long": "Illumination", + "med": "Illumination", + "page": 12, + "short": "Illumination", + "usage": 53, + }, + { + "category": "Other", + "long": "Function Buttons", + "med": "Function Buttons", + "page": 12, + "short": "Function Buttons", + "usage": 54, + }, + { + "category": "Other", + "long": "Menu", + "med": "Menu", + "page": 12, + "short": "Menu", + "usage": 64, + }, + { + "category": "Other", + "long": "Menu Pick", + "med": "Menu Pick", + "page": 12, + "short": "Menu Pick", + "usage": 65, + }, + { + "category": "Other", + "long": "Menu Up", + "med": "Menu Up", + "page": 12, + "short": "Menu Up", + "usage": 66, + }, + { + "category": "Other", + "long": "Menu Down", + "med": "Menu Down", + "page": 12, + "short": "Menu Down", + "usage": 67, + }, + { + "category": "Other", + "long": "Menu Left", + "med": "Menu Left", + "page": 12, + "short": "Menu Left", + "usage": 68, + }, + { + "category": "Other", + "long": "Menu Right", + "med": "Menu Right", + "page": 12, + "short": "Menu Right", + "usage": 69, + }, + { + "category": "Other", + "long": "Menu Escape", + "med": "Menu Escape", + "page": 12, + "short": "Menu Escape", + "usage": 70, + }, + { + "category": "Other", + "long": "Menu Value Increase", + "med": "Menu Value Increase", + "page": 12, + "short": "Menu Value Increase", + "usage": 71, + }, + { + "category": "Other", + "long": "Menu Value Decrease", + "med": "Menu Value Decrease", + "page": 12, + "short": "Menu Value Decrease", + "usage": 72, + }, + { + "category": "Other", + "long": "Data On Screen", + "med": "Data On Screen", + "page": 12, + "short": "Data On Screen", + "usage": 96, + }, + { + "category": "Other", + "long": "Closed Caption", + "med": "Closed Caption", + "page": 12, + "short": "Closed Caption", + "usage": 97, + }, + { + "category": "Other", + "long": "Closed Caption Select", + "med": "Closed Caption Select", + "page": 12, + "short": "Closed Caption Select", + "usage": 98, + }, + { + "category": "Other", + "long": "VCR/TV", + "med": "VCR/TV", + "page": 12, + "short": "VCR/TV", + "usage": 99, + }, + { + "category": "Other", + "long": "Broadcast Mode", + "med": "Broadcast Mode", + "page": 12, + "short": "Broadcast Mode", + "usage": 100, + }, + { + "category": "Other", + "long": "Snapshot", + "med": "Snapshot", + "page": 12, + "short": "Snapshot", + "usage": 101, + }, + { + "category": "Other", + "long": "Still", + "med": "Still", + "page": 12, + "short": "Still", + "usage": 102, + }, + { + "category": "Other", + "long": "Picture-in-Picture Toggle", + "med": "Picture-in-Picture Toggle", + "page": 12, + "short": "Picture-in-Picture Toggle", + "usage": 103, + }, + { + "category": "Other", + "long": "Picture-in-Picture Swap", + "med": "Picture-in-Picture Swap", + "page": 12, + "short": "Picture-in-Picture Swap", + "usage": 104, + }, + { + "category": "Other", + "long": "Red Menu Button", + "med": "Red Menu Button", + "page": 12, + "short": "Red Menu Button", + "usage": 105, + }, + { + "category": "Other", + "long": "Green Menu Button", + "med": "Green Menu Button", + "page": 12, + "short": "Green Menu Button", + "usage": 106, + }, + { + "category": "Other", + "long": "Blue Menu Button", + "med": "Blue Menu Button", + "page": 12, + "short": "Blue Menu Button", + "usage": 107, + }, + { + "category": "Other", + "long": "Yellow Menu Button", + "med": "Yellow Menu Button", + "page": 12, + "short": "Yellow Menu Button", + "usage": 108, + }, + { + "category": "Other", + "long": "Aspect", + "med": "Aspect", + "page": 12, + "short": "Aspect", + "usage": 109, + }, + { + "category": "Other", + "long": "3D Mode Select", + "med": "3D Mode Select", + "page": 12, + "short": "3D Mode Select", + "usage": 110, + }, + { + "category": "Apps/Media/Special", + "page": 12, + "short": "🔆", + "usage": 111, + }, + { + "category": "Apps/Media/Special", + "page": 12, + "short": "🔅", + "usage": 112, + }, + { + "category": "Other", + "long": "Display Brightness", + "med": "Display Brightness", + "page": 12, + "short": "Display Brightness", + "usage": 113, + }, + { + "category": "Other", + "long": "Display Backlight Toggle", + "med": "Display Backlight Toggle", + "page": 12, + "short": "Display Backlight Toggle", + "usage": 114, + }, + { + "category": "Other", + "long": "Display Set Brightness to Minimum", + "med": "Display Set Brightness to Minimum", + "page": 12, + "short": "Display Set Brightness to Minimum", + "usage": 115, + }, + { + "category": "Other", + "long": "Display Set Brightness to Maximum", + "med": "Display Set Brightness to Maximum", + "page": 12, + "short": "Display Set Brightness to Maximum", + "usage": 116, + }, + { + "category": "Other", + "long": "Display Set Auto Brightness", + "med": "Display Set Auto Brightness", + "page": 12, + "short": "Display Set Auto Brightness", + "usage": 117, + }, + { + "category": "Other", + "long": "Camera Access Enabled", + "med": "Camera Access Enabled", + "page": 12, + "short": "Camera Access Enabled", + "usage": 118, + }, + { + "category": "Other", + "long": "Camera Access Disabled", + "med": "Camera Access Disabled", + "page": 12, + "short": "Camera Access Disabled", + "usage": 119, + }, + { + "category": "Other", + "long": "Camera Access Toggle", + "med": "Camera Access Toggle", + "page": 12, + "short": "Camera Access Toggle", + "usage": 120, + }, + { + "category": "Other", + "long": "Keyboard Brightness Increment", + "med": "Brightness Increment", + "page": 12, + "short": "Brightness Increment", + "usage": 121, + }, + { + "category": "Other", + "long": "Keyboard Brightness Decrement", + "med": "Brightness Decrement", + "page": 12, + "short": "Brightness Decrement", + "usage": 122, + }, + { + "category": "Other", + "long": "Keyboard Backlight Set Level", + "med": "Backlight Set Level", + "page": 12, + "short": "Backlight Set Level", + "usage": 123, + }, + { + "category": "Other", + "long": "Keyboard Backlight OOC", + "med": "Backlight OOC", + "page": 12, + "short": "Backlight OOC", + "usage": 124, + }, + { + "category": "Other", + "long": "Keyboard Backlight Set Minimum", + "med": "Backlight Set Minimum", + "page": 12, + "short": "Backlight Set Minimum", + "usage": 125, + }, + { + "category": "Other", + "long": "Keyboard Backlight Set Maximum", + "med": "Backlight Set Maximum", + "page": 12, + "short": "Backlight Set Maximum", + "usage": 126, + }, + { + "category": "Other", + "long": "Keyboard Backlight Auto", + "med": "Backlight Auto", + "page": 12, + "short": "Backlight Auto", + "usage": 127, + }, + { + "category": "Other", + "long": "Selection", + "med": "Selection", + "page": 12, + "short": "Selection", + "usage": 128, + }, + { + "category": "Other", + "long": "Assign Selection", + "med": "Assign Selection", + "page": 12, + "short": "Assign Selection", + "usage": 129, + }, + { + "category": "Other", + "long": "Mode Step", + "med": "Mode Step", + "page": 12, + "short": "Mode Step", + "usage": 130, + }, + { + "category": "Other", + "long": "Recall Last", + "med": "Recall Last", + "page": 12, + "short": "Recall Last", + "usage": 131, + }, + { + "category": "Other", + "long": "Enter Channel", + "med": "Enter Channel", + "page": 12, + "short": "Enter Channel", + "usage": 132, + }, + { + "category": "Other", + "long": "Order Movie", + "med": "Order Movie", + "page": 12, + "short": "Order Movie", + "usage": 133, + }, + { + "category": "Other", + "long": "Channel", + "med": "Channel", + "page": 12, + "short": "Channel", + "usage": 134, + }, + { + "category": "Other", + "long": "Media Selection", + "med": "Media Selection", + "page": 12, + "short": "Media Selection", + "usage": 135, + }, + { + "category": "Other", + "long": "Media Select Computer", + "med": "Media Select Computer", + "page": 12, + "short": "Media Select Computer", + "usage": 136, + }, + { + "category": "Other", + "long": "Media Select TV", + "med": "Media Select TV", + "page": 12, + "short": "Media Select TV", + "usage": 137, + }, + { + "category": "Other", + "long": "Media Select WWW", + "med": "Media Select WWW", + "page": 12, + "short": "Media Select WWW", + "usage": 138, + }, + { + "category": "Other", + "long": "Media Select DVD", + "med": "Media Select DVD", + "page": 12, + "short": "Media Select DVD", + "usage": 139, + }, + { + "category": "Other", + "long": "Media Select Telephone", + "med": "Media Select Telephone", + "page": 12, + "short": "Media Select Telephone", + "usage": 140, + }, + { + "category": "Other", + "long": "Media Select Program Guide", + "med": "Media Select Program Guide", + "page": 12, + "short": "Media Select Program Guide", + "usage": 141, + }, + { + "category": "Other", + "long": "Media Select Video Phone", + "med": "Media Select Video Phone", + "page": 12, + "short": "Media Select Video Phone", + "usage": 142, + }, + { + "category": "Other", + "long": "Media Select Games", + "med": "Media Select Games", + "page": 12, + "short": "Media Select Games", + "usage": 143, + }, + { + "category": "Other", + "long": "Media Select Messages", + "med": "Media Select Messages", + "page": 12, + "short": "Media Select Messages", + "usage": 144, + }, + { + "category": "Other", + "long": "Media Select CD", + "med": "Media Select CD", + "page": 12, + "short": "Media Select CD", + "usage": 145, + }, + { + "category": "Other", + "long": "Media Select VCR", + "med": "Media Select VCR", + "page": 12, + "short": "Media Select VCR", + "usage": 146, + }, + { + "category": "Other", + "long": "Media Select Tuner", + "med": "Media Select Tuner", + "page": 12, + "short": "Media Select Tuner", + "usage": 147, + }, + { + "category": "Other", + "long": "Quit", + "med": "Quit", + "page": 12, + "short": "Quit", + "usage": 148, + }, + { + "category": "Other", + "long": "Help", + "med": "Help", + "page": 12, + "short": "Help", + "usage": 149, + }, + { + "category": "Other", + "long": "Media Select Tape", + "med": "Media Select Tape", + "page": 12, + "short": "Media Select Tape", + "usage": 150, + }, + { + "category": "Other", + "long": "Media Select Cable", + "med": "Media Select Cable", + "page": 12, + "short": "Media Select Cable", + "usage": 151, + }, + { + "category": "Other", + "long": "Media Select Satellite", + "med": "Media Select Satellite", + "page": 12, + "short": "Media Select Satellite", + "usage": 152, + }, + { + "category": "Other", + "long": "Media Select Security", + "med": "Media Select Security", + "page": 12, + "short": "Media Select Security", + "usage": 153, + }, + { + "category": "Other", + "long": "Media Select Home", + "med": "Media Select Home", + "page": 12, + "short": "Media Select Home", + "usage": 154, + }, + { + "category": "Other", + "long": "Media Select Call", + "med": "Media Select Call", + "page": 12, + "short": "Media Select Call", + "usage": 155, + }, + { + "category": "Other", + "long": "Channel Increment", + "med": "Channel Increment", + "page": 12, + "short": "Channel Increment", + "usage": 156, + }, + { + "category": "Other", + "long": "Channel Decrement", + "med": "Channel Decrement", + "page": 12, + "short": "Channel Decrement", + "usage": 157, + }, + { + "category": "Other", + "long": "Media Select SAP", + "med": "Media Select SAP", + "page": 12, + "short": "Media Select SAP", + "usage": 158, + }, + { + "category": "Other", + "long": "VCR Plus", + "med": "VCR Plus", + "page": 12, + "short": "VCR Plus", + "usage": 160, + }, + { + "category": "Other", + "long": "Once", + "med": "Once", + "page": 12, + "short": "Once", + "usage": 161, + }, + { + "category": "Other", + "long": "Daily", + "med": "Daily", + "page": 12, + "short": "Daily", + "usage": 162, + }, + { + "category": "Other", + "long": "Weekly", + "med": "Weekly", + "page": 12, + "short": "Weekly", + "usage": 163, + }, + { + "category": "Other", + "long": "Monthly", + "med": "Monthly", + "page": 12, + "short": "Monthly", + "usage": 164, + }, + { + "category": "Other", + "long": "Play", + "med": "Play", + "page": 12, + "short": "Play", + "usage": 176, + }, + { + "category": "Other", + "long": "Pause", + "med": "Pause", + "page": 12, + "short": "Pause", + "usage": 177, + }, + { + "category": "Other", + "long": "Record", + "med": "Record", + "page": 12, + "short": "Record", + "usage": 178, + }, + { + "category": "Other", + "long": "Fast Forward", + "med": "Fast Forward", + "page": 12, + "short": "Fast Forward", + "usage": 179, + }, + { + "category": "Other", + "long": "Rewind", + "med": "Rewind", + "page": 12, + "short": "Rewind", + "usage": 180, + }, + { + "category": "Apps/Media/Special", + "page": 12, + "short": "⇥", + "usage": 181, + }, + { + "category": "Apps/Media/Special", + "page": 12, + "short": "⇤", + "usage": 182, + }, + { + "category": "Other", + "long": "Stop", + "med": "Stop", + "page": 12, + "short": "Stop", + "usage": 183, + }, + { + "category": "Other", + "long": "Eject", + "med": "Eject", + "page": 12, + "short": "Eject", + "usage": 184, + }, + { + "category": "Other", + "long": "Random Play", + "med": "Random Play", + "page": 12, + "short": "Random Play", + "usage": 185, + }, + { + "category": "Other", + "long": "Select Disc", + "med": "Select Disc", + "page": 12, + "short": "Select Disc", + "usage": 186, + }, + { + "category": "Other", + "long": "Enter Disc", + "med": "Enter Disc", + "page": 12, + "short": "Enter Disc", + "usage": 187, + }, + { + "category": "Other", + "long": "Repeat", + "med": "Repeat", + "page": 12, + "short": "Repeat", + "usage": 188, + }, + { + "category": "Other", + "long": "Tracking", + "med": "Tracking", + "page": 12, + "short": "Tracking", + "usage": 189, + }, + { + "category": "Other", + "long": "Track Normal", + "med": "Track Normal", + "page": 12, + "short": "Track Normal", + "usage": 190, + }, + { + "category": "Other", + "long": "Slow Tracking", + "med": "Slow Tracking", + "page": 12, + "short": "Slow Tracking", + "usage": 191, + }, + { + "category": "Other", + "long": "Frame Forward", + "med": "Frame Forward", + "page": 12, + "short": "Frame Forward", + "usage": 192, + }, + { + "category": "Other", + "long": "Frame Back", + "med": "Frame Back", + "page": 12, + "short": "Frame Back", + "usage": 193, + }, + { + "category": "Other", + "long": "Mark", + "med": "Mark", + "page": 12, + "short": "Mark", + "usage": 194, + }, + { + "category": "Other", + "long": "Clear Mark", + "med": "Clear Mark", + "page": 12, + "short": "Clear Mark", + "usage": 195, + }, + { + "category": "Other", + "long": "Repeat From Mark", + "med": "Repeat From Mark", + "page": 12, + "short": "Repeat From Mark", + "usage": 196, + }, + { + "category": "Other", + "long": "Return To Mark", + "med": "Return To Mark", + "page": 12, + "short": "Return To Mark", + "usage": 197, + }, + { + "category": "Other", + "long": "Search Mark Forward", + "med": "Search Mark Forward", + "page": 12, + "short": "Search Mark Forward", + "usage": 198, + }, + { + "category": "Other", + "long": "Search Mark Backwards", + "med": "Search Mark Backwards", + "page": 12, + "short": "Search Mark Backwards", + "usage": 199, + }, + { + "category": "Other", + "long": "Counter Reset", + "med": "Counter Reset", + "page": 12, + "short": "Counter Reset", + "usage": 200, + }, + { + "category": "Other", + "long": "Show Counter", + "med": "Show Counter", + "page": 12, + "short": "Show Counter", + "usage": 201, + }, + { + "category": "Other", + "long": "Tracking Increment", + "med": "Tracking Increment", + "page": 12, + "short": "Tracking Increment", + "usage": 202, + }, + { + "category": "Other", + "long": "Tracking Decrement", + "med": "Tracking Decrement", + "page": 12, + "short": "Tracking Decrement", + "usage": 203, + }, + { + "category": "Other", + "long": "Stop/Eject", + "med": "Stop/Eject", + "page": 12, + "short": "Stop/Eject", + "usage": 204, + }, + { + "category": "Apps/Media/Special", + "page": 12, + "short": "⏯️", + "usage": 205, + }, + { + "category": "Other", + "long": "Play/Skip", + "med": "Play/Skip", + "page": 12, + "short": "Play/Skip", + "usage": 206, + }, + { + "category": "Other", + "long": "Voice Command", + "med": "Voice Command", + "page": 12, + "short": "Voice Command", + "usage": 207, + }, + { + "category": "Other", + "long": "Invoke Capture Interface", + "med": "Invoke Capture Interface", + "page": 12, + "short": "Invoke Capture Interface", + "usage": 208, + }, + { + "category": "Other", + "long": "Start or Stop Game Recording", + "med": "Start or Stop Game Recording", + "page": 12, + "short": "Start or Stop Game Recording", + "usage": 209, + }, + { + "category": "Other", + "long": "Historical Game Capture", + "med": "Historical Game Capture", + "page": 12, + "short": "Historical Game Capture", + "usage": 210, + }, + { + "category": "Other", + "long": "Capture Game Screenshot", + "med": "Capture Game Screenshot", + "page": 12, + "short": "Capture Game Screenshot", + "usage": 211, + }, + { + "category": "Other", + "long": "Show or Hide Recording Indicator", + "med": "Show or Hide Recording Indicator", + "page": 12, + "short": "Show or Hide Recording Indicator", + "usage": 212, + }, + { + "category": "Other", + "long": "Start or Stop Microphone Capture", + "med": "Start or Stop Microphone Capture", + "page": 12, + "short": "Start or Stop Microphone Capture", + "usage": 213, + }, + { + "category": "Other", + "long": "Start or Stop Camera Capture", + "med": "Start or Stop Camera Capture", + "page": 12, + "short": "Start or Stop Camera Capture", + "usage": 214, + }, + { + "category": "Other", + "long": "Start or Stop Game Broadcast", + "med": "Start or Stop Game Broadcast", + "page": 12, + "short": "Start or Stop Game Broadcast", + "usage": 215, + }, + { + "category": "Other", + "long": "Start or Stop Voice Dictation Session", + "med": "Start or Stop Voice Dictation Session", + "page": 12, + "short": "Start or Stop Voice Dictation Session", + "usage": 216, + }, + { + "category": "Other", + "long": "Invoke/Dismiss Emoji Picker", + "med": "Invoke/Dismiss Emoji Picker", + "page": 12, + "short": "Invoke/Dismiss Emoji Picker", + "usage": 217, + }, + { + "category": "Other", + "long": "Volume", + "med": "Volume", + "page": 12, + "short": "Volume", + "usage": 224, + }, + { + "category": "Other", + "long": "Balance", + "med": "Balance", + "page": 12, + "short": "Balance", + "usage": 225, + }, + { + "category": "Apps/Media/Special", + "page": 12, + "short": "🔇", + "usage": 226, + }, + { + "category": "Other", + "long": "Bass", + "med": "Bass", + "page": 12, + "short": "Bass", + "usage": 227, + }, + { + "category": "Other", + "long": "Treble", + "med": "Treble", + "page": 12, + "short": "Treble", + "usage": 228, + }, + { + "category": "Other", + "long": "Bass Boost", + "med": "Bass Boost", + "page": 12, + "short": "Bass Boost", + "usage": 229, + }, + { + "category": "Other", + "long": "Surround Mode", + "med": "Surround Mode", + "page": 12, + "short": "Surround Mode", + "usage": 230, + }, + { + "category": "Other", + "long": "Loudness", + "med": "Loudness", + "page": 12, + "short": "Loudness", + "usage": 231, + }, + { + "category": "Other", + "long": "MPX", + "med": "MPX", + "page": 12, + "short": "MPX", + "usage": 232, + }, + { + "category": "Apps/Media/Special", + "page": 12, + "short": "🔊", + "usage": 233, + }, + { + "category": "Apps/Media/Special", + "page": 12, + "short": "🔉", + "usage": 234, + }, + { + "category": "Other", + "long": "Speed Select", + "med": "Speed Select", + "page": 12, + "short": "Speed Select", + "usage": 240, + }, + { + "category": "Other", + "long": "Playback Speed", + "med": "Playback Speed", + "page": 12, + "short": "Playback Speed", + "usage": 241, + }, + { + "category": "Other", + "long": "Standard Play", + "med": "Standard Play", + "page": 12, + "short": "Standard Play", + "usage": 242, + }, + { + "category": "Other", + "long": "Long Play", + "med": "Long Play", + "page": 12, + "short": "Long Play", + "usage": 243, + }, + { + "category": "Other", + "long": "Extended Play", + "med": "Extended Play", + "page": 12, + "short": "Extended Play", + "usage": 244, + }, + { + "category": "Other", + "long": "Slow", + "med": "Slow", + "page": 12, + "short": "Slow", + "usage": 245, + }, + { + "category": "Other", + "long": "Fan Enable", + "med": "Fan Enable", + "page": 12, + "short": "Fan Enable", + "usage": 256, + }, + { + "category": "Other", + "long": "Fan Speed", + "med": "Fan Speed", + "page": 12, + "short": "Fan Speed", + "usage": 257, + }, + { + "category": "Other", + "long": "Light Enable", + "med": "Light Enable", + "page": 12, + "short": "Light Enable", + "usage": 258, + }, + { + "category": "Other", + "long": "Light Illumination Level", + "med": "Light Illumination Level", + "page": 12, + "short": "Light Illumination Level", + "usage": 259, + }, + { + "category": "Other", + "long": "Climate Control Enable", + "med": "Climate Control Enable", + "page": 12, + "short": "Climate Control Enable", + "usage": 260, + }, + { + "category": "Other", + "long": "Room Temperature", + "med": "Room Temperature", + "page": 12, + "short": "Room Temperature", + "usage": 261, + }, + { + "category": "Other", + "long": "Security Enable", + "med": "Security Enable", + "page": 12, + "short": "Security Enable", + "usage": 262, + }, + { + "category": "Other", + "long": "Fire Alarm", + "med": "Fire Alarm", + "page": 12, + "short": "Fire Alarm", + "usage": 263, + }, + { + "category": "Other", + "long": "Police Alarm", + "med": "Police Alarm", + "page": 12, + "short": "Police Alarm", + "usage": 264, + }, + { + "category": "Other", + "long": "Proximity", + "med": "Proximity", + "page": 12, + "short": "Proximity", + "usage": 265, + }, + { + "category": "Other", + "long": "Motion", + "med": "Motion", + "page": 12, + "short": "Motion", + "usage": 266, + }, + { + "category": "Other", + "long": "Duress Alarm", + "med": "Duress Alarm", + "page": 12, + "short": "Duress Alarm", + "usage": 267, + }, + { + "category": "Other", + "long": "Holdup Alarm", + "med": "Holdup Alarm", + "page": 12, + "short": "Holdup Alarm", + "usage": 268, + }, + { + "category": "Other", + "long": "Medical Alarm", + "med": "Medical Alarm", + "page": 12, + "short": "Medical Alarm", + "usage": 269, + }, + { + "category": "Other", + "long": "Balance Right", + "med": "Balance Right", + "page": 12, + "short": "Balance Right", + "usage": 336, + }, + { + "category": "Other", + "long": "Balance Left", + "med": "Balance Left", + "page": 12, + "short": "Balance Left", + "usage": 337, + }, + { + "category": "Other", + "long": "Bass Increment", + "med": "Bass Increment", + "page": 12, + "short": "Bass Increment", + "usage": 338, + }, + { + "category": "Other", + "long": "Bass Decrement", + "med": "Bass Decrement", + "page": 12, + "short": "Bass Decrement", + "usage": 339, + }, + { + "category": "Other", + "long": "Treble Increment", + "med": "Treble Increment", + "page": 12, + "short": "Treble Increment", + "usage": 340, + }, + { + "category": "Other", + "long": "Treble Decrement", + "med": "Treble Decrement", + "page": 12, + "short": "Treble Decrement", + "usage": 341, + }, + { + "category": "Other", + "long": "Speaker System", + "med": "Speaker System", + "page": 12, + "short": "Speaker System", + "usage": 352, + }, + { + "category": "Other", + "long": "Channel Left", + "med": "Channel Left", + "page": 12, + "short": "Channel Left", + "usage": 353, + }, + { + "category": "Other", + "long": "Channel Right", + "med": "Channel Right", + "page": 12, + "short": "Channel Right", + "usage": 354, + }, + { + "category": "Other", + "long": "Channel Center", + "med": "Channel Center", + "page": 12, + "short": "Channel Center", + "usage": 355, + }, + { + "category": "Other", + "long": "Channel Front", + "med": "Channel Front", + "page": 12, + "short": "Channel Front", + "usage": 356, + }, + { + "category": "Other", + "long": "Channel Center Front", + "med": "Channel Center Front", + "page": 12, + "short": "Channel Center Front", + "usage": 357, + }, + { + "category": "Other", + "long": "Channel Side", + "med": "Channel Side", + "page": 12, + "short": "Channel Side", + "usage": 358, + }, + { + "category": "Other", + "long": "Channel Surround", + "med": "Channel Surround", + "page": 12, + "short": "Channel Surround", + "usage": 359, + }, + { + "category": "Other", + "long": "Channel Low Frequency Enhancement", + "med": "Channel Low Frequency Enhancement", + "page": 12, + "short": "Channel Low Frequency Enhancement", + "usage": 360, + }, + { + "category": "Other", + "long": "Channel Top", + "med": "Channel Top", + "page": 12, + "short": "Channel Top", + "usage": 361, + }, + { + "category": "Other", + "long": "Channel Unknown", + "med": "Channel Unknown", + "page": 12, + "short": "Channel Unknown", + "usage": 362, + }, + { + "category": "Other", + "long": "Sub-channel", + "med": "Sub-channel", + "page": 12, + "short": "Sub-channel", + "usage": 368, + }, + { + "category": "Other", + "long": "Sub-channel Increment", + "med": "Sub-channel Increment", + "page": 12, + "short": "Sub-channel Increment", + "usage": 369, + }, + { + "category": "Other", + "long": "Sub-channel Decrement", + "med": "Sub-channel Decrement", + "page": 12, + "short": "Sub-channel Decrement", + "usage": 370, + }, + { + "category": "Other", + "long": "Alternate Audio Increment", + "med": "Alternate Audio Increment", + "page": 12, + "short": "Alternate Audio Increment", + "usage": 371, + }, + { + "category": "Other", + "long": "Alternate Audio Decrement", + "med": "Alternate Audio Decrement", + "page": 12, + "short": "Alternate Audio Decrement", + "usage": 372, + }, + { + "category": "Other", + "long": "Application Launch Buttons", + "med": "Application Launch Buttons", + "page": 12, + "short": "Application Launch Buttons", + "usage": 384, + }, + { + "category": "Other", + "long": "AL Launch Button Configuration Tool", + "med": "AL Launch Button Configuration Tool", + "page": 12, + "short": "AL Launch Button Configuration Tool", + "usage": 385, + }, + { + "category": "Other", + "long": "AL Programmable Button Configuration", + "med": "AL Programmable Button Configuration", + "page": 12, + "short": "AL Programmable Button Configuration", + "usage": 386, + }, + { + "category": "Other", + "long": "AL Consumer Control Configuration", + "med": "AL Consumer Control Configuration", + "page": 12, + "short": "AL Consumer Control Configuration", + "usage": 387, + }, + { + "category": "Other", + "long": "AL Word Processor", + "med": "AL Word Processor", + "page": 12, + "short": "AL Word Processor", + "usage": 388, + }, + { + "category": "Other", + "long": "AL Text Editor", + "med": "AL Text Editor", + "page": 12, + "short": "AL Text Editor", + "usage": 389, + }, + { + "category": "Other", + "long": "AL Spreadsheet", + "med": "AL Spreadsheet", + "page": 12, + "short": "AL Spreadsheet", + "usage": 390, + }, + { + "category": "Other", + "long": "AL Graphics Editor", + "med": "AL Graphics Editor", + "page": 12, + "short": "AL Graphics Editor", + "usage": 391, + }, + { + "category": "Other", + "long": "AL Presentation App", + "med": "AL Presentation App", + "page": 12, + "short": "AL Presentation App", + "usage": 392, + }, + { + "category": "Other", + "long": "AL Database App", + "med": "AL Database App", + "page": 12, + "short": "AL Database App", + "usage": 393, + }, + { + "category": "Other", + "long": "AL Email Reader", + "med": "AL Email Reader", + "page": 12, + "short": "AL Email Reader", + "usage": 394, + }, + { + "category": "Other", + "long": "AL Newsreader", + "med": "AL Newsreader", + "page": 12, + "short": "AL Newsreader", + "usage": 395, + }, + { + "category": "Other", + "long": "AL Voicemail", + "med": "AL Voicemail", + "page": 12, + "short": "AL Voicemail", + "usage": 396, + }, + { + "category": "Other", + "long": "AL Contacts/Address Book", + "med": "AL Contacts/Address Book", + "page": 12, + "short": "AL Contacts/Address Book", + "usage": 397, + }, + { + "category": "Other", + "long": "AL Calendar/Schedule", + "med": "AL Calendar/Schedule", + "page": 12, + "short": "AL Calendar/Schedule", + "usage": 398, + }, + { + "category": "Other", + "long": "AL Task/Project Manager", + "med": "AL Task/Project Manager", + "page": 12, + "short": "AL Task/Project Manager", + "usage": 399, + }, + { + "category": "Other", + "long": "AL Log/Journal/Timecard", + "med": "AL Log/Journal/Timecard", + "page": 12, + "short": "AL Log/Journal/Timecard", + "usage": 400, + }, + { + "category": "Other", + "long": "AL Checkbook/Finance", + "med": "AL Checkbook/Finance", + "page": 12, + "short": "AL Checkbook/Finance", + "usage": 401, + }, + { + "category": "Other", + "long": "AL Calculator", + "med": "AL Calculator", + "page": 12, + "short": "AL Calculator", + "usage": 402, + }, + { + "category": "Other", + "long": "AL A/V Capture/Playback", + "med": "AL A/V Capture/Playback", + "page": 12, + "short": "AL A/V Capture/Playback", + "usage": 403, + }, + { + "category": "Other", + "long": "AL Local Machine Browser", + "med": "AL Local Machine Browser", + "page": 12, + "short": "AL Local Machine Browser", + "usage": 404, + }, + { + "category": "Other", + "long": "AL LAN/WAN Browser", + "med": "AL LAN/WAN Browser", + "page": 12, + "short": "AL LAN/WAN Browser", + "usage": 405, + }, + { + "category": "Other", + "long": "AL Internet Browser", + "med": "AL Internet Browser", + "page": 12, + "short": "AL Internet Browser", + "usage": 406, + }, + { + "category": "Other", + "long": "AL Remote Networking/ISP Connect", + "med": "AL Remote Networking/ISP Connect", + "page": 12, + "short": "AL Remote Networking/ISP Connect", + "usage": 407, + }, + { + "category": "Other", + "long": "AL Network Conference", + "med": "AL Network Conference", + "page": 12, + "short": "AL Network Conference", + "usage": 408, + }, + { + "category": "Other", + "long": "AL Network Chat", + "med": "AL Network Chat", + "page": 12, + "short": "AL Network Chat", + "usage": 409, + }, + { + "category": "Other", + "long": "AL Telephony/Dialer", + "med": "AL Telephony/Dialer", + "page": 12, + "short": "AL Telephony/Dialer", + "usage": 410, + }, + { + "category": "Other", + "long": "AL Logon", + "med": "AL Logon", + "page": 12, + "short": "AL Logon", + "usage": 411, + }, + { + "category": "Other", + "long": "AL Logoff", + "med": "AL Logoff", + "page": 12, + "short": "AL Logoff", + "usage": 412, + }, + { + "category": "Other", + "long": "AL Logon/Logoff", + "med": "AL Logon/Logoff", + "page": 12, + "short": "AL Logon/Logoff", + "usage": 413, + }, + { + "category": "Other", + "long": "AL Terminal Lock/Screensaver", + "med": "AL Terminal Lock/Screensaver", + "page": 12, + "short": "AL Terminal Lock/Screensaver", + "usage": 414, + }, + { + "category": "Other", + "long": "AL Control Panel", + "med": "AL Control Panel", + "page": 12, + "short": "AL Control Panel", + "usage": 415, + }, + { + "category": "Other", + "long": "AL Command Line Processor/Run", + "med": "AL Command Line Processor/Run", + "page": 12, + "short": "AL Command Line Processor/Run", + "usage": 416, + }, + { + "category": "Other", + "long": "AL Process/Task Manager", + "med": "AL Process/Task Manager", + "page": 12, + "short": "AL Process/Task Manager", + "usage": 417, + }, + { + "category": "Other", + "long": "AL Select Task/Application", + "med": "AL Select Task/Application", + "page": 12, + "short": "AL Select Task/Application", + "usage": 418, + }, + { + "category": "Other", + "long": "AL Next Task/Application", + "med": "AL Next Task/Application", + "page": 12, + "short": "AL Next Task/Application", + "usage": 419, + }, + { + "category": "Other", + "long": "AL Previous Task/Application", + "med": "AL Previous Task/Application", + "page": 12, + "short": "AL Previous Task/Application", + "usage": 420, + }, + { + "category": "Other", + "long": "AL Preemptive Halt Task/Application", + "med": "AL Preemptive Halt Task/Application", + "page": 12, + "short": "AL Preemptive Halt Task/Application", + "usage": 421, + }, + { + "category": "Other", + "long": "AL Integrated Help Center", + "med": "AL Integrated Help Center", + "page": 12, + "short": "AL Integrated Help Center", + "usage": 422, + }, + { + "category": "Other", + "long": "AL Documents", + "med": "AL Documents", + "page": 12, + "short": "AL Documents", + "usage": 423, + }, + { + "category": "Other", + "long": "AL Thesaurus", + "med": "AL Thesaurus", + "page": 12, + "short": "AL Thesaurus", + "usage": 424, + }, + { + "category": "Other", + "long": "AL Dictionary", + "med": "AL Dictionary", + "page": 12, + "short": "AL Dictionary", + "usage": 425, + }, + { + "category": "Other", + "long": "AL Desktop", + "med": "AL Desktop", + "page": 12, + "short": "AL Desktop", + "usage": 426, + }, + { + "category": "Other", + "long": "AL Spell Check", + "med": "AL Spell Check", + "page": 12, + "short": "AL Spell Check", + "usage": 427, + }, + { + "category": "Other", + "long": "AL Grammar Check", + "med": "AL Grammar Check", + "page": 12, + "short": "AL Grammar Check", + "usage": 428, + }, + { + "category": "Other", + "long": "AL Wireless Status", + "med": "AL Wireless Status", + "page": 12, + "short": "AL Wireless Status", + "usage": 429, + }, + { + "category": "Other", + "long": "AL Keyboard Layout", + "med": "AL Keyboard Layout", + "page": 12, + "short": "AL Keyboard Layout", + "usage": 430, + }, + { + "category": "Other", + "long": "AL Virus Protection", + "med": "AL Virus Protection", + "page": 12, + "short": "AL Virus Protection", + "usage": 431, + }, + { + "category": "Other", + "long": "AL Encryption", + "med": "AL Encryption", + "page": 12, + "short": "AL Encryption", + "usage": 432, + }, + { + "category": "Other", + "long": "AL Screen Saver", + "med": "AL Screen Saver", + "page": 12, + "short": "AL Screen Saver", + "usage": 433, + }, + { + "category": "Other", + "long": "AL Alarms", + "med": "AL Alarms", + "page": 12, + "short": "AL Alarms", + "usage": 434, + }, + { + "category": "Other", + "long": "AL Clock", + "med": "AL Clock", + "page": 12, + "short": "AL Clock", + "usage": 435, + }, + { + "category": "Other", + "long": "AL File Browser", + "med": "AL File Browser", + "page": 12, + "short": "AL File Browser", + "usage": 436, + }, + { + "category": "Other", + "long": "AL Power Status", + "med": "AL Power Status", + "page": 12, + "short": "AL Power Status", + "usage": 437, + }, + { + "category": "Other", + "long": "AL Image Browser", + "med": "AL Image Browser", + "page": 12, + "short": "AL Image Browser", + "usage": 438, + }, + { + "category": "Other", + "long": "AL Audio Browser", + "med": "AL Audio Browser", + "page": 12, + "short": "AL Audio Browser", + "usage": 439, + }, + { + "category": "Other", + "long": "AL Movie Browser", + "med": "AL Movie Browser", + "page": 12, + "short": "AL Movie Browser", + "usage": 440, + }, + { + "category": "Other", + "long": "AL Digital Rights Manager", + "med": "AL Digital Rights Manager", + "page": 12, + "short": "AL Digital Rights Manager", + "usage": 441, + }, + { + "category": "Other", + "long": "AL Digital Wallet", + "med": "AL Digital Wallet", + "page": 12, + "short": "AL Digital Wallet", + "usage": 442, + }, + { + "category": "Other", + "long": "AL Instant Messaging", + "med": "AL Instant Messaging", + "page": 12, + "short": "AL Instant Messaging", + "usage": 444, + }, + { + "category": "Other", + "long": "AL OEM Features/ Tips/Tutorial Browser", + "med": "AL OEM Features/ Tips/Tutorial Browser", + "page": 12, + "short": "AL OEM Features/ Tips/Tutorial Browser", + "usage": 445, + }, + { + "category": "Other", + "long": "AL OEM Help", + "med": "AL OEM Help", + "page": 12, + "short": "AL OEM Help", + "usage": 446, + }, + { + "category": "Other", + "long": "AL Online Community", + "med": "AL Online Community", + "page": 12, + "short": "AL Online Community", + "usage": 447, + }, + { + "category": "Other", + "long": "AL Entertainment Content Browser", + "med": "AL Entertainment Content Browser", + "page": 12, + "short": "AL Entertainment Content Browser", + "usage": 448, + }, + { + "category": "Other", + "long": "AL Online Shopping Browser", + "med": "AL Online Shopping Browser", + "page": 12, + "short": "AL Online Shopping Browser", + "usage": 449, + }, + { + "category": "Other", + "long": "AL SmartCard Information/Help", + "med": "AL SmartCard Information/Help", + "page": 12, + "short": "AL SmartCard Information/Help", + "usage": 450, + }, + { + "category": "Other", + "long": "AL Market Monitor/Finance Browser", + "med": "AL Market Monitor/Finance Browser", + "page": 12, + "short": "AL Market Monitor/Finance Browser", + "usage": 451, + }, + { + "category": "Other", + "long": "AL Customized Corporate News Browser", + "med": "AL Customized Corporate News Browser", + "page": 12, + "short": "AL Customized Corporate News Browser", + "usage": 452, + }, + { + "category": "Other", + "long": "AL Online Activity Browser", + "med": "AL Online Activity Browser", + "page": 12, + "short": "AL Online Activity Browser", + "usage": 453, + }, + { + "category": "Other", + "long": "AL Research/Search Browser", + "med": "AL Research/Search Browser", + "page": 12, + "short": "AL Research/Search Browser", + "usage": 454, + }, + { + "category": "Other", + "long": "AL Audio Player", + "med": "AL Audio Player", + "page": 12, + "short": "AL Audio Player", + "usage": 455, + }, + { + "category": "Other", + "long": "AL Message Status", + "med": "AL Message Status", + "page": 12, + "short": "AL Message Status", + "usage": 456, + }, + { + "category": "Other", + "long": "AL Contact Sync", + "med": "AL Contact Sync", + "page": 12, + "short": "AL Contact Sync", + "usage": 457, + }, + { + "category": "Other", + "long": "AL Navigation", + "med": "AL Navigation", + "page": 12, + "short": "AL Navigation", + "usage": 458, + }, + { + "category": "Other", + "long": "AL Context‐aware Desktop Assistant", + "med": "AL Context‐aware Desktop Assistant", + "page": 12, + "short": "AL Context‐aware Desktop Assistant", + "usage": 459, + }, + { + "category": "Other", + "long": "Generic GUI Application Controls", + "med": "Generic GUI Application Controls", + "page": 12, + "short": "Generic GUI Application Controls", + "usage": 512, + }, + { + "category": "Other", + "long": "AC New", + "med": "AC New", + "page": 12, + "short": "AC New", + "usage": 513, + }, + { + "category": "Other", + "long": "AC Open", + "med": "AC Open", + "page": 12, + "short": "AC Open", + "usage": 514, + }, + { + "category": "Other", + "long": "AC Close", + "med": "AC Close", + "page": 12, + "short": "AC Close", + "usage": 515, + }, + { + "category": "Other", + "long": "AC Exit", + "med": "AC Exit", + "page": 12, + "short": "AC Exit", + "usage": 516, + }, + { + "category": "Other", + "long": "AC Maximize", + "med": "AC Maximize", + "page": 12, + "short": "AC Maximize", + "usage": 517, + }, + { + "category": "Other", + "long": "AC Minimize", + "med": "AC Minimize", + "page": 12, + "short": "AC Minimize", + "usage": 518, + }, + { + "category": "Other", + "long": "AC Save", + "med": "AC Save", + "page": 12, + "short": "AC Save", + "usage": 519, + }, + { + "category": "Other", + "long": "AC Print", + "med": "AC Print", + "page": 12, + "short": "AC Print", + "usage": 520, + }, + { + "category": "Other", + "long": "AC Properties", + "med": "AC Properties", + "page": 12, + "short": "AC Properties", + "usage": 521, + }, + { + "category": "Other", + "long": "AC Undo", + "med": "AC Undo", + "page": 12, + "short": "AC Undo", + "usage": 538, + }, + { + "category": "Other", + "long": "AC Copy", + "med": "AC Copy", + "page": 12, + "short": "AC Copy", + "usage": 539, + }, + { + "category": "Other", + "long": "AC Cut", + "med": "AC Cut", + "page": 12, + "short": "AC Cut", + "usage": 540, + }, + { + "category": "Other", + "long": "AC Paste", + "med": "AC Paste", + "page": 12, + "short": "AC Paste", + "usage": 541, + }, + { + "category": "Other", + "long": "AC Select All", + "med": "AC Select All", + "page": 12, + "short": "AC Select All", + "usage": 542, + }, + { + "category": "Other", + "long": "AC Find", + "med": "AC Find", + "page": 12, + "short": "AC Find", + "usage": 543, + }, + { + "category": "Other", + "long": "AC Find and Replace", + "med": "AC Find and Replace", + "page": 12, + "short": "AC Find and Replace", + "usage": 544, + }, + { + "category": "Other", + "long": "AC Search", + "med": "AC Search", + "page": 12, + "short": "AC Search", + "usage": 545, + }, + { + "category": "Other", + "long": "AC Go To", + "med": "AC Go To", + "page": 12, + "short": "AC Go To", + "usage": 546, + }, + { + "category": "Other", + "long": "AC Home", + "med": "AC Home", + "page": 12, + "short": "AC Home", + "usage": 547, + }, + { + "category": "Other", + "long": "AC Back", + "med": "AC Back", + "page": 12, + "short": "AC Back", + "usage": 548, + }, + { + "category": "Other", + "long": "AC Forward", + "med": "AC Forward", + "page": 12, + "short": "AC Forward", + "usage": 549, + }, + { + "category": "Other", + "long": "AC Stop", + "med": "AC Stop", + "page": 12, + "short": "AC Stop", + "usage": 550, + }, + { + "category": "Other", + "long": "AC Refresh", + "med": "AC Refresh", + "page": 12, + "short": "AC Refresh", + "usage": 551, + }, + { + "category": "Other", + "long": "AC Previous Link", + "med": "AC Previous Link", + "page": 12, + "short": "AC Previous Link", + "usage": 552, + }, + { + "category": "Other", + "long": "AC Next Link", + "med": "AC Next Link", + "page": 12, + "short": "AC Next Link", + "usage": 553, + }, + { + "category": "Other", + "long": "AC Bookmarks", + "med": "AC Bookmarks", + "page": 12, + "short": "AC Bookmarks", + "usage": 554, + }, + { + "category": "Other", + "long": "AC History", + "med": "AC History", + "page": 12, + "short": "AC History", + "usage": 555, + }, + { + "category": "Other", + "long": "AC Subscriptions", + "med": "AC Subscriptions", + "page": 12, + "short": "AC Subscriptions", + "usage": 556, + }, + { + "category": "Other", + "long": "AC Zoom In", + "med": "AC Zoom In", + "page": 12, + "short": "AC Zoom In", + "usage": 557, + }, + { + "category": "Other", + "long": "AC Zoom Out", + "med": "AC Zoom Out", + "page": 12, + "short": "AC Zoom Out", + "usage": 558, + }, + { + "category": "Other", + "long": "AC Zoom", + "med": "AC Zoom", + "page": 12, + "short": "AC Zoom", + "usage": 559, + }, + { + "category": "Other", + "long": "AC Full Screen View", + "med": "AC Full Screen View", + "page": 12, + "short": "AC Full Screen View", + "usage": 560, + }, + { + "category": "Other", + "long": "AC Normal View", + "med": "AC Normal View", + "page": 12, + "short": "AC Normal View", + "usage": 561, + }, + { + "category": "Other", + "long": "AC View Toggle", + "med": "AC View Toggle", + "page": 12, + "short": "AC View Toggle", + "usage": 562, + }, + { + "category": "Other", + "long": "AC Scroll Up", + "med": "AC Scroll Up", + "page": 12, + "short": "AC Scroll Up", + "usage": 563, + }, + { + "category": "Other", + "long": "AC Scroll Down", + "med": "AC Scroll Down", + "page": 12, + "short": "AC Scroll Down", + "usage": 564, + }, + { + "category": "Other", + "long": "AC Scroll", + "med": "AC Scroll", + "page": 12, + "short": "AC Scroll", + "usage": 565, + }, + { + "category": "Other", + "long": "AC Pan Left", + "med": "AC Pan Left", + "page": 12, + "short": "AC Pan Left", + "usage": 566, + }, + { + "category": "Other", + "long": "AC Pan Right", + "med": "AC Pan Right", + "page": 12, + "short": "AC Pan Right", + "usage": 567, + }, + { + "category": "Other", + "long": "AC Pan", + "med": "AC Pan", + "page": 12, + "short": "AC Pan", + "usage": 568, + }, + { + "category": "Other", + "long": "AC New Window", + "med": "AC New Window", + "page": 12, + "short": "AC New Window", + "usage": 569, + }, + { + "category": "Other", + "long": "AC Tile Horizontally", + "med": "AC Tile Horizontally", + "page": 12, + "short": "AC Tile Horizontally", + "usage": 570, + }, + { + "category": "Other", + "long": "AC Tile Vertically", + "med": "AC Tile Vertically", + "page": 12, + "short": "AC Tile Vertically", + "usage": 571, + }, + { + "category": "Other", + "long": "AC Format", + "med": "AC Format", + "page": 12, + "short": "AC Format", + "usage": 572, + }, + { + "category": "Other", + "long": "AC Edit", + "med": "AC Edit", + "page": 12, + "short": "AC Edit", + "usage": 573, + }, + { + "category": "Other", + "long": "AC Bold", + "med": "AC Bold", + "page": 12, + "short": "AC Bold", + "usage": 574, + }, + { + "category": "Other", + "long": "AC Italics", + "med": "AC Italics", + "page": 12, + "short": "AC Italics", + "usage": 575, + }, + { + "category": "Other", + "long": "AC Underline", + "med": "AC Underline", + "page": 12, + "short": "AC Underline", + "usage": 576, + }, + { + "category": "Other", + "long": "AC Strikethrough", + "med": "AC Strikethrough", + "page": 12, + "short": "AC Strikethrough", + "usage": 577, + }, + { + "category": "Other", + "long": "AC Subscript", + "med": "AC Subscript", + "page": 12, + "short": "AC Subscript", + "usage": 578, + }, + { + "category": "Other", + "long": "AC Superscript", + "med": "AC Superscript", + "page": 12, + "short": "AC Superscript", + "usage": 579, + }, + { + "category": "Other", + "long": "AC All Caps", + "med": "AC All Caps", + "page": 12, + "short": "AC All Caps", + "usage": 580, + }, + { + "category": "Other", + "long": "AC Rotate", + "med": "AC Rotate", + "page": 12, + "short": "AC Rotate", + "usage": 581, + }, + { + "category": "Other", + "long": "AC Resize", + "med": "AC Resize", + "page": 12, + "short": "AC Resize", + "usage": 582, + }, + { + "category": "Other", + "long": "AC Flip Horizontal", + "med": "AC Flip Horizontal", + "page": 12, + "short": "AC Flip Horizontal", + "usage": 583, + }, + { + "category": "Other", + "long": "AC Flip Vertical", + "med": "AC Flip Vertical", + "page": 12, + "short": "AC Flip Vertical", + "usage": 584, + }, + { + "category": "Other", + "long": "AC Mirror Horizontal", + "med": "AC Mirror Horizontal", + "page": 12, + "short": "AC Mirror Horizontal", + "usage": 585, + }, + { + "category": "Other", + "long": "AC Mirror Vertical", + "med": "AC Mirror Vertical", + "page": 12, + "short": "AC Mirror Vertical", + "usage": 586, + }, + { + "category": "Other", + "long": "AC Font Select", + "med": "AC Font Select", + "page": 12, + "short": "AC Font Select", + "usage": 587, + }, + { + "category": "Other", + "long": "AC Font Color", + "med": "AC Font Color", + "page": 12, + "short": "AC Font Color", + "usage": 588, + }, + { + "category": "Other", + "long": "AC Font Size", + "med": "AC Font Size", + "page": 12, + "short": "AC Font Size", + "usage": 589, + }, + { + "category": "Other", + "long": "AC Justify Left", + "med": "AC Justify Left", + "page": 12, + "short": "AC Justify Left", + "usage": 590, + }, + { + "category": "Other", + "long": "AC Justify Center H", + "med": "AC Justify Center H", + "page": 12, + "short": "AC Justify Center H", + "usage": 591, + }, + { + "category": "Other", + "long": "AC Justify Right", + "med": "AC Justify Right", + "page": 12, + "short": "AC Justify Right", + "usage": 592, + }, + { + "category": "Other", + "long": "AC Justify Block H", + "med": "AC Justify Block H", + "page": 12, + "short": "AC Justify Block H", + "usage": 593, + }, + { + "category": "Other", + "long": "AC Justify Top", + "med": "AC Justify Top", + "page": 12, + "short": "AC Justify Top", + "usage": 594, + }, + { + "category": "Other", + "long": "AC Justify Center V", + "med": "AC Justify Center V", + "page": 12, + "short": "AC Justify Center V", + "usage": 595, + }, + { + "category": "Other", + "long": "AC Justify Bottom", + "med": "AC Justify Bottom", + "page": 12, + "short": "AC Justify Bottom", + "usage": 596, + }, + { + "category": "Other", + "long": "AC Justify Block V", + "med": "AC Justify Block V", + "page": 12, + "short": "AC Justify Block V", + "usage": 597, + }, + { + "category": "Other", + "long": "AC Indent Decrease", + "med": "AC Indent Decrease", + "page": 12, + "short": "AC Indent Decrease", + "usage": 598, + }, + { + "category": "Other", + "long": "AC Indent Increase", + "med": "AC Indent Increase", + "page": 12, + "short": "AC Indent Increase", + "usage": 599, + }, + { + "category": "Other", + "long": "AC Numbered List", + "med": "AC Numbered List", + "page": 12, + "short": "AC Numbered List", + "usage": 600, + }, + { + "category": "Other", + "long": "AC Restart Numbering", + "med": "AC Restart Numbering", + "page": 12, + "short": "AC Restart Numbering", + "usage": 601, + }, + { + "category": "Other", + "long": "AC Bulleted List", + "med": "AC Bulleted List", + "page": 12, + "short": "AC Bulleted List", + "usage": 602, + }, + { + "category": "Other", + "long": "AC Promote", + "med": "AC Promote", + "page": 12, + "short": "AC Promote", + "usage": 603, + }, + { + "category": "Other", + "long": "AC Demote", + "med": "AC Demote", + "page": 12, + "short": "AC Demote", + "usage": 604, + }, + { + "category": "Other", + "long": "AC Yes", + "med": "AC Yes", + "page": 12, + "short": "AC Yes", + "usage": 605, + }, + { + "category": "Other", + "long": "AC No", + "med": "AC No", + "page": 12, + "short": "AC No", + "usage": 606, + }, + { + "category": "Other", + "long": "AC Cancel", + "med": "AC Cancel", + "page": 12, + "short": "AC Cancel", + "usage": 607, + }, + { + "category": "Other", + "long": "AC Catalog", + "med": "AC Catalog", + "page": 12, + "short": "AC Catalog", + "usage": 608, + }, + { + "category": "Other", + "long": "AC Buy/Checkout", + "med": "AC Buy/Checkout", + "page": 12, + "short": "AC Buy/Checkout", + "usage": 609, + }, + { + "category": "Other", + "long": "AC Add to Cart", + "med": "AC Add to Cart", + "page": 12, + "short": "AC Add to Cart", + "usage": 610, + }, + { + "category": "Other", + "long": "AC Expand", + "med": "AC Expand", + "page": 12, + "short": "AC Expand", + "usage": 611, + }, + { + "category": "Other", + "long": "AC Expand All", + "med": "AC Expand All", + "page": 12, + "short": "AC Expand All", + "usage": 612, + }, + { + "category": "Other", + "long": "AC Collapse", + "med": "AC Collapse", + "page": 12, + "short": "AC Collapse", + "usage": 613, + }, + { + "category": "Other", + "long": "AC Collapse All", + "med": "AC Collapse All", + "page": 12, + "short": "AC Collapse All", + "usage": 614, + }, + { + "category": "Other", + "long": "AC Print Preview", + "med": "AC Print Preview", + "page": 12, + "short": "AC Print Preview", + "usage": 615, + }, + { + "category": "Other", + "long": "AC Paste Special", + "med": "AC Paste Special", + "page": 12, + "short": "AC Paste Special", + "usage": 616, + }, + { + "category": "Other", + "long": "AC Insert Mode", + "med": "AC Insert Mode", + "page": 12, + "short": "AC Insert Mode", + "usage": 617, + }, + { + "category": "Other", + "long": "AC Delete", + "med": "AC Delete", + "page": 12, + "short": "AC Delete", + "usage": 618, + }, + { + "category": "Other", + "long": "AC Lock", + "med": "AC Lock", + "page": 12, + "short": "AC Lock", + "usage": 619, + }, + { + "category": "Other", + "long": "AC Unlock", + "med": "AC Unlock", + "page": 12, + "short": "AC Unlock", + "usage": 620, + }, + { + "category": "Other", + "long": "AC Protect", + "med": "AC Protect", + "page": 12, + "short": "AC Protect", + "usage": 621, + }, + { + "category": "Other", + "long": "AC Unprotect", + "med": "AC Unprotect", + "page": 12, + "short": "AC Unprotect", + "usage": 622, + }, + { + "category": "Other", + "long": "AC Attach Comment", + "med": "AC Attach Comment", + "page": 12, + "short": "AC Attach Comment", + "usage": 623, + }, + { + "category": "Other", + "long": "AC Delete Comment", + "med": "AC Delete Comment", + "page": 12, + "short": "AC Delete Comment", + "usage": 624, + }, + { + "category": "Other", + "long": "AC View Comment", + "med": "AC View Comment", + "page": 12, + "short": "AC View Comment", + "usage": 625, + }, + { + "category": "Other", + "long": "AC Select Word", + "med": "AC Select Word", + "page": 12, + "short": "AC Select Word", + "usage": 626, + }, + { + "category": "Other", + "long": "AC Select Sentence", + "med": "AC Select Sentence", + "page": 12, + "short": "AC Select Sentence", + "usage": 627, + }, + { + "category": "Other", + "long": "AC Select Paragraph", + "med": "AC Select Paragraph", + "page": 12, + "short": "AC Select Paragraph", + "usage": 628, + }, + { + "category": "Other", + "long": "AC Select Column", + "med": "AC Select Column", + "page": 12, + "short": "AC Select Column", + "usage": 629, + }, + { + "category": "Other", + "long": "AC Select Row", + "med": "AC Select Row", + "page": 12, + "short": "AC Select Row", + "usage": 630, + }, + { + "category": "Other", + "long": "AC Select Table", + "med": "AC Select Table", + "page": 12, + "short": "AC Select Table", + "usage": 631, + }, + { + "category": "Other", + "long": "AC Select Object", + "med": "AC Select Object", + "page": 12, + "short": "AC Select Object", + "usage": 632, + }, + { + "category": "Other", + "long": "AC Redo/Repeat", + "med": "AC Redo/Repeat", + "page": 12, + "short": "AC Redo/Repeat", + "usage": 633, + }, + { + "category": "Other", + "long": "AC Sort", + "med": "AC Sort", + "page": 12, + "short": "AC Sort", + "usage": 634, + }, + { + "category": "Other", + "long": "AC Sort Ascending", + "med": "AC Sort Ascending", + "page": 12, + "short": "AC Sort Ascending", + "usage": 635, + }, + { + "category": "Other", + "long": "AC Sort Descending", + "med": "AC Sort Descending", + "page": 12, + "short": "AC Sort Descending", + "usage": 636, + }, + { + "category": "Other", + "long": "AC Filter", + "med": "AC Filter", + "page": 12, + "short": "AC Filter", + "usage": 637, + }, + { + "category": "Other", + "long": "AC Set Clock", + "med": "AC Set Clock", + "page": 12, + "short": "AC Set Clock", + "usage": 638, + }, + { + "category": "Other", + "long": "AC View Clock", + "med": "AC View Clock", + "page": 12, + "short": "AC View Clock", + "usage": 639, + }, + { + "category": "Other", + "long": "AC Select Time Zone", + "med": "AC Select Time Zone", + "page": 12, + "short": "AC Select Time Zone", + "usage": 640, + }, + { + "category": "Other", + "long": "AC Edit Time Zones", + "med": "AC Edit Time Zones", + "page": 12, + "short": "AC Edit Time Zones", + "usage": 641, + }, + { + "category": "Other", + "long": "AC Set Alarm", + "med": "AC Set Alarm", + "page": 12, + "short": "AC Set Alarm", + "usage": 642, + }, + { + "category": "Other", + "long": "AC Clear Alarm", + "med": "AC Clear Alarm", + "page": 12, + "short": "AC Clear Alarm", + "usage": 643, + }, + { + "category": "Other", + "long": "AC Snooze Alarm", + "med": "AC Snooze Alarm", + "page": 12, + "short": "AC Snooze Alarm", + "usage": 644, + }, + { + "category": "Other", + "long": "AC Reset Alarm", + "med": "AC Reset Alarm", + "page": 12, + "short": "AC Reset Alarm", + "usage": 645, + }, + { + "category": "Other", + "long": "AC Synchronize", + "med": "AC Synchronize", + "page": 12, + "short": "AC Synchronize", + "usage": 646, + }, + { + "category": "Other", + "long": "AC Send/Receive", + "med": "AC Send/Receive", + "page": 12, + "short": "AC Send/Receive", + "usage": 647, + }, + { + "category": "Other", + "long": "AC Send To", + "med": "AC Send To", + "page": 12, + "short": "AC Send To", + "usage": 648, + }, + { + "category": "Other", + "long": "AC Reply", + "med": "AC Reply", + "page": 12, + "short": "AC Reply", + "usage": 649, + }, + { + "category": "Other", + "long": "AC Reply All", + "med": "AC Reply All", + "page": 12, + "short": "AC Reply All", + "usage": 650, + }, + { + "category": "Other", + "long": "AC Forward Msg", + "med": "AC Forward Msg", + "page": 12, + "short": "AC Forward Msg", + "usage": 651, + }, + { + "category": "Other", + "long": "AC Send", + "med": "AC Send", + "page": 12, + "short": "AC Send", + "usage": 652, + }, + { + "category": "Other", + "long": "AC Attach File", + "med": "AC Attach File", + "page": 12, + "short": "AC Attach File", + "usage": 653, + }, + { + "category": "Other", + "long": "AC Upload", + "med": "AC Upload", + "page": 12, + "short": "AC Upload", + "usage": 654, + }, + { + "category": "Other", + "long": "AC Download (Save Target As)", + "med": "AC Download (Save Target As)", + "page": 12, + "short": "AC Download (Save Target As)", + "usage": 655, + }, + { + "category": "Other", + "long": "AC Set Borders", + "med": "AC Set Borders", + "page": 12, + "short": "AC Set Borders", + "usage": 656, + }, + { + "category": "Other", + "long": "AC Insert Row", + "med": "AC Insert Row", + "page": 12, + "short": "AC Insert Row", + "usage": 657, + }, + { + "category": "Other", + "long": "AC Insert Column", + "med": "AC Insert Column", + "page": 12, + "short": "AC Insert Column", + "usage": 658, + }, + { + "category": "Other", + "long": "AC Insert File", + "med": "AC Insert File", + "page": 12, + "short": "AC Insert File", + "usage": 659, + }, + { + "category": "Other", + "long": "AC Insert Picture", + "med": "AC Insert Picture", + "page": 12, + "short": "AC Insert Picture", + "usage": 660, + }, + { + "category": "Other", + "long": "AC Insert Object", + "med": "AC Insert Object", + "page": 12, + "short": "AC Insert Object", + "usage": 661, + }, + { + "category": "Other", + "long": "AC Insert Symbol", + "med": "AC Insert Symbol", + "page": 12, + "short": "AC Insert Symbol", + "usage": 662, + }, + { + "category": "Other", + "long": "AC Save and Close", + "med": "AC Save and Close", + "page": 12, + "short": "AC Save and Close", + "usage": 663, + }, + { + "category": "Other", + "long": "AC Rename", + "med": "AC Rename", + "page": 12, + "short": "AC Rename", + "usage": 664, + }, + { + "category": "Other", + "long": "AC Merge", + "med": "AC Merge", + "page": 12, + "short": "AC Merge", + "usage": 665, + }, + { + "category": "Other", + "long": "AC Split", + "med": "AC Split", + "page": 12, + "short": "AC Split", + "usage": 666, + }, + { + "category": "Other", + "long": "AC Disribute Horizontally", + "med": "AC Disribute Horizontally", + "page": 12, + "short": "AC Disribute Horizontally", + "usage": 667, + }, + { + "category": "Other", + "long": "AC Distribute Vertically", + "med": "AC Distribute Vertically", + "page": 12, + "short": "AC Distribute Vertically", + "usage": 668, + }, + { + "category": "Other", + "long": "AC Next Keyboard Layout Select", + "med": "AC Next Keyboard Layout Select", + "page": 12, + "short": "AC Next Keyboard Layout Select", + "usage": 669, + }, + { + "category": "Other", + "long": "AC Navigation Guidance", + "med": "AC Navigation Guidance", + "page": 12, + "short": "AC Navigation Guidance", + "usage": 670, + }, + { + "category": "Other", + "long": "AC Desktop Show All Windows", + "med": "AC Desktop Show All Windows", + "page": 12, + "short": "AC Desktop Show All Windows", + "usage": 671, + }, + { + "category": "Other", + "long": "AC Soft Key Left", + "med": "AC Soft Key Left", + "page": 12, + "short": "AC Soft Key Left", + "usage": 672, + }, + { + "category": "Other", + "long": "AC Soft Key Right", + "med": "AC Soft Key Right", + "page": 12, + "short": "AC Soft Key Right", + "usage": 673, + }, + { + "category": "Other", + "long": "AC Desktop Show All Applications", + "med": "AC Desktop Show All Applications", + "page": 12, + "short": "AC Desktop Show All Applications", + "usage": 674, + }, + { + "category": "Other", + "long": "AC Idle Keep Alive", + "med": "AC Idle Keep Alive", + "page": 12, + "short": "AC Idle Keep Alive", + "usage": 688, + }, + { + "category": "Other", + "long": "Extended Keyboard Attributes Collection", + "med": "Extended Keyboard Attributes Collection", + "page": 12, + "short": "Extended Keyboard Attributes Collection", + "usage": 704, + }, + { + "category": "Other", + "long": "Keyboard Form Factor", + "med": "Form Factor", + "page": 12, + "short": "Form Factor", + "usage": 705, + }, + { + "category": "Other", + "long": "Keyboard Key Type", + "med": "Key Type", + "page": 12, + "short": "Key Type", + "usage": 706, + }, + { + "category": "Other", + "long": "Keyboard Physical Layout", + "med": "Physical Layout", + "page": 12, + "short": "Physical Layout", + "usage": 707, + }, + { + "category": "Other", + "long": "Vendor‐Specific Keyboard Physical Layout", + "med": "Vendor‐Specific Keyboard Physical Layout", + "page": 12, + "short": "Vendor‐Specific Keyboard Physical Layout", + "usage": 708, + }, + { + "category": "Other", + "long": "Keyboard IETF Language Tag Index", + "med": "IETF Language Tag Index", + "page": 12, + "short": "IETF Language Tag Index", + "usage": 709, + }, + { + "category": "Other", + "long": "Implemented Keyboard Input Assist Controls", + "med": "Implemented Keyboard Input Assist Controls", + "page": 12, + "short": "Implemented Keyboard Input Assist Controls", + "usage": 710, + }, + { + "category": "Other", + "long": "Keyboard Input Assist Previous", + "med": "Input Assist Previous", + "page": 12, + "short": "Input Assist Previous", + "usage": 711, + }, + { + "category": "Other", + "long": "Keyboard Input Assist Next", + "med": "Input Assist Next", + "page": 12, + "short": "Input Assist Next", + "usage": 712, + }, + { + "category": "Other", + "long": "Keyboard Input Assist Previous Group", + "med": "Input Assist Previous Group", + "page": 12, + "short": "Input Assist Previous Group", + "usage": 713, + }, + { + "category": "Other", + "long": "Keyboard Input Assist Next Group", + "med": "Input Assist Next Group", + "page": 12, + "short": "Input Assist Next Group", + "usage": 714, + }, + { + "category": "Other", + "long": "Keyboard Input Assist Accept", + "med": "Input Assist Accept", + "page": 12, + "short": "Input Assist Accept", + "usage": 715, + }, + { + "category": "Other", + "long": "Keyboard Input Assist Cancel", + "med": "Input Assist Cancel", + "page": 12, + "short": "Input Assist Cancel", + "usage": 716, + }, + { + "category": "Other", + "long": "Privacy Screen Toggle", + "med": "Privacy Screen Toggle", + "page": 12, + "short": "Privacy Screen Toggle", + "usage": 720, + }, + { + "category": "Other", + "long": "Privacy Screen Level Decrement", + "med": "Privacy Screen Level Decrement", + "page": 12, + "short": "Privacy Screen Level Decrement", + "usage": 721, + }, + { + "category": "Other", + "long": "Privacy Screen Level Increment", + "med": "Privacy Screen Level Increment", + "page": 12, + "short": "Privacy Screen Level Increment", + "usage": 722, + }, + { + "category": "Other", + "long": "Privacy Screen Level Minimum", + "med": "Privacy Screen Level Minimum", + "page": 12, + "short": "Privacy Screen Level Minimum", + "usage": 723, + }, + { + "category": "Other", + "long": "Privacy Screen Level Maximum", + "med": "Privacy Screen Level Maximum", + "page": 12, + "short": "Privacy Screen Level Maximum", + "usage": 724, + }, + { + "category": "Other", + "long": "Contact Edited", + "med": "Contact Edited", + "page": 12, + "short": "Contact Edited", + "usage": 1280, + }, + { + "category": "Other", + "long": "Contact Added", + "med": "Contact Added", + "page": 12, + "short": "Contact Added", + "usage": 1281, + }, + { + "category": "Other", + "long": "Contact Record Active", + "med": "Contact Record Active", + "page": 12, + "short": "Contact Record Active", + "usage": 1282, + }, + { + "category": "Other", + "long": "Contact Index", + "med": "Contact Index", + "page": 12, + "short": "Contact Index", + "usage": 1283, + }, + { + "category": "Other", + "long": "Contact Nickname", + "med": "Contact Nickname", + "page": 12, + "short": "Contact Nickname", + "usage": 1284, + }, + { + "category": "Other", + "long": "Contact First Name", + "med": "Contact First Name", + "page": 12, + "short": "Contact First Name", + "usage": 1285, + }, + { + "category": "Other", + "long": "Contact Last Name", + "med": "Contact Last Name", + "page": 12, + "short": "Contact Last Name", + "usage": 1286, + }, + { + "category": "Other", + "long": "Contact Full Name", + "med": "Contact Full Name", + "page": 12, + "short": "Contact Full Name", + "usage": 1287, + }, + { + "category": "Other", + "long": "Contact Phone Number Personal", + "med": "Contact Phone Number Personal", + "page": 12, + "short": "Contact Phone Number Personal", + "usage": 1288, + }, + { + "category": "Other", + "long": "Contact Phone Number Business", + "med": "Contact Phone Number Business", + "page": 12, + "short": "Contact Phone Number Business", + "usage": 1289, + }, + { + "category": "Other", + "long": "Contact Phone Number Mobile", + "med": "Contact Phone Number Mobile", + "page": 12, + "short": "Contact Phone Number Mobile", + "usage": 1290, + }, + { + "category": "Other", + "long": "Contact Phone Number Pager", + "med": "Contact Phone Number Pager", + "page": 12, + "short": "Contact Phone Number Pager", + "usage": 1291, + }, + { + "category": "Other", + "long": "Contact Phone Number Fax", + "med": "Contact Phone Number Fax", + "page": 12, + "short": "Contact Phone Number Fax", + "usage": 1292, + }, + { + "category": "Other", + "long": "Contact Phone Number Other", + "med": "Contact Phone Number Other", + "page": 12, + "short": "Contact Phone Number Other", + "usage": 1293, + }, + { + "category": "Other", + "long": "Contact Email Personal", + "med": "Contact Email Personal", + "page": 12, + "short": "Contact Email Personal", + "usage": 1294, + }, + { + "category": "Other", + "long": "Contact Email Business", + "med": "Contact Email Business", + "page": 12, + "short": "Contact Email Business", + "usage": 1295, + }, + { + "category": "Other", + "long": "Contact Email Other", + "med": "Contact Email Other", + "page": 12, + "short": "Contact Email Other", + "usage": 1296, + }, + { + "category": "Other", + "long": "Contact Email Main", + "med": "Contact Email Main", + "page": 12, + "short": "Contact Email Main", + "usage": 1297, + }, + { + "category": "Other", + "long": "Contact Speed Dial Number", + "med": "Contact Speed Dial Number", + "page": 12, + "short": "Contact Speed Dial Number", + "usage": 1298, + }, + { + "category": "Other", + "long": "Contact Status Flag", + "med": "Contact Status Flag", + "page": 12, + "short": "Contact Status Flag", + "usage": 1299, + }, + { + "category": "Other", + "long": "Contact Misc.", + "med": "Contact Misc.", + "page": 12, + "short": "Contact Misc.", + "usage": 1300, + }, +] +`; + +exports[`hid_usage_page_get_ids > returns the expected pages with stable usage counts 1`] = ` +[ + { + "id": 12, + "usageCount": 450, + }, + { + "id": 7, + "usageCount": 218, + }, +] +`; diff --git a/src/__snapshots__/keymap-parser.test.ts.snap b/src/__snapshots__/keymap-parser.test.ts.snap new file mode 100644 index 00000000..a86f5383 --- /dev/null +++ b/src/__snapshots__/keymap-parser.test.ts.snap @@ -0,0 +1,530 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`keymap-parser canonical table > captures every canonical ZMK name <-> HID code mapping 1`] = ` +[ + { + "code": "0x00070004", + "name": "A", + }, + { + "code": "0x00070005", + "name": "B", + }, + { + "code": "0x00070006", + "name": "C", + }, + { + "code": "0x00070007", + "name": "D", + }, + { + "code": "0x00070008", + "name": "E", + }, + { + "code": "0x00070009", + "name": "F", + }, + { + "code": "0x0007000a", + "name": "G", + }, + { + "code": "0x0007000b", + "name": "H", + }, + { + "code": "0x0007000c", + "name": "I", + }, + { + "code": "0x0007000d", + "name": "J", + }, + { + "code": "0x0007000e", + "name": "K", + }, + { + "code": "0x0007000f", + "name": "L", + }, + { + "code": "0x00070010", + "name": "M", + }, + { + "code": "0x00070011", + "name": "N", + }, + { + "code": "0x00070012", + "name": "O", + }, + { + "code": "0x00070013", + "name": "P", + }, + { + "code": "0x00070014", + "name": "Q", + }, + { + "code": "0x00070015", + "name": "R", + }, + { + "code": "0x00070016", + "name": "S", + }, + { + "code": "0x00070017", + "name": "T", + }, + { + "code": "0x00070018", + "name": "U", + }, + { + "code": "0x00070019", + "name": "V", + }, + { + "code": "0x0007001a", + "name": "W", + }, + { + "code": "0x0007001b", + "name": "X", + }, + { + "code": "0x0007001c", + "name": "Y", + }, + { + "code": "0x0007001d", + "name": "Z", + }, + { + "code": "0x0007001e", + "name": "N1", + }, + { + "code": "0x0007001f", + "name": "N2", + }, + { + "code": "0x00070020", + "name": "N3", + }, + { + "code": "0x00070021", + "name": "N4", + }, + { + "code": "0x00070022", + "name": "N5", + }, + { + "code": "0x00070023", + "name": "N6", + }, + { + "code": "0x00070024", + "name": "N7", + }, + { + "code": "0x00070025", + "name": "N8", + }, + { + "code": "0x00070026", + "name": "N9", + }, + { + "code": "0x00070027", + "name": "N0", + }, + { + "code": "0x00070028", + "name": "RET", + }, + { + "code": "0x00070029", + "name": "ESC", + }, + { + "code": "0x0007002a", + "name": "BSPC", + }, + { + "code": "0x0007002b", + "name": "TAB", + }, + { + "code": "0x0007002c", + "name": "SPACE", + }, + { + "code": "0x0007002d", + "name": "MINUS", + }, + { + "code": "0x0007002e", + "name": "EQUAL", + }, + { + "code": "0x0007002f", + "name": "LBKT", + }, + { + "code": "0x00070030", + "name": "RBKT", + }, + { + "code": "0x00070031", + "name": "BSLH", + }, + { + "code": "0x00070032", + "name": "NUHS", + }, + { + "code": "0x00070033", + "name": "SEMI", + }, + { + "code": "0x00070034", + "name": "SQT", + }, + { + "code": "0x00070035", + "name": "GRAVE", + }, + { + "code": "0x00070036", + "name": "COMMA", + }, + { + "code": "0x00070037", + "name": "DOT", + }, + { + "code": "0x00070038", + "name": "FSLH", + }, + { + "code": "0x00070039", + "name": "CAPS", + }, + { + "code": "0x0007003a", + "name": "F1", + }, + { + "code": "0x0007003b", + "name": "F2", + }, + { + "code": "0x0007003c", + "name": "F3", + }, + { + "code": "0x0007003d", + "name": "F4", + }, + { + "code": "0x0007003e", + "name": "F5", + }, + { + "code": "0x0007003f", + "name": "F6", + }, + { + "code": "0x00070040", + "name": "F7", + }, + { + "code": "0x00070041", + "name": "F8", + }, + { + "code": "0x00070042", + "name": "F9", + }, + { + "code": "0x00070043", + "name": "F10", + }, + { + "code": "0x00070044", + "name": "F11", + }, + { + "code": "0x00070045", + "name": "F12", + }, + { + "code": "0x00070046", + "name": "PRSC", + }, + { + "code": "0x00070047", + "name": "SLCK", + }, + { + "code": "0x00070048", + "name": "PAUSE", + }, + { + "code": "0x00070049", + "name": "INS", + }, + { + "code": "0x0007004a", + "name": "HOME", + }, + { + "code": "0x0007004b", + "name": "PGUP", + }, + { + "code": "0x0007004c", + "name": "DEL", + }, + { + "code": "0x0007004d", + "name": "END", + }, + { + "code": "0x0007004e", + "name": "PGDN", + }, + { + "code": "0x0007004f", + "name": "RIGHT", + }, + { + "code": "0x00070050", + "name": "LEFT", + }, + { + "code": "0x00070051", + "name": "DOWN", + }, + { + "code": "0x00070052", + "name": "UP", + }, + { + "code": "0x00070053", + "name": "KP_NUM", + }, + { + "code": "0x00070054", + "name": "KP_SLASH", + }, + { + "code": "0x00070055", + "name": "KP_ASTERISK", + }, + { + "code": "0x00070056", + "name": "KP_MINUS", + }, + { + "code": "0x00070057", + "name": "KP_PLUS", + }, + { + "code": "0x00070058", + "name": "KP_ENTER", + }, + { + "code": "0x00070059", + "name": "KP_N1", + }, + { + "code": "0x0007005a", + "name": "KP_N2", + }, + { + "code": "0x0007005b", + "name": "KP_N3", + }, + { + "code": "0x0007005c", + "name": "KP_N4", + }, + { + "code": "0x0007005d", + "name": "KP_N5", + }, + { + "code": "0x0007005e", + "name": "KP_N6", + }, + { + "code": "0x0007005f", + "name": "KP_N7", + }, + { + "code": "0x00070060", + "name": "KP_N8", + }, + { + "code": "0x00070061", + "name": "KP_N9", + }, + { + "code": "0x00070062", + "name": "KP_N0", + }, + { + "code": "0x00070063", + "name": "KP_DOT", + }, + { + "code": "0x00070064", + "name": "NUBS", + }, + { + "code": "0x00070065", + "name": "K_APP", + }, + { + "code": "0x00070067", + "name": "KP_EQUAL", + }, + { + "code": "0x00070068", + "name": "F13", + }, + { + "code": "0x00070069", + "name": "F14", + }, + { + "code": "0x0007006a", + "name": "F15", + }, + { + "code": "0x0007006b", + "name": "F16", + }, + { + "code": "0x0007006c", + "name": "F17", + }, + { + "code": "0x0007006d", + "name": "F18", + }, + { + "code": "0x0007006e", + "name": "F19", + }, + { + "code": "0x0007006f", + "name": "F20", + }, + { + "code": "0x00070070", + "name": "F21", + }, + { + "code": "0x00070071", + "name": "F22", + }, + { + "code": "0x00070072", + "name": "F23", + }, + { + "code": "0x00070073", + "name": "F24", + }, + { + "code": "0x000700e0", + "name": "LCTL", + }, + { + "code": "0x000700e1", + "name": "LSHFT", + }, + { + "code": "0x000700e2", + "name": "LALT", + }, + { + "code": "0x000700e3", + "name": "LGUI", + }, + { + "code": "0x000700e4", + "name": "RCTL", + }, + { + "code": "0x000700e5", + "name": "RSHFT", + }, + { + "code": "0x000700e6", + "name": "RALT", + }, + { + "code": "0x000700e7", + "name": "RGUI", + }, + { + "code": "0x000c0030", + "name": "C_PWR", + }, + { + "code": "0x000c0032", + "name": "C_SLEEP", + }, + { + "code": "0x000c006f", + "name": "C_BRI_UP", + }, + { + "code": "0x000c0070", + "name": "C_BRI_DN", + }, + { + "code": "0x000c00b5", + "name": "C_NEXT", + }, + { + "code": "0x000c00b6", + "name": "C_PREV", + }, + { + "code": "0x000c00b7", + "name": "C_STOP", + }, + { + "code": "0x000c00b8", + "name": "C_EJECT", + }, + { + "code": "0x000c00cd", + "name": "C_PP", + }, + { + "code": "0x000c00e2", + "name": "C_MUTE", + }, + { + "code": "0x000c00e9", + "name": "C_VOL_UP", + }, + { + "code": "0x000c00ea", + "name": "C_VOL_DN", + }, +] +`; diff --git a/src/hid-usages.test.ts b/src/hid-usages.test.ts new file mode 100644 index 00000000..48584be1 --- /dev/null +++ b/src/hid-usages.test.ts @@ -0,0 +1,74 @@ +import { describe, expect, it } from "vitest"; + +import { UsagePages } from "./keyboard-and-consumer-usage-tables.json"; +import HidOverrides from "./hid-usage-metadata.json"; +import { + hid_usage_get_label, + hid_usage_get_metadata, + hid_usage_page_get_ids, +} from "./hid-usages"; + +// Enumerate every (page, usage) pair that *could* surface a label in the UI: +// every entry in the HID spec table for pages we use, plus every entry that +// has a hand-curated override. Sorted so the snapshot diff is stable. +const allPairs = (() => { + const seen = new Set(); + const out: Array<{ page: number; usage: number }> = []; + for (const page of UsagePages) { + for (const u of page.UsageIds) { + const k = `${page.Id}:${u.Id}`; + if (!seen.has(k)) { + seen.add(k); + out.push({ page: page.Id, usage: u.Id }); + } + } + } + for (const [pageStr, idMap] of Object.entries( + HidOverrides as Record> + )) { + for (const idStr of Object.keys(idMap)) { + const k = `${pageStr}:${idStr}`; + if (!seen.has(k)) { + seen.add(k); + out.push({ page: Number(pageStr), usage: Number(idStr) }); + } + } + } + out.sort((a, b) => a.page - b.page || a.usage - b.usage); + return out; +})(); + +describe("hid_usage_get_metadata", () => { + it("captures the full picker-label baseline (pre-SSOT snapshot)", () => { + const snapshot = allPairs.map(({ page, usage }) => ({ + page, + usage, + ...hid_usage_get_metadata(page, usage), + })); + expect(snapshot).toMatchSnapshot(); + }); +}); + +describe("hid_usage_get_label", () => { + it("captures the compact-label baseline (pre-SSOT snapshot)", () => { + const snapshot = allPairs.map(({ page, usage }) => ({ + page, + usage, + label: hid_usage_get_label(page, usage), + })); + expect(snapshot).toMatchSnapshot(); + }); +}); + +describe("hid_usage_page_get_ids", () => { + // Just the page IDs / sizes — the full usage lists are huge and already + // covered by the snapshots above. This is here so a future refactor that + // accidentally drops a page (e.g. consumer 0x0c) trips a loud test. + it("returns the expected pages with stable usage counts", () => { + const pages = UsagePages.map((p) => ({ + id: p.Id, + usageCount: hid_usage_page_get_ids(p.Id)?.UsageIds.length ?? 0, + })); + expect(pages).toMatchSnapshot(); + }); +}); diff --git a/src/keymap-parser.test.ts b/src/keymap-parser.test.ts new file mode 100644 index 00000000..d2c43032 --- /dev/null +++ b/src/keymap-parser.test.ts @@ -0,0 +1,52 @@ +import { describe, expect, it } from "vitest"; + +import { + codeToZmkName, + keycodeLookup, + formatBindingParam, + parseBindingParam, +} from "./keymap-parser"; + +describe("keymap-parser canonical table", () => { + it("captures every canonical ZMK name <-> HID code mapping", () => { + // Snapshot the full canonical name table so a future SSOT refactor + // (e.g. moving names into src/keycodes.ts) trips loudly if any name + // or code drifts. Sorted by code for stable diffs. + const entries = [...codeToZmkName.entries()] + .sort(([a], [b]) => a - b) + .map(([code, name]) => ({ + code: `0x${code.toString(16).padStart(8, "0")}`, + name, + })); + expect(entries).toMatchSnapshot(); + }); + + it("round-trips every canonical name through formatBindingParam", () => { + // For each canonical name in the table: name -> code -> formatted name + // must equal the canonical name. Guards against forward/reverse drift. + for (const [code, canonicalName] of codeToZmkName.entries()) { + const formatted = formatBindingParam(code); + expect(formatted, `code 0x${code.toString(16)}`).toBe(canonicalName); + } + }); + + it("round-trips every canonical name through parseBindingParam", () => { + for (const [code, canonicalName] of codeToZmkName.entries()) { + const parsed = parseBindingParam(canonicalName); + expect(parsed, `name ${canonicalName}`).toBe(code); + } + }); + + it("treats LS()/LC()/... modifier wrappers as inverses of formatBindingParam", () => { + // Pick a representative key (N1) and verify each modifier wrapper + // round-trips. Catches accidental changes to the modifier bit layout. + const n1 = keycodeLookup.get("N1"); + expect(n1).toBeDefined(); + for (const mod of ["LC", "LS", "LA", "LG", "RC", "RS", "RA", "RG"]) { + const token = `${mod}(N1)`; + const code = parseBindingParam(token); + expect(code, token).toBeDefined(); + expect(formatBindingParam(code!), token).toBe(token); + } + }); +}); From a69af44e2fd7817dcd78d7c3aabe8e232a8ee83e Mon Sep 17 00:00:00 2001 From: numachang Date: Mon, 25 May 2026 21:13:41 +0900 Subject: [PATCH 2/2] refactor(keycodes): Consolidate ZMK names and picker labels into one TS table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ZMK keymap text names (used by import / export) and picker UI labels (used by the keycap grid) used to live in two independent places — an inline `ZMK_KEYCODES` array inside keymap-parser.ts and the hid-usage-metadata.json from upstream PR #159. Both could drift; HID 7:230 famously labelled "AltGr" in the picker but exported as `&kp RALT`. Promote both to a single TS table in src/keycodes.ts: - One `Keycode` row per (page, usage) carries the ZMK `name`, picker `short` / `med` / `long`, and picker `category`. Editing one row updates both the picker and the exporter. - keymap-parser.ts derives `keycodeLookup` / `codeToZmkName` from the rows whose `name` is set; the parser-side alias map widens to also accept any `short` / `med` / `long` label as a parser input, so hand-edited keymaps using picker labels (e.g. "Volume Up") still resolve. - hid-usages.ts looks up labels from the same table, falling back to the HID spec name for usages we don't curate. - hid-usage-metadata.json is removed. The Vitest snapshot baselines from the previous commit catch any visual regression — picker labels and the canonical name table are byte-for-byte identical post-refactor. Closes #2. Co-Authored-By: Claude --- src/hid-usage-metadata.json | 282 ------------------------------------ src/hid-usages.test.ts | 20 +-- src/hid-usages.ts | 55 +++---- src/keycodes.ts | 270 ++++++++++++++++++++++++++++++++++ src/keymap-parser.ts | 108 ++------------ 5 files changed, 323 insertions(+), 412 deletions(-) delete mode 100644 src/hid-usage-metadata.json create mode 100644 src/keycodes.ts diff --git a/src/hid-usage-metadata.json b/src/hid-usage-metadata.json deleted file mode 100644 index 555eb148..00000000 --- a/src/hid-usage-metadata.json +++ /dev/null @@ -1,282 +0,0 @@ -{ - "7": { - "4": { "category": "Letters" }, - "5": { "category": "Letters" }, - "6": { "category": "Letters" }, - "7": { "category": "Letters" }, - "8": { "category": "Letters" }, - "9": { "category": "Letters" }, - "10": { "category": "Letters" }, - "11": { "category": "Letters" }, - "12": { "category": "Letters" }, - "13": { "category": "Letters" }, - "14": { "category": "Letters" }, - "15": { "category": "Letters" }, - "16": { "category": "Letters" }, - "17": { "category": "Letters" }, - "18": { "category": "Letters" }, - "19": { "category": "Letters" }, - "20": { "category": "Letters" }, - "21": { "category": "Letters" }, - "22": { "category": "Letters" }, - "23": { "category": "Letters" }, - "24": { "category": "Letters" }, - "25": { "category": "Letters" }, - "26": { "category": "Letters" }, - "27": { "category": "Letters" }, - "28": { "category": "Letters" }, - "29": { "category": "Letters" }, - "30": { "short": "1 !", "category": "Numbers + Punctuation" }, - "31": { "short": "2 @", "category": "Numbers + Punctuation" }, - "32": { "short": "3 #", "category": "Numbers + Punctuation" }, - "33": { "short": "4 $", "category": "Numbers + Punctuation" }, - "34": { "short": "5 %", "category": "Numbers + Punctuation" }, - "35": { "short": "6 ^", "category": "Numbers + Punctuation" }, - "36": { "short": "7 &", "category": "Numbers + Punctuation" }, - "37": { "short": "8 *", "category": "Numbers + Punctuation" }, - "38": { "short": "9 (", "category": "Numbers + Punctuation" }, - "39": { "short": "0 )", "category": "Numbers + Punctuation" }, - "40": { - "short": "Ret", - "med": "Return", - "category": "Function + Navigation" - }, - "41": { - "short": "Esc", - "long": "Escape", - "category": "Function + Navigation" - }, - "42": { - "short": "BkSp", - "med": "BkSpc", - "long": "Backspace", - "category": "Function + Navigation" - }, - "43": { "category": "Function + Navigation" }, - "44": { "short": "␣", "med": "Space", "category": "Function + Navigation" }, - "45": { - "short": "- _", - "med": "Dash", - "category": "Numbers + Punctuation" - }, - "46": { - "short": "= +", - "med": "Equals", - "category": "Numbers + Punctuation" - }, - "47": { "short": "[ {", "category": "Numbers + Punctuation" }, - "48": { "short": "] }", "category": "Numbers + Punctuation" }, - "49": { "short": "\\ |", "category": "Numbers + Punctuation" }, - "50": { - "short": "NUHS", - "long": "NonUS Hash", - "category": "International" - }, - "51": { "short": "; :", "category": "Numbers + Punctuation" }, - "52": { "short": "' \"", "category": "Numbers + Punctuation" }, - "53": { "short": "` ~", "category": "Numbers + Punctuation" }, - "54": { "short": ", <", "category": "Numbers + Punctuation" }, - "55": { "short": ". >", "category": "Numbers + Punctuation" }, - "56": { "short": "/ ?", "category": "Numbers + Punctuation" }, - "57": { - "short": "Cap", - "med": "CapsLk", - "long": "Caps Lock", - "category": "Function + Navigation" - }, - "58": { "category": "Function + Navigation" }, - "59": { "category": "Function + Navigation" }, - "60": { "category": "Function + Navigation" }, - "61": { "category": "Function + Navigation" }, - "62": { "category": "Function + Navigation" }, - "63": { "category": "Function + Navigation" }, - "64": { "category": "Function + Navigation" }, - "65": { "category": "Function + Navigation" }, - "66": { "category": "Function + Navigation" }, - "67": { "category": "Function + Navigation" }, - "68": { "category": "Function + Navigation" }, - "69": { "category": "Function + Navigation" }, - "70": { - "short": "PrSc", - "long": "Print Scr", - "category": "Function + Navigation" - }, - "71": { - "short": "ScLk", - "long": "ScrollLock", - "category": "Function + Navigation" - }, - "72": { - "short": "Paus", - "med": "Pause", - "category": "Function + Navigation" - }, - "73": { - "short": "Ins", - "med": "Insert", - "category": "Function + Navigation" - }, - "74": { "category": "Function + Navigation" }, - "75": { - "short": "PgUp", - "med": "PageUp", - "long": "Page Up", - "category": "Function + Navigation" - }, - "76": { - "short": "Del", - "med": "Delete", - "category": "Function + Navigation" - }, - "77": { "category": "Function + Navigation" }, - "78": { - "short": "PgDn", - "med": "PageDn", - "long": "Page Down", - "category": "Function + Navigation" - }, - "79": { "short": "→", "category": "Function + Navigation" }, - "80": { "short": "←", "category": "Function + Navigation" }, - "81": { "short": "↓", "category": "Function + Navigation" }, - "82": { "short": "↑", "category": "Function + Navigation" }, - "83": { - "short": "Num", - "med": "NumLck", - "long": "Num Lock", - "category": "Numpad" - }, - "84": { "short": "/", "category": "Numpad" }, - "85": { "short": "*", "category": "Numpad" }, - "86": { "short": "-", "category": "Numpad" }, - "87": { "short": "+", "category": "Numpad" }, - "88": { - "short": "Ent", - "med": "KP Ent", - "long": "KP Enter", - "category": "Numpad" - }, - "89": { "short": "1 En", "med": "1 End", "category": "Numpad" }, - "90": { "short": "2 ↓", "category": "Numpad" }, - "91": { "short": "3 PD", "med": "3 PgDn", "category": "Numpad" }, - "92": { "short": "4 ←", "category": "Numpad" }, - "93": { "short": "5", "category": "Numpad" }, - "94": { "short": "6 →", "category": "Numpad" }, - "95": { "short": "7 Hm", "med": "7 Home", "category": "Numpad" }, - "96": { "short": "8 ↑", "category": "Numpad" }, - "97": { "short": "9 PU", "med": "9 PgUp", "category": "Numpad" }, - "98": { - "short": "0 In", - "med": "0 Ins", - "long": "0 Insert", - "category": "Numpad" - }, - "99": { - "short": ". Dl", - "med": ". Del", - "long": ". Delete", - "category": "Numpad" - }, - "101": { - "short": "Menu", - "med": "Menu", - "long": "Applicat'n (Menu)", - "category": "Function + Navigation" - }, - "102": { - "short": "Power", - "med": "Power", - "category": "Apps/Media/Special" - }, - "100": { "short": "NUBS", "category": "International" }, - "103": { "short": "=", "category": "Numpad" }, - "104": { "category": "Apps/Media/Special" }, - "105": { "category": "Apps/Media/Special" }, - "106": { "category": "Apps/Media/Special" }, - "107": { "category": "Apps/Media/Special" }, - "108": { "category": "Apps/Media/Special" }, - "109": { "category": "Apps/Media/Special" }, - "110": { "category": "Apps/Media/Special" }, - "111": { "category": "Apps/Media/Special" }, - "112": { "category": "Apps/Media/Special" }, - "113": { "category": "Apps/Media/Special" }, - "114": { "category": "Apps/Media/Special" }, - "115": { "category": "Apps/Media/Special" }, - "118": { "category": "Apps/Media/Special" }, - "133": { "short": ",", "category": "Numpad" }, - "135": { "short": "Intl1", "category": "International" }, - "136": { "short": "Intl2", "category": "International" }, - "137": { "short": "Intl3", "category": "International" }, - "138": { "short": "Intl4", "category": "International" }, - "139": { "short": "Intl5", "category": "International" }, - "140": { "short": "Intl6", "category": "International" }, - "141": { "short": "Intl7", "category": "International" }, - "142": { "short": "Intl8", "category": "International" }, - "143": { "short": "Intl9", "category": "International" }, - "144": { "short": "Lang1", "category": "International" }, - "145": { "short": "Lang2", "category": "International" }, - "146": { "short": "Lang3", "category": "International" }, - "147": { "short": "Lang4", "category": "International" }, - "148": { "short": "Lang5", "category": "International" }, - "149": { "short": "Lang6", "category": "International" }, - "150": { "short": "Lang7", "category": "International" }, - "151": { "short": "Lang8", "category": "International" }, - "152": { "short": "Lang9", "category": "International" }, - "176": { "short": "00", "category": "Numpad" }, - "177": { "short": "000" }, - "224": { - "short": "Ctrl", - "med": "L Ctrl", - "category": "Function + Navigation" - }, - "225": { - "short": "Shft", - "med": "L Shft", - "long": "L Shift", - "category": "Function + Navigation" - }, - "226": { - "short": "Alt", - "med": "L Alt", - "long": "Left Alt", - "category": "Function + Navigation" - }, - "227": { - "short": "GUI", - "med": "L GUI", - "long": "Left GUI", - "category": "Function + Navigation" - }, - "228": { - "short": "Ctrl", - "med": "R Ctrl", - "category": "Function + Navigation" - }, - "229": { - "short": "Shft", - "med": "R Shft", - "long": "R Shift", - "category": "Function + Navigation" - }, - "230": { - "short": "AltG", - "med": "AltGr", - "category": "Function + Navigation" - }, - "231": { - "short": "GUI", - "med": "R GUI", - "long": "Right GUI", - "category": "Function + Navigation" - } - }, - "12": { - "111": { "short": "🔆", "category": "Apps/Media/Special" }, - "112": { "short": "🔅", "category": "Apps/Media/Special" }, - "181": { "short": "⇥", "category": "Apps/Media/Special" }, - "182": { "short": "⇤", "category": "Apps/Media/Special" }, - "205": { "short": "⏯️", "category": "Apps/Media/Special" }, - "226": { "short": "🔇", "category": "Apps/Media/Special" }, - "233": { "short": "🔊", "category": "Apps/Media/Special" }, - "234": { "short": "🔉", "category": "Apps/Media/Special" } - } -} diff --git a/src/hid-usages.test.ts b/src/hid-usages.test.ts index 48584be1..d30d792f 100644 --- a/src/hid-usages.test.ts +++ b/src/hid-usages.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from "vitest"; import { UsagePages } from "./keyboard-and-consumer-usage-tables.json"; -import HidOverrides from "./hid-usage-metadata.json"; +import { KEYCODES } from "./keycodes"; import { hid_usage_get_label, hid_usage_get_metadata, @@ -9,8 +9,8 @@ import { } from "./hid-usages"; // Enumerate every (page, usage) pair that *could* surface a label in the UI: -// every entry in the HID spec table for pages we use, plus every entry that -// has a hand-curated override. Sorted so the snapshot diff is stable. +// every entry in the HID spec table for pages we use, plus every entry in +// the curated keycode table. Sorted so the snapshot diff is stable. const allPairs = (() => { const seen = new Set(); const out: Array<{ page: number; usage: number }> = []; @@ -23,15 +23,11 @@ const allPairs = (() => { } } } - for (const [pageStr, idMap] of Object.entries( - HidOverrides as Record> - )) { - for (const idStr of Object.keys(idMap)) { - const k = `${pageStr}:${idStr}`; - if (!seen.has(k)) { - seen.add(k); - out.push({ page: Number(pageStr), usage: Number(idStr) }); - } + for (const k of KEYCODES) { + const key = `${k.page}:${k.usage}`; + if (!seen.has(key)) { + seen.add(key); + out.push({ page: k.page, usage: k.usage }); } } out.sort((a, b) => a.page - b.page || a.usage - b.usage); diff --git a/src/hid-usages.ts b/src/hid-usages.ts index d99ceefc..805f98f9 100644 --- a/src/hid-usages.ts +++ b/src/hid-usages.ts @@ -1,16 +1,7 @@ // import { UsagePages } from "./HidUsageTables-1.5.json"; // Filtered with `cat src/HidUsageTables-1.5.json | jq '{ UsagePages: [.UsagePages[] | select([.Id] |inside([7, 12]))] }' > src/keyboard-and-consumer-usage-tables.json` import { UsagePages } from "./keyboard-and-consumer-usage-tables.json"; -import HidSupplementaryMetadata from "./hid-usage-metadata.json"; - -interface HidMetadata { - short?: string; - med?: string; - long?: string; - category?: string; -} - -const overrides: Record> = HidSupplementaryMetadata; +import { KEYCODE_BY_HID } from "./keycodes"; export interface UsageId { Id: number; @@ -37,7 +28,7 @@ export const hid_usage_get_label = ( usage_page: number, usage_id: number ): string | undefined => - overrides[usage_page.toString()]?.[usage_id.toString()]?.short || + KEYCODE_BY_HID.get((usage_page << 16) | usage_id)?.short || UsagePages.find((p) => p.Id === usage_page)?.UsageIds?.find( (u) => u.Id === usage_id )?.Name; @@ -45,18 +36,32 @@ export const hid_usage_get_label = ( export const hid_usage_get_metadata = ( usage_page: number, usage_id: number -): { short?: string; med?: string; long?: string, category?: string } => { - if(overrides[usage_page.toString()]?.[usage_id.toString()]?.short) { - return overrides[usage_page.toString()]?.[usage_id.toString()]; - } else { - const fullName = UsagePages.find((p) => p.Id === usage_page)?.UsageIds?.find( - (u) => u.Id === usage_id - )?.Name - return { - short: fullName?.replace(/^Keyboard /, ""), - med: fullName?.replace(/^Keyboard /, ""), - long: fullName, - category: overrides[usage_page.toString()]?.[usage_id.toString()]?.category || "Other" - } +): { short?: string; med?: string; long?: string; category?: string } => { + // Single source of truth for editorial labels: src/keycodes.ts. When the + // entry provides a `short` we hand back the curated triplet as-is (note + // that `med` / `long` may legitimately be undefined — the picker + // gracefully falls back). When it doesn't (no curated label, or no + // entry at all), derive the labels from the HID spec table just like + // upstream PR #159 did. + const entry = KEYCODE_BY_HID.get((usage_page << 16) | usage_id); + if (entry?.short) { + // Spread skips undefined-valued keys, so callers see the same + // "sparse" shape the JSON-driven implementation used to return. + const out: { short?: string; med?: string; long?: string; category?: string } = { + short: entry.short, + }; + if (entry.med !== undefined) out.med = entry.med; + if (entry.long !== undefined) out.long = entry.long; + if (entry.category !== undefined) out.category = entry.category; + return out; } -} + const fullName = UsagePages.find((p) => p.Id === usage_page)?.UsageIds?.find( + (u) => u.Id === usage_id + )?.Name; + return { + short: fullName?.replace(/^Keyboard /, ""), + med: fullName?.replace(/^Keyboard /, ""), + long: fullName, + category: entry?.category || "Other", + }; +}; diff --git a/src/keycodes.ts b/src/keycodes.ts new file mode 100644 index 00000000..6cd106f9 --- /dev/null +++ b/src/keycodes.ts @@ -0,0 +1,270 @@ +// ============================================================================= +// Keycode source of truth +// ============================================================================= +// Single canonical table of every HID usage we care about editorially: +// +// - ZMK keymap text name (consumed by keymap-parser for import / export) +// - picker UI labels (short / med / long, consumed by hid-usages.ts) +// - picker category (Basic / Function + Nav / Numpad / ...) +// +// Background: these used to live in three independent places (the HID spec +// JSON, an inline `ZMK_KEYCODES` table in keymap-parser.ts, and +// hid-usage-metadata.json from upstream PR #159). They could drift apart — +// the picker would label HID 7:230 "AltGr" while the exporter wrote "&kp +// RALT" for the same code. See issue #2 for the full backstory. +// +// Rules: +// - `name` is the canonical ZMK text name. Omit on label-only rows +// (Lang1, International1, raw consumer brightness, ...) where ZMK has +// no idiomatic short name today. +// - The first row for a given (page, usage) wins on reverse lookups; +// subsequent rows with the same code can register parse-only aliases +// by adding entries via `PARSE_ONLY_ALIASES` below. +// - Picker fallback: when `short` is absent the picker derives it from +// the HID spec table (`keyboard-and-consumer-usage-tables.json`). This +// keeps the editorial surface small for the long tail of usages. +// ============================================================================= + +export interface Keycode { + /** HID usage page (0x07 = keyboard/keypad, 0x0c = consumer). */ + page: number; + /** HID usage ID within the page. */ + usage: number; + /** + * ZMK keymap text name (e.g. "RALT"). When defined, this is the name + * the keymap exporter emits and the importer accepts as canonical. + * Omit for picker-label-only rows. + */ + name?: string; + /** Compact picker label (≤ ~5 chars). */ + short?: string; + /** Medium picker label. */ + med?: string; + /** Spelled-out picker label. */ + long?: string; + /** Picker tab grouping. */ + category?: string; +} + +const KBD = 0x07; +const CONSUMER = 0x0c; + +const CAT_LETTERS = "Letters"; +const CAT_NUMPUNC = "Numbers + Punctuation"; +const CAT_FN_NAV = "Function + Navigation"; +const CAT_NUMPAD = "Numpad"; +const CAT_INTL = "International"; +const CAT_MEDIA = "Apps/Media/Special"; + +const LETTERS: Keycode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + .split("") + .map((l, i) => ({ name: l, page: KBD, usage: 4 + i, category: CAT_LETTERS })); + +const NUMBER_ROW: Keycode[] = [ + { name: "N1", page: KBD, usage: 30, short: "1 !", category: CAT_NUMPUNC }, + { name: "N2", page: KBD, usage: 31, short: "2 @", category: CAT_NUMPUNC }, + { name: "N3", page: KBD, usage: 32, short: "3 #", category: CAT_NUMPUNC }, + { name: "N4", page: KBD, usage: 33, short: "4 $", category: CAT_NUMPUNC }, + { name: "N5", page: KBD, usage: 34, short: "5 %", category: CAT_NUMPUNC }, + { name: "N6", page: KBD, usage: 35, short: "6 ^", category: CAT_NUMPUNC }, + { name: "N7", page: KBD, usage: 36, short: "7 &", category: CAT_NUMPUNC }, + { name: "N8", page: KBD, usage: 37, short: "8 *", category: CAT_NUMPUNC }, + { name: "N9", page: KBD, usage: 38, short: "9 (", category: CAT_NUMPUNC }, + { name: "N0", page: KBD, usage: 39, short: "0 )", category: CAT_NUMPUNC }, +]; + +const WHITESPACE_AND_CONTROL: Keycode[] = [ + { name: "RET", page: KBD, usage: 40, short: "Ret", med: "Return", category: CAT_FN_NAV }, + { name: "ESC", page: KBD, usage: 41, short: "Esc", long: "Escape", category: CAT_FN_NAV }, + { name: "BSPC", page: KBD, usage: 42, short: "BkSp", med: "BkSpc", long: "Backspace", category: CAT_FN_NAV }, + { name: "TAB", page: KBD, usage: 43, category: CAT_FN_NAV }, + { name: "SPACE", page: KBD, usage: 44, short: "␣", med: "Space", category: CAT_FN_NAV }, +]; + +const PUNCTUATION: Keycode[] = [ + { name: "MINUS", page: KBD, usage: 45, short: "- _", med: "Dash", category: CAT_NUMPUNC }, + { name: "EQUAL", page: KBD, usage: 46, short: "= +", med: "Equals", category: CAT_NUMPUNC }, + { name: "LBKT", page: KBD, usage: 47, short: "[ {", category: CAT_NUMPUNC }, + { name: "RBKT", page: KBD, usage: 48, short: "] }", category: CAT_NUMPUNC }, + { name: "BSLH", page: KBD, usage: 49, short: "\\ |", category: CAT_NUMPUNC }, + { name: "NUHS", page: KBD, usage: 50, short: "NUHS", long: "NonUS Hash", category: CAT_INTL }, + { name: "SEMI", page: KBD, usage: 51, short: "; :", category: CAT_NUMPUNC }, + { name: "SQT", page: KBD, usage: 52, short: "' \"", category: CAT_NUMPUNC }, + { name: "GRAVE", page: KBD, usage: 53, short: "` ~", category: CAT_NUMPUNC }, + { name: "COMMA", page: KBD, usage: 54, short: ", <", category: CAT_NUMPUNC }, + { name: "DOT", page: KBD, usage: 55, short: ". >", category: CAT_NUMPUNC }, + { name: "FSLH", page: KBD, usage: 56, short: "/ ?", category: CAT_NUMPUNC }, + { name: "CAPS", page: KBD, usage: 57, short: "Cap", med: "CapsLk", long: "Caps Lock", category: CAT_FN_NAV }, +]; + +const FUNCTION_ROW: Keycode[] = [ + { name: "F1", page: KBD, usage: 58, category: CAT_FN_NAV }, + { name: "F2", page: KBD, usage: 59, category: CAT_FN_NAV }, + { name: "F3", page: KBD, usage: 60, category: CAT_FN_NAV }, + { name: "F4", page: KBD, usage: 61, category: CAT_FN_NAV }, + { name: "F5", page: KBD, usage: 62, category: CAT_FN_NAV }, + { name: "F6", page: KBD, usage: 63, category: CAT_FN_NAV }, + { name: "F7", page: KBD, usage: 64, category: CAT_FN_NAV }, + { name: "F8", page: KBD, usage: 65, category: CAT_FN_NAV }, + { name: "F9", page: KBD, usage: 66, category: CAT_FN_NAV }, + { name: "F10", page: KBD, usage: 67, category: CAT_FN_NAV }, + { name: "F11", page: KBD, usage: 68, category: CAT_FN_NAV }, + { name: "F12", page: KBD, usage: 69, category: CAT_FN_NAV }, +]; + +const SYSTEM_AND_NAV: Keycode[] = [ + { name: "PRSC", page: KBD, usage: 70, short: "PrSc", long: "Print Scr", category: CAT_FN_NAV }, + { name: "SLCK", page: KBD, usage: 71, short: "ScLk", long: "ScrollLock", category: CAT_FN_NAV }, + { name: "PAUSE", page: KBD, usage: 72, short: "Paus", med: "Pause", category: CAT_FN_NAV }, + { name: "INS", page: KBD, usage: 73, short: "Ins", med: "Insert", category: CAT_FN_NAV }, + { name: "HOME", page: KBD, usage: 74, category: CAT_FN_NAV }, + { name: "PGUP", page: KBD, usage: 75, short: "PgUp", med: "PageUp", long: "Page Up", category: CAT_FN_NAV }, + { name: "DEL", page: KBD, usage: 76, short: "Del", med: "Delete", category: CAT_FN_NAV }, + { name: "END", page: KBD, usage: 77, category: CAT_FN_NAV }, + { name: "PGDN", page: KBD, usage: 78, short: "PgDn", med: "PageDn", long: "Page Down", category: CAT_FN_NAV }, + { name: "RIGHT", page: KBD, usage: 79, short: "→", category: CAT_FN_NAV }, + { name: "LEFT", page: KBD, usage: 80, short: "←", category: CAT_FN_NAV }, + { name: "DOWN", page: KBD, usage: 81, short: "↓", category: CAT_FN_NAV }, + { name: "UP", page: KBD, usage: 82, short: "↑", category: CAT_FN_NAV }, +]; + +const KEYPAD: Keycode[] = [ + { name: "KP_NUM", page: KBD, usage: 83, short: "Num", med: "NumLck", long: "Num Lock", category: CAT_NUMPAD }, + { name: "KP_SLASH", page: KBD, usage: 84, short: "/", category: CAT_NUMPAD }, + { name: "KP_ASTERISK", page: KBD, usage: 85, short: "*", category: CAT_NUMPAD }, + { name: "KP_MINUS", page: KBD, usage: 86, short: "-", category: CAT_NUMPAD }, + { name: "KP_PLUS", page: KBD, usage: 87, short: "+", category: CAT_NUMPAD }, + { name: "KP_ENTER", page: KBD, usage: 88, short: "Ent", med: "KP Ent", long: "KP Enter", category: CAT_NUMPAD }, + { name: "KP_N1", page: KBD, usage: 89, short: "1 En", med: "1 End", category: CAT_NUMPAD }, + { name: "KP_N2", page: KBD, usage: 90, short: "2 ↓", category: CAT_NUMPAD }, + { name: "KP_N3", page: KBD, usage: 91, short: "3 PD", med: "3 PgDn", category: CAT_NUMPAD }, + { name: "KP_N4", page: KBD, usage: 92, short: "4 ←", category: CAT_NUMPAD }, + { name: "KP_N5", page: KBD, usage: 93, short: "5", category: CAT_NUMPAD }, + { name: "KP_N6", page: KBD, usage: 94, short: "6 →", category: CAT_NUMPAD }, + { name: "KP_N7", page: KBD, usage: 95, short: "7 Hm", med: "7 Home", category: CAT_NUMPAD }, + { name: "KP_N8", page: KBD, usage: 96, short: "8 ↑", category: CAT_NUMPAD }, + { name: "KP_N9", page: KBD, usage: 97, short: "9 PU", med: "9 PgUp", category: CAT_NUMPAD }, + { name: "KP_N0", page: KBD, usage: 98, short: "0 In", med: "0 Ins", long: "0 Insert", category: CAT_NUMPAD }, + { name: "KP_DOT", page: KBD, usage: 99, short: ". Dl", med: ". Del", long: ". Delete", category: CAT_NUMPAD }, +]; + +const MISC: Keycode[] = [ + { name: "NUBS", page: KBD, usage: 100, short: "NUBS", category: CAT_INTL }, + { name: "K_APP", page: KBD, usage: 101, short: "Menu", med: "Menu", long: "Applicat'n (Menu)", category: CAT_FN_NAV }, + // Power is a keyboard-page usage (HID 7:102) in addition to the consumer-page + // C_PWR (HID 12:0x30). Label-only here; ZMK doesn't have a stock name for + // the kbd-page version, so no `name`. + { page: KBD, usage: 102, short: "Power", med: "Power", category: CAT_MEDIA }, + { name: "KP_EQUAL", page: KBD, usage: 103, short: "=", category: CAT_NUMPAD }, +]; + +const FUNCTION_ROW_EXTENDED: Keycode[] = Array.from({ length: 12 }, (_, i) => ({ + name: `F${13 + i}`, + page: KBD, + usage: 104 + i, + category: CAT_MEDIA, +})); + +const INTERNATIONAL_AND_LANG: Keycode[] = [ + // International / Lang have no canonical ZMK short names today — leave + // `name` unset so the exporter doesn't accidentally claim them. + { page: KBD, usage: 118, category: CAT_MEDIA }, + { page: KBD, usage: 133, short: ",", category: CAT_NUMPAD }, + { page: KBD, usage: 135, short: "Intl1", category: CAT_INTL }, + { page: KBD, usage: 136, short: "Intl2", category: CAT_INTL }, + { page: KBD, usage: 137, short: "Intl3", category: CAT_INTL }, + { page: KBD, usage: 138, short: "Intl4", category: CAT_INTL }, + { page: KBD, usage: 139, short: "Intl5", category: CAT_INTL }, + { page: KBD, usage: 140, short: "Intl6", category: CAT_INTL }, + { page: KBD, usage: 141, short: "Intl7", category: CAT_INTL }, + { page: KBD, usage: 142, short: "Intl8", category: CAT_INTL }, + { page: KBD, usage: 143, short: "Intl9", category: CAT_INTL }, + { page: KBD, usage: 144, short: "Lang1", category: CAT_INTL }, + { page: KBD, usage: 145, short: "Lang2", category: CAT_INTL }, + { page: KBD, usage: 146, short: "Lang3", category: CAT_INTL }, + { page: KBD, usage: 147, short: "Lang4", category: CAT_INTL }, + { page: KBD, usage: 148, short: "Lang5", category: CAT_INTL }, + { page: KBD, usage: 149, short: "Lang6", category: CAT_INTL }, + { page: KBD, usage: 150, short: "Lang7", category: CAT_INTL }, + { page: KBD, usage: 151, short: "Lang8", category: CAT_INTL }, + { page: KBD, usage: 152, short: "Lang9", category: CAT_INTL }, + { page: KBD, usage: 176, short: "00", category: CAT_NUMPAD }, + { page: KBD, usage: 177, short: "000" }, +]; + +const MODIFIERS: Keycode[] = [ + { name: "LCTL", page: KBD, usage: 224, short: "Ctrl", med: "L Ctrl", category: CAT_FN_NAV }, + { name: "LSHFT", page: KBD, usage: 225, short: "Shft", med: "L Shft", long: "L Shift", category: CAT_FN_NAV }, + { name: "LALT", page: KBD, usage: 226, short: "Alt", med: "L Alt", long: "Left Alt", category: CAT_FN_NAV }, + { name: "LGUI", page: KBD, usage: 227, short: "GUI", med: "L GUI", long: "Left GUI", category: CAT_FN_NAV }, + { name: "RCTL", page: KBD, usage: 228, short: "Ctrl", med: "R Ctrl", category: CAT_FN_NAV }, + { name: "RSHFT", page: KBD, usage: 229, short: "Shft", med: "R Shft", long: "R Shift", category: CAT_FN_NAV }, + { name: "RALT", page: KBD, usage: 230, short: "AltG", med: "AltGr", category: CAT_FN_NAV }, + { name: "RGUI", page: KBD, usage: 231, short: "GUI", med: "R GUI", long: "Right GUI", category: CAT_FN_NAV }, +]; + +const CONSUMER_KEYCODES: Keycode[] = [ + { name: "C_PWR", page: CONSUMER, usage: 0x30 }, + { name: "C_SLEEP", page: CONSUMER, usage: 0x32 }, + { name: "C_BRI_UP", page: CONSUMER, usage: 0x6f, short: "🔆", category: CAT_MEDIA }, + { name: "C_BRI_DN", page: CONSUMER, usage: 0x70, short: "🔅", category: CAT_MEDIA }, + { name: "C_NEXT", page: CONSUMER, usage: 0xb5, short: "⇥", category: CAT_MEDIA }, + { name: "C_PREV", page: CONSUMER, usage: 0xb6, short: "⇤", category: CAT_MEDIA }, + { name: "C_STOP", page: CONSUMER, usage: 0xb7 }, + { name: "C_EJECT", page: CONSUMER, usage: 0xb8 }, + { name: "C_PP", page: CONSUMER, usage: 0xcd, short: "⏯️", category: CAT_MEDIA }, + { name: "C_MUTE", page: CONSUMER, usage: 0xe2, short: "🔇", category: CAT_MEDIA }, + { name: "C_VOL_UP", page: CONSUMER, usage: 0xe9, short: "🔊", category: CAT_MEDIA }, + { name: "C_VOL_DN", page: CONSUMER, usage: 0xea, short: "🔉", category: CAT_MEDIA }, +]; + +export const KEYCODES: Keycode[] = [ + ...LETTERS, + ...NUMBER_ROW, + ...WHITESPACE_AND_CONTROL, + ...PUNCTUATION, + ...FUNCTION_ROW, + ...SYSTEM_AND_NAV, + ...KEYPAD, + ...MISC, + ...FUNCTION_ROW_EXTENDED, + ...INTERNATIONAL_AND_LANG, + ...MODIFIERS, + ...CONSUMER_KEYCODES, +]; + +// ============================================================================= +// Lookups +// ============================================================================= + +export function hidCodeOf(k: Pick): number { + return (k.page << 16) | k.usage; +} + +/** + * Reverse lookup: HID code -> the first matching keycode entry. Used by + * both the picker (for labels) and the exporter (for the ZMK text name). + * "First wins" so put the canonical row before any alias rows for the + * same code. + */ +export const KEYCODE_BY_HID: ReadonlyMap = (() => { + const m = new Map(); + for (const k of KEYCODES) { + const code = hidCodeOf(k); + if (!m.has(code)) m.set(code, k); + } + return m; +})(); + +/** + * Forward lookup: uppercase ZMK name -> HID code. Includes every row + * that has a `name`; first row wins on collision. + */ +export const HID_BY_ZMK_NAME: ReadonlyMap = (() => { + const m = new Map(); + for (const k of KEYCODES) { + if (!k.name) continue; + if (!m.has(k.name)) m.set(k.name, hidCodeOf(k)); + } + return m; +})(); diff --git a/src/keymap-parser.ts b/src/keymap-parser.ts index 2cba6e2a..755e70d2 100644 --- a/src/keymap-parser.ts +++ b/src/keymap-parser.ts @@ -1,14 +1,5 @@ import { UsagePages } from "./keyboard-and-consumer-usage-tables.json"; -import HidOverrides from "./hid-usage-metadata.json"; - -interface HidLabels { - short?: string; - med?: string; - long?: string; - category?: string; -} - -const overrides: Record> = HidOverrides; +import { KEYCODES, hidCodeOf } from "./keycodes"; export interface ParsedBinding { behavior: string; @@ -20,73 +11,6 @@ export interface ParsedLayer { bindings: ParsedBinding[]; } -// ============================================================================= -// Canonical ZMK keycode table -// ============================================================================= -// `[zmkName, hidPage, hidUsageId]`. Single source of truth used to build both -// the forward (name -> code) and reverse (code -> name) lookups, so we never -// give a code two different canonical names. Order matters only inside groups -// of synonyms; the first entry for a given code wins on the reverse side. -// ============================================================================= - -type Keycode = readonly [name: string, page: number, usage: number]; - -const LETTERS: Keycode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - .split("") - .map((l, i) => [l, 0x07, 4 + i] as const); - -const KEYBOARD_KEYCODES: Keycode[] = [ - // Number row - ["N1", 0x07, 30], ["N2", 0x07, 31], ["N3", 0x07, 32], ["N4", 0x07, 33], - ["N5", 0x07, 34], ["N6", 0x07, 35], ["N7", 0x07, 36], ["N8", 0x07, 37], - ["N9", 0x07, 38], ["N0", 0x07, 39], - // Control / whitespace - ["RET", 0x07, 40], ["ESC", 0x07, 41], ["BSPC", 0x07, 42], - ["TAB", 0x07, 43], ["SPACE", 0x07, 44], - // Punctuation - ["MINUS", 0x07, 45], ["EQUAL", 0x07, 46], ["LBKT", 0x07, 47], - ["RBKT", 0x07, 48], ["BSLH", 0x07, 49], ["NUHS", 0x07, 50], - ["SEMI", 0x07, 51], ["SQT", 0x07, 52], ["GRAVE", 0x07, 53], - ["COMMA", 0x07, 54], ["DOT", 0x07, 55], ["FSLH", 0x07, 56], - ["CAPS", 0x07, 57], - // F-row - ["F1", 0x07, 58], ["F2", 0x07, 59], ["F3", 0x07, 60], ["F4", 0x07, 61], - ["F5", 0x07, 62], ["F6", 0x07, 63], ["F7", 0x07, 64], ["F8", 0x07, 65], - ["F9", 0x07, 66], ["F10", 0x07, 67], ["F11", 0x07, 68], ["F12", 0x07, 69], - // System - ["PRSC", 0x07, 70], ["SLCK", 0x07, 71], ["PAUSE", 0x07, 72], - ["INS", 0x07, 73], ["HOME", 0x07, 74], ["PGUP", 0x07, 75], - ["DEL", 0x07, 76], ["END", 0x07, 77], ["PGDN", 0x07, 78], - // Arrows - ["RIGHT", 0x07, 79], ["LEFT", 0x07, 80], ["DOWN", 0x07, 81], ["UP", 0x07, 82], - // Keypad - ["KP_NUM", 0x07, 83], ["KP_SLASH", 0x07, 84], ["KP_ASTERISK", 0x07, 85], - ["KP_MINUS", 0x07, 86], ["KP_PLUS", 0x07, 87], ["KP_ENTER", 0x07, 88], - ["KP_N1", 0x07, 89], ["KP_N2", 0x07, 90], ["KP_N3", 0x07, 91], - ["KP_N4", 0x07, 92], ["KP_N5", 0x07, 93], ["KP_N6", 0x07, 94], - ["KP_N7", 0x07, 95], ["KP_N8", 0x07, 96], ["KP_N9", 0x07, 97], - ["KP_N0", 0x07, 98], ["KP_DOT", 0x07, 99], - // Misc - ["NUBS", 0x07, 100], ["K_APP", 0x07, 101], ["KP_EQUAL", 0x07, 103], - ["F13", 0x07, 104], ["F14", 0x07, 105], ["F15", 0x07, 106], - ["F16", 0x07, 107], ["F17", 0x07, 108], ["F18", 0x07, 109], - ["F19", 0x07, 110], ["F20", 0x07, 111], ["F21", 0x07, 112], - ["F22", 0x07, 113], ["F23", 0x07, 114], ["F24", 0x07, 115], - // Modifiers - ["LCTL", 0x07, 224], ["LSHFT", 0x07, 225], ["LALT", 0x07, 226], ["LGUI", 0x07, 227], - ["RCTL", 0x07, 228], ["RSHFT", 0x07, 229], ["RALT", 0x07, 230], ["RGUI", 0x07, 231], -]; - -const CONSUMER_KEYCODES: Keycode[] = [ - ["C_PWR", 0x0c, 0x30], ["C_SLEEP", 0x0c, 0x32], - ["C_BRI_UP", 0x0c, 0x6f], ["C_BRI_DN", 0x0c, 0x70], - ["C_NEXT", 0x0c, 0xb5], ["C_PREV", 0x0c, 0xb6], ["C_STOP", 0x0c, 0xb7], - ["C_EJECT", 0x0c, 0xb8], ["C_PP", 0x0c, 0xcd], - ["C_MUTE", 0x0c, 0xe2], ["C_VOL_UP", 0x0c, 0xe9], ["C_VOL_DN", 0x0c, 0xea], -]; - -const ZMK_KEYCODES: Keycode[] = [...LETTERS, ...KEYBOARD_KEYCODES, ...CONSUMER_KEYCODES]; - // ============================================================================= // ZMK implicit-modifier flags // ============================================================================= @@ -111,21 +35,17 @@ const MOD_NAME_TO_BIT: Map = new Map( ); // ============================================================================= -// Lookups built from the canonical table +// Lookups built from the canonical table (src/keycodes.ts) // ============================================================================= -function keycodeFromTuple(t: Keycode): number { - return (t[1] << 16) + t[2]; -} - const keycodeLookup: Map = new Map(); const codeToZmkName: Map = new Map(); -for (const t of ZMK_KEYCODES) { - const code = keycodeFromTuple(t); - const name = t[0]; - if (!keycodeLookup.has(name)) keycodeLookup.set(name, code); - if (!codeToZmkName.has(code)) codeToZmkName.set(code, name); +for (const k of KEYCODES) { + if (!k.name) continue; + const code = hidCodeOf(k); + if (!keycodeLookup.has(k.name)) keycodeLookup.set(k.name, code); + if (!codeToZmkName.has(code)) codeToZmkName.set(code, k.name); } // Parse-only HID-name fallback. The canonical table is authoritative; these @@ -138,12 +58,14 @@ for (const t of ZMK_KEYCODES) { for (const usage of page.UsageIds) { const code = (page.Id << 16) + usage.Id; hidNameToCode.set(usage.Name.toLowerCase(), code); - const pageOverrides = overrides[page.Id.toString()]?.[usage.Id.toString()]; - if (pageOverrides) { - if (pageOverrides.short) hidNameToCode.set(pageOverrides.short.toLowerCase(), code); - if (pageOverrides.med) hidNameToCode.set(pageOverrides.med.toLowerCase(), code); - if (pageOverrides.long) hidNameToCode.set(pageOverrides.long.toLowerCase(), code); - } + } + } + // Picker-label aliases: anything we surface to the user as a label is also + // accepted as a parser alias, so "Volume Up" or "AltGr" round-trips. + for (const k of KEYCODES) { + const code = hidCodeOf(k); + for (const label of [k.short, k.med, k.long]) { + if (label) hidNameToCode.set(label.toLowerCase(), code); } }