Compare commits

..

1 commit

Author SHA1 Message Date
Pete Johanson
c773f2d87d chore(main): release 0.4.0 2026-06-19 22:26:02 -06:00
30 changed files with 235 additions and 68 deletions

View file

@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@v6
- name: Find test directories
id: test-dirs
run: |
@ -38,7 +38,7 @@ jobs:
image: docker.io/zmkfirmware/zmk-build-arm:4.1
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@v6
- name: Cache west modules
uses: actions/cache@v5
env:

View file

@ -33,7 +33,7 @@ jobs:
has_valid_build_matrix: ${{ steps.fetch.outputs.has_valid_build_matrix }}
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@v6
- name: Fetch Build Matrix
id: fetch
@ -67,7 +67,7 @@ jobs:
curl -fsSL https://deb.nodesource.com/setup_22.x | bash && apt install -y nodejs
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@v6
- name: Create build directory
run: |

View file

@ -30,7 +30,7 @@ jobs:
include: ${{ fromJSON(needs.compile-matrix.outputs.include-list) }}
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@v6
with:
persist-credentials: false
- name: Cache west modules
@ -63,7 +63,7 @@ jobs:
- name: Install @actions/artifact
run: npm install @actions/artifact@5.0.3
- name: Build
uses: actions/github-script@v9
uses: actions/github-script@v7
id: boards-list
with:
script: |
@ -95,7 +95,7 @@ jobs:
throw new Error('Failed to build one or more configurations');
}
- name: Upload artifacts
uses: actions/github-script@v9
uses: actions/github-script@v7
continue-on-error: ${{ github.event_name == 'pull_request' }}
id: boards-upload
with:
@ -146,7 +146,7 @@ jobs:
include-list: ${{ steps.compile-list.outputs.result }}
steps:
- name: Join build lists
uses: actions/github-script@v9
uses: actions/github-script@v7
id: compile-list
with:
script: |
@ -187,7 +187,7 @@ jobs:
core-include: ${{ steps.core-list.outputs.result }}
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@v6
with:
persist-credentials: false
- name: Use Node.js
@ -196,7 +196,7 @@ jobs:
node-version: "14.x"
- name: Install js-yaml
run: npm install js-yaml
- uses: actions/github-script@v9
- uses: actions/github-script@v7
id: core-list
with:
script: |
@ -218,14 +218,14 @@ jobs:
boards-include: ${{ steps.boards-list.outputs.result }}
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@v6
- name: Use Node.js
uses: actions/setup-node@v6
with:
node-version: "14.x"
- name: Install js-yaml
run: npm install js-yaml
- uses: actions/github-script@v9
- uses: actions/github-script@v7
id: boards-list
with:
script: |
@ -303,7 +303,7 @@ jobs:
nightly-include: ${{ steps.nightly-list.outputs.result }}
steps:
- name: Create nightly list
uses: actions/github-script@v9
uses: actions/github-script@v7
id: nightly-list
with:
script: |
@ -346,7 +346,7 @@ jobs:
organized-metadata: ${{ steps.organize-metadata.outputs.result }}
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@v6
with:
persist-credentials: false
- name: Use Node.js
@ -356,7 +356,7 @@ jobs:
- name: Install js-yaml
run: npm install js-yaml
- name: Aggregate Metadata
uses: actions/github-script@v9
uses: actions/github-script@v7
id: aggregate-metadata
with:
script: |
@ -374,7 +374,7 @@ jobs:
result-encoding: string
- name: Organize Metadata
uses: actions/github-script@v9
uses: actions/github-script@v7
id: organize-metadata
with:
script: |
@ -428,7 +428,7 @@ jobs:
core-changes: ${{ steps.core-changes.outputs.result }}
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@v6
with:
persist-credentials: false
- uses: tj-actions/changed-files@9200e69727eb73eb060652b19946b8a2fdfb654b # pin to v45.0.8 due to https://github.com/tj-actions/changed-files/issues/2463 https://www.stepsecurity.io/blog/harden-runner-detection-tj-actions-changed-files-action-is-compromised
@ -436,7 +436,7 @@ jobs:
with:
json: true
escape_json: false
- uses: actions/github-script@v9
- uses: actions/github-script@v7
id: board-changes
with:
script: |
@ -444,7 +444,7 @@ jobs:
const boardChanges = changedFiles.filter(f => f.startsWith('app/boards'));
return boardChanges.length ? 'true' : 'false';
result-encoding: string
- uses: actions/github-script@v9
- uses: actions/github-script@v7
id: core-changes
with:
script: |

View file

@ -14,7 +14,7 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v6
- uses: bahmutov/npm-install@v1
with:
working-directory: docs
@ -24,7 +24,7 @@ jobs:
typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v6
- uses: bahmutov/npm-install@v1
with:
working-directory: docs

View file

@ -20,7 +20,7 @@ jobs:
container:
image: docker.io/zmkfirmware/zmk-dev-arm:4.1
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v6
- name: Install dependencies
run: pip install --break-system-packages -r app/scripts/requirements.txt
- name: West init

View file

@ -8,7 +8,7 @@ jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: 3.x

View file

