From 17a3dbc1591b6cdd96076b94a9d3648c19f7e2ab Mon Sep 17 00:00:00 2001 From: Olivier Date: Sun, 3 Jul 2016 14:38:03 +0200 Subject: [PATCH 01/37] Integrate mouse keys into function layer, delete mouse layer. --- keyboards/ergodox_ez/keymaps/bepo/keymap.c | 64 +++++----------------- 1 file changed, 13 insertions(+), 51 deletions(-) diff --git a/keyboards/ergodox_ez/keymaps/bepo/keymap.c b/keyboards/ergodox_ez/keymaps/bepo/keymap.c index 921a94d63a..5c127ab78e 100644 --- a/keyboards/ergodox_ez/keymaps/bepo/keymap.c +++ b/keyboards/ergodox_ez/keymaps/bepo/keymap.c @@ -9,7 +9,6 @@ #define AQWER 3 // alted qwerty compat layer #define FNAV 4 // function / navigation keys #define NUM 5 // numeric keypad keys -#define MSE 6 // mouse keys #define KP_00 0 #define CA_Fx 1 @@ -26,7 +25,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------| * | E_CIRC |A_GRAV| Y | X | . | K | | | | ' | Q | G | H | F | C_CEDIL| * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' - * |QWERTY| |LSuper| LCtrl| LAlt| |Escape| L_Mse| | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause| + * |QWERTY| |LSuper| LCtrl| LAlt| |Escape| | | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause| * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' * | | | L_Num| | CA_Fx| | | * | Space|LShift|------| |------|RShift|Enter | @@ -40,7 +39,7 @@ BP_PERCENT, BP_B, BP_E_ACUTE, BP_P, BP_O, BP_E_GRAVE, KC_BSPC, BP_W, BP_A, BP_U, BP_I, BP_E, BP_COMMA, BP_ECRC, BP_A_GRAVE, BP_Y, BP_X, BP_DOT, BP_K, KC_TAB, TG(QWER), KC_NO, KC_LGUI, KC_LCTL, KC_LALT, - KC_ESC, MO(MSE), + KC_ESC, KC_NO, MO(NUM), KC_SPC, KC_LSHIFT, MO(FNAV), // Right hand @@ -63,7 +62,7 @@ MO(FNAV), KC_RSHIFT, KC_ENTER), * |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------| * | e | a | y | x | . | k | | | | ' | q | g | h | f | c | * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' - * | BEPO | |LSuper| LCtrl| LAlt| |Escape| L_Mse| | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause| + * | BEPO | |LSuper| LCtrl| LAlt| |Escape| | | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause| * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' * | | | L_Num| | | | | * | Space|LShift|------| |------|RShift|Enter | @@ -77,7 +76,7 @@ KC_PERCENT, KC_B, KC_E, KC_P, KC_O, KC_E, KC_BSPC, KC_W, KC_A, KC_U, KC_I, KC_E, KC_COMMA, KC_E, KC_A, KC_Y, KC_X, KC_DOT, KC_K, KC_TAB, KC_TRNS, KC_NO, KC_LGUI, KC_LCTL, KC_LALT, - KC_ESC, MO(MSE), + KC_ESC, KC_NO, MO(NUM), KC_SPC, MO(SQWER), MO(FNAV), // Right hand @@ -100,7 +99,7 @@ MO(FNAV), MO(SQWER), KC_ENTER), * |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------| * | E | A | Y | X | : | K | | | | ? | Q | G | H | F | C | * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' - * | BEPO | |LSuper| LCtrl| LAlt| |Escape| L_Mse| | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause| + * | BEPO | |LSuper| LCtrl| LAlt| |Escape| | | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause| * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' * | | | L_Num| | | | | * | Space|LShift|------| |------|RShift|Enter | @@ -114,7 +113,7 @@ KC_GRV, S(KC_B), S(KC_E), S(KC_P), S(KC_O), S(KC_E), KC_TRNS, S(KC_W), S(KC_A), S(KC_U), S(KC_I), S(KC_E), KC_SCOLON, S(KC_E), S(KC_A), S(KC_Y), S(KC_X), KC_COLON, S(KC_K), S(KC_TAB), KC_TRNS, KC_TRNS, S(KC_LGUI), S(KC_LCTL), S(KC_LALT), - KC_TRNS, KC_TRNS, + KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, // Right hand @@ -137,7 +136,7 @@ KC_TRNS, KC_TRNS, KC_TRNS), * |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------| * | e | \ | { | } | . | ~ | | | | ' | q | g | h | f | c | * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' - * | BEPO | |LSuper| LCtrl| LAlt| |Escape| L_Mse| | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause| + * | BEPO | |LSuper| LCtrl| LAlt| |Escape| | | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause| * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' * | | | L_Num| | | | | * | _ |LShift|------| |------|RShift|Enter | @@ -151,7 +150,7 @@ KC_PERCENT, KC_PIPE, KC_E, KC_AMPR, KC_O, KC_E, KC_BSPC, KC_W, KC_A, KC_U, KC_I, RALT(KC_5), KC_COMMA, KC_E, KC_BSLASH, KC_LCBR, KC_RCBR, KC_DOT, KC_TILDE, KC_TAB, KC_TRNS, KC_NO, KC_LGUI, KC_LCTL, KC_LALT, - KC_ESC, MO(MSE), + KC_ESC, KC_NO, MO(NUM), KC_UNDS, MO(SQWER), MO(FNAV), // Right hand @@ -168,9 +167,9 @@ MO(FNAV), MO(SQWER), KC_ENTER), * ,--------------------------------------------------. ,--------------------------------------------------. * | | F1 | F2 | F3 | F4 | F5 |VolMut| | | F6 | F7 | F8 | F9 | F10 | | * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------| - * | | | | | | |VolDwn| | | PgUp | Home | Up | End | F11 | | + * | | Next |LClick| Up |RClick| WhUp |VolDwn| | | PgUp | Home | Up | End | F11 | | * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------| - * | | | | | | |------| |------| PgDn | Left | Down | Right| F12 | | + * | | Prev | Left | Down | Right|WhDown|------| |------| PgDn | Left | Down | Right| F12 | | * |--------+------+------+------+------+------| VolUp| | |------+------+------+------+------+--------| * | | Undo | Cut | Copy | Paste| | | | | | | | | | | * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' @@ -184,8 +183,8 @@ MO(FNAV), MO(SQWER), KC_ENTER), [FNAV] = KEYMAP( // Left hand KC_NO, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_MUTE, -KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_VOLU, -KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, +KC_NO, KC_MS_BTN5, KC_MS_BTN1, KC_MS_UP, KC_MS_BTN2, KC_MS_WH_UP, KC_VOLU, +KC_NO, KC_MS_BTN4, KC_MS_LEFT, KC_MS_DOWN, KC_MS_RIGHT, KC_MS_WH_DOWN, KC_NO, KC_UNDO, KC_CUT, KC_COPY, KC_PASTE, KC_NO, KC_VOLD, KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_NO, @@ -236,44 +235,7 @@ KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, KC_KP_0, M(KP_00), KC_KP_COMMA, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, -KC_NO, KC_TRNS, KC_KP_ENTER), -/* Keymap 6: mouse layer - * - * ,--------------------------------------------------. ,--------------------------------------------------. - * | | | | | | | | | | | | | | | | - * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------| - * | | | | | | | | | | |LClick| Up |RClick| WhUp | | - * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------| - * | | | | | | |------| |------| | Left | Down | Right|WhDown| | - * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------| - * | | | | | | | | | | | | | | | | - * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' - * | | | | | | | | | | | | | | | | | | - * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' - * | | | | | | | | - * | | |------| |------| | | - * | | | | | | | | - * `--------------------' `--------------------' - */ -[MSE] = KEYMAP( -// Left hand -KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, -KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, -KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, -KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, -KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, - KC_NO, KC_TRNS, - KC_NO, - KC_NO, KC_TRNS, KC_NO, -// Right hand - KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, - KC_NO, KC_NO, KC_MS_BTN1, KC_MS_UP, KC_MS_BTN2, KC_MS_WH_UP, KC_NO, - KC_NO, KC_MS_LEFT, KC_MS_DOWN, KC_MS_RIGHT, KC_MS_WH_DOWN, KC_NO, - KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, - KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_NO, -KC_NO, KC_NO, -KC_NO, -KC_NO, KC_TRNS, KC_NO) +KC_NO, KC_TRNS, KC_KP_ENTER) }; const uint16_t PROGMEM fn_actions[] = { From 9aceaaed4cbdf49c12db85cf3ff40a9e762558a6 Mon Sep 17 00:00:00 2001 From: Olivier Date: Sun, 3 Jul 2016 15:51:55 +0200 Subject: [PATCH 02/37] Replace the "Ctrl+Alt+Fx" macro I was using to switch terminals without moving hands by a numeric layer switch key like on the left half, for consistency. --- keyboards/ergodox_ez/keymaps/bepo/keymap.c | 54 +++++++++------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/keyboards/ergodox_ez/keymaps/bepo/keymap.c b/keyboards/ergodox_ez/keymaps/bepo/keymap.c index 5c127ab78e..dd47357998 100644 --- a/keyboards/ergodox_ez/keymaps/bepo/keymap.c +++ b/keyboards/ergodox_ez/keymaps/bepo/keymap.c @@ -11,7 +11,6 @@ #define NUM 5 // numeric keypad keys #define KP_00 0 -#define CA_Fx 1 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { /* Keymap 0: Base layer @@ -27,7 +26,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' * |QWERTY| |LSuper| LCtrl| LAlt| |Escape| | | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause| * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' - * | | | L_Num| | CA_Fx| | | + * | | | L_Num| | L_Num| | | * | Space|LShift|------| |------|RShift|Enter | * | | |L_FNav| |L_FNav| | | * `--------------------' `--------------------' @@ -39,7 +38,7 @@ BP_PERCENT, BP_B, BP_E_ACUTE, BP_P, BP_O, BP_E_GRAVE, KC_BSPC, BP_W, BP_A, BP_U, BP_I, BP_E, BP_COMMA, BP_ECRC, BP_A_GRAVE, BP_Y, BP_X, BP_DOT, BP_K, KC_TAB, TG(QWER), KC_NO, KC_LGUI, KC_LCTL, KC_LALT, - KC_ESC, KC_NO, + KC_ESC, KC_TRNS, MO(NUM), KC_SPC, KC_LSHIFT, MO(FNAV), // Right hand @@ -48,8 +47,8 @@ TG(QWER), KC_NO, KC_LGUI, KC_LCTL, KC_LALT, BP_C, BP_T, BP_S, BP_R, BP_N, BP_M, KC_NUMLOCK, BP_APOS, BP_Q, BP_G, BP_H, BP_F, BP_CCED, BP_ALGR, KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE, -KC_NO, KC_INS, -M(CA_Fx), +KC_TRNS, KC_INS, +MO(NUM), MO(FNAV), KC_RSHIFT, KC_ENTER), /* Keymap 1: QWERTY system compatibility layer * @@ -64,7 +63,7 @@ MO(FNAV), KC_RSHIFT, KC_ENTER), * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' * | BEPO | |LSuper| LCtrl| LAlt| |Escape| | | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause| * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' - * | | | L_Num| | | | | + * | | | L_Num| | L_Num| | | * | Space|LShift|------| |------|RShift|Enter | * | | |L_FNav| |L_FNav| | | * `--------------------' `--------------------' @@ -76,7 +75,7 @@ KC_PERCENT, KC_B, KC_E, KC_P, KC_O, KC_E, KC_BSPC, KC_W, KC_A, KC_U, KC_I, KC_E, KC_COMMA, KC_E, KC_A, KC_Y, KC_X, KC_DOT, KC_K, KC_TAB, KC_TRNS, KC_NO, KC_LGUI, KC_LCTL, KC_LALT, - KC_ESC, KC_NO, + KC_ESC, KC_TRNS, MO(NUM), KC_SPC, MO(SQWER), MO(FNAV), // Right hand @@ -85,8 +84,8 @@ KC_TRNS, KC_NO, KC_LGUI, KC_LCTL, KC_LALT, KC_C, KC_T, KC_S, KC_R, KC_N, KC_M, KC_NUMLOCK, KC_QUOT, KC_Q, KC_G, KC_H, KC_F, KC_C, MO(AQWER), KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE, -KC_NO, KC_INS, -KC_TRNS, +KC_TRNS, KC_INS, +MO(NUM), MO(FNAV), MO(SQWER), KC_ENTER), /* Keymap 2: QWERTY shifted system compatibility layer * @@ -101,7 +100,7 @@ MO(FNAV), MO(SQWER), KC_ENTER), * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' * | BEPO | |LSuper| LCtrl| LAlt| |Escape| | | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause| * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' - * | | | L_Num| | | | | + * | | | L_Num| | L_Num| | | * | Space|LShift|------| |------|RShift|Enter | * | | |L_FNav| |L_FNav| | | * `--------------------' `--------------------' @@ -113,7 +112,7 @@ KC_GRV, S(KC_B), S(KC_E), S(KC_P), S(KC_O), S(KC_E), KC_TRNS, S(KC_W), S(KC_A), S(KC_U), S(KC_I), S(KC_E), KC_SCOLON, S(KC_E), S(KC_A), S(KC_Y), S(KC_X), KC_COLON, S(KC_K), S(KC_TAB), KC_TRNS, KC_TRNS, S(KC_LGUI), S(KC_LCTL), S(KC_LALT), - KC_TRNS, KC_NO, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, // Right hand @@ -138,7 +137,7 @@ KC_TRNS, KC_TRNS, KC_TRNS), * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' * | BEPO | |LSuper| LCtrl| LAlt| |Escape| | | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause| * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' - * | | | L_Num| | | | | + * | | | L_Num| | L_Num| | | * | _ |LShift|------| |------|RShift|Enter | * | | |L_FNav| |L_FNav| | | * `--------------------' `--------------------' @@ -150,7 +149,7 @@ KC_PERCENT, KC_PIPE, KC_E, KC_AMPR, KC_O, KC_E, KC_BSPC, KC_W, KC_A, KC_U, KC_I, RALT(KC_5), KC_COMMA, KC_E, KC_BSLASH, KC_LCBR, KC_RCBR, KC_DOT, KC_TILDE, KC_TAB, KC_TRNS, KC_NO, KC_LGUI, KC_LCTL, KC_LALT, - KC_ESC, KC_NO, + KC_ESC, KC_TRNS, MO(NUM), KC_UNDS, MO(SQWER), MO(FNAV), // Right hand @@ -159,8 +158,8 @@ KC_TRNS, KC_NO, KC_LGUI, KC_LCTL, KC_LALT, KC_C, KC_T, KC_S, KC_R, KC_N, KC_M, KC_NUMLOCK, KC_QUOT, KC_Q, KC_G, KC_H, KC_F, KC_C, KC_TRNS, KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE, -KC_NO, KC_INS, -KC_TRNS, +KC_TRNS, KC_INS, +MO(NUM), MO(FNAV), MO(SQWER), KC_ENTER), /* Keymap 4: function / navigation layer * @@ -187,8 +186,8 @@ KC_NO, KC_MS_BTN5, KC_MS_BTN1, KC_MS_UP, KC_MS_BTN2, KC_MS_WH_UP, KC_VOLU, KC_NO, KC_MS_BTN4, KC_MS_LEFT, KC_MS_DOWN, KC_MS_RIGHT, KC_MS_WH_DOWN, KC_NO, KC_UNDO, KC_CUT, KC_COPY, KC_PASTE, KC_NO, KC_VOLD, KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, - KC_NO, KC_NO, - KC_NO, + KC_TRNS, KC_TRNS, + KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, // Right hand KC_NO, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_NO, @@ -196,7 +195,7 @@ KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, KC_PGDOWN, KC_LEFT, KC_DOWN, KC_RIGHT, KC_F12, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_NO, -KC_NO, KC_NO, +KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO), /* Keymap 5: numeric layer, sends keypad codes @@ -224,18 +223,18 @@ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, - KC_NO, KC_NO, + KC_TRNS, KC_TRNS, KC_TRNS, - KC_NO, KC_TRNS, KC_NO, + KC_NO, KC_TRNS, KC_TRNS, // Right hand KC_NO, KC_NO, KC_KP_PLUS, KC_KP_MINUS, KC_KP_SLASH, KC_KP_ASTERISK, KC_NO, KC_NO, KC_NO, KC_KP_7, KC_KP_8, KC_KP_9, KC_NO, KC_NO, KC_NO, KC_KP_4, KC_KP_5, KC_KP_6, KC_NO, KC_NO, KC_NO, KC_NO, KC_KP_1, KC_KP_2, KC_KP_3, KC_NO, KC_NO, KC_KP_0, M(KP_00), KC_KP_COMMA, KC_NO, KC_NO, -KC_NO, KC_NO, -KC_NO, -KC_NO, KC_TRNS, KC_KP_ENTER) +KC_TRNS, KC_TRNS, +KC_TRNS, +KC_TRNS, KC_TRNS, KC_KP_ENTER) }; const uint16_t PROGMEM fn_actions[] = { @@ -251,15 +250,6 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) return MACRO( U(KP_0), END ); } break; - case CA_Fx: - if (record->event.pressed) { - layer_on(FNAV); - return MACRO( D(LALT), D(LCTL), END ); - } else { - layer_off(FNAV); - return MACRO( U(LCTL), U(LALT), END ); - } - break; } return MACRO_NONE; }; From 6d195dc60c696d2e07bfe7d098b00598f36fe5a6 Mon Sep 17 00:00:00 2001 From: Olivier Date: Sun, 3 Jul 2016 16:27:08 +0200 Subject: [PATCH 03/37] Add a Makefile for the keymap to disable command mode (to keep the keyboard from going into command mode when both Shift keys are hold at the same time) and to allow issuing a simple "make" in the keymap folder to compile it. --- keyboards/ergodox_ez/keymaps/bepo/Makefile | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 keyboards/ergodox_ez/keymaps/bepo/Makefile diff --git a/keyboards/ergodox_ez/keymaps/bepo/Makefile b/keyboards/ergodox_ez/keymaps/bepo/Makefile new file mode 100644 index 0000000000..b673c5ce52 --- /dev/null +++ b/keyboards/ergodox_ez/keymaps/bepo/Makefile @@ -0,0 +1,9 @@ +# Having a file like this allows you to override Makefile definitions +# for your own particular keymap + +SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend +COMMAND_ENABLE = no # Commands for debug and configuration + +ifndef QUANTUM_DIR + include ../../../../Makefile +endif From 82edc37238a0f4239da0a6eee74d62773362a2d2 Mon Sep 17 00:00:00 2001 From: Olivier Date: Sun, 3 Jul 2016 16:44:57 +0200 Subject: [PATCH 04/37] Move Escape and Insert keys, Escape is now easier to reach (useful for vi). Change the layer switching used to keep a bepo layout on US keyboards. --- keyboards/ergodox_ez/keymaps/bepo/bepo.png | Bin 79747 -> 80838 bytes keyboards/ergodox_ez/keymaps/bepo/keymap.c | 28 ++++++++++---------- keyboards/ergodox_ez/keymaps/bepo/readme.md | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/keyboards/ergodox_ez/keymaps/bepo/bepo.png b/keyboards/ergodox_ez/keymaps/bepo/bepo.png index 3df7aa609f6300a48c36425320323935aeb435e3..bde2e2cfacb326e7934c5743aea2f303c8a42527 100644 GIT binary patch literal 80838 zcmb@ucR1Jm`v%+)%81N_jGIdKCK6?2lw|XzrWw_IgaO#=RP`)ZsGHOzt(k~*Lj}T%U}M1B;Eyz3#U$RM9hlkJLUv;4 z{`o9yF`*yR(+N2_YdvQj9UXZ#*RlTNNrGbVbZZ+Myo&}#MjLKi|Gu`UU*NZI(m#Iu zI1u3^{rA&6=7 zh6#I-^18`D{yH%>9^Ulfj?~F)>B^)S(PO(IAN`${pP&5Mvu6W^rer-PJY8K~_q?S) z)n=i}#%E@H%!i8BkM{pMd8eFnJ^6$f?yqz25SSBCQ{(gT@%_cf_*2UaEiEQ?W_WlQ z{;_R;HT?J6{(b^2@`O7H@;a-d6)czBOiY**nMgh+CR)w3Toxs~awX7awvCpDr?B32 zbub_6g15)c*v;R=iUXpI=@}Ut7Ai#6 zs?U}mYn?y&of0o6UXO7ynEAF&lS02&uNs=(ToZ>$@Q_F}PX1I#X9q7kiu1@hR=~zb zDKt!>{A4s}B-?EIgs zo&(R!gSNT?4holoWb)}J5`E&*Y3q~D)X2W^>IgNtSY2ck7!>rSBjGNKu!faYZmTn| zk|qnOY)FYCfde{lgqOVHWt- z`FJU5+>>=Y^}E&@mlx?6dL7ny_iijP88b zC*I{jrkg=)SED_@tXbZ4d-g7b|-1vi}W`dHZVG~{Kr*(;+(znr&ExGM3x}g$v*zFP5A9GPYD6|H{p%cs zs=QS%oOn;Sob%B5s!GG3P-s9+MTPgK>5H?6Y4G-|-TAMxTND%&uR}v$)(4X5Z_Kpv zvM9)r2OAoUaq8?hGGLEr)S#vA^JuxWpG9^wfuO?j>48l%9v&V`8=Ja`I^WQkm_W6B z!-=|!A_d0n$||O{E$gLzM^mf;ffQ?<@AO>ul?1lT&P3s06vOeh^ibq$nfJ^3`c+Ek zV6Bdv`zZm$TY*wO)A;_tUsGArcHw!XZ{pfTs{>1~v*;c>3a2(Kj&eBu{Ba-S+&SbS z#3VyS=5??F8t+XNdc_I6xL=#R3JYUJ=EKf)qm|Fn*4FFI8zM|x@)u!YmtuCzs;Dx3 z;)SlTy=timvMNov{y8pqRa4yZA{?x1Qatl^ijfaK-+lV@dU-{Kz)c17OjR9nOw5YQ zRmbYVe6ur;L(|e~d(%}WCMHhX+uLWT=AJR_&mtj#nQwSadzal|O-HlBsh6`cDJ_r& z+nA=8l0h7WOwyb}sv`Mq7k*AIu7vLSwGsQV!E&Rru#a_%`5U1&ji)?EgWeGKJCOGTM@U#Wq4Viq>4B@|;sh9cQaqCPl_C|LPw}FQ zo{a?9E%vEp$uSa9yR3;mP-ZFU%lCHG@UJNQw(9s0lc?P0U8Z_YBg{|vpZUp=bE-Pr zj+yq0C)0KzbU)l8yXK#sN$)nPPZ6>k%`4$qD03myRioWFG$1I*3tmQAT3UxQI!C_| zzkID0Cw4whIZ5%GdO63nt0dDBQL?yhN0pb-Npr`_a}&jxgoUXN_qL`oItoa#8CMR> zt9u^3BRwu+K{ZFP+||+f(A)o5LE&{&)OG%_u&|7kcd-!>KGoHCGSu=V^3c0&8W^IM zo{Bba74358Pd{HB#gmk5B>jtlVK4)We@~y`;Kv|KiJMxZn#Bf8X>DEIS(Pl!nvpX5 zT>Dim+{>I8hWXJ%s6MA6oHW4}cY&+!MwjKajT*9j(+PGJs9Ox5ITz_SzS5oRNI+v43JgejTsrCVX9y=(JSO+H7X5;Q3(-?HkOTI%mv5?}TxMB3Xi7xW z1f0?y!F|Q6{!*XFix>t4g*S<7{yJDBFegY55 z%F60GE9;CfV`f6HNrEC%CU3SmRRY8Fe@Fan)V8p92+4}`^YgL8S7Qzn$$e^O?9_)R zc28@j*ednIet$XL9I26Ye6(*N^y|kP-r)Ywv*823j8mrtAL>^RH#uh5t-mkEUI8F7 zj!`6e@HRYLEvr3FIM68GwJ-T5>4J$|O4`9JmzgoyqIuqdte<7VO?vvX)}@ri&qfw_ z^=bDbsI#$%X+-*~qjPCC>7!*Ci2%PWKOlqYpuv6yaV?JzmAS<${pr$8<&5#AqXBZ9 z8%VS-LtS8u)M`+nUZCrJ$Ov}R7XyuOwfX1Ev<%J4`TUWzC4RHxw}3U zOOjgj>Irwu<-fl4>dkm*#s+47qN^8+?0otqibMZ{LaMx?;+N7~9TqJ{BG2$_l5yz( z{3o9z+JeqG`$cA!_J5d?CL7!GhG7thy$Ul~nbv?`^$H2O2(Vh9ta#gr_lUS_ zQDZ+7q9&i9`TnlP8{_ly{u{IHHtI?0HdX0Na@gwG^`=}KR?BgCFH)omGZ)jdD{H?O zn%1xf$pxJ=T^HPbOj3E2VWos~8K<_Z(ERcFo>`4&7*BZlcwfHnthW!Q#rC-3^*S-> zo%650@Te%iNG&J-Zf8@A`r2M@s!?q(CXx|?R4tKZKC^XD$dw_s`9CdbKRdW($Udn;7f53 z5)z({mc7i|n|B#if_FfN z-Q`U~jLd#sF0vpAuG_~+#Ni~F*@g(hPYNNheyeE1HiquY)((N%z}m@T`7+M_^YE$7 zCW`dzN97rdX{o8Ak2*yRTVR1{BAd-AveD{9-=vRIkC9~+rim|PO@%Qkk;SOfsOsx} zdwWB*%B?~vw5h4dFC;`#Q#1Ah^0&2hUa#|LfiY3?!+2I0a@c5g)lmQ}`Nzu2%F9K= z`V(fhED`1Erz+Zpalh*)=%dl5^|ciP*7dcponxrtd2D86+iVM;|JD7j-n;cx`<|s7 z$1K_`Sk$6n#x8iqL(8b4an*R@T00{QY>6`AM@n0@_)2SATSL@@ z=QzsUXtAg+lL=%u55i0*C86Vs*_XqI;}hq!a07}otB?b?~PTuGNcE}bqy65zv<-)y~)I6 z7O}Z~TwJ>l{gtQJmg%0P?fq6&OMCmqOpRjZ#-~<}eKw}(8QE`l-Lh(|gOnxPoJhO) zWgleJCC%F8{OCQ?>_Ugk#1-1lorl+)TQ5+)EA7K+w*OO+7~K;7>ml9 z>X&ENdmcZWmopA8?f%3qeM1$M?Si zf`i4Clt``-)sreJDymY+E;C@IF62cTu-=o3v_oxeZCO5lK4b8y<*-26WlN9?Hu1a6 zw}htUZnxA&YE$U{9?nYE4Kh~EYMXXpqf%aS+!DLR2su;fJrb&j^1b%34IfOdpEmQV z5?u^Jf{8L|?f3Nh>yt_S+EfYl{+itLyP80wgu=bsG(2j1xYe(1X=PROHI#k=cF6rV zj1x1hF|orMrgA#l=EBLrojOhF=T0(XBq=SQWUL$wpia@@kk{6V_Wf_qV&Ut|v_vB* zY^{Z>U8gTY4f21HoawjtP@Y}bpB^GiHR;_y5gbhn=oyXSM{IY0E7~uRzP3sA!~J_` zsYukkLV9nMpdHh*(em>ZS|K5~_psqaAnzc_`9!l@_b@<$t44>N{zv)+W;|wsC*^NH zuTHj>{(^|A&q3POSbX&85~NGdOJj9x40)j!WoX51K|VoMN%w;-4^X_sg?gU8z?j$Tq%L7}LeHs@aE<>j%C zU5TlnC--^zz^H*g+e}f3!aTXT?Nb}e69O2tb}-+FrC;zp{>9t7G$tk)SIv6~)lJW2YxmJE>s3sD|G=m3VUNFHQa^&B ztVEIPqI$p2};U(>NDi+kAdPo8Jga>m{jTS6^SR zTm9nn*RNk+bUwXjX=$0CoO83F4Zr!8M&2*-UM_>%}2JMl9H+$8?nw};#R{U_TSrc z>RTNfoQ-R-6&`&T8FG2bI@i_a#wKO_k5Aq6Ikxi(8JeY+YHDiA8~uZS&xHqIfD0Ec zAoY+gzc&o+pe$`ocN&E=Sy-heD`!2FuErq(-)t?J-Xh{zE? zf^OkIQan>5V^cRONR)#_Hpo=)R-}vj7rnGWx#%zVAXr>%&z47W8JM4kLhBf@@85Hn z^jwFc`=u^9Kw|w`uk#4PfMQ8QlMB}qco4lWeuU)wmNaM1o(+xccTk*wDr0FLv_cL6%9Rk<6*IYY@Ed<&?Jg~ir^k|J{5I1_J(@d!P)sP^?>Za6|<97xWbgbbYduve^=i@2f$!yVz2;qmbouU)(LH!v@? zW>C&lKj&l2P3p9>5=?dL`3E!_U2k{){&`IlD)ja1Q=T<1g0Jw^j*X4|%rDcg_mHPW zcDAjOikTU6d3iZ=|7?4FW7W|X8*GH=**F=ph4qG5_g6L*&((arxqb@th6A?%^)vmo zYgjM`=I`Rg{E<{|q7O>}l{3j3M!7R}?BraAxJHr(YXbf&(?Dn}^6Dq}1Bub3N`vz7 zw!JS&HfHAoU~*3SRa$m-aRx#4XtbXFKt6vtrjof;ng4f+F#1VG#iJK&5Nh6YmIu9B2KBxz0p@B*HC*Tu`Wear$uH@zO{j3!p+tvO=C3vjiEb z*Q{L(7)y`-eMwG=;DI9ZD-y3L&ueRI%SN#$MCY=*>{>SOjJi`%QsTnvex3el_%%lR8pV?It_RQlxn3*>GXFU_Ug_~LM5doUdiPaoA!wu>7|2$9_x_~9iRAEUdbnq zaqgKjV_;zDbbJs+I22fjj&v0^*dmD~C8{~1gdVwfZjzSt7dr1e8*QYj541f``1?#S zNQ&RPSKZu<12i=799S2r%?z2pPFtV6*riJz3^Ea_S-}$Yz*?|e;SYnHBNbU<2Sum) z&(n3>S*k$z@@nU<&HK1-3jtfEd*El*roxO(SjI~V1r!i#R_l}E2kVVjTLS{+J;fS4 z*2cy9qq&U6mzRTY*{`f+`A&+XcRv*3vBT10&v%DY78Rqw z)a)JJ+8DN(7lUxL(;jzWUd1lzn6ucK8JnbxkJJaBDj*=>g3DH~3UX#vPfs}I0RIx_ z0EbPKHF64SSd`J}V+3VqjoUu>Y=*>ieyafAX3w!%jqaxGuyUB*;hv zQ+Q7`hSWhQ4Gj%lroaJE^rPv`+UDlH`VchnQ{MXaXG(I3Bmy;3n2c;{I#Rm` z9pEwf#2xK+xTS*Ztc(m?C|t$jZ@az@5AV&&rFqlzIxOsrkFMqJnl5aiDA{CQ?J{@Y z?Ny1f7%R!B&QfRM1Jj53jO8Fmw{0!dA|IvbyXu( z5yS}9An)$a4k=r1V6u5SeNp*=DII!LaQuE4 zJQi5v;^7_GCy$hsed68r&P#vlGDL4L5BWw#k!$JM9343F3kc|beND@aueQKRjyq6l za}CJ?xYR=A+Aizopg_aXrxg$=g?L~wT5c%P2m#&S-`~9Q`7!=7Rd2ohd!&-QzH{MX z*OT~@PfkkuYjjJ#Jn1vwV94m0SLP@0oJ8M>iWt|THx?xwO4`~Xz*mG8>ua{hi-Z6) z@8Vy2kp)>Fn0WGFiNCI0)8Ad2;CDOVZ-ehc<)K>1#>tr%o%=!lI&=1ATuh;#U+Dn` zE5~H3?U&m~+ODIFusy~xv#c$|#m_+|&~Ookx}2Jt`fFQTk&8KOI&vWgc4-+I+BZ!f z6q&51zme?j?fndM_Qssgdx(Of(yR0757fna87K5W&lyhAr#b7%GM^MC06u-}At53< zTcKs~>vEa>s>Gv5gsbZBI_7Qt{Qc*x%PSAJHCzB!m(SDaCrqKAuMGP`>7JOJj7dU5 zLe67Cj8xDNDJOu42NgvWpe8UGT`j7>`+k9=i=Wu(w>(r_H#9Vq*C=M1Jz~KOTwFqV zd2HdIET|)+Ut`8Qb+|Jo`QX8W{Oq!lk`Dz1>lwdb7eV-p3Od(SpJqfvp}A%D(Zr5Xv*yQ z?$1--!f%!v(;`D*Vq#*4ny;j!q`J44q&bq!S1a4M$)FZ~0x2G#l${*N)pwW*=Bs88 zZm2CV?q-LQRcLQ6kzClxHvciLy7RJ|eoa$TYQ1nMC}mxr^Go~9c=dNyMjR&nuOY;o z{%qU()*$cy31=d)e013%U~SHIo;^O=sd}WYe&OQ9iw7_T2FwFek;TRK#bd`aA|f-g zkrkU}B8QtqA3uIXqdc=jeRt^k#l||i$`gJuPyrYLIf{D#jp~PUi-d}&h2Ni*TD*VY z3mM*1m;6g(;}jqhRA2bJcL82r7+)G1CLx-8&@nP%GKGIzaJA>wdMLc5m|k{hk7dAY z8(xmR$uyYefJ_7LnTeZk2-7DGe-cjIE^1trqkZd@Elx*1XZ8ItMqmEbrW+N7V{4fa2B_JjB zfe5Uw)je+ub!XAiue%LmJM)*ya%l_)8WvYZ${ZFmiyf}ob5|unVSaLUHHsJZR?1e{ zLC|=1cykwsD9iEc(~xFDb30x-D5eMDBx%F2Q;*!uLl%FCd0Lkr(pS_%%@-p9r=AIC>W8|OP$?x;2}NRItjQkCGS zmx!Rbk--xyg>g0I0{pp{#SroJ!KLtrk-x%La&ec`;1PtmDkdgIg_|Ipsa_FyK z_1=YCVEN-Kq1J5INAW-?iMp29?6#x$euvMyMm9ZVtCd5{7q!r~O?u2gz3DWCF+}tS zoqz~k-k2KpT5eJ(1reR?9AMw zbwlSR^P~tV$)dl#00;?i68zZEP@0~;diCm$+1Wsa$f$X#a$tmBrK@EBB)y_Rjsq+< zV2B@w{K@0vI-H~!@}}4xbAs<%AFZ#iBT(ttaLG$FTCgQf_zF}pr|Q_hHZ{FWPrnJY zH!fh^c9G*@>oB~!94^v~_ln)2l)Z!~O?pzExzEw- zi&EtHN7m>(-Of!|kr?~XSk^d}(0YX->(5Ka$l2WpmqsXyLq{?GXL*oGb8~Yu7pyHU zpW1!a;`peXJ^?bIpw{vJ*zwxf@lj;)?yv=O0U2A-#^RfYx97JRJa_J%Y(!cT!I(rq zqLq6KH%rROreIe{NJ(KQKX`BAc=%rsB4nu8LPJYmpIP-*YBIe*KxWq5+|%C(v82A8 zk0LngmOU#evnoy0@KAJ|95!ganGW|0i$l|(P3$$H~j5ejBsi1@^T>{x6cRE z){4d6vd0JRl<7EZ3v}90_Al3D`)S2r=`-FI)!2skvTgUA-{0vG`aslhVknqopLK6c@hcmU( zM_-g`L?lABJm`fHDI7zP5Z5Ybz}%sepPE%rzzunA3a~m9uSCSKyiyMyJlm?g>M(wq zQpkY-_$TlbE&wV$5}4_mP@&wu zeY?Ev8Yd}Wa_m&l^6Dk}f06C}>pT1`*cfu)!H-yTAEzoJ_!IFpP*M)h z99-g}iq;1F3*=z=NyX@q<4t}bKgPIJKBgph9alc)6Wl^U3RKb$OrebM^F$h zJMLL;vD1a>EKgB-K2E$=w9}&!pyd2cw}Xn2QKj~m0J#H1`k<1nMOvW;JfiM!i52$6 zix&27{?V^m*xoc@kdcvbb91lp#>1EqO4mcthWH8!GILR^(DdqR2t;QJfTvJwHC7!T zS^$Uy4}$)|?s^0fi&vUV3+x-#q~Rf{69U&sA5^c&&H3&qUh{V}56H*$at_z(E=CDC zazZ8_T#h-k%#>*vzU7ZkErjhYraO2~QueC>C+r?CA0LI#JrQmSJhn2;F<{xjd*G!A z8i-!vBG4wt(Pg@MGZYj+-8!F|_V$a~?uR^auG?xsQsdjFwHDrh@S~ev+n=F`>}S{%E=5+V*w>92E5y z4vuL&2vVv^EAFS_c}yefo6rvHbUqiavd(?T=?ssK_HVzvk9+_A{Q+RaR-Fds7KV!1 z-byp9`Ul*6EB)z7H{~CzjN3yL11;@oaNEGBBF)OxW3)jwg1ROm_W)wVB-F6wZJ(Wk zy}`Yt%ok&F(_%PV=4rv-v>V98xxGp#R50xHsnXdvL|}iUsOYt{Waj1TOV7pi*b@EQ z7lQwNad5?zku#=scXuje9Tb~MKwUG!M%}3dGAxjkoLp40D(t)s z{vIh_t;|-oLUp`P3jQ}$vS@%rPm~C*h2{6Y!uM>g0Xfglm(?|^+^9G>I7%GW^?WxP zD$u(QWHeXyHQm3N4p)abjZPHEIH9Dl_1)T=zCb zRaMDX&!?wT3Rq*nmo;FjfXJ?6cLUY^pic1ptDTZz1R+B4ld<9x3-k(zeuEB$g_`UP z4Cjz#2GXF&Y|sND)+qQvE+C~t`Tj~7zx$C8{E~Xb>UKmX@BHNB5T1d#KUJ1O>m!9; zhF)qgdQ8+M8xhrVh5nRaZZn9(tYi1vTYUKC*fnB{i|`6cO-&6p-ZN2UWzuZ)@^{4N zP*_;FI}>ApR7ObM0=S;{(A(L;LG{T9+AbE4SEKtKrYY_f-k>d=KtI11`T1PHk0JWG zm$$b+68Br;MXuuGqx zQrhkXcTs}~m475b(7D7xzYd(SiTtQ#Y?&i!37d_nChwz+ezm3Vswo*6_fV+!(}@J` z$A^4CPPOjO{#tU(K>=k1>+S{KBPi#Ym|R?3a**Y(a4H0lo&t5!%bpkw51KC_C(Zz# z`c^H(OSLO$w$2$XxBH07=lGsQ-9s{Wucl!aB6VlCK2w}WS8!nDbx=MsH+TRd{~+pV zxxZ~*gDL*aQ!c$%Z!qr(@E(Yn!^PEAydG>HTX-xYIr&ElkuIAR?TuHw4`8WVLu3fIFi?RE+;_S)?p7pRrHfvNj8fH^n z_FbkG)Taf6jOm%cF=u7vFcWRGHe^vnOG9&Nu|K;J#05v;?_YI5*o_4im9{I6HB&hd zC;&YGZhip)lNFZ#!_Y-y+qEcdom1@Ke>s(}7(>+WDkNMGN{Xppgv2d_PIknvbyry9 z+9boa5nbv6kmvV|m;t-<4Gl~J%X;U|ol}Ut3V6StZcO(K4H+k=rfvxhtn@Q*fA1#w z|KJBJMWa80dj%#9{y6N-e_jW=cby`?DB!K)RBy3`_Pu-e*0h95nQH-qz0UXp{1NYr z(usFw+YC}+MBFlBwt~n-c=c+#+OZuknsiFipzdK@@Z+jnF0!Ruqc;m&q2T^VJ@=7| z6pjbrR;+O8a}X;E)q@d>Tb%Habt~C#OIYSg!%&}2ezMHr6BC`Z`rsNQ!L9pHSxH@Ww0AQ$HWutrH5wjI(-9+-X{0r>bE8(zplgrNw2IN zp=AFcQ@O6DCgE{|7}4nHDF5@ND4O7N;FSV(A1RV~%?7G9rW!~@MMc+s{)9R?^nXpV zpguEquH%Lwvue(Z{C(jq4Ltlq`TNMO2#;V~`Fmd&Gy9R;aM#M_L3MU^majN=QZG}j zcVE^Q&F-H9xCt(l+CtNQhwi@U;3r?Gvq3V_EO#ITq5u&Z!83z|=0~{@lmV>PH8-aZ zt~CAY+WLsNwon|TP%W=zyB`MTJ5P71o^0D2i+Yc-5JkuEF-mXjM-F|1ShiNh_>UhL zpu99*b*J3lUM8wwrL8q=RENU=A$E6vUmxn*k9t3UG(j2d+gpBJ356jlbr#wB^I;|z zJ4p0txwwcx{f-?mvM0w;2#$;j&12=|`Ga+PmAh_1F$9u;<6-)3m8RkElC--G)Pagh zN>c*ua_%VgT)lIv?ko!}+K~tVg9?~$KRsH}ju3+u4_W#YWa(8@m~p8D-{$YXeV41l z9;M4&RH<^$>d{#v^p~Kwuv5=^@Q|wS3x!4*FWM;RC3D@+E-$A9BI$;S$-vcm`X6-S z4Ib>a#@rMRj*hg~ulwydc9H;}06F2z!-o%_a#J+@O|Jb8`(D)J#fb=mO{)FuX8yMc z_Qi|SMVzEa4*9h)Ym@xYq(Kan$VzNh(_YP8>zJ*_zXbE`y-r46cqgX;{E@!BRPy!G zkhq91cpKQ+ZL2mgf=Q!{Mc_MKw9KF?QvR_&Us6R7G)TZ#-F9hBOijDW15HmMt0mGKSEs~Gt!4T*!k#{_$refFI(}VEhfWUbd zt2ncZpRw9DsJ{L?2Efb~S&Y4!jdOmrqs<8Xy0zI@B`Oas`16z-@KdAI(&kD@NhZuL zV3Ty%9yB5(BJzYXAGq4_a22f@P=m2NYiRgU5R$+rs~Ff1^A1p}tGn9@Br{Q~!#z9T zGt}*h6F+|JfEf1QD^Z_}1>Bef>{5BXDDO15a#92~RE`+8gR-B#9Um;Q=E%d*h$Hgn>4SB-@ThyDz7-OOX$}I z`_+{(3@Oc!MN>|%_c({cZrDPeejmjQHZR#&enL=J!up=9Hh2)sr)9;)QiA*ez%75U zohMp$ZEI`V+~!-`TtHypT`Mb&RSsjkOl6!;3WJlCL$|{2Fa3*@-d4<`tBM^byvYE# zi>PL`zrW=Rf%4l?YJBKIRO|Bbt%bpi#RXQ-awuB8Q5siTz3H(i zL{>T>K!9$p&|8mLLxCgrQmx4BGI-7cft;=G?^jX8y?UDxPy^x%D^Sl&vIDw92%WYF z)DdEW?Tx3Rpa{6kW#}gn*%4yE87&LW>7rY}hmimFtATrKWNgR<%$}`#FTm0W6#-uC zu>PA|0;`k@V7u5@x5FM8sw}-D9Ak$XF=l3O5t*q)PmAkBwOz(hQtEPH49m;fCMd|2 zSL!XfvWm7_9G{x*y-?;H|(5wL}cYm2kRx4|Fxdt)E=+2*of%ms| z$5wvwir|Z`PmZaUfbruRecJj;7ad69p{~sx#`+0q(oQgQ{k^0fyri!v1a|*!WgE^DT+)`4q|~_Nf|3C$`3%KETgCNr?3oGPEthTMl2L_P}Fc! z$mPeI^2TsH`9_SK+qY=1fC1YlV_h0Yc}XlLcfP8S>~bX4=7kbn`9q9}`Uyx&m+~## z!)tJS0;r(%yXLrb|3i^O40m^TFfQnJC(Feeo3tW0cV5MIclv|fdp$q0t5Y3)4YlFK zRAA@IP`a(D@7f+(WDBkesgv3n_Uq$h*&3kuGXrEFJdkj45t^Kw#1MzS;Rs}oZh$X= z-F45lX#unW2g`&-I3$Si6^QkVz=MLur2~Nxl$;;SU+-rHL`eMF6yQ%BPRF;*IUV^2Xa3VgYA!< z96hTl0gI}p<`04jIk>H6Hu)uPPchu{dd55;_McuEkY+Mgo;pv|o`dN}IID~dS$QDL z=%GY}DuZPOl#`DZW0hgOy`fm>WO}z120A*i*Z14w0*OK8d%zEgkodwmm;_{_PXKrm zS0dS;juPt;$5ff!b<;lg+(jXvDS#4jaLoH$0;n^PQdZ)UN?A8UJYnODMcg3{4zq zOh?ov-y!1GF6fxB2}mhL3jbvTmXoilVx18tqX_YILUu28iy!%M>Zt>hDx+IxBbkd&eU(XS( zeJyj6Lg!9^dL;M+wm%03oqGlo57{B) z?oC)DKJB-~yNJ;j+(tZL^jVRUk(pY?HoVbG3}Wv0uHKH0Q<9RB#3UrSZpZU(rR02c zSEg1co`?ib+vP{s{5*H=YpMRzb&DaV%ycvW1Pw~Z(L~9Mkm+!EwP5w0274!;2A?|` zACJ8fOg8!n^UU8N6*6m<5CF|Lxs`HN+6n9nmQR>Faz792a~HKdME2??q0Fm1rIoGC z&4OPu!P}~jVcyY^Z4@}}Mups%K=MJjcy7+(9WPYo?by+0S_Jma?8cNwi8&w$)-(Xk zOHi0gqgZkxg1^6IkBISewt}4tmza=sI1TIYTh{}eC>6OzgW66HG}WK5RAs0fR>nLI z6<}%cEYivsFCTS3c0~v+sG>cB!6tF1!Q<4m&cg;V$k`sAo(PbBw0Mb0uLox81>cwp z5wM&Hs|Bueh6I_kbvhI>oVQSf(xGbaW}p?UALmT$T+HEg5vU9p3r^dcxndQdq+;Iy zk3TV3WWK{PuW0y`_4xCH1PBNos$2KqkrPfK-r)5{YB;~3AmT#S1Ud;6DAkZye8B-M zdDYdxE}M{J0osP7;CNurKKVT`g2XHn6i)=TGmf!iYDs!kpzC?(HCOADIXgT1@{;fR zv@;=Pt(CqH^+gjq$3rElYar)3geW=xCM_}e{a3Veb$DZd<-?)!4io1NARR;gffhi} zC+|U*-r^2fUT%)nlmvo-04qGn^lf*53f6!b+wzi{MlRBd1FcFl0s?==4jf*B`|%MX zZ-R07k%EE;&@P>e|7+^gvj#HA%dH#;BPd;oERN9>y<5Fu9Zwb=Sk&?`U>p*1a(I>d zE4QE!v!C-4N}#|&>}-&|f}mC%)&HXW_jY^qCby%^-U9fb1b9EBjvK9T7SEJP@sm?= zbQGX=+tpnft+)aem?!kv^kr)J0v7=%UU5ns!ZPsYK=pt#!wc)?Xl$j0)wI45pp? zXRmtHQe$12U%0LC_%X-R4w|06K19%gIvMdqON3AdgQuU0I=`Fl1Qfnsb zoUKh#ayf}di+bdkozX@)M_&XpaJ65x>lM*wb3WW$|CZiTH&m4+_UsAkri8Fqn|t6| zbK|}2K)mggzZJCk1+Oe{D}eKFbhUy9jt9`3_Xx8=HLLFKCPJzo;D5d~H|N^SJ`mbp z$_Fg-1*mUm>v>A~T`E$RaZ2t_a{VxTQz+?!X|~D5p8^i2KF7849)wz5&}}-VwAa!^ zdD(@oNDBiBKPli;I(U=wY}WtV>e(zVA?ym+x5Fw>D;0bw-+6#rD?TJFm72n^|A& zCDvX1c3oOBY7gsy?W1}VurQl*?I7e`@G1gKF#Vt?pbhEm~pv}#5;d) z7B6b65WCxgmNg{uI65F_u$STQ6c>&$FF`%Ol1{HoSGI(|vamWi^yPRWxGvCApSF>n|FQ4Wjnj0I&4`1;=U1cZ zF7%He8sd@>nB@`*3JSb)U&qD{xBS=CTZTG=i0O!!F+i!W12t`^ReNVPZreJP#U^{u z%tw>85o{qMqo)1?rk|oY^bh@aBKlK_dt27!-iW#Q{hG2!-Gz)L$hKuhP*_ z-c{~S;*193sDNeTx6ZcBTLmp<|I>^3+ei=tq(hv;zo4FR2~kG zk1o>mX+15C?BX9^LxGPb9|b3q@>odbA95dhX?S8<5zVbH3)RfzUTDM&2qV|&IBP}= zd>6pl;e!J1ez1-O`{b*$Ff`jAy9GM&E(|6m|7)Z8^yw3r=PrZ);_knVLDuOzht+2< zjstxJXazckC|A!Vr$ZU?QM=0Rw;Z};?&gpBleK z{DbkA)fdD|@;WJ39yD5TFRd35%Q1Pj4h@wxqrbFNyqSZs!>2~b z*?#c?enl+d4iG{lH%`|Xjq=;f;DZ01r5`*%zM8C(Agamz{S4Y4qx&0C@YQ+w9x=?@Lc^)u` z=w;u4CUIC?tmQ2;F&D;3ItxD(1XJ+ECm7e)B2EjWXax@|(zB_^6t3e*mt50FsIU9~ zr|N;0Z%yb06aVwuX|3j}iy()S9%4?0=^;bTD@8)~%~dBW^h zkqmb$e29~yEa=ZazYZi^yAwqA6U%Q&JQ$C_J}B8CO4zNl=$8w~tmE^;tDrrv$K{~E z0dInQi3mqxl@tP5$<+7swT& zR^Zf4N=hnl8Z+CFaCNPio;nX&xWn<`POeVP8FpFyx@8dW)X=8O=v3N^I5>6Ce8(c9 z^0~VPHVNaK)cPvZzgPY$YmoP~IEUK2@7&j~W5@7W6qO&rZlYmh%N`NxM>Tj1m}8nh=`xDW!+ z3N|k87bwF3!Z0$4iHRW=6MlaFahOZHy2-7g$bv!kZZcdBe!{IzNg-wF`Ef z3vg2L05rjlL0Zo}&Id$cYDflqBLd<7tAZb%Z+L&MsYYv(!Ej(E7~D>X2*$@p1{n$B zTPE+YIm-8c*$Xue%8DwB>8D=PU|V&g8pI@j#T4jY!z{6r<3_RTp2^ZIrHlIDXPjf#quOCos0u;_Q0rj8!3QPa5r@H70+?nU7#4gp z?19rZDI3@+Ex@{n1?;jXv@}a3)<8|l0Zv_Z*~TDmAe#WBP5zv2h6n6I@jo#;YqT|1 zxK*J^a>Ikh>!JN+9I7T8AYqa2_WSLOhD*7y{e#_?ZfF7Fc+zJ0loNO5kO7${IDQ41 zMuvuZkW&#`07S#SXLx?#G_(tx$z&M>TIz}CQ&Ux|l?%ZITME~TDc6zGO;=OXO zU0GW;1*g76KSZpuZ9qh=Cr>;Gnp#@!0j%}KiXpHA1Xu9+CY%=Q((+yd>-jDQu=3#q zfLNkdp#t(f%sp)0V7t(tV3YzoyF$+Uk~T^GF<6yysC>ci0wzsN=ov#Y0JO`D14fK})%duocf8|bcu&3^ofd>% zG}#T|MZ0@Q@CET5d^m7@0QA|yeHtEgP>xD}%Ih6*7@{x}>*0aYtq=X@<{7nKa4AEF zRCQV0t1pXiXU*E$+Uty5nqG%YwR}v_LCbl}HHn}Me9|0o{-bemJ^zp2T@hkmA0brQ z`uYU7jQiZW0UQE z%9)v&TF_r1P)1~54wgWodT;NN2)ct>lLBX(G`oO%LYV0OmKqdL;6i*vfukq>ExzAW zP6Yu3T+7}P&XNaGy{fNG%E5eX35`My4i42LBUA|S0X8o2dN2%3tgIjnDa|WQE_};H z6u!Sr(4yZ2zQvgY3^<=Ex=A`bGQt7z4@_d;W!WMdJSysCTBOweu0&!ME;&EewScfY z)%#Wi&Ia(N&`}eD@Jaz-YlChOs^{GWL>RPgNpXoO$=Fz|PBDmVvp!irH&!Kr*fb5A zE&-gkbc%-#NtiV~iEn?GZ(yrbd_xU)0Q4v+^*XfKbZbXKtz5IO9Vocb{|WR>9WWLa z=)t{Ok7%YT#d*Y4Z3~Ny!KJNBA#w)kjWYXQa3110xc?*~SKAHrELn?4wJ{>~7JV7` zos&s1JqKsdUKcLoblus6UdZ@sm$=MbA4s@ZY%I4q?PHx3dgz`3!}rVPOJ)V+ksX$ z3))NCX!{ibmqH(e9k^cr_HPdQY?|tM92@|U;L0hw|B&$w?X6p7gZ*y16Iki@wXpBE zkDm0}A$2xqbjIbKM)~V#Xq4?+z#oO;A5b1KCB(MOmD($?^Wl04siM^J-`gJi3fr2G z8Rgy?r2Yazq}AyqWcN0=W0h{(jH8e3j9O;4AnZ?cN?xr8VjHo}0Lk#>%NHoB!rzeK z$o&;UtNzoY^lLzF|r{tc}zF>MJ2fm`g+f>}t*_DL*-K|vqitvKfu zfl>EpP1?xjT-W{QC(0cfB*2?04*j*t{Vz_RB_JW`o#grLF$Bs3JhFG?5kn!=d&(or z;3NWosgfsm>vx=i0^;MluCLt>MS_tlB#z3ez{Fr6j=zas;eswWQEBN5j1S{*!B~rM zBCy}Y&CD`%8g(Uuz?x)U%F4o0-^^AO1T^&b%~25?rh1j3=8ShZ=JR3yVP$}givUNY zS4VC^Pc&6gZ}N*jHa7O_0#;`}QZGMY3Y^UOzt#MmQ3~J>AyU=5+HVd#rbX^HlR`{i zX*YrgYE?mVj5@Zy4gIuHw-_#NBp3a#RBdj(m}+E->OVvxKXQRvQez(}k7{rya+OQQ z*Ozc((!z!vRTo3=i519G2c(s1qzffZBlh z!1G_#zRc?D@4GR8oJ~pQ)=MYB87$t65}+*}LfQtwuwQI3)&L4|F1T-FM)!?GKk<{B z9AX6h$JG~L223*<4z>qNB1Fv^2({wgfN7vt;mM%4%D0oJ7Jb*RsjnB`M8nL0L#7gu zwPD94r4wpghKiPEKjJhVo&hrmKbs4^IFPojig(jxSb(%iC(s8Vw z9C}Tv%Sg>;93AGwl((jwa>H0X;;-pW&&wtZD8;a#DH7TBhS1U%TrarTX|4yTYP}8& z8kPucX6M@9+B-N}YowGk)H&-s;GC`IUVc2l#lO-n)b12#B%HskUUgm}QtRPNte*i2 zMLW>op^%Dn5Qm0^>2=fA--8VcUKO|~$G^9pcg_)d{XTrCUMRGv{Dld(rw|%+*lhnl zoV^D)&~4j4-qet&tc*mc%$6NRNNJIfJqnrGI}JierKpTTl4NJEWK|-{-jb1-%E)yP7?-tHzII7S2%>F3jg{y%v$SeP^@! z;~bVaztR1NB2Q&qsb#EV)y8(?1l*{rxA!_BQlV4tJGUmMpvZG7OWcjcc@tYzf{dFM ztEFoC_=OXZ0V}QhQxO-0xU@0+mr|J_&Xz;jKIQGos}_8y+?rc!CQ#-eLXIGD78VJQ z0smZvLK#cOdnUM|2V2kLr8@Riv6AW?V)*iHf%~sMe!NvD#H5C^&fYL`&N+Vum$e~X zfc>*Sf~xjHS;ednpk!`u(UwDp(f~JZVreN4Y*F5y@e2Bps*#{X^-i6TTNhOfyC7e~ zI=`Zm#1JN++$Z~Fz#xcnMT>f}h!09rt83S&AY~U0kBjd-_*}qvO|OjSKx$G&WhK@2 z6Jed&erYZLJf2c{62(B&YS^eW-A6zmp@XO&ocScem~#FQe-yoneogMZ#?(l95#AYx z(yO-~=e%jan^PFdY5cORMu^^1%11#`_@)X1FRo?p9e^*EXtPE&!rFA)`Ve67n(9f} z4&j^=;o>WOWj}wL`C_~HL!Jo~u-l)gy(b`?eOZ{ke`{3EGlA!dOGKju3Vy8flIfyQ zHiXFlr)~+Tna4MXP82Bvl0oaG-Rw4P6w>yF7LjbAb{lUW2^ffekHCRW3 zuKVX_SUry>va8ro&0IR4X?msi=yS!@|Kkt-Vj~6uxpXGKCHndEwQIei)Q;SciCoQw zD-I1)R#Lihc#HE2;83cM!hf3)tZnwJK=JI*FFY~&G*IT0wn_-iMR~IFpD|NX((}E7 zYl^P{ojfr!L!NTZ`FMhAG$=h2b8}ixrJQba@R~r<@y?|+H5-`6edI!_ALoRfR6B8E z{lLJ0Q^QA1ZCInxK*RpEgP)&{7M^==6&^VNP)T=ay<|2>;U#2<_4o-E97LSh_wV2J zb});us;#om1X^;C65$epL3+WlHMNu7UX?1Ogk zfsyX<>OB=RkWk6l@>tJ3FB<4Le{|HK>gU=#;f!?^9Z9d#c@x40cmxFx7hak}nRI9U zWS)7`9-<9|lV{W2e5@KJ5qgBN1&|ah8~306O2qn_W>lG)H$gHVaJF9Eebn*lHPv{s ziIdD6Y$!FWRz=F#i#D)6eWvMXtuW33JVViTQrvp2Fkpoc%0+8gdxDIaJEO#X(*)}f|(1>`4RzM2Lv{o z7pOh6kZvtBrQyjos#AZKeZC~#@ZH6Eb4uuKTsJZAa#ZDdZ!}_eFC>J#A;6XQ&xGw_ z3Lvl!>I4(RNWnX`bMo0P<2>kUjeqr6|N7oD_1RBw7dl18b(1Wd`}eZ|JE8Me%Gtys z_3O(f*~5no!2zk~Ii>VpyLKuP@3jF<@vV@M^4#F|fsK1#rW}mCwLEV3yC&Nh8vJd= z24Lo7H$#2Gv44N-cX8ZHzAqK|NP~2p0%$Jm83b1oH5Ct#P~8u%s0?G%x^h&||b@ zq8!fKJ$C&JL>h@}rYWL(a<*n}?)vmjOgDw(!-ASIM7m~h15*2lM!Q+PKb~{EbE`(O z-co|~UZ{?%n)k>-|Ri+opm7|GoutF|Pp|7B;rCHwRj|dFxtEP-e-Z=+^w%JG-;o(PZy!b7t9xU z=zgUU(RIMh`ZA?j?Z`lp^h^A!#~$oi38z&VP;?OlNBoeHFPx2wdPcz6G}tN^&A4T~}OP zCZo$0w`x@liM|{exrs0WJs6Gk?ze7uY%667FX68hKm zpayWb(Odj=k>a0v@B?726`<5lxdmwl+Pn6@Pk}f*=>bh1CZ1$Y=M4qN{EF^;k!$2! zU=p$Fcsb3ydtiXlwXK6l_!^RQ%dwtmn3)HmfGyH1ixRsxC7gkdY1oJ+B*05M*MXgf zXD#&kMes1JzK)~5>TA_j7ZfAA^JaY`(2ml#+3T#sOdHi7LmfbF~^=4c)?I|nT-6jcHV*mmxkthRZ)XLyogh< zEd%KI<0;f*Y*z0K8(9~HM3YW1W*IKS@PL#OeFhRAr8j#8B*JX`8Hs;`-?EXG^9qr{ zvj4hPWYZd8)qs1o4_TQ~jYt7$90fS9oj&|kemucx>Zhv_kZ`}yQDEd{EBn!qZA0hd zp;KpslXZu;5WRz&Zs4i6>FZmwE9c^9h8sxThE~Nq`)R<+o7TP3oGRoPUyWlNNmGz; z08@dUmjT5^IS?;760p)WIOvC32okQb2t(}bnYS3D6)JbCsCC%qKFBXz4RQ6;~zgmnmC!gw-^8z91rC;$YCw5VtJgFw%a~?5EF2*cKv0Me9o} z^zn1@B`@M*CrktVh*$s~8CVgxq@_Fj8Y zdtukVA|86W|LBn;(l$1GtaB7zHb9s_(#sGlz{1bZPXq)yIuZT$<7GO)V6kk1b(b>; z>b##xa+UlgRNc|RcInb3yV7M|GFv&zb|~ADOub5ZxA6|avHAI%v5~%K8s1WFPoBL< z8_cS4WAvnl_w-Yjn!!DLjbzytSj5!QYVgQL<-C)Xn0Q^Z%}I6feF+Xj<82yh4i3UH zhYs;KFa?wivDpoX@h~tQ(*VSDF3W0iSa2@IsgO`QL&I&O4$ilpKIMj80rX={lNk)*1X>|+rSc%sXtS5 z>Sq5Yvs3Q557Ww)B{Z>I`~Kn6l&~%3rKVARYz+@E z(Y|TQ2l4Bn7-bk>Ndm=H8J>GGaVpJuR*@}=fZIS5svb_b)9IbhstceSQQ(8$BIKj5 zfGvaW4k;HaOJSxUQ5Q8P;;oJv8ccwood5k@MGowFa9rKPlvUtN$m7VkE59$V*q5?A zMXzK3myYVFx7D79ymqQjb_mLidOx|D)c&t$x5b8_efwy! zk`E!Sb;G6pXJav^c7Xh=L|u9)_7l=-9J8zf6(eq3KGGT9qlWG6tI1h}b(5_I^UJN_Gb(4#+2@qz8}93id|S&kv@gxtqvu8Iy zeE4t|I`d}ri^=)xS;cF2YR}Dp%qDx~y?Y&b22Ouz0qy~2Z_Kn}L&?td*H7$lhUfVr zN~#+J15)`3OPeEk={-liu|e}4VDX|95qyRCk2l%HjXUNtx6a(%J5a7x>H1xaucE zlMn%Vw{ZWQ zxgmmKbkZ`gxmg3Q=-eE*4~9l+dF69lELDakY%*}AiDn)dpJNm3cRgUNtz&e3@~7F8 z_St=-wsBBF+aPJFNhLR*Nu_-7KR=pu60ov>byL#RQ&W^L+95vEcVb z{Ok9jeh2JKI3PsL?jRA^s`10^lZU7!J@Fb56$1nCw+KBKMR2W%R)A*Z*o*uy3%Buf zB!WCEe=2CUi|dQH3|B+4<#;|AF*b`lNHvrz)1Z&sEl!Ve7RrpLo?3hwUq?~YHh&u37* za_X%RB`VX5M@MxTwtlJq{bwS~6F<{{xZ;6D z5YGqb%Y8@YJkSZ9Qd29RxxZ1f)ki0?c(#d-m5DN2tg`x?NYkvyVh<7c_fy%d0Uq6$ zg-8;(8SuO9g}u>e3|}+B-3Onyhc0SzW~WoS$}@^7lI34fubCP(83U?8K4xsgbD!uHrZj52TSQ}vRlE`XJ(2Z z9mJ_HwmnKYj$}e1UBzJdyp`MA9-G#j@xruwfyi}2W!i2iCjt7&K_qmeMytto-fjWm zvf5WB`?^1R)o&?1^aojBM=SjEr+V28PT78**jpOQs~;X`u{)D?n@NPIClxaC1pe4{_m^N9rJ2KA_NVQynzA7=+gMi zp_WW)@_#KY1+cA{3&fapT*!(ko!H>&_OZ5hMS`lCt;jjJXR(qEhU=Paq~WUsn+XnS z%?-o=AW15BlK)9ok^TNJf8#B;AD&i7Ap4D5W9@&xJY?C4ac*2ggw-Lsmp0>My`{jZ zTHDZ&=8yq%d)KOS?`oP_{=S)mf^UsFUm{?eNsqn;1 za4cajrAq8(|7U}*4U1}!P@_6%COrT3X1+oI^PeSuHAq|&l1?4>@iP@wQy}zUHM`w2 zmysci!qmQ{2{CZVMwLt}R;@AwwHjprc_+DA{AHiXL&j+#_ctiFUcAeORAuW!rv4m4 zu`gRH&zdetnPE>4`9@Q$^+D-UJ2uTrw-i0h-tgfi+?9Jer z5q)8k8FoDO6KR>yoh~{LSy=dZX6NQe>=RgSNUDl{=^I9`F$-4f&QC^$?zCiZp>ADw zXXmjAs3C7KYnA`Cx`9H)iOD57CNdqw0W!?BzhqZ~ttXp}2Nq^GK@N%6K!A~5uv&rT2u~LPQBTYSWI_mvn^E7i*e5YD zT>&EPuYiSOdclfKEKCCd>bc6^o4c*l^XIDu=^Pf08y6Kd4RINTNgh$!LEH8FIf-gg zZFM+cC+u329kGj)U{Pj#=ZuU<@@byOuL(Hgq>YS>GQ;6$M*X?qP9PCv4)O`6W`@Igo3jwKa!$F1=(TFDu7^@!vp;vJ;I~EFFxXBMUKvP6RL-R`fNCFa2k#U(C7PZ^BiX{(m@?qcm{fOgI-*LSV(bP!6}>5Kde} zO?~*>InES0iGP0rGNx3o>ZwV1pUoEq)D8QDg<<$w2a?$dTUSkeJ+~-%Bfjn@WMLr9 zK4=%s&Y#gi3?dihX63(>+<_L}Iiy#$L^jNK9 zD1APYh@tWEbaAC{#y+=9&d_^AL?U4IAxR{?_}=nXiMra^mz;FG5d&@owrg5|@rSX1jVGr%yQvH3wF1?2c@7=1=6zSO zPSTX`mZ{+X*0zFnenLO|rv~6G-(mc2CkmX#sV*SN81ks3?gXY`NI%kofub!efu*lwDuF27^zt_Z~}nRm7QJSx7g1Gu?aQ>)5Ay@!WG^ zIV~2h>E*;Q2qcXVwIt(AwiF7`Kc?KzE310?Ae|}zJgSluJ8t4A5%V*9cE5~FQS%rKgu`67$_w;sM;k`)KK5O^s`Xv@AV}K=4r!h3=-D?&MJo4KB&Vp);niZL8+PC5 zrR}O|Y3_yKmgJ7zdi2O@JR9*Yf(26?7JNS=|4p!fT}{pg0ePRf5(*Wy8q5I?S5apWnEdyVvn4@18v$N7lFFVL-2P z6*0NxBLaEwNFv$8#wQ=cvaSQuc!iG=P*4d}Xft`wI)5L)of5H_Fy`RW_K8u>cI`Ek zO$bp!g|d93?+T)b9%)aXduE{fO3oq;i)!lEFVg!0u@pcOVKSIDK|b zX{tWTg}@JCtjBLnaM=IZEs_JsVk0PYE@Pmkyn`IR6uex66<{$%7V|Ta`!VIn{qJZKfzLP?cI0bHy@eAD0@k^8d&6; zB&_TLD{yFHQL4JO?`?qBOvj_y*Y@wj&#ZC3HhzgN{401384V2$?@5Rtz|w&Hh76u( z2eD5)IA)ZV3qFPdF{j?b^oWSN0+yo)q!{7`@6w?FSkKS%XX|%ij@EJRp@WC1#U>vQ zhUDu2UqrB|(@1t7ae`yFttg4h%3|Eaee4w^^M0>hy;|R(RkFkQ!%h-AMMyg$6TsXJ z6mun^NWvz=0dVSm7+9GxVGv(|1~aqc(jnw&qr2IKa2%3{VW16WIr{lc}im*zv-u*|$x#HLk5NYGF<`*P&aN(5v$m)lR;pj@ZWV6RR-rtE(W_b?Abli4}pnshEYU z=_qN}#+3gQmY+j8?*uOge}iED&yBF5-_XpoEP{6kry?Yt1cAjdQM7B4iIOPIV3EbiG%P+;uZWRd8h+yN%ft~oU*q@puh8+T>Om7uaKq+iaRJBCHJD1GeW1P@CllH3 zUg&591k$TYyL@gR@cbM_ua*1pXpoAC9faIaii&-iZ`?-@0*IHPt>kHvsY{Gv|6!yK za3d9WGLEgjwzd;cY`PW$J^e&B+xKt+Yl`4GfFvr$*9HI(T=8q-R|*cMhwNNKRRE6+ ze~t>b=-i%2ETo8th~UQg&h%}zF?+w7cu@et>)^tB_I-yTHq#*NUl$BP)JjQz7yxj6stF3fL$8{#;IZ z$|1*OXLtS#_tV}BvmY-{b|k)H3lSG+i#~FLOz_b43Fi2#gM8f7S=n442zji_1-%UvOEFUHE!K#8nf;R;D z>43$MF3@IbYmA&&2*JV2fC@Xraa+CJ_1nX;_V&d*S9SIKl^^C2{q+sV=ndpNSl820 za#r~&)Ys8LCxE~WLTW#PhWdk! zX;f$EEbfa=i$4sle3rD=U}1!UMZ#_sKflq?O#0G=?9r0d51&lc5EVsg$Tqt_DvOI7 zq6M_FmcSbZvuNvgpD!pD$XBeJHSoKb;n4Z$LFnk9 z=6ZzyC%zN^Ey-1>VRfe-#|fy znmlw85}5!zxlOR7mC4u!5x$Xq#%|NQM5biu2c$IA&yS1Pr^~Z6$Ct--2Q zyctT%qt$Pqd4JrKZdB7sM$G!BeXd8vdBaEu8-YO_B7*C5JbgmoO?~i~-)8E%X2W9d z>+Q#QUO04&Ov3=Ps+z&T1@RSY;%IT)kNzI}Uav3o_24SchUPl2#HlV;0x*wn708R~2a zNH?+E(=wY|CLh$pc=X{D@rIr^r`flBneUZ09<^>$&$8)Ri_xFoz@zxI>&SQt)9;}D z&JL|Yc(vqM$tHl!hfbf~MDje5S>db0P~2)ZF^f?>tJkc#lA9|rKap9e55u9;KwNBp z9L=&%|Ll;9nw3UoSs)KC`4N*#^a9~s4Xvs@b8+jLki9ExBRPb%HHB-NCFOr~D~#N% z$tz4bg|UV37K~0Ip*=3&srnCGNhtN`c+jU%od%!g0OCz#m}yO@5DjYTHlsE{=eQTl zM|w!3-EHyh#MDCih?SAl98xy}qH|nUQT0~E#OJ4+f_DpKE8Jh#9gkO;3jQtkP;s<} zry7>86<{#89u0xgk8xkDua>^!CL$7N8@g>JHkj zt>XeKWn+h4Q+6Lcz+z7_K7q~s=Z1n`z05c>i+yjz*yLZl;3My9JtDvsao^7OVlm;6E)t{QvxI~m?VwXOgiTcXEn)F7;ag3$ zTePKXdFBSG1eVZ-hQ|F9qtIN0Nwjc?6RvCE^NEIQp&}Uvs6#_Tc}=yoNUi%N=;UXd z15?Or-oVN_eCjWdQZhgZehMOE7q)8m#}q~q8He5o)eMGx1V?kVbf2Cfvm8JWjS-vz z@$*D0#eVN7=|u@4&4z%%N9FAV7|=yL`KXw(0ti_m*I9g`QC57gwthy%aXmgho{nfd zp8SVmB_-_Zd%D8WLW>I=dCaO;^7dBldihZ4OwIM-R=!zb;@1v(!&th_cdlot^ z!bC7W9W0Z9>;z8)c73Dw_m}$0E`xOpkDHt{`tB-w)Kb(ihxNdLN0TgX)j-fb6FB@e zRj7ek+zyWX-RrL5;LXF3J>pM<=W7hl^GD7YuLbTgDmnSqSYPH9)gRH%}`Qw~ry$nc6YvA4bgKL7;Q z;C2r&qh9h7%D=$3AD?;fAVkhG9Jep)=UDQg@P4m+xxA!AZ@4);U~U?Yb?!+4YN zBcfqp4L$+DJ#Hc@he#aQsSXR#H?#R+T_3*50%HH+Y1w$*BtC}tK=&J5Z~eZd^U>2$ z(aH8hEO1-2LBf9E?wO%YYhR}5b!Ue{lfAlrhdD`LhSBk|{>X4TxK1Bh_UJp)l(8II!ARNlmw@qFxK}8tzf`>2THO zO*EV3wZux0hr_`{`NTd26m9DH3X%nY&+YYZ8~!Uqe2Eq|41`+jdg;*0dG13Z1te_x z0JvfiIlCqYNv?dM>bIZ#;m@HWT7eP>@Rfe)4LS%lctt|^&R)gs6C)Zd>8mhsVE?XT z4FO&#w=l05zN~dj`<{K8`Ev)&%o=X|EhgEPd(-vj+p|r~Eojpd3sM<;ZS()M{j5@% zadB%fGi2z;nE`XMNt$umgww{m>z3gYwTuNe#jqNEK4Fbn~2- zKH8!!r^Y8brbR;Y{s4n@eNO>ZT6xScTWvoCuH#CT!$9rM{c}G*sh%K}1olph6ug%< zV}4<`VcqA@)%UcDr}`4R64WZj2JY`6PxN#D;H_};FDm3(8UV0Z!+HJL4w9hfe&n#e z17V>O(p28(y!YSyOXTHL|K#~MycOHzL!yV}K5GS{PS(k1LW0Dbii&GRddV+3o3pI9 z2|mpE2=;}hMxFR%F*xR&+|i>qwg$YGZ$J}2hIMW~)k^vn+<91g{M(YwZ&zBJ7KYd6 zZFFP(bjWHeG&&)Q;sQmH(kHWWsxVd(yJl;Sz2A<-VqYsmTO zB8g+VuIsi@!*EL_LaVn*Hz3K4jGp~$2caZ(txd6hDhHnY-a^&@Ij^gm)Os!;9c9D- zVcOQGDYx7vw&KtFU$xceM%AB*Ns|3?Wl||7>2-Lp1d$au^v(0QxTaj;)wZy(faDu< z2+NUnx#B;6DNbf2;hR$GXzcZ&hHZ`ETt-e!jx^p?|L;_YXu8ATg=tc2SSr z81++~IW`P|SA)oAQ9S!BP3&GG6ixSo%C16(jGdZ^ znc2C<`T)K$MoE{KF`t@1-#`k0QIIaKw+Fmc7>G=gQ`*!&Drc%Yx+BE8UY$m{a$+lI zt+{;K2D<6BL+_ie+x>d5Ypz?lOa)Hf)KR{0npex*U@}$ z)KnjA`0pKsNZg`5vvEl7Ih!)bZL;YQp8Yem09MlTrY)YH50ATUqrSbWqx?oOTVz38 z#EwOtANH!>N`o+YHHc`i(!jcf>kMw(Yml-waLG=vCsVum>5b=O+X5< zZSZJt&$Q*BHqk=J2i<1;FPC?;0kk+&YV~H|ktHVHy?y(&+NbLdxH}AM(nu84&hbR9 zcuPKaDfJOn-L}69zr_lAkc6b8^mS^G)*w>zt`8b;oc27gP*6@%T9F zCNbUpjp`^>y^e9G#aE!5966D1ARArt3T}#h6E3$BhkDGr6_F45TgA>o7cKm@@cQ?Y zF+I~xW4mX=#y8>YDh*}$R_ZH6cE%~C@#O;}^+-ce*>~44`e(K18jLxD5mq9>ioC;|1?% zgS$g_Xvf}J1P^+IYj|J%?$&Bq5OCgGs)VbJ3sF3rk0dWAoo8NzyGBQKFGDs}ZEiAh zu~N=r+eD+HDIq7jwoW{(+&~`VKPrWlD_3G46Lp{72cz96nOJ}X9ylcT|6kM+d`zxw z)Xc7HoZU#i3>;T+`?4zmH@1tya zy-^t(T!*;QDXIrARC3e*|IvXA<=}E*$fen`r9Dm;k~oClt|t>Z1s9&4@|2%3l!i{_ zMX)DwRvAFq<Z^lL*o<5@S*@sNHLGv#to!{2pFKJe)wdCe`B}& zNxO0G!(V!P4LV<4aqzhP?!yOf)%bKRvwchz-$zMIl%06{4;HW2bU>*|PBHlbbaX2N zEqq}SQzYy4Z7Yn z=Sot393C6}IUZa%`Xc2bM4|gKgvIU2LpGT_tdX{c?LU+&p>7z~2j-+73an33KA1CX zbyn5UBZZrOL{~KvG;!=PD)QHZ~=&(6&~BoOjr%d;#Qfe=mM%CU)w49#1X!Lt%=qIXau?T)T7A>#_; zV;b7LPy#*|P&QivQPH(TQ{l);Uvuf#T1mNo?PW$mWo7aRtGM<5T`iN5{nH-cKNcr@ zz0O2g$ZyRh@{j)3T;4mHz@2Zt_*(ZJz&_R3nyeIG2mK~e+v<570McVJ4cw7r=1A~i z&i;8y+TF_N(jcqA{3aS?Tcv$pm}u*&c=t~H%Q)~c@Z<4^J)4{03k53YGV4Qw`b9A^a=ifXLu8k}X25o_`)49r?dDwziOR7})OA zp0RBM9gx@ZRT>ILq;M0`N}xy~5<9r2(2xPmTsc$(FOQOzsxGO!KDHm7q|O zag$jxg-@~Kc^Iw(zS&&EPOwuBlU$pTE(4*3i=7oJZe{!1i)yH;h`qEU=q;aOf|r7s885z= zbcUt3=J%UB!ktuldFk>O5!5DQUjkK}Ay-j|^{kT}x4BiFm#efk0dubR; zT48NTXe_8)8`b}r)pIyr@>}tPVR5U2R#D6bsrunU-F~pIbt)-Hn3Z2=6Nyx;+ z90MSw%DKhKK^rz;zVe>-9~`C5h$JJy%6@)+mF~32%f=rYr}LEKkgfgc=Fu2f{M9l= z_HhZx-+mt7Rvs3!_yqBb6zcHqeK5)K-cbqnOSi1nQ5=e`cu?|`3~W5;;NTFFgJ;q1 z_TxB=1;xF4&J*{>b&+mhnDG^+`wC5`GCrGoqOSQ=FGh|?Ovc#XdNG0 zw(VW~GOJWcnaG%&9&)NrcKDWX1LE-@2GL$j^A8cw{ybNac^KG38`t$kF-~bo$w7|W zja1yu&dw;Xu9BRd-h9)2i()SXg_m$cQ}f%ALfam+J>*DZMTMWbw)qcfW#v2C9vJw3 zT|TNn9;bEKpk9diclhLb@8n;2`*&d7HDiQLv$0C?PU(yd_-It^1AEB1041 zT;nd1eciFopTFy!r-W+iIuv*C5;eHYG=DiFnhc8_f?&}}>->40 zy~V1>V7wB9(L(*eGFeF9&M?FYErH7Okkt^^#2>~4zR z{e2hiRDMv#fO`P}hi4z`GZthp3-#+f<=rjOm?e#%UE-!!Qc?=OANJ@`Aofsffyc%8;RuTDCNJl_4WBFYSLG-{#a>co78D|IS(WmpHy>k$vNZ~ z)&8+=!+|GcS;RDSw8%*UL`Qvg|A2=StZo84y&oP?!>0pw=Ik8DiRX!l+`QOxg&*y# z1l}VP*&ozLhb@kbEvm5jIpL~s{CFu;bI5%;j3;jAhn!?GG8>8x)p-mnq(WDXKyfLt zEg$rDA$F}%DhP#Kw{K-H@fvdjLr zYzU<}2d3>ja-Vqcj3h+CzGqP;r)=MZ@saHqUvT%h>*N=wx9w34gE(=PXKPtvW+{B$ zkSL+c$w|2VSxX^C8TTa3ahptHqG$VPvJYhvq0HRf-5*Vl<4s|G>Dz|E&SF0}bp-gy zg&e3op9yr;Y{HzabJ*P$Jt(%%1eC9BspC4P?N-je))DD&FF$p2o#CMqoNt(S^29du z%ZX$VA-9Db&%7fYhuH-Lsy!?h@T{I4s1j~RMBIcCseLpi3G%YnD3>gnHMoPur*ZEFdmey}T8jsc z#R3CJ^yAKU*%xy!#!%K)IJeRE$wHNhhX_?BdZa|`nh+&8=~lT7*7IX+`LT7JJbCjG z?Or?pg_9?@yNp6FxCE%=&vT=zcOSy&kQ6y+6fR$05-Rcd1{pGkK9nZjulDg_T)43* zp^5QV^vL!xKJJB(4ip^8fPdRZD{ljfqlTg(<3b;<4cglFx#Vz^QSe;Kz@vio6FhSa z3kkM74ADdA(TeuM(?>hfFh34OkRD1{)tMatDk#AHp}hl04O3cq|b-zfV8_mnuV? zbl||oEmg=aI2uFpe}Nb#*jaWI5E%ykAyQ6uY;Qo}1*o@p;MWg_=D-lzkLO;5qrL*- zhtgJaI57{c7h;6K&-y61Dv93-4fTU-ir7D)^~s!)f%zTbg^2WW(zQ19!@cL02Mo96 zGN3t?oxkBxn2!U4|6vQ8l?}o>SM<1Bnay_RQD5MV8?TYyWHEr0<$YK|&Xdxv$!#82 zO5Sen(K*eBxGhBBz5{eE-ITk)K8^+{6=R+S7VShdRU2K>?VsHSjmCm&Vd z9N-Y@2gqE!nTZmkEX$r83CdYFjiZE&ZXiY9)Ra>VLjhJI>auG%Fye%^ZHvZd*3#Te z!dKhfYtQXDdowoA<4~T1EA*%v>efZIwycVon|d=N!h$vdj|Lm-NKmwrt6!1cK_jE5 zm3u3DY{U?EBfDU7`9y3nVq7{$M%s&XCa@K6MA7I}=$N=Qo!F@ls|hjt+H%}MV%TG5 zN|(8O8QY$B_kcd`gWho`4@#LaP=w8VTaSE_GbP{Ws;>cFfXu*|w+!3#_4XnLPLpn) zc=J(@;xj-DTS@Nqh&_jv(1V zyqh(0A#exW&SAOtq~w^a>SoHe{M4Q86rM&iN8* z@*mEZa8fBremH>cFx2%ZvDI-0K`xP@SV+QbQO?0+37uuVu3s{!=B}f5eoT_-W#seX!_rK2-P1L4f@JDqjiDX}_P3dSx;!^SUk5ShD%>@n3!CC7l1H_Q= zlbeDEYXv+W#~w+s0!DyAsu-?|Peo-AdEl43O1!@%?yk9vr1$f+GDwpi~I}w>@O{w zgJ?Uf<3(U3u2A-AdQ_wO^9H~y?gq=!GtAdhBu{E-3-|m zT1iHsU@coY4}*hwH9t4wJb4D-m!m;1gji@8Ut@kdnMbH4;Ehln>>w*G1dU~R?tLby z$FdyKSn-gnqHXJW5=bpIwFG)Phw?<#_?|X~pr9aYNR~hhK*md==AiTspAQAWyn~i? za`ny~S(Ci=z>8L9a~$QlX8=^1DDkZ2qH7Kcgg_`9TQM64h~cI-veVJ%Dvh3xZm{i8 zCo?4Ro=8cFjgbN^(z0T85&Drw7h6pGFDj94%IWW;se~T#ry(ki2gfM#BNj#qB?krv zhaGYxDAzwhjv9Fbg!i7pOi%s>yd!``#L|wVj6VsB$gujcG=%tg`(+St=sS;MLE;*N z2WNurqTV^iefrVh#)zWv7cRNNiy4A z6i>|%WL_VAH73YDc+k`%7>|we6{cw?1Uu>$xNXLwWu31#*%yTguW0cQ&ar;{6Eq;G z*g|uV9qdE0R-rq6>ALLtso@?ti|E+-_|^er#lYUQt0iz+G>?d15i5_ui-I|38x zf zuYuE}v!{pa&C|7-Sud87Dequ$h+^RQ@#E^L=hjGJl*%rDQB}U`hm|QmWl8x08`maH z*#>o*>8+qMNpUG4dh5BLein7FA3gtTr0t96&0_%>KrE-4Lmi4kn%YM z)glI{Wf=M1<=A7Q4 zS_U#!Jrc1|n^mx>x%mbPR~89}_XFc#`8!b=K{`D;(?XeVw0}VDxZ9w_=fvb; zr8t!r+zk0K2?%L?GW~s(-GeJo&m^-23Db-=0g&l~r8?mIKDq zGHTS72~9kk&m5+$PHyhA093q#j&^Vm}HnuGFy5tHu-*#Xa&8bd7s zks{_^7E~<6rgd*`0QrW|cWbJ2$R_{x92VfnPo?Kouw3J&g##ZSQ&hYLnVN~(ChN1y zN#JZ_@>0RPZ_7{*?#6(3rN!g`^+hR}FaM$!f8eva8VY}GPuC${evE`+gmILi@+4XD zWEeO07!sU{X~Ey>HLb4bi*vJ~Fafhr+|l#p3;u-@$rA&EQCCN^>NWw$7}_EjcWQ^| z1An**w@FAa!<6-0p&bAQ{7M^WX>0om#ksk-2%#rz--r4uJGNvFwLJUo-5Vfz+Y7be z3Rr^RfZ*ihBw@P2zH)$)&fD0d#6&M@tWz z^!{D=IKh8m(}*%%+?^H!u{LS`4!j_8y})gD!*DK;p%#eUBhko;yR$JDg9LwI6Gg0( z4CX>WfqW;&?(0S*Vd`h&9)-#KMI>W**&VK+u4ch|;l2aI30K=A5!aJK=esX$x z`o{OEBY5=4Nbf?PI>b=2FvD@52=jr*c$fb$*|IjT`}B)5cQ4HJX6Edj{yB{$^pN3H zmH8!NiIOr0)dLyFg6TdVDd zv%zv14A+Lsmo-U@csIvS=6I%V+lO)}7q79=t*XGiSmf}~N<{eo1DC|lG2oCVQNW1c z6t%lU@V8?R_q~k_5`c+** zO){j=w5H|iM<+;fdFlyntodr!2oM-m9tOo)UZCjd>(f-7gbd#?*&D5C?}FjzQ1L_Y zPqPOWUZ^>8y}zr#%Xra$=+wD$0XLSuC{~Xzw6A?$yV*Nqn`NwGChLQ6R*hI>(xx}Y z^^Yi+jZqCMzMyL`(2TpqAj;0Zon|d+Y zuWnoIvgPcP&Q(9YWRLb06gtYSG<3-W4~Em8B#WY}D03c;p9qqalq6(55f~!^GZI2L zfridCGnj?-C8bRHir3hDCCW+UPKsK6`t%8DEA@|=1$8e1O9Bp5cI+PL8RF@g>~nrO zWkX$EQ*(t&F?cI@AC$Ny*#D7%;EyySJ9WJ)Hd!;%)1u+#0-lng$>ma*{as=(=D9gZ zPi8gW3iiqFVquM3l7x>?lIZB@IcRJjhrGQbC;`Bg&qdPuRkeHBDq z3f$hc_RwhzNkRiZ!>QeBn*JHW+2kg3Mn=YiuC5X&)0W46@+I;lhY~FT2Fup0E3nL+ zYxM}?JOXg0Z1-_w<6v+_{8LYjgzKdSYjVaO`h+2P306MTJ(EuBsVJ7CxkC>iHu#;N zo-)4oAQ~KqI|%4iHi$SKm;6huADS6--K0Gj+6&y7y{Xxro}|R~Z3|##pNPmItV5_@ z$9ylI)752zf#1~B^m@}794I)*i_L{swK@G-Hfi6)dQ{gCnxnh}4bjq#Ei2ewZ)uqs z%Wtf0T@aB4*^1?j@`$85yI`$tE;KYeAfu2DRBGB!z!Wj(%! z$1yRaVX^bj4>7yAoRi+~YsNvX;Y*%lOpmmSo~*8%%<18$_gl$v`%QGYxE%5l(b;r} zyrX4hWkrm5G0SzRQP89jGu(gfiiU>^&JyC zmSGg==bDIA6i?`hyQejWhlgKO_2ONks9x5cIV#>=)OToRZK|uSv8PB-!o!EwN?m0@1K&WSwt@* zlPs#RkPXE!;vgQIwMs}xkfHBjp}TNQO?=&XNmG+KcGp*A;9axKbCY&-6k#o4G<8Hn zj9uf<^SLL7U)YX&-51^}n)QhuDZmX!M5Yzm=VMW)EV7HNG zN;nRRfdG8_)%VDCb{$tnpH23+N|BCEK#;`yKm5$ub^*jV-{aH7am>!aAyxb#f-pT*c+OkI9KFN2`f8`$6fZCD z*GFJsi{LvZW~}NSNqDUAG2oAIuP$G{9EaBw!uPsts4Vw`IMuC3GhD%>@&GA_SwgFx zjcxRmmBRjmX?kZ{PQr4}At4buY22pinIGU`GH6m-Z=0n5>Fa^cgX2<-tA=#6f23<~ zau1Z;m;4Q*RI0CjK`_=4&eNuBjPY22g^7982 z7-hDQ{9Q80cLyI|2_`Tf)lZwW#^u_vBr^DSJC$|hkuORE} zobA0VPcZVkR*1r=16CaW z23{T>(d9nSdzRwWD4jif#Ol5WB9hQStqTYUz_g!oU<8t>7^b}vo8i)s!BOdb9%22N z85yZ-?~b6mK_^M|Zj4EAz4vnT`~K2&=%-TDS@tx^ylyX>TqjEL?UAv~sTm9Yk@1e= z4xR;OW2Obi60`Yav#8M&Zwh)svZ{|D2dGfbnXJ zU;A?E{g=U0uftk{u(_B-yImB$2-^!1EfJnma1~1f-dM$j2paWoNq_BoRIoX0vBeAO z9~qIy&Ug1{OgVQB*f~_M_Yoratfhig+-~)r2mUo9IpPbe=t;g530cDNir2+Mj#u~x zX-J2N|GivLAVmOL)%bh!;77_f^sPAKSY>CUt*pH4w!)XmR0a=!wP&_KQLrs<<>K;6 z5qQM;*1BV|y${;vNMnlU;WYB}~|5XTRT#h^U%L8>K2r%^b^!XbabC zOA|`>2;kSvJ6dR&eZEXr%GLQ_@2Rzd0V9y8$X4~!EKcRwX?p`>?$PZ(l|JvpkHtNErH{v7n*jefjWHP+SE9^RxR zqWiJEef`y~r<9bsy7r?AgAKA1Q6b-Q+Vs(78oC~FTy=Hp>OwK<{QUeaS154>5fNLa z?GXn-Mn?s9M1~zmoJ>ecGL}p~fp9z&!)8qt3bFMCTawU;pPZVwi*Hu_cM1$X&3@O; z_L~Y|xK~2ZkQ@yAGvL zEWW4IB3%b-ckV=Uy~OvMGR)}`Uu?1({%&NkVHxG6t?CTLvr5 z!&ts$fGp5Hvv7CpO1jO8HyNHs=q9M{t^eUyYJk@G$|v6)J9g+<2!6e(lhnuGhH-lj z6LlT4DGKet6TFK{LrqxJtdk1J7#`9W_7fD>iUiLK7BD8ADltvxKo$yOM83blw{r|t z1V}h3Itu&34)d>LsO``{g-tU-GGN=DmL6zsWko$Dj=dj-m0l%>;xf1z#40XkmHFXy z280N9er&*oyUuqasGxbdR@TL(_=O}!2rG(6JW$_S*Lw%XEH3gEH|s82+Rf`fCaq#w z-uSHXvW}}@U%Flj@7;+;Ln^-H^XJx4@i_%44aUD()?)nm9YycE{rVNEUGK!l>IJOo z>DiMzS54`#a6i|MeA&Np`DC=VTau=hd0WoCw5o`~FMAmK2L}yb^r;~{@XZ@&aX90* zjj=6^v7tq%@TpSJZtFP717B1kyvVy|@W&IeR+Ho7n005TPEmZyPCWeZ;9*D5+R$X3 ztfq=R&E63dxI{jAiap{UWsqX+S z?PlIY#vYq5F-W<*b#>suI)%Jny`f+U&aouHT|FkQQ*c=$^MN@sSP4nw{D?to%9NTQ z6kR66+tM*oV@8A2jbk1cLuYR;<*|Hyh9#`}lJ|g}U4h`75 z&Co=zDAZp=7e}bnCN<$*YQ1azOTAM>{ViW~wZj^Rwj{E+Ql!&Ep5#zx9jYtKeWXCK zx2>)1|FQKR@L2b4AMiyPkr9Q+NIMjjk)5W7T__nzDrAIgAsSYRw2%~ujLfnLrI5X{ zIvq`0$1X|q|@2^yVWSg zuk!BWvcruXaIQFFH`pAp8^d}4S5a&?O9X9>)QEl2Fi_Rh)Hm&X@^$InuwPjj5f>SV zT^{PTl5~T$5IK-UzGFcXj`PQMNz2Ie2@6KQpyx!K{8r$zQs&!6u-@Z&Ey6(&$KZO)@4t7%f+x{_kV0sa+CJ4|n!=bDf?4+UPR%dQBot z)_KYnox$IB9iOy4Xxvv`UoZ)kH1lQEd7S_7Skj540k;(25j$Uh)Yt+jfyS=Sf2@#a zmD<2uTgRl3EF>c0ts~5LrgXW@dBg|<2BK_EZolniWBw+%S+P;F`btvkwcBW1sxEJs zdICuU;5DdUi{I=(j-D^_C~iut;U0%Ak|#P(F=#XX4Vaj*XYC7HFHUfBb90lBsbibj zkp56ZY16Qq_1LwpcX05ci0=+z;X}~C0K($h%ah$lYn-e@{W7w{hDo{{To^WY{QCWy zlHC@ai2Svv#J`UZ-PFg{v)c>mn6?TDG4e>5cep0ZI0r7meo9GeSQ-{}Uz}_p!YfnP znPZcK9_C+rPta~yF;nwI;pOb5y|m9)%p_giEpH*a_h*`6hFSJX-}6d_Mho_iDe3ec z-m7HquFP7QH7uDmqo45@p!%lzra1MVNyz`s9oLPhbb>$=Pa=G63bByB=SRlR=OX5~MJ*f!N8 zD8A#*2#t*Utct6(H#+44`PKV$qm!ztM{%tH$KXnY_z4in zlZKw=PAk%Z0onm2#{5zAL6gPle0sK0c)1d|F?> z;>p%>Nx)hd@{~7HLKfiN)YN@srqS5m`K*ez2sGEME5*J=qkAD<>GZtFNGcN(6DgM& z(N7n|u#S#&y~+fJ>~-%R1CfUepR=^wjWk!vmsF%s=?J5)`Td4Bh8Q=_zU$5ze4Ul` zZ0ryzw1BIALPJ7KY;8ROGA;w#9ahvirA9|zYHSP*4i><<4_A-L>LhjEV<-b1W(SR{ z)D1n^=vz}vSs<%7+{fJ~23^&D2>;5B@-$DMrb%h~HqhuFGBss?#?>GA6=7$xD|rnD zlRrQVssOqio5Gt28t|2$Pj>1}4lZ5&x_z)|rpO@I3-C6+q7?)Kt4uiC={;yd8F$67 zTe!D)=T1GC@AT0y?8KRh2#w$K2M?_p#4i{bdZ{x1F)Pb)dEsE+&=8GsQ2aJicE@Zi zO&=R1%GXOfhpBKTNjn=H+^=?$`4|vo94z$5Utmn5Bf@ye^8p{HwX+x!8RXy(rlssz zJI(F%teiuw#SBP8%ZaisoBH>h{zurgj!)yjf`Ss%7M}?(YKp%TDMor>kM-?X#Qu!)KX3uRBq-(0pm)!|NK|%7}wQ ziP}Y@%N$WA^UtiNrlYVxYvt0IwWo#;ls`3yyfnmM8&o$jqNfmhbL_7B;Ys7bmrK)m z2S@4(jy1mfJ)W6Ov3Q)36EN5F{`=@cUSx*9qgQX-?Q*%dCngumD=SM;?%ajN9G;og zyFwWk7Z+!W_?K=%Bu^6VNn7g-Z^O4|l7aGlkt<*NOs&z+vKQfV=%B*gQNMe7-kL4B zsjIDU5RJrv!|47g%D)#y^-&89>%2RI>fNfosm0vG?w;#msM%w#FX9lrq+{UpwzU&1 zCLs7VJUlXk6OQ{(2sZCvuDxP+^e7#GBjbBBsE$d92!>1Im3j&|?51!r)P>vhUJ)19 z2Of{3l0I|Ev&kGx-d4a9Kqr|4KWOUeuJS)pw8PG(Qz-xOgVHpyU|<%TLZ8T z>@_02Wxk$vEFFpIeud#8qUO7uc}9XQre_ok=9$gi{J(Y;0$C>G*jv{*mYU1Kf;xE$n;)S%^cI)>h8$JlVZ=A>4fRz4;`E`^bL?7 zIMrLDS#|vbO+c=^p4$zXUCWcanR;FxG_6rzdOu1v(teuj;uOW&QSmwTGLM=O(#44t zZqNjfIX`&!#D;~ph;aZOWJC;DZGl~|#r^*Qjoo8z!>+fy{jjAOOt$`ZKppcT#c}*n zh4egV?zWLGoes8GwA4xvwn87Mvw{|v1b7@HBO~Z255pJ?ZT-=A(yE=gM&=e4lW~-a zF3}@LjtGj0JxCec!pcn1v6k9^830B71F>UIWgUNu4y|@4r5}mb2TN;v|I%fF9cp1~ zN~pD+7GQ&7<>yy*mt@JgCdzfhTw#Bkb+q(TznDP}23hdCgjW|7EHuvc(Exl14*^k0 zfIsjX*Lkf$b9(B_<;z#EUa(^ZL|4`*vaNBt(S^L`$dlWLn%d;^m|DKJP2oMyG3&XN zqqjyQK`ugMkm`K0`w6PG|ExIt@5$s64{IUi!GN(0YV# zxb;2r(){rG)I|%{bFvjE7&3YH!Jws!*doXG>i97Ua0qEl-)s2K}GwcZ4BwhwT4H<_0p zrA}&K(5p%8r>DqJMnXbB%DXnTH%?2CRep<5;K!DO0L|DfVewra2$Yg${XOViK-)jx zF&wEe^)n%_W7t+>Xa`X8Mf*8~5E2b12r2AIq$arY<=U;y_I`KK=XhY~my6J&8oB5L zRKpk-m!&6wJ!m`ykN{EgI!aAP2f(K%G94foK%jVQ+_xx*Z4IXen5yZ z81?435k^Rlv1U!?-HTaQ_Bor&k7}PQQM)8K(saa(Gt^-G-%38AwCekJMgE_e^D;nq zUY`&|%=IX8jmFa!u4s!|8_;nG(@hs7Er{Xz@9|i?t)f@q%-Ep1)2B75K;w>q zb9OW}qsr|Sj}Fd{)|JGN|5VKsUgz`h?$(y$%=p;;?)JOf3QLxj@A;ndMXf)6oXksa z8FIjISn_JVJ>SochnIO{gs;tQ-U3G}-(9-M-BP&jLAeg@}hO(c@FsmUQ?zV74vz>h3SU_93Vej!3*@ z=hIU^u>ih*Cxa1wqI8gdH#@NfHLaIM>_n3HW@VDngZD7@H5)I{=-Y4gogoKwrxdLb zE{elAa5<%^v4*mafhJldtn6u%@jh*-iiVg*7ivuRWWdr<`Xmy`lF* zHEn3k-8lZ-z&L)6?+s45AN*RRheXGYOgCg`nTX0QnoYE3Q{hZ~)+0YoFI=lI|E+!b zjJv|>WlOPP{rP%JmS-6r-q0H{pNU&XfLII?#cXUS47|V<5v+mlVJxUTU<%2BNvt}o zxv!L5N$IlPRIs*xFsI;J#=)qnr1Ue4EG(v{t|!FtnD026c6q~7pHr_-YuYtmNPfKc zozrHQFp0{L?(C~|I}ycd1Tmyv!|g{o0J+hJxy%n`BoOt&_;XTz2>b;HShL$1eT$VEI+?owDoMG{O(ZQ_Uc1(PGEnuziK2V!gt!v% zyN7Ldyv@zb&VDZb^)nA9?*JO#$aa_9x_o@Y>c0>6>8nx6p~LMr)O2Dr7jaMy!k@hH zNtJj|ZV5EXBzdVVFDkp$c-&i|d5_N?cE?I^RGAA;8w}ieF?VCyJQQdpH|Q6h?h!J3 z1{EY`a2;440_m<~Sa5pzaW0vhXDvYTpugeZg?Hx8BzS~8vD%rNQ z?na`)!DU`@?fILPD*Rk6jCw|~#yyulrpP0gXXvua*nYjwi<|Tk3i6dsH_O^y7NXnB zbC3DO@Qs1KpnEb*lf8My<9$Wl7KWWU(``i%k=;v3*aZ~+0!-JW`i8{t9*Pxpc$*BgHj2% ze$c~*Yu2ydpD+~+HWOjlT%q3$w6!@=l!fiF@bw%R9O3AGYIRsrh2%*o-E4h!Ir9v&Dd zg3m`v*zlOi$IKf)UckFWBu)@T>Fzy`R>M5KiZPq^_)!m$n>|)iQdu!-UAu6j{(-;= zfH(g*(3?al^_#6cG5_W6M>^Ii^Mc}I6!Eik&%Y+3+ATog1{3N%=)H~M`e_78E$WVz zUQQ?Z0u3!KEohNZk_-+Dv(<-N`GvuV`WFjMU(?)C$HaIF%@jl^%M@YbW!Td2<`ysAY6!%;XNdilq9F7C_1S zTvt!kM8xi&O2hm{GY!RWmKSL!Qe6+`1N{{41Syztxw%Z1Gyn}2dUovvM<5oiuCCrXNJ=3f;g^+an^<0FWN-qyt2zM2$K%*$ zPhi%{%3qQO^xpky)JQ#g`~#l|npcQD&{;<@58mJWrC(sn=FI~8_diJ+JpAsAb8rr* zIi~ADbyvkn_8E$~pZ5#c3^VPAxCdfWP|`Z`9FMA^kJT!3;-B5+4G6UmRq!bC&m+Mf zuRPF!`5?9*{FNdNUD7kFDc5amdhO#+HrPqGzG+c~5ez7B{cOJonj?r?ppV0y;(2oG z`1Te7Wj3_oNFPi7^(G@DG;NCoC_oS~WTm!LXdDPptE%B*2+bwk5Pmo;Cp>-Q{Ety3 zhpfY1ePiqVrUh=Cw2Sl8HD>kDwE04NWVED$)%pn0HK-@Z40H%Z$=nsf8>twWZ3k%K zNy|Z9jGjd_Z}zFSg0li%U!N(cCZxo|@pS;yERAVSU!dE>CL$F9)^|EpB$&+e1Gc>)zLnx%FC;@V9h6d$8yDw0?I_Cu<>TMR5RvC%`qSML$=E6@54?E!vao2)7xe-XiL9E)Kf)@2#y&A;*gwcU5&-DaO z#-D>6Thh}ekhlN8?`Zm&>e_z$RUS0_f-5POVCxu*jX@ z1bh$Xvo;uF;>H|jNlH7ajNabS+EbYj7NKtUsi;uFG5wRE?$8Y5G=A8P2%tiA$Q5BS zIJuJyT9|EsL|u{di$sdy1x)R5dvXx|H?#}1l=gRT-hfxUo!iMY&3D6BK{tGq%n~5(_u*7=DS0nxiY+@wt`yj63 z?42rvd;$T$T7dVFZ)iEQdtbwbdvIi8MjyoG6j`RO>SQzm_4`vV6f@+NM~)3AA6$=J zaP~)_y!xA#uJUF)-CMWI6YahC3_t9J<`+I(uVb5E4l%96C|N($>lBFBr;DRKS%50) zsGhrB-*lTB=eStNgU!l#_=p{KqW|zAN+b5jyV17RR)1(wq|2XTNJ|hKM4Uutg5nL@ zTuQaUi)KxYE3XbJ&^25!v$vnRgJ~jmMKZJ>^t^J?Rl}sckwZb|t=rx`cJLt4W;i)J zWAz~q@fOIv!Y=NUMJ!rprL>!Tl_H6Ewq51iyE8(N^_M*1wSx$$Y*&4la zn?BpTEBucKj~upU{}ChLQ$hA`r>~3=(}5;oyrk1XNfhCQ9`vzI*M}?m4Tn9jtc` z#WPzuI?mo<<~m)eoU?@S?^Vz~0B%EZ!6*fV79M3)O^p})N{Ef4z4-0Jp=orQN$6Me zDqh2C5TP0KDj{IMA?3u}{JfZ`sAAqOA))c_C4?F!n*em^$BSJcEM_nzh%4<7w!zKy zb>c>E&NFy>a!{Gn?6793wzId#5OItIIIef8-A}rg(EqN2&g@%=(cv z?_b+zDQxdJ9?#(6J^#yy@-;#2$V?D}$P9NPf=Q8aCwgu4N&nzMnygl499L&e`C(Ot z9Qe$syD%&_nn!7;-nhLpkjrW3iIAgYhB#~o;Gc?AbdP#DI}%YG)?8fCBXotx{*ayh z_0X>&XNU6@3yWd^C%v{d;30_u3vslNLXfd=2q?84X_I>{W$h`SW?^Z06lPN#3O$^r zzHx&lP;F4Dr)Hde_gLJFV|U*e$V{Tv_*ckPrtV{RMUg4*nrApMi6V$= zYtYk#XXrUwvTrvJU%cqmIptS8}KLLP_&^%fqyZ z=d+IZ?gQ(}6As;`^i4IOz6i*L*R94Q7Kk!A4>BFb1kr_C0SGFYm>EO5fo|9ffNswr z_!PMQ7Pue~q4=jOmW~H5LrZer=|uk>BiLbJ*Y!D520b%4y}GG zDR9pPGcFnhAMp+Y<5np|R&zfXEbXFFs7$~4;>Jr@! zFK0ovjND@qnn;XVQ1vn5dN6+f^_l5uQ0*S`Vo8MefyPP*L2S8#l9HVGTeB-yxNr0e zwIpTm1+XK-M5Cy;O-NO)E-oDe}aK+4wBJ8Z2>*A=` zQ;!jSx-AZ{*`=nX`L|pG+=KJH`an4OUBFO@(yi(;D#2}|NItGMCNG+d2N}x&2Q-FS z(f5isevG$nHveUeJa(ia1?z2s^s?~;Q#fRs{&C9xcp{{m|RC)YF9%DwPhh1kdf z0)ku&m8^UVy~>JdV?z%CdRZK!l(%-we*)tX4ajavZ%J^-K7r}?Koe$2}V z{be)f;u<6$j56e-Z9$F}22cwC)JHLliUmug(z- zYlAxQ=@J%iB-j}shcC@Kc(}QHNBliJsG#$9$Ofw%*x>$ss z(W_~<9yuNuGAhdiaJ1ITiDk@4y z=H#UKk8^20Y&a+5=eV)tV2xyPm{&GpVLf}Y_Rl+#mVR213#Uur-b&en1|tIlUSM2` zI`d(TGbLr;TRL{!~o$#VJW}+xA_gDk~lSCEZl$+Z%@Ttuwxa$y@o!=TTR}Z z;h;yX75{ZJSp&B1i{5`;+r<-_n8N@XZd$kLt6EPQLd8^;Gg^ko*f`h(!U|_GNTL(r zG2aI!XK)mdWfvI0z6tmCx2Ms$HeJWt&Qfxa8B2OrN{=A@g>PLFP*g^^{9c7^K?GoV zstDd8tj_T8wK>yu4BkhZ?j@FlmRAW23q#fCeQYzgcAPA%YN%=M91_F~cp|H{wT%6v z0yI%9HsNKaGyQN1ttMKB^(p>JIg7uJiRh)IqenYyl;{2?l*3ZWTB{unXo*&Lv$M;}TGN)#Y?_)hO^ICo+!IKzxI zjw_LRjr+VZ_5v7@qG>>c5}U31%(lBSrKg=1<`}p6xoeP0$@i{=z6ZT0Kx2$W!<$V*Cn1joNh}KUKKU{BAQ;gwBCxF&X)^M!H+b!Ui|L*nBO+ zYqPQoP*%JoTn*D-9hyOM(Pg3R5_~|9M;f)W3n~U+&InFngZvC<%*ED_rx^W!5 zahXqXjOhqpl9NN#&B$Oaj%D~)9%s#vhtdFj7T|F@oJJ52eI__Ip z!EBo)1w=4x2mTV1cbl2_2+ctTCgsvyKthsi{2#9=pCo$x*LC zU(jH@?H4tpme5{L0mYz;YLUo7(1_*A6FuVeKkJ&D?6_dg9L5~+uZuU>;A0e!HnVtQE60C;d2AejKS{KLwY=WO)TR$L^00I^TE4Dbs*cZcJpu?+J z=7Cgnz>icyUN~KeS-p2|84n@y&6_*&57L{=rEGgyUHQ>8jdg_@REIIbG^ZoU3fCYa zc`e{!jn~}-t#f?XF{~JXrNq|&n;~Dj+q?)mrPW!j0T7lFr4xLGz&Q1N&j-)}7yv)N z^HHA){2;_C0LKK(qRz4r5E~o>?r`+xH&?fQTWOLN8XLPqz}}zZE&E+(ZO(h>%MKkn zB(QVmJ@Gp-+^$USHnYD?0yVfp%|y-m$t*nF_W;`O0zY!nvxHQswt?K4BjcwO1z1<6 zsG`^gbt^RE#4eYlXz>$AypbrECqwk^W0w5sY8k#GJ%<(Z+yDAw_SQFP8gLY3dQ8(o z99PrF)pG-+D)xb{S@??BoeF25W5M42`X*2D_5EcyA0SRC!FU|vr9%z#61pEejf-_> z3>n^!hS;doRca=}Q%N4=%d9LOK&~qfd_QmpFOJCTn8@TvQWQQj+|;n}Y>x>8MTgXK zv0Cpd6p$m~Rqzk4*R`|Y0{|k?kwRW6s>-1@bj}y6$ca*-b?wt3K(sJUtU`Y$ZdOm+ z_2dF4$!x@!L7olF!?MGxl!M4sKQMVf{plx~kkg+oIzzVgUt^AR*skqm6*xtFYAFAu@uxW&$mT` zx#)7u6@#d)^zDB1vQ>?ZpB*fTt{GAv=)+y6noMB>kIK3_^9*8g_)8JO_VVLLC#_0# z+{k!<$}N^@XMrOj#L9i0J*Gpgr~mGBfL zI7cORTH;QCR#P(m*G9~%=jG)EW?PI51}_N70NOY%?9wj5pUEL%-k3k{!p=G>$zHeZ z=^J~;z0pdB2OJuyr;=9D-`csU&H=>TTaL@P8c~X27@HiK_TJhUsAal4%pG=p z(J<0GVha<2nmyQ>tO{qXrb9tZ2%9RVnhbHerNZjTZ3tp8k{id8bHFe~1;`iA8 zRAy($RjqBe@D{uP)IZpCbQBruoez%k6@a;MY~mu1wgft7r=j2hMs;RwJaGKa|=9I0UXnHD; zpNs3ob56W8|`i>`VTKs!BoaXU^>Wbr_( zjYmhdn5`w?_3l?BP;sDy#dv;nIHXcAr@X35YAx3K^QH?Z1+h|B(a$`*+s}SVD=T|_ z%?l=Bm@)5)O-cmMRt384GaC9i@3@9_loQn_f}D+ArtGA7A;5Jy*bKB0-2y^(?r|(g zqnfCPR&}&o7U0o;>q?y4x6j9Xs-X_)9x(kG-x| z4?UFmm)nPx$1r8~sI5v=)r-{BwJ0`Ug>hT*K7sgR!NViw>huMyK^4C zQQMvb+#bX`ss7;8TlR-<{^yOnd0uQ~eW$)H1V_+GGNjta?QbCY8LiLrm|JLrh=4p> zAK!6QQ^}wp#3|=mtMuBnYYjmgVx1i!4Idj@?^H0*PyA9G?R}5yPrQ{?daVI_>6adl zC!{>bgt-m%KPv#c=R_Y`ecNr<+ri>i52j1>o=9ME`2MOi@aWNku>XM~N&Xxvj{EoT zD=PTnlq<%TOU7SZVtOK0i&k%6tu`*M`l*LFGw@4I>Kd?lFVr<~v0(K}VFzRWB8p5Bk^iZ-m)eo>;inXMBy zJ6Cin{$OOQ`lJ2X1ak?5WS`5+dB^XrtP2NY|1vGDZe)&eSHtHE)+f^z3Rc&#J^T`` z__~xxl_5Kc)$$a$BNi%mfAd|eW}=nFYa~+~QR2(KKS7Wb2u#3iC~am-?$3c9^ro!p zQf4S|a$VO%L4^ts@CJWcZixe_^dVaG9q*~60RAVj1~Kk)+mL38^4RhGZ&5bfMDasM z0SOTe^tgOGPPl^qoN!mZ({i8>BZUuScbC7#94xqrt^mV`0ssQpD79=65UqOA+#*(9 zgR|;QUB9|a13(}${5b*Xq^K8qC!JvEk_uA+h{p?PHZ}7(icwrLxU)u4+Rob+#WxJ- zs-B_z{0W%!7NJH4BERbg`6F|P!ERs3xb-L64<8TfvUd9af;fN4iAzRJIK@#Wkh03Md~%@0;Jru|0? zkWVcxiW}-NDktncyi7I?vZ)EcgwO(6t@Leg&r?&g-vvkuvHESharyeGAPh+obDOJ) z_z6WoA#5pFiwYf}vNCalk@24B3rRN40r5aPe%Tb8x0tl%TLy1i#AY?c#wCH z-CHsM_Ub^DjGM69Q#QS4H^BVrOzjCqvj)OZP+p$Q1Sj^mf=Lb(lt>9}7%)ni)pz%Z z8$|ZYmWwGBuul{};X@?l$hdP8sJ`arv&3RvV`mBdzyW}&$ZjLJH|Tx`ZiThpN*;uY z5ES&ZE&}*lx^`kU?H{w$#nnzhkYCAtm=G@!x{pd4RW3pRNW2o{RbEr z!=kK%Ce|yaV4w@|GY&_FF%f3{?-jdgO|1vbbiqb?YP69|JFsP?=!{=BZxLYa_p8;1 z6hFXhTv}B0CRpR|iKgXGy@|IFO()cDI+<1*f$Sn9$nE#Thz>m5LxB8|;>qN#B-Wj0 zmeGQwR4&y8wCM0(=+^k}ICWReY`1b%ZS5zia63CY9ZY5?JjkEc5Ssu*4a8;gVOy2i zNUvaPYpXV}+v>`3oV^0Ob_Gn&N}R#gLP{XPW=rP#zS_S5M1b80oX~XWZ70*;gdgyE zxT%4DPWMV3lrz&i%k;Nj<3`R!fkT+U9re&FG>lM>$2W-sAHsAn4>Ve<0|K-Si~-3K z;~wD$Fv9XDW_wzF&_lE<3%=H=Wj){$kXX51%_!Y$3-Zz6MdX` zzfy+RlP8681z8a4>Qt{a`W{XNgJzyw`8YPr=na8Q>L+Fhx(%9C#sypbYMPVY(56^L zEl7v(F|f=Kgr`iG^<%{eJ3Fr@bmq+VXj$;Dp_?e?Ua1wUmDIFQ!5c?v+@>Q71HgI}m-We%6u-OUX2+M+8za7aCz>Lqp zK17;XKdYgf~x4MkdAnBYB#`37-5((NvZI3s(U&t$iG?5Oc63sZ0# zf6evw-#moNHePaC1}+U;_4)K{HzUaAiZ`p2UY7=*X8(n9Ux1#P+y9cDG)eac33%-I zaiV#~tCZVw4x9$>A*)I)P@E>G0^4DP`QL5U#jlS*8}C2YsWG$-TNR#-Ba@OljE+QA z9b0Y(2zme6Ge%sWxMqwY_k`sveMoE}hLoh^C6pd3ViDku?1hpVV~lWAj; z0Dg?R<9@*E1eYLsO$T20qd7*rj1te7NImlT^NZ!mKHCehm(D~i&+1LS!#5p$U`adV~?tm>fg21qgtJ7hr=%`DHNSL$h-XG^Fx(jDN1`9 z=K(U|zRYjfz_`gy>;Z~uDnrZnad=pAXH#IlUW4!)Fl2c6c;E!Ih4g;JZCZv%!*Pfp3Dyq|BRKx}=iHVGm&mp1NUJR`7MH>Twd9fSR^m;JGA<5#$}B;9o_G z5ok}qGyN0`UwHs+e?Vh_hmf2+M&4Z?)_A&t-Fo;4Wb8XbZ2HZTOy=OMAU6?-N`Ud9 z&t~uO$5pN;$wAYpR#V6Dc(lBG=oAiyn2(Wzku!t1OtgIww1W|$XjppR7tfk=@ zitW+)0J;$|i3o&Za={chB*hZ7AP_lg_{GI?VkBe2hpBCbAuG;HSDM(S7ZZ+q7T-Dk zDO<2{UwM1qz`#Kq>o63`O>pAX0oN7a@I{=ZAHKD9-)@AA07S+n@zHcQdi6f^u0#Ko zw6i2bt0aN1?N#YHVGcN^cJYGODG+`P-WfO-N(m)F9KQ4MHnJ>Zq9Vb zUIr8i_0^2lYeyj@GfrPqS5R_!-*5RIq~)yifl!D1Y%YO}jmOC<;DWE|*)>NMgXuuA zG%>KWQ4G%5A)U$%<*A7vpL;?j8brLW!^8voQ5B ztTNz=9W;UFI=fQRU6jL>(2S_x@GwhkxGdGTuLV^GZtEz1?!uc7I=g~yXUN_fO1dIl$H_IQO1 zVV3bKToc`=QX*#c9$Tm4M5sv5SCt)G`S+|agx(HYq9eBl4efKgse;X(XU?AOPcz=5 z5hnLqxYEAtoW4HuGm(8ET?5e1g>*r~uN%^Z{EAYSvH=7J;CeBdV+5#(t^!d7iV*(1 zixdl=3JyN_qp|T0S_@D)#3lGzLoB)i=~~W8LSKP6K=o`LUFwc#2rH=#e_3%k;5w#e zr4PuE0aA-XCPW|;!3P2g3hl;xr?s?h3f!?aS@P3r4to0Z-eF%3G5vx03^xa<~adaCpk}FlipikQ0NzR{%Gc&a-dvR zxcS<8p5Md|nSY;%DKbC(wta4^ZK4apTZi?DB}OHTJ7e$re?{AU)vx0#j={||A`$3~ z7g{kDgp-wISlIRDZg-A+?($k=)w?q%Waj>2uK#0tLAO!ja`qZ7VO(Rsf7>9kjEViB zEq^7p%6-e-``JKe#P^K_KQzF@2jdPfyW}4~a!}v~f~tQbxCGMqeEAYt`hc4gzv9uO zN7e%y@Th@mh)O@zx{uU@zW9O1$6qr%wKGoz1_V01#G3SGsHAiz#pyk{q7&8C)NZ17 z{0ZRS>#O*7KcRAK=i6Mh=JwUxbwrpRMcLpD48*#sk$>BcwMp+e(;trgAGJfNaz-L>>4K-?X29h= z$TVO$L?5;fcOe}Sl17)epgFK%jB#P2&_?tr6OLf6SJeP4Lmb7q-@K2;2o59rkVlVD zd{6^jnLKMiYKi{~7>r*Y;t|etXJOicfk~)1dI;J=Pp<}Wl8VY>9*Gd1mi zQs7x%3yXyhTqv#;G@d>_w77{(^ep6`z%NL`Rv;I|21j2a`&<`tT?B)Ksq};n{&TyC zDrocm8p^|As<{<8_QvL(jJRyBiK;fT_m2=CmBg8 zD7dPirat@T^EuJ6Muw4BS<@4ZCqQW6sOjXP!>NC~d*Hfz$>b55WM zHLBZWoWZQHXbOM_9MT7Ng<_i;f}Y{4RKcA`?>U-9sR-dS_+#NI)a^dVdg$0CL8L3e z>stTf_`g(mR)Sxx+n&bG{%a3`MIcD6t>+opf#qBO9Kyqzz>W?HJ}?*i6f()*1x6CiUw0D5^Ia?-Wr!(T&SU&gI{%aLmP!2kT{s{&6Y>0jW0b8F1#JE=5b}PQ9={*WT$b{zB3wJrs37rnw zOsq0!$AOyd4Y;yB)WQE%BAi$ie@lRWKPE3uG$jb7C|fNA?>raVzX3)n9ANkdOpPD& zQIfy&S$BIuw^c1j$SqrFz{J&cc4Q5{hOYeVJNw6q=K-+62a83`3hV%eSy9>}jU=KL z#|$>MOVHnuB1HqvXa2u7p(tBC=)V>AqlRzc52`6BK284-Q)}9v8;#OU{AO>PThNto zwU?as#N51@?^=w47B9-p zz(U&h-aWKch!6VKd*A0{G<40z>+Bw)yEu7r!iueRRr-5QaBI+G;R11du7XyOXo2ww zak8Sj^;5E2OVDp1A9xi7NF$dZPWutfq<)yjwdsQ4^{#rl!kiZ|8@wYDes%#sa|4HW zuGN}X-u2)N&L`ZdS-i%P_{e)5vcWz6*`WE0h+jY%nQ4i}4(+q4R!dJ@MVmGhwP7ly znVl#9S0o(sJSg=Ly)2*-FX!q^fy>mQSS5C2=l}xqUcq-r8>gW9z>y`aj1;$tf zqymx(9wdtuav6(uD_76vxVx);F}!q()sxC)`gz0t0l$Bg_eS)&4EJ0gF(G5z&?yC8 z*}b^v>)iD|E{<_S>4C%s)h7R-&`>%|y#UxmsCg0)1o2YteCr5`tg1)7&LF<=B3-7l z+7Bx#{sT0_<2IiYJ!%tFnVK53;LZR#6_sg!4!2ueba0PV=4J@lwIj zz8o$j<|qWrNDM@zv<&SX);bFp6Le4tLk>``={!0=(R1dQvvZcAD_jfS$j!VX-$uW2 zdK-f>dl&F?@i|MKgEim*9 zf3qIxLAT-smAjQylHm!X01C(HtG*ck8_}?j$VE`3a69~%PCHG%@#l+t>W#m0k>NNf zR_PYYv1eS1S08XN6oT+)WS5>lzxLAj^zZR;VpPW%xF|&Jr&h{|igsAPuCKER+&xr$ zn%6D%)K190ad3+b?ZsG>g$_CeR#!ifEs%*kek9n@TxqpETelL-n&EdmjLf7H-W z;7o$vj?C+~O?1_>3KkZ66i6!9Kux7eZeXhrPGtQ3xCeUVcG*il{xGU#K!FMf`U-Ye zzcot33Tt%)ZV5X>u@GQ5kXHQMRDoS}XbXm=v94Wv3-f#PCR0Y>D1mm9$fa?HF0|w= zKC5K+{P4S0e-CD-K>x^h{j2HO2Ye}k9?6$GtnTIQHGYrE>q;y?-bedv#f>-7e_jPj zrkK~XPs%TWufF3J;0i>V3fK&nA>iqp(y51FOr_UpSbRS+U1f^G6A^o z9NKn%I{)=q?W4VXy>An(kxX4x%DwT|l9C6F(&zUWc!?`9)HXclK3wGmU+gYi5DW?m z0^_)tes&sKVhcOrIXIH zg9|Y;G}q}rGD_?9>TZa8n(&m(<>7Wn=~J47=N!&4NCjY7bmZ_0KME60VY=+t%xAgh z3Gi(BD##2%RGjM^86xbtL!Ic;jvpsz^GdIsz#Lyjj6Csc zDUDgoSaPeJ6i2bTz3~{muG*hBV+P3Kt6=4lK1twmewv6`8OCm7<}D{MaRH+Pv$jEw zwn8VzNgTE&8qn`hG+^qd>j8P0Qfp7~Ex2jO6g1ck#=@^#ZdJ<|{!uu-W!bw%gg?L8 zwD{cV*_ouS)ZU&S7n13tb0ABM`tU(_Vk~_viPaQ*FeB2@ZRvN|tLMZLqk_yce-EP( zFS~@B=MEk$O0Bd*j@pg+FCSL^==4kxzEd6C;LIMM z+A@TG)pL5KDqg1d22)MbOS!I9b)NkvZZP&U2duuZT&kNX@8H^ORvDo%lAL?w%$Y~M z6n|EmWwN&}HoeyoMyPF9`Qh_#9jA67ni8U>Y?j~z4kx9dEl9Z4)(&lO|JrHQG2gzt z6f9__FyB-;3I|5kvg^#K5fXT=w<+Afaa1bOP8My3i}S;&-$yk!F6rHvaTsD&B94m5tz!NbH1fgUmZ#zAJ5A9SNeQjPK%nK!jolstV9{(8>4-pU5xt9 z1?#vvWnyp)NjXit>7`ig*pHt}|EX2F7Rb-bPZr_lxy$_Fj*`4~_0piLe(-(p=T!Kd z|C&crdu+t7bXq|ZP%Xv^5ovrxs>kwU&CTvUS2cZl6iMw@VapE;z}gYN`V|8 zlC7e?=k(!n6W$HzJ^G1VwF9HMtd?cAZ7a>Go{3Rd zT*dD)N<}8S1m?AO z+IHOE$~nh)Bhf!$DekjW8t3ATt^HQP5+NNKN7|byvu`spw5@#SF>(n?ryV%6u9{2m z5d048d)wV^rMe9>nUk9qJ}hmnI4?uO1=+>(iuudkt@s-ZzIXPlTkc`L7&iNI_3b7D zhlMbhUO40T6Q2?!>{P9ms)p^WB?xUzuU zL8(B_Ct5l>5+4Z^MRu+?iicU2Kn#tIl z-u}FM?PoY&WJX?Y9?+xO3Oi8%#o>lAh+$CiNcK50A$F8rcWHZ)BE9Y-d^MW!LH{F^ zpm*<3Pp;g?1Unv{8<6i#IfQ+5XS2yjNccd*XNcvZ((~!TnA&knyHRkd9wSQV0vR|Q8Q9mfmyY@y(jW`}EI zqXe|s%btJkjI8EQkbk2(*XoiW;8i)S{2L~=P<2s-x+_}Pa!JAV*-z+hQHs<;TNi8+C z`&m;^CFPU6-Itk}jWKx`rL)I))SBRqrISuM4KkY-%CWKvCmAzqTRN94*YzkAiM6W# z$aGz?K1N@$vZGb8A%`j&R6`LEQMUvT{Z|!~>2+EE>26(d<{s2f*7$8$1cATl$YT;e@M0#90J-};TD7wQDN~if5{;G4uQN*H~;sKSXxUh znOhH)VDaSIF;S+*9IvPXM5d|HM_-c!m3vibi$*$rE*Q9!dzD!)%Z|yC`*&+Y*@&4+ z$6{ssb$(M3;eh^t%;m+9A)$TeXI<(W{ME{dcpT&rlMRONVP}BF%wu!IavK8IiOKS1prq30-$(vj2%AEVJMwQBIUn{m zF_H82v1f_57*fO~RDLyWL$a0dHwk|6Er>Z0-LuCN%2{{&m{7lffS)1S`UQv>5tElE z(oEF3GuhmYt*s(b%4L`kh~zp5J4VV<;+k`IyJsY)Pz~jO2h8VIHgn)vwzW(F?j zPOUt?B)zfL<+R6&i0pfT=M)NOuPw(rA!pUoM7JQ7bLTgS8@LJSSFc|Cqi+vCjs6g` zjQ;#DQ&Cqr^<$})Z&%w?#qy1%VY_ zo7npyrF5V$85@T`HC8w$K)qVzyDjMHv`qOcU@ ztdxfYZe-zB#nzSZL*`RgID3Rtuj~dm5p~AK?d6#`nv7EIGiT;ZoL#PHu6mmA zgK2H1w0|b`Y5okiTkTeP_Wa9bQ|rFfKaqLt@bm5d{2P^Eh*A8GHU>SSNF|Q=qHdo- zQ*iD^LkMyHdeHIZhZ?x8in%Umh^(c+>9%L|pO{!!=3S?QGp79jq~h?df*sN?(9qW9 zr*n?gA~m`DhulwjTT6${Je&=5$mqPb^K(l{#;Cza+-PXY4eOzLaj7u&1EmnA0PHLX z)0;k@AAhYuLTG?` zPVap$EHmQWTT)s&)}yez9%2OH+{GcwtaGXol9I;Q#PXbe=4NK&nRAct-xuIIW-~NA zTG}JyJZzlpG_~$WW~=X1oBhQ{Ije^+Y#|!|`o&d;C*AGyrgBR11m*{YX1roqW6sHs z>J%G%&dQtqSG8U zg8Cw?VgCLJl*1jnVh~JEz!s8qY|t`}kv!qn z#4NiWj@p>1kD9#DhLn_SOW?_B9aag1t@Bro0(}!K`L7SMDs``;;h^96^*AKN#CVa& zpRR}eC?W_H<>Gk7yZ}@cZ%Zp+qgt+ch3#zD^6#znOkr3G7Jwy#nM<=I@5^@q~9@ZxNBucn{cPWe6#kTi#4k58#2Bvjw1_MNynrTW^?)v)Vh7|AT8a``IYCEi_xsok! z+MGFZ+(l@c>uY=xmUiU@6r;p1P+3Jnp;oUxgyDi9c~_R+&yZmRxsEPwSmgsZ4^Ppi zKv_?aFL`d!9|9nWCWhHhB_#~$o5BOb||zrG|&Z5Rt^k)`-OsA(b_t>*Vv!+y^Fe`2kZNI5VW^^e16MscP3(j z)kQC2W3Q;!8d#ln=n*3q|PIPSPj_--ufm)aHL0JP_4lN7e4J##p4^h9Vv@?LukZC6 zcEDD_40;w?bk2p`q8_lxp3{|px;F0LzaG<_I^`;?pBs!s;3lNm5|I};n3CA>@Vcp( zguKu1-3kR=@>noO@9R#rYu?-2JY)|wqlXa}VqwPW%SL@LRt0x9;InOWTsSZ-|JG}G z<#4Zk}z`o1g#&zJ=Ug&V@(^LqkQY;&&JUhIs<`F9``1BSP2OY}S2$ z{@ik?nPbSJcpAhP>gUmLPVK|akrE#M{_G-K7u8d(CESV@oyyKk18g{XWlfJi;zMyF zw^hPjK@vl%N*ipZz{FQL{#k1>Q8%m}FK!_h7iydC>8V#P<`T~gcbZ)S!b3z&n8A{YmWvCG1C`6I5GEIm;lw>%Dq>_Xrj`64t z9U=29eCs)S-|zeG@7~|--g3@=c%J?2z1G@mD+(AiegTeKW&#UZMn4?Je&PSj&e75g14t@SA-OqJKFVJ9oP+)_7-Q!ZqE zjcaU`G#pgw4x`b`QI_eNnl6g6a=)s~0K7ql|AO0Y{^{s1AlJ&Sqv~)tkvUC(x*-0_ z9ts*yFM{vP)*SC~f*S@0_t%?!uI+Ssyh2p;nsy4)``;N& zSm#FDgp>#JGR@Yg=_0Q<9~C~5BP?0+I~b2BD^zObPj{pip}Sg z$f8{%VH>NF&Us45yZ+J9O&Ht&RoS~qu@wPEeLLp(K06_W86j;`C$UB_4HcFcBY6re z^;j8IplQy%W;TV5{!NnEDusnqs!m3-1`M8{gTvbGV0QSRqZ$3D?zVhxG?jQ6YacRs z07vBIQ^Ig^qYe&0bOm+$TqK<6d+0CRPo<+r@YT3TWKlaUChbtp4`ho7on=ok}{P3x5g2&W!`ut*gUEP8L zv#Lo~cvlm>E0idnUN6)71tZB3XmAeQ-DqFWFlOt~_4KL}6)EvIcE9WIY%nyR$g5*^ z0W$%~+UtofG7P1O=&)e);_Ct+Wt*lJJtcis6OuEa-Z~LkBpbG%2!#8Yzx<%Ail!c3G%zN?euiCwFSNNo5M+4A?Ep= zWxZ)_VzSOTItn1Ebvbw7ZbZa4={{mHQD1+8L5JHk=);3URoz{qZJQi_ZVo8VUWIw^ ze7q$ePf#o#RvHq0(}xd4B97ixloT36{pws2B-l1*3tCKFBfFvOB2qb^(?n##V505| zNnSZ=H;iM*USAbX4rD{JD(rSiu3r7B>q5}DGR0-*vBpD=j~1^cH@x{Q`>>99ws7wb(!P3Ki?$0#2KPFM?*#jLEYX(r1CMXBlO zBTow7dBss-nDZnFaM%kH%q2z@FvSYN2f%?zp$e{fztzJ;on zFI~Lo?o}TO_448MOw%}Y-Nx0H^qiJcQo=}~E+>wDL?ARI-y3Q09lYNPziZOk3j}Jg zeB3!}>}1eT5J(r$kYCK4osd4V+2ktNhA&4K=#MGmepjk;q`=s z-n?1MG4OVSU4TKV>8;)W0G_?EA47XK844KwTZsP|w{6bBi_35ilH^F{;y0YShDV4c z%Gg@WaBLr(fr#-fzfa#hh&MnH9`^iH3s-`{Zk6*@n1^^MuV5|mz}A*Oj3Ml0i+f!M zM!rIm1GRoptPDPH{GI~YcF7o|NycX%9on|1hrt7(77` zo@HR~tHr-~!wl-{vt<8NEt)({;6xPZ>OpTLD(v3q!AEGVs`-h5K0imR%uG!~(GbEY z5?!(4U}|It6xQ50(t5)lHrR)cM%A9fseRvN_iG5n(A2f*iu}VCy~y0WPsD2m(&T&# ze=DP*QJKT8%YE;A&E)^7JJE;W9*z+a7$4zdR%K{xyi!Uqq=T+1;qMm0z9)FZ-@xKy zq?KgqK{bm(cFPdjNZ&QOyEzOi5f%l6g@ZsThAT1-Wffp>#S*U!a;ktXF%NS^hX|5R zj1x#cJd)qgsnRs~h+S0vHsEeO7Ul~20zq1{h*5R{pfQoOb3DMKM%DT1xfCi;ufj`2 z3xS2>0rPER(TcN1R#pI! z!!OM{%Xlm4{v>%bGe56fcS#&Isywp>BqS;I$C=k8Bp)l-Zz6H8sL@fBN!ee!!{uu9I8$^J@>A4j~(+MVH|r9RXZE1>SBNg`&jJ{LI}c5FLT=` zg{6^Y^RtXYaVh9jki=^{m(}Q9AirbB16c2&a!yM-|6$lRvw>{CR#k|izLM6-A z+4Dm~?A2K+kv5zM`5pS18V^Z3&*nxr|BRyE0vMvx{cF#0lsfs8mBZ~CAG-%{^R`y| zZBeDjd8gHP+e3`uek>Ac7;+kj2V`%g+}QkafMq_)^tdmie39QOi+pCJ{35^QL+>f|eJo9}h? z3K1jfwXM+sNe99g)`<|O&11)EZqU`?s{tOM_<48i`lm=WA*>?HgqUL?tJ7Ywdwpb? zcPLPEcP|}O+o~JAd7?O>2SspTGy51-JF*w&>Js& z>4(rrtV__DR^gfd{Q2juv>)k1L7s+JO@A&XXD{{!T8f@1#!)?+jxFR+L1O_&_C0Ym z9}zspL`un<$!B7sq7^ii!iNt}89%ACJpD!QZbkY%&?7v_odonJ2noie_c{R+fdxo) z?>1>k3(2uXqqZWS+fD=j*f{=MMIn}tK_?HvZe}yQYJ`P5^yL@nunwVyL5pcz2VGXe z|05@Rfr>YCa=*+Sy*0l~UoBy;MHXe$8aJ zk1XYEa(+)`z3AvnD?(jT_4~;JnqR#7@Xj+z6xfc!DEDX_FvyhziL?|uoL(gBzOFhF z;Ti`!h8lCHKLDOB-O#vjedNKuVih^LCD6DnZ?=D0dk&g0@9C!aPMI8oC8ond`6?8z z^>hj}^coHhRL|kNy~EfeV3Y-?Jl17qgC|0!(id+?AMb$(#@c#=1M60U2Y5lCfdWE8 zfuIBJU}W^cJMrbqx|Xw6(s75*oC}ysP8<0q|79tHcTIP6&p(Q*UoqZGB-iznQ|Nzx#}@dXk5InkYiRZ z97bJ)p9jd$|6{#Q6j}Cn2kg?c6utjDnUFp$lgMLv$W-lSYbIJ_)CR zYsKbw>s$&!|C#!tOeXr>cZ2Q0WtQsDm5D1X5yk2mjn+fyd~gm>&B(7l<#CI{rIa>)Z-aJvq2aA^wQ(v@Z3`n=1$69C|utc zS=w5F3WbcIeRQ56`(X&aCDJd+PFxE^N^$u13bxLHcO`rVZWi|O>DvzKxsn(Re z`ku=d9_d}ps-esF2)l;+!fgo!$3ewHN#CTWuUxdE(K~^l%q-8j&S8V z5CC0W@Gg)K7@gp%`d{%DWnoBE9ZQuI( zjxFKKEPB;`KN>He@L9@}(c(;yMSEQLvZU+kYij0&F~Osp(H|xDJ6L*n*=SO8`*uwT zH%F>9t+Q+Vn@8ElTZq5bqwf_a@dwdRAsnz5hi$&jt~03sCmd_HL##@44>~$RR<(mT z=uPuAN628Z$g(~XnV|j!n%tkOVg+pB*`EE=tlo#8hWH>lGUuiURGV<}i98rur_Qx_4||EPC3a?{ z*<$^Ao-7rQT{v>lg3!EGY{PCqBRD_S-AyqyG3h$yS(dw`QS4V^ymZ9husWC%tRZLR znU{?k0-85Kn;J!opc$JT_f~Wz^=*qejHgjb>Ndb0@b1PSIL{9`KNJAmJV;8iC@#g6 zHz6t2v%vB}wzv-DEL5DxRQ$ z#`K1$K7RFDM>|!o;RNv`EZ&nMk86MxLo+rK_bf5_q64CX4+|6l4UW_c9vxM*+Hj-V=7P|<XjsPWm~h+jnMFizsq$Ta~%@h+Gl(`1Pmuq>f)Xmrzw;~ z?KM=Sy$JN2w`X=t`1KC@3f!8(?5({ylbOqNwPIZYrF()WUEjBGG}$0^G0sP}+6>+9 zu!>1M^3VD~>nYOAghS=^>1RPcaf@d%*_yt%XGhM0P=u}LGh~J^b6WsFdmqrq+Xtn} zpX21(PoX4qSiC|mV<~rpJL8BC71CJ2*jss>x;Z0z$bD$h5ic1m#0G0h z@wF}?jJDAm7@y2habBg((y%6JD-rh%^%*!hMZS@bnKNgV#6gX{$G4%H3j|8A`QzVQ z5@H1WQWso-5J=kc(J}^wj4Epo#YT?!QxjujLAzQPpihvFVWxxY26dbd$hX|K{G`Js zD5+ZNI(Kbbu)ei5>%|07C1W~^8_cbU_E$gEfID6WfIbfAwjV#P`*=r;M?xh++Ud0| zff_tRvm!dUzQJ!5PA>b*%ow+ADHtojRM2zn>O&Ld)%{7|O#5XvZbS`A3YsL95g`2?(QBs@1jKjF1dM2xO(mm1ay%q&-IEakjdAx z(d2f;nGyt1$h+sj@_O(I1fHZ6MW$$4bgrrymtD-LY5t|XrR(d%w<0|UGMnx34lwxX@k`N>X@GR0JFiI6ckUI2^#Kl z3JULOYm6~$)$Cg{dRwrRiL)U&#}LC4DF-aSk#2nmW65M+(%6ncB7-|!CtFapOVvQhUQ4U$-hZ)&aU%_ z1NDEP@{zEFitDjk0%=7>tyKOo0NG+qhhYB5C76Rj*dRNEy#H!XLvaTJ?AIWX->r$z z9d`4Zo(>KJXur7ToFg*HVsqKCEZf&!whj(~7*;D8!;j(z@o&+9j5c|RUqsAuh9S^p#lV#W36#rQ~^%2rB!szl0 zkTDb(bjRl0Dnj z)>p{yuwKMh)oJOIl=Sb8l^1Q)R{57mOly??jI~L1cX+6UYjE)HGRblL=GQ@AxHuem zUv|;ddB(PHRl9ERJO+}GG1Ufah!ny=wRsi@um*B}U82#LA5VT3Ly3!I6DJWy@$PRC zQ6r|Li6soX9aC!ZVllinBXMLvZC$Ii@kg4VA9XrKs9$e@w;Uq^o<`j zl|Rp??Es?;qM(D$wV1!u2_gwJd)x&T%<86LyukO`2vm8xnNKsEWD5=K!7RM}(r zRj(H3*DalpFrX(C_oDnVy1RGuWEY^?HO!yVu_`K;o34hWobx$$EYkc)FmS%;ck?CIBsO;;M5m~b?GI^S9-O6q2!sYPx6RezPz zFYBvrBL@u4vvq#ow{T!SvZhMdI>>k0_6Eu2cK-UcJocn03V%GUM9NYPFZ?iYsuNMm z)7&g{Mup7`O!u8@Uf1oN$5TKrwH`+Kn;>Mjg@!muY&Bq)&DP7>+NPGaswpX5pGB5m z+3c7Q(SbnhkAhl`81&uS`_irvUr{u~u+ zoA(&3#{^`nRifL=MHtgKJw=DU<$*&y$lnCrCWm7dcjfpCXBUemYd zzc}t2tFF`jqA%m+hyeuJXXOPPCU_J%_(1L*zJBZ#U)@O!>AxloU^{AzPFBx_C zW>6%$L8sZjy*$EbD&IEcbHT7C^fBOC`9Rd*M8jyFhE_H2lqI!#NOc|svp4=>L{#u3 zq)N2CD8CA<5Y`iJwq~JJ-t|wIr*!=IGSnRp4N~31ZL^H2jfbWmeqBF3nzGc_^=p)< ziTsKF+FV-X1O8UpwV9^YL3&x(yp&ej&faUHrc1>OtL}hnM|B+HGhOyQ0`1<=XfjNB z!0gL9vSj#5HA0urb8_(*Lc5Aa6tn~Et74rkvy2I>T6zU=FcJ4a(8FNvPjWKWB@=ki z6?DlsCKOF~sG9NGjwvm{OAug3SUFdao-iE1*y>u=$nEr6eSn)3N;p8)JRa47f?XJv z0E!wJTK*PP+gZ5J?b;{1FKsaUyGwmE>sj#X*OS>dr*579V0)dB8(gADM;XvRoiN$| zIg{R3{n*6j{6OsMZ>iPQdPq-bN6XnF^0RXLlF@DDx7!sl;et|2epdX8rZ|OI7tscp zhKzPf+E{neTm=zryUCZ!ql*eB$<&^k1!QGwQzA5mNGXaU5iu97$Mf{_z3IPz@4 zHB!%oeymIIp$A58uvZ^#I1d4b*Z5nmOZNFUOr|d7yALfet16_;`-uhmIQ*nvOV69E zREx2^655^vIy(Hq0pEVzAiZ!9GXR43tU7CBvj_6s(#c?XJW%v@kV+bg@F1UbZi%+p z$d(%pxEjm|xXwO}|KGvo6|-??E&smUw55i-OJyC)!|2nc0o~Ddc--$Ni_G$!I_xtN z+Xqi6=Qb3Xd<+Z-05{RQ>lZLhSeJfiU!OlK{L?*te8;awr&W01tKBCO zR4GC;SkA^x8e9@<*kPkN5GXd1G*r%RA*tgZF#BlZMlKM;`Aauq3<4nOgbjz5TXXg& zrNxbzeW#BV8G6Vnn3v+MJab`M@iyn(7mD|7Ti|o2tM&S%`qFE@5AJVB zZ8+xHBduU?=Gr$^`?`2+2z=Od$#rxY#ES{mqhBkM(Dc+p+ZHC;ntOw~d%qKNLSbN< zD%5G6=Q!}@2#$2Gl|n#!dv-kbR5OG(5P-q8OUh!6zcEq)lh2+fD1%wYeT$J$aiG3M%*-!^%|vxw-7Xe)Vac}(I`JZW8_a(DnvQjRX{j}{E#2sI z*JFjeM=99B7pY$TGZ(-4#uo+Tt!!2Lo2b6*$5kPH19q&TmSX7yrW>Aof_7?Uvgm4g z?Dg)Qh}*OpHSd@RYSod5nJEgL?6~^ryUQD^7PQPvafX||tF7ENYI|t9IeZ^y`sB`z zGw3_8O(z8#0e&HkqxeOGpdl9N#CN8;Y7_DzZg$Z$8T)_rDDEL!J(3`@0s#ydA%FbK zp#DGUqZ0~zmW|0zKcBI>z?_O)n%1pdx0r9YK=(`ovxBX6>FTKjIZ*Dp7ni44VIj;|K=Tx@NKXcFf ze!QMM5#04#r>LvMcE%;U<7fTdc|u#KMFZJ%NxbWg45==AwV$?uDEQ+s&z(?%0f19}p;7pZTap)aI^?L8`tZT^;Sr z#LF7|Y`iWoR4$|6>^#a6VhOekznc; z57v60@y0J(TNAu@TwV}4`coh&DG6c)^q4L^8Jq>}R)YNV3+R`V+_B@f{M389T}b3T znj2g^Kk*@_sL$$`llI!#pJ%#CrevVKWlgAs#ZubJlbZx8LQ9|#s0_r0l;xGoVZK`K z)m-FTWH@>U$uv+V^Wn}~xb7{ULdy}?VzzogqUK}rv|nmL+dO{duTJ+fp$9NDq~~)A zuAi*S0FTS%KOgc7CcP592 zFL0@^8;##+MN7}f(@V6ay9-_18CSU@aa!+1TP|ZB8r4yu2|#KdWu?M62CgI&x!UF+ z;IW7169nF$3qD5wMwg0f7N3t^7GoOtId1Xapa_eCu#{3m;D1 z4&R19x)KD-l_n_o{Mkw3`x^+ByBru0(i0IDU`9MMxUcR-@+wWFsCQ_pcY1vb9+%KbVV8|*gd?hDxB@WRsL1n%zA8drFjZl;G zG0Q6Aa*&7=&)vPyr#A2-i~6u5?tbRN#PKI7DV*rpPO0f%@U`b6m{qS{&sJhr3?mR2 z03+$^Z+5A||4T&slcZ;UZz8kK{PkstvCaz6DAj*Hc;ureDjvH zRXBYF*S`9C)K>WQtF#!`!xvm#d47bj+S)KQ&}e9IZxk8i2ILPIgf{IR43Azte`+{4 zC-$k>?{B{fIYbX2LIdRFERoHRTkQ{vZG8G)ND}9kLpXqx8jmTrcY{9^xa=6s6_ZKy z-D6X|zP-b3uXj4htqe6c5(Lld_WN3$&xZGyiqsuJJ-_G&D$D+n;o$+9tO4E{wX#Py?dBsV;H_ zdNIu=s3lx30UWi%fXTW@UPIMfGio6A1+bUD4&M;z`O8%uDx>*LKkx;pnuDj~BHJx6 zf|9gE7cf9HV~B^)1$jRK!`)?QuA_by8^hf}x3p)d7aVwyFB@ilA8V9mfWC$Nkw#n9 zBfG#rK(B#ij=mX<`^xBUz@8t_jzzcl;*~44G~0tHMpA-=JV{;(Bmp{HUVi?NUF(TB z#7X2t)Ue`%Pw+m1I3Em5%@_^^D|WH0{yPyOP~>0)pskO0UXK=6L?pcAq6r{@NszIPC}F zht%If_+(iAR2P{%_qucYHrLC9r-1n`UL4L3p9>lwjQQjEfrrnW5?!tX1B2QmD|{_9 zoO9R#=i{m{CYh{_>>ZP2CzTIwyI+B|hK^uw@4*@aDvS`M$_J*W;1_dF=AfVk1~kBx zpo(UT-XM=!pU?CbCA<{;1lVWRGhx5yUS!D*Q*&X*Q5`CjB$FUP3f6YIuf%8M8bbRMd8`aK@Yz;+k1oI$+@vTigt;2nT<`!yStQ_`@aKE1cHIZ0!iTjAYHB=RT`6~39cM(Wf!(#n z4k&UYKvgv|BRH(GjImVVl>hlG-4a;ViKw`mFfx(~va|v-HGBb5dZG-6&ggL%o<=i^ zeRygtLkA{|A?`q~2iY7XwaI?Th$Wv|bqEU}v1SQvS{?HckifSr@IhRJ5a;@|XvAb>#TmGH z?g$fCtMn|`&dadvJw$4)=4@bPxxiQ!RO)++ie50Y>t2a@% zN^ajCIjU59E(_YEe7Y;j6?h6jnsrQ+n3AFbMeTf)WGxbYvsp{EBFvc~=6h-1(n-X8 z7Lu4tP%O&}3MToV1B7Zv>zmy!oyiqZR#1l7EYTFa1_~F-8$YXtv-BsB+Tr7!&l5VC zOXBqG64xx#_myDBfh7QMSwlf(!$O4nNY1(eXd^(1{Zpg?VwpLN{{nSmQph8Gz@oGSSAXG1E-W7(RC3GFpPedX^IeDD`y^ zQwuO{>&Yb@!AHM;dqEy=ZcJZCq<4_SR!D{YY$Z& z;1Xw_gl&q;cNQ4ByDK7KViaZ=hF}Iwuiyp(U`i5pf#+=iGI3fG!I;*g&j10W5q8<4 zo?Dtn*g}bBmWO2Iu?=`s5LiUqxdV5c^%K^T_}Le;r^v1U-JK$e&Tm-3Q2-*4I%~`* z`+u~AH8xb;s+2AmLBfcI5S^9eg#A6cvZ9p#o3`?yn#*MHiQ%ky+xh<1Cs;*(`t->t zW$tnzArSh4sG%@DT42fr`MHtV?D8>k%t|@FaT$V{nNI#oht@EJ>*`iD2?jX**C0RG zoBXEcRrV^5T7JJ`0mN39FVDe@3Xi8nx-ja>J*lnu!}8#>20Lh7#b`-@`hbQ4K3)yg zk@3Gvum=ohAC=UR^dbn+<jFP0EP$?1(}IS$v1{zWns>?2Y@A?m~s$;JhbSi zkSi~fB~SXn?AXnC|uYp%~! zUWY@#pC3WSTnd_}x}ia_FBCHsV{@I`uXi}$VE*$3hYmnu0`qR?AFB*fhkKtIbh$x6 z(cy6Yzkecx;_50dO(|49on<`Jv#NFMoqQpB)Th$$ZQ=Mq4mze`BDiS!M*g`2EC6Mg zr2f?MebrtbeIT7uR5-FKa;EBB*0d?k1y2x>uF|G?^Z#=V{sKZ63O8eliGf3)Dy~H` cxo6b&du&SH@jdhQ9Q<`qQ(Gfl-Q4eg02i7zmjD0& literal 79747 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ⅆG8`Zu9v?x4jfsuz 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 gZEvd;`R<3>|YaV{>*VfTW)-?C~KmTJ>)Bpeg diff --git a/keyboards/ergodox_ez/keymaps/bepo/keymap.c b/keyboards/ergodox_ez/keymaps/bepo/keymap.c index dd47357998..7c30d58788 100644 --- a/keyboards/ergodox_ez/keymaps/bepo/keymap.c +++ b/keyboards/ergodox_ez/keymaps/bepo/keymap.c @@ -24,7 +24,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------| * | E_CIRC |A_GRAV| Y | X | . | K | | | | ' | Q | G | H | F | C_CEDIL| * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' - * |QWERTY| |LSuper| LCtrl| LAlt| |Escape| | | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause| + * |Escape|Insert|LSuper| LCtrl| LAlt| | BEPO |QWERTY| |AZERTY| BEPO | | AltGr| RCtrl|RSuper|PrntSc| Pause| * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' * | | | L_Num| | L_Num| | | * | Space|LShift|------| |------|RShift|Enter | @@ -37,8 +37,8 @@ BP_DOLLAR, BP_DQOT, BP_LGIL, BP_RGIL, BP_LPRN, BP_RPRN, KC_DEL, BP_PERCENT, BP_B, BP_E_ACUTE, BP_P, BP_O, BP_E_GRAVE, KC_BSPC, BP_W, BP_A, BP_U, BP_I, BP_E, BP_COMMA, BP_ECRC, BP_A_GRAVE, BP_Y, BP_X, BP_DOT, BP_K, KC_TAB, -TG(QWER), KC_NO, KC_LGUI, KC_LCTL, KC_LALT, - KC_ESC, KC_TRNS, +KC_ESC, KC_INS, KC_LGUI, KC_LCTL, KC_LALT, + DF(BASE), DF(QWER), MO(NUM), KC_SPC, KC_LSHIFT, MO(FNAV), // Right hand @@ -47,7 +47,7 @@ TG(QWER), KC_NO, KC_LGUI, KC_LCTL, KC_LALT, BP_C, BP_T, BP_S, BP_R, BP_N, BP_M, KC_NUMLOCK, BP_APOS, BP_Q, BP_G, BP_H, BP_F, BP_CCED, BP_ALGR, KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE, -KC_TRNS, KC_INS, +DF(QWER), DF(BASE), MO(NUM), MO(FNAV), KC_RSHIFT, KC_ENTER), /* Keymap 1: QWERTY system compatibility layer @@ -61,7 +61,7 @@ MO(FNAV), KC_RSHIFT, KC_ENTER), * |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------| * | e | a | y | x | . | k | | | | ' | q | g | h | f | c | * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' - * | BEPO | |LSuper| LCtrl| LAlt| |Escape| | | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause| + * |Escape|Insert|LSuper| LCtrl| LAlt| | BEPO |QWERTY| |AZERTY| BEPO | | AltGr| RCtrl|RSuper|PrntSc| Pause| * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' * | | | L_Num| | L_Num| | | * | Space|LShift|------| |------|RShift|Enter | @@ -74,8 +74,8 @@ KC_DOLLAR, S(KC_QUOT), S(KC_COMM), S(KC_DOT), KC_LPRN, KC_RPRN, KC_DEL, KC_PERCENT, KC_B, KC_E, KC_P, KC_O, KC_E, KC_BSPC, KC_W, KC_A, KC_U, KC_I, KC_E, KC_COMMA, KC_E, KC_A, KC_Y, KC_X, KC_DOT, KC_K, KC_TAB, -KC_TRNS, KC_NO, KC_LGUI, KC_LCTL, KC_LALT, - KC_ESC, KC_TRNS, +KC_ESC, KC_INS, KC_LGUI, KC_LCTL, KC_LALT, + DF(BASE), DF(QWER), MO(NUM), KC_SPC, MO(SQWER), MO(FNAV), // Right hand @@ -84,7 +84,7 @@ KC_TRNS, KC_NO, KC_LGUI, KC_LCTL, KC_LALT, KC_C, KC_T, KC_S, KC_R, KC_N, KC_M, KC_NUMLOCK, KC_QUOT, KC_Q, KC_G, KC_H, KC_F, KC_C, MO(AQWER), KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE, -KC_TRNS, KC_INS, +DF(QWER), DF(BASE), MO(NUM), MO(FNAV), MO(SQWER), KC_ENTER), /* Keymap 2: QWERTY shifted system compatibility layer @@ -98,7 +98,7 @@ MO(FNAV), MO(SQWER), KC_ENTER), * |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------| * | E | A | Y | X | : | K | | | | ? | Q | G | H | F | C | * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' - * | BEPO | |LSuper| LCtrl| LAlt| |Escape| | | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause| + * |Escape|Insert|LSuper| LCtrl| LAlt| | BEPO |QWERTY| |AZERTY| BEPO | | AltGr| RCtrl|RSuper|PrntSc| Pause| * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' * | | | L_Num| | L_Num| | | * | Space|LShift|------| |------|RShift|Enter | @@ -111,7 +111,7 @@ KC_HASH, KC_1, KC_2, KC_3, KC_4, KC_5, KC_TRNS, KC_GRV, S(KC_B), S(KC_E), S(KC_P), S(KC_O), S(KC_E), KC_TRNS, S(KC_W), S(KC_A), S(KC_U), S(KC_I), S(KC_E), KC_SCOLON, S(KC_E), S(KC_A), S(KC_Y), S(KC_X), KC_COLON, S(KC_K), S(KC_TAB), -KC_TRNS, KC_TRNS, S(KC_LGUI), S(KC_LCTL), S(KC_LALT), +S(KC_ESC), S(KC_INS), S(KC_LGUI), S(KC_LCTL), S(KC_LALT), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, @@ -135,7 +135,7 @@ KC_TRNS, KC_TRNS, KC_TRNS), * |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------| * | e | \ | { | } | . | ~ | | | | ' | q | g | h | f | c | * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' - * | BEPO | |LSuper| LCtrl| LAlt| |Escape| | | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause| + * |Escape|Insert|LSuper| LCtrl| LAlt| | BEPO |QWERTY| |AZERTY| BEPO | | AltGr| RCtrl|RSuper|PrntSc| Pause| * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' * | | | L_Num| | L_Num| | | * | _ |LShift|------| |------|RShift|Enter | @@ -148,8 +148,8 @@ KC_DOLLAR, S(KC_QUOT), S(KC_COMM), S(KC_DOT), KC_LBRC, KC_RBRC, KC_DEL, KC_PERCENT, KC_PIPE, KC_E, KC_AMPR, KC_O, KC_E, KC_BSPC, KC_W, KC_A, KC_U, KC_I, RALT(KC_5), KC_COMMA, KC_E, KC_BSLASH, KC_LCBR, KC_RCBR, KC_DOT, KC_TILDE, KC_TAB, -KC_TRNS, KC_NO, KC_LGUI, KC_LCTL, KC_LALT, - KC_ESC, KC_TRNS, +KC_ESC, KC_INS, KC_LGUI, KC_LCTL, KC_LALT, + KC_TRNS, KC_TRNS, MO(NUM), KC_UNDS, MO(SQWER), MO(FNAV), // Right hand @@ -158,7 +158,7 @@ KC_TRNS, KC_NO, KC_LGUI, KC_LCTL, KC_LALT, KC_C, KC_T, KC_S, KC_R, KC_N, KC_M, KC_NUMLOCK, KC_QUOT, KC_Q, KC_G, KC_H, KC_F, KC_C, KC_TRNS, KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE, -KC_TRNS, KC_INS, +KC_TRNS, KC_TRNS, MO(NUM), MO(FNAV), MO(SQWER), KC_ENTER), /* Keymap 4: function / navigation layer diff --git a/keyboards/ergodox_ez/keymaps/bepo/readme.md b/keyboards/ergodox_ez/keymaps/bepo/readme.md index 4a18cd80ff..207b675715 100644 --- a/keyboards/ergodox_ez/keymaps/bepo/readme.md +++ b/keyboards/ergodox_ez/keymaps/bepo/readme.md @@ -27,7 +27,7 @@ Touche de fonction permettant de saisir les touches F1 à F12, les touches F1 à Touche de fonction permettant l'accès au pavé numérique comme sur la TypeMatrix 2030, mais sans avoir à déplacer la main droite : avec les doigts sur la rangée de repos, possibilité de saisir les chiffres "4", "5" et "6" comme sur un pavé numérique classique. Le double "0" de la TypeMatrix a été conservé, et gagne une possibilité de répétition en simples "0". -L'appui sur une touche permet de basculer en mode BEPO sur un système configuré pour un clavier QWERTY. Cette compatibilité n'est pas parfaite (pas encore de gestion des accents mais ça devrait être faisable avec une disposition en qwerty international, et les combinaisons de touches ne sont pas toutes supportées puisque le clavier traduit déjà certaines touches en combinaisons) mais reste pratique pour une saisie de texte occasionnelle. +Touche permettant de basculer en mode BEPO sur un système configuré pour un clavier QWERTY. Cette compatibilité n'est pas parfaite (pas encore de gestion des accents mais ça devrait être faisable avec une disposition en qwerty international, et les combinaisons de touches ne sont pas toutes supportées puisque le clavier traduit déjà certaines touches en combinaisons) mais reste pratique pour une saisie de texte occasionnelle. TODO : couche de compatibilité pour utiliser la disposition BÉPO sur un système configuré pour un clavier AZERTY. From 4cfb262faab653247f4d66d44bf5f3339d82bd36 Mon Sep 17 00:00:00 2001 From: Olivier Date: Mon, 4 Jul 2016 01:10:40 +0200 Subject: [PATCH 05/37] Spellchecking. --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index c24d951d8d..02207702c4 100644 --- a/readme.md +++ b/readme.md @@ -570,7 +570,7 @@ Enable the backlight from the Makefile. All of these functions are available in the `*_kb()` or `*_user()` variety. `kb` ones should only be used in the `/.c` file, and `user` ones should only be used in the `keymap.c`. The keyboard ones call the user ones - it's necessary to keep these calls to allow the keymap functions to work correctly. -## `void martix_init_*(void)` +## `void matrix_init_*(void)` This function gets called when the matrix is initiated, and can contain start-up code for your keyboard/keymap. From b5172e3afab515b1f93cd09c51b4c6c1b5174dc7 Mon Sep 17 00:00:00 2001 From: Olivier Date: Sat, 20 Aug 2016 18:19:03 +0200 Subject: [PATCH 06/37] Rename file following upstream folder rename. --- keyboards/{ergodox_ez => ergodox}/keymaps/bepo/Makefile | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename keyboards/{ergodox_ez => ergodox}/keymaps/bepo/Makefile (100%) diff --git a/keyboards/ergodox_ez/keymaps/bepo/Makefile b/keyboards/ergodox/keymaps/bepo/Makefile similarity index 100% rename from keyboards/ergodox_ez/keymaps/bepo/Makefile rename to keyboards/ergodox/keymaps/bepo/Makefile From b8679bbe045a2285d6ab6bbc420121b26f516b9a Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 5 Oct 2016 20:41:33 -0400 Subject: [PATCH 07/37] RGBW lights --- keyboards/ergodox/config.h | 2 ++ keyboards/ergodox/keymaps/jack/Makefile | 5 +++++ keyboards/ergodox/keymaps/jack/config.h | 14 ++++++++++++++ keyboards/ergodox/keymaps/jack/keymap.c | 4 ++-- quantum/rgblight.c | 18 +++++++++++++++--- quantum/rgblight.h | 1 + 6 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 keyboards/ergodox/keymaps/jack/Makefile create mode 100644 keyboards/ergodox/keymaps/jack/config.h diff --git a/keyboards/ergodox/config.h b/keyboards/ergodox/config.h index edc60caae1..049c707a56 100644 --- a/keyboards/ergodox/config.h +++ b/keyboards/ergodox/config.h @@ -1,6 +1,8 @@ #ifndef KEYBOARDS_ERGODOX_CONFIG_H_ #define KEYBOARDS_ERGODOX_CONFIG_H_ +#include "config_common.h" + #define MOUSEKEY_DELAY 100 #define MOUSEKEY_INTERVAL 20 #define MOUSEKEY_MAX_SPEED 3 diff --git a/keyboards/ergodox/keymaps/jack/Makefile b/keyboards/ergodox/keymaps/jack/Makefile new file mode 100644 index 0000000000..1e57612788 --- /dev/null +++ b/keyboards/ergodox/keymaps/jack/Makefile @@ -0,0 +1,5 @@ +RGBLIGHT_ENABLE = yes + +ifndef QUANTUM_DIR + include ../../../../Makefile +endif diff --git a/keyboards/ergodox/keymaps/jack/config.h b/keyboards/ergodox/keymaps/jack/config.h new file mode 100644 index 0000000000..01ccfb3a2a --- /dev/null +++ b/keyboards/ergodox/keymaps/jack/config.h @@ -0,0 +1,14 @@ +#ifndef CONFIG_USER_H +#define CONFIG_USER_H + +#include "../../config.h" + +/* ws2812 RGB LED */ +#define RGB_DI_PIN D7 +// #define RGBLIGHT_TIMER +#define RGBLED_NUM 20 // Number of LEDs +#define RGBLIGHT_HUE_STEP 8 +#define RGBLIGHT_SAT_STEP 8 +#define RGBLIGHT_VAL_STEP 8 + +#endif \ No newline at end of file diff --git a/keyboards/ergodox/keymaps/jack/keymap.c b/keyboards/ergodox/keymaps/jack/keymap.c index dda253fa45..1dd5a76187 100644 --- a/keyboards/ergodox/keymaps/jack/keymap.c +++ b/keyboards/ergodox/keymaps/jack/keymap.c @@ -24,7 +24,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NO, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH, KC_ENT, MO(1), KC_LEFT,KC_DOWN,KC_UP, KC_RGHT, - KC_NO, KC_NO, + RGB_TOG, RGB_HUI, KC_PGUP, KC_PGDN, KC_SPC,KC_SPC ), @@ -90,7 +90,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) // Runs just one time when the keyboard initializes. void matrix_init_user(void) { - + }; // Runs constantly in the background, in a loop. diff --git a/quantum/rgblight.c b/quantum/rgblight.c index f82e3ec558..801ca1d0d9 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -50,7 +50,11 @@ const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {100, 50, 20}; rgblight_config_t rgblight_config; rgblight_config_t inmem_config; -struct cRGB led[RGBLED_NUM]; +#ifdef RGBW + struct cRGBW led[RGBLED_NUM]; +#else + struct cRGB led[RGBLED_NUM]; +#endif uint8_t rgblight_inited = 0; @@ -334,14 +338,22 @@ void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) { void rgblight_set(void) { if (rgblight_config.enable) { - ws2812_setleds(led, RGBLED_NUM); + #ifdef RGBW + ws2812_setleds_rgbw(led, RGBLED_NUM); + #else + ws2812_setleds(led, RGBLED_NUM); + #endif } else { for (uint8_t i = 0; i < RGBLED_NUM; i++) { led[i].r = 0; led[i].g = 0; led[i].b = 0; } - ws2812_setleds(led, RGBLED_NUM); + #ifdef RGBW + ws2812_setleds_rgbw(led, RGBLED_NUM); + #else + ws2812_setleds(led, RGBLED_NUM); + #endif } } diff --git a/quantum/rgblight.h b/quantum/rgblight.h index def26c428c..2a712d8be4 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -1,6 +1,7 @@ #ifndef RGBLIGHT_H #define RGBLIGHT_H +#define RGBW 1 #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) #define RGBLIGHT_MODES 23 From 5f91fb413624781ac79db641549b9e08753c04b5 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sun, 16 Oct 2016 16:03:33 -0400 Subject: [PATCH 08/37] working with power limit --- build_keyboard.mk | 6 ++ keyboards/ergodox/keymaps/jack/config.h | 2 +- keyboards/ergodox/keymaps/jack/keymap.c | 4 +- quantum/keymap.h | 4 + quantum/light_ws2812.c | 137 +++++++++++++++++++++++- quantum/light_ws2812.h | 7 ++ quantum/quantum.c | 3 + quantum/quantum.h | 4 + 8 files changed, 163 insertions(+), 4 deletions(-) diff --git a/build_keyboard.mk b/build_keyboard.mk index 03a69b1464..cd9f44c7bd 100644 --- a/build_keyboard.mk +++ b/build_keyboard.mk @@ -169,6 +169,12 @@ ifeq ($(strip $(TAP_DANCE_ENABLE)), yes) SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c endif +ifeq ($(strip $(PRINTING_ENABLE)), yes) + OPT_DEFS += -DPRINTING_ENABLE + SRC += $(QUANTUM_DIR)/process_keycode/process_printer.c + SRC += $(TMK_DIR)/protocol/serial_uart.c +endif + ifeq ($(strip $(SERIAL_LINK_ENABLE)), yes) SRC += $(patsubst $(QUANTUM_PATH)/%,%,$(SERIAL_SRC)) OPT_DEFS += $(SERIAL_DEFS) diff --git a/keyboards/ergodox/keymaps/jack/config.h b/keyboards/ergodox/keymaps/jack/config.h index 01ccfb3a2a..f0932084a0 100644 --- a/keyboards/ergodox/keymaps/jack/config.h +++ b/keyboards/ergodox/keymaps/jack/config.h @@ -6,7 +6,7 @@ /* ws2812 RGB LED */ #define RGB_DI_PIN D7 // #define RGBLIGHT_TIMER -#define RGBLED_NUM 20 // Number of LEDs +#define RGBLED_NUM 15 // Number of LEDs #define RGBLIGHT_HUE_STEP 8 #define RGBLIGHT_SAT_STEP 8 #define RGBLIGHT_VAL_STEP 8 diff --git a/keyboards/ergodox/keymaps/jack/keymap.c b/keyboards/ergodox/keymaps/jack/keymap.c index 1dd5a76187..fabd27a618 100644 --- a/keyboards/ergodox/keymaps/jack/keymap.c +++ b/keyboards/ergodox/keymaps/jack/keymap.c @@ -25,7 +25,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_NO, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH, KC_ENT, MO(1), KC_LEFT,KC_DOWN,KC_UP, KC_RGHT, RGB_TOG, RGB_HUI, - KC_PGUP, + RGB_MOD, KC_PGDN, KC_SPC,KC_SPC ), [SYMB] = KEYMAP( @@ -90,7 +90,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) // Runs just one time when the keyboard initializes. void matrix_init_user(void) { - + }; // Runs constantly in the background, in a loop. diff --git a/quantum/keymap.h b/quantum/keymap.h index 98ddfd0c53..41aa116228 100644 --- a/quantum/keymap.h +++ b/quantum/keymap.h @@ -174,6 +174,10 @@ enum quantum_keycodes { // Right shift, close paren KC_RSPC, + // Printing + PRINT_ON, + PRINT_OFF, + // always leave at the end SAFE_RANGE }; diff --git a/quantum/light_ws2812.c b/quantum/light_ws2812.c index 401845e855..d38dac4c69 100755 --- a/quantum/light_ws2812.c +++ b/quantum/light_ws2812.c @@ -16,6 +16,122 @@ #include #include "debug.h" +#define RGBW_BB_TWI 1 + +#ifdef RGBW_BB_TWI + +// Port for the I2C +#define I2C_DDR DDRD +#define I2C_PIN PIND +#define I2C_PORT PORTD + +// Pins to be used in the bit banging +#define I2C_CLK 0 +#define I2C_DAT 1 + +#define I2C_DATA_HI()\ +I2C_DDR &= ~ (1 << I2C_DAT);\ +I2C_PORT |= (1 << I2C_DAT); +#define I2C_DATA_LO()\ +I2C_DDR |= (1 << I2C_DAT);\ +I2C_PORT &= ~ (1 << I2C_DAT); + +#define I2C_CLOCK_HI()\ +I2C_DDR &= ~ (1 << I2C_CLK);\ +I2C_PORT |= (1 << I2C_CLK); +#define I2C_CLOCK_LO()\ +I2C_DDR |= (1 << I2C_CLK);\ +I2C_PORT &= ~ (1 << I2C_CLK); + +#define I2C_DELAY 1 + +void I2C_WriteBit(unsigned char c) +{ + if (c > 0) + { + I2C_DATA_HI(); + } + else + { + I2C_DATA_LO(); + } + + I2C_CLOCK_HI(); + _delay_us(I2C_DELAY); + + I2C_CLOCK_LO(); + _delay_us(I2C_DELAY); + + if (c > 0) + { + I2C_DATA_LO(); + } + + _delay_us(I2C_DELAY); +} + +// Inits bitbanging port, must be called before using the functions below +// +void I2C_Init() +{ + I2C_PORT &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK)); + + I2C_CLOCK_HI(); + I2C_DATA_HI(); + + _delay_us(I2C_DELAY); +} + +// Send a START Condition +// +void I2C_Start() +{ + // set both to high at the same time + I2C_DDR &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK)); + _delay_us(I2C_DELAY); + + I2C_DATA_LO(); + _delay_us(I2C_DELAY); + + I2C_CLOCK_LO(); + _delay_us(I2C_DELAY); +} + +// Send a STOP Condition +// +void I2C_Stop() +{ + I2C_CLOCK_HI(); + _delay_us(I2C_DELAY); + + I2C_DATA_HI(); + _delay_us(I2C_DELAY); +} + +// write a byte to the I2C slave device +// +unsigned char I2C_Write(unsigned char c) +{ + for (char i = 0; i < 8; i++) + { + I2C_WriteBit(c & 128); + + c <<= 1; + } + + + I2C_WriteBit(0); + _delay_us(I2C_DELAY); + _delay_us(I2C_DELAY); + + // _delay_us(I2C_DELAY); + //return I2C_ReadBit(); + return 0; +} + + +#endif + // Setleds for standard RGB void inline ws2812_setleds(struct cRGB *ledarray, uint16_t leds) { @@ -41,6 +157,25 @@ void inline ws2812_setleds_rgbw(struct cRGBW *ledarray, uint16_t leds) _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= _BV(RGB_DI_PIN & 0xF); ws2812_sendarray_mask((uint8_t*)ledarray,leds<<2,_BV(RGB_DI_PIN & 0xF)); + + #ifdef RGBW_BB_TWI + cli(); + TWCR = 0; + I2C_Init(); + I2C_Start(); + I2C_Write(0x84); + uint16_t datlen = leds<<2; + uint8_t curbyte; + uint8_t * data = (uint8_t*)ledarray; + while (datlen--) { + curbyte=*data++; + I2C_Write(curbyte % 0x10); + } + I2C_Stop(); + sei(); + #endif + + _delay_us(80); } @@ -123,7 +258,7 @@ void inline ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi) cli(); while (datlen--) { - curbyte=*data++; + curbyte=(*data++) % 0x10; asm volatile( " ldi %0,8 \n\t" diff --git a/quantum/light_ws2812.h b/quantum/light_ws2812.h index 54eef22d9e..576c3bc483 100755 --- a/quantum/light_ws2812.h +++ b/quantum/light_ws2812.h @@ -16,6 +16,13 @@ #include #include //#include "ws2812_config.h" +#include "i2cmaster.h" + +#define LIGHT_I2C 1 +#define LIGHT_I2C_ADDR 0x84 +#define LIGHT_I2C_ADDR_WRITE ( (LIGHT_I2C_ADDR<<1) | I2C_WRITE ) +#define LIGHT_I2C_ADDR_READ ( (LIGHT_I2C_ADDR<<1) | I2C_READ ) + /* * Structure of the LED array diff --git a/quantum/quantum.c b/quantum/quantum.c index a16bd5443c..5fa5e66b32 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -128,6 +128,9 @@ bool process_record_quantum(keyrecord_t *record) { #endif #ifdef UCIS_ENABLE process_ucis(keycode, record) && + #endif + #ifdef PRINTING_ENABLE + process_printer(keycode, record) && #endif true)) { return false; diff --git a/quantum/quantum.h b/quantum/quantum.h index 0c60466495..06a2e049dc 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -59,6 +59,10 @@ extern uint32_t default_layer_state; #include "process_tap_dance.h" +#ifdef PRINTING_ENABLE + #include "process_printer.h" +#endif + #define SEND_STRING(str) send_string(PSTR(str)) void send_string(const char *str); From a889b899e2cf52b3b7807d8a7ad39f12e0761a10 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sun, 16 Oct 2016 16:03:56 -0400 Subject: [PATCH 09/37] working with power limit --- .../planck/keymaps/thermal_printer/Makefile | 26 ++ .../planck/keymaps/thermal_printer/config.h | 23 ++ .../planck/keymaps/thermal_printer/keymap.c | 314 ++++++++++++++++++ .../planck/keymaps/thermal_printer/readme.md | 2 + quantum/process_keycode/process_printer.c | 254 ++++++++++++++ quantum/process_keycode/process_printer.h | 8 + quantum/process_keycode/process_printer_bb.c | 260 +++++++++++++++ 7 files changed, 887 insertions(+) create mode 100644 keyboards/planck/keymaps/thermal_printer/Makefile create mode 100644 keyboards/planck/keymaps/thermal_printer/config.h create mode 100644 keyboards/planck/keymaps/thermal_printer/keymap.c create mode 100644 keyboards/planck/keymaps/thermal_printer/readme.md create mode 100644 quantum/process_keycode/process_printer.c create mode 100644 quantum/process_keycode/process_printer.h create mode 100644 quantum/process_keycode/process_printer_bb.c diff --git a/keyboards/planck/keymaps/thermal_printer/Makefile b/keyboards/planck/keymaps/thermal_printer/Makefile new file mode 100644 index 0000000000..3d1d11877f --- /dev/null +++ b/keyboards/planck/keymaps/thermal_printer/Makefile @@ -0,0 +1,26 @@ + + +# Build Options +# change to "no" to disable the options, or define them in the Makefile in +# the appropriate keymap folder that will get included automatically +# +BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) +MOUSEKEY_ENABLE = yes # Mouse keys(+4700) +EXTRAKEY_ENABLE = yes # Audio control and System control(+450) +CONSOLE_ENABLE = no # Console for debug(+400) +COMMAND_ENABLE = yes # Commands for debug and configuration +NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality +MIDI_ENABLE = no # MIDI controls +AUDIO_ENABLE = yes # Audio output on port C6 +UNICODE_ENABLE = no # Unicode +BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID +RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time. +PRINTING_ENABLE = yes + +# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE +SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend + +ifndef QUANTUM_DIR + include ../../../../Makefile +endif diff --git a/keyboards/planck/keymaps/thermal_printer/config.h b/keyboards/planck/keymaps/thermal_printer/config.h new file mode 100644 index 0000000000..430b6493cf --- /dev/null +++ b/keyboards/planck/keymaps/thermal_printer/config.h @@ -0,0 +1,23 @@ +#ifndef CONFIG_USER_H +#define CONFIG_USER_H + +#include "../../config.h" + +# define SERIAL_UART_BAUD 19200 +# define SERIAL_UART_DATA UDR1 +# define SERIAL_UART_UBRR (F_CPU / (16UL * SERIAL_UART_BAUD) - 1) +# define SERIAL_UART_RXD_VECT USART1_RX_vect +# define SERIAL_UART_TXD_READY (UCSR1A & _BV(UDRE1)) +# define SERIAL_UART_INIT() do { \ + /* baud rate */ \ + UBRR1L = SERIAL_UART_UBRR; \ + /* baud rate */ \ + UBRR1H = SERIAL_UART_UBRR >> 8; \ + /* enable TX */ \ + UCSR1B = _BV(TXEN1); \ + /* 8-bit data */ \ + UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); \ + sei(); \ + } while(0) + + #endif \ No newline at end of file diff --git a/keyboards/planck/keymaps/thermal_printer/keymap.c b/keyboards/planck/keymaps/thermal_printer/keymap.c new file mode 100644 index 0000000000..e880597319 --- /dev/null +++ b/keyboards/planck/keymaps/thermal_printer/keymap.c @@ -0,0 +1,314 @@ +// This is the canonical layout file for the Quantum project. If you want to add another keyboard, +// this is the style you want to emulate. + +#include "planck.h" +#include "action_layer.h" +#ifdef AUDIO_ENABLE + #include "audio.h" +#endif +#include "eeconfig.h" + +extern keymap_config_t keymap_config; + +// Each layer gets a name for readability, which is then used in the keymap matrix below. +// The underscores don't mean anything - you can have a layer called STUFF or any other name. +// Layer names don't all need to be of the same length, obviously, and you can also skip them +// entirely and just use numbers. +#define _QWERTY 0 +#define _COLEMAK 1 +#define _DVORAK 2 +#define _LOWER 3 +#define _RAISE 4 +#define _PLOVER 5 +#define _ADJUST 16 + +enum planck_keycodes { + QWERTY = SAFE_RANGE, + COLEMAK, + DVORAK, + PLOVER, + LOWER, + RAISE, + BACKLIT, + EXT_PLV +}; + +// Fillers to make layering more clear +#define _______ KC_TRNS +#define XXXXXXX KC_NO + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +/* Qwerty + * ,-----------------------------------------------------------------------------------. + * | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Esc | A | S | D | F | G | H | J | K | L | ; | " | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | Shift| Z | X | C | V | B | N | M | , | . | / |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_QWERTY] = { + {KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC}, + {KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT}, + {KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT }, + {BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT} +}, + +/* Colemak + * ,-----------------------------------------------------------------------------------. + * | Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Esc | A | R | S | T | D | H | N | E | I | O | " | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | Shift| Z | X | C | V | B | K | M | , | . | / |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_COLEMAK] = { + {KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC}, + {KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT}, + {KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT }, + {BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT} +}, + +/* Dvorak + * ,-----------------------------------------------------------------------------------. + * | Tab | " | , | . | P | Y | F | G | C | R | L | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Esc | A | O | E | U | I | D | H | T | N | S | / | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_DVORAK] = { + {KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC}, + {KC_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_SLSH}, + {KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_ENT }, + {BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT} +}, + +/* Lower + * ,-----------------------------------------------------------------------------------. + * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Del | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | { | } | | | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | | |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | Next | Vol- | Vol+ | Play | + * `-----------------------------------------------------------------------------------' + */ +[_LOWER] = { + {KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC}, + {KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE}, + {_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,S(KC_NUHS),S(KC_NUBS),_______, _______, _______}, + {_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY} +}, + +/* Raise + * ,-----------------------------------------------------------------------------------. + * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Del | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO # |ISO / | | |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | Next | Vol- | Vol+ | Play | + * `-----------------------------------------------------------------------------------' + */ +[_RAISE] = { + {KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC}, + {KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS}, + {_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, _______, _______, _______}, + {_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY} +}, + +/* Plover layer (http://opensteno.org) + * ,-----------------------------------------------------------------------------------. + * | # | # | # | # | # | # | # | # | # | # | # | # | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | | S | T | P | H | * | * | F | P | L | T | D | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * |TogOut| S | K | W | R | * | * | R | B | G | S | Z | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Exit | | | A | O | | E | U | | | | + * `-----------------------------------------------------------------------------------' + */ + +[_PLOVER] = { + {KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1 }, + {XXXXXXX, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC}, + {XXXXXXX, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT}, + {EXT_PLV, XXXXXXX, XXXXXXX, KC_C, KC_V, XXXXXXX, XXXXXXX, KC_N, KC_M, XXXXXXX, XXXXXXX, XXXXXXX} +}, + +/* Adjust (Lower + Raise) + * ,-----------------------------------------------------------------------------------. + * | | Reset| | Print|no prnt | | | | | | | Del | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | | | |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak|Plover| | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof| | | | | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | | | | | + * `-----------------------------------------------------------------------------------' + */ +[_ADJUST] = { + {_______, RESET, _______, PRINT_ON, PRINT_OFF, _______, _______, _______, _______, _______, _______, KC_DEL}, + {_______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______}, + {_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______}, + {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______} +} + + +}; + +#ifdef AUDIO_ENABLE + +float tone_startup[][2] = SONG(STARTUP_SOUND); +float tone_qwerty[][2] = SONG(QWERTY_SOUND); +float tone_dvorak[][2] = SONG(DVORAK_SOUND); +float tone_colemak[][2] = SONG(COLEMAK_SOUND); +float tone_plover[][2] = SONG(PLOVER_SOUND); +float tone_plover_gb[][2] = SONG(PLOVER_GOODBYE_SOUND); +float music_scale[][2] = SONG(MUSIC_SCALE_SOUND); + +float tone_goodbye[][2] = SONG(GOODBYE_SOUND); +#endif + + +void persistant_default_layer_set(uint16_t default_layer) { + eeconfig_update_default_layer(default_layer); + default_layer_set(default_layer); +} + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case QWERTY: + if (record->event.pressed) { + #ifdef AUDIO_ENABLE + PLAY_NOTE_ARRAY(tone_qwerty, false, 0); + #endif + persistant_default_layer_set(1UL<<_QWERTY); + } + return false; + break; + case COLEMAK: + if (record->event.pressed) { + #ifdef AUDIO_ENABLE + PLAY_NOTE_ARRAY(tone_colemak, false, 0); + #endif + persistant_default_layer_set(1UL<<_COLEMAK); + } + return false; + break; + case DVORAK: + if (record->event.pressed) { + #ifdef AUDIO_ENABLE + PLAY_NOTE_ARRAY(tone_dvorak, false, 0); + #endif + persistant_default_layer_set(1UL<<_DVORAK); + } + return false; + break; + case LOWER: + if (record->event.pressed) { + layer_on(_LOWER); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } else { + layer_off(_LOWER); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } + return false; + break; + case RAISE: + if (record->event.pressed) { + layer_on(_RAISE); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } else { + layer_off(_RAISE); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } + return false; + break; + case BACKLIT: + if (record->event.pressed) { + register_code(KC_RSFT); + #ifdef BACKLIGHT_ENABLE + backlight_step(); + #endif + } else { + unregister_code(KC_RSFT); + } + return false; + break; + case PLOVER: + if (record->event.pressed) { + #ifdef AUDIO_ENABLE + stop_all_notes(); + PLAY_NOTE_ARRAY(tone_plover, false, 0); + #endif + layer_off(_RAISE); + layer_off(_LOWER); + layer_off(_ADJUST); + layer_on(_PLOVER); + if (!eeconfig_is_enabled()) { + eeconfig_init(); + } + keymap_config.raw = eeconfig_read_keymap(); + keymap_config.nkro = 1; + eeconfig_update_keymap(keymap_config.raw); + } + return false; + break; + case EXT_PLV: + if (record->event.pressed) { + #ifdef AUDIO_ENABLE + PLAY_NOTE_ARRAY(tone_plover_gb, false, 0); + #endif + layer_off(_PLOVER); + } + return false; + break; + } + return true; +} + +void matrix_init_user(void) { + #ifdef AUDIO_ENABLE + startup_user(); + #endif +} + +#ifdef AUDIO_ENABLE + +void startup_user() +{ + _delay_ms(20); // gets rid of tick + PLAY_NOTE_ARRAY(tone_startup, false, 0); +} + +void shutdown_user() +{ + PLAY_NOTE_ARRAY(tone_goodbye, false, 0); + _delay_ms(150); + stop_all_notes(); +} + +void music_on_user(void) +{ + music_scale_user(); +} + +void music_scale_user(void) +{ + PLAY_NOTE_ARRAY(music_scale, false, 0); +} + +#endif diff --git a/keyboards/planck/keymaps/thermal_printer/readme.md b/keyboards/planck/keymaps/thermal_printer/readme.md new file mode 100644 index 0000000000..de9680b498 --- /dev/null +++ b/keyboards/planck/keymaps/thermal_printer/readme.md @@ -0,0 +1,2 @@ +# The Default Planck Layout + diff --git a/quantum/process_keycode/process_printer.c b/quantum/process_keycode/process_printer.c new file mode 100644 index 0000000000..2e11dd366c --- /dev/null +++ b/quantum/process_keycode/process_printer.c @@ -0,0 +1,254 @@ +#include "process_printer.h" +#include "action_util.h" + +bool printing_enabled = false; +uint8_t character_shift = 0; + +void enabled_printing() { + printing_enabled = true; + serial_init(); +} + +void disable_printing() { + printing_enabled = false; +} + +uint8_t shifted_numbers[10] = {0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29}; + +// uint8_t keycode_to_ascii[0xFF][2]; + +// keycode_to_ascii[KC_MINS] = {0x2D, 0x5F}; + +void print_char(char c) { + USB_Disable(); + serial_send(c); + USB_Init(); +} + +void print_box_string(uint8_t text[]) { + uint8_t len = strlen(text); + uint8_t out[len * 3 + 8]; + out[0] = 0xDA; + for (uint8_t i = 0; i < len; i++) { + out[i+1] = 0xC4; + } + out[len + 1] = 0xBF; + out[len + 2] = '\n'; + + out[len + 3] = 0xB3; + for (uint8_t i = 0; i < len; i++) { + out[len + 4 + i] = text[i]; + } + out[len * 2 + 4] = 0xB3; + out[len * 2 + 5] = '\n'; + + + out[len * 2 + 6] = 0xC0; + for (uint8_t i = 0; i < len; i++) { + out[len * 2 + 7 + i] = 0xC4; + } + out[len * 3 + 7] = 0xD9; + out[len * 3 + 8] = '\n'; + + print_string(out); +} + +void print_string(char c[]) { + for(uint8_t i = 0; i < strlen(c); i++) + print_char(c[i]); +} + +bool process_printer(uint16_t keycode, keyrecord_t *record) { + if (keycode == PRINT_ON) { + enabled_printing(); + return false; + } + if (keycode == PRINT_OFF) { + disable_printing(); + return false; + } + + if (printing_enabled) { + switch(keycode) { + case KC_EXLM ... KC_RPRN: + case KC_UNDS: + case KC_PLUS: + case KC_LCBR: + case KC_RCBR: + case KC_PIPE: + case KC_TILD: + keycode &= 0xFF; + case KC_LSFT: + case KC_RSFT: + if (record->event.pressed) { + character_shift++; + } else { + character_shift--; + } + return false; + break; + } + + switch(keycode) { + case KC_F1: + if (record->event.pressed) { + print_box_string("This is a line of text!"); + } + return false; + case KC_ESC: + if (record->event.pressed) { + print_char(0x1B); + } + return false; + break; + case KC_SPC: + if (record->event.pressed) { + print_char(0x20); + } + return false; + break; + case KC_A ... KC_Z: + if (record->event.pressed) { + if (character_shift) { + print_char(0x41 + (keycode - KC_A)); + } else { + print_char(0x61 + (keycode - KC_A)); + } + } + return false; + break; + case KC_1 ... KC_0: + if (record->event.pressed) { + if (character_shift) { + print_char(shifted_numbers[keycode - KC_1]); + } else { + print_char(0x30 + ((keycode - KC_1 + 1) % 10)); + } + } + return false; + break; + case KC_ENT: + if (record->event.pressed) { + if (character_shift) { + print_char(0x0C); + } else { + print_char(0x0A); + } + } + return false; + break; + case KC_BSPC: + if (record->event.pressed) { + if (character_shift) { + print_char(0x18); + } else { + print_char(0x1A); + } + } + return false; + break; + case KC_DOT: + if (record->event.pressed) { + if (character_shift) { + print_char(0x3E); + } else { + print_char(0x2E); + } + } + return false; + break; + case KC_COMM: + if (record->event.pressed) { + if (character_shift) { + print_char(0x3C); + } else { + print_char(0x2C); + } + } + return false; + break; + case KC_SLSH: + if (record->event.pressed) { + if (character_shift) { + print_char(0x3F); + } else { + print_char(0x2F); + } + } + return false; + break; + case KC_QUOT: + if (record->event.pressed) { + if (character_shift) { + print_char(0x22); + } else { + print_char(0x27); + } + } + return false; + break; + case KC_GRV: + if (record->event.pressed) { + if (character_shift) { + print_char(0x7E); + } else { + print_char(0x60); + } + } + return false; + break; + case KC_MINS: + if (record->event.pressed) { + if (character_shift) { + print_char(0x5F); + } else { + print_char(0x2D); + } + } + return false; + break; + case KC_EQL: + if (record->event.pressed) { + if (character_shift) { + print_char(0x2B); + } else { + print_char(0x3D); + } + } + return false; + break; + case KC_LBRC: + if (record->event.pressed) { + if (character_shift) { + print_char(0x7B); + } else { + print_char(0x5B); + } + } + return false; + break; + case KC_RBRC: + if (record->event.pressed) { + if (character_shift) { + print_char(0x7D); + } else { + print_char(0x5D); + } + } + return false; + break; + case KC_BSLS: + if (record->event.pressed) { + if (character_shift) { + print_char(0x7C); + } else { + print_char(0x5C); + } + } + return false; + break; + } + } + return true; + +} \ No newline at end of file diff --git a/quantum/process_keycode/process_printer.h b/quantum/process_keycode/process_printer.h new file mode 100644 index 0000000000..fdd36d75a8 --- /dev/null +++ b/quantum/process_keycode/process_printer.h @@ -0,0 +1,8 @@ +#ifndef PROCESS_PRINTER_H +#define PROCESS_PRINTER_H + +#include "quantum.h" + +#include "protocol/serial.h" + +#endif \ No newline at end of file diff --git a/quantum/process_keycode/process_printer_bb.c b/quantum/process_keycode/process_printer_bb.c new file mode 100644 index 0000000000..1924d03774 --- /dev/null +++ b/quantum/process_keycode/process_printer_bb.c @@ -0,0 +1,260 @@ +#include "process_printer.h" +#include "action_util.h" + +bool printing_enabled = false; +uint8_t character_shift = 0; + +#define SERIAL_PIN_DDR DDRD +#define SERIAL_PIN_PORT PORTD +#define SERIAL_PIN_MASK _BV(PD3) +#define SERIAL_DELAY 52 + +inline static +void serial_delay(void) { + _delay_us(SERIAL_DELAY); +} + +inline static +void serial_high(void) { + SERIAL_PIN_PORT |= SERIAL_PIN_MASK; +} + +inline static +void serial_low(void) { + SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK; +} + +inline static +void serial_output(void) { + SERIAL_PIN_DDR |= SERIAL_PIN_MASK; +} + + +void enabled_printing() { + printing_enabled = true; + serial_output(); + serial_high(); +} + +void disable_printing() { + printing_enabled = false; +} + +uint8_t shifted_numbers[10] = {0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29}; + +// uint8_t keycode_to_ascii[0xFF][2]; + +// keycode_to_ascii[KC_MINS] = {0x2D, 0x5F}; + +void print_char(char c) { + uint8_t b = 8; + serial_output(); + while( b-- ) { + if(c & (1 << b)) { + serial_high(); + } else { + serial_low(); + } + serial_delay(); + } +} + +void print_string(char c[]) { + for(uint8_t i = 0; i < strlen(c); i++) + print_char(c[i]); +} + +bool process_printer(uint16_t keycode, keyrecord_t *record) { + if (keycode == PRINT_ON) { + enabled_printing(); + return false; + } + if (keycode == PRINT_OFF) { + disable_printing(); + return false; + } + + if (printing_enabled) { + switch(keycode) { + case KC_EXLM ... KC_RPRN: + case KC_UNDS: + case KC_PLUS: + case KC_LCBR: + case KC_RCBR: + case KC_PIPE: + case KC_TILD: + keycode &= 0xFF; + case KC_LSFT: + case KC_RSFT: + if (record->event.pressed) { + character_shift++; + } else { + character_shift--; + } + return false; + break; + } + + switch(keycode) { + case KC_F1: + if (record->event.pressed) { + print_string("This is a line of text!\n\n\n"); + } + return false; + case KC_ESC: + if (record->event.pressed) { + print_char(0x1B); + } + return false; + break; + case KC_SPC: + if (record->event.pressed) { + print_char(0x20); + } + return false; + break; + case KC_A ... KC_Z: + if (record->event.pressed) { + if (character_shift) { + print_char(0x41 + (keycode - KC_A)); + } else { + print_char(0x61 + (keycode - KC_A)); + } + } + return false; + break; + case KC_1 ... KC_0: + if (record->event.pressed) { + if (character_shift) { + print_char(shifted_numbers[keycode - KC_1]); + } else { + print_char(0x30 + ((keycode - KC_1 + 1) % 10)); + } + } + return false; + break; + case KC_ENT: + if (record->event.pressed) { + if (character_shift) { + print_char(0x0C); + } else { + print_char(0x0A); + } + } + return false; + break; + case KC_BSPC: + if (record->event.pressed) { + if (character_shift) { + print_char(0x18); + } else { + print_char(0x1A); + } + } + return false; + break; + case KC_DOT: + if (record->event.pressed) { + if (character_shift) { + print_char(0x3E); + } else { + print_char(0x2E); + } + } + return false; + break; + case KC_COMM: + if (record->event.pressed) { + if (character_shift) { + print_char(0x3C); + } else { + print_char(0x2C); + } + } + return false; + break; + case KC_SLSH: + if (record->event.pressed) { + if (character_shift) { + print_char(0x3F); + } else { + print_char(0x2F); + } + } + return false; + break; + case KC_QUOT: + if (record->event.pressed) { + if (character_shift) { + print_char(0x22); + } else { + print_char(0x27); + } + } + return false; + break; + case KC_GRV: + if (record->event.pressed) { + if (character_shift) { + print_char(0x7E); + } else { + print_char(0x60); + } + } + return false; + break; + case KC_MINS: + if (record->event.pressed) { + if (character_shift) { + print_char(0x5F); + } else { + print_char(0x2D); + } + } + return false; + break; + case KC_EQL: + if (record->event.pressed) { + if (character_shift) { + print_char(0x2B); + } else { + print_char(0x3D); + } + } + return false; + break; + case KC_LBRC: + if (record->event.pressed) { + if (character_shift) { + print_char(0x7B); + } else { + print_char(0x5B); + } + } + return false; + break; + case KC_RBRC: + if (record->event.pressed) { + if (character_shift) { + print_char(0x7D); + } else { + print_char(0x5D); + } + } + return false; + break; + case KC_BSLS: + if (record->event.pressed) { + if (character_shift) { + print_char(0x7C); + } else { + print_char(0x5C); + } + } + return false; + break; + } + } + return true; + +} \ No newline at end of file From e9f748751808de2f1e85cf7fb670d78773bd5e76 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sun, 13 Nov 2016 23:02:38 -0500 Subject: [PATCH 10/37] mostly working --- keyboards/ergodox/ez/ez.c | 10 ++- keyboards/ergodox/ez/matrix.c | 2 +- keyboards/ergodox/keymaps/jack/Makefile | 1 + keyboards/ergodox/keymaps/jack/config.h | 4 +- quantum/light_ws2812.c | 21 +++-- quantum/light_ws2812.h | 14 +++- quantum/quantum.c | 1 + quantum/rgblight.c | 101 ++++++++++++------------ quantum/rgblight.h | 10 ++- tmk_core/protocol/lufa/lufa.c | 33 +++++++- 10 files changed, 125 insertions(+), 72 deletions(-) diff --git a/keyboards/ergodox/ez/ez.c b/keyboards/ergodox/ez/ez.c index ddb8ff0cf7..039e4c6bb1 100644 --- a/keyboards/ergodox/ez/ez.c +++ b/keyboards/ergodox/ez/ez.c @@ -16,10 +16,10 @@ void matrix_init_kb(void) { // unused pins - C7, D4, D5, D7, E6 // set as input with internal pull-ip enabled DDRC &= ~(1<<7); - DDRD &= ~(1<<7 | 1<<5 | 1<<4); + DDRD &= ~(1<<5 | 1<<4); DDRE &= ~(1<<6); PORTC |= (1<<7); - PORTD |= (1<<7 | 1<<5 | 1<<4); + PORTD |= (1<<5 | 1<<4); PORTE |= (1<<6); ergodox_blink_all_leds(); @@ -51,6 +51,10 @@ uint8_t init_mcp23018(void) { mcp23018_status = 0x20; // I2C subsystem + + uint8_t sreg_prev; + sreg_prev=SREG; + cli(); if (i2c_initialized == 0) { i2c_init(); // on pins D(1,0) i2c_initialized++; @@ -79,6 +83,8 @@ uint8_t init_mcp23018(void) { out: i2c_stop(); + SREG=sreg_prev; + return mcp23018_status; } diff --git a/keyboards/ergodox/ez/matrix.c b/keyboards/ergodox/ez/matrix.c index a19bab90b2..43f5152591 100644 --- a/keyboards/ergodox/ez/matrix.c +++ b/keyboards/ergodox/ez/matrix.c @@ -121,7 +121,7 @@ void matrix_init(void) matrix_scan_count = 0; #endif - matrix_init_kb(); + matrix_init_quantum(); } diff --git a/keyboards/ergodox/keymaps/jack/Makefile b/keyboards/ergodox/keymaps/jack/Makefile index 1e57612788..7c257af501 100644 --- a/keyboards/ergodox/keymaps/jack/Makefile +++ b/keyboards/ergodox/keymaps/jack/Makefile @@ -1,4 +1,5 @@ RGBLIGHT_ENABLE = yes +MIDI_ENABLE = yes ifndef QUANTUM_DIR include ../../../../Makefile diff --git a/keyboards/ergodox/keymaps/jack/config.h b/keyboards/ergodox/keymaps/jack/config.h index 1781563b84..5bf109c184 100644 --- a/keyboards/ergodox/keymaps/jack/config.h +++ b/keyboards/ergodox/keymaps/jack/config.h @@ -5,10 +5,12 @@ /* ws2812 RGB LED */ #define RGB_DI_PIN D7 -// #define RGBLIGHT_TIMER +#define RGBLIGHT_TIMER #define RGBLED_NUM 15 // Number of LEDs #define RGBLIGHT_HUE_STEP 12 #define RGBLIGHT_SAT_STEP 255 #define RGBLIGHT_VAL_STEP 12 +#define RGB_MIDI + #endif \ No newline at end of file diff --git a/quantum/light_ws2812.c b/quantum/light_ws2812.c index 497543339b..6edbc0f2bd 100755 --- a/quantum/light_ws2812.c +++ b/quantum/light_ws2812.c @@ -133,13 +133,13 @@ unsigned char I2C_Write(unsigned char c) #endif // Setleds for standard RGB -void inline ws2812_setleds(struct cRGB *ledarray, uint16_t leds) +void inline ws2812_setleds(LED_TYPE *ledarray, uint16_t leds) { // ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin)); ws2812_setleds_pin(ledarray,leds, _BV(RGB_DI_PIN & 0xF)); } -void inline ws2812_setleds_pin(struct cRGB *ledarray, uint16_t leds, uint8_t pinmask) +void inline ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmask) { // ws2812_DDRREG |= pinmask; // Enable DDR // new universal format (DDR) @@ -150,12 +150,15 @@ void inline ws2812_setleds_pin(struct cRGB *ledarray, uint16_t leds, uint8_t pin } // Setleds for SK6812RGBW -void inline ws2812_setleds_rgbw(struct cRGBW *ledarray, uint16_t leds) +void inline ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t leds) { #ifdef RGBW_BB_TWI + uint8_t sreg_prev, twcr_prev; + sreg_prev=SREG; + twcr_prev=TWCR; cli(); - TWCR = 0; + TWCR &= ~(1<> 8) & 0xff; - OCR3AL = RGBLED_TIMER_TOP & 0xff; - SREG = sreg; + // static uint8_t rgblight_timer_is_init = 0; + // if (rgblight_timer_is_init) { + // return; + // } + // rgblight_timer_is_init = 1; + // /* Timer 3 setup */ + // TCCR3B = _BV(WGM32) // CTC mode OCR3A as TOP + // | _BV(CS30); // Clock selelct: clk/1 + // /* Set TOP value */ + // uint8_t sreg = SREG; + // cli(); + // OCR3AH = (RGBLED_TIMER_TOP >> 8) & 0xff; + // OCR3AL = RGBLED_TIMER_TOP & 0xff; + // SREG = sreg; + + rgblight_timer_enabled = true; } void rgblight_timer_enable(void) { - TIMSK3 |= _BV(OCIE3A); + rgblight_timer_enabled = true; dprintf("TIMER3 enabled.\n"); } void rgblight_timer_disable(void) { - TIMSK3 &= ~_BV(OCIE3A); + rgblight_timer_enabled = false; dprintf("TIMER3 disabled.\n"); } void rgblight_timer_toggle(void) { - TIMSK3 ^= _BV(OCIE3A); + rgblight_timer_enabled ^= rgblight_timer_enabled; dprintf("TIMER3 toggled.\n"); } -ISR(TIMER3_COMPA_vect) { - // mode = 1, static light, do nothing here - if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) { - // mode = 2 to 5, breathing mode - rgblight_effect_breathing(rgblight_config.mode - 2); - } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 8) { - // mode = 6 to 8, rainbow mood mod - rgblight_effect_rainbow_mood(rgblight_config.mode - 6); - } else if (rgblight_config.mode >= 9 && rgblight_config.mode <= 14) { - // mode = 9 to 14, rainbow swirl mode - rgblight_effect_rainbow_swirl(rgblight_config.mode - 9); - } else if (rgblight_config.mode >= 15 && rgblight_config.mode <= 20) { - // mode = 15 to 20, snake mode - rgblight_effect_snake(rgblight_config.mode - 15); - } else if (rgblight_config.mode >= 21 && rgblight_config.mode <= 23) { - // mode = 21 to 23, knight mode - rgblight_effect_knight(rgblight_config.mode - 21); +void rgblight_task(void) { + if (rgblight_timer_enabled) { + // mode = 1, static light, do nothing here + if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) { + // mode = 2 to 5, breathing mode + rgblight_effect_breathing(rgblight_config.mode - 2); + } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 8) { + // mode = 6 to 8, rainbow mood mod + rgblight_effect_rainbow_mood(rgblight_config.mode - 6); + } else if (rgblight_config.mode >= 9 && rgblight_config.mode <= 14) { + // mode = 9 to 14, rainbow swirl mode + rgblight_effect_rainbow_swirl(rgblight_config.mode - 9); + } else if (rgblight_config.mode >= 15 && rgblight_config.mode <= 20) { + // mode = 15 to 20, snake mode + rgblight_effect_snake(rgblight_config.mode - 15); + } else if (rgblight_config.mode >= 21 && rgblight_config.mode <= 23) { + // mode = 21 to 23, knight mode + rgblight_effect_knight(rgblight_config.mode - 21); + } } } @@ -461,7 +462,7 @@ void rgblight_effect_rainbow_swirl(uint8_t interval) { last_timer = timer_read(); for (i = 0; i < RGBLED_NUM; i++) { hue = (360 / RGBLED_NUM * i + current_hue) % 360; - sethsv(hue, rgblight_config.sat, rgblight_config.val, &led[i]); + sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]); } rgblight_set(); @@ -498,7 +499,7 @@ void rgblight_effect_snake(uint8_t interval) { k = k + RGBLED_NUM; } if (i == k) { - sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val*(RGBLIGHT_EFFECT_SNAKE_LENGTH-j)/RGBLIGHT_EFFECT_SNAKE_LENGTH), &led[i]); + sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val*(RGBLIGHT_EFFECT_SNAKE_LENGTH-j)/RGBLIGHT_EFFECT_SNAKE_LENGTH), (LED_TYPE *)&led[i]); } } } @@ -518,7 +519,7 @@ void rgblight_effect_knight(uint8_t interval) { static uint16_t last_timer = 0; uint8_t i, j, cur; int8_t k; - struct cRGB preled[RGBLED_NUM]; + LED_TYPE preled[RGBLED_NUM]; static int8_t increment = -1; if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_KNIGHT_INTERVALS[interval])) { return; @@ -537,7 +538,7 @@ void rgblight_effect_knight(uint8_t interval) { k = RGBLED_NUM - 1; } if (i == k) { - sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, &preled[i]); + sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&preled[i]); } } } diff --git a/quantum/rgblight.h b/quantum/rgblight.h index efc685f312..d16ba24e53 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -1,8 +1,6 @@ #ifndef RGBLIGHT_H #define RGBLIGHT_H -#define RGBW 1 - #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) #define RGBLIGHT_MODES 23 #else @@ -35,6 +33,7 @@ #endif #define RGBLED_TIMER_TOP F_CPU/(256*64) +// #define RGBLED_TIMER_TOP 0xFF10 #include #include @@ -79,10 +78,13 @@ void eeconfig_update_rgblight(uint32_t val); void eeconfig_update_rgblight_default(void); void eeconfig_debug_rgblight(void); -void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1); -void setrgb(uint8_t r, uint8_t g, uint8_t b, struct cRGB *led1); +void sethsv(uint16_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1); +void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1); void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val); + +void rgblight_task(void); + void rgblight_timer_init(void); void rgblight_timer_enable(void); void rgblight_timer_disable(void); diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index 01c0e45b0b..fe466f6047 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -71,6 +71,10 @@ #include "virtser.h" #endif +#ifdef RGB_MIDI + #include "rgblight.h" +#endif + uint8_t keyboard_idle = 0; /* 0: Boot Protocol, 1: Report Protocol(default) */ uint8_t keyboard_protocol = 1; @@ -1045,6 +1049,10 @@ int main(void) #endif keyboard_task(); +#ifdef RGBLIGHT_ENABLE + rgblight_task(); +#endif + #ifdef VIRTSER_ENABLE virtser_task(); CDC_Device_USBTask(&cdc_device); @@ -1077,15 +1085,34 @@ void fallthrough_callback(MidiDevice * device, #endif } +#ifdef RGB_MIDI + rgblight_config_t rgblight_config; +#endif + void cc_callback(MidiDevice * device, uint8_t chan, uint8_t num, uint8_t val) { //sending it back on the next channel - midi_send_cc(device, (chan + 1) % 16, num, val); + // midi_send_cc(device, (chan + 1) % 16, num, val); + #ifdef RGB_MIDI + rgblight_config.raw = eeconfig_read_rgblight(); + switch (num) { + case 14: + rgblight_config.hue = val * 360 / 127; + break; + case 15: + rgblight_config.sat = val << 1; + break; + case 16: + rgblight_config.val = val << 1; + break; + } + rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val); + #endif } void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) { - for (int i = 0; i < length; i++) - midi_send_cc(device, 15, 0x7F & data[i], 0x7F & (start + i)); + // for (int i = 0; i < length; i++) + // midi_send_cc(device, 15, 0x7F & data[i], 0x7F & (start + i)); } #endif From 530dd3377e4d409a7ca2fee7e47b60b735ebc0fa Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 15 Nov 2016 13:18:10 -0500 Subject: [PATCH 11/37] animations, midi, etc --- quantum/light_ws2812.c | 1 - tmk_core/protocol/lufa/lufa.c | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/quantum/light_ws2812.c b/quantum/light_ws2812.c index 6edbc0f2bd..aac058f534 100755 --- a/quantum/light_ws2812.c +++ b/quantum/light_ws2812.c @@ -171,7 +171,6 @@ void inline ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t leds) } I2C_Stop(); SREG=sreg_prev; - // TWCR = (1< Date: Thu, 17 Nov 2016 17:42:14 -0500 Subject: [PATCH 12/37] rgb light through midi --- keyboards/amj60/config.h | 2 +- keyboards/clueboard/rev1/config.h | 2 +- keyboards/clueboard/rev2/config.h | 2 +- keyboards/cluecard/config.h | 2 +- .../cluecard/keymaps/rgb_effects/config.h | 2 +- keyboards/cluepad/config.h | 2 +- keyboards/ergodox/keymaps/jack/config.h | 3 +- keyboards/gh60/keymaps/robotmaxtron/config.h | 2 +- .../handwired/minorca/keymaps/rgb/config.h | 2 +- keyboards/jd40/config.h | 2 +- keyboards/kc60/keymaps/ws2812/config.h | 2 +- keyboards/lets_split/config.h | 2 +- keyboards/lets_split/keymaps/i2c/config.h | 2 +- keyboards/lets_split/keymaps/serial/config.h | 2 +- keyboards/phantom/config.h | 2 +- .../planck/keymaps/experimental/config.h | 2 +- keyboards/planck/keymaps/yang/config.h | 2 +- keyboards/preonic/config.h | 2 +- keyboards/preonic/keymaps/kinesis/config.h | 2 +- keyboards/satan/config.h | 2 +- keyboards/tada68/config.h | 2 +- quantum/light_ws2812.c | 2 - quantum/rgblight.c | 10 +- quantum/rgblight.h | 2 +- readme.md | 4 +- tmk_core/protocol/lufa/lufa.c | 96 +++++++++++++++++++ 26 files changed, 126 insertions(+), 31 deletions(-) diff --git a/keyboards/amj60/config.h b/keyboards/amj60/config.h index d98e0e9f2f..7c06f9a6c7 100644 --- a/keyboards/amj60/config.h +++ b/keyboards/amj60/config.h @@ -67,7 +67,7 @@ along with this program. If not, see . */ #define RGB_DI_PIN E2 -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 8 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/clueboard/rev1/config.h b/keyboards/clueboard/rev1/config.h index 8c94972324..f40876ffbf 100644 --- a/keyboards/clueboard/rev1/config.h +++ b/keyboards/clueboard/rev1/config.h @@ -26,7 +26,7 @@ /* Underlight configuration */ #define RGB_DI_PIN B2 -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 14 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/clueboard/rev2/config.h b/keyboards/clueboard/rev2/config.h index 15ca4ece86..8435fd02be 100644 --- a/keyboards/clueboard/rev2/config.h +++ b/keyboards/clueboard/rev2/config.h @@ -30,7 +30,7 @@ /* Underlight configuration */ #define RGB_DI_PIN D7 -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 14 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/cluecard/config.h b/keyboards/cluecard/config.h index 765347b131..6520eb5574 100644 --- a/keyboards/cluecard/config.h +++ b/keyboards/cluecard/config.h @@ -140,7 +140,7 @@ along with this program. If not, see . /* Underlight configuration */ #define RGB_DI_PIN E6 -//#define RGBLIGHT_TIMER +//#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 4 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/cluecard/keymaps/rgb_effects/config.h b/keyboards/cluecard/keymaps/rgb_effects/config.h index e88847df4d..c6c9342c81 100644 --- a/keyboards/cluecard/keymaps/rgb_effects/config.h +++ b/keyboards/cluecard/keymaps/rgb_effects/config.h @@ -4,7 +4,7 @@ #include "../../config.h" // place overrides here -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLIGHT_EFFECT_SNAKE_LENGTH 3 #define RGBLIGHT_EFFECT_KNIGHT_LENGTH 2 #define RGBLIGHT_EFFECT_KNIGHT_OFFSET 2 diff --git a/keyboards/cluepad/config.h b/keyboards/cluepad/config.h index bae05fade3..bd64dfd27d 100644 --- a/keyboards/cluepad/config.h +++ b/keyboards/cluepad/config.h @@ -70,7 +70,7 @@ along with this program. If not, see . /* Underlight configuration */ #define RGB_DI_PIN F6 -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 4 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/ergodox/keymaps/jack/config.h b/keyboards/ergodox/keymaps/jack/config.h index 5bf109c184..5c11652264 100644 --- a/keyboards/ergodox/keymaps/jack/config.h +++ b/keyboards/ergodox/keymaps/jack/config.h @@ -5,12 +5,13 @@ /* ws2812 RGB LED */ #define RGB_DI_PIN D7 -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 15 // Number of LEDs #define RGBLIGHT_HUE_STEP 12 #define RGBLIGHT_SAT_STEP 255 #define RGBLIGHT_VAL_STEP 12 #define RGB_MIDI +#define RGBW_BB_TWI #endif \ No newline at end of file diff --git a/keyboards/gh60/keymaps/robotmaxtron/config.h b/keyboards/gh60/keymaps/robotmaxtron/config.h index 6a29e6b8c2..bcd7534617 100644 --- a/keyboards/gh60/keymaps/robotmaxtron/config.h +++ b/keyboards/gh60/keymaps/robotmaxtron/config.h @@ -182,7 +182,7 @@ along with this program. If not, see . #define ws2812_pin PF4 */ #define RGB_DI_PIN F4 -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 8 // Number of LEDs #define RGBLIGHT_HUE_STEP 8 #define RGBLIGHT_SAT_STEP 8 diff --git a/keyboards/handwired/minorca/keymaps/rgb/config.h b/keyboards/handwired/minorca/keymaps/rgb/config.h index deaac2e26f..43b3c59110 100644 --- a/keyboards/handwired/minorca/keymaps/rgb/config.h +++ b/keyboards/handwired/minorca/keymaps/rgb/config.h @@ -11,7 +11,7 @@ /* ws2812 RGB LED */ #define RGB_DI_PIN D5 -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 13 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/jd40/config.h b/keyboards/jd40/config.h index e2594f4b37..047be5707b 100644 --- a/keyboards/jd40/config.h +++ b/keyboards/jd40/config.h @@ -70,7 +70,7 @@ along with this program. If not, see . ) #define RGB_DI_PIN D3 -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 12 // Number of LEDs #define RGBLIGHT_HUE_STEP 8 #define RGBLIGHT_SAT_STEP 8 diff --git a/keyboards/kc60/keymaps/ws2812/config.h b/keyboards/kc60/keymaps/ws2812/config.h index 2f39ea8e55..43abf6228e 100644 --- a/keyboards/kc60/keymaps/ws2812/config.h +++ b/keyboards/kc60/keymaps/ws2812/config.h @@ -2,7 +2,7 @@ /* WS2812B RGB Underglow LED */ #define RGB_DI_PIN F5 // Based on wiring depicted in ws2812_wiring.jpg -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 16 // Number of LEDs. Change this to match your use case. #define RGBLIGHT_HUE_STEP 8 #define RGBLIGHT_SAT_STEP 8 diff --git a/keyboards/lets_split/config.h b/keyboards/lets_split/config.h index f4d900accb..b0ad522fcb 100644 --- a/keyboards/lets_split/config.h +++ b/keyboards/lets_split/config.h @@ -75,7 +75,7 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGB_DI_PIN D4 -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 8 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/lets_split/keymaps/i2c/config.h b/keyboards/lets_split/keymaps/i2c/config.h index 2671fabf6d..72e5ae66ba 100644 --- a/keyboards/lets_split/keymaps/i2c/config.h +++ b/keyboards/lets_split/keymaps/i2c/config.h @@ -75,7 +75,7 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGB_DI_PIN D4 -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 8 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/lets_split/keymaps/serial/config.h b/keyboards/lets_split/keymaps/serial/config.h index f4d900accb..b0ad522fcb 100644 --- a/keyboards/lets_split/keymaps/serial/config.h +++ b/keyboards/lets_split/keymaps/serial/config.h @@ -75,7 +75,7 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGB_DI_PIN D4 -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 8 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/phantom/config.h b/keyboards/phantom/config.h index 983a1d73f2..71a33498b4 100644 --- a/keyboards/phantom/config.h +++ b/keyboards/phantom/config.h @@ -63,7 +63,7 @@ along with this program. If not, see . /* Underlight configuration */ #define RGB_DI_PIN E2 -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 20 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/planck/keymaps/experimental/config.h b/keyboards/planck/keymaps/experimental/config.h index 52acd1905e..cc093bee49 100644 --- a/keyboards/planck/keymaps/experimental/config.h +++ b/keyboards/planck/keymaps/experimental/config.h @@ -9,7 +9,7 @@ /* ws2812 RGB LED */ #define RGB_DI_PIN B1 -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 8 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/planck/keymaps/yang/config.h b/keyboards/planck/keymaps/yang/config.h index feb5a11901..4ed19d76f9 100644 --- a/keyboards/planck/keymaps/yang/config.h +++ b/keyboards/planck/keymaps/yang/config.h @@ -5,7 +5,7 @@ /* ws2812 RGB LED */ #define RGB_DI_PIN D1 -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 28 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/preonic/config.h b/keyboards/preonic/config.h index 3fb978c2f6..f88acf2111 100644 --- a/keyboards/preonic/config.h +++ b/keyboards/preonic/config.h @@ -63,7 +63,7 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGB_DI_PIN D1 -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 28 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/preonic/keymaps/kinesis/config.h b/keyboards/preonic/keymaps/kinesis/config.h index 086baa84ff..e6099ceb82 100644 --- a/keyboards/preonic/keymaps/kinesis/config.h +++ b/keyboards/preonic/keymaps/kinesis/config.h @@ -63,7 +63,7 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGB_DI_PIN D1 -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 28 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/satan/config.h b/keyboards/satan/config.h index 7e9f91cc82..eb357b39e0 100644 --- a/keyboards/satan/config.h +++ b/keyboards/satan/config.h @@ -67,7 +67,7 @@ along with this program. If not, see . */ #define RGB_DI_PIN E2 -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 8 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/tada68/config.h b/keyboards/tada68/config.h index 5d8757936d..19cf9c9b39 100644 --- a/keyboards/tada68/config.h +++ b/keyboards/tada68/config.h @@ -67,7 +67,7 @@ along with this program. If not, see . */ /*#define RGB_DI_PIN E2 -#define RGBLIGHT_TIMER +#define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 2 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/quantum/light_ws2812.c b/quantum/light_ws2812.c index aac058f534..a883b13884 100755 --- a/quantum/light_ws2812.c +++ b/quantum/light_ws2812.c @@ -16,8 +16,6 @@ #include #include "debug.h" -#define RGBW_BB_TWI 1 - #ifdef RGBW_BB_TWI // Port for the I2C diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 1901010bf9..6b58f66547 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -174,7 +174,7 @@ void rgblight_init(void) { } eeconfig_debug_rgblight(); // display current eeprom values - #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + #ifdef RGBLIGHT_ANIMATIONS rgblight_timer_init(); // setup the timer #endif @@ -221,7 +221,7 @@ void rgblight_mode(uint8_t mode) { eeconfig_update_rgblight(rgblight_config.raw); xprintf("rgblight mode: %u\n", rgblight_config.mode); if (rgblight_config.mode == 1) { - #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + #ifdef RGBLIGHT_ANIMATIONS rgblight_timer_disable(); #endif } else if (rgblight_config.mode >= 2 && rgblight_config.mode <= 23) { @@ -231,7 +231,7 @@ void rgblight_mode(uint8_t mode) { // MODE 15-20, snake // MODE 21-23, knight - #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + #ifdef RGBLIGHT_ANIMATIONS rgblight_timer_enable(); #endif } @@ -245,7 +245,7 @@ void rgblight_toggle(void) { if (rgblight_config.enable) { rgblight_mode(rgblight_config.mode); } else { - #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + #ifdef RGBLIGHT_ANIMATIONS rgblight_timer_disable(); #endif _delay_ms(50); @@ -371,7 +371,7 @@ void rgblight_set(void) { } } -#if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) +#ifdef RGBLIGHT_ANIMATIONS // Animation timer -- AVR Timer3 void rgblight_timer_init(void) { diff --git a/quantum/rgblight.h b/quantum/rgblight.h index d16ba24e53..330c2fe1ba 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -1,7 +1,7 @@ #ifndef RGBLIGHT_H #define RGBLIGHT_H -#if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) +#ifdef RGBLIGHT_ANIMATIONS #define RGBLIGHT_MODES 23 #else #define RGBLIGHT_MODES 1 diff --git a/readme.md b/readme.md index d5a259ccb8..2364b53010 100644 --- a/readme.md +++ b/readme.md @@ -1135,12 +1135,12 @@ For this mod, you need an unused pin wiring to DI of WS2812 strip. After wiring RGBLIGHT_ENABLE = yes -In order to use the underglow timer functions, you need to have `#define RGBLIGHT_TIMER` in your `config.h`, and have audio disabled (`AUDIO_ENABLE = no` in your Makefile). +In order to use the underglow animation functions, you need to have `#define RGBLIGHT_ANIMATIONS` in your `config.h`. Please add the following options into your config.h, and set them up according your hardware configuration. These settings are for the `F4` pin by default: #define RGB_DI_PIN F4 // The pin your RGB strip is wired to - #define RGBLIGHT_TIMER // Require for fancier stuff (not compatible with audio) + #define RGBLIGHT_ANIMATIONS // Require for fancier stuff (not compatible with audio) #define RGBLED_NUM 14 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index b628cde370..7eb9be601e 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -51,6 +51,7 @@ #include "descriptor.h" #include "lufa.h" +#include "quantum.h" #ifdef NKRO_ENABLE #include "keycode_config.h" @@ -1111,9 +1112,104 @@ void cc_callback(MidiDevice * device, #endif } +void send_dword(uint32_t number) { + uint16_t word = (number >> 16); + send_word(word); + send_word(number & 0xFFFFUL); +} + +void send_word(uint16_t number) { + uint8_t byte = number >> 8; + send_byte(byte); + send_byte(number & 0xFF); +} + +void send_byte(uint8_t number) { + uint8_t nibble = number >> 4; + send_nibble(nibble); + send_nibble(number & 0xF); +} + +void send_nibble(uint8_t number) { + switch (number) { + case 0: + register_code(KC_0); + unregister_code(KC_0); + break; + case 1 ... 9: + register_code(KC_1 + (number - 1)); + unregister_code(KC_1 + (number - 1)); + break; + case 0xA ... 0xF: + register_code(KC_A + (number - 0xA)); + unregister_code(KC_A + (number - 0xA)); + break; + } +} + +uint8_t midi_buffer[16] = {0}; + void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) { // for (int i = 0; i < length; i++) // midi_send_cc(device, 15, 0x7F & data[i], 0x7F & (start + i)); + // if (start == 0x27) { + // SEND_STRING("\n"); + // send_word(start); + // SEND_STRING(": "); + for (uint8_t place = 0; place < length; place++) { + // send_byte(*data); + midi_buffer[start + place] = *data; + if (*data == 0xF7) + sysex_buffer_callback(start + place, &midi_buffer); + // SEND_STRING(" "); + data++; + } + // } + } + +void sysex_buffer_callback(uint8_t length, uint8_t * data) { + uint8_t * pointer_copy = data; + + if (*data++ != 0xF0) + return + data++; + data++; + data++; + data++; + + switch (*data++) { + case 0x27: ; // RGB LED functions + switch (*data++) + case 0x00: ; // Update HSV + uint32_t part1 = *data++; + uint32_t part2 = *data++; + uint32_t part3 = *data++; + uint32_t part4 = *data++; + uint32_t part5 = *data++; + uint32_t chunk = ((part1 & 0x1FUL) << 28) | (part2 << 21) | (part3 << 14) | (part4 << 7) | part5; + // SEND_STRING("\nCHUNK: "); + // send_dword(chunk); + rgblight_sethsv(((chunk >> 16) & 0xFFFF) % 360, (chunk >> 8) & 0xFF, chunk & 0xFF); + // SEND_STRING("\nHUE: "); + // send_word(((chunk >> 16) & 0xFFFF) % 360); + // SEND_STRING("\nSAT: "); + // send_word((chunk >> 8) & 0xFF); + // SEND_STRING("\nVAL: "); + // send_word(chunk & 0xFF); + break; + case 0x01: ; // Update RGB + break; + break; + } + + // SEND_STRING("\nDATA:\n"); + // while (*pointer_copy != 0xF7) { + // send_byte(*pointer_copy++); + // SEND_STRING(" "); + // } + +} + #endif From 9bbc9a7ce024edb4d80ce65d43c82456e3714928 Mon Sep 17 00:00:00 2001 From: Erez Zukerman Date: Thu, 17 Nov 2016 19:47:08 -0500 Subject: [PATCH 13/37] Initial Erez Experimental keymap tweaks --- keyboards/ergodox/keymaps/erez_experimental/Makefile | 2 ++ keyboards/ergodox/keymaps/erez_experimental/config.h | 11 +++++++++++ keyboards/ergodox/keymaps/erez_experimental/keymap.c | 12 ++++++------ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/keyboards/ergodox/keymaps/erez_experimental/Makefile b/keyboards/ergodox/keymaps/erez_experimental/Makefile index b673c5ce52..dbe89d1410 100644 --- a/keyboards/ergodox/keymaps/erez_experimental/Makefile +++ b/keyboards/ergodox/keymaps/erez_experimental/Makefile @@ -3,6 +3,8 @@ SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend COMMAND_ENABLE = no # Commands for debug and configuration +RGBLIGHT_ENABLE = yes +MIDI_ENABLE = yes ifndef QUANTUM_DIR include ../../../../Makefile diff --git a/keyboards/ergodox/keymaps/erez_experimental/config.h b/keyboards/ergodox/keymaps/erez_experimental/config.h index e5d7fe1885..fbd12ab797 100644 --- a/keyboards/ergodox/keymaps/erez_experimental/config.h +++ b/keyboards/ergodox/keymaps/erez_experimental/config.h @@ -8,5 +8,16 @@ #undef LEADER_TIMEOUT #define LEADER_TIMEOUT 300 + +/* ws2812 RGB LED */ +#define RGB_DI_PIN D7 +#define RGBLIGHT_ANIMATIONS +#define RGBLED_NUM 15 // Number of LEDs +#define RGBLIGHT_HUE_STEP 12 +#define RGBLIGHT_SAT_STEP 255 +#define RGBLIGHT_VAL_STEP 12 + +#define RGB_MIDI +#define RGBW_BB_TWI #endif diff --git a/keyboards/ergodox/keymaps/erez_experimental/keymap.c b/keyboards/ergodox/keymaps/erez_experimental/keymap.c index 4804959d63..b867d36013 100644 --- a/keyboards/ergodox/keymaps/erez_experimental/keymap.c +++ b/keyboards/ergodox/keymaps/erez_experimental/keymap.c @@ -67,9 +67,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * ,-------------. ,-------------. * | | | | | | * ,------|------|------| |------+------+------. - * | | | | | | | | + * |VAI |VAD |HUI | |SAI |TOG |MOD | * | | |------| |------| | | - * | | | | | | | | + * | | |HUD | |SAD | | | * `--------------------' `--------------------' */ // SYMBOLS @@ -81,8 +81,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_TRNS, KC_6, KC_7, KC_8, KC_9, KC_0, KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,LCTL(KC_PGUP), LCTL(KC_PGDN), KC_TRNS,KC_TRNS, - KC_TRNS, - KC_TRNS,KC_TRNS,KC_TRNS, + RGB_HUI, + RGB_VAI,RGB_VAD,RGB_HUD, // right hand KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_F12, @@ -90,8 +90,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_TRNS, KC_PIPE, KC_AT, KC_EQL, KC_PERC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS + RGB_SAI, + RGB_SAD, RGB_TOG, RGB_MOD ), /* Keymap 2: Media and mouse keys * From 285c5a91f23e972d9c579184283443111186329d Mon Sep 17 00:00:00 2001 From: Erez Zukerman Date: Thu, 17 Nov 2016 20:56:36 -0500 Subject: [PATCH 14/37] Groundwork for dedicated color keycodes --- .../keymaps/erez_experimental/keymap.c | 24 ++++++++++++++++++- quantum/rgblight.c | 7 ++++++ quantum/rgblight.h | 1 + 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/keyboards/ergodox/keymaps/erez_experimental/keymap.c b/keyboards/ergodox/keymaps/erez_experimental/keymap.c index b867d36013..4a23c7ac58 100644 --- a/keyboards/ergodox/keymaps/erez_experimental/keymap.c +++ b/keyboards/ergodox/keymaps/erez_experimental/keymap.c @@ -7,6 +7,12 @@ #define SYMB 1 // symbols #define MDIA 2 // media keys +enum custom_keycodes { + PLACEHOLDER = SAFE_RANGE, // can always be here + RGB_FF00BB // always start with RGB_ +}; + + const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { /* Keymap 0: Basic layer * @@ -75,7 +81,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { // SYMBOLS [SYMB] = KEYMAP( // left hand - KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS, + RGB_FF00BB, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_1, KC_2, KC_3, KC_4, KC_5, KC_TRNS, KC_6, KC_7, KC_8, KC_9, KC_0, KC_TRNS, @@ -152,6 +158,22 @@ void matrix_init_user(void) { }; + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + // dynamically generate these. + case RGB_FF00BB: + if (record->event.pressed) { + rgblight_enable(); + rgblight_mode(1); + rgblight_setrgb(0xff,0x00,0xbb); + } + return false; + break; + } + return true; +} + LEADER_EXTERNS(); // Runs constantly in the background, in a loop. diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 6b58f66547..00620da58e 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -253,6 +253,13 @@ void rgblight_toggle(void) { } } +void rgblight_enable(void) { + rgblight_config.enable = 1; + eeconfig_update_rgblight(rgblight_config.raw); + xprintf("rgblight enable: rgblight_config.enable = %u\n", rgblight_config.enable); + rgblight_mode(rgblight_config.mode); +} + void rgblight_increase_hue(void) { uint16_t hue; diff --git a/quantum/rgblight.h b/quantum/rgblight.h index 330c2fe1ba..a3673348e7 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -61,6 +61,7 @@ void rgblight_init(void); void rgblight_increase(void); void rgblight_decrease(void); void rgblight_toggle(void); +void rgblight_enable(void); void rgblight_step(void); void rgblight_mode(uint8_t mode); void rgblight_set(void); From 161bd5596b5d8199f2e56246a27ccbdb8c80bb36 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Fri, 18 Nov 2016 22:22:24 -0500 Subject: [PATCH 15/37] midi back and forth --- keyboards/ergodox/keymaps/jack/keymap.c | 7 ++- tmk_core/protocol/lufa/lufa.c | 62 ++++++++++++++++++------- tmk_core/protocol/lufa/lufa.h | 1 + 3 files changed, 52 insertions(+), 18 deletions(-) diff --git a/keyboards/ergodox/keymaps/jack/keymap.c b/keyboards/ergodox/keymaps/jack/keymap.c index 8721b9644a..eb41f12127 100644 --- a/keyboards/ergodox/keymaps/jack/keymap.c +++ b/keyboards/ergodox/keymaps/jack/keymap.c @@ -26,7 +26,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { MO(1), KC_LEFT,KC_DOWN,KC_UP, KC_RGHT, RGB_TOG, RGB_HUI, RGB_MOD, - KC_PGDN, KC_SPC,KC_SPC + M(2), KC_SPC,KC_SPC ), [SYMB] = KEYMAP( // left hand @@ -89,6 +89,11 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) eeconfig_init(); } break; + case 2: + if (record->event.pressed) { // For resetting EEPROM + send_unicode_midi(0x0CA0); + } + break; } return MACRO_NONE; }; diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index 7eb9be601e..ae9cc2f962 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -1161,7 +1161,7 @@ void sysex_callback(MidiDevice * device, // send_byte(*data); midi_buffer[start + place] = *data; if (*data == 0xF7) - sysex_buffer_callback(start + place, &midi_buffer); + sysex_buffer_callback(device, start + place, &midi_buffer); // SEND_STRING(" "); data++; } @@ -1169,7 +1169,24 @@ void sysex_callback(MidiDevice * device, } -void sysex_buffer_callback(uint8_t length, uint8_t * data) { +uint32_t decode_4byte_chunk(uint8_t * data) { + uint32_t part1 = *data++; + uint32_t part2 = *data++; + uint32_t part3 = *data++; + uint32_t part4 = *data++; + uint32_t part5 = *data++; + return ((part1 & 0x1FUL) << 28) | (part2 << 21) | (part3 << 14) | (part4 << 7) | part5; +} + +void encode_4byte_chunk(uint32_t data, uint8_t * pointer) { + *pointer++ = (data >> 28) & 0x7F; + *pointer++ = (data >> 21) & 0x7F; + *pointer++ = (data >> 14) & 0x7F; + *pointer++ = (data >> 7) & 0x7F; + *pointer++ = (data) & 0x7F; +} + +void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data) { uint8_t * pointer_copy = data; if (*data++ != 0xF0) @@ -1180,28 +1197,31 @@ void sysex_buffer_callback(uint8_t length, uint8_t * data) { data++; switch (*data++) { + case 0x13: ; // Get info from keyboard + switch (*data++) { + case 0x00: ; // Get layer state + // send_dword(layer_state); + uint8_t chunk[5]; + encode_4byte_chunk(layer_state | default_layer_state, &chunk); + + uint8_t array[] = {0xF0, 0x00, 0x00, 0x00, 0x00, chunk[0], chunk[1], chunk[2], chunk[3], chunk[4], 0xF7}; + midi_send_array(&midi_device, 11, &array); + // midi_send_data(device, 3, 0x00, layer_state >> 24 & 0x7f, layer_state >> 16 & 0x7f); + // midi_send_data(device, 6, layer_state >> 8 & 0x7f, layer_state & 0x7f, 0xF7); + break; + } + #ifdef RGBLIGHT_ENABLE case 0x27: ; // RGB LED functions - switch (*data++) + switch (*data++) { case 0x00: ; // Update HSV - uint32_t part1 = *data++; - uint32_t part2 = *data++; - uint32_t part3 = *data++; - uint32_t part4 = *data++; - uint32_t part5 = *data++; - uint32_t chunk = ((part1 & 0x1FUL) << 28) | (part2 << 21) | (part3 << 14) | (part4 << 7) | part5; - // SEND_STRING("\nCHUNK: "); - // send_dword(chunk); + uint32_t chunk = decode_4byte_chunk(data); rgblight_sethsv(((chunk >> 16) & 0xFFFF) % 360, (chunk >> 8) & 0xFF, chunk & 0xFF); - // SEND_STRING("\nHUE: "); - // send_word(((chunk >> 16) & 0xFFFF) % 360); - // SEND_STRING("\nSAT: "); - // send_word((chunk >> 8) & 0xFF); - // SEND_STRING("\nVAL: "); - // send_word(chunk & 0xFF); break; case 0x01: ; // Update RGB break; + } break; + #endif } // SEND_STRING("\nDATA:\n"); @@ -1212,4 +1232,12 @@ void sysex_buffer_callback(uint8_t length, uint8_t * data) { } +void send_unicode_midi(uint32_t unicode) { + uint8_t chunk[5]; + encode_4byte_chunk(unicode, &chunk); + + uint8_t array[] = {0xF0, 0x00, 0x00, 0x00, 0x05, chunk[0], chunk[1], chunk[2], chunk[3], chunk[4], 0xF7}; + midi_send_array(&midi_device, 11, &array); +} + #endif diff --git a/tmk_core/protocol/lufa/lufa.h b/tmk_core/protocol/lufa/lufa.h index aad08d6407..3fec797b6c 100644 --- a/tmk_core/protocol/lufa/lufa.h +++ b/tmk_core/protocol/lufa/lufa.h @@ -70,6 +70,7 @@ typedef struct { #ifdef MIDI_ENABLE void MIDI_Task(void); MidiDevice midi_device; +void send_unicode_midi(uint32_t unicode); #endif // #if LUFA_VERSION_INTEGER < 0x120730 From b57cf3c0c851f2fb0e32c955b16fc6f0ad236e54 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Mon, 21 Nov 2016 12:54:06 -0500 Subject: [PATCH 16/37] more structure to the package --- tmk_core/protocol/lufa/lufa.c | 109 +++++++++++++++++++++++++++------- tmk_core/protocol/lufa/lufa.h | 15 ++++- 2 files changed, 101 insertions(+), 23 deletions(-) diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index ae9cc2f962..cc00b3b89b 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -1147,10 +1147,9 @@ void send_nibble(uint8_t number) { } } -uint8_t midi_buffer[16] = {0}; +uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0}; -void sysex_callback(MidiDevice * device, - uint16_t start, uint8_t length, uint8_t * data) { +void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) { // for (int i = 0; i < length; i++) // midi_send_cc(device, 15, 0x7F & data[i], 0x7F & (start + i)); // if (start == 0x27) { @@ -1169,7 +1168,7 @@ void sysex_callback(MidiDevice * device, } -uint32_t decode_4byte_chunk(uint8_t * data) { +uint32_t decode_uint32_chunk(uint8_t * data) { uint32_t part1 = *data++; uint32_t part2 = *data++; uint32_t part3 = *data++; @@ -1178,7 +1177,13 @@ uint32_t decode_4byte_chunk(uint8_t * data) { return ((part1 & 0x1FUL) << 28) | (part2 << 21) | (part3 << 14) | (part4 << 7) | part5; } -void encode_4byte_chunk(uint32_t data, uint8_t * pointer) { +uint32_t decode_uint8_chunk(uint8_t * data) { + uint32_t part4 = *data++; + uint32_t part5 = *data++; + return (part4 << 7) | part5; +} + +void encode_uint32_chunk(uint32_t data, uint8_t * pointer) { *pointer++ = (data >> 28) & 0x7F; *pointer++ = (data >> 21) & 0x7F; *pointer++ = (data >> 14) & 0x7F; @@ -1186,6 +1191,11 @@ void encode_4byte_chunk(uint32_t data, uint8_t * pointer) { *pointer++ = (data) & 0x7F; } +void encode_uint8_chunk(uint8_t data, uint8_t * pointer) { + *pointer++ = (data >> 7) & 0x7F; + *pointer++ = (data) & 0x7F; +} + void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data) { uint8_t * pointer_copy = data; @@ -1197,28 +1207,77 @@ void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data) data++; switch (*data++) { - case 0x13: ; // Get info from keyboard + case 0x12: ; // Set info on keyboard switch (*data++) { - case 0x00: ; // Get layer state - // send_dword(layer_state); - uint8_t chunk[5]; - encode_4byte_chunk(layer_state | default_layer_state, &chunk); - - uint8_t array[] = {0xF0, 0x00, 0x00, 0x00, 0x00, chunk[0], chunk[1], chunk[2], chunk[3], chunk[4], 0xF7}; - midi_send_array(&midi_device, 11, &array); - // midi_send_data(device, 3, 0x00, layer_state >> 24 & 0x7f, layer_state >> 16 & 0x7f); - // midi_send_data(device, 6, layer_state >> 8 & 0x7f, layer_state & 0x7f, 0xF7); + case 0x02: ; // set default layer + uint8_t default_layer = decode_uint8_chunk(data); + eeconfig_update_default_layer(default_layer); + default_layer_set((uint32_t)default_layer); + break; + case 0x08: ; // set keymap options + uint8_t keymap_options = decode_uint8_chunk(data); + eeconfig_update_keymap(keymap_options); break; } + break; + case 0x13: ; // Get info from keyboard + switch (*data++) { + case 0x00: ; // Handshake + send_bytes_sysex(0x00, NULL, 0); + break; + case 0x01: ; // Get debug state + uint8_t debug[2]; + encode_uint8_chunk(eeprom_read_byte(EECONFIG_DEBUG), &debug); + send_bytes_sysex(0x01, &debug, 2); + break; + case 0x02: ; // Get default layer + uint8_t default_layer[2]; + encode_uint8_chunk(eeprom_read_byte(EECONFIG_DEFAULT_LAYER), &default_layer); + send_bytes_sysex(0x02, &default_layer, 2); + break; + #ifdef AUDIO_ENABLE + case 0x03: ; // Get backlight state + uint8_t audio[2]; + encode_uint8_chunk(eeprom_read_byte(EECONFIG_AUDIO), &audio); + send_bytes_sysex(0x03, &audio, 2); + #endif + case 0x04: ; // Get layer state + uint8_t layers[5]; + encode_uint32_chunk(layer_state, &layers); + send_bytes_sysex(0x04, &layers, 5); + break; + #ifdef BACKLIGHT_ENABLE + case 0x06: ; // Get backlight state + uint8_t backlight[2]; + encode_uint8_chunk(eeprom_read_byte(EECONFIG_BACKLIGHT), &backlight); + send_bytes_sysex(0x06, &backlight, 2); + #endif + #ifdef RGBLIGHT_ENABLE + case 0x07: ; // Get rgblight state + uint8_t rgblight[2]; + encode_uint32_chunk(eeprom_read_dword(EECONFIG_RGBLIGHT), &rgblight); + send_bytes_sysex(0x07, &rgblight, 5); + #endif + case 0x08: ; // Keymap options + uint8_t keymap_options[2]; + encode_uint8_chunk(eeconfig_read_keymap(), &keymap_options); + send_bytes_sysex(0x08, &keymap_options, 2); + break; + } + break; #ifdef RGBLIGHT_ENABLE case 0x27: ; // RGB LED functions switch (*data++) { case 0x00: ; // Update HSV - uint32_t chunk = decode_4byte_chunk(data); - rgblight_sethsv(((chunk >> 16) & 0xFFFF) % 360, (chunk >> 8) & 0xFF, chunk & 0xFF); + uint32_t hsv = decode_uint32_chunk(data); + rgblight_sethsv(((hsv >> 16) & 0xFFFF) % 360, (hsv >> 8) & 0xFF, hsv & 0xFF); break; case 0x01: ; // Update RGB break; + case 0x02: ; // Update mode + uint8_t rgb_mode = decode_uint8_chunk(data); + rgblight_mode(rgb_mode); + break; } break; #endif @@ -1234,10 +1293,20 @@ void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data) void send_unicode_midi(uint32_t unicode) { uint8_t chunk[5]; - encode_4byte_chunk(unicode, &chunk); + encode_uint32_chunk(unicode, &chunk); + send_bytes_sysex(0x05, &chunk, 5); +} - uint8_t array[] = {0xF0, 0x00, 0x00, 0x00, 0x05, chunk[0], chunk[1], chunk[2], chunk[3], chunk[4], 0xF7}; - midi_send_array(&midi_device, 11, &array); +void send_bytes_sysex(uint8_t type, uint8_t * bytes, uint8_t length) { + uint8_t * array = malloc(sizeof(uint8_t) * (length + 6)); + array[0] = 0xF0; + array[1] = 0x00; + array[2] = 0x00; + array[3] = 0x00; + array[4] = type; + array[length + 5] = 0xF7; + memcpy(array + 5, bytes, length); + midi_send_array(&midi_device, length + 6, array); } #endif diff --git a/tmk_core/protocol/lufa/lufa.h b/tmk_core/protocol/lufa/lufa.h index 3fec797b6c..198964f901 100644 --- a/tmk_core/protocol/lufa/lufa.h +++ b/tmk_core/protocol/lufa/lufa.h @@ -68,9 +68,18 @@ typedef struct { } __attribute__ ((packed)) report_extra_t; #ifdef MIDI_ENABLE -void MIDI_Task(void); -MidiDevice midi_device; -void send_unicode_midi(uint32_t unicode); + #define MIDI_SYSEX_BUFFER 16 + void MIDI_Task(void); + MidiDevice midi_device; + + void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data); + uint32_t decode_uint32_chunk(uint8_t * data); + uint32_t decode_uint8_chunk(uint8_t * data); + void encode_uint32_chunk(uint32_t data, uint8_t * pointer); + void encode_uint8_chunk(uint8_t data, uint8_t * pointer); + void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data); + void send_unicode_midi(uint32_t unicode); + void send_bytes_sysex(uint8_t type, uint8_t * bytes, uint8_t length); #endif // #if LUFA_VERSION_INTEGER < 0x120730 From c1037b1dc060d14a09a59f697fefe2b5b91bf373 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Mon, 21 Nov 2016 18:05:06 -0500 Subject: [PATCH 17/37] working with helper, qmk_helper_windows@05b0105 --- keyboards/planck/keymaps/default/Makefile | 8 ++++---- keyboards/planck/keymaps/default/keymap.c | 4 ++-- tmk_core/protocol/lufa/lufa.c | 6 ++++++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/keyboards/planck/keymaps/default/Makefile b/keyboards/planck/keymaps/default/Makefile index 0f4953888d..267a087ea9 100644 --- a/keyboards/planck/keymaps/default/Makefile +++ b/keyboards/planck/keymaps/default/Makefile @@ -5,17 +5,17 @@ # the appropriate keymap folder that will get included automatically # BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) -MOUSEKEY_ENABLE = yes # Mouse keys(+4700) +MOUSEKEY_ENABLE = no # Mouse keys(+4700) EXTRAKEY_ENABLE = yes # Audio control and System control(+450) CONSOLE_ENABLE = no # Console for debug(+400) -COMMAND_ENABLE = yes # Commands for debug and configuration +COMMAND_ENABLE = no # Commands for debug and configuration NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality -MIDI_ENABLE = no # MIDI controls +MIDI_ENABLE = yes # MIDI controls AUDIO_ENABLE = yes # Audio output on port C6 UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID -RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time. +RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend diff --git a/keyboards/planck/keymaps/default/keymap.c b/keyboards/planck/keymaps/default/keymap.c index 5f71ae7d19..ddbe4d7b27 100644 --- a/keyboards/planck/keymaps/default/keymap.c +++ b/keyboards/planck/keymaps/default/keymap.c @@ -107,7 +107,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_LOWER] = { {KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC}, {KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE}, - {_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,S(KC_NUHS),S(KC_NUBS),_______, _______, _______}, + {_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,S(KC_NUHS),S(KC_NUBS),KC_HOME, KC_END, _______}, {_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY} }, @@ -125,7 +125,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_RAISE] = { {KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC}, {KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS}, - {_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, _______, _______, _______}, + {_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, KC_PGUP, KC_PGDN, _______}, {_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY} }, diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index cc00b3b89b..35739e3211 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -1207,6 +1207,12 @@ void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data) data++; switch (*data++) { + case 0x07: ; // Quantum action + break; + case 0x08: ; // Keyboard acion + break; + case 0x09: ; // User action + break; case 0x12: ; // Set info on keyboard switch (*data++) { case 0x02: ; // set default layer From 664c0a036b3d7c3ed39f4a7a78d97f4a9cc7d20c Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Mon, 21 Nov 2016 19:50:55 -0500 Subject: [PATCH 18/37] cleaning up new code --- quantum/light_ws2812.h | 2 +- quantum/quantum.c | 40 ++++++++++++++++ quantum/quantum.h | 5 ++ tmk_core/protocol/lufa/lufa.c | 90 +++++++++++------------------------ 4 files changed, 73 insertions(+), 64 deletions(-) diff --git a/quantum/light_ws2812.h b/quantum/light_ws2812.h index 0bef93d5ec..9498e550e9 100755 --- a/quantum/light_ws2812.h +++ b/quantum/light_ws2812.h @@ -16,7 +16,7 @@ #include #include //#include "ws2812_config.h" -#include "i2cmaster.h" +//#include "i2cmaster.h" #define LIGHT_I2C 1 #define LIGHT_I2C_ADDR 0x84 diff --git a/quantum/quantum.c b/quantum/quantum.c index 9fd9a6ef72..8b2fefef65 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -802,6 +802,46 @@ void backlight_set(uint8_t level) #endif // backlight +// Functions for spitting out values +// + +void send_dword(uint32_t number) { // this might not actually work + uint16_t word = (number >> 16); + send_word(word); + send_word(number & 0xFFFFUL); +} + +void send_word(uint16_t number) { + uint8_t byte = number >> 8; + send_byte(byte); + send_byte(number & 0xFF); +} + +void send_byte(uint8_t number) { + uint8_t nibble = number >> 4; + send_nibble(nibble); + send_nibble(number & 0xF); +} + +void send_nibble(uint8_t number) { + switch (number) { + case 0: + register_code(KC_0); + unregister_code(KC_0); + break; + case 1 ... 9: + register_code(KC_1 + (number - 1)); + unregister_code(KC_1 + (number - 1)); + break; + case 0xA ... 0xF: + register_code(KC_A + (number - 0xA)); + unregister_code(KC_A + (number - 0xA)); + break; + } +} + + + __attribute__ ((weak)) void led_set_user(uint8_t usb_led) { diff --git a/quantum/quantum.h b/quantum/quantum.h index 06a2e049dc..3d35f11fad 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -110,6 +110,11 @@ void breathing_speed_dec(uint8_t value); #endif #endif +void send_dword(uint32_t number); +void send_word(uint16_t number); +void send_byte(uint8_t number); +void send_nibble(uint8_t number); + void led_set_user(uint8_t usb_led); void led_set_kb(uint8_t usb_led); diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index 35739e3211..14da3b8039 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -84,9 +84,9 @@ static uint8_t keyboard_led_stats = 0; static report_keyboard_t keyboard_report_sent; #ifdef MIDI_ENABLE -void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2); -void usb_get_midi(MidiDevice * device); -void midi_usb_init(MidiDevice * device); +static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2); +static void usb_get_midi(MidiDevice * device); +static void midi_usb_init(MidiDevice * device); #endif /* Host driver */ @@ -714,7 +714,7 @@ int8_t sendchar(uint8_t c) ******************************************************************************/ #ifdef MIDI_ENABLE -void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) { +static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) { MIDI_EventPacket_t event; event.Data1 = byte0; event.Data2 = byte1; @@ -774,7 +774,7 @@ void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byt USB_USBTask(); } -void usb_get_midi(MidiDevice * device) { +static void usb_get_midi(MidiDevice * device) { MIDI_EventPacket_t event; while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) { @@ -804,12 +804,12 @@ void usb_get_midi(MidiDevice * device) { USB_USBTask(); } -void midi_usb_init(MidiDevice * device){ +static void midi_usb_init(MidiDevice * device){ midi_device_init(device); midi_device_set_send_func(device, usb_send_func); midi_device_set_pre_input_process_func(device, usb_get_midi); - SetupHardware(); + // SetupHardware(); sei(); } @@ -1112,41 +1112,6 @@ void cc_callback(MidiDevice * device, #endif } -void send_dword(uint32_t number) { - uint16_t word = (number >> 16); - send_word(word); - send_word(number & 0xFFFFUL); -} - -void send_word(uint16_t number) { - uint8_t byte = number >> 8; - send_byte(byte); - send_byte(number & 0xFF); -} - -void send_byte(uint8_t number) { - uint8_t nibble = number >> 4; - send_nibble(nibble); - send_nibble(number & 0xF); -} - -void send_nibble(uint8_t number) { - switch (number) { - case 0: - register_code(KC_0); - unregister_code(KC_0); - break; - case 1 ... 9: - register_code(KC_1 + (number - 1)); - unregister_code(KC_1 + (number - 1)); - break; - case 0xA ... 0xF: - register_code(KC_A + (number - 0xA)); - unregister_code(KC_A + (number - 0xA)); - break; - } -} - uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0}; void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) { @@ -1159,8 +1124,8 @@ void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t for (uint8_t place = 0; place < length; place++) { // send_byte(*data); midi_buffer[start + place] = *data; - if (*data == 0xF7) - sysex_buffer_callback(device, start + place, &midi_buffer); + if (*data == 0xF7 && midi_buffer[0] == 0xF0) + sysex_buffer_callback(device, start + place, midi_buffer); // SEND_STRING(" "); data++; } @@ -1197,10 +1162,9 @@ void encode_uint8_chunk(uint8_t data, uint8_t * pointer) { } void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data) { - uint8_t * pointer_copy = data; + // uint8_t * pointer_copy = data; // use for debugging - if (*data++ != 0xF0) - return + //data++; // i'm 98% sure there's a better way to do this data++; data++; data++; @@ -1233,41 +1197,41 @@ void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data) break; case 0x01: ; // Get debug state uint8_t debug[2]; - encode_uint8_chunk(eeprom_read_byte(EECONFIG_DEBUG), &debug); - send_bytes_sysex(0x01, &debug, 2); + encode_uint8_chunk(eeprom_read_byte(EECONFIG_DEBUG), debug); + send_bytes_sysex(0x01, debug, 2); break; case 0x02: ; // Get default layer uint8_t default_layer[2]; - encode_uint8_chunk(eeprom_read_byte(EECONFIG_DEFAULT_LAYER), &default_layer); - send_bytes_sysex(0x02, &default_layer, 2); + encode_uint8_chunk(eeprom_read_byte(EECONFIG_DEFAULT_LAYER), default_layer); + send_bytes_sysex(0x02, default_layer, 2); break; #ifdef AUDIO_ENABLE case 0x03: ; // Get backlight state uint8_t audio[2]; - encode_uint8_chunk(eeprom_read_byte(EECONFIG_AUDIO), &audio); - send_bytes_sysex(0x03, &audio, 2); + encode_uint8_chunk(eeprom_read_byte(EECONFIG_AUDIO), audio); + send_bytes_sysex(0x03, audio, 2); #endif case 0x04: ; // Get layer state uint8_t layers[5]; - encode_uint32_chunk(layer_state, &layers); - send_bytes_sysex(0x04, &layers, 5); + encode_uint32_chunk(layer_state, layers); + send_bytes_sysex(0x04, layers, 5); break; #ifdef BACKLIGHT_ENABLE case 0x06: ; // Get backlight state uint8_t backlight[2]; - encode_uint8_chunk(eeprom_read_byte(EECONFIG_BACKLIGHT), &backlight); - send_bytes_sysex(0x06, &backlight, 2); + encode_uint8_chunk(eeprom_read_byte(EECONFIG_BACKLIGHT), backlight); + send_bytes_sysex(0x06, backlight, 2); #endif #ifdef RGBLIGHT_ENABLE case 0x07: ; // Get rgblight state uint8_t rgblight[2]; - encode_uint32_chunk(eeprom_read_dword(EECONFIG_RGBLIGHT), &rgblight); - send_bytes_sysex(0x07, &rgblight, 5); + encode_uint32_chunk(eeprom_read_dword(EECONFIG_RGBLIGHT), rgblight); + send_bytes_sysex(0x07, rgblight, 5); #endif case 0x08: ; // Keymap options uint8_t keymap_options[2]; - encode_uint8_chunk(eeconfig_read_keymap(), &keymap_options); - send_bytes_sysex(0x08, &keymap_options, 2); + encode_uint8_chunk(eeconfig_read_keymap(), keymap_options); + send_bytes_sysex(0x08, keymap_options, 2); break; } break; @@ -1299,8 +1263,8 @@ void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data) void send_unicode_midi(uint32_t unicode) { uint8_t chunk[5]; - encode_uint32_chunk(unicode, &chunk); - send_bytes_sysex(0x05, &chunk, 5); + encode_uint32_chunk(unicode, chunk); + send_bytes_sysex(0x05, chunk, 5); } void send_bytes_sysex(uint8_t type, uint8_t * bytes, uint8_t length) { From 6390033e8688550826a4bd3004a2e76568600657 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Mon, 21 Nov 2016 20:14:16 -0500 Subject: [PATCH 19/37] cleaning up midid --- quantum/config_common.h | 99 ++++++++++++++++++----------------- tmk_core/common/host_driver.h | 9 +++- tmk_core/protocol/lufa/lufa.c | 2 +- 3 files changed, 59 insertions(+), 51 deletions(-) diff --git a/quantum/config_common.h b/quantum/config_common.h index 8ed5f4a106..f3897dc2ce 100644 --- a/quantum/config_common.h +++ b/quantum/config_common.h @@ -5,55 +5,56 @@ #define COL2ROW 0 #define ROW2COL 1 /* I/O pins */ -#define B0 0x30 -#define B1 0x31 -#define B2 0x32 -#define B3 0x33 -#define B4 0x34 -#define B5 0x35 -#define B6 0x36 -#define B7 0x37 -#define C0 0x60 -#define C1 0x61 -#define C2 0x62 -#define C3 0x63 -#define C4 0x64 -#define C5 0x65 -#define C6 0x66 -#define C7 0x67 -#define D0 0x90 -#define D1 0x91 -#define D2 0x92 -#define D3 0x93 -#define D4 0x94 -#define D5 0x95 -#define D6 0x96 -#define D7 0x97 -#define E0 0xC0 -#define E1 0xC1 -#define E2 0xC2 -#define E3 0xC3 -#define E4 0xC4 -#define E5 0xC5 -#define E6 0xC6 -#define E7 0xC7 -#define F0 0xF0 -#define F1 0xF1 -#define F2 0xF2 -#define F3 0xF3 -#define F4 0xF4 -#define F5 0xF5 -#define F6 0xF6 -#define F7 0xF7 -#define A0 0x00 -#define A1 0x01 -#define A2 0x02 -#define A3 0x03 -#define A4 0x04 -#define A5 0x05 -#define A6 0x06 -#define A7 0x07 - +#ifndef F0 + #define B0 0x30 + #define B1 0x31 + #define B2 0x32 + #define B3 0x33 + #define B4 0x34 + #define B5 0x35 + #define B6 0x36 + #define B7 0x37 + #define C0 0x60 + #define C1 0x61 + #define C2 0x62 + #define C3 0x63 + #define C4 0x64 + #define C5 0x65 + #define C6 0x66 + #define C7 0x67 + #define D0 0x90 + #define D1 0x91 + #define D2 0x92 + #define D3 0x93 + #define D4 0x94 + #define D5 0x95 + #define D6 0x96 + #define D7 0x97 + #define E0 0xC0 + #define E1 0xC1 + #define E2 0xC2 + #define E3 0xC3 + #define E4 0xC4 + #define E5 0xC5 + #define E6 0xC6 + #define E7 0xC7 + #define F0 0xF0 + #define F1 0xF1 + #define F2 0xF2 + #define F3 0xF3 + #define F4 0xF4 + #define F5 0xF5 + #define F6 0xF6 + #define F7 0xF7 + #define A0 0x00 + #define A1 0x01 + #define A2 0x02 + #define A3 0x03 + #define A4 0x04 + #define A5 0x05 + #define A6 0x06 + #define A7 0x07 +#endif /* USART configuration */ #ifdef BLUETOOTH_ENABLE diff --git a/tmk_core/common/host_driver.h b/tmk_core/common/host_driver.h index edb9e5dd9c..588d1c0be8 100644 --- a/tmk_core/common/host_driver.h +++ b/tmk_core/common/host_driver.h @@ -20,7 +20,9 @@ along with this program. If not, see . #include #include "report.h" - +#ifdef MIDI_ENABLE + #include "midi.h" +#endif typedef struct { uint8_t (*keyboard_leds)(void); @@ -28,6 +30,11 @@ typedef struct { void (*send_mouse)(report_mouse_t *); void (*send_system)(uint16_t); void (*send_consumer)(uint16_t); +#ifdef MIDI_ENABLE + void (*usb_send_func)(MidiDevice *, uint16_t, uint8_t, uint8_t, uint8_t); + void (*usb_get_midi)(MidiDevice *); + void (*midi_usb_init)(MidiDevice *); +#endif } host_driver_t; #endif diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index 14da3b8039..a33a16599e 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -1051,7 +1051,7 @@ int main(void) // MIDI_Task(); #endif -#ifdef RGBLIGHT_ENABLE +#ifdef RGBLIGHT_ANIMATIONS rgblight_task(); #endif From 06a2677b7eedbf58532fa1a673ba1277e756174d Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Mon, 21 Nov 2016 20:17:32 -0500 Subject: [PATCH 20/37] fix infinity --- keyboards/ergodox/config.h | 2 -- keyboards/ergodox/ez/config.h | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/keyboards/ergodox/config.h b/keyboards/ergodox/config.h index 049c707a56..edc60caae1 100644 --- a/keyboards/ergodox/config.h +++ b/keyboards/ergodox/config.h @@ -1,8 +1,6 @@ #ifndef KEYBOARDS_ERGODOX_CONFIG_H_ #define KEYBOARDS_ERGODOX_CONFIG_H_ -#include "config_common.h" - #define MOUSEKEY_DELAY 100 #define MOUSEKEY_INTERVAL 20 #define MOUSEKEY_MAX_SPEED 3 diff --git a/keyboards/ergodox/ez/config.h b/keyboards/ergodox/ez/config.h index 084a044ee1..67a856e511 100644 --- a/keyboards/ergodox/ez/config.h +++ b/keyboards/ergodox/ez/config.h @@ -21,6 +21,8 @@ along with this program. If not, see . #include "../config.h" +#include "config_common.h" + /* USB Device descriptor parameter */ #define VENDOR_ID 0xFEED #define PRODUCT_ID 0x1307 From 3d7aaa31e41a9c96e785b0c089d74dfda525dfbe Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 23 Nov 2016 00:30:06 -0500 Subject: [PATCH 21/37] converted to 8bit messages --- Dockerfile | 3 +- tmk_core/protocol/lufa/lufa.c | 119 +++++++++++++++++++--------------- tmk_core/protocol/midi.mk | 1 + 3 files changed, 70 insertions(+), 53 deletions(-) diff --git a/Dockerfile b/Dockerfile index 744ded8579..c42bbeb32a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,5 +25,4 @@ ENV subproject=ez ENV keymap=default VOLUME /qmk -WORKDIR /qmk -CMD make clean ; make keyboard=${keyboard} subproject=${subproject} keymap=${keymap} +WORKDIR /qmk \ No newline at end of file diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index a33a16599e..c4531c8d73 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -76,6 +76,10 @@ #include "rgblight.h" #endif +#ifdef MIDI_ENABLE + #include "sysex_tools.h" +#endif + uint8_t keyboard_idle = 0; /* 0: Boot Protocol, 1: Report Protocol(default) */ uint8_t keyboard_protocol = 1; @@ -1124,8 +1128,16 @@ void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t for (uint8_t place = 0; place < length; place++) { // send_byte(*data); midi_buffer[start + place] = *data; - if (*data == 0xF7 && midi_buffer[0] == 0xF0) - sysex_buffer_callback(device, start + place, midi_buffer); + if (*data == 0xF7) { + // SEND_STRING("\nRD: "); + // for (uint8_t i = 0; i < start + place + 1; i++){ + // send_byte(midi_buffer[i]); + // SEND_STRING(" "); + // } + uint8_t * decoded = malloc(sizeof(uint8_t) * (sysex_decoded_length(start + place - 4))); + uint16_t decode_length = sysex_decode(decoded, midi_buffer + 4, start + place - 4); + sysex_buffer_callback(device, decode_length, decoded); + } // SEND_STRING(" "); data++; } @@ -1161,32 +1173,35 @@ void encode_uint8_chunk(uint8_t data, uint8_t * pointer) { *pointer++ = (data) & 0x7F; } -void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data) { - // uint8_t * pointer_copy = data; // use for debugging +void dword_to_bytes(uint8_t * bytes, uint32_t dword) { + bytes[0] = (dword >> 24) & 0xFF; + bytes[1] = (dword >> 16) & 0xFF; + bytes[2] = (dword >> 8) & 0xFF; + bytes[3] = (dword >> 0) & 0xFF; +} - //data++; // i'm 98% sure there's a better way to do this - data++; - data++; - data++; - data++; +void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data) { + // SEND_STRING("\nRX: "); + // for (uint8_t i = 0; i < length; i++) { + // send_byte(data[i]); + // SEND_STRING(" "); + // } switch (*data++) { case 0x07: ; // Quantum action break; - case 0x08: ; // Keyboard acion + case 0x08: ; // Keyboard action break; case 0x09: ; // User action break; case 0x12: ; // Set info on keyboard switch (*data++) { case 0x02: ; // set default layer - uint8_t default_layer = decode_uint8_chunk(data); - eeconfig_update_default_layer(default_layer); - default_layer_set((uint32_t)default_layer); + eeconfig_update_default_layer(data[0] << 8 | data[1]); + default_layer_set((uint32_t)(data[0] << 8 | data[1])); break; case 0x08: ; // set keymap options - uint8_t keymap_options = decode_uint8_chunk(data); - eeconfig_update_keymap(keymap_options); + eeconfig_update_keymap(data[0]); break; } break; @@ -1196,42 +1211,37 @@ void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data) send_bytes_sysex(0x00, NULL, 0); break; case 0x01: ; // Get debug state - uint8_t debug[2]; - encode_uint8_chunk(eeprom_read_byte(EECONFIG_DEBUG), debug); - send_bytes_sysex(0x01, debug, 2); + uint8_t debug_bytes[1] = { eeprom_read_byte(EECONFIG_DEBUG) }; + send_bytes_sysex(0x01, debug_bytes, 1); break; case 0x02: ; // Get default layer - uint8_t default_layer[2]; - encode_uint8_chunk(eeprom_read_byte(EECONFIG_DEFAULT_LAYER), default_layer); - send_bytes_sysex(0x02, default_layer, 2); + uint8_t default_bytes[1] = { eeprom_read_byte(EECONFIG_DEFAULT_LAYER) }; + send_bytes_sysex(0x02, default_bytes, 1); break; #ifdef AUDIO_ENABLE case 0x03: ; // Get backlight state - uint8_t audio[2]; - encode_uint8_chunk(eeprom_read_byte(EECONFIG_AUDIO), audio); - send_bytes_sysex(0x03, audio, 2); + uint8_t audio_bytes[1] = { eeprom_read_byte(EECONFIG_AUDIO) }; + send_bytes_sysex(0x03, audio_bytes, 1); #endif case 0x04: ; // Get layer state - uint8_t layers[5]; - encode_uint32_chunk(layer_state, layers); - send_bytes_sysex(0x04, layers, 5); + uint8_t layer_state_bytes[4]; + dword_to_bytes(layer_state_bytes, layer_state); + send_bytes_sysex(0x04, layer_state_bytes, 4); break; #ifdef BACKLIGHT_ENABLE case 0x06: ; // Get backlight state - uint8_t backlight[2]; - encode_uint8_chunk(eeprom_read_byte(EECONFIG_BACKLIGHT), backlight); - send_bytes_sysex(0x06, backlight, 2); + uint8_t backlight_bytes[1] = { eeprom_read_byte(EECONFIG_BACKLIGHT) }; + send_bytes_sysex(0x06, backlight_bytes, 1); #endif #ifdef RGBLIGHT_ENABLE case 0x07: ; // Get rgblight state - uint8_t rgblight[2]; - encode_uint32_chunk(eeprom_read_dword(EECONFIG_RGBLIGHT), rgblight); - send_bytes_sysex(0x07, rgblight, 5); + uint8_t rgblight_bytes[4]; + dword_to_bytes(rgblight_bytes, eeprom_read_dword(EECONFIG_RGBLIGHT)); + send_bytes_sysex(0x07, rgblight_bytes, 4); #endif case 0x08: ; // Keymap options - uint8_t keymap_options[2]; - encode_uint8_chunk(eeconfig_read_keymap(), keymap_options); - send_bytes_sysex(0x08, keymap_options, 2); + uint8_t keymap_bytes[1] = { eeconfig_read_keymap() }; + send_bytes_sysex(0x08, keymap_bytes, 1); break; } break; @@ -1239,26 +1249,18 @@ void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data) case 0x27: ; // RGB LED functions switch (*data++) { case 0x00: ; // Update HSV - uint32_t hsv = decode_uint32_chunk(data); - rgblight_sethsv(((hsv >> 16) & 0xFFFF) % 360, (hsv >> 8) & 0xFF, hsv & 0xFF); + rgblight_sethsv((data[0] << 8 | data[1]) % 360, data[2], data[3]); break; case 0x01: ; // Update RGB break; case 0x02: ; // Update mode - uint8_t rgb_mode = decode_uint8_chunk(data); - rgblight_mode(rgb_mode); + rgblight_mode(data[0]); break; } break; #endif } - // SEND_STRING("\nDATA:\n"); - // while (*pointer_copy != 0xF7) { - // send_byte(*pointer_copy++); - // SEND_STRING(" "); - // } - } void send_unicode_midi(uint32_t unicode) { @@ -1268,15 +1270,30 @@ void send_unicode_midi(uint32_t unicode) { } void send_bytes_sysex(uint8_t type, uint8_t * bytes, uint8_t length) { - uint8_t * array = malloc(sizeof(uint8_t) * (length + 6)); + // SEND_STRING("\nTX: "); + // for (uint8_t i = 0; i < length; i++) { + // send_byte(bytes[i]); + // SEND_STRING(" "); + // } + uint8_t * precode = malloc(sizeof(uint8_t) * (length + 1)); + precode[0] = type; + memcpy(precode + 1, bytes, length); + uint8_t * encoded = malloc(sizeof(uint8_t) * (sysex_encoded_length(length + 1))); + uint16_t encoded_length = sysex_encode(encoded, precode, length + 1); + uint8_t * array = malloc(sizeof(uint8_t) * (encoded_length + 5)); array[0] = 0xF0; array[1] = 0x00; array[2] = 0x00; array[3] = 0x00; - array[4] = type; - array[length + 5] = 0xF7; - memcpy(array + 5, bytes, length); - midi_send_array(&midi_device, length + 6, array); + array[encoded_length + 4] = 0xF7; + memcpy(array + 4, encoded, encoded_length); + midi_send_array(&midi_device, encoded_length + 5, array); + + // SEND_STRING("\nTD: "); + // for (uint8_t i = 0; i < encoded_length + 5; i++) { + // send_byte(array[i]); + // SEND_STRING(" "); + // } } #endif diff --git a/tmk_core/protocol/midi.mk b/tmk_core/protocol/midi.mk index c85ae42ff2..4855b23d30 100644 --- a/tmk_core/protocol/midi.mk +++ b/tmk_core/protocol/midi.mk @@ -4,6 +4,7 @@ SRC += midi.c \ midi_device.c \ bytequeue/bytequeue.c \ bytequeue/interrupt_setting.c \ + sysex_tools.c \ $(LUFA_SRC_USBCLASS) VPATH += $(TMK_PATH)/$(MIDI_DIR) \ No newline at end of file From 2e23689b8e3222982082c1f5a4f8ce7686f9658b Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 23 Nov 2016 18:52:02 -0500 Subject: [PATCH 22/37] converted to new format --- quantum/rgblight.c | 13 ++ quantum/rgblight.h | 1 + tmk_core/protocol/lufa/lufa.c | 313 +++++++++++++++++++++------------- tmk_core/protocol/lufa/lufa.h | 16 +- 4 files changed, 217 insertions(+), 126 deletions(-) diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 00620da58e..bb03d6e913 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -183,6 +183,19 @@ void rgblight_init(void) { } } +void rgblight_update_dword(uint32_t dword) { + rgblight_config.raw = dword; + eeconfig_update_rgblight(rgblight_config.raw); + if (rgblight_config.enable) + rgblight_mode(rgblight_config.mode); + else { + #ifdef RGBLIGHT_ANIMATIONS + rgblight_timer_disable(); + #endif + rgblight_set(); + } +} + void rgblight_increase(void) { uint8_t mode = 0; if (rgblight_config.mode < RGBLIGHT_MODES) { diff --git a/quantum/rgblight.h b/quantum/rgblight.h index a3673348e7..28a410e480 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -65,6 +65,7 @@ void rgblight_enable(void); void rgblight_step(void); void rgblight_mode(uint8_t mode); void rgblight_set(void); +void rgblight_update_dword(uint32_t dword); void rgblight_increase_hue(void); void rgblight_decrease_hue(void); void rgblight_increase_sat(void); diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index c4531c8d73..c3234b8ce5 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -1145,141 +1145,58 @@ void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t } -uint32_t decode_uint32_chunk(uint8_t * data) { - uint32_t part1 = *data++; - uint32_t part2 = *data++; - uint32_t part3 = *data++; - uint32_t part4 = *data++; - uint32_t part5 = *data++; - return ((part1 & 0x1FUL) << 28) | (part2 << 21) | (part3 << 14) | (part4 << 7) | part5; -} - -uint32_t decode_uint8_chunk(uint8_t * data) { - uint32_t part4 = *data++; - uint32_t part5 = *data++; - return (part4 << 7) | part5; -} - -void encode_uint32_chunk(uint32_t data, uint8_t * pointer) { - *pointer++ = (data >> 28) & 0x7F; - *pointer++ = (data >> 21) & 0x7F; - *pointer++ = (data >> 14) & 0x7F; - *pointer++ = (data >> 7) & 0x7F; - *pointer++ = (data) & 0x7F; -} - -void encode_uint8_chunk(uint8_t data, uint8_t * pointer) { - *pointer++ = (data >> 7) & 0x7F; - *pointer++ = (data) & 0x7F; -} - -void dword_to_bytes(uint8_t * bytes, uint32_t dword) { +void dword_to_bytes(uint32_t dword, uint8_t * bytes) { bytes[0] = (dword >> 24) & 0xFF; bytes[1] = (dword >> 16) & 0xFF; bytes[2] = (dword >> 8) & 0xFF; bytes[3] = (dword >> 0) & 0xFF; } -void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data) { - // SEND_STRING("\nRX: "); - // for (uint8_t i = 0; i < length; i++) { - // send_byte(data[i]); - // SEND_STRING(" "); - // } - - switch (*data++) { - case 0x07: ; // Quantum action - break; - case 0x08: ; // Keyboard action - break; - case 0x09: ; // User action - break; - case 0x12: ; // Set info on keyboard - switch (*data++) { - case 0x02: ; // set default layer - eeconfig_update_default_layer(data[0] << 8 | data[1]); - default_layer_set((uint32_t)(data[0] << 8 | data[1])); - break; - case 0x08: ; // set keymap options - eeconfig_update_keymap(data[0]); - break; - } - break; - case 0x13: ; // Get info from keyboard - switch (*data++) { - case 0x00: ; // Handshake - send_bytes_sysex(0x00, NULL, 0); - break; - case 0x01: ; // Get debug state - uint8_t debug_bytes[1] = { eeprom_read_byte(EECONFIG_DEBUG) }; - send_bytes_sysex(0x01, debug_bytes, 1); - break; - case 0x02: ; // Get default layer - uint8_t default_bytes[1] = { eeprom_read_byte(EECONFIG_DEFAULT_LAYER) }; - send_bytes_sysex(0x02, default_bytes, 1); - break; - #ifdef AUDIO_ENABLE - case 0x03: ; // Get backlight state - uint8_t audio_bytes[1] = { eeprom_read_byte(EECONFIG_AUDIO) }; - send_bytes_sysex(0x03, audio_bytes, 1); - #endif - case 0x04: ; // Get layer state - uint8_t layer_state_bytes[4]; - dword_to_bytes(layer_state_bytes, layer_state); - send_bytes_sysex(0x04, layer_state_bytes, 4); - break; - #ifdef BACKLIGHT_ENABLE - case 0x06: ; // Get backlight state - uint8_t backlight_bytes[1] = { eeprom_read_byte(EECONFIG_BACKLIGHT) }; - send_bytes_sysex(0x06, backlight_bytes, 1); - #endif - #ifdef RGBLIGHT_ENABLE - case 0x07: ; // Get rgblight state - uint8_t rgblight_bytes[4]; - dword_to_bytes(rgblight_bytes, eeprom_read_dword(EECONFIG_RGBLIGHT)); - send_bytes_sysex(0x07, rgblight_bytes, 4); - #endif - case 0x08: ; // Keymap options - uint8_t keymap_bytes[1] = { eeconfig_read_keymap() }; - send_bytes_sysex(0x08, keymap_bytes, 1); - break; - } - break; - #ifdef RGBLIGHT_ENABLE - case 0x27: ; // RGB LED functions - switch (*data++) { - case 0x00: ; // Update HSV - rgblight_sethsv((data[0] << 8 | data[1]) % 360, data[2], data[3]); - break; - case 0x01: ; // Update RGB - break; - case 0x02: ; // Update mode - rgblight_mode(data[0]); - break; - } - break; - #endif - } - +uint32_t bytes_to_dword(uint8_t * bytes, uint8_t index) { + return ((uint32_t)bytes[index + 0] << 24) | ((uint32_t)bytes[index + 1] << 16) | ((uint32_t)bytes[index + 2] << 8) | (uint32_t)bytes[index + 3]; } -void send_unicode_midi(uint32_t unicode) { - uint8_t chunk[5]; - encode_uint32_chunk(unicode, chunk); - send_bytes_sysex(0x05, chunk, 5); -} +enum MESSAGE_TYPE { + MT_GET_DATA = 0x10, // Get data from keyboard + MT_GET_DATA_ACK = 0x11, // returned data to process (ACK) + MT_SET_DATA = 0x20, // Set data on keyboard + MT_SET_DATA_ACK = 0x21, // returned data to confirm (ACK) + MT_SEND_DATA = 0x30, // Sending data/action from keyboard + MT_SEND_DATA_ACK = 0x31, // returned data/action confirmation (ACK) + MT_EXE_ACTION = 0x40, // executing actions on keyboard + MT_EXE_ACTION_ACK =0x41, // return confirmation/value (ACK) + MT_TYPE_ERROR = 0x80 // type not recofgnised (ACK) +}; -void send_bytes_sysex(uint8_t type, uint8_t * bytes, uint8_t length) { +enum DATA_TYPE { + DT_NONE = 0x00, + DT_HANDSHAKE, + DT_DEFAULT_LAYER, + DT_CURRENT_LAYER, + DT_KEYMAP_OPTIONS, + DT_BACKLIGHT, + DT_RGBLIGHT, + DT_UNICODE, + DT_DEBUG, + DT_AUDIO, + DT_QUANTUM_ACTION, + DT_KEYBOARD_ACTION, + DT_USER_ACTION, + +}; + +void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint8_t length) { // SEND_STRING("\nTX: "); // for (uint8_t i = 0; i < length; i++) { // send_byte(bytes[i]); // SEND_STRING(" "); // } - uint8_t * precode = malloc(sizeof(uint8_t) * (length + 1)); - precode[0] = type; - memcpy(precode + 1, bytes, length); - uint8_t * encoded = malloc(sizeof(uint8_t) * (sysex_encoded_length(length + 1))); - uint16_t encoded_length = sysex_encode(encoded, precode, length + 1); + uint8_t * precode = malloc(sizeof(uint8_t) * (length + 2)); + precode[0] = message_type; + precode[1] = data_type; + memcpy(precode + 2, bytes, length); + uint8_t * encoded = malloc(sizeof(uint8_t) * (sysex_encoded_length(length + 2))); + uint16_t encoded_length = sysex_encode(encoded, precode, length + 2); uint8_t * array = malloc(sizeof(uint8_t) * (encoded_length + 5)); array[0] = 0xF0; array[1] = 0x00; @@ -1296,4 +1213,158 @@ void send_bytes_sysex(uint8_t type, uint8_t * bytes, uint8_t length) { // } } +#define MT_GET_DATA(data_type, data, length) send_bytes_sysex(MT_GET_DATA, data_type, data, length) +#define MT_GET_DATA_ACK(data_type, data, length) send_bytes_sysex(MT_GET_DATA_ACK, data_type, data, length) +#define MT_SET_DATA(data_type, data, length) send_bytes_sysex(MT_SET_DATA, data_type, data, length) +#define MT_SET_DATA_ACK(data_type, data, length) send_bytes_sysex(MT_SET_DATA_ACK, data_type, data, length) +#define MT_SEND_DATA(data_type, data, length) send_bytes_sysex(MT_SEND_DATA, data_type, data, length) +#define MT_SEND_DATA_ACK(data_type, data, length) send_bytes_sysex(MT_SEND_DATA_ACK, data_type, data, length) +#define MT_EXE_ACTION(data_type, data, length) send_bytes_sysex(MT_EXE_ACTION, data_type, data, length) +#define MT_EXE_ACTION_ACK(data_type, data, length) send_bytes_sysex(MT_EXE_ACTION_ACK, data_type, data, length) + +__attribute__ ((weak)) +bool sysex_process_quantum(uint8_t length, uint8_t * data) { + return sysex_process_keyboard(length, data); +} + +__attribute__ ((weak)) +bool sysex_process_keyboard(uint8_t length, uint8_t * data) { + return sysex_process_user(length, data); +} + +__attribute__ ((weak)) +bool sysex_process_user(uint8_t length, uint8_t * data) { + return true; +} + +void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data) { + // SEND_STRING("\nRX: "); + // for (uint8_t i = 0; i < length; i++) { + // send_byte(data[i]); + // SEND_STRING(" "); + // } + if (!sysex_process_quantum(length, data)) + return; + + switch (data[0]) { + case MT_SET_DATA: + switch (data[1]) { + case DT_DEFAULT_LAYER: { + eeconfig_update_default_layer(data[2]); + default_layer_set((uint32_t)(data[2])); + break; + } + case DT_KEYMAP_OPTIONS: { + eeconfig_update_keymap(data[2]); + break; + } + case DT_RGBLIGHT: { + #ifdef RGBLIGHT_ENABLE + uint32_t rgblight = bytes_to_dword(data, 2); + rgblight_update_dword(rgblight); + #endif + break; + } + } + case MT_GET_DATA: + switch (data[1]) { + case DT_HANDSHAKE: { + MT_GET_DATA_ACK(DT_HANDSHAKE, NULL, 0); + break; + } + case DT_DEBUG: { + uint8_t debug_bytes[1] = { eeprom_read_byte(EECONFIG_DEBUG) }; + MT_GET_DATA_ACK(DT_DEBUG, debug_bytes, 1); + break; + } + case DT_DEFAULT_LAYER: { + uint8_t default_bytes[1] = { eeprom_read_byte(EECONFIG_DEFAULT_LAYER) }; + MT_GET_DATA_ACK(DT_DEFAULT_LAYER, default_bytes, 1); + break; + } + case DT_CURRENT_LAYER: { + uint8_t layer_state_bytes[4]; + dword_to_bytes(layer_state, layer_state_bytes); + MT_GET_DATA_ACK(DT_CURRENT_LAYER, layer_state_bytes, 4); + break; + } + case DT_AUDIO: { + #ifdef AUDIO_ENABLE + uint8_t audio_bytes[1] = { eeprom_read_byte(EECONFIG_AUDIO) }; + MT_GET_DATA_ACK(DT_AUDIO, audio_bytes, 1); + #else + MT_GET_DATA_ACK(DT_AUDIO, NULL, 0); + #endif + break; + } + case DT_BACKLIGHT: { + #ifdef BACKLIGHT_ENABLE + uint8_t backlight_bytes[1] = { eeprom_read_byte(EECONFIG_BACKLIGHT) }; + MT_GET_DATA_ACK(DT_BACKLIGHT, backlight_bytes, 1); + #else + MT_GET_DATA_ACK(DT_BACKLIGHT, NULL, 0); + #endif + break; + } + case DT_RGBLIGHT: { + #ifdef RGBLIGHT_ENABLE + uint8_t rgblight_bytes[4]; + dword_to_bytes(eeconfig_read_rgblight(), rgblight_bytes); + MT_GET_DATA_ACK(DT_RGBLIGHT, rgblight_bytes, 4); + #else + MT_GET_DATA_ACK(DT_RGBLIGHT, NULL, 0) + #endif + break; + } + case DT_KEYMAP_OPTIONS: { + uint8_t keymap_bytes[1] = { eeconfig_read_keymap() }; + MT_GET_DATA_ACK(DT_KEYMAP_OPTIONS, keymap_bytes, 1); + break; + } + default: + break; + } + break; + case MT_SET_DATA_ACK: + case MT_GET_DATA_ACK: + break; + case MT_SEND_DATA: + break; + case MT_SEND_DATA_ACK: + break; + case MT_EXE_ACTION: + break; + case MT_EXE_ACTION_ACK: + break; + case MT_TYPE_ERROR: + break; + default: ; // command not recognised + send_bytes_sysex(MT_TYPE_ERROR, DT_NONE, data, length); + break; + + // #ifdef RGBLIGHT_ENABLE + // case 0x27: ; // RGB LED functions + // switch (*data++) { + // case 0x00: ; // Update HSV + // rgblight_sethsv((data[0] << 8 | data[1]) % 360, data[2], data[3]); + // break; + // case 0x01: ; // Update RGB + // break; + // case 0x02: ; // Update mode + // rgblight_mode(data[0]); + // break; + // } + // break; + // #endif + } + +} + +void send_unicode_midi(uint32_t unicode) { + uint8_t chunk[4]; + dword_to_bytes(unicode, chunk); + MT_SEND_DATA(DT_UNICODE, chunk, 5); +} + + #endif diff --git a/tmk_core/protocol/lufa/lufa.h b/tmk_core/protocol/lufa/lufa.h index 198964f901..99b089f42b 100644 --- a/tmk_core/protocol/lufa/lufa.h +++ b/tmk_core/protocol/lufa/lufa.h @@ -73,13 +73,19 @@ typedef struct { MidiDevice midi_device; void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data); - uint32_t decode_uint32_chunk(uint8_t * data); - uint32_t decode_uint8_chunk(uint8_t * data); - void encode_uint32_chunk(uint32_t data, uint8_t * pointer); - void encode_uint8_chunk(uint8_t data, uint8_t * pointer); void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data); void send_unicode_midi(uint32_t unicode); - void send_bytes_sysex(uint8_t type, uint8_t * bytes, uint8_t length); + void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint8_t length); + + __attribute__ ((weak)) + bool sysex_process_quantum(uint8_t length, uint8_t * data); + + __attribute__ ((weak)) + bool sysex_process_keyboard(uint8_t length, uint8_t * data); + + __attribute__ ((weak)) + bool sysex_process_user(uint8_t length, uint8_t * data); + #endif // #if LUFA_VERSION_INTEGER < 0x120730 From cefa8468fb5f28bd67a0c02d371a4aef0964e20c Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 23 Nov 2016 20:16:38 -0500 Subject: [PATCH 23/37] travis pls --- keyboards/ergodox/infinity/rules.mk | 2 + keyboards/ergodox/keymaps/jack/Makefile | 4 +- quantum/quantum.c | 9 ++++- quantum/quantum.h | 2 + tmk_core/protocol/lufa/lufa.c | 49 +------------------------ tmk_core/protocol/lufa/lufa.h | 42 ++++++++++++++++++++- 6 files changed, 56 insertions(+), 52 deletions(-) diff --git a/keyboards/ergodox/infinity/rules.mk b/keyboards/ergodox/infinity/rules.mk index ccb735a485..473a6dfec6 100644 --- a/keyboards/ergodox/infinity/rules.mk +++ b/keyboards/ergodox/infinity/rules.mk @@ -63,6 +63,8 @@ VISUALIZER_ENABLE ?= no #temporarily disabled to make everything compile LCD_ENABLE ?= yes LED_ENABLE ?= yes LCD_BACKLIGHT_ENABLE ?= yes +MIDI_ENABLE = no +RGBLIGHT_ENABLE = no ifndef QUANTUM_DIR include ../../../Makefile diff --git a/keyboards/ergodox/keymaps/jack/Makefile b/keyboards/ergodox/keymaps/jack/Makefile index 7c257af501..3ca69bb923 100644 --- a/keyboards/ergodox/keymaps/jack/Makefile +++ b/keyboards/ergodox/keymaps/jack/Makefile @@ -1,5 +1,5 @@ -RGBLIGHT_ENABLE = yes -MIDI_ENABLE = yes +RGBLIGHT_ENABLE ?= yes +MIDI_ENABLE ?= yes ifndef QUANTUM_DIR include ../../../../Makefile diff --git a/quantum/quantum.c b/quantum/quantum.c index f9f1ef22d0..8372a7adc5 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -847,8 +847,13 @@ void send_nibble(uint8_t number) { } } - - +void send_unicode_midi(uint32_t unicode) { + #ifdef MIDI_ENABLE + uint8_t chunk[4]; + dword_to_bytes(unicode, chunk); + MT_SEND_DATA(DT_UNICODE, chunk, 5); + #endif +} __attribute__ ((weak)) void led_set_user(uint8_t usb_led) { diff --git a/quantum/quantum.h b/quantum/quantum.h index 3d35f11fad..316da15b9a 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -119,4 +119,6 @@ void send_nibble(uint8_t number); void led_set_user(uint8_t usb_led); void led_set_kb(uint8_t usb_led); +void send_unicode_midi(uint32_t unicode); + #endif diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index c3234b8ce5..eae3e8f298 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -72,7 +72,7 @@ #include "virtser.h" #endif -#ifdef RGB_MIDI +#if (defined(RGB_MIDI) | defined(RGBLIGHT_ANIMATIONS)) & defined(RGBLIGHT_ENABLE) #include "rgblight.h" #endif @@ -1156,35 +1156,6 @@ uint32_t bytes_to_dword(uint8_t * bytes, uint8_t index) { return ((uint32_t)bytes[index + 0] << 24) | ((uint32_t)bytes[index + 1] << 16) | ((uint32_t)bytes[index + 2] << 8) | (uint32_t)bytes[index + 3]; } -enum MESSAGE_TYPE { - MT_GET_DATA = 0x10, // Get data from keyboard - MT_GET_DATA_ACK = 0x11, // returned data to process (ACK) - MT_SET_DATA = 0x20, // Set data on keyboard - MT_SET_DATA_ACK = 0x21, // returned data to confirm (ACK) - MT_SEND_DATA = 0x30, // Sending data/action from keyboard - MT_SEND_DATA_ACK = 0x31, // returned data/action confirmation (ACK) - MT_EXE_ACTION = 0x40, // executing actions on keyboard - MT_EXE_ACTION_ACK =0x41, // return confirmation/value (ACK) - MT_TYPE_ERROR = 0x80 // type not recofgnised (ACK) -}; - -enum DATA_TYPE { - DT_NONE = 0x00, - DT_HANDSHAKE, - DT_DEFAULT_LAYER, - DT_CURRENT_LAYER, - DT_KEYMAP_OPTIONS, - DT_BACKLIGHT, - DT_RGBLIGHT, - DT_UNICODE, - DT_DEBUG, - DT_AUDIO, - DT_QUANTUM_ACTION, - DT_KEYBOARD_ACTION, - DT_USER_ACTION, - -}; - void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint8_t length) { // SEND_STRING("\nTX: "); // for (uint8_t i = 0; i < length; i++) { @@ -1213,15 +1184,6 @@ void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, // } } -#define MT_GET_DATA(data_type, data, length) send_bytes_sysex(MT_GET_DATA, data_type, data, length) -#define MT_GET_DATA_ACK(data_type, data, length) send_bytes_sysex(MT_GET_DATA_ACK, data_type, data, length) -#define MT_SET_DATA(data_type, data, length) send_bytes_sysex(MT_SET_DATA, data_type, data, length) -#define MT_SET_DATA_ACK(data_type, data, length) send_bytes_sysex(MT_SET_DATA_ACK, data_type, data, length) -#define MT_SEND_DATA(data_type, data, length) send_bytes_sysex(MT_SEND_DATA, data_type, data, length) -#define MT_SEND_DATA_ACK(data_type, data, length) send_bytes_sysex(MT_SEND_DATA_ACK, data_type, data, length) -#define MT_EXE_ACTION(data_type, data, length) send_bytes_sysex(MT_EXE_ACTION, data_type, data, length) -#define MT_EXE_ACTION_ACK(data_type, data, length) send_bytes_sysex(MT_EXE_ACTION_ACK, data_type, data, length) - __attribute__ ((weak)) bool sysex_process_quantum(uint8_t length, uint8_t * data) { return sysex_process_keyboard(length, data); @@ -1312,7 +1274,7 @@ void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data) dword_to_bytes(eeconfig_read_rgblight(), rgblight_bytes); MT_GET_DATA_ACK(DT_RGBLIGHT, rgblight_bytes, 4); #else - MT_GET_DATA_ACK(DT_RGBLIGHT, NULL, 0) + MT_GET_DATA_ACK(DT_RGBLIGHT, NULL, 0); #endif break; } @@ -1360,11 +1322,4 @@ void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data) } -void send_unicode_midi(uint32_t unicode) { - uint8_t chunk[4]; - dword_to_bytes(unicode, chunk); - MT_SEND_DATA(DT_UNICODE, chunk, 5); -} - - #endif diff --git a/tmk_core/protocol/lufa/lufa.h b/tmk_core/protocol/lufa/lufa.h index 99b089f42b..0962dda8d8 100644 --- a/tmk_core/protocol/lufa/lufa.h +++ b/tmk_core/protocol/lufa/lufa.h @@ -74,8 +74,9 @@ typedef struct { void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data); void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data); - void send_unicode_midi(uint32_t unicode); void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint8_t length); + void dword_to_bytes(uint32_t dword, uint8_t * bytes); + uint32_t bytes_to_dword(uint8_t * bytes, uint8_t index); __attribute__ ((weak)) bool sysex_process_quantum(uint8_t length, uint8_t * data); @@ -86,6 +87,45 @@ typedef struct { __attribute__ ((weak)) bool sysex_process_user(uint8_t length, uint8_t * data); + enum MESSAGE_TYPE { + MT_GET_DATA = 0x10, // Get data from keyboard + MT_GET_DATA_ACK = 0x11, // returned data to process (ACK) + MT_SET_DATA = 0x20, // Set data on keyboard + MT_SET_DATA_ACK = 0x21, // returned data to confirm (ACK) + MT_SEND_DATA = 0x30, // Sending data/action from keyboard + MT_SEND_DATA_ACK = 0x31, // returned data/action confirmation (ACK) + MT_EXE_ACTION = 0x40, // executing actions on keyboard + MT_EXE_ACTION_ACK =0x41, // return confirmation/value (ACK) + MT_TYPE_ERROR = 0x80 // type not recofgnised (ACK) + }; + + enum DATA_TYPE { + DT_NONE = 0x00, + DT_HANDSHAKE, + DT_DEFAULT_LAYER, + DT_CURRENT_LAYER, + DT_KEYMAP_OPTIONS, + DT_BACKLIGHT, + DT_RGBLIGHT, + DT_UNICODE, + DT_DEBUG, + DT_AUDIO, + DT_QUANTUM_ACTION, + DT_KEYBOARD_ACTION, + DT_USER_ACTION, + + }; + + + #define MT_GET_DATA(data_type, data, length) send_bytes_sysex(MT_GET_DATA, data_type, data, length) + #define MT_GET_DATA_ACK(data_type, data, length) send_bytes_sysex(MT_GET_DATA_ACK, data_type, data, length) + #define MT_SET_DATA(data_type, data, length) send_bytes_sysex(MT_SET_DATA, data_type, data, length) + #define MT_SET_DATA_ACK(data_type, data, length) send_bytes_sysex(MT_SET_DATA_ACK, data_type, data, length) + #define MT_SEND_DATA(data_type, data, length) send_bytes_sysex(MT_SEND_DATA, data_type, data, length) + #define MT_SEND_DATA_ACK(data_type, data, length) send_bytes_sysex(MT_SEND_DATA_ACK, data_type, data, length) + #define MT_EXE_ACTION(data_type, data, length) send_bytes_sysex(MT_EXE_ACTION, data_type, data, length) + #define MT_EXE_ACTION_ACK(data_type, data, length) send_bytes_sysex(MT_EXE_ACTION_ACK, data_type, data, length) + #endif // #if LUFA_VERSION_INTEGER < 0x120730 From f25596b8dc2f15f620c07164d871023d9284618c Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 23 Nov 2016 21:28:12 -0500 Subject: [PATCH 24/37] rgblight fixes --- keyboards/ergodox/keymaps/erez_experimental/Makefile | 4 ++-- keyboards/ergodox/keymaps/erez_experimental/keymap.c | 8 +++++--- tmk_core/protocol/lufa/lufa.c | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/keyboards/ergodox/keymaps/erez_experimental/Makefile b/keyboards/ergodox/keymaps/erez_experimental/Makefile index dbe89d1410..51a0c74c54 100644 --- a/keyboards/ergodox/keymaps/erez_experimental/Makefile +++ b/keyboards/ergodox/keymaps/erez_experimental/Makefile @@ -3,8 +3,8 @@ SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend COMMAND_ENABLE = no # Commands for debug and configuration -RGBLIGHT_ENABLE = yes -MIDI_ENABLE = yes +RGBLIGHT_ENABLE ?= yes +MIDI_ENABLE ?= yes ifndef QUANTUM_DIR include ../../../../Makefile diff --git a/keyboards/ergodox/keymaps/erez_experimental/keymap.c b/keyboards/ergodox/keymaps/erez_experimental/keymap.c index 4a23c7ac58..0c0e3c4e39 100644 --- a/keyboards/ergodox/keymaps/erez_experimental/keymap.c +++ b/keyboards/ergodox/keymaps/erez_experimental/keymap.c @@ -164,9 +164,11 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { // dynamically generate these. case RGB_FF00BB: if (record->event.pressed) { - rgblight_enable(); - rgblight_mode(1); - rgblight_setrgb(0xff,0x00,0xbb); + #ifdef RGBLIGHT_ENABLE + rgblight_enable(); + rgblight_mode(1); + rgblight_setrgb(0xff,0x00,0xbb); + #endif } return false; break; diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index eae3e8f298..aa2e781c80 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -1055,7 +1055,7 @@ int main(void) // MIDI_Task(); #endif -#ifdef RGBLIGHT_ANIMATIONS +#if defined(RGBLIGHT_ANIMATIONS) & defined(RGBLIGHT_ENABLE) rgblight_task(); #endif From 7edac212c8ed8442bf4207e70dc8194631b2bf27 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sat, 26 Nov 2016 15:37:46 -0500 Subject: [PATCH 25/37] separated into api files/folder --- build_keyboard.mk | 8 + common.mk | 1 + keyboards/ergodox/keymaps/jack/keymap.c | 2 +- keyboards/ergodox/rules.mk | 1 - keyboards/planck/rules.mk | 1 + keyboards/preonic/keymaps/default/Makefile | 22 --- keyboards/preonic/rules.mk | 3 +- quantum/api.c | 178 ++++++++++++++++++ quantum/api.h | 59 ++++++ quantum/api/api_sysex.c | 29 +++ quantum/api/api_sysex.h | 10 + quantum/quantum.c | 6 +- quantum/quantum.h | 2 +- tmk_core/protocol/lufa/lufa.c | 203 +-------------------- tmk_core/protocol/lufa/lufa.h | 61 +------ 15 files changed, 303 insertions(+), 283 deletions(-) create mode 100644 quantum/api.c create mode 100644 quantum/api.h create mode 100644 quantum/api/api_sysex.c create mode 100644 quantum/api/api_sysex.h diff --git a/build_keyboard.mk b/build_keyboard.mk index 42f8f8ac7b..c1e5540039 100644 --- a/build_keyboard.mk +++ b/build_keyboard.mk @@ -131,6 +131,14 @@ ifndef CUSTOM_MATRIX SRC += $(QUANTUM_DIR)/matrix.c endif +ifeq ($(strip $(API_SYSEX_ENABLE)), yes) + OPT_DEFS += -DAPI_SYSEX_ENABLE + SRC += $(QUANTUM_DIR)/api/api_sysex.c + OPT_DEFS += -DAPI_ENABLE + SRC += $(QUANTUM_DIR)/api.c + MIDI_ENABLE=yes +endif + ifeq ($(strip $(MIDI_ENABLE)), yes) OPT_DEFS += -DMIDI_ENABLE SRC += $(QUANTUM_DIR)/process_keycode/process_midi.c diff --git a/common.mk b/common.mk index 18751cd5ac..c4b9394a24 100644 --- a/common.mk +++ b/common.mk @@ -23,4 +23,5 @@ COMMON_VPATH += $(QUANTUM_PATH) COMMON_VPATH += $(QUANTUM_PATH)/keymap_extras COMMON_VPATH += $(QUANTUM_PATH)/audio COMMON_VPATH += $(QUANTUM_PATH)/process_keycode +COMMON_VPATH += $(QUANTUM_PATH)/api COMMON_VPATH += $(SERIAL_PATH) \ No newline at end of file diff --git a/keyboards/ergodox/keymaps/jack/keymap.c b/keyboards/ergodox/keymaps/jack/keymap.c index eb41f12127..9cb80c59d1 100644 --- a/keyboards/ergodox/keymaps/jack/keymap.c +++ b/keyboards/ergodox/keymaps/jack/keymap.c @@ -91,7 +91,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) break; case 2: if (record->event.pressed) { // For resetting EEPROM - send_unicode_midi(0x0CA0); + api_send_unicode(0x0CA0); } break; } diff --git a/keyboards/ergodox/rules.mk b/keyboards/ergodox/rules.mk index add64ec76f..2e501e81b2 100644 --- a/keyboards/ergodox/rules.mk +++ b/keyboards/ergodox/rules.mk @@ -24,6 +24,5 @@ COMMAND_ENABLE ?= yes # Commands for debug and configuration CUSTOM_MATRIX ?= yes # Custom matrix file for the ErgoDox EZ SLEEP_LED_ENABLE ?= yes # Breathing sleep LED during USB suspend NKRO_ENABLE ?= yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work -MIDI_ENABLE ?= no # MIDI controls UNICODE_ENABLE ?= yes # Unicode ONEHAND_ENABLE ?= yes # Allow swapping hands of keyboard diff --git a/keyboards/planck/rules.mk b/keyboards/planck/rules.mk index 25db53a315..ccee972715 100644 --- a/keyboards/planck/rules.mk +++ b/keyboards/planck/rules.mk @@ -62,6 +62,7 @@ AUDIO_ENABLE ?= no # Audio output on port C6 UNICODE_ENABLE ?= no # Unicode BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time. +API_SYSEX_ENABLE = yes # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend \ No newline at end of file diff --git a/keyboards/preonic/keymaps/default/Makefile b/keyboards/preonic/keymaps/default/Makefile index 581e08cd02..3d4659ceb9 100644 --- a/keyboards/preonic/keymaps/default/Makefile +++ b/keyboards/preonic/keymaps/default/Makefile @@ -1,25 +1,3 @@ - - -# Build Options -# change to "no" to disable the options, or define them in the Makefile in -# the appropriate keymap folder that will get included automatically -# -BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) -MOUSEKEY_ENABLE = yes # Mouse keys(+4700) -EXTRAKEY_ENABLE = yes # Audio control and System control(+450) -CONSOLE_ENABLE = no # Console for debug(+400) -COMMAND_ENABLE = yes # Commands for debug and configuration -NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work -BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality -MIDI_ENABLE = no # MIDI controls -AUDIO_ENABLE = yes # Audio output on port C6 -UNICODE_ENABLE = no # Unicode -BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID -RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time. - -# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE -SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend - ifndef QUANTUM_DIR include ../../../../Makefile endif \ No newline at end of file diff --git a/keyboards/preonic/rules.mk b/keyboards/preonic/rules.mk index d0f3a3a1c0..c4ce2aacca 100644 --- a/keyboards/preonic/rules.mk +++ b/keyboards/preonic/rules.mk @@ -53,7 +53,7 @@ OPT_DEFS += -DBOOTLOADER_SIZE=4096 # the appropriate keymap folder that will get included automatically # BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000) -MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700) +MOUSEKEY_ENABLE ?= no # Mouse keys(+4700) EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450) CONSOLE_ENABLE ?= no # Console for debug(+400) COMMAND_ENABLE ?= yes # Commands for debug and configuration @@ -64,6 +64,7 @@ AUDIO_ENABLE ?= no # Audio output on port C6 UNICODE_ENABLE ?= no # Unicode BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time. +API_SYSEX_ENABLE ?= yes # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend \ No newline at end of file diff --git a/quantum/api.c b/quantum/api.c new file mode 100644 index 0000000000..4ca3b96762 --- /dev/null +++ b/quantum/api.c @@ -0,0 +1,178 @@ +#include "api.h" +#include "quantum.h" + +void dword_to_bytes(uint32_t dword, uint8_t * bytes) { + bytes[0] = (dword >> 24) & 0xFF; + bytes[1] = (dword >> 16) & 0xFF; + bytes[2] = (dword >> 8) & 0xFF; + bytes[3] = (dword >> 0) & 0xFF; +} + +uint32_t bytes_to_dword(uint8_t * bytes, uint8_t index) { + return ((uint32_t)bytes[index + 0] << 24) | ((uint32_t)bytes[index + 1] << 16) | ((uint32_t)bytes[index + 2] << 8) | (uint32_t)bytes[index + 3]; +} + +__attribute__ ((weak)) +bool process_api_quantum(uint8_t length, uint8_t * data) { + return process_api_keyboard(length, data); +} + +__attribute__ ((weak)) +bool process_api_keyboard(uint8_t length, uint8_t * data) { + return process_api_user(length, data); +} + +__attribute__ ((weak)) +bool process_api_user(uint8_t length, uint8_t * data) { + return true; +} + +void process_api(uint16_t length, uint8_t * data) { + // SEND_STRING("\nRX: "); + // for (uint8_t i = 0; i < length; i++) { + // send_byte(data[i]); + // SEND_STRING(" "); + // } + if (!process_api_quantum(length, data)) + return; + + switch (data[0]) { + case MT_SET_DATA: + switch (data[1]) { + case DT_DEFAULT_LAYER: { + eeconfig_update_default_layer(data[2]); + default_layer_set((uint32_t)(data[2])); + break; + } + case DT_KEYMAP_OPTIONS: { + eeconfig_update_keymap(data[2]); + break; + } + case DT_RGBLIGHT: { + #ifdef RGBLIGHT_ENABLE + uint32_t rgblight = bytes_to_dword(data, 2); + rgblight_update_dword(rgblight); + #endif + break; + } + } + case MT_GET_DATA: + switch (data[1]) { + case DT_HANDSHAKE: { + MT_GET_DATA_ACK(DT_HANDSHAKE, NULL, 0); + break; + } + case DT_DEBUG: { + uint8_t debug_bytes[1] = { eeprom_read_byte(EECONFIG_DEBUG) }; + MT_GET_DATA_ACK(DT_DEBUG, debug_bytes, 1); + break; + } + case DT_DEFAULT_LAYER: { + uint8_t default_bytes[1] = { eeprom_read_byte(EECONFIG_DEFAULT_LAYER) }; + MT_GET_DATA_ACK(DT_DEFAULT_LAYER, default_bytes, 1); + break; + } + case DT_CURRENT_LAYER: { + uint8_t layer_state_bytes[4]; + dword_to_bytes(layer_state, layer_state_bytes); + MT_GET_DATA_ACK(DT_CURRENT_LAYER, layer_state_bytes, 4); + break; + } + case DT_AUDIO: { + #ifdef AUDIO_ENABLE + uint8_t audio_bytes[1] = { eeprom_read_byte(EECONFIG_AUDIO) }; + MT_GET_DATA_ACK(DT_AUDIO, audio_bytes, 1); + #else + MT_GET_DATA_ACK(DT_AUDIO, NULL, 0); + #endif + break; + } + case DT_BACKLIGHT: { + #ifdef BACKLIGHT_ENABLE + uint8_t backlight_bytes[1] = { eeprom_read_byte(EECONFIG_BACKLIGHT) }; + MT_GET_DATA_ACK(DT_BACKLIGHT, backlight_bytes, 1); + #else + MT_GET_DATA_ACK(DT_BACKLIGHT, NULL, 0); + #endif + break; + } + case DT_RGBLIGHT: { + #ifdef RGBLIGHT_ENABLE + uint8_t rgblight_bytes[4]; + dword_to_bytes(eeconfig_read_rgblight(), rgblight_bytes); + MT_GET_DATA_ACK(DT_RGBLIGHT, rgblight_bytes, 4); + #else + MT_GET_DATA_ACK(DT_RGBLIGHT, NULL, 0); + #endif + break; + } + case DT_KEYMAP_OPTIONS: { + uint8_t keymap_bytes[1] = { eeconfig_read_keymap() }; + MT_GET_DATA_ACK(DT_KEYMAP_OPTIONS, keymap_bytes, 1); + break; + } + case DT_KEYMAP_SIZE: { + uint8_t keymap_size[2] = {MATRIX_ROWS, MATRIX_COLS}; + MT_GET_DATA_ACK(DT_KEYMAP_SIZE, keymap_size, 2); + break; + } + case DT_KEYMAP: { + uint8_t keymap_data[MATRIX_ROWS * MATRIX_COLS * 4 + 3]; + keymap_data[0] = data[2]; + keymap_data[1] = MATRIX_ROWS; + keymap_data[2] = MATRIX_COLS; + for (int i = 0; i < MATRIX_ROWS; i++) { + for (int j = 0; j < MATRIX_COLS; j++) { + keymap_data[3 + (i*MATRIX_COLS*2) + (j*2)] = pgm_read_word(&keymaps[data[2]][i][j]) >> 8; + keymap_data[3 + (i*MATRIX_COLS*2) + (j*2) + 1] = pgm_read_word(&keymaps[data[2]][i][j]) & 0xFF; + } + } + MT_GET_DATA_ACK(DT_KEYMAP, keymap_data, MATRIX_ROWS * MATRIX_COLS * 4 + 3); + // uint8_t keymap_data[5]; + // keymap_data[0] = data[2]; + // keymap_data[1] = data[3]; + // keymap_data[2] = data[4]; + // keymap_data[3] = pgm_read_word(&keymaps[data[2]][data[3]][data[4]]) >> 8; + // keymap_data[4] = pgm_read_word(&keymaps[data[2]][data[3]][data[4]]) & 0xFF; + + // MT_GET_DATA_ACK(DT_KEYMAP, keymap_data, 5); + break; + } + default: + break; + } + break; + case MT_SET_DATA_ACK: + case MT_GET_DATA_ACK: + break; + case MT_SEND_DATA: + break; + case MT_SEND_DATA_ACK: + break; + case MT_EXE_ACTION: + break; + case MT_EXE_ACTION_ACK: + break; + case MT_TYPE_ERROR: + break; + default: ; // command not recognised + SEND_BYTES(MT_TYPE_ERROR, DT_NONE, data, length); + break; + + // #ifdef RGBLIGHT_ENABLE + // case 0x27: ; // RGB LED functions + // switch (*data++) { + // case 0x00: ; // Update HSV + // rgblight_sethsv((data[0] << 8 | data[1]) % 360, data[2], data[3]); + // break; + // case 0x01: ; // Update RGB + // break; + // case 0x02: ; // Update mode + // rgblight_mode(data[0]); + // break; + // } + // break; + // #endif + } + +} \ No newline at end of file diff --git a/quantum/api.h b/quantum/api.h new file mode 100644 index 0000000000..00dcdb8954 --- /dev/null +++ b/quantum/api.h @@ -0,0 +1,59 @@ +#ifndef _API_H_ +#define _API_H_ + +#include "lufa.h" + +enum MESSAGE_TYPE { + MT_GET_DATA = 0x10, // Get data from keyboard + MT_GET_DATA_ACK = 0x11, // returned data to process (ACK) + MT_SET_DATA = 0x20, // Set data on keyboard + MT_SET_DATA_ACK = 0x21, // returned data to confirm (ACK) + MT_SEND_DATA = 0x30, // Sending data/action from keyboard + MT_SEND_DATA_ACK = 0x31, // returned data/action confirmation (ACK) + MT_EXE_ACTION = 0x40, // executing actions on keyboard + MT_EXE_ACTION_ACK =0x41, // return confirmation/value (ACK) + MT_TYPE_ERROR = 0x80 // type not recofgnised (ACK) +}; + +enum DATA_TYPE { + DT_NONE = 0x00, + DT_HANDSHAKE, + DT_DEFAULT_LAYER, + DT_CURRENT_LAYER, + DT_KEYMAP_OPTIONS, + DT_BACKLIGHT, + DT_RGBLIGHT, + DT_UNICODE, + DT_DEBUG, + DT_AUDIO, + DT_QUANTUM_ACTION, + DT_KEYBOARD_ACTION, + DT_USER_ACTION, + DT_KEYMAP_SIZE, + DT_KEYMAP +}; + +void dword_to_bytes(uint32_t dword, uint8_t * bytes); +uint32_t bytes_to_dword(uint8_t * bytes, uint8_t index); + +#define MT_GET_DATA(data_type, data, length) SEND_BYTES(MT_GET_DATA, data_type, data, length) +#define MT_GET_DATA_ACK(data_type, data, length) SEND_BYTES(MT_GET_DATA_ACK, data_type, data, length) +#define MT_SET_DATA(data_type, data, length) SEND_BYTES(MT_SET_DATA, data_type, data, length) +#define MT_SET_DATA_ACK(data_type, data, length) SEND_BYTES(MT_SET_DATA_ACK, data_type, data, length) +#define MT_SEND_DATA(data_type, data, length) SEND_BYTES(MT_SEND_DATA, data_type, data, length) +#define MT_SEND_DATA_ACK(data_type, data, length) SEND_BYTES(MT_SEND_DATA_ACK, data_type, data, length) +#define MT_EXE_ACTION(data_type, data, length) SEND_BYTES(MT_EXE_ACTION, data_type, data, length) +#define MT_EXE_ACTION_ACK(data_type, data, length) SEND_BYTES(MT_EXE_ACTION_ACK, data_type, data, length) + +void process_api(uint16_t length, uint8_t * data); + +__attribute__ ((weak)) +bool process_api_quantum(uint8_t length, uint8_t * data); + +__attribute__ ((weak)) +bool process_api_keyboard(uint8_t length, uint8_t * data); + +__attribute__ ((weak)) +bool process_api_user(uint8_t length, uint8_t * data); + +#endif \ No newline at end of file diff --git a/quantum/api/api_sysex.c b/quantum/api/api_sysex.c new file mode 100644 index 0000000000..a4a554e764 --- /dev/null +++ b/quantum/api/api_sysex.c @@ -0,0 +1,29 @@ +#include "api_sysex.h" + +void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint16_t length) { + // SEND_STRING("\nTX: "); + // for (uint8_t i = 0; i < length; i++) { + // send_byte(bytes[i]); + // SEND_STRING(" "); + // } + uint8_t * precode = malloc(sizeof(uint8_t) * (length + 2)); + precode[0] = message_type; + precode[1] = data_type; + memcpy(precode + 2, bytes, length); + uint8_t * encoded = malloc(sizeof(uint8_t) * (sysex_encoded_length(length + 2))); + uint16_t encoded_length = sysex_encode(encoded, precode, length + 2); + uint8_t * array = malloc(sizeof(uint8_t) * (encoded_length + 5)); + array[0] = 0xF0; + array[1] = 0x00; + array[2] = 0x00; + array[3] = 0x00; + array[encoded_length + 4] = 0xF7; + memcpy(array + 4, encoded, encoded_length); + midi_send_array(&midi_device, encoded_length + 5, array); + + // SEND_STRING("\nTD: "); + // for (uint8_t i = 0; i < encoded_length + 5; i++) { + // send_byte(array[i]); + // SEND_STRING(" "); + // } +} \ No newline at end of file diff --git a/quantum/api/api_sysex.h b/quantum/api/api_sysex.h new file mode 100644 index 0000000000..b947b60e54 --- /dev/null +++ b/quantum/api/api_sysex.h @@ -0,0 +1,10 @@ +#ifndef _API_SYSEX_H_ +#define _API_SYSEX_H_ + +#include "api.h" + +void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint16_t length); + +#define SEND_BYTES(mt, dt, b, l) send_bytes_sysex(mt, dt, b, l) + +#endif \ No newline at end of file diff --git a/quantum/quantum.c b/quantum/quantum.c index 8372a7adc5..f653564a67 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -847,12 +847,12 @@ void send_nibble(uint8_t number) { } } -void send_unicode_midi(uint32_t unicode) { - #ifdef MIDI_ENABLE +void api_send_unicode(uint32_t unicode) { +#ifdef API_ENABLE uint8_t chunk[4]; dword_to_bytes(unicode, chunk); MT_SEND_DATA(DT_UNICODE, chunk, 5); - #endif +#endif } __attribute__ ((weak)) diff --git a/quantum/quantum.h b/quantum/quantum.h index 316da15b9a..e6adf974ab 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -119,6 +119,6 @@ void send_nibble(uint8_t number); void led_set_user(uint8_t usb_led); void led_set_kb(uint8_t usb_led); -void send_unicode_midi(uint32_t unicode); +void api_send_unicode(uint32_t unicode); #endif diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index aa2e781c80..39d4824b6b 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -1091,37 +1091,17 @@ void fallthrough_callback(MidiDevice * device, #endif } -#ifdef RGB_MIDI - rgblight_config_t rgblight_config; -#endif void cc_callback(MidiDevice * device, uint8_t chan, uint8_t num, uint8_t val) { //sending it back on the next channel // midi_send_cc(device, (chan + 1) % 16, num, val); - #ifdef RGB_MIDI - rgblight_config.raw = eeconfig_read_rgblight(); - switch (num) { - case 14: - rgblight_config.hue = val * 360 / 127; - break; - case 15: - rgblight_config.sat = val << 1; - break; - case 16: - rgblight_config.val = val << 1; - break; - } - rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val); - #endif } uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0}; void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) { - // for (int i = 0; i < length; i++) - // midi_send_cc(device, 15, 0x7F & data[i], 0x7F & (start + i)); - // if (start == 0x27) { + #ifdef API_SYSEX_ENABLE // SEND_STRING("\n"); // send_word(start); // SEND_STRING(": "); @@ -1136,190 +1116,13 @@ void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t // } uint8_t * decoded = malloc(sizeof(uint8_t) * (sysex_decoded_length(start + place - 4))); uint16_t decode_length = sysex_decode(decoded, midi_buffer + 4, start + place - 4); - sysex_buffer_callback(device, decode_length, decoded); + process_api(decode_length, decoded); } // SEND_STRING(" "); data++; } - // } - + #endif } -void dword_to_bytes(uint32_t dword, uint8_t * bytes) { - bytes[0] = (dword >> 24) & 0xFF; - bytes[1] = (dword >> 16) & 0xFF; - bytes[2] = (dword >> 8) & 0xFF; - bytes[3] = (dword >> 0) & 0xFF; -} - -uint32_t bytes_to_dword(uint8_t * bytes, uint8_t index) { - return ((uint32_t)bytes[index + 0] << 24) | ((uint32_t)bytes[index + 1] << 16) | ((uint32_t)bytes[index + 2] << 8) | (uint32_t)bytes[index + 3]; -} - -void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint8_t length) { - // SEND_STRING("\nTX: "); - // for (uint8_t i = 0; i < length; i++) { - // send_byte(bytes[i]); - // SEND_STRING(" "); - // } - uint8_t * precode = malloc(sizeof(uint8_t) * (length + 2)); - precode[0] = message_type; - precode[1] = data_type; - memcpy(precode + 2, bytes, length); - uint8_t * encoded = malloc(sizeof(uint8_t) * (sysex_encoded_length(length + 2))); - uint16_t encoded_length = sysex_encode(encoded, precode, length + 2); - uint8_t * array = malloc(sizeof(uint8_t) * (encoded_length + 5)); - array[0] = 0xF0; - array[1] = 0x00; - array[2] = 0x00; - array[3] = 0x00; - array[encoded_length + 4] = 0xF7; - memcpy(array + 4, encoded, encoded_length); - midi_send_array(&midi_device, encoded_length + 5, array); - - // SEND_STRING("\nTD: "); - // for (uint8_t i = 0; i < encoded_length + 5; i++) { - // send_byte(array[i]); - // SEND_STRING(" "); - // } -} - -__attribute__ ((weak)) -bool sysex_process_quantum(uint8_t length, uint8_t * data) { - return sysex_process_keyboard(length, data); -} - -__attribute__ ((weak)) -bool sysex_process_keyboard(uint8_t length, uint8_t * data) { - return sysex_process_user(length, data); -} - -__attribute__ ((weak)) -bool sysex_process_user(uint8_t length, uint8_t * data) { - return true; -} - -void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data) { - // SEND_STRING("\nRX: "); - // for (uint8_t i = 0; i < length; i++) { - // send_byte(data[i]); - // SEND_STRING(" "); - // } - if (!sysex_process_quantum(length, data)) - return; - - switch (data[0]) { - case MT_SET_DATA: - switch (data[1]) { - case DT_DEFAULT_LAYER: { - eeconfig_update_default_layer(data[2]); - default_layer_set((uint32_t)(data[2])); - break; - } - case DT_KEYMAP_OPTIONS: { - eeconfig_update_keymap(data[2]); - break; - } - case DT_RGBLIGHT: { - #ifdef RGBLIGHT_ENABLE - uint32_t rgblight = bytes_to_dword(data, 2); - rgblight_update_dword(rgblight); - #endif - break; - } - } - case MT_GET_DATA: - switch (data[1]) { - case DT_HANDSHAKE: { - MT_GET_DATA_ACK(DT_HANDSHAKE, NULL, 0); - break; - } - case DT_DEBUG: { - uint8_t debug_bytes[1] = { eeprom_read_byte(EECONFIG_DEBUG) }; - MT_GET_DATA_ACK(DT_DEBUG, debug_bytes, 1); - break; - } - case DT_DEFAULT_LAYER: { - uint8_t default_bytes[1] = { eeprom_read_byte(EECONFIG_DEFAULT_LAYER) }; - MT_GET_DATA_ACK(DT_DEFAULT_LAYER, default_bytes, 1); - break; - } - case DT_CURRENT_LAYER: { - uint8_t layer_state_bytes[4]; - dword_to_bytes(layer_state, layer_state_bytes); - MT_GET_DATA_ACK(DT_CURRENT_LAYER, layer_state_bytes, 4); - break; - } - case DT_AUDIO: { - #ifdef AUDIO_ENABLE - uint8_t audio_bytes[1] = { eeprom_read_byte(EECONFIG_AUDIO) }; - MT_GET_DATA_ACK(DT_AUDIO, audio_bytes, 1); - #else - MT_GET_DATA_ACK(DT_AUDIO, NULL, 0); - #endif - break; - } - case DT_BACKLIGHT: { - #ifdef BACKLIGHT_ENABLE - uint8_t backlight_bytes[1] = { eeprom_read_byte(EECONFIG_BACKLIGHT) }; - MT_GET_DATA_ACK(DT_BACKLIGHT, backlight_bytes, 1); - #else - MT_GET_DATA_ACK(DT_BACKLIGHT, NULL, 0); - #endif - break; - } - case DT_RGBLIGHT: { - #ifdef RGBLIGHT_ENABLE - uint8_t rgblight_bytes[4]; - dword_to_bytes(eeconfig_read_rgblight(), rgblight_bytes); - MT_GET_DATA_ACK(DT_RGBLIGHT, rgblight_bytes, 4); - #else - MT_GET_DATA_ACK(DT_RGBLIGHT, NULL, 0); - #endif - break; - } - case DT_KEYMAP_OPTIONS: { - uint8_t keymap_bytes[1] = { eeconfig_read_keymap() }; - MT_GET_DATA_ACK(DT_KEYMAP_OPTIONS, keymap_bytes, 1); - break; - } - default: - break; - } - break; - case MT_SET_DATA_ACK: - case MT_GET_DATA_ACK: - break; - case MT_SEND_DATA: - break; - case MT_SEND_DATA_ACK: - break; - case MT_EXE_ACTION: - break; - case MT_EXE_ACTION_ACK: - break; - case MT_TYPE_ERROR: - break; - default: ; // command not recognised - send_bytes_sysex(MT_TYPE_ERROR, DT_NONE, data, length); - break; - - // #ifdef RGBLIGHT_ENABLE - // case 0x27: ; // RGB LED functions - // switch (*data++) { - // case 0x00: ; // Update HSV - // rgblight_sethsv((data[0] << 8 | data[1]) % 360, data[2], data[3]); - // break; - // case 0x01: ; // Update RGB - // break; - // case 0x02: ; // Update mode - // rgblight_mode(data[0]); - // break; - // } - // break; - // #endif - } - -} #endif diff --git a/tmk_core/protocol/lufa/lufa.h b/tmk_core/protocol/lufa/lufa.h index 0962dda8d8..b11854101d 100644 --- a/tmk_core/protocol/lufa/lufa.h +++ b/tmk_core/protocol/lufa/lufa.h @@ -68,64 +68,17 @@ typedef struct { } __attribute__ ((packed)) report_extra_t; #ifdef MIDI_ENABLE - #define MIDI_SYSEX_BUFFER 16 void MIDI_Task(void); MidiDevice midi_device; + #define MIDI_SYSEX_BUFFER 32 +#endif - void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data); - void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data); - void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint8_t length); - void dword_to_bytes(uint32_t dword, uint8_t * bytes); - uint32_t bytes_to_dword(uint8_t * bytes, uint8_t index); - - __attribute__ ((weak)) - bool sysex_process_quantum(uint8_t length, uint8_t * data); - - __attribute__ ((weak)) - bool sysex_process_keyboard(uint8_t length, uint8_t * data); - - __attribute__ ((weak)) - bool sysex_process_user(uint8_t length, uint8_t * data); - - enum MESSAGE_TYPE { - MT_GET_DATA = 0x10, // Get data from keyboard - MT_GET_DATA_ACK = 0x11, // returned data to process (ACK) - MT_SET_DATA = 0x20, // Set data on keyboard - MT_SET_DATA_ACK = 0x21, // returned data to confirm (ACK) - MT_SEND_DATA = 0x30, // Sending data/action from keyboard - MT_SEND_DATA_ACK = 0x31, // returned data/action confirmation (ACK) - MT_EXE_ACTION = 0x40, // executing actions on keyboard - MT_EXE_ACTION_ACK =0x41, // return confirmation/value (ACK) - MT_TYPE_ERROR = 0x80 // type not recofgnised (ACK) - }; - - enum DATA_TYPE { - DT_NONE = 0x00, - DT_HANDSHAKE, - DT_DEFAULT_LAYER, - DT_CURRENT_LAYER, - DT_KEYMAP_OPTIONS, - DT_BACKLIGHT, - DT_RGBLIGHT, - DT_UNICODE, - DT_DEBUG, - DT_AUDIO, - DT_QUANTUM_ACTION, - DT_KEYBOARD_ACTION, - DT_USER_ACTION, - - }; - - - #define MT_GET_DATA(data_type, data, length) send_bytes_sysex(MT_GET_DATA, data_type, data, length) - #define MT_GET_DATA_ACK(data_type, data, length) send_bytes_sysex(MT_GET_DATA_ACK, data_type, data, length) - #define MT_SET_DATA(data_type, data, length) send_bytes_sysex(MT_SET_DATA, data_type, data, length) - #define MT_SET_DATA_ACK(data_type, data, length) send_bytes_sysex(MT_SET_DATA_ACK, data_type, data, length) - #define MT_SEND_DATA(data_type, data, length) send_bytes_sysex(MT_SEND_DATA, data_type, data, length) - #define MT_SEND_DATA_ACK(data_type, data, length) send_bytes_sysex(MT_SEND_DATA_ACK, data_type, data, length) - #define MT_EXE_ACTION(data_type, data, length) send_bytes_sysex(MT_EXE_ACTION, data_type, data, length) - #define MT_EXE_ACTION_ACK(data_type, data, length) send_bytes_sysex(MT_EXE_ACTION_ACK, data_type, data, length) +#ifdef API_ENABLE + #include "api.h" +#endif +#ifdef API_SYSEX_ENABLE + #include "api_sysex.h" #endif // #if LUFA_VERSION_INTEGER < 0x120730 From e26a80508f2247d27e431a7415df1ff3405f598a Mon Sep 17 00:00:00 2001 From: Olivier Date: Mon, 28 Nov 2016 11:20:00 +0100 Subject: [PATCH 26/37] Reorganize the numeric keypad layer more like a traditional numeric keypad. --- keyboards/ergodox/keymaps/bepo/bepo.png | Bin 80838 -> 80249 bytes keyboards/ergodox/keymaps/bepo/keymap.c | 24 ++++++++++++------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/keyboards/ergodox/keymaps/bepo/bepo.png b/keyboards/ergodox/keymaps/bepo/bepo.png index bde2e2cfacb326e7934c5743aea2f303c8a42527..54992f5ae54c6c38b29221a78c45224af611573f 100644 GIT binary patch literal 80249 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 bo?k4vBG|Zx;Uvdj_)BfS#=c}#WAFb1kA(g2 literal 80838 zcmb@ucR1Jm`v%+)%81N_jGIdKCK6?2lw|XzrWw_IgaO#=RP`)ZsGHOzt(k~*Lj}T%U}M1B;Eyz3#U$RM9hlkJLUv;4 z{`o9yF`*yR(+N2_YdvQj9UXZ#*RlTNNrGbVbZZ+Myo&}#MjLKi|Gu`UU*NZI(m#Iu zI1u3^{rA&6=7 zh6#I-^18`D{yH%>9^Ulfj?~F)>B^)S(PO(IAN`${pP&5Mvu6W^rer-PJY8K~_q?S) z)n=i}#%E@H%!i8BkM{pMd8eFnJ^6$f?yqz25SSBCQ{(gT@%_cf_*2UaEiEQ?W_WlQ z{;_R;HT?J6{(b^2@`O7H@;a-d6)czBOiY**nMgh+CR)w3Toxs~awX7awvCpDr?B32 zbub_6g15)c*v;R=iUXpI=@}Ut7Ai#6 zs?U}mYn?y&of0o6UXO7ynEAF&lS02&uNs=(ToZ>$@Q_F}PX1I#X9q7kiu1@hR=~zb zDKt!>{A4s}B-?EIgs zo&(R!gSNT?4holoWb)}J5`E&*Y3q~D)X2W^>IgNtSY2ck7!>rSBjGNKu!faYZmTn| zk|qnOY)FYCfde{lgqOVHWt- z`FJU5+>>=Y^}E&@mlx?6dL7ny_iijP88b zC*I{jrkg=)SED_@tXbZ4d-g7b|-1vi}W`dHZVG~{Kr*(;+(znr&ExGM3x}g$v*zFP5A9GPYD6|H{p%cs zs=QS%oOn;Sob%B5s!GG3P-s9+MTPgK>5H?6Y4G-|-TAMxTND%&uR}v$)(4X5Z_Kpv zvM9)r2OAoUaq8?hGGLEr)S#vA^JuxWpG9^wfuO?j>48l%9v&V`8=Ja`I^WQkm_W6B z!-=|!A_d0n$||O{E$gLzM^mf;ffQ?<@AO>ul?1lT&P3s06vOeh^ibq$nfJ^3`c+Ek zV6Bdv`zZm$TY*wO)A;_tUsGArcHw!XZ{pfTs{>1~v*;c>3a2(Kj&eBu{Ba-S+&SbS z#3VyS=5??F8t+XNdc_I6xL=#R3JYUJ=EKf)qm|Fn*4FFI8zM|x@)u!YmtuCzs;Dx3 z;)SlTy=timvMNov{y8pqRa4yZA{?x1Qatl^ijfaK-+lV@dU-{Kz)c17OjR9nOw5YQ zRmbYVe6ur;L(|e~d(%}WCMHhX+uLWT=AJR_&mtj#nQwSadzal|O-HlBsh6`cDJ_r& z+nA=8l0h7WOwyb}sv`Mq7k*AIu7vLSwGsQV!E&Rru#a_%`5U1&ji)?EgWeGKJCOGTM@U#Wq4Viq>4B@|;sh9cQaqCPl_C|LPw}FQ zo{a?9E%vEp$uSa9yR3;mP-ZFU%lCHG@UJNQw(9s0lc?P0U8Z_YBg{|vpZUp=bE-Pr zj+yq0C)0KzbU)l8yXK#sN$)nPPZ6>k%`4$qD03myRioWFG$1I*3tmQAT3UxQI!C_| zzkID0Cw4whIZ5%GdO63nt0dDBQL?yhN0pb-Npr`_a}&jxgoUXN_qL`oItoa#8CMR> zt9u^3BRwu+K{ZFP+||+f(A)o5LE&{&)OG%_u&|7kcd-!>KGoHCGSu=V^3c0&8W^IM zo{Bba74358Pd{HB#gmk5B>jtlVK4)We@~y`;Kv|KiJMxZn#Bf8X>DEIS(Pl!nvpX5 zT>Dim+{>I8hWXJ%s6MA6oHW4}cY&+!MwjKajT*9j(+PGJs9Ox5ITz_SzS5oRNI+v43JgejTsrCVX9y=(JSO+H7X5;Q3(-?HkOTI%mv5?}TxMB3Xi7xW z1f0?y!F|Q6{!*XFix>t4g*S<7{yJDBFegY55 z%F60GE9;CfV`f6HNrEC%CU3SmRRY8Fe@Fan)V8p92+4}`^YgL8S7Qzn$$e^O?9_)R zc28@j*ednIet$XL9I26Ye6(*N^y|kP-r)Ywv*823j8mrtAL>^RH#uh5t-mkEUI8F7 zj!`6e@HRYLEvr3FIM68GwJ-T5>4J$|O4`9JmzgoyqIuqdte<7VO?vvX)}@ri&qfw_ z^=bDbsI#$%X+-*~qjPCC>7!*Ci2%PWKOlqYpuv6yaV?JzmAS<${pr$8<&5#AqXBZ9 z8%VS-LtS8u)M`+nUZCrJ$Ov}R7XyuOwfX1Ev<%J4`TUWzC4RHxw}3U zOOjgj>Irwu<-fl4>dkm*#s+47qN^8+?0otqibMZ{LaMx?;+N7~9TqJ{BG2$_l5yz( z{3o9z+JeqG`$cA!_J5d?CL7!GhG7thy$Ul~nbv?`^$H2O2(Vh9ta#gr_lUS_ zQDZ+7q9&i9`TnlP8{_ly{u{IHHtI?0HdX0Na@gwG^`=}KR?BgCFH)omGZ)jdD{H?O zn%1xf$pxJ=T^HPbOj3E2VWos~8K<_Z(ERcFo>`4&7*BZlcwfHnthW!Q#rC-3^*S-> zo%650@Te%iNG&J-Zf8@A`r2M@s!?q(CXx|?R4tKZKC^XD$dw_s`9CdbKRdW($Udn;7f53 z5)z({mc7i|n|B#if_FfN z-Q`U~jLd#sF0vpAuG_~+#Ni~F*@g(hPYNNheyeE1HiquY)((N%z}m@T`7+M_^YE$7 zCW`dzN97rdX{o8Ak2*yRTVR1{BAd-AveD{9-=vRIkC9~+rim|PO@%Qkk;SOfsOsx} zdwWB*%B?~vw5h4dFC;`#Q#1Ah^0&2hUa#|LfiY3?!+2I0a@c5g)lmQ}`Nzu2%F9K= z`V(fhED`1Erz+Zpalh*)=%dl5^|ciP*7dcponxrtd2D86+iVM;|JD7j-n;cx`<|s7 z$1K_`Sk$6n#x8iqL(8b4an*R@T00{QY>6`AM@n0@_)2SATSL@@ z=QzsUXtAg+lL=%u55i0*C86Vs*_XqI;}hq!a07}otB?b?~PTuGNcE}bqy65zv<-)y~)I6 z7O}Z~TwJ>l{gtQJmg%0P?fq6&OMCmqOpRjZ#-~<}eKw}(8QE`l-Lh(|gOnxPoJhO) zWgleJCC%F8{OCQ?>_Ugk#1-1lorl+)TQ5+)EA7K+w*OO+7~K;7>ml9 z>X&ENdmcZWmopA8?f%3qeM1$M?Si zf`i4Clt``-)sreJDymY+E;C@IF62cTu-=o3v_oxeZCO5lK4b8y<*-26WlN9?Hu1a6 zw}htUZnxA&YE$U{9?nYE4Kh~EYMXXpqf%aS+!DLR2su;fJrb&j^1b%34IfOdpEmQV z5?u^Jf{8L|?f3Nh>yt_S+EfYl{+itLyP80wgu=bsG(2j1xYe(1X=PROHI#k=cF6rV zj1x1hF|orMrgA#l=EBLrojOhF=T0(XBq=SQWUL$wpia@@kk{6V_Wf_qV&Ut|v_vB* zY^{Z>U8gTY4f21HoawjtP@Y}bpB^GiHR;_y5gbhn=oyXSM{IY0E7~uRzP3sA!~J_` zsYukkLV9nMpdHh*(em>ZS|K5~_psqaAnzc_`9!l@_b@<$t44>N{zv)+W;|wsC*^NH zuTHj>{(^|A&q3POSbX&85~NGdOJj9x40)j!WoX51K|VoMN%w;-4^X_sg?gU8z?j$Tq%L7}LeHs@aE<>j%C zU5TlnC--^zz^H*g+e}f3!aTXT?Nb}e69O2tb}-+FrC;zp{>9t7G$tk)SIv6~)lJW2YxmJE>s3sD|G=m3VUNFHQa^&B ztVEIPqI$p2};U(>NDi+kAdPo8Jga>m{jTS6^SR zTm9nn*RNk+bUwXjX=$0CoO83F4Zr!8M&2*-UM_>%}2JMl9H+$8?nw};#R{U_TSrc z>RTNfoQ-R-6&`&T8FG2bI@i_a#wKO_k5Aq6Ikxi(8JeY+YHDiA8~uZS&xHqIfD0Ec zAoY+gzc&o+pe$`ocN&E=Sy-heD`!2FuErq(-)t?J-Xh{zE? zf^OkIQan>5V^cRONR)#_Hpo=)R-}vj7rnGWx#%zVAXr>%&z47W8JM4kLhBf@@85Hn z^jwFc`=u^9Kw|w`uk#4PfMQ8QlMB}qco4lWeuU)wmNaM1o(+xccTk*wDr0FLv_cL6%9Rk<6*IYY@Ed<&?Jg~ir^k|J{5I1_J(@d!P)sP^?>Za6|<97xWbgbbYduve^=i@2f$!yVz2;qmbouU)(LH!v@? zW>C&lKj&l2P3p9>5=?dL`3E!_U2k{){&`IlD)ja1Q=T<1g0Jw^j*X4|%rDcg_mHPW zcDAjOikTU6d3iZ=|7?4FW7W|X8*GH=**F=ph4qG5_g6L*&((arxqb@th6A?%^)vmo zYgjM`=I`Rg{E<{|q7O>}l{3j3M!7R}?BraAxJHr(YXbf&(?Dn}^6Dq}1Bub3N`vz7 zw!JS&HfHAoU~*3SRa$m-aRx#4XtbXFKt6vtrjof;ng4f+F#1VG#iJK&5Nh6YmIu9B2KBxz0p@B*HC*Tu`Wear$uH@zO{j3!p+tvO=C3vjiEb z*Q{L(7)y`-eMwG=;DI9ZD-y3L&ueRI%SN#$MCY=*>{>SOjJi`%QsTnvex3el_%%lR8pV?It_RQlxn3*>GXFU_Ug_~LM5doUdiPaoA!wu>7|2$9_x_~9iRAEUdbnq zaqgKjV_;zDbbJs+I22fjj&v0^*dmD~C8{~1gdVwfZjzSt7dr1e8*QYj541f``1?#S zNQ&RPSKZu<12i=799S2r%?z2pPFtV6*riJz3^Ea_S-}$Yz*?|e;SYnHBNbU<2Sum) z&(n3>S*k$z@@nU<&HK1-3jtfEd*El*roxO(SjI~V1r!i#R_l}E2kVVjTLS{+J;fS4 z*2cy9qq&U6mzRTY*{`f+`A&+XcRv*3vBT10&v%DY78Rqw z)a)JJ+8DN(7lUxL(;jzWUd1lzn6ucK8JnbxkJJaBDj*=>g3DH~3UX#vPfs}I0RIx_ z0EbPKHF64SSd`J}V+3VqjoUu>Y=*>ieyafAX3w!%jqaxGuyUB*;hv zQ+Q7`hSWhQ4Gj%lroaJE^rPv`+UDlH`VchnQ{MXaXG(I3Bmy;3n2c;{I#Rm` z9pEwf#2xK+xTS*Ztc(m?C|t$jZ@az@5AV&&rFqlzIxOsrkFMqJnl5aiDA{CQ?J{@Y z?Ny1f7%R!B&QfRM1Jj53jO8Fmw{0!dA|IvbyXu( z5yS}9An)$a4k=r1V6u5SeNp*=DII!LaQuE4 zJQi5v;^7_GCy$hsed68r&P#vlGDL4L5BWw#k!$JM9343F3kc|beND@aueQKRjyq6l za}CJ?xYR=A+Aizopg_aXrxg$=g?L~wT5c%P2m#&S-`~9Q`7!=7Rd2ohd!&-QzH{MX z*OT~@PfkkuYjjJ#Jn1vwV94m0SLP@0oJ8M>iWt|THx?xwO4`~Xz*mG8>ua{hi-Z6) z@8Vy2kp)>Fn0WGFiNCI0)8Ad2;CDOVZ-ehc<)K>1#>tr%o%=!lI&=1ATuh;#U+Dn` zE5~H3?U&m~+ODIFusy~xv#c$|#m_+|&~Ookx}2Jt`fFQTk&8KOI&vWgc4-+I+BZ!f z6q&51zme?j?fndM_Qssgdx(Of(yR0757fna87K5W&lyhAr#b7%GM^MC06u-}At53< zTcKs~>vEa>s>Gv5gsbZBI_7Qt{Qc*x%PSAJHCzB!m(SDaCrqKAuMGP`>7JOJj7dU5 zLe67Cj8xDNDJOu42NgvWpe8UGT`j7>`+k9=i=Wu(w>(r_H#9Vq*C=M1Jz~KOTwFqV zd2HdIET|)+Ut`8Qb+|Jo`QX8W{Oq!lk`Dz1>lwdb7eV-p3Od(SpJqfvp}A%D(Zr5Xv*yQ z?$1--!f%!v(;`D*Vq#*4ny;j!q`J44q&bq!S1a4M$)FZ~0x2G#l${*N)pwW*=Bs88 zZm2CV?q-LQRcLQ6kzClxHvciLy7RJ|eoa$TYQ1nMC}mxr^Go~9c=dNyMjR&nuOY;o z{%qU()*$cy31=d)e013%U~SHIo;^O=sd}WYe&OQ9iw7_T2FwFek;TRK#bd`aA|f-g zkrkU}B8QtqA3uIXqdc=jeRt^k#l||i$`gJuPyrYLIf{D#jp~PUi-d}&h2Ni*TD*VY z3mM*1m;6g(;}jqhRA2bJcL82r7+)G1CLx-8&@nP%GKGIzaJA>wdMLc5m|k{hk7dAY z8(xmR$uyYefJ_7LnTeZk2-7DGe-cjIE^1trqkZd@Elx*1XZ8ItMqmEbrW+N7V{4fa2B_JjB zfe5Uw)je+ub!XAiue%LmJM)*ya%l_)8WvYZ${ZFmiyf}ob5|unVSaLUHHsJZR?1e{ zLC|=1cykwsD9iEc(~xFDb30x-D5eMDBx%F2Q;*!uLl%FCd0Lkr(pS_%%@-p9r=AIC>W8|OP$?x;2}NRItjQkCGS zmx!Rbk--xyg>g0I0{pp{#SroJ!KLtrk-x%La&ec`;1PtmDkdgIg_|Ipsa_FyK z_1=YCVEN-Kq1J5INAW-?iMp29?6#x$euvMyMm9ZVtCd5{7q!r~O?u2gz3DWCF+}tS zoqz~k-k2KpT5eJ(1reR?9AMw zbwlSR^P~tV$)dl#00;?i68zZEP@0~;diCm$+1Wsa$f$X#a$tmBrK@EBB)y_Rjsq+< zV2B@w{K@0vI-H~!@}}4xbAs<%AFZ#iBT(ttaLG$FTCgQf_zF}pr|Q_hHZ{FWPrnJY zH!fh^c9G*@>oB~!94^v~_ln)2l)Z!~O?pzExzEw- zi&EtHN7m>(-Of!|kr?~XSk^d}(0YX->(5Ka$l2WpmqsXyLq{?GXL*oGb8~Yu7pyHU zpW1!a;`peXJ^?bIpw{vJ*zwxf@lj;)?yv=O0U2A-#^RfYx97JRJa_J%Y(!cT!I(rq zqLq6KH%rROreIe{NJ(KQKX`BAc=%rsB4nu8LPJYmpIP-*YBIe*KxWq5+|%C(v82A8 zk0LngmOU#evnoy0@KAJ|95!ganGW|0i$l|(P3$$H~j5ejBsi1@^T>{x6cRE z){4d6vd0JRl<7EZ3v}90_Al3D`)S2r=`-FI)!2skvTgUA-{0vG`aslhVknqopLK6c@hcmU( zM_-g`L?lABJm`fHDI7zP5Z5Ybz}%sepPE%rzzunA3a~m9uSCSKyiyMyJlm?g>M(wq zQpkY-_$TlbE&wV$5}4_mP@&wu zeY?Ev8Yd}Wa_m&l^6Dk}f06C}>pT1`*cfu)!H-yTAEzoJ_!IFpP*M)h z99-g}iq;1F3*=z=NyX@q<4t}bKgPIJKBgph9alc)6Wl^U3RKb$OrebM^F$h zJMLL;vD1a>EKgB-K2E$=w9}&!pyd2cw}Xn2QKj~m0J#H1`k<1nMOvW;JfiM!i52$6 zix&27{?V^m*xoc@kdcvbb91lp#>1EqO4mcthWH8!GILR^(DdqR2t;QJfTvJwHC7!T zS^$Uy4}$)|?s^0fi&vUV3+x-#q~Rf{69U&sA5^c&&H3&qUh{V}56H*$at_z(E=CDC zazZ8_T#h-k%#>*vzU7ZkErjhYraO2~QueC>C+r?CA0LI#JrQmSJhn2;F<{xjd*G!A z8i-!vBG4wt(Pg@MGZYj+-8!F|_V$a~?uR^auG?xsQsdjFwHDrh@S~ev+n=F`>}S{%E=5+V*w>92E5y z4vuL&2vVv^EAFS_c}yefo6rvHbUqiavd(?T=?ssK_HVzvk9+_A{Q+RaR-Fds7KV!1 z-byp9`Ul*6EB)z7H{~CzjN3yL11;@oaNEGBBF)OxW3)jwg1ROm_W)wVB-F6wZJ(Wk zy}`Yt%ok&F(_%PV=4rv-v>V98xxGp#R50xHsnXdvL|}iUsOYt{Waj1TOV7pi*b@EQ z7lQwNad5?zku#=scXuje9Tb~MKwUG!M%}3dGAxjkoLp40D(t)s z{vIh_t;|-oLUp`P3jQ}$vS@%rPm~C*h2{6Y!uM>g0Xfglm(?|^+^9G>I7%GW^?WxP zD$u(QWHeXyHQm3N4p)abjZPHEIH9Dl_1)T=zCb zRaMDX&!?wT3Rq*nmo;FjfXJ?6cLUY^pic1ptDTZz1R+B4ld<9x3-k(zeuEB$g_`UP z4Cjz#2GXF&Y|sND)+qQvE+C~t`Tj~7zx$C8{E~Xb>UKmX@BHNB5T1d#KUJ1O>m!9; zhF)qgdQ8+M8xhrVh5nRaZZn9(tYi1vTYUKC*fnB{i|`6cO-&6p-ZN2UWzuZ)@^{4N zP*_;FI}>ApR7ObM0=S;{(A(L;LG{T9+AbE4SEKtKrYY_f-k>d=KtI11`T1PHk0JWG zm$$b+68Br;MXuuGqx zQrhkXcTs}~m475b(7D7xzYd(SiTtQ#Y?&i!37d_nChwz+ezm3Vswo*6_fV+!(}@J` z$A^4CPPOjO{#tU(K>=k1>+S{KBPi#Ym|R?3a**Y(a4H0lo&t5!%bpkw51KC_C(Zz# z`c^H(OSLO$w$2$XxBH07=lGsQ-9s{Wucl!aB6VlCK2w}WS8!nDbx=MsH+TRd{~+pV zxxZ~*gDL*aQ!c$%Z!qr(@E(Yn!^PEAydG>HTX-xYIr&ElkuIAR?TuHw4`8WVLu3fIFi?RE+;_S)?p7pRrHfvNj8fH^n z_FbkG)Taf6jOm%cF=u7vFcWRGHe^vnOG9&Nu|K;J#05v;?_YI5*o_4im9{I6HB&hd zC;&YGZhip)lNFZ#!_Y-y+qEcdom1@Ke>s(}7(>+WDkNMGN{Xppgv2d_PIknvbyry9 z+9boa5nbv6kmvV|m;t-<4Gl~J%X;U|ol}Ut3V6StZcO(K4H+k=rfvxhtn@Q*fA1#w z|KJBJMWa80dj%#9{y6N-e_jW=cby`?DB!K)RBy3`_Pu-e*0h95nQH-qz0UXp{1NYr z(usFw+YC}+MBFlBwt~n-c=c+#+OZuknsiFipzdK@@Z+jnF0!Ruqc;m&q2T^VJ@=7| z6pjbrR;+O8a}X;E)q@d>Tb%Habt~C#OIYSg!%&}2ezMHr6BC`Z`rsNQ!L9pHSxH@Ww0AQ$HWutrH5wjI(-9+-X{0r>bE8(zplgrNw2IN zp=AFcQ@O6DCgE{|7}4nHDF5@ND4O7N;FSV(A1RV~%?7G9rW!~@MMc+s{)9R?^nXpV zpguEquH%Lwvue(Z{C(jq4Ltlq`TNMO2#;V~`Fmd&Gy9R;aM#M_L3MU^majN=QZG}j zcVE^Q&F-H9xCt(l+CtNQhwi@U;3r?Gvq3V_EO#ITq5u&Z!83z|=0~{@lmV>PH8-aZ zt~CAY+WLsNwon|TP%W=zyB`MTJ5P71o^0D2i+Yc-5JkuEF-mXjM-F|1ShiNh_>UhL zpu99*b*J3lUM8wwrL8q=RENU=A$E6vUmxn*k9t3UG(j2d+gpBJ356jlbr#wB^I;|z zJ4p0txwwcx{f-?mvM0w;2#$;j&12=|`Ga+PmAh_1F$9u;<6-)3m8RkElC--G)Pagh zN>c*ua_%VgT)lIv?ko!}+K~tVg9?~$KRsH}ju3+u4_W#YWa(8@m~p8D-{$YXeV41l z9;M4&RH<^$>d{#v^p~Kwuv5=^@Q|wS3x!4*FWM;RC3D@+E-$A9BI$;S$-vcm`X6-S z4Ib>a#@rMRj*hg~ulwydc9H;}06F2z!-o%_a#J+@O|Jb8`(D)J#fb=mO{)FuX8yMc z_Qi|SMVzEa4*9h)Ym@xYq(Kan$VzNh(_YP8>zJ*_zXbE`y-r46cqgX;{E@!BRPy!G zkhq91cpKQ+ZL2mgf=Q!{Mc_MKw9KF?QvR_&Us6R7G)TZ#-F9hBOijDW15HmMt0mGKSEs~Gt!4T*!k#{_$refFI(}VEhfWUbd zt2ncZpRw9DsJ{L?2Efb~S&Y4!jdOmrqs<8Xy0zI@B`Oas`16z-@KdAI(&kD@NhZuL zV3Ty%9yB5(BJzYXAGq4_a22f@P=m2NYiRgU5R$+rs~Ff1^A1p}tGn9@Br{Q~!#z9T zGt}*h6F+|JfEf1QD^Z_}1>Bef>{5BXDDO15a#92~RE`+8gR-B#9Um;Q=E%d*h$Hgn>4SB-@ThyDz7-OOX$}I z`_+{(3@Oc!MN>|%_c({cZrDPeejmjQHZR#&enL=J!up=9Hh2)sr)9;)QiA*ez%75U zohMp$ZEI`V+~!-`TtHypT`Mb&RSsjkOl6!;3WJlCL$|{2Fa3*@-d4<`tBM^byvYE# zi>PL`zrW=Rf%4l?YJBKIRO|Bbt%bpi#RXQ-awuB8Q5siTz3H(i zL{>T>K!9$p&|8mLLxCgrQmx4BGI-7cft;=G?^jX8y?UDxPy^x%D^Sl&vIDw92%WYF z)DdEW?Tx3Rpa{6kW#}gn*%4yE87&LW>7rY}hmimFtATrKWNgR<%$}`#FTm0W6#-uC zu>PA|0;`k@V7u5@x5FM8sw}-D9Ak$XF=l3O5t*q)PmAkBwOz(hQtEPH49m;fCMd|2 zSL!XfvWm7_9G{x*y-?;H|(5wL}cYm2kRx4|Fxdt)E=+2*of%ms| z$5wvwir|Z`PmZaUfbruRecJj;7ad69p{~sx#`+0q(oQgQ{k^0fyri!v1a|*!WgE^DT+)`4q|~_Nf|3C$`3%KETgCNr?3oGPEthTMl2L_P}Fc! z$mPeI^2TsH`9_SK+qY=1fC1YlV_h0Yc}XlLcfP8S>~bX4=7kbn`9q9}`Uyx&m+~## z!)tJS0;r(%yXLrb|3i^O40m^TFfQnJC(Feeo3tW0cV5MIclv|fdp$q0t5Y3)4YlFK zRAA@IP`a(D@7f+(WDBkesgv3n_Uq$h*&3kuGXrEFJdkj45t^Kw#1MzS;Rs}oZh$X= z-F45lX#unW2g`&-I3$Si6^QkVz=MLur2~Nxl$;;SU+-rHL`eMF6yQ%BPRF;*IUV^2Xa3VgYA!< z96hTl0gI}p<`04jIk>H6Hu)uPPchu{dd55;_McuEkY+Mgo;pv|o`dN}IID~dS$QDL z=%GY}DuZPOl#`DZW0hgOy`fm>WO}z120A*i*Z14w0*OK8d%zEgkodwmm;_{_PXKrm zS0dS;juPt;$5ff!b<;lg+(jXvDS#4jaLoH$0;n^PQdZ)UN?A8UJYnODMcg3{4zq zOh?ov-y!1GF6fxB2}mhL3jbvTmXoilVx18tqX_YILUu28iy!%M>Zt>hDx+IxBbkd&eU(XS( zeJyj6Lg!9^dL;M+wm%03oqGlo57{B) z?oC)DKJB-~yNJ;j+(tZL^jVRUk(pY?HoVbG3}Wv0uHKH0Q<9RB#3UrSZpZU(rR02c zSEg1co`?ib+vP{s{5*H=YpMRzb&DaV%ycvW1Pw~Z(L~9Mkm+!EwP5w0274!;2A?|` zACJ8fOg8!n^UU8N6*6m<5CF|Lxs`HN+6n9nmQR>Faz792a~HKdME2??q0Fm1rIoGC z&4OPu!P}~jVcyY^Z4@}}Mups%K=MJjcy7+(9WPYo?by+0S_Jma?8cNwi8&w$)-(Xk zOHi0gqgZkxg1^6IkBISewt}4tmza=sI1TIYTh{}eC>6OzgW66HG}WK5RAs0fR>nLI z6<}%cEYivsFCTS3c0~v+sG>cB!6tF1!Q<4m&cg;V$k`sAo(PbBw0Mb0uLox81>cwp z5wM&Hs|Bueh6I_kbvhI>oVQSf(xGbaW}p?UALmT$T+HEg5vU9p3r^dcxndQdq+;Iy zk3TV3WWK{PuW0y`_4xCH1PBNos$2KqkrPfK-r)5{YB;~3AmT#S1Ud;6DAkZye8B-M zdDYdxE}M{J0osP7;CNurKKVT`g2XHn6i)=TGmf!iYDs!kpzC?(HCOADIXgT1@{;fR zv@;=Pt(CqH^+gjq$3rElYar)3geW=xCM_}e{a3Veb$DZd<-?)!4io1NARR;gffhi} zC+|U*-r^2fUT%)nlmvo-04qGn^lf*53f6!b+wzi{MlRBd1FcFl0s?==4jf*B`|%MX zZ-R07k%EE;&@P>e|7+^gvj#HA%dH#;BPd;oERN9>y<5Fu9Zwb=Sk&?`U>p*1a(I>d zE4QE!v!C-4N}#|&>}-&|f}mC%)&HXW_jY^qCby%^-U9fb1b9EBjvK9T7SEJP@sm?= zbQGX=+tpnft+)aem?!kv^kr)J0v7=%UU5ns!ZPsYK=pt#!wc)?Xl$j0)wI45pp? zXRmtHQe$12U%0LC_%X-R4w|06K19%gIvMdqON3AdgQuU0I=`Fl1Qfnsb zoUKh#ayf}di+bdkozX@)M_&XpaJ65x>lM*wb3WW$|CZiTH&m4+_UsAkri8Fqn|t6| zbK|}2K)mggzZJCk1+Oe{D}eKFbhUy9jt9`3_Xx8=HLLFKCPJzo;D5d~H|N^SJ`mbp z$_Fg-1*mUm>v>A~T`E$RaZ2t_a{VxTQz+?!X|~D5p8^i2KF7849)wz5&}}-VwAa!^ zdD(@oNDBiBKPli;I(U=wY}WtV>e(zVA?ym+x5Fw>D;0bw-+6#rD?TJFm72n^|A& zCDvX1c3oOBY7gsy?W1}VurQl*?I7e`@G1gKF#Vt?pbhEm~pv}#5;d) z7B6b65WCxgmNg{uI65F_u$STQ6c>&$FF`%Ol1{HoSGI(|vamWi^yPRWxGvCApSF>n|FQ4Wjnj0I&4`1;=U1cZ zF7%He8sd@>nB@`*3JSb)U&qD{xBS=CTZTG=i0O!!F+i!W12t`^ReNVPZreJP#U^{u z%tw>85o{qMqo)1?rk|oY^bh@aBKlK_dt27!-iW#Q{hG2!-Gz)L$hKuhP*_ z-c{~S;*193sDNeTx6ZcBTLmp<|I>^3+ei=tq(hv;zo4FR2~kG zk1o>mX+15C?BX9^LxGPb9|b3q@>odbA95dhX?S8<5zVbH3)RfzUTDM&2qV|&IBP}= zd>6pl;e!J1ez1-O`{b*$Ff`jAy9GM&E(|6m|7)Z8^yw3r=PrZ);_knVLDuOzht+2< zjstxJXazckC|A!Vr$ZU?QM=0Rw;Z};?&gpBleK z{DbkA)fdD|@;WJ39yD5TFRd35%Q1Pj4h@wxqrbFNyqSZs!>2~b z*?#c?enl+d4iG{lH%`|Xjq=;f;DZ01r5`*%zM8C(Agamz{S4Y4qx&0C@YQ+w9x=?@Lc^)u` z=w;u4CUIC?tmQ2;F&D;3ItxD(1XJ+ECm7e)B2EjWXax@|(zB_^6t3e*mt50FsIU9~ zr|N;0Z%yb06aVwuX|3j}iy()S9%4?0=^;bTD@8)~%~dBW^h zkqmb$e29~yEa=ZazYZi^yAwqA6U%Q&JQ$C_J}B8CO4zNl=$8w~tmE^;tDrrv$K{~E z0dInQi3mqxl@tP5$<+7swT& zR^Zf4N=hnl8Z+CFaCNPio;nX&xWn<`POeVP8FpFyx@8dW)X=8O=v3N^I5>6Ce8(c9 z^0~VPHVNaK)cPvZzgPY$YmoP~IEUK2@7&j~W5@7W6qO&rZlYmh%N`NxM>Tj1m}8nh=`xDW!+ z3N|k87bwF3!Z0$4iHRW=6MlaFahOZHy2-7g$bv!kZZcdBe!{IzNg-wF`Ef z3vg2L05rjlL0Zo}&Id$cYDflqBLd<7tAZb%Z+L&MsYYv(!Ej(E7~D>X2*$@p1{n$B zTPE+YIm-8c*$Xue%8DwB>8D=PU|V&g8pI@j#T4jY!z{6r<3_RTp2^ZIrHlIDXPjf#quOCos0u;_Q0rj8!3QPa5r@H70+?nU7#4gp z?19rZDI3@+Ex@{n1?;jXv@}a3)<8|l0Zv_Z*~TDmAe#WBP5zv2h6n6I@jo#;YqT|1 zxK*J^a>Ikh>!JN+9I7T8AYqa2_WSLOhD*7y{e#_?ZfF7Fc+zJ0loNO5kO7${IDQ41 zMuvuZkW&#`07S#SXLx?#G_(tx$z&M>TIz}CQ&Ux|l?%ZITME~TDc6zGO;=OXO zU0GW;1*g76KSZpuZ9qh=Cr>;Gnp#@!0j%}KiXpHA1Xu9+CY%=Q((+yd>-jDQu=3#q zfLNkdp#t(f%sp)0V7t(tV3YzoyF$+Uk~T^GF<6yysC>ci0wzsN=ov#Y0JO`D14fK})%duocf8|bcu&3^ofd>% zG}#T|MZ0@Q@CET5d^m7@0QA|yeHtEgP>xD}%Ih6*7@{x}>*0aYtq=X@<{7nKa4AEF zRCQV0t1pXiXU*E$+Uty5nqG%YwR}v_LCbl}HHn}Me9|0o{-bemJ^zp2T@hkmA0brQ z`uYU7jQiZW0UQE z%9)v&TF_r1P)1~54wgWodT;NN2)ct>lLBX(G`oO%LYV0OmKqdL;6i*vfukq>ExzAW zP6Yu3T+7}P&XNaGy{fNG%E5eX35`My4i42LBUA|S0X8o2dN2%3tgIjnDa|WQE_};H z6u!Sr(4yZ2zQvgY3^<=Ex=A`bGQt7z4@_d;W!WMdJSysCTBOweu0&!ME;&EewScfY z)%#Wi&Ia(N&`}eD@Jaz-YlChOs^{GWL>RPgNpXoO$=Fz|PBDmVvp!irH&!Kr*fb5A zE&-gkbc%-#NtiV~iEn?GZ(yrbd_xU)0Q4v+^*XfKbZbXKtz5IO9Vocb{|WR>9WWLa z=)t{Ok7%YT#d*Y4Z3~Ny!KJNBA#w)kjWYXQa3110xc?*~SKAHrELn?4wJ{>~7JV7` zos&s1JqKsdUKcLoblus6UdZ@sm$=MbA4s@ZY%I4q?PHx3dgz`3!}rVPOJ)V+ksX$ z3))NCX!{ibmqH(e9k^cr_HPdQY?|tM92@|U;L0hw|B&$w?X6p7gZ*y16Iki@wXpBE zkDm0}A$2xqbjIbKM)~V#Xq4?+z#oO;A5b1KCB(MOmD($?^Wl04siM^J-`gJi3fr2G z8Rgy?r2Yazq}AyqWcN0=W0h{(jH8e3j9O;4AnZ?cN?xr8VjHo}0Lk#>%NHoB!rzeK z$o&;UtNzoY^lLzF|r{tc}zF>MJ2fm`g+f>}t*_DL*-K|vqitvKfu zfl>EpP1?xjT-W{QC(0cfB*2?04*j*t{Vz_RB_JW`o#grLF$Bs3JhFG?5kn!=d&(or z;3NWosgfsm>vx=i0^;MluCLt>MS_tlB#z3ez{Fr6j=zas;eswWQEBN5j1S{*!B~rM zBCy}Y&CD`%8g(Uuz?x)U%F4o0-^^AO1T^&b%~25?rh1j3=8ShZ=JR3yVP$}givUNY zS4VC^Pc&6gZ}N*jHa7O_0#;`}QZGMY3Y^UOzt#MmQ3~J>AyU=5+HVd#rbX^HlR`{i zX*YrgYE?mVj5@Zy4gIuHw-_#NBp3a#RBdj(m}+E->OVvxKXQRvQez(}k7{rya+OQQ z*Ozc((!z!vRTo3=i519G2c(s1qzffZBlh z!1G_#zRc?D@4GR8oJ~pQ)=MYB87$t65}+*}LfQtwuwQI3)&L4|F1T-FM)!?GKk<{B z9AX6h$JG~L223*<4z>qNB1Fv^2({wgfN7vt;mM%4%D0oJ7Jb*RsjnB`M8nL0L#7gu zwPD94r4wpghKiPEKjJhVo&hrmKbs4^IFPojig(jxSb(%iC(s8Vw z9C}Tv%Sg>;93AGwl((jwa>H0X;;-pW&&wtZD8;a#DH7TBhS1U%TrarTX|4yTYP}8& z8kPucX6M@9+B-N}YowGk)H&-s;GC`IUVc2l#lO-n)b12#B%HskUUgm}QtRPNte*i2 zMLW>op^%Dn5Qm0^>2=fA--8VcUKO|~$G^9pcg_)d{XTrCUMRGv{Dld(rw|%+*lhnl zoV^D)&~4j4-qet&tc*mc%$6NRNNJIfJqnrGI}JierKpTTl4NJEWK|-{-jb1-%E)yP7?-tHzII7S2%>F3jg{y%v$SeP^@! z;~bVaztR1NB2Q&qsb#EV)y8(?1l*{rxA!_BQlV4tJGUmMpvZG7OWcjcc@tYzf{dFM ztEFoC_=OXZ0V}QhQxO-0xU@0+mr|J_&Xz;jKIQGos}_8y+?rc!CQ#-eLXIGD78VJQ z0smZvLK#cOdnUM|2V2kLr8@Riv6AW?V)*iHf%~sMe!NvD#H5C^&fYL`&N+Vum$e~X zfc>*Sf~xjHS;ednpk!`u(UwDp(f~JZVreN4Y*F5y@e2Bps*#{X^-i6TTNhOfyC7e~ zI=`Zm#1JN++$Z~Fz#xcnMT>f}h!09rt83S&AY~U0kBjd-_*}qvO|OjSKx$G&WhK@2 z6Jed&erYZLJf2c{62(B&YS^eW-A6zmp@XO&ocScem~#FQe-yoneogMZ#?(l95#AYx z(yO-~=e%jan^PFdY5cORMu^^1%11#`_@)X1FRo?p9e^*EXtPE&!rFA)`Ve67n(9f} z4&j^=;o>WOWj}wL`C_~HL!Jo~u-l)gy(b`?eOZ{ke`{3EGlA!dOGKju3Vy8flIfyQ zHiXFlr)~+Tna4MXP82Bvl0oaG-Rw4P6w>yF7LjbAb{lUW2^ffekHCRW3 zuKVX_SUry>va8ro&0IR4X?msi=yS!@|Kkt-Vj~6uxpXGKCHndEwQIei)Q;SciCoQw zD-I1)R#Lihc#HE2;83cM!hf3)tZnwJK=JI*FFY~&G*IT0wn_-iMR~IFpD|NX((}E7 zYl^P{ojfr!L!NTZ`FMhAG$=h2b8}ixrJQba@R~r<@y?|+H5-`6edI!_ALoRfR6B8E z{lLJ0Q^QA1ZCInxK*RpEgP)&{7M^==6&^VNP)T=ay<|2>;U#2<_4o-E97LSh_wV2J zb});us;#om1X^;C65$epL3+WlHMNu7UX?1Ogk zfsyX<>OB=RkWk6l@>tJ3FB<4Le{|HK>gU=#;f!?^9Z9d#c@x40cmxFx7hak}nRI9U zWS)7`9-<9|lV{W2e5@KJ5qgBN1&|ah8~306O2qn_W>lG)H$gHVaJF9Eebn*lHPv{s ziIdD6Y$!FWRz=F#i#D)6eWvMXtuW33JVViTQrvp2Fkpoc%0+8gdxDIaJEO#X(*)}f|(1>`4RzM2Lv{o z7pOh6kZvtBrQyjos#AZKeZC~#@ZH6Eb4uuKTsJZAa#ZDdZ!}_eFC>J#A;6XQ&xGw_ z3Lvl!>I4(RNWnX`bMo0P<2>kUjeqr6|N7oD_1RBw7dl18b(1Wd`}eZ|JE8Me%Gtys z_3O(f*~5no!2zk~Ii>VpyLKuP@3jF<@vV@M^4#F|fsK1#rW}mCwLEV3yC&Nh8vJd= z24Lo7H$#2Gv44N-cX8ZHzAqK|NP~2p0%$Jm83b1oH5Ct#P~8u%s0?G%x^h&||b@ zq8!fKJ$C&JL>h@}rYWL(a<*n}?)vmjOgDw(!-ASIM7m~h15*2lM!Q+PKb~{EbE`(O z-co|~UZ{?%n)k>-|Ri+opm7|GoutF|Pp|7B;rCHwRj|dFxtEP-e-Z=+^w%JG-;o(PZy!b7t9xU z=zgUU(RIMh`ZA?j?Z`lp^h^A!#~$oi38z&VP;?OlNBoeHFPx2wdPcz6G}tN^&A4T~}OP zCZo$0w`x@liM|{exrs0WJs6Gk?ze7uY%667FX68hKm zpayWb(Odj=k>a0v@B?726`<5lxdmwl+Pn6@Pk}f*=>bh1CZ1$Y=M4qN{EF^;k!$2! zU=p$Fcsb3ydtiXlwXK6l_!^RQ%dwtmn3)HmfGyH1ixRsxC7gkdY1oJ+B*05M*MXgf zXD#&kMes1JzK)~5>TA_j7ZfAA^JaY`(2ml#+3T#sOdHi7LmfbF~^=4c)?I|nT-6jcHV*mmxkthRZ)XLyogh< zEd%KI<0;f*Y*z0K8(9~HM3YW1W*IKS@PL#OeFhRAr8j#8B*JX`8Hs;`-?EXG^9qr{ zvj4hPWYZd8)qs1o4_TQ~jYt7$90fS9oj&|kemucx>Zhv_kZ`}yQDEd{EBn!qZA0hd zp;KpslXZu;5WRz&Zs4i6>FZmwE9c^9h8sxThE~Nq`)R<+o7TP3oGRoPUyWlNNmGz; z08@dUmjT5^IS?;760p)WIOvC32okQb2t(}bnYS3D6)JbCsCC%qKFBXz4RQ6;~zgmnmC!gw-^8z91rC;$YCw5VtJgFw%a~?5EF2*cKv0Me9o} z^zn1@B`@M*CrktVh*$s~8CVgxq@_Fj8Y zdtukVA|86W|LBn;(l$1GtaB7zHb9s_(#sGlz{1bZPXq)yIuZT$<7GO)V6kk1b(b>; z>b##xa+UlgRNc|RcInb3yV7M|GFv&zb|~ADOub5ZxA6|avHAI%v5~%K8s1WFPoBL< z8_cS4WAvnl_w-Yjn!!DLjbzytSj5!QYVgQL<-C)Xn0Q^Z%}I6feF+Xj<82yh4i3UH zhYs;KFa?wivDpoX@h~tQ(*VSDF3W0iSa2@IsgO`QL&I&O4$ilpKIMj80rX={lNk)*1X>|+rSc%sXtS5 z>Sq5Yvs3Q557Ww)B{Z>I`~Kn6l&~%3rKVARYz+@E z(Y|TQ2l4Bn7-bk>Ndm=H8J>GGaVpJuR*@}=fZIS5svb_b)9IbhstceSQQ(8$BIKj5 zfGvaW4k;HaOJSxUQ5Q8P;;oJv8ccwood5k@MGowFa9rKPlvUtN$m7VkE59$V*q5?A zMXzK3myYVFx7D79ymqQjb_mLidOx|D)c&t$x5b8_efwy! zk`E!Sb;G6pXJav^c7Xh=L|u9)_7l=-9J8zf6(eq3KGGT9qlWG6tI1h}b(5_I^UJN_Gb(4#+2@qz8}93id|S&kv@gxtqvu8Iy zeE4t|I`d}ri^=)xS;cF2YR}Dp%qDx~y?Y&b22Ouz0qy~2Z_Kn}L&?td*H7$lhUfVr zN~#+J15)`3OPeEk={-liu|e}4VDX|95qyRCk2l%HjXUNtx6a(%J5a7x>H1xaucE zlMn%Vw{ZWQ zxgmmKbkZ`gxmg3Q=-eE*4~9l+dF69lELDakY%*}AiDn)dpJNm3cRgUNtz&e3@~7F8 z_St=-wsBBF+aPJFNhLR*Nu_-7KR=pu60ov>byL#RQ&W^L+95vEcVb z{Ok9jeh2JKI3PsL?jRA^s`10^lZU7!J@Fb56$1nCw+KBKMR2W%R)A*Z*o*uy3%Buf zB!WCEe=2CUi|dQH3|B+4<#;|AF*b`lNHvrz)1Z&sEl!Ve7RrpLo?3hwUq?~YHh&u37* za_X%RB`VX5M@MxTwtlJq{bwS~6F<{{xZ;6D z5YGqb%Y8@YJkSZ9Qd29RxxZ1f)ki0?c(#d-m5DN2tg`x?NYkvyVh<7c_fy%d0Uq6$ zg-8;(8SuO9g}u>e3|}+B-3Onyhc0SzW~WoS$}@^7lI34fubCP(83U?8K4xsgbD!uHrZj52TSQ}vRlE`XJ(2Z z9mJ_HwmnKYj$}e1UBzJdyp`MA9-G#j@xruwfyi}2W!i2iCjt7&K_qmeMytto-fjWm zvf5WB`?^1R)o&?1^aojBM=SjEr+V28PT78**jpOQs~;X`u{)D?n@NPIClxaC1pe4{_m^N9rJ2KA_NVQynzA7=+gMi zp_WW)@_#KY1+cA{3&fapT*!(ko!H>&_OZ5hMS`lCt;jjJXR(qEhU=Paq~WUsn+XnS z%?-o=AW15BlK)9ok^TNJf8#B;AD&i7Ap4D5W9@&xJY?C4ac*2ggw-Lsmp0>My`{jZ zTHDZ&=8yq%d)KOS?`oP_{=S)mf^UsFUm{?eNsqn;1 za4cajrAq8(|7U}*4U1}!P@_6%COrT3X1+oI^PeSuHAq|&l1?4>@iP@wQy}zUHM`w2 zmysci!qmQ{2{CZVMwLt}R;@AwwHjprc_+DA{AHiXL&j+#_ctiFUcAeORAuW!rv4m4 zu`gRH&zdetnPE>4`9@Q$^+D-UJ2uTrw-i0h-tgfi+?9Jer z5q)8k8FoDO6KR>yoh~{LSy=dZX6NQe>=RgSNUDl{=^I9`F$-4f&QC^$?zCiZp>ADw zXXmjAs3C7KYnA`Cx`9H)iOD57CNdqw0W!?BzhqZ~ttXp}2Nq^GK@N%6K!A~5uv&rT2u~LPQBTYSWI_mvn^E7i*e5YD zT>&EPuYiSOdclfKEKCCd>bc6^o4c*l^XIDu=^Pf08y6Kd4RINTNgh$!LEH8FIf-gg zZFM+cC+u329kGj)U{Pj#=ZuU<@@byOuL(Hgq>YS>GQ;6$M*X?qP9PCv4)O`6W`@Igo3jwKa!$F1=(TFDu7^@!vp;vJ;I~EFFxXBMUKvP6RL-R`fNCFa2k#U(C7PZ^BiX{(m@?qcm{fOgI-*LSV(bP!6}>5Kde} zO?~*>InES0iGP0rGNx3o>ZwV1pUoEq)D8QDg<<$w2a?$dTUSkeJ+~-%Bfjn@WMLr9 zK4=%s&Y#gi3?dihX63(>+<_L}Iiy#$L^jNK9 zD1APYh@tWEbaAC{#y+=9&d_^AL?U4IAxR{?_}=nXiMra^mz;FG5d&@owrg5|@rSX1jVGr%yQvH3wF1?2c@7=1=6zSO zPSTX`mZ{+X*0zFnenLO|rv~6G-(mc2CkmX#sV*SN81ks3?gXY`NI%kofub!efu*lwDuF27^zt_Z~}nRm7QJSx7g1Gu?aQ>)5Ay@!WG^ zIV~2h>E*;Q2qcXVwIt(AwiF7`Kc?KzE310?Ae|}zJgSluJ8t4A5%V*9cE5~FQS%rKgu`67$_w;sM;k`)KK5O^s`Xv@AV}K=4r!h3=-D?&MJo4KB&Vp);niZL8+PC5 zrR}O|Y3_yKmgJ7zdi2O@JR9*Yf(26?7JNS=|4p!fT}{pg0ePRf5(*Wy8q5I?S5apWnEdyVvn4@18v$N7lFFVL-2P z6*0NxBLaEwNFv$8#wQ=cvaSQuc!iG=P*4d}Xft`wI)5L)of5H_Fy`RW_K8u>cI`Ek zO$bp!g|d93?+T)b9%)aXduE{fO3oq;i)!lEFVg!0u@pcOVKSIDK|b zX{tWTg}@JCtjBLnaM=IZEs_JsVk0PYE@Pmkyn`IR6uex66<{$%7V|Ta`!VIn{qJZKfzLP?cI0bHy@eAD0@k^8d&6; zB&_TLD{yFHQL4JO?`?qBOvj_y*Y@wj&#ZC3HhzgN{401384V2$?@5Rtz|w&Hh76u( z2eD5)IA)ZV3qFPdF{j?b^oWSN0+yo)q!{7`@6w?FSkKS%XX|%ij@EJRp@WC1#U>vQ zhUDu2UqrB|(@1t7ae`yFttg4h%3|Eaee4w^^M0>hy;|R(RkFkQ!%h-AMMyg$6TsXJ z6mun^NWvz=0dVSm7+9GxVGv(|1~aqc(jnw&qr2IKa2%3{VW16WIr{lc}im*zv-u*|$x#HLk5NYGF<`*P&aN(5v$m)lR;pj@ZWV6RR-rtE(W_b?Abli4}pnshEYU z=_qN}#+3gQmY+j8?*uOge}iED&yBF5-_XpoEP{6kry?Yt1cAjdQM7B4iIOPIV3EbiG%P+;uZWRd8h+yN%ft~oU*q@puh8+T>Om7uaKq+iaRJBCHJD1GeW1P@CllH3 zUg&591k$TYyL@gR@cbM_ua*1pXpoAC9faIaii&-iZ`?-@0*IHPt>kHvsY{Gv|6!yK za3d9WGLEgjwzd;cY`PW$J^e&B+xKt+Yl`4GfFvr$*9HI(T=8q-R|*cMhwNNKRRE6+ ze~t>b=-i%2ETo8th~UQg&h%}zF?+w7cu@et>)^tB_I-yTHq#*NUl$BP)JjQz7yxj6stF3fL$8{#;IZ z$|1*OXLtS#_tV}BvmY-{b|k)H3lSG+i#~FLOz_b43Fi2#gM8f7S=n442zji_1-%UvOEFUHE!K#8nf;R;D z>43$MF3@IbYmA&&2*JV2fC@Xraa+CJ_1nX;_V&d*S9SIKl^^C2{q+sV=ndpNSl820 za#r~&)Ys8LCxE~WLTW#PhWdk! zX;f$EEbfa=i$4sle3rD=U}1!UMZ#_sKflq?O#0G=?9r0d51&lc5EVsg$Tqt_DvOI7 zq6M_FmcSbZvuNvgpD!pD$XBeJHSoKb;n4Z$LFnk9 z=6ZzyC%zN^Ey-1>VRfe-#|fy znmlw85}5!zxlOR7mC4u!5x$Xq#%|NQM5biu2c$IA&yS1Pr^~Z6$Ct--2Q zyctT%qt$Pqd4JrKZdB7sM$G!BeXd8vdBaEu8-YO_B7*C5JbgmoO?~i~-)8E%X2W9d z>+Q#QUO04&Ov3=Ps+z&T1@RSY;%IT)kNzI}Uav3o_24SchUPl2#HlV;0x*wn708R~2a zNH?+E(=wY|CLh$pc=X{D@rIr^r`flBneUZ09<^>$&$8)Ri_xFoz@zxI>&SQt)9;}D z&JL|Yc(vqM$tHl!hfbf~MDje5S>db0P~2)ZF^f?>tJkc#lA9|rKap9e55u9;KwNBp z9L=&%|Ll;9nw3UoSs)KC`4N*#^a9~s4Xvs@b8+jLki9ExBRPb%HHB-NCFOr~D~#N% z$tz4bg|UV37K~0Ip*=3&srnCGNhtN`c+jU%od%!g0OCz#m}yO@5DjYTHlsE{=eQTl zM|w!3-EHyh#MDCih?SAl98xy}qH|nUQT0~E#OJ4+f_DpKE8Jh#9gkO;3jQtkP;s<} zry7>86<{#89u0xgk8xkDua>^!CL$7N8@g>JHkj zt>XeKWn+h4Q+6Lcz+z7_K7q~s=Z1n`z05c>i+yjz*yLZl;3My9JtDvsao^7OVlm;6E)t{QvxI~m?VwXOgiTcXEn)F7;ag3$ zTePKXdFBSG1eVZ-hQ|F9qtIN0Nwjc?6RvCE^NEIQp&}Uvs6#_Tc}=yoNUi%N=;UXd z15?Or-oVN_eCjWdQZhgZehMOE7q)8m#}q~q8He5o)eMGx1V?kVbf2Cfvm8JWjS-vz z@$*D0#eVN7=|u@4&4z%%N9FAV7|=yL`KXw(0ti_m*I9g`QC57gwthy%aXmgho{nfd zp8SVmB_-_Zd%D8WLW>I=dCaO;^7dBldihZ4OwIM-R=!zb;@1v(!&th_cdlot^ z!bC7W9W0Z9>;z8)c73Dw_m}$0E`xOpkDHt{`tB-w)Kb(ihxNdLN0TgX)j-fb6FB@e zRj7ek+zyWX-RrL5;LXF3J>pM<=W7hl^GD7YuLbTgDmnSqSYPH9)gRH%}`Qw~ry$nc6YvA4bgKL7;Q z;C2r&qh9h7%D=$3AD?;fAVkhG9Jep)=UDQg@P4m+xxA!AZ@4);U~U?Yb?!+4YN zBcfqp4L$+DJ#Hc@he#aQsSXR#H?#R+T_3*50%HH+Y1w$*BtC}tK=&J5Z~eZd^U>2$ z(aH8hEO1-2LBf9E?wO%YYhR}5b!Ue{lfAlrhdD`LhSBk|{>X4TxK1Bh_UJp)l(8II!ARNlmw@qFxK}8tzf`>2THO zO*EV3wZux0hr_`{`NTd26m9DH3X%nY&+YYZ8~!Uqe2Eq|41`+jdg;*0dG13Z1te_x z0JvfiIlCqYNv?dM>bIZ#;m@HWT7eP>@Rfe)4LS%lctt|^&R)gs6C)Zd>8mhsVE?XT z4FO&#w=l05zN~dj`<{K8`Ev)&%o=X|EhgEPd(-vj+p|r~Eojpd3sM<;ZS()M{j5@% zadB%fGi2z;nE`XMNt$umgww{m>z3gYwTuNe#jqNEK4Fbn~2- zKH8!!r^Y8brbR;Y{s4n@eNO>ZT6xScTWvoCuH#CT!$9rM{c}G*sh%K}1olph6ug%< zV}4<`VcqA@)%UcDr}`4R64WZj2JY`6PxN#D;H_};FDm3(8UV0Z!+HJL4w9hfe&n#e z17V>O(p28(y!YSyOXTHL|K#~MycOHzL!yV}K5GS{PS(k1LW0Dbii&GRddV+3o3pI9 z2|mpE2=;}hMxFR%F*xR&+|i>qwg$YGZ$J}2hIMW~)k^vn+<91g{M(YwZ&zBJ7KYd6 zZFFP(bjWHeG&&)Q;sQmH(kHWWsxVd(yJl;Sz2A<-VqYsmTO zB8g+VuIsi@!*EL_LaVn*Hz3K4jGp~$2caZ(txd6hDhHnY-a^&@Ij^gm)Os!;9c9D- zVcOQGDYx7vw&KtFU$xceM%AB*Ns|3?Wl||7>2-Lp1d$au^v(0QxTaj;)wZy(faDu< z2+NUnx#B;6DNbf2;hR$GXzcZ&hHZ`ETt-e!jx^p?|L;_YXu8ATg=tc2SSr z81++~IW`P|SA)oAQ9S!BP3&GG6ixSo%C16(jGdZ^ znc2C<`T)K$MoE{KF`t@1-#`k0QIIaKw+Fmc7>G=gQ`*!&Drc%Yx+BE8UY$m{a$+lI zt+{;K2D<6BL+_ie+x>d5Ypz?lOa)Hf)KR{0npex*U@}$ z)KnjA`0pKsNZg`5vvEl7Ih!)bZL;YQp8Yem09MlTrY)YH50ATUqrSbWqx?oOTVz38 z#EwOtANH!>N`o+YHHc`i(!jcf>kMw(Yml-waLG=vCsVum>5b=O+X5< zZSZJt&$Q*BHqk=J2i<1;FPC?;0kk+&YV~H|ktHVHy?y(&+NbLdxH}AM(nu84&hbR9 zcuPKaDfJOn-L}69zr_lAkc6b8^mS^G)*w>zt`8b;oc27gP*6@%T9F zCNbUpjp`^>y^e9G#aE!5966D1ARArt3T}#h6E3$BhkDGr6_F45TgA>o7cKm@@cQ?Y zF+I~xW4mX=#y8>YDh*}$R_ZH6cE%~C@#O;}^+-ce*>~44`e(K18jLxD5mq9>ioC;|1?% zgS$g_Xvf}J1P^+IYj|J%?$&Bq5OCgGs)VbJ3sF3rk0dWAoo8NzyGBQKFGDs}ZEiAh zu~N=r+eD+HDIq7jwoW{(+&~`VKPrWlD_3G46Lp{72cz96nOJ}X9ylcT|6kM+d`zxw z)Xc7HoZU#i3>;T+`?4zmH@1tya zy-^t(T!*;QDXIrARC3e*|IvXA<=}E*$fen`r9Dm;k~oClt|t>Z1s9&4@|2%3l!i{_ zMX)DwRvAFq<Z^lL*o<5@S*@sNHLGv#to!{2pFKJe)wdCe`B}& zNxO0G!(V!P4LV<4aqzhP?!yOf)%bKRvwchz-$zMIl%06{4;HW2bU>*|PBHlbbaX2N zEqq}SQzYy4Z7Yn z=Sot393C6}IUZa%`Xc2bM4|gKgvIU2LpGT_tdX{c?LU+&p>7z~2j-+73an33KA1CX zbyn5UBZZrOL{~KvG;!=PD)QHZ~=&(6&~BoOjr%d;#Qfe=mM%CU)w49#1X!Lt%=qIXau?T)T7A>#_; zV;b7LPy#*|P&QivQPH(TQ{l);Uvuf#T1mNo?PW$mWo7aRtGM<5T`iN5{nH-cKNcr@ zz0O2g$ZyRh@{j)3T;4mHz@2Zt_*(ZJz&_R3nyeIG2mK~e+v<570McVJ4cw7r=1A~i z&i;8y+TF_N(jcqA{3aS?Tcv$pm}u*&c=t~H%Q)~c@Z<4^J)4{03k53YGV4Qw`b9A^a=ifXLu8k}X25o_`)49r?dDwziOR7})OA zp0RBM9gx@ZRT>ILq;M0`N}xy~5<9r2(2xPmTsc$(FOQOzsxGO!KDHm7q|O zag$jxg-@~Kc^Iw(zS&&EPOwuBlU$pTE(4*3i=7oJZe{!1i)yH;h`qEU=q;aOf|r7s885z= zbcUt3=J%UB!ktuldFk>O5!5DQUjkK}Ay-j|^{kT}x4BiFm#efk0dubR; zT48NTXe_8)8`b}r)pIyr@>}tPVR5U2R#D6bsrunU-F~pIbt)-Hn3Z2=6Nyx;+ z90MSw%DKhKK^rz;zVe>-9~`C5h$JJy%6@)+mF~32%f=rYr}LEKkgfgc=Fu2f{M9l= z_HhZx-+mt7Rvs3!_yqBb6zcHqeK5)K-cbqnOSi1nQ5=e`cu?|`3~W5;;NTFFgJ;q1 z_TxB=1;xF4&J*{>b&+mhnDG^+`wC5`GCrGoqOSQ=FGh|?Ovc#XdNG0 zw(VW~GOJWcnaG%&9&)NrcKDWX1LE-@2GL$j^A8cw{ybNac^KG38`t$kF-~bo$w7|W zja1yu&dw;Xu9BRd-h9)2i()SXg_m$cQ}f%ALfam+J>*DZMTMWbw)qcfW#v2C9vJw3 zT|TNn9;bEKpk9diclhLb@8n;2`*&d7HDiQLv$0C?PU(yd_-It^1AEB1041 zT;nd1eciFopTFy!r-W+iIuv*C5;eHYG=DiFnhc8_f?&}}>->40 zy~V1>V7wB9(L(*eGFeF9&M?FYErH7Okkt^^#2>~4zR z{e2hiRDMv#fO`P}hi4z`GZthp3-#+f<=rjOm?e#%UE-!!Qc?=OANJ@`Aofsffyc%8;RuTDCNJl_4WBFYSLG-{#a>co78D|IS(WmpHy>k$vNZ~ z)&8+=!+|GcS;RDSw8%*UL`Qvg|A2=StZo84y&oP?!>0pw=Ik8DiRX!l+`QOxg&*y# z1l}VP*&ozLhb@kbEvm5jIpL~s{CFu;bI5%;j3;jAhn!?GG8>8x)p-mnq(WDXKyfLt zEg$rDA$F}%DhP#Kw{K-H@fvdjLr zYzU<}2d3>ja-Vqcj3h+CzGqP;r)=MZ@saHqUvT%h>*N=wx9w34gE(=PXKPtvW+{B$ zkSL+c$w|2VSxX^C8TTa3ahptHqG$VPvJYhvq0HRf-5*Vl<4s|G>Dz|E&SF0}bp-gy zg&e3op9yr;Y{HzabJ*P$Jt(%%1eC9BspC4P?N-je))DD&FF$p2o#CMqoNt(S^29du z%ZX$VA-9Db&%7fYhuH-Lsy!?h@T{I4s1j~RMBIcCseLpi3G%YnD3>gnHMoPur*ZEFdmey}T8jsc z#R3CJ^yAKU*%xy!#!%K)IJeRE$wHNhhX_?BdZa|`nh+&8=~lT7*7IX+`LT7JJbCjG z?Or?pg_9?@yNp6FxCE%=&vT=zcOSy&kQ6y+6fR$05-Rcd1{pGkK9nZjulDg_T)43* zp^5QV^vL!xKJJB(4ip^8fPdRZD{ljfqlTg(<3b;<4cglFx#Vz^QSe;Kz@vio6FhSa z3kkM74ADdA(TeuM(?>hfFh34OkRD1{)tMatDk#AHp}hl04O3cq|b-zfV8_mnuV? zbl||oEmg=aI2uFpe}Nb#*jaWI5E%ykAyQ6uY;Qo}1*o@p;MWg_=D-lzkLO;5qrL*- zhtgJaI57{c7h;6K&-y61Dv93-4fTU-ir7D)^~s!)f%zTbg^2WW(zQ19!@cL02Mo96 zGN3t?oxkBxn2!U4|6vQ8l?}o>SM<1Bnay_RQD5MV8?TYyWHEr0<$YK|&Xdxv$!#82 zO5Sen(K*eBxGhBBz5{eE-ITk)K8^+{6=R+S7VShdRU2K>?VsHSjmCm&Vd z9N-Y@2gqE!nTZmkEX$r83CdYFjiZE&ZXiY9)Ra>VLjhJI>auG%Fye%^ZHvZd*3#Te z!dKhfYtQXDdowoA<4~T1EA*%v>efZIwycVon|d=N!h$vdj|Lm-NKmwrt6!1cK_jE5 zm3u3DY{U?EBfDU7`9y3nVq7{$M%s&XCa@K6MA7I}=$N=Qo!F@ls|hjt+H%}MV%TG5 zN|(8O8QY$B_kcd`gWho`4@#LaP=w8VTaSE_GbP{Ws;>cFfXu*|w+!3#_4XnLPLpn) zc=J(@;xj-DTS@Nqh&_jv(1V zyqh(0A#exW&SAOtq~w^a>SoHe{M4Q86rM&iN8* z@*mEZa8fBremH>cFx2%ZvDI-0K`xP@SV+QbQO?0+37uuVu3s{!=B}f5eoT_-W#seX!_rK2-P1L4f@JDqjiDX}_P3dSx;!^SUk5ShD%>@n3!CC7l1H_Q= zlbeDEYXv+W#~w+s0!DyAsu-?|Peo-AdEl43O1!@%?yk9vr1$f+GDwpi~I}w>@O{w zgJ?Uf<3(U3u2A-AdQ_wO^9H~y?gq=!GtAdhBu{E-3-|m zT1iHsU@coY4}*hwH9t4wJb4D-m!m;1gji@8Ut@kdnMbH4;Ehln>>w*G1dU~R?tLby z$FdyKSn-gnqHXJW5=bpIwFG)Phw?<#_?|X~pr9aYNR~hhK*md==AiTspAQAWyn~i? za`ny~S(Ci=z>8L9a~$QlX8=^1DDkZ2qH7Kcgg_`9TQM64h~cI-veVJ%Dvh3xZm{i8 zCo?4Ro=8cFjgbN^(z0T85&Drw7h6pGFDj94%IWW;se~T#ry(ki2gfM#BNj#qB?krv zhaGYxDAzwhjv9Fbg!i7pOi%s>yd!``#L|wVj6VsB$gujcG=%tg`(+St=sS;MLE;*N z2WNurqTV^iefrVh#)zWv7cRNNiy4A z6i>|%WL_VAH73YDc+k`%7>|we6{cw?1Uu>$xNXLwWu31#*%yTguW0cQ&ar;{6Eq;G z*g|uV9qdE0R-rq6>ALLtso@?ti|E+-_|^er#lYUQt0iz+G>?d15i5_ui-I|38x zf zuYuE}v!{pa&C|7-Sud87Dequ$h+^RQ@#E^L=hjGJl*%rDQB}U`hm|QmWl8x08`maH z*#>o*>8+qMNpUG4dh5BLein7FA3gtTr0t96&0_%>KrE-4Lmi4kn%YM z)glI{Wf=M1<=A7Q4 zS_U#!Jrc1|n^mx>x%mbPR~89}_XFc#`8!b=K{`D;(?XeVw0}VDxZ9w_=fvb; zr8t!r+zk0K2?%L?GW~s(-GeJo&m^-23Db-=0g&l~r8?mIKDq zGHTS72~9kk&m5+$PHyhA093q#j&^Vm}HnuGFy5tHu-*#Xa&8bd7s zks{_^7E~<6rgd*`0QrW|cWbJ2$R_{x92VfnPo?Kouw3J&g##ZSQ&hYLnVN~(ChN1y zN#JZ_@>0RPZ_7{*?#6(3rN!g`^+hR}FaM$!f8eva8VY}GPuC${evE`+gmILi@+4XD zWEeO07!sU{X~Ey>HLb4bi*vJ~Fafhr+|l#p3;u-@$rA&EQCCN^>NWw$7}_EjcWQ^| z1An**w@FAa!<6-0p&bAQ{7M^WX>0om#ksk-2%#rz--r4uJGNvFwLJUo-5Vfz+Y7be z3Rr^RfZ*ihBw@P2zH)$)&fD0d#6&M@tWz z^!{D=IKh8m(}*%%+?^H!u{LS`4!j_8y})gD!*DK;p%#eUBhko;yR$JDg9LwI6Gg0( z4CX>WfqW;&?(0S*Vd`h&9)-#KMI>W**&VK+u4ch|;l2aI30K=A5!aJK=esX$x z`o{OEBY5=4Nbf?PI>b=2FvD@52=jr*c$fb$*|IjT`}B)5cQ4HJX6Edj{yB{$^pN3H zmH8!NiIOr0)dLyFg6TdVDd zv%zv14A+Lsmo-U@csIvS=6I%V+lO)}7q79=t*XGiSmf}~N<{eo1DC|lG2oCVQNW1c z6t%lU@V8?R_q~k_5`c+** zO){j=w5H|iM<+;fdFlyntodr!2oM-m9tOo)UZCjd>(f-7gbd#?*&D5C?}FjzQ1L_Y zPqPOWUZ^>8y}zr#%Xra$=+wD$0XLSuC{~Xzw6A?$yV*Nqn`NwGChLQ6R*hI>(xx}Y z^^Yi+jZqCMzMyL`(2TpqAj;0Zon|d+Y zuWnoIvgPcP&Q(9YWRLb06gtYSG<3-W4~Em8B#WY}D03c;p9qqalq6(55f~!^GZI2L zfridCGnj?-C8bRHir3hDCCW+UPKsK6`t%8DEA@|=1$8e1O9Bp5cI+PL8RF@g>~nrO zWkX$EQ*(t&F?cI@AC$Ny*#D7%;EyySJ9WJ)Hd!;%)1u+#0-lng$>ma*{as=(=D9gZ zPi8gW3iiqFVquM3l7x>?lIZB@IcRJjhrGQbC;`Bg&qdPuRkeHBDq z3f$hc_RwhzNkRiZ!>QeBn*JHW+2kg3Mn=YiuC5X&)0W46@+I;lhY~FT2Fup0E3nL+ zYxM}?JOXg0Z1-_w<6v+_{8LYjgzKdSYjVaO`h+2P306MTJ(EuBsVJ7CxkC>iHu#;N zo-)4oAQ~KqI|%4iHi$SKm;6huADS6--K0Gj+6&y7y{Xxro}|R~Z3|##pNPmItV5_@ z$9ylI)752zf#1~B^m@}794I)*i_L{swK@G-Hfi6)dQ{gCnxnh}4bjq#Ei2ewZ)uqs z%Wtf0T@aB4*^1?j@`$85yI`$tE;KYeAfu2DRBGB!z!Wj(%! z$1yRaVX^bj4>7yAoRi+~YsNvX;Y*%lOpmmSo~*8%%<18$_gl$v`%QGYxE%5l(b;r} zyrX4hWkrm5G0SzRQP89jGu(gfiiU>^&JyC zmSGg==bDIA6i?`hyQejWhlgKO_2ONks9x5cIV#>=)OToRZK|uSv8PB-!o!EwN?m0@1K&WSwt@* zlPs#RkPXE!;vgQIwMs}xkfHBjp}TNQO?=&XNmG+KcGp*A;9axKbCY&-6k#o4G<8Hn zj9uf<^SLL7U)YX&-51^}n)QhuDZmX!M5Yzm=VMW)EV7HNG zN;nRRfdG8_)%VDCb{$tnpH23+N|BCEK#;`yKm5$ub^*jV-{aH7am>!aAyxb#f-pT*c+OkI9KFN2`f8`$6fZCD z*GFJsi{LvZW~}NSNqDUAG2oAIuP$G{9EaBw!uPsts4Vw`IMuC3GhD%>@&GA_SwgFx zjcxRmmBRjmX?kZ{PQr4}At4buY22pinIGU`GH6m-Z=0n5>Fa^cgX2<-tA=#6f23<~ zau1Z;m;4Q*RI0CjK`_=4&eNuBjPY22g^7982 z7-hDQ{9Q80cLyI|2_`Tf)lZwW#^u_vBr^DSJC$|hkuORE} zobA0VPcZVkR*1r=16CaW z23{T>(d9nSdzRwWD4jif#Ol5WB9hQStqTYUz_g!oU<8t>7^b}vo8i)s!BOdb9%22N z85yZ-?~b6mK_^M|Zj4EAz4vnT`~K2&=%-TDS@tx^ylyX>TqjEL?UAv~sTm9Yk@1e= z4xR;OW2Obi60`Yav#8M&Zwh)svZ{|D2dGfbnXJ zU;A?E{g=U0uftk{u(_B-yImB$2-^!1EfJnma1~1f-dM$j2paWoNq_BoRIoX0vBeAO z9~qIy&Ug1{OgVQB*f~_M_Yoratfhig+-~)r2mUo9IpPbe=t;g530cDNir2+Mj#u~x zX-J2N|GivLAVmOL)%bh!;77_f^sPAKSY>CUt*pH4w!)XmR0a=!wP&_KQLrs<<>K;6 z5qQM;*1BV|y${;vNMnlU;WYB}~|5XTRT#h^U%L8>K2r%^b^!XbabC zOA|`>2;kSvJ6dR&eZEXr%GLQ_@2Rzd0V9y8$X4~!EKcRwX?p`>?$PZ(l|JvpkHtNErH{v7n*jefjWHP+SE9^RxR zqWiJEef`y~r<9bsy7r?AgAKA1Q6b-Q+Vs(78oC~FTy=Hp>OwK<{QUeaS154>5fNLa z?GXn-Mn?s9M1~zmoJ>ecGL}p~fp9z&!)8qt3bFMCTawU;pPZVwi*Hu_cM1$X&3@O; z_L~Y|xK~2ZkQ@yAGvL zEWW4IB3%b-ckV=Uy~OvMGR)}`Uu?1({%&NkVHxG6t?CTLvr5 z!&ts$fGp5Hvv7CpO1jO8HyNHs=q9M{t^eUyYJk@G$|v6)J9g+<2!6e(lhnuGhH-lj z6LlT4DGKet6TFK{LrqxJtdk1J7#`9W_7fD>iUiLK7BD8ADltvxKo$yOM83blw{r|t z1V}h3Itu&34)d>LsO``{g-tU-GGN=DmL6zsWko$Dj=dj-m0l%>;xf1z#40XkmHFXy z280N9er&*oyUuqasGxbdR@TL(_=O}!2rG(6JW$_S*Lw%XEH3gEH|s82+Rf`fCaq#w z-uSHXvW}}@U%Flj@7;+;Ln^-H^XJx4@i_%44aUD()?)nm9YycE{rVNEUGK!l>IJOo z>DiMzS54`#a6i|MeA&Np`DC=VTau=hd0WoCw5o`~FMAmK2L}yb^r;~{@XZ@&aX90* zjj=6^v7tq%@TpSJZtFP717B1kyvVy|@W&IeR+Ho7n005TPEmZyPCWeZ;9*D5+R$X3 ztfq=R&E63dxI{jAiap{UWsqX+S z?PlIY#vYq5F-W<*b#>suI)%Jny`f+U&aouHT|FkQQ*c=$^MN@sSP4nw{D?to%9NTQ z6kR66+tM*oV@8A2jbk1cLuYR;<*|Hyh9#`}lJ|g}U4h`75 z&Co=zDAZp=7e}bnCN<$*YQ1azOTAM>{ViW~wZj^Rwj{E+Ql!&Ep5#zx9jYtKeWXCK zx2>)1|FQKR@L2b4AMiyPkr9Q+NIMjjk)5W7T__nzDrAIgAsSYRw2%~ujLfnLrI5X{ zIvq`0$1X|q|@2^yVWSg zuk!BWvcruXaIQFFH`pAp8^d}4S5a&?O9X9>)QEl2Fi_Rh)Hm&X@^$InuwPjj5f>SV zT^{PTl5~T$5IK-UzGFcXj`PQMNz2Ie2@6KQpyx!K{8r$zQs&!6u-@Z&Ey6(&$KZO)@4t7%f+x{_kV0sa+CJ4|n!=bDf?4+UPR%dQBot z)_KYnox$IB9iOy4Xxvv`UoZ)kH1lQEd7S_7Skj540k;(25j$Uh)Yt+jfyS=Sf2@#a zmD<2uTgRl3EF>c0ts~5LrgXW@dBg|<2BK_EZolniWBw+%S+P;F`btvkwcBW1sxEJs zdICuU;5DdUi{I=(j-D^_C~iut;U0%Ak|#P(F=#XX4Vaj*XYC7HFHUfBb90lBsbibj zkp56ZY16Qq_1LwpcX05ci0=+z;X}~C0K($h%ah$lYn-e@{W7w{hDo{{To^WY{QCWy zlHC@ai2Svv#J`UZ-PFg{v)c>mn6?TDG4e>5cep0ZI0r7meo9GeSQ-{}Uz}_p!YfnP znPZcK9_C+rPta~yF;nwI;pOb5y|m9)%p_giEpH*a_h*`6hFSJX-}6d_Mho_iDe3ec z-m7HquFP7QH7uDmqo45@p!%lzra1MVNyz`s9oLPhbb>$=Pa=G63bByB=SRlR=OX5~MJ*f!N8 zD8A#*2#t*Utct6(H#+44`PKV$qm!ztM{%tH$KXnY_z4in zlZKw=PAk%Z0onm2#{5zAL6gPle0sK0c)1d|F?> z;>p%>Nx)hd@{~7HLKfiN)YN@srqS5m`K*ez2sGEME5*J=qkAD<>GZtFNGcN(6DgM& z(N7n|u#S#&y~+fJ>~-%R1CfUepR=^wjWk!vmsF%s=?J5)`Td4Bh8Q=_zU$5ze4Ul` zZ0ryzw1BIALPJ7KY;8ROGA;w#9ahvirA9|zYHSP*4i><<4_A-L>LhjEV<-b1W(SR{ z)D1n^=vz}vSs<%7+{fJ~23^&D2>;5B@-$DMrb%h~HqhuFGBss?#?>GA6=7$xD|rnD zlRrQVssOqio5Gt28t|2$Pj>1}4lZ5&x_z)|rpO@I3-C6+q7?)Kt4uiC={;yd8F$67 zTe!D)=T1GC@AT0y?8KRh2#w$K2M?_p#4i{bdZ{x1F)Pb)dEsE+&=8GsQ2aJicE@Zi zO&=R1%GXOfhpBKTNjn=H+^=?$`4|vo94z$5Utmn5Bf@ye^8p{HwX+x!8RXy(rlssz zJI(F%teiuw#SBP8%ZaisoBH>h{zurgj!)yjf`Ss%7M}?(YKp%TDMor>kM-?X#Qu!)KX3uRBq-(0pm)!|NK|%7}wQ ziP}Y@%N$WA^UtiNrlYVxYvt0IwWo#;ls`3yyfnmM8&o$jqNfmhbL_7B;Ys7bmrK)m z2S@4(jy1mfJ)W6Ov3Q)36EN5F{`=@cUSx*9qgQX-?Q*%dCngumD=SM;?%ajN9G;og zyFwWk7Z+!W_?K=%Bu^6VNn7g-Z^O4|l7aGlkt<*NOs&z+vKQfV=%B*gQNMe7-kL4B zsjIDU5RJrv!|47g%D)#y^-&89>%2RI>fNfosm0vG?w;#msM%w#FX9lrq+{UpwzU&1 zCLs7VJUlXk6OQ{(2sZCvuDxP+^e7#GBjbBBsE$d92!>1Im3j&|?51!r)P>vhUJ)19 z2Of{3l0I|Ev&kGx-d4a9Kqr|4KWOUeuJS)pw8PG(Qz-xOgVHpyU|<%TLZ8T z>@_02Wxk$vEFFpIeud#8qUO7uc}9XQre_ok=9$gi{J(Y;0$C>G*jv{*mYU1Kf;xE$n;)S%^cI)>h8$JlVZ=A>4fRz4;`E`^bL?7 zIMrLDS#|vbO+c=^p4$zXUCWcanR;FxG_6rzdOu1v(teuj;uOW&QSmwTGLM=O(#44t zZqNjfIX`&!#D;~ph;aZOWJC;DZGl~|#r^*Qjoo8z!>+fy{jjAOOt$`ZKppcT#c}*n zh4egV?zWLGoes8GwA4xvwn87Mvw{|v1b7@HBO~Z255pJ?ZT-=A(yE=gM&=e4lW~-a zF3}@LjtGj0JxCec!pcn1v6k9^830B71F>UIWgUNu4y|@4r5}mb2TN;v|I%fF9cp1~ zN~pD+7GQ&7<>yy*mt@JgCdzfhTw#Bkb+q(TznDP}23hdCgjW|7EHuvc(Exl14*^k0 zfIsjX*Lkf$b9(B_<;z#EUa(^ZL|4`*vaNBt(S^L`$dlWLn%d;^m|DKJP2oMyG3&XN zqqjyQK`ugMkm`K0`w6PG|ExIt@5$s64{IUi!GN(0YV# zxb;2r(){rG)I|%{bFvjE7&3YH!Jws!*doXG>i97Ua0qEl-)s2K}GwcZ4BwhwT4H<_0p zrA}&K(5p%8r>DqJMnXbB%DXnTH%?2CRep<5;K!DO0L|DfVewra2$Yg${XOViK-)jx zF&wEe^)n%_W7t+>Xa`X8Mf*8~5E2b12r2AIq$arY<=U;y_I`KK=XhY~my6J&8oB5L zRKpk-m!&6wJ!m`ykN{EgI!aAP2f(K%G94foK%jVQ+_xx*Z4IXen5yZ z81?435k^Rlv1U!?-HTaQ_Bor&k7}PQQM)8K(saa(Gt^-G-%38AwCekJMgE_e^D;nq zUY`&|%=IX8jmFa!u4s!|8_;nG(@hs7Er{Xz@9|i?t)f@q%-Ep1)2B75K;w>q zb9OW}qsr|Sj}Fd{)|JGN|5VKsUgz`h?$(y$%=p;;?)JOf3QLxj@A;ndMXf)6oXksa z8FIjISn_JVJ>SochnIO{gs;tQ-U3G}-(9-M-BP&jLAeg@}hO(c@FsmUQ?zV74vz>h3SU_93Vej!3*@ z=hIU^u>ih*Cxa1wqI8gdH#@NfHLaIM>_n3HW@VDngZD7@H5)I{=-Y4gogoKwrxdLb zE{elAa5<%^v4*mafhJldtn6u%@jh*-iiVg*7ivuRWWdr<`Xmy`lF* zHEn3k-8lZ-z&L)6?+s45AN*RRheXGYOgCg`nTX0QnoYE3Q{hZ~)+0YoFI=lI|E+!b zjJv|>WlOPP{rP%JmS-6r-q0H{pNU&XfLII?#cXUS47|V<5v+mlVJxUTU<%2BNvt}o zxv!L5N$IlPRIs*xFsI;J#=)qnr1Ue4EG(v{t|!FtnD026c6q~7pHr_-YuYtmNPfKc zozrHQFp0{L?(C~|I}ycd1Tmyv!|g{o0J+hJxy%n`BoOt&_;XTz2>b;HShL$1eT$VEI+?owDoMG{O(ZQ_Uc1(PGEnuziK2V!gt!v% zyN7Ldyv@zb&VDZb^)nA9?*JO#$aa_9x_o@Y>c0>6>8nx6p~LMr)O2Dr7jaMy!k@hH zNtJj|ZV5EXBzdVVFDkp$c-&i|d5_N?cE?I^RGAA;8w}ieF?VCyJQQdpH|Q6h?h!J3 z1{EY`a2;440_m<~Sa5pzaW0vhXDvYTpugeZg?Hx8BzS~8vD%rNQ z?na`)!DU`@?fILPD*Rk6jCw|~#yyulrpP0gXXvua*nYjwi<|Tk3i6dsH_O^y7NXnB zbC3DO@Qs1KpnEb*lf8My<9$Wl7KWWU(``i%k=;v3*aZ~+0!-JW`i8{t9*Pxpc$*BgHj2% ze$c~*Yu2ydpD+~+HWOjlT%q3$w6!@=l!fiF@bw%R9O3AGYIRsrh2%*o-E4h!Ir9v&Dd zg3m`v*zlOi$IKf)UckFWBu)@T>Fzy`R>M5KiZPq^_)!m$n>|)iQdu!-UAu6j{(-;= zfH(g*(3?al^_#6cG5_W6M>^Ii^Mc}I6!Eik&%Y+3+ATog1{3N%=)H~M`e_78E$WVz zUQQ?Z0u3!KEohNZk_-+Dv(<-N`GvuV`WFjMU(?)C$HaIF%@jl^%M@YbW!Td2<`ysAY6!%;XNdilq9F7C_1S zTvt!kM8xi&O2hm{GY!RWmKSL!Qe6+`1N{{41Syztxw%Z1Gyn}2dUovvM<5oiuCCrXNJ=3f;g^+an^<0FWN-qyt2zM2$K%*$ zPhi%{%3qQO^xpky)JQ#g`~#l|npcQD&{;<@58mJWrC(sn=FI~8_diJ+JpAsAb8rr* zIi~ADbyvkn_8E$~pZ5#c3^VPAxCdfWP|`Z`9FMA^kJT!3;-B5+4G6UmRq!bC&m+Mf zuRPF!`5?9*{FNdNUD7kFDc5amdhO#+HrPqGzG+c~5ez7B{cOJonj?r?ppV0y;(2oG z`1Te7Wj3_oNFPi7^(G@DG;NCoC_oS~WTm!LXdDPptE%B*2+bwk5Pmo;Cp>-Q{Ety3 zhpfY1ePiqVrUh=Cw2Sl8HD>kDwE04NWVED$)%pn0HK-@Z40H%Z$=nsf8>twWZ3k%K zNy|Z9jGjd_Z}zFSg0li%U!N(cCZxo|@pS;yERAVSU!dE>CL$F9)^|EpB$&+e1Gc>)zLnx%FC;@V9h6d$8yDw0?I_Cu<>TMR5RvC%`qSML$=E6@54?E!vao2)7xe-XiL9E)Kf)@2#y&A;*gwcU5&-DaO z#-D>6Thh}ekhlN8?`Zm&>e_z$RUS0_f-5POVCxu*jX@ z1bh$Xvo;uF;>H|jNlH7ajNabS+EbYj7NKtUsi;uFG5wRE?$8Y5G=A8P2%tiA$Q5BS zIJuJyT9|EsL|u{di$sdy1x)R5dvXx|H?#}1l=gRT-hfxUo!iMY&3D6BK{tGq%n~5(_u*7=DS0nxiY+@wt`yj63 z?42rvd;$T$T7dVFZ)iEQdtbwbdvIi8MjyoG6j`RO>SQzm_4`vV6f@+NM~)3AA6$=J zaP~)_y!xA#uJUF)-CMWI6YahC3_t9J<`+I(uVb5E4l%96C|N($>lBFBr;DRKS%50) zsGhrB-*lTB=eStNgU!l#_=p{KqW|zAN+b5jyV17RR)1(wq|2XTNJ|hKM4Uutg5nL@ zTuQaUi)KxYE3XbJ&^25!v$vnRgJ~jmMKZJ>^t^J?Rl}sckwZb|t=rx`cJLt4W;i)J zWAz~q@fOIv!Y=NUMJ!rprL>!Tl_H6Ewq51iyE8(N^_M*1wSx$$Y*&4la zn?BpTEBucKj~upU{}ChLQ$hA`r>~3=(}5;oyrk1XNfhCQ9`vzI*M}?m4Tn9jtc` z#WPzuI?mo<<~m)eoU?@S?^Vz~0B%EZ!6*fV79M3)O^p})N{Ef4z4-0Jp=orQN$6Me zDqh2C5TP0KDj{IMA?3u}{JfZ`sAAqOA))c_C4?F!n*em^$BSJcEM_nzh%4<7w!zKy zb>c>E&NFy>a!{Gn?6793wzId#5OItIIIef8-A}rg(EqN2&g@%=(cv z?_b+zDQxdJ9?#(6J^#yy@-;#2$V?D}$P9NPf=Q8aCwgu4N&nzMnygl499L&e`C(Ot z9Qe$syD%&_nn!7;-nhLpkjrW3iIAgYhB#~o;Gc?AbdP#DI}%YG)?8fCBXotx{*ayh z_0X>&XNU6@3yWd^C%v{d;30_u3vslNLXfd=2q?84X_I>{W$h`SW?^Z06lPN#3O$^r zzHx&lP;F4Dr)Hde_gLJFV|U*e$V{Tv_*ckPrtV{RMUg4*nrApMi6V$= zYtYk#XXrUwvTrvJU%cqmIptS8}KLLP_&^%fqyZ z=d+IZ?gQ(}6As;`^i4IOz6i*L*R94Q7Kk!A4>BFb1kr_C0SGFYm>EO5fo|9ffNswr z_!PMQ7Pue~q4=jOmW~H5LrZer=|uk>BiLbJ*Y!D520b%4y}GG zDR9pPGcFnhAMp+Y<5np|R&zfXEbXFFs7$~4;>Jr@! zFK0ovjND@qnn;XVQ1vn5dN6+f^_l5uQ0*S`Vo8MefyPP*L2S8#l9HVGTeB-yxNr0e zwIpTm1+XK-M5Cy;O-NO)E-oDe}aK+4wBJ8Z2>*A=` zQ;!jSx-AZ{*`=nX`L|pG+=KJH`an4OUBFO@(yi(;D#2}|NItGMCNG+d2N}x&2Q-FS z(f5isevG$nHveUeJa(ia1?z2s^s?~;Q#fRs{&C9xcp{{m|RC)YF9%DwPhh1kdf z0)ku&m8^UVy~>JdV?z%CdRZK!l(%-we*)tX4ajavZ%J^-K7r}?Koe$2}V z{be)f;u<6$j56e-Z9$F}22cwC)JHLliUmug(z- zYlAxQ=@J%iB-j}shcC@Kc(}QHNBliJsG#$9$Ofw%*x>$ss z(W_~<9yuNuGAhdiaJ1ITiDk@4y z=H#UKk8^20Y&a+5=eV)tV2xyPm{&GpVLf}Y_Rl+#mVR213#Uur-b&en1|tIlUSM2` zI`d(TGbLr;TRL{!~o$#VJW}+xA_gDk~lSCEZl$+Z%@Ttuwxa$y@o!=TTR}Z z;h;yX75{ZJSp&B1i{5`;+r<-_n8N@XZd$kLt6EPQLd8^;Gg^ko*f`h(!U|_GNTL(r zG2aI!XK)mdWfvI0z6tmCx2Ms$HeJWt&Qfxa8B2OrN{=A@g>PLFP*g^^{9c7^K?GoV zstDd8tj_T8wK>yu4BkhZ?j@FlmRAW23q#fCeQYzgcAPA%YN%=M91_F~cp|H{wT%6v z0yI%9HsNKaGyQN1ttMKB^(p>JIg7uJiRh)IqenYyl;{2?l*3ZWTB{unXo*&Lv$M;}TGN)#Y?_)hO^ICo+!IKzxI zjw_LRjr+VZ_5v7@qG>>c5}U31%(lBSrKg=1<`}p6xoeP0$@i{=z6ZT0Kx2$W!<$V*Cn1joNh}KUKKU{BAQ;gwBCxF&X)^M!H+b!Ui|L*nBO+ zYqPQoP*%JoTn*D-9hyOM(Pg3R5_~|9M;f)W3n~U+&InFngZvC<%*ED_rx^W!5 zahXqXjOhqpl9NN#&B$Oaj%D~)9%s#vhtdFj7T|F@oJJ52eI__Ip z!EBo)1w=4x2mTV1cbl2_2+ctTCgsvyKthsi{2#9=pCo$x*LC zU(jH@?H4tpme5{L0mYz;YLUo7(1_*A6FuVeKkJ&D?6_dg9L5~+uZuU>;A0e!HnVtQE60C;d2AejKS{KLwY=WO)TR$L^00I^TE4Dbs*cZcJpu?+J z=7Cgnz>icyUN~KeS-p2|84n@y&6_*&57L{=rEGgyUHQ>8jdg_@REIIbG^ZoU3fCYa zc`e{!jn~}-t#f?XF{~JXrNq|&n;~Dj+q?)mrPW!j0T7lFr4xLGz&Q1N&j-)}7yv)N z^HHA){2;_C0LKK(qRz4r5E~o>?r`+xH&?fQTWOLN8XLPqz}}zZE&E+(ZO(h>%MKkn zB(QVmJ@Gp-+^$USHnYD?0yVfp%|y-m$t*nF_W;`O0zY!nvxHQswt?K4BjcwO1z1<6 zsG`^gbt^RE#4eYlXz>$AypbrECqwk^W0w5sY8k#GJ%<(Z+yDAw_SQFP8gLY3dQ8(o z99PrF)pG-+D)xb{S@??BoeF25W5M42`X*2D_5EcyA0SRC!FU|vr9%z#61pEejf-_> z3>n^!hS;doRca=}Q%N4=%d9LOK&~qfd_QmpFOJCTn8@TvQWQQj+|;n}Y>x>8MTgXK zv0Cpd6p$m~Rqzk4*R`|Y0{|k?kwRW6s>-1@bj}y6$ca*-b?wt3K(sJUtU`Y$ZdOm+ z_2dF4$!x@!L7olF!?MGxl!M4sKQMVf{plx~kkg+oIzzVgUt^AR*skqm6*xtFYAFAu@uxW&$mT` zx#)7u6@#d)^zDB1vQ>?ZpB*fTt{GAv=)+y6noMB>kIK3_^9*8g_)8JO_VVLLC#_0# z+{k!<$}N^@XMrOj#L9i0J*Gpgr~mGBfL zI7cORTH;QCR#P(m*G9~%=jG)EW?PI51}_N70NOY%?9wj5pUEL%-k3k{!p=G>$zHeZ z=^J~;z0pdB2OJuyr;=9D-`csU&H=>TTaL@P8c~X27@HiK_TJhUsAal4%pG=p z(J<0GVha<2nmyQ>tO{qXrb9tZ2%9RVnhbHerNZjTZ3tp8k{id8bHFe~1;`iA8 zRAy($RjqBe@D{uP)IZpCbQBruoez%k6@a;MY~mu1wgft7r=j2hMs;RwJaGKa|=9I0UXnHD; zpNs3ob56W8|`i>`VTKs!BoaXU^>Wbr_( zjYmhdn5`w?_3l?BP;sDy#dv;nIHXcAr@X35YAx3K^QH?Z1+h|B(a$`*+s}SVD=T|_ z%?l=Bm@)5)O-cmMRt384GaC9i@3@9_loQn_f}D+ArtGA7A;5Jy*bKB0-2y^(?r|(g zqnfCPR&}&o7U0o;>q?y4x6j9Xs-X_)9x(kG-x| z4?UFmm)nPx$1r8~sI5v=)r-{BwJ0`Ug>hT*K7sgR!NViw>huMyK^4C zQQMvb+#bX`ss7;8TlR-<{^yOnd0uQ~eW$)H1V_+GGNjta?QbCY8LiLrm|JLrh=4p> zAK!6QQ^}wp#3|=mtMuBnYYjmgVx1i!4Idj@?^H0*PyA9G?R}5yPrQ{?daVI_>6adl zC!{>bgt-m%KPv#c=R_Y`ecNr<+ri>i52j1>o=9ME`2MOi@aWNku>XM~N&Xxvj{EoT zD=PTnlq<%TOU7SZVtOK0i&k%6tu`*M`l*LFGw@4I>Kd?lFVr<~v0(K}VFzRWB8p5Bk^iZ-m)eo>;inXMBy zJ6Cin{$OOQ`lJ2X1ak?5WS`5+dB^XrtP2NY|1vGDZe)&eSHtHE)+f^z3Rc&#J^T`` z__~xxl_5Kc)$$a$BNi%mfAd|eW}=nFYa~+~QR2(KKS7Wb2u#3iC~am-?$3c9^ro!p zQf4S|a$VO%L4^ts@CJWcZixe_^dVaG9q*~60RAVj1~Kk)+mL38^4RhGZ&5bfMDasM z0SOTe^tgOGPPl^qoN!mZ({i8>BZUuScbC7#94xqrt^mV`0ssQpD79=65UqOA+#*(9 zgR|;QUB9|a13(}${5b*Xq^K8qC!JvEk_uA+h{p?PHZ}7(icwrLxU)u4+Rob+#WxJ- zs-B_z{0W%!7NJH4BERbg`6F|P!ERs3xb-L64<8TfvUd9af;fN4iAzRJIK@#Wkh03Md~%@0;Jru|0? zkWVcxiW}-NDktncyi7I?vZ)EcgwO(6t@Leg&r?&g-vvkuvHESharyeGAPh+obDOJ) z_z6WoA#5pFiwYf}vNCalk@24B3rRN40r5aPe%Tb8x0tl%TLy1i#AY?c#wCH z-CHsM_Ub^DjGM69Q#QS4H^BVrOzjCqvj)OZP+p$Q1Sj^mf=Lb(lt>9}7%)ni)pz%Z z8$|ZYmWwGBuul{};X@?l$hdP8sJ`arv&3RvV`mBdzyW}&$ZjLJH|Tx`ZiThpN*;uY z5ES&ZE&}*lx^`kU?H{w$#nnzhkYCAtm=G@!x{pd4RW3pRNW2o{RbEr z!=kK%Ce|yaV4w@|GY&_FF%f3{?-jdgO|1vbbiqb?YP69|JFsP?=!{=BZxLYa_p8;1 z6hFXhTv}B0CRpR|iKgXGy@|IFO()cDI+<1*f$Sn9$nE#Thz>m5LxB8|;>qN#B-Wj0 zmeGQwR4&y8wCM0(=+^k}ICWReY`1b%ZS5zia63CY9ZY5?JjkEc5Ssu*4a8;gVOy2i zNUvaPYpXV}+v>`3oV^0Ob_Gn&N}R#gLP{XPW=rP#zS_S5M1b80oX~XWZ70*;gdgyE zxT%4DPWMV3lrz&i%k;Nj<3`R!fkT+U9re&FG>lM>$2W-sAHsAn4>Ve<0|K-Si~-3K z;~wD$Fv9XDW_wzF&_lE<3%=H=Wj){$kXX51%_!Y$3-Zz6MdX` zzfy+RlP8681z8a4>Qt{a`W{XNgJzyw`8YPr=na8Q>L+Fhx(%9C#sypbYMPVY(56^L zEl7v(F|f=Kgr`iG^<%{eJ3Fr@bmq+VXj$;Dp_?e?Ua1wUmDIFQ!5c?v+@>Q71HgI}m-We%6u-OUX2+M+8za7aCz>Lqp zK17;XKdYgf~x4MkdAnBYB#`37-5((NvZI3s(U&t$iG?5Oc63sZ0# zf6evw-#moNHePaC1}+U;_4)K{HzUaAiZ`p2UY7=*X8(n9Ux1#P+y9cDG)eac33%-I zaiV#~tCZVw4x9$>A*)I)P@E>G0^4DP`QL5U#jlS*8}C2YsWG$-TNR#-Ba@OljE+QA z9b0Y(2zme6Ge%sWxMqwY_k`sveMoE}hLoh^C6pd3ViDku?1hpVV~lWAj; z0Dg?R<9@*E1eYLsO$T20qd7*rj1te7NImlT^NZ!mKHCehm(D~i&+1LS!#5p$U`adV~?tm>fg21qgtJ7hr=%`DHNSL$h-XG^Fx(jDN1`9 z=K(U|zRYjfz_`gy>;Z~uDnrZnad=pAXH#IlUW4!)Fl2c6c;E!Ih4g;JZCZv%!*Pfp3Dyq|BRKx}=iHVGm&mp1NUJR`7MH>Twd9fSR^m;JGA<5#$}B;9o_G z5ok}qGyN0`UwHs+e?Vh_hmf2+M&4Z?)_A&t-Fo;4Wb8XbZ2HZTOy=OMAU6?-N`Ud9 z&t~uO$5pN;$wAYpR#V6Dc(lBG=oAiyn2(Wzku!t1OtgIww1W|$XjppR7tfk=@ zitW+)0J;$|i3o&Za={chB*hZ7AP_lg_{GI?VkBe2hpBCbAuG;HSDM(S7ZZ+q7T-Dk zDO<2{UwM1qz`#Kq>o63`O>pAX0oN7a@I{=ZAHKD9-)@AA07S+n@zHcQdi6f^u0#Ko zw6i2bt0aN1?N#YHVGcN^cJYGODG+`P-WfO-N(m)F9KQ4MHnJ>Zq9Vb zUIr8i_0^2lYeyj@GfrPqS5R_!-*5RIq~)yifl!D1Y%YO}jmOC<;DWE|*)>NMgXuuA zG%>KWQ4G%5A)U$%<*A7vpL;?j8brLW!^8voQ5B ztTNz=9W;UFI=fQRU6jL>(2S_x@GwhkxGdGTuLV^GZtEz1?!uc7I=g~yXUN_fO1dIl$H_IQO1 zVV3bKToc`=QX*#c9$Tm4M5sv5SCt)G`S+|agx(HYq9eBl4efKgse;X(XU?AOPcz=5 z5hnLqxYEAtoW4HuGm(8ET?5e1g>*r~uN%^Z{EAYSvH=7J;CeBdV+5#(t^!d7iV*(1 zixdl=3JyN_qp|T0S_@D)#3lGzLoB)i=~~W8LSKP6K=o`LUFwc#2rH=#e_3%k;5w#e zr4PuE0aA-XCPW|;!3P2g3hl;xr?s?h3f!?aS@P3r4to0Z-eF%3G5vx03^xa<~adaCpk}FlipikQ0NzR{%Gc&a-dvR zxcS<8p5Md|nSY;%DKbC(wta4^ZK4apTZi?DB}OHTJ7e$re?{AU)vx0#j={||A`$3~ z7g{kDgp-wISlIRDZg-A+?($k=)w?q%Waj>2uK#0tLAO!ja`qZ7VO(Rsf7>9kjEViB zEq^7p%6-e-``JKe#P^K_KQzF@2jdPfyW}4~a!}v~f~tQbxCGMqeEAYt`hc4gzv9uO zN7e%y@Th@mh)O@zx{uU@zW9O1$6qr%wKGoz1_V01#G3SGsHAiz#pyk{q7&8C)NZ17 z{0ZRS>#O*7KcRAK=i6Mh=JwUxbwrpRMcLpD48*#sk$>BcwMp+e(;trgAGJfNaz-L>>4K-?X29h= z$TVO$L?5;fcOe}Sl17)epgFK%jB#P2&_?tr6OLf6SJeP4Lmb7q-@K2;2o59rkVlVD zd{6^jnLKMiYKi{~7>r*Y;t|etXJOicfk~)1dI;J=Pp<}Wl8VY>9*Gd1mi zQs7x%3yXyhTqv#;G@d>_w77{(^ep6`z%NL`Rv;I|21j2a`&<`tT?B)Ksq};n{&TyC zDrocm8p^|As<{<8_QvL(jJRyBiK;fT_m2=CmBg8 zD7dPirat@T^EuJ6Muw4BS<@4ZCqQW6sOjXP!>NC~d*Hfz$>b55WM zHLBZWoWZQHXbOM_9MT7Ng<_i;f}Y{4RKcA`?>U-9sR-dS_+#NI)a^dVdg$0CL8L3e z>stTf_`g(mR)Sxx+n&bG{%a3`MIcD6t>+opf#qBO9Kyqzz>W?HJ}?*i6f()*1x6CiUw0D5^Ia?-Wr!(T&SU&gI{%aLmP!2kT{s{&6Y>0jW0b8F1#JE=5b}PQ9={*WT$b{zB3wJrs37rnw zOsq0!$AOyd4Y;yB)WQE%BAi$ie@lRWKPE3uG$jb7C|fNA?>raVzX3)n9ANkdOpPD& zQIfy&S$BIuw^c1j$SqrFz{J&cc4Q5{hOYeVJNw6q=K-+62a83`3hV%eSy9>}jU=KL z#|$>MOVHnuB1HqvXa2u7p(tBC=)V>AqlRzc52`6BK284-Q)}9v8;#OU{AO>PThNto zwU?as#N51@?^=w47B9-p zz(U&h-aWKch!6VKd*A0{G<40z>+Bw)yEu7r!iueRRr-5QaBI+G;R11du7XyOXo2ww zak8Sj^;5E2OVDp1A9xi7NF$dZPWutfq<)yjwdsQ4^{#rl!kiZ|8@wYDes%#sa|4HW zuGN}X-u2)N&L`ZdS-i%P_{e)5vcWz6*`WE0h+jY%nQ4i}4(+q4R!dJ@MVmGhwP7ly znVl#9S0o(sJSg=Ly)2*-FX!q^fy>mQSS5C2=l}xqUcq-r8>gW9z>y`aj1;$tf zqymx(9wdtuav6(uD_76vxVx);F}!q()sxC)`gz0t0l$Bg_eS)&4EJ0gF(G5z&?yC8 z*}b^v>)iD|E{<_S>4C%s)h7R-&`>%|y#UxmsCg0)1o2YteCr5`tg1)7&LF<=B3-7l z+7Bx#{sT0_<2IiYJ!%tFnVK53;LZR#6_sg!4!2ueba0PV=4J@lwIj zz8o$j<|qWrNDM@zv<&SX);bFp6Le4tLk>``={!0=(R1dQvvZcAD_jfS$j!VX-$uW2 zdK-f>dl&F?@i|MKgEim*9 zf3qIxLAT-smAjQylHm!X01C(HtG*ck8_}?j$VE`3a69~%PCHG%@#l+t>W#m0k>NNf zR_PYYv1eS1S08XN6oT+)WS5>lzxLAj^zZR;VpPW%xF|&Jr&h{|igsAPuCKER+&xr$ zn%6D%)K190ad3+b?ZsG>g$_CeR#!ifEs%*kek9n@TxqpETelL-n&EdmjLf7H-W z;7o$vj?C+~O?1_>3KkZ66i6!9Kux7eZeXhrPGtQ3xCeUVcG*il{xGU#K!FMf`U-Ye zzcot33Tt%)ZV5X>u@GQ5kXHQMRDoS}XbXm=v94Wv3-f#PCR0Y>D1mm9$fa?HF0|w= zKC5K+{P4S0e-CD-K>x^h{j2HO2Ye}k9?6$GtnTIQHGYrE>q;y?-bedv#f>-7e_jPj zrkK~XPs%TWufF3J;0i>V3fK&nA>iqp(y51FOr_UpSbRS+U1f^G6A^o z9NKn%I{)=q?W4VXy>An(kxX4x%DwT|l9C6F(&zUWc!?`9)HXclK3wGmU+gYi5DW?m z0^_)tes&sKVhcOrIXIH zg9|Y;G}q}rGD_?9>TZa8n(&m(<>7Wn=~J47=N!&4NCjY7bmZ_0KME60VY=+t%xAgh z3Gi(BD##2%RGjM^86xbtL!Ic;jvpsz^GdIsz#Lyjj6Csc zDUDgoSaPeJ6i2bTz3~{muG*hBV+P3Kt6=4lK1twmewv6`8OCm7<}D{MaRH+Pv$jEw zwn8VzNgTE&8qn`hG+^qd>j8P0Qfp7~Ex2jO6g1ck#=@^#ZdJ<|{!uu-W!bw%gg?L8 zwD{cV*_ouS)ZU&S7n13tb0ABM`tU(_Vk~_viPaQ*FeB2@ZRvN|tLMZLqk_yce-EP( zFS~@B=MEk$O0Bd*j@pg+FCSL^==4kxzEd6C;LIMM z+A@TG)pL5KDqg1d22)MbOS!I9b)NkvZZP&U2duuZT&kNX@8H^ORvDo%lAL?w%$Y~M z6n|EmWwN&}HoeyoMyPF9`Qh_#9jA67ni8U>Y?j~z4kx9dEl9Z4)(&lO|JrHQG2gzt z6f9__FyB-;3I|5kvg^#K5fXT=w<+Afaa1bOP8My3i}S;&-$yk!F6rHvaTsD&B94m5tz!NbH1fgUmZ#zAJ5A9SNeQjPK%nK!jolstV9{(8>4-pU5xt9 z1?#vvWnyp)NjXit>7`ig*pHt}|EX2F7Rb-bPZr_lxy$_Fj*`4~_0piLe(-(p=T!Kd z|C&crdu+t7bXq|ZP%Xv^5ovrxs>kwU&CTvUS2cZl6iMw@VapE;z}gYN`V|8 zlC7e?=k(!n6W$HzJ^G1VwF9HMtd?cAZ7a>Go{3Rd zT*dD)N<}8S1m?AO z+IHOE$~nh)Bhf!$DekjW8t3ATt^HQP5+NNKN7|byvu`spw5@#SF>(n?ryV%6u9{2m z5d048d)wV^rMe9>nUk9qJ}hmnI4?uO1=+>(iuudkt@s-ZzIXPlTkc`L7&iNI_3b7D zhlMbhUO40T6Q2?!>{P9ms)p^WB?xUzuU zL8(B_Ct5l>5+4Z^MRu+?iicU2Kn#tIl z-u}FM?PoY&WJX?Y9?+xO3Oi8%#o>lAh+$CiNcK50A$F8rcWHZ)BE9Y-d^MW!LH{F^ zpm*<3Pp;g?1Unv{8<6i#IfQ+5XS2yjNccd*XNcvZ((~!TnA&knyHRkd9wSQV0vR|Q8Q9mfmyY@y(jW`}EI zqXe|s%btJkjI8EQkbk2(*XoiW;8i)S{2L~=P<2s-x+_}Pa!JAV*-z+hQHs<;TNi8+C z`&m;^CFPU6-Itk}jWKx`rL)I))SBRqrISuM4KkY-%CWKvCmAzqTRN94*YzkAiM6W# z$aGz?K1N@$vZGb8A%`j&R6`LEQMUvT{Z|!~>2+EE>26(d<{s2f*7$8$1cATl$YT;e@M0#90J-};TD7wQDN~if5{;G4uQN*H~;sKSXxUh znOhH)VDaSIF;S+*9IvPXM5d|HM_-c!m3vibi$*$rE*Q9!dzD!)%Z|yC`*&+Y*@&4+ z$6{ssb$(M3;eh^t%;m+9A)$TeXI<(W{ME{dcpT&rlMRONVP}BF%wu!IavK8IiOKS1prq30-$(vj2%AEVJMwQBIUn{m zF_H82v1f_57*fO~RDLyWL$a0dHwk|6Er>Z0-LuCN%2{{&m{7lffS)1S`UQv>5tElE z(oEF3GuhmYt*s(b%4L`kh~zp5J4VV<;+k`IyJsY)Pz~jO2h8VIHgn)vwzW(F?j zPOUt?B)zfL<+R6&i0pfT=M)NOuPw(rA!pUoM7JQ7bLTgS8@LJSSFc|Cqi+vCjs6g` zjQ;#DQ&Cqr^<$})Z&%w?#qy1%VY_ zo7npyrF5V$85@T`HC8w$K)qVzyDjMHv`qOcU@ ztdxfYZe-zB#nzSZL*`RgID3Rtuj~dm5p~AK?d6#`nv7EIGiT;ZoL#PHu6mmA zgK2H1w0|b`Y5okiTkTeP_Wa9bQ|rFfKaqLt@bm5d{2P^Eh*A8GHU>SSNF|Q=qHdo- zQ*iD^LkMyHdeHIZhZ?x8in%Umh^(c+>9%L|pO{!!=3S?QGp79jq~h?df*sN?(9qW9 zr*n?gA~m`DhulwjTT6${Je&=5$mqPb^K(l{#;Cza+-PXY4eOzLaj7u&1EmnA0PHLX z)0;k@AAhYuLTG?` zPVap$EHmQWTT)s&)}yez9%2OH+{GcwtaGXol9I;Q#PXbe=4NK&nRAct-xuIIW-~NA zTG}JyJZzlpG_~$WW~=X1oBhQ{Ije^+Y#|!|`o&d;C*AGyrgBR11m*{YX1roqW6sHs z>J%G%&dQtqSG8U zg8Cw?VgCLJl*1jnVh~JEz!s8qY|t`}kv!qn z#4NiWj@p>1kD9#DhLn_SOW?_B9aag1t@Bro0(}!K`L7SMDs``;;h^96^*AKN#CVa& zpRR}eC?W_H<>Gk7yZ}@cZ%Zp+qgt+ch3#zD^6#znOkr3G7Jwy#nM<=I@5^@q~9@ZxNBucn{cPWe6#kTi#4k58#2Bvjw1_MNynrTW^?)v)Vh7|AT8a``IYCEi_xsok! z+MGFZ+(l@c>uY=xmUiU@6r;p1P+3Jnp;oUxgyDi9c~_R+&yZmRxsEPwSmgsZ4^Ppi zKv_?aFL`d!9|9nWCWhHhB_#~$o5BOb||zrG|&Z5Rt^k)`-OsA(b_t>*Vv!+y^Fe`2kZNI5VW^^e16MscP3(j z)kQC2W3Q;!8d#ln=n*3q|PIPSPj_--ufm)aHL0JP_4lN7e4J##p4^h9Vv@?LukZC6 zcEDD_40;w?bk2p`q8_lxp3{|px;F0LzaG<_I^`;?pBs!s;3lNm5|I};n3CA>@Vcp( zguKu1-3kR=@>noO@9R#rYu?-2JY)|wqlXa}VqwPW%SL@LRt0x9;InOWTsSZ-|JG}G z<#4Zk}z`o1g#&zJ=Ug&V@(^LqkQY;&&JUhIs<`F9``1BSP2OY}S2$ z{@ik?nPbSJcpAhP>gUmLPVK|akrE#M{_G-K7u8d(CESV@oyyKk18g{XWlfJi;zMyF zw^hPjK@vl%N*ipZz{FQL{#k1>Q8%m}FK!_h7iydC>8V#P<`T~gcbZ)S!b3z&n8A{YmWvCG1C`6I5GEIm;lw>%Dq>_Xrj`64t z9U=29eCs)S-|zeG@7~|--g3@=c%J?2z1G@mD+(AiegTeKW&#UZMn4?Je&PSj&e75g14t@SA-OqJKFVJ9oP+)_7-Q!ZqE zjcaU`G#pgw4x`b`QI_eNnl6g6a=)s~0K7ql|AO0Y{^{s1AlJ&Sqv~)tkvUC(x*-0_ z9ts*yFM{vP)*SC~f*S@0_t%?!uI+Ssyh2p;nsy4)``;N& zSm#FDgp>#JGR@Yg=_0Q<9~C~5BP?0+I~b2BD^zObPj{pip}Sg z$f8{%VH>NF&Us45yZ+J9O&Ht&RoS~qu@wPEeLLp(K06_W86j;`C$UB_4HcFcBY6re z^;j8IplQy%W;TV5{!NnEDusnqs!m3-1`M8{gTvbGV0QSRqZ$3D?zVhxG?jQ6YacRs z07vBIQ^Ig^qYe&0bOm+$TqK<6d+0CRPo<+r@YT3TWKlaUChbtp4`ho7on=ok}{P3x5g2&W!`ut*gUEP8L zv#Lo~cvlm>E0idnUN6)71tZB3XmAeQ-DqFWFlOt~_4KL}6)EvIcE9WIY%nyR$g5*^ z0W$%~+UtofG7P1O=&)e);_Ct+Wt*lJJtcis6OuEa-Z~LkBpbG%2!#8Yzx<%Ail!c3G%zN?euiCwFSNNo5M+4A?Ep= zWxZ)_VzSOTItn1Ebvbw7ZbZa4={{mHQD1+8L5JHk=);3URoz{qZJQi_ZVo8VUWIw^ ze7q$ePf#o#RvHq0(}xd4B97ixloT36{pws2B-l1*3tCKFBfFvOB2qb^(?n##V505| zNnSZ=H;iM*USAbX4rD{JD(rSiu3r7B>q5}DGR0-*vBpD=j~1^cH@x{Q`>>99ws7wb(!P3Ki?$0#2KPFM?*#jLEYX(r1CMXBlO zBTow7dBss-nDZnFaM%kH%q2z@FvSYN2f%?zp$e{fztzJ;on zFI~Lo?o}TO_448MOw%}Y-Nx0H^qiJcQo=}~E+>wDL?ARI-y3Q09lYNPziZOk3j}Jg zeB3!}>}1eT5J(r$kYCK4osd4V+2ktNhA&4K=#MGmepjk;q`=s z-n?1MG4OVSU4TKV>8;)W0G_?EA47XK844KwTZsP|w{6bBi_35ilH^F{;y0YShDV4c z%Gg@WaBLr(fr#-fzfa#hh&MnH9`^iH3s-`{Zk6*@n1^^MuV5|mz}A*Oj3Ml0i+f!M zM!rIm1GRoptPDPH{GI~YcF7o|NycX%9on|1hrt7(77` zo@HR~tHr-~!wl-{vt<8NEt)({;6xPZ>OpTLD(v3q!AEGVs`-h5K0imR%uG!~(GbEY z5?!(4U}|It6xQ50(t5)lHrR)cM%A9fseRvN_iG5n(A2f*iu}VCy~y0WPsD2m(&T&# ze=DP*QJKT8%YE;A&E)^7JJE;W9*z+a7$4zdR%K{xyi!Uqq=T+1;qMm0z9)FZ-@xKy zq?KgqK{bm(cFPdjNZ&QOyEzOi5f%l6g@ZsThAT1-Wffp>#S*U!a;ktXF%NS^hX|5R zj1x#cJd)qgsnRs~h+S0vHsEeO7Ul~20zq1{h*5R{pfQoOb3DMKM%DT1xfCi;ufj`2 z3xS2>0rPER(TcN1R#pI! z!!OM{%Xlm4{v>%bGe56fcS#&Isywp>BqS;I$C=k8Bp)l-Zz6H8sL@fBN!ee!!{uu9I8$^J@>A4j~(+MVH|r9RXZE1>SBNg`&jJ{LI}c5FLT=` zg{6^Y^RtXYaVh9jki=^{m(}Q9AirbB16c2&a!yM-|6$lRvw>{CR#k|izLM6-A z+4Dm~?A2K+kv5zM`5pS18V^Z3&*nxr|BRyE0vMvx{cF#0lsfs8mBZ~CAG-%{^R`y| zZBeDjd8gHP+e3`uek>Ac7;+kj2V`%g+}QkafMq_)^tdmie39QOi+pCJ{35^QL+>f|eJo9}h? z3K1jfwXM+sNe99g)`<|O&11)EZqU`?s{tOM_<48i`lm=WA*>?HgqUL?tJ7Ywdwpb? zcPLPEcP|}O+o~JAd7?O>2SspTGy51-JF*w&>Js& z>4(rrtV__DR^gfd{Q2juv>)k1L7s+JO@A&XXD{{!T8f@1#!)?+jxFR+L1O_&_C0Ym z9}zspL`un<$!B7sq7^ii!iNt}89%ACJpD!QZbkY%&?7v_odonJ2noie_c{R+fdxo) z?>1>k3(2uXqqZWS+fD=j*f{=MMIn}tK_?HvZe}yQYJ`P5^yL@nunwVyL5pcz2VGXe z|05@Rfr>YCa=*+Sy*0l~UoBy;MHXe$8aJ zk1XYEa(+)`z3AvnD?(jT_4~;JnqR#7@Xj+z6xfc!DEDX_FvyhziL?|uoL(gBzOFhF z;Ti`!h8lCHKLDOB-O#vjedNKuVih^LCD6DnZ?=D0dk&g0@9C!aPMI8oC8ond`6?8z z^>hj}^coHhRL|kNy~EfeV3Y-?Jl17qgC|0!(id+?AMb$(#@c#=1M60U2Y5lCfdWE8 zfuIBJU}W^cJMrbqx|Xw6(s75*oC}ysP8<0q|79tHcTIP6&p(Q*UoqZGB-iznQ|Nzx#}@dXk5InkYiRZ z97bJ)p9jd$|6{#Q6j}Cn2kg?c6utjDnUFp$lgMLv$W-lSYbIJ_)CR zYsKbw>s$&!|C#!tOeXr>cZ2Q0WtQsDm5D1X5yk2mjn+fyd~gm>&B(7l<#CI{rIa>)Z-aJvq2aA^wQ(v@Z3`n=1$69C|utc zS=w5F3WbcIeRQ56`(X&aCDJd+PFxE^N^$u13bxLHcO`rVZWi|O>DvzKxsn(Re z`ku=d9_d}ps-esF2)l;+!fgo!$3ewHN#CTWuUxdE(K~^l%q-8j&S8V z5CC0W@Gg)K7@gp%`d{%DWnoBE9ZQuI( zjxFKKEPB;`KN>He@L9@}(c(;yMSEQLvZU+kYij0&F~Osp(H|xDJ6L*n*=SO8`*uwT zH%F>9t+Q+Vn@8ElTZq5bqwf_a@dwdRAsnz5hi$&jt~03sCmd_HL##@44>~$RR<(mT z=uPuAN628Z$g(~XnV|j!n%tkOVg+pB*`EE=tlo#8hWH>lGUuiURGV<}i98rur_Qx_4||EPC3a?{ z*<$^Ao-7rQT{v>lg3!EGY{PCqBRD_S-AyqyG3h$yS(dw`QS4V^ymZ9husWC%tRZLR znU{?k0-85Kn;J!opc$JT_f~Wz^=*qejHgjb>Ndb0@b1PSIL{9`KNJAmJV;8iC@#g6 zHz6t2v%vB}wzv-DEL5DxRQ$ z#`K1$K7RFDM>|!o;RNv`EZ&nMk86MxLo+rK_bf5_q64CX4+|6l4UW_c9vxM*+Hj-V=7P|<XjsPWm~h+jnMFizsq$Ta~%@h+Gl(`1Pmuq>f)Xmrzw;~ z?KM=Sy$JN2w`X=t`1KC@3f!8(?5({ylbOqNwPIZYrF()WUEjBGG}$0^G0sP}+6>+9 zu!>1M^3VD~>nYOAghS=^>1RPcaf@d%*_yt%XGhM0P=u}LGh~J^b6WsFdmqrq+Xtn} zpX21(PoX4qSiC|mV<~rpJL8BC71CJ2*jss>x;Z0z$bD$h5ic1m#0G0h z@wF}?jJDAm7@y2habBg((y%6JD-rh%^%*!hMZS@bnKNgV#6gX{$G4%H3j|8A`QzVQ z5@H1WQWso-5J=kc(J}^wj4Epo#YT?!QxjujLAzQPpihvFVWxxY26dbd$hX|K{G`Js zD5+ZNI(Kbbu)ei5>%|07C1W~^8_cbU_E$gEfID6WfIbfAwjV#P`*=r;M?xh++Ud0| zff_tRvm!dUzQJ!5PA>b*%ow+ADHtojRM2zn>O&Ld)%{7|O#5XvZbS`A3YsL95g`2?(QBs@1jKjF1dM2xO(mm1ay%q&-IEakjdAx z(d2f;nGyt1$h+sj@_O(I1fHZ6MW$$4bgrrymtD-LY5t|XrR(d%w<0|UGMnx34lwxX@k`N>X@GR0JFiI6ckUI2^#Kl z3JULOYm6~$)$Cg{dRwrRiL)U&#}LC4DF-aSk#2nmW65M+(%6ncB7-|!CtFapOVvQhUQ4U$-hZ)&aU%_ z1NDEP@{zEFitDjk0%=7>tyKOo0NG+qhhYB5C76Rj*dRNEy#H!XLvaTJ?AIWX->r$z z9d`4Zo(>KJXur7ToFg*HVsqKCEZf&!whj(~7*;D8!;j(z@o&+9j5c|RUqsAuh9S^p#lV#W36#rQ~^%2rB!szl0 zkTDb(bjRl0Dnj z)>p{yuwKMh)oJOIl=Sb8l^1Q)R{57mOly??jI~L1cX+6UYjE)HGRblL=GQ@AxHuem zUv|;ddB(PHRl9ERJO+}GG1Ufah!ny=wRsi@um*B}U82#LA5VT3Ly3!I6DJWy@$PRC zQ6r|Li6soX9aC!ZVllinBXMLvZC$Ii@kg4VA9XrKs9$e@w;Uq^o<`j zl|Rp??Es?;qM(D$wV1!u2_gwJd)x&T%<86LyukO`2vm8xnNKsEWD5=K!7RM}(r zRj(H3*DalpFrX(C_oDnVy1RGuWEY^?HO!yVu_`K;o34hWobx$$EYkc)FmS%;ck?CIBsO;;M5m~b?GI^S9-O6q2!sYPx6RezPz zFYBvrBL@u4vvq#ow{T!SvZhMdI>>k0_6Eu2cK-UcJocn03V%GUM9NYPFZ?iYsuNMm z)7&g{Mup7`O!u8@Uf1oN$5TKrwH`+Kn;>Mjg@!muY&Bq)&DP7>+NPGaswpX5pGB5m z+3c7Q(SbnhkAhl`81&uS`_irvUr{u~u+ zoA(&3#{^`nRifL=MHtgKJw=DU<$*&y$lnCrCWm7dcjfpCXBUemYd zzc}t2tFF`jqA%m+hyeuJXXOPPCU_J%_(1L*zJBZ#U)@O!>AxloU^{AzPFBx_C zW>6%$L8sZjy*$EbD&IEcbHT7C^fBOC`9Rd*M8jyFhE_H2lqI!#NOc|svp4=>L{#u3 zq)N2CD8CA<5Y`iJwq~JJ-t|wIr*!=IGSnRp4N~31ZL^H2jfbWmeqBF3nzGc_^=p)< ziTsKF+FV-X1O8UpwV9^YL3&x(yp&ej&faUHrc1>OtL}hnM|B+HGhOyQ0`1<=XfjNB z!0gL9vSj#5HA0urb8_(*Lc5Aa6tn~Et74rkvy2I>T6zU=FcJ4a(8FNvPjWKWB@=ki z6?DlsCKOF~sG9NGjwvm{OAug3SUFdao-iE1*y>u=$nEr6eSn)3N;p8)JRa47f?XJv z0E!wJTK*PP+gZ5J?b;{1FKsaUyGwmE>sj#X*OS>dr*579V0)dB8(gADM;XvRoiN$| zIg{R3{n*6j{6OsMZ>iPQdPq-bN6XnF^0RXLlF@DDx7!sl;et|2epdX8rZ|OI7tscp zhKzPf+E{neTm=zryUCZ!ql*eB$<&^k1!QGwQzA5mNGXaU5iu97$Mf{_z3IPz@4 zHB!%oeymIIp$A58uvZ^#I1d4b*Z5nmOZNFUOr|d7yALfet16_;`-uhmIQ*nvOV69E zREx2^655^vIy(Hq0pEVzAiZ!9GXR43tU7CBvj_6s(#c?XJW%v@kV+bg@F1UbZi%+p z$d(%pxEjm|xXwO}|KGvo6|-??E&smUw55i-OJyC)!|2nc0o~Ddc--$Ni_G$!I_xtN z+Xqi6=Qb3Xd<+Z-05{RQ>lZLhSeJfiU!OlK{L?*te8;awr&W01tKBCO zR4GC;SkA^x8e9@<*kPkN5GXd1G*r%RA*tgZF#BlZMlKM;`Aauq3<4nOgbjz5TXXg& zrNxbzeW#BV8G6Vnn3v+MJab`M@iyn(7mD|7Ti|o2tM&S%`qFE@5AJVB zZ8+xHBduU?=Gr$^`?`2+2z=Od$#rxY#ES{mqhBkM(Dc+p+ZHC;ntOw~d%qKNLSbN< zD%5G6=Q!}@2#$2Gl|n#!dv-kbR5OG(5P-q8OUh!6zcEq)lh2+fD1%wYeT$J$aiG3M%*-!^%|vxw-7Xe)Vac}(I`JZW8_a(DnvQjRX{j}{E#2sI z*JFjeM=99B7pY$TGZ(-4#uo+Tt!!2Lo2b6*$5kPH19q&TmSX7yrW>Aof_7?Uvgm4g z?Dg)Qh}*OpHSd@RYSod5nJEgL?6~^ryUQD^7PQPvafX||tF7ENYI|t9IeZ^y`sB`z zGw3_8O(z8#0e&HkqxeOGpdl9N#CN8;Y7_DzZg$Z$8T)_rDDEL!J(3`@0s#ydA%FbK zp#DGUqZ0~zmW|0zKcBI>z?_O)n%1pdx0r9YK=(`ovxBX6>FTKjIZ*Dp7ni44VIj;|K=Tx@NKXcFf ze!QMM5#04#r>LvMcE%;U<7fTdc|u#KMFZJ%NxbWg45==AwV$?uDEQ+s&z(?%0f19}p;7pZTap)aI^?L8`tZT^;Sr z#LF7|Y`iWoR4$|6>^#a6VhOekznc; z57v60@y0J(TNAu@TwV}4`coh&DG6c)^q4L^8Jq>}R)YNV3+R`V+_B@f{M389T}b3T znj2g^Kk*@_sL$$`llI!#pJ%#CrevVKWlgAs#ZubJlbZx8LQ9|#s0_r0l;xGoVZK`K z)m-FTWH@>U$uv+V^Wn}~xb7{ULdy}?VzzogqUK}rv|nmL+dO{duTJ+fp$9NDq~~)A zuAi*S0FTS%KOgc7CcP592 zFL0@^8;##+MN7}f(@V6ay9-_18CSU@aa!+1TP|ZB8r4yu2|#KdWu?M62CgI&x!UF+ z;IW7169nF$3qD5wMwg0f7N3t^7GoOtId1Xapa_eCu#{3m;D1 z4&R19x)KD-l_n_o{Mkw3`x^+ByBru0(i0IDU`9MMxUcR-@+wWFsCQ_pcY1vb9+%KbVV8|*gd?hDxB@WRsL1n%zA8drFjZl;G zG0Q6Aa*&7=&)vPyr#A2-i~6u5?tbRN#PKI7DV*rpPO0f%@U`b6m{qS{&sJhr3?mR2 z03+$^Z+5A||4T&slcZ;UZz8kK{PkstvCaz6DAj*Hc;ureDjvH zRXBYF*S`9C)K>WQtF#!`!xvm#d47bj+S)KQ&}e9IZxk8i2ILPIgf{IR43Azte`+{4 zC-$k>?{B{fIYbX2LIdRFERoHRTkQ{vZG8G)ND}9kLpXqx8jmTrcY{9^xa=6s6_ZKy z-D6X|zP-b3uXj4htqe6c5(Lld_WN3$&xZGyiqsuJJ-_G&D$D+n;o$+9tO4E{wX#Py?dBsV;H_ zdNIu=s3lx30UWi%fXTW@UPIMfGio6A1+bUD4&M;z`O8%uDx>*LKkx;pnuDj~BHJx6 zf|9gE7cf9HV~B^)1$jRK!`)?QuA_by8^hf}x3p)d7aVwyFB@ilA8V9mfWC$Nkw#n9 zBfG#rK(B#ij=mX<`^xBUz@8t_jzzcl;*~44G~0tHMpA-=JV{;(Bmp{HUVi?NUF(TB z#7X2t)Ue`%Pw+m1I3Em5%@_^^D|WH0{yPyOP~>0)pskO0UXK=6L?pcAq6r{@NszIPC}F zht%If_+(iAR2P{%_qucYHrLC9r-1n`UL4L3p9>lwjQQjEfrrnW5?!tX1B2QmD|{_9 zoO9R#=i{m{CYh{_>>ZP2CzTIwyI+B|hK^uw@4*@aDvS`M$_J*W;1_dF=AfVk1~kBx zpo(UT-XM=!pU?CbCA<{;1lVWRGhx5yUS!D*Q*&X*Q5`CjB$FUP3f6YIuf%8M8bbRMd8`aK@Yz;+k1oI$+@vTigt;2nT<`!yStQ_`@aKE1cHIZ0!iTjAYHB=RT`6~39cM(Wf!(#n z4k&UYKvgv|BRH(GjImVVl>hlG-4a;ViKw`mFfx(~va|v-HGBb5dZG-6&ggL%o<=i^ zeRygtLkA{|A?`q~2iY7XwaI?Th$Wv|bqEU}v1SQvS{?HckifSr@IhRJ5a;@|XvAb>#TmGH z?g$fCtMn|`&dadvJw$4)=4@bPxxiQ!RO)++ie50Y>t2a@% zN^ajCIjU59E(_YEe7Y;j6?h6jnsrQ+n3AFbMeTf)WGxbYvsp{EBFvc~=6h-1(n-X8 z7Lu4tP%O&}3MToV1B7Zv>zmy!oyiqZR#1l7EYTFa1_~F-8$YXtv-BsB+Tr7!&l5VC zOXBqG64xx#_myDBfh7QMSwlf(!$O4nNY1(eXd^(1{Zpg?VwpLN{{nSmQph8Gz@oGSSAXG1E-W7(RC3GFpPedX^IeDD`y^ zQwuO{>&Yb@!AHM;dqEy=ZcJZCq<4_SR!D{YY$Z& z;1Xw_gl&q;cNQ4ByDK7KViaZ=hF}Iwuiyp(U`i5pf#+=iGI3fG!I;*g&j10W5q8<4 zo?Dtn*g}bBmWO2Iu?=`s5LiUqxdV5c^%K^T_}Le;r^v1U-JK$e&Tm-3Q2-*4I%~`* z`+u~AH8xb;s+2AmLBfcI5S^9eg#A6cvZ9p#o3`?yn#*MHiQ%ky+xh<1Cs;*(`t->t zW$tnzArSh4sG%@DT42fr`MHtV?D8>k%t|@FaT$V{nNI#oht@EJ>*`iD2?jX**C0RG zoBXEcRrV^5T7JJ`0mN39FVDe@3Xi8nx-ja>J*lnu!}8#>20Lh7#b`-@`hbQ4K3)yg zk@3Gvum=ohAC=UR^dbn+<jFP0EP$?1(}IS$v1{zWns>?2Y@A?m~s$;JhbSi zkSi~fB~SXn?AXnC|uYp%~! zUWY@#pC3WSTnd_}x}ia_FBCHsV{@I`uXi}$VE*$3hYmnu0`qR?AFB*fhkKtIbh$x6 z(cy6Yzkecx;_50dO(|49on<`Jv#NFMoqQpB)Th$$ZQ=Mq4mze`BDiS!M*g`2EC6Mg zr2f?MebrtbeIT7uR5-FKa;EBB*0d?k1y2x>uF|G?^Z#=V{sKZ63O8eliGf3)Dy~H` cxo6b&du&SH@jdhQ9Q<`qQ(Gfl-Q4eg02i7zmjD0& diff --git a/keyboards/ergodox/keymaps/bepo/keymap.c b/keyboards/ergodox/keymaps/bepo/keymap.c index ae8047ab59..c1a8ae21d9 100644 --- a/keyboards/ergodox/keymaps/bepo/keymap.c +++ b/keyboards/ergodox/keymaps/bepo/keymap.c @@ -201,18 +201,18 @@ KC_TRNS, KC_TRNS, KC_NO), /* Keymap 5: numeric layer, sends keypad codes * * ,--------------------------------------------------. ,--------------------------------------------------. - * | | | | | | | | | | | + | - | / | * | | + * | | | | | | | | | | | NumLo| / | * | - | | * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------| - * | | | | | | | | | | | 7 | 8 | 9 | | | + * | | | | | | | | | | | 7 | 8 | 9 | + | | * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------| - * | | | | | | |------| |------| | 4 | 5 | 6 | | | + * | | | | | | |------| |------| | 4 | 5 | 6 | + | | * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------| - * | | | | | | | | | | | 1 | 2 | 3 | | | + * | | | | | | | | | | | 1 | 2 | 3 | Enter| | * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' - * | | | | | | | | | | | | | 0 | 00 | . | | | + * | | | | | | | | | | | | | 0 | 00 | . | Enter| | * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' * | | | | | | | | - * | | |------| |------| | Enter| + * | | |------| |------| | | * | | | | | | | | * `--------------------' `--------------------' */ @@ -227,14 +227,14 @@ KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, // Right hand - KC_NO, KC_NO, KC_KP_PLUS, KC_KP_MINUS, KC_KP_SLASH, KC_KP_ASTERISK, KC_NO, - KC_NO, KC_NO, KC_KP_7, KC_KP_8, KC_KP_9, KC_NO, KC_NO, - KC_NO, KC_KP_4, KC_KP_5, KC_KP_6, KC_NO, KC_NO, - KC_NO, KC_NO, KC_KP_1, KC_KP_2, KC_KP_3, KC_NO, KC_NO, - KC_KP_0, M(KP_00), KC_KP_COMMA, KC_NO, KC_NO, + KC_NO, KC_NO, KC_NUMLOCK, KC_KP_SLASH, KC_KP_ASTERISK, KC_KP_MINUS, KC_NO, + KC_NO, KC_NO, KC_KP_7, KC_KP_8, KC_KP_9, KC_KP_PLUS, KC_NO, + KC_NO, KC_KP_4, KC_KP_5, KC_KP_6, KC_KP_PLUS, KC_NO, + KC_NO, KC_NO, KC_KP_1, KC_KP_2, KC_KP_3, KC_KP_ENTER, KC_NO, + KC_KP_0, M(KP_00), KC_KP_COMMA, KC_KP_ENTER, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, -KC_TRNS, KC_TRNS, KC_KP_ENTER) +KC_TRNS, KC_TRNS, KC_TRNS) }; const uint16_t PROGMEM fn_actions[] = { From 3f1fca2eb8078cdfbf576d6d4168de8e6ae1c2f6 Mon Sep 17 00:00:00 2001 From: Olivier Date: Mon, 28 Nov 2016 11:21:23 +0100 Subject: [PATCH 27/37] Adjust comment. --- keyboards/ergodox/keymaps/bepo/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keyboards/ergodox/keymaps/bepo/readme.md b/keyboards/ergodox/keymaps/bepo/readme.md index 207b675715..51a5069851 100644 --- a/keyboards/ergodox/keymaps/bepo/readme.md +++ b/keyboards/ergodox/keymaps/bepo/readme.md @@ -23,7 +23,7 @@ La touche "Tab" est placée comme sur la TypeMatrix 2020. Meilleure symétrie et accessibilité que la TypeMatrix 2030 : les touches "W" et "%" ont dû être déplacées du côté gauche en raison du nombre de touches de l'ErgoDox, mais l'auriculaire droit ne gère maintenant que deux colonnes de touches au lieu de trois. La touche "Ê" redevient accessible sur la même rangée que les autres lettres, comme sur un clavier classique en disposition bépo. Les lettres, chiffres et symboles sont tous regroupés sur 4 lignes et 6 colonnes pour chaque main, et la première rangée de lettres à la main gauche conserve une identité visuelle "BÉPO". -Touche de fonction permettant de saisir les touches F1 à F12, les touches F1 à F10 sont placées de façon logique par rapport aux chiffres 1 à 0. Cette même touche permet l'accès aux touches directionnelles sans déplacer la main droite. Les touches "Home" et "End" sont placées de la même façon que sur une TypeMatrix 2030 par rapport aux touches directionnelles. Les touches "Page Up" et "Page Down" sont également accessibles facilement sans déplacer la main droite. Les fonctions "VolUp" et "VolDown" sont placées comme sur la TypeMatrix 2030, avec la fonction "Mute" juste au dessus. Les fonctions "Undo", "Cut", "Copy" et "Paste" sont placées côte à côte comme elles le seraient sur un clavier QWERTY en combinaison avec la touche "Ctrl" (à l'emplacement des lettres "Z", "X", "C" et "V"). Par rapport au layout "SpaceFN", l'utilisation d'une touche de fonction dédiée au pouce permet de ne pas ajouter de latence, et la touche espace reste compatible avec les jeux (action au moment de l'appui et possibilité d'appui long). +Touche de fonction permettant de saisir les touches F1 à F12, les touches F1 à F10 sont placées de façon logique par rapport aux chiffres 1 à 0. Cette même touche permet l'accès aux touches directionnelles sans déplacer la main droite et d'effectuer des actions souris avec uniquement la main gauche. Les touches "Home" et "End" sont placées de la même façon que sur une TypeMatrix 2030 par rapport aux touches directionnelles. Les touches "Page Up" et "Page Down" sont également accessibles facilement sans déplacer la main droite. Les fonctions "VolUp" et "VolDown" sont placées comme sur la TypeMatrix 2030, avec la fonction "Mute" juste au dessus. Les fonctions "Undo", "Cut", "Copy" et "Paste" sont placées côte à côte comme elles le seraient sur un clavier QWERTY en combinaison avec la touche "Ctrl" (à l'emplacement des lettres "Z", "X", "C" et "V"). Par rapport au layout "SpaceFN", l'utilisation d'une touche de fonction dédiée au pouce permet de ne pas ajouter de latence, et la touche espace reste compatible avec les jeux (action au moment de l'appui et possibilité d'appui long). Touche de fonction permettant l'accès au pavé numérique comme sur la TypeMatrix 2030, mais sans avoir à déplacer la main droite : avec les doigts sur la rangée de repos, possibilité de saisir les chiffres "4", "5" et "6" comme sur un pavé numérique classique. Le double "0" de la TypeMatrix a été conservé, et gagne une possibilité de répétition en simples "0". From 2d0ada01902a0103dc4f4f54a416f0666c641b5b Mon Sep 17 00:00:00 2001 From: Erez Zukerman Date: Mon, 28 Nov 2016 07:55:02 -0500 Subject: [PATCH 28/37] Pulls LED config into common config for EZ --- keyboards/ergodox/ez/config.h | 11 +++++++++++ keyboards/ergodox/keymaps/erez_experimental/config.h | 10 ---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/keyboards/ergodox/ez/config.h b/keyboards/ergodox/ez/config.h index 67a856e511..0b7e8b2ee1 100644 --- a/keyboards/ergodox/ez/config.h +++ b/keyboards/ergodox/ez/config.h @@ -45,6 +45,17 @@ along with this program. If not, see . /* Set 0 if debouncing isn't needed */ #define DEBOUNCE 5 +/* ws2812 RGB LED */ +#define RGB_DI_PIN D7 +#define RGBLIGHT_ANIMATIONS +#define RGBLED_NUM 15 // Number of LEDs +#define RGBLIGHT_HUE_STEP 12 +#define RGBLIGHT_SAT_STEP 255 +#define RGBLIGHT_VAL_STEP 12 + +#define RGB_MIDI +#define RGBW_BB_TWI + /* * Feature disable options * These options are also useful to firmware size reduction. diff --git a/keyboards/ergodox/keymaps/erez_experimental/config.h b/keyboards/ergodox/keymaps/erez_experimental/config.h index fbd12ab797..4da18c65aa 100644 --- a/keyboards/ergodox/keymaps/erez_experimental/config.h +++ b/keyboards/ergodox/keymaps/erez_experimental/config.h @@ -9,15 +9,5 @@ #undef LEADER_TIMEOUT #define LEADER_TIMEOUT 300 -/* ws2812 RGB LED */ -#define RGB_DI_PIN D7 -#define RGBLIGHT_ANIMATIONS -#define RGBLED_NUM 15 // Number of LEDs -#define RGBLIGHT_HUE_STEP 12 -#define RGBLIGHT_SAT_STEP 255 -#define RGBLIGHT_VAL_STEP 12 - -#define RGB_MIDI -#define RGBW_BB_TWI #endif From 9caf866618840ca38f4ceb1166ad679174c752c3 Mon Sep 17 00:00:00 2001 From: Erez Zukerman Date: Mon, 28 Nov 2016 07:59:01 -0500 Subject: [PATCH 29/37] Tweaks EZ Makefile --- keyboards/ergodox/ez/Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/keyboards/ergodox/ez/Makefile b/keyboards/ergodox/ez/Makefile index 191c6bb664..9b6121e2c2 100644 --- a/keyboards/ergodox/ez/Makefile +++ b/keyboards/ergodox/ez/Makefile @@ -1,3 +1,8 @@ +SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend +COMMAND_ENABLE = no # Commands for debug and configuration +RGBLIGHT_ENABLE ?= yes +MIDI_ENABLE ?= yes + ifndef MAKEFILE_INCLUDED include ../../../Makefile -endif \ No newline at end of file +endif From d2b6438e391743544d437ca8c2998de6ab631894 Mon Sep 17 00:00:00 2001 From: Olivier Date: Mon, 28 Nov 2016 14:10:31 +0100 Subject: [PATCH 30/37] A little cleanup, add some comments, change others. --- keyboards/ergodox/keymaps/bepo/keymap.c | 42 ++++++++++--------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/keyboards/ergodox/keymaps/bepo/keymap.c b/keyboards/ergodox/keymaps/bepo/keymap.c index c1a8ae21d9..8f068e238d 100644 --- a/keyboards/ergodox/keymaps/bepo/keymap.c +++ b/keyboards/ergodox/keymaps/bepo/keymap.c @@ -1,19 +1,19 @@ #include "ergodox.h" -#include "debug.h" -#include "action_layer.h" #include "keymap_bepo.h" -#define BASE 0 // default layer -#define QWER 1 // qwerty compat layer -#define SQWER 2 // shifted qwerty compat layer -#define AQWER 3 // alted qwerty compat layer -#define FNAV 4 // function / navigation keys -#define NUM 5 // numeric keypad keys +// keymaps +#define BASE 0 // default layer, for bepo compatible systems +#define QWER 1 // bepo to qwerty base compat layer, for qwerty systems +#define SQWER 2 // bepo with shift key to qwerty compat layer +#define AQWER 3 // bepo with altgr key to qwerty compat layer +#define FNAV 4 // function / navigation / mouse layer +#define NUM 5 // numeric keypad layer -#define KP_00 0 +// macros +#define KP_00 0 // keypad "double 0" const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { -/* Keymap 0: Base layer +/* Keymap 0: default layer * * ,--------------------------------------------------. ,--------------------------------------------------. * | $ | " | < | > | ( | ) |Delete| |ScroLo| @ | + | - | / | * | = | @@ -50,7 +50,7 @@ KC_ESC, KC_INS, KC_LGUI, KC_LCTL, KC_LALT, DF(QWER), DF(BASE), MO(NUM), MO(FNAV), KC_RSHIFT, KC_ENTER), -/* Keymap 1: QWERTY system compatibility layer +/* Keymap 1: bepo to qwerty base compat layer * * ,--------------------------------------------------. ,--------------------------------------------------. * | $ | " | < | > | ( | ) |Delete| |ScroLo| @ | + | - | / | * | = | @@ -87,7 +87,7 @@ KC_ESC, KC_INS, KC_LGUI, KC_LCTL, KC_LALT, DF(QWER), DF(BASE), MO(NUM), MO(FNAV), MO(SQWER), KC_ENTER), -/* Keymap 2: QWERTY shifted system compatibility layer +/* Keymap 2: bepo with shift key to qwerty compat layer * * ,--------------------------------------------------. ,--------------------------------------------------. * | # | 1 | 2 | 3 | 4 | 5 |Delete| |ScroLo| 6 | 7 | 8 | 9 | 0 | = | @@ -124,7 +124,7 @@ S(KC_ESC), S(KC_INS), S(KC_LGUI), S(KC_LCTL), S(KC_LALT), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), -/* Keymap 3: QWERTY alted system compatibility layer +/* Keymap 3: bepo with altgr key to qwerty compat layer * * ,--------------------------------------------------. ,--------------------------------------------------. * | $ | " | < | > | [ | ] |Delete| |ScroLo| @ | + | - | / | * | = | @@ -161,7 +161,7 @@ KC_ESC, KC_INS, KC_LGUI, KC_LCTL, KC_LALT, KC_TRNS, KC_TRNS, MO(NUM), MO(FNAV), MO(SQWER), KC_ENTER), -/* Keymap 4: function / navigation layer +/* Keymap 4: function / navigation / mouse layer * * ,--------------------------------------------------. ,--------------------------------------------------. * | | F1 | F2 | F3 | F4 | F5 |VolMut| | | F6 | F7 | F8 | F9 | F10 | | @@ -198,7 +198,7 @@ KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO), -/* Keymap 5: numeric layer, sends keypad codes +/* Keymap 5: numeric keypad layer, sends keypad codes * * ,--------------------------------------------------. ,--------------------------------------------------. * | | | | | | | | | | | NumLo| / | * | - | | @@ -237,12 +237,10 @@ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS) }; -const uint16_t PROGMEM fn_actions[] = { -}; - const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { switch(id) { + // keypad "double 0" case KP_00: if (record->event.pressed) { return MACRO( T(KP_0), D(KP_0), END ); @@ -253,11 +251,3 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) } return MACRO_NONE; }; - -// Runs just one time when the keyboard initializes. -void matrix_init_user(void) { -}; - -// Runs constantly in the background, in a loop. -void matrix_scan_user(void) { -}; From 84735836e309fe9e2c45ed991a58820ae2bb9123 Mon Sep 17 00:00:00 2001 From: Erez Zukerman Date: Mon, 28 Nov 2016 08:13:32 -0500 Subject: [PATCH 31/37] Tweaks position of TOG not to conflict with MO --- keyboards/ergodox/keymaps/erez_experimental/keymap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/keyboards/ergodox/keymaps/erez_experimental/keymap.c b/keyboards/ergodox/keymaps/erez_experimental/keymap.c index 0c0e3c4e39..2963c40e31 100644 --- a/keyboards/ergodox/keymaps/erez_experimental/keymap.c +++ b/keyboards/ergodox/keymaps/erez_experimental/keymap.c @@ -71,7 +71,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * | | | |NxtTab|PrvTab| | | | | | | * `----------------------------------' `----------------------------------' * ,-------------. ,-------------. - * | | | | | | + * | | | |TOG | * ,------|------|------| |------+------+------. * |VAI |VAD |HUI | |SAI |TOG |MOD | * | | |------| |------| | | @@ -95,9 +95,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_AMPR, KC_UNDS, KC_MINS, CM_SCLN, KC_PLUS, KC_TRNS, KC_TRNS, KC_PIPE, KC_AT, KC_EQL, KC_PERC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, + RGB_TOG, KC_TRNS, RGB_SAI, - RGB_SAD, RGB_TOG, RGB_MOD + RGB_SAD, KC_TRNS, RGB_MOD ), /* Keymap 2: Media and mouse keys * From f02eccbb29ee6a8cf421895dcef2e55a76c1bdcb Mon Sep 17 00:00:00 2001 From: Olivier Date: Mon, 28 Nov 2016 14:16:42 +0100 Subject: [PATCH 32/37] Change layer names (cosmetic change) and reorder them so that the "shift" layer can be accessed from the "alt" layer when in QWERTY compat mode. --- keyboards/ergodox/keymaps/bepo/keymap.c | 124 ++++++++++++------------ 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/keyboards/ergodox/keymaps/bepo/keymap.c b/keyboards/ergodox/keymaps/bepo/keymap.c index 8f068e238d..c19ab0d48d 100644 --- a/keyboards/ergodox/keymaps/bepo/keymap.c +++ b/keyboards/ergodox/keymaps/bepo/keymap.c @@ -2,12 +2,12 @@ #include "keymap_bepo.h" // keymaps -#define BASE 0 // default layer, for bepo compatible systems -#define QWER 1 // bepo to qwerty base compat layer, for qwerty systems -#define SQWER 2 // bepo with shift key to qwerty compat layer -#define AQWER 3 // bepo with altgr key to qwerty compat layer +#define BEPO 0 // default layer, for bepo compatible systems +#define QW_B 1 // bepo to qwerty base compat layer, for qwerty systems +#define QW_A 2 // bepo with altgr key to qwerty compat layer +#define QW_S 3 // bepo with shift key to qwerty compat layer #define FNAV 4 // function / navigation / mouse layer -#define NUM 5 // numeric keypad layer +#define NUMK 5 // numeric keypad layer // macros #define KP_00 0 // keypad "double 0" @@ -26,20 +26,20 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' * |Escape|Insert|LSuper| LCtrl| LAlt| | BEPO |QWERTY| |AZERTY| BEPO | | AltGr| RCtrl|RSuper|PrntSc| Pause| * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' - * | | | L_Num| | L_Num| | | + * | | |L_NumK| |L_NumK| | | * | Space|LShift|------| |------|RShift|Enter | * | | |L_FNav| |L_FNav| | | * `--------------------' `--------------------' */ -[BASE] = KEYMAP( +[BEPO] = KEYMAP( // Left hand BP_DOLLAR, BP_DQOT, BP_LGIL, BP_RGIL, BP_LPRN, BP_RPRN, KC_DEL, BP_PERCENT, BP_B, BP_E_ACUTE, BP_P, BP_O, BP_E_GRAVE, KC_BSPC, BP_W, BP_A, BP_U, BP_I, BP_E, BP_COMMA, BP_ECRC, BP_A_GRAVE, BP_Y, BP_X, BP_DOT, BP_K, KC_TAB, KC_ESC, KC_INS, KC_LGUI, KC_LCTL, KC_LALT, - DF(BASE), DF(QWER), - MO(NUM), + DF(BEPO), DF(QW_B), + MO(NUMK), KC_SPC, KC_LSHIFT, MO(FNAV), // Right hand KC_SLCK, BP_AT, BP_PLUS, BP_MINUS, BP_SLASH, BP_ASTR, BP_EQUAL, @@ -47,8 +47,8 @@ KC_ESC, KC_INS, KC_LGUI, KC_LCTL, KC_LALT, BP_C, BP_T, BP_S, BP_R, BP_N, BP_M, KC_NUMLOCK, BP_APOS, BP_Q, BP_G, BP_H, BP_F, BP_CCED, BP_ALGR, KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE, -DF(QWER), DF(BASE), -MO(NUM), +DF(QW_B), DF(BEPO), +MO(NUMK), MO(FNAV), KC_RSHIFT, KC_ENTER), /* Keymap 1: bepo to qwerty base compat layer * @@ -63,31 +63,68 @@ MO(FNAV), KC_RSHIFT, KC_ENTER), * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' * |Escape|Insert|LSuper| LCtrl| LAlt| | BEPO |QWERTY| |AZERTY| BEPO | | AltGr| RCtrl|RSuper|PrntSc| Pause| * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' - * | | | L_Num| | L_Num| | | + * | | |L_NumK| |L_NumK| | | * | Space|LShift|------| |------|RShift|Enter | * | | |L_FNav| |L_FNav| | | * `--------------------' `--------------------' */ -[QWER] = KEYMAP( +[QW_B] = KEYMAP( // Left hand KC_DOLLAR, S(KC_QUOT), S(KC_COMM), S(KC_DOT), KC_LPRN, KC_RPRN, KC_DEL, KC_PERCENT, KC_B, KC_E, KC_P, KC_O, KC_E, KC_BSPC, KC_W, KC_A, KC_U, KC_I, KC_E, KC_COMMA, KC_E, KC_A, KC_Y, KC_X, KC_DOT, KC_K, KC_TAB, KC_ESC, KC_INS, KC_LGUI, KC_LCTL, KC_LALT, - DF(BASE), DF(QWER), - MO(NUM), - KC_SPC, MO(SQWER), MO(FNAV), + KC_TRNS, KC_TRNS, + KC_TRNS, + KC_SPC, MO(QW_S), KC_TRNS, // Right hand KC_SLCK, KC_AT, KC_PLUS, KC_MINUS, KC_SLASH, KC_ASTR, KC_EQUAL, KC_CAPSLOCK, KC_CIRC, KC_V, KC_D, KC_L, KC_J, KC_Z, KC_C, KC_T, KC_S, KC_R, KC_N, KC_M, KC_NUMLOCK, KC_QUOT, KC_Q, KC_G, KC_H, KC_F, KC_C, - MO(AQWER), KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE, -DF(QWER), DF(BASE), -MO(NUM), -MO(FNAV), MO(SQWER), KC_ENTER), -/* Keymap 2: bepo with shift key to qwerty compat layer + MO(QW_A), KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE, +KC_TRNS, KC_TRNS, +KC_TRNS, +KC_TRNS, MO(QW_S), KC_ENTER), +/* Keymap 2: bepo with altgr key to qwerty compat layer + * + * ,--------------------------------------------------. ,--------------------------------------------------. + * | $ | " | < | > | [ | ] |Delete| |ScroLo| @ | + | - | / | * | = | + * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------| + * | % | | | e | & | o | e |Backsp| |CapsLo| ^ | v | d | l | j | z | + * |--------+------+------+------+------+------| ace | | |------+------+------+------+------+--------| + * | w | a | u | i | € | , |------| |------| c | t | s | r | n | m | + * |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------| + * | e | \ | { | } | . | ~ | | | | ' | q | g | h | f | c | + * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' + * |Escape|Insert|LSuper| LCtrl| LAlt| | BEPO |QWERTY| |AZERTY| BEPO | | AltGr| RCtrl|RSuper|PrntSc| Pause| + * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' + * | | |L_NumK| |L_NumK| | | + * | _ |LShift|------| |------|RShift|Enter | + * | | |L_FNav| |L_FNav| | | + * `--------------------' `--------------------' + */ +[QW_A] = KEYMAP( +// Left hand +KC_DOLLAR, S(KC_QUOT), S(KC_COMM), S(KC_DOT), KC_LBRC, KC_RBRC, KC_DEL, +KC_PERCENT, KC_PIPE, KC_E, KC_AMPR, KC_O, KC_E, KC_BSPC, +KC_W, KC_A, KC_U, KC_I, RALT(KC_5), KC_COMMA, +KC_E, KC_BSLASH, KC_LCBR, KC_RCBR, KC_DOT, KC_TILDE, KC_TAB, +KC_ESC, KC_INS, KC_LGUI, KC_LCTL, KC_LALT, + KC_TRNS, KC_TRNS, + KC_TRNS, + KC_UNDS, MO(QW_S), KC_TRNS, +// Right hand + KC_SLCK, KC_AT, KC_PLUS, KC_MINUS, KC_SLASH, KC_ASTR, KC_EQUAL, + KC_CAPSLOCK, KC_CIRC, KC_V, KC_D, KC_L, KC_J, KC_Z, + KC_C, KC_T, KC_S, KC_R, KC_N, KC_M, + KC_NUMLOCK, KC_QUOT, KC_Q, KC_G, KC_H, KC_F, KC_C, + KC_TRNS, KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE, +KC_TRNS, KC_TRNS, +KC_TRNS, +KC_TRNS, MO(QW_S), KC_ENTER), +/* Keymap 3: bepo with shift key to qwerty compat layer * * ,--------------------------------------------------. ,--------------------------------------------------. * | # | 1 | 2 | 3 | 4 | 5 |Delete| |ScroLo| 6 | 7 | 8 | 9 | 0 | = | @@ -100,12 +137,12 @@ MO(FNAV), MO(SQWER), KC_ENTER), * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' * |Escape|Insert|LSuper| LCtrl| LAlt| | BEPO |QWERTY| |AZERTY| BEPO | | AltGr| RCtrl|RSuper|PrntSc| Pause| * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' - * | | | L_Num| | L_Num| | | + * | | |L_NumK| |L_NumK| | | * | Space|LShift|------| |------|RShift|Enter | * | | |L_FNav| |L_FNav| | | * `--------------------' `--------------------' */ -[SQWER] = KEYMAP( +[QW_S] = KEYMAP( // Left hand KC_HASH, KC_1, KC_2, KC_3, KC_4, KC_5, KC_TRNS, KC_GRV, S(KC_B), S(KC_E), S(KC_P), S(KC_O), S(KC_E), KC_TRNS, @@ -124,43 +161,6 @@ S(KC_ESC), S(KC_INS), S(KC_LGUI), S(KC_LCTL), S(KC_LALT), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), -/* Keymap 3: bepo with altgr key to qwerty compat layer - * - * ,--------------------------------------------------. ,--------------------------------------------------. - * | $ | " | < | > | [ | ] |Delete| |ScroLo| @ | + | - | / | * | = | - * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------| - * | % | | | e | & | o | e |Backsp| |CapsLo| ^ | v | d | l | j | z | - * |--------+------+------+------+------+------| ace | | |------+------+------+------+------+--------| - * | w | a | u | i | € | , |------| |------| c | t | s | r | n | m | - * |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------| - * | e | \ | { | } | . | ~ | | | | ' | q | g | h | f | c | - * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' - * |Escape|Insert|LSuper| LCtrl| LAlt| | BEPO |QWERTY| |AZERTY| BEPO | | AltGr| RCtrl|RSuper|PrntSc| Pause| - * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' - * | | | L_Num| | L_Num| | | - * | _ |LShift|------| |------|RShift|Enter | - * | | |L_FNav| |L_FNav| | | - * `--------------------' `--------------------' - */ -[AQWER] = KEYMAP( -// Left hand -KC_DOLLAR, S(KC_QUOT), S(KC_COMM), S(KC_DOT), KC_LBRC, KC_RBRC, KC_DEL, -KC_PERCENT, KC_PIPE, KC_E, KC_AMPR, KC_O, KC_E, KC_BSPC, -KC_W, KC_A, KC_U, KC_I, RALT(KC_5), KC_COMMA, -KC_E, KC_BSLASH, KC_LCBR, KC_RCBR, KC_DOT, KC_TILDE, KC_TAB, -KC_ESC, KC_INS, KC_LGUI, KC_LCTL, KC_LALT, - KC_TRNS, KC_TRNS, - MO(NUM), - KC_UNDS, MO(SQWER), MO(FNAV), -// Right hand - KC_SLCK, KC_AT, KC_PLUS, KC_MINUS, KC_SLASH, KC_ASTR, KC_EQUAL, - KC_CAPSLOCK, KC_CIRC, KC_V, KC_D, KC_L, KC_J, KC_Z, - KC_C, KC_T, KC_S, KC_R, KC_N, KC_M, - KC_NUMLOCK, KC_QUOT, KC_Q, KC_G, KC_H, KC_F, KC_C, - KC_TRNS, KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE, -KC_TRNS, KC_TRNS, -MO(NUM), -MO(FNAV), MO(SQWER), KC_ENTER), /* Keymap 4: function / navigation / mouse layer * * ,--------------------------------------------------. ,--------------------------------------------------. @@ -216,7 +216,7 @@ KC_TRNS, KC_TRNS, KC_NO), * | | | | | | | | * `--------------------' `--------------------' */ -[NUM] = KEYMAP( +[NUMK] = KEYMAP( // Left hand KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, @@ -234,7 +234,7 @@ KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, KC_KP_0, M(KP_00), KC_KP_COMMA, KC_KP_ENTER, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, -KC_TRNS, KC_TRNS, KC_TRNS) +KC_TRNS, KC_TRNS, KC_NO) }; const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) From 5a2501d90fb9d2ea1a60d42dfd664d899865e6b5 Mon Sep 17 00:00:00 2001 From: Olivier Date: Mon, 28 Nov 2016 16:38:03 +0100 Subject: [PATCH 33/37] Add the AZERTY compatibility layer. --- keyboards/ergodox/keymaps/bepo/keymap.c | 125 ++++++++++++++++++++++- keyboards/ergodox/keymaps/bepo/readme.md | 4 +- 2 files changed, 122 insertions(+), 7 deletions(-) diff --git a/keyboards/ergodox/keymaps/bepo/keymap.c b/keyboards/ergodox/keymaps/bepo/keymap.c index c19ab0d48d..05250ee6a7 100644 --- a/keyboards/ergodox/keymaps/bepo/keymap.c +++ b/keyboards/ergodox/keymaps/bepo/keymap.c @@ -1,13 +1,17 @@ #include "ergodox.h" #include "keymap_bepo.h" +#include "keymap_french.h" // keymaps #define BEPO 0 // default layer, for bepo compatible systems #define QW_B 1 // bepo to qwerty base compat layer, for qwerty systems #define QW_A 2 // bepo with altgr key to qwerty compat layer #define QW_S 3 // bepo with shift key to qwerty compat layer -#define FNAV 4 // function / navigation / mouse layer -#define NUMK 5 // numeric keypad layer +#define AZ_B 4 // bepo to azerty base compat layer, for azerty systems +#define AZ_A 5 // bepo with altgr key to azerty compat layer +#define AZ_S 6 // bepo with shift key to azerty compat layer +#define FNAV 7 // function / navigation / mouse layer +#define NUMK 8 // numeric keypad layer // macros #define KP_00 0 // keypad "double 0" @@ -47,7 +51,7 @@ KC_ESC, KC_INS, KC_LGUI, KC_LCTL, KC_LALT, BP_C, BP_T, BP_S, BP_R, BP_N, BP_M, KC_NUMLOCK, BP_APOS, BP_Q, BP_G, BP_H, BP_F, BP_CCED, BP_ALGR, KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE, -DF(QW_B), DF(BEPO), +DF(AZ_B), DF(BEPO), MO(NUMK), MO(FNAV), KC_RSHIFT, KC_ENTER), /* Keymap 1: bepo to qwerty base compat layer @@ -161,7 +165,118 @@ S(KC_ESC), S(KC_INS), S(KC_LGUI), S(KC_LCTL), S(KC_LALT), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), -/* Keymap 4: function / navigation / mouse layer +/* Keymap 4: bepo to azerty base compat layer + * + * ,--------------------------------------------------. ,--------------------------------------------------. + * | $ | " | < | > | ( | ) |Delete| |ScroLo| @ | + | - | / | * | = | + * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------| + * | % | b |e_acut| p | o |e_grav|Backsp| |CapsLo| ^ | v | d | l | j | z | + * |--------+------+------+------+------+------| ace | | |------+------+------+------+------+--------| + * | w | a | u | i | e | , |------| |------| c | t | s | r | n | m | + * |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------| + * | e |a_grav| y | x | . | k | | | | ' | q | g | h | f | c_cedil| + * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' + * |Escape|Insert|LSuper| LCtrl| LAlt| | BEPO |QWERTY| |AZERTY| BEPO | | AltGr| RCtrl|RSuper|PrntSc| Pause| + * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' + * | | |L_NumK| |L_NumK| | | + * | Space|LShift|------| |------|RShift|Enter | + * | | |L_FNav| |L_FNav| | | + * `--------------------' `--------------------' + */ +[AZ_B] = KEYMAP( +// Left hand +FR_DLR, FR_QUOT, FR_LESS, FR_GRTR, FR_LPRN, FR_RPRN, KC_DEL, +FR_PERC, KC_B, FR_EACU, KC_P, KC_O, FR_EGRV, KC_BSPC, +FR_W, FR_A, KC_U, KC_I, KC_E, FR_COMM, +KC_E, FR_AGRV, KC_Y, KC_X, FR_DOT, KC_K, KC_TAB, +KC_ESC, KC_INS, KC_LGUI, KC_LCTL, KC_LALT, + KC_TRNS, KC_TRNS, + KC_TRNS, + KC_SPC, MO(AZ_S), KC_TRNS, +// Right hand + KC_SLCK, FR_AT, FR_PLUS, FR_MINS, FR_SLSH, FR_ASTR, FR_EQL, + KC_CAPSLOCK, KC_LBRC, KC_V, KC_D, KC_L, KC_J, FR_Z, + KC_C, KC_T, KC_S, KC_R, KC_N, FR_M, + KC_NUMLOCK, FR_APOS, FR_Q, KC_G, KC_H, KC_F, FR_CCED, + MO(AZ_A), KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE, +KC_TRNS, KC_TRNS, +KC_TRNS, +KC_TRNS, MO(AZ_S), KC_ENTER), +/* Keymap 5: bepo with altgr key to azerty compat layer + * + * ,--------------------------------------------------. ,--------------------------------------------------. + * | $ | " | < | > | [ | ] |Delete| |ScroLo| @ | + | - | / | * | = | + * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------| + * | % | | | e | & | o | e |Backsp| |CapsLo| ^ | v | d | l | j | z | + * |--------+------+------+------+------+------| ace | | |------+------+------+------+------+--------| + * | w | a |u_grav| trem | € | , |------| |------| c | t | s | r | n | m | + * |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------| + * | / | \ | { | } | . | ~ | | | | ' | q | g | h | f | c | + * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' + * |Escape|Insert|LSuper| LCtrl| LAlt| | BEPO |QWERTY| |AZERTY| BEPO | | AltGr| RCtrl|RSuper|PrntSc| Pause| + * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' + * | | |L_NumK| |L_NumK| | | + * | _ |LShift|------| |------|RShift|Enter | + * | | |L_FNav| |L_FNav| | | + * `--------------------' `--------------------' + */ +[AZ_A] = KEYMAP( +// Left hand +FR_DLR, FR_QUOT, FR_LESS, FR_GRTR, FR_LBRC, FR_RBRC, KC_DEL, +FR_PERC, FR_PIPE, FR_EACU, FR_AMP, KC_O, FR_EGRV, KC_BSPC, +FR_W, FR_A, FR_UGRV, S(KC_LBRC), FR_EURO, FR_COMM, +FR_SLSH, FR_BSLS, FR_LCBR, FR_RCBR, FR_DOT, FR_TILD, KC_TAB, +KC_ESC, KC_INS, KC_LGUI, KC_LCTL, KC_LALT, + KC_TRNS, KC_TRNS, + KC_TRNS, + FR_UNDS, MO(AZ_S), KC_TRNS, +// Right hand + KC_SLCK, FR_AT, FR_PLUS, FR_MINS, FR_SLSH, FR_ASTR, FR_EQL, + KC_CAPSLOCK, KC_LBRC, KC_V, KC_D, KC_L, KC_J, FR_Z, + KC_C, KC_T, KC_S, KC_R, KC_N, FR_M, + KC_NUMLOCK, FR_APOS, FR_Q, KC_G, KC_H, KC_F, FR_CCED, + KC_TRNS, KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE, +KC_TRNS, KC_TRNS, +KC_TRNS, +KC_TRNS, MO(AZ_S), KC_ENTER), +/* Keymap 6: bepo with shift key to azerty compat layer + * + * ,--------------------------------------------------. ,--------------------------------------------------. + * | # | 1 | 2 | 3 | 4 | 5 |Delete| |ScroLo| 6 | 7 | 8 | 9 | 0 | ° | + * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------| + * | ` | B | E | P | O | E |Backsp| |CapsLo| ! | V | D | L | J | Z | + * |--------+------+------+------+------+------| ace | | |------+------+------+------+------+--------| + * | W | A | U | I | E | ; |------| |------| C | T | S | R | N | M | + * |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------| + * | E | A | Y | X | : | K | | | | ? | Q | G | H | F | C | + * `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------' + * |Escape|Insert|LSuper| LCtrl| LAlt| | BEPO |QWERTY| |AZERTY| BEPO | | AltGr| RCtrl|RSuper|PrntSc| Pause| + * `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------' + * | | |L_NumK| |L_NumK| | | + * | Space|LShift|------| |------|RShift|Enter | + * | | |L_FNav| |L_FNav| | | + * `--------------------' `--------------------' + */ +[AZ_S] = KEYMAP( +// Left hand +FR_HASH, FR_1, FR_2, FR_3, FR_4, FR_5, KC_TRNS, +FR_GRV, S(KC_B), S(KC_E), S(KC_P), S(KC_O), S(KC_E), KC_TRNS, +S(FR_W), S(FR_A), S(KC_U), S(KC_I), S(KC_E), FR_SCLN, +S(KC_E), S(FR_A), S(KC_Y), S(KC_X), FR_COLN, S(KC_K), S(KC_TAB), +S(KC_ESC), S(KC_INS), S(KC_LGUI), S(KC_LCTL), S(KC_LALT), + KC_TRNS, KC_TRNS, + KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, +// Right hand + KC_TRNS, FR_6, FR_7, FR_8, FR_9, FR_0, FR_OVRR, + KC_TRNS, FR_EXLM, S(KC_V), S(KC_D), S(KC_L), S(KC_J), S(FR_Z), + S(KC_C), S(KC_T), S(KC_S), S(KC_R), S(KC_N), S(FR_M), + KC_TRNS, FR_QUES, S(FR_Q), S(KC_G), S(KC_H), S(KC_F), S(KC_C), + S(KC_RALT), S(KC_RCTL), S(KC_RGUI), KC_TRNS, KC_TRNS, +KC_TRNS, KC_TRNS, +KC_TRNS, +KC_TRNS, KC_TRNS, KC_TRNS), +/* Keymap 7: function / navigation / mouse layer * * ,--------------------------------------------------. ,--------------------------------------------------. * | | F1 | F2 | F3 | F4 | F5 |VolMut| | | F6 | F7 | F8 | F9 | F10 | | @@ -198,7 +313,7 @@ KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO), -/* Keymap 5: numeric keypad layer, sends keypad codes +/* Keymap 8: numeric keypad layer, sends keypad codes * * ,--------------------------------------------------. ,--------------------------------------------------. * | | | | | | | | | | | NumLo| / | * | - | | diff --git a/keyboards/ergodox/keymaps/bepo/readme.md b/keyboards/ergodox/keymaps/bepo/readme.md index 51a5069851..2959ac8298 100644 --- a/keyboards/ergodox/keymaps/bepo/readme.md +++ b/keyboards/ergodox/keymaps/bepo/readme.md @@ -27,8 +27,8 @@ Touche de fonction permettant de saisir les touches F1 à F12, les touches F1 à Touche de fonction permettant l'accès au pavé numérique comme sur la TypeMatrix 2030, mais sans avoir à déplacer la main droite : avec les doigts sur la rangée de repos, possibilité de saisir les chiffres "4", "5" et "6" comme sur un pavé numérique classique. Le double "0" de la TypeMatrix a été conservé, et gagne une possibilité de répétition en simples "0". -Touche permettant de basculer en mode BEPO sur un système configuré pour un clavier QWERTY. Cette compatibilité n'est pas parfaite (pas encore de gestion des accents mais ça devrait être faisable avec une disposition en qwerty international, et les combinaisons de touches ne sont pas toutes supportées puisque le clavier traduit déjà certaines touches en combinaisons) mais reste pratique pour une saisie de texte occasionnelle. +Touche permettant de basculer en mode BEPO sur un système configuré pour un clavier QWERTY. Cette compatibilité n'est pas parfaite (pas encore de gestion des accents mais ça devrait être faisable avec une disposition en qwerty international, et les combinaisons de touches ne sont pas toutes supportées puisque le clavier traduit déjà certaines touches en combinaisons) mais reste pratique pour une saisie de texte occasionnelle et pour des accès BIOS ou console en QWERTY. -TODO : couche de compatibilité pour utiliser la disposition BÉPO sur un système configuré pour un clavier AZERTY. +Touche permettant de basculer en mode BEPO sur un système configuré pour un clavier AZERTY. Cette compatibilité n'est pas parfaite (pas de gestion des caractères non présents sur le clavier AZERTY, et les combinaisons de touches ne sont pas toutes supportées puisque le clavier traduit déjà certaines touches en combinaisons) mais reste pratique pour une saisie de texte occasionnelle et pour faire du bureau à distance vers un système Windows sans BEPO. > Olivier Smedts From 06f18e95d4670a055ca349da7d653e0bcb37d83a Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 29 Nov 2016 00:06:12 -0500 Subject: [PATCH 34/37] enable api sysex for ez --- keyboards/ergodox/ez/rules.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/keyboards/ergodox/ez/rules.mk b/keyboards/ergodox/ez/rules.mk index a9715beb85..f570061fe4 100644 --- a/keyboards/ergodox/ez/rules.mk +++ b/keyboards/ergodox/ez/rules.mk @@ -72,6 +72,7 @@ OPT_DEFS += -DBOOTLOADER_SIZE=512 # SLEEP_LED_ENABLE = no +API_SYSEX_ENABLE ?= yes ifndef QUANTUM_DIR include ../../../Makefile From d0cefef946660865dae80877886fcce610920a27 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 29 Nov 2016 00:09:56 -0500 Subject: [PATCH 35/37] enable rgblight by default for ez --- keyboards/ergodox/ez/config.h | 11 +++++++++++ keyboards/ergodox/ez/rules.mk | 1 + 2 files changed, 12 insertions(+) diff --git a/keyboards/ergodox/ez/config.h b/keyboards/ergodox/ez/config.h index 67a856e511..c2750a321f 100644 --- a/keyboards/ergodox/ez/config.h +++ b/keyboards/ergodox/ez/config.h @@ -41,6 +41,17 @@ along with this program. If not, see . #define LED_BRIGHTNESS_LO 15 #define LED_BRIGHTNESS_HI 255 +/* ws2812 RGB LED */ +#define RGB_DI_PIN D7 +#define RGBLIGHT_ANIMATIONS +#define RGBLED_NUM 15 // Number of LEDs +#define RGBLIGHT_HUE_STEP 12 +#define RGBLIGHT_SAT_STEP 255 +#define RGBLIGHT_VAL_STEP 12 + +#define RGB_MIDI +#define RGBW_BB_TWI + /* Set 0 if debouncing isn't needed */ #define DEBOUNCE 5 diff --git a/keyboards/ergodox/ez/rules.mk b/keyboards/ergodox/ez/rules.mk index f570061fe4..893cfa7a84 100644 --- a/keyboards/ergodox/ez/rules.mk +++ b/keyboards/ergodox/ez/rules.mk @@ -73,6 +73,7 @@ OPT_DEFS += -DBOOTLOADER_SIZE=512 SLEEP_LED_ENABLE = no API_SYSEX_ENABLE ?= yes +RGBLIGHT_ENABLE ?= yes ifndef QUANTUM_DIR include ../../../Makefile From f946d830f98da0161753d37da9659caa7469cf4f Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 29 Nov 2016 00:11:11 -0500 Subject: [PATCH 36/37] guess i didnt pull --- keyboards/ergodox/ez/config.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/keyboards/ergodox/ez/config.h b/keyboards/ergodox/ez/config.h index f3e1020bdb..c2750a321f 100644 --- a/keyboards/ergodox/ez/config.h +++ b/keyboards/ergodox/ez/config.h @@ -56,17 +56,6 @@ along with this program. If not, see . /* Set 0 if debouncing isn't needed */ #define DEBOUNCE 5 -/* ws2812 RGB LED */ -#define RGB_DI_PIN D7 -#define RGBLIGHT_ANIMATIONS -#define RGBLED_NUM 15 // Number of LEDs -#define RGBLIGHT_HUE_STEP 12 -#define RGBLIGHT_SAT_STEP 255 -#define RGBLIGHT_VAL_STEP 12 - -#define RGB_MIDI -#define RGBW_BB_TWI - /* * Feature disable options * These options are also useful to firmware size reduction. From 4094544d41450617bc21ab58646603b8964eae0e Mon Sep 17 00:00:00 2001 From: Erez Zukerman Date: Tue, 29 Nov 2016 09:23:16 -0500 Subject: [PATCH 37/37] Test layout for ErgoDox EZ manufacturing robot --- .../keymaps/robot_test_layout/keymap.c | 130 ++++++++++++++++++ .../keymaps/robot_test_layout/readme.md | 5 + quantum/rgblight.c | 6 + quantum/rgblight.h | 2 + 4 files changed, 143 insertions(+) create mode 100644 keyboards/ergodox/keymaps/robot_test_layout/keymap.c create mode 100644 keyboards/ergodox/keymaps/robot_test_layout/readme.md diff --git a/keyboards/ergodox/keymaps/robot_test_layout/keymap.c b/keyboards/ergodox/keymaps/robot_test_layout/keymap.c new file mode 100644 index 0000000000..0363eedc2b --- /dev/null +++ b/keyboards/ergodox/keymaps/robot_test_layout/keymap.c @@ -0,0 +1,130 @@ +#include "ergodox.h" +#include "debug.h" +#include "action_layer.h" +#include "version.h" + +enum custom_keycodes { + PLACEHOLDER = SAFE_RANGE, // can always be here + RGB_FF0000, + RGB_00FF00, + RGB_0000FF, + RGB_FFFFFF, + RGB_TOGGLE +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +[0] = KEYMAP( + RGB_TOGGLE,RGB_FF0000,RGB_00FF00,RGB_0000FF,RGB_FFFFFF,RGB_TOGGLE,KC_6, + KC_A,KC_Q,KC_W,KC_E,KC_R,KC_T,KC_E,KC_A,KC_A,KC_S,KC_D,KC_F,KC_G,KC_A,KC_Z,KC_X,KC_C,KC_V,KC_B,KC_L,KC_Z,KC_QUOTE,KC_N,KC_U,KC_C,KC_E,KC_8,KC_9,KC_Y,KC_COMMA,KC_6,KC_7,KC_6,KC_7,KC_8,KC_9,KC_0,KC_MINUS,KC_J,KC_Y,KC_U,KC_I,KC_O,KC_P,KC_BSLASH,KC_H,KC_J,KC_K,KC_L,KC_J,KC_K,KC_Z,KC_N,KC_M,KC_COMMA,KC_DOT,KC_E,KC_QUOTE,KC_8,KC_7,KC_LBRACKET,KC_RBRACKET,KC_H,KC_9,KC_7,KC_8,KC_7,KC_6,KC_9), +}; + +const uint16_t PROGMEM fn_actions[] = { + [1] = ACTION_LAYER_TAP_TOGGLE(1) +}; + +const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) +{ + switch(id) { + case 0: + if (record->event.pressed) { + SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION); + } + break; + } + return MACRO_NONE; +}; + + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + // dynamically generate these. + case RGB_FF0000: + if (record->event.pressed) { + #ifdef RGBLIGHT_ENABLE + EZ_RGB(0xff0000); + register_code(KC_A); unregister_code(KC_A); + #endif + } + return false; + break; + case RGB_00FF00: + if (record->event.pressed) { + #ifdef RGBLIGHT_ENABLE + EZ_RGB(0x00ff00); + register_code(KC_B); unregister_code(KC_B); + #endif + } + return false; + break; + case RGB_0000FF: + if (record->event.pressed) { + #ifdef RGBLIGHT_ENABLE + EZ_RGB(0x0000ff); + register_code(KC_C); unregister_code(KC_C); + #endif + } + return false; + break; + case RGB_FFFFFF: + if (record->event.pressed) { + #ifdef RGBLIGHT_ENABLE + EZ_RGB(0xffffff); + register_code(KC_D); unregister_code(KC_D); + #endif + } + return false; + break; + case RGB_TOGGLE: + if (record->event.pressed) { + #ifdef RGBLIGHT_ENABLE + rgblight_toggle(); + register_code(KC_F); unregister_code(KC_F); + #endif + } + return false; + break; + } + return true; +} + +void matrix_scan_user(void) { + + uint8_t layer = biton32(layer_state); + + ergodox_board_led_off(); + ergodox_right_led_1_off(); + ergodox_right_led_2_off(); + ergodox_right_led_3_off(); + switch (layer) { + case 1: + ergodox_right_led_1_on(); + break; + case 2: + ergodox_right_led_2_on(); + break; + case 3: + ergodox_right_led_3_on(); + break; + case 4: + ergodox_right_led_1_on(); + ergodox_right_led_2_on(); + break; + case 5: + ergodox_right_led_1_on(); + ergodox_right_led_3_on(); + break; + case 6: + ergodox_right_led_2_on(); + ergodox_right_led_3_on(); + break; + case 7: + ergodox_right_led_1_on(); + ergodox_right_led_2_on(); + ergodox_right_led_3_on(); + break; + default: + break; + } + +}; diff --git a/keyboards/ergodox/keymaps/robot_test_layout/readme.md b/keyboards/ergodox/keymaps/robot_test_layout/readme.md new file mode 100644 index 0000000000..45dc2aa76c --- /dev/null +++ b/keyboards/ergodox/keymaps/robot_test_layout/readme.md @@ -0,0 +1,5 @@ +# Robot test layout + +Use this layout if you like to pretend you're [Norman](https://www.youtube.com/watch?v=-sbxFBay-tg), the ErgoDox EZ manufacturing robot. + +It's really meant just for internal use, but we're posting it on GitHub anyway, because hurray to open source. :) diff --git a/quantum/rgblight.c b/quantum/rgblight.c index bb03d6e913..625971e0fe 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -425,6 +425,12 @@ void rgblight_timer_toggle(void) { dprintf("TIMER3 toggled.\n"); } +void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b) { + rgblight_enable(); + rgblight_mode(1); + rgblight_setrgb(r, g, b); +} + void rgblight_task(void) { if (rgblight_timer_enabled) { // mode = 1, static light, do nothing here diff --git a/quantum/rgblight.h b/quantum/rgblight.h index 28a410e480..aa1d026e0e 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -84,6 +84,8 @@ void sethsv(uint16_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1); void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1); void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val); +#define EZ_RGB(val) rgblight_show_solid_color((val >> 16) & 0xFF, (val >> 8) & 0xFF, val & 0xFF) +void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b); void rgblight_task(void);