70cbf08b673c2cc59e603503e834ac460040ecc1
- Author
- Nick Brassel <nick@tzarc.org>
- Committer
- GitHub <noreply@github.com>
- Date
Message
Diff
This diff is truncated to protect this page.
1diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk
2index 498614dd2641f47c65492275e115e14aff2e2d91..c1cdd5d8865fe7dccaf854c22d277b1f9d7a8bfd 100644
3--- a/builddefs/common_features.mk
4+++ b/builddefs/common_features.mk
5@@ -881,7 +881,7 @@ ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
6 OPT_DEFS += -DBLUETOOTH_$(strip $(shell echo $(BLUETOOTH_DRIVER) | tr '[:lower:]' '[:upper:]'))
7 NO_USB_STARTUP_CHECK := yes
8 COMMON_VPATH += $(DRIVER_PATH)/bluetooth
9- SRC += outputselect.c
10+ SRC += outputselect.c process_connection.c
11
12 ifeq ($(strip $(BLUETOOTH_DRIVER)), bluefruit_le)
13 SPI_DRIVER_REQUIRED = yes
14diff --git a/data/constants/keycodes/keycodes_0.0.5_connection.hjson b/data/constants/keycodes/keycodes_0.0.5_connection.hjson
15new file mode 100644
16index 0000000000000000000000000000000000000000..9a1a750f1aee67d4c14bf375843a8caf23d63097
17--- /dev/null
18+++ b/data/constants/keycodes/keycodes_0.0.5_connection.hjson
19@@ -0,0 +1,109 @@
20+{
21+ "ranges": {
22+ "0x7780/0x003F": {
23+ "define": "QK_CONNECTION"
24+ }
25+ }
26+ "keycodes": {
27+ "0x7780": {
28+ "group": "connection",
29+ "key": "QK_OUTPUT_NEXT",
30+ "aliases": [
31+ "OU_NEXT",
32+ "OU_AUTO"
33+ ]
34+ },
35+ "0x7781": {
36+ "group": "connection",
37+ "key": "QK_OUTPUT_PREV",
38+ "aliases": [
39+ "OU_PREV"
40+ ]
41+ },
42+ "0x7782": {
43+ "group": "connection",
44+ "key": "QK_OUTPUT_NONE",
45+ "aliases": [
46+ "OU_NONE"
47+ ]
48+ },
49+ "0x7783": {
50+ "group": "connection",
51+ "key": "QK_OUTPUT_USB",
52+ "aliases": [
53+ "OU_USB"
54+ ]
55+ },
56+ "0x7784": {
57+ "group": "connection",
58+ "key": "QK_OUTPUT_2P4GHZ",
59+ "aliases": [
60+ "OU_2P4G"
61+ ]
62+ },
63+ "0x7785": {
64+ "group": "connection",
65+ "key": "QK_OUTPUT_BLUETOOTH",
66+ "aliases": [
67+ "OU_BT"
68+ ]
69+ },
70+
71+ "0x7790": {
72+ "group": "connection",
73+ "key": "QK_BLUETOOTH_PROFILE_NEXT",
74+ "aliases": [
75+ "BT_NEXT"
76+ ]
77+ },
78+ "0x7791": {
79+ "group": "connection",
80+ "key": "QK_BLUETOOTH_PROFILE_PREV",
81+ "aliases": [
82+ "BT_PREV"
83+ ]
84+ },
85+ "0x7792": {
86+ "group": "connection",
87+ "key": "QK_BLUETOOTH_UNPAIR",
88+ "aliases": [
89+ "BT_UNPR"
90+ ]
91+ }
92+ "0x7793": {
93+ "group": "connection",
94+ "key": "QK_BLUETOOTH_PROFILE1",
95+ "aliases": [
96+ "BT_PRF1"
97+ ]
98+ },
99+ "0x7794": {
100+ "group": "connection",
101+ "key": "QK_BLUETOOTH_PROFILE2",
102+ "aliases": [
103+ "BT_PRF2"
104+ ]
105+ },
106+ "0x7795": {
107+ "group": "connection",
108+ "key": "QK_BLUETOOTH_PROFILE3",
109+ "aliases": [
110+ "BT_PRF3"
111+ ]
112+ },
113+ "0x7796": {
114+ "group": "connection",
115+ "key": "QK_BLUETOOTH_PROFILE4",
116+ "aliases": [
117+ "BT_PRF4"
118+ ]
119diff --git a/data/constants/keycodes/keycodes_0.0.5_quantum.hjson b/data/constants/keycodes/keycodes_0.0.5_quantum.hjson
120new file mode 100644
121index 0000000000000000000000000000000000000000..814cd66a5b127bd5441535eee2c6faa8f2de6318
122--- /dev/null
123+++ b/data/constants/keycodes/keycodes_0.0.5_quantum.hjson
124@@ -0,0 +1,7 @@
125+{
126+ "keycodes": {
127+ "0x7C20": "!delete!", // old QK_OUTPUT_AUTO
128+ "0x7C21": "!delete!", // old QK_OUTPUT_USB
129+ "0x7C22": "!delete!", // old QK_OUTPUT_BLUETOOTH
130+ }
131+}
132diff --git a/docs/features/bluetooth.md b/docs/features/bluetooth.md
133index 1dbf15f4e104bff87eb1e93f593c6a3a5c7afbb7..d3634498be4e34980ba430d5e41bddaa20b63279 100644
134--- a/docs/features/bluetooth.md
135+++ b/docs/features/bluetooth.md
136@@ -39,8 +39,8 @@ BLUETOOTH_DRIVER = bluefruit_le # or rn42
137
138 This is used when multiple keyboard outputs can be selected. Currently this only allows for switching between USB and Bluetooth on keyboards that support both.
139
140-|Key |Aliases |Description |
141-|---------------------|---------|----------------------------------------------|
142-|`QK_OUTPUT_AUTO` |`OU_AUTO`|Automatically switch between USB and Bluetooth|
143-|`QK_OUTPUT_USB` |`OU_USB` |USB only |
144-|`QK_OUTPUT_BLUETOOTH`|`OU_BT` |Bluetooth only |
145+| Key | Aliases | Description |
146+|-----------------------|----------------------|------------------------------------------------|
147+| `QK_OUTPUT_NEXT` | `OU_NEXT`, `OU_AUTO` | Automatically switch between USB and Bluetooth |
148+| `QK_OUTPUT_USB` | `OU_USB` | USB only |
149+| `QK_OUTPUT_BLUETOOTH` | `OU_BT` | Bluetooth only |
150diff --git a/docs/keycodes.md b/docs/keycodes.md
151index 9038c2b6d739d1ea199a5d35d4da7d8e4e30deda..9107ca5eb88da2348765af365371e1ba825efd2b 100644
152--- a/docs/keycodes.md
153+++ b/docs/keycodes.md
154@@ -294,11 +294,11 @@ See also: [Backlighting](features/backlight)
155
156 See also: [Bluetooth](features/bluetooth)
157
158-|Key |Aliases |Description |
159-|---------------------|---------|----------------------------------------------|
160-|`QK_OUTPUT_AUTO` |`OU_AUTO`|Automatically switch between USB and Bluetooth|
161-|`QK_OUTPUT_USB` |`OU_USB` |USB only |
162-|`QK_OUTPUT_BLUETOOTH`|`OU_BT` |Bluetooth only |
163+| Key | Aliases | Description |
164+|-----------------------|----------------------|------------------------------------------------|
165+| `QK_OUTPUT_NEXT` | `OU_NEXT`, `OU_AUTO` | Automatically switch between USB and Bluetooth |
166+| `QK_OUTPUT_USB` | `OU_USB` | USB only |
167+| `QK_OUTPUT_BLUETOOTH` | `OU_BT` | Bluetooth only |
168
169 ## Caps Word {#caps-word}
170
171diff --git a/quantum/keycodes.h b/quantum/keycodes.h
172index f461e4a586e22caebfecd28143e12ce7c1d60e21..38127bb6da1fd86b393daf086a024db24ff9d7a5 100644
173--- a/quantum/keycodes.h
174+++ b/quantum/keycodes.h
175@@ -72,6 +72,8 @@ enum qk_keycode_ranges {
176 QK_STENO_MAX = 0x74FF,
177 QK_MACRO = 0x7700,
178 QK_MACRO_MAX = 0x777F,
179+ QK_CONNECTION = 0x7780,
180+ QK_CONNECTION_MAX = 0x77BF,
181 QK_LIGHTING = 0x7800,
182 QK_LIGHTING_MAX = 0x78FF,
183 QK_QUANTUM = 0x7C00,
184@@ -620,6 +622,20 @@ enum qk_keycode_defines {
185 QK_MACRO_29 = 0x771D,
186 QK_MACRO_30 = 0x771E,
187 QK_MACRO_31 = 0x771F,
188+ QK_OUTPUT_NEXT = 0x7780,
189+ QK_OUTPUT_PREV = 0x7781,
190+ QK_OUTPUT_NONE = 0x7782,
191+ QK_OUTPUT_USB = 0x7783,
192+ QK_OUTPUT_2P4GHZ = 0x7784,
193+ QK_OUTPUT_BLUETOOTH = 0x7785,
194+ QK_BLUETOOTH_PROFILE_NEXT = 0x7790,
195+ QK_BLUETOOTH_PROFILE_PREV = 0x7791,
196+ QK_BLUETOOTH_UNPAIR = 0x7792,
197+ QK_BLUETOOTH_PROFILE1 = 0x7793,
198+ QK_BLUETOOTH_PROFILE2 = 0x7794,
199+ QK_BLUETOOTH_PROFILE3 = 0x7795,
200+ QK_BLUETOOTH_PROFILE4 = 0x7796,
201+ QK_BLUETOOTH_PROFILE5 = 0x7797,
202 QK_BACKLIGHT_ON = 0x7800,
203 QK_BACKLIGHT_OFF = 0x7801,
204 QK_BACKLIGHT_TOGGLE = 0x7802,
205@@ -690,9 +706,6 @@ enum qk_keycode_defines {
206 QK_SPACE_CADET_LEFT_ALT_PARENTHESIS_OPEN = 0x7C1C,
207 QK_SPACE_CADET_RIGHT_ALT_PARENTHESIS_CLOSE = 0x7C1D,
208 QK_SPACE_CADET_RIGHT_SHIFT_ENTER = 0x7C1E,
209- QK_OUTPUT_AUTO = 0x7C20,
210- QK_OUTPUT_USB = 0x7C21,
211- QK_OUTPUT_BLUETOOTH = 0x7C22,
212 QK_UNICODE_MODE_NEXT = 0x7C30,
213 QK_UNICODE_MODE_PREVIOUS = 0x7C31,
214 QK_UNICODE_MODE_MACOS = 0x7C32,
215@@ -1296,6 +1309,21 @@ enum qk_keycode_defines {
216 MC_29 = QK_MACRO_29,
217 MC_30 = QK_MACRO_30,
218 MC_31 = QK_MACRO_31,
219+ OU_NEXT = QK_OUTPUT_NEXT,
220+ OU_AUTO = QK_OUTPUT_NEXT,
221+ OU_PREV = QK_OUTPUT_PREV,
222+ OU_NONE = QK_OUTPUT_NONE,
223+ OU_USB = QK_OUTPUT_USB,
224+ OU_2P4G = QK_OUTPUT_2P4GHZ,
225+ OU_BT = QK_OUTPUT_BLUETOOTH,
226+ BT_NEXT = QK_BLUETOOTH_PROFILE_NEXT,
227+ BT_PREV = QK_BLUETOOTH_PROFILE_PREV,
228+ BT_UNPR = QK_BLUETOOTH_UNPAIR,
229+ BT_PRF1 = QK_BLUETOOTH_PROFILE1,
230+ BT_PRF2 = QK_BLUETOOTH_PROFILE2,
231+ BT_PRF3 = QK_BLUETOOTH_PROFILE3,
232+ BT_PRF4 = QK_BLUETOOTH_PROFILE4,
233+ BT_PRF5 = QK_BLUETOOTH_PROFILE5,
234 BL_ON = QK_BACKLIGHT_ON,
235 BL_OFF = QK_BACKLIGHT_OFF,
236 BL_TOGG = QK_BACKLIGHT_TOGGLE,
237@@ -1365,9 +1393,6 @@ enum qk_keycode_defines {
238 SC_LAPO = QK_SPACE_CADET_LEFT_ALT_PARENTHESIS_OPEN,
239 SC_RAPC = QK_SPACE_CADET_RIGHT_ALT_PARENTHESIS_CLOSE,
240 SC_SENT = QK_SPACE_CADET_RIGHT_SHIFT_ENTER,
241- OU_AUTO = QK_OUTPUT_AUTO,
242- OU_USB = QK_OUTPUT_USB,
243- OU_BT = QK_OUTPUT_BLUETOOTH,
244 UC_NEXT = QK_UNICODE_MODE_NEXT,
245 UC_PREV = QK_UNICODE_MODE_PREVIOUS,
246 UC_MAC = QK_UNICODE_MODE_MACOS,
247@@ -1444,6 +1469,7 @@ enum qk_keycode_defines {
248 #define IS_QK_AUDIO(code) ((code) >= QK_AUDIO && (code) <= QK_AUDIO_MAX)
249 #define IS_QK_STENO(code) ((code) >= QK_STENO && (code) <= QK_STENO_MAX)
250 #define IS_QK_MACRO(code) ((code) >= QK_MACRO && (code) <= QK_MACRO_MAX)
251+#define IS_QK_CONNECTION(code) ((code) >= QK_CONNECTION && (code) <= QK_CONNECTION_MAX)
252 #define IS_QK_LIGHTING(code) ((code) >= QK_LIGHTING && (code) <= QK_LIGHTING_MAX)
253 #define IS_QK_QUANTUM(code) ((code) >= QK_QUANTUM && (code) <= QK_QUANTUM_MAX)
254 #define IS_QK_KB(code) ((code) >= QK_KB && (code) <= QK_KB_MAX)
255@@ -1468,6 +1494,7 @@ enum qk_keycode_defines {
256 #define IS_AUDIO_KEYCODE(code) ((code) >= QK_AUDIO_ON && (code) <= QK_AUDIO_VOICE_PREVIOUS)
257 #define IS_STENO_KEYCODE(code) ((code) >= QK_STENO_BOLT && (code) <= QK_STENO_COMB_MAX)
258 #define IS_MACRO_KEYCODE(code) ((code) >= QK_MACRO_0 && (code) <= QK_MACRO_31)
259+#define IS_CONNECTION_KEYCODE(code) ((code) >= QK_OUTPUT_NEXT && (code) <= QK_BLUETOOTH_PROFILE5)
260 #define IS_BACKLIGHT_KEYCODE(code) ((code) >= QK_BACKLIGHT_ON && (code) <= QK_BACKLIGHT_TOGGLE_BREATHING)
261 #define IS_LED_MATRIX_KEYCODE(code) ((code) >= QK_LED_MATRIX_ON && (code) <= QK_LED_MATRIX_SPEED_DOWN)
262 #define IS_UNDERGLOW_KEYCODE(code) ((code) >= QK_UNDERGLOW_TOGGLE && (code) <= QK_UNDERGLOW_SPEED_DOWN)
263@@ -1493,6 +1520,7 @@ enum qk_keycode_defines {
264 #define AUDIO_KEYCODE_RANGE QK_AUDIO_ON ... QK_AUDIO_VOICE_PREVIOUS
265 #define STENO_KEYCODE_RANGE QK_STENO_BOLT ... QK_STENO_COMB_MAX
266 #define MACRO_KEYCODE_RANGE QK_MACRO_0 ... QK_MACRO_31
267+#define CONNECTION_KEYCODE_RANGE QK_OUTPUT_NEXT ... QK_BLUETOOTH_PROFILE5
268 #define BACKLIGHT_KEYCODE_RANGE QK_BACKLIGHT_ON ... QK_BACKLIGHT_TOGGLE_BREATHING
269 #define LED_MATRIX_KEYCODE_RANGE QK_LED_MATRIX_ON ... QK_LED_MATRIX_SPEED_DOWN
270 #define UNDERGLOW_KEYCODE_RANGE QK_UNDERGLOW_TOGGLE ... QK_UNDERGLOW_SPEED_DOWN
271diff --git a/quantum/process_keycode/process_connection.c b/quantum/process_keycode/process_connection.c
272new file mode 100644
273index 0000000000000000000000000000000000000000..b0e230d680a146bb3c2fd597d46b64baae74da12
274--- /dev/null
275+++ b/quantum/process_keycode/process_connection.c
276@@ -0,0 +1,36 @@
277+// Copyright 2024 Nick Brassel (@tzarc)
278+// SPDX-License-Identifier: GPL-2.0-or-later
279+#include "outputselect.h"
280+#include "process_connection.h"
281+
282+bool process_connection(uint16_t keycode, keyrecord_t *record) {
283+ if (record->event.pressed) {
284+ switch (keycode) {
285+ case QK_OUTPUT_NEXT:
286+ set_output(OUTPUT_AUTO); // This should cycle through the outputs going forward. Ensure `docs/keycodes.md`, `docs/features/bluetooth.md` are updated when it does.
287+ return false;
288+ case QK_OUTPUT_USB:
289+ set_output(OUTPUT_USB);
290+ return false;
291+ case QK_OUTPUT_BLUETOOTH:
292+ set_output(OUTPUT_BLUETOOTH);
293+ return false;
294+
295+ case QK_OUTPUT_PREV:
296+ case QK_OUTPUT_NONE:
297+ case QK_OUTPUT_2P4GHZ:
298+ case QK_BLUETOOTH_PROFILE_NEXT:
299+ case QK_BLUETOOTH_PROFILE_PREV:
300+ case QK_BLUETOOTH_UNPAIR:
301+ case QK_BLUETOOTH_PROFILE1:
302+ case QK_BLUETOOTH_PROFILE2:
303+ case QK_BLUETOOTH_PROFILE3:
304+ case QK_BLUETOOTH_PROFILE4:
305+ case QK_BLUETOOTH_PROFILE5:
306+ // As-yet unimplemented.
307+ // When implementation is done, ensure `docs/keycodes.md`, `docs/features/bluetooth.md` are updated accordingly.
308+ return false;
309+ }
310+ }
311+ return true;
312+}
313diff --git a/quantum/process_keycode/process_connection.h b/quantum/process_keycode/process_connection.h
314new file mode 100644
315index 0000000000000000000000000000000000000000..cc58011bb766a2f3ed0ccb609257c4be369af962
316--- /dev/null
317+++ b/quantum/process_keycode/process_connection.h
318@@ -0,0 +1,9 @@
319+// Copyright 2024 Nick Brassel (@tzarc)
320+// SPDX-License-Identifier: GPL-2.0-or-later
321+#pragma once
322+
323+#include <stdint.h>
324+#include <stdbool.h>
325+#include "action.h"
326+
327+bool process_connection(uint16_t keycode, keyrecord_t *record);
328diff --git a/quantum/quantum.c b/quantum/quantum.c
329index b21d6f1a3d13495d00ecbeb65115ef76d9b1eca2..db323e31c9883686868fe9e3b920f12ce07ea3aa 100644
330--- a/quantum/quantum.c
331+++ b/quantum/quantum.c
332@@ -21,7 +21,7 @@
333 #endif
334
335 #ifdef BLUETOOTH_ENABLE
336-# include "outputselect.h"
337+# include "process_connection.h"
338 #endif
339
340 #ifdef GRAVE_ESC_ENABLE
341@@ -392,6 +392,9 @@ bool process_record_quantum(keyrecord_t *record) {
342 #endif
343 #ifdef TRI_LAYER_ENABLE
344 process_tri_layer(keycode, record) &&
345+#endif
346+#ifdef BLUETOOTH_ENABLE
347+ process_connection(keycode, record) &&
348 #endif
349 true)) {
350 return false;
351@@ -430,17 +433,6 @@ bool process_record_quantum(keyrecord_t *record) {
352 velocikey_toggle();
353 return false;
354 #endif
355-#ifdef BLUETOOTH_ENABLE
356- case QK_OUTPUT_AUTO:
357- set_output(OUTPUT_AUTO);
358- return false;
359- case QK_OUTPUT_USB:
360- set_output(OUTPUT_USB);
361- return false;
362- case QK_OUTPUT_BLUETOOTH:
363- set_output(OUTPUT_BLUETOOTH);
364- return false;
365-#endif
366 #ifndef NO_ACTION_ONESHOT
367 case QK_ONE_SHOT_TOGGLE:
368 oneshot_toggle();
369diff --git a/quantum/quantum_keycodes_legacy.h b/quantum/quantum_keycodes_legacy.h
370index e1562077e5f3cd714ca3bec79692a5c539d731e3..21aec90675a12a52ef10d64affa531bd701e9bca 100644
371--- a/quantum/quantum_keycodes_legacy.h
372+++ b/quantum/quantum_keycodes_legacy.h
373@@ -55,3 +55,5 @@
374 #define KC_ACL1 QK_MOUSE_ACCELERATION_1
375 #define KC_MS_ACCEL2 QK_MOUSE_ACCELERATION_2
376 #define KC_ACL2 QK_MOUSE_ACCELERATION_2
377+
378+#define QK_OUTPUT_AUTO OU_AUTO
379diff --git a/tests/test_common/keycode_table.cpp b/tests/test_common/keycode_table.cpp
380index 4c28ab4d20dd514530bd202d908922147ef674a7..e4d445de82805374c212c6bc53b4fdfe822e2f80 100644
381--- a/tests/test_common/keycode_table.cpp
382+++ b/tests/test_common/keycode_table.cpp
383@@ -562,6 +562,20 @@ std::map<uint16_t, std::string> KEYCODE_ID_TABLE = {
384 {QK_MACRO_29, "QK_MACRO_29"},
385 {QK_MACRO_30, "QK_MACRO_30"},
386 {QK_MACRO_31, "QK_MACRO_31"},
387+ {QK_OUTPUT_NEXT, "QK_OUTPUT_NEXT"},
388+ {QK_OUTPUT_PREV, "QK_OUTPUT_PREV"},
389+ {QK_OUTPUT_NONE, "QK_OUTPUT_NONE"},
390+ {QK_OUTPUT_USB, "QK_OUTPUT_USB"},
391+ {QK_OUTPUT_2P4GHZ, "QK_OUTPUT_2P4GHZ"},
392+ {QK_OUTPUT_BLUETOOTH, "QK_OUTPUT_BLUETOOTH"},
393+ {QK_BLUETOOTH_PROFILE_NEXT, "QK_BLUETOOTH_PROFILE_NEXT"},
394+ {QK_BLUETOOTH_PROFILE_PREV, "QK_BLUETOOTH_PROFILE_PREV"},
395+ {QK_BLUETOOTH_UNPAIR, "QK_BLUETOOTH_UNPAIR"},
396+ {QK_BLUETOOTH_PROFILE1, "QK_BLUETOOTH_PROFILE1"},
397+ {QK_BLUETOOTH_PROFILE2, "QK_BLUETOOTH_PROFILE2"},
398+ {QK_BLUETOOTH_PROFILE3, "QK_BLUETOOTH_PROFILE3"},
399+ {QK_BLUETOOTH_PROFILE4, "QK_BLUETOOTH_PROFILE4"},
400+ {QK_BLUETOOTH_PROFILE5, "QK_BLUETOOTH_PROFILE5"},
401 {QK_BACKLIGHT_ON, "QK_BACKLIGHT_ON"},
402 {QK_BACKLIGHT_OFF, "QK_BACKLIGHT_OFF"},
403 {QK_BACKLIGHT_TOGGLE, "QK_BACKLIGHT_TOGGLE"},
404@@ -632,9 +646,6 @@ std::map<uint16_t, std::string> KEYCODE_ID_TABLE = {
405 {QK_SPACE_CADET_LEFT_ALT_PARENTHESIS_OPEN, "QK_SPACE_CADET_LEFT_ALT_PARENTHESIS_OPEN"},
406 {QK_SPACE_CADET_RIGHT_ALT_PARENTHESIS_CLOSE, "QK_SPACE_CADET_RIGHT_ALT_PARENTHESIS_CLOSE"},
407 {QK_SPACE_CADET_RIGHT_SHIFT_ENTER, "QK_SPACE_CADET_RIGHT_SHIFT_ENTER"},
408- {QK_OUTPUT_AUTO, "QK_OUTPUT_AUTO"},
409- {QK_OUTPUT_USB, "QK_OUTPUT_USB"},
410- {QK_OUTPUT_BLUETOOTH, "QK_OUTPUT_BLUETOOTH"},
411 {QK_UNICODE_MODE_NEXT, "QK_UNICODE_MODE_NEXT"},
412 {QK_UNICODE_MODE_PREVIOUS, "QK_UNICODE_MODE_PREVIOUS"},
413 {QK_UNICODE_MODE_MACOS, "QK_UNICODE_MODE_MACOS"},