pake-cli 2.3.6 → 2.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +78 -52
- package/dist/cli.js +17 -26
- package/package.json +13 -13
- package/src-tauri/Cargo.lock +1344 -721
- package/src-tauri/Cargo.toml +2 -1
- package/src-tauri/icons/devv.icns +0 -0
- package/src-tauri/icons/juchats.icns +0 -0
- package/src-tauri/pake.json +0 -5
- package/src-tauri/src/app/config.rs +0 -6
- package/src-tauri/src/app/menu.rs +10 -94
- package/src-tauri/src/inject/component.js +0 -128
- package/src-tauri/src/inject/event.js +7 -4
- package/src-tauri/src/inject/style.js +14 -4
- package/src-tauri/src/main.rs +12 -21
- package/src-tauri/tauri.conf.json +1 -1
package/src-tauri/Cargo.toml
CHANGED
|
@@ -19,6 +19,7 @@ serde_json = "1.0.108"
|
|
|
19
19
|
serde = { version = "1.0.192", features = ["derive"] }
|
|
20
20
|
tauri = { version = "1.5.2", features = ["api-all", "system-tray"] }
|
|
21
21
|
tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
|
|
22
|
+
tauri-plugin-oauth = { git = "https://github.com/FabianLars/tauri-plugin-oauth", branch = "main" }
|
|
22
23
|
|
|
23
24
|
[dev-dependencies]
|
|
24
25
|
cargo-bloat = "0.11.1"
|
|
@@ -29,6 +30,6 @@ cli-build = []
|
|
|
29
30
|
# by default Tauri runs in production mode
|
|
30
31
|
# when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL
|
|
31
32
|
default = ["custom-protocol"]
|
|
32
|
-
# this feature is used
|
|
33
|
+
# this feature is used for production builds where `devPath` points to the filesystem
|
|
33
34
|
# DO NOT remove this
|
|
34
35
|
custom-protocol = ["tauri/custom-protocol"]
|
|
Binary file
|
|
Binary file
|
package/src-tauri/pake.json
CHANGED
|
@@ -15,11 +15,6 @@
|
|
|
15
15
|
"linux": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
|
|
16
16
|
"windows": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
|
|
17
17
|
},
|
|
18
|
-
"menu": {
|
|
19
|
-
"macos": false,
|
|
20
|
-
"linux": false,
|
|
21
|
-
"windows": false
|
|
22
|
-
},
|
|
23
18
|
"system_tray": {
|
|
24
19
|
"macos": false,
|
|
25
20
|
"linux": true,
|
|
@@ -47,16 +47,10 @@ pub type FunctionON = PlatformSpecific<bool>;
|
|
|
47
47
|
pub struct PakeConfig {
|
|
48
48
|
pub windows: Vec<WindowConfig>,
|
|
49
49
|
pub user_agent: UserAgent,
|
|
50
|
-
pub menu: FunctionON,
|
|
51
50
|
pub system_tray: FunctionON,
|
|
52
51
|
}
|
|
53
52
|
|
|
54
53
|
impl PakeConfig {
|
|
55
|
-
pub fn show_menu(&self) -> bool {
|
|
56
|
-
self.menu.copied()
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
#[cfg(not(target_os = "macos"))]
|
|
60
54
|
pub fn show_system_tray(&self) -> bool {
|
|
61
55
|
self.system_tray.copied()
|
|
62
56
|
}
|
|
@@ -1,114 +1,30 @@
|
|
|
1
|
-
use tauri::
|
|
2
|
-
|
|
3
|
-
use tauri::{CustomMenuItem, Menu, Submenu, WindowMenuEvent};
|
|
4
|
-
|
|
5
|
-
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
|
6
|
-
use tauri::{Manager, SystemTray, SystemTrayEvent, SystemTrayMenu};
|
|
7
|
-
|
|
8
|
-
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
|
1
|
+
use tauri::{CustomMenuItem,Manager, SystemTray, SystemTrayEvent, SystemTrayMenu};
|
|
9
2
|
use tauri_plugin_window_state::{AppHandleExt, StateFlags};
|
|
10
3
|
|
|
11
|
-
pub fn
|
|
12
|
-
let
|
|
13
|
-
let
|
|
14
|
-
.accelerator("CmdOrCtrl+Shift+L");
|
|
15
|
-
let first_menu = Menu::new()
|
|
16
|
-
.add_native_item(MenuItem::Copy)
|
|
17
|
-
.add_native_item(MenuItem::Cut)
|
|
18
|
-
.add_native_item(MenuItem::Paste)
|
|
19
|
-
.add_native_item(MenuItem::Undo)
|
|
20
|
-
.add_native_item(MenuItem::Redo)
|
|
21
|
-
.add_native_item(MenuItem::SelectAll)
|
|
22
|
-
.add_native_item(MenuItem::Separator)
|
|
23
|
-
.add_item(goto_url_item)
|
|
24
|
-
.add_native_item(MenuItem::Separator)
|
|
25
|
-
.add_native_item(MenuItem::EnterFullScreen)
|
|
26
|
-
.add_native_item(MenuItem::Minimize)
|
|
27
|
-
.add_native_item(MenuItem::Hide)
|
|
28
|
-
.add_native_item(MenuItem::HideOthers)
|
|
29
|
-
.add_native_item(MenuItem::ShowAll)
|
|
30
|
-
.add_native_item(MenuItem::Separator)
|
|
31
|
-
.add_item(close)
|
|
32
|
-
.add_native_item(MenuItem::Quit);
|
|
33
|
-
|
|
34
|
-
let app_menu = Submenu::new("File", first_menu);
|
|
35
|
-
Menu::new().add_submenu(app_menu)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
pub fn menu_event_handle(event: WindowMenuEvent) {
|
|
39
|
-
if event.menu_item_id() == "close" {
|
|
40
|
-
event.window().minimize().expect("can't minimize window");
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if event.menu_item_id() == "goto_url" {
|
|
44
|
-
let js_code = "showUrlModal();";
|
|
45
|
-
event.window().eval(js_code).unwrap();
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
|
50
|
-
pub fn get_system_tray(show_menu: bool) -> SystemTray {
|
|
51
|
-
let hide_app = CustomMenuItem::new("hide_app".to_string(), "Hide App");
|
|
52
|
-
let show_app = CustomMenuItem::new("show_app".to_string(), "Show App");
|
|
4
|
+
pub fn get_system_tray() -> SystemTray {
|
|
5
|
+
let hide_app = CustomMenuItem::new("hide_app".to_string(), "Hide");
|
|
6
|
+
let show_app = CustomMenuItem::new("show_app".to_string(), "Show");
|
|
53
7
|
let quit = CustomMenuItem::new("quit".to_string(), "Quit");
|
|
54
|
-
let
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
let tray_menu = tray_menu
|
|
60
|
-
.add_item(hide_menu)
|
|
61
|
-
.add_item(show_menu)
|
|
62
|
-
.add_item(quit)
|
|
63
|
-
.add_item(about);
|
|
64
|
-
SystemTray::new().with_menu(tray_menu)
|
|
65
|
-
} else {
|
|
66
|
-
let tray_menu = tray_menu.add_item(quit).add_item(about);
|
|
67
|
-
SystemTray::new().with_menu(tray_menu)
|
|
68
|
-
}
|
|
8
|
+
let tray_menu = SystemTrayMenu::new()
|
|
9
|
+
.add_item(show_app)
|
|
10
|
+
.add_item(hide_app)
|
|
11
|
+
.add_item(quit);
|
|
12
|
+
SystemTray::new().with_menu(tray_menu)
|
|
69
13
|
}
|
|
70
14
|
|
|
71
|
-
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
|
72
15
|
pub fn system_tray_handle(app: &tauri::AppHandle, event: SystemTrayEvent) {
|
|
73
16
|
if let SystemTrayEvent::MenuItemClick { tray_id: _, id, .. } = event {
|
|
74
17
|
match id.as_str() {
|
|
75
18
|
"hide_app" => {
|
|
76
|
-
app.get_window("pake").unwrap().
|
|
19
|
+
app.get_window("pake").unwrap().minimize().unwrap();
|
|
77
20
|
}
|
|
78
21
|
"show_app" => {
|
|
79
22
|
app.get_window("pake").unwrap().show().unwrap();
|
|
80
23
|
}
|
|
81
|
-
"hide_menu" => {
|
|
82
|
-
app.get_window("pake")
|
|
83
|
-
.unwrap()
|
|
84
|
-
.menu_handle()
|
|
85
|
-
.hide()
|
|
86
|
-
.unwrap();
|
|
87
|
-
}
|
|
88
|
-
"show_menu" => {
|
|
89
|
-
app.get_window("pake")
|
|
90
|
-
.unwrap()
|
|
91
|
-
.menu_handle()
|
|
92
|
-
.show()
|
|
93
|
-
.unwrap();
|
|
94
|
-
}
|
|
95
24
|
"quit" => {
|
|
96
25
|
let _res = app.save_window_state(StateFlags::all());
|
|
97
26
|
std::process::exit(0);
|
|
98
27
|
}
|
|
99
|
-
// ignore about for now, because about_pake.html have be erased.
|
|
100
|
-
// "about" => {
|
|
101
|
-
// let _about_window = WindowBuilder::new(
|
|
102
|
-
// app,
|
|
103
|
-
// "about",
|
|
104
|
-
// WindowUrl::App(std::path::PathBuf::from("about_pake.html")),
|
|
105
|
-
// )
|
|
106
|
-
// .resizable(true)
|
|
107
|
-
// .title("About")
|
|
108
|
-
// .inner_size(600.0, 400.0)
|
|
109
|
-
// .build()
|
|
110
|
-
// .expect("can't open about!");
|
|
111
|
-
// }
|
|
112
28
|
_ => {}
|
|
113
29
|
}
|
|
114
30
|
};
|
|
@@ -1,132 +1,4 @@
|
|
|
1
1
|
document.addEventListener('DOMContentLoaded', () => {
|
|
2
|
-
// Create a modal
|
|
3
|
-
const modalHtml = `
|
|
4
|
-
<div id="pakeUrlModal" class="pake-modal">
|
|
5
|
-
<div class="pake-modal-container">
|
|
6
|
-
<div class="pake-modal-content">
|
|
7
|
-
<label for="pakeUrlInput">Enter URL to navigate anywhere</label>
|
|
8
|
-
<input type="text" id="pakeUrlInput" />
|
|
9
|
-
<button id="pakeUrlSubmit">Submit</button>
|
|
10
|
-
<button id="pakeUrlClose">Close</button>
|
|
11
|
-
</div>
|
|
12
|
-
</div>
|
|
13
|
-
</div>
|
|
14
|
-
`;
|
|
15
|
-
|
|
16
|
-
const modalStyle = `
|
|
17
|
-
.pake-modal {
|
|
18
|
-
display: none;
|
|
19
|
-
position: fixed;
|
|
20
|
-
z-index: 1000;
|
|
21
|
-
left: 0;
|
|
22
|
-
top: 0;
|
|
23
|
-
width: 100%;
|
|
24
|
-
height: 100%;
|
|
25
|
-
background-color: rgba(0, 0, 0, 0.4);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
.pake-modal-container {
|
|
29
|
-
display: flex;
|
|
30
|
-
align-items: center;
|
|
31
|
-
justify-content: center;
|
|
32
|
-
width: 100%;
|
|
33
|
-
height: 100%;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
.pake-modal-content {
|
|
37
|
-
background-color: #fff;
|
|
38
|
-
padding: 20px;
|
|
39
|
-
border-radius: 10px;
|
|
40
|
-
width: 80%;
|
|
41
|
-
max-width: 400px;
|
|
42
|
-
font-size:14px;
|
|
43
|
-
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
.pake-modal-content label {
|
|
47
|
-
display: block;
|
|
48
|
-
color: #11182B;
|
|
49
|
-
margin-bottom: 12px;
|
|
50
|
-
font-weight: bold;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
.pake-modal-content input[type="text"] {
|
|
54
|
-
width: 90%;
|
|
55
|
-
padding: 8px;
|
|
56
|
-
border: 1px solid #ccc;
|
|
57
|
-
border-radius: 4px;
|
|
58
|
-
font-size: 14px;
|
|
59
|
-
margin-bottom: 12px;
|
|
60
|
-
outline: none;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
.pake-modal-content button {
|
|
64
|
-
background: #11182B;
|
|
65
|
-
color: #FFF;
|
|
66
|
-
padding: 6px 14px;
|
|
67
|
-
border-radius: 4px;
|
|
68
|
-
cursor: pointer;
|
|
69
|
-
margin-right: 4px;
|
|
70
|
-
font-size:14px;
|
|
71
|
-
border: 1px solid #11182B;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
#pakeUrlClose{
|
|
75
|
-
background: #fff;
|
|
76
|
-
color: #11182B;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
#pakeUrlInput {
|
|
80
|
-
min-width: 320px;
|
|
81
|
-
text-align: left;
|
|
82
|
-
min-height: 30px;
|
|
83
|
-
}
|
|
84
|
-
`;
|
|
85
|
-
|
|
86
|
-
const modalDiv = document.createElement('div');
|
|
87
|
-
modalDiv.innerHTML = modalHtml;
|
|
88
|
-
document.body.appendChild(modalDiv);
|
|
89
|
-
|
|
90
|
-
const modalStyleElement = document.createElement('style');
|
|
91
|
-
modalStyleElement.innerText = modalStyle;
|
|
92
|
-
document.head.appendChild(modalStyleElement);
|
|
93
|
-
|
|
94
|
-
const urlModal = document.getElementById('pakeUrlModal');
|
|
95
|
-
const urlInput = document.getElementById('pakeUrlInput');
|
|
96
|
-
const urlSubmit = document.getElementById('pakeUrlSubmit');
|
|
97
|
-
const urlClose = document.getElementById('pakeUrlClose');
|
|
98
|
-
|
|
99
|
-
urlSubmit.onclick = function() {
|
|
100
|
-
const url = urlInput.value;
|
|
101
|
-
if (url) {
|
|
102
|
-
window.location.href = url;
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
urlClose.onclick = function() {
|
|
107
|
-
urlModal.style.display = 'none';
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
urlInput.addEventListener('keydown', function(event) {
|
|
111
|
-
if (event.key === 'Enter') {
|
|
112
|
-
const url = urlInput.value;
|
|
113
|
-
if (url) {
|
|
114
|
-
window.location.href = url;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
document.addEventListener('keydown', function(event) {
|
|
120
|
-
if (event.key === 'Escape' && urlModal.style.display === 'block') {
|
|
121
|
-
urlModal.style.display = 'none';
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
window.showUrlModal = function() {
|
|
126
|
-
urlModal.style.display = 'block';
|
|
127
|
-
urlInput.focus();
|
|
128
|
-
};
|
|
129
|
-
|
|
130
2
|
// Toast
|
|
131
3
|
function pakeToast(msg) {
|
|
132
4
|
const m = document.createElement('div');
|
|
@@ -63,10 +63,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
63
63
|
const appWindow = tauri.window.appWindow;
|
|
64
64
|
const invoke = tauri.tauri.invoke;
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
if(!document.getElementById('pake-top-dom')){
|
|
67
|
+
const topDom = document.createElement('div');
|
|
68
|
+
topDom.id = 'pake-top-dom';
|
|
69
|
+
document.body.appendChild(topDom);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const domEl = document.getElementById('pake-top-dom');
|
|
70
73
|
|
|
71
74
|
domEl.addEventListener('touchstart', () => {
|
|
72
75
|
appWindow.startDragging().then();
|
|
@@ -312,7 +312,7 @@ window.addEventListener('DOMContentLoaded', _event => {
|
|
|
312
312
|
}
|
|
313
313
|
|
|
314
314
|
#__next .overflow-hidden>.overflow-x-hidden .scrollbar-trigger > nav {
|
|
315
|
-
padding-top:
|
|
315
|
+
padding-top: 12px;
|
|
316
316
|
}
|
|
317
317
|
|
|
318
318
|
#__next > div.relative.z-0.flex.h-full.w-full.overflow-hidden > div.relative.flex.h-full.max-w-full.flex-1.flex-col.overflow-hidden > main > div.flex.h-full.flex-col > div.flex-1.overflow-hidden > div > div.absolute.left-0.right-0 > div > div.flex.items-center.gap-2 > button{
|
|
@@ -320,6 +320,16 @@ window.addEventListener('DOMContentLoaded', _event => {
|
|
|
320
320
|
margin-right: -10px;
|
|
321
321
|
}
|
|
322
322
|
|
|
323
|
+
#__next > div.relative.z-0.flex.h-full.w-full.overflow-hidden > div.dark.flex-shrink-0.overflow-x-hidden.bg-black > div > div > div > div > nav > div.flex.flex-col.pt-2.empty\\:hidden.dark\\:border-white\\/20 > a,
|
|
324
|
+
#__next > div.relative.z-0.flex.h-full.w-full.overflow-hidden > div.relative.flex.h-full.max-w-full.flex-1.flex-col.overflow-hidden > main > div.group.fixed.bottom-3.right-3.z-10.hidden.gap-1.lg\\:flex > div,
|
|
325
|
+
#__next > div.relative.z-0.flex.h-full.w-full.overflow-hidden > div.flex-shrink-0.overflow-x-hidden.bg-token-sidebar-surface-primary > div > div > div > div > nav > div.flex.flex-col.pt-2.empty\\:hidden.dark\\:border-white\\/20 > a {
|
|
326
|
+
display: none;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
#__next .md\\:px-\\[60px\\].text-token-text-secondary.text-xs.text-center.py-2.px-2.relative{
|
|
330
|
+
visibility:hidden;
|
|
331
|
+
}
|
|
332
|
+
|
|
323
333
|
#__next>div>div>.flex.h-screen.w-full.flex-col.items-center {
|
|
324
334
|
padding-top: 20px;
|
|
325
335
|
}
|
|
@@ -373,12 +383,12 @@ window.addEventListener('DOMContentLoaded', _event => {
|
|
|
373
383
|
top: 28px;
|
|
374
384
|
}
|
|
375
385
|
|
|
376
|
-
#
|
|
386
|
+
#pake-top-dom:active {
|
|
377
387
|
cursor: grabbing;
|
|
378
388
|
cursor: -webkit-grabbing;
|
|
379
389
|
}
|
|
380
390
|
|
|
381
|
-
#
|
|
391
|
+
#pake-top-dom{
|
|
382
392
|
position:fixed;
|
|
383
393
|
background:transparent;
|
|
384
394
|
top:0;
|
|
@@ -388,7 +398,7 @@ window.addEventListener('DOMContentLoaded', _event => {
|
|
|
388
398
|
-webkit-app-region: drag;
|
|
389
399
|
user-select: none;
|
|
390
400
|
-webkit-user-select: none;
|
|
391
|
-
z-index:
|
|
401
|
+
z-index: 99999;
|
|
392
402
|
}
|
|
393
403
|
|
|
394
404
|
@media (max-width:767px){
|
package/src-tauri/src/main.rs
CHANGED
|
@@ -1,46 +1,36 @@
|
|
|
1
1
|
#![cfg_attr(
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
all(not(debug_assertions), target_os = "windows"),
|
|
3
|
+
windows_subsystem = "windows"
|
|
4
4
|
)]
|
|
5
5
|
|
|
6
6
|
mod app;
|
|
7
7
|
mod util;
|
|
8
8
|
|
|
9
|
-
use app::{invoke,
|
|
9
|
+
use app::{invoke, window, menu};
|
|
10
10
|
use invoke::{download_file, download_file_by_binary};
|
|
11
|
-
use menu::{
|
|
11
|
+
use menu::{get_system_tray, system_tray_handle};
|
|
12
12
|
use tauri_plugin_window_state::Builder as windowStatePlugin;
|
|
13
13
|
use util::{get_data_dir, get_pake_config};
|
|
14
14
|
use window::get_window;
|
|
15
15
|
|
|
16
16
|
pub fn run_app() {
|
|
17
17
|
let (pake_config, tauri_config) = get_pake_config();
|
|
18
|
-
let show_menu = pake_config.show_menu();
|
|
19
|
-
let menu = get_menu();
|
|
20
18
|
let data_dir = get_data_dir(tauri_config);
|
|
21
19
|
|
|
22
20
|
let mut tauri_app = tauri::Builder::default();
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
#[cfg(not(target_os = "macos"))]
|
|
29
|
-
{
|
|
30
|
-
use menu::{get_system_tray, system_tray_handle};
|
|
31
|
-
|
|
32
|
-
let show_system_tray = pake_config.show_system_tray();
|
|
33
|
-
let system_tray = get_system_tray(show_menu);
|
|
22
|
+
let show_system_tray = pake_config.show_system_tray();
|
|
23
|
+
let system_tray = get_system_tray();
|
|
34
24
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
25
|
+
if show_system_tray {
|
|
26
|
+
tauri_app = tauri_app
|
|
27
|
+
.system_tray(system_tray)
|
|
28
|
+
.on_system_tray_event(system_tray_handle);
|
|
40
29
|
}
|
|
41
30
|
|
|
42
31
|
tauri_app
|
|
43
32
|
.plugin(windowStatePlugin::default().build())
|
|
33
|
+
.plugin(tauri_plugin_oauth::init())
|
|
44
34
|
.invoke_handler(tauri::generate_handler![
|
|
45
35
|
download_file,
|
|
46
36
|
download_file_by_binary
|
|
@@ -56,6 +46,7 @@ pub fn run_app() {
|
|
|
56
46
|
#[cfg(target_os = "macos")]
|
|
57
47
|
{
|
|
58
48
|
event.window().minimize().unwrap();
|
|
49
|
+
event.window().hide().unwrap();
|
|
59
50
|
}
|
|
60
51
|
|
|
61
52
|
#[cfg(not(target_os = "macos"))]
|