@ -20,7 +20,7 @@ jobs:
minor: ${{ steps.release.outputs.minor }}
patch: ${{ steps.release.outputs.patch }}
steps:
- uses: googleapis/release-please-action@v5
- uses: googleapis/release-please-action@v4
id: release
with:
token: ${{ secrets.ZMK_RELEASE_PLEASE_TOKEN }}
@ -35,7 +35,7 @@ jobs:
ZMK_RELEASE_PLEASE_TOKEN: ${{ secrets.ZMK_RELEASE_PLEASE_TOKEN }}
VERSION: v${{ needs.handle-commit.outputs.major }}.${{ needs.handle-commit.outputs.minor }}
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v6
- name: Create major.minor branch
if: ${{ needs.handle-commit.outputs.patch == '0' }}

View file

@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@v6
- name: Find test directories
id: test-dirs
run: |
@ -40,7 +40,7 @@ jobs:
image: docker.io/zmkfirmware/zmk-build-arm:4.1
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@v6
- name: Cache west modules
uses: actions/cache@v5
env:

View file

@ -1 +1 @@
{".":"0.3.0"}
{".":"0.4.0"}

View file

@ -1,5 +1,107 @@
# Changelog
## [0.4.0](https://github.com/zmkfirmware/zmk/compare/v0.3.0...v0.4.0) (2026-06-20)
### ⚠ BREAKING CHANGES
* Move to zephyr v4.1 ([#3060](https://github.com/zmkfirmware/zmk/issues/3060))
* **core:** Allow layer behaviors to "lock" layers on (https://github.com/zmkfirmware/zmk/pull/2717)
### Features
* Add double tap to enter bootloader functionality ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* Add LED indicator support ([#3239](https://github.com/zmkfirmware/zmk/issues/3239)) ([197f899](https://github.com/zmkfirmware/zmk/commit/197f8997776c960b6d2d368909895735f859a4b4))
* Add nBOOT_SEL bit setup for STM32 G0/C0 targets ([f85ec7e](https://github.com/zmkfirmware/zmk/commit/f85ec7e7a24be10f1cf59025a192569dc0b33167))
* Add ZMK_BOARD_COMPAT Kconfig symbol, and check for it ([a23aa00](https://github.com/zmkfirmware/zmk/commit/a23aa009d7a07d67fe5609caca7372e16610f238))
* Allow layer behaviors to "lock" layers on (https://github.com/zmkfirmware/zmk/pull/2717) ([5138c6f](https://github.com/zmkfirmware/zmk/commit/5138c6fb14783b756c5a3e61581625c700f3555b))
* **behaviors:** add `&out OUT_NONE` ([#3235](https://github.com/zmkfirmware/zmk/issues/3235)) ([8a44ef1](https://github.com/zmkfirmware/zmk/commit/8a44ef109ae301ce084b32dd5fe25200da9e402f))
* **behaviors:** Add retention boot mode to reset. ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **ble:** Use appearance set in the BT_DEVICE_APPEARANCE config ([#3115](https://github.com/zmkfirmware/zmk/issues/3115)) ([ad7fbfe](https://github.com/zmkfirmware/zmk/commit/ad7fbfef920d9907ca8f143e273fa9eb7d84b25a))
* **boards/shields:** Add settings for Rpi Pico and add tester_rpi_pico shield ([#2900](https://github.com/zmkfirmware/zmk/issues/2900)) ([ccf20a1](https://github.com/zmkfirmware/zmk/commit/ccf20a1f5c1534a197d32279abbe0eaf651099d8))
* **boards:** Add Kconfig for nrf52840dongle ZMK board variant ([#3284](https://github.com/zmkfirmware/zmk/issues/3284)) ([a1aca03](https://github.com/zmkfirmware/zmk/commit/a1aca03aa02589329cf99870dec7cd258814385c))
* **boards:** add physical layout for reviung34 ([#3351](https://github.com/zmkfirmware/zmk/issues/3351)) ([0a6c6a1](https://github.com/zmkfirmware/zmk/commit/0a6c6a185680d08abdb463cca6d001b0142a49bf))
* **boards:** add support for nrf52840dongle_nrf52840 ([#3011](https://github.com/zmkfirmware/zmk/issues/3011)) ([c7fae18](https://github.com/zmkfirmware/zmk/commit/c7fae18ae122b2465080507380dd55d096edd666))
* **core:** (Optionally) use Zephyr keyboard input devices ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **core:** mapper for magic bootloader values. ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **display:** Add thread name to dedicated display queue. ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **docs:** Update New Behavior Guide ([#3107](https://github.com/zmkfirmware/zmk/issues/3107)) ([e34793e](https://github.com/zmkfirmware/zmk/commit/e34793e8c7193bc868b95ec38d78f67956f759cb))
* **endpoints:** add "no endpoint" value ([6e7e0de](https://github.com/zmkfirmware/zmk/commit/6e7e0de2b621073392816b284ab4931bee709ee8))
* **endpoints:** add "no endpoint" value ([#3140](https://github.com/zmkfirmware/zmk/issues/3140)) ([6e7e0de](https://github.com/zmkfirmware/zmk/commit/6e7e0de2b621073392816b284ab4931bee709ee8))
* **layouts:** Add physical layout for Redox shield ([61de01a](https://github.com/zmkfirmware/zmk/commit/61de01abb00a73349a188ef2e10ad1cd040d31b3))
* Move to zephyr v4.1 ([#3060](https://github.com/zmkfirmware/zmk/issues/3060)) ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **pointing:** Handle INPUT_BTN_TOUCH codes for mouse buttons ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **pointing:** Release pressed keys on disconnect ([#3204](https://github.com/zmkfirmware/zmk/issues/3204)) ([24487bd](https://github.com/zmkfirmware/zmk/commit/24487bd9744f504724089f0e1cec98431a2d3333))
* **shields:** Add Studio support to boardsource3x4 ([#3154](https://github.com/zmkfirmware/zmk/issues/3154)) ([40e06f3](https://github.com/zmkfirmware/zmk/commit/40e06f3c0084751f7ae012a71d92d5801ac3b7a0))
* **split:** Add HID indicators and physical layout set to Wired split ([#3103](https://github.com/zmkfirmware/zmk/issues/3103)) ([7738924](https://github.com/zmkfirmware/zmk/commit/773892434931b74bdf54474b73c909779daa9471))
### Bug Fixes
* Add "optional" folder to .gitignore ([#3141](https://github.com/zmkfirmware/zmk/issues/3141)) ([c099041](https://github.com/zmkfirmware/zmk/commit/c0990410da4c0a0c3776448e8c05ca2ce8778c8a))
* **behaviors:** correctly handle sensor rotation remainder ([#3084](https://github.com/zmkfirmware/zmk/issues/3084)) ([958fa78](https://github.com/zmkfirmware/zmk/commit/958fa788067e18c2228d016fcd826000bb8f0320))
* **boards:** Add xiao_ble sd_partition label for nosd snippet compat ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **boards:** Adjust defconfig check for Planck with HWMv2 changes ([#3357](https://github.com/zmkfirmware/zmk/issues/3357)) ([9917e2f](https://github.com/zmkfirmware/zmk/commit/9917e2f1371d5bb051bf8eb782c1297db41d742b))
* **boards:** Fix pillbug board.yml to report extension ([a23aa00](https://github.com/zmkfirmware/zmk/commit/a23aa009d7a07d67fe5609caca7372e16610f238))
* **boards:** Properly note ZMK compat for xiao_rp2040/zmk variant ([#3326](https://github.com/zmkfirmware/zmk/issues/3326)) ([0331b7d](https://github.com/zmkfirmware/zmk/commit/0331b7d16e80954b807917f9323e59ffc1e3b626))
* **boards:** Remove nano overlays for old nice_nano_v2 board ID. ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **boards:** Remove some references to old nice_nano_v2 board ID. ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **boards:** Retore bootloader support on XIAO BLE. ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **ci:** Better safeguards for ZMK variant build check ([#3277](https://github.com/zmkfirmware/zmk/issues/3277)) ([8feeb52](https://github.com/zmkfirmware/zmk/commit/8feeb52eafc716c1697cfe0515e98b78281c3543))
* **ci:** disable nrf5340dk from being built in our CI ([#3066](https://github.com/zmkfirmware/zmk/issues/3066)) ([522971f](https://github.com/zmkfirmware/zmk/commit/522971f41d62d7e5d6664eb61c84d190781feeb9))
* **ci:** Fix release please template bump ([#3021](https://github.com/zmkfirmware/zmk/issues/3021)) ([f3233c1](https://github.com/zmkfirmware/zmk/commit/f3233c1b60e4cb4c095572740bcbcaf7111eb804))
* **ci:** Pin @actions/artifact to a compatible release ([#3230](https://github.com/zmkfirmware/zmk/issues/3230)) ([ada1542](https://github.com/zmkfirmware/zmk/commit/ada1542940c3a01c0866c9fe9c30f489bc087328))
* **ci:** Prevent slash characters in artifact names. ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **ci:** Skip build on empty build matrix ([#3271](https://github.com/zmkfirmware/zmk/issues/3271)) ([df2e979](https://github.com/zmkfirmware/zmk/commit/df2e979d7e03ba84a503e3d90975a599d484b9e0)), closes [#3179](https://github.com/zmkfirmware/zmk/issues/3179)
* **core:** Don't force CBPRINTF_NANO, for proper formatting. ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **core:** Generate correct keymap layer names for all builds ([#3047](https://github.com/zmkfirmware/zmk/issues/3047)) ([0b5a103](https://github.com/zmkfirmware/zmk/commit/0b5a103c187ad337b9f50d824667866c4d7252e1)), closes [#3045](https://github.com/zmkfirmware/zmk/issues/3045)
* **core:** One tick kscan wait on RP2350 ([#3255](https://github.com/zmkfirmware/zmk/issues/3255)) ([9278505](https://github.com/zmkfirmware/zmk/commit/9278505975759e9cf01b4e6e8ead359b14a11400))
* **core:** Set a system work queue stack size of 2048 by default ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **core:** support magic bootloader values for nRF52833 ([#3163](https://github.com/zmkfirmware/zmk/issues/3163)) ([308de56](https://github.com/zmkfirmware/zmk/commit/308de56fb938057da7648a411ce0dce780dfc3f1))
* Disable Nordic dt-bindings header checks. ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **display:** add serial VCOM inversion for Nice! View ([#3294](https://github.com/zmkfirmware/zmk/issues/3294)) ([3538843](https://github.com/zmkfirmware/zmk/commit/3538843a0989a8611cd997bb5246d3540b0474b2))
* **display:** Adjust stack sizes for display usage. ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **display:** Fix setting the small font for the mono theme. ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **display:** port nice!view display code ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **docs:** Improve ZMK setup instructions ([#3209](https://github.com/zmkfirmware/zmk/issues/3209)) ([354cff9](https://github.com/zmkfirmware/zmk/commit/354cff9c36b49eee6abbb8a61e6b927539aebbf2))
* **docs:** Tweak layer tap example to be clearer ([#3023](https://github.com/zmkfirmware/zmk/issues/3023)) ([919bce7](https://github.com/zmkfirmware/zmk/commit/919bce7962db78139415ccf0e80fb858c89adb3d))
* Don't enable ZMK Display by default for a few shields ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **endpoints:** Add endpoint setting upgrade ([6e7e0de](https://github.com/zmkfirmware/zmk/commit/6e7e0de2b621073392816b284ab4931bee709ee8))
* Fix redundant const warning ([#3139](https://github.com/zmkfirmware/zmk/issues/3139)) ([8987f39](https://github.com/zmkfirmware/zmk/commit/8987f3979d7877114ede2f34edb5570a6b454460))
* **hid:** initialize missing d_scroll_x field in mouse report ([#3196](https://github.com/zmkfirmware/zmk/issues/3196)) ([abce9de](https://github.com/zmkfirmware/zmk/commit/abce9deab76124d72c61a824aaa1affc3dbc1260))
* **keymap:** Fix overflow in get/set bindings ([#3205](https://github.com/zmkfirmware/zmk/issues/3205)) ([ab46f48](https://github.com/zmkfirmware/zmk/commit/ab46f48dde8aa70e44a2fc2d2a1b81ae703d4981))
* nice!view built-in widgets render failure from insufficient memory ([#3243](https://github.com/zmkfirmware/zmk/issues/3243)) ([536375e](https://github.com/zmkfirmware/zmk/commit/536375e45ef6d01a9c194803525bf9dd5e119421)), closes [#3219](https://github.com/zmkfirmware/zmk/issues/3219)
* **pointing:** Refactor for changes to input API ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* Refactor for new Zephyr PM API ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* Remove usage of renamed Kconfig from core coverage. ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* replace removed `K_THREAD_STACK_MEMBER` with `K_KERNEL_STACK_MEMBER` ([#3218](https://github.com/zmkfirmware/zmk/issues/3218)) ([f6c629e](https://github.com/zmkfirmware/zmk/commit/f6c629e895bbe3957ec243afb80b11e1e4b4e503))
* **sensors:** Initialize sensor data to 0 before fetching. ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* Set default transport according to enabled transports ([6e7e0de](https://github.com/zmkfirmware/zmk/commit/6e7e0de2b621073392816b284ab4931bee709ee8))
* **shields:** Proper transparent binding in sofle raise layer ([#3238](https://github.com/zmkfirmware/zmk/issues/3238)) ([5cfc67a](https://github.com/zmkfirmware/zmk/commit/5cfc67a33402b24ab893b8d71cef1af2a869adbb))
* **split:** correct async UART RX buffer definition ([#3193](https://github.com/zmkfirmware/zmk/issues/3193)) ([36dbf46](https://github.com/zmkfirmware/zmk/commit/36dbf467644d4b4b6b9176241d42261d27fb18f2))
* **split:** int to pointer cast in bas proxy ([#3105](https://github.com/zmkfirmware/zmk/issues/3105)) ([ece2ce1](https://github.com/zmkfirmware/zmk/commit/ece2ce11b8c7245fbe2b4e41ec9fa7a870632e6c))
* **split:** Properly return from command handler ([#3120](https://github.com/zmkfirmware/zmk/issues/3120)) ([d32ffb0](https://github.com/zmkfirmware/zmk/commit/d32ffb0a335ece70a9ce3dc3ce014676534ee99b))
* **split:** Use correct Kconfig for bumping TX buffers for discovery ([#3216](https://github.com/zmkfirmware/zmk/issues/3216)) ([9490391](https://github.com/zmkfirmware/zmk/commit/9490391e1e4010c83291d437b7f9a71ace244581)), closes [#3156](https://github.com/zmkfirmware/zmk/issues/3156)
* **studio:** Allow setting UART RPC thread priority ([#3290](https://github.com/zmkfirmware/zmk/issues/3290)) ([e4fb39d](https://github.com/zmkfirmware/zmk/commit/e4fb39d4a6514fe90d44b1570f908bddc5df0ad2))
* **studio:** avoid decoding buffer overflow ([#3185](https://github.com/zmkfirmware/zmk/issues/3185)) ([70ab6b2](https://github.com/zmkfirmware/zmk/commit/70ab6b243a90b556d113fcdd0c8de1ef3dccdc1e))
* **studio:** Correct `memset` usage. ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **studio:** Correct usage of thread analyzer API ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **studio:** Properly serialize GATT RPC indications. ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **tests:** Fix BLE test to account for Zephyr changes ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **underglow:** Remove use of removed Kconfig WS2812 symbol ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **usb:** Adjust Kconfig settings for USB. ([c06fa48](https://github.com/zmkfirmware/zmk/commit/c06fa48ce59e016105d79c20942d085314502d8d))
* **usb:** Prevent unexpected USB disconnection caused by USB SOF ([#3070](https://github.com/zmkfirmware/zmk/issues/3070)) ([118359c](https://github.com/zmkfirmware/zmk/commit/118359c83efa0758144489fd5e12cc6f5bdbad4c))
### Documentation
* Added documentation note on locking layers ([5138c6f](https://github.com/zmkfirmware/zmk/commit/5138c6fb14783b756c5a3e61581625c700f3555b))
### Code Refactoring
* **core:** Allow layer behaviors to "lock" layers on (https://github.com/zmkfirmware/zmk/pull/2717) ([5138c6f](https://github.com/zmkfirmware/zmk/commit/5138c6fb14783b756c5a3e61581625c700f3555b))
## [0.3.0](https://github.com/zmkfirmware/zmk/compare/v0.2.1...v0.3.0) (2025-08-01)

View file

@ -3,7 +3,7 @@ VERSION_MAJOR = 0
# x-release-please-end
# x-release-please-start-minor
VERSION_MINOR = 3
VERSION_MINOR = 4
# x-release-please-end
# x-release-please-start-patch

View file

@ -55,8 +55,12 @@ Per sensor overrides can be added with ordered nested nodes with the correct ove
};
```
:::note
The names of the child nodes are not important, and are applied in order to the sensors listed in the `sensors` property of the sensors node.
:::
Applies to the node and child nodes of: `compatible = "zmk,keymap-sensors"`
Definition file: [zmk/app/drivers/zephyr/dts/bindings/zmk,keymap-sensors.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/drivers/zephyr/dts/bindings/zmk%2Ckeymap-sensors.yaml)

View file

@ -11,8 +11,6 @@ This document outlines how to test your documentation changes locally and prepar
The documentation is written with [Docusaurus](https://docusaurus.io/). The ZMK source code has all of the necessary Docusaurus dependencies included, but referencing their documentation can be helpful at times.
The website is built using the latest LTS version of node, which is available at <https://nodejs.org/en/download/>.
The general process for updating the ZMK documentation is:
1. Update the documentation
@ -20,6 +18,14 @@ The general process for updating the ZMK documentation is:
3. Ensure the sources are formatted properly and linted
4. Create a Pull Request for review and inclusion into the ZMK sources
:::note
If you are working with the documentation from within VS Code+Docker please be aware the documentation will not be auto-generated when making changes while the server is running. You'll need to restart the server when saving changes to the documentation.
:::
:::note
You will need `Node.js` and `npm` installed to update the documentation. If you're using the ZMK dev container (Docker) the necessary dependencies are already installed. Otherwise, you must install these dependencies yourself. Since `Node.js` packages in Linux distributions tend to be outdated, it's recommended to install the current version from a repository like [NodeSource](https://github.com/nodesource/distributions) to avoid build errors.
:::
## Testing Documentation Updates Locally
To verify documentation updates locally, follow the following procedure. The `npm` commands and first step will need to be run from a terminal.
@ -46,9 +52,15 @@ The check commands can be run with the following procedure in a terminal that's
3. Run `npm run lint`
4. Run `npm run build`
:::danger
If any of the above steps throw an error, they need to be addressed and all of the checks re-run prior to submitting a pull request.
:::
The documentation uses American English spelling and grammar conventions. Title case is used for the first three heading levels, with sentence case used beyond that. Please make sure your changes conform to these conventions.
:::note
The documentation uses American English spelling and grammar conventions. Title case is used for the first three heading levels, with sentence case used beyond that.
Please make sure your changes conform to these conventions - prettier and lint are unfortunately unable to do this automatically.
:::
## Submitting a Pull Request

View file

@ -12,7 +12,9 @@ sidebar_label: ZMK Module Creation
See also Zephyr's [page on modules](https://docs.zephyrproject.org/4.1.0/develop/modules.html).
For open source hardware designs, it's recommended to **not** include the hardware design files in the ZMK module itself, since the module will be fetched by users during build and having design files in the module would likely make the module unnecessarily large and slow to fetch.
:::tip
For open source hardware designs, it can be convenient to use [Git submodules](https://github.blog/open-source/git/working-with-submodules/) to have the ZMK module also be a Git submodule of the repository hosting the hardware design.
:::
## Module Setup
@ -131,15 +133,15 @@ Note that the `include` and `src` folders are not mandated by the module system,
Modules should expose all provided header files with an include path name beginning with the module-name, for example at `include/zmk_<type>_<description>/<header>.h`.
:::info
If your module requires adding drivers to existing subsystems in modules, you will need to use the `zephyr_library_amend()` CMake command, which requires you to have a specific directory structure. See [`zephyr/cmake/modules/extensions.cmake`](https://github.com/zephyrproject-rtos/zephyr/blob/main@%7B2025-Feb-15%7D/cmake/modules/extensions.cmake#L492) for the definition and some documentation in the comments, with an example in [`petejohanson/ec-support-zmk-module`](https://github.com/petejohanson/ec-support-zmk-module/tree/main/drivers/kscan).
If your module requires adding drivers to existing subsystems in modules, you will need to use the `zephyr_library_amend()` CMake command, which requires you to have a specific directory structure. See [here](https://github.com/zephyrproject-rtos/zephyr/blob/main/cmake/modules/extensions.cmake#L454) for the definition and some documentation in the comments, with an example [here](https://github.com/petejohanson/ec-support-zmk-module/tree/main/drivers/kscan).
:::
## Examples
Below are some examples of modules for different types. Unless under the `zmkfirmware` project, these are not endorsed officially and may not follow our conventions perfectly. For such reason, the modules chosen to be presented here may change with time.
- Keyboard: <https://github.com/petejohanson/zmk-keyboards-katori>
- Behavior: <https://github.com/urob/zmk-leader-key>
- Driver: <https://github.com/petejohanson/cirque-input-module>
- Feature: <https://github.com/joelspadin/zmk-locales>
- VFX: <https://github.com/caksoylar/zmk-rgbled-widget>
- Keyboard: https://github.com/petejohanson/zmk-keyboards-katori
- Behavior: https://github.com/urob/zmk-leader-key
- Driver: https://github.com/petejohanson/cirque-input-module
- Feature: https://github.com/joelspadin/zmk-locales
- VFX: https://github.com/caksoylar/zmk-rgbled-widget

View file

@ -54,10 +54,14 @@ For example, if you want the LED to be off when the indicator is active, 100% br
};
```
:::note
If the LED is not configured to support brightness control, any value greater than 0 will result in maximum brightness.
For most LEDs, you can enable PWM brightness control, though this will increase power usage slightly. See the [LED indicators hardware integration page](../hardware-integration/lighting/led-indicators.md) for details on configuring the LEDs.
:::
## Adding LED Indicator Support to a Keyboard
See the [LED indicators hardware integration page](../hardware-integration/lighting/led-indicators.md) for instructions to enable this feature on a keyboard.

View file

@ -11,7 +11,7 @@ Your keyboard likely uses only one type, depending on the type of LED hardware i
- [Backlight](#backlight) system controls parallel-connected, non-addressable, single color LEDs.
These are found on keyboards that have a single color backlight that only allows for brightness control.
:::info
:::warning
Although the naming of the systems might imply it, which system you use typically does _not_ depend on the physical location of the LEDs.
Instead, you should use the one that supports the LED hardware type that your keyboard has, as described above.

View file

@ -44,9 +44,13 @@ It is recommended to add the `wakeup-source` property to `kscan` devices even if
The soft off feature is used to turn the keyboard on and off explicitly, rather than through a timeout like the deep sleep feature. Depending on the keyboard, this may be through a dedicated on/off push button defined in hardware, or merely through an additional binding in the keymap to turn the device off and an existing reset button to turn the device back on.
The feature is intended as an alternative to using a hardware switch to physically cut power from the battery to the keyboard. This can be useful for existing PCBs not designed for wireless that don't have a power switch, or for new designs that favor a push button on/off like found on other devices. It yields power savings comparable to the deep sleep state.
:::note
The device enters the same software power-off state as in deep sleep, but is significantly more restrictive in the sources which can wake it. Power is _not_ technically removed from the entire system, unlike a hardware switch.
The feature is intended as an alternative to using a hardware switch to physically cut power from the battery to the keyboard. This can be useful for existing PCBs not designed for wireless that don't have a power switch, or for new designs that favor a push button on/off like found on other devices. It yields power savings comparable to the deep sleep state.
:::
A device can be put in the soft off state by:

View file

@ -6,7 +6,7 @@ ZMK Studio provides runtime update functionality to ZMK powered devices, allowin
:::info
To use ZMK Studio, a keyboard needs to be [configured appropriately](#adding-zmk-studio-support-to-a-keyboard). ZMK has updated some, but not all, of its in-tree keyboards for use with ZMK Studio, the list of which can be found in the [ZMK Studio blog post](/blog/2024/11/11/zmk-studio-mvp-ga). If your keyboard is supported by an external module/config, check with the maintainer to see if support has been added.
To use ZMK Studio, a keyboard needs to be [configured appropriately](#adding-zmk-studio-support-to-a-keyboard). ZMK has updated some, but not all, of its in-tree keyboards for use with ZMK Studio, the list of which can be found [here](/blog/2024/11/11/zmk-studio-mvp-ga). If your keyboard is supported by an external module/config, check with the maintainer to see if support has been added.
:::
@ -54,7 +54,7 @@ Generally, if you intend to use ZMK Studio, then you should not make any further
## Accessing ZMK Studio
You can use ZMK Studio with Chrome/Edge at <https://zmk.studio/>.
You can use ZMK Studio with Chrome/Edge at https://zmk.studio/.
To use the native app for Linux, macOS, or Windows, visit the [download page](https://zmk.studio/download).

View file

@ -15,10 +15,12 @@ For example: the `kyria` shield has a [`boards/nice_nano_nrf52840_zmk.overlay`](
### nRF52-Based Boards
Using an SPI-based LED strip driver on the `&spi3` interface is the simplest option for nRF52-based boards.
Using an SPI-based LED strip driver on the `&spi3` interface is the simplest option for nRF52-based boards. If possible, avoid using pins which are limited to low-frequency I/O for this purpose. The resulting interference may result in poor wireless performance.
:::info
If possible, avoid using pins which are limited to low-frequency I/O for this purpose. The resulting interference may result in poor wireless performance. The list of low frequency I/O pins for the nRF52840 can be found at <https://docs.nordicsemi.com/bundle/ps_nrf52840/page/pin.html>.
The list of low frequency I/O pins for the nRF52840 can be found [here](https://docs.nordicsemi.com/bundle/ps_nrf52840/page/pin.html).
:::
The following example uses `P0.06` as the "Data In" pin of a WS2812-compatible LED strip:
@ -67,9 +69,13 @@ The following example uses `P0.06` as the "Data In" pin of a WS2812-compatible L
};
```
:::note
Standard WS2812 LEDs use a wire protocol where the bits for the colors green, red, and blue values are sent in that order.
If your board/shield uses LEDs that require the data sent in a different order, the `color-mapping` property ordering should be changed to match.
:::
### Other Boards
Be sure to check the Zephyr documentation for the LED strip and necessary hardware bindings. Not every board has an `spi3` node, or configures `pinctrl` the same way. Reconcile this with any hardware restrictions found in the manufacturer's datasheet. Additional hardware interfaces may need to be enabled via Kconfig.

View file

@ -32,7 +32,7 @@ This guide assumes you already have a configured GitHub account. If you don't ye
Follow these steps to create your new repository:
- Visit <https://github.com/zmkfirmware/unified-zmk-config-template>
- Visit https://github.com/zmkfirmware/unified-zmk-config-template
- Click the green "Use this template" button
- In the drop down that opens, click "Use this template".
- In the following screen, provide the following information:

View file

@ -62,7 +62,11 @@ A key description has the shape `<&key_physical_attrs w h x y r rx ry>` with the
You can specify negative values in devicetree using parentheses around it, e.g. `(-3000)` for a 30 degree counterclockwise rotation.
We recommend the use of <https://zmk-physical-layout-converter.streamlit.app> for writing a physical layout or converting one from a QMK JSON definition. If your keyboard already has a physical layout defined for the use with KLE, we recommend using <https://nickcoutsos.github.io/keymap-layout-tools/> first to convert your existing layout into QMK JSON. The second tool can also import the position data from KiCAD, if said program was used to design the keyboard.
:::tip
We recommend the use of [this tool](https://zmk-physical-layout-converter.streamlit.app/) for writing a physical layout or converting one from a QMK JSON definition. If your keyboard already has a physical layout defined for the use with KLE, we recommend using [this other tool](https://nickcoutsos.github.io/keymap-layout-tools/) first to convert your existing layout into QMK JSON. The second tool can also import the position data from KiCAD, if said program was used to design the keyboard.
:::
### Physical Layout with Keys Example
@ -203,7 +207,11 @@ The position map should be marked as `complete` if all desired binding transfers
See also the [configuration section on position maps](../config/layout.md#physical-layout-position-map).
We recommend the use of <https://zmk-layout-helper.netlify.app>, distinct from the previous two mentioned, for the purposes of writing a position map.
:::tip
We recommend the use of [this tool](https://zmk-layout-helper.netlify.app/), distinct from the previous two mentioned, for the purposes of writing a position map.
:::
#### Writing a position map

View file

@ -8,11 +8,15 @@ import TabItem from "@theme/TabItem";
import InterconnectTabs from "@site/src/components/interconnect-tabs";
import Metadata from "@site/src/data/hardware-metadata.json";
:::info
This page exists to provide a guide to [Pin Control](https://docs.zephyrproject.org/4.1.0/hardware/pinctrl/index.html#pin-control) for ZMK users and designers. Refer to [Zephyr's page on Pin Control](https://docs.zephyrproject.org/4.1.0/hardware/pinctrl/index.html#pin-control) for elaboration and more details on any of the points raised here.
:::
A basic keyboard design as introduced in the [new shield guide](./new-shield.mdx) only uses its pins for the keyboard matrix. Many keyboard designs make use of advanced components or functionality, such as displays or shift registers. This results in the keyboard making use of communication protocols such as (but not limited to) SPI, I2C, or UART. Configuring pins for the usage of advanced functionality such as drivers for the previously named protocols is referred to as "Pin Control".
:::warning
The details of pin control can vary from vendor to vendor. An attempt was made to be as general as possible, but it isn't possible to cover all possible cases. The approaches for the nRF52840 and RP2040 MCUs/SoCs are documented in their entirety below. For other MCUs/SoCs, please refer to the [Zephyr documentation](https://docs.zephyrproject.org/4.1.0/index.html) and the examples and other files found in-tree of [ZMK](https://github.com/zmkfirmware/zmk/tree/main/app/boards) and [ZMK's fork of Zephyr](https://github.com/zmkfirmware/zephyr).
:::
## Boards, Shields, and Modules
@ -29,8 +33,10 @@ Pin control is always defined for a _board_, never for a shield:
```
Note that you will need to define a separate overlay _for each_ of the boards to be used with the shield.
:::info
Assume that the shield that you are using is found in-tree of ZMK or within an external module, and _does not_ contain the overlay for the board that you wish to use.
If this is the case, then you should fork the source repository and add the overlay to the fork. Use said fork to build your firmware, and potentially submit a PR to upstream.
:::
## Predefined Nodes

View file

@ -9,7 +9,9 @@ Shift registers are the recommended method of adding additional GPIO pins to MCU
This page assumes that you are using a SIPO shift register with the part number 74HC595. Other shift registers can work as well but this is the most commonly used one.
:::
:::tip
To understand how shift registers work, we recommend reading through ["How does the 74HC595 Shift Register work?"](https://lastminuteengineers.com/74hc595-shift-register-arduino-tutorial/#how-does-the-74hc595-shift-register-work).
:::
## Design Guidelines

View file

@ -372,10 +372,12 @@ Including `hold-trigger-key-positions` in your hold-tap definition turns on the
In all other situations, positional hold-tap will not modify the behavior of your hold-tap. Positional hold-tap is useful when used with home-row modifiers: for example, if you have a home-row modifier key in the left hand, by including only key positions from the right hand in `hold-trigger-key-positions`, you will only get hold behaviors during cross-hand key combinations unless you exceed `tapping-term-ms` when using "balanced" or "hold-preferred" flavors.
`hold-trigger-key-positions` is an array of key position indexes. Key positions are numbered sequentially according to your keymap, starting with 0. So if the first key in your keymap is Q, this key is in position 0. The next key (probably W) will be in position 1, et cetera.
For home-row mods, it is recommended to use this property with `hold-trigger-on-release` so that modifiers on the same hand can be combined.
:::info
`hold-trigger-key-positions` is an array of key position indexes. Key positions are numbered sequentially according to your keymap, starting with 0. So if the first key in your keymap is Q, this key is in position 0. The next key (probably W) will be in position 1, et cetera.
:::
<details>
<summary>The following example uses a hold-tap behavior definition configured with the `hold-preferred` flavor, and with positional hold-tap enabled:</summary>

View file

@ -312,6 +312,10 @@ To avoid repetition or possible typos when declaring a **zero parameter macro**,
)
```
:::note
`ZMK_MACRO()` **only supports declaring non-parameterized (zero parameter) macros**; parameterized declarations are not currently supported.
:::
This can be used instead of a complete macro definition. During the firmware build process, the example above would produce the complete macro definition below:
```dts

View file

@ -48,7 +48,7 @@ The on/off state that is set by the `&ext_power` behavior will be [saved to flas
However it will only be saved after [`CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE`](../../config/system.md#general) milliseconds in order to reduce potential wear on the flash memory.
:::
### Examples
### Example:
1. Behavior binding to enable the external power

View file

@ -7,8 +7,12 @@ sidebar_label: Behaviors
The behaviors input processor is used invoke standard behaviors when certain input events occur; most frequently this is used to trigger behaviors when certain mouse buttons are triggered by physical pointing devices.
:::note
This input processor is primarily intended for `INPUT_EV_KEY` type of events that have a binary on/off state, not vector types for relative or absolute movements.
:::
:::note[Source-specific behaviors on split keyboards]
Invoking a [source-specific behavior](../../features/split-keyboards.md#source-locality-behaviors) such as one of the [reset behaviors](../behaviors/reset.md) using this input processor will always trigger it on the central side of the keyboard, regardless of the side includes the input device that originally generated the input event.
:::

View file

@ -9,6 +9,11 @@ import Table from "@site/src/components/codes/Table";
This is the reference page for keycodes used by behaviors. Use the table of contents (on the right or the top) for easy navigation.
:::warning
Take extra notice of the spelling of the keycodes, especially the shorthand spelling.
Otherwise, it will result in an elusive parsing error!
:::
:::info[Keyboard vs. Consumer keycodes]
In the below tables, there are keycode pairs with similar names where one variant has a `K_` prefix and another `C_`.
These variants correspond to similarly named usages from different [HID usage pages](https://usb.org/sites/default/files/hut1_2.pdf#page=16),

View file

@ -53,10 +53,12 @@ A `devicetree_generated.h` error that follows with an "undeclared here" string i
In this example, the error string `DT_N_S_keymap_S_symbol_layer_P_bindings_IDX_12_PH_P_label` indicates a problem with the key binding in position `12` in the `symbol_layer` of the keymap.
:::info
Key positions are numbered starting from `0` at the top left key on the keymap, incrementing horizontally, row by row.
:::
:::tip
A common mistake that leads to this error is to use [key press keycodes](keymaps/behaviors/key-press.md) without the leading `&kp` binding. That is, having entries such as `&kp A SPACE &kp B` that should have been `&kp A &kp SPACE &kp B`.
A common mistake that leads to this error is to use [key press keycodes](keymaps/behaviors/key-press.md) without the leading `&kp` binding. That is, having entries such as `SPACE` that should have been `&kp SPACE`.
:::
## Diagnosing Unexpected Build Results

32
docs/package-lock.json generated
View file

@ -13847,13 +13847,13 @@
}
},
"node_modules/launch-editor": {
"version": "2.14.1",
"resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.14.1.tgz",
"integrity": "sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==",
"version": "2.13.2",
"resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.13.2.tgz",
"integrity": "sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==",
"license": "MIT",
"dependencies": {
"picocolors": "^1.1.1",
"shell-quote": "^1.8.4"
"shell-quote": "^1.8.3"
}
},
"node_modules/layout-base": {
@ -20819,9 +20819,9 @@
}
},
"node_modules/shell-quote": {
"version": "1.8.4",
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.4.tgz",
"integrity": "sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ==",
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz",
"integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
@ -23154,9 +23154,9 @@
}
},
"node_modules/webpack-dev-server": {
"version": "5.2.5",
"resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.5.tgz",
"integrity": "sha512-4wZtCquSuv9CKX8oybo+mqxtxZqWz47uM1Ch94lxowBztOhWCbhqvRbfC/mODOwxgV2brY+JGZpHq58/SuVFYg==",
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.4.tgz",
"integrity": "sha512-GqDPGZN9bRqKBTkp4aWkobDDHMsrXKoGSdOH56smIri8qR0JG8gfL8/v/f/OZR3/OKXjG8uwJbFVhKm/FNU/UA==",
"license": "MIT",
"dependencies": {
"@types/bonjour": "^3.5.13",
@ -23241,9 +23241,9 @@
}
},
"node_modules/webpack-dev-server/node_modules/ws": {
"version": "8.21.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz",
"integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==",
"version": "8.20.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz",
"integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
@ -23636,9 +23636,9 @@
}
},
"node_modules/ws": {
"version": "7.5.11",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.11.tgz",
"integrity": "sha512-zS54Oen9bITtp7kp2XM3AydrCIq1D+HwJOuH+c+e4LfpL/lotP5osijd+UoMnxwAam1GN8R4KtLAyIrIcBNpiA==",
"version": "7.5.10",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
"integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
"license": "MIT",
"engines": {
"node": ">=8.3.0"