mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 07:03:16 +00:00
automatically save settings changes, note when settings are dirty, add default settings button
This commit is contained in:
parent
f733a56945
commit
110ec2b2d8
6 changed files with 101 additions and 75 deletions
109
noita-proxy/Cargo.lock
generated
109
noita-proxy/Cargo.lock
generated
|
@ -1,6 +1,6 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "ab_glyph"
|
||||
|
@ -279,9 +279,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.10.0"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c"
|
||||
checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"serde",
|
||||
|
@ -380,9 +380,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.37"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf"
|
||||
checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"libc",
|
||||
|
@ -540,9 +540,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.14"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0"
|
||||
checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
@ -1028,9 +1028,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.34"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0"
|
||||
checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
|
@ -1238,8 +1238,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1284,7 +1286,7 @@ dependencies = [
|
|||
"aho-corasick",
|
||||
"bstr",
|
||||
"log",
|
||||
"regex-automata 0.4.8",
|
||||
"regex-automata 0.4.9",
|
||||
"regex-syntax 0.8.5",
|
||||
]
|
||||
|
||||
|
@ -1673,7 +1675,7 @@ dependencies = [
|
|||
"globset",
|
||||
"log",
|
||||
"memchr",
|
||||
"regex-automata 0.4.8",
|
||||
"regex-automata 0.4.9",
|
||||
"same-file",
|
||||
"walkdir",
|
||||
"winapi-util",
|
||||
|
@ -1843,9 +1845,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.162"
|
||||
version = "0.2.164"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
|
||||
checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
|
@ -2062,7 +2064,7 @@ dependencies = [
|
|||
"image",
|
||||
"lz4_flex",
|
||||
"poll-promise",
|
||||
"quick-xml 0.37.0",
|
||||
"quick-xml 0.37.1",
|
||||
"rand",
|
||||
"reqwest",
|
||||
"ron",
|
||||
|
@ -2074,7 +2076,7 @@ dependencies = [
|
|||
"socket2",
|
||||
"steamworks",
|
||||
"tangled",
|
||||
"thiserror 2.0.2",
|
||||
"thiserror 2.0.3",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-appender",
|
||||
|
@ -2620,9 +2622,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.37.0"
|
||||
version = "0.37.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffbfb3ddf5364c9cfcd65549a1e7b801d0e8d1b14c1a1590a6408aa93cfbfa84"
|
||||
checksum = "f22f29bdff3987b4d8632ef95fd6424ec7e4e0a57e2f4fc63e489e75357f6a03"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"serde",
|
||||
|
@ -2630,9 +2632,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "quinn"
|
||||
version = "0.11.5"
|
||||
version = "0.11.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684"
|
||||
checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"pin-project-lite",
|
||||
|
@ -2641,27 +2643,30 @@ dependencies = [
|
|||
"rustc-hash 2.0.0",
|
||||
"rustls",
|
||||
"socket2",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror 2.0.3",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn-proto"
|
||||
version = "0.11.8"
|
||||
version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6"
|
||||
checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"getrandom",
|
||||
"rand",
|
||||
"ring",
|
||||
"rustc-hash 2.0.0",
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"rustls-platform-verifier",
|
||||
"slab",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror 2.0.3",
|
||||
"tinyvec",
|
||||
"tracing",
|
||||
"web-time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2779,7 +2784,7 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
|||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata 0.4.8",
|
||||
"regex-automata 0.4.9",
|
||||
"regex-syntax 0.8.5",
|
||||
]
|
||||
|
||||
|
@ -2794,9 +2799,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.8"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
|
||||
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
|
@ -2936,9 +2941,9 @@ checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
|
|||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.39"
|
||||
version = "0.38.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee"
|
||||
checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"errno",
|
||||
|
@ -2949,9 +2954,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.23.16"
|
||||
version = "0.23.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e"
|
||||
checksum = "7f1a745511c54ba6d4465e8d5dfbd81b45791756de28d4981af70d6dca128f1e"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
|
@ -3002,12 +3007,15 @@ name = "rustls-pki-types"
|
|||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b"
|
||||
dependencies = [
|
||||
"web-time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-platform-verifier"
|
||||
version = "0.3.4"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afbb878bdfdf63a336a5e63561b1835e7a8c91524f51621db870169eac84b490"
|
||||
checksum = "a4c7dc240fec5517e6c4eab3310438636cfe6391dfc345ba013109909a90d136"
|
||||
dependencies = [
|
||||
"core-foundation 0.9.4",
|
||||
"core-foundation-sys",
|
||||
|
@ -3020,8 +3028,8 @@ dependencies = [
|
|||
"rustls-webpki",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"webpki-roots",
|
||||
"winapi",
|
||||
"webpki-root-certs",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3129,18 +3137,18 @@ checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.214"
|
||||
version = "1.0.215"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
|
||||
checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.214"
|
||||
version = "1.0.215"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
|
||||
checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -3149,9 +3157,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.132"
|
||||
version = "1.0.133"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
|
||||
checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
|
@ -3422,7 +3430,7 @@ dependencies = [
|
|||
"rcgen",
|
||||
"serde",
|
||||
"test-log",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror 2.0.3",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
|
@ -3473,11 +3481,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.2"
|
||||
version = "2.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "037e29b009aa709f293b974da5cd33b15783c049e07f8435778ce8c4871525d8"
|
||||
checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa"
|
||||
dependencies = [
|
||||
"thiserror-impl 2.0.2",
|
||||
"thiserror-impl 2.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3493,9 +3501,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.2"
|
||||
version = "2.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea4778c7e8ff768bdb32a58a2349903859fe719a320300d7d4ce8636f19a1e69"
|
||||
checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -4223,6 +4231,15 @@ dependencies = [
|
|||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-root-certs"
|
||||
version = "0.26.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8c6dfa3ac045bc517de14c7b1384298de1dbd229d38e08e169d9ae8c170937c"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.26.6"
|
||||
|
|
|
@ -53,6 +53,7 @@ noita_connected = Local Noita instance connected.
|
|||
netman_save_lobby = Save lobby id to clipboard
|
||||
netman_show_settings = Show settings screen
|
||||
netman_apply_settings = Apply settings to be used in the next run
|
||||
apply_default_settings = Resets settings to default
|
||||
|
||||
ip_note = Note: steam networking is more reliable. Use it, if possible.
|
||||
ip_connect = Connect to IP
|
||||
|
|
|
@ -102,16 +102,14 @@ impl GameSettings {
|
|||
.radio_value(&mut temp, GameMode::SharedHealth, tr("Shared-health"))
|
||||
.changed()
|
||||
|| ui
|
||||
.radio_value(&mut temp, GameMode::LocalHealth, tr("Local-health"))
|
||||
.changed()
|
||||
.radio_value(&mut temp, GameMode::LocalHealth, tr("Local-health"))
|
||||
.changed()
|
||||
{
|
||||
game_settings.game_mode = Some(temp)
|
||||
}
|
||||
}
|
||||
|
||||
ui.scope(|ui| {
|
||||
ui.set_height(100.0);
|
||||
|
||||
match game_settings.game_mode.unwrap_or(def.game_mode) {
|
||||
GameMode::SharedHealth => {
|
||||
ui.label(tr("shared_health_desc_1"));
|
||||
|
@ -184,7 +182,6 @@ impl GameSettings {
|
|||
}
|
||||
}
|
||||
ui.add_space(10.0);
|
||||
|
||||
ui.label("World generation");
|
||||
ui.horizontal(|ui| {
|
||||
ui.checkbox(
|
||||
|
@ -207,7 +204,6 @@ impl GameSettings {
|
|||
}
|
||||
}
|
||||
ui.add_space(10.0);
|
||||
|
||||
ui.label("Player settings");
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(tr("connect_settings_max_players"));
|
||||
|
@ -242,7 +238,6 @@ impl GameSettings {
|
|||
game_settings.tether_length = Some(temp)
|
||||
}
|
||||
});
|
||||
|
||||
ui.label(tr("Amount-of-chunks-host-has-loaded-at-once-synced-enemies-and-physics-objects-need-to-be-loaded-in-by-host-to-be-rendered-by-clients"));
|
||||
{
|
||||
let mut temp = game_settings.chunk_target.unwrap_or(def.chunk_target);
|
||||
|
@ -251,7 +246,6 @@ impl GameSettings {
|
|||
}
|
||||
}
|
||||
ui.add_space(10.0);
|
||||
|
||||
ui.label("Perks");
|
||||
{
|
||||
let mut temp = game_settings.randomize_perks.unwrap_or(def.randomize_perks);
|
||||
|
@ -294,9 +288,11 @@ impl GameSettings {
|
|||
game_settings.enemy_hp_mult = Some(temp)
|
||||
}
|
||||
}
|
||||
if ui.button(tr("apply_default_settings")).clicked() {
|
||||
*game_settings = GameSettings::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DefaultSettings {
|
||||
debug_mode: bool,
|
||||
world_sync_version: u32,
|
||||
|
@ -1164,6 +1160,7 @@ impl App {
|
|||
});
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.horizontal(|ui| {
|
||||
let last = self.connected_menu;
|
||||
ui.selectable_value(&mut self.connected_menu, ConnectedMenu::Normal, "Lobby");
|
||||
if netman.peer.is_host() {
|
||||
ui.selectable_value(
|
||||
|
@ -1177,8 +1174,15 @@ impl App {
|
|||
ConnectedMenu::ConnectionInfo,
|
||||
"Connection Info",
|
||||
);
|
||||
if last == ConnectedMenu::Settings && last != self.connected_menu {
|
||||
let new_settings = self.app_saved_state.game_settings.clone();
|
||||
*netman.pending_settings.lock().unwrap() = new_settings.clone();
|
||||
let mut old_settings = netman.settings.lock().unwrap().clone();
|
||||
old_settings.progress.clear();
|
||||
old_settings.seed = new_settings.seed;
|
||||
netman.dirty.store(old_settings != new_settings, Ordering::Relaxed)
|
||||
}
|
||||
});
|
||||
|
||||
ui.separator();
|
||||
|
||||
if stopped {
|
||||
|
@ -1228,15 +1232,20 @@ impl App {
|
|||
|
||||
if netman.peer.is_host() {
|
||||
ui.add_space(15.0);
|
||||
if !self.end_run_confirmation && ui.button(tr("launcher_end_run")).clicked()
|
||||
{
|
||||
self.end_run_confirmation = true
|
||||
} else if self.end_run_confirmation
|
||||
&& ui.button(tr("launcher_end_run_confirm")).clicked()
|
||||
{
|
||||
self.end_run_confirmation = false;
|
||||
netman.end_run.store(true, Ordering::Relaxed)
|
||||
}
|
||||
ui.horizontal(|ui| {
|
||||
if !self.end_run_confirmation && ui.button(tr("launcher_end_run")).clicked()
|
||||
{
|
||||
self.end_run_confirmation = true
|
||||
} else if self.end_run_confirmation
|
||||
&& ui.button(tr("launcher_end_run_confirm")).clicked()
|
||||
{
|
||||
self.end_run_confirmation = false;
|
||||
netman.end_run.store(true, Ordering::Relaxed);
|
||||
};
|
||||
if netman.dirty.load(Ordering::Relaxed) {
|
||||
ui.label("PENDING SETTINGS NOT SET UNTIL RUN ENDS");
|
||||
}
|
||||
});
|
||||
ui.add_space(15.0);
|
||||
let mut temp = netman.no_more_players.load(Ordering::Relaxed);
|
||||
if ui
|
||||
|
@ -1272,10 +1281,6 @@ impl App {
|
|||
}
|
||||
ConnectedMenu::Settings => {
|
||||
self.app_saved_state.game_settings.show_editor(ui);
|
||||
if ui.button(tr("netman_apply_settings")).clicked() {
|
||||
*netman.pending_settings.lock().unwrap() =
|
||||
self.app_saved_state.game_settings.clone();
|
||||
}
|
||||
}
|
||||
ConnectedMenu::ConnectionInfo => match &netman.peer {
|
||||
PeerVariant::Tangled(_) => {
|
||||
|
@ -1660,4 +1665,4 @@ pub fn host_cli(port: u16) {
|
|||
let player_path = netmaninit.player_path.clone();
|
||||
let netman = net::NetManager::new(varient, netmaninit);
|
||||
netman.start_inner(player_path, true).unwrap();
|
||||
}
|
||||
}
|
|
@ -135,6 +135,7 @@ pub struct NetManager {
|
|||
pub kick_list: Mutex<Vec<OmniPeerId>>,
|
||||
pub no_more_players: AtomicBool,
|
||||
dont_kick: Mutex<Vec<OmniPeerId>>,
|
||||
pub dirty: AtomicBool,
|
||||
}
|
||||
|
||||
impl NetManager {
|
||||
|
@ -159,6 +160,7 @@ impl NetManager {
|
|||
kick_list: Default::default(),
|
||||
no_more_players: AtomicBool::new(false),
|
||||
dont_kick: Default::default(),
|
||||
dirty: AtomicBool::new(false),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
@ -721,7 +723,8 @@ impl NetManager {
|
|||
.get_progress()
|
||||
.unwrap_or_default();
|
||||
*self.settings.lock().unwrap() = settings;
|
||||
state.world.reset()
|
||||
state.world.reset();
|
||||
self.dirty.store(false, Ordering::Relaxed);
|
||||
}
|
||||
self.resend_game_settings();
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ serde = {features = ["derive"], version = "1.0.142"}
|
|||
quinn = "0.11.5"
|
||||
num-bigint = "0.4.6"
|
||||
rcgen = "0.13.1"
|
||||
thiserror = "1.0.63"
|
||||
thiserror = "2.0.3"
|
||||
tokio = { version = "1.40.0", features = ["macros", "io-util", "sync"] }
|
||||
bitcode = "0.6.3"
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue