{"id":13830053,"url":"https://github.com/sunaku/glove80-keymaps","last_synced_at":"2026-02-28T13:31:52.491Z","repository":{"id":195660075,"uuid":"693406138","full_name":"sunaku/glove80-keymaps","owner":"sunaku","description":"Glorious Engrammer keymap for Glove80 keyboard","archived":false,"fork":false,"pushed_at":"2026-02-27T16:34:12.000Z","size":163886,"stargazers_count":707,"open_issues_count":19,"forks_count":230,"subscribers_count":16,"default_branch":"main","last_synced_at":"2026-02-27T21:19:28.008Z","etag":null,"topics":["engram","glove80","home-row-mods","keyboard-layout","miryoku","zmk-config"],"latest_commit_sha":null,"homepage":"https://sunaku.github.io/moergo-glove80-keyboard.html#layers","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sunaku.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-09-19T01:10:56.000Z","updated_at":"2026-02-23T19:10:30.000Z","dependencies_parsed_at":"2026-01-08T20:10:14.613Z","dependency_job_id":null,"html_url":"https://github.com/sunaku/glove80-keymaps","commit_stats":null,"previous_names":["sunaku/glove80-keymaps"],"tags_count":53,"template":false,"template_full_name":null,"purl":"pkg:github/sunaku/glove80-keymaps","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunaku%2Fglove80-keymaps","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunaku%2Fglove80-keymaps/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunaku%2Fglove80-keymaps/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunaku%2Fglove80-keymaps/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sunaku","download_url":"https://codeload.github.com/sunaku/glove80-keymaps/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunaku%2Fglove80-keymaps/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29935360,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-28T13:16:57.922Z","status":"ssl_error","status_checked_at":"2026-02-28T13:11:15.149Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["engram","glove80","home-row-mods","keyboard-layout","miryoku","zmk-config"],"created_at":"2024-08-04T10:00:54.418Z","updated_at":"2026-02-28T13:31:52.447Z","avatar_url":"https://github.com/sunaku.png","language":"HTML","funding_links":[],"categories":["Keymaps","HTML","Community zmk-config user configurations"],"sub_categories":["Written","Additional Resources"],"readme":"# \"Glorious Engrammer\" keymap for MoErgo Glove80\n\nThis is [my Glove80] keymap featuring the [Enthium] and [Engram] layouts with\n[Miryoku]-style layers and [home row mods].  Other layouts (**QWERTY**, Dvorak,\nColemak/DH, etc.) are also provided to ease your transition to the full glory.\n\n![Photograph of my Glove80 with Enthium layout and per-key RGB illumination.](\nREADME/base-layer-photograph-Enthium.jpg )\n\n[my Glove80]:    https://sunaku.github.io/moergo-glove80-keyboard.html\n[Enthium]:       https://sunaku.github.io/enthium-keyboard-layout.html\n[Engram]:        https://sunaku.github.io/engram-keyboard-layout.html\n[Engrammer]:     https://sunaku.github.io/engrammer-keyboard-layout.html\n[Miryoku]:       https://github.com/manna-harbour/miryoku\n[home row mods]: https://sunaku.github.io/home-row-mods.html\n\n## Keymap\n\nVersion 42-rc4 (PREVIEW)\n- Changes: https://github.com/sunaku/glove80-keymaps/releases/v42-rc4\n- Release: https://my.glove80.com/#/layout/user/856cc9f9-35f3-458f-a239-a44fb25071d9\n\n### Legend\n\nSee [interactive layer map][map] for overview and documentation.\n\u003eNOTE: This is also available as a [printable PDF document][pdf].\n\nSee [release notes][rel] for a visual overview of recent updates.\n\n[map]: https://sunaku.github.io/moergo-glove80-keyboard.html#layers\n[pdf]: README/all-layer-diagrams.pdf\n[rel]: https://github.com/sunaku/glove80-keymaps/releases\n\n### Contents\n\n\u003c!-- vim-markdown-toc GFM --\u003e\n\n* [Guide](#guide)\n  * [Factory layout](#factory-layout)\n  * [Operating system](#operating-system)\n  * [Home row mods](#home-row-mods)\n    * [Difficulty level](#difficulty-level)\n    * [One-shot shifts](#one-shot-shifts)\n    * [Shift forgiveness](#shift-forgiveness)\n    * [Bilateral combinations](#bilateral-combinations)\n  * [Layer access keys](#layer-access-keys)\n  * [Key auto-repeat](#key-auto-repeat)\n  * [Alpha layouts](#alpha-layouts)\n  * [Unicode and Emoji](#unicode-and-emoji)\n    * [OS-native compose](#os-native-compose)\n* [Installing](#installing)\n  * [Enabling mouse emulation](#enabling-mouse-emulation)\n    * [Choose a firmware that supports mouse emulation](#choose-a-firmware-that-supports-mouse-emulation)\n  * [Enabling per-key RGB lighting](#enabling-per-key-rgb-lighting)\n  * [Flashing](#flashing)\n* [Upgrading](#upgrading)\n* [Customizing](#customizing)\n  * [Overriding the defaults](#overriding-the-defaults)\n    * [Reordering home row mods](#reordering-home-row-mods)\n    * [Fine-tuning the timing](#fine-tuning-the-timing)\n  * [Compiling from source](#compiling-from-source)\n    * [World and Emoji characters](#world-and-emoji-characters)\n      * [Adding a new World character](#adding-a-new-world-character)\n      * [Shift key for World characters](#shift-key-for-world-characters)\n      * [Modifiers for World characters](#modifiers-for-world-characters)\n      * [Compose for World characters](#compose-for-world-characters)\n      * [Adding a new Emoji character](#adding-a-new-emoji-character)\n      * [Shift key for Emoji characters](#shift-key-for-emoji-characters)\n    * [Editing layer map diagrams](#editing-layer-map-diagrams)\n    * [Rearranging the base layer](#rearranging-the-base-layer)\n      * [Mirroring horizontally](#mirroring-horizontally)\n* [Discussion](#discussion)\n* [License](#license)\n\n\u003c!-- vim-markdown-toc --\u003e\n\n## Guide\n\nWelcome to the *Glorious Engrammer* keymap! 🧑‍🚀🚀✨  This introductory\nguide will orient you to the world of custom layouts, keymaps, and firmware. 💁\n\n\u003e \"Hey, I'm glad you came! Are you comfortable?\" 🚁  \n\u003e _What?_ 😯  \n\u003e \"Are you comfortable?\" 😎  \n\u003e _No_ 😰  \n\u003e \"Hold on tight...\" ✨  \n\u003e -- Walter Mitty https://vimeo.com/106472147#t=72s\n\n### Factory layout\n\nBefore we get started, let's talk about your escape route back to familiarity.\n\nIf you're a new user (perhaps you've just unboxed your Glove80 or you haven't\ncustomized its default keymap), you might find the Factory layer to be useful:\n\n1. Press \u0026 hold the Magic key (bottom left corner key on left half of Glove80)\n2. Tap the left hand's T3 key (furthest key on the upper arc of thumb cluster)\n\nThis shortcut will toggle the Factory layer on/off and allow you to experiment\nwith this keymap while maintaining an easy escape route to the factory default.\n\n### Operating system\n\nFirst, let's configure this keymap to better suit your operating system by\nadding one of the following lines (just copy+paste whichever is appropriate)\natop the \"Custom Defined Behaviors\" text box in your clone of this keymap:\n\n```h\n#define OPERATING_SYSTEM 'L' // Linux\n#define OPERATING_SYSTEM 'M' // macOS\n#define OPERATING_SYSTEM 'W' // Windows\n```\n\n### Home row mods\n\nNext, let's become familiar with the concept of [home row mods], which are\ndual-function keys that *either* send normal keycodes (such as the letter `A`\nor the number `1`) when tapped or modifiers (such as Shift or Ctrl) when held.\n\n![Concept diagram of *home row mods* on a row-staggered keyboard](https://sunaku.github.io/home-row-mods.png)\n\nThe diagram above shows the default \"GACS\" order of home row mods in this keymap:\n- \"G\" means `LGUI`, which is the Win key in Windows, Cmd in macOS, Super in Linux.\n- \"A\" means `LALT`, which is the Alt key in Windows and Linux, Option in macOS.\n- \"C\" means `LCTL`, which is the Control key in Windows, macOS, and Linux alike.\n- \"S\" means `LSFT`, which is the Shift key in Windows, macOS, and Linux alike.\n\n**NOTE:** If you set your operating system to macOS in the preceding section,\nthe home row mods order will be automatically rearranged into \"CAGS\" because\nmacOS shortcuts tend to use the Cmd key like Windows/Linux use the Ctrl key.\nHowever, you can inhibit the automatic rearrangement by adding this setting:\n```h\n#define MACOS_USE_GACS\n```\n\n#### Difficulty level\n\nIn order to help ease your transition to using [home row mods], this keymap\nprovides a difficulty level setting (like in a video game) that you can set:\n\n```h\n//\n// DIFFICULTY_LEVEL specifies your level of expertise with this keymap.\n// It's meant to help newcomers gradually work their way up to mastery.\n//\n#define DIFFICULTY_LEVEL 1 // novice (500ms)\n#define DIFFICULTY_LEVEL 2 // slower (400ms)\n#define DIFFICULTY_LEVEL 3 // normal (300ms)\n#define DIFFICULTY_LEVEL 4 // faster (200ms)\n#define DIFFICULTY_LEVEL 5 // expert (100ms)\n//\n// You can disable this setting by omitting it or assigning a `0` zero,\n// in which case it will default to my personal set of time thresholds.\n//\n#define DIFFICULTY_LEVEL 0 // sunaku (150ms)\n//\n// No matter what difficulty level you choose, you can always override\n// any settings in this keymap at the beginning of this configuration.\n//\n```\n\nUnless you're already proficient in using home row mods, you might consider\nchoosing an appropriate difficulty level to match your current abilities and\ngradually increase the difficulty level as you work your way up to mastery.\n\nOn the contrary, you can disable the difficulty level feature altogether by\nremoving the `#define DIFFICULTY_LEVEL` line or by setting its value to zero.\nThen, you can experience the default values of all settings (representing my\npersonal fine-tuned configuration) or directly override them per your taste.\n\n#### One-shot shifts\n\nThe traditional pinky shift keys on the base layer are one-shot sticky shifts,\nwhereby tapping them temporarily activates a sticky Shift that applies itself\nto the next key you tap.  This can be useful for single letter capitalization,\nsuch as for the frequent \"I\" in English or when typing camel/PascalCase names.\n\n#### Shift forgiveness\n\nWhat should happen when a home row shift is held and released without any other\nkey having been pressed in the meantime?  I've often found myself in that exact\nscenario for having lingered too long (slow tap) while tapping a home row shift\nkey: instead of typing the underlying letter (per my intention), the tap would\nnot produce any output (to my surprise) since it would hold and release shift.\n\nThanks to the `hold-while-undecided` feature in a newer ZMK release that MoErgo\nhas made available in the `v24.08-beta1` firmware, I finally tamed this nuance:\n\n```h\n#define SHIFT_FORGIVENESS\n```\n\nThis setting will tap when home row shift is merely held and released,\nwithout any other key having been tapped while the shift was held down.\nFor example, suppose you hold a home row shift key and, before pressing\nanother key, suddenly decide that you don't want to use shift after all:\n\n1.  If this setting is enabled, the underlying tap behavior is triggered\n    to type a single character when you release that home row shift key.\n\n2.  Otherwise, nothing happens when you release that home row shift key.\n\nThis requires the \"hold-while-undecided\" ZMK feature in a beta firmware:\nplease select \"v24.08-beta1\" or newer from the drop-down menu located at\nGlove80 Layout Editor \u003e Settings \u003e Advanced Settings \u003e Firmware Version.\n\n\u003eCAUTION: This can interfere with mod-click mouse usage where you hold a\nhome row shift key and perform mouse actions (move, click, drag \u0026 drop):\nwhen you release that home row shift key, its underlying character would\nbe typed, potentially triggering an unexpected action on your selection!\nTo prevent the underlying character from being typed, press another key\n(such as a dedicated shift key, a neighboring home row mod key, or even\na layer access key) before you release the original home row shift key.\n\n\u003eNOTE: You may potentially encounter \"flashing mods\" where an application\nor operating system action is triggered by a standalone tap of a shift,\nbut this is unlikely as people regularly tap shift without consequence.\n\n#### Bilateral combinations\n\nIn order to encourage proper touch-typing technique for shortcuts (where one\nhand holds modifiers while the other taps keys to be modified) and for a more\nnatural typing experience that forgives [same-hand chords] and lingering holds,\nthis keymap provides bilateral combinations enforcement as an optional feature:\n\n```h\n//\n// ENFORCE_BILATERAL cancels out single-handed home row mods activation by\n// releasing any currently pressed mods and replacing them with plain taps.\n//\n// NOTE: You may still encounter \"flashing mods\" where an operating system\n// action is triggered by the release of mods, such as LGUI which launches\n// the Windows Start Menu and LALT which opens the Microsoft Office Ribbon.\n//\n#define ENFORCE_BILATERAL\n```\n\nWhy not just use one-handed shortcuts?  I visualize it this way: I'm trying to\nreach a cookie jar that is high up on a kitchen shelf, so I place one hand on\nthe kitchen counter (the modifier-holding hand) to stabilize myself while I\nreach up for the jar with my other hand (the modified-key tapping hand). 🙋✨\nIn contrast, one-handed shortcuts can be more strenuous as you have to contort\nyour hand to hold a modifier _and_ tap modified keys; plus the act of holding a\nmodifier limits the hand's range of motion when reaching for keys to be tapped.\n\nNevertheless, if you still prefer using one-handed shortcuts, you can disable\nbilateral combinations enforcement by removing the `#define ENFORCE_BILATERAL`\nline and, optionally, deleting the bilateral combinations layers in the keymap.\n\n[same-hand chords]: https://sunaku.github.io/home-row-mods.html#same-hand-chords\n\n### Layer access keys\n\nThis keymap borrows heavily from the legendary [Miryoku] system, featuring:\n\n- Six specialized layers: Cursor, Number, Function, Symbol, Mouse, System\n- Layer access via thumb keys: Backspace, Delete, Escape, Enter, Tab, Space\n- Home row mods on the base layer and on same-hand of all layer access keys\n\nThe idea is that you can always access modifiers with the same hand as the\nlayer access key (which your thumb is holding down) to modify keystrokes on\nthat respective layer.  This way, you don't need to lift your hands off the\nkeyboard or your fingers away from their home position to execute shortcuts.\n\n### Key auto-repeat\n\nSince dual-function keys (such as home row mods and layer access keys) have a\nspecial effect when held, they won't auto-repeat when held like a normal key.\nInstead, you have two options for engaging auto-repeat on dual-function keys:\n\n1. Use the \"Tap then hold\" method: first tap (press and release) and then hold\n   (press and don't release until the desired amount of repetition is reached).\n\n2. Using repetition access keys: first hold down a Typing layer access key and\n   then hold the key you want to repeat for the desired amount of repetition.\n\n![Using repetition access keys](README/repeat-layer-diagram.png)\n\n### Alpha layouts\n\nThis keymap lets you dynamically switch to alpha layouts (such as QWERTY and\nDvorak) other than the one you chose for your base layer during installation,\nby holding the Magic key and tapping the respective number key for that layer.\n\n| Shortcut  | Layer number | Alpha layout                        |\n| --------- | ------------ | ----------------------------------- |\n| Magic+`=` | 0            | Enthium (base layer; your choice)   |\n| Magic+`1` | 1            | Engrammer                           |\n| Magic+`2` | 2            | Engram                              |\n| Magic+`3` | 3            | Dvorak                              |\n| Magic+`4` | 4            | Colemak                             |\n| Magic+`5` | 5            | QWERTY                              |\n| Magic+`6` | 6            | ColemakDH                           |\n| Magic+`7` | 7            | Canary                              |\n\nFor the first 5 alpha layouts, the respective number key for each layout will\nilluminate when you tap the Magic key.  For example, suppose that we activate\nthe QWERTY layout by typing Magic+`5` and that we've forgotten about it after\nsome time... 😅 how can we know which alpha layout is currently active?  Well,\nby simply tapping the Magic key, we'll see that number 5 illuminates in pink 🚨\nthereby indicating that the QWERTY alpha layout (at layer number 5) is active.\n\nHowever, note that number row illumination isn't available for layer 6 onwards.\nThat's just how the Glove80's firmware is currently implemented today; you have\nthe option of implementing such enhancements by editing its ZMK code if desired.\n\n### Unicode and Emoji\n\nUnicode characters (including Emoji 🔥) are typed through ZMK macros (sequences\nof multiple keystrokes) generated from the `world.yaml` and `emoji.yaml` files\nby the `rake` command.  However, in order for these macros to take effect, you\nmay need to enable support for Unicode hexadecimal character input in your OS:\n\n- (macOS) https://uknowit.uwgb.edu/page.php?id=22623\n    and   https://github.com/ldanet/unicode-hex-input-fix\n- (Linux) https://help.ubuntu.com/stable/ubuntu-help/tips-specialchars.html.en#ctrlshiftu\n- (Windows) https://github.com/samhocevar/wincompose\n\nSee also: the `UNICODE_*_DELAY` settings and the `UNICODE_SEQ_*` functions.\n\n#### OS-native compose\n\nIf you prefer using your operating system's built-in shortcuts (rather than\nUnicode) to type international characters in the World layer, activate this:\n\n```h\n//\n// WORLD_USE_COMPOSE uses OS-native Compose keycodes instead of Unicode\n// for characters in the \"compositions\" section of the `world.yaml` file.\n//\n#define WORLD_USE_COMPOSE\n```\n\nSee also: the `COMPOSE_KEY_LINUX` setting and the `COMPOSE_SEQ_*` functions.\n\n## Installing\n\nOpen the [keymap link above](#keymap) and follow these instructions:\n1. Log in (account is required)\n2. Clone the keymap to customize and/or build it!\n3. Choose your base layout (place at top as layer number #0) via drag \u0026 drop.\n4. Customize the keymap behavior in this text box.\n5. Build the firmware and download the `*.uf2` file.\n\n![installation instructions](README/installing.png)\n\n### Enabling mouse emulation\n\nFirst in the \"Custom Defined Behaviors\" section of your layout scroll to the\nline that has `#define ENABLE_MOUSE_KEYS` and uncomment the line by removing the\n`//` characters at the beginning of the line.\n\nNext, in the \"Advanced Configuration\" tab towards the bottom of the page,\nenable the `HID_POINTING` setting by ticking the \"Overriden\" checkbox and\nthen the \"y\" radio button.\n\n#### Choose a firmware that supports mouse emulation\n\nThe default firmware (25.0.1) now supports mouse emulation, but if you still\nwant to verify that you're using a firmware that supports mouse emulation then\nbefore building the firmware (step 5 above), change the firmware version to\n25.0.1 or newer under the \"Settings\" tab, and then go back to the \"Edit\" tab.\n\n![beta firmware](README/settings.png)\n\nAlternatively, you might use the newer PR36 beta firmware for this too:\nselect \"community.pr36.mouse-keys\" from the drop-down menu located at\nGlove80 Layout Editor \u003e Settings \u003e Advanced Settings \u003e Firmware Version.\n\nNow proceed to build and flash your keymap.\n\n### Enabling per-key RGB lighting\n\nBefore building the firmware (step 5 above), change the version to PR36:\nopen the \"Settings\" tab, choose PR36, and then go back to the \"Edit\" tab.\n\n![beta firmware](README/settings.png)\n\nNext, in the \"Advanced Configuration\" tab towards the bottom of the page,\nenable the `EXPERIMENTAL_RGB_LAYER` experimental setting by ticking the\n\"Overriden\" checkbox and the \"y\" radio button.  Finally, after flashing\nthe firmware, turn on the RGB lighting and cycle past the rainbow effect.\n\n### Flashing\n\n- For the initial flash, see [\"Loading new ZMK firmware onto your Glove80\"](\nhttps://docs.moergo.com/glove80-user-guide/customizing-key-layout/#loading-new-zmk-firmware-onto-your-glove80\n) and use the [\"Entering bootloader mass storage device mode on power-up\"](\nhttps://docs.moergo.com/glove80-user-guide/customizing-key-layout/#entering-bootloader-mass-storage-device-mode-on-power-up\n) fail-safe on both halves.  Subsequent flashes can target just the left half.\n\n- If you're installing a different firmware version compared to what your\nkeyboard currently has, then ⚠️ **after flashing both halves** ⚠️ perform a\n[\"Configuration Factory Reset and re-pair left \u0026 right halves procedure\"](\nhttps://docs.moergo.com/glove80-user-guide/troubleshooting/#configuration-factory-reset-and-re-pairing-left-and-right-halves\n) on both halves and then turn RGB effects on, watch them illuminate, and\nfinally turn them back off for the newly installed firmware to take effect.\n\n## Upgrading\n\n- Copy the ZMK snippet from the \"Custom Defined Behaviors\" text box in either\nkeymap linked above and paste into yours.  The contents of that text box are\nalso available in the `*.dtsi` files provided in this Git repository.\n\n- You can diff and copy changes between a JSON export of your keymap (via\n\"Advanced Settings\" \u003e \"Enable local config\" then go back to \"Edit\" and click\n\"Download\") and the `*.json` files provided in this Git repository.\n\n## Customizing\n\n### Overriding the defaults\n\nYou can override the various `#define` settings that govern this keymap by\nadding them above the snippet in the \"Custom Defined Behaviors\" text box:\n\n```h\n// add your overrides here, up at the very top:\n#define OPERATING_SYSTEM 'W' // windows\n#define EMOJI_HAIR_STYLE_PRESET 'C' // curly_hair\n\n// ... rest of snippet goes here, unchanged ...\n```\n\nFor your reference, the following diagram shows the default values for all\nsettings and how they inherit from each other, so you can override them\ntogether as a group (by inheritance) or each individually (fine-grained).\nAlso see the `define.json` file for a convenient listing of the _effective_\ndefault values, taken after all inheritance and C pre-processor expansions.\n\n![Default values and inheritance for all `#define` settings](define.svg)\n\n#### Reordering home row mods\n\nThe `*_FINGER_MOD` settings specify which modifiers are used by home row mod\nkeys. Miryoku's \"GACS\" (Win, Alt, Ctrl, Shift) order is the default -- unless\nyou set `OPERATING_SYSTEM` to macOS, in which case Win and Ctrl are swapped.\n\n```h\n#define PINKY_FINGER_MOD LGUI\n#define RINGY_FINGER_MOD LALT\n#define MIDDY_FINGER_MOD LCTL\n#define INDEX_FINGER_MOD LSFT\n```\n\nThe above settings mirror finger-mod assignments across both hands, but you can\nalso make them different through the following additional settings if you want:\n\n```h\n#define  LEFT_PINKY_MOD RALT\n#define RIGHT_PINKY_MOD LCTL\n```\n\nFor completeness, here are all finger-mod settings available for customization:\n\n```h\n#define  LEFT_PINKY_MOD ...\n#define RIGHT_PINKY_MOD ...\n#define  LEFT_RINGY_MOD ...\n#define RIGHT_RINGY_MOD ...\n#define  LEFT_MIDDY_MOD ...\n#define RIGHT_MIDDY_MOD ...\n#define  LEFT_INDEX_MOD ...\n#define RIGHT_INDEX_MOD ...\n```\n\n#### Fine-tuning the timing\n\nActivate the typing layer, launch the [QMK Configurator's testing tool](\nhttps://config.qmk.fm/#/test ), and then pretend to use home row mods. Note the\ntiming and duration of keystrokes reported by the tool and then use them to\nadjust the `#define` time thresholds in the \"Custom Defined Behaviors\" snippet.\n\n### Compiling from source\n\n\u003e**NOTE:** If you're on Windows, try using [Ubuntu in WSL] for the following.\n\n1. Clone or download a copy of this Git repository (if you haven't already).\n\n2. Install dependencies OR skip this step if you have Docker on your system:\n\n   ```sh\n   add-apt-repository universe \u0026\u0026 apt update # may be needed if using Ubuntu \n   apt install rake graphviz graphicsmagick poppler-utils\n   ```\n\n3. In your copy of this repository, run `rake` OR `./rake` if using Docker.\n\n[Ubuntu in WSL]: https://ubuntu.com/desktop/wsl\n\n#### World and Emoji characters\n\nYou can customize the predefined characters in the Emoji and World layers by\nediting their respective YAML source files in this repository.  Afterwards,\nrun the `rake` command and then copy the new `keymap.dtsi` contents back into\nthe \"Custom Defined Behaviors\" text box in the Layout Editor for your keymap.\n\n##### Adding a new World character\n\nSuppose you wanted to add a key for the copyright sign © character in your keymap.\n\nFirst, open the `world.yaml` file and add a new entry under the `codepoints` section:\n\n```yaml\n#\n# codepoints:\n#   \u003cname\u003e: \"\u003cstring_of_unicode_characters\u003e\"\n#\ncodepoints:\n  copyright_sign: \"️©\"\n```\n\nNote that you can directly paste Unicode characters into the file, as illustrated above!\n\nNext, [compile from source](#compiling-from-source) to generate the `\u0026world_copyright_sign` behavior for ZMK:\n\n```h\nUNICODE(world_copyright_sign_macro, /* ️© */\n  #if OPERATING_SYSTEM == 'L'\n    UNICODE_SEQ_LINUX(\u0026kp F \u0026kp E \u0026kp N0 \u0026kp F), \u003c\u0026macro_wait_time UNICODE_SEQ_DELAY\u003e, UNICODE_SEQ_LINUX(\u0026kp A \u0026kp N9)\n  #elif OPERATING_SYSTEM == 'M'\n    UNICODE_SEQ_MACOS(\u0026kp F \u0026kp E \u0026kp N0 \u0026kp F), \u003c\u0026macro_wait_time UNICODE_SEQ_DELAY\u003e, UNICODE_SEQ_MACOS(\u0026kp N0 \u0026kp N0 \u0026kp A \u0026kp N9)\n  #elif OPERATING_SYSTEM == 'W'\n    UNICODE_SEQ_WINDOWS(\u0026kp N0 \u0026kp F \u0026kp E \u0026kp N0 \u0026kp F), \u003c\u0026macro_wait_time UNICODE_SEQ_DELAY\u003e, UNICODE_SEQ_WINDOWS(\u0026kp N0 \u0026kp A \u0026kp N9)\n  #endif\n)\nworld_copyright_sign: world_copyright_sign {\n  compatible = \"zmk,behavior-mod-morph\";\n  #binding-cells = \u003c0\u003e;\n  bindings = \u003c\u0026world_copyright_sign_macro\u003e, \u003c\u0026world_copyright_sign_macro\u003e;\n  mods = \u003c(~(\n    #ifdef WORLD_USE_COMPOSE_FOR_world_copyright_sign\n      COMPOSE_MORPH_MODS\n    #else\n      UNICODE_MORPH_MODS\n    #endif\n  ))\u003e;\n};\n```\n\nFinally, assign `\u0026world_copyright_sign` to a \"Custom\" key in the Glove80 Layout Editor.\n\n##### Shift key for World characters\n\nSuppose you wanted a World character that changed when you press the shift key, like lowercase and uppercase letters in English.  For example, consider the copyright sign © character from the previous section: let's change it into a registered sign ® character when typed with the shift key.\n\nFirst, open the `world.yaml` file and add a new entry under the `characters` section:\n\n```yaml\n#\n# characters:\n#   \u003cgroup\u003e:\n#     \u003cname\u003e: { \u003cwithout_shift\u003e, \u003cwith_shift\u003e }\n#\ncharacters:\n  sign:\n    copyright: { regular: \"©\", shifted: \"®\" }\n```\n\nNote that you can directly paste Unicode characters into the file, as illustrated above!\n\nNext, [compile from source](#compiling-from-source) to generate the `\u0026world_sign_copyright` behavior for ZMK:\n* The `\u0026world_sign_copyright_regular` behavior will type the regular character: ©\n* The `\u0026world_sign_copyright_shifted` behavior will type the shifted character: ®\n* The `\u0026world_sign_copyright` behavior will choose one of the above based on shift\n\n```h\nUNICODE(world_sign_copyright_regular_macro, /* © */\n  #if OPERATING_SYSTEM == 'L'\n    UNICODE_SEQ_LINUX(\u0026kp A \u0026kp N9)\n  #elif OPERATING_SYSTEM == 'M'\n    UNICODE_SEQ_MACOS(\u0026kp N0 \u0026kp N0 \u0026kp A \u0026kp N9)\n  #elif OPERATING_SYSTEM == 'W'\n    UNICODE_SEQ_WINDOWS(\u0026kp N0 \u0026kp A \u0026kp N9)\n  #endif\n)\nworld_sign_copyright_regular: world_sign_copyright_regular {\n  compatible = \"zmk,behavior-mod-morph\";\n  #binding-cells = \u003c0\u003e;\n  bindings = \u003c\u0026world_sign_copyright_regular_macro\u003e, \u003c\u0026world_sign_copyright_regular_macro\u003e;\n  mods = \u003c(~(\n    #ifdef WORLD_USE_COMPOSE_FOR_world_sign_copyright_regular\n      COMPOSE_MORPH_MODS\n    #else\n      UNICODE_MORPH_MODS\n    #endif\n  ))\u003e;\n};\nUNICODE(world_sign_copyright_shifted_macro, /* ® */\n  #if OPERATING_SYSTEM == 'L'\n    UNICODE_SEQ_LINUX(\u0026kp A \u0026kp E)\n  #elif OPERATING_SYSTEM == 'M'\n    UNICODE_SEQ_MACOS(\u0026kp N0 \u0026kp N0 \u0026kp A \u0026kp E)\n  #elif OPERATING_SYSTEM == 'W'\n    UNICODE_SEQ_WINDOWS(\u0026kp N0 \u0026kp A \u0026kp E)\n  #endif\n)\nworld_sign_copyright_shifted: world_sign_copyright_shifted {\n    compatible = \"zmk,behavior-mod-morph\";\n    #binding-cells = \u003c0\u003e;\n    bindings = \u003c\u0026world_sign_copyright_shifted_macro\u003e, \u003c\u0026world_sign_copyright_shifted_macro\u003e;\n    mods = \u003c(~(\n    #ifdef WORLD_USE_COMPOSE_FOR_world_sign_copyright_shifted\n      COMPOSE_MORPH_MODS\n    #else\n      UNICODE_MORPH_MODS\n    #endif\n  ))\u003e;\n};\nworld_sign_copyright: world_sign_copyright {\n  compatible = \"zmk,behavior-mod-morph\";\n  #binding-cells = \u003c0\u003e;\n  bindings = \u003c\u0026world_sign_copyright_regular\u003e, \u003c\u0026world_sign_copyright_shifted\u003e;\n  mods = \u003cMOD_LSFT\u003e;\n};\n```\n\nFinally, assign `\u0026world_sign_copyright` to a \"Custom\" key in the Glove80 Layout Editor.\n\n##### Modifiers for World characters\n\nSuppose you wanted to enhance the copyright/registered World character from the previous section so that it changes when you press the control key.  For example, let's change it into a trademark sign ™ character when typed with the control key, and into a service mark sign ℠ character when typed with the control and shift keys together.\n\nFirst, open the `world.yaml` file and add a new entry under the `characters` section:\n\n```yaml\n#\n# characters:\n#   \u003cgroup\u003e:\n#     \u003cname\u003e: { \u003cwithout_shift\u003e, \u003cwith_shift\u003e }\n#\ncharacters:\n  sign:\n    copyright: { regular: \"©\", shifted: \"®\" }\n    trademark: { regular: \"™\", shifted: \"℠\" }\n```\n\nNote that you can directly paste Unicode characters into the file, as illustrated above!\n\nNext, add a new entry under the `transforms` section to specify what goes with control:\n\n```yaml\n#\n# transforms:\n#   \u003cgroup\u003e:\n#     base: \u003cname\u003e\n#     \u003cmodifier\u003e: \u003cname\u003e\n#\n# Where \u003cmodifier\u003e is either LALT, RALT, LCTL, RCTL, or RSFT.\n#\ntransforms:\n  sign:\n    base: copyright\n    LCTL: trademark\n```\n\nNext, [compile from source](#compiling-from-source) to generate the `\u0026world_sign_trademark` behavior for ZMK:\n* The `\u0026world_sign_trademark_regular` behavior will type the regular character: ™\n* The `\u0026world_sign_trademark_shifted` behavior will type the shifted character: ℠\n* The `\u0026world_sign_trademark` behavior will choose one of the above based on shift\n\n```h\nUNICODE(world_sign_trademark_regular_macro, /* ™ */\n  #if OPERATING_SYSTEM == 'L'\n    UNICODE_SEQ_LINUX(\u0026kp N2 \u0026kp N1 \u0026kp N2 \u0026kp N2)\n  #elif OPERATING_SYSTEM == 'M'\n    UNICODE_SEQ_MACOS(\u0026kp N2 \u0026kp N1 \u0026kp N2 \u0026kp N2)\n  #elif OPERATING_SYSTEM == 'W'\n    UNICODE_SEQ_WINDOWS(\u0026kp N0 \u0026kp N2 \u0026kp N1 \u0026kp N2 \u0026kp N2)\n  #endif\n)\nworld_sign_trademark_regular: world_sign_trademark_regular {\n  compatible = \"zmk,behavior-mod-morph\";\n  #binding-cells = \u003c0\u003e;\n  bindings = \u003c\u0026world_sign_trademark_regular_macro\u003e, \u003c\u0026world_sign_trademark_regular_macro\u003e;\n  mods = \u003c(~(\n    #ifdef WORLD_USE_COMPOSE_FOR_world_sign_trademark_regular\n      COMPOSE_MORPH_MODS\n    #else\n      UNICODE_MORPH_MODS\n    #endif\n  ))\u003e;\n};\nUNICODE(world_sign_trademark_shifted_macro, /* ℠ */\n  #if OPERATING_SYSTEM == 'L'\n    UNICODE_SEQ_LINUX(\u0026kp N2 \u0026kp N1 \u0026kp N2 \u0026kp N0)\n  #elif OPERATING_SYSTEM == 'M'\n    UNICODE_SEQ_MACOS(\u0026kp N2 \u0026kp N1 \u0026kp N2 \u0026kp N0)\n  #elif OPERATING_SYSTEM == 'W'\n    UNICODE_SEQ_WINDOWS(\u0026kp N0 \u0026kp N2 \u0026kp N1 \u0026kp N2 \u0026kp N0)\n  #endif\n)\nworld_sign_trademark_shifted: world_sign_trademark_shifted {\n  compatible = \"zmk,behavior-mod-morph\";\n  #binding-cells = \u003c0\u003e;\n  bindings = \u003c\u0026world_sign_trademark_shifted_macro\u003e, \u003c\u0026world_sign_trademark_shifted_macro\u003e;\n  mods = \u003c(~(\n    #ifdef WORLD_USE_COMPOSE_FOR_world_sign_trademark_shifted\n      COMPOSE_MORPH_MODS\n    #else\n      UNICODE_MORPH_MODS\n    #endif\n  ))\u003e;\n};\nworld_sign_trademark: world_sign_trademark {\n  compatible = \"zmk,behavior-mod-morph\";\n  #binding-cells = \u003c0\u003e;\n  bindings = \u003c\u0026world_sign_trademark_regular\u003e, \u003c\u0026world_sign_trademark_shifted\u003e;\n  mods = \u003cMOD_LSFT\u003e;\n};\n```\n\nAlso, notice the new `\u0026world_sign_base` behavior that chooses between the other two:\n* The `\u0026world_sign_copyright` behavior will type the copyright/registered sign\n* The `\u0026world_sign_trademark` behavior will type the trade/service mark sign\n* The `\u0026world_sign_base` behavior will choose one of the above based on control\n\n```h\nworld_sign_base: world_sign_base {\n  compatible = \"zmk,behavior-mod-morph\";\n  #binding-cells = \u003c0\u003e;\n  bindings = \u003c\u0026world_sign_copyright\u003e, \u003c\u0026world_sign_trademark\u003e;\n  mods = \u003c(MOD_LCTL)\u003e;\n};\n```\n\nFinally, assign `\u0026world_sign_base` to a \"Custom\" key in the Glove80 Layout Editor.\n\n##### Compose for World characters\n\nSuppose you wanted the copyright sign © character from the previous section to\nbe typed using your operating system's native Compose key rather than Unicode.\n\nFirst, open the `world.yaml` file and add a new entry in the `compositions` section:\n\n```yaml\n#\n# compositions:\n#   \u003ccharacter\u003e:\n#     linux:   \u003ckeystrokes\u003e\n#     macos:   \u003ckeystrokes\u003e\n#     windows: \u003ckeystrokes\u003e\n#\n# Where \u003ckeystrokes\u003e is composed of ZMK keycodes with some specialities:\n# - \"COMPOSE\" is a special keyword that is replaced by COMPOSE_KEY_LINUX\n# - \"ALT+\" is a special prefix that is replaced by COMPOSE_SEQ_WINDOWS()\n#\n# For reference on Compose key shortcuts and the characters they produce:\n# - linux:   https://wiki.linuxquestions.org/wiki/Accented_Characters\n# - macos:   https://sites.psu.edu/symbolcodes/mac/codemac/\n# - windows: https://sites.psu.edu/symbolcodes/windows/codealt/\n#\ncompositions:\n  \"©\":\n    linux:   COMPOSE O C\n    macos:   LA(G)\n    windows: ALT+0169\n```\n\nNote that you can directly paste Unicode characters into the file, as illustrated above!\n\nNext, [compile from source](#compiling-from-source) to regenerate the `\u0026world_sign*macro` behaviors for ZMK:\n\n```h\nUNICODE(world_sign_copyright_regular_macro, /* © */\n  #if OPERATING_SYSTEM == 'L'\n    #ifdef WORLD_USE_COMPOSE\n    #define WORLD_USE_COMPOSE_FOR_world_sign_copyright_regular\n    COMPOSE_SEQ_LINUX(\u0026kp O \u0026kp C)\n    #else\n    UNICODE_SEQ_LINUX(\u0026kp A \u0026kp N9)\n    #endif\n  #elif OPERATING_SYSTEM == 'M'\n    #ifdef WORLD_USE_COMPOSE\n    #define WORLD_USE_COMPOSE_FOR_world_sign_copyright_regular\n    COMPOSE_SEQ_MACOS(\u0026kp LA(G))\n    #else\n    UNICODE_SEQ_MACOS(\u0026kp N0 \u0026kp N0 \u0026kp A \u0026kp N9)\n    #endif\n  #elif OPERATING_SYSTEM == 'W'\n    #ifdef WORLD_USE_COMPOSE\n    #define WORLD_USE_COMPOSE_FOR_world_sign_copyright_regular\n    COMPOSE_SEQ_WINDOWS(\u0026kp KP_N0 \u0026kp KP_N1 \u0026kp KP_N6 \u0026kp KP_N9)\n    #else\n    UNICODE_SEQ_WINDOWS(\u0026kp N0 \u0026kp A \u0026kp N9)\n    #endif\n  #endif\n)\n```\n\nNotice how Compose key shortcuts will be used when `WORLD_USE_COMPOSE` is enabled.\n\n##### Adding a new Emoji character\n\nSuppose you wanted to add a key for the \"unamused face\" 😒 emoji in your keymap.\n\nFirst, open the `emoji.yaml` file and add a new entry under the `codepoints` section:\n\n```yaml\n#\n# codepoints:\n#   \u003cname\u003e: \"\u003cstring_of_unicode_characters\u003e\"\n#\ncodepoints:\n  unamused_face: \"️😒\"\n```\n\nNote that you can directly paste an Emoji character into the file, as illustrated above!\n\nNext, [compile from source](#compiling-from-source) to generate the `\u0026emoji_unamused_face` behavior for ZMK:\n\n```h\nUNICODE(emoji_unamused_face_macro, /* ️😒 */\n  #if OPERATING_SYSTEM == 'L'\n    UNICODE_SEQ_LINUX(\u0026kp F \u0026kp E \u0026kp N0 \u0026kp F), \u003c\u0026macro_wait_time UNICODE_SEQ_DELAY\u003e, UNICODE_SEQ_LINUX(\u0026kp N1 \u0026kp F \u0026kp N6 \u0026kp N1 \u0026kp N2)\n  #elif OPERATING_SYSTEM == 'M'\n    UNICODE_SEQ_MACOS(\u0026kp F \u0026kp E \u0026kp N0 \u0026kp F), \u003c\u0026macro_wait_time UNICODE_SEQ_DELAY\u003e, UNICODE_SEQ_MACOS(\u0026kp D \u0026kp N8 \u0026kp N3 \u0026kp D \u0026kp D \u0026kp E \u0026kp N1 \u0026kp N2)\n  #elif OPERATING_SYSTEM == 'W'\n    UNICODE_SEQ_WINDOWS(\u0026kp N0 \u0026kp F \u0026kp E \u0026kp N0 \u0026kp F), \u003c\u0026macro_wait_time UNICODE_SEQ_DELAY\u003e, UNICODE_SEQ_WINDOWS(\u0026kp N0 \u0026kp N1 \u0026kp F \u0026kp N6 \u0026kp N1 \u0026kp N2)\n  #endif\n)\nemoji_unamused_face: emoji_unamused_face {\n  compatible = \"zmk,behavior-mod-morph\";\n  #binding-cells = \u003c0\u003e;\n  bindings = \u003c\u0026emoji_unamused_face_macro\u003e, \u003c\u0026emoji_unamused_face_macro\u003e;\n  mods = \u003c(~(\n    #ifdef WORLD_USE_COMPOSE_FOR_emoji_unamused_face\n      COMPOSE_MORPH_MODS\n    #else\n      UNICODE_MORPH_MODS\n    #endif\n  ))\u003e;\n};\n```\n\nFinally, assign `\u0026emoji_unamused_face` to a \"Custom\" key in the Glove80 Layout Editor.\n\n##### Shift key for Emoji characters\n\nSuppose you wanted an Emoji character that changed when you press the shift key, like lowercase and uppercase letters in English.  For example, consider the \"unamused face\" 😒 emoji from the previous section: let's change it into a \"face with rolling eyes\" 🙄 emoji when typed with the shift key.\n\nFirst, open the `emoji.yaml` file and add a new entry under the `characters` section:\n\n```yaml\n#\n# characters:\n#   \u003cgroup\u003e:\n#     \u003cname\u003e: { \u003cwithout_shift\u003e, \u003cwith_shift\u003e }\n#\ncharacters:\n  face:\n    unamused: { regular: \"😒\", shifted: \"🙄\" }\n```\n\nNote that you can directly paste Emoji characters into the file, as illustrated above!\n\nNext, [compile from source](#compiling-from-source) to generate the `\u0026emoji_face_unamused` behavior for ZMK:\n* The `\u0026emoji_face_unamused_regular` behavior will type the regular character: 😒\n* The `\u0026emoji_face_unamused_shifted` behavior will type the shifted character: 🙄\n* The `\u0026emoji_face_unamused` behavior will choose one of the above based on shift\n\n```h\nUNICODE(emoji_face_unamused_regular_macro, /* 😒 */\n  #if OPERATING_SYSTEM == 'L'\n    UNICODE_SEQ_LINUX(\u0026kp N1 \u0026kp F \u0026kp N6 \u0026kp N1 \u0026kp N2)\n  #elif OPERATING_SYSTEM == 'M'\n    UNICODE_SEQ_MACOS(\u0026kp D \u0026kp N8 \u0026kp N3 \u0026kp D \u0026kp D \u0026kp E \u0026kp N1 \u0026kp N2)\n  #elif OPERATING_SYSTEM == 'W'\n    UNICODE_SEQ_WINDOWS(\u0026kp N0 \u0026kp N1 \u0026kp F \u0026kp N6 \u0026kp N1 \u0026kp N2)\n  #endif\n)\nemoji_face_unamused_regular: emoji_face_unamused_regular {\n  compatible = \"zmk,behavior-mod-morph\";\n  #binding-cells = \u003c0\u003e;\n  bindings = \u003c\u0026emoji_face_unamused_regular_macro\u003e, \u003c\u0026emoji_face_unamused_regular_macro\u003e;\n  mods = \u003c(~(\n    #ifdef WORLD_USE_COMPOSE_FOR_emoji_face_unamused_regular\n      COMPOSE_MORPH_MODS\n    #else\n      UNICODE_MORPH_MODS\n    #endif\n  ))\u003e;\n};\nUNICODE(emoji_face_unamused_shifted_macro, /* 🙄 */\n  #if OPERATING_SYSTEM == 'L'\n    UNICODE_SEQ_LINUX(\u0026kp N1 \u0026kp F \u0026kp N6 \u0026kp N4 \u0026kp N4)\n  #elif OPERATING_SYSTEM == 'M'\n    UNICODE_SEQ_MACOS(\u0026kp D \u0026kp N8 \u0026kp N3 \u0026kp D \u0026kp D \u0026kp E \u0026kp N4 \u0026kp N4)\n  #elif OPERATING_SYSTEM == 'W'\n    UNICODE_SEQ_WINDOWS(\u0026kp N0 \u0026kp N1 \u0026kp F \u0026kp N6 \u0026kp N4 \u0026kp N4)\n  #endif\n)\nemoji_face_unamused_shifted: emoji_face_unamused_shifted {\n  compatible = \"zmk,behavior-mod-morph\";\n  #binding-cells = \u003c0\u003e;\n  bindings = \u003c\u0026emoji_face_unamused_shifted_macro\u003e, \u003c\u0026emoji_face_unamused_shifted_macro\u003e;\n  mods = \u003c(~(\n    #ifdef WORLD_USE_COMPOSE_FOR_emoji_face_unamused_shifted\n      COMPOSE_MORPH_MODS\n    #else\n      UNICODE_MORPH_MODS\n    #endif\n  ))\u003e;\n};\nemoji_face_unamused: emoji_face_unamused {\n  compatible = \"zmk,behavior-mod-morph\";\n  #binding-cells = \u003c0\u003e;\n  bindings = \u003c\u0026emoji_face_unamused_regular\u003e, \u003c\u0026emoji_face_unamused_shifted\u003e;\n  mods = \u003cMOD_LSFT\u003e;\n};\n```\n\nFinally, assign `\u0026emoji_face_unamused` to a \"Custom\" key in the Glove80 Layout Editor.\n\n#### Editing layer map diagrams\n\nThe `README/` directory in this repository contains sources and renderings of\nlayer map diagrams for all layers in this keymap, as well as a blank template\nfor your own customization: for example, if you use a different alpha layout.\n\nTo edit a diagram, upload its corresponding JSON file into [the KLE app][KLE]\nby drag/drop onto the canvas or clicking \"Upload JSON\" in the \"Raw data\" tab.\n\n[KLE]: https://www.keyboard-layout-editor.com\n\nTo render a layer diagram, use [the \"Screenshot node\" feature in Firefox][FFS]\non the `#keyboard-bg` element; or use your favorite screenshot capturing tool.\n\n[FFS]: https://youtu.be/p2pjF_BrE1o\n\nTo assemble a PDF document with all rendered layer diagrams, run `rake pdf` to\nconvert each of them into PDF documents and then stitch them together into one.\n\n#### Rearranging the base layer\n\nIf you rearrange the base layer (say, for a custom or alternative layout) then:\n\n1. Export your keymap as a JSON file (via \"Advanced Settings\" \u003e \"Enable local\n   config\" then go back to \"Edit\" and click \"Download\") in the Layout Editor.\n   ![Enable local config](https://github.com/sunaku/glove80-keymaps/assets/9863/5bf7ff67-94bc-4d8e-9673-271863966dd2)\n   ![Download JSON export](https://github.com/sunaku/glove80-keymaps/assets/9863/a7ad7155-e0e6-47e1-ad4c-c89b4d8521b9)\n\n2. Overwrite the `keymap.json` file in this repository with your exported file.\n\n3. Run the `rake` command in this repository.\n\n4. Copy the new `keymap.dtsi` contents back into the \"Custom Defined Behaviors\"\n   text box in the Layout Editor for your keymap.\n\nYou don't need to change the per-finger layers (such as \"LeftPinky\") manually.\n\n##### Mirroring horizontally\n\nTo horizontally mirror a keymap's physical layout in the Glove80 Layout Editor:\n\n1. Activate the \"Enable local config\" option in the Glove80 Layout Editor's settings panel under the \"Experimental Settings\" section.\n1. Return to the editor and export your keymap to a JSON file by clicking on the \"Download\" button.\n2. Paste the contents of the exported JSON file into your Web browser's JavaScript console (found in the \"Developer Tools\" panel, typically activated by pressing Ctrl+F12) at the location indicated by the comment in the first line of the following code snippet.\n6. Right-click the result, copy to clipboard, save to file, and upload into the Glove80 Layout Editor.\n7. Presto! 🫰 Everything should be mirrored now.\n\n```javascript\nlayout = /* paste contents of exported JSON file here */;\nmirroring_transformation = {\n//\n// |------------------------|------------------------|\n// | LEFT_HAND_KEYS         |        RIGHT_HAND_KEYS |\n// |                        |                        |\n// |  0  1  2  3  4         |          5  6  7  8  9 |\n// | 10 11 12 13 14 15      |      16 17 18 19 20 21 |\n// | 22 23 24 25 26 27      |      28 29 30 31 32 33 |\n// | 34 35 36 37 38 39      |      40 41 42 43 44 45 |\n// | 46 47 48 49 50 51      |      58 59 60 61 62 63 |\n// | 64 65 66 67 68         |         75 76 77 78 79 |\n// |                69 52   |   57 74                |\n// |                 70 53  |  56 73                 |\n// |                  71 54 | 55 72                  |\n// |------------------------|------------------------|\n// | LEFT_HAND_MIRRORED     |    RIGHT_HAND_MIRRORED |\n// |                        |                        |\n// |  9  8  7  6  5         |          4  3  2  1  0 |\n// | 21 20 19 18 17 16      |      15 14 13 12 11 10 |\n// | 33 32 31 30 29 28      |      27 26 25 24 23 22 |\n// | 45 44 43 42 41 40      |      39 38 37 36 35 34 |\n// | 63 62 61 60 59 58      |      51 50 49 48 47 46 |\n// | 79 78 77 76 75         |         68 67 66 65 64 |\n// |                74 57   |   52 69                |\n// |                 73 56  |  53 70                 |\n// |                  72 55 | 54 71                  |\n// |------------------------|------------------------|\n//\n   0: 9,  1: 8,  2: 7,  3: 6,  4: 5,                              5: 4,  6: 3,  7: 2,  8: 1,  9: 0,\n  10:21, 11:20, 12:19, 13:18, 14:17, 15:16,               16:15, 17:14, 18:13, 19:12, 20:11, 21:10,\n  22:33, 23:32, 24:31, 25:30, 26:29, 27:28,               28:27, 29:26, 30:25, 31:24, 32:23, 33:22,\n  34:45, 35:44, 36:43, 37:42, 38:41, 39:40,               40:39, 41:38, 42:37, 43:36, 44:35, 45:34,\n  46:63, 47:62, 48:61, 49:60, 50:59, 51:58,               58:51, 59:50, 60:49, 61:48, 62:47, 63:46,\n  64:79, 65:78, 66:77, 67:76, 68:75,                             75:68, 76:67, 77:66, 78:65, 79:64,\n                                     69:74, 52:57, 57:52, 74:69,\n                                     70:73, 53:56, 56:53, 73:70,\n                                     71:72, 54:55, 55:54, 72:71,\n};\nmirrored_layers = layout[\"layers\"].map((layer) =\u003e {\n  return layer.map((key,pos) =\u003e {\n    return layer[mirroring_transformation[pos]];\n  });\n});\nmirrored_layout = Object.assign({}, layout);\nmirrored_layout[\"layers\"] = mirrored_layers;\nmirrored_layout; /* dumps to the console for copying */\n```\n\n## Discussion\n\nJoin the [`#glorious-engrammer`][ch] channel on [MoErgo's discord server][sv].\n\n[ch]: https://discord.com/channels/877392805654306816/1111469812850380831\n[sv]: https://www.moergo.com/discord\n\n## License\n\n[Spare A Life]: https://sunaku.github.io/vegan-for-life.html\n\u003e Like my work? 👍 Please [spare a life] today as thanks! 🐄🐖🐑🐔🐣🐟✨🙊✌  \n\u003e Why? For 💕 ethics, the 🌎 environment, and 💪 health; see link above. 🙇\n\n(the ISC license)\n\nCopyright 2023 Suraj N. Kurapati \u003chttps://github.com/sunaku\u003e\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted, provided that the above\ncopyright notice and this permission notice appear in all copies.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\nWITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\nANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\nWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\nACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\nOR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsunaku%2Fglove80-keymaps","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsunaku%2Fglove80-keymaps","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsunaku%2Fglove80-keymaps/lists"}