From 6edf3d4ffcf3bb851e2a5683a472eef02d8837ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Tue, 15 Oct 2024 12:30:00 +0200 Subject: [PATCH 01/26] Introduce gateways in WireguardNetwork --- ...8645c9d47dd5b5810ac32aae572d58d39a5e.json} | 4 +- ...b7387eca5822e9cc45205bcbc0d2fcb21d97.json} | 10 +- ...f87c3d6eec3665cfb338df1b45f0822fc1ce.json} | 4 +- ...105d0f94ca2d204e25148b63b833ba69459b.json} | 10 +- ...638b98025f0471a34c949f3e0935818e080b.json} | 4 +- ...3aa9c95ce849f71f2a36d10797fa5cf8f834.json} | 7 +- ...f15e69dbf56925fed7a2ae98f449cc23a815.json} | 7 +- ...0219bd0eb14a5bb95e65844fc919a77fdc3d.json} | 10 +- ...4730a4d22fd487a1dc6c13575c0f1aa394f4.json} | 10 +- Cargo.lock | 183 +++--- build.rs | 6 +- .../20241015074303_network_gateways.down.sql | 1 + .../20241015074303_network_gateways.up.sql | 1 + src/bin/defguard.rs | 7 +- src/db/models/device.rs | 2 +- src/db/models/enrollment.rs | 6 +- src/db/models/wireguard.rs | 36 +- src/grpc/gateway.rs | 338 ++++++----- src/grpc/mod.rs | 39 +- src/grpc/password_reset.rs | 271 --------- src/grpc/{enrollment.rs => proxy.rs} | 573 +++++++++++++----- src/mail.rs | 2 +- src/wireguard_peer_disconnect.rs | 21 +- 23 files changed, 773 insertions(+), 779 deletions(-) rename .sqlx/{query-1403aba7198c132812aa5642166e70c14b3c40a969b496972d499a975fb7b0b4.json => query-140ed5c4dfb4e42aea2e349f73ae8645c9d47dd5b5810ac32aae572d58d39a5e.json} (80%) rename .sqlx/{query-7e10835be17818738155cb84070d878013fe50819f88285ac6f2606b42a3dd3d.json => query-722d953898ad19874bfb026f2a1cb7387eca5822e9cc45205bcbc0d2fcb21d97.json} (86%) rename .sqlx/{query-0e9a8c2395d43898748c176db0d89fa20784cd93ca1dfd00b2755934937d8270.json => query-89c6cd12cbf91f5b504df0dd8861f87c3d6eec3665cfb338df1b45f0822fc1ce.json} (82%) rename .sqlx/{query-5678d744e1e6ba8e7301a3b9e200b61fcc18530d40e13549b4b0d99ed10cb86c.json => query-8f397a1393682f42600ba4799b69105d0f94ca2d204e25148b63b833ba69459b.json} (85%) rename .sqlx/{query-06d1ac982dc99c5dae010089cfb73a044397c5cb6bb9654dc5df420bf00d2955.json => query-9cc07a695832c444bbc66fe38c49638b98025f0471a34c949f3e0935818e080b.json} (74%) rename .sqlx/{query-38f3ad2dc19d222226b85a10d6c83e209cf075f9b128ed33908c73cd74297d81.json => query-d4b301389bd9f8d87517841cd5573aa9c95ce849f71f2a36d10797fa5cf8f834.json} (77%) rename .sqlx/{query-f222309aff56e5182091655c0a6c34cddfee21a48f981c3ca22a6e064c18a769.json => query-db50a47b12760f342f4856593254f15e69dbf56925fed7a2ae98f449cc23a815.json} (73%) rename .sqlx/{query-8c772071e52ac1fb10931f9f698b7555093606011a31706e23dc891321d8836c.json => query-f0bf6cbba9693a015a995f00dac10219bd0eb14a5bb95e65844fc919a77fdc3d.json} (85%) rename .sqlx/{query-f95b0887794cfac8c96bc32a99c3ea4a8e635965c409d72d678045abf28bd16f.json => query-f568188bc7c8b54ffccad38cee004730a4d22fd487a1dc6c13575c0f1aa394f4.json} (85%) create mode 100644 migrations/20241015074303_network_gateways.down.sql create mode 100644 migrations/20241015074303_network_gateways.up.sql delete mode 100644 src/grpc/password_reset.rs rename src/grpc/{enrollment.rs => proxy.rs} (58%) diff --git a/.sqlx/query-1403aba7198c132812aa5642166e70c14b3c40a969b496972d499a975fb7b0b4.json b/.sqlx/query-140ed5c4dfb4e42aea2e349f73ae8645c9d47dd5b5810ac32aae572d58d39a5e.json similarity index 80% rename from .sqlx/query-1403aba7198c132812aa5642166e70c14b3c40a969b496972d499a975fb7b0b4.json rename to .sqlx/query-140ed5c4dfb4e42aea2e349f73ae8645c9d47dd5b5810ac32aae572d58d39a5e.json index b753d65e6..2419b35b6 100644 --- a/.sqlx/query-1403aba7198c132812aa5642166e70c14b3c40a969b496972d499a975fb7b0b4.json +++ b/.sqlx/query-140ed5c4dfb4e42aea2e349f73ae8645c9d47dd5b5810ac32aae572d58d39a5e.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "WITH stats AS ( SELECT DISTINCT ON (network) network, endpoint, latest_handshake FROM wireguard_peer_stats WHERE device_id = $2 ORDER BY network, collected_at DESC ) SELECT n.id network_id, n.name network_name, n.endpoint gateway_endpoint, wnd.wireguard_ip \"device_wireguard_ip: IpAddr\", stats.endpoint device_endpoint, stats.latest_handshake \"latest_handshake?\", COALESCE (((NOW() - stats.latest_handshake) < $1 * interval '1 minute'), false) as \"is_active!\" FROM wireguard_network_device wnd JOIN wireguard_network n ON n.id = wnd.wireguard_network_id LEFT JOIN stats on n.id = stats.network WHERE wnd.device_id = $2", + "query": "WITH stats AS ( SELECT DISTINCT ON (network) network, endpoint, latest_handshake FROM wireguard_peer_stats WHERE device_id = $2 ORDER BY network, collected_at DESC ) SELECT n.id network_id, n.name network_name, n.endpoint gateway_endpoint, wnd.wireguard_ip \"device_wireguard_ip: IpAddr\", stats.endpoint device_endpoint, stats.latest_handshake \"latest_handshake?\", COALESCE (((NOW() - stats.latest_handshake) < $1 * interval '1m'), false) as \"is_active!\" FROM wireguard_network_device wnd JOIN wireguard_network n ON n.id = wnd.wireguard_network_id LEFT JOIN stats on n.id = stats.network WHERE wnd.device_id = $2", "describe": { "columns": [ { @@ -55,5 +55,5 @@ null ] }, - "hash": "1403aba7198c132812aa5642166e70c14b3c40a969b496972d499a975fb7b0b4" + "hash": "140ed5c4dfb4e42aea2e349f73ae8645c9d47dd5b5810ac32aae572d58d39a5e" } diff --git a/.sqlx/query-7e10835be17818738155cb84070d878013fe50819f88285ac6f2606b42a3dd3d.json b/.sqlx/query-722d953898ad19874bfb026f2a1cb7387eca5822e9cc45205bcbc0d2fcb21d97.json similarity index 86% rename from .sqlx/query-7e10835be17818738155cb84070d878013fe50819f88285ac6f2606b42a3dd3d.json rename to .sqlx/query-722d953898ad19874bfb026f2a1cb7387eca5822e9cc45205bcbc0d2fcb21d97.json index 3d8918576..75978ff6c 100644 --- a/.sqlx/query-7e10835be17818738155cb84070d878013fe50819f88285ac6f2606b42a3dd3d.json +++ b/.sqlx/query-722d953898ad19874bfb026f2a1cb7387eca5822e9cc45205bcbc0d2fcb21d97.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold FROM wireguard_network WHERE name = $1", + "query": "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold, gateways FROM wireguard_network WHERE name = $1", "describe": { "columns": [ { @@ -67,6 +67,11 @@ "ordinal": 12, "name": "peer_disconnect_threshold", "type_info": "Int4" + }, + { + "ordinal": 13, + "name": "gateways", + "type_info": "InetArray" } ], "parameters": { @@ -87,8 +92,9 @@ true, false, false, + false, false ] }, - "hash": "7e10835be17818738155cb84070d878013fe50819f88285ac6f2606b42a3dd3d" + "hash": "722d953898ad19874bfb026f2a1cb7387eca5822e9cc45205bcbc0d2fcb21d97" } diff --git a/.sqlx/query-0e9a8c2395d43898748c176db0d89fa20784cd93ca1dfd00b2755934937d8270.json b/.sqlx/query-89c6cd12cbf91f5b504df0dd8861f87c3d6eec3665cfb338df1b45f0822fc1ce.json similarity index 82% rename from .sqlx/query-0e9a8c2395d43898748c176db0d89fa20784cd93ca1dfd00b2755934937d8270.json rename to .sqlx/query-89c6cd12cbf91f5b504df0dd8861f87c3d6eec3665cfb338df1b45f0822fc1ce.json index 25c3f61e0..25e8b614c 100644 --- a/.sqlx/query-0e9a8c2395d43898748c176db0d89fa20784cd93ca1dfd00b2755934937d8270.json +++ b/.sqlx/query-89c6cd12cbf91f5b504df0dd8861f87c3d6eec3665cfb338df1b45f0822fc1ce.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "WITH stats AS ( SELECT DISTINCT ON (device_id) device_id, endpoint, latest_handshake FROM wireguard_peer_stats WHERE network = $1 ORDER BY device_id, collected_at DESC ) SELECT d.id, d.name, d.wireguard_pubkey, d.user_id, d.created FROM device d JOIN wireguard_network_device wnd ON wnd.device_id = d.id LEFT JOIN stats on d.id = stats.device_id WHERE wnd.wireguard_network_id = $1 AND wnd.is_authorized = true AND (wnd.authorized_at IS NULL OR (NOW() - wnd.authorized_at) > $2 * interval '1 second') AND (stats.latest_handshake IS NULL OR (NOW() - stats.latest_handshake) > $2 * interval '1 second')", + "query": "WITH stats AS ( SELECT DISTINCT ON (device_id) device_id, endpoint, latest_handshake FROM wireguard_peer_stats WHERE network = $1 ORDER BY device_id, collected_at DESC ) SELECT d.id, d.name, d.wireguard_pubkey, d.user_id, d.created FROM device d JOIN wireguard_network_device wnd ON wnd.device_id = d.id LEFT JOIN stats on d.id = stats.device_id WHERE wnd.wireguard_network_id = $1 AND wnd.is_authorized = true AND (wnd.authorized_at IS NULL OR (NOW() - wnd.authorized_at) > $2 * interval '1s') AND (stats.latest_handshake IS NULL OR (NOW() - stats.latest_handshake) > $2 * interval '1s')", "describe": { "columns": [ { @@ -43,5 +43,5 @@ false ] }, - "hash": "0e9a8c2395d43898748c176db0d89fa20784cd93ca1dfd00b2755934937d8270" + "hash": "89c6cd12cbf91f5b504df0dd8861f87c3d6eec3665cfb338df1b45f0822fc1ce" } diff --git a/.sqlx/query-5678d744e1e6ba8e7301a3b9e200b61fcc18530d40e13549b4b0d99ed10cb86c.json b/.sqlx/query-8f397a1393682f42600ba4799b69105d0f94ca2d204e25148b63b833ba69459b.json similarity index 85% rename from .sqlx/query-5678d744e1e6ba8e7301a3b9e200b61fcc18530d40e13549b4b0d99ed10cb86c.json rename to .sqlx/query-8f397a1393682f42600ba4799b69105d0f94ca2d204e25148b63b833ba69459b.json index bb4d744b8..08e7d818c 100644 --- a/.sqlx/query-5678d744e1e6ba8e7301a3b9e200b61fcc18530d40e13549b4b0d99ed10cb86c.json +++ b/.sqlx/query-8f397a1393682f42600ba4799b69105d0f94ca2d204e25148b63b833ba69459b.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold FROM wireguard_network WHERE mfa_enabled = true", + "query": "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold, gateways FROM wireguard_network WHERE mfa_enabled = true", "describe": { "columns": [ { @@ -67,6 +67,11 @@ "ordinal": 12, "name": "peer_disconnect_threshold", "type_info": "Int4" + }, + { + "ordinal": 13, + "name": "gateways", + "type_info": "InetArray" } ], "parameters": { @@ -85,8 +90,9 @@ true, false, false, + false, false ] }, - "hash": "5678d744e1e6ba8e7301a3b9e200b61fcc18530d40e13549b4b0d99ed10cb86c" + "hash": "8f397a1393682f42600ba4799b69105d0f94ca2d204e25148b63b833ba69459b" } diff --git a/.sqlx/query-06d1ac982dc99c5dae010089cfb73a044397c5cb6bb9654dc5df420bf00d2955.json b/.sqlx/query-9cc07a695832c444bbc66fe38c49638b98025f0471a34c949f3e0935818e080b.json similarity index 74% rename from .sqlx/query-06d1ac982dc99c5dae010089cfb73a044397c5cb6bb9654dc5df420bf00d2955.json rename to .sqlx/query-9cc07a695832c444bbc66fe38c49638b98025f0471a34c949f3e0935818e080b.json index e2fcfb80f..53cd365de 100644 --- a/.sqlx/query-06d1ac982dc99c5dae010089cfb73a044397c5cb6bb9654dc5df420bf00d2955.json +++ b/.sqlx/query-9cc07a695832c444bbc66fe38c49638b98025f0471a34c949f3e0935818e080b.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT latest_handshake \"latest_handshake: NaiveDateTime\" FROM wireguard_peer_stats_view WHERE device_id = $1 AND latest_handshake IS NOT NULL AND (latest_handshake_diff > $2 * interval '1 minute' OR latest_handshake_diff IS NULL) AND network = $3 ORDER BY collected_at DESC LIMIT 1", + "query": "SELECT latest_handshake \"latest_handshake: NaiveDateTime\" FROM wireguard_peer_stats_view WHERE device_id = $1 AND latest_handshake IS NOT NULL AND (latest_handshake_diff > $2 * interval '1m' OR latest_handshake_diff IS NULL) AND network = $3 ORDER BY collected_at DESC LIMIT 1", "describe": { "columns": [ { @@ -20,5 +20,5 @@ true ] }, - "hash": "06d1ac982dc99c5dae010089cfb73a044397c5cb6bb9654dc5df420bf00d2955" + "hash": "9cc07a695832c444bbc66fe38c49638b98025f0471a34c949f3e0935818e080b" } diff --git a/.sqlx/query-38f3ad2dc19d222226b85a10d6c83e209cf075f9b128ed33908c73cd74297d81.json b/.sqlx/query-d4b301389bd9f8d87517841cd5573aa9c95ce849f71f2a36d10797fa5cf8f834.json similarity index 77% rename from .sqlx/query-38f3ad2dc19d222226b85a10d6c83e209cf075f9b128ed33908c73cd74297d81.json rename to .sqlx/query-d4b301389bd9f8d87517841cd5573aa9c95ce849f71f2a36d10797fa5cf8f834.json index d187d6402..1e0fd7119 100644 --- a/.sqlx/query-38f3ad2dc19d222226b85a10d6c83e209cf075f9b128ed33908c73cd74297d81.json +++ b/.sqlx/query-d4b301389bd9f8d87517841cd5573aa9c95ce849f71f2a36d10797fa5cf8f834.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "UPDATE \"wireguard_network\" SET \"name\" = $2,\"address\" = $3,\"port\" = $4,\"pubkey\" = $5,\"prvkey\" = $6,\"endpoint\" = $7,\"dns\" = $8,\"allowed_ips\" = $9,\"connected_at\" = $10,\"mfa_enabled\" = $11,\"keepalive_interval\" = $12,\"peer_disconnect_threshold\" = $13 WHERE id = $1", + "query": "UPDATE \"wireguard_network\" SET \"name\" = $2,\"address\" = $3,\"port\" = $4,\"pubkey\" = $5,\"prvkey\" = $6,\"endpoint\" = $7,\"dns\" = $8,\"allowed_ips\" = $9,\"connected_at\" = $10,\"mfa_enabled\" = $11,\"keepalive_interval\" = $12,\"peer_disconnect_threshold\" = $13,\"gateways\" = $14 WHERE id = $1", "describe": { "columns": [], "parameters": { @@ -17,10 +17,11 @@ "Timestamp", "Bool", "Int4", - "Int4" + "Int4", + "InetArray" ] }, "nullable": [] }, - "hash": "38f3ad2dc19d222226b85a10d6c83e209cf075f9b128ed33908c73cd74297d81" + "hash": "d4b301389bd9f8d87517841cd5573aa9c95ce849f71f2a36d10797fa5cf8f834" } diff --git a/.sqlx/query-f222309aff56e5182091655c0a6c34cddfee21a48f981c3ca22a6e064c18a769.json b/.sqlx/query-db50a47b12760f342f4856593254f15e69dbf56925fed7a2ae98f449cc23a815.json similarity index 73% rename from .sqlx/query-f222309aff56e5182091655c0a6c34cddfee21a48f981c3ca22a6e064c18a769.json rename to .sqlx/query-db50a47b12760f342f4856593254f15e69dbf56925fed7a2ae98f449cc23a815.json index 25ae273d7..f927b3022 100644 --- a/.sqlx/query-f222309aff56e5182091655c0a6c34cddfee21a48f981c3ca22a6e064c18a769.json +++ b/.sqlx/query-db50a47b12760f342f4856593254f15e69dbf56925fed7a2ae98f449cc23a815.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "INSERT INTO \"wireguard_network\" (\"name\",\"address\",\"port\",\"pubkey\",\"prvkey\",\"endpoint\",\"dns\",\"allowed_ips\",\"connected_at\",\"mfa_enabled\",\"keepalive_interval\",\"peer_disconnect_threshold\") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12) RETURNING id", + "query": "INSERT INTO \"wireguard_network\" (\"name\",\"address\",\"port\",\"pubkey\",\"prvkey\",\"endpoint\",\"dns\",\"allowed_ips\",\"connected_at\",\"mfa_enabled\",\"keepalive_interval\",\"peer_disconnect_threshold\",\"gateways\") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13) RETURNING id", "describe": { "columns": [ { @@ -22,12 +22,13 @@ "Timestamp", "Bool", "Int4", - "Int4" + "Int4", + "InetArray" ] }, "nullable": [ false ] }, - "hash": "f222309aff56e5182091655c0a6c34cddfee21a48f981c3ca22a6e064c18a769" + "hash": "db50a47b12760f342f4856593254f15e69dbf56925fed7a2ae98f449cc23a815" } diff --git a/.sqlx/query-8c772071e52ac1fb10931f9f698b7555093606011a31706e23dc891321d8836c.json b/.sqlx/query-f0bf6cbba9693a015a995f00dac10219bd0eb14a5bb95e65844fc919a77fdc3d.json similarity index 85% rename from .sqlx/query-8c772071e52ac1fb10931f9f698b7555093606011a31706e23dc891321d8836c.json rename to .sqlx/query-f0bf6cbba9693a015a995f00dac10219bd0eb14a5bb95e65844fc919a77fdc3d.json index ad29454b2..fa877bf42 100644 --- a/.sqlx/query-8c772071e52ac1fb10931f9f698b7555093606011a31706e23dc891321d8836c.json +++ b/.sqlx/query-f0bf6cbba9693a015a995f00dac10219bd0eb14a5bb95e65844fc919a77fdc3d.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT id, \"name\",\"address\" \"address: _\",\"port\",\"pubkey\",\"prvkey\",\"endpoint\",\"dns\",\"allowed_ips\" \"allowed_ips: _\",\"connected_at\",\"mfa_enabled\",\"keepalive_interval\",\"peer_disconnect_threshold\" FROM \"wireguard_network\"", + "query": "SELECT id, \"name\",\"address\" \"address: _\",\"port\",\"pubkey\",\"prvkey\",\"endpoint\",\"dns\",\"allowed_ips\" \"allowed_ips: _\",\"connected_at\",\"mfa_enabled\",\"keepalive_interval\",\"peer_disconnect_threshold\",\"gateways\" \"gateways: _\" FROM \"wireguard_network\"", "describe": { "columns": [ { @@ -67,6 +67,11 @@ "ordinal": 12, "name": "peer_disconnect_threshold", "type_info": "Int4" + }, + { + "ordinal": 13, + "name": "gateways: _", + "type_info": "InetArray" } ], "parameters": { @@ -85,8 +90,9 @@ true, false, false, + false, false ] }, - "hash": "8c772071e52ac1fb10931f9f698b7555093606011a31706e23dc891321d8836c" + "hash": "f0bf6cbba9693a015a995f00dac10219bd0eb14a5bb95e65844fc919a77fdc3d" } diff --git a/.sqlx/query-f95b0887794cfac8c96bc32a99c3ea4a8e635965c409d72d678045abf28bd16f.json b/.sqlx/query-f568188bc7c8b54ffccad38cee004730a4d22fd487a1dc6c13575c0f1aa394f4.json similarity index 85% rename from .sqlx/query-f95b0887794cfac8c96bc32a99c3ea4a8e635965c409d72d678045abf28bd16f.json rename to .sqlx/query-f568188bc7c8b54ffccad38cee004730a4d22fd487a1dc6c13575c0f1aa394f4.json index a31da94fa..056328e66 100644 --- a/.sqlx/query-f95b0887794cfac8c96bc32a99c3ea4a8e635965c409d72d678045abf28bd16f.json +++ b/.sqlx/query-f568188bc7c8b54ffccad38cee004730a4d22fd487a1dc6c13575c0f1aa394f4.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT id, \"name\",\"address\" \"address: _\",\"port\",\"pubkey\",\"prvkey\",\"endpoint\",\"dns\",\"allowed_ips\" \"allowed_ips: _\",\"connected_at\",\"mfa_enabled\",\"keepalive_interval\",\"peer_disconnect_threshold\" FROM \"wireguard_network\" WHERE id = $1", + "query": "SELECT id, \"name\",\"address\" \"address: _\",\"port\",\"pubkey\",\"prvkey\",\"endpoint\",\"dns\",\"allowed_ips\" \"allowed_ips: _\",\"connected_at\",\"mfa_enabled\",\"keepalive_interval\",\"peer_disconnect_threshold\",\"gateways\" \"gateways: _\" FROM \"wireguard_network\" WHERE id = $1", "describe": { "columns": [ { @@ -67,6 +67,11 @@ "ordinal": 12, "name": "peer_disconnect_threshold", "type_info": "Int4" + }, + { + "ordinal": 13, + "name": "gateways: _", + "type_info": "InetArray" } ], "parameters": { @@ -87,8 +92,9 @@ true, false, false, + false, false ] }, - "hash": "f95b0887794cfac8c96bc32a99c3ea4a8e635965c409d72d678045abf28bd16f" + "hash": "f568188bc7c8b54ffccad38cee004730a4d22fd487a1dc6c13575c0f1aa394f4" } diff --git a/Cargo.lock b/Cargo.lock index 0a8671c16..b1dd49980 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] @@ -619,9 +619,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.24" +version = "1.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" +checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" dependencies = [ "jobserver", "libc", @@ -711,9 +711,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.19" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -721,9 +721,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.19" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", @@ -1205,18 +1205,18 @@ dependencies = [ [[package]] name = "derive_builder" -version = "0.20.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd33f37ee6a119146a1781d3356a7c26028f83d779b2e04ecd45fdc75c76877b" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" dependencies = [ "derive_builder_macro", ] [[package]] name = "derive_builder_core" -version = "0.20.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7431fa049613920234f22c47fdc33e6cf3ee83067091ea4277a3f8c4587aae38" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" dependencies = [ "darling", "proc-macro2", @@ -1226,9 +1226,9 @@ dependencies = [ [[package]] name = "derive_builder_macro" -version = "0.20.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4abae7035bf79b9877b779505d8cf3749285b80c43941eda66604841889451dc" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", "syn 2.0.79", @@ -1650,9 +1650,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -1665,9 +1665,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -1675,15 +1675,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -1703,15 +1703,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", @@ -1720,21 +1720,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -1793,9 +1793,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "git2" @@ -2138,7 +2138,7 @@ dependencies = [ "http 1.1.0", "hyper 1.4.1", "hyper-util", - "rustls 0.23.13", + "rustls 0.23.14", "rustls-pki-types", "tokio", "tokio-rustls 0.26.0", @@ -2465,9 +2465,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.10.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" [[package]] name = "ipnetwork" @@ -2525,9 +2525,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] @@ -2989,9 +2989,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.4" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] @@ -3019,12 +3019,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.1" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" -dependencies = [ - "portable-atomic", -] +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "opaque-debug" @@ -3304,9 +3301,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.13" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" +checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", "thiserror", @@ -3315,9 +3312,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.13" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d3a6e3394ec80feb3b6393c725571754c6188490265c61aaf260810d6b95aa0" +checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" dependencies = [ "pest", "pest_generator", @@ -3325,9 +3322,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.13" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94429506bde1ca69d1b5601962c73f4172ab4726571a59ea95931218cb0e930e" +checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" dependencies = [ "pest", "pest_meta", @@ -3338,9 +3335,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.13" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac8a071862e93690b6e34e9a5fb8e33ff3734473ac0245b27232222c4906a33f" +checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" dependencies = [ "once_cell", "pest", @@ -3461,18 +3458,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" dependencies = [ "proc-macro2", "quote", @@ -3530,12 +3527,6 @@ dependencies = [ "universal-hash", ] -[[package]] -name = "portable-atomic" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" - [[package]] name = "powerfmt" version = "0.2.0" @@ -3619,9 +3610,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" dependencies = [ "unicode-ident", ] @@ -3750,7 +3741,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.13", + "rustls 0.23.14", "socket2", "thiserror", "tokio", @@ -3767,7 +3758,7 @@ dependencies = [ "rand", "ring", "rustc-hash", - "rustls 0.23.13", + "rustls 0.23.14", "slab", "thiserror", "tinyvec", @@ -3974,7 +3965,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.13", + "rustls 0.23.14", "rustls-pemfile 2.2.0", "rustls-pki-types", "serde", @@ -4191,9 +4182,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.13" +version = "0.23.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" +checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" dependencies = [ "once_cell", "ring", @@ -4263,9 +4254,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "ryu" @@ -4308,9 +4299,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" +checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" dependencies = [ "windows-sys 0.59.0", ] @@ -4508,9 +4499,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.10.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9720086b3357bcb44fce40117d769a4d068c70ecfa190850a980a71755f66fcc" +checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" dependencies = [ "base64 0.22.1", "chrono", @@ -4526,9 +4517,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.10.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f1abbfe725f27678f4663bcacb75a83e829fd464c25d78dd038a3a29e307cec" +checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" dependencies = [ "darling", "proc-macro2", @@ -5342,7 +5333,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.13", + "rustls 0.23.14", "rustls-pki-types", "tokio", ] @@ -5823,9 +5814,9 @@ dependencies = [ [[package]] name = "utoipa-gen" -version = "4.3.0" +version = "4.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bf0e16c02bc4bf5322ab65f10ab1149bdbcaa782cba66dc7057370a3f8190be" +checksum = "20c24e8ab68ff9ee746aad22d39b5535601e6416d1b0feeabf78be986a5c4392" dependencies = [ "proc-macro-error", "proc-macro2", @@ -5952,9 +5943,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", "once_cell", @@ -5963,9 +5954,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", @@ -5978,9 +5969,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.43" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" dependencies = [ "cfg-if", "js-sys", @@ -5990,9 +5981,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6000,9 +5991,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", @@ -6013,9 +6004,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "wasm-streams" @@ -6032,9 +6023,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/build.rs b/build.rs index 43c2aa4dd..9db06b09b 100644 --- a/build.rs +++ b/build.rs @@ -12,20 +12,20 @@ fn main() -> Result<(), Box> { &[ "proto/core/auth.proto", "proto/core/proxy.proto", - "proto/core/vpn.proto", "src/enterprise/proto/license.proto", - "proto/worker/worker.proto", "proto/wireguard/gateway.proto", + "proto/worker/worker.proto", ], &[ "proto/core", - "proto/worker", "proto/wireguard", + "proto/worker", "src/enterprise/proto", ], )?; println!("cargo:rerun-if-changed=migrations"); println!("cargo:rerun-if-changed=proto"); println!("cargo:rerun-if-changed=web/dist"); + Ok(()) } diff --git a/migrations/20241015074303_network_gateways.down.sql b/migrations/20241015074303_network_gateways.down.sql new file mode 100644 index 000000000..0197bef93 --- /dev/null +++ b/migrations/20241015074303_network_gateways.down.sql @@ -0,0 +1 @@ +ALTER TABLE wireguard_network DROP COLUMN gateways; diff --git a/migrations/20241015074303_network_gateways.up.sql b/migrations/20241015074303_network_gateways.up.sql new file mode 100644 index 000000000..8dd37e805 --- /dev/null +++ b/migrations/20241015074303_network_gateways.up.sql @@ -0,0 +1 @@ +ALTER TABLE wireguard_network ADD COLUMN gateways inet[] NOT NULL DEFAULT array[]::inet[]; diff --git a/src/bin/defguard.rs b/src/bin/defguard.rs index a25f50a83..5626e1ef0 100644 --- a/src/bin/defguard.rs +++ b/src/bin/defguard.rs @@ -78,7 +78,7 @@ async fn main() -> Result<(), anyhow::Error> { let (wireguard_tx, _wireguard_rx) = broadcast::channel::(256); let (mail_tx, mail_rx) = unbounded_channel::(); let worker_state = Arc::new(Mutex::new(WorkerState::new(webhook_tx.clone()))); - let gateway_state = Arc::new(Mutex::new(GatewayMap::new())); + let gateway_map = Arc::new(Mutex::new(GatewayMap::new())); let user_agent_parser = create_user_agent_parser(); // initialize admin user @@ -115,12 +115,13 @@ async fn main() -> Result<(), anyhow::Error> { // run services tokio::select! { res = run_grpc_bidi_stream(pool.clone(), wireguard_tx.clone(), mail_tx.clone(), user_agent_parser.clone()), if config.proxy_url.is_some() => error!("Proxy gRPC stream returned early: {res:#?}"), - res = run_grpc_server(Arc::clone(&worker_state), pool.clone(), Arc::clone(&gateway_state), wireguard_tx.clone(), mail_tx.clone(), grpc_cert, grpc_key, failed_logins.clone()) => error!("gRPC server returned early: {res:#?}"), - res = run_web_server(worker_state, gateway_state, webhook_tx, webhook_rx, wireguard_tx.clone(), mail_tx, pool.clone(), user_agent_parser, failed_logins) => error!("Web server returned early: {res:#?}"), + res = run_grpc_server(Arc::clone(&worker_state), pool.clone(), Arc::clone(&gateway_map), wireguard_tx.clone(), mail_tx.clone(), grpc_cert, grpc_key, failed_logins.clone()) => error!("gRPC server returned early: {res:#?}"), + res = run_web_server(worker_state, gateway_map, webhook_tx, webhook_rx, wireguard_tx.clone(), mail_tx, pool.clone(), user_agent_parser, failed_logins) => error!("Web server returned early: {res:#?}"), res = run_mail_handler(mail_rx, pool.clone()) => error!("Mail handler returned early: {res:#?}"), res = run_periodic_peer_disconnect(pool.clone(), wireguard_tx) => error!("Periodic peer disconnect task returned early: {res:#?}"), res = run_periodic_stats_purge(pool.clone(), config.stats_purge_frequency.into(), config.stats_purge_threshold.into()), if !config.disable_stats_purge => error!("Periodic stats purge task returned early: {res:#?}"), res = run_periodic_license_check(pool) => error!("Periodic license check task returned early: {res:#?}"), } + Ok(()) } diff --git a/src/db/models/device.rs b/src/db/models/device.rs index 6dd9028d7..08d88173c 100644 --- a/src/db/models/device.rs +++ b/src/db/models/device.rs @@ -127,7 +127,7 @@ impl UserDevice { n.id network_id, n.name network_name, n.endpoint gateway_endpoint, \ wnd.wireguard_ip \"device_wireguard_ip: IpAddr\", stats.endpoint device_endpoint, \ stats.latest_handshake \"latest_handshake?\", \ - COALESCE (((NOW() - stats.latest_handshake) < $1 * interval '1 minute'), false) as \"is_active!\" \ + COALESCE (((NOW() - stats.latest_handshake) < $1 * interval '1m'), false) as \"is_active!\" \ FROM wireguard_network_device wnd \ JOIN wireguard_network n ON n.id = wnd.wireguard_network_id \ LEFT JOIN stats on n.id = stats.network \ diff --git a/src/db/models/enrollment.rs b/src/db/models/enrollment.rs index c4b871adb..100b2b6d6 100644 --- a/src/db/models/enrollment.rs +++ b/src/db/models/enrollment.rs @@ -16,8 +16,8 @@ use crate::{ VERSION, }; -pub static ENROLLMENT_TOKEN_TYPE: &str = "ENROLLMENT"; -pub static PASSWORD_RESET_TOKEN_TYPE: &str = "PASSWORD_RESET"; +pub(crate) static ENROLLMENT_TOKEN_TYPE: &str = "ENROLLMENT"; +pub(crate) static PASSWORD_RESET_TOKEN_TYPE: &str = "PASSWORD_RESET"; static ENROLLMENT_START_MAIL_SUBJECT: &str = "Defguard user enrollment"; static DESKTOP_START_MAIL_SUBJECT: &str = "Defguard desktop client configuration"; @@ -78,7 +78,7 @@ impl From for Status { } // Representation of a user enrollment session -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct Token { pub id: String, pub user_id: Id, diff --git a/src/db/models/wireguard.rs b/src/db/models/wireguard.rs index 5bc14aa9e..6134a1ac7 100644 --- a/src/db/models/wireguard.rs +++ b/src/db/models/wireguard.rs @@ -88,6 +88,8 @@ pub struct WireguardNetwork { pub mfa_enabled: bool, pub keepalive_interval: i32, pub peer_disconnect_threshold: i32, + #[model(ref)] + pub gateways: Vec, } pub struct WireguardKey { @@ -155,6 +157,7 @@ impl WireguardNetwork { mfa_enabled, keepalive_interval, peer_disconnect_threshold, + gateways: Vec::new(), }) } @@ -176,23 +179,22 @@ impl WireguardNetwork { { let networks = query_as!( WireguardNetwork, - "SELECT \ - id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, \ - connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold \ + "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, \ + connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold, gateways \ FROM wireguard_network WHERE name = $1", name ) .fetch_all(executor) .await?; - if networks.is_empty() { - return Ok(None); - } - - Ok(Some(networks)) + Ok(if networks.is_empty() { + None + } else { + Some(networks) + }) } - // run sync_allowed_devices on all wireguard networks + /// Run `sync_allowed_devices()` on all WireGuard networks. pub async fn sync_all_networks(app: &AppState) -> Result<(), WireguardNetworkError> { info!("Syncing allowed devices for all WireGuard locations"); let mut transaction = app.pool.begin().await?; @@ -210,13 +212,18 @@ impl WireguardNetwork { &self, transaction: &mut PgConnection, ) -> Result { - let count = query_scalar!("SELECT count(*) \"count!\" FROM wireguard_network_device WHERE wireguard_network_id = $1", self.id) - .fetch_one(transaction) - .await?; + let count = query_scalar!( + "SELECT count(*) \"count!\" FROM wireguard_network_device \ + WHERE wireguard_network_id = $1", + self.id + ) + .fetch_one(transaction) + .await?; Ok(count) } + /// Check if given number of devices could fit the network. pub fn validate_network_size(&self, device_count: usize) -> Result<(), WireguardNetworkError> { debug!("Checking if {device_count} devices can fit in network {self}"); let network_size = self.address.size(); @@ -237,7 +244,7 @@ impl WireguardNetwork { Ok(()) } - /// Utility method to create WireGuard keypair + /// Utility method to create WireGuard keypair. #[must_use] pub fn genkey() -> WireguardKey { let private = StaticSecret::random_from_rng(OsRng); @@ -696,7 +703,7 @@ impl WireguardNetwork { FROM wireguard_peer_stats_view \ WHERE device_id = $1 \ AND latest_handshake IS NOT NULL \ - AND (latest_handshake_diff > $2 * interval '1 minute' OR latest_handshake_diff IS NULL) \ + AND (latest_handshake_diff > $2 * interval '1m' OR latest_handshake_diff IS NULL) \ AND network = $3 \ ORDER BY collected_at DESC \ LIMIT 1", @@ -934,6 +941,7 @@ impl Default for WireguardNetwork { mfa_enabled: false, keepalive_interval: DEFAULT_KEEPALIVE_INTERVAL, peer_disconnect_threshold: DEFAULT_DISCONNECT_THRESHOLD, + gateways: Vec::default(), } } } diff --git a/src/grpc/gateway.rs b/src/grpc/gateway.rs index 64125f34a..5fedabf81 100644 --- a/src/grpc/gateway.rs +++ b/src/grpc/gateway.rs @@ -343,6 +343,7 @@ impl GatewayUpdatesHandler { error!(msg); return Err(Status::new(Code::Internal, msg)); } + debug!("Network update sent for network {network}"); Ok(()) } @@ -374,6 +375,7 @@ impl GatewayUpdatesHandler { error!(msg); return Err(Status::new(Code::Internal, msg)); } + debug!("Network delete command sent for network {}", self.network); Ok(()) } @@ -401,6 +403,7 @@ impl GatewayUpdatesHandler { error!(msg); return Err(Status::new(Code::Internal, msg)); } + debug!("Peer update sent for network {}", self.network); Ok(()) } @@ -428,6 +431,7 @@ impl GatewayUpdatesHandler { error!(msg); return Err(Status::new(Code::Internal, msg)); } + debug!("Peer delete command sent for network {}", self.network); Ok(()) } @@ -485,170 +489,170 @@ impl Drop for GatewayUpdatesStream { } } -#[tonic::async_trait] -impl gateway_service_server::GatewayService for GatewayServer { - type UpdatesStream = GatewayUpdatesStream; - - /// Retrieve stats from gateway and save it to database - async fn stats( - &self, - request: Request>, - ) -> Result, Status> { - let network_id = Self::get_network_id(request.metadata())?; - let mut stream = request.into_inner(); - while let Some(stats_update) = stream.message().await? { - debug!("Received stats message: {stats_update:?}"); - let Some(stats_update::Payload::PeerStats(peer_stats)) = stats_update.payload else { - debug!("Received stats message is empty, skipping."); - continue; - }; - let public_key = peer_stats.public_key.clone(); - let mut stats = WireguardPeerStats::from_peer_stats(peer_stats, network_id); - // Get device by public key and fill in stats.device_id - // FIXME: keep an in-memory device map to avoid repeated DB requests - stats.device_id = match Device::find_by_pubkey(&self.pool, &public_key).await { - Ok(Some(device)) => device.id, - Ok(None) => { - error!("Device with public key {public_key} not found"); - return Err(Status::new( - Code::Internal, - format!("Device with public key {public_key} not found"), - )); - } - Err(err) => { - error!("Failed to retrieve device with public key {public_key}: {err}",); - return Err(Status::new( - Code::Internal, - format!("Failed to retrieve device with public key {public_key}: {err}",), - )); - } - }; - // Save stats to db - let stats = match stats.save(&self.pool).await { - Ok(stats) => stats, - Err(err) => { - error!("Saving WireGuard peer stats to db failed: {err}"); - return Err(Status::new( - Code::Internal, - format!("Saving WireGuard peer stats to db failed: {err}"), - )); - } - }; - info!("Saved WireGuard peer stats to db."); - debug!("WireGuard peer stats: {stats:?}"); - } - - Ok(Response::new(())) - } - - async fn config( - &self, - request: Request, - ) -> Result, Status> { - debug!("Sending configuration to gateway client."); - let network_id = Self::get_network_id(request.metadata())?; - let hostname = Self::get_gateway_hostname(request.metadata())?; - - let mut network = WireguardNetwork::find_by_id(&self.pool, network_id) - .await - .map_err(|e| { - error!("Network {network_id} not found"); - Status::new(Code::Internal, format!("Failed to retrieve network: {e}")) - })? - .ok_or_else(|| { - Status::new( - Code::Internal, - format!("Network with id {network_id} not found"), - ) - })?; - - debug!("Sending configuration to gateway client, network {network}."); - - // store connected gateway in memory - { - let mut state = self.state.lock().unwrap(); - state.add_gateway( - network_id, - &network.name, - hostname, - request.into_inner().name, - self.mail_tx.clone(), - ); - } - - network.connected_at = Some(Utc::now().naive_utc()); - if let Err(err) = network.save(&self.pool).await { - error!("Failed to save updated network {network_id} in the database, status: {err}"); - } - - let peers = network.get_peers(&self.pool).await.map_err(|error| { - error!("Failed to fetch peers from the database for network {network_id}: {error}",); - Status::new( - Code::Internal, - format!("Failed to retrieve peers from the database for network: {network_id}"), - ) - })?; - - info!("Configuration sent to gateway client, network {network}."); - - Ok(Response::new(gen_config(&network, peers))) - } - - async fn updates(&self, request: Request<()>) -> Result, Status> { - let gateway_network_id = Self::get_network_id(request.metadata())?; - let hostname = Self::get_gateway_hostname(request.metadata())?; - - let Some(network) = WireguardNetwork::find_by_id(&self.pool, gateway_network_id) - .await - .map_err(|_| { - error!("Failed to fetch network {gateway_network_id} from the database"); - Status::new( - Code::Internal, - format!("Failed to retrieve network {gateway_network_id} from the database"), - ) - })? - else { - return Err(Status::new( - Code::Internal, - format!("Network with id {gateway_network_id} not found"), - )); - }; - - info!("New client connected to updates stream: {hostname}, network {network}",); - - let (tx, rx) = mpsc::channel(4); - let events_rx = self.wireguard_tx.subscribe(); - let mut state = self.state.lock().unwrap(); - state - .connect_gateway(gateway_network_id, &hostname) - .map_err(|err| { - error!("Failed to connect gateway on network {gateway_network_id}: {err}"); - Status::new( - Code::Internal, - "Failed to connect gateway on network {gateway_network_id}", - ) - })?; - - // clone here before moving into a closure - let gateway_hostname = hostname.clone(); - let handle = tokio::spawn(async move { - let mut update_handler = GatewayUpdatesHandler::new( - gateway_network_id, - network, - gateway_hostname, - events_rx, - tx, - ); - update_handler.run().await; - }); - - Ok(Response::new(GatewayUpdatesStream::new( - handle, - rx, - gateway_network_id, - hostname, - Arc::clone(&self.state), - self.pool.clone(), - ))) - } -} +// #[tonic::async_trait] +// impl gateway_service_server::GatewayService for GatewayServer { +// type UpdatesStream = GatewayUpdatesStream; + +// /// Retrieve stats from gateway and save it to database +// async fn stats( +// &self, +// request: Request>, +// ) -> Result, Status> { +// let network_id = Self::get_network_id(request.metadata())?; +// let mut stream = request.into_inner(); +// while let Some(stats_update) = stream.message().await? { +// debug!("Received stats message: {stats_update:?}"); +// let Some(stats_update::Payload::PeerStats(peer_stats)) = stats_update.payload else { +// debug!("Received stats message is empty, skipping."); +// continue; +// }; +// let public_key = peer_stats.public_key.clone(); +// let mut stats = WireguardPeerStats::from_peer_stats(peer_stats, network_id); +// // Get device by public key and fill in stats.device_id +// // FIXME: keep an in-memory device map to avoid repeated DB requests +// stats.device_id = match Device::find_by_pubkey(&self.pool, &public_key).await { +// Ok(Some(device)) => device.id, +// Ok(None) => { +// error!("Device with public key {public_key} not found"); +// return Err(Status::new( +// Code::Internal, +// format!("Device with public key {public_key} not found"), +// )); +// } +// Err(err) => { +// error!("Failed to retrieve device with public key {public_key}: {err}",); +// return Err(Status::new( +// Code::Internal, +// format!("Failed to retrieve device with public key {public_key}: {err}",), +// )); +// } +// }; +// // Save stats to db +// let stats = match stats.save(&self.pool).await { +// Ok(stats) => stats, +// Err(err) => { +// error!("Saving WireGuard peer stats to db failed: {err}"); +// return Err(Status::new( +// Code::Internal, +// format!("Saving WireGuard peer stats to db failed: {err}"), +// )); +// } +// }; +// info!("Saved WireGuard peer stats to db."); +// debug!("WireGuard peer stats: {stats:?}"); +// } + +// Ok(Response::new(())) +// } + +// async fn config( +// &self, +// request: Request, +// ) -> Result, Status> { +// debug!("Sending configuration to gateway client."); +// let network_id = Self::get_network_id(request.metadata())?; +// let hostname = Self::get_gateway_hostname(request.metadata())?; + +// let mut network = WireguardNetwork::find_by_id(&self.pool, network_id) +// .await +// .map_err(|e| { +// error!("Network {network_id} not found"); +// Status::new(Code::Internal, format!("Failed to retrieve network: {e}")) +// })? +// .ok_or_else(|| { +// Status::new( +// Code::Internal, +// format!("Network with id {network_id} not found"), +// ) +// })?; + +// debug!("Sending configuration to gateway client, network {network}."); + +// // store connected gateway in memory +// { +// let mut state = self.state.lock().unwrap(); +// state.add_gateway( +// network_id, +// &network.name, +// hostname, +// request.into_inner().name, +// self.mail_tx.clone(), +// ); +// } + +// network.connected_at = Some(Utc::now().naive_utc()); +// if let Err(err) = network.save(&self.pool).await { +// error!("Failed to save updated network {network_id} in the database, status: {err}"); +// } + +// let peers = network.get_peers(&self.pool).await.map_err(|error| { +// error!("Failed to fetch peers from the database for network {network_id}: {error}",); +// Status::new( +// Code::Internal, +// format!("Failed to retrieve peers from the database for network: {network_id}"), +// ) +// })?; + +// info!("Configuration sent to gateway client, network {network}."); + +// Ok(Response::new(gen_config(&network, peers))) +// } + +// async fn updates(&self, request: Request<()>) -> Result, Status> { +// let gateway_network_id = Self::get_network_id(request.metadata())?; +// let hostname = Self::get_gateway_hostname(request.metadata())?; + +// let Some(network) = WireguardNetwork::find_by_id(&self.pool, gateway_network_id) +// .await +// .map_err(|_| { +// error!("Failed to fetch network {gateway_network_id} from the database"); +// Status::new( +// Code::Internal, +// format!("Failed to retrieve network {gateway_network_id} from the database"), +// ) +// })? +// else { +// return Err(Status::new( +// Code::Internal, +// format!("Network with id {gateway_network_id} not found"), +// )); +// }; + +// info!("New client connected to updates stream: {hostname}, network {network}",); + +// let (tx, rx) = mpsc::channel(4); +// let events_rx = self.wireguard_tx.subscribe(); +// let mut state = self.state.lock().unwrap(); +// state +// .connect_gateway(gateway_network_id, &hostname) +// .map_err(|err| { +// error!("Failed to connect gateway on network {gateway_network_id}: {err}"); +// Status::new( +// Code::Internal, +// "Failed to connect gateway on network {gateway_network_id}", +// ) +// })?; + +// // clone here before moving into a closure +// let gateway_hostname = hostname.clone(); +// let handle = tokio::spawn(async move { +// let mut update_handler = GatewayUpdatesHandler::new( +// gateway_network_id, +// network, +// gateway_hostname, +// events_rx, +// tx, +// ); +// update_handler.run().await; +// }); + +// Ok(Response::new(GatewayUpdatesStream::new( +// handle, +// rx, +// gateway_network_id, +// hostname, +// Arc::clone(&self.state), +// self.pool.clone(), +// ))) +// } +// } diff --git a/src/grpc/mod.rs b/src/grpc/mod.rs index ea2a26cbd..3f812eec0 100644 --- a/src/grpc/mod.rs +++ b/src/grpc/mod.rs @@ -35,9 +35,8 @@ use self::gateway::{gateway_service_server::GatewayServiceServer, GatewayServer} use self::{ auth::{auth_service_server::AuthServiceServer, AuthServer}, desktop_client_mfa::ClientMfaServer, - enrollment::EnrollmentServer, - password_reset::PasswordResetServer, proto::core_response, + proxy::ProxyHandler, }; #[cfg(feature = "worker")] use self::{ @@ -61,12 +60,11 @@ use crate::{auth::ClaimsType, db::GatewayEvent}; mod auth; mod desktop_client_mfa; -pub mod enrollment; #[cfg(feature = "wireguard")] pub(crate) mod gateway; #[cfg(any(feature = "wireguard", feature = "worker"))] mod interceptor; -pub mod password_reset; +mod proxy; pub(crate) mod utils; #[cfg(feature = "worker")] pub mod worker; @@ -355,14 +353,12 @@ pub async fn run_grpc_bidi_stream( ) -> Result<(), anyhow::Error> { let config = server_config(); - // TODO: merge the two - let enrollment_server = EnrollmentServer::new( + let proxy_handler = ProxyHandler::new( pool.clone(), wireguard_tx.clone(), mail_tx.clone(), user_agent_parser, ); - let password_reset_server = PasswordResetServer::new(pool.clone(), mail_tx.clone()); let mut client_mfa_server = ClientMfaServer::new(pool.clone(), mail_tx, wireguard_tx); let polling_server = PollingServer::new(pool); @@ -405,7 +401,7 @@ pub async fn run_grpc_bidi_stream( let payload = match received.payload { // rpc StartEnrollment (EnrollmentStartRequest) returns (EnrollmentStartResponse) Some(core_request::Payload::EnrollmentStart(request)) => { - match enrollment_server.start_enrollment(request).await { + match proxy_handler.start_enrollment(request).await { Ok(response_payload) => { Some(core_response::Payload::EnrollmentStart(response_payload)) } @@ -417,7 +413,7 @@ pub async fn run_grpc_bidi_stream( } // rpc ActivateUser (ActivateUserRequest) returns (google.protobuf.Empty) Some(core_request::Payload::ActivateUser(request)) => { - match enrollment_server + match proxy_handler .activate_user(request, received.device_info) .await { @@ -430,7 +426,7 @@ pub async fn run_grpc_bidi_stream( } // rpc CreateDevice (NewDevice) returns (DeviceConfigResponse) Some(core_request::Payload::NewDevice(request)) => { - match enrollment_server + match proxy_handler .create_device(request, received.device_info) .await { @@ -445,7 +441,7 @@ pub async fn run_grpc_bidi_stream( } // rpc GetNetworkInfo (ExistingDevice) returns (DeviceConfigResponse) Some(core_request::Payload::ExistingDevice(request)) => { - match enrollment_server.get_network_info(request).await { + match proxy_handler.get_network_info(request).await { Ok(response_payload) => { Some(core_response::Payload::DeviceConfig(response_payload)) } @@ -457,7 +453,7 @@ pub async fn run_grpc_bidi_stream( } // rpc RequestPasswordReset (PasswordResetInitializeRequest) returns (google.protobuf.Empty) Some(core_request::Payload::PasswordResetInit(request)) => { - match password_reset_server + match proxy_handler .request_password_reset(request, received.device_info) .await { @@ -470,7 +466,7 @@ pub async fn run_grpc_bidi_stream( } // rpc StartPasswordReset (PasswordResetStartRequest) returns (PasswordResetStartResponse) Some(core_request::Payload::PasswordResetStart(request)) => { - match password_reset_server.start_password_reset(request).await { + match proxy_handler.start_password_reset(request).await { Ok(response_payload) => Some( core_response::Payload::PasswordResetStart(response_payload), ), @@ -482,7 +478,7 @@ pub async fn run_grpc_bidi_stream( } // rpc ResetPassword (PasswordResetRequest) returns (google.protobuf.Empty) Some(core_request::Payload::PasswordReset(request)) => { - match password_reset_server + match proxy_handler .reset_password(request, received.device_info) .await { @@ -578,11 +574,11 @@ pub async fn run_grpc_server( WorkerServer::new(pool.clone(), worker_state), JwtInterceptor::new(ClaimsType::YubiBridge), ); - #[cfg(feature = "wireguard")] - let gateway_service = GatewayServiceServer::with_interceptor( - GatewayServer::new(pool, gateway_state, wireguard_tx, mail_tx), - JwtInterceptor::new(ClaimsType::Gateway), - ); + // #[cfg(feature = "wireguard")] + // let gateway_service = GatewayServiceServer::with_interceptor( + // GatewayServer::new(pool, gateway_state, wireguard_tx, mail_tx), + // JwtInterceptor::new(ClaimsType::Gateway), + // ); let (mut health_reporter, health_service) = tonic_health::server::health_reporter(); health_reporter @@ -603,11 +599,12 @@ pub async fn run_grpc_server( .tcp_keepalive(Some(TEN_SECS)) .add_service(health_service) .add_service(auth_service); - #[cfg(feature = "wireguard")] - let router = router.add_service(gateway_service); + // #[cfg(feature = "wireguard")] + // let router = router.add_service(gateway_service); #[cfg(feature = "worker")] let router = router.add_service(worker_service); router.serve(addr).await?; + info!("gRPC server started on {addr}"); Ok(()) } diff --git a/src/grpc/password_reset.rs b/src/grpc/password_reset.rs deleted file mode 100644 index 6a5516c16..000000000 --- a/src/grpc/password_reset.rs +++ /dev/null @@ -1,271 +0,0 @@ -use sqlx::PgPool; -use tokio::sync::mpsc::UnboundedSender; -use tonic::Status; - -use super::proto::{ - DeviceInfo, PasswordResetInitializeRequest, PasswordResetRequest, PasswordResetStartRequest, - PasswordResetStartResponse, -}; -use crate::{ - db::{ - models::enrollment::{Token, PASSWORD_RESET_TOKEN_TYPE}, - User, - }, - handlers::{ - mail::{send_password_reset_email, send_password_reset_success_email}, - user::check_password_strength, - }, - ldap::utils::ldap_change_password, - mail::Mail, - server_config, -}; - -pub(super) struct PasswordResetServer { - pool: PgPool, - mail_tx: UnboundedSender, - // ldap_feature_active: bool, -} - -impl PasswordResetServer { - #[must_use] - pub fn new(pool: PgPool, mail_tx: UnboundedSender) -> Self { - // FIXME: check if LDAP feature is enabled - // let ldap_feature_active = true; - Self { - pool, - mail_tx, - // ldap_feature_active, - } - } - - /// Checks if token provided with request corresponds to a valid password reset session - async fn validate_session(&self, token: &Option) -> Result { - info!("Validating password reset session. Token: {token:?}"); - let Some(token) = token else { - error!("Missing authorization header in request"); - return Err(Status::unauthenticated("Missing authorization header")); - }; - let enrollment = Token::find_by_id(&self.pool, token).await?; - debug!("Found matching token, verifying validity: {enrollment:?}."); - if !enrollment - .token_type - .as_ref() - .is_some_and(|token_type| token_type == PASSWORD_RESET_TOKEN_TYPE) - { - error!( - "Invalid token type used in password reset process: {:?}", - enrollment.token_type - ); - return Err(Status::permission_denied("invalid token")); - } - - if enrollment.is_session_valid(server_config().enrollment_session_timeout.as_secs()) { - info!("Password reset session validated: {enrollment:?}.",); - Ok(enrollment) - } else { - error!("Password reset session expired: {enrollment:?}"); - Err(Status::unauthenticated("Session expired")) - } - } - - pub async fn request_password_reset( - &self, - request: PasswordResetInitializeRequest, - req_device_info: Option, - ) -> Result<(), Status> { - let config = server_config(); - debug!("Starting password reset request"); - - let ip_address; - let user_agent; - if let Some(info) = req_device_info { - ip_address = info.ip_address.unwrap_or_default(); - user_agent = info.user_agent.unwrap_or_default(); - } else { - ip_address = String::new(); - user_agent = String::new(); - } - - let email = request.email; - - let user = User::find_by_email(&self.pool, email.to_string().as_str()) - .await - .map_err(|_| { - error!("Failed to fetch user by email: {email}"); - Status::internal("unexpected error") - })?; - - let Some(user) = user else { - // Do not return information whether user exists - debug!("Password reset skipped for non-existing user {email}"); - return Ok(()); - }; - - // Do not allow password change if user is disabled or not enrolled - if !user.has_password() || !user.is_active { - debug!( - "Password reset skipped for disabled or not enrolled user {} ({email})", - user.username - ); - return Ok(()); - } - - let mut transaction = self.pool.begin().await.map_err(|_| { - error!("Failed to begin transaction"); - Status::internal("unexpected error") - })?; - - Token::delete_unused_user_password_reset_tokens(&mut transaction, user.id).await?; - - let enrollment = Token::new( - user.id, - None, - Some(email.clone()), - config.password_reset_token_timeout.as_secs(), - Some(PASSWORD_RESET_TOKEN_TYPE.to_string()), - ); - enrollment.save(&mut transaction).await?; - - transaction.commit().await.map_err(|_| { - error!("Failed to commit transaction"); - Status::internal("unexpected error") - })?; - - send_password_reset_email( - &user, - &self.mail_tx, - config.enrollment_url.clone(), - &enrollment.id, - Some(&ip_address), - Some(&user_agent), - )?; - - info!( - "Finished processing password reset request for user {}.", - user.username - ); - - Ok(()) - } - - pub async fn start_password_reset( - &self, - request: PasswordResetStartRequest, - ) -> Result { - debug!("Starting password reset session: {request:?}"); - - let mut enrollment = Token::find_by_id(&self.pool, &request.token).await?; - - if enrollment.token_type != Some("PASSWORD_RESET".to_string()) { - error!( - "Invalid token type ({:?}) for password reset session", - enrollment.token_type - ); - return Err(Status::permission_denied("invalid token")); - } - - let user = enrollment.fetch_user(&self.pool).await?; - - if !user.has_password() || !user.is_active { - error!( - "Can't start password reset for a disabled or not enrolled user {}.", - user.username - ); - return Err(Status::permission_denied( - "user disabled or not yet enrolled", - )); - } - - let mut transaction = self.pool.begin().await.map_err(|_| { - error!("Failed to begin transaction"); - Status::internal("unexpected error") - })?; - - let session_deadline = enrollment - .start_session( - &mut transaction, - server_config().password_reset_session_timeout.as_secs(), - ) - .await?; - - let response = PasswordResetStartResponse { - deadline_timestamp: session_deadline.and_utc().timestamp(), - }; - - transaction.commit().await.map_err(|_| { - error!("Failed to commit transaction"); - Status::internal("unexpected error") - })?; - - info!( - "Finished processing password reset session for user {}.", - user.username - ); - - Ok(response) - } - - pub async fn reset_password( - &self, - request: PasswordResetRequest, - req_device_info: Option, - ) -> Result<(), Status> { - debug!("Starting password reset: {request:?}"); - let enrollment = self.validate_session(&request.token).await?; - - let ip_address; - let user_agent; - if let Some(info) = req_device_info { - ip_address = info.ip_address.unwrap_or_default(); - user_agent = info.user_agent.unwrap_or_default(); - } else { - ip_address = String::new(); - user_agent = String::new(); - } - - if let Err(err) = check_password_strength(&request.password) { - error!("Password not strong enough: {err}"); - return Err(Status::invalid_argument("password not strong enough")); - } - - let mut user = enrollment.fetch_user(&self.pool).await?; - - if !user.is_active { - error!( - "Can't reset password for a disabled user {}.", - user.username - ); - return Err(Status::permission_denied("user disabled")); - } - - let mut transaction = self.pool.begin().await.map_err(|_| { - error!("Failed to begin transaction"); - Status::internal("unexpected error") - })?; - - // update user - user.set_password(&request.password); - user.save(&mut *transaction).await.map_err(|err| { - error!("Failed to update user {}: {err}", user.username); - Status::internal("unexpected error") - })?; - - // if self.ldap_feature_active { - let _ = ldap_change_password(&self.pool, &user.username, &request.password).await; - // }; - - transaction.commit().await.map_err(|_| { - error!("Failed to commit transaction"); - Status::internal("unexpected error") - })?; - - send_password_reset_success_email( - &user, - &self.mail_tx, - Some(&ip_address), - Some(&user_agent), - )?; - - Ok(()) - } -} diff --git a/src/grpc/enrollment.rs b/src/grpc/proxy.rs similarity index 58% rename from src/grpc/enrollment.rs rename to src/grpc/proxy.rs index c308d7523..22d2bea5b 100644 --- a/src/grpc/enrollment.rs +++ b/src/grpc/proxy.rs @@ -10,30 +10,37 @@ use super::{ proto::{ ActivateUserRequest, AdminInfo, Device as ProtoDevice, DeviceConfig as ProtoDeviceConfig, DeviceConfigResponse, EnrollmentStartRequest, EnrollmentStartResponse, ExistingDevice, - InitialUserInfo, NewDevice, + InitialUserInfo, NewDevice, PasswordResetInitializeRequest, PasswordResetRequest, + PasswordResetStartRequest, PasswordResetStartResponse, }, + utils::build_device_config_response, InstanceInfo, }; use crate::{ db::{ models::{ device::{DeviceConfig, DeviceInfo}, - enrollment::{Token, TokenError, ENROLLMENT_TOKEN_TYPE}, + enrollment::{Token, TokenError, ENROLLMENT_TOKEN_TYPE, PASSWORD_RESET_TOKEN_TYPE}, polling_token::PollingToken, }, Device, GatewayEvent, Id, Settings, User, }, enterprise::db::models::enterprise_settings::EnterpriseSettings, - grpc::utils::build_device_config_response, - handlers::{mail::send_new_device_added_email, user::check_password_strength}, + handlers::{ + mail::{ + send_new_device_added_email, send_password_reset_email, + send_password_reset_success_email, + }, + user::check_password_strength, + }, headers::get_device_info, - ldap::utils::ldap_add_user, + ldap::utils::{ldap_add_user, ldap_change_password}, mail::Mail, server_config, templates::{self, TemplateLocation}, }; -pub(super) struct EnrollmentServer { +pub(super) struct ProxyHandler { pool: PgPool, wireguard_tx: Sender, mail_tx: UnboundedSender, @@ -41,7 +48,7 @@ pub(super) struct EnrollmentServer { ldap_feature_active: bool, } -impl EnrollmentServer { +impl ProxyHandler { #[must_use] pub fn new( pool: PgPool, @@ -61,30 +68,30 @@ impl EnrollmentServer { } /// Checks if token provided with request corresponds to a valid enrollment session - async fn validate_session(&self, token: &Option) -> Result { + async fn validate_enrollment_session(&self, token: &Option) -> Result { info!("Validating enrollment session. Token: {token:?}"); let Some(token) = token else { error!("Missing authorization header in request"); return Err(Status::unauthenticated("Missing authorization header")); }; - let enrollment = Token::find_by_id(&self.pool, token).await?; - debug!("Found matching token, verifying validity: {enrollment:?}."); - if !enrollment + let token = Token::find_by_id(&self.pool, token).await?; + debug!("Found matching token, verifying validity: {token:?}."); + if !token .token_type .as_ref() .is_some_and(|token_type| token_type == ENROLLMENT_TOKEN_TYPE) { error!( "Invalid token type used in enrollment process: {:?}", - enrollment.token_type + token.token_type ); return Err(Status::permission_denied("invalid token")); } - if enrollment.is_session_valid(server_config().enrollment_session_timeout.as_secs()) { - info!("Enrollment session validated: {enrollment:?}"); - Ok(enrollment) + if token.is_session_valid(server_config().enrollment_session_timeout.as_secs()) { + info!("Enrollment session validated: {token:?}"); + Ok(token) } else { - error!("Enrollment session expired: {enrollment:?}"); + error!("Enrollment session expired: {token:?}"); Err(Status::unauthenticated("Session expired")) } } @@ -103,145 +110,140 @@ impl EnrollmentServer { debug!("Starting enrollment session, request: {request:?}"); // fetch enrollment token debug!("Try to find an enrollment token {}.", request.token); - let mut enrollment = Token::find_by_id(&self.pool, &request.token).await?; + let mut token = Token::find_by_id(&self.pool, &request.token).await?; - if let Some(token_type) = &enrollment.token_type { - if token_type != ENROLLMENT_TOKEN_TYPE { - error!("Invalid token type used while trying to start enrollment: {token_type}"); - return Err(Status::permission_denied("invalid token")); - } + let Some(token_type) = &token.token_type else { + debug!("Invalid enrollment token, the token does not have specified type."); + return Err(Status::permission_denied("invalid token")); + }; + + if token_type != ENROLLMENT_TOKEN_TYPE { + error!("Invalid token type used while trying to start enrollment: {token_type}"); + return Err(Status::permission_denied("invalid token")); + } - // fetch related users - let user = enrollment.fetch_user(&self.pool).await?; - let admin = enrollment.fetch_admin(&self.pool).await?; + // fetch related users + let user = token.fetch_user(&self.pool).await?; + let admin = token.fetch_admin(&self.pool).await?; - debug!( - "Checking if user {}({:?}) is active", - user.username, user.id - ); - if !user.is_active { - warn!( - "Can't start enrollment for disabled user {}.", - user.username - ); - return Err(Status::permission_denied("user is disabled")); - }; - info!( - "User {}({:?}) is active, proceeding with enrollment", - user.username, user.id + debug!("Checking if user {}({}) is active", user.username, user.id); + if !user.is_active { + warn!( + "Can't start enrollment for disabled user {}.", + user.username ); + return Err(Status::permission_denied("user is disabled")); + }; + info!( + "User {}({}) is active, proceeding with enrollment", + user.username, user.id + ); - let mut transaction = self.pool.begin().await.map_err(|err| { - error!("Failed to begin a transaction for enrollment: {err}"); + let mut transaction = self.pool.begin().await.map_err(|err| { + error!("Failed to begin a transaction for enrollment: {err}"); + Status::internal("unexpected error") + })?; + + // validate token & start session + debug!( + "Validating enrollment token and starting session for user {}({})", + user.username, user.id, + ); + let session_deadline = token + .start_session( + &mut transaction, + server_config().enrollment_session_timeout.as_secs(), + ) + .await?; + info!( + "Enrollment session started for user {}({})", + user.username, user.id + ); + + debug!( + "Retrieving settings for enrollment of user {}({}).", + user.username, user.id + ); + let settings = Settings::get_settings(&mut *transaction) + .await + .map_err(|err| { + error!("Failed to get settings: {err}"); Status::internal("unexpected error") })?; + debug!("Settings: {settings:?}"); - // validate token & start session - debug!( - "Validating enrollment token and starting session for user {}({:?})", - user.username, user.id, - ); - let session_deadline = enrollment - .start_session( - &mut transaction, - server_config().enrollment_session_timeout.as_secs(), - ) - .await?; - info!( - "Enrollment session started for user {}({:?})", - user.username, user.id - ); - - debug!( - "Retrieving settings for enrollment of user {}({:?}).", - user.username, user.id - ); - let settings = Settings::get_settings(&mut *transaction) + debug!( + "Retrieving enterprise settings for enrollment of user {}({}).", + user.username, user.id + ); + let enterprise_settings = + EnterpriseSettings::get(&mut *transaction) .await .map_err(|err| { - error!("Failed to get settings: {err}"); + error!("Failed to get enterprise settings: {err}"); Status::internal("unexpected error") })?; - debug!("Settings: {settings:?}"); + debug!("Enterprise settings: {enterprise_settings:?}"); - debug!( - "Retrieving enterprise settings for enrollment of user {}({:?}).", - user.username, user.id - ); - let enterprise_settings = - EnterpriseSettings::get(&mut *transaction) - .await - .map_err(|err| { - error!("Failed to get enterprise settings: {err}"); - Status::internal("unexpected error") - })?; - debug!("Enterprise settings: {enterprise_settings:?}"); - - let vpn_setup_optional = settings.enrollment_vpn_step_optional; - debug!( - "Retrieving instance info for user {}({:?}).", - user.username, user.id - ); - let instance_info = InstanceInfo::new(settings, &user.username, &enterprise_settings); - debug!("Instance info {instance_info:?}"); + let vpn_setup_optional = settings.enrollment_vpn_step_optional; + debug!( + "Retrieving instance info for user {}({}).", + user.username, user.id + ); + let instance_info = InstanceInfo::new(settings, &user.username, &enterprise_settings); + debug!("Instance info {instance_info:?}"); - debug!( - "Preparing initial user info to send for user enrollment, user {}({:?}).", - user.username, user.id - ); - let (username, user_id) = (user.username.clone(), user.id); - let user_info = InitialUserInfo::from_user(&self.pool, user) + debug!( + "Preparing initial user info to send for user enrollment, user {}({}).", + user.username, user.id + ); + let (username, user_id) = (user.username.clone(), user.id); + let user_info = InitialUserInfo::from_user(&self.pool, user) + .await + .map_err(|err| { + error!( + "Failed to get user info for user {}({}): {err}", + username, user_id, + ); + Status::internal("unexpected error") + })?; + debug!("User info {user_info:?}"); + + debug!("Trying to get basic admin info..."); + let admin_info = admin.map(AdminInfo::from); + debug!("Admin info {admin_info:?}"); + + debug!( + "Creating enrollment start response for user {}({}).", + username, user_id, + ); + let enterprise_settings = + EnterpriseSettings::get(&mut *transaction) .await .map_err(|err| { - error!( - "Failed to get user info for user {}({:?}): {err}", - username, user_id, - ); + error!("Failed to get enterprise settings: {err}"); Status::internal("unexpected error") })?; - debug!("User info {user_info:?}"); - - debug!("Trying to get basic admin info..."); - let admin_info = admin.map(AdminInfo::from); - debug!("Admin info {admin_info:?}"); + let enrollment_settings = super::proto::Settings { + vpn_setup_optional, + only_client_activation: enterprise_settings.only_client_activation, + }; + let response = super::proto::EnrollmentStartResponse { + admin: admin_info, + user: Some(user_info), + deadline_timestamp: session_deadline.and_utc().timestamp(), + final_page_content: token.get_welcome_page_content(&mut transaction).await?, + instance: Some(instance_info.into()), + settings: Some(enrollment_settings), + }; + debug!("Response {response:?}"); - debug!( - "Creating enrollment start response for user {}({:?}).", - username, user_id, - ); - let enterprise_settings = - EnterpriseSettings::get(&mut *transaction) - .await - .map_err(|err| { - error!("Failed to get enterprise settings: {err}"); - Status::internal("unexpected error") - })?; - let enrollment_settings = super::proto::Settings { - vpn_setup_optional, - only_client_activation: enterprise_settings.only_client_activation, - }; - let response = super::proto::EnrollmentStartResponse { - admin: admin_info, - user: Some(user_info), - deadline_timestamp: session_deadline.and_utc().timestamp(), - final_page_content: enrollment - .get_welcome_page_content(&mut transaction) - .await?, - instance: Some(instance_info.into()), - settings: Some(enrollment_settings), - }; - debug!("Response {response:?}"); - - transaction.commit().await.map_err(|err| { - error!("Failed to commit transaction: {err}"); - Status::internal("unexpected error") - })?; + transaction.commit().await.map_err(|err| { + error!("Failed to commit transaction: {err}"); + Status::internal("unexpected error") + })?; - Ok(response) - } else { - debug!("Invalid enrollment token, the token does not have specified type."); - Err(Status::permission_denied("invalid token")) - } + Ok(response) } pub async fn activate_user( @@ -250,7 +252,7 @@ impl EnrollmentServer { req_device_info: Option, ) -> Result<(), Status> { debug!("Activating user account: {request:?}"); - let enrollment = self.validate_session(&request.token).await?; + let enrollment = self.validate_enrollment_session(&request.token).await?; let ip_address; let device_info; @@ -262,7 +264,7 @@ impl EnrollmentServer { ip_address = String::new(); device_info = None; } - debug!("Ip address {}, device info {device_info:?}", ip_address); + debug!("IP address {}, device info {device_info:?}", ip_address); // check if password is strong enough debug!("Verifying password strength for user activation process."); @@ -370,19 +372,16 @@ impl EnrollmentServer { req_device_info: Option, ) -> Result { debug!("Adding new user device: {request:?}"); - let enrollment = self.validate_session(&request.token).await?; + let enrollment = self.validate_enrollment_session(&request.token).await?; // fetch related users let user = enrollment.fetch_user(&self.pool).await?; // add device - debug!( - "Verifying if user {}({:?}) is active", - user.username, user.id - ); + debug!("Verifying if user {}({}) is active", user.username, user.id); if !user.is_active { error!( - "Can't create device for disabled user {}({:?})", + "Can't create device for disabled user {}({})", user.username, user.id ); return Err(Status::invalid_argument( @@ -390,7 +389,7 @@ impl EnrollmentServer { )); } info!( - "User {}({:?}) is active, proceeding with device creation, pubkey: {}", + "User {}({}) is active, proceeding with device creation, pubkey: {}", user.username, user.id, request.pubkey ); @@ -404,27 +403,27 @@ impl EnrollmentServer { ip_address = String::new(); device_info = None; } - debug!("Ip address {}, device info {device_info:?}", ip_address); + debug!("IP address {}, device info {device_info:?}", ip_address); debug!( - "Validating pubkey {} for device creation process for user {}({:?})", + "Validating pubkey {} for device creation process for user {}({})", request.pubkey, user.username, user.id, ); Device::validate_pubkey(&request.pubkey).map_err(|err| { error!( - "Invalid pubkey {}, device won't be created for user {}({:?}): {err}", + "Invalid pubkey {}, device won't be created for user {}({}): {err}", request.pubkey, user.username, user.id ); Status::invalid_argument("invalid pubkey") })?; info!( - "Pubkey {} is valid for device creation process for user {}({:?})", + "Pubkey {} is valid for device creation process for user {}({})", request.pubkey, user.username, user.id ); // Make sure there is no device with the same pubkey, such state may lead to unexpected issues debug!( - "Checking pubkey {} uniqueness for device creation process for user {}({:?}).", + "Checking pubkey {} uniqueness for device creation process for user {}({}).", request.pubkey, user.username, user.id, ); if let Some(device) = Device::find_by_pubkey(&self.pool, &request.pubkey) @@ -438,7 +437,7 @@ impl EnrollmentServer { })? { warn!( - "User {}({:?}) failed to add device {}, identical pubkey ({}) already exists for device {}", + "User {}({}) failed to add device {}, identical pubkey ({}) already exists for device {}", user.username, user.id, request.name, @@ -448,7 +447,7 @@ impl EnrollmentServer { return Err(Status::invalid_argument("invalid key")); }; info!( - "Pubkey {} is unique for device creation process for user {}({:?}).", + "Pubkey {} is unique for device creation process for user {}({}).", request.pubkey, user.username, user.id ); @@ -458,7 +457,7 @@ impl EnrollmentServer { enrollment.user_id, ); debug!( - "Creating new device for user {}({:?}) {device:?}.", + "Creating new device for user {}({}) {device:?}.", user.username, user.id, ); @@ -468,7 +467,7 @@ impl EnrollmentServer { })?; let device = device.save(&mut *transaction).await.map_err(|err| { error!( - "Failed to save device {}, pubkey {} for user {}({:?}): {err}", + "Failed to save device {}, pubkey {} for user {}({}): {err}", request.name, request.pubkey, user.username, user.id, ); Status::internal("unexpected error") @@ -476,7 +475,7 @@ impl EnrollmentServer { info!("New device created: {device:?}."); debug!( - "Adding device {} to all existing user networks for user {}({:?}).", + "Adding device {} to all existing user networks for user {}({}).", device.wireguard_pubkey, user.username, user.id, ); let (network_info, configs) = @@ -492,11 +491,11 @@ impl EnrollmentServer { })?; info!( - "Added device {} to all existing user networks for user {}({:?})", + "Added device {} to all existing user networks for user {}({})", device.wireguard_pubkey, user.username, user.id ); debug!( - "Sending DeviceCreated event to gateway for device {}, user {}({:?})", + "Sending DeviceCreated event to gateway for device {}, user {}({})", device.wireguard_pubkey, user.username, user.id, ); self.send_wireguard_event(GatewayEvent::DeviceCreated(DeviceInfo { @@ -504,19 +503,19 @@ impl EnrollmentServer { network_info, })); info!( - "Sent DeviceCreated event to gateway for device {}, user {}({:?})", + "Sent DeviceCreated event to gateway for device {}, user {}({})", device.wireguard_pubkey, user.username, user.id, ); debug!( - "Fetching settings for device {} creation process for user {}({:?})", + "Fetching settings for device {} creation process for user {}({})", device.wireguard_pubkey, user.username, user.id, ); let settings = Settings::get_settings(&mut *transaction) .await .map_err(|err| { error!( - "Failed to fetch settings for device {} creation process for user {}({:?}): {err}", + "Failed to fetch settings for device {} creation process for user {}({}): {err}", device.wireguard_pubkey, user.username, user.id, ); Status::internal("unexpected error") @@ -524,14 +523,14 @@ impl EnrollmentServer { debug!("Settings: {settings:?}"); debug!( - "Fetching enterprise settings for device {} creation process for user {}({:?})", + "Fetching enterprise settings for device {} creation process for user {}({})", device.wireguard_pubkey, user.username, user.id, ); let enterprise_settings = EnterpriseSettings::get(&mut *transaction) .await .map_err(|err| { error!( - "Failed to fetch enterprise settings for device {} creation process for user {}({:?}): {err}", + "Failed to fetch enterprise settings for device {} creation process for user {}({}): {err}", device.wireguard_pubkey, user.username, user.id, ); Status::internal("unexpected error") @@ -540,7 +539,7 @@ impl EnrollmentServer { // create polling token for further client communication debug!( - "Creating polling token for further client communication for device {}, user {}({:?})", + "Creating polling token for further client communication for device {}, user {}({})", device.wireguard_pubkey, user.username, user.id, ); let token = PollingToken::new(device.id) @@ -548,19 +547,19 @@ impl EnrollmentServer { .await .map_err(|err| { error!( - "Failed to save PollingToken for device {}, user {}({:?}): {err}", + "Failed to save PollingToken for device {}, user {}({}): {err}", device.wireguard_pubkey, user.username, user.id ); Status::internal("failed to save polling token") })?; info!( - "Created polling token for further client communication for device: {}, user {}({:?})", + "Created polling token for further client communication for device: {}, user {}({})", device.wireguard_pubkey, user.username, user.id, ); transaction.commit().await.map_err(|err| { error!( - "Failed to commit transaction, device {} won't be created for user {}({:?}): {err}", + "Failed to commit transaction, device {} won't be created for user {}({}): {err}", device.wireguard_pubkey, user.username, user.id, ); Status::internal("unexpected error") @@ -575,7 +574,7 @@ impl EnrollmentServer { .collect(); debug!( - "Sending device created mail for device {}, user {}({:?})", + "Sending device created mail for device {}, user {}({})", device.wireguard_pubkey, user.username, user.id ); send_new_device_added_email( @@ -590,7 +589,7 @@ impl EnrollmentServer { .map_err(|_| Status::internal("error rendering email template"))?; info!( - "Device {} assigned to user {}({:?}) and added to all networks.", + "Device {} assigned to user {}({}) and added to all networks.", device.name, user.username, user.id, ); @@ -613,10 +612,248 @@ impl EnrollmentServer { request: ExistingDevice, ) -> Result { debug!("Getting network info for device: {:?}", request.pubkey); - let _token = self.validate_session(&request.token).await?; + let _token = self.validate_enrollment_session(&request.token).await?; build_device_config_response(&self.pool, &request.pubkey, true).await } + + /// Checks if token provided with request corresponds to a valid password reset session + async fn validate_password_reset_session( + &self, + token: &Option, + ) -> Result { + info!("Validating password reset session. Token: {token:?}"); + let Some(token) = token else { + error!("Missing authorization header in request"); + return Err(Status::unauthenticated("Missing authorization header")); + }; + let token = Token::find_by_id(&self.pool, token).await?; + debug!("Found matching token, verifying validity: {token:?}."); + if !token + .token_type + .as_ref() + .is_some_and(|token_type| token_type == PASSWORD_RESET_TOKEN_TYPE) + { + error!( + "Invalid token type used in password reset process: {:?}", + token.token_type + ); + return Err(Status::permission_denied("invalid token")); + } + + if token.is_session_valid(server_config().enrollment_session_timeout.as_secs()) { + info!("Password reset session validated: {token:?}.",); + Ok(token) + } else { + error!("Password reset session expired: {token:?}"); + Err(Status::unauthenticated("Session expired")) + } + } + + pub async fn request_password_reset( + &self, + request: PasswordResetInitializeRequest, + req_device_info: Option, + ) -> Result<(), Status> { + let config = server_config(); + debug!("Starting password reset request"); + + let ip_address; + let user_agent; + if let Some(info) = req_device_info { + ip_address = info.ip_address.unwrap_or_default(); + user_agent = info.user_agent.unwrap_or_default(); + } else { + ip_address = String::new(); + user_agent = String::new(); + } + + let email = request.email; + + let user = User::find_by_email(&self.pool, email.to_string().as_str()) + .await + .map_err(|_| { + error!("Failed to fetch user by email: {email}"); + Status::internal("unexpected error") + })?; + + let Some(user) = user else { + // Do not return information whether user exists + debug!("Password reset skipped for non-existing user {email}"); + return Ok(()); + }; + + // Do not allow password change if user is disabled or not enrolled + if !user.has_password() || !user.is_active { + debug!( + "Password reset skipped for disabled or not enrolled user {} ({email})", + user.username + ); + return Ok(()); + } + + let mut transaction = self.pool.begin().await.map_err(|_| { + error!("Failed to begin transaction"); + Status::internal("unexpected error") + })?; + + Token::delete_unused_user_password_reset_tokens(&mut transaction, user.id).await?; + + let enrollment = Token::new( + user.id, + None, + Some(email.clone()), + config.password_reset_token_timeout.as_secs(), + Some(PASSWORD_RESET_TOKEN_TYPE.to_string()), + ); + enrollment.save(&mut transaction).await?; + + transaction.commit().await.map_err(|_| { + error!("Failed to commit transaction"); + Status::internal("unexpected error") + })?; + + send_password_reset_email( + &user, + &self.mail_tx, + config.enrollment_url.clone(), + &enrollment.id, + Some(&ip_address), + Some(&user_agent), + )?; + + info!( + "Finished processing password reset request for user {}.", + user.username + ); + + Ok(()) + } + + pub async fn start_password_reset( + &self, + request: PasswordResetStartRequest, + ) -> Result { + debug!("Starting password reset session: {request:?}"); + + let mut token = Token::find_by_id(&self.pool, &request.token).await?; + + if !token + .token_type + .as_ref() + .is_some_and(|token_type| token_type == PASSWORD_RESET_TOKEN_TYPE) + { + error!( + "Invalid token type ({:?}) for password reset session", + token.token_type + ); + return Err(Status::permission_denied("invalid token")); + } + + let user = token.fetch_user(&self.pool).await?; + + if !user.has_password() || !user.is_active { + error!( + "Can't start password reset for a disabled or not enrolled user {}.", + user.username + ); + return Err(Status::permission_denied( + "user disabled or not yet enrolled", + )); + } + + let mut transaction = self.pool.begin().await.map_err(|_| { + error!("Failed to begin transaction"); + Status::internal("unexpected error") + })?; + + let session_deadline = token + .start_session( + &mut transaction, + server_config().password_reset_session_timeout.as_secs(), + ) + .await?; + + let response = PasswordResetStartResponse { + deadline_timestamp: session_deadline.and_utc().timestamp(), + }; + + transaction.commit().await.map_err(|_| { + error!("Failed to commit transaction"); + Status::internal("unexpected error") + })?; + + info!( + "Finished processing password reset session for user {}.", + user.username + ); + + Ok(response) + } + + pub async fn reset_password( + &self, + request: PasswordResetRequest, + req_device_info: Option, + ) -> Result<(), Status> { + debug!("Starting password reset: {request:?}"); + let enrollment = self.validate_password_reset_session(&request.token).await?; + + let ip_address; + let user_agent; + if let Some(info) = req_device_info { + ip_address = info.ip_address.unwrap_or_default(); + user_agent = info.user_agent.unwrap_or_default(); + } else { + ip_address = String::new(); + user_agent = String::new(); + } + + if let Err(err) = check_password_strength(&request.password) { + error!("Password not strong enough: {err}"); + return Err(Status::invalid_argument("password not strong enough")); + } + + let mut user = enrollment.fetch_user(&self.pool).await?; + + if !user.is_active { + error!( + "Can't reset password for a disabled user {}.", + user.username + ); + return Err(Status::permission_denied("user disabled")); + } + + let mut transaction = self.pool.begin().await.map_err(|_| { + error!("Failed to begin transaction"); + Status::internal("unexpected error") + })?; + + // update user + user.set_password(&request.password); + user.save(&mut *transaction).await.map_err(|err| { + error!("Failed to update user {}: {err}", user.username); + Status::internal("unexpected error") + })?; + + // if self.ldap_feature_active { + let _ = ldap_change_password(&self.pool, &user.username, &request.password).await; + // }; + + transaction.commit().await.map_err(|_| { + error!("Failed to commit transaction"); + Status::internal("unexpected error") + })?; + + send_password_reset_success_email( + &user, + &self.mail_tx, + Some(&ip_address), + Some(&user_agent), + )?; + + Ok(()) + } } impl From> for AdminInfo { diff --git a/src/mail.rs b/src/mail.rs index 6b93b326f..8b7845d2c 100644 --- a/src/mail.rs +++ b/src/mail.rs @@ -181,7 +181,7 @@ impl MailHandler { // Construct lettre Message let result_tx = mail.result_tx.clone(); - let message: Message = match mail.into_message(&settings.sender) { + let message = match mail.into_message(&settings.sender) { Ok(message) => message, Err(err) => { error!("Failed to build message to: {to}, subject: {subject}, error: {err}"); diff --git a/src/wireguard_peer_disconnect.rs b/src/wireguard_peer_disconnect.rs index e8d0fc0d4..723ce524c 100644 --- a/src/wireguard_peer_disconnect.rs +++ b/src/wireguard_peer_disconnect.rs @@ -48,9 +48,8 @@ pub async fn run_periodic_peer_disconnect( // get all MFA-protected locations let locations = query_as!( WireguardNetwork::, - "SELECT \ - id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, \ - connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold \ + "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, \ + connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold, gateways \ FROM wireguard_network WHERE mfa_enabled = true", ) .fetch_all(&pool) @@ -62,20 +61,20 @@ pub async fn run_periodic_peer_disconnect( let devices = query_as!( Device, "WITH stats AS ( \ - SELECT DISTINCT ON (device_id) device_id, endpoint, latest_handshake \ - FROM wireguard_peer_stats \ - WHERE network = $1 \ - ORDER BY device_id, collected_at DESC \ - ) \ + SELECT DISTINCT ON (device_id) device_id, endpoint, latest_handshake \ + FROM wireguard_peer_stats \ + WHERE network = $1 \ + ORDER BY device_id, collected_at DESC \ + ) \ SELECT d.id, d.name, d.wireguard_pubkey, d.user_id, d.created \ FROM device d \ JOIN wireguard_network_device wnd ON wnd.device_id = d.id \ LEFT JOIN stats on d.id = stats.device_id \ WHERE wnd.wireguard_network_id = $1 AND wnd.is_authorized = true AND \ - (wnd.authorized_at IS NULL OR (NOW() - wnd.authorized_at) > $2 * interval '1 second') AND \ - (stats.latest_handshake IS NULL OR (NOW() - stats.latest_handshake) > $2 * interval '1 second')", + (wnd.authorized_at IS NULL OR (NOW() - wnd.authorized_at) > $2 * interval '1s') AND \ + (stats.latest_handshake IS NULL OR (NOW() - stats.latest_handshake) > $2 * interval '1s')", location.id, - f64::from(location.peer_disconnect_threshold) + f64::from(location.peer_disconnect_threshold) ) .fetch_all(&pool) .await?; From 0a7719441e085b0d7e8a57ffb290469d2a3875b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Tue, 15 Oct 2024 13:17:13 +0200 Subject: [PATCH 02/26] Gateways is a list of string --- ...cb7387eca5822e9cc45205bcbc0d2fcb21d97.json | 2 +- ...9105d0f94ca2d204e25148b63b833ba69459b.json | 2 +- ...73aa9c95ce849f71f2a36d10797fa5cf8f834.json | 2 +- ...4f15e69dbf56925fed7a2ae98f449cc23a815.json | 2 +- ...10219bd0eb14a5bb95e65844fc919a77fdc3d.json | 2 +- ...04730a4d22fd487a1dc6c13575c0f1aa394f4.json | 2 +- .../20241015074303_network_gateways.up.sql | 2 +- src/db/models/wireguard.rs | 44 +++++++++++++------ src/grpc/mod.rs | 30 +++++-------- src/handlers/wireguard.rs | 9 ++-- src/lib.rs | 5 +-- src/wg_config.rs | 2 +- src/wireguard_peer_disconnect.rs | 12 +---- tests/wireguard_network_import.rs | 3 +- 14 files changed, 60 insertions(+), 59 deletions(-) diff --git a/.sqlx/query-722d953898ad19874bfb026f2a1cb7387eca5822e9cc45205bcbc0d2fcb21d97.json b/.sqlx/query-722d953898ad19874bfb026f2a1cb7387eca5822e9cc45205bcbc0d2fcb21d97.json index 75978ff6c..a12b4aeab 100644 --- a/.sqlx/query-722d953898ad19874bfb026f2a1cb7387eca5822e9cc45205bcbc0d2fcb21d97.json +++ b/.sqlx/query-722d953898ad19874bfb026f2a1cb7387eca5822e9cc45205bcbc0d2fcb21d97.json @@ -71,7 +71,7 @@ { "ordinal": 13, "name": "gateways", - "type_info": "InetArray" + "type_info": "TextArray" } ], "parameters": { diff --git a/.sqlx/query-8f397a1393682f42600ba4799b69105d0f94ca2d204e25148b63b833ba69459b.json b/.sqlx/query-8f397a1393682f42600ba4799b69105d0f94ca2d204e25148b63b833ba69459b.json index 08e7d818c..1c46253a4 100644 --- a/.sqlx/query-8f397a1393682f42600ba4799b69105d0f94ca2d204e25148b63b833ba69459b.json +++ b/.sqlx/query-8f397a1393682f42600ba4799b69105d0f94ca2d204e25148b63b833ba69459b.json @@ -71,7 +71,7 @@ { "ordinal": 13, "name": "gateways", - "type_info": "InetArray" + "type_info": "TextArray" } ], "parameters": { diff --git a/.sqlx/query-d4b301389bd9f8d87517841cd5573aa9c95ce849f71f2a36d10797fa5cf8f834.json b/.sqlx/query-d4b301389bd9f8d87517841cd5573aa9c95ce849f71f2a36d10797fa5cf8f834.json index 1e0fd7119..9388c5467 100644 --- a/.sqlx/query-d4b301389bd9f8d87517841cd5573aa9c95ce849f71f2a36d10797fa5cf8f834.json +++ b/.sqlx/query-d4b301389bd9f8d87517841cd5573aa9c95ce849f71f2a36d10797fa5cf8f834.json @@ -18,7 +18,7 @@ "Bool", "Int4", "Int4", - "InetArray" + "TextArray" ] }, "nullable": [] diff --git a/.sqlx/query-db50a47b12760f342f4856593254f15e69dbf56925fed7a2ae98f449cc23a815.json b/.sqlx/query-db50a47b12760f342f4856593254f15e69dbf56925fed7a2ae98f449cc23a815.json index f927b3022..cb07063fa 100644 --- a/.sqlx/query-db50a47b12760f342f4856593254f15e69dbf56925fed7a2ae98f449cc23a815.json +++ b/.sqlx/query-db50a47b12760f342f4856593254f15e69dbf56925fed7a2ae98f449cc23a815.json @@ -23,7 +23,7 @@ "Bool", "Int4", "Int4", - "InetArray" + "TextArray" ] }, "nullable": [ diff --git a/.sqlx/query-f0bf6cbba9693a015a995f00dac10219bd0eb14a5bb95e65844fc919a77fdc3d.json b/.sqlx/query-f0bf6cbba9693a015a995f00dac10219bd0eb14a5bb95e65844fc919a77fdc3d.json index fa877bf42..a7f9f03ba 100644 --- a/.sqlx/query-f0bf6cbba9693a015a995f00dac10219bd0eb14a5bb95e65844fc919a77fdc3d.json +++ b/.sqlx/query-f0bf6cbba9693a015a995f00dac10219bd0eb14a5bb95e65844fc919a77fdc3d.json @@ -71,7 +71,7 @@ { "ordinal": 13, "name": "gateways: _", - "type_info": "InetArray" + "type_info": "TextArray" } ], "parameters": { diff --git a/.sqlx/query-f568188bc7c8b54ffccad38cee004730a4d22fd487a1dc6c13575c0f1aa394f4.json b/.sqlx/query-f568188bc7c8b54ffccad38cee004730a4d22fd487a1dc6c13575c0f1aa394f4.json index 056328e66..a4c5e6ca4 100644 --- a/.sqlx/query-f568188bc7c8b54ffccad38cee004730a4d22fd487a1dc6c13575c0f1aa394f4.json +++ b/.sqlx/query-f568188bc7c8b54ffccad38cee004730a4d22fd487a1dc6c13575c0f1aa394f4.json @@ -71,7 +71,7 @@ { "ordinal": 13, "name": "gateways: _", - "type_info": "InetArray" + "type_info": "TextArray" } ], "parameters": { diff --git a/migrations/20241015074303_network_gateways.up.sql b/migrations/20241015074303_network_gateways.up.sql index 8dd37e805..9c866c4ef 100644 --- a/migrations/20241015074303_network_gateways.up.sql +++ b/migrations/20241015074303_network_gateways.up.sql @@ -1 +1 @@ -ALTER TABLE wireguard_network ADD COLUMN gateways inet[] NOT NULL DEFAULT array[]::inet[]; +ALTER TABLE wireguard_network ADD COLUMN gateways text[] NOT NULL DEFAULT array[]::text[]; diff --git a/src/db/models/wireguard.rs b/src/db/models/wireguard.rs index 6134a1ac7..0149e1eca 100644 --- a/src/db/models/wireguard.rs +++ b/src/db/models/wireguard.rs @@ -30,8 +30,8 @@ use crate::{ pub const DEFAULT_KEEPALIVE_INTERVAL: i32 = 25; pub const DEFAULT_DISCONNECT_THRESHOLD: i32 = 180; -// Used in process of importing network from wireguard config -#[derive(Clone, Debug, Deserialize, Serialize)] +// Used in process of importing network from WireGuard config +#[derive(Debug, Deserialize, Serialize)] pub struct MappedDevice { pub user_id: Id, pub name: String, @@ -88,8 +88,9 @@ pub struct WireguardNetwork { pub mfa_enabled: bool, pub keepalive_interval: i32, pub peer_disconnect_threshold: i32, + // URLs pointing to all gateways serving gRPC #[model(ref)] - pub gateways: Vec, + pub gateways: Vec, } pub struct WireguardKey { @@ -130,6 +131,7 @@ pub enum WireguardNetworkError { } impl WireguardNetwork { + #[must_use] pub fn new( name: String, address: IpNetwork, @@ -140,10 +142,10 @@ impl WireguardNetwork { mfa_enabled: bool, keepalive_interval: i32, peer_disconnect_threshold: i32, - ) -> Result { + ) -> Self { let prvkey = StaticSecret::random_from_rng(OsRng); let pubkey = PublicKey::from(&prvkey); - Ok(Self { + Self { id: NoId, name, address, @@ -158,7 +160,7 @@ impl WireguardNetwork { keepalive_interval, peer_disconnect_threshold, gateways: Vec::new(), - }) + } } /// Try to set `address` from `&str`. @@ -173,12 +175,12 @@ impl WireguardNetwork { pub async fn find_by_name<'e, E>( executor: E, name: &str, - ) -> Result>, WireguardNetworkError> + ) -> Result>, SqlxError> where E: PgExecutor<'e>, { let networks = query_as!( - WireguardNetwork, + Self, "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, \ connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold, gateways \ FROM wireguard_network WHERE name = $1", @@ -194,6 +196,21 @@ impl WireguardNetwork { }) } + /// Fetch all networks with MFA protection turned on. + pub(crate) async fn all_mfa_enabled<'e, E>(executor: E) -> Result, SqlxError> + where + E: PgExecutor<'e>, + { + query_as!( + Self, + "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, \ + connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold, gateways \ + FROM wireguard_network WHERE mfa_enabled = true", + ) + .fetch_all(executor) + .await + } + /// Run `sync_allowed_devices()` on all WireGuard networks. pub async fn sync_all_networks(app: &AppState) -> Result<(), WireguardNetworkError> { info!("Syncing allowed devices for all WireGuard locations"); @@ -394,7 +411,7 @@ impl WireguardNetwork { Ok(wireguard_network_device) } else { info!("Device {device} not allowed in network {self}"); - Err(WireguardNetworkError::DeviceNotAllowed(format!("{device}"))) + Err(WireguardNetworkError::DeviceNotAllowed(device.to_string())) } } @@ -561,7 +578,7 @@ impl WireguardNetwork { pub async fn handle_mapped_devices( &self, transaction: &mut PgConnection, - mapped_devices: Vec, + mapped_devices: &[MappedDevice], ) -> Result, WireguardNetworkError> { info!("Mapping user devices for network {}", self); // get allowed groups for network @@ -570,7 +587,7 @@ impl WireguardNetwork { let mut events = Vec::new(); // use a helper hashmap to avoid repeated queries let mut user_groups = HashMap::new(); - for mapped_device in &mapped_devices { + for mapped_device in mapped_devices { debug!("Mapping device {}", mapped_device.name); // validate device pubkey Device::validate_pubkey(&mapped_device.wireguard_pubkey).map_err(|_| { @@ -660,8 +677,9 @@ impl WireguardNetwork { ) -> Result>, SqlxError> { let stats = query_as!( WireguardPeerStats, - "SELECT id, device_id \"device_id!\", collected_at \"collected_at!\", network \"network!\", \ - endpoint, upload \"upload!\", download \"download!\", latest_handshake \"latest_handshake!\", allowed_ips \ + "SELECT id, device_id \"device_id!\", collected_at \"collected_at!\", \ + network \"network!\", endpoint, upload \"upload!\", download \"download!\", \ + latest_handshake \"latest_handshake!\", allowed_ips \ FROM wireguard_peer_stats \ WHERE device_id = $1 AND network = $2 \ ORDER BY collected_at DESC \ diff --git a/src/grpc/mod.rs b/src/grpc/mod.rs index 3f812eec0..732e8b1a3 100644 --- a/src/grpc/mod.rs +++ b/src/grpc/mod.rs @@ -374,20 +374,18 @@ pub async fn run_grpc_bidi_stream( } else { endpoint }; + let uri = endpoint.uri(); loop { - debug!("Connecting to proxy at {}", endpoint.uri()); + debug!("Connecting to proxy at {uri}",); let mut client = ProxyClient::new(endpoint.connect_lazy()); let (tx, rx) = mpsc::unbounded_channel(); let Ok(response) = client.bidi(UnboundedReceiverStream::new(rx)).await else { - error!( - "Failed to connect to proxy @ {}, retrying in 10s", - endpoint.uri() - ); + error!("Failed to connect to proxy @ {uri}, retrying in 10s",); sleep(TEN_SECS).await; continue; }; - info!("Connected to proxy at {}", endpoint.uri()); + info!("Connected to proxy at {uri}"); let mut resp_stream = response.into_inner(); 'message: loop { match resp_stream.message().await { @@ -520,18 +518,14 @@ pub async fn run_grpc_bidi_stream( Some(core_response::Payload::InstanceInfo(response_payload)) } Err(err) => { - match err.code() { - // Ignore the case when we are not enterprise but the client is trying to fetch the instance config, - // to avoid spamming the logs with misleading errors. - Code::FailedPrecondition => { - debug!("A client tried to fetch the instance config, but we are not enterprise."); - Some(core_response::Payload::CoreError(err.into())) - } - _ => { - error!("Instance info error {err}"); - Some(core_response::Payload::CoreError(err.into())) - } + // Ignore the case when we are not enterprise but the client is trying to fetch the instance config, + // to avoid spamming the logs with misleading errors. + if err.code() == Code::FailedPrecondition { + debug!("A client tried to fetch the instance config, but we are not enterprise."); + } else { + error!("Instance info error {err}"); } + Some(core_response::Payload::CoreError(err.into())) } } } @@ -545,7 +539,7 @@ pub async fn run_grpc_bidi_stream( tx.send(req).unwrap(); } Err(err) => { - error!("Disconnected from proxy at {}", endpoint.uri()); + error!("Disconnected from proxy at {uri}"); error!("stream error: {err}"); debug!("waiting 10s to re-establish the connection"); sleep(TEN_SECS).await; diff --git a/src/handlers/wireguard.rs b/src/handlers/wireguard.rs index 149433e2d..07969d3e6 100644 --- a/src/handlers/wireguard.rs +++ b/src/handlers/wireguard.rs @@ -62,7 +62,7 @@ impl WireguardNetworkData { } // Used in process of importing network from WireGuard config -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Debug, Deserialize, Serialize)] pub struct MappedDevices { pub devices: Vec, } @@ -114,8 +114,7 @@ pub async fn create_network( data.mfa_enabled, data.keepalive_interval, data.peer_disconnect_threshold, - ) - .map_err(|_| WebError::Serialization("Invalid network address".into()))?; + ); let mut transaction = appstate.pool.begin().await?; let network = network.save(&mut *transaction).await?; @@ -388,7 +387,7 @@ pub async fn add_user_devices( Path(network_id): Path, Json(request_data): Json, ) -> ApiResult { - let mapped_devices = request_data.devices.clone(); + let mapped_devices = request_data.devices; let user = session.user; let device_count = mapped_devices.len(); @@ -410,7 +409,7 @@ pub async fn add_user_devices( // wrap loop in transaction to abort if a device is invalid let mut transaction = appstate.pool.begin().await?; let events = network - .handle_mapped_devices(&mut transaction, mapped_devices) + .handle_mapped_devices(&mut transaction, mapped_devices.as_slice()) .await?; appstate.send_multiple_wireguard_events(events); transaction.commit().await?; diff --git a/src/lib.rs b/src/lib.rs index f3f2f3deb..49522dd0f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -594,8 +594,7 @@ pub async fn init_dev_env(config: &DefGuardConfig) { false, DEFAULT_KEEPALIVE_INTERVAL, DEFAULT_DISCONNECT_THRESHOLD, - ) - .expect("Could not create network"); + ); network.pubkey = "zGMeVGm9HV9I4wSKF9AXmYnnAIhDySyqLMuKpcfIaQo=".to_string(); network.prvkey = "MAk3d5KuB167G88HM7nGYR6ksnPMAOguAg2s5EcPp1M=".to_string(); network @@ -674,7 +673,7 @@ pub async fn init_vpn_location( false, DEFAULT_KEEPALIVE_INTERVAL, DEFAULT_DISCONNECT_THRESHOLD, - )? + ) .save(pool) .await?; diff --git a/src/wg_config.rs b/src/wg_config.rs index 0e65ac62f..8c171e8f4 100644 --- a/src/wg_config.rs +++ b/src/wg_config.rs @@ -94,7 +94,7 @@ pub fn parse_wireguard_config( false, DEFAULT_KEEPALIVE_INTERVAL, DEFAULT_DISCONNECT_THRESHOLD, - )?; + ); network.pubkey = pubkey; network.prvkey = prvkey.to_string(); diff --git a/src/wireguard_peer_disconnect.rs b/src/wireguard_peer_disconnect.rs index 723ce524c..af9ee999f 100644 --- a/src/wireguard_peer_disconnect.rs +++ b/src/wireguard_peer_disconnect.rs @@ -16,7 +16,7 @@ use crate::db::{ error::ModelError, wireguard::WireguardNetworkError, }, - Device, GatewayEvent, Id, WireguardNetwork, + Device, GatewayEvent, WireguardNetwork, }; // How long to sleep between loop iterations @@ -45,15 +45,7 @@ pub async fn run_periodic_peer_disconnect( loop { debug!("Starting periodic inactive device disconnect"); - // get all MFA-protected locations - let locations = query_as!( - WireguardNetwork::, - "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, \ - connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold, gateways \ - FROM wireguard_network WHERE mfa_enabled = true", - ) - .fetch_all(&pool) - .await?; + let locations = WireguardNetwork::all_mfa_enabled(&pool).await?; // loop over all locations for location in locations { diff --git a/tests/wireguard_network_import.rs b/tests/wireguard_network_import.rs index d5e43656f..96fb5a5cd 100644 --- a/tests/wireguard_network_import.rs +++ b/tests/wireguard_network_import.rs @@ -55,8 +55,7 @@ async fn test_config_import() { false, DEFAULT_KEEPALIVE_INTERVAL, DEFAULT_DISCONNECT_THRESHOLD, - ) - .unwrap(); + ); initial_network.save(&pool).await.unwrap(); // add existing devices From c869bc31078c6a533a99863915f11f52600430d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Wed, 16 Oct 2024 15:57:51 +0200 Subject: [PATCH 03/26] WIP: gateway RPC client --- .../20241015074303_network_gateways.down.sql | 2 +- .../20241015074303_network_gateways.up.sql | 6 +- src/bin/defguard.rs | 5 +- src/db/models/wireguard.rs | 11 +- src/grpc/gateway.rs | 84 +++++++++- src/grpc/mod.rs | 145 ++++++++++-------- src/handlers/mail.rs | 4 +- src/handlers/wireguard.rs | 9 +- 8 files changed, 184 insertions(+), 82 deletions(-) diff --git a/migrations/20241015074303_network_gateways.down.sql b/migrations/20241015074303_network_gateways.down.sql index 0197bef93..6bbc938ef 100644 --- a/migrations/20241015074303_network_gateways.down.sql +++ b/migrations/20241015074303_network_gateways.down.sql @@ -1 +1 @@ -ALTER TABLE wireguard_network DROP COLUMN gateways; +DROP TABLE gateway; diff --git a/migrations/20241015074303_network_gateways.up.sql b/migrations/20241015074303_network_gateways.up.sql index 9c866c4ef..000a79a0c 100644 --- a/migrations/20241015074303_network_gateways.up.sql +++ b/migrations/20241015074303_network_gateways.up.sql @@ -1 +1,5 @@ -ALTER TABLE wireguard_network ADD COLUMN gateways text[] NOT NULL DEFAULT array[]::text[]; +CREATE TABLE gateway ( + id bigserial PRIMARY KEY, + network_id bigint NOT NULL, + FOREIGN KEY(network_id) REFERENCES wireguard_network(id) +); diff --git a/src/bin/defguard.rs b/src/bin/defguard.rs index 5626e1ef0..9521ae363 100644 --- a/src/bin/defguard.rs +++ b/src/bin/defguard.rs @@ -8,7 +8,9 @@ use defguard::{ config::{Command, DefGuardConfig}, db::{init_db, AppEvent, GatewayEvent, Settings, User}, enterprise::license::{run_periodic_license_check, set_cached_license, License}, - grpc::{run_grpc_bidi_stream, run_grpc_server, GatewayMap, WorkerState}, + grpc::{ + run_grpc_bidi_stream, run_grpc_gateway_stream, run_grpc_server, GatewayMap, WorkerState, + }, headers::create_user_agent_parser, init_dev_env, init_vpn_location, mail::{run_mail_handler, Mail}, @@ -114,6 +116,7 @@ async fn main() -> Result<(), anyhow::Error> { // run services tokio::select! { + res = run_grpc_gateway_stream(pool.clone()) => error!("Gateway gRPC stream returned early: {res:#?}"), res = run_grpc_bidi_stream(pool.clone(), wireguard_tx.clone(), mail_tx.clone(), user_agent_parser.clone()), if config.proxy_url.is_some() => error!("Proxy gRPC stream returned early: {res:#?}"), res = run_grpc_server(Arc::clone(&worker_state), pool.clone(), Arc::clone(&gateway_map), wireguard_tx.clone(), mail_tx.clone(), grpc_cert, grpc_key, failed_logins.clone()) => error!("gRPC server returned early: {res:#?}"), res = run_web_server(worker_state, gateway_map, webhook_tx, webhook_rx, wireguard_tx.clone(), mail_tx, pool.clone(), user_agent_parser, failed_logins) => error!("Web server returned early: {res:#?}"), diff --git a/src/db/models/wireguard.rs b/src/db/models/wireguard.rs index 0149e1eca..b384a18bb 100644 --- a/src/db/models/wireguard.rs +++ b/src/db/models/wireguard.rs @@ -88,9 +88,6 @@ pub struct WireguardNetwork { pub mfa_enabled: bool, pub keepalive_interval: i32, pub peer_disconnect_threshold: i32, - // URLs pointing to all gateways serving gRPC - #[model(ref)] - pub gateways: Vec, } pub struct WireguardKey { @@ -159,7 +156,6 @@ impl WireguardNetwork { mfa_enabled, keepalive_interval, peer_disconnect_threshold, - gateways: Vec::new(), } } @@ -182,7 +178,7 @@ impl WireguardNetwork { let networks = query_as!( Self, "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, \ - connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold, gateways \ + connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold \ FROM wireguard_network WHERE name = $1", name ) @@ -204,7 +200,7 @@ impl WireguardNetwork { query_as!( Self, "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, \ - connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold, gateways \ + connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold \ FROM wireguard_network WHERE mfa_enabled = true", ) .fetch_all(executor) @@ -959,12 +955,11 @@ impl Default for WireguardNetwork { mfa_enabled: false, keepalive_interval: DEFAULT_KEEPALIVE_INTERVAL, peer_disconnect_threshold: DEFAULT_DISCONNECT_THRESHOLD, - gateways: Vec::default(), } } } -#[derive(Serialize, Clone, Debug)] +#[derive(Debug, Serialize)] pub struct WireguardNetworkInfo { #[serde(flatten)] pub network: WireguardNetwork, diff --git a/src/grpc/gateway.rs b/src/grpc/gateway.rs index 5fedabf81..41ef42192 100644 --- a/src/grpc/gateway.rs +++ b/src/grpc/gateway.rs @@ -1,7 +1,9 @@ use std::{ + fs::read_to_string, pin::Pin, sync::{Arc, Mutex}, task::{Context, Poll}, + time::Duration, }; use chrono::{DateTime, Utc}; @@ -12,9 +14,14 @@ use tokio::{ mpsc::{self, Receiver, UnboundedSender}, }, task::JoinHandle, + time::sleep, +}; +use tokio_stream::{wrappers::UnboundedReceiverStream, Stream}; +use tonic::{ + metadata::MetadataMap, + transport::{Certificate, ClientTlsConfig, Endpoint, Identity, Server}, + Code, Request, Response, Status, }; -use tokio_stream::Stream; -use tonic::{metadata::MetadataMap, Code, Request, Response, Status}; use super::GatewayMap; use crate::{ @@ -166,6 +173,79 @@ impl WireguardPeerStats { } } +// TODO: merge with super. +const TEN_SECS: Duration = Duration::from_secs(10); + +pub(super) struct GatewayHandler { + endpoint: Endpoint, +} + +impl GatewayHandler { + pub(super) fn new(url: &str, ca_path: Option<&str>) -> Result { + let endpoint = Endpoint::from_shared(url.to_string())?; + let endpoint = endpoint + .http2_keep_alive_interval(TEN_SECS) + .tcp_keepalive(Some(TEN_SECS)) + .keep_alive_while_idle(true); + let endpoint = if let Some(ca) = ca_path { + let ca = read_to_string(ca).unwrap(); // FIXME: use custom error + let tls = ClientTlsConfig::new().ca_certificate(Certificate::from_pem(ca)); + endpoint.tls_config(tls)? + } else { + endpoint + }; + + Ok(Self { endpoint }) + } + + pub(super) async fn handle_connection(&self) -> ! { + let uri = self.endpoint.uri(); + loop { + debug!("Connecting to gateway at {uri}"); + let mut client = gateway_client::GatewayClient::new(self.endpoint.connect_lazy()); + let (tx, rx) = mpsc::unbounded_channel(); + let Ok(response) = client.bidi(UnboundedReceiverStream::new(rx)).await else { + error!("Failed to connect to gateway @ {uri}, retrying in 10s",); + sleep(TEN_SECS).await; + continue; + }; + info!("Connected to proxy at {uri}"); + let mut resp_stream = response.into_inner(); + 'message: loop { + match resp_stream.message().await { + Ok(None) => { + info!("stream was closed by the sender"); + break 'message; + } + Ok(Some(received)) => { + info!("Received message from gateway."); + debug!("Received the following message from gateway: {received:?}"); + let payload: Option = match received.payload { + Some(core_request::Payload::ConfigRequest(config_request)) => { + info!("*** ConfigurationRequest {config_request:?}"); + None + } + Some(core_request::Payload::PeerStats(peer_stats)) => { + info!("*** PeerStats {peer_stats:?}"); + None + } + // Reply without payload. + None => None, + }; + } + Err(err) => { + error!("Disconnected from gateway at {uri}"); + error!("stream error: {err}"); + debug!("waiting 10s to re-establish the connection"); + sleep(TEN_SECS).await; + break 'message; + } + } + } + } + } +} + /// Helper struct for handling gateway events struct GatewayUpdatesHandler { network_id: Id, diff --git a/src/grpc/mod.rs b/src/grpc/mod.rs index 732e8b1a3..da749dd80 100644 --- a/src/grpc/mod.rs +++ b/src/grpc/mod.rs @@ -20,6 +20,7 @@ use tokio::{ broadcast::Sender, mpsc::{self, UnboundedSender}, }, + task::JoinSet, time::sleep, }; use tokio_stream::wrappers::UnboundedReceiverStream; @@ -28,10 +29,9 @@ use tonic::{ Code, Status, }; use uaparser::UserAgentParser; -use uuid::Uuid; #[cfg(feature = "wireguard")] -use self::gateway::{gateway_service_server::GatewayServiceServer, GatewayServer}; +use self::gateway::GatewayHandler; use self::{ auth::{auth_service_server::AuthServiceServer, AuthServer}, desktop_client_mfa::ClientMfaServer, @@ -78,7 +78,6 @@ use proto::{core_request, proxy_client::ProxyClient, CoreError, CoreResponse}; // Helper struct used to handle gateway state // gateways are grouped by network type GatewayHostname = String; -#[derive(Debug)] pub struct GatewayMap(HashMap>); #[derive(Error, Debug)] @@ -88,9 +87,9 @@ pub enum GatewayMapError { #[error("Network {0} not found")] NetworkNotFound(i64), #[error("Gateway with UID {0} not found")] - UidNotFound(Uuid), + UidNotFound(Id), #[error("Cannot remove. Gateway with UID {0} is still active")] - RemoveActive(Uuid), + RemoveActive(Id), #[error("Config missing")] ConfigError, } @@ -104,44 +103,44 @@ impl GatewayMap { // add a new gateway to map // this method is meant to be called when a gateway requests a config // as a sort of "registration" - pub fn add_gateway( - &mut self, - network_id: Id, - network_name: &str, - hostname: String, - name: Option, - mail_tx: UnboundedSender, - ) { - info!("Adding gateway {hostname} with to gateway map for network {network_id}",); - let gateway_state = GatewayState::new(network_id, network_name, &hostname, name, mail_tx); - - if let Some(network_gateway_map) = self.0.get_mut(&network_id) { - network_gateway_map.entry(hostname).or_insert(gateway_state); - } else { - // no map for a given network exists yet - let mut network_gateway_map = HashMap::new(); - network_gateway_map.insert(hostname, gateway_state); - self.0.insert(network_id, network_gateway_map); - } - } + // pub fn add_gateway( + // &mut self, + // network_id: Id, + // network_name: &str, + // hostname: String, + // name: Option, + // mail_tx: UnboundedSender, + // ) { + // info!("Adding gateway {hostname} with to gateway map for network {network_id}",); + // let gateway_state = GatewayState::new(network_id, network_name, &hostname, name, mail_tx); + + // if let Some(network_gateway_map) = self.0.get_mut(&network_id) { + // network_gateway_map.entry(hostname).or_insert(gateway_state); + // } else { + // // no map for a given network exists yet + // let mut network_gateway_map = HashMap::new(); + // network_gateway_map.insert(hostname, gateway_state); + // self.0.insert(network_id, network_gateway_map); + // } + // } // remove gateway from map - pub fn remove_gateway(&mut self, network_id: Id, uid: Uuid) -> Result<(), GatewayMapError> { + pub fn remove_gateway(&mut self, network_id: Id, id: Id) -> Result<(), GatewayMapError> { debug!("Removing gateway from network {network_id}"); if let Some(network_gateway_map) = self.0.get_mut(&network_id) { // find gateway by uuid let hostname = match network_gateway_map .iter() - .find(|(_address, state)| state.uid == uid) + .find(|(_address, state)| state.id == id) { None => { - error!("Failed to find gateway with UID {uid}"); - return Err(GatewayMapError::UidNotFound(uid)); + error!("Failed to find gateway with ID {id}"); + return Err(GatewayMapError::UidNotFound(id)); } Some((hostname, state)) => { if state.connected { - error!("Cannot remove. Gateway with UID {uid} is still active"); - return Err(GatewayMapError::RemoveActive(uid)); + error!("Cannot remove. Gateway with UID {id} is still active"); + return Err(GatewayMapError::RemoveActive(id)); } hostname.clone() } @@ -153,7 +152,8 @@ impl GatewayMap { error!("Network {network_id} not found in gateway map"); return Err(GatewayMapError::NetworkNotFound(network_id)); }; - info!("Gateway with UID {uid} removed from network {network_id}"); + + info!("Gateway with UID {id} removed from network {network_id}"); Ok(()) } @@ -183,6 +183,7 @@ impl GatewayMap { error!("Network {network_id} not found in gateway map"); return Err(GatewayMapError::NetworkNotFound(network_id)); }; + info!("Gateway {hostname} connected in network {network_id}"); Ok(()) } @@ -252,9 +253,9 @@ impl Default for GatewayMap { } } -#[derive(Serialize, Clone, Debug)] -pub struct GatewayState { - pub uid: Uuid, +#[derive(Clone, Debug, Serialize)] +pub(crate) struct GatewayState { + pub id: Id, pub connected: bool, pub network_id: Id, pub network_name: String, @@ -269,27 +270,27 @@ pub struct GatewayState { } impl GatewayState { - #[must_use] - pub fn new>( - network_id: Id, - network_name: S, - hostname: S, - name: Option, - mail_tx: UnboundedSender, - ) -> Self { - Self { - uid: Uuid::new_v4(), - connected: false, - network_id, - network_name: network_name.into(), - name, - hostname: hostname.into(), - connected_at: None, - disconnected_at: None, - mail_tx, - last_email_notification: None, - } - } + // #[must_use] + // pub fn new>( + // network_id: Id, + // network_name: S, + // hostname: S, + // name: Option, + // mail_tx: UnboundedSender, + // ) -> Self { + // Self { + // uid: Uuid::new_v4(), + // connected: false, + // network_id, + // network_name: network_name.into(), + // name, + // hostname: hostname.into(), + // connected_at: None, + // disconnected_at: None, + // mail_tx, + // last_email_notification: None, + // } + // } /// Send gateway disconnected notification /// Sends notification only if last notification time is bigger than specified in config @@ -315,11 +316,11 @@ impl GatewayState { // FIXME: Try to get rid of spawn and use something like block_on // To return result instead of logging tokio::spawn(async move { - if let Err(e) = - send_gateway_disconnected_email(name, network_name, &hostname, &mail_tx, &pool) + if let Err(err) = + send_gateway_disconnected_email(name, &network_name, &hostname, &mail_tx, &pool) .await { - error!("Failed to send gateway disconnect notification: {e}"); + error!("Failed to send gateway disconnect notification: {err}"); } else { info!("Gateway {hostname} disconnected. Email notification sent",); } @@ -344,6 +345,28 @@ impl From for CoreError { } } +/// Bi-directional gRPC stream for comminication with Defguard proxy. +pub async fn run_grpc_gateway_stream(pool: PgPool) -> Result<(), anyhow::Error> { + // TODO: for each gateway... + let gateway_url = "http://localhost:50066"; + + let config = server_config(); + + let mut tasks = JoinSet::new(); + + tasks.spawn(async { + let gateway_client = + GatewayHandler::new(gateway_url, config.proxy_grpc_ca.as_deref()).unwrap(); + gateway_client.handle_connection().await; + }); + + while let Some(Ok(_result)) = tasks.join_next().await { + debug!("Gateway gRPC task has ended"); + } + + Ok(()) +} + /// Bi-directional gRPC stream for comminication with Defguard proxy. pub async fn run_grpc_bidi_stream( pool: PgPool, @@ -377,11 +400,11 @@ pub async fn run_grpc_bidi_stream( let uri = endpoint.uri(); loop { - debug!("Connecting to proxy at {uri}",); + debug!("Connecting to proxy at {uri}"); let mut client = ProxyClient::new(endpoint.connect_lazy()); let (tx, rx) = mpsc::unbounded_channel(); let Ok(response) = client.bidi(UnboundedReceiverStream::new(rx)).await else { - error!("Failed to connect to proxy @ {uri}, retrying in 10s",); + error!("Failed to connect to proxy @ {uri}, retrying in 10s"); sleep(TEN_SECS).await; continue; }; diff --git a/src/handlers/mail.rs b/src/handlers/mail.rs index f2cc35f90..6efa29e73 100644 --- a/src/handlers/mail.rs +++ b/src/handlers/mail.rs @@ -210,7 +210,7 @@ pub fn send_new_device_added_email( pub async fn send_gateway_disconnected_email( gateway_name: Option, - network_name: String, + network_name: &str, gateway_adress: &str, mail_tx: &UnboundedSender, pool: &PgPool, @@ -225,7 +225,7 @@ pub async fn send_gateway_disconnected_email( content: templates::gateway_disconnected_mail( &gateway_name, gateway_adress, - &network_name, + network_name, )?, attachments: Vec::new(), result_tx: None, diff --git a/src/handlers/wireguard.rs b/src/handlers/wireguard.rs index 07969d3e6..1e9fd0322 100644 --- a/src/handlers/wireguard.rs +++ b/src/handlers/wireguard.rs @@ -305,8 +305,9 @@ pub async fn gateway_status( }) } +// TODO: gateway_id should be enough; remove network_id. pub async fn remove_gateway( - Path((network_id, gateway_id)): Path<(i64, String)>, + Path((network_id, gateway_id)): Path<(i64, i64)>, _role: VpnRole, Extension(gateway_state): Extension>>, ) -> ApiResult { @@ -315,11 +316,7 @@ pub async fn remove_gateway( .lock() .expect("Failed to acquire gateway state lock"); - gateway_state.remove_gateway( - network_id, - Uuid::from_str(&gateway_id) - .map_err(|_| WebError::Http(StatusCode::INTERNAL_SERVER_ERROR))?, - )?; + gateway_state.remove_gateway(network_id, gateway_id)?; info!("Removed gateway {gateway_id} in network {network_id}"); From 6f215248f6fa305e180cd84f5c48e651f3a06dc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Tue, 15 Oct 2024 12:30:00 +0200 Subject: [PATCH 04/26] Introduce gateways in WireguardNetwork --- ...8645c9d47dd5b5810ac32aae572d58d39a5e.json} | 4 +- ...b7387eca5822e9cc45205bcbc0d2fcb21d97.json} | 10 +- ...f87c3d6eec3665cfb338df1b45f0822fc1ce.json} | 4 +- ...105d0f94ca2d204e25148b63b833ba69459b.json} | 10 +- ...638b98025f0471a34c949f3e0935818e080b.json} | 4 +- ...3aa9c95ce849f71f2a36d10797fa5cf8f834.json} | 7 +- ...f15e69dbf56925fed7a2ae98f449cc23a815.json} | 7 +- ...0219bd0eb14a5bb95e65844fc919a77fdc3d.json} | 10 +- ...4730a4d22fd487a1dc6c13575c0f1aa394f4.json} | 10 +- Cargo.lock | 183 +++--- build.rs | 6 +- .../20241015074303_network_gateways.down.sql | 1 + .../20241015074303_network_gateways.up.sql | 1 + src/bin/defguard.rs | 7 +- src/db/models/device.rs | 2 +- src/db/models/enrollment.rs | 6 +- src/db/models/wireguard.rs | 36 +- src/grpc/gateway.rs | 338 ++++++----- src/grpc/mod.rs | 39 +- src/grpc/password_reset.rs | 271 --------- src/grpc/{enrollment.rs => proxy.rs} | 573 +++++++++++++----- src/mail.rs | 2 +- src/wireguard_peer_disconnect.rs | 21 +- 23 files changed, 773 insertions(+), 779 deletions(-) rename .sqlx/{query-1403aba7198c132812aa5642166e70c14b3c40a969b496972d499a975fb7b0b4.json => query-140ed5c4dfb4e42aea2e349f73ae8645c9d47dd5b5810ac32aae572d58d39a5e.json} (80%) rename .sqlx/{query-7e10835be17818738155cb84070d878013fe50819f88285ac6f2606b42a3dd3d.json => query-722d953898ad19874bfb026f2a1cb7387eca5822e9cc45205bcbc0d2fcb21d97.json} (86%) rename .sqlx/{query-0e9a8c2395d43898748c176db0d89fa20784cd93ca1dfd00b2755934937d8270.json => query-89c6cd12cbf91f5b504df0dd8861f87c3d6eec3665cfb338df1b45f0822fc1ce.json} (82%) rename .sqlx/{query-5678d744e1e6ba8e7301a3b9e200b61fcc18530d40e13549b4b0d99ed10cb86c.json => query-8f397a1393682f42600ba4799b69105d0f94ca2d204e25148b63b833ba69459b.json} (85%) rename .sqlx/{query-06d1ac982dc99c5dae010089cfb73a044397c5cb6bb9654dc5df420bf00d2955.json => query-9cc07a695832c444bbc66fe38c49638b98025f0471a34c949f3e0935818e080b.json} (74%) rename .sqlx/{query-38f3ad2dc19d222226b85a10d6c83e209cf075f9b128ed33908c73cd74297d81.json => query-d4b301389bd9f8d87517841cd5573aa9c95ce849f71f2a36d10797fa5cf8f834.json} (77%) rename .sqlx/{query-f222309aff56e5182091655c0a6c34cddfee21a48f981c3ca22a6e064c18a769.json => query-db50a47b12760f342f4856593254f15e69dbf56925fed7a2ae98f449cc23a815.json} (73%) rename .sqlx/{query-8c772071e52ac1fb10931f9f698b7555093606011a31706e23dc891321d8836c.json => query-f0bf6cbba9693a015a995f00dac10219bd0eb14a5bb95e65844fc919a77fdc3d.json} (85%) rename .sqlx/{query-f95b0887794cfac8c96bc32a99c3ea4a8e635965c409d72d678045abf28bd16f.json => query-f568188bc7c8b54ffccad38cee004730a4d22fd487a1dc6c13575c0f1aa394f4.json} (85%) create mode 100644 migrations/20241015074303_network_gateways.down.sql create mode 100644 migrations/20241015074303_network_gateways.up.sql delete mode 100644 src/grpc/password_reset.rs rename src/grpc/{enrollment.rs => proxy.rs} (58%) diff --git a/.sqlx/query-1403aba7198c132812aa5642166e70c14b3c40a969b496972d499a975fb7b0b4.json b/.sqlx/query-140ed5c4dfb4e42aea2e349f73ae8645c9d47dd5b5810ac32aae572d58d39a5e.json similarity index 80% rename from .sqlx/query-1403aba7198c132812aa5642166e70c14b3c40a969b496972d499a975fb7b0b4.json rename to .sqlx/query-140ed5c4dfb4e42aea2e349f73ae8645c9d47dd5b5810ac32aae572d58d39a5e.json index b753d65e6..2419b35b6 100644 --- a/.sqlx/query-1403aba7198c132812aa5642166e70c14b3c40a969b496972d499a975fb7b0b4.json +++ b/.sqlx/query-140ed5c4dfb4e42aea2e349f73ae8645c9d47dd5b5810ac32aae572d58d39a5e.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "WITH stats AS ( SELECT DISTINCT ON (network) network, endpoint, latest_handshake FROM wireguard_peer_stats WHERE device_id = $2 ORDER BY network, collected_at DESC ) SELECT n.id network_id, n.name network_name, n.endpoint gateway_endpoint, wnd.wireguard_ip \"device_wireguard_ip: IpAddr\", stats.endpoint device_endpoint, stats.latest_handshake \"latest_handshake?\", COALESCE (((NOW() - stats.latest_handshake) < $1 * interval '1 minute'), false) as \"is_active!\" FROM wireguard_network_device wnd JOIN wireguard_network n ON n.id = wnd.wireguard_network_id LEFT JOIN stats on n.id = stats.network WHERE wnd.device_id = $2", + "query": "WITH stats AS ( SELECT DISTINCT ON (network) network, endpoint, latest_handshake FROM wireguard_peer_stats WHERE device_id = $2 ORDER BY network, collected_at DESC ) SELECT n.id network_id, n.name network_name, n.endpoint gateway_endpoint, wnd.wireguard_ip \"device_wireguard_ip: IpAddr\", stats.endpoint device_endpoint, stats.latest_handshake \"latest_handshake?\", COALESCE (((NOW() - stats.latest_handshake) < $1 * interval '1m'), false) as \"is_active!\" FROM wireguard_network_device wnd JOIN wireguard_network n ON n.id = wnd.wireguard_network_id LEFT JOIN stats on n.id = stats.network WHERE wnd.device_id = $2", "describe": { "columns": [ { @@ -55,5 +55,5 @@ null ] }, - "hash": "1403aba7198c132812aa5642166e70c14b3c40a969b496972d499a975fb7b0b4" + "hash": "140ed5c4dfb4e42aea2e349f73ae8645c9d47dd5b5810ac32aae572d58d39a5e" } diff --git a/.sqlx/query-7e10835be17818738155cb84070d878013fe50819f88285ac6f2606b42a3dd3d.json b/.sqlx/query-722d953898ad19874bfb026f2a1cb7387eca5822e9cc45205bcbc0d2fcb21d97.json similarity index 86% rename from .sqlx/query-7e10835be17818738155cb84070d878013fe50819f88285ac6f2606b42a3dd3d.json rename to .sqlx/query-722d953898ad19874bfb026f2a1cb7387eca5822e9cc45205bcbc0d2fcb21d97.json index 3d8918576..75978ff6c 100644 --- a/.sqlx/query-7e10835be17818738155cb84070d878013fe50819f88285ac6f2606b42a3dd3d.json +++ b/.sqlx/query-722d953898ad19874bfb026f2a1cb7387eca5822e9cc45205bcbc0d2fcb21d97.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold FROM wireguard_network WHERE name = $1", + "query": "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold, gateways FROM wireguard_network WHERE name = $1", "describe": { "columns": [ { @@ -67,6 +67,11 @@ "ordinal": 12, "name": "peer_disconnect_threshold", "type_info": "Int4" + }, + { + "ordinal": 13, + "name": "gateways", + "type_info": "InetArray" } ], "parameters": { @@ -87,8 +92,9 @@ true, false, false, + false, false ] }, - "hash": "7e10835be17818738155cb84070d878013fe50819f88285ac6f2606b42a3dd3d" + "hash": "722d953898ad19874bfb026f2a1cb7387eca5822e9cc45205bcbc0d2fcb21d97" } diff --git a/.sqlx/query-0e9a8c2395d43898748c176db0d89fa20784cd93ca1dfd00b2755934937d8270.json b/.sqlx/query-89c6cd12cbf91f5b504df0dd8861f87c3d6eec3665cfb338df1b45f0822fc1ce.json similarity index 82% rename from .sqlx/query-0e9a8c2395d43898748c176db0d89fa20784cd93ca1dfd00b2755934937d8270.json rename to .sqlx/query-89c6cd12cbf91f5b504df0dd8861f87c3d6eec3665cfb338df1b45f0822fc1ce.json index 25c3f61e0..25e8b614c 100644 --- a/.sqlx/query-0e9a8c2395d43898748c176db0d89fa20784cd93ca1dfd00b2755934937d8270.json +++ b/.sqlx/query-89c6cd12cbf91f5b504df0dd8861f87c3d6eec3665cfb338df1b45f0822fc1ce.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "WITH stats AS ( SELECT DISTINCT ON (device_id) device_id, endpoint, latest_handshake FROM wireguard_peer_stats WHERE network = $1 ORDER BY device_id, collected_at DESC ) SELECT d.id, d.name, d.wireguard_pubkey, d.user_id, d.created FROM device d JOIN wireguard_network_device wnd ON wnd.device_id = d.id LEFT JOIN stats on d.id = stats.device_id WHERE wnd.wireguard_network_id = $1 AND wnd.is_authorized = true AND (wnd.authorized_at IS NULL OR (NOW() - wnd.authorized_at) > $2 * interval '1 second') AND (stats.latest_handshake IS NULL OR (NOW() - stats.latest_handshake) > $2 * interval '1 second')", + "query": "WITH stats AS ( SELECT DISTINCT ON (device_id) device_id, endpoint, latest_handshake FROM wireguard_peer_stats WHERE network = $1 ORDER BY device_id, collected_at DESC ) SELECT d.id, d.name, d.wireguard_pubkey, d.user_id, d.created FROM device d JOIN wireguard_network_device wnd ON wnd.device_id = d.id LEFT JOIN stats on d.id = stats.device_id WHERE wnd.wireguard_network_id = $1 AND wnd.is_authorized = true AND (wnd.authorized_at IS NULL OR (NOW() - wnd.authorized_at) > $2 * interval '1s') AND (stats.latest_handshake IS NULL OR (NOW() - stats.latest_handshake) > $2 * interval '1s')", "describe": { "columns": [ { @@ -43,5 +43,5 @@ false ] }, - "hash": "0e9a8c2395d43898748c176db0d89fa20784cd93ca1dfd00b2755934937d8270" + "hash": "89c6cd12cbf91f5b504df0dd8861f87c3d6eec3665cfb338df1b45f0822fc1ce" } diff --git a/.sqlx/query-5678d744e1e6ba8e7301a3b9e200b61fcc18530d40e13549b4b0d99ed10cb86c.json b/.sqlx/query-8f397a1393682f42600ba4799b69105d0f94ca2d204e25148b63b833ba69459b.json similarity index 85% rename from .sqlx/query-5678d744e1e6ba8e7301a3b9e200b61fcc18530d40e13549b4b0d99ed10cb86c.json rename to .sqlx/query-8f397a1393682f42600ba4799b69105d0f94ca2d204e25148b63b833ba69459b.json index bb4d744b8..08e7d818c 100644 --- a/.sqlx/query-5678d744e1e6ba8e7301a3b9e200b61fcc18530d40e13549b4b0d99ed10cb86c.json +++ b/.sqlx/query-8f397a1393682f42600ba4799b69105d0f94ca2d204e25148b63b833ba69459b.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold FROM wireguard_network WHERE mfa_enabled = true", + "query": "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold, gateways FROM wireguard_network WHERE mfa_enabled = true", "describe": { "columns": [ { @@ -67,6 +67,11 @@ "ordinal": 12, "name": "peer_disconnect_threshold", "type_info": "Int4" + }, + { + "ordinal": 13, + "name": "gateways", + "type_info": "InetArray" } ], "parameters": { @@ -85,8 +90,9 @@ true, false, false, + false, false ] }, - "hash": "5678d744e1e6ba8e7301a3b9e200b61fcc18530d40e13549b4b0d99ed10cb86c" + "hash": "8f397a1393682f42600ba4799b69105d0f94ca2d204e25148b63b833ba69459b" } diff --git a/.sqlx/query-06d1ac982dc99c5dae010089cfb73a044397c5cb6bb9654dc5df420bf00d2955.json b/.sqlx/query-9cc07a695832c444bbc66fe38c49638b98025f0471a34c949f3e0935818e080b.json similarity index 74% rename from .sqlx/query-06d1ac982dc99c5dae010089cfb73a044397c5cb6bb9654dc5df420bf00d2955.json rename to .sqlx/query-9cc07a695832c444bbc66fe38c49638b98025f0471a34c949f3e0935818e080b.json index e2fcfb80f..53cd365de 100644 --- a/.sqlx/query-06d1ac982dc99c5dae010089cfb73a044397c5cb6bb9654dc5df420bf00d2955.json +++ b/.sqlx/query-9cc07a695832c444bbc66fe38c49638b98025f0471a34c949f3e0935818e080b.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT latest_handshake \"latest_handshake: NaiveDateTime\" FROM wireguard_peer_stats_view WHERE device_id = $1 AND latest_handshake IS NOT NULL AND (latest_handshake_diff > $2 * interval '1 minute' OR latest_handshake_diff IS NULL) AND network = $3 ORDER BY collected_at DESC LIMIT 1", + "query": "SELECT latest_handshake \"latest_handshake: NaiveDateTime\" FROM wireguard_peer_stats_view WHERE device_id = $1 AND latest_handshake IS NOT NULL AND (latest_handshake_diff > $2 * interval '1m' OR latest_handshake_diff IS NULL) AND network = $3 ORDER BY collected_at DESC LIMIT 1", "describe": { "columns": [ { @@ -20,5 +20,5 @@ true ] }, - "hash": "06d1ac982dc99c5dae010089cfb73a044397c5cb6bb9654dc5df420bf00d2955" + "hash": "9cc07a695832c444bbc66fe38c49638b98025f0471a34c949f3e0935818e080b" } diff --git a/.sqlx/query-38f3ad2dc19d222226b85a10d6c83e209cf075f9b128ed33908c73cd74297d81.json b/.sqlx/query-d4b301389bd9f8d87517841cd5573aa9c95ce849f71f2a36d10797fa5cf8f834.json similarity index 77% rename from .sqlx/query-38f3ad2dc19d222226b85a10d6c83e209cf075f9b128ed33908c73cd74297d81.json rename to .sqlx/query-d4b301389bd9f8d87517841cd5573aa9c95ce849f71f2a36d10797fa5cf8f834.json index d187d6402..1e0fd7119 100644 --- a/.sqlx/query-38f3ad2dc19d222226b85a10d6c83e209cf075f9b128ed33908c73cd74297d81.json +++ b/.sqlx/query-d4b301389bd9f8d87517841cd5573aa9c95ce849f71f2a36d10797fa5cf8f834.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "UPDATE \"wireguard_network\" SET \"name\" = $2,\"address\" = $3,\"port\" = $4,\"pubkey\" = $5,\"prvkey\" = $6,\"endpoint\" = $7,\"dns\" = $8,\"allowed_ips\" = $9,\"connected_at\" = $10,\"mfa_enabled\" = $11,\"keepalive_interval\" = $12,\"peer_disconnect_threshold\" = $13 WHERE id = $1", + "query": "UPDATE \"wireguard_network\" SET \"name\" = $2,\"address\" = $3,\"port\" = $4,\"pubkey\" = $5,\"prvkey\" = $6,\"endpoint\" = $7,\"dns\" = $8,\"allowed_ips\" = $9,\"connected_at\" = $10,\"mfa_enabled\" = $11,\"keepalive_interval\" = $12,\"peer_disconnect_threshold\" = $13,\"gateways\" = $14 WHERE id = $1", "describe": { "columns": [], "parameters": { @@ -17,10 +17,11 @@ "Timestamp", "Bool", "Int4", - "Int4" + "Int4", + "InetArray" ] }, "nullable": [] }, - "hash": "38f3ad2dc19d222226b85a10d6c83e209cf075f9b128ed33908c73cd74297d81" + "hash": "d4b301389bd9f8d87517841cd5573aa9c95ce849f71f2a36d10797fa5cf8f834" } diff --git a/.sqlx/query-f222309aff56e5182091655c0a6c34cddfee21a48f981c3ca22a6e064c18a769.json b/.sqlx/query-db50a47b12760f342f4856593254f15e69dbf56925fed7a2ae98f449cc23a815.json similarity index 73% rename from .sqlx/query-f222309aff56e5182091655c0a6c34cddfee21a48f981c3ca22a6e064c18a769.json rename to .sqlx/query-db50a47b12760f342f4856593254f15e69dbf56925fed7a2ae98f449cc23a815.json index 25ae273d7..f927b3022 100644 --- a/.sqlx/query-f222309aff56e5182091655c0a6c34cddfee21a48f981c3ca22a6e064c18a769.json +++ b/.sqlx/query-db50a47b12760f342f4856593254f15e69dbf56925fed7a2ae98f449cc23a815.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "INSERT INTO \"wireguard_network\" (\"name\",\"address\",\"port\",\"pubkey\",\"prvkey\",\"endpoint\",\"dns\",\"allowed_ips\",\"connected_at\",\"mfa_enabled\",\"keepalive_interval\",\"peer_disconnect_threshold\") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12) RETURNING id", + "query": "INSERT INTO \"wireguard_network\" (\"name\",\"address\",\"port\",\"pubkey\",\"prvkey\",\"endpoint\",\"dns\",\"allowed_ips\",\"connected_at\",\"mfa_enabled\",\"keepalive_interval\",\"peer_disconnect_threshold\",\"gateways\") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13) RETURNING id", "describe": { "columns": [ { @@ -22,12 +22,13 @@ "Timestamp", "Bool", "Int4", - "Int4" + "Int4", + "InetArray" ] }, "nullable": [ false ] }, - "hash": "f222309aff56e5182091655c0a6c34cddfee21a48f981c3ca22a6e064c18a769" + "hash": "db50a47b12760f342f4856593254f15e69dbf56925fed7a2ae98f449cc23a815" } diff --git a/.sqlx/query-8c772071e52ac1fb10931f9f698b7555093606011a31706e23dc891321d8836c.json b/.sqlx/query-f0bf6cbba9693a015a995f00dac10219bd0eb14a5bb95e65844fc919a77fdc3d.json similarity index 85% rename from .sqlx/query-8c772071e52ac1fb10931f9f698b7555093606011a31706e23dc891321d8836c.json rename to .sqlx/query-f0bf6cbba9693a015a995f00dac10219bd0eb14a5bb95e65844fc919a77fdc3d.json index ad29454b2..fa877bf42 100644 --- a/.sqlx/query-8c772071e52ac1fb10931f9f698b7555093606011a31706e23dc891321d8836c.json +++ b/.sqlx/query-f0bf6cbba9693a015a995f00dac10219bd0eb14a5bb95e65844fc919a77fdc3d.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT id, \"name\",\"address\" \"address: _\",\"port\",\"pubkey\",\"prvkey\",\"endpoint\",\"dns\",\"allowed_ips\" \"allowed_ips: _\",\"connected_at\",\"mfa_enabled\",\"keepalive_interval\",\"peer_disconnect_threshold\" FROM \"wireguard_network\"", + "query": "SELECT id, \"name\",\"address\" \"address: _\",\"port\",\"pubkey\",\"prvkey\",\"endpoint\",\"dns\",\"allowed_ips\" \"allowed_ips: _\",\"connected_at\",\"mfa_enabled\",\"keepalive_interval\",\"peer_disconnect_threshold\",\"gateways\" \"gateways: _\" FROM \"wireguard_network\"", "describe": { "columns": [ { @@ -67,6 +67,11 @@ "ordinal": 12, "name": "peer_disconnect_threshold", "type_info": "Int4" + }, + { + "ordinal": 13, + "name": "gateways: _", + "type_info": "InetArray" } ], "parameters": { @@ -85,8 +90,9 @@ true, false, false, + false, false ] }, - "hash": "8c772071e52ac1fb10931f9f698b7555093606011a31706e23dc891321d8836c" + "hash": "f0bf6cbba9693a015a995f00dac10219bd0eb14a5bb95e65844fc919a77fdc3d" } diff --git a/.sqlx/query-f95b0887794cfac8c96bc32a99c3ea4a8e635965c409d72d678045abf28bd16f.json b/.sqlx/query-f568188bc7c8b54ffccad38cee004730a4d22fd487a1dc6c13575c0f1aa394f4.json similarity index 85% rename from .sqlx/query-f95b0887794cfac8c96bc32a99c3ea4a8e635965c409d72d678045abf28bd16f.json rename to .sqlx/query-f568188bc7c8b54ffccad38cee004730a4d22fd487a1dc6c13575c0f1aa394f4.json index a31da94fa..056328e66 100644 --- a/.sqlx/query-f95b0887794cfac8c96bc32a99c3ea4a8e635965c409d72d678045abf28bd16f.json +++ b/.sqlx/query-f568188bc7c8b54ffccad38cee004730a4d22fd487a1dc6c13575c0f1aa394f4.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT id, \"name\",\"address\" \"address: _\",\"port\",\"pubkey\",\"prvkey\",\"endpoint\",\"dns\",\"allowed_ips\" \"allowed_ips: _\",\"connected_at\",\"mfa_enabled\",\"keepalive_interval\",\"peer_disconnect_threshold\" FROM \"wireguard_network\" WHERE id = $1", + "query": "SELECT id, \"name\",\"address\" \"address: _\",\"port\",\"pubkey\",\"prvkey\",\"endpoint\",\"dns\",\"allowed_ips\" \"allowed_ips: _\",\"connected_at\",\"mfa_enabled\",\"keepalive_interval\",\"peer_disconnect_threshold\",\"gateways\" \"gateways: _\" FROM \"wireguard_network\" WHERE id = $1", "describe": { "columns": [ { @@ -67,6 +67,11 @@ "ordinal": 12, "name": "peer_disconnect_threshold", "type_info": "Int4" + }, + { + "ordinal": 13, + "name": "gateways: _", + "type_info": "InetArray" } ], "parameters": { @@ -87,8 +92,9 @@ true, false, false, + false, false ] }, - "hash": "f95b0887794cfac8c96bc32a99c3ea4a8e635965c409d72d678045abf28bd16f" + "hash": "f568188bc7c8b54ffccad38cee004730a4d22fd487a1dc6c13575c0f1aa394f4" } diff --git a/Cargo.lock b/Cargo.lock index 0a8671c16..b1dd49980 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] @@ -619,9 +619,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.24" +version = "1.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" +checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" dependencies = [ "jobserver", "libc", @@ -711,9 +711,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.19" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -721,9 +721,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.19" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", @@ -1205,18 +1205,18 @@ dependencies = [ [[package]] name = "derive_builder" -version = "0.20.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd33f37ee6a119146a1781d3356a7c26028f83d779b2e04ecd45fdc75c76877b" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" dependencies = [ "derive_builder_macro", ] [[package]] name = "derive_builder_core" -version = "0.20.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7431fa049613920234f22c47fdc33e6cf3ee83067091ea4277a3f8c4587aae38" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" dependencies = [ "darling", "proc-macro2", @@ -1226,9 +1226,9 @@ dependencies = [ [[package]] name = "derive_builder_macro" -version = "0.20.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4abae7035bf79b9877b779505d8cf3749285b80c43941eda66604841889451dc" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", "syn 2.0.79", @@ -1650,9 +1650,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -1665,9 +1665,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -1675,15 +1675,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -1703,15 +1703,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", @@ -1720,21 +1720,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -1793,9 +1793,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "git2" @@ -2138,7 +2138,7 @@ dependencies = [ "http 1.1.0", "hyper 1.4.1", "hyper-util", - "rustls 0.23.13", + "rustls 0.23.14", "rustls-pki-types", "tokio", "tokio-rustls 0.26.0", @@ -2465,9 +2465,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.10.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" [[package]] name = "ipnetwork" @@ -2525,9 +2525,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] @@ -2989,9 +2989,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.4" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] @@ -3019,12 +3019,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.1" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" -dependencies = [ - "portable-atomic", -] +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "opaque-debug" @@ -3304,9 +3301,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.13" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" +checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", "thiserror", @@ -3315,9 +3312,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.13" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d3a6e3394ec80feb3b6393c725571754c6188490265c61aaf260810d6b95aa0" +checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" dependencies = [ "pest", "pest_generator", @@ -3325,9 +3322,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.13" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94429506bde1ca69d1b5601962c73f4172ab4726571a59ea95931218cb0e930e" +checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" dependencies = [ "pest", "pest_meta", @@ -3338,9 +3335,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.13" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac8a071862e93690b6e34e9a5fb8e33ff3734473ac0245b27232222c4906a33f" +checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" dependencies = [ "once_cell", "pest", @@ -3461,18 +3458,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" dependencies = [ "proc-macro2", "quote", @@ -3530,12 +3527,6 @@ dependencies = [ "universal-hash", ] -[[package]] -name = "portable-atomic" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" - [[package]] name = "powerfmt" version = "0.2.0" @@ -3619,9 +3610,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" dependencies = [ "unicode-ident", ] @@ -3750,7 +3741,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.13", + "rustls 0.23.14", "socket2", "thiserror", "tokio", @@ -3767,7 +3758,7 @@ dependencies = [ "rand", "ring", "rustc-hash", - "rustls 0.23.13", + "rustls 0.23.14", "slab", "thiserror", "tinyvec", @@ -3974,7 +3965,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.13", + "rustls 0.23.14", "rustls-pemfile 2.2.0", "rustls-pki-types", "serde", @@ -4191,9 +4182,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.13" +version = "0.23.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" +checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" dependencies = [ "once_cell", "ring", @@ -4263,9 +4254,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "ryu" @@ -4308,9 +4299,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" +checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" dependencies = [ "windows-sys 0.59.0", ] @@ -4508,9 +4499,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.10.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9720086b3357bcb44fce40117d769a4d068c70ecfa190850a980a71755f66fcc" +checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" dependencies = [ "base64 0.22.1", "chrono", @@ -4526,9 +4517,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.10.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f1abbfe725f27678f4663bcacb75a83e829fd464c25d78dd038a3a29e307cec" +checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" dependencies = [ "darling", "proc-macro2", @@ -5342,7 +5333,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.13", + "rustls 0.23.14", "rustls-pki-types", "tokio", ] @@ -5823,9 +5814,9 @@ dependencies = [ [[package]] name = "utoipa-gen" -version = "4.3.0" +version = "4.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bf0e16c02bc4bf5322ab65f10ab1149bdbcaa782cba66dc7057370a3f8190be" +checksum = "20c24e8ab68ff9ee746aad22d39b5535601e6416d1b0feeabf78be986a5c4392" dependencies = [ "proc-macro-error", "proc-macro2", @@ -5952,9 +5943,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", "once_cell", @@ -5963,9 +5954,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", @@ -5978,9 +5969,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.43" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" dependencies = [ "cfg-if", "js-sys", @@ -5990,9 +5981,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6000,9 +5991,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", @@ -6013,9 +6004,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "wasm-streams" @@ -6032,9 +6023,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/build.rs b/build.rs index 43c2aa4dd..9db06b09b 100644 --- a/build.rs +++ b/build.rs @@ -12,20 +12,20 @@ fn main() -> Result<(), Box> { &[ "proto/core/auth.proto", "proto/core/proxy.proto", - "proto/core/vpn.proto", "src/enterprise/proto/license.proto", - "proto/worker/worker.proto", "proto/wireguard/gateway.proto", + "proto/worker/worker.proto", ], &[ "proto/core", - "proto/worker", "proto/wireguard", + "proto/worker", "src/enterprise/proto", ], )?; println!("cargo:rerun-if-changed=migrations"); println!("cargo:rerun-if-changed=proto"); println!("cargo:rerun-if-changed=web/dist"); + Ok(()) } diff --git a/migrations/20241015074303_network_gateways.down.sql b/migrations/20241015074303_network_gateways.down.sql new file mode 100644 index 000000000..0197bef93 --- /dev/null +++ b/migrations/20241015074303_network_gateways.down.sql @@ -0,0 +1 @@ +ALTER TABLE wireguard_network DROP COLUMN gateways; diff --git a/migrations/20241015074303_network_gateways.up.sql b/migrations/20241015074303_network_gateways.up.sql new file mode 100644 index 000000000..8dd37e805 --- /dev/null +++ b/migrations/20241015074303_network_gateways.up.sql @@ -0,0 +1 @@ +ALTER TABLE wireguard_network ADD COLUMN gateways inet[] NOT NULL DEFAULT array[]::inet[]; diff --git a/src/bin/defguard.rs b/src/bin/defguard.rs index a25f50a83..5626e1ef0 100644 --- a/src/bin/defguard.rs +++ b/src/bin/defguard.rs @@ -78,7 +78,7 @@ async fn main() -> Result<(), anyhow::Error> { let (wireguard_tx, _wireguard_rx) = broadcast::channel::(256); let (mail_tx, mail_rx) = unbounded_channel::(); let worker_state = Arc::new(Mutex::new(WorkerState::new(webhook_tx.clone()))); - let gateway_state = Arc::new(Mutex::new(GatewayMap::new())); + let gateway_map = Arc::new(Mutex::new(GatewayMap::new())); let user_agent_parser = create_user_agent_parser(); // initialize admin user @@ -115,12 +115,13 @@ async fn main() -> Result<(), anyhow::Error> { // run services tokio::select! { res = run_grpc_bidi_stream(pool.clone(), wireguard_tx.clone(), mail_tx.clone(), user_agent_parser.clone()), if config.proxy_url.is_some() => error!("Proxy gRPC stream returned early: {res:#?}"), - res = run_grpc_server(Arc::clone(&worker_state), pool.clone(), Arc::clone(&gateway_state), wireguard_tx.clone(), mail_tx.clone(), grpc_cert, grpc_key, failed_logins.clone()) => error!("gRPC server returned early: {res:#?}"), - res = run_web_server(worker_state, gateway_state, webhook_tx, webhook_rx, wireguard_tx.clone(), mail_tx, pool.clone(), user_agent_parser, failed_logins) => error!("Web server returned early: {res:#?}"), + res = run_grpc_server(Arc::clone(&worker_state), pool.clone(), Arc::clone(&gateway_map), wireguard_tx.clone(), mail_tx.clone(), grpc_cert, grpc_key, failed_logins.clone()) => error!("gRPC server returned early: {res:#?}"), + res = run_web_server(worker_state, gateway_map, webhook_tx, webhook_rx, wireguard_tx.clone(), mail_tx, pool.clone(), user_agent_parser, failed_logins) => error!("Web server returned early: {res:#?}"), res = run_mail_handler(mail_rx, pool.clone()) => error!("Mail handler returned early: {res:#?}"), res = run_periodic_peer_disconnect(pool.clone(), wireguard_tx) => error!("Periodic peer disconnect task returned early: {res:#?}"), res = run_periodic_stats_purge(pool.clone(), config.stats_purge_frequency.into(), config.stats_purge_threshold.into()), if !config.disable_stats_purge => error!("Periodic stats purge task returned early: {res:#?}"), res = run_periodic_license_check(pool) => error!("Periodic license check task returned early: {res:#?}"), } + Ok(()) } diff --git a/src/db/models/device.rs b/src/db/models/device.rs index 6dd9028d7..08d88173c 100644 --- a/src/db/models/device.rs +++ b/src/db/models/device.rs @@ -127,7 +127,7 @@ impl UserDevice { n.id network_id, n.name network_name, n.endpoint gateway_endpoint, \ wnd.wireguard_ip \"device_wireguard_ip: IpAddr\", stats.endpoint device_endpoint, \ stats.latest_handshake \"latest_handshake?\", \ - COALESCE (((NOW() - stats.latest_handshake) < $1 * interval '1 minute'), false) as \"is_active!\" \ + COALESCE (((NOW() - stats.latest_handshake) < $1 * interval '1m'), false) as \"is_active!\" \ FROM wireguard_network_device wnd \ JOIN wireguard_network n ON n.id = wnd.wireguard_network_id \ LEFT JOIN stats on n.id = stats.network \ diff --git a/src/db/models/enrollment.rs b/src/db/models/enrollment.rs index c4b871adb..100b2b6d6 100644 --- a/src/db/models/enrollment.rs +++ b/src/db/models/enrollment.rs @@ -16,8 +16,8 @@ use crate::{ VERSION, }; -pub static ENROLLMENT_TOKEN_TYPE: &str = "ENROLLMENT"; -pub static PASSWORD_RESET_TOKEN_TYPE: &str = "PASSWORD_RESET"; +pub(crate) static ENROLLMENT_TOKEN_TYPE: &str = "ENROLLMENT"; +pub(crate) static PASSWORD_RESET_TOKEN_TYPE: &str = "PASSWORD_RESET"; static ENROLLMENT_START_MAIL_SUBJECT: &str = "Defguard user enrollment"; static DESKTOP_START_MAIL_SUBJECT: &str = "Defguard desktop client configuration"; @@ -78,7 +78,7 @@ impl From for Status { } // Representation of a user enrollment session -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct Token { pub id: String, pub user_id: Id, diff --git a/src/db/models/wireguard.rs b/src/db/models/wireguard.rs index 5bc14aa9e..6134a1ac7 100644 --- a/src/db/models/wireguard.rs +++ b/src/db/models/wireguard.rs @@ -88,6 +88,8 @@ pub struct WireguardNetwork { pub mfa_enabled: bool, pub keepalive_interval: i32, pub peer_disconnect_threshold: i32, + #[model(ref)] + pub gateways: Vec, } pub struct WireguardKey { @@ -155,6 +157,7 @@ impl WireguardNetwork { mfa_enabled, keepalive_interval, peer_disconnect_threshold, + gateways: Vec::new(), }) } @@ -176,23 +179,22 @@ impl WireguardNetwork { { let networks = query_as!( WireguardNetwork, - "SELECT \ - id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, \ - connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold \ + "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, \ + connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold, gateways \ FROM wireguard_network WHERE name = $1", name ) .fetch_all(executor) .await?; - if networks.is_empty() { - return Ok(None); - } - - Ok(Some(networks)) + Ok(if networks.is_empty() { + None + } else { + Some(networks) + }) } - // run sync_allowed_devices on all wireguard networks + /// Run `sync_allowed_devices()` on all WireGuard networks. pub async fn sync_all_networks(app: &AppState) -> Result<(), WireguardNetworkError> { info!("Syncing allowed devices for all WireGuard locations"); let mut transaction = app.pool.begin().await?; @@ -210,13 +212,18 @@ impl WireguardNetwork { &self, transaction: &mut PgConnection, ) -> Result { - let count = query_scalar!("SELECT count(*) \"count!\" FROM wireguard_network_device WHERE wireguard_network_id = $1", self.id) - .fetch_one(transaction) - .await?; + let count = query_scalar!( + "SELECT count(*) \"count!\" FROM wireguard_network_device \ + WHERE wireguard_network_id = $1", + self.id + ) + .fetch_one(transaction) + .await?; Ok(count) } + /// Check if given number of devices could fit the network. pub fn validate_network_size(&self, device_count: usize) -> Result<(), WireguardNetworkError> { debug!("Checking if {device_count} devices can fit in network {self}"); let network_size = self.address.size(); @@ -237,7 +244,7 @@ impl WireguardNetwork { Ok(()) } - /// Utility method to create WireGuard keypair + /// Utility method to create WireGuard keypair. #[must_use] pub fn genkey() -> WireguardKey { let private = StaticSecret::random_from_rng(OsRng); @@ -696,7 +703,7 @@ impl WireguardNetwork { FROM wireguard_peer_stats_view \ WHERE device_id = $1 \ AND latest_handshake IS NOT NULL \ - AND (latest_handshake_diff > $2 * interval '1 minute' OR latest_handshake_diff IS NULL) \ + AND (latest_handshake_diff > $2 * interval '1m' OR latest_handshake_diff IS NULL) \ AND network = $3 \ ORDER BY collected_at DESC \ LIMIT 1", @@ -934,6 +941,7 @@ impl Default for WireguardNetwork { mfa_enabled: false, keepalive_interval: DEFAULT_KEEPALIVE_INTERVAL, peer_disconnect_threshold: DEFAULT_DISCONNECT_THRESHOLD, + gateways: Vec::default(), } } } diff --git a/src/grpc/gateway.rs b/src/grpc/gateway.rs index 64125f34a..5fedabf81 100644 --- a/src/grpc/gateway.rs +++ b/src/grpc/gateway.rs @@ -343,6 +343,7 @@ impl GatewayUpdatesHandler { error!(msg); return Err(Status::new(Code::Internal, msg)); } + debug!("Network update sent for network {network}"); Ok(()) } @@ -374,6 +375,7 @@ impl GatewayUpdatesHandler { error!(msg); return Err(Status::new(Code::Internal, msg)); } + debug!("Network delete command sent for network {}", self.network); Ok(()) } @@ -401,6 +403,7 @@ impl GatewayUpdatesHandler { error!(msg); return Err(Status::new(Code::Internal, msg)); } + debug!("Peer update sent for network {}", self.network); Ok(()) } @@ -428,6 +431,7 @@ impl GatewayUpdatesHandler { error!(msg); return Err(Status::new(Code::Internal, msg)); } + debug!("Peer delete command sent for network {}", self.network); Ok(()) } @@ -485,170 +489,170 @@ impl Drop for GatewayUpdatesStream { } } -#[tonic::async_trait] -impl gateway_service_server::GatewayService for GatewayServer { - type UpdatesStream = GatewayUpdatesStream; - - /// Retrieve stats from gateway and save it to database - async fn stats( - &self, - request: Request>, - ) -> Result, Status> { - let network_id = Self::get_network_id(request.metadata())?; - let mut stream = request.into_inner(); - while let Some(stats_update) = stream.message().await? { - debug!("Received stats message: {stats_update:?}"); - let Some(stats_update::Payload::PeerStats(peer_stats)) = stats_update.payload else { - debug!("Received stats message is empty, skipping."); - continue; - }; - let public_key = peer_stats.public_key.clone(); - let mut stats = WireguardPeerStats::from_peer_stats(peer_stats, network_id); - // Get device by public key and fill in stats.device_id - // FIXME: keep an in-memory device map to avoid repeated DB requests - stats.device_id = match Device::find_by_pubkey(&self.pool, &public_key).await { - Ok(Some(device)) => device.id, - Ok(None) => { - error!("Device with public key {public_key} not found"); - return Err(Status::new( - Code::Internal, - format!("Device with public key {public_key} not found"), - )); - } - Err(err) => { - error!("Failed to retrieve device with public key {public_key}: {err}",); - return Err(Status::new( - Code::Internal, - format!("Failed to retrieve device with public key {public_key}: {err}",), - )); - } - }; - // Save stats to db - let stats = match stats.save(&self.pool).await { - Ok(stats) => stats, - Err(err) => { - error!("Saving WireGuard peer stats to db failed: {err}"); - return Err(Status::new( - Code::Internal, - format!("Saving WireGuard peer stats to db failed: {err}"), - )); - } - }; - info!("Saved WireGuard peer stats to db."); - debug!("WireGuard peer stats: {stats:?}"); - } - - Ok(Response::new(())) - } - - async fn config( - &self, - request: Request, - ) -> Result, Status> { - debug!("Sending configuration to gateway client."); - let network_id = Self::get_network_id(request.metadata())?; - let hostname = Self::get_gateway_hostname(request.metadata())?; - - let mut network = WireguardNetwork::find_by_id(&self.pool, network_id) - .await - .map_err(|e| { - error!("Network {network_id} not found"); - Status::new(Code::Internal, format!("Failed to retrieve network: {e}")) - })? - .ok_or_else(|| { - Status::new( - Code::Internal, - format!("Network with id {network_id} not found"), - ) - })?; - - debug!("Sending configuration to gateway client, network {network}."); - - // store connected gateway in memory - { - let mut state = self.state.lock().unwrap(); - state.add_gateway( - network_id, - &network.name, - hostname, - request.into_inner().name, - self.mail_tx.clone(), - ); - } - - network.connected_at = Some(Utc::now().naive_utc()); - if let Err(err) = network.save(&self.pool).await { - error!("Failed to save updated network {network_id} in the database, status: {err}"); - } - - let peers = network.get_peers(&self.pool).await.map_err(|error| { - error!("Failed to fetch peers from the database for network {network_id}: {error}",); - Status::new( - Code::Internal, - format!("Failed to retrieve peers from the database for network: {network_id}"), - ) - })?; - - info!("Configuration sent to gateway client, network {network}."); - - Ok(Response::new(gen_config(&network, peers))) - } - - async fn updates(&self, request: Request<()>) -> Result, Status> { - let gateway_network_id = Self::get_network_id(request.metadata())?; - let hostname = Self::get_gateway_hostname(request.metadata())?; - - let Some(network) = WireguardNetwork::find_by_id(&self.pool, gateway_network_id) - .await - .map_err(|_| { - error!("Failed to fetch network {gateway_network_id} from the database"); - Status::new( - Code::Internal, - format!("Failed to retrieve network {gateway_network_id} from the database"), - ) - })? - else { - return Err(Status::new( - Code::Internal, - format!("Network with id {gateway_network_id} not found"), - )); - }; - - info!("New client connected to updates stream: {hostname}, network {network}",); - - let (tx, rx) = mpsc::channel(4); - let events_rx = self.wireguard_tx.subscribe(); - let mut state = self.state.lock().unwrap(); - state - .connect_gateway(gateway_network_id, &hostname) - .map_err(|err| { - error!("Failed to connect gateway on network {gateway_network_id}: {err}"); - Status::new( - Code::Internal, - "Failed to connect gateway on network {gateway_network_id}", - ) - })?; - - // clone here before moving into a closure - let gateway_hostname = hostname.clone(); - let handle = tokio::spawn(async move { - let mut update_handler = GatewayUpdatesHandler::new( - gateway_network_id, - network, - gateway_hostname, - events_rx, - tx, - ); - update_handler.run().await; - }); - - Ok(Response::new(GatewayUpdatesStream::new( - handle, - rx, - gateway_network_id, - hostname, - Arc::clone(&self.state), - self.pool.clone(), - ))) - } -} +// #[tonic::async_trait] +// impl gateway_service_server::GatewayService for GatewayServer { +// type UpdatesStream = GatewayUpdatesStream; + +// /// Retrieve stats from gateway and save it to database +// async fn stats( +// &self, +// request: Request>, +// ) -> Result, Status> { +// let network_id = Self::get_network_id(request.metadata())?; +// let mut stream = request.into_inner(); +// while let Some(stats_update) = stream.message().await? { +// debug!("Received stats message: {stats_update:?}"); +// let Some(stats_update::Payload::PeerStats(peer_stats)) = stats_update.payload else { +// debug!("Received stats message is empty, skipping."); +// continue; +// }; +// let public_key = peer_stats.public_key.clone(); +// let mut stats = WireguardPeerStats::from_peer_stats(peer_stats, network_id); +// // Get device by public key and fill in stats.device_id +// // FIXME: keep an in-memory device map to avoid repeated DB requests +// stats.device_id = match Device::find_by_pubkey(&self.pool, &public_key).await { +// Ok(Some(device)) => device.id, +// Ok(None) => { +// error!("Device with public key {public_key} not found"); +// return Err(Status::new( +// Code::Internal, +// format!("Device with public key {public_key} not found"), +// )); +// } +// Err(err) => { +// error!("Failed to retrieve device with public key {public_key}: {err}",); +// return Err(Status::new( +// Code::Internal, +// format!("Failed to retrieve device with public key {public_key}: {err}",), +// )); +// } +// }; +// // Save stats to db +// let stats = match stats.save(&self.pool).await { +// Ok(stats) => stats, +// Err(err) => { +// error!("Saving WireGuard peer stats to db failed: {err}"); +// return Err(Status::new( +// Code::Internal, +// format!("Saving WireGuard peer stats to db failed: {err}"), +// )); +// } +// }; +// info!("Saved WireGuard peer stats to db."); +// debug!("WireGuard peer stats: {stats:?}"); +// } + +// Ok(Response::new(())) +// } + +// async fn config( +// &self, +// request: Request, +// ) -> Result, Status> { +// debug!("Sending configuration to gateway client."); +// let network_id = Self::get_network_id(request.metadata())?; +// let hostname = Self::get_gateway_hostname(request.metadata())?; + +// let mut network = WireguardNetwork::find_by_id(&self.pool, network_id) +// .await +// .map_err(|e| { +// error!("Network {network_id} not found"); +// Status::new(Code::Internal, format!("Failed to retrieve network: {e}")) +// })? +// .ok_or_else(|| { +// Status::new( +// Code::Internal, +// format!("Network with id {network_id} not found"), +// ) +// })?; + +// debug!("Sending configuration to gateway client, network {network}."); + +// // store connected gateway in memory +// { +// let mut state = self.state.lock().unwrap(); +// state.add_gateway( +// network_id, +// &network.name, +// hostname, +// request.into_inner().name, +// self.mail_tx.clone(), +// ); +// } + +// network.connected_at = Some(Utc::now().naive_utc()); +// if let Err(err) = network.save(&self.pool).await { +// error!("Failed to save updated network {network_id} in the database, status: {err}"); +// } + +// let peers = network.get_peers(&self.pool).await.map_err(|error| { +// error!("Failed to fetch peers from the database for network {network_id}: {error}",); +// Status::new( +// Code::Internal, +// format!("Failed to retrieve peers from the database for network: {network_id}"), +// ) +// })?; + +// info!("Configuration sent to gateway client, network {network}."); + +// Ok(Response::new(gen_config(&network, peers))) +// } + +// async fn updates(&self, request: Request<()>) -> Result, Status> { +// let gateway_network_id = Self::get_network_id(request.metadata())?; +// let hostname = Self::get_gateway_hostname(request.metadata())?; + +// let Some(network) = WireguardNetwork::find_by_id(&self.pool, gateway_network_id) +// .await +// .map_err(|_| { +// error!("Failed to fetch network {gateway_network_id} from the database"); +// Status::new( +// Code::Internal, +// format!("Failed to retrieve network {gateway_network_id} from the database"), +// ) +// })? +// else { +// return Err(Status::new( +// Code::Internal, +// format!("Network with id {gateway_network_id} not found"), +// )); +// }; + +// info!("New client connected to updates stream: {hostname}, network {network}",); + +// let (tx, rx) = mpsc::channel(4); +// let events_rx = self.wireguard_tx.subscribe(); +// let mut state = self.state.lock().unwrap(); +// state +// .connect_gateway(gateway_network_id, &hostname) +// .map_err(|err| { +// error!("Failed to connect gateway on network {gateway_network_id}: {err}"); +// Status::new( +// Code::Internal, +// "Failed to connect gateway on network {gateway_network_id}", +// ) +// })?; + +// // clone here before moving into a closure +// let gateway_hostname = hostname.clone(); +// let handle = tokio::spawn(async move { +// let mut update_handler = GatewayUpdatesHandler::new( +// gateway_network_id, +// network, +// gateway_hostname, +// events_rx, +// tx, +// ); +// update_handler.run().await; +// }); + +// Ok(Response::new(GatewayUpdatesStream::new( +// handle, +// rx, +// gateway_network_id, +// hostname, +// Arc::clone(&self.state), +// self.pool.clone(), +// ))) +// } +// } diff --git a/src/grpc/mod.rs b/src/grpc/mod.rs index ea2a26cbd..3f812eec0 100644 --- a/src/grpc/mod.rs +++ b/src/grpc/mod.rs @@ -35,9 +35,8 @@ use self::gateway::{gateway_service_server::GatewayServiceServer, GatewayServer} use self::{ auth::{auth_service_server::AuthServiceServer, AuthServer}, desktop_client_mfa::ClientMfaServer, - enrollment::EnrollmentServer, - password_reset::PasswordResetServer, proto::core_response, + proxy::ProxyHandler, }; #[cfg(feature = "worker")] use self::{ @@ -61,12 +60,11 @@ use crate::{auth::ClaimsType, db::GatewayEvent}; mod auth; mod desktop_client_mfa; -pub mod enrollment; #[cfg(feature = "wireguard")] pub(crate) mod gateway; #[cfg(any(feature = "wireguard", feature = "worker"))] mod interceptor; -pub mod password_reset; +mod proxy; pub(crate) mod utils; #[cfg(feature = "worker")] pub mod worker; @@ -355,14 +353,12 @@ pub async fn run_grpc_bidi_stream( ) -> Result<(), anyhow::Error> { let config = server_config(); - // TODO: merge the two - let enrollment_server = EnrollmentServer::new( + let proxy_handler = ProxyHandler::new( pool.clone(), wireguard_tx.clone(), mail_tx.clone(), user_agent_parser, ); - let password_reset_server = PasswordResetServer::new(pool.clone(), mail_tx.clone()); let mut client_mfa_server = ClientMfaServer::new(pool.clone(), mail_tx, wireguard_tx); let polling_server = PollingServer::new(pool); @@ -405,7 +401,7 @@ pub async fn run_grpc_bidi_stream( let payload = match received.payload { // rpc StartEnrollment (EnrollmentStartRequest) returns (EnrollmentStartResponse) Some(core_request::Payload::EnrollmentStart(request)) => { - match enrollment_server.start_enrollment(request).await { + match proxy_handler.start_enrollment(request).await { Ok(response_payload) => { Some(core_response::Payload::EnrollmentStart(response_payload)) } @@ -417,7 +413,7 @@ pub async fn run_grpc_bidi_stream( } // rpc ActivateUser (ActivateUserRequest) returns (google.protobuf.Empty) Some(core_request::Payload::ActivateUser(request)) => { - match enrollment_server + match proxy_handler .activate_user(request, received.device_info) .await { @@ -430,7 +426,7 @@ pub async fn run_grpc_bidi_stream( } // rpc CreateDevice (NewDevice) returns (DeviceConfigResponse) Some(core_request::Payload::NewDevice(request)) => { - match enrollment_server + match proxy_handler .create_device(request, received.device_info) .await { @@ -445,7 +441,7 @@ pub async fn run_grpc_bidi_stream( } // rpc GetNetworkInfo (ExistingDevice) returns (DeviceConfigResponse) Some(core_request::Payload::ExistingDevice(request)) => { - match enrollment_server.get_network_info(request).await { + match proxy_handler.get_network_info(request).await { Ok(response_payload) => { Some(core_response::Payload::DeviceConfig(response_payload)) } @@ -457,7 +453,7 @@ pub async fn run_grpc_bidi_stream( } // rpc RequestPasswordReset (PasswordResetInitializeRequest) returns (google.protobuf.Empty) Some(core_request::Payload::PasswordResetInit(request)) => { - match password_reset_server + match proxy_handler .request_password_reset(request, received.device_info) .await { @@ -470,7 +466,7 @@ pub async fn run_grpc_bidi_stream( } // rpc StartPasswordReset (PasswordResetStartRequest) returns (PasswordResetStartResponse) Some(core_request::Payload::PasswordResetStart(request)) => { - match password_reset_server.start_password_reset(request).await { + match proxy_handler.start_password_reset(request).await { Ok(response_payload) => Some( core_response::Payload::PasswordResetStart(response_payload), ), @@ -482,7 +478,7 @@ pub async fn run_grpc_bidi_stream( } // rpc ResetPassword (PasswordResetRequest) returns (google.protobuf.Empty) Some(core_request::Payload::PasswordReset(request)) => { - match password_reset_server + match proxy_handler .reset_password(request, received.device_info) .await { @@ -578,11 +574,11 @@ pub async fn run_grpc_server( WorkerServer::new(pool.clone(), worker_state), JwtInterceptor::new(ClaimsType::YubiBridge), ); - #[cfg(feature = "wireguard")] - let gateway_service = GatewayServiceServer::with_interceptor( - GatewayServer::new(pool, gateway_state, wireguard_tx, mail_tx), - JwtInterceptor::new(ClaimsType::Gateway), - ); + // #[cfg(feature = "wireguard")] + // let gateway_service = GatewayServiceServer::with_interceptor( + // GatewayServer::new(pool, gateway_state, wireguard_tx, mail_tx), + // JwtInterceptor::new(ClaimsType::Gateway), + // ); let (mut health_reporter, health_service) = tonic_health::server::health_reporter(); health_reporter @@ -603,11 +599,12 @@ pub async fn run_grpc_server( .tcp_keepalive(Some(TEN_SECS)) .add_service(health_service) .add_service(auth_service); - #[cfg(feature = "wireguard")] - let router = router.add_service(gateway_service); + // #[cfg(feature = "wireguard")] + // let router = router.add_service(gateway_service); #[cfg(feature = "worker")] let router = router.add_service(worker_service); router.serve(addr).await?; + info!("gRPC server started on {addr}"); Ok(()) } diff --git a/src/grpc/password_reset.rs b/src/grpc/password_reset.rs deleted file mode 100644 index 6a5516c16..000000000 --- a/src/grpc/password_reset.rs +++ /dev/null @@ -1,271 +0,0 @@ -use sqlx::PgPool; -use tokio::sync::mpsc::UnboundedSender; -use tonic::Status; - -use super::proto::{ - DeviceInfo, PasswordResetInitializeRequest, PasswordResetRequest, PasswordResetStartRequest, - PasswordResetStartResponse, -}; -use crate::{ - db::{ - models::enrollment::{Token, PASSWORD_RESET_TOKEN_TYPE}, - User, - }, - handlers::{ - mail::{send_password_reset_email, send_password_reset_success_email}, - user::check_password_strength, - }, - ldap::utils::ldap_change_password, - mail::Mail, - server_config, -}; - -pub(super) struct PasswordResetServer { - pool: PgPool, - mail_tx: UnboundedSender, - // ldap_feature_active: bool, -} - -impl PasswordResetServer { - #[must_use] - pub fn new(pool: PgPool, mail_tx: UnboundedSender) -> Self { - // FIXME: check if LDAP feature is enabled - // let ldap_feature_active = true; - Self { - pool, - mail_tx, - // ldap_feature_active, - } - } - - /// Checks if token provided with request corresponds to a valid password reset session - async fn validate_session(&self, token: &Option) -> Result { - info!("Validating password reset session. Token: {token:?}"); - let Some(token) = token else { - error!("Missing authorization header in request"); - return Err(Status::unauthenticated("Missing authorization header")); - }; - let enrollment = Token::find_by_id(&self.pool, token).await?; - debug!("Found matching token, verifying validity: {enrollment:?}."); - if !enrollment - .token_type - .as_ref() - .is_some_and(|token_type| token_type == PASSWORD_RESET_TOKEN_TYPE) - { - error!( - "Invalid token type used in password reset process: {:?}", - enrollment.token_type - ); - return Err(Status::permission_denied("invalid token")); - } - - if enrollment.is_session_valid(server_config().enrollment_session_timeout.as_secs()) { - info!("Password reset session validated: {enrollment:?}.",); - Ok(enrollment) - } else { - error!("Password reset session expired: {enrollment:?}"); - Err(Status::unauthenticated("Session expired")) - } - } - - pub async fn request_password_reset( - &self, - request: PasswordResetInitializeRequest, - req_device_info: Option, - ) -> Result<(), Status> { - let config = server_config(); - debug!("Starting password reset request"); - - let ip_address; - let user_agent; - if let Some(info) = req_device_info { - ip_address = info.ip_address.unwrap_or_default(); - user_agent = info.user_agent.unwrap_or_default(); - } else { - ip_address = String::new(); - user_agent = String::new(); - } - - let email = request.email; - - let user = User::find_by_email(&self.pool, email.to_string().as_str()) - .await - .map_err(|_| { - error!("Failed to fetch user by email: {email}"); - Status::internal("unexpected error") - })?; - - let Some(user) = user else { - // Do not return information whether user exists - debug!("Password reset skipped for non-existing user {email}"); - return Ok(()); - }; - - // Do not allow password change if user is disabled or not enrolled - if !user.has_password() || !user.is_active { - debug!( - "Password reset skipped for disabled or not enrolled user {} ({email})", - user.username - ); - return Ok(()); - } - - let mut transaction = self.pool.begin().await.map_err(|_| { - error!("Failed to begin transaction"); - Status::internal("unexpected error") - })?; - - Token::delete_unused_user_password_reset_tokens(&mut transaction, user.id).await?; - - let enrollment = Token::new( - user.id, - None, - Some(email.clone()), - config.password_reset_token_timeout.as_secs(), - Some(PASSWORD_RESET_TOKEN_TYPE.to_string()), - ); - enrollment.save(&mut transaction).await?; - - transaction.commit().await.map_err(|_| { - error!("Failed to commit transaction"); - Status::internal("unexpected error") - })?; - - send_password_reset_email( - &user, - &self.mail_tx, - config.enrollment_url.clone(), - &enrollment.id, - Some(&ip_address), - Some(&user_agent), - )?; - - info!( - "Finished processing password reset request for user {}.", - user.username - ); - - Ok(()) - } - - pub async fn start_password_reset( - &self, - request: PasswordResetStartRequest, - ) -> Result { - debug!("Starting password reset session: {request:?}"); - - let mut enrollment = Token::find_by_id(&self.pool, &request.token).await?; - - if enrollment.token_type != Some("PASSWORD_RESET".to_string()) { - error!( - "Invalid token type ({:?}) for password reset session", - enrollment.token_type - ); - return Err(Status::permission_denied("invalid token")); - } - - let user = enrollment.fetch_user(&self.pool).await?; - - if !user.has_password() || !user.is_active { - error!( - "Can't start password reset for a disabled or not enrolled user {}.", - user.username - ); - return Err(Status::permission_denied( - "user disabled or not yet enrolled", - )); - } - - let mut transaction = self.pool.begin().await.map_err(|_| { - error!("Failed to begin transaction"); - Status::internal("unexpected error") - })?; - - let session_deadline = enrollment - .start_session( - &mut transaction, - server_config().password_reset_session_timeout.as_secs(), - ) - .await?; - - let response = PasswordResetStartResponse { - deadline_timestamp: session_deadline.and_utc().timestamp(), - }; - - transaction.commit().await.map_err(|_| { - error!("Failed to commit transaction"); - Status::internal("unexpected error") - })?; - - info!( - "Finished processing password reset session for user {}.", - user.username - ); - - Ok(response) - } - - pub async fn reset_password( - &self, - request: PasswordResetRequest, - req_device_info: Option, - ) -> Result<(), Status> { - debug!("Starting password reset: {request:?}"); - let enrollment = self.validate_session(&request.token).await?; - - let ip_address; - let user_agent; - if let Some(info) = req_device_info { - ip_address = info.ip_address.unwrap_or_default(); - user_agent = info.user_agent.unwrap_or_default(); - } else { - ip_address = String::new(); - user_agent = String::new(); - } - - if let Err(err) = check_password_strength(&request.password) { - error!("Password not strong enough: {err}"); - return Err(Status::invalid_argument("password not strong enough")); - } - - let mut user = enrollment.fetch_user(&self.pool).await?; - - if !user.is_active { - error!( - "Can't reset password for a disabled user {}.", - user.username - ); - return Err(Status::permission_denied("user disabled")); - } - - let mut transaction = self.pool.begin().await.map_err(|_| { - error!("Failed to begin transaction"); - Status::internal("unexpected error") - })?; - - // update user - user.set_password(&request.password); - user.save(&mut *transaction).await.map_err(|err| { - error!("Failed to update user {}: {err}", user.username); - Status::internal("unexpected error") - })?; - - // if self.ldap_feature_active { - let _ = ldap_change_password(&self.pool, &user.username, &request.password).await; - // }; - - transaction.commit().await.map_err(|_| { - error!("Failed to commit transaction"); - Status::internal("unexpected error") - })?; - - send_password_reset_success_email( - &user, - &self.mail_tx, - Some(&ip_address), - Some(&user_agent), - )?; - - Ok(()) - } -} diff --git a/src/grpc/enrollment.rs b/src/grpc/proxy.rs similarity index 58% rename from src/grpc/enrollment.rs rename to src/grpc/proxy.rs index c308d7523..22d2bea5b 100644 --- a/src/grpc/enrollment.rs +++ b/src/grpc/proxy.rs @@ -10,30 +10,37 @@ use super::{ proto::{ ActivateUserRequest, AdminInfo, Device as ProtoDevice, DeviceConfig as ProtoDeviceConfig, DeviceConfigResponse, EnrollmentStartRequest, EnrollmentStartResponse, ExistingDevice, - InitialUserInfo, NewDevice, + InitialUserInfo, NewDevice, PasswordResetInitializeRequest, PasswordResetRequest, + PasswordResetStartRequest, PasswordResetStartResponse, }, + utils::build_device_config_response, InstanceInfo, }; use crate::{ db::{ models::{ device::{DeviceConfig, DeviceInfo}, - enrollment::{Token, TokenError, ENROLLMENT_TOKEN_TYPE}, + enrollment::{Token, TokenError, ENROLLMENT_TOKEN_TYPE, PASSWORD_RESET_TOKEN_TYPE}, polling_token::PollingToken, }, Device, GatewayEvent, Id, Settings, User, }, enterprise::db::models::enterprise_settings::EnterpriseSettings, - grpc::utils::build_device_config_response, - handlers::{mail::send_new_device_added_email, user::check_password_strength}, + handlers::{ + mail::{ + send_new_device_added_email, send_password_reset_email, + send_password_reset_success_email, + }, + user::check_password_strength, + }, headers::get_device_info, - ldap::utils::ldap_add_user, + ldap::utils::{ldap_add_user, ldap_change_password}, mail::Mail, server_config, templates::{self, TemplateLocation}, }; -pub(super) struct EnrollmentServer { +pub(super) struct ProxyHandler { pool: PgPool, wireguard_tx: Sender, mail_tx: UnboundedSender, @@ -41,7 +48,7 @@ pub(super) struct EnrollmentServer { ldap_feature_active: bool, } -impl EnrollmentServer { +impl ProxyHandler { #[must_use] pub fn new( pool: PgPool, @@ -61,30 +68,30 @@ impl EnrollmentServer { } /// Checks if token provided with request corresponds to a valid enrollment session - async fn validate_session(&self, token: &Option) -> Result { + async fn validate_enrollment_session(&self, token: &Option) -> Result { info!("Validating enrollment session. Token: {token:?}"); let Some(token) = token else { error!("Missing authorization header in request"); return Err(Status::unauthenticated("Missing authorization header")); }; - let enrollment = Token::find_by_id(&self.pool, token).await?; - debug!("Found matching token, verifying validity: {enrollment:?}."); - if !enrollment + let token = Token::find_by_id(&self.pool, token).await?; + debug!("Found matching token, verifying validity: {token:?}."); + if !token .token_type .as_ref() .is_some_and(|token_type| token_type == ENROLLMENT_TOKEN_TYPE) { error!( "Invalid token type used in enrollment process: {:?}", - enrollment.token_type + token.token_type ); return Err(Status::permission_denied("invalid token")); } - if enrollment.is_session_valid(server_config().enrollment_session_timeout.as_secs()) { - info!("Enrollment session validated: {enrollment:?}"); - Ok(enrollment) + if token.is_session_valid(server_config().enrollment_session_timeout.as_secs()) { + info!("Enrollment session validated: {token:?}"); + Ok(token) } else { - error!("Enrollment session expired: {enrollment:?}"); + error!("Enrollment session expired: {token:?}"); Err(Status::unauthenticated("Session expired")) } } @@ -103,145 +110,140 @@ impl EnrollmentServer { debug!("Starting enrollment session, request: {request:?}"); // fetch enrollment token debug!("Try to find an enrollment token {}.", request.token); - let mut enrollment = Token::find_by_id(&self.pool, &request.token).await?; + let mut token = Token::find_by_id(&self.pool, &request.token).await?; - if let Some(token_type) = &enrollment.token_type { - if token_type != ENROLLMENT_TOKEN_TYPE { - error!("Invalid token type used while trying to start enrollment: {token_type}"); - return Err(Status::permission_denied("invalid token")); - } + let Some(token_type) = &token.token_type else { + debug!("Invalid enrollment token, the token does not have specified type."); + return Err(Status::permission_denied("invalid token")); + }; + + if token_type != ENROLLMENT_TOKEN_TYPE { + error!("Invalid token type used while trying to start enrollment: {token_type}"); + return Err(Status::permission_denied("invalid token")); + } - // fetch related users - let user = enrollment.fetch_user(&self.pool).await?; - let admin = enrollment.fetch_admin(&self.pool).await?; + // fetch related users + let user = token.fetch_user(&self.pool).await?; + let admin = token.fetch_admin(&self.pool).await?; - debug!( - "Checking if user {}({:?}) is active", - user.username, user.id - ); - if !user.is_active { - warn!( - "Can't start enrollment for disabled user {}.", - user.username - ); - return Err(Status::permission_denied("user is disabled")); - }; - info!( - "User {}({:?}) is active, proceeding with enrollment", - user.username, user.id + debug!("Checking if user {}({}) is active", user.username, user.id); + if !user.is_active { + warn!( + "Can't start enrollment for disabled user {}.", + user.username ); + return Err(Status::permission_denied("user is disabled")); + }; + info!( + "User {}({}) is active, proceeding with enrollment", + user.username, user.id + ); - let mut transaction = self.pool.begin().await.map_err(|err| { - error!("Failed to begin a transaction for enrollment: {err}"); + let mut transaction = self.pool.begin().await.map_err(|err| { + error!("Failed to begin a transaction for enrollment: {err}"); + Status::internal("unexpected error") + })?; + + // validate token & start session + debug!( + "Validating enrollment token and starting session for user {}({})", + user.username, user.id, + ); + let session_deadline = token + .start_session( + &mut transaction, + server_config().enrollment_session_timeout.as_secs(), + ) + .await?; + info!( + "Enrollment session started for user {}({})", + user.username, user.id + ); + + debug!( + "Retrieving settings for enrollment of user {}({}).", + user.username, user.id + ); + let settings = Settings::get_settings(&mut *transaction) + .await + .map_err(|err| { + error!("Failed to get settings: {err}"); Status::internal("unexpected error") })?; + debug!("Settings: {settings:?}"); - // validate token & start session - debug!( - "Validating enrollment token and starting session for user {}({:?})", - user.username, user.id, - ); - let session_deadline = enrollment - .start_session( - &mut transaction, - server_config().enrollment_session_timeout.as_secs(), - ) - .await?; - info!( - "Enrollment session started for user {}({:?})", - user.username, user.id - ); - - debug!( - "Retrieving settings for enrollment of user {}({:?}).", - user.username, user.id - ); - let settings = Settings::get_settings(&mut *transaction) + debug!( + "Retrieving enterprise settings for enrollment of user {}({}).", + user.username, user.id + ); + let enterprise_settings = + EnterpriseSettings::get(&mut *transaction) .await .map_err(|err| { - error!("Failed to get settings: {err}"); + error!("Failed to get enterprise settings: {err}"); Status::internal("unexpected error") })?; - debug!("Settings: {settings:?}"); + debug!("Enterprise settings: {enterprise_settings:?}"); - debug!( - "Retrieving enterprise settings for enrollment of user {}({:?}).", - user.username, user.id - ); - let enterprise_settings = - EnterpriseSettings::get(&mut *transaction) - .await - .map_err(|err| { - error!("Failed to get enterprise settings: {err}"); - Status::internal("unexpected error") - })?; - debug!("Enterprise settings: {enterprise_settings:?}"); - - let vpn_setup_optional = settings.enrollment_vpn_step_optional; - debug!( - "Retrieving instance info for user {}({:?}).", - user.username, user.id - ); - let instance_info = InstanceInfo::new(settings, &user.username, &enterprise_settings); - debug!("Instance info {instance_info:?}"); + let vpn_setup_optional = settings.enrollment_vpn_step_optional; + debug!( + "Retrieving instance info for user {}({}).", + user.username, user.id + ); + let instance_info = InstanceInfo::new(settings, &user.username, &enterprise_settings); + debug!("Instance info {instance_info:?}"); - debug!( - "Preparing initial user info to send for user enrollment, user {}({:?}).", - user.username, user.id - ); - let (username, user_id) = (user.username.clone(), user.id); - let user_info = InitialUserInfo::from_user(&self.pool, user) + debug!( + "Preparing initial user info to send for user enrollment, user {}({}).", + user.username, user.id + ); + let (username, user_id) = (user.username.clone(), user.id); + let user_info = InitialUserInfo::from_user(&self.pool, user) + .await + .map_err(|err| { + error!( + "Failed to get user info for user {}({}): {err}", + username, user_id, + ); + Status::internal("unexpected error") + })?; + debug!("User info {user_info:?}"); + + debug!("Trying to get basic admin info..."); + let admin_info = admin.map(AdminInfo::from); + debug!("Admin info {admin_info:?}"); + + debug!( + "Creating enrollment start response for user {}({}).", + username, user_id, + ); + let enterprise_settings = + EnterpriseSettings::get(&mut *transaction) .await .map_err(|err| { - error!( - "Failed to get user info for user {}({:?}): {err}", - username, user_id, - ); + error!("Failed to get enterprise settings: {err}"); Status::internal("unexpected error") })?; - debug!("User info {user_info:?}"); - - debug!("Trying to get basic admin info..."); - let admin_info = admin.map(AdminInfo::from); - debug!("Admin info {admin_info:?}"); + let enrollment_settings = super::proto::Settings { + vpn_setup_optional, + only_client_activation: enterprise_settings.only_client_activation, + }; + let response = super::proto::EnrollmentStartResponse { + admin: admin_info, + user: Some(user_info), + deadline_timestamp: session_deadline.and_utc().timestamp(), + final_page_content: token.get_welcome_page_content(&mut transaction).await?, + instance: Some(instance_info.into()), + settings: Some(enrollment_settings), + }; + debug!("Response {response:?}"); - debug!( - "Creating enrollment start response for user {}({:?}).", - username, user_id, - ); - let enterprise_settings = - EnterpriseSettings::get(&mut *transaction) - .await - .map_err(|err| { - error!("Failed to get enterprise settings: {err}"); - Status::internal("unexpected error") - })?; - let enrollment_settings = super::proto::Settings { - vpn_setup_optional, - only_client_activation: enterprise_settings.only_client_activation, - }; - let response = super::proto::EnrollmentStartResponse { - admin: admin_info, - user: Some(user_info), - deadline_timestamp: session_deadline.and_utc().timestamp(), - final_page_content: enrollment - .get_welcome_page_content(&mut transaction) - .await?, - instance: Some(instance_info.into()), - settings: Some(enrollment_settings), - }; - debug!("Response {response:?}"); - - transaction.commit().await.map_err(|err| { - error!("Failed to commit transaction: {err}"); - Status::internal("unexpected error") - })?; + transaction.commit().await.map_err(|err| { + error!("Failed to commit transaction: {err}"); + Status::internal("unexpected error") + })?; - Ok(response) - } else { - debug!("Invalid enrollment token, the token does not have specified type."); - Err(Status::permission_denied("invalid token")) - } + Ok(response) } pub async fn activate_user( @@ -250,7 +252,7 @@ impl EnrollmentServer { req_device_info: Option, ) -> Result<(), Status> { debug!("Activating user account: {request:?}"); - let enrollment = self.validate_session(&request.token).await?; + let enrollment = self.validate_enrollment_session(&request.token).await?; let ip_address; let device_info; @@ -262,7 +264,7 @@ impl EnrollmentServer { ip_address = String::new(); device_info = None; } - debug!("Ip address {}, device info {device_info:?}", ip_address); + debug!("IP address {}, device info {device_info:?}", ip_address); // check if password is strong enough debug!("Verifying password strength for user activation process."); @@ -370,19 +372,16 @@ impl EnrollmentServer { req_device_info: Option, ) -> Result { debug!("Adding new user device: {request:?}"); - let enrollment = self.validate_session(&request.token).await?; + let enrollment = self.validate_enrollment_session(&request.token).await?; // fetch related users let user = enrollment.fetch_user(&self.pool).await?; // add device - debug!( - "Verifying if user {}({:?}) is active", - user.username, user.id - ); + debug!("Verifying if user {}({}) is active", user.username, user.id); if !user.is_active { error!( - "Can't create device for disabled user {}({:?})", + "Can't create device for disabled user {}({})", user.username, user.id ); return Err(Status::invalid_argument( @@ -390,7 +389,7 @@ impl EnrollmentServer { )); } info!( - "User {}({:?}) is active, proceeding with device creation, pubkey: {}", + "User {}({}) is active, proceeding with device creation, pubkey: {}", user.username, user.id, request.pubkey ); @@ -404,27 +403,27 @@ impl EnrollmentServer { ip_address = String::new(); device_info = None; } - debug!("Ip address {}, device info {device_info:?}", ip_address); + debug!("IP address {}, device info {device_info:?}", ip_address); debug!( - "Validating pubkey {} for device creation process for user {}({:?})", + "Validating pubkey {} for device creation process for user {}({})", request.pubkey, user.username, user.id, ); Device::validate_pubkey(&request.pubkey).map_err(|err| { error!( - "Invalid pubkey {}, device won't be created for user {}({:?}): {err}", + "Invalid pubkey {}, device won't be created for user {}({}): {err}", request.pubkey, user.username, user.id ); Status::invalid_argument("invalid pubkey") })?; info!( - "Pubkey {} is valid for device creation process for user {}({:?})", + "Pubkey {} is valid for device creation process for user {}({})", request.pubkey, user.username, user.id ); // Make sure there is no device with the same pubkey, such state may lead to unexpected issues debug!( - "Checking pubkey {} uniqueness for device creation process for user {}({:?}).", + "Checking pubkey {} uniqueness for device creation process for user {}({}).", request.pubkey, user.username, user.id, ); if let Some(device) = Device::find_by_pubkey(&self.pool, &request.pubkey) @@ -438,7 +437,7 @@ impl EnrollmentServer { })? { warn!( - "User {}({:?}) failed to add device {}, identical pubkey ({}) already exists for device {}", + "User {}({}) failed to add device {}, identical pubkey ({}) already exists for device {}", user.username, user.id, request.name, @@ -448,7 +447,7 @@ impl EnrollmentServer { return Err(Status::invalid_argument("invalid key")); }; info!( - "Pubkey {} is unique for device creation process for user {}({:?}).", + "Pubkey {} is unique for device creation process for user {}({}).", request.pubkey, user.username, user.id ); @@ -458,7 +457,7 @@ impl EnrollmentServer { enrollment.user_id, ); debug!( - "Creating new device for user {}({:?}) {device:?}.", + "Creating new device for user {}({}) {device:?}.", user.username, user.id, ); @@ -468,7 +467,7 @@ impl EnrollmentServer { })?; let device = device.save(&mut *transaction).await.map_err(|err| { error!( - "Failed to save device {}, pubkey {} for user {}({:?}): {err}", + "Failed to save device {}, pubkey {} for user {}({}): {err}", request.name, request.pubkey, user.username, user.id, ); Status::internal("unexpected error") @@ -476,7 +475,7 @@ impl EnrollmentServer { info!("New device created: {device:?}."); debug!( - "Adding device {} to all existing user networks for user {}({:?}).", + "Adding device {} to all existing user networks for user {}({}).", device.wireguard_pubkey, user.username, user.id, ); let (network_info, configs) = @@ -492,11 +491,11 @@ impl EnrollmentServer { })?; info!( - "Added device {} to all existing user networks for user {}({:?})", + "Added device {} to all existing user networks for user {}({})", device.wireguard_pubkey, user.username, user.id ); debug!( - "Sending DeviceCreated event to gateway for device {}, user {}({:?})", + "Sending DeviceCreated event to gateway for device {}, user {}({})", device.wireguard_pubkey, user.username, user.id, ); self.send_wireguard_event(GatewayEvent::DeviceCreated(DeviceInfo { @@ -504,19 +503,19 @@ impl EnrollmentServer { network_info, })); info!( - "Sent DeviceCreated event to gateway for device {}, user {}({:?})", + "Sent DeviceCreated event to gateway for device {}, user {}({})", device.wireguard_pubkey, user.username, user.id, ); debug!( - "Fetching settings for device {} creation process for user {}({:?})", + "Fetching settings for device {} creation process for user {}({})", device.wireguard_pubkey, user.username, user.id, ); let settings = Settings::get_settings(&mut *transaction) .await .map_err(|err| { error!( - "Failed to fetch settings for device {} creation process for user {}({:?}): {err}", + "Failed to fetch settings for device {} creation process for user {}({}): {err}", device.wireguard_pubkey, user.username, user.id, ); Status::internal("unexpected error") @@ -524,14 +523,14 @@ impl EnrollmentServer { debug!("Settings: {settings:?}"); debug!( - "Fetching enterprise settings for device {} creation process for user {}({:?})", + "Fetching enterprise settings for device {} creation process for user {}({})", device.wireguard_pubkey, user.username, user.id, ); let enterprise_settings = EnterpriseSettings::get(&mut *transaction) .await .map_err(|err| { error!( - "Failed to fetch enterprise settings for device {} creation process for user {}({:?}): {err}", + "Failed to fetch enterprise settings for device {} creation process for user {}({}): {err}", device.wireguard_pubkey, user.username, user.id, ); Status::internal("unexpected error") @@ -540,7 +539,7 @@ impl EnrollmentServer { // create polling token for further client communication debug!( - "Creating polling token for further client communication for device {}, user {}({:?})", + "Creating polling token for further client communication for device {}, user {}({})", device.wireguard_pubkey, user.username, user.id, ); let token = PollingToken::new(device.id) @@ -548,19 +547,19 @@ impl EnrollmentServer { .await .map_err(|err| { error!( - "Failed to save PollingToken for device {}, user {}({:?}): {err}", + "Failed to save PollingToken for device {}, user {}({}): {err}", device.wireguard_pubkey, user.username, user.id ); Status::internal("failed to save polling token") })?; info!( - "Created polling token for further client communication for device: {}, user {}({:?})", + "Created polling token for further client communication for device: {}, user {}({})", device.wireguard_pubkey, user.username, user.id, ); transaction.commit().await.map_err(|err| { error!( - "Failed to commit transaction, device {} won't be created for user {}({:?}): {err}", + "Failed to commit transaction, device {} won't be created for user {}({}): {err}", device.wireguard_pubkey, user.username, user.id, ); Status::internal("unexpected error") @@ -575,7 +574,7 @@ impl EnrollmentServer { .collect(); debug!( - "Sending device created mail for device {}, user {}({:?})", + "Sending device created mail for device {}, user {}({})", device.wireguard_pubkey, user.username, user.id ); send_new_device_added_email( @@ -590,7 +589,7 @@ impl EnrollmentServer { .map_err(|_| Status::internal("error rendering email template"))?; info!( - "Device {} assigned to user {}({:?}) and added to all networks.", + "Device {} assigned to user {}({}) and added to all networks.", device.name, user.username, user.id, ); @@ -613,10 +612,248 @@ impl EnrollmentServer { request: ExistingDevice, ) -> Result { debug!("Getting network info for device: {:?}", request.pubkey); - let _token = self.validate_session(&request.token).await?; + let _token = self.validate_enrollment_session(&request.token).await?; build_device_config_response(&self.pool, &request.pubkey, true).await } + + /// Checks if token provided with request corresponds to a valid password reset session + async fn validate_password_reset_session( + &self, + token: &Option, + ) -> Result { + info!("Validating password reset session. Token: {token:?}"); + let Some(token) = token else { + error!("Missing authorization header in request"); + return Err(Status::unauthenticated("Missing authorization header")); + }; + let token = Token::find_by_id(&self.pool, token).await?; + debug!("Found matching token, verifying validity: {token:?}."); + if !token + .token_type + .as_ref() + .is_some_and(|token_type| token_type == PASSWORD_RESET_TOKEN_TYPE) + { + error!( + "Invalid token type used in password reset process: {:?}", + token.token_type + ); + return Err(Status::permission_denied("invalid token")); + } + + if token.is_session_valid(server_config().enrollment_session_timeout.as_secs()) { + info!("Password reset session validated: {token:?}.",); + Ok(token) + } else { + error!("Password reset session expired: {token:?}"); + Err(Status::unauthenticated("Session expired")) + } + } + + pub async fn request_password_reset( + &self, + request: PasswordResetInitializeRequest, + req_device_info: Option, + ) -> Result<(), Status> { + let config = server_config(); + debug!("Starting password reset request"); + + let ip_address; + let user_agent; + if let Some(info) = req_device_info { + ip_address = info.ip_address.unwrap_or_default(); + user_agent = info.user_agent.unwrap_or_default(); + } else { + ip_address = String::new(); + user_agent = String::new(); + } + + let email = request.email; + + let user = User::find_by_email(&self.pool, email.to_string().as_str()) + .await + .map_err(|_| { + error!("Failed to fetch user by email: {email}"); + Status::internal("unexpected error") + })?; + + let Some(user) = user else { + // Do not return information whether user exists + debug!("Password reset skipped for non-existing user {email}"); + return Ok(()); + }; + + // Do not allow password change if user is disabled or not enrolled + if !user.has_password() || !user.is_active { + debug!( + "Password reset skipped for disabled or not enrolled user {} ({email})", + user.username + ); + return Ok(()); + } + + let mut transaction = self.pool.begin().await.map_err(|_| { + error!("Failed to begin transaction"); + Status::internal("unexpected error") + })?; + + Token::delete_unused_user_password_reset_tokens(&mut transaction, user.id).await?; + + let enrollment = Token::new( + user.id, + None, + Some(email.clone()), + config.password_reset_token_timeout.as_secs(), + Some(PASSWORD_RESET_TOKEN_TYPE.to_string()), + ); + enrollment.save(&mut transaction).await?; + + transaction.commit().await.map_err(|_| { + error!("Failed to commit transaction"); + Status::internal("unexpected error") + })?; + + send_password_reset_email( + &user, + &self.mail_tx, + config.enrollment_url.clone(), + &enrollment.id, + Some(&ip_address), + Some(&user_agent), + )?; + + info!( + "Finished processing password reset request for user {}.", + user.username + ); + + Ok(()) + } + + pub async fn start_password_reset( + &self, + request: PasswordResetStartRequest, + ) -> Result { + debug!("Starting password reset session: {request:?}"); + + let mut token = Token::find_by_id(&self.pool, &request.token).await?; + + if !token + .token_type + .as_ref() + .is_some_and(|token_type| token_type == PASSWORD_RESET_TOKEN_TYPE) + { + error!( + "Invalid token type ({:?}) for password reset session", + token.token_type + ); + return Err(Status::permission_denied("invalid token")); + } + + let user = token.fetch_user(&self.pool).await?; + + if !user.has_password() || !user.is_active { + error!( + "Can't start password reset for a disabled or not enrolled user {}.", + user.username + ); + return Err(Status::permission_denied( + "user disabled or not yet enrolled", + )); + } + + let mut transaction = self.pool.begin().await.map_err(|_| { + error!("Failed to begin transaction"); + Status::internal("unexpected error") + })?; + + let session_deadline = token + .start_session( + &mut transaction, + server_config().password_reset_session_timeout.as_secs(), + ) + .await?; + + let response = PasswordResetStartResponse { + deadline_timestamp: session_deadline.and_utc().timestamp(), + }; + + transaction.commit().await.map_err(|_| { + error!("Failed to commit transaction"); + Status::internal("unexpected error") + })?; + + info!( + "Finished processing password reset session for user {}.", + user.username + ); + + Ok(response) + } + + pub async fn reset_password( + &self, + request: PasswordResetRequest, + req_device_info: Option, + ) -> Result<(), Status> { + debug!("Starting password reset: {request:?}"); + let enrollment = self.validate_password_reset_session(&request.token).await?; + + let ip_address; + let user_agent; + if let Some(info) = req_device_info { + ip_address = info.ip_address.unwrap_or_default(); + user_agent = info.user_agent.unwrap_or_default(); + } else { + ip_address = String::new(); + user_agent = String::new(); + } + + if let Err(err) = check_password_strength(&request.password) { + error!("Password not strong enough: {err}"); + return Err(Status::invalid_argument("password not strong enough")); + } + + let mut user = enrollment.fetch_user(&self.pool).await?; + + if !user.is_active { + error!( + "Can't reset password for a disabled user {}.", + user.username + ); + return Err(Status::permission_denied("user disabled")); + } + + let mut transaction = self.pool.begin().await.map_err(|_| { + error!("Failed to begin transaction"); + Status::internal("unexpected error") + })?; + + // update user + user.set_password(&request.password); + user.save(&mut *transaction).await.map_err(|err| { + error!("Failed to update user {}: {err}", user.username); + Status::internal("unexpected error") + })?; + + // if self.ldap_feature_active { + let _ = ldap_change_password(&self.pool, &user.username, &request.password).await; + // }; + + transaction.commit().await.map_err(|_| { + error!("Failed to commit transaction"); + Status::internal("unexpected error") + })?; + + send_password_reset_success_email( + &user, + &self.mail_tx, + Some(&ip_address), + Some(&user_agent), + )?; + + Ok(()) + } } impl From> for AdminInfo { diff --git a/src/mail.rs b/src/mail.rs index 6b93b326f..8b7845d2c 100644 --- a/src/mail.rs +++ b/src/mail.rs @@ -181,7 +181,7 @@ impl MailHandler { // Construct lettre Message let result_tx = mail.result_tx.clone(); - let message: Message = match mail.into_message(&settings.sender) { + let message = match mail.into_message(&settings.sender) { Ok(message) => message, Err(err) => { error!("Failed to build message to: {to}, subject: {subject}, error: {err}"); diff --git a/src/wireguard_peer_disconnect.rs b/src/wireguard_peer_disconnect.rs index e8d0fc0d4..723ce524c 100644 --- a/src/wireguard_peer_disconnect.rs +++ b/src/wireguard_peer_disconnect.rs @@ -48,9 +48,8 @@ pub async fn run_periodic_peer_disconnect( // get all MFA-protected locations let locations = query_as!( WireguardNetwork::, - "SELECT \ - id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, \ - connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold \ + "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, \ + connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold, gateways \ FROM wireguard_network WHERE mfa_enabled = true", ) .fetch_all(&pool) @@ -62,20 +61,20 @@ pub async fn run_periodic_peer_disconnect( let devices = query_as!( Device, "WITH stats AS ( \ - SELECT DISTINCT ON (device_id) device_id, endpoint, latest_handshake \ - FROM wireguard_peer_stats \ - WHERE network = $1 \ - ORDER BY device_id, collected_at DESC \ - ) \ + SELECT DISTINCT ON (device_id) device_id, endpoint, latest_handshake \ + FROM wireguard_peer_stats \ + WHERE network = $1 \ + ORDER BY device_id, collected_at DESC \ + ) \ SELECT d.id, d.name, d.wireguard_pubkey, d.user_id, d.created \ FROM device d \ JOIN wireguard_network_device wnd ON wnd.device_id = d.id \ LEFT JOIN stats on d.id = stats.device_id \ WHERE wnd.wireguard_network_id = $1 AND wnd.is_authorized = true AND \ - (wnd.authorized_at IS NULL OR (NOW() - wnd.authorized_at) > $2 * interval '1 second') AND \ - (stats.latest_handshake IS NULL OR (NOW() - stats.latest_handshake) > $2 * interval '1 second')", + (wnd.authorized_at IS NULL OR (NOW() - wnd.authorized_at) > $2 * interval '1s') AND \ + (stats.latest_handshake IS NULL OR (NOW() - stats.latest_handshake) > $2 * interval '1s')", location.id, - f64::from(location.peer_disconnect_threshold) + f64::from(location.peer_disconnect_threshold) ) .fetch_all(&pool) .await?; From a374e31e6f2487642bbb219f645340e3a7c3bd49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Tue, 15 Oct 2024 13:17:13 +0200 Subject: [PATCH 05/26] Gateways is a list of string --- ...cb7387eca5822e9cc45205bcbc0d2fcb21d97.json | 2 +- ...9105d0f94ca2d204e25148b63b833ba69459b.json | 2 +- ...73aa9c95ce849f71f2a36d10797fa5cf8f834.json | 2 +- ...4f15e69dbf56925fed7a2ae98f449cc23a815.json | 2 +- ...10219bd0eb14a5bb95e65844fc919a77fdc3d.json | 2 +- ...04730a4d22fd487a1dc6c13575c0f1aa394f4.json | 2 +- .../20241015074303_network_gateways.up.sql | 2 +- src/db/models/wireguard.rs | 44 +++++++++++++------ src/grpc/mod.rs | 30 +++++-------- src/handlers/wireguard.rs | 9 ++-- src/lib.rs | 5 +-- src/wg_config.rs | 2 +- src/wireguard_peer_disconnect.rs | 12 +---- tests/wireguard_network_import.rs | 3 +- 14 files changed, 60 insertions(+), 59 deletions(-) diff --git a/.sqlx/query-722d953898ad19874bfb026f2a1cb7387eca5822e9cc45205bcbc0d2fcb21d97.json b/.sqlx/query-722d953898ad19874bfb026f2a1cb7387eca5822e9cc45205bcbc0d2fcb21d97.json index 75978ff6c..a12b4aeab 100644 --- a/.sqlx/query-722d953898ad19874bfb026f2a1cb7387eca5822e9cc45205bcbc0d2fcb21d97.json +++ b/.sqlx/query-722d953898ad19874bfb026f2a1cb7387eca5822e9cc45205bcbc0d2fcb21d97.json @@ -71,7 +71,7 @@ { "ordinal": 13, "name": "gateways", - "type_info": "InetArray" + "type_info": "TextArray" } ], "parameters": { diff --git a/.sqlx/query-8f397a1393682f42600ba4799b69105d0f94ca2d204e25148b63b833ba69459b.json b/.sqlx/query-8f397a1393682f42600ba4799b69105d0f94ca2d204e25148b63b833ba69459b.json index 08e7d818c..1c46253a4 100644 --- a/.sqlx/query-8f397a1393682f42600ba4799b69105d0f94ca2d204e25148b63b833ba69459b.json +++ b/.sqlx/query-8f397a1393682f42600ba4799b69105d0f94ca2d204e25148b63b833ba69459b.json @@ -71,7 +71,7 @@ { "ordinal": 13, "name": "gateways", - "type_info": "InetArray" + "type_info": "TextArray" } ], "parameters": { diff --git a/.sqlx/query-d4b301389bd9f8d87517841cd5573aa9c95ce849f71f2a36d10797fa5cf8f834.json b/.sqlx/query-d4b301389bd9f8d87517841cd5573aa9c95ce849f71f2a36d10797fa5cf8f834.json index 1e0fd7119..9388c5467 100644 --- a/.sqlx/query-d4b301389bd9f8d87517841cd5573aa9c95ce849f71f2a36d10797fa5cf8f834.json +++ b/.sqlx/query-d4b301389bd9f8d87517841cd5573aa9c95ce849f71f2a36d10797fa5cf8f834.json @@ -18,7 +18,7 @@ "Bool", "Int4", "Int4", - "InetArray" + "TextArray" ] }, "nullable": [] diff --git a/.sqlx/query-db50a47b12760f342f4856593254f15e69dbf56925fed7a2ae98f449cc23a815.json b/.sqlx/query-db50a47b12760f342f4856593254f15e69dbf56925fed7a2ae98f449cc23a815.json index f927b3022..cb07063fa 100644 --- a/.sqlx/query-db50a47b12760f342f4856593254f15e69dbf56925fed7a2ae98f449cc23a815.json +++ b/.sqlx/query-db50a47b12760f342f4856593254f15e69dbf56925fed7a2ae98f449cc23a815.json @@ -23,7 +23,7 @@ "Bool", "Int4", "Int4", - "InetArray" + "TextArray" ] }, "nullable": [ diff --git a/.sqlx/query-f0bf6cbba9693a015a995f00dac10219bd0eb14a5bb95e65844fc919a77fdc3d.json b/.sqlx/query-f0bf6cbba9693a015a995f00dac10219bd0eb14a5bb95e65844fc919a77fdc3d.json index fa877bf42..a7f9f03ba 100644 --- a/.sqlx/query-f0bf6cbba9693a015a995f00dac10219bd0eb14a5bb95e65844fc919a77fdc3d.json +++ b/.sqlx/query-f0bf6cbba9693a015a995f00dac10219bd0eb14a5bb95e65844fc919a77fdc3d.json @@ -71,7 +71,7 @@ { "ordinal": 13, "name": "gateways: _", - "type_info": "InetArray" + "type_info": "TextArray" } ], "parameters": { diff --git a/.sqlx/query-f568188bc7c8b54ffccad38cee004730a4d22fd487a1dc6c13575c0f1aa394f4.json b/.sqlx/query-f568188bc7c8b54ffccad38cee004730a4d22fd487a1dc6c13575c0f1aa394f4.json index 056328e66..a4c5e6ca4 100644 --- a/.sqlx/query-f568188bc7c8b54ffccad38cee004730a4d22fd487a1dc6c13575c0f1aa394f4.json +++ b/.sqlx/query-f568188bc7c8b54ffccad38cee004730a4d22fd487a1dc6c13575c0f1aa394f4.json @@ -71,7 +71,7 @@ { "ordinal": 13, "name": "gateways: _", - "type_info": "InetArray" + "type_info": "TextArray" } ], "parameters": { diff --git a/migrations/20241015074303_network_gateways.up.sql b/migrations/20241015074303_network_gateways.up.sql index 8dd37e805..9c866c4ef 100644 --- a/migrations/20241015074303_network_gateways.up.sql +++ b/migrations/20241015074303_network_gateways.up.sql @@ -1 +1 @@ -ALTER TABLE wireguard_network ADD COLUMN gateways inet[] NOT NULL DEFAULT array[]::inet[]; +ALTER TABLE wireguard_network ADD COLUMN gateways text[] NOT NULL DEFAULT array[]::text[]; diff --git a/src/db/models/wireguard.rs b/src/db/models/wireguard.rs index 6134a1ac7..0149e1eca 100644 --- a/src/db/models/wireguard.rs +++ b/src/db/models/wireguard.rs @@ -30,8 +30,8 @@ use crate::{ pub const DEFAULT_KEEPALIVE_INTERVAL: i32 = 25; pub const DEFAULT_DISCONNECT_THRESHOLD: i32 = 180; -// Used in process of importing network from wireguard config -#[derive(Clone, Debug, Deserialize, Serialize)] +// Used in process of importing network from WireGuard config +#[derive(Debug, Deserialize, Serialize)] pub struct MappedDevice { pub user_id: Id, pub name: String, @@ -88,8 +88,9 @@ pub struct WireguardNetwork { pub mfa_enabled: bool, pub keepalive_interval: i32, pub peer_disconnect_threshold: i32, + // URLs pointing to all gateways serving gRPC #[model(ref)] - pub gateways: Vec, + pub gateways: Vec, } pub struct WireguardKey { @@ -130,6 +131,7 @@ pub enum WireguardNetworkError { } impl WireguardNetwork { + #[must_use] pub fn new( name: String, address: IpNetwork, @@ -140,10 +142,10 @@ impl WireguardNetwork { mfa_enabled: bool, keepalive_interval: i32, peer_disconnect_threshold: i32, - ) -> Result { + ) -> Self { let prvkey = StaticSecret::random_from_rng(OsRng); let pubkey = PublicKey::from(&prvkey); - Ok(Self { + Self { id: NoId, name, address, @@ -158,7 +160,7 @@ impl WireguardNetwork { keepalive_interval, peer_disconnect_threshold, gateways: Vec::new(), - }) + } } /// Try to set `address` from `&str`. @@ -173,12 +175,12 @@ impl WireguardNetwork { pub async fn find_by_name<'e, E>( executor: E, name: &str, - ) -> Result>, WireguardNetworkError> + ) -> Result>, SqlxError> where E: PgExecutor<'e>, { let networks = query_as!( - WireguardNetwork, + Self, "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, \ connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold, gateways \ FROM wireguard_network WHERE name = $1", @@ -194,6 +196,21 @@ impl WireguardNetwork { }) } + /// Fetch all networks with MFA protection turned on. + pub(crate) async fn all_mfa_enabled<'e, E>(executor: E) -> Result, SqlxError> + where + E: PgExecutor<'e>, + { + query_as!( + Self, + "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, \ + connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold, gateways \ + FROM wireguard_network WHERE mfa_enabled = true", + ) + .fetch_all(executor) + .await + } + /// Run `sync_allowed_devices()` on all WireGuard networks. pub async fn sync_all_networks(app: &AppState) -> Result<(), WireguardNetworkError> { info!("Syncing allowed devices for all WireGuard locations"); @@ -394,7 +411,7 @@ impl WireguardNetwork { Ok(wireguard_network_device) } else { info!("Device {device} not allowed in network {self}"); - Err(WireguardNetworkError::DeviceNotAllowed(format!("{device}"))) + Err(WireguardNetworkError::DeviceNotAllowed(device.to_string())) } } @@ -561,7 +578,7 @@ impl WireguardNetwork { pub async fn handle_mapped_devices( &self, transaction: &mut PgConnection, - mapped_devices: Vec, + mapped_devices: &[MappedDevice], ) -> Result, WireguardNetworkError> { info!("Mapping user devices for network {}", self); // get allowed groups for network @@ -570,7 +587,7 @@ impl WireguardNetwork { let mut events = Vec::new(); // use a helper hashmap to avoid repeated queries let mut user_groups = HashMap::new(); - for mapped_device in &mapped_devices { + for mapped_device in mapped_devices { debug!("Mapping device {}", mapped_device.name); // validate device pubkey Device::validate_pubkey(&mapped_device.wireguard_pubkey).map_err(|_| { @@ -660,8 +677,9 @@ impl WireguardNetwork { ) -> Result>, SqlxError> { let stats = query_as!( WireguardPeerStats, - "SELECT id, device_id \"device_id!\", collected_at \"collected_at!\", network \"network!\", \ - endpoint, upload \"upload!\", download \"download!\", latest_handshake \"latest_handshake!\", allowed_ips \ + "SELECT id, device_id \"device_id!\", collected_at \"collected_at!\", \ + network \"network!\", endpoint, upload \"upload!\", download \"download!\", \ + latest_handshake \"latest_handshake!\", allowed_ips \ FROM wireguard_peer_stats \ WHERE device_id = $1 AND network = $2 \ ORDER BY collected_at DESC \ diff --git a/src/grpc/mod.rs b/src/grpc/mod.rs index 3f812eec0..732e8b1a3 100644 --- a/src/grpc/mod.rs +++ b/src/grpc/mod.rs @@ -374,20 +374,18 @@ pub async fn run_grpc_bidi_stream( } else { endpoint }; + let uri = endpoint.uri(); loop { - debug!("Connecting to proxy at {}", endpoint.uri()); + debug!("Connecting to proxy at {uri}",); let mut client = ProxyClient::new(endpoint.connect_lazy()); let (tx, rx) = mpsc::unbounded_channel(); let Ok(response) = client.bidi(UnboundedReceiverStream::new(rx)).await else { - error!( - "Failed to connect to proxy @ {}, retrying in 10s", - endpoint.uri() - ); + error!("Failed to connect to proxy @ {uri}, retrying in 10s",); sleep(TEN_SECS).await; continue; }; - info!("Connected to proxy at {}", endpoint.uri()); + info!("Connected to proxy at {uri}"); let mut resp_stream = response.into_inner(); 'message: loop { match resp_stream.message().await { @@ -520,18 +518,14 @@ pub async fn run_grpc_bidi_stream( Some(core_response::Payload::InstanceInfo(response_payload)) } Err(err) => { - match err.code() { - // Ignore the case when we are not enterprise but the client is trying to fetch the instance config, - // to avoid spamming the logs with misleading errors. - Code::FailedPrecondition => { - debug!("A client tried to fetch the instance config, but we are not enterprise."); - Some(core_response::Payload::CoreError(err.into())) - } - _ => { - error!("Instance info error {err}"); - Some(core_response::Payload::CoreError(err.into())) - } + // Ignore the case when we are not enterprise but the client is trying to fetch the instance config, + // to avoid spamming the logs with misleading errors. + if err.code() == Code::FailedPrecondition { + debug!("A client tried to fetch the instance config, but we are not enterprise."); + } else { + error!("Instance info error {err}"); } + Some(core_response::Payload::CoreError(err.into())) } } } @@ -545,7 +539,7 @@ pub async fn run_grpc_bidi_stream( tx.send(req).unwrap(); } Err(err) => { - error!("Disconnected from proxy at {}", endpoint.uri()); + error!("Disconnected from proxy at {uri}"); error!("stream error: {err}"); debug!("waiting 10s to re-establish the connection"); sleep(TEN_SECS).await; diff --git a/src/handlers/wireguard.rs b/src/handlers/wireguard.rs index 149433e2d..07969d3e6 100644 --- a/src/handlers/wireguard.rs +++ b/src/handlers/wireguard.rs @@ -62,7 +62,7 @@ impl WireguardNetworkData { } // Used in process of importing network from WireGuard config -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Debug, Deserialize, Serialize)] pub struct MappedDevices { pub devices: Vec, } @@ -114,8 +114,7 @@ pub async fn create_network( data.mfa_enabled, data.keepalive_interval, data.peer_disconnect_threshold, - ) - .map_err(|_| WebError::Serialization("Invalid network address".into()))?; + ); let mut transaction = appstate.pool.begin().await?; let network = network.save(&mut *transaction).await?; @@ -388,7 +387,7 @@ pub async fn add_user_devices( Path(network_id): Path, Json(request_data): Json, ) -> ApiResult { - let mapped_devices = request_data.devices.clone(); + let mapped_devices = request_data.devices; let user = session.user; let device_count = mapped_devices.len(); @@ -410,7 +409,7 @@ pub async fn add_user_devices( // wrap loop in transaction to abort if a device is invalid let mut transaction = appstate.pool.begin().await?; let events = network - .handle_mapped_devices(&mut transaction, mapped_devices) + .handle_mapped_devices(&mut transaction, mapped_devices.as_slice()) .await?; appstate.send_multiple_wireguard_events(events); transaction.commit().await?; diff --git a/src/lib.rs b/src/lib.rs index f3f2f3deb..49522dd0f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -594,8 +594,7 @@ pub async fn init_dev_env(config: &DefGuardConfig) { false, DEFAULT_KEEPALIVE_INTERVAL, DEFAULT_DISCONNECT_THRESHOLD, - ) - .expect("Could not create network"); + ); network.pubkey = "zGMeVGm9HV9I4wSKF9AXmYnnAIhDySyqLMuKpcfIaQo=".to_string(); network.prvkey = "MAk3d5KuB167G88HM7nGYR6ksnPMAOguAg2s5EcPp1M=".to_string(); network @@ -674,7 +673,7 @@ pub async fn init_vpn_location( false, DEFAULT_KEEPALIVE_INTERVAL, DEFAULT_DISCONNECT_THRESHOLD, - )? + ) .save(pool) .await?; diff --git a/src/wg_config.rs b/src/wg_config.rs index 0e65ac62f..8c171e8f4 100644 --- a/src/wg_config.rs +++ b/src/wg_config.rs @@ -94,7 +94,7 @@ pub fn parse_wireguard_config( false, DEFAULT_KEEPALIVE_INTERVAL, DEFAULT_DISCONNECT_THRESHOLD, - )?; + ); network.pubkey = pubkey; network.prvkey = prvkey.to_string(); diff --git a/src/wireguard_peer_disconnect.rs b/src/wireguard_peer_disconnect.rs index 723ce524c..af9ee999f 100644 --- a/src/wireguard_peer_disconnect.rs +++ b/src/wireguard_peer_disconnect.rs @@ -16,7 +16,7 @@ use crate::db::{ error::ModelError, wireguard::WireguardNetworkError, }, - Device, GatewayEvent, Id, WireguardNetwork, + Device, GatewayEvent, WireguardNetwork, }; // How long to sleep between loop iterations @@ -45,15 +45,7 @@ pub async fn run_periodic_peer_disconnect( loop { debug!("Starting periodic inactive device disconnect"); - // get all MFA-protected locations - let locations = query_as!( - WireguardNetwork::, - "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, \ - connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold, gateways \ - FROM wireguard_network WHERE mfa_enabled = true", - ) - .fetch_all(&pool) - .await?; + let locations = WireguardNetwork::all_mfa_enabled(&pool).await?; // loop over all locations for location in locations { diff --git a/tests/wireguard_network_import.rs b/tests/wireguard_network_import.rs index d5e43656f..96fb5a5cd 100644 --- a/tests/wireguard_network_import.rs +++ b/tests/wireguard_network_import.rs @@ -55,8 +55,7 @@ async fn test_config_import() { false, DEFAULT_KEEPALIVE_INTERVAL, DEFAULT_DISCONNECT_THRESHOLD, - ) - .unwrap(); + ); initial_network.save(&pool).await.unwrap(); // add existing devices From 7f9906adbc2b7f7879520068dbfe21ee340040f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Wed, 16 Oct 2024 15:57:51 +0200 Subject: [PATCH 06/26] WIP: gateway RPC client --- .../20241015074303_network_gateways.down.sql | 2 +- .../20241015074303_network_gateways.up.sql | 6 +- src/bin/defguard.rs | 5 +- src/db/models/wireguard.rs | 11 +- src/grpc/gateway.rs | 84 +++++++++- src/grpc/mod.rs | 145 ++++++++++-------- src/handlers/mail.rs | 4 +- src/handlers/wireguard.rs | 9 +- 8 files changed, 184 insertions(+), 82 deletions(-) diff --git a/migrations/20241015074303_network_gateways.down.sql b/migrations/20241015074303_network_gateways.down.sql index 0197bef93..6bbc938ef 100644 --- a/migrations/20241015074303_network_gateways.down.sql +++ b/migrations/20241015074303_network_gateways.down.sql @@ -1 +1 @@ -ALTER TABLE wireguard_network DROP COLUMN gateways; +DROP TABLE gateway; diff --git a/migrations/20241015074303_network_gateways.up.sql b/migrations/20241015074303_network_gateways.up.sql index 9c866c4ef..000a79a0c 100644 --- a/migrations/20241015074303_network_gateways.up.sql +++ b/migrations/20241015074303_network_gateways.up.sql @@ -1 +1,5 @@ -ALTER TABLE wireguard_network ADD COLUMN gateways text[] NOT NULL DEFAULT array[]::text[]; +CREATE TABLE gateway ( + id bigserial PRIMARY KEY, + network_id bigint NOT NULL, + FOREIGN KEY(network_id) REFERENCES wireguard_network(id) +); diff --git a/src/bin/defguard.rs b/src/bin/defguard.rs index 5626e1ef0..9521ae363 100644 --- a/src/bin/defguard.rs +++ b/src/bin/defguard.rs @@ -8,7 +8,9 @@ use defguard::{ config::{Command, DefGuardConfig}, db::{init_db, AppEvent, GatewayEvent, Settings, User}, enterprise::license::{run_periodic_license_check, set_cached_license, License}, - grpc::{run_grpc_bidi_stream, run_grpc_server, GatewayMap, WorkerState}, + grpc::{ + run_grpc_bidi_stream, run_grpc_gateway_stream, run_grpc_server, GatewayMap, WorkerState, + }, headers::create_user_agent_parser, init_dev_env, init_vpn_location, mail::{run_mail_handler, Mail}, @@ -114,6 +116,7 @@ async fn main() -> Result<(), anyhow::Error> { // run services tokio::select! { + res = run_grpc_gateway_stream(pool.clone()) => error!("Gateway gRPC stream returned early: {res:#?}"), res = run_grpc_bidi_stream(pool.clone(), wireguard_tx.clone(), mail_tx.clone(), user_agent_parser.clone()), if config.proxy_url.is_some() => error!("Proxy gRPC stream returned early: {res:#?}"), res = run_grpc_server(Arc::clone(&worker_state), pool.clone(), Arc::clone(&gateway_map), wireguard_tx.clone(), mail_tx.clone(), grpc_cert, grpc_key, failed_logins.clone()) => error!("gRPC server returned early: {res:#?}"), res = run_web_server(worker_state, gateway_map, webhook_tx, webhook_rx, wireguard_tx.clone(), mail_tx, pool.clone(), user_agent_parser, failed_logins) => error!("Web server returned early: {res:#?}"), diff --git a/src/db/models/wireguard.rs b/src/db/models/wireguard.rs index 0149e1eca..b384a18bb 100644 --- a/src/db/models/wireguard.rs +++ b/src/db/models/wireguard.rs @@ -88,9 +88,6 @@ pub struct WireguardNetwork { pub mfa_enabled: bool, pub keepalive_interval: i32, pub peer_disconnect_threshold: i32, - // URLs pointing to all gateways serving gRPC - #[model(ref)] - pub gateways: Vec, } pub struct WireguardKey { @@ -159,7 +156,6 @@ impl WireguardNetwork { mfa_enabled, keepalive_interval, peer_disconnect_threshold, - gateways: Vec::new(), } } @@ -182,7 +178,7 @@ impl WireguardNetwork { let networks = query_as!( Self, "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, \ - connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold, gateways \ + connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold \ FROM wireguard_network WHERE name = $1", name ) @@ -204,7 +200,7 @@ impl WireguardNetwork { query_as!( Self, "SELECT id, name, address, port, pubkey, prvkey, endpoint, dns, allowed_ips, \ - connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold, gateways \ + connected_at, mfa_enabled, keepalive_interval, peer_disconnect_threshold \ FROM wireguard_network WHERE mfa_enabled = true", ) .fetch_all(executor) @@ -959,12 +955,11 @@ impl Default for WireguardNetwork { mfa_enabled: false, keepalive_interval: DEFAULT_KEEPALIVE_INTERVAL, peer_disconnect_threshold: DEFAULT_DISCONNECT_THRESHOLD, - gateways: Vec::default(), } } } -#[derive(Serialize, Clone, Debug)] +#[derive(Debug, Serialize)] pub struct WireguardNetworkInfo { #[serde(flatten)] pub network: WireguardNetwork, diff --git a/src/grpc/gateway.rs b/src/grpc/gateway.rs index 5fedabf81..41ef42192 100644 --- a/src/grpc/gateway.rs +++ b/src/grpc/gateway.rs @@ -1,7 +1,9 @@ use std::{ + fs::read_to_string, pin::Pin, sync::{Arc, Mutex}, task::{Context, Poll}, + time::Duration, }; use chrono::{DateTime, Utc}; @@ -12,9 +14,14 @@ use tokio::{ mpsc::{self, Receiver, UnboundedSender}, }, task::JoinHandle, + time::sleep, +}; +use tokio_stream::{wrappers::UnboundedReceiverStream, Stream}; +use tonic::{ + metadata::MetadataMap, + transport::{Certificate, ClientTlsConfig, Endpoint, Identity, Server}, + Code, Request, Response, Status, }; -use tokio_stream::Stream; -use tonic::{metadata::MetadataMap, Code, Request, Response, Status}; use super::GatewayMap; use crate::{ @@ -166,6 +173,79 @@ impl WireguardPeerStats { } } +// TODO: merge with super. +const TEN_SECS: Duration = Duration::from_secs(10); + +pub(super) struct GatewayHandler { + endpoint: Endpoint, +} + +impl GatewayHandler { + pub(super) fn new(url: &str, ca_path: Option<&str>) -> Result { + let endpoint = Endpoint::from_shared(url.to_string())?; + let endpoint = endpoint + .http2_keep_alive_interval(TEN_SECS) + .tcp_keepalive(Some(TEN_SECS)) + .keep_alive_while_idle(true); + let endpoint = if let Some(ca) = ca_path { + let ca = read_to_string(ca).unwrap(); // FIXME: use custom error + let tls = ClientTlsConfig::new().ca_certificate(Certificate::from_pem(ca)); + endpoint.tls_config(tls)? + } else { + endpoint + }; + + Ok(Self { endpoint }) + } + + pub(super) async fn handle_connection(&self) -> ! { + let uri = self.endpoint.uri(); + loop { + debug!("Connecting to gateway at {uri}"); + let mut client = gateway_client::GatewayClient::new(self.endpoint.connect_lazy()); + let (tx, rx) = mpsc::unbounded_channel(); + let Ok(response) = client.bidi(UnboundedReceiverStream::new(rx)).await else { + error!("Failed to connect to gateway @ {uri}, retrying in 10s",); + sleep(TEN_SECS).await; + continue; + }; + info!("Connected to proxy at {uri}"); + let mut resp_stream = response.into_inner(); + 'message: loop { + match resp_stream.message().await { + Ok(None) => { + info!("stream was closed by the sender"); + break 'message; + } + Ok(Some(received)) => { + info!("Received message from gateway."); + debug!("Received the following message from gateway: {received:?}"); + let payload: Option = match received.payload { + Some(core_request::Payload::ConfigRequest(config_request)) => { + info!("*** ConfigurationRequest {config_request:?}"); + None + } + Some(core_request::Payload::PeerStats(peer_stats)) => { + info!("*** PeerStats {peer_stats:?}"); + None + } + // Reply without payload. + None => None, + }; + } + Err(err) => { + error!("Disconnected from gateway at {uri}"); + error!("stream error: {err}"); + debug!("waiting 10s to re-establish the connection"); + sleep(TEN_SECS).await; + break 'message; + } + } + } + } + } +} + /// Helper struct for handling gateway events struct GatewayUpdatesHandler { network_id: Id, diff --git a/src/grpc/mod.rs b/src/grpc/mod.rs index 732e8b1a3..da749dd80 100644 --- a/src/grpc/mod.rs +++ b/src/grpc/mod.rs @@ -20,6 +20,7 @@ use tokio::{ broadcast::Sender, mpsc::{self, UnboundedSender}, }, + task::JoinSet, time::sleep, }; use tokio_stream::wrappers::UnboundedReceiverStream; @@ -28,10 +29,9 @@ use tonic::{ Code, Status, }; use uaparser::UserAgentParser; -use uuid::Uuid; #[cfg(feature = "wireguard")] -use self::gateway::{gateway_service_server::GatewayServiceServer, GatewayServer}; +use self::gateway::GatewayHandler; use self::{ auth::{auth_service_server::AuthServiceServer, AuthServer}, desktop_client_mfa::ClientMfaServer, @@ -78,7 +78,6 @@ use proto::{core_request, proxy_client::ProxyClient, CoreError, CoreResponse}; // Helper struct used to handle gateway state // gateways are grouped by network type GatewayHostname = String; -#[derive(Debug)] pub struct GatewayMap(HashMap>); #[derive(Error, Debug)] @@ -88,9 +87,9 @@ pub enum GatewayMapError { #[error("Network {0} not found")] NetworkNotFound(i64), #[error("Gateway with UID {0} not found")] - UidNotFound(Uuid), + UidNotFound(Id), #[error("Cannot remove. Gateway with UID {0} is still active")] - RemoveActive(Uuid), + RemoveActive(Id), #[error("Config missing")] ConfigError, } @@ -104,44 +103,44 @@ impl GatewayMap { // add a new gateway to map // this method is meant to be called when a gateway requests a config // as a sort of "registration" - pub fn add_gateway( - &mut self, - network_id: Id, - network_name: &str, - hostname: String, - name: Option, - mail_tx: UnboundedSender, - ) { - info!("Adding gateway {hostname} with to gateway map for network {network_id}",); - let gateway_state = GatewayState::new(network_id, network_name, &hostname, name, mail_tx); - - if let Some(network_gateway_map) = self.0.get_mut(&network_id) { - network_gateway_map.entry(hostname).or_insert(gateway_state); - } else { - // no map for a given network exists yet - let mut network_gateway_map = HashMap::new(); - network_gateway_map.insert(hostname, gateway_state); - self.0.insert(network_id, network_gateway_map); - } - } + // pub fn add_gateway( + // &mut self, + // network_id: Id, + // network_name: &str, + // hostname: String, + // name: Option, + // mail_tx: UnboundedSender, + // ) { + // info!("Adding gateway {hostname} with to gateway map for network {network_id}",); + // let gateway_state = GatewayState::new(network_id, network_name, &hostname, name, mail_tx); + + // if let Some(network_gateway_map) = self.0.get_mut(&network_id) { + // network_gateway_map.entry(hostname).or_insert(gateway_state); + // } else { + // // no map for a given network exists yet + // let mut network_gateway_map = HashMap::new(); + // network_gateway_map.insert(hostname, gateway_state); + // self.0.insert(network_id, network_gateway_map); + // } + // } // remove gateway from map - pub fn remove_gateway(&mut self, network_id: Id, uid: Uuid) -> Result<(), GatewayMapError> { + pub fn remove_gateway(&mut self, network_id: Id, id: Id) -> Result<(), GatewayMapError> { debug!("Removing gateway from network {network_id}"); if let Some(network_gateway_map) = self.0.get_mut(&network_id) { // find gateway by uuid let hostname = match network_gateway_map .iter() - .find(|(_address, state)| state.uid == uid) + .find(|(_address, state)| state.id == id) { None => { - error!("Failed to find gateway with UID {uid}"); - return Err(GatewayMapError::UidNotFound(uid)); + error!("Failed to find gateway with ID {id}"); + return Err(GatewayMapError::UidNotFound(id)); } Some((hostname, state)) => { if state.connected { - error!("Cannot remove. Gateway with UID {uid} is still active"); - return Err(GatewayMapError::RemoveActive(uid)); + error!("Cannot remove. Gateway with UID {id} is still active"); + return Err(GatewayMapError::RemoveActive(id)); } hostname.clone() } @@ -153,7 +152,8 @@ impl GatewayMap { error!("Network {network_id} not found in gateway map"); return Err(GatewayMapError::NetworkNotFound(network_id)); }; - info!("Gateway with UID {uid} removed from network {network_id}"); + + info!("Gateway with UID {id} removed from network {network_id}"); Ok(()) } @@ -183,6 +183,7 @@ impl GatewayMap { error!("Network {network_id} not found in gateway map"); return Err(GatewayMapError::NetworkNotFound(network_id)); }; + info!("Gateway {hostname} connected in network {network_id}"); Ok(()) } @@ -252,9 +253,9 @@ impl Default for GatewayMap { } } -#[derive(Serialize, Clone, Debug)] -pub struct GatewayState { - pub uid: Uuid, +#[derive(Clone, Debug, Serialize)] +pub(crate) struct GatewayState { + pub id: Id, pub connected: bool, pub network_id: Id, pub network_name: String, @@ -269,27 +270,27 @@ pub struct GatewayState { } impl GatewayState { - #[must_use] - pub fn new>( - network_id: Id, - network_name: S, - hostname: S, - name: Option, - mail_tx: UnboundedSender, - ) -> Self { - Self { - uid: Uuid::new_v4(), - connected: false, - network_id, - network_name: network_name.into(), - name, - hostname: hostname.into(), - connected_at: None, - disconnected_at: None, - mail_tx, - last_email_notification: None, - } - } + // #[must_use] + // pub fn new>( + // network_id: Id, + // network_name: S, + // hostname: S, + // name: Option, + // mail_tx: UnboundedSender, + // ) -> Self { + // Self { + // uid: Uuid::new_v4(), + // connected: false, + // network_id, + // network_name: network_name.into(), + // name, + // hostname: hostname.into(), + // connected_at: None, + // disconnected_at: None, + // mail_tx, + // last_email_notification: None, + // } + // } /// Send gateway disconnected notification /// Sends notification only if last notification time is bigger than specified in config @@ -315,11 +316,11 @@ impl GatewayState { // FIXME: Try to get rid of spawn and use something like block_on // To return result instead of logging tokio::spawn(async move { - if let Err(e) = - send_gateway_disconnected_email(name, network_name, &hostname, &mail_tx, &pool) + if let Err(err) = + send_gateway_disconnected_email(name, &network_name, &hostname, &mail_tx, &pool) .await { - error!("Failed to send gateway disconnect notification: {e}"); + error!("Failed to send gateway disconnect notification: {err}"); } else { info!("Gateway {hostname} disconnected. Email notification sent",); } @@ -344,6 +345,28 @@ impl From for CoreError { } } +/// Bi-directional gRPC stream for comminication with Defguard proxy. +pub async fn run_grpc_gateway_stream(pool: PgPool) -> Result<(), anyhow::Error> { + // TODO: for each gateway... + let gateway_url = "http://localhost:50066"; + + let config = server_config(); + + let mut tasks = JoinSet::new(); + + tasks.spawn(async { + let gateway_client = + GatewayHandler::new(gateway_url, config.proxy_grpc_ca.as_deref()).unwrap(); + gateway_client.handle_connection().await; + }); + + while let Some(Ok(_result)) = tasks.join_next().await { + debug!("Gateway gRPC task has ended"); + } + + Ok(()) +} + /// Bi-directional gRPC stream for comminication with Defguard proxy. pub async fn run_grpc_bidi_stream( pool: PgPool, @@ -377,11 +400,11 @@ pub async fn run_grpc_bidi_stream( let uri = endpoint.uri(); loop { - debug!("Connecting to proxy at {uri}",); + debug!("Connecting to proxy at {uri}"); let mut client = ProxyClient::new(endpoint.connect_lazy()); let (tx, rx) = mpsc::unbounded_channel(); let Ok(response) = client.bidi(UnboundedReceiverStream::new(rx)).await else { - error!("Failed to connect to proxy @ {uri}, retrying in 10s",); + error!("Failed to connect to proxy @ {uri}, retrying in 10s"); sleep(TEN_SECS).await; continue; }; diff --git a/src/handlers/mail.rs b/src/handlers/mail.rs index f2cc35f90..6efa29e73 100644 --- a/src/handlers/mail.rs +++ b/src/handlers/mail.rs @@ -210,7 +210,7 @@ pub fn send_new_device_added_email( pub async fn send_gateway_disconnected_email( gateway_name: Option, - network_name: String, + network_name: &str, gateway_adress: &str, mail_tx: &UnboundedSender, pool: &PgPool, @@ -225,7 +225,7 @@ pub async fn send_gateway_disconnected_email( content: templates::gateway_disconnected_mail( &gateway_name, gateway_adress, - &network_name, + network_name, )?, attachments: Vec::new(), result_tx: None, diff --git a/src/handlers/wireguard.rs b/src/handlers/wireguard.rs index 07969d3e6..1e9fd0322 100644 --- a/src/handlers/wireguard.rs +++ b/src/handlers/wireguard.rs @@ -305,8 +305,9 @@ pub async fn gateway_status( }) } +// TODO: gateway_id should be enough; remove network_id. pub async fn remove_gateway( - Path((network_id, gateway_id)): Path<(i64, String)>, + Path((network_id, gateway_id)): Path<(i64, i64)>, _role: VpnRole, Extension(gateway_state): Extension>>, ) -> ApiResult { @@ -315,11 +316,7 @@ pub async fn remove_gateway( .lock() .expect("Failed to acquire gateway state lock"); - gateway_state.remove_gateway( - network_id, - Uuid::from_str(&gateway_id) - .map_err(|_| WebError::Http(StatusCode::INTERNAL_SERVER_ERROR))?, - )?; + gateway_state.remove_gateway(network_id, gateway_id)?; info!("Removed gateway {gateway_id} in network {network_id}"); From 808a1aa2b6f819e6b0967ecb2d63457423034323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Mon, 21 Oct 2024 13:37:19 +0200 Subject: [PATCH 07/26] Send config to gateway --- Cargo.lock | 185 ++++++++++++++++++------------------- src/db/models/wireguard.rs | 21 ++++- src/grpc/gateway.rs | 142 ++++++++++++++++------------ src/grpc/mod.rs | 14 ++- 4 files changed, 205 insertions(+), 157 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b1dd49980..d85c990f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -145,9 +145,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95" [[package]] name = "arbitrary" @@ -234,7 +234,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -245,7 +245,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -265,7 +265,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -287,7 +287,7 @@ dependencies = [ "futures-util", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.30", + "hyper 0.14.31", "itoa", "matchit", "memchr", @@ -315,7 +315,7 @@ dependencies = [ "http 1.1.0", "http-body 1.0.1", "http-body-util", - "hyper 1.4.1", + "hyper 1.5.0", "hyper-util", "itoa", "matchit", @@ -619,9 +619,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.30" +version = "1.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" +checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" dependencies = [ "jobserver", "libc", @@ -740,7 +740,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1031,7 +1031,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1055,7 +1055,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1066,7 +1066,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1200,7 +1200,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1221,7 +1221,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1231,7 +1231,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1244,7 +1244,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1282,7 +1282,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1593,9 +1593,9 @@ dependencies = [ [[package]] name = "flume" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" dependencies = [ "futures-core", "futures-sink", @@ -1715,7 +1715,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -2072,9 +2072,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.30" +version = "0.14.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" dependencies = [ "bytes", "futures-channel", @@ -2096,9 +2096,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" dependencies = [ "bytes", "futures-channel", @@ -2122,7 +2122,7 @@ checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http 0.2.12", - "hyper 0.14.30", + "hyper 0.14.31", "rustls 0.21.12", "tokio", "tokio-rustls 0.24.1", @@ -2136,9 +2136,9 @@ checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", "http 1.1.0", - "hyper 1.4.1", + "hyper 1.5.0", "hyper-util", - "rustls 0.23.14", + "rustls 0.23.15", "rustls-pki-types", "tokio", "tokio-rustls 0.26.0", @@ -2152,7 +2152,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper 0.14.30", + "hyper 0.14.31", "pin-project-lite", "tokio", "tokio-io-timeout", @@ -2165,7 +2165,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper 0.14.30", + "hyper 0.14.31", "native-tls", "tokio", "tokio-native-tls", @@ -2182,7 +2182,7 @@ dependencies = [ "futures-util", "http 1.1.0", "http-body 1.0.1", - "hyper 1.4.1", + "hyper 1.5.0", "pin-project-lite", "socket2", "tokio", @@ -2328,7 +2328,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -2643,9 +2643,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.159" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libgit2-sys" @@ -2810,7 +2810,7 @@ name = "model_derive" version = "0.2.0" dependencies = [ "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -2955,7 +2955,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -3088,9 +3088,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.66" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ "bitflags 2.6.0", "cfg-if", @@ -3109,7 +3109,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -3120,9 +3120,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.103" +version = "0.9.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", @@ -3330,7 +3330,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -3473,7 +3473,7 @@ checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -3544,12 +3544,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.22" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" +checksum = "910d41a655dac3b764f1ade94821093d3610248694320cd072303a8eedcf221d" dependencies = [ "proc-macro2", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -3610,9 +3610,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.87" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" dependencies = [ "unicode-ident", ] @@ -3660,7 +3660,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.79", + "syn 2.0.82", "tempfile", ] @@ -3674,7 +3674,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -3741,7 +3741,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.14", + "rustls 0.23.15", "socket2", "thiserror", "tokio", @@ -3758,7 +3758,7 @@ dependencies = [ "rand", "ring", "rustc-hash", - "rustls 0.23.14", + "rustls 0.23.15", "slab", "thiserror", "tinyvec", @@ -3907,7 +3907,7 @@ dependencies = [ "h2", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.30", + "hyper 0.14.31", "hyper-rustls 0.24.2", "hyper-tls", "ipnet", @@ -3954,7 +3954,7 @@ dependencies = [ "http 1.1.0", "http-body 1.0.1", "http-body-util", - "hyper 1.4.1", + "hyper 1.5.0", "hyper-rustls 0.27.3", "hyper-util", "ipnet", @@ -3965,7 +3965,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.14", + "rustls 0.23.15", "rustls-pemfile 2.2.0", "rustls-pki-types", "serde", @@ -4080,7 +4080,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.79", + "syn 2.0.82", "walkdir", ] @@ -4182,9 +4182,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.14" +version = "0.23.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" +checksum = "5fbb44d7acc4e873d613422379f69f237a1b141928c02f6bc6ccfddddc2d7993" dependencies = [ "once_cell", "ring", @@ -4227,9 +4227,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" [[package]] name = "rustls-webpki" @@ -4440,14 +4440,14 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "itoa", "memchr", @@ -4524,7 +4524,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -4769,7 +4769,7 @@ dependencies = [ "quote", "sqlx-core", "sqlx-macros-core", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -4792,7 +4792,7 @@ dependencies = [ "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn 2.0.79", + "syn 2.0.82", "tempfile", "tokio", "url", @@ -4931,9 +4931,9 @@ dependencies = [ [[package]] name = "ssh-key" -version = "0.6.6" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca9b366a80cf18bb6406f4cf4d10aebfb46140a8c0c33f666a144c5c76ecbafc" +checksum = "3b86f5297f0f04d08cabaa0f6bff7cb6aec4d9c3b49d87990d63da9d9156a8c3" dependencies = [ "p256", "p384", @@ -5008,7 +5008,7 @@ checksum = "4596646090f0d724e6c7f3b65d694f99a0daa1a5893a78ef83887025e041405c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -5030,7 +5030,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -5052,9 +5052,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021" dependencies = [ "proc-macro2", "quote", @@ -5096,7 +5096,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -5178,7 +5178,7 @@ checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -5293,7 +5293,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -5333,7 +5333,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.14", + "rustls 0.23.15", "rustls-pki-types", "tokio", ] @@ -5395,7 +5395,7 @@ dependencies = [ "h2", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.30", + "hyper 0.14.31", "hyper-timeout", "percent-encoding", "pin-project", @@ -5422,7 +5422,7 @@ dependencies = [ "proc-macro2", "prost-build", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -5543,7 +5543,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -5696,12 +5696,9 @@ dependencies = [ [[package]] name = "unicase" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] +checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" [[package]] name = "unicode-bidi" @@ -5822,7 +5819,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -5845,9 +5842,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" dependencies = [ "getrandom", "serde", @@ -5963,7 +5960,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", "wasm-bindgen-shared", ] @@ -5997,7 +5994,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6472,7 +6469,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", "synstructure 0.13.1", ] @@ -6494,7 +6491,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -6514,7 +6511,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", "synstructure 0.13.1", ] @@ -6535,7 +6532,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -6557,7 +6554,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] diff --git a/src/db/models/wireguard.rs b/src/db/models/wireguard.rs index b384a18bb..a401edcc1 100644 --- a/src/db/models/wireguard.rs +++ b/src/db/models/wireguard.rs @@ -10,7 +10,9 @@ use chrono::{Duration, NaiveDateTime, Utc}; use ipnetwork::{IpNetwork, IpNetworkError, NetworkSize}; use model_derive::Model; use rand_core::OsRng; -use sqlx::{query_as, query_scalar, Error as SqlxError, FromRow, PgConnection, PgExecutor, PgPool}; +use sqlx::{ + query, query_as, query_scalar, Error as SqlxError, FromRow, PgConnection, PgExecutor, PgPool, +}; use thiserror::Error; use utoipa::ToSchema; use x25519_dalek::{PublicKey, StaticSecret}; @@ -705,6 +707,23 @@ impl WireguardNetwork { .and_then(|ep| Some(ep.split(':').next()?.to_owned())) } + /// Update `connected_at` to the current time and save it to the database. + pub(crate) async fn touch_connected_at<'e, E>(&mut self, executor: E) -> Result<(), SqlxError> + where + E: PgExecutor<'e>, + { + self.connected_at = Some(Utc::now().naive_utc()); + query!( + "UPDATE wireguard_network SET connected_at = $2 WHERE name = $1", + self.name, + self.connected_at + ) + .execute(executor) + .await?; + + Ok(()) + } + /// Finds when the device connected based on handshake timestamps async fn connected_at( &self, diff --git a/src/grpc/gateway.rs b/src/grpc/gateway.rs index 41ef42192..c82a838af 100644 --- a/src/grpc/gateway.rs +++ b/src/grpc/gateway.rs @@ -1,7 +1,10 @@ use std::{ fs::read_to_string, pin::Pin, - sync::{Arc, Mutex}, + sync::{ + atomic::{AtomicU64, Ordering}, + Arc, Mutex, + }, task::{Context, Poll}, time::Duration, }; @@ -178,10 +181,18 @@ const TEN_SECS: Duration = Duration::from_secs(10); pub(super) struct GatewayHandler { endpoint: Endpoint, + message_id: AtomicU64, + network_id: Id, + pool: PgPool, } impl GatewayHandler { - pub(super) fn new(url: &str, ca_path: Option<&str>) -> Result { + pub(super) fn new( + url: &str, + ca_path: Option<&str>, + network_id: Id, + pool: PgPool, + ) -> Result { let endpoint = Endpoint::from_shared(url.to_string())?; let endpoint = endpoint .http2_keep_alive_interval(TEN_SECS) @@ -195,7 +206,61 @@ impl GatewayHandler { endpoint }; - Ok(Self { endpoint }) + Ok(Self { + endpoint, + message_id: AtomicU64::new(0), + network_id, + pool, + }) + } + + async fn config(&self) -> Result { + debug!("Sending configuration to gateway client."); + let network_id = self.network_id; + // let hostname = Self::get_gateway_hostname(request.metadata())?; + + let mut network = WireguardNetwork::find_by_id(&self.pool, network_id) + .await + .map_err(|e| { + error!("Network {network_id} not found"); + Status::new(Code::Internal, format!("Failed to retrieve network: {e}")) + })? + .ok_or_else(|| { + Status::new( + Code::Internal, + format!("Network with id {network_id} not found"), + ) + })?; + + debug!("Sending configuration to gateway client, network {network}."); + + // store connected gateway in memory + // { + // let mut state = self.state.lock().unwrap(); + // state.add_gateway( + // network_id, + // &network.name, + // hostname, + // request.into_inner().name, + // self.mail_tx.clone(), + // ); + // } + + if let Err(err) = network.touch_connected_at(&self.pool).await { + error!("Failed to update network {network_id} in the database, status: {err}"); + } + + let peers = network.get_peers(&self.pool).await.map_err(|error| { + error!("Failed to fetch peers from the database for network {network_id}: {error}",); + Status::new( + Code::Internal, + format!("Failed to retrieve peers from the database for network: {network_id}"), + ) + })?; + + info!("Configuration sent to gateway client, network {network}."); + + Ok(gen_config(&network, peers)) } pub(super) async fn handle_connection(&self) -> ! { @@ -205,12 +270,26 @@ impl GatewayHandler { let mut client = gateway_client::GatewayClient::new(self.endpoint.connect_lazy()); let (tx, rx) = mpsc::unbounded_channel(); let Ok(response) = client.bidi(UnboundedReceiverStream::new(rx)).await else { - error!("Failed to connect to gateway @ {uri}, retrying in 10s",); + error!("Failed to connect to gateway at {uri}, retrying in 10s",); sleep(TEN_SECS).await; continue; }; - info!("Connected to proxy at {uri}"); + info!("Connected to gateway at {uri}"); let mut resp_stream = response.into_inner(); + + debug!("Sending configuration to gateway at {uri}"); + match self.config().await { + Ok(config) => { + let payload = Some(core_response::Payload::Config(config)); + let id = self.message_id.fetch_add(1, Ordering::Relaxed); + let req = CoreResponse { id, payload }; + tx.send(req).unwrap(); + } + Err(err) => { + error!("Failed to obtain configuration"); + } + } + 'message: loop { match resp_stream.message().await { Ok(None) => { @@ -625,59 +704,6 @@ impl Drop for GatewayUpdatesStream { // Ok(Response::new(())) // } -// async fn config( -// &self, -// request: Request, -// ) -> Result, Status> { -// debug!("Sending configuration to gateway client."); -// let network_id = Self::get_network_id(request.metadata())?; -// let hostname = Self::get_gateway_hostname(request.metadata())?; - -// let mut network = WireguardNetwork::find_by_id(&self.pool, network_id) -// .await -// .map_err(|e| { -// error!("Network {network_id} not found"); -// Status::new(Code::Internal, format!("Failed to retrieve network: {e}")) -// })? -// .ok_or_else(|| { -// Status::new( -// Code::Internal, -// format!("Network with id {network_id} not found"), -// ) -// })?; - -// debug!("Sending configuration to gateway client, network {network}."); - -// // store connected gateway in memory -// { -// let mut state = self.state.lock().unwrap(); -// state.add_gateway( -// network_id, -// &network.name, -// hostname, -// request.into_inner().name, -// self.mail_tx.clone(), -// ); -// } - -// network.connected_at = Some(Utc::now().naive_utc()); -// if let Err(err) = network.save(&self.pool).await { -// error!("Failed to save updated network {network_id} in the database, status: {err}"); -// } - -// let peers = network.get_peers(&self.pool).await.map_err(|error| { -// error!("Failed to fetch peers from the database for network {network_id}: {error}",); -// Status::new( -// Code::Internal, -// format!("Failed to retrieve peers from the database for network: {network_id}"), -// ) -// })?; - -// info!("Configuration sent to gateway client, network {network}."); - -// Ok(Response::new(gen_config(&network, peers))) -// } - // async fn updates(&self, request: Request<()>) -> Result, Status> { // let gateway_network_id = Self::get_network_id(request.metadata())?; // let hostname = Self::get_gateway_hostname(request.metadata())?; diff --git a/src/grpc/mod.rs b/src/grpc/mod.rs index da749dd80..8ce7c98de 100644 --- a/src/grpc/mod.rs +++ b/src/grpc/mod.rs @@ -345,18 +345,24 @@ impl From for CoreError { } } -/// Bi-directional gRPC stream for comminication with Defguard proxy. +/// Bi-directional gRPC stream for comminication with Defguard gateway. pub async fn run_grpc_gateway_stream(pool: PgPool) -> Result<(), anyhow::Error> { // TODO: for each gateway... let gateway_url = "http://localhost:50066"; + let network_id = 3; let config = server_config(); let mut tasks = JoinSet::new(); - tasks.spawn(async { - let gateway_client = - GatewayHandler::new(gateway_url, config.proxy_grpc_ca.as_deref()).unwrap(); + tasks.spawn(async move { + let gateway_client = GatewayHandler::new( + gateway_url, + config.proxy_grpc_ca.as_deref(), + network_id, + pool.clone(), + ) + .unwrap(); // FIXME gateway_client.handle_connection().await; }); From 769790a70b0b1f9883d7a2c5edb0deff7556ea6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Mon, 21 Oct 2024 14:22:33 +0200 Subject: [PATCH 08/26] Handle peer stats --- src/auth/mod.rs | 29 ++++--- src/db/models/wireguard.rs | 39 +++++++++ src/grpc/gateway.rs | 159 ++++++++++--------------------------- 3 files changed, 93 insertions(+), 134 deletions(-) diff --git a/src/auth/mod.rs b/src/auth/mod.rs index d1d0d0336..58c7b054e 100644 --- a/src/auth/mod.rs +++ b/src/auth/mod.rs @@ -126,23 +126,22 @@ where async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { let appstate = AppState::from_ref(state); - if let Ok(cookies) = CookieJar::from_request_parts(parts, state).await { - if let Some(session_cookie) = cookies.get(SESSION_COOKIE_NAME) { - return { - match Session::find_by_id(&appstate.pool, session_cookie.value()).await { - Ok(Some(session)) => { - if session.expired() { - let _result = session.delete(&appstate.pool).await; - Err(WebError::Authorization("Session expired".into())) - } else { - Ok(session) - } + let Ok(cookies) = CookieJar::from_request_parts(parts, state).await; + if let Some(session_cookie) = cookies.get(SESSION_COOKIE_NAME) { + return { + match Session::find_by_id(&appstate.pool, session_cookie.value()).await { + Ok(Some(session)) => { + if session.expired() { + let _result = session.delete(&appstate.pool).await; + Err(WebError::Authorization("Session expired".into())) + } else { + Ok(session) } - Ok(None) => Err(WebError::Authorization("Session not found".into())), - Err(err) => Err(err.into()), } - }; - } + Ok(None) => Err(WebError::Authorization("Session not found".into())), + Err(err) => Err(err.into()), + } + }; } Err(WebError::Authorization("Session is required".into())) } diff --git a/src/db/models/wireguard.rs b/src/db/models/wireguard.rs index a401edcc1..04573198d 100644 --- a/src/db/models/wireguard.rs +++ b/src/db/models/wireguard.rs @@ -707,6 +707,45 @@ impl WireguardNetwork { .and_then(|ep| Some(ep.split(':').next()?.to_owned())) } + /// Get a list of all allowed peers + /// + /// Each device is marked as allowed or not allowed in a given network, + /// which enables enforcing peer disconnect in MFA-protected networks. + pub async fn get_peers<'e, E>(&self, executor: E) -> Result, SqlxError> + where + E: PgExecutor<'e>, + { + debug!("Fetching all peers for network {}", self.id); + let rows = query!( + "SELECT d.wireguard_pubkey pubkey, preshared_key, \ + array[host(wnd.wireguard_ip)] \"allowed_ips!: Vec\" \ + FROM wireguard_network_device wnd \ + JOIN device d ON wnd.device_id = d.id \ + JOIN \"user\" u ON d.user_id = u.id \ + WHERE wireguard_network_id = $1 AND (is_authorized = true OR NOT $2) \ + AND u.is_active = true \ + ORDER BY d.id ASC", + self.id, + self.mfa_enabled + ) + .fetch_all(executor) + .await?; + + // keepalive has to be added manually because Postgres + // doesn't support unsigned integers + let result = rows + .into_iter() + .map(|row| Peer { + pubkey: row.pubkey, + allowed_ips: row.allowed_ips, + preshared_key: row.preshared_key, + keepalive_interval: Some(self.keepalive_interval as u32), + }) + .collect(); + + Ok(result) + } + /// Update `connected_at` to the current time and save it to the database. pub(crate) async fn touch_connected_at<'e, E>(&mut self, executor: E) -> Result<(), SqlxError> where diff --git a/src/grpc/gateway.rs b/src/grpc/gateway.rs index 10028871d..035da8b0b 100644 --- a/src/grpc/gateway.rs +++ b/src/grpc/gateway.rs @@ -44,47 +44,6 @@ pub struct GatewayServer { mail_tx: UnboundedSender, } -impl WireguardNetwork { - /// Get a list of all allowed peers - /// - /// Each device is marked as allowed or not allowed in a given network, - /// which enables enforcing peer disconnect in MFA-protected networks. - pub async fn get_peers<'e, E>(&self, executor: E) -> Result, SqlxError> - where - E: PgExecutor<'e>, - { - debug!("Fetching all peers for network {}", self.id); - let rows = query!( - "SELECT d.wireguard_pubkey pubkey, preshared_key, \ - array[host(wnd.wireguard_ip)] \"allowed_ips!: Vec\" \ - FROM wireguard_network_device wnd \ - JOIN device d ON wnd.device_id = d.id \ - JOIN \"user\" u ON d.user_id = u.id \ - WHERE wireguard_network_id = $1 AND (is_authorized = true OR NOT $2) \ - AND u.is_active = true \ - ORDER BY d.id ASC", - self.id, - self.mfa_enabled - ) - .fetch_all(executor) - .await?; - - // keepalive has to be added manually because Postgres - // doesn't support unsigned integers - let result = rows - .into_iter() - .map(|row| Peer { - pubkey: row.pubkey, - allowed_ips: row.allowed_ips, - preshared_key: row.preshared_key, - keepalive_interval: Some(self.keepalive_interval as u32), - }) - .collect(); - - Ok(result) - } -} - impl GatewayServer { /// Create new gateway server instance #[must_use] @@ -179,6 +138,7 @@ impl WireguardPeerStats { // TODO: merge with super. const TEN_SECS: Duration = Duration::from_secs(10); +/// One instance per connected gateway. pub(super) struct GatewayHandler { endpoint: Endpoint, message_id: AtomicU64, @@ -214,8 +174,8 @@ impl GatewayHandler { }) } - async fn config(&self) -> Result { - debug!("Sending configuration to gateway client."); + async fn send_configuration(&self, tx: &UnboundedSender) -> Result<(), Status> { + debug!("Sending configuration to gateway."); let network_id = self.network_id; // let hostname = Self::get_gateway_hostname(request.metadata())?; @@ -247,7 +207,7 @@ impl GatewayHandler { // } if let Err(err) = network.touch_connected_at(&self.pool).await { - error!("Failed to update network {network_id} in the database, status: {err}"); + error!("Failed to update connected at for network {network_id} in the database, status: {err}"); } let peers = network.get_peers(&self.pool).await.map_err(|error| { @@ -258,37 +218,31 @@ impl GatewayHandler { ) })?; + let payload = Some(core_response::Payload::Config(gen_config(&network, peers))); + let id = self.message_id.fetch_add(1, Ordering::Relaxed); + let req = CoreResponse { id, payload }; + tx.send(req).unwrap(); info!("Configuration sent to gateway client, network {network}."); - Ok(gen_config(&network, peers)) + Ok(()) } pub(super) async fn handle_connection(&self) -> ! { let uri = self.endpoint.uri(); loop { - debug!("Connecting to gateway at {uri}"); + debug!("Connecting to gateway {uri}"); let mut client = gateway_client::GatewayClient::new(self.endpoint.connect_lazy()); let (tx, rx) = mpsc::unbounded_channel(); let Ok(response) = client.bidi(UnboundedReceiverStream::new(rx)).await else { - error!("Failed to connect to gateway at {uri}, retrying in 10s",); + error!("Failed to connect to gateway {uri}, retrying in 10s",); sleep(TEN_SECS).await; continue; }; - info!("Connected to gateway at {uri}"); + info!("Connected to gateway {uri}"); let mut resp_stream = response.into_inner(); - debug!("Sending configuration to gateway at {uri}"); - match self.config().await { - Ok(config) => { - let payload = Some(core_response::Payload::Config(config)); - let id = self.message_id.fetch_add(1, Ordering::Relaxed); - let req = CoreResponse { id, payload }; - tx.send(req).unwrap(); - } - Err(err) => { - error!("Failed to obtain configuration"); - } - } + // TODO: probably fail on error + let _ = self.send_configuration(&tx).await; 'message: loop { match resp_stream.message().await { @@ -298,18 +252,38 @@ impl GatewayHandler { } Ok(Some(received)) => { info!("Received message from gateway."); - debug!("Received the following message from gateway: {received:?}"); - let payload: Option = match received.payload { + debug!("Message from gateway {uri}: {received:?}"); + match received.payload { Some(core_request::Payload::ConfigRequest(config_request)) => { info!("*** ConfigurationRequest {config_request:?}"); - None } Some(core_request::Payload::PeerStats(peer_stats)) => { info!("*** PeerStats {peer_stats:?}"); - None + + let public_key = peer_stats.public_key.clone(); + let mut stats = WireguardPeerStats::from_peer_stats( + peer_stats, + self.network_id, + ); + // Get device by public key and fill in stats.device_id + // FIXME: keep an in-memory device map to avoid repeated DB requests + match Device::find_by_pubkey(&self.pool, &public_key).await { + Ok(Some(device)) => { + stats.device_id = device.id; + match stats.save(&self.pool).await { + Ok(_) => info!("Saved WireGuard peer stats to database."), + Err(err) => error!("Failed to save WireGuard peer stats to database: {err}"), + } + } + Ok(None) => { + error!("Device with public key {public_key} not found"); + } + Err(err) => { + error!("Failed to retrieve device with public key {public_key}: {err}",); + } + }; } - // Reply without payload. - None => None, + None => (), }; } Err(err) => { @@ -652,58 +626,6 @@ impl Drop for GatewayUpdatesStream { // impl gateway_service_server::GatewayService for GatewayServer { // type UpdatesStream = GatewayUpdatesStream; -// /// Retrieve stats from gateway and save it to database -// async fn stats( -// &self, -// request: Request>, -// ) -> Result, Status> { -// let network_id = Self::get_network_id(request.metadata())?; -// let mut stream = request.into_inner(); -// while let Some(stats_update) = stream.message().await? { -// debug!("Received stats message: {stats_update:?}"); -// let Some(stats_update::Payload::PeerStats(peer_stats)) = stats_update.payload else { -// debug!("Received stats message is empty, skipping."); -// continue; -// }; -// let public_key = peer_stats.public_key.clone(); -// let mut stats = WireguardPeerStats::from_peer_stats(peer_stats, network_id); -// // Get device by public key and fill in stats.device_id -// // FIXME: keep an in-memory device map to avoid repeated DB requests -// stats.device_id = match Device::find_by_pubkey(&self.pool, &public_key).await { -// Ok(Some(device)) => device.id, -// Ok(None) => { -// error!("Device with public key {public_key} not found"); -// return Err(Status::new( -// Code::Internal, -// format!("Device with public key {public_key} not found"), -// )); -// } -// Err(err) => { -// error!("Failed to retrieve device with public key {public_key}: {err}",); -// return Err(Status::new( -// Code::Internal, -// format!("Failed to retrieve device with public key {public_key}: {err}",), -// )); -// } -// }; -// // Save stats to db -// let stats = match stats.save(&self.pool).await { -// Ok(stats) => stats, -// Err(err) => { -// error!("Saving WireGuard peer stats to db failed: {err}"); -// return Err(Status::new( -// Code::Internal, -// format!("Saving WireGuard peer stats to db failed: {err}"), -// )); -// } -// }; -// info!("Saved WireGuard peer stats to db."); -// debug!("WireGuard peer stats: {stats:?}"); -// } - -// Ok(Response::new(())) -// } - // async fn updates(&self, request: Request<()>) -> Result, Status> { // let gateway_network_id = Self::get_network_id(request.metadata())?; // let hostname = Self::get_gateway_hostname(request.metadata())?; @@ -725,7 +647,6 @@ impl Drop for GatewayUpdatesStream { // }; // info!("New client connected to updates stream: {hostname}, network {network}",); - // let (tx, rx) = mpsc::channel(4); // let events_rx = self.wireguard_tx.subscribe(); // let mut state = self.state.lock().unwrap(); From a9a450183af0cdcdff57f5113908d012df296d87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Mon, 21 Oct 2024 16:33:52 +0200 Subject: [PATCH 09/26] Cleanup gateway events handling --- src/db/models/wireguard.rs | 8 +- src/grpc/gateway.rs | 198 +++++++++++++++++-------------------- src/grpc/mod.rs | 2 +- 3 files changed, 93 insertions(+), 115 deletions(-) diff --git a/src/db/models/wireguard.rs b/src/db/models/wireguard.rs index 04573198d..ea9df06f9 100644 --- a/src/db/models/wireguard.rs +++ b/src/db/models/wireguard.rs @@ -41,8 +41,8 @@ pub struct MappedDevice { pub wireguard_ip: IpAddr, } -pub static WIREGUARD_MAX_HANDSHAKE_MINUTES: i64 = 5; -pub static PEER_STATS_LIMIT: i64 = 6 * 60; +pub(super) static WIREGUARD_MAX_HANDSHAKE_MINUTES: i64 = 5; +static PEER_STATS_LIMIT: i64 = 6 * 60; /// Defines datetime aggregation levels pub enum DateTimeAggregation { @@ -1017,8 +1017,8 @@ impl Default for WireguardNetwork { } } -#[derive(Debug, Serialize)] -pub struct WireguardNetworkInfo { +#[derive(Serialize)] +pub(crate) struct WireguardNetworkInfo { #[serde(flatten)] pub network: WireguardNetwork, pub connected: bool, diff --git a/src/grpc/gateway.rs b/src/grpc/gateway.rs index 035da8b0b..0a3299155 100644 --- a/src/grpc/gateway.rs +++ b/src/grpc/gateway.rs @@ -10,7 +10,7 @@ use std::{ }; use chrono::{DateTime, Utc}; -use sqlx::{query, Error as SqlxError, PgExecutor, PgPool}; +use sqlx::PgPool; use tokio::{ sync::{ broadcast::{Receiver as BroadcastReceiver, Sender}, @@ -23,7 +23,7 @@ use tokio_stream::{wrappers::UnboundedReceiverStream, Stream}; use tonic::{ metadata::MetadataMap, transport::{Certificate, ClientTlsConfig, Endpoint}, - Code, Request, Response, Status, + Code, Status, }; use super::GatewayMap; @@ -192,7 +192,7 @@ impl GatewayHandler { ) })?; - debug!("Sending configuration to gateway client, network {network}."); + debug!("Sending configuration to gateway, network {network}."); // store connected gateway in memory // { @@ -305,7 +305,7 @@ struct GatewayUpdatesHandler { network: WireguardNetwork, gateway_hostname: String, events_rx: BroadcastReceiver, - tx: mpsc::Sender>, + tx: UnboundedSender, } impl GatewayUpdatesHandler { @@ -314,7 +314,7 @@ impl GatewayUpdatesHandler { network: WireguardNetwork, gateway_hostname: String, events_rx: BroadcastReceiver, - tx: mpsc::Sender>, + tx: UnboundedSender, ) -> Self { Self { network_id, @@ -335,31 +335,31 @@ impl GatewayUpdatesHandler { self.gateway_hostname, self.network ); while let Ok(update) = self.events_rx.recv().await { - debug!("Received WireGuard update: {update:?}"); + debug!("Received networking state update: {update:?}"); let result = match update { GatewayEvent::NetworkCreated(network_id, network) => { - if network_id == self.network_id { - self.send_network_update(&network, Vec::new(), 0).await - } else { - Ok(()) + if network_id != self.network_id { + continue; } + self.send_network_update(&network, Vec::new(), UpdateType::Create) + .await } GatewayEvent::NetworkModified(network_id, network, peers) => { - if network_id == self.network_id { - let result = self.send_network_update(&network, peers, 1).await; - // update stored network data - self.network = network; - result - } else { - Ok(()) + if network_id != self.network_id { + continue; } + let result = self + .send_network_update(&network, peers, UpdateType::Modify) + .await; + // update stored network data + self.network = network; + result } GatewayEvent::NetworkDeleted(network_id, network_name) => { - if network_id == self.network_id { - self.send_network_delete(&network_name).await - } else { - Ok(()) + if network_id != self.network_id { + continue; } + self.send_network_delete(&network_name).await } GatewayEvent::DeviceCreated(device) => { // check if a peer has to be added in the current network @@ -375,18 +375,13 @@ impl GatewayUpdatesHandler { ); continue; }; - self.send_peer_update( - Peer { - pubkey: device.device.wireguard_pubkey, - allowed_ips: vec![network_info.device_wireguard_ip.to_string()], - preshared_key: network_info.preshared_key.clone(), - keepalive_interval: Some( - self.network.keepalive_interval as u32, - ), - }, - 0, - ) - .await + let peer = Peer { + pubkey: device.device.wireguard_pubkey, + allowed_ips: vec![network_info.device_wireguard_ip.to_string()], + preshared_key: network_info.preshared_key.clone(), + keepalive_interval: Some(self.network.keepalive_interval as u32), + }; + self.send_peer_update(peer, UpdateType::Create).await } None => Ok(()), } @@ -405,18 +400,13 @@ impl GatewayUpdatesHandler { ); continue; }; - self.send_peer_update( - Peer { - pubkey: device.device.wireguard_pubkey, - allowed_ips: vec![network_info.device_wireguard_ip.to_string()], - preshared_key: network_info.preshared_key.clone(), - keepalive_interval: Some( - self.network.keepalive_interval as u32, - ), - }, - 1, - ) - .await + let peer = Peer { + pubkey: device.device.wireguard_pubkey, + allowed_ips: vec![network_info.device_wireguard_ip.to_string()], + preshared_key: network_info.preshared_key.clone(), + keepalive_interval: Some(self.network.keepalive_interval as u32), + }; + self.send_peer_update(peer, UpdateType::Modify).await } None => Ok(()), } @@ -448,30 +438,25 @@ impl GatewayUpdatesHandler { &self, network: &WireguardNetwork, peers: Vec, - update_type: i32, + update_type: UpdateType, ) -> Result<(), Status> { debug!("Sending network update for network {network}"); - if let Err(err) = self - .tx - .send(Ok(Update { - update_type, - update: Some(update::Update::Network(Configuration { - name: network.name.clone(), - prvkey: network.prvkey.clone(), - address: network.address.to_string(), - port: network.port as u32, - peers, - })), - })) - .await - { + let update = Update { + update_type: update_type as i32, + update: Some(update::Update::Network(Configuration { + name: network.name.clone(), + prvkey: network.prvkey.clone(), + address: network.address.to_string(), + port: network.port as u32, + peers, + })), + }; + let payload = Some(core_response::Payload::Update(update)); + let req = CoreResponse { id: 0, payload }; + if let Err(err) = self.tx.send(req) { let msg = format!( - "Failed to send network update, network {network}, update type: {update_type} ({}), error: {err}", - if update_type == 0 { - "CREATE" - } else { - "MODIFY" - }, + "Failed to send network update, network {network}, update type: {}, error: {err}", + update_type.as_str_name(), ); error!(msg); return Err(Status::new(Code::Internal, msg)); @@ -487,22 +472,21 @@ impl GatewayUpdatesHandler { "Sending network delete command for network {}", self.network ); - if let Err(err) = self - .tx - .send(Ok(Update { - update_type: 2, - update: Some(update::Update::Network(Configuration { - name: network_name.to_string(), - prvkey: String::new(), - address: String::new(), - port: 0, - peers: Vec::new(), - })), - })) - .await - { + let update = Update { + update_type: UpdateType::Delete as i32, + update: Some(update::Update::Network(Configuration { + name: network_name.to_string(), + prvkey: String::new(), + address: String::new(), + port: 0, + peers: Vec::new(), + })), + }; + let payload = Some(core_response::Payload::Update(update)); + let req = CoreResponse { id: 0, payload }; + if let Err(err) = self.tx.send(req) { let msg = format!( - "Failed to send network update, network {}, update type: 2 (DELETE), error: {err}", + "Failed to send network update, network {}, update type: DELETE, error: {err}", self.network, ); error!(msg); @@ -514,24 +498,19 @@ impl GatewayUpdatesHandler { } /// Send update peer command to gateway - async fn send_peer_update(&self, peer: Peer, update_type: i32) -> Result<(), Status> { + async fn send_peer_update(&self, peer: Peer, update_type: UpdateType) -> Result<(), Status> { debug!("Sending peer update for network {}", self.network); - if let Err(err) = self - .tx - .send(Ok(Update { - update_type, - update: Some(update::Update::Peer(peer)), - })) - .await - { + let update = Update { + update_type: update_type as i32, + update: Some(update::Update::Peer(peer)), + }; + let payload = Some(core_response::Payload::Update(update)); + let req = CoreResponse { id: 0, payload }; + if let Err(err) = self.tx.send(req) { let msg = format!( - "Failed to send peer update for network {}, update type: {update_type} ({}), error: {err}", + "Failed to send peer update for network {}, update type: {}, error: {err}", self.network, - if update_type == 0 { - "CREATE" - } else { - "MODIFY" - }, + update_type.as_str_name(), ); error!(msg); return Err(Status::new(Code::Internal, msg)); @@ -544,21 +523,20 @@ impl GatewayUpdatesHandler { /// Send delete peer command to gateway async fn send_peer_delete(&self, peer_pubkey: &str) -> Result<(), Status> { debug!("Sending peer delete for network {}", self.network); - if let Err(err) = self - .tx - .send(Ok(Update { - update_type: 2, - update: Some(update::Update::Peer(Peer { - pubkey: peer_pubkey.into(), - allowed_ips: Vec::new(), - preshared_key: None, - keepalive_interval: None, - })), - })) - .await - { + let update = Update { + update_type: 2, + update: Some(update::Update::Peer(Peer { + pubkey: peer_pubkey.into(), + allowed_ips: Vec::new(), + preshared_key: None, + keepalive_interval: None, + })), + }; + let payload = Some(core_response::Payload::Update(update)); + let req = CoreResponse { id: 0, payload }; + if let Err(err) = self.tx.send(req) { let msg = format!( - "Failed to send peer update for network {}, peer {peer_pubkey}, update type: 2 (DELETE), error: {err}", + "Failed to send peer update for network {}, peer {peer_pubkey}, update type: DELETE, error: {err}", self.network, ); error!(msg); diff --git a/src/grpc/mod.rs b/src/grpc/mod.rs index 8ce7c98de..fb72bbd1a 100644 --- a/src/grpc/mod.rs +++ b/src/grpc/mod.rs @@ -224,7 +224,7 @@ impl GatewayMap { // return a list af aff statuses af all gateways in a given network #[must_use] - pub fn get_network_gateway_status(&self, network_id: Id) -> Vec { + pub(crate) fn get_network_gateway_status(&self, network_id: Id) -> Vec { match self.0.get(&network_id) { Some(network_gateway_map) => network_gateway_map.clone().into_values().collect(), None => Vec::new(), From 8afd720ff550ea6e4c651c8dc0a3e96d92d67722 Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Mon, 21 Oct 2024 17:20:10 +0200 Subject: [PATCH 10/26] gateway crud --- .../20241021091427_add_gateway_url.down.sql | 1 + .../20241021091427_add_gateway_url.up.sql | 1 + src/db/models/gateway.rs | 34 +++ src/db/models/mod.rs | 1 + src/handlers/gateway.rs | 197 ++++++++++++++++++ src/handlers/mod.rs | 2 + src/lib.rs | 9 + 7 files changed, 245 insertions(+) create mode 100644 migrations/20241021091427_add_gateway_url.down.sql create mode 100644 migrations/20241021091427_add_gateway_url.up.sql create mode 100644 src/db/models/gateway.rs create mode 100644 src/handlers/gateway.rs diff --git a/migrations/20241021091427_add_gateway_url.down.sql b/migrations/20241021091427_add_gateway_url.down.sql new file mode 100644 index 000000000..b5cb12f9d --- /dev/null +++ b/migrations/20241021091427_add_gateway_url.down.sql @@ -0,0 +1 @@ +ALTER TABLE gateway DROP COLUMN url; diff --git a/migrations/20241021091427_add_gateway_url.up.sql b/migrations/20241021091427_add_gateway_url.up.sql new file mode 100644 index 000000000..59af27ae9 --- /dev/null +++ b/migrations/20241021091427_add_gateway_url.up.sql @@ -0,0 +1 @@ +ALTER TABLE gateway ADD COLUMN url TEXT NOT NULL; diff --git a/src/db/models/gateway.rs b/src/db/models/gateway.rs new file mode 100644 index 000000000..e403953fc --- /dev/null +++ b/src/db/models/gateway.rs @@ -0,0 +1,34 @@ +use model_derive::Model; +use sqlx::{Error as SqlxError, PgPool}; + +use crate::db::{Id, NoId}; + +#[derive(Clone, Debug, Model, PartialEq, Serialize)] +pub struct Gateway { + pub id: I, + pub network_id: Id, + pub url: String, +} + +impl Gateway { + #[must_use] + pub fn new>(network_id: Id, url: S) -> Self { + Self { + id: NoId, + network_id, + url: url.into(), + } + } +} + +impl Gateway { + pub async fn find_by_network_id(pool: &PgPool, network_id: Id) -> Result, SqlxError> { + sqlx::query_as!( + Self, + "SELECT * FROM gateway WHERE network_id = $1", + network_id + ) + .fetch_all(pool) + .await + } +} diff --git a/src/db/models/mod.rs b/src/db/models/mod.rs index d13db81b3..e54337215 100644 --- a/src/db/models/mod.rs +++ b/src/db/models/mod.rs @@ -5,6 +5,7 @@ pub mod device; pub mod device_login; pub mod enrollment; pub mod error; +pub mod gateway; pub mod group; #[cfg(feature = "openid")] pub mod oauth2authorizedapp; diff --git a/src/handlers/gateway.rs b/src/handlers/gateway.rs new file mode 100644 index 000000000..f76da4d72 --- /dev/null +++ b/src/handlers/gateway.rs @@ -0,0 +1,197 @@ +use axum::{ + extract::{Json, Path, State}, + http::StatusCode, +}; +use serde_json::json; + +use super::{ApiResponse, ApiResult, WebError}; +use crate::{ + appstate::AppState, + auth::{SessionInfo, VpnRole}, + db::{models::gateway::Gateway, Id, WireguardNetwork}, +}; + +#[derive(Serialize, Deserialize)] +pub struct AddGatewayData { + pub url: String, +} + +pub async fn add_gateway( + _role: VpnRole, + State(appstate): State, + session: SessionInfo, + Path(network_id): Path, + Json(data): Json, +) -> ApiResult { + let network = WireguardNetwork::find_by_id(&appstate.pool, network_id) + .await? + .ok_or_else(|| { + WebError::ObjectNotFound(format!( + "Network with id {} not found while adding a new gateway, aborting", + network_id + )) + })?; + + debug!( + "User {} is adding a new gateway with url {} to network {}", + session.user.username, data.url, network.name + ); + + let gateway = Gateway::new(network_id, &data.url); + + gateway.save(&appstate.pool).await?; + + info!( + "User {} has added a new gateway with url {} to network {}", + session.user.username, data.url, network.name + ); + + Ok(ApiResponse { + json: json!({}), + status: StatusCode::CREATED, + }) +} + +pub async fn delete_gateway( + _role: VpnRole, + State(appstate): State, + session: SessionInfo, + Path(gateway_id): Path, +) -> ApiResult { + debug!( + "User {} is removing gateway with id {}", + session.user.username, gateway_id + ); + let gateway = Gateway::find_by_id(&appstate.pool, gateway_id) + .await? + .ok_or_else(|| { + WebError::ObjectNotFound(format!( + "Gateway with id {} not found while removing gateway, aborting", + gateway_id + )) + })?; + debug!( + "The gateway with id {} which is being removed by user {} has url {}", + gateway_id, session.user.username, gateway.url + ); + + let msg = format!( + "User {} has removed gateway with url {}", + session.user.username, gateway.url + ); + + gateway.delete(&appstate.pool).await?; + + info!("{msg}"); + + Ok(ApiResponse { + json: json!({}), + status: StatusCode::OK, + }) +} + +#[derive(Serialize, Deserialize)] +pub struct GetGatewaysData { + pub network_id: Id, +} + +pub async fn get_gateways( + _role: VpnRole, + State(appstate): State, + session: SessionInfo, + Path(network_id): Path, +) -> ApiResult { + let network = WireguardNetwork::find_by_id(&appstate.pool, network_id) + .await? + .ok_or_else(|| { + WebError::ObjectNotFound(format!( + "Network with id {} not found while getting gateways, aborting", + network_id + )) + })?; + + debug!( + "User {} is getting gateways for network {}", + session.user.username, network.name + ); + + let gateways = Gateway::find_by_network_id(&appstate.pool, network_id).await?; + + Ok(ApiResponse { + json: json!({ "gateways": gateways }), + status: StatusCode::OK, + }) +} + +#[derive(Serialize, Deserialize)] +pub struct GetGatewayData { + pub gateway_id: Id, +} + +pub async fn get_gateway( + _role: VpnRole, + State(appstate): State, + session: SessionInfo, + Path(gateway_id): Path, +) -> ApiResult { + debug!( + "User {} is getting gateway with id {}", + session.user.username, gateway_id + ); + let gateway = Gateway::find_by_id(&appstate.pool, gateway_id) + .await? + .ok_or_else(|| { + WebError::ObjectNotFound(format!( + "Gateway with id {} not found while getting gateway, aborting", + gateway_id + )) + })?; + + Ok(ApiResponse { + json: json!({ "gateway": gateway }), + status: StatusCode::OK, + }) +} + +#[derive(Serialize, Deserialize)] +pub struct UpdateGatewayData { + pub url: String, +} + +pub async fn update_gateway( + _role: VpnRole, + State(appstate): State, + session: SessionInfo, + Path(gateway_id): Path, + Json(data): Json, +) -> ApiResult { + debug!( + "User {} is updating gateway with id {}", + session.user.username, gateway_id + ); + let mut gateway = Gateway::find_by_id(&appstate.pool, gateway_id) + .await? + .ok_or_else(|| { + WebError::ObjectNotFound(format!( + "Gateway with id {} not found while updating gateway, aborting", + gateway_id + )) + })?; + + debug!( + "The gateway with id {} which is being updated by user {} has url {}", + gateway_id, session.user.username, gateway.url + ); + + gateway.save(&appstate.pool).await?; + + info!( + "User {} has updated gateway with id {} to have url {}", + session.user.username, gateway_id, data.url + ); + + Ok(ApiResponse { + json: json!({}), + status: StatusCode::OK, + }) +} diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 55edbf4da..48483123d 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -37,6 +37,8 @@ pub mod wireguard; #[cfg(feature = "worker")] pub mod worker; pub(crate) mod yubikey; +#[cfg(feature = "wireguard")] +pub mod gateway; pub(crate) static SESSION_COOKIE_NAME: &str = "defguard_session"; pub(crate) static SIGN_IN_COOKIE_NAME: &str = "defguard_sign_in"; diff --git a/src/lib.rs b/src/lib.rs index 49522dd0f..b03070090 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -45,6 +45,10 @@ use utoipa::{ }; use utoipa_swagger_ui::SwaggerUi; +#[cfg(feature = "wireguard")] +use self::handlers::gateway::{ + add_gateway, delete_gateway, get_gateway, get_gateways, update_gateway, +}; #[cfg(feature = "wireguard")] use self::handlers::wireguard::{ add_device, add_user_devices, create_network, create_network_token, delete_device, @@ -471,6 +475,11 @@ pub fn build_webapp( .route("/network/:network_id/token", get(create_network_token)) .route("/network/:network_id/stats/users", get(user_stats)) .route("/network/:network_id/stats", get(network_stats)) + .route("/network/:network_id/gateway", post(add_gateway)) + .route("/gateway/:gateway_id", get(get_gateway)) + .route("/gateway/:gateway_id", put(update_gateway)) + .route("/gateway/:gateway_id", delete(delete_gateway)) + .route("/network/:network_id/all_gateways", get(get_gateways)) .layer(Extension(gateway_state)), ); From a237e78f6163d21632fc650fc563cfe2fa225bc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Tue, 22 Oct 2024 09:17:22 +0200 Subject: [PATCH 11/26] Merge migrations --- Cargo.lock | 12 ++++++------ migrations/20241015074303_network_gateways.up.sql | 1 + migrations/20241021091427_add_gateway_url.down.sql | 1 - migrations/20241021091427_add_gateway_url.up.sql | 1 - 4 files changed, 7 insertions(+), 8 deletions(-) delete mode 100644 migrations/20241021091427_add_gateway_url.down.sql delete mode 100644 migrations/20241021091427_add_gateway_url.up.sql diff --git a/Cargo.lock b/Cargo.lock index d85c990f7..28dbb17f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -591,9 +591,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" dependencies = [ "serde", ] @@ -4396,9 +4396,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.211" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "1ac55e59090389fb9f0dd9e0f3c09615afed1d19094284d0b200441f13550793" dependencies = [ "serde_derive", ] @@ -4434,9 +4434,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.211" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "54be4f245ce16bc58d57ef2716271d0d4519e0f6defa147f6e081005bcb278ff" dependencies = [ "proc-macro2", "quote", diff --git a/migrations/20241015074303_network_gateways.up.sql b/migrations/20241015074303_network_gateways.up.sql index 000a79a0c..718960e42 100644 --- a/migrations/20241015074303_network_gateways.up.sql +++ b/migrations/20241015074303_network_gateways.up.sql @@ -1,5 +1,6 @@ CREATE TABLE gateway ( id bigserial PRIMARY KEY, network_id bigint NOT NULL, + url TEXT NOT NULL, FOREIGN KEY(network_id) REFERENCES wireguard_network(id) ); diff --git a/migrations/20241021091427_add_gateway_url.down.sql b/migrations/20241021091427_add_gateway_url.down.sql deleted file mode 100644 index b5cb12f9d..000000000 --- a/migrations/20241021091427_add_gateway_url.down.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE gateway DROP COLUMN url; diff --git a/migrations/20241021091427_add_gateway_url.up.sql b/migrations/20241021091427_add_gateway_url.up.sql deleted file mode 100644 index 59af27ae9..000000000 --- a/migrations/20241021091427_add_gateway_url.up.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE gateway ADD COLUMN url TEXT NOT NULL; From 7c47aebd4aee403e26ad66ba0312d7f46214bab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Tue, 22 Oct 2024 10:27:06 +0200 Subject: [PATCH 12/26] Update web packages --- web/package.json | 124 +- web/pnpm-lock.yaml | 7190 +++++++++-------- web/src/pwa/playstore.png | Bin 9449 -> 9437 bytes web/src/shared/images/png/manual-config-1.png | Bin 20128 -> 14044 bytes 4 files changed, 3684 insertions(+), 3630 deletions(-) diff --git a/web/package.json b/web/package.json index c7ed2738c..679377bfe 100644 --- a/web/package.json +++ b/web/package.json @@ -41,105 +41,105 @@ } }, "dependencies": { - "@floating-ui/react": "^0.26.7", + "@floating-ui/react": "^0.26.25", "@github/webauthn-json": "^2.1.1", - "@hookform/resolvers": "^3.3.4", - "@ladle/react": "^4.0.2", + "@hookform/resolvers": "^3.9.0", + "@ladle/react": "^4.1.2", "@metamask/detect-provider": "^2.0.0", "@react-rxjs/core": "^0.10.7", - "@stablelib/base64": "^1.0.1", - "@stablelib/x25519": "^1.0.3", - "@tanstack/query-core": "^4.32.6", - "@tanstack/react-query": "^4.32.6", + "@stablelib/base64": "^2.0.0", + "@stablelib/x25519": "^2.0.0", + "@tanstack/query-core": "^4.36.1", + "@tanstack/react-query": "^4.36.1", "@tanstack/react-virtual": "3.0.0-beta.9", "@tanstack/virtual-core": "3.0.0-beta.9", - "@tauri-apps/api": "^1.5.3", + "@tauri-apps/api": "^1.6.0", "@types/react-virtualized-auto-sizer": "^1.0.4", "@types/react-window": "^1.8.8", - "@vitejs/plugin-legacy": "^5.3.0", - "@vitejs/plugin-react": "^4.2.1", - "axios": "^1.6.7", - "byte-size": "^8.1.1", + "@vitejs/plugin-legacy": "^5.4.2", + "@vitejs/plugin-react": "^4.3.3", + "axios": "^1.7.7", + "byte-size": "^9.0.0", "classnames": "^2.5.1", - "dayjs": "^1.11.10", + "dayjs": "^1.11.13", "detect-browser": "^5.3.0", - "ethers": "^6.10.0", + "ethers": "^6.13.4", "events": "^3.3.0", "fast-deep-equal": "^3.1.3", "file-saver": "^2.0.5", - "framer-motion": "^11.0.3", + "framer-motion": "^11.11.9", "get-text-width": "^1.0.3", "hex-rgb": "^5.0.0", - "html-react-parser": "^5.1.1", - "itertools": "^2.2.3", + "html-react-parser": "^5.1.18", + "itertools": "^2.3.2", "lodash-es": "^4.17.21", - "numbro": "^2.4.0", - "qrcode": "^1.5.3", - "radash": "^11.0.0", - "react": "^18.2.0", + "numbro": "^2.5.0", + "qrcode": "^1.5.4", + "radash": "^12.1.0", + "react": "^18.3.1", "react-click-away-listener": "^2.2.3", - "react-dom": "^18.2.0", - "react-hook-form": "^7.49.3", + "react-dom": "^18.3.1", + "react-hook-form": "^7.53.1", "react-idle-timer": "^5.7.2", - "react-is": "^18.2.0", - "react-loading-skeleton": "^3.3.1", + "react-is": "^18.3.1", + "react-loading-skeleton": "^3.5.0", "react-markdown": "^9.0.1", - "react-qr-code": "^2.0.12", - "react-router": "^6.21.3", - "react-router-dom": "^6.21.3", - "react-virtualized-auto-sizer": "^1.0.21", + "react-qr-code": "^2.0.15", + "react-router": "^6.27.0", + "react-router-dom": "^6.27.0", + "react-virtualized-auto-sizer": "^1.0.24", "react-window": "^1.8.10", - "recharts": "^2.10.4", - "rollup": "^4.9.6", + "recharts": "^2.13.0", + "rollup": "npm:@rollup/wasm-node@^4.24.0", "rxjs": "^7.8.1", - "terser": "^5.27.0", + "terser": "^5.36.0", "typesafe-i18n": "^5.26.2", "use-breakpoint": "^4.0.1", - "zod": "^3.22.4", - "zustand": "^4.5.0" + "zod": "^3.23.8", + "zustand": "^4.5.5" }, "devDependencies": { - "@babel/core": "^7.23.9", - "@csstools/css-parser-algorithms": "^2.5.0", - "@csstools/css-tokenizer": "^2.2.3", + "@babel/core": "^7.25.8", + "@csstools/css-parser-algorithms": "^2.7.1", + "@csstools/css-tokenizer": "^2.4.1", "@hookform/devtools": "^4.3.1", "@svgr/cli": "^8.1.0", - "@tanstack/react-query-devtools": "^4.32.6", + "@tanstack/react-query-devtools": "^4.36.1", "@types/byte-size": "^8.1.2", "@types/file-saver": "^2.0.7", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.11.7", - "@types/react": "^18.2.48", - "@types/react-dom": "^18.2.18", + "@types/node": "^20.16.14", + "@types/react": "^18.3.11", + "@types/react-dom": "^18.3.1", "@types/react-router-dom": "^5.3.3", - "@typescript-eslint/eslint-plugin": "^6.19.1", - "@typescript-eslint/parser": "^6.19.1", - "@vitejs/plugin-react-swc": "^3.5.0", - "autoprefixer": "^10.4.17", - "concurrently": "^8.2.2", - "esbuild": "^0.19.12", - "eslint": "^8.56.0", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "@vitejs/plugin-react-swc": "^3.7.1", + "autoprefixer": "^10.4.20", + "concurrently": "^9.0.1", + "esbuild": "^0.24.0", + "eslint": "^8.57.1", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jsx-a11y": "^6.8.0", - "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-react": "^7.33.2", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.5", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jsx-a11y": "^6.10.1", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-react": "^7.37.1", + "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-react-refresh": "^0.4.13", "eslint-plugin-simple-import-sort": "^10.0.0", - "postcss": "^8.4.33", - "prettier": "^3.2.4", + "postcss": "^8.4.47", + "prettier": "^3.3.3", "prop-types": "^15.8.1", - "rollup-plugin-preserve-directives": "^0.3.1", - "sass": "^1.70.0", + "rollup-plugin-preserve-directives": "^0.4.0", + "sass": "^1.80.3", "standard-version": "^9.5.0", "stylelint-config-prettier-scss": "^1.0.0", - "stylelint-config-standard-scss": "^13.0.0", - "stylelint-scss": "^6.1.0", - "typedoc": "^0.25.7", + "stylelint-config-standard-scss": "^13.1.0", + "stylelint-scss": "^6.8.1", + "typedoc": "^0.25.13", "typescript": "~5.3.3", "typescript-eslint-language-service": "^5.0.5", - "vite": "^5.0.12", + "vite": "^5.4.9", "vite-plugin-eslint": "^1.8.1", "vite-plugin-package-version": "^1.1.0" }, diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index ba7fe4b1a..dc14acf6a 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -12,44 +12,44 @@ importers: .: dependencies: '@floating-ui/react': - specifier: ^0.26.7 - version: 0.26.7(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^0.26.25 + version: 0.26.25(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@github/webauthn-json': specifier: ^2.1.1 version: 2.1.1 '@hookform/resolvers': - specifier: ^3.3.4 - version: 3.3.4(react-hook-form@7.49.3(react@18.2.0)) + specifier: ^3.9.0 + version: 3.9.0(react-hook-form@7.53.1(react@18.3.1)) '@ladle/react': - specifier: ^4.0.2 - version: 4.0.2(@types/node@20.11.7)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.70.0)(terser@5.27.0)(typescript@5.3.3) + specifier: ^4.1.2 + version: 4.1.2(@types/node@20.16.14)(@types/react@18.3.11)(acorn@8.13.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.80.3)(terser@5.36.0)(typescript@5.3.3) '@metamask/detect-provider': specifier: ^2.0.0 version: 2.0.0 '@react-rxjs/core': specifier: ^0.10.7 - version: 0.10.7(react@18.2.0)(rxjs@7.8.1) + version: 0.10.7(react@18.3.1)(rxjs@7.8.1) '@stablelib/base64': - specifier: ^1.0.1 - version: 1.0.1 + specifier: ^2.0.0 + version: 2.0.0 '@stablelib/x25519': - specifier: ^1.0.3 - version: 1.0.3 + specifier: ^2.0.0 + version: 2.0.0 '@tanstack/query-core': - specifier: ^4.32.6 + specifier: ^4.36.1 version: 4.36.1 '@tanstack/react-query': - specifier: ^4.32.6 - version: 4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^4.36.1 + version: 4.36.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tanstack/react-virtual': specifier: 3.0.0-beta.9 - version: 3.0.0-beta.9(react@18.2.0) + version: 3.0.0-beta.9(react@18.3.1) '@tanstack/virtual-core': specifier: 3.0.0-beta.9 version: 3.0.0-beta.9 '@tauri-apps/api': - specifier: ^1.5.3 - version: 1.5.3 + specifier: ^1.6.0 + version: 1.6.0 '@types/react-virtualized-auto-sizer': specifier: ^1.0.4 version: 1.0.4 @@ -57,29 +57,29 @@ importers: specifier: ^1.8.8 version: 1.8.8 '@vitejs/plugin-legacy': - specifier: ^5.3.0 - version: 5.3.0(esbuild@0.19.12)(terser@5.27.0)(vite@5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0)) + specifier: ^5.4.2 + version: 5.4.2(terser@5.36.0)(vite@5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0)) '@vitejs/plugin-react': - specifier: ^4.2.1 - version: 4.2.1(vite@5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0)) + specifier: ^4.3.3 + version: 4.3.3(vite@5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0)) axios: - specifier: ^1.6.7 - version: 1.6.7 + specifier: ^1.7.7 + version: 1.7.7 byte-size: - specifier: ^8.1.1 - version: 8.1.1 + specifier: ^9.0.0 + version: 9.0.0 classnames: specifier: ^2.5.1 version: 2.5.1 dayjs: - specifier: ^1.11.10 - version: 1.11.10 + specifier: ^1.11.13 + version: 1.11.13 detect-browser: specifier: ^5.3.0 version: 5.3.0 ethers: - specifier: ^6.10.0 - version: 6.10.0 + specifier: ^6.13.4 + version: 6.13.4 events: specifier: ^3.3.0 version: 3.3.0 @@ -90,8 +90,8 @@ importers: specifier: ^2.0.5 version: 2.0.5 framer-motion: - specifier: ^11.0.3 - version: 11.0.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^11.11.9 + version: 11.11.9(@emotion/is-prop-valid@1.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) get-text-width: specifier: ^1.0.3 version: 1.0.3 @@ -99,65 +99,65 @@ importers: specifier: ^5.0.0 version: 5.0.0 html-react-parser: - specifier: ^5.1.1 - version: 5.1.1(react@18.2.0) + specifier: ^5.1.18 + version: 5.1.18(@types/react@18.3.11)(react@18.3.1) itertools: - specifier: ^2.2.3 - version: 2.2.3 + specifier: ^2.3.2 + version: 2.3.2 lodash-es: specifier: ^4.17.21 version: 4.17.21 numbro: - specifier: ^2.4.0 - version: 2.4.0 + specifier: ^2.5.0 + version: 2.5.0 qrcode: - specifier: ^1.5.3 - version: 1.5.3 + specifier: ^1.5.4 + version: 1.5.4 radash: - specifier: ^11.0.0 - version: 11.0.0 + specifier: ^12.1.0 + version: 12.1.0 react: - specifier: ^18.2.0 - version: 18.2.0 + specifier: ^18.3.1 + version: 18.3.1 react-click-away-listener: specifier: ^2.2.3 - version: 2.2.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 2.2.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-dom: - specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) react-hook-form: - specifier: ^7.49.3 - version: 7.49.3(react@18.2.0) + specifier: ^7.53.1 + version: 7.53.1(react@18.3.1) react-idle-timer: specifier: ^5.7.2 - version: 5.7.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 5.7.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-is: - specifier: ^18.2.0 - version: 18.2.0 + specifier: ^18.3.1 + version: 18.3.1 react-loading-skeleton: - specifier: ^3.3.1 - version: 3.3.1(react@18.2.0) + specifier: ^3.5.0 + version: 3.5.0(react@18.3.1) react-markdown: specifier: ^9.0.1 - version: 9.0.1(@types/react@18.2.48)(react@18.2.0) + version: 9.0.1(@types/react@18.3.11)(react@18.3.1) react-qr-code: - specifier: ^2.0.12 - version: 2.0.12(react@18.2.0) + specifier: ^2.0.15 + version: 2.0.15(react@18.3.1) react-router: - specifier: ^6.21.3 - version: 6.21.3(react@18.2.0) + specifier: ^6.27.0 + version: 6.27.0(react@18.3.1) react-router-dom: - specifier: ^6.21.3 - version: 6.21.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^6.27.0 + version: 6.27.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-virtualized-auto-sizer: - specifier: ^1.0.21 - version: 1.0.21(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^1.0.24 + version: 1.0.24(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-window: specifier: ^1.8.10 - version: 1.8.10(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 1.8.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1) recharts: - specifier: ^2.10.4 - version: 2.10.4(prop-types@15.8.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^2.13.0 + version: 2.13.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) rollup: specifier: npm:@rollup/wasm-node version: '@rollup/wasm-node@4.24.0' @@ -165,39 +165,39 @@ importers: specifier: ^7.8.1 version: 7.8.1 terser: - specifier: ^5.27.0 - version: 5.27.0 + specifier: ^5.36.0 + version: 5.36.0 typesafe-i18n: specifier: ^5.26.2 version: 5.26.2(typescript@5.3.3) use-breakpoint: specifier: ^4.0.1 - version: 4.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 4.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) zod: - specifier: ^3.22.4 - version: 3.22.4 + specifier: ^3.23.8 + version: 3.23.8 zustand: - specifier: ^4.5.0 - version: 4.5.0(@types/react@18.2.48)(react@18.2.0) + specifier: ^4.5.5 + version: 4.5.5(@types/react@18.3.11)(react@18.3.1) devDependencies: '@babel/core': - specifier: ^7.23.9 - version: 7.23.9 + specifier: ^7.25.8 + version: 7.25.8 '@csstools/css-parser-algorithms': - specifier: ^2.5.0 - version: 2.5.0(@csstools/css-tokenizer@2.2.3) + specifier: ^2.7.1 + version: 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': - specifier: ^2.2.3 - version: 2.2.3 + specifier: ^2.4.1 + version: 2.4.1 '@hookform/devtools': specifier: ^4.3.1 - version: 4.3.1(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 4.3.1(@types/react@18.3.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@svgr/cli': specifier: ^8.1.0 version: 8.1.0(typescript@5.3.3) '@tanstack/react-query-devtools': - specifier: ^4.32.6 - version: 4.36.1(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^4.36.1 + version: 4.36.1(@tanstack/react-query@4.36.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/byte-size': specifier: ^8.1.2 version: 8.1.2 @@ -208,77 +208,77 @@ importers: specifier: ^4.17.12 version: 4.17.12 '@types/node': - specifier: ^20.11.7 - version: 20.11.7 + specifier: ^20.16.14 + version: 20.16.14 '@types/react': - specifier: ^18.2.48 - version: 18.2.48 + specifier: ^18.3.11 + version: 18.3.11 '@types/react-dom': - specifier: ^18.2.18 - version: 18.2.18 + specifier: ^18.3.1 + version: 18.3.1 '@types/react-router-dom': specifier: ^5.3.3 version: 5.3.3 '@typescript-eslint/eslint-plugin': - specifier: ^6.19.1 - version: 6.19.1(@typescript-eslint/parser@6.19.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3) + specifier: ^6.21.0 + version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3) '@typescript-eslint/parser': - specifier: ^6.19.1 - version: 6.19.1(eslint@8.56.0)(typescript@5.3.3) + specifier: ^6.21.0 + version: 6.21.0(eslint@8.57.1)(typescript@5.3.3) '@vitejs/plugin-react-swc': - specifier: ^3.5.0 - version: 3.5.0(vite@5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0)) + specifier: ^3.7.1 + version: 3.7.1(vite@5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0)) autoprefixer: - specifier: ^10.4.17 - version: 10.4.17(postcss@8.4.33) + specifier: ^10.4.20 + version: 10.4.20(postcss@8.4.47) concurrently: - specifier: ^8.2.2 - version: 8.2.2 + specifier: ^9.0.1 + version: 9.0.1 esbuild: - specifier: ^0.19.12 - version: 0.19.12 + specifier: ^0.24.0 + version: 0.24.0 eslint: - specifier: ^8.56.0 - version: 8.56.0 + specifier: ^8.57.1 + version: 8.57.1 eslint-config-prettier: specifier: ^9.1.0 - version: 9.1.0(eslint@8.56.0) + version: 9.1.0(eslint@8.57.1) eslint-plugin-import: - specifier: ^2.29.1 - version: 2.29.1(@typescript-eslint/parser@6.19.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0) + specifier: ^2.31.0 + version: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1) eslint-plugin-jsx-a11y: - specifier: ^6.8.0 - version: 6.8.0(eslint@8.56.0) + specifier: ^6.10.1 + version: 6.10.1(eslint@8.57.1) eslint-plugin-prettier: - specifier: ^5.1.3 - version: 5.1.3(@types/eslint@8.56.2)(eslint-config-prettier@9.1.0(eslint@8.56.0))(eslint@8.56.0)(prettier@3.2.4) + specifier: ^5.2.1 + version: 5.2.1(@types/eslint@8.56.12)(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.3.3) eslint-plugin-react: - specifier: ^7.33.2 - version: 7.33.2(eslint@8.56.0) + specifier: ^7.37.1 + version: 7.37.1(eslint@8.57.1) eslint-plugin-react-hooks: - specifier: ^4.6.0 - version: 4.6.0(eslint@8.56.0) + specifier: ^4.6.2 + version: 4.6.2(eslint@8.57.1) eslint-plugin-react-refresh: - specifier: ^0.4.5 - version: 0.4.5(eslint@8.56.0) + specifier: ^0.4.13 + version: 0.4.13(eslint@8.57.1) eslint-plugin-simple-import-sort: specifier: ^10.0.0 - version: 10.0.0(eslint@8.56.0) + version: 10.0.0(eslint@8.57.1) postcss: - specifier: ^8.4.33 - version: 8.4.33 + specifier: ^8.4.47 + version: 8.4.47 prettier: - specifier: ^3.2.4 - version: 3.2.4 + specifier: ^3.3.3 + version: 3.3.3 prop-types: specifier: ^15.8.1 version: 15.8.1 rollup-plugin-preserve-directives: - specifier: ^0.3.1 - version: 0.3.1(@rollup/wasm-node@4.24.0) + specifier: ^0.4.0 + version: 0.4.0(@rollup/wasm-node@4.24.0) sass: - specifier: ^1.70.0 - version: 1.70.0 + specifier: ^1.80.3 + version: 1.80.3 standard-version: specifier: ^9.5.0 version: 9.5.0 @@ -286,295 +286,199 @@ importers: specifier: ^1.0.0 version: 1.0.0(stylelint@16.2.0(typescript@5.3.3)) stylelint-config-standard-scss: - specifier: ^13.0.0 - version: 13.0.0(postcss@8.4.33)(stylelint@16.2.0(typescript@5.3.3)) + specifier: ^13.1.0 + version: 13.1.0(postcss@8.4.47)(stylelint@16.2.0(typescript@5.3.3)) stylelint-scss: - specifier: ^6.1.0 - version: 6.1.0(stylelint@16.2.0(typescript@5.3.3)) + specifier: ^6.8.1 + version: 6.8.1(stylelint@16.2.0(typescript@5.3.3)) typedoc: - specifier: ^0.25.7 - version: 0.25.7(typescript@5.3.3) + specifier: ^0.25.13 + version: 0.25.13(typescript@5.3.3) typescript: specifier: ~5.3.3 version: 5.3.3 typescript-eslint-language-service: specifier: ^5.0.5 - version: 5.0.5(@typescript-eslint/parser@6.19.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3) + version: 5.0.5(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3) vite: - specifier: ^5.0.12 - version: 5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0) + specifier: ^5.4.9 + version: 5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0) vite-plugin-eslint: specifier: ^1.8.1 - version: 1.8.1(eslint@8.56.0)(vite@5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0)) + version: 1.8.1(eslint@8.57.1)(vite@5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0)) vite-plugin-package-version: specifier: ^1.1.0 - version: 1.1.0(vite@5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0)) + version: 1.1.0(vite@5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0)) packages: - '@aashutoshrathi/word-wrap@1.2.6': - resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} - engines: {node: '>=0.10.0'} - - '@adraffy/ens-normalize@1.10.0': - resolution: {integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==} + '@adraffy/ens-normalize@1.10.1': + resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==} - '@ampproject/remapping@2.2.1': - resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@babel/code-frame@7.23.5': - resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} + '@babel/code-frame@7.25.7': + resolution: {integrity: sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.23.5': - resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} + '@babel/compat-data@7.25.8': + resolution: {integrity: sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==} engines: {node: '>=6.9.0'} - '@babel/core@7.23.9': - resolution: {integrity: sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==} + '@babel/core@7.25.8': + resolution: {integrity: sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==} engines: {node: '>=6.9.0'} - '@babel/generator@7.23.6': - resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} + '@babel/generator@7.25.7': + resolution: {integrity: sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==} engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.22.5': - resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} + '@babel/helper-annotate-as-pure@7.25.7': + resolution: {integrity: sha512-4xwU8StnqnlIhhioZf1tqnVWeQ9pvH/ujS8hRfw/WOza+/a+1qv69BWNy+oY231maTCWgKWhfBU7kDpsds6zAA==} engines: {node: '>=6.9.0'} - '@babel/helper-builder-binary-assignment-operator-visitor@7.22.15': - resolution: {integrity: sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==} + '@babel/helper-builder-binary-assignment-operator-visitor@7.25.7': + resolution: {integrity: sha512-12xfNeKNH7jubQNm7PAkzlLwEmCs1tfuX3UjIw6vP6QXi+leKh6+LyC/+Ed4EIQermwd58wsyh070yjDHFlNGg==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.23.6': - resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} + '@babel/helper-compilation-targets@7.25.7': + resolution: {integrity: sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==} engines: {node: '>=6.9.0'} - '@babel/helper-create-class-features-plugin@7.23.7': - resolution: {integrity: sha512-xCoqR/8+BoNnXOY7RVSgv6X+o7pmT5q1d+gGcRlXYkI+9B31glE4jeejhKVpA04O1AtzOt7OSQ6VYKP5FcRl9g==} + '@babel/helper-create-class-features-plugin@7.25.7': + resolution: {integrity: sha512-bD4WQhbkx80mAyj/WCm4ZHcF4rDxkoLFO6ph8/5/mQ3z4vAzltQXAmbc7GvVJx5H+lk5Mi5EmbTeox5nMGCsbw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-create-regexp-features-plugin@7.22.15': - resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==} + '@babel/helper-create-regexp-features-plugin@7.25.7': + resolution: {integrity: sha512-byHhumTj/X47wJ6C6eLpK7wW/WBEcnUeb7D0FNc/jFQnQVw7DOso3Zz5u9x/zLrFVkHa89ZGDbkAa1D54NdrCQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-define-polyfill-provider@0.4.4': - resolution: {integrity: sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==} + '@babel/helper-define-polyfill-provider@0.6.2': + resolution: {integrity: sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - '@babel/helper-define-polyfill-provider@0.5.0': - resolution: {integrity: sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - - '@babel/helper-environment-visitor@7.22.20': - resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-function-name@7.23.0': - resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-hoist-variables@7.22.5': - resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-member-expression-to-functions@7.23.0': - resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==} + '@babel/helper-member-expression-to-functions@7.25.7': + resolution: {integrity: sha512-O31Ssjd5K6lPbTX9AAYpSKrZmLeagt9uwschJd+Ixo6QiRyfpvgtVQp8qrDR9UNFjZ8+DO34ZkdrN+BnPXemeA==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.22.15': - resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} + '@babel/helper-module-imports@7.25.7': + resolution: {integrity: sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.23.3': - resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} + '@babel/helper-module-transforms@7.25.7': + resolution: {integrity: sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-optimise-call-expression@7.22.5': - resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} + '@babel/helper-optimise-call-expression@7.25.7': + resolution: {integrity: sha512-VAwcwuYhv/AT+Vfr28c9y6SHzTan1ryqrydSTFGjU0uDJHw3uZ+PduI8plCLkRsDnqK2DMEDmwrOQRsK/Ykjng==} engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.22.5': - resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} + '@babel/helper-plugin-utils@7.25.7': + resolution: {integrity: sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==} engines: {node: '>=6.9.0'} - '@babel/helper-remap-async-to-generator@7.22.20': - resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==} + '@babel/helper-remap-async-to-generator@7.25.7': + resolution: {integrity: sha512-kRGE89hLnPfcz6fTrlNU+uhgcwv0mBE4Gv3P9Ke9kLVJYpi4AMVVEElXvB5CabrPZW4nCM8P8UyyjrzCM0O2sw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-replace-supers@7.22.20': - resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==} + '@babel/helper-replace-supers@7.25.7': + resolution: {integrity: sha512-iy8JhqlUW9PtZkd4pHM96v6BdJ66Ba9yWSE4z0W4TvSZwLBPkyDsiIU3ENe4SmrzRBs76F7rQXTy1lYC49n6Lw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-simple-access@7.22.5': - resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} - engines: {node: '>=6.9.0'} - - '@babel/helper-skip-transparent-expression-wrappers@7.22.5': - resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} + '@babel/helper-simple-access@7.25.7': + resolution: {integrity: sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==} engines: {node: '>=6.9.0'} - '@babel/helper-split-export-declaration@7.22.6': - resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + '@babel/helper-skip-transparent-expression-wrappers@7.25.7': + resolution: {integrity: sha512-pPbNbchZBkPMD50K0p3JGcFMNLVUCuU/ABybm/PGNj4JiHrpmNyqqCphBk4i19xXtNV0JhldQJJtbSW5aUvbyA==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.23.4': - resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} + '@babel/helper-string-parser@7.25.7': + resolution: {integrity: sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.22.20': - resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + '@babel/helper-validator-identifier@7.25.7': + resolution: {integrity: sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.23.5': - resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} + '@babel/helper-validator-option@7.25.7': + resolution: {integrity: sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==} engines: {node: '>=6.9.0'} - '@babel/helper-wrap-function@7.22.20': - resolution: {integrity: sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==} + '@babel/helper-wrap-function@7.25.7': + resolution: {integrity: sha512-MA0roW3JF2bD1ptAaJnvcabsVlNQShUaThyJbCDD4bCp8NEgiFvpoqRI2YS22hHlc2thjO/fTg2ShLMC3jygAg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.23.9': - resolution: {integrity: sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==} + '@babel/helpers@7.25.7': + resolution: {integrity: sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==} engines: {node: '>=6.9.0'} - '@babel/highlight@7.23.4': - resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} + '@babel/highlight@7.25.7': + resolution: {integrity: sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.23.6': - resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/parser@7.23.9': - resolution: {integrity: sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==} + '@babel/parser@7.25.8': + resolution: {integrity: sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3': - resolution: {integrity: sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==} + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.7': + resolution: {integrity: sha512-UV9Lg53zyebzD1DwQoT9mzkEKa922LNUp5YkTJ6Uta0RbyXaQNUgcvSt7qIu1PpPzVb6rd10OVNTzkyBGeVmxQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.23.3': - resolution: {integrity: sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.13.0 - - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.23.7': - resolution: {integrity: sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==} + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.7': + resolution: {integrity: sha512-GDDWeVLNxRIkQTnJn2pDOM1pkCgYdSqPeT1a9vh9yIqu2uzzgw1zcqEb+IJOhy+dTBMlNdThrDIksr2o09qrrQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': - resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.7': + resolution: {integrity: sha512-wxyWg2RYaSUYgmd9MR0FyRGyeOMQE/Uzr1wzd/g5cf5bwi9A4v6HFdDm7y1MgDtod/fLOSTZY6jDgV0xU9d5bA==} engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-async-generators@7.8.4': - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-class-properties@7.12.13': - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^7.0.0 - '@babel/plugin-syntax-class-static-block@7.14.5': - resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.7': + resolution: {integrity: sha512-Xwg6tZpLxc4iQjorYsyGMyfJE7nP5MV8t/Ka58BgiA7Jw0fRqQNcANlLfdJ/yvBt9z9LD2We+BEkT7vLqZRWng==} engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-dynamic-import@7.8.3': - resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-export-namespace-from@7.8.3': - resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^7.13.0 - '@babel/plugin-syntax-import-assertions@7.23.3': - resolution: {integrity: sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==} + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.7': + resolution: {integrity: sha512-UVATLMidXrnH+GMUIuxq55nejlj02HP7F5ETyBONzP6G87fPBogG4CH6kxrSrdIuAjdwNO9VzyaYsrZPscWUrw==} engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^7.0.0 - '@babel/plugin-syntax-import-attributes@7.23.3': - resolution: {integrity: sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==} + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-meta@7.10.4': - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-json-strings@7.8.3': - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-logical-assignment-operators@7.10.4': - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-numeric-separator@7.10.4': - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-object-rest-spread@7.8.3': - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-optional-catch-binding@7.8.3': - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-optional-chaining@7.8.3': - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-private-property-in-object@7.14.5': - resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + '@babel/plugin-syntax-import-assertions@7.25.7': + resolution: {integrity: sha512-ZvZQRmME0zfJnDQnVBKYzHxXT7lYBB3Revz1GuS7oLXWMgqUPX4G+DDbT30ICClht9WKV34QVrZhSw6WdklwZQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-top-level-await@7.14.5': - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + '@babel/plugin-syntax-import-attributes@7.25.7': + resolution: {integrity: sha512-AqVo+dguCgmpi/3mYBdu9lkngOBlQ2w2vnNpa6gfiCxQZLzV4ZbhsXitJ2Yblkoe1VQwtHSaNmIaGll/26YWRw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -585,308 +489,314 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-arrow-functions@7.23.3': - resolution: {integrity: sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==} + '@babel/plugin-transform-arrow-functions@7.25.7': + resolution: {integrity: sha512-EJN2mKxDwfOUCPxMO6MUI58RN3ganiRAG/MS/S3HfB6QFNjroAMelQo/gybyYq97WerCBAZoyrAoW8Tzdq2jWg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-generator-functions@7.23.7': - resolution: {integrity: sha512-PdxEpL71bJp1byMG0va5gwQcXHxuEYC/BgI/e88mGTtohbZN28O5Yit0Plkkm/dBzCF/BxmbNcses1RH1T+urA==} + '@babel/plugin-transform-async-generator-functions@7.25.8': + resolution: {integrity: sha512-9ypqkozyzpG+HxlH4o4gdctalFGIjjdufzo7I2XPda0iBnZ6a+FO0rIEQcdSPXp02CkvGsII1exJhmROPQd5oA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-to-generator@7.23.3': - resolution: {integrity: sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==} + '@babel/plugin-transform-async-to-generator@7.25.7': + resolution: {integrity: sha512-ZUCjAavsh5CESCmi/xCpX1qcCaAglzs/7tmuvoFnJgA1dM7gQplsguljoTg+Ru8WENpX89cQyAtWoaE0I3X3Pg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoped-functions@7.23.3': - resolution: {integrity: sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==} + '@babel/plugin-transform-block-scoped-functions@7.25.7': + resolution: {integrity: sha512-xHttvIM9fvqW+0a3tZlYcZYSBpSWzGBFIt/sYG3tcdSzBB8ZeVgz2gBP7Df+sM0N1850jrviYSSeUuc+135dmQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoping@7.23.4': - resolution: {integrity: sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==} + '@babel/plugin-transform-block-scoping@7.25.7': + resolution: {integrity: sha512-ZEPJSkVZaeTFG/m2PARwLZQ+OG0vFIhPlKHK/JdIMy8DbRJ/htz6LRrTFtdzxi9EHmcwbNPAKDnadpNSIW+Aow==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-properties@7.23.3': - resolution: {integrity: sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==} + '@babel/plugin-transform-class-properties@7.25.7': + resolution: {integrity: sha512-mhyfEW4gufjIqYFo9krXHJ3ElbFLIze5IDp+wQTxoPd+mwFb1NxatNAwmv8Q8Iuxv7Zc+q8EkiMQwc9IhyGf4g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-static-block@7.23.4': - resolution: {integrity: sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==} + '@babel/plugin-transform-class-static-block@7.25.8': + resolution: {integrity: sha512-e82gl3TCorath6YLf9xUwFehVvjvfqFhdOo4+0iVIVju+6XOi5XHkqB3P2AXnSwoeTX0HBoXq5gJFtvotJzFnQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 - '@babel/plugin-transform-classes@7.23.8': - resolution: {integrity: sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==} + '@babel/plugin-transform-classes@7.25.7': + resolution: {integrity: sha512-9j9rnl+YCQY0IGoeipXvnk3niWicIB6kCsWRGLwX241qSXpbA4MKxtp/EdvFxsc4zI5vqfLxzOd0twIJ7I99zg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-computed-properties@7.23.3': - resolution: {integrity: sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==} + '@babel/plugin-transform-computed-properties@7.25.7': + resolution: {integrity: sha512-QIv+imtM+EtNxg/XBKL3hiWjgdLjMOmZ+XzQwSgmBfKbfxUjBzGgVPklUuE55eq5/uVoh8gg3dqlrwR/jw3ZeA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-destructuring@7.23.3': - resolution: {integrity: sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==} + '@babel/plugin-transform-destructuring@7.25.7': + resolution: {integrity: sha512-xKcfLTlJYUczdaM1+epcdh1UGewJqr9zATgrNHcLBcV2QmfvPPEixo/sK/syql9cEmbr7ulu5HMFG5vbbt/sEA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-dotall-regex@7.23.3': - resolution: {integrity: sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==} + '@babel/plugin-transform-dotall-regex@7.25.7': + resolution: {integrity: sha512-kXzXMMRzAtJdDEgQBLF4oaiT6ZCU3oWHgpARnTKDAqPkDJ+bs3NrZb310YYevR5QlRo3Kn7dzzIdHbZm1VzJdQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-duplicate-keys@7.23.3': - resolution: {integrity: sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==} + '@babel/plugin-transform-duplicate-keys@7.25.7': + resolution: {integrity: sha512-by+v2CjoL3aMnWDOyCIg+yxU9KXSRa9tN6MbqggH5xvymmr9p4AMjYkNlQy4brMceBnUyHZ9G8RnpvT8wP7Cfg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-dynamic-import@7.23.4': - resolution: {integrity: sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==} + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.7': + resolution: {integrity: sha512-HvS6JF66xSS5rNKXLqkk7L9c/jZ/cdIVIcoPVrnl8IsVpLggTjXs8OWekbLHs/VtYDDh5WXnQyeE3PPUGm22MA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-dynamic-import@7.25.8': + resolution: {integrity: sha512-gznWY+mr4ZQL/EWPcbBQUP3BXS5FwZp8RUOw06BaRn8tQLzN4XLIxXejpHN9Qo8x8jjBmAAKp6FoS51AgkSA/A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-exponentiation-operator@7.23.3': - resolution: {integrity: sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==} + '@babel/plugin-transform-exponentiation-operator@7.25.7': + resolution: {integrity: sha512-yjqtpstPfZ0h/y40fAXRv2snciYr0OAoMXY/0ClC7tm4C/nG5NJKmIItlaYlLbIVAWNfrYuy9dq1bE0SbX0PEg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-export-namespace-from@7.23.4': - resolution: {integrity: sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==} + '@babel/plugin-transform-export-namespace-from@7.25.8': + resolution: {integrity: sha512-sPtYrduWINTQTW7FtOy99VCTWp4H23UX7vYcut7S4CIMEXU+54zKX9uCoGkLsWXteyaMXzVHgzWbLfQ1w4GZgw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-for-of@7.23.6': - resolution: {integrity: sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==} + '@babel/plugin-transform-for-of@7.25.7': + resolution: {integrity: sha512-n/TaiBGJxYFWvpJDfsxSj9lEEE44BFM1EPGz4KEiTipTgkoFVVcCmzAL3qA7fdQU96dpo4gGf5HBx/KnDvqiHw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-function-name@7.23.3': - resolution: {integrity: sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==} + '@babel/plugin-transform-function-name@7.25.7': + resolution: {integrity: sha512-5MCTNcjCMxQ63Tdu9rxyN6cAWurqfrDZ76qvVPrGYdBxIj+EawuuxTu/+dgJlhK5eRz3v1gLwp6XwS8XaX2NiQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-json-strings@7.23.4': - resolution: {integrity: sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==} + '@babel/plugin-transform-json-strings@7.25.8': + resolution: {integrity: sha512-4OMNv7eHTmJ2YXs3tvxAfa/I43di+VcF+M4Wt66c88EAED1RoGaf1D64cL5FkRpNL+Vx9Hds84lksWvd/wMIdA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-literals@7.23.3': - resolution: {integrity: sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==} + '@babel/plugin-transform-literals@7.25.7': + resolution: {integrity: sha512-fwzkLrSu2fESR/cm4t6vqd7ebNIopz2QHGtjoU+dswQo/P6lwAG04Q98lliE3jkz/XqnbGFLnUcE0q0CVUf92w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-logical-assignment-operators@7.23.4': - resolution: {integrity: sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==} + '@babel/plugin-transform-logical-assignment-operators@7.25.8': + resolution: {integrity: sha512-f5W0AhSbbI+yY6VakT04jmxdxz+WsID0neG7+kQZbCOjuyJNdL5Nn4WIBm4hRpKnUcO9lP0eipUhFN12JpoH8g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-member-expression-literals@7.23.3': - resolution: {integrity: sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==} + '@babel/plugin-transform-member-expression-literals@7.25.7': + resolution: {integrity: sha512-Std3kXwpXfRV0QtQy5JJcRpkqP8/wG4XL7hSKZmGlxPlDqmpXtEPRmhF7ztnlTCtUN3eXRUJp+sBEZjaIBVYaw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-amd@7.23.3': - resolution: {integrity: sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==} + '@babel/plugin-transform-modules-amd@7.25.7': + resolution: {integrity: sha512-CgselSGCGzjQvKzghCvDTxKHP3iooenLpJDO842ehn5D2G5fJB222ptnDwQho0WjEvg7zyoxb9P+wiYxiJX5yA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-commonjs@7.23.3': - resolution: {integrity: sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==} + '@babel/plugin-transform-modules-commonjs@7.25.7': + resolution: {integrity: sha512-L9Gcahi0kKFYXvweO6n0wc3ZG1ChpSFdgG+eV1WYZ3/dGbJK7vvk91FgGgak8YwRgrCuihF8tE/Xg07EkL5COg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-systemjs@7.23.3': - resolution: {integrity: sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==} + '@babel/plugin-transform-modules-systemjs@7.25.7': + resolution: {integrity: sha512-t9jZIvBmOXJsiuyOwhrIGs8dVcD6jDyg2icw1VL4A/g+FnWyJKwUfSSU2nwJuMV2Zqui856El9u+ElB+j9fV1g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-umd@7.23.3': - resolution: {integrity: sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==} + '@babel/plugin-transform-modules-umd@7.25.7': + resolution: {integrity: sha512-p88Jg6QqsaPh+EB7I9GJrIqi1Zt4ZBHUQtjw3z1bzEXcLh6GfPqzZJ6G+G1HBGKUNukT58MnKG7EN7zXQBCODw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-named-capturing-groups-regex@7.22.5': - resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==} + '@babel/plugin-transform-named-capturing-groups-regex@7.25.7': + resolution: {integrity: sha512-BtAT9LzCISKG3Dsdw5uso4oV1+v2NlVXIIomKJgQybotJY3OwCwJmkongjHgwGKoZXd0qG5UZ12JUlDQ07W6Ow==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-new-target@7.23.3': - resolution: {integrity: sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==} + '@babel/plugin-transform-new-target@7.25.7': + resolution: {integrity: sha512-CfCS2jDsbcZaVYxRFo2qtavW8SpdzmBXC2LOI4oO0rP+JSRDxxF3inF4GcPsLgfb5FjkhXG5/yR/lxuRs2pySA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-nullish-coalescing-operator@7.23.4': - resolution: {integrity: sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==} + '@babel/plugin-transform-nullish-coalescing-operator@7.25.8': + resolution: {integrity: sha512-Z7WJJWdQc8yCWgAmjI3hyC+5PXIubH9yRKzkl9ZEG647O9szl9zvmKLzpbItlijBnVhTUf1cpyWBsZ3+2wjWPQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-numeric-separator@7.23.4': - resolution: {integrity: sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==} + '@babel/plugin-transform-numeric-separator@7.25.8': + resolution: {integrity: sha512-rm9a5iEFPS4iMIy+/A/PiS0QN0UyjPIeVvbU5EMZFKJZHt8vQnasbpo3T3EFcxzCeYO0BHfc4RqooCZc51J86Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-rest-spread@7.23.4': - resolution: {integrity: sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==} + '@babel/plugin-transform-object-rest-spread@7.25.8': + resolution: {integrity: sha512-LkUu0O2hnUKHKE7/zYOIjByMa4VRaV2CD/cdGz0AxU9we+VA3kDDggKEzI0Oz1IroG+6gUP6UmWEHBMWZU316g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-super@7.23.3': - resolution: {integrity: sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==} + '@babel/plugin-transform-object-super@7.25.7': + resolution: {integrity: sha512-pWT6UXCEW3u1t2tcAGtE15ornCBvopHj9Bps9D2DsH15APgNVOTwwczGckX+WkAvBmuoYKRCFa4DK+jM8vh5AA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-catch-binding@7.23.4': - resolution: {integrity: sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==} + '@babel/plugin-transform-optional-catch-binding@7.25.8': + resolution: {integrity: sha512-EbQYweoMAHOn7iJ9GgZo14ghhb9tTjgOc88xFgYngifx7Z9u580cENCV159M4xDh3q/irbhSjZVpuhpC2gKBbg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-chaining@7.23.4': - resolution: {integrity: sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==} + '@babel/plugin-transform-optional-chaining@7.25.8': + resolution: {integrity: sha512-q05Bk7gXOxpTHoQ8RSzGSh/LHVB9JEIkKnk3myAWwZHnYiTGYtbdrYkIsS8Xyh4ltKf7GNUSgzs/6P2bJtBAQg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-parameters@7.23.3': - resolution: {integrity: sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==} + '@babel/plugin-transform-parameters@7.25.7': + resolution: {integrity: sha512-FYiTvku63me9+1Nz7TOx4YMtW3tWXzfANZtrzHhUZrz4d47EEtMQhzFoZWESfXuAMMT5mwzD4+y1N8ONAX6lMQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-methods@7.23.3': - resolution: {integrity: sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==} + '@babel/plugin-transform-private-methods@7.25.7': + resolution: {integrity: sha512-KY0hh2FluNxMLwOCHbxVOKfdB5sjWG4M183885FmaqWWiGMhRZq4DQRKH6mHdEucbJnyDyYiZNwNG424RymJjA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-property-in-object@7.23.4': - resolution: {integrity: sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==} + '@babel/plugin-transform-private-property-in-object@7.25.8': + resolution: {integrity: sha512-8Uh966svuB4V8RHHg0QJOB32QK287NBksJOByoKmHMp1TAobNniNalIkI2i5IPj5+S9NYCG4VIjbEuiSN8r+ow==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-property-literals@7.23.3': - resolution: {integrity: sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==} + '@babel/plugin-transform-property-literals@7.25.7': + resolution: {integrity: sha512-lQEeetGKfFi0wHbt8ClQrUSUMfEeI3MMm74Z73T9/kuz990yYVtfofjf3NuA42Jy3auFOpbjDyCSiIkTs1VIYw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx-self@7.23.3': - resolution: {integrity: sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==} + '@babel/plugin-transform-react-jsx-self@7.25.7': + resolution: {integrity: sha512-JD9MUnLbPL0WdVK8AWC7F7tTG2OS6u/AKKnsK+NdRhUiVdnzyR1S3kKQCaRLOiaULvUiqK6Z4JQE635VgtCFeg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx-source@7.23.3': - resolution: {integrity: sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==} + '@babel/plugin-transform-react-jsx-source@7.25.7': + resolution: {integrity: sha512-S/JXG/KrbIY06iyJPKfxr0qRxnhNOdkNXYBl/rmwgDd72cQLH9tEGkDm/yJPGvcSIUoikzfjMios9i+xT/uv9w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regenerator@7.23.3': - resolution: {integrity: sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==} + '@babel/plugin-transform-regenerator@7.25.7': + resolution: {integrity: sha512-mgDoQCRjrY3XK95UuV60tZlFCQGXEtMg8H+IsW72ldw1ih1jZhzYXbJvghmAEpg5UVhhnCeia1CkGttUvCkiMQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-reserved-words@7.23.3': - resolution: {integrity: sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==} + '@babel/plugin-transform-reserved-words@7.25.7': + resolution: {integrity: sha512-3OfyfRRqiGeOvIWSagcwUTVk2hXBsr/ww7bLn6TRTuXnexA+Udov2icFOxFX9abaj4l96ooYkcNN1qi2Zvqwng==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-shorthand-properties@7.23.3': - resolution: {integrity: sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==} + '@babel/plugin-transform-shorthand-properties@7.25.7': + resolution: {integrity: sha512-uBbxNwimHi5Bv3hUccmOFlUy3ATO6WagTApenHz9KzoIdn0XeACdB12ZJ4cjhuB2WSi80Ez2FWzJnarccriJeA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-spread@7.23.3': - resolution: {integrity: sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==} + '@babel/plugin-transform-spread@7.25.7': + resolution: {integrity: sha512-Mm6aeymI0PBh44xNIv/qvo8nmbkpZze1KvR8MkEqbIREDxoiWTi18Zr2jryfRMwDfVZF9foKh060fWgni44luw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-sticky-regex@7.23.3': - resolution: {integrity: sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==} + '@babel/plugin-transform-sticky-regex@7.25.7': + resolution: {integrity: sha512-ZFAeNkpGuLnAQ/NCsXJ6xik7Id+tHuS+NT+ue/2+rn/31zcdnupCdmunOizEaP0JsUmTFSTOPoQY7PkK2pttXw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-template-literals@7.23.3': - resolution: {integrity: sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==} + '@babel/plugin-transform-template-literals@7.25.7': + resolution: {integrity: sha512-SI274k0nUsFFmyQupiO7+wKATAmMFf8iFgq2O+vVFXZ0SV9lNfT1NGzBEhjquFmD8I9sqHLguH+gZVN3vww2AA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typeof-symbol@7.23.3': - resolution: {integrity: sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==} + '@babel/plugin-transform-typeof-symbol@7.25.7': + resolution: {integrity: sha512-OmWmQtTHnO8RSUbL0NTdtpbZHeNTnm68Gj5pA4Y2blFNh+V4iZR68V1qL9cI37J21ZN7AaCnkfdHtLExQPf2uA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-escapes@7.23.3': - resolution: {integrity: sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==} + '@babel/plugin-transform-unicode-escapes@7.25.7': + resolution: {integrity: sha512-BN87D7KpbdiABA+t3HbVqHzKWUDN3dymLaTnPFAMyc8lV+KN3+YzNhVRNdinaCPA4AUqx7ubXbQ9shRjYBl3SQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-property-regex@7.23.3': - resolution: {integrity: sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==} + '@babel/plugin-transform-unicode-property-regex@7.25.7': + resolution: {integrity: sha512-IWfR89zcEPQGB/iB408uGtSPlQd3Jpq11Im86vUgcmSTcoWAiQMCTOa2K2yNNqFJEBVICKhayctee65Ka8OB0w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-regex@7.23.3': - resolution: {integrity: sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==} + '@babel/plugin-transform-unicode-regex@7.25.7': + resolution: {integrity: sha512-8JKfg/hiuA3qXnlLx8qtv5HWRbgyFx2hMMtpDDuU2rTckpKkGu4ycK5yYHwuEa16/quXfoxHBIApEsNyMWnt0g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-sets-regex@7.23.3': - resolution: {integrity: sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==} + '@babel/plugin-transform-unicode-sets-regex@7.25.7': + resolution: {integrity: sha512-YRW8o9vzImwmh4Q3Rffd09bH5/hvY0pxg+1H1i0f7APoUeg12G7+HhLj9ZFNIrYkgBXhIijPJ+IXypN0hLTIbw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/preset-env@7.23.8': - resolution: {integrity: sha512-lFlpmkApLkEP6woIKprO6DO60RImpatTQKtz4sUcDjVcK8M8mQ4sZsuxaTMNOZf0sqAq/ReYW1ZBHnOQwKpLWA==} + '@babel/preset-env@7.25.8': + resolution: {integrity: sha512-58T2yulDHMN8YMUxiLq5YmWUnlDCyY1FsHM+v12VMx+1/FlrUj5tY50iDCpofFQEM8fMYOaY9YRvym2jcjn1Dg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -896,35 +806,20 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 - '@babel/regjsgen@0.8.0': - resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} - - '@babel/runtime@7.23.8': - resolution: {integrity: sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==} - engines: {node: '>=6.9.0'} - - '@babel/template@7.22.15': - resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} - engines: {node: '>=6.9.0'} - - '@babel/template@7.23.9': - resolution: {integrity: sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.23.7': - resolution: {integrity: sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==} + '@babel/runtime@7.25.7': + resolution: {integrity: sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.23.9': - resolution: {integrity: sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==} + '@babel/template@7.25.7': + resolution: {integrity: sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==} engines: {node: '>=6.9.0'} - '@babel/types@7.23.6': - resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==} + '@babel/traverse@7.25.7': + resolution: {integrity: sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==} engines: {node: '>=6.9.0'} - '@babel/types@7.23.9': - resolution: {integrity: sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==} + '@babel/types@7.25.8': + resolution: {integrity: sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==} engines: {node: '>=6.9.0'} '@bundled-es-modules/cookie@2.0.0': @@ -933,52 +828,49 @@ packages: '@bundled-es-modules/statuses@1.0.1': resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} - '@csstools/css-parser-algorithms@2.5.0': - resolution: {integrity: sha512-abypo6m9re3clXA00eu5syw+oaPHbJTPapu9C4pzNsJ4hdZDzushT50Zhu+iIYXgEe1CxnRMn7ngsbV+MLrlpQ==} + '@bundled-es-modules/tough-cookie@0.1.6': + resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==} + + '@csstools/css-parser-algorithms@2.7.1': + resolution: {integrity: sha512-2SJS42gxmACHgikc1WGesXLIT8d/q2l0UFM7TaEeIzdFCE/FPMtTiizcPGGJtlPo2xuQzY09OhrLTzRxqJqwGw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: - '@csstools/css-tokenizer': ^2.2.3 + '@csstools/css-tokenizer': ^2.4.1 - '@csstools/css-tokenizer@2.2.3': - resolution: {integrity: sha512-pp//EvZ9dUmGuGtG1p+n17gTHEOqu9jO+FiCUjNN3BDmyhdA2Jq9QsVeR7K8/2QCK17HSsioPlTW9ZkzoWb3Lg==} + '@csstools/css-tokenizer@2.4.1': + resolution: {integrity: sha512-eQ9DIktFJBhGjioABJRtUucoWR2mwllurfnM8LuNGAqX3ViZXaUchqk+1s7jjtkFiT9ySdACsFEA3etErkALUg==} engines: {node: ^14 || ^16 || >=18} - '@csstools/media-query-list-parser@2.1.7': - resolution: {integrity: sha512-lHPKJDkPUECsyAvD60joYfDmp8UERYxHGkFfyLJFTVK/ERJe0sVlIFLXU5XFxdjNDTerp5L4KeaKG+Z5S94qxQ==} + '@csstools/media-query-list-parser@2.1.13': + resolution: {integrity: sha512-XaHr+16KRU9Gf8XLi3q8kDlI18d5vzKSKCY510Vrtc9iNR0NJzbY9hhTmwhzYZj/ZwGL4VmB3TA9hJW0Um2qFA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: - '@csstools/css-parser-algorithms': ^2.5.0 - '@csstools/css-tokenizer': ^2.2.3 + '@csstools/css-parser-algorithms': ^2.7.1 + '@csstools/css-tokenizer': ^2.4.1 - '@csstools/selector-specificity@3.0.1': - resolution: {integrity: sha512-NPljRHkq4a14YzZ3YD406uaxh7s0g6eAq3L9aLOWywoqe8PkYamAvtsh7KNX6c++ihDrJ0RiU+/z7rGnhlZ5ww==} + '@csstools/selector-specificity@3.1.1': + resolution: {integrity: sha512-a7cxGcJ2wIlMFLlh8z2ONm+715QkPHiyJcxwQlKOz/03GPw1COpfhcmC9wm4xlZfp//jWHNNMwzjtqHXVWU9KA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss-selector-parser: ^6.0.13 - '@emotion/babel-plugin@11.11.0': - resolution: {integrity: sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==} + '@emotion/babel-plugin@11.12.0': + resolution: {integrity: sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==} - '@emotion/cache@11.11.0': - resolution: {integrity: sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==} + '@emotion/cache@11.13.1': + resolution: {integrity: sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==} - '@emotion/hash@0.9.1': - resolution: {integrity: sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==} + '@emotion/hash@0.9.2': + resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} - '@emotion/is-prop-valid@0.8.8': - resolution: {integrity: sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==} + '@emotion/is-prop-valid@1.3.1': + resolution: {integrity: sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==} - '@emotion/is-prop-valid@1.2.1': - resolution: {integrity: sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==} + '@emotion/memoize@0.9.0': + resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} - '@emotion/memoize@0.7.4': - resolution: {integrity: sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==} - - '@emotion/memoize@0.8.1': - resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} - - '@emotion/react@11.11.3': - resolution: {integrity: sha512-Cnn0kuq4DoONOMcnoVsTOR8E+AdnKFf//6kUWc4LCdnxj31pZWn7rIULd6Y7/Js1PiPHzn7SKCM9vB/jBni8eA==} + '@emotion/react@11.13.3': + resolution: {integrity: sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==} peerDependencies: '@types/react': '*' react: '>=16.8.0' @@ -986,14 +878,14 @@ packages: '@types/react': optional: true - '@emotion/serialize@1.1.3': - resolution: {integrity: sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==} + '@emotion/serialize@1.3.2': + resolution: {integrity: sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==} - '@emotion/sheet@1.2.2': - resolution: {integrity: sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==} + '@emotion/sheet@1.4.0': + resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==} - '@emotion/styled@11.11.0': - resolution: {integrity: sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==} + '@emotion/styled@11.13.0': + resolution: {integrity: sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==} peerDependencies: '@emotion/react': ^11.0.0-rc.0 '@types/react': '*' @@ -1002,196 +894,340 @@ packages: '@types/react': optional: true - '@emotion/unitless@0.8.1': - resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==} + '@emotion/unitless@0.10.0': + resolution: {integrity: sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==} - '@emotion/use-insertion-effect-with-fallbacks@1.0.1': - resolution: {integrity: sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==} + '@emotion/use-insertion-effect-with-fallbacks@1.1.0': + resolution: {integrity: sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==} peerDependencies: react: '>=16.8.0' - '@emotion/utils@1.2.1': - resolution: {integrity: sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==} + '@emotion/utils@1.4.1': + resolution: {integrity: sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA==} - '@emotion/weak-memoize@0.3.1': - resolution: {integrity: sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==} + '@emotion/weak-memoize@0.4.0': + resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} - '@esbuild/aix-ppc64@0.19.12': - resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.19.12': - resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} + '@esbuild/aix-ppc64@0.24.0': + resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} engines: {node: '>=12'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.19.12': - resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} + '@esbuild/android-arm64@0.24.0': + resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} engines: {node: '>=12'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.19.12': - resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} + '@esbuild/android-arm@0.24.0': + resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} engines: {node: '>=12'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.19.12': - resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} + '@esbuild/android-x64@0.24.0': + resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.19.12': - resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} + '@esbuild/darwin-arm64@0.24.0': + resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} engines: {node: '>=12'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.19.12': - resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} + '@esbuild/darwin-x64@0.24.0': + resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.19.12': - resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} + '@esbuild/freebsd-arm64@0.24.0': + resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.19.12': - resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} + '@esbuild/freebsd-x64@0.24.0': + resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} engines: {node: '>=12'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.19.12': - resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} + '@esbuild/linux-arm64@0.24.0': + resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} engines: {node: '>=12'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.19.12': - resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} + '@esbuild/linux-arm@0.24.0': + resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} engines: {node: '>=12'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.19.12': - resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} + '@esbuild/linux-ia32@0.24.0': + resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} engines: {node: '>=12'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.19.12': - resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} + '@esbuild/linux-loong64@0.24.0': + resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.19.12': - resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} + '@esbuild/linux-mips64el@0.24.0': + resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.19.12': - resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} + '@esbuild/linux-ppc64@0.24.0': + resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.19.12': - resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} + '@esbuild/linux-riscv64@0.24.0': + resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} engines: {node: '>=12'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.19.12': - resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} + '@esbuild/linux-s390x@0.24.0': + resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} engines: {node: '>=12'} cpu: [x64] os: [linux] - '@esbuild/netbsd-x64@0.19.12': - resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} + '@esbuild/linux-x64@0.24.0': + resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-x64@0.19.12': - resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} + '@esbuild/netbsd-x64@0.24.0': + resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.24.0': + resolution: {integrity: sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] - '@esbuild/sunos-x64@0.19.12': - resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} + '@esbuild/openbsd-x64@0.24.0': + resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} engines: {node: '>=12'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.19.12': - resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} + '@esbuild/sunos-x64@0.24.0': + resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} engines: {node: '>=12'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.19.12': - resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} + '@esbuild/win32-arm64@0.24.0': + resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} engines: {node: '>=12'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.19.12': - resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} + '@esbuild/win32-ia32@0.24.0': + resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} engines: {node: '>=12'} cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.24.0': + resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.4.0': resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.10.0': - resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + '@eslint-community/regexpp@4.11.1': + resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} '@eslint/eslintrc@2.1.4': resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@eslint/js@8.56.0': - resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==} + '@eslint/js@8.57.1': + resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@floating-ui/core@1.6.0': - resolution: {integrity: sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==} + '@floating-ui/core@1.6.8': + resolution: {integrity: sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==} - '@floating-ui/dom@1.6.0': - resolution: {integrity: sha512-SZ0BEXzsaaS6THZfZJUcAobbZTD+MvfGM42bxgeg0Tnkp4/an/avqwAXiVLsFtIBZtfsx3Ymvwx0+KnnhdA/9g==} + '@floating-ui/dom@1.6.11': + resolution: {integrity: sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==} - '@floating-ui/react-dom@2.0.7': - resolution: {integrity: sha512-B5GJxKUyPcGsvE1vua+Abvw0t6zVMyTbtG+Jk7BoI4hfc5Ahv50dstRIAn0nS0274kR9gnKwxIXyGA8EzBZJrA==} + '@floating-ui/react-dom@2.1.2': + resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' - '@floating-ui/react@0.26.7': - resolution: {integrity: sha512-0uMI9IBJBPPt8N+8uRg4gazJvQReWTu/fVUHHLfAOuy1WB6f242jtjWm52hLJG8nzuZVuU+2crW4lJbJQoqeIA==} + '@floating-ui/react@0.26.25': + resolution: {integrity: sha512-hZOmgN0NTOzOuZxI1oIrDu3Gcl8WViIkvPMpB4xdd4QD6xAMtwgwr3VPoiyH/bLtRcS1cDnhxLSD1NsMJmwh/A==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' - '@floating-ui/utils@0.2.1': - resolution: {integrity: sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==} + '@floating-ui/utils@0.2.8': + resolution: {integrity: sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==} '@github/webauthn-json@2.1.1': resolution: {integrity: sha512-XrftRn4z75SnaJOmZQbt7Mk+IIjqVHw+glDGOxuHwXkZBZh/MBoRS7MHjSZMDaLhT4RjN2VqiEU7EOYleuJWSQ==} @@ -1203,13 +1239,13 @@ packages: react: ^16.8.0 || ^17 || ^18 react-dom: ^16.8.0 || ^17 || ^18 - '@hookform/resolvers@3.3.4': - resolution: {integrity: sha512-o5cgpGOuJYrd+iMKvkttOclgwRW86EsWJZZRC23prf0uU2i48Htq4PuT73AVb9ionFyZrwYEITuOFGF+BydEtQ==} + '@hookform/resolvers@3.9.0': + resolution: {integrity: sha512-bU0Gr4EepJ/EQsH/IwEzYLsT/PEj5C0ynLQ4m+GSHS+xKH4TfSelhluTgOaoc4kA5s7eCsQbM4wvZLzELmWzUg==} peerDependencies: react-hook-form: ^7.0.0 - '@humanwhocodes/config-array@0.11.14': - resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + '@humanwhocodes/config-array@0.13.0': + resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} engines: {node: '>=10.10.0'} deprecated: Use @eslint/config-array instead @@ -1217,38 +1253,50 @@ packages: resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - '@humanwhocodes/object-schema@2.0.2': - resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} deprecated: Use @eslint/object-schema instead '@hutson/parse-repository-url@3.0.2': resolution: {integrity: sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==} engines: {node: '>=6.9.0'} - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} + '@inquirer/confirm@4.0.1': + resolution: {integrity: sha512-46yL28o2NJ9doViqOy0VDcoTzng7rAb6yPQKU7VDLqkmbCaH4JqK4yk4XqlzNWy9PVC5pG1ZUXPBQv+VqnYs2w==} + engines: {node: '>=18'} - '@jridgewell/gen-mapping@0.3.3': - resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + '@inquirer/core@9.2.1': + resolution: {integrity: sha512-F2VBt7W/mwqEU4bL0RnHNZmC/OxzNx9cOYxHqnXX3MP6ruYvZUZAW9imgN9+h/uBT/oP8Gh888J2OZSbjSeWcg==} + engines: {node: '>=18'} + + '@inquirer/figures@1.0.7': + resolution: {integrity: sha512-m+Trk77mp54Zma6xLkLuY+mvanPxlE4A7yNKs2HBiyZ4UkVs28Mv5c/pgWrHeInx+USHeX/WEPzjrWrcJiQgjw==} + engines: {node: '>=18'} + + '@inquirer/type@2.0.0': + resolution: {integrity: sha512-XvJRx+2KR3YXyYtPUUy+qd9i7p+GO9Ko6VIIpWlBrpWwXDv8WLFeHTxz35CfQFUiBMLXlGHhGzys7lqit9gWag==} + engines: {node: '>=18'} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} - '@jridgewell/resolve-uri@3.1.1': - resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/set-array@1.1.2': - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} engines: {node: '>=6.0.0'} - '@jridgewell/source-map@0.3.5': - resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} + '@jridgewell/source-map@0.3.6': + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} - '@jridgewell/sourcemap-codec@1.4.15': - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - '@jridgewell/trace-mapping@0.3.22': - resolution: {integrity: sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==} + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} '@ladle/react-context@1.0.1': resolution: {integrity: sha512-xVQ8siyOEQG6e4Knibes1uA3PTyXnqiMmfSmd5pIbkzeDty8NCBtYHhTXSlfmcDNEsw/G8OzNWo4VbyQAVDl2A==} @@ -1256,19 +1304,19 @@ packages: react: '>=16.14.0' react-dom: '>=16.14.0' - '@ladle/react@4.0.2': - resolution: {integrity: sha512-SnYniR/U7kJX1Zh199jhjxqiFa5e5eA8chuX6uYEZYAUtCCY/hQqGr7/7Grr0j6Q4FYu9iQyyV2K1NJKDdUZIw==} - engines: {node: '>=18.0.0'} + '@ladle/react@4.1.2': + resolution: {integrity: sha512-6nMIPCsnkGCjIRz5kpRojJyieqcFPsq34QeqJp5mFpT1xFeX7sKwdCpQJ92d5ORsejmxTyp9gkQA+AXG3i3AGw==} + engines: {node: '>=20.0.0'} hasBin: true peerDependencies: react: '>=18.0.0' react-dom: '>=18.0.0' - '@mdx-js/mdx@3.0.0': - resolution: {integrity: sha512-Icm0TBKBLYqroYbNW3BPnzMGn+7mwpQOK310aZ7+fkCtiU3aqv2cdcX+nd0Ydo3wI5Rx8bX2Z2QmGb/XcAClCw==} + '@mdx-js/mdx@3.1.0': + resolution: {integrity: sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==} - '@mdx-js/react@3.0.0': - resolution: {integrity: sha512-nDctevR9KyYFyV+m+/+S4cpzCWHqj+iHDHq3QrsWezcC+B17uZdIWgCguESUkwFhM3n/56KxWVE3V6EokrmONQ==} + '@mdx-js/react@3.1.0': + resolution: {integrity: sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==} peerDependencies: '@types/react': '>=16' react: '>=16' @@ -1277,12 +1325,8 @@ packages: resolution: {integrity: sha512-sFpN+TX13E9fdBDh9lvQeZdJn4qYoRb/6QF2oZZK/Pn559IhCFacPMU1rMuqyXoFQF3JSJfii2l98B87QDPeCQ==} engines: {node: '>=14.0.0'} - '@mswjs/cookies@1.1.0': - resolution: {integrity: sha512-0ZcCVQxifZmhwNBoQIrystCb+2sWBY2Zw8lpfJBPCHGCA/HWqehITeCRVIv4VMy8MPlaHo2w2pTHFV2pFfqKPw==} - engines: {node: '>=18'} - - '@mswjs/interceptors@0.25.14': - resolution: {integrity: sha512-2dnIxl+obqIqjoPXTFldhe6pcdOrqiz+GcLaQQ6hmL02OldAF7nIC+rUgTWm+iF6lvmyCVhFFqbgbapNhR8eag==} + '@mswjs/interceptors@0.36.5': + resolution: {integrity: sha512-aQ8WF5zQwOdcxLsxSEk9Jd01GgGb80xxqCaiDDlewhtwqpSm8MOvUHslwPydVirasdW09++NxDNNftm1vLY8yA==} engines: {node: '>=18'} '@noble/curves@1.2.0': @@ -1313,9 +1357,81 @@ packages: '@open-draft/until@2.1.0': resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} + '@parcel/watcher-android-arm64@2.4.1': + resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.4.1': + resolution: {integrity: sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.4.1': + resolution: {integrity: sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.4.1': + resolution: {integrity: sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.4.1': + resolution: {integrity: sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm64-glibc@2.4.1': + resolution: {integrity: sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-arm64-musl@2.4.1': + resolution: {integrity: sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-x64-glibc@2.4.1': + resolution: {integrity: sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-linux-x64-musl@2.4.1': + resolution: {integrity: sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-win32-arm64@2.4.1': + resolution: {integrity: sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.4.1': + resolution: {integrity: sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.4.1': + resolution: {integrity: sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.4.1': + resolution: {integrity: sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==} + engines: {node: '>= 10.0.0'} '@pkgr/core@0.1.1': resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} @@ -1330,51 +1446,63 @@ packages: react: '>=16.8.0' rxjs: '>=7' - '@remix-run/router@1.14.2': - resolution: {integrity: sha512-ACXpdMM9hmKZww21yEqWwiLws/UPLhNKvimN8RrYSqPSvB3ov7sLvAcfvaxePeLvccTQKGdkDIhLYApZVDFuKg==} + '@remix-run/router@1.20.0': + resolution: {integrity: sha512-mUnk8rPJBI9loFDZ+YzPGdeniYK+FTmRD1TMCz7ev2SNIozyKKpnGgsxO34u6Z4z/t0ITuu7voi/AshfsGsgFg==} engines: {node: '>=14.0.0'} '@rollup/pluginutils@4.2.1': resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} + '@rollup/pluginutils@5.1.2': + resolution: {integrity: sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: npm:@rollup/wasm-node + peerDependenciesMeta: + rollup: + optional: true + '@rollup/wasm-node@4.24.0': resolution: {integrity: sha512-LL6oALR6fKG6GihtH0K0uWLAl19Q/QJst+oKJT1VWwFo4sPLA0/7JeZaSqrpFWq8OPloiKx/NDG4BWppFSX2vQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + '@rx-state/core@0.1.4': resolution: {integrity: sha512-Z+3hjU2xh1HisLxt+W5hlYX/eGSDaXXP+ns82gq/PLZpkXLu0uwcNUh9RLY3Clq4zT+hSsA3vcpIGt6+UAb8rQ==} peerDependencies: rxjs: '>=7' - '@sindresorhus/merge-streams@1.0.0': - resolution: {integrity: sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw==} + '@sindresorhus/merge-streams@2.3.0': + resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} engines: {node: '>=18'} - '@stablelib/base64@1.0.1': - resolution: {integrity: sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==} + '@stablelib/base64@2.0.0': + resolution: {integrity: sha512-ffSfySa1ZpZYzM5FQ2xILQ2jifQ+GlgbDJzRTCtaB0sqta88KYghB/tlSV2VS2iHRCvMdUvJlLOW1rmSkziWnw==} - '@stablelib/binary@1.0.1': - resolution: {integrity: sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==} + '@stablelib/binary@2.0.0': + resolution: {integrity: sha512-dHejKHMtq5OtNwDSMcFx+djhixVAnZ76Rqga3WOOKe6KV3NlnE7JBXlmdLIn04G4FxqhRSEx+zkoO4Izdw10ZA==} - '@stablelib/bytes@1.0.1': - resolution: {integrity: sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ==} + '@stablelib/bytes@2.0.0': + resolution: {integrity: sha512-oSfT6VTfk/XK5s/BUi1L8Obp1Uoh/RFJHWDAG9Yj5D/kiGTnR7sEnzJIRenbIFDbzkb+lXP3OSDp+ttgI51Nng==} - '@stablelib/int@1.0.1': - resolution: {integrity: sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==} + '@stablelib/int@2.0.0': + resolution: {integrity: sha512-EiSYDisTYKk1wuCqoh7wuBySmE0A1isq7TQbsijQ6XFi6nIAozchgAT7Zv2PCl2iY8BTe0URScC4PdYHOe3Yow==} - '@stablelib/keyagreement@1.0.1': - resolution: {integrity: sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg==} + '@stablelib/keyagreement@2.0.0': + resolution: {integrity: sha512-SryWYB3S8w9EyjSJ1OdJb375Foj1Ujxgd4S6mh7L+ESiPVD/24EQWMbFANyhtpaPmpsAmgIBGyXlR+LfHW5X0Q==} - '@stablelib/random@1.0.2': - resolution: {integrity: sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w==} + '@stablelib/random@2.0.0': + resolution: {integrity: sha512-qvOSbiPq2B3ajvn/IDftC1mzL/W89OGv59gdJ7klMjm327Yk/54NyGl4Jtrwcz35GjCPy/ScVnQXC8YQk8uAUQ==} - '@stablelib/wipe@1.0.1': - resolution: {integrity: sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==} + '@stablelib/wipe@2.0.0': + resolution: {integrity: sha512-VBMpCJx8py9j9F5DxV5dGmSSO+vkYDnXHXG4alkfpaD08UTfNTqsQoRlUh5obeqBNHiO+3Iv40GxKpM0gfd5xA==} - '@stablelib/x25519@1.0.3': - resolution: {integrity: sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw==} + '@stablelib/x25519@2.0.0': + resolution: {integrity: sha512-mnl4U+1dE73rgrnhL2jPuT2u6TVOJPCwWKnC+A18JkYZaRKXERKVXJzuhc+jSNEnWHdv3BDMut50v8bpIdZCCQ==} '@svgr/babel-plugin-add-jsx-attribute@8.0.0': resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} @@ -1461,83 +1589,83 @@ packages: peerDependencies: '@svgr/core': '*' - '@swc/core-darwin-arm64@1.3.106': - resolution: {integrity: sha512-XYcbViNyHnnm7RWOAO1YipMmthM7m2aXF32b0y+JMLYFBEyFpjVX9btLkzeL7wRx/5B3I35yJNhE+xyx0Q1Gkw==} + '@swc/core-darwin-arm64@1.7.39': + resolution: {integrity: sha512-o2nbEL6scMBMCTvY9OnbyVXtepLuNbdblV9oNJEFia5v5eGj9WMrnRQiylH3Wp/G2NYkW7V1/ZVW+kfvIeYe9A==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.3.106': - resolution: {integrity: sha512-YKDPhUdfuwhmOUS9+CaIwl/0Tp+f1b73BH2EIESuxSNsogZf18a8HQ8O0fQEwdiwmA5LEqw47cj+kfOWV/0+kw==} + '@swc/core-darwin-x64@1.7.39': + resolution: {integrity: sha512-qMlv3XPgtPi/Fe11VhiPDHSLiYYk2dFYl747oGsHZPq+6tIdDQjIhijXPcsUHIXYDyG7lNpODPL8cP/X1sc9MA==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.3.106': - resolution: {integrity: sha512-bHxxJXogvFfocLL5inZxxtx/x/WgKozigp80Vbx0viac1fPDJrqKBw2X4MzpMiuTRAGVQ03jJI6pDwbSBf+yDw==} + '@swc/core-linux-arm-gnueabihf@1.7.39': + resolution: {integrity: sha512-NP+JIkBs1ZKnpa3Lk2W1kBJMwHfNOxCUJXuTa2ckjFsuZ8OUu2gwdeLFkTHbR43dxGwH5UzSmuGocXeMowra/Q==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.3.106': - resolution: {integrity: sha512-c7jue++CHLgtpeaakEukoCLT9eNrImizbleE9Y7Is8CHqLq/7DG4s+7ma9DFKXIzW2MpTg9byIEQfpqSphVW6A==} + '@swc/core-linux-arm64-gnu@1.7.39': + resolution: {integrity: sha512-cPc+/HehyHyHcvAsk3ML/9wYcpWVIWax3YBaA+ScecJpSE04l/oBHPfdqKUPslqZ+Gcw0OWnIBGJT/fBZW2ayw==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-arm64-musl@1.3.106': - resolution: {integrity: sha512-51EaC3Q8qAhLtWVnAVqoYX/gk3tK31cCBzUpwCcmhianhEBM2/WtKRAS4MqPhE8VVZuN3WjO2c2JaF2mX0yuoA==} + '@swc/core-linux-arm64-musl@1.7.39': + resolution: {integrity: sha512-8RxgBC6ubFem66bk9XJ0vclu3exJ6eD7x7CwDhp5AD/tulZslTYXM7oNPjEtje3xxabXuj/bEUMNvHZhQRFdqA==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-x64-gnu@1.3.106': - resolution: {integrity: sha512-tOUi8BB6jAeCXgx7ESLNnX7nrbMVKQ/XajK77v7Ad4SXf9HYArnimBJpXUUyVFJTXLSv4e6c7s6XHHqXb5Lwcg==} + '@swc/core-linux-x64-gnu@1.7.39': + resolution: {integrity: sha512-3gtCPEJuXLQEolo9xsXtuPDocmXQx12vewEyFFSMSjOfakuPOBmOQMa0sVL8Wwius8C1eZVeD1fgk0omMqeC+Q==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-linux-x64-musl@1.3.106': - resolution: {integrity: sha512-binLw4Lbd83NPy4/m/teH2nbaifxveSD+sKDvpxywRbvYW2I0w/iCBpUBcbnl16TQF4TPOGpq5YwG9lVxPVw5g==} + '@swc/core-linux-x64-musl@1.7.39': + resolution: {integrity: sha512-mg39pW5x/eqqpZDdtjZJxrUvQNSvJF4O8wCl37fbuFUqOtXs4TxsjZ0aolt876HXxxhsQl7rS+N4KioEMSgTZw==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-win32-arm64-msvc@1.3.106': - resolution: {integrity: sha512-n4ttBWr8tM7DPzwcEOIBTyTMHZTzCmbic/HTtxEsPyMAf/Daen+yrTKzjPP6k2usfSrjkxA780RSJJxI1N8r2w==} + '@swc/core-win32-arm64-msvc@1.7.39': + resolution: {integrity: sha512-NZwuS0mNJowH3e9bMttr7B1fB8bW5svW/yyySigv9qmV5VcQRNz1kMlCvrCLYRsa93JnARuiaBI6FazSeG8mpA==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.3.106': - resolution: {integrity: sha512-GhDNIwxE5FhkujESI6h/4ysT3wxwmrzTUlZYaR8rRui6a6SdX9feIPUHPEE5o5hpyp+xqlmvRxKkRxOnwsq8iA==} + '@swc/core-win32-ia32-msvc@1.7.39': + resolution: {integrity: sha512-qFmvv5UExbJPXhhvCVDBnjK5Duqxr048dlVB6ZCgGzbRxuarOlawCzzLK4N172230pzlAWGLgn9CWl3+N6zfHA==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.3.106': - resolution: {integrity: sha512-2M6yWChuMS1+/MPo3Dor0SOMkvmiugonWlzsZBAu/oZboH2xKrHSRv7brsBujb2Oe47r+NsbV+vq9tnnP9Vl1Q==} + '@swc/core-win32-x64-msvc@1.7.39': + resolution: {integrity: sha512-o+5IMqgOtj9+BEOp16atTfBgCogVak9svhBpwsbcJQp67bQbxGYhAPPDW/hZ2rpSSF7UdzbY9wudoX9G4trcuQ==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.3.106': - resolution: {integrity: sha512-++QPSPkFq2qELYVScxNHJC42hKQChjiTWS2P0QQ5JWT4NHb9lmNSfrc1ylFIyImwRnxsW2MTBALLYLf95EFAsg==} + '@swc/core@1.7.39': + resolution: {integrity: sha512-jns6VFeOT49uoTKLWIEfiQqJAlyqldNAt80kAr8f7a5YjX0zgnG3RBiLMpksx4Ka4SlK4O6TJ/lumIM3Trp82g==} engines: {node: '>=10'} peerDependencies: - '@swc/helpers': ^0.5.0 + '@swc/helpers': '*' peerDependenciesMeta: '@swc/helpers': optional: true - '@swc/counter@0.1.2': - resolution: {integrity: sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw==} + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - '@swc/types@0.1.5': - resolution: {integrity: sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==} + '@swc/types@0.1.13': + resolution: {integrity: sha512-JL7eeCk6zWCbiYQg2xQSdLXQJl8Qoc9rXmG2cEKvHe3CKwMHwHGpfOb8frzNLmbycOo6I51qxnLnn9ESf4I20Q==} - '@tanstack/match-sorter-utils@8.11.7': - resolution: {integrity: sha512-4PUKgaaFpiB7MK406N5VAiLu2VUhDumojGWhEC8kNQ767RGU2vsJDI7Xp4D8lMBzijqswRWz3U8ioa2zUKnFeQ==} + '@tanstack/match-sorter-utils@8.19.4': + resolution: {integrity: sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==} engines: {node: '>=12'} '@tanstack/query-core@4.36.1': @@ -1572,8 +1700,8 @@ packages: resolution: {integrity: sha512-Aaku1DMatF8GNbAZj2ahGN9F3l6KLe2n1jzgAUO8IT07D1spoZ9jCeazOQ7gvCIIEZjceuL9klx08MnsFJdCqg==} engines: {node: '>=12'} - '@tauri-apps/api@1.5.3': - resolution: {integrity: sha512-zxnDjHHKjOsrIzZm6nO5Xapb/BxqUq1tc7cGkFXsFkGTsSWgCPH1D8mm0XS9weJY2OaR73I3k3S+b7eSzJDfqA==} + '@tauri-apps/api@1.6.0': + resolution: {integrity: sha512-rqI++FWClU5I2UBp4HXFvl+sBWkdigBkxnpJDQUWttNyG7IZP4FwQGhTNL5EOw0vI8i6eSAJ5frLqO7n7jbJdg==} engines: {node: '>= 14.6.0', npm: '>= 6.6.0', yarn: '>= 1.19.1'} '@trysound/sax@0.2.0': @@ -1592,8 +1720,8 @@ packages: '@types/babel__template@7.4.4': resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - '@types/babel__traverse@7.20.5': - resolution: {integrity: sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==} + '@types/babel__traverse@7.20.6': + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} '@types/byte-size@8.1.2': resolution: {integrity: sha512-jGyVzYu6avI8yuqQCNTZd65tzI8HZrLjKX9sdMqZrGWVlNChu0rf6p368oVEDCYJe5BMx2Ov04tD1wqtgTwGSA==} @@ -1613,8 +1741,8 @@ packages: '@types/d3-interpolate@3.0.4': resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} - '@types/d3-path@3.0.2': - resolution: {integrity: sha512-WAIEVlOCdd/NKRYTsqCpOMHQHemKBEINf8YXMYOtXH0GA7SY0dqMB78P3Uhgfy+4X+/Mlw2wDtlETkN6kQUCMA==} + '@types/d3-path@3.1.0': + resolution: {integrity: sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==} '@types/d3-scale@4.0.8': resolution: {integrity: sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==} @@ -1631,14 +1759,11 @@ packages: '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} - '@types/eslint@8.56.2': - resolution: {integrity: sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw==} + '@types/eslint@8.56.12': + resolution: {integrity: sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==} - '@types/estree-jsx@1.0.3': - resolution: {integrity: sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w==} - - '@types/estree@1.0.5': - resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} @@ -1646,8 +1771,8 @@ packages: '@types/file-saver@2.0.7': resolution: {integrity: sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==} - '@types/hast@3.0.3': - resolution: {integrity: sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==} + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} '@types/history@4.7.11': resolution: {integrity: sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==} @@ -1661,14 +1786,14 @@ packages: '@types/lodash-es@4.17.12': resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} - '@types/lodash@4.14.202': - resolution: {integrity: sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==} + '@types/lodash@4.17.12': + resolution: {integrity: sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ==} - '@types/mdast@4.0.3': - resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==} + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} - '@types/mdx@2.0.10': - resolution: {integrity: sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg==} + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} '@types/minimist@1.2.5': resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} @@ -1676,11 +1801,17 @@ packages: '@types/ms@0.7.34': resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} - '@types/node@18.15.13': - resolution: {integrity: sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==} + '@types/mute-stream@0.0.4': + resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==} + + '@types/node@20.16.14': + resolution: {integrity: sha512-vtgGzjxLF7QT88qRHtXMzCWpAAmwonE7fwgVjFtXosUva2oSpnIEc3gNO9P7uIfOxKnii2f79/xtOnfreYtDaA==} - '@types/node@20.11.7': - resolution: {integrity: sha512-GPmeN1C3XAyV5uybAf4cMLWT9fDWcmQhZVtMFu7OR32WjrqGG+Wnk2V1d0bmtUyE/Zy1QJ9BxyiTih9z8Oks8A==} + '@types/node@22.7.5': + resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} + + '@types/node@22.7.8': + resolution: {integrity: sha512-a922jJy31vqR5sk+kAdIENJjHblqcZ4RmERviFsER4WJcEONqxKcjNOlk0q7OUfrF5sddT+vng070cdfMlrPLg==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -1688,14 +1819,14 @@ packages: '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} - '@types/prismjs@1.26.3': - resolution: {integrity: sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==} + '@types/prismjs@1.26.4': + resolution: {integrity: sha512-rlAnzkW2sZOjbqZ743IHUhFcvzaGbqijwOu8QZnZCjfQzBqFE3s4lOTJEsxikImav9uzz/42I+O7YUs1mWgMlg==} - '@types/prop-types@15.7.11': - resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} + '@types/prop-types@15.7.13': + resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==} - '@types/react-dom@18.2.18': - resolution: {integrity: sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==} + '@types/react-dom@18.3.1': + resolution: {integrity: sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==} '@types/react-router-dom@5.3.3': resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==} @@ -1709,26 +1840,29 @@ packages: '@types/react-window@1.8.8': resolution: {integrity: sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==} - '@types/react@18.2.48': - resolution: {integrity: sha512-qboRCl6Ie70DQQG9hhNREz81jqC1cs9EVNcjQ1AU+jH6NFfSAhVVbrrY/+nSF+Bsk4AOwm9Qa61InvMCyV+H3w==} + '@types/react@18.3.11': + resolution: {integrity: sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ==} + + '@types/semver@7.5.8': + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} - '@types/scheduler@0.16.8': - resolution: {integrity: sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==} + '@types/statuses@2.0.5': + resolution: {integrity: sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==} - '@types/semver@7.5.6': - resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==} + '@types/tough-cookie@4.0.5': + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} - '@types/statuses@2.0.4': - resolution: {integrity: sha512-eqNDvZsCNY49OAXB0Firg/Sc2BgoWsntsLUdybGFOhAfCD6QJ2n9HXUIHGqt5qjrxmMv4wS8WLAw43ZkKcJ8Pw==} + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} - '@types/unist@2.0.10': - resolution: {integrity: sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==} + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - '@types/unist@3.0.2': - resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} + '@types/wrap-ansi@3.0.0': + resolution: {integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==} - '@typescript-eslint/eslint-plugin@6.19.1': - resolution: {integrity: sha512-roQScUGFruWod9CEyoV5KlCYrubC/fvG8/1zXuT0WTcxX87GnMMmnksMwSg99lo1xiKrBzw2icsJPMAw1OtKxg==} + '@typescript-eslint/eslint-plugin@6.21.0': + resolution: {integrity: sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha @@ -1738,8 +1872,8 @@ packages: typescript: optional: true - '@typescript-eslint/parser@6.19.1': - resolution: {integrity: sha512-WEfX22ziAh6pRE9jnbkkLGp/4RhTpffr2ZK5bJ18M8mIfA8A+k97U9ZyaXCEJRlmMHh7R9MJZWXp/r73DzINVQ==} + '@typescript-eslint/parser@6.21.0': + resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -1748,12 +1882,12 @@ packages: typescript: optional: true - '@typescript-eslint/scope-manager@6.19.1': - resolution: {integrity: sha512-4CdXYjKf6/6aKNMSly/BP4iCSOpvMmqtDzRtqFyyAae3z5kkqEjKndR5vDHL8rSuMIIWP8u4Mw4VxLyxZW6D5w==} + '@typescript-eslint/scope-manager@6.21.0': + resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} engines: {node: ^16.0.0 || >=18.0.0} - '@typescript-eslint/type-utils@6.19.1': - resolution: {integrity: sha512-0vdyld3ecfxJuddDjACUvlAeYNrHP/pDeQk2pWBR2ESeEzQhg52DF53AbI9QCBkYE23lgkhLCZNkHn2hEXXYIg==} + '@typescript-eslint/type-utils@6.21.0': + resolution: {integrity: sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -1762,12 +1896,12 @@ packages: typescript: optional: true - '@typescript-eslint/types@6.19.1': - resolution: {integrity: sha512-6+bk6FEtBhvfYvpHsDgAL3uo4BfvnTnoge5LrrCj2eJN8g3IJdLTD4B/jK3Q6vo4Ql/Hoip9I8aB6fF+6RfDqg==} + '@typescript-eslint/types@6.21.0': + resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} engines: {node: ^16.0.0 || >=18.0.0} - '@typescript-eslint/typescript-estree@6.19.1': - resolution: {integrity: sha512-aFdAxuhzBFRWhy+H20nYu19+Km+gFfwNO4TEqyszkMcgBDYQjmPJ61erHxuT2ESJXhlhrO7I5EFIlZ+qGR8oVA==} + '@typescript-eslint/typescript-estree@6.21.0': + resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -1775,33 +1909,33 @@ packages: typescript: optional: true - '@typescript-eslint/utils@6.19.1': - resolution: {integrity: sha512-JvjfEZuP5WoMqwh9SPAPDSHSg9FBHHGhjPugSRxu5jMfjvBpq5/sGTD+9M9aQ5sh6iJ8AY/Kk/oUYVEMAPwi7w==} + '@typescript-eslint/utils@6.21.0': + resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 - '@typescript-eslint/visitor-keys@6.19.1': - resolution: {integrity: sha512-gkdtIO+xSO/SmI0W68DBg4u1KElmIUo3vXzgHyGPs6cxgB0sa3TlptRAAE0hUY1hM6FcDKEv7aIwiTGm76cXfQ==} + '@typescript-eslint/visitor-keys@6.21.0': + resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} engines: {node: ^16.0.0 || >=18.0.0} '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - '@vitejs/plugin-legacy@5.3.0': - resolution: {integrity: sha512-BhW+WcJmEgW5G/1UQRiVQ7wz9/ZPnxqzExT9n0zAk4RlqQQ/26udIeXzdU8+03AGnaF61wmZlCspexgEnxFWMA==} + '@vitejs/plugin-legacy@5.4.2': + resolution: {integrity: sha512-hlyyQL+wEIyOWdwsUKX+0g3kBU4AbHmVzHarLvVKiGGGqLIYjttMvvjk6zGY8RD9dab6QuFNhDoxg0YFhQ26xA==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: terser: ^5.4.0 vite: ^5.0.0 - '@vitejs/plugin-react-swc@3.5.0': - resolution: {integrity: sha512-1PrOvAaDpqlCV+Up8RkAh9qaiUjoDUcjtttyhXDKw53XA6Ve16SOp6cCOpRs8Dj8DqUQs6eTW5YkLcLJjrXAig==} + '@vitejs/plugin-react-swc@3.7.1': + resolution: {integrity: sha512-vgWOY0i1EROUK0Ctg1hwhtC3SdcDjZcdit4Ups4aPkDcB1jYhmo+RMYWY87cmXMhvtD5uf8lV89j2w16vkdSVg==} peerDependencies: vite: ^4 || ^5 - '@vitejs/plugin-react@4.2.1': - resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==} + '@vitejs/plugin-react@4.3.3': + resolution: {integrity: sha512-NooDe9GpHGqNns1i8XDERg0Vsg5SSYRhRxxyTGogUdkdNt47jal+fbuYi+Yfq6pzRCKXyoPcWisfxE6RIM3GKA==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: vite: ^4.2.0 || ^5.0.0 @@ -1819,8 +1953,8 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.11.3: - resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + acorn@8.13.0: + resolution: {integrity: sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==} engines: {node: '>=0.4.0'} hasBin: true @@ -1833,8 +1967,8 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - ajv@8.12.0: - resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} ansi-align@3.0.1: resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} @@ -1847,8 +1981,8 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} engines: {node: '>=12'} ansi-sequence-parser@1.1.1: @@ -1873,25 +2007,31 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - aria-query@5.3.0: - resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} - array-buffer-byte-length@1.0.0: - resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} + array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} array-ify@1.0.0: resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} - array-includes@3.1.7: - resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==} + array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} engines: {node: '>= 0.4'} array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} - array.prototype.findlastindex@1.2.3: - resolution: {integrity: sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==} + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.5: + resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} engines: {node: '>= 0.4'} array.prototype.flat@1.3.2: @@ -1902,11 +2042,12 @@ packages: resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} engines: {node: '>= 0.4'} - array.prototype.tosorted@1.1.2: - resolution: {integrity: sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg==} + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} - arraybuffer.prototype.slice@1.0.2: - resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} + arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} engines: {node: '>= 0.4'} arrify@1.0.1: @@ -1920,57 +2061,51 @@ packages: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} - astring@1.8.6: - resolution: {integrity: sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==} + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} hasBin: true - asynciterator.prototype@1.0.0: - resolution: {integrity: sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==} - asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - autoprefixer@10.4.17: - resolution: {integrity: sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==} + autoprefixer@10.4.20: + resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: postcss: ^8.1.0 - available-typed-arrays@1.0.5: - resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axe-core@4.7.0: - resolution: {integrity: sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==} + axe-core@4.10.1: + resolution: {integrity: sha512-qPC9o+kD8Tir0lzNGLeghbOrWMr3ZJpaRlCIb6Uobt/7N4FiEDvqUMnxzCHRHmg8vOg14kr5gVNyScRmbMaJ9g==} engines: {node: '>=4'} - axe-core@4.8.3: - resolution: {integrity: sha512-d5ZQHPSPkF9Tw+yfyDcRoUOc4g/8UloJJe5J8m4L5+c7AtDdjDLRxew/knnI4CxvtdxEUVgWz4x3OIQUIFiMfw==} - engines: {node: '>=4'} - - axios@1.6.7: - resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==} + axios@1.7.7: + resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} - axobject-query@3.2.1: - resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} babel-plugin-macros@3.1.0: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} engines: {node: '>=10', npm: '>=6'} - babel-plugin-polyfill-corejs2@0.4.8: - resolution: {integrity: sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg==} + babel-plugin-polyfill-corejs2@0.4.11: + resolution: {integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-corejs3@0.8.7: - resolution: {integrity: sha512-KyDvZYxAzkC0Aj2dAPyDzi2Ym15e5JKZSK+maI7NAwSqofvuFglbSsxE7wUOvTg9oFVnHMzVzBKcqEb4PJgtOA==} + babel-plugin-polyfill-corejs3@0.10.6: + resolution: {integrity: sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-regenerator@0.5.5: - resolution: {integrity: sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==} + babel-plugin-polyfill-regenerator@0.6.2: + resolution: {integrity: sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -1983,26 +2118,16 @@ packages: balanced-match@2.0.0: resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==} - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - bcp-47-match@2.0.3: resolution: {integrity: sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==} - big-integer@1.6.52: - resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} - engines: {node: '>=0.6'} - bignumber.js@9.1.2: resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} - binary-extensions@2.2.0: - resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -2010,10 +2135,6 @@ packages: resolution: {integrity: sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==} engines: {node: '>=14.16'} - bplist-parser@0.2.0: - resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==} - engines: {node: '>= 5.10.0'} - brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -2024,31 +2145,36 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.22.2: - resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==} + browserslist-to-esbuild@2.1.1: + resolution: {integrity: sha512-KN+mty6C3e9AN8Z5dI1xeN15ExcRNeISoC3g7V0Kax/MMF9MSoYA2G7lkTTcVUFntiEjkpI0HNgqJC1NjdyNUw==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + browserslist: '*' + + browserslist@4.24.2: + resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - - bundle-name@3.0.0: - resolution: {integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==} - engines: {node: '>=12'} + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} - byte-size@8.1.1: - resolution: {integrity: sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg==} + byte-size@9.0.0: + resolution: {integrity: sha512-xrJ8Hki7eQ6xew55mM6TG9zHI852OoAHcPfduWWtR6yxk2upTuIZy13VioRBDyHReHDdbeDPifUboeNkK/sXXA==} engines: {node: '>=12.17'} cache-content-type@1.0.1: resolution: {integrity: sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==} engines: {node: '>= 6.0.0'} - call-bind@1.0.5: - resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} @@ -2070,8 +2196,8 @@ packages: resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} engines: {node: '>=14.16'} - caniuse-lite@1.0.30001580: - resolution: {integrity: sha512-mtj5ur2FFPZcCEpXFy8ADXbDACuNFXg6mxVDqp7tqooX6l3zwm+d8EPoeOSIFRDvHs8qu7/SLFOGniULkcH2iA==} + caniuse-lite@1.0.30001669: + resolution: {integrity: sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==} ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -2100,13 +2226,14 @@ packages: character-reference-invalid@2.0.1: resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} - chardet@0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - - chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} + chokidar@4.0.1: + resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} + engines: {node: '>= 14.16.0'} + classnames@2.5.1: resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} @@ -2114,17 +2241,9 @@ packages: resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} engines: {node: '>=10'} - cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - - cli-spinners@2.9.2: - resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} - engines: {node: '>=6'} - - cli-width@3.0.0: - resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} - engines: {node: '>= 10'} + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} cliui@6.0.0: resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} @@ -2136,12 +2255,8 @@ packages: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} - clone@1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} - - clsx@2.1.0: - resolution: {integrity: sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==} + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} co@4.6.0: @@ -2174,9 +2289,9 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - commander@11.1.0: - resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} - engines: {node: '>=16'} + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -2199,9 +2314,9 @@ packages: resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} engines: {'0': node >= 6.0} - concurrently@8.2.2: - resolution: {integrity: sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==} - engines: {node: ^14.13.0 || >=16.0.0} + concurrently@9.0.1: + resolution: {integrity: sha512-wYKvCd/f54sTXJMSfV6Ln/B8UrfLBKOYa+lzc6CHay3Qek+LorVSBdMVfyewFhRbH0Rbabsk4D+3PL/VjQ5gzg==} + engines: {node: '>=18'} hasBin: true content-disposition@0.5.4: @@ -2300,11 +2415,11 @@ packages: resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} engines: {node: '>=12.13'} - core-js-compat@3.35.1: - resolution: {integrity: sha512-sftHa5qUJY3rs9Zht1WEnmkvXputCyDBczPnr7QDgL8n3qrF3CMXY4VPSYtOLLiOUJcah2WNXREd48iOl6mQIw==} + core-js-compat@3.38.1: + resolution: {integrity: sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==} - core-js@3.35.1: - resolution: {integrity: sha512-IgdsbxNyMskrTFxa9lWHyMwAJU5gXOPP+1yO+K59d50VLVAIDAbs7gIv705KzALModfK3ZrSZTPNpC0PQgIZuw==} + core-js@3.38.1: + resolution: {integrity: sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==} core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -2335,15 +2450,15 @@ packages: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} - css-functions-list@3.2.1: - resolution: {integrity: sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==} + css-functions-list@3.2.3: + resolution: {integrity: sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==} engines: {node: '>=12 || >=16'} css-select@5.1.0: resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} - css-selector-parser@3.0.4: - resolution: {integrity: sha512-pnmS1dbKsz6KA4EW4BznyPL2xxkNDRg62hcD0v8g6DEw2W7hxOln5M953jsp9hmw5Dg57S6o/A8GOn37mbAgcQ==} + css-selector-parser@3.0.5: + resolution: {integrity: sha512-3itoDFbKUNx1eKmVpYMFyqKX04Ww9osZ+dLgrk6GEv6KMVeXUhUnp4I5X+evw+u3ZxVU6RFXSSRxlTeMh8bA+g==} css-tree@2.2.1: resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} @@ -2353,6 +2468,10 @@ packages: resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + css-tree@3.0.0: + resolution: {integrity: sha512-o88DVQ6GzsABn1+6+zo2ct801dBO5OASVyxbbvA2W20ue2puSh/VOuqUj90eUeMSX/xqGqBmOKiRQN7tJOuBXw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + css-what@6.1.0: resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} engines: {node: '>= 6'} @@ -2424,15 +2543,23 @@ packages: resolution: {integrity: sha512-hpA5C/YrPjucXypHPPc0oJ1l9Hf6wWbiOL7Ik42cxnsUOhWiCB/fylKbKqqJalW9FgkNQCw16YO8uW9Hs0Iy1A==} engines: {node: '>=4'} - date-fns@2.30.0: - resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} - engines: {node: '>=0.11'} + data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} dateformat@3.0.3: resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==} - dayjs@1.11.10: - resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} @@ -2442,8 +2569,8 @@ packages: supports-color: optional: true - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -2479,19 +2606,16 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} - default-browser-id@3.0.0: - resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==} - engines: {node: '>=12'} - - default-browser@4.0.0: - resolution: {integrity: sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==} - engines: {node: '>=14.16'} + default-browser-id@5.0.0: + resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} + engines: {node: '>=18'} - defaults@1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + default-browser@5.2.1: + resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} + engines: {node: '>=18'} - define-data-property@1.1.1: - resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} define-lazy-prop@3.0.0: @@ -2532,6 +2656,11 @@ packages: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} + detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -2558,8 +2687,8 @@ packages: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} - dom-helpers@3.4.0: - resolution: {integrity: sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==} + dom-helpers@5.2.1: + resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} @@ -2591,8 +2720,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.4.645: - resolution: {integrity: sha512-EeS1oQDCmnYsRDRy2zTeC336a/4LZ6WKqvSaM1jLocEk5ZuyszkQtCpsqvuvaIXGOUjwtvF6LTcS8WueibXvSw==} + electron-to-chromium@1.5.42: + resolution: {integrity: sha512-gIfKavKDw1mhvic9nbzA5lZw8QSHpdMwLwXc0cWidQz9B15pDoDdDH4boIatuFfeoCatb3a/NGL6CYRVFxGZ9g==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -2600,9 +2729,6 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - encode-utf8@1.0.3: - resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} - encodeurl@1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} @@ -2618,15 +2744,28 @@ packages: error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - es-abstract@1.22.3: - resolution: {integrity: sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==} + es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-iterator-helpers@1.1.0: + resolution: {integrity: sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==} engines: {node: '>= 0.4'} - es-iterator-helpers@1.0.15: - resolution: {integrity: sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==} + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} - es-set-tostringtag@2.0.2: - resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==} + es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} engines: {node: '>= 0.4'} es-shim-unscopables@1.0.2: @@ -2636,20 +2775,24 @@ packages: resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} engines: {node: '>= 0.4'} - esbuild-plugin-browserslist@0.10.0: - resolution: {integrity: sha512-rZWFcp3l+73xDiJB+Vl9UqP1VVs+L4E0lygbwJl6UTmW2qQago7DLT56hBu0vocH/TtZsAcRHj0+qHqkkB5Gww==} - engines: {node: '>=18'} - peerDependencies: - browserslist: ^4.21.8 - esbuild: ~0.19.2 + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} - esbuild@0.19.12: - resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} hasBin: true - escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + esbuild@0.24.0: + resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} escape-html@1.0.3: @@ -2676,8 +2819,8 @@ packages: eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} - eslint-module-utils@2.8.0: - resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} + eslint-module-utils@2.12.0: + resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -2697,24 +2840,24 @@ packages: eslint-import-resolver-webpack: optional: true - eslint-plugin-import@2.29.1: - resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} + eslint-plugin-import@2.31.0: + resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 peerDependenciesMeta: '@typescript-eslint/parser': optional: true - eslint-plugin-jsx-a11y@6.8.0: - resolution: {integrity: sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==} + eslint-plugin-jsx-a11y@6.10.1: + resolution: {integrity: sha512-zHByM9WTUMnfsDTafGXRiqxp6lFtNoSOWBY6FonVRn3A+BUwN1L/tdBXT40BcBJi0cZjOGTXZ0eD/rTG9fEJ0g==} engines: {node: '>=4.0'} peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 - eslint-plugin-prettier@5.1.3: - resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} + eslint-plugin-prettier@5.2.1: + resolution: {integrity: sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: '@types/eslint': '>=8.0.0' @@ -2727,22 +2870,22 @@ packages: eslint-config-prettier: optional: true - eslint-plugin-react-hooks@4.6.0: - resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} + eslint-plugin-react-hooks@4.6.2: + resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==} engines: {node: '>=10'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - eslint-plugin-react-refresh@0.4.5: - resolution: {integrity: sha512-D53FYKJa+fDmZMtriODxvhwrO+IOqrxoEo21gMA0sjHdU6dPVH4OhyFip9ypl8HOF5RV5KdTo+rBQLvnY2cO8w==} + eslint-plugin-react-refresh@0.4.13: + resolution: {integrity: sha512-f1EppwrpJRWmqDTyvAyomFVDYRtrS7iTEqv3nokETnMiMzs2SSTmKRTACce4O2p4jYyowiSMvpdwC/RLcMFhuQ==} peerDependencies: eslint: '>=7' - eslint-plugin-react@7.33.2: - resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==} + eslint-plugin-react@7.37.1: + resolution: {integrity: sha512-xwTnwDqzbDRA8uJ7BMxPs/EXRB3i8ZfnOIp8BsxEQkT0nHPp+WWceqGgo6rKb9ctNi8GJLDT4Go5HAWELa/WMg==} engines: {node: '>=4'} peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 eslint-plugin-simple-import-sort@10.0.0: resolution: {integrity: sha512-AeTvO9UCMSNzIHRkg8S6c3RPy5YEwKWSQPx3DYghLedo2ZQxowPFLGDN1AZ2evfg6r6mjBSZSLxLFsWSu3acsw==} @@ -2757,17 +2900,18 @@ packages: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint@8.56.0: - resolution: {integrity: sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==} + eslint@8.57.1: + resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} esrecurse@4.3.0: @@ -2787,6 +2931,9 @@ packages: estree-util-is-identifier-name@3.0.0: resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + estree-util-to-js@2.0.0: resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} @@ -2803,8 +2950,8 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} - ethers@6.10.0: - resolution: {integrity: sha512-nMNwYHzs6V1FR3Y4cdfxSQmNgZsRj1RiTU25JwvnJLmyzw9z3SKxNc2XKDuiXXo/v9ds5Mp9m6HBabgYQQ26tA==} + ethers@6.13.4: + resolution: {integrity: sha512-21YtnZVg4/zKkCQPjrDj38B1r4nQvTZLopUGMLQ1ePU2zV/joCfDC3t3iKQjWRzjjjbzR+mdAIoikeBRNkdllA==} engines: {node: '>=14.0.0'} eventemitter3@4.0.7: @@ -2814,21 +2961,9 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} - execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} - - execa@7.2.0: - resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} - engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} - extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - external-editor@3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} - fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -2849,12 +2984,15 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-uri@3.0.3: + resolution: {integrity: sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==} + fastest-levenshtein@1.0.16: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} engines: {node: '>= 4.9.1'} - fastq@1.16.0: - resolution: {integrity: sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==} + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} figures@3.2.0: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} @@ -2902,15 +3040,15 @@ packages: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} - flat-cache@4.0.0: - resolution: {integrity: sha512-EryKbCE/wxpxKniQlyas6PY1I9vwtF3uCBweX+N8KYTCn3Y12RTGtQAJ/bd5pl7kxUAc8v/R3Ake/N17OZiFqA==} + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} - flatted@3.2.9: - resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} - follow-redirects@1.15.5: - resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==} + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -2921,23 +3059,22 @@ packages: for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - foreground-child@3.1.1: - resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} - engines: {node: '>=14'} - - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + form-data@4.0.1: + resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} engines: {node: '>= 6'} fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} - framer-motion@11.0.3: - resolution: {integrity: sha512-6x2poQpIWBdbZwLd73w6cKZ1I9IEPIU94C6/Swp1Zt3LJ+sB5bPe1E2wC6EH5hSISXNkMJ4afH7AdwS7MrtkWw==} + framer-motion@11.11.9: + resolution: {integrity: sha512-XpdZseuCrZehdHGuW22zZt3SF5g6AHJHJi7JwQIigOznW4Jg1n0oGPMJQheMaKLC+0rp5gxUKMRYI6ytd3q4RQ==} peerDependencies: + '@emotion/is-prop-valid': '*' react: ^18.0.0 react-dom: ^18.0.0 peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true react: optional: true react-dom: @@ -2973,24 +3110,21 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-intrinsic@1.2.2: - resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} get-pkg-repo@4.2.1: resolution: {integrity: sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==} engines: {node: '>=6.9.0'} hasBin: true - get-port@7.0.0: - resolution: {integrity: sha512-mDHFgApoQd+azgMdwylJrv2DX47ywGq1i5VFJE7fZ0dttNq3iQMfsU4IvEgBHojA3KqEudyu7Vq+oN8kNaNkWw==} + get-port@7.1.0: + resolution: {integrity: sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==} engines: {node: '>=16'} - get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - - get-symbol-description@1.0.0: - resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} engines: {node: '>= 0.4'} get-text-width@1.0.3: @@ -3021,11 +3155,6 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob@10.3.10: - resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported @@ -3051,16 +3180,16 @@ packages: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} - globalthis@1.0.3: - resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} - globby@14.0.0: - resolution: {integrity: sha512-/1WM/LNHRAOH9lZta77uGbq0dAEQM+XjNesWwhlERDVenqothRbnzTrL3/LrIoEPPjeUHC3vrS6TwoyxeHs7MQ==} + globby@14.0.2: + resolution: {integrity: sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==} engines: {node: '>=18'} globjoin@0.1.4: @@ -3078,8 +3207,8 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - graphql@16.8.1: - resolution: {integrity: sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==} + graphql@16.9.0: + resolution: {integrity: sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} handlebars@4.7.8: @@ -3102,23 +3231,23 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - has-property-descriptors@1.0.1: - resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - has-proto@1.0.1: - resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} engines: {node: '>= 0.4'} has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} - has-tostringtag@1.0.0: - resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} - hasown@2.0.0: - resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} hast-util-classnames@3.0.0: @@ -3133,23 +3262,23 @@ packages: hast-util-parse-selector@4.0.0: resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} - hast-util-raw@9.0.2: - resolution: {integrity: sha512-PldBy71wO9Uq1kyaMch9AHIghtQvIwxBUkv823pKmkTM3oV1JxtsTNYdevMxvUHqcnOAuO65JKU2+0NOxc2ksA==} + hast-util-raw@9.0.4: + resolution: {integrity: sha512-LHE65TD2YiNsHD3YuXcKPHXPLuYh/gjp12mOfU8jxSrm1f/yJpsb0F/KKljS6U9LJoP0Ux+tCe8iJ2AsPzTdgA==} - hast-util-select@6.0.2: - resolution: {integrity: sha512-hT/SD/d/Meu+iobvgkffo1QecV8WeKWxwsNMzcTJsKw1cKTQKSR/7ArJeURLNJF9HDjp9nVoORyNNJxrvBye8Q==} + hast-util-select@6.0.3: + resolution: {integrity: sha512-OVRQlQ1XuuLP8aFVLYmC2atrfWHS5UD3shonxpnyrjcCkwtvmt/+N6kYJdcY4mkMJhxp4kj2EFIxQ9kvkkt/eQ==} hast-util-to-estree@3.1.0: resolution: {integrity: sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==} - hast-util-to-jsx-runtime@2.3.0: - resolution: {integrity: sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==} + hast-util-to-jsx-runtime@2.3.2: + resolution: {integrity: sha512-1ngXYb+V9UT5h+PxNRa1O1FYguZK/XL+gkeqvp7EdHlB9oHUG0eYRo/vY5inBdcqo3RkPMC58/H94HvkbfGdyg==} hast-util-to-parse5@8.0.0: resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==} - hast-util-to-string@3.0.0: - resolution: {integrity: sha512-OGkAxX1Ua3cbcW6EJ5pT/tslVb90uViVkcJ4ZZIMW/R33DX/AkcJcRrPebPwJkHYwlDHXz4aIwvAAaAdtrACFA==} + hast-util-to-string@3.0.1: + resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} hast-util-whitespace@3.0.0: resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} @@ -3157,8 +3286,8 @@ packages: hastscript@8.0.0: resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==} - headers-polyfill@4.0.2: - resolution: {integrity: sha512-EWGTfnTqAO2L/j5HZgoM/3z82L7necsJ0pO9Tp0X1wil3PDLrkypTBRgVO2ExehEEvUycejZD3FuRaXpZZc3kw==} + headers-polyfill@4.0.3: + resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} hex-rgb@5.0.0: resolution: {integrity: sha512-NQO+lgVUCtHxZ792FodgW0zflK+ozS9X9dwGp9XvvmPlH7pyxd588cn24TD3rmPm/N0AIRXF10Otah8yKqGw4w==} @@ -3177,20 +3306,24 @@ packages: resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} engines: {node: '>=10'} - html-dom-parser@5.0.7: - resolution: {integrity: sha512-2YD2/yB0QgrlkBIn0CsGaRXC89E1gtuPVpiOGC52NTzPCC83n0WMdGD+5q7lpcKqbCpnWValQbovuy/NI/0kag==} + html-dom-parser@5.0.10: + resolution: {integrity: sha512-GwArYL3V3V8yU/mLKoFF7HlLBv80BZ2Ey1BzfVNRpAci0cEKhFHI/Qh8o8oyt3qlAMLlK250wsxLdYX4viedvg==} - html-react-parser@5.1.1: - resolution: {integrity: sha512-L5VK0rKN3VM7uzRH+4wxAL9elvHuCNDjyWKKjcCDR+YWW5Qr7WWSK7+e627DcePVAFi5IMqc+rAU8j/1DpC/Tw==} + html-react-parser@5.1.18: + resolution: {integrity: sha512-65BwC0zzrdeW96jB2FRr5f1ovBhRMpLPJNvwkY5kA8Ay5xdL9t/RH2/uUTM7p+cl5iM88i6dDk4LXtfMnRmaJQ==} peerDependencies: + '@types/react': 0.14 || 15 || 16 || 17 || 18 react: 0.14 || 15 || 16 || 17 || 18 + peerDependenciesMeta: + '@types/react': + optional: true html-tags@3.3.1: resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} engines: {node: '>=8'} - html-url-attributes@3.0.0: - resolution: {integrity: sha512-/sXbVCWayk6GDVg3ctOX6nxaVj7So40FcFAnWlWGNAB1LpYKcV5Cd10APjPjW80O7zYW2MsjBV4zZ7IZO5fVow==} + html-url-attributes@3.0.1: + resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} @@ -3206,27 +3339,12 @@ packages: resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==} engines: {node: '>= 0.6'} - human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - - human-signals@4.3.1: - resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} - engines: {node: '>=14.18.0'} - - iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - - ignore@5.3.0: - resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==} + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - immutable@4.3.4: - resolution: {integrity: sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==} + immutable@4.3.7: + resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==} import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} @@ -3253,15 +3371,11 @@ packages: inline-style-parser@0.1.1: resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} - inline-style-parser@0.2.2: - resolution: {integrity: sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ==} + inline-style-parser@0.2.4: + resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} - inquirer@8.2.6: - resolution: {integrity: sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==} - engines: {node: '>=12.0.0'} - - internal-slot@1.0.6: - resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==} + internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} internmap@2.0.3: @@ -3274,8 +3388,9 @@ packages: is-alphanumerical@2.0.1: resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} - is-array-buffer@3.0.2: - resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} @@ -3295,16 +3410,17 @@ packages: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} - is-buffer@2.0.5: - resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} - engines: {node: '>=4'} - is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} - is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + is-core-module@2.15.1: + resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} @@ -3313,11 +3429,6 @@ packages: is-decimal@2.0.1: resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} - is-docker@2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} - hasBin: true - is-docker@3.0.0: resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -3350,15 +3461,12 @@ packages: engines: {node: '>=14.16'} hasBin: true - is-interactive@1.0.0: - resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} - engines: {node: '>=8'} - - is-map@2.0.2: - resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} - is-negative-zero@2.0.2: - resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} is-node-process@1.2.0: @@ -3392,26 +3500,17 @@ packages: resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} engines: {node: '>=0.10.0'} - is-reference@3.0.2: - resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==} - is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} - is-set@2.0.2: - resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} - - is-shared-array-buffer@1.0.2: - resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} - - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} - is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} @@ -3425,30 +3524,28 @@ packages: resolution: {integrity: sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==} engines: {node: '>=0.10.0'} - is-typed-array@1.1.12: - resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} engines: {node: '>= 0.4'} - is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} - - is-weakmap@2.0.1: - resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} - is-weakset@2.0.2: - resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} + is-weakset@2.0.3: + resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} + engines: {node: '>= 0.4'} is-what@4.1.16: resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} engines: {node: '>=12.13'} - is-wsl@2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} @@ -3459,15 +3556,12 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - iterator.prototype@1.1.2: - resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} + iterator.prototype@1.1.3: + resolution: {integrity: sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==} + engines: {node: '>= 0.4'} - itertools@2.2.3: - resolution: {integrity: sha512-TV4TDJ2FrLxhRJDX/AgdyI76i6cHi2Z1hml/d+HLcGVHxmgfxsLpoQBN2ZE9OizPt10+VW+LamLfCDASlnxvNg==} - - jackspeak@2.3.6: - resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} - engines: {node: '>=14'} + itertools@2.3.2: + resolution: {integrity: sha512-urRg24zOOKt4qQHm3gzQLK5Mima/kMSP3DUfcVw05W3veUHxxqHPTEW08aKY9GIZm9CKvnULVqXdjZWNYalJHQ==} js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -3476,13 +3570,9 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true - jsesc@0.5.0: - resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} - hasBin: true - - jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} hasBin: true json-buffer@3.0.1: @@ -3515,8 +3605,8 @@ packages: engines: {node: '>=6'} hasBin: true - jsonc-parser@3.2.1: - resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} jsonparse@1.3.1: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} @@ -3540,6 +3630,9 @@ packages: known-css-properties@0.29.0: resolution: {integrity: sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==} + known-css-properties@0.34.0: + resolution: {integrity: sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==} + koa-compose@4.1.0: resolution: {integrity: sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==} @@ -3550,12 +3643,12 @@ packages: resolution: {integrity: sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==} engines: {node: '>= 10'} - koa@2.15.0: - resolution: {integrity: sha512-KEL/vU1knsoUvfP4MC4/GthpQrY/p6dzwaaGI6Rt4NQuFqkw3qrvsdYF5pz3wOfi7IGTvMPHC9aZIcUKYFNxsw==} + koa@2.15.3: + resolution: {integrity: sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==} engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4} - language-subtag-registry@0.3.22: - resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==} + language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} language-tags@1.0.9: resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} @@ -3611,10 +3704,6 @@ packages: lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} @@ -3625,10 +3714,6 @@ packages: lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} - lru-cache@10.1.0: - resolution: {integrity: sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==} - engines: {node: 14 || >=16.14} - lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -3639,9 +3724,8 @@ packages: lunr@2.3.9: resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} - magic-string@0.30.5: - resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} - engines: {node: '>=12'} + magic-string@0.30.12: + resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} map-obj@1.0.1: resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} @@ -3669,11 +3753,11 @@ packages: mdast-util-find-and-replace@3.0.1: resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==} - mdast-util-from-markdown@2.0.0: - resolution: {integrity: sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==} + mdast-util-from-markdown@2.0.1: + resolution: {integrity: sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==} - mdast-util-gfm-autolink-literal@2.0.0: - resolution: {integrity: sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==} + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} mdast-util-gfm-footnote@2.0.0: resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==} @@ -3690,11 +3774,11 @@ packages: mdast-util-gfm@3.0.0: resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==} - mdast-util-mdx-expression@2.0.0: - resolution: {integrity: sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==} + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} - mdast-util-mdx-jsx@3.0.0: - resolution: {integrity: sha512-XZuPPzQNBPAlaqsTTgRrcJnyFbSOBovSadFgbFu8SnuNgm+6Bdx1K+IWoitsmj6Lq6MNtI+ytOqwN70n//NaBA==} + mdast-util-mdx-jsx@3.1.3: + resolution: {integrity: sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ==} mdast-util-mdx@3.0.0: resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} @@ -3702,11 +3786,11 @@ packages: mdast-util-mdxjs-esm@2.0.1: resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} - mdast-util-phrasing@4.0.0: - resolution: {integrity: sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==} + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} - mdast-util-to-hast@13.1.0: - resolution: {integrity: sha512-/e2l/6+OdGp/FB+ctrJ9Avz71AN/GRH3oi/3KAx/kMnoUsD6q0woXlDT8lLEeViVKE7oZxE7RXzvO3T8kF2/sA==} + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} mdast-util-to-markdown@2.1.0: resolution: {integrity: sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==} @@ -3720,6 +3804,12 @@ packages: mdn-data@2.0.30: resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + mdn-data@2.10.0: + resolution: {integrity: sha512-qq7C3EtK3yJXMwz1zAab65pjl+UhohqMOctTgcqjLOWABqmwj+me02LSsCuEUxnst9X1lCBpoE0WArGKgdGDzw==} + + mdn-data@2.11.1: + resolution: {integrity: sha512-Hdx3wmyqPFrhd6YHVuSkUK2eIGAcxR0xlndcgZqjA68yMJTbfXrjJwbgsBOsNjI7LnBIVUQnmyMVSdi/ob0GpQ==} + media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} @@ -3727,41 +3817,38 @@ packages: memoize-one@5.2.1: resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} - meow@13.1.0: - resolution: {integrity: sha512-o5R/R3Tzxq0PJ3v3qcQJtSvSE9nKOLSAaDuuoMzDVuGTwHdccMWcYomh9Xolng2tjT6O/Y83d+0coVGof6tqmA==} + meow@13.2.0: + resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} engines: {node: '>=18'} meow@8.1.2: resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==} engines: {node: '>=10'} - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - micromark-core-commonmark@2.0.0: - resolution: {integrity: sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==} + micromark-core-commonmark@2.0.1: + resolution: {integrity: sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==} - micromark-extension-gfm-autolink-literal@2.0.0: - resolution: {integrity: sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==} + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} - micromark-extension-gfm-footnote@2.0.0: - resolution: {integrity: sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==} + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} - micromark-extension-gfm-strikethrough@2.0.0: - resolution: {integrity: sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==} + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} - micromark-extension-gfm-table@2.0.0: - resolution: {integrity: sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==} + micromark-extension-gfm-table@2.1.0: + resolution: {integrity: sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==} micromark-extension-gfm-tagfilter@2.0.0: resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} - micromark-extension-gfm-task-list-item@2.0.1: - resolution: {integrity: sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==} + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} micromark-extension-gfm@3.0.0: resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} @@ -3769,8 +3856,8 @@ packages: micromark-extension-mdx-expression@3.0.0: resolution: {integrity: sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==} - micromark-extension-mdx-jsx@3.0.0: - resolution: {integrity: sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==} + micromark-extension-mdx-jsx@3.0.1: + resolution: {integrity: sha512-vNuFb9czP8QCtAQcEJn0UJQJZA8Dk6DXKBqx+bg/w0WGuSxDxNr7hErW89tHUY31dUW4NqEOWwmEUNhjTFmHkg==} micromark-extension-mdx-md@2.0.0: resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} @@ -3787,8 +3874,8 @@ packages: micromark-factory-label@2.0.0: resolution: {integrity: sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==} - micromark-factory-mdx-expression@2.0.1: - resolution: {integrity: sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==} + micromark-factory-mdx-expression@2.0.2: + resolution: {integrity: sha512-5E5I2pFzJyg2CtemqAbcyCktpHXuJbABnsb32wX2U8IQKhhVFBqkcZR5LRm1WVoFqa4kTueZK4abep7wdo9nrw==} micromark-factory-space@2.0.0: resolution: {integrity: sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==} @@ -3799,8 +3886,8 @@ packages: micromark-factory-whitespace@2.0.0: resolution: {integrity: sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==} - micromark-util-character@2.0.1: - resolution: {integrity: sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==} + micromark-util-character@2.1.0: + resolution: {integrity: sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==} micromark-util-chunked@2.0.0: resolution: {integrity: sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==} @@ -3835,8 +3922,8 @@ packages: micromark-util-sanitize-uri@2.0.0: resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} - micromark-util-subtokenize@2.0.0: - resolution: {integrity: sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==} + micromark-util-subtokenize@2.0.1: + resolution: {integrity: sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==} micromark-util-symbol@2.0.0: resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} @@ -3847,8 +3934,8 @@ packages: micromark@4.0.0: resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} - micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} mime-db@1.52.0: @@ -3859,14 +3946,6 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} - mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - - mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} @@ -3882,6 +3961,10 @@ packages: resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} engines: {node: '>=16 || 14 >=14.17'} + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + minimist-options@4.1.0: resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} engines: {node: '>= 6'} @@ -3889,32 +3972,26 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@7.0.4: - resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} - engines: {node: '>=16 || 14 >=14.17'} - modify-values@1.0.1: resolution: {integrity: sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==} engines: {node: '>=0.10.0'} - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - msw@2.1.4: - resolution: {integrity: sha512-YyIQpfLqAJf/O1kYPWBSbDqjgv71kRBmEbGLxkkai1Btcs/LcxKiAwT1My3COa9J/vTh9Ua41B/ReuiW9cXmkw==} + msw@2.4.13: + resolution: {integrity: sha512-EDA7ls/twh3XG5QEYv0LvAnnFs3wYL6GFNMSqG4hh2+1rq7h78iDbh5jB2iaO8hKi1JVmZLO6ItssXmP1A7nxQ==} engines: {node: '>=18'} hasBin: true peerDependencies: - typescript: '>= 4.7.x <= 5.3.x' + typescript: '>= 4.8.x' peerDependenciesMeta: typescript: optional: true - mute-stream@0.0.8: - resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + mute-stream@1.0.0: + resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} nanoid@3.3.7: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} @@ -3934,8 +4011,11 @@ packages: no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} - node-releases@2.0.14: - resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -3952,29 +4032,19 @@ packages: resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} engines: {node: '>=0.10.0'} - not@0.1.0: - resolution: {integrity: sha512-5PDmaAsVfnWUgTUbJ3ERwn7u79Z0dYxN9ErxCpVJJqe2RK0PJ3z+iFUxuqjwtlDDegXvtWoxD/3Fzxox7tFGWA==} - - npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - - npm-run-path@5.2.0: - resolution: {integrity: sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - numbro@2.4.0: - resolution: {integrity: sha512-t6rVkO1CcKvffvOJJu/zMo70VIcQSR6w3AmIhfHGvmk4vHbNe6zHgomB0aWFAPZWM9JBVWBM0efJv9DBiRoSTA==} + numbro@2.5.0: + resolution: {integrity: sha512-xDcctDimhzko/e+y+Q2/8i3qNC9Svw1QgOkSkQoO0kIPI473tR9QRbo2KP88Ty9p8WbPy+3OpTaAIzehtuHq+A==} object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - object-inspect@1.13.1: - resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} @@ -3984,22 +4054,20 @@ packages: resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} engines: {node: '>= 0.4'} - object.entries@1.1.7: - resolution: {integrity: sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==} + object.entries@1.1.8: + resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==} engines: {node: '>= 0.4'} - object.fromentries@2.0.7: - resolution: {integrity: sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==} + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} engines: {node: '>= 0.4'} - object.groupby@1.0.1: - resolution: {integrity: sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==} - - object.hasown@1.1.3: - resolution: {integrity: sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==} + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} - object.values@1.1.7: - resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==} + object.values@1.2.0: + resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} engines: {node: '>= 0.4'} on-finished@2.4.1: @@ -4009,35 +4077,19 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - - onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} - only@0.0.2: resolution: {integrity: sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==} - open@9.1.0: - resolution: {integrity: sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==} - engines: {node: '>=14.16'} + open@10.1.0: + resolution: {integrity: sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==} + engines: {node: '>=18'} - optionator@0.9.3: - resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} - ora@5.4.1: - resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} - engines: {node: '>=10'} - - os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} - - outvariant@1.4.2: - resolution: {integrity: sha512-Ou3dJ6bA/UJ5GVHxah4LnqDwZRwAmWxrG3wtrHrbGnP4RnLCtA64A4F+ae7Y8ww660JaddSoArUR5HjipWSHAQ==} + outvariant@1.4.3: + resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} p-limit@1.3.0: resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} @@ -4090,8 +4142,8 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} - parse5@7.1.2: - resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + parse5@7.2.0: + resolution: {integrity: sha512-ZkDsAOcxsUMZ4Lz5fVciOehNcJ+Gb8gTzcA4yl3wnc273BAybYWrQ+Ks/OjCjSEpjvQkDSeZbybK9qj2VHHdGA==} parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} @@ -4113,19 +4165,11 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@1.10.1: - resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} - engines: {node: '>=16 || 14 >=14.17'} - - path-to-regexp@6.2.1: - resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} path-type@3.0.0: resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} @@ -4139,11 +4183,8 @@ packages: resolution: {integrity: sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==} engines: {node: '>=12'} - periscopic@3.1.0: - resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} - - picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -4161,14 +4202,18 @@ packages: resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} engines: {node: '>=10.13.0'} + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + postcss-media-query-parser@0.2.3: resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==} - postcss-resolve-nested-selector@0.1.1: - resolution: {integrity: sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==} + postcss-resolve-nested-selector@0.1.6: + resolution: {integrity: sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==} - postcss-safe-parser@7.0.0: - resolution: {integrity: sha512-ovehqRNVCpuFzbXoTb4qLtyzK3xn3t/CUBxOs8LsnQjQrShaB4lKiHoVqY8ANaC0hBMHq5QVWk77rwGklFUDrg==} + postcss-safe-parser@7.0.1: + resolution: {integrity: sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==} engines: {node: '>=18.0'} peerDependencies: postcss: ^8.4.31 @@ -4179,15 +4224,15 @@ packages: peerDependencies: postcss: ^8.4.29 - postcss-selector-parser@6.0.15: - resolution: {integrity: sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==} + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} engines: {node: '>=4'} postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.4.33: - resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==} + postcss@8.4.47: + resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: @@ -4203,13 +4248,13 @@ packages: engines: {node: '>=10.13.0'} hasBin: true - prettier@3.2.4: - resolution: {integrity: sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==} + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} engines: {node: '>=14'} hasBin: true - prism-react-renderer@2.3.1: - resolution: {integrity: sha512-Rdf+HzBLR7KYjzpJ1rSoxT9ioO85nZngQEoFIhL07XhtJHlCU3SOz0GJ6+qvMyQe0Se+BV3qpe6Yd/NmQF5Juw==} + prism-react-renderer@2.4.0: + resolution: {integrity: sha512-327BsVCD/unU4CNLZTWVHyUHKnsqcvj2qbPlQ8MiBE2eq2rgctjigPA1Gp9HLF83kZ20zNN6jgizHJeEsyFYOw==} peerDependencies: react: '>=16.0.0' @@ -4219,12 +4264,15 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - property-information@6.4.1: - resolution: {integrity: sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w==} + property-information@6.5.0: + resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + psl@1.9.0: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -4240,14 +4288,17 @@ packages: qr.js@0.0.0: resolution: {integrity: sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ==} - qrcode@1.5.3: - resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} + qrcode@1.5.4: + resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==} engines: {node: '>=10.13.0'} hasBin: true - query-string@8.1.0: - resolution: {integrity: sha512-BFQeWxJOZxZGix7y+SByG3F36dA0AbTy9o6pSmKFcFz7DAj0re9Frkty3saBn3nHo3D0oZJ/+rx3r8H8r8Jbpw==} - engines: {node: '>=14.16'} + query-string@9.1.1: + resolution: {integrity: sha512-MWkCOVIcJP9QSKU52Ngow6bsAWAPlPK2MludXvcrS2bGZSl+T1qX9MZvRIkqUIkGLJquMJHWfsT6eRqUpp4aWg==} + engines: {node: '>=18'} + + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -4256,8 +4307,8 @@ packages: resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} engines: {node: '>=8'} - radash@11.0.0: - resolution: {integrity: sha512-CRWxTFTDff0IELGJ/zz58yY4BDgyI14qSM5OLNKbCItJrff7m7dXbVF0kWYVCXQtPb3SXIVhXvAImH6eT7VLSg==} + radash@12.1.0: + resolution: {integrity: sha512-b0Zcf09AhqKS83btmUeYBS8tFK7XL2e3RvLmZcm0sTdF1/UUlHSsjXdCcWNxe7yfmAlPve5ym0DmKGtTzP6kVQ==} engines: {node: '>=14.18.0'} react-click-away-listener@2.2.3: @@ -4266,19 +4317,19 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom@18.2.0: - resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} peerDependencies: - react: ^18.2.0 + react: ^18.3.1 - react-hook-form@7.49.3: - resolution: {integrity: sha512-foD6r3juidAT1cOZzpmD/gOKt7fRsDhXXZ0y28+Al1CHgX+AY1qIN9VSIIItXRq1dN68QrRwl1ORFlwjBaAqeQ==} - engines: {node: '>=18', pnpm: '8'} + react-hook-form@7.53.1: + resolution: {integrity: sha512-6aiQeBda4zjcuaugWvim9WsGqisoUk+etmFEsSUMm451/Ic8L/UAb7sRtMj3V+Hdzm6mMjU1VhiSzYUZeBm0Vg==} + engines: {node: '>=18.0.0'} peerDependencies: - react: ^16.8.0 || ^17 || ^18 + react: ^16.8.0 || ^17 || ^18 || ^19 - react-hotkeys-hook@4.4.4: - resolution: {integrity: sha512-wzZmqb/Obr0ds9Myc1sIFPJ52GA/Eeg/vXBWV0HA1LvHlVAW5Va3KB0q6EZNlNSHQWscWZ2K8+6w0GYSie2o7A==} + react-hotkeys-hook@4.5.1: + resolution: {integrity: sha512-scAEJOh3Irm0g95NIn6+tQVf/OICCjsQsC9NBHfQws/Vxw4sfq1tDQut5fhTEvPraXhu/sHxRd9lOtxzyYuNAg==} peerDependencies: react: '>=16.8.1' react-dom: '>=16.8.1' @@ -4297,14 +4348,11 @@ packages: react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - react-is@18.2.0: - resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - react-lifecycles-compat@3.0.4: - resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} - - react-loading-skeleton@3.3.1: - resolution: {integrity: sha512-NilqqwMh2v9omN7LteiDloEVpFyMIa0VGqF+ukqp0ncVlYu1sKYbYGX9JEl+GtOT9TKsh04zCHAbavnQ2USldA==} + react-loading-skeleton@3.5.0: + resolution: {integrity: sha512-gxxSyLbrEAdXTKgfbpBEFZCO/P153DnqSCQau2+o6lNy1jgMRr2MmRmOzMmyrwSaSYLRB8g7b0waYPmUjz7IhQ==} peerDependencies: react: '>=16.8.0' @@ -4317,28 +4365,24 @@ packages: react-property@2.0.2: resolution: {integrity: sha512-+PbtI3VuDV0l6CleQMsx2gtK0JZbZKbpdu5ynr+lbsuvtmgbNcS3VM0tuY2QjFNOcWxvXeHjDpy42RO+4U2rug==} - react-qr-code@2.0.12: - resolution: {integrity: sha512-k+pzP5CKLEGBRwZsDPp98/CAJeXlsYRHM2iZn1Sd5Th/HnKhIZCSg27PXO58zk8z02RaEryg+60xa4vyywMJwg==} + react-qr-code@2.0.15: + resolution: {integrity: sha512-MkZcjEXqVKqXEIMVE0mbcGgDpkfSdd8zhuzXEl9QzYeNcw8Hq2oVIzDLWuZN2PQBwM5PWjc2S31K8Q1UbcFMfw==} peerDependencies: - react: ^16.x || ^17.x || ^18.x - react-native-svg: '*' - peerDependenciesMeta: - react-native-svg: - optional: true + react: '*' - react-refresh@0.14.0: - resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} + react-refresh@0.14.2: + resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} - react-router-dom@6.21.3: - resolution: {integrity: sha512-kNzubk7n4YHSrErzjLK72j0B5i969GsuCGazRl3G6j1zqZBLjuSlYBdVdkDOgzGdPIffUOc9nmgiadTEVoq91g==} + react-router-dom@6.27.0: + resolution: {integrity: sha512-+bvtFWMC0DgAFrfKXKG9Fc+BcXWRUO1aJIihbB79xaeq0v5UzfvnM5houGUm1Y461WVRcgAQ+Clh5rdb1eCx4g==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' react-dom: '>=16.8' - react-router@6.21.3: - resolution: {integrity: sha512-a0H638ZXULv1OdkmiK6s6itNhoy33ywxmUFT/xtSoVyf9VnC7n7+VT4LjVzdIHSaF5TIh9ylUgxMXksHTgGrKg==} + react-router@6.27.0: + resolution: {integrity: sha512-YA+HGZXz4jaAkVoYBE98VQl+nVzI+cVI2Oj/06F5ZM+0u3TgedN9Y9kmMRo2mnkSK2nCpNQn0DVob4HCsY/WLw==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' @@ -4348,21 +4392,20 @@ packages: peerDependencies: react-dom: ^16.8.0 || ^17 || ^18 - react-smooth@2.0.5: - resolution: {integrity: sha512-BMP2Ad42tD60h0JW6BFaib+RJuV5dsXJK9Baxiv/HlNFjvRLqA9xrNKxVWnUIZPQfzUwGXIlU/dSYLU+54YGQA==} + react-smooth@4.0.1: + resolution: {integrity: sha512-OE4hm7XqR0jNOq3Qmk9mFLyd6p2+j6bvbPJ7qlB7+oo0eNcL2l7WQzG6MBnT3EXY6xzkLMUBec3AfewJdA0J8w==} peerDependencies: - prop-types: ^15.6.0 - react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 - react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-transition-group@2.9.0: - resolution: {integrity: sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==} + react-transition-group@4.4.5: + resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} peerDependencies: - react: '>=15.0.0' - react-dom: '>=15.0.0' + react: '>=16.6.0' + react-dom: '>=16.6.0' - react-virtualized-auto-sizer@1.0.21: - resolution: {integrity: sha512-RedZxj452+ITLfqIrR02BjvCaXV63YVIcVrvmruDZXFpJGazg4gHNs1AShPGVLvEuLGZdZ9AtkGKhWvzEujL8g==} + react-virtualized-auto-sizer@1.0.24: + resolution: {integrity: sha512-3kCn7N9NEb3FlvJrSHWGQ4iVl+ydQObq2fHMn12i5wbtm74zHOPhz/i64OL3c1S1vi9i2GXtZqNqUJTQ+BnNfg==} peerDependencies: react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 @@ -4374,8 +4417,8 @@ packages: react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 - react@18.2.0: - resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} read-pkg-up@3.0.0: @@ -4405,27 +4448,42 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + readdirp@4.0.2: + resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} + engines: {node: '>= 14.16.0'} + recharts-scale@0.4.5: resolution: {integrity: sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==} - recharts@2.10.4: - resolution: {integrity: sha512-/Q7/wdf8bW91lN3NEeCjL9RWfaiXQViJFgdnas4Eix/I8B9HAI3tHHK/CW/zDfgRMh4fzW1zlfjoz1IAapLO1Q==} + recharts@2.13.0: + resolution: {integrity: sha512-sbfxjWQ+oLWSZEWmvbq/DFVdeRLqqA6d0CDjKx2PkxVVdoXo16jvENCE+u/x7HxOO+/fwx//nYRwb8p8X6s/lQ==} engines: {node: '>=14'} peerDependencies: - prop-types: ^15.6.0 react: ^16.0.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.0: + resolution: {integrity: sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q==} + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} - reflect.getprototypeof@1.0.4: - resolution: {integrity: sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==} + reflect.getprototypeof@1.0.6: + resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==} engines: {node: '>= 0.4'} - regenerate-unicode-properties@10.1.1: - resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==} + regenerate-unicode-properties@10.2.0: + resolution: {integrity: sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==} engines: {node: '>=4'} regenerate@1.4.2: @@ -4437,41 +4495,47 @@ packages: regenerator-transform@0.15.2: resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} - regexp.prototype.flags@1.5.1: - resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} + regexp.prototype.flags@1.5.3: + resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} engines: {node: '>= 0.4'} - regexpu-core@5.3.2: - resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} + regexpu-core@6.1.1: + resolution: {integrity: sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw==} engines: {node: '>=4'} - regjsparser@0.9.1: - resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + regjsgen@0.8.0: + resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} + + regjsparser@0.11.1: + resolution: {integrity: sha512-1DHODs4B8p/mQHU9kr+jv8+wIC9mtG4eBHxWxIq5mhjE3D5oORhCc6deRKzTjs9DcfRFmj9BHSDguZklqCGFWQ==} hasBin: true - rehype-class-names@1.0.14: - resolution: {integrity: sha512-eFBt6Qxb7K77y6P82tUtN9rKpU7guWlaK4XA4RrrSFHkUTCvr2D3cgb9OR5d4t1AaGOvR59FH9nRwUnbpn9AEg==} + rehype-class-names@2.0.0: + resolution: {integrity: sha512-jldCIiAEvXKdq8hqr5f5PzNdIDkvHC6zfKhwta9oRoMu7bn0W7qLES/JrrjBvr9rKz3nJ8x4vY1EWI+dhjHVZQ==} rehype-raw@7.0.0: resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + remark-gfm@4.0.0: resolution: {integrity: sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==} - remark-mdx@3.0.0: - resolution: {integrity: sha512-O7yfjuC6ra3NHPbRVxfflafAj3LTwx3b73aBvkEFU5z4PsD6FD4vrqJAkE5iNGLz71GdjXfgRqm3SQ0h0VuE7g==} + remark-mdx@3.1.0: + resolution: {integrity: sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==} remark-parse@11.0.0: resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} - remark-rehype@11.1.0: - resolution: {integrity: sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==} + remark-rehype@11.1.1: + resolution: {integrity: sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ==} remark-stringify@11.0.0: resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} - remove-accents@0.4.2: - resolution: {integrity: sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==} + remove-accents@0.5.0: + resolution: {integrity: sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==} require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} @@ -4484,6 +4548,9 @@ packages: require-main-filename@2.0.0: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -4500,10 +4567,6 @@ packages: resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} hasBin: true - restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -4513,23 +4576,14 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - rimraf@5.0.5: - resolution: {integrity: sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==} - engines: {node: '>=14'} - hasBin: true - - rollup-plugin-preserve-directives@0.3.1: - resolution: {integrity: sha512-Jn1gWU7G55A1sU6eFpXmwknfBasF0XbBzRqsE6nqrb/gun+mGV7nx++CwOSGPJQpFzFqvKm5U4XNKo3LTLi4Hg==} + rollup-plugin-preserve-directives@0.4.0: + resolution: {integrity: sha512-gx4nBxYm5BysmEQS+e2tAMrtFxrGvk+Pe5ppafRibQi0zlW7VYAbEGk6IKDw9sJGPdFWgVTE0o4BU4cdG0Fylg==} peerDependencies: rollup: npm:@rollup/wasm-node - run-applescript@5.0.0: - resolution: {integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==} - engines: {node: '>=12'} - - run-async@2.4.1: - resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} - engines: {node: '>=0.12.0'} + run-applescript@7.0.0: + resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} + engines: {node: '>=18'} run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -4537,8 +4591,8 @@ packages: rxjs@7.8.1: resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} - safe-array-concat@1.1.0: - resolution: {integrity: sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==} + safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} engines: {node: '>=0.4'} safe-buffer@5.1.2: @@ -4547,20 +4601,17 @@ packages: safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - safe-regex-test@1.0.2: - resolution: {integrity: sha512-83S9w6eFq12BBIJYvjMux6/dkirb8+4zJRA9cxNBVb7Wq5fJBW+Xze48WqR8pxua7bDuAaaAxtVVd4Idjp1dBQ==} + safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} engines: {node: '>= 0.4'} - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - sass@1.70.0: - resolution: {integrity: sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==} + sass@1.80.3: + resolution: {integrity: sha512-ptDWyVmDMVielpz/oWy3YP3nfs7LpJTHIJZboMVs8GEC9eUmtZTZhMHlTW98wY4aEorDfjN38+Wr/XjskFWcfA==} engines: {node: '>=14.0.0'} hasBin: true - scheduler@0.23.0: - resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} @@ -4570,20 +4621,20 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} hasBin: true set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - set-function-length@1.2.0: - resolution: {integrity: sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==} + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} - set-function-name@2.0.1: - resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} engines: {node: '>= 0.4'} setprototypeof@1.2.0: @@ -4603,11 +4654,9 @@ packages: shiki@0.14.7: resolution: {integrity: sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==} - side-channel@1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} - - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} @@ -4628,8 +4677,8 @@ packages: snake-case@3.0.4: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} - source-map-js@1.0.2: - resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} source-map-support@0.5.21: @@ -4650,20 +4699,17 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} - spawn-command@0.0.2: - resolution: {integrity: sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==} - spdx-correct@3.2.0: resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} - spdx-exceptions@2.4.0: - resolution: {integrity: sha512-hcjppoJ68fhxA/cjbN4T8N6uCUejN8yFw69ttpqtBeCbF3u13n7mb31NB9jKwGTTWWnt9IbRA/mf1FprYS8wfw==} + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} spdx-expression-parse@3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - spdx-license-ids@3.0.16: - resolution: {integrity: sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==} + spdx-license-ids@3.0.20: + resolution: {integrity: sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==} split-on-first@3.0.0: resolution: {integrity: sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA==} @@ -4699,18 +4745,27 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} - string.prototype.matchall@4.0.10: - resolution: {integrity: sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==} + string.prototype.includes@2.0.1: + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} + engines: {node: '>= 0.4'} - string.prototype.trim@1.2.8: - resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} + string.prototype.matchall@4.0.11: + resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} engines: {node: '>= 0.4'} - string.prototype.trimend@1.0.7: - resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} - string.prototype.trimstart@1.0.7: - resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} + string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} @@ -4718,8 +4773,8 @@ packages: string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - stringify-entities@4.0.3: - resolution: {integrity: sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==} + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} stringify-package@1.0.1: resolution: {integrity: sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==} @@ -4737,14 +4792,6 @@ packages: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} - strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - - strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} - strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -4753,14 +4800,14 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - style-to-js@1.1.10: - resolution: {integrity: sha512-VC7MBJa+y0RZhpnLKDPmVRLRswsASLmixkiZ5R8xZpNT9VyjeRzwnXd2pBzAWdgSGv/pCNNH01gPCCUsB9exYg==} + style-to-js@1.1.16: + resolution: {integrity: sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==} style-to-object@0.4.4: resolution: {integrity: sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==} - style-to-object@1.0.5: - resolution: {integrity: sha512-rDRwHtoDD3UMMrmZ6BzOW0naTjMsVZLIjsGleSKS/0Oz+cgCfAPRspaqJuE8rDzpKha/nEvnM0IF4seEAZUTKQ==} + style-to-object@1.0.8: + resolution: {integrity: sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==} stylelint-config-prettier-scss@1.0.0: resolution: {integrity: sha512-Gr2qLiyvJGKeDk0E/+awNTrZB/UtNVPLqCDOr07na/sLekZwm26Br6yYIeBYz3ulsEcQgs5j+2IIMXCC+wsaQA==} @@ -4769,40 +4816,40 @@ packages: peerDependencies: stylelint: '>=15.0.0' - stylelint-config-recommended-scss@14.0.0: - resolution: {integrity: sha512-HDvpoOAQ1RpF+sPbDOT2Q2/YrBDEJDnUymmVmZ7mMCeNiFSdhRdyGEimBkz06wsN+HaFwUh249gDR+I9JR7Onw==} + stylelint-config-recommended-scss@14.1.0: + resolution: {integrity: sha512-bhaMhh1u5dQqSsf6ri2GVWWQW5iUjBYgcHkh7SgDDn92ijoItC/cfO/W+fpXshgTQWhwFkP1rVcewcv4jaftRg==} engines: {node: '>=18.12.0'} peerDependencies: postcss: ^8.3.3 - stylelint: ^16.0.2 + stylelint: ^16.6.1 peerDependenciesMeta: postcss: optional: true - stylelint-config-recommended@14.0.0: - resolution: {integrity: sha512-jSkx290CglS8StmrLp2TxAppIajzIBZKYm3IxT89Kg6fGlxbPiTiyH9PS5YUuVAFwaJLl1ikiXX0QWjI0jmgZQ==} + stylelint-config-recommended@14.0.1: + resolution: {integrity: sha512-bLvc1WOz/14aPImu/cufKAZYfXs/A/owZfSMZ4N+16WGXLoX5lOir53M6odBxvhgmgdxCVnNySJmZKx73T93cg==} engines: {node: '>=18.12.0'} peerDependencies: - stylelint: ^16.0.0 + stylelint: ^16.1.0 - stylelint-config-standard-scss@13.0.0: - resolution: {integrity: sha512-WaLvkP689qSYUpJQPCo30TFJSSc3VzvvoWnrgp+7PpVby5o8fRUY1cZcP0sePZfjrFl9T8caGhcKg0GO34VDiQ==} + stylelint-config-standard-scss@13.1.0: + resolution: {integrity: sha512-Eo5w7/XvwGHWkeGLtdm2FZLOMYoZl1omP2/jgFCXyl2x5yNz7/8vv4Tj6slHvMSSUNTaGoam/GAZ0ZhukvalfA==} engines: {node: '>=18.12.0'} peerDependencies: postcss: ^8.3.3 - stylelint: ^16.1.0 + stylelint: ^16.3.1 peerDependenciesMeta: postcss: optional: true - stylelint-config-standard@36.0.0: - resolution: {integrity: sha512-3Kjyq4d62bYFp/Aq8PMKDwlgUyPU4nacXsjDLWJdNPRUgpuxALu1KnlAHIj36cdtxViVhXexZij65yM0uNIHug==} + stylelint-config-standard@36.0.1: + resolution: {integrity: sha512-8aX8mTzJ6cuO8mmD5yon61CWuIM4UD8Q5aBcWKGSf6kg+EC3uhB+iOywpTK4ca6ZL7B49en8yanOFtUW0qNzyw==} engines: {node: '>=18.12.0'} peerDependencies: stylelint: ^16.1.0 - stylelint-scss@6.1.0: - resolution: {integrity: sha512-kCfK8TQzthGwb4vaZniZgxRsVbCM4ZckmT1b/H5m4FU3I8Dz0id9llKsy1NMp3XXqC8+OPD4rVKtUbSxXlJb5g==} + stylelint-scss@6.8.1: + resolution: {integrity: sha512-al+5eRb72bKrFyVAY+CLWKUMX+k+wsDCgyooSfhISJA2exqnJq1PX1iIIpdrvhu3GtJgNJZl9/BIW6EVSMCxdg==} engines: {node: '>=18.12.0'} peerDependencies: stylelint: ^16.0.2 @@ -4831,8 +4878,8 @@ packages: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} engines: {node: '>=10'} - supports-hyperlinks@3.0.0: - resolution: {integrity: sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==} + supports-hyperlinks@3.1.0: + resolution: {integrity: sha512-2rn0BZ+/f7puLOHZm1HOJfwBggfaHXUpPUSSG/SWM4TWp5KCfmNYwnC3hruy2rZlMnmWZ+QAGpZfchu3f3695A==} engines: {node: '>=14.18'} supports-preserve-symlinks-flag@1.0.0: @@ -4845,27 +4892,27 @@ packages: svg-tags@1.0.0: resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} - svgo@3.2.0: - resolution: {integrity: sha512-4PP6CMW/V7l/GmKRKzsLR8xxjdHTV4IMvhTnpuHwwBazSIlw5W/5SmPjN8Dwyt7lKbSJrRDgp4t9ph0HgChFBQ==} + svgo@3.3.2: + resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==} engines: {node: '>=14.0.0'} hasBin: true - synckit@0.8.8: - resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} + synckit@0.9.2: + resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==} engines: {node: ^14.18.0 || >=16.0.0} - systemjs@6.14.3: - resolution: {integrity: sha512-hQv45irdhXudAOr8r6SVSpJSGtogdGZUbJBRKCE5nsIS7tsxxvnIHqT4IOPWj+P+HcSzeWzHlGCGpmhPDIKe+w==} + systemjs@6.15.1: + resolution: {integrity: sha512-Nk8c4lXvMB98MtbmjX7JwJRgJOL8fluecYCfCeYBznwmpOs8Bf15hLM6z4z71EDAhQVrQrI+wt1aLWSXZq+hXA==} tabbable@6.2.0: resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} - table@6.8.1: - resolution: {integrity: sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==} + table@6.8.2: + resolution: {integrity: sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==} engines: {node: '>=10.0.0'} - terser@5.27.0: - resolution: {integrity: sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==} + terser@5.36.0: + resolution: {integrity: sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==} engines: {node: '>=10'} hasBin: true @@ -4885,16 +4932,8 @@ packages: through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - tiny-invariant@1.3.1: - resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==} - - titleize@3.0.0: - resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==} - engines: {node: '>=12'} - - tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} @@ -4908,6 +4947,10 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + engines: {node: '>=6'} + tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -4919,17 +4962,17 @@ packages: resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} engines: {node: '>=8'} - trough@2.1.0: - resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} - ts-api-utils@1.0.3: - resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} - engines: {node: '>=16.13.0'} + ts-api-utils@1.3.0: + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' - tsconfck@3.0.1: - resolution: {integrity: sha512-7ppiBlF3UEddCLeI1JRx5m2Ryq+xk4JrZuq4EuYXykipebaq1dV0Fhgr1hb7CkmHt32QSgOZlcqVLEtHBG4/mg==} + tsconfck@3.1.4: + resolution: {integrity: sha512-kdqWFGVJqe+KGYvlSO9NIaWn9jT1Ny4oKVzAJsKii5eoE9snzTJzL4+MMVOMn+fikWGFmKEylcXL710V/kIPJQ==} engines: {node: ^18 || >=20} hasBin: true peerDependencies: @@ -4941,11 +4984,11 @@ packages: tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} - tslib@2.4.0: - resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} - tslib@2.6.2: - resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + tslib@2.8.0: + resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} tsscmp@1.0.6: resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} @@ -4979,38 +5022,39 @@ packages: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} engines: {node: '>=12.20'} - type-fest@4.10.1: - resolution: {integrity: sha512-7ZnJYTp6uc04uYRISWtiX3DSKB/fxNQT0B5o1OUeCqiQiwF+JC9+rJiZIDrPrNCLLuTqyQmh4VdQqh/ZOkv9MQ==} + type-fest@4.26.1: + resolution: {integrity: sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==} engines: {node: '>=16'} type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} - typed-array-buffer@1.0.0: - resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} + typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} engines: {node: '>= 0.4'} - typed-array-byte-length@1.0.0: - resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} + typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} engines: {node: '>= 0.4'} - typed-array-byte-offset@1.0.0: - resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} + typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} engines: {node: '>= 0.4'} - typed-array-length@1.0.4: - resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - typedoc@0.25.7: - resolution: {integrity: sha512-m6A6JjQRg39p2ZVRIN3NKXgrN8vzlHhOS+r9ymUYtcUP/TIQPvWSq7YgE5ZjASfv5Vd5BW5xrir6Gm2XNNcOow==} + typedoc@0.25.13: + resolution: {integrity: sha512-pQqiwiJ+Z4pigfOnnysObszLiU3mVLWAExSPf+Mu06G/qsc3wzbuM56SZQvONhHLncLUhYzOVkjFFpFfL5AzhQ==} engines: {node: '>= 16'} hasBin: true peerDependencies: - typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x + typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x typesafe-i18n@5.26.2: resolution: {integrity: sha512-2QAriFmiY5JwUAJtG7yufoE/XZ1aFBY++wj7YFS2yo89a3jLBfKoWSdq5JfQYk1V2BS7V2c/u+KEcaCQoE65hw==} @@ -5030,27 +5074,27 @@ packages: engines: {node: '>=14.17'} hasBin: true - uglify-js@3.17.4: - resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} engines: {node: '>=0.8.0'} hasBin: true unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - unicode-canonical-property-names-ecmascript@2.0.0: - resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} + unicode-canonical-property-names-ecmascript@2.0.1: + resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} engines: {node: '>=4'} unicode-match-property-ecmascript@2.0.0: resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} engines: {node: '>=4'} - unicode-match-property-value-ecmascript@2.1.0: - resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} + unicode-match-property-value-ecmascript@2.2.0: + resolution: {integrity: sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==} engines: {node: '>=4'} unicode-property-aliases-ecmascript@2.1.0: @@ -5061,11 +5105,8 @@ packages: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} engines: {node: '>=18'} - unified@10.1.2: - resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} - - unified@11.0.4: - resolution: {integrity: sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==} + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} unist-util-is@6.0.0: resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} @@ -5076,12 +5117,6 @@ packages: unist-util-position@5.0.0: resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} - unist-util-remove-position@5.0.0: - resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} - - unist-util-stringify-position@3.0.3: - resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==} - unist-util-stringify-position@4.0.0: resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} @@ -5091,12 +5126,12 @@ packages: unist-util-visit@5.0.0: resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} - untildify@4.0.0: - resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} - engines: {node: '>=8'} + universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} - update-browserslist-db@1.0.13: - resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} + update-browserslist-db@1.1.1: + resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -5104,6 +5139,9 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + use-breakpoint@4.0.1: resolution: {integrity: sha512-Fa5Duxv3BY3bw8kmj/lmryTETXVUmBQeYJpBgPJ2yJRiIaGVG8rlMNKQE+JS2rywCZHWaggVUz+ytbr7sH/yyg==} peerDependencies: @@ -5116,8 +5154,8 @@ packages: peerDependencies: react: '>=16.13' - use-sync-external-store@1.2.0: - resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + use-sync-external-store@1.2.2: + resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -5135,23 +5173,17 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - vfile-location@5.0.2: - resolution: {integrity: sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==} - - vfile-message@3.1.4: - resolution: {integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==} + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} vfile-message@4.0.2: resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} - vfile@5.3.7: - resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==} + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - vfile@6.0.1: - resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} - - victory-vendor@36.8.2: - resolution: {integrity: sha512-NfSQi7ISCdBbDpn3b6rg+8RpFZmWIM9mcks48BbogHE2F6h1XKdA34oiCKP5hP1OGvTotDRzsexiJKzrK4Exuw==} + victory-vendor@36.9.2: + resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==} vite-plugin-eslint@1.8.1: resolution: {integrity: sha512-PqdMf3Y2fLO9FsNPmMX+//2BF5SF8nEWspZdgl4kSt7UvHDRHVVfHvxsD7ULYzZrJDGRxR81Nq7TOFgwMnUang==} @@ -5164,16 +5196,16 @@ packages: peerDependencies: vite: '>=2.0.0-beta.69' - vite-tsconfig-paths@4.3.1: - resolution: {integrity: sha512-cfgJwcGOsIxXOLU/nELPny2/LUD/lcf1IbfyeKTv2bsupVbTH/xpFtdQlBmIP1GEK2CjjLxYhFfB+QODFAx5aw==} + vite-tsconfig-paths@4.3.2: + resolution: {integrity: sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==} peerDependencies: vite: '*' peerDependenciesMeta: vite: optional: true - vite@5.0.12: - resolution: {integrity: sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==} + vite@5.4.9: + resolution: {integrity: sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -5181,6 +5213,7 @@ packages: less: '*' lightningcss: ^1.21.0 sass: '*' + sass-embedded: '*' stylus: '*' sugarss: '*' terser: ^5.4.0 @@ -5193,6 +5226,8 @@ packages: optional: true sass: optional: true + sass-embedded: + optional: true stylus: optional: true sugarss: @@ -5206,27 +5241,25 @@ packages: vscode-textmate@8.0.0: resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==} - wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} - web-namespaces@2.0.1: resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} - which-builtin-type@1.1.3: - resolution: {integrity: sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==} + which-builtin-type@1.1.4: + resolution: {integrity: sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==} engines: {node: '>= 0.4'} - which-collection@1.0.1: - resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} which-module@2.0.1: resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} - which-typed-array@1.1.13: - resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} which@1.3.1: @@ -5242,6 +5275,10 @@ packages: resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==} engines: {node: '>=12'} + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} @@ -5264,12 +5301,12 @@ packages: resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - ws@8.5.0: - resolution: {integrity: sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==} + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 + utf-8-validate: '>=5.0.2' peerDependenciesMeta: bufferutil: optional: true @@ -5321,19 +5358,23 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} - ylru@1.3.2: - resolution: {integrity: sha512-RXRJzMiK6U2ye0BlGGZnmpwJDPgakn6aNQ0A7gHRbD4I0uvK4TW6UqkK1V0pp9jskjJBAXd3dRrbzWkqJ+6cxA==} + ylru@1.4.0: + resolution: {integrity: sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA==} engines: {node: '>= 4.0.0'} yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - zod@3.22.4: - resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + yoctocolors-cjs@2.1.2: + resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} + engines: {node: '>=18'} + + zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} - zustand@4.5.0: - resolution: {integrity: sha512-zlVFqS5TQ21nwijjhJlx4f9iGrXSL0o/+Dpy4txAP22miJ8Ti6c1Ol1RLNN98BMib83lmDH/2KmLwaNXpjrO1A==} + zustand@4.5.5: + resolution: {integrity: sha512-+0PALYNJNgK6hldkgDq2vLrw5f6g/jCInz52n9RTpropGgeAf/ioFUCdtsjCqu4gNhW9D01rUQBROoRjdzyn2Q==} engines: {node: '>=12.7.0'} peerDependencies: '@types/react': '>=16.8' @@ -5352,767 +5393,678 @@ packages: snapshots: - '@aashutoshrathi/word-wrap@1.2.6': {} - - '@adraffy/ens-normalize@1.10.0': {} + '@adraffy/ens-normalize@1.10.1': {} - '@ampproject/remapping@2.2.1': + '@ampproject/remapping@2.3.0': dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.22 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 - '@babel/code-frame@7.23.5': + '@babel/code-frame@7.25.7': dependencies: - '@babel/highlight': 7.23.4 - chalk: 2.4.2 + '@babel/highlight': 7.25.7 + picocolors: 1.1.1 - '@babel/compat-data@7.23.5': {} + '@babel/compat-data@7.25.8': {} - '@babel/core@7.23.9': + '@babel/core@7.25.8': dependencies: - '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.23.5 - '@babel/generator': 7.23.6 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.9) - '@babel/helpers': 7.23.9 - '@babel/parser': 7.23.9 - '@babel/template': 7.23.9 - '@babel/traverse': 7.23.9 - '@babel/types': 7.23.9 + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.25.7 + '@babel/generator': 7.25.7 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) + '@babel/helpers': 7.25.7 + '@babel/parser': 7.25.8 + '@babel/template': 7.25.7 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 convert-source-map: 2.0.0 - debug: 4.3.4 + debug: 4.3.7 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/generator@7.23.6': + '@babel/generator@7.25.7': dependencies: - '@babel/types': 7.23.6 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.22 - jsesc: 2.5.2 + '@babel/types': 7.25.8 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.0.2 - '@babel/helper-annotate-as-pure@7.22.5': + '@babel/helper-annotate-as-pure@7.25.7': dependencies: - '@babel/types': 7.23.6 + '@babel/types': 7.25.8 - '@babel/helper-builder-binary-assignment-operator-visitor@7.22.15': + '@babel/helper-builder-binary-assignment-operator-visitor@7.25.7': dependencies: - '@babel/types': 7.23.6 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + transitivePeerDependencies: + - supports-color - '@babel/helper-compilation-targets@7.23.6': + '@babel/helper-compilation-targets@7.25.7': dependencies: - '@babel/compat-data': 7.23.5 - '@babel/helper-validator-option': 7.23.5 - browserslist: 4.22.2 + '@babel/compat-data': 7.25.8 + '@babel/helper-validator-option': 7.25.7 + browserslist: 4.24.2 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.23.7(@babel/core@7.23.9)': - dependencies: - '@babel/core': 7.23.9 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-member-expression-to-functions': 7.23.0 - '@babel/helper-optimise-call-expression': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.9) - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-create-class-features-plugin@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-annotate-as-pure': 7.25.7 + '@babel/helper-member-expression-to-functions': 7.25.7 + '@babel/helper-optimise-call-expression': 7.25.7 + '@babel/helper-replace-supers': 7.25.7(@babel/core@7.25.8) + '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 + '@babel/traverse': 7.25.7 semver: 6.3.1 + transitivePeerDependencies: + - supports-color - '@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.23.9)': + '@babel/helper-create-regexp-features-plugin@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-annotate-as-pure': 7.22.5 - regexpu-core: 5.3.2 + '@babel/core': 7.25.8 + '@babel/helper-annotate-as-pure': 7.25.7 + regexpu-core: 6.1.1 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.4.4(@babel/core@7.23.9)': + '@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 - debug: 4.3.4 + '@babel/core': 7.25.8 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + debug: 4.3.7 lodash.debounce: 4.0.8 resolve: 1.22.8 transitivePeerDependencies: - supports-color - '@babel/helper-define-polyfill-provider@0.5.0(@babel/core@7.23.9)': + '@babel/helper-member-expression-to-functions@7.25.7': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 - debug: 4.3.4 - lodash.debounce: 4.0.8 - resolve: 1.22.8 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 transitivePeerDependencies: - supports-color - '@babel/helper-environment-visitor@7.22.20': {} - - '@babel/helper-function-name@7.23.0': - dependencies: - '@babel/template': 7.22.15 - '@babel/types': 7.23.6 - - '@babel/helper-hoist-variables@7.22.5': - dependencies: - '@babel/types': 7.23.6 - - '@babel/helper-member-expression-to-functions@7.23.0': + '@babel/helper-module-imports@7.25.7': dependencies: - '@babel/types': 7.23.6 - - '@babel/helper-module-imports@7.22.15': - dependencies: - '@babel/types': 7.23.6 - - '@babel/helper-module-transforms@7.23.3(@babel/core@7.23.9)': - dependencies: - '@babel/core': 7.23.9 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-module-imports': 7.22.15 - '@babel/helper-simple-access': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/helper-validator-identifier': 7.22.20 - - '@babel/helper-optimise-call-expression@7.22.5': - dependencies: - '@babel/types': 7.23.6 - - '@babel/helper-plugin-utils@7.22.5': {} - - '@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.23.9)': - dependencies: - '@babel/core': 7.23.9 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-wrap-function': 7.22.20 - - '@babel/helper-replace-supers@7.22.20(@babel/core@7.23.9)': - dependencies: - '@babel/core': 7.23.9 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-member-expression-to-functions': 7.23.0 - '@babel/helper-optimise-call-expression': 7.22.5 - - '@babel/helper-simple-access@7.22.5': - dependencies: - '@babel/types': 7.23.9 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + transitivePeerDependencies: + - supports-color - '@babel/helper-skip-transparent-expression-wrappers@7.22.5': + '@babel/helper-module-transforms@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/types': 7.23.6 + '@babel/core': 7.25.8 + '@babel/helper-module-imports': 7.25.7 + '@babel/helper-simple-access': 7.25.7 + '@babel/helper-validator-identifier': 7.25.7 + '@babel/traverse': 7.25.7 + transitivePeerDependencies: + - supports-color - '@babel/helper-split-export-declaration@7.22.6': + '@babel/helper-optimise-call-expression@7.25.7': dependencies: - '@babel/types': 7.23.6 - - '@babel/helper-string-parser@7.23.4': {} + '@babel/types': 7.25.8 - '@babel/helper-validator-identifier@7.22.20': {} - - '@babel/helper-validator-option@7.23.5': {} - - '@babel/helper-wrap-function@7.22.20': - dependencies: - '@babel/helper-function-name': 7.23.0 - '@babel/template': 7.22.15 - '@babel/types': 7.23.6 + '@babel/helper-plugin-utils@7.25.7': {} - '@babel/helpers@7.23.9': + '@babel/helper-remap-async-to-generator@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/template': 7.23.9 - '@babel/traverse': 7.23.9 - '@babel/types': 7.23.9 + '@babel/core': 7.25.8 + '@babel/helper-annotate-as-pure': 7.25.7 + '@babel/helper-wrap-function': 7.25.7 + '@babel/traverse': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/highlight@7.23.4': + '@babel/helper-replace-supers@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/helper-validator-identifier': 7.22.20 - chalk: 2.4.2 - js-tokens: 4.0.0 - - '@babel/parser@7.23.6': - dependencies: - '@babel/types': 7.23.6 - - '@babel/parser@7.23.9': - dependencies: - '@babel/types': 7.23.9 + '@babel/core': 7.25.8 + '@babel/helper-member-expression-to-functions': 7.25.7 + '@babel/helper-optimise-call-expression': 7.25.7 + '@babel/traverse': 7.25.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3(@babel/core@7.23.9)': + '@babel/helper-simple-access@7.25.7': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + transitivePeerDependencies: + - supports-color - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.23.3(@babel/core@7.23.9)': + '@babel/helper-skip-transparent-expression-wrappers@7.25.7': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.23.9) + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + transitivePeerDependencies: + - supports-color - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.23.7(@babel/core@7.23.9)': - dependencies: - '@babel/core': 7.23.9 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-string-parser@7.25.7': {} - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.9)': - dependencies: - '@babel/core': 7.23.9 + '@babel/helper-validator-identifier@7.25.7': {} - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.9)': - dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option@7.25.7': {} - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.9)': + '@babel/helper-wrap-function@7.25.7': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/template': 7.25.7 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + transitivePeerDependencies: + - supports-color - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.23.9)': + '@babel/helpers@7.25.7': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/template': 7.25.7 + '@babel/types': 7.25.8 - '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.23.9)': + '@babel/highlight@7.25.7': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-identifier': 7.25.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.1.1 - '@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.23.9)': + '@babel/parser@7.25.8': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/types': 7.25.8 - '@babel/plugin-syntax-import-assertions@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/traverse': 7.25.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-syntax-import-attributes@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.9)': + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.9)': + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 + '@babel/plugin-transform-optional-chaining': 7.25.8(@babel/core@7.25.8) + transitivePeerDependencies: + - supports-color - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.9)': + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/traverse': 7.25.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.9)': + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.9)': + '@babel/plugin-syntax-import-assertions@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.9)': + '@babel/plugin-syntax-import-attributes@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.9)': + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.9)': + '@babel/plugin-transform-arrow-functions@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.23.9)': + '@babel/plugin-transform-async-generator-functions@7.25.8(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-remap-async-to-generator': 7.25.7(@babel/core@7.25.8) + '@babel/traverse': 7.25.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.9)': + '@babel/plugin-transform-async-to-generator@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-module-imports': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-remap-async-to-generator': 7.25.7(@babel/core@7.25.8) + transitivePeerDependencies: + - supports-color - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.23.9)': + '@babel/plugin-transform-block-scoped-functions@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.9) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-arrow-functions@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-block-scoping@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-async-generator-functions@7.23.7(@babel/core@7.23.9)': + '@babel/plugin-transform-class-properties@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.9) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.9) + '@babel/core': 7.25.8 + '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-async-to-generator@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-class-static-block@7.25.8(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-module-imports': 7.22.15 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.9) + '@babel/core': 7.25.8 + '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-block-scoped-functions@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-classes@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-annotate-as-pure': 7.25.7 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-replace-supers': 7.25.7(@babel/core@7.25.8) + '@babel/traverse': 7.25.7 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-block-scoping@7.23.4(@babel/core@7.23.9)': + '@babel/plugin-transform-computed-properties@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/template': 7.25.7 - '@babel/plugin-transform-class-properties@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-destructuring@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-create-class-features-plugin': 7.23.7(@babel/core@7.23.9) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-class-static-block@7.23.4(@babel/core@7.23.9)': + '@babel/plugin-transform-dotall-regex@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-create-class-features-plugin': 7.23.7(@babel/core@7.23.9) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.9) + '@babel/core': 7.25.8 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-classes@7.23.8(@babel/core@7.23.9)': + '@babel/plugin-transform-duplicate-keys@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.9) - '@babel/helper-split-export-declaration': 7.22.6 - globals: 11.12.0 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-computed-properties@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/template': 7.22.15 + '@babel/core': 7.25.8 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-destructuring@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-dynamic-import@7.25.8(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-dotall-regex@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-exponentiation-operator@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.9) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-duplicate-keys@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-export-namespace-from@7.25.8(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-dynamic-import@7.23.4(@babel/core@7.23.9)': + '@babel/plugin-transform-for-of@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.9) + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-exponentiation-operator@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-function-name@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/traverse': 7.25.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-export-namespace-from@7.23.4(@babel/core@7.23.9)': + '@babel/plugin-transform-json-strings@7.25.8(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.9) + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-for-of@7.23.6(@babel/core@7.23.9)': + '@babel/plugin-transform-literals@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-function-name@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-logical-assignment-operators@7.25.8(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-json-strings@7.23.4(@babel/core@7.23.9)': + '@babel/plugin-transform-member-expression-literals@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.9) + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-literals@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-modules-amd@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-logical-assignment-operators@7.23.4(@babel/core@7.23.9)': + '@babel/plugin-transform-modules-commonjs@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.9) + '@babel/core': 7.25.8 + '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-simple-access': 7.25.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-member-expression-literals@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-modules-systemjs@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-validator-identifier': 7.25.7 + '@babel/traverse': 7.25.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-modules-amd@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-modules-umd@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.9) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-modules-commonjs@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-named-capturing-groups-regex@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.9) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-simple-access': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-modules-systemjs@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-new-target@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.9) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-validator-identifier': 7.22.20 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-modules-umd@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-nullish-coalescing-operator@7.25.8(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.9) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.23.9)': + '@babel/plugin-transform-numeric-separator@7.25.8(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.9) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-new-target@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-object-rest-spread@7.25.8(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/plugin-transform-parameters': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-nullish-coalescing-operator@7.23.4(@babel/core@7.23.9)': + '@babel/plugin-transform-object-super@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.9) + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-replace-supers': 7.25.7(@babel/core@7.25.8) + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-numeric-separator@7.23.4(@babel/core@7.23.9)': + '@babel/plugin-transform-optional-catch-binding@7.25.8(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.9) + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-object-rest-spread@7.23.4(@babel/core@7.23.9)': + '@babel/plugin-transform-optional-chaining@7.25.8(@babel/core@7.25.8)': dependencies: - '@babel/compat-data': 7.23.5 - '@babel/core': 7.23.9 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.9) - '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.23.9) + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-object-super@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-parameters@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.9) + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-optional-catch-binding@7.23.4(@babel/core@7.23.9)': + '@babel/plugin-transform-private-methods@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.9) + '@babel/core': 7.25.8 + '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-optional-chaining@7.23.4(@babel/core@7.23.9)': + '@babel/plugin-transform-private-property-in-object@7.25.8(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.9) + '@babel/core': 7.25.8 + '@babel/helper-annotate-as-pure': 7.25.7 + '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-parameters@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-property-literals@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-private-methods@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-react-jsx-self@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-create-class-features-plugin': 7.23.7(@babel/core@7.23.9) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-private-property-in-object@7.23.4(@babel/core@7.23.9)': + '@babel/plugin-transform-react-jsx-source@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.23.7(@babel/core@7.23.9) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.9) + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-property-literals@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-regenerator@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + regenerator-transform: 0.15.2 - '@babel/plugin-transform-react-jsx-self@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-reserved-words@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-react-jsx-source@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-shorthand-properties@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-regenerator@7.23.3(@babel/core@7.23.9)': + '@babel/plugin-transform-spread@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - regenerator-transform: 0.15.2 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-reserved-words@7.23.3(@babel/core@7.23.9)': - dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - - '@babel/plugin-transform-shorthand-properties@7.23.3(@babel/core@7.23.9)': - dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - - '@babel/plugin-transform-spread@7.23.3(@babel/core@7.23.9)': - dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - - '@babel/plugin-transform-sticky-regex@7.23.3(@babel/core@7.23.9)': - dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - - '@babel/plugin-transform-template-literals@7.23.3(@babel/core@7.23.9)': - dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - - '@babel/plugin-transform-typeof-symbol@7.23.3(@babel/core@7.23.9)': - dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - - '@babel/plugin-transform-unicode-escapes@7.23.3(@babel/core@7.23.9)': - dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - - '@babel/plugin-transform-unicode-property-regex@7.23.3(@babel/core@7.23.9)': - dependencies: - '@babel/core': 7.23.9 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.9) - '@babel/helper-plugin-utils': 7.22.5 - - '@babel/plugin-transform-unicode-regex@7.23.3(@babel/core@7.23.9)': - dependencies: - '@babel/core': 7.23.9 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.9) - '@babel/helper-plugin-utils': 7.22.5 - - '@babel/plugin-transform-unicode-sets-regex@7.23.3(@babel/core@7.23.9)': - dependencies: - '@babel/core': 7.23.9 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.9) - '@babel/helper-plugin-utils': 7.22.5 - - '@babel/preset-env@7.23.8(@babel/core@7.23.9)': - dependencies: - '@babel/compat-data': 7.23.5 - '@babel/core': 7.23.9 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-validator-option': 7.23.5 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.23.7(@babel/core@7.23.9) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.9) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.9) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.9) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.9) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.9) - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.9) - '@babel/plugin-syntax-import-assertions': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-syntax-import-attributes': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.9) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.9) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.9) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.9) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.9) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.9) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.9) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.9) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.9) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.9) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.23.9) - '@babel/plugin-transform-arrow-functions': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-async-generator-functions': 7.23.7(@babel/core@7.23.9) - '@babel/plugin-transform-async-to-generator': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-block-scoped-functions': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-block-scoping': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-class-properties': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-class-static-block': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-classes': 7.23.8(@babel/core@7.23.9) - '@babel/plugin-transform-computed-properties': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-destructuring': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-dotall-regex': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-duplicate-keys': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-dynamic-import': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-exponentiation-operator': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-export-namespace-from': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-for-of': 7.23.6(@babel/core@7.23.9) - '@babel/plugin-transform-function-name': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-json-strings': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-literals': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-logical-assignment-operators': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-member-expression-literals': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-modules-amd': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-modules-systemjs': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-modules-umd': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.23.9) - '@babel/plugin-transform-new-target': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-nullish-coalescing-operator': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-numeric-separator': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-object-rest-spread': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-object-super': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-optional-catch-binding': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-private-methods': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-private-property-in-object': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-property-literals': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-regenerator': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-reserved-words': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-shorthand-properties': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-spread': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-sticky-regex': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-template-literals': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-typeof-symbol': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-unicode-escapes': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-unicode-property-regex': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-unicode-regex': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-unicode-sets-regex': 7.23.3(@babel/core@7.23.9) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.23.9) - babel-plugin-polyfill-corejs2: 0.4.8(@babel/core@7.23.9) - babel-plugin-polyfill-corejs3: 0.8.7(@babel/core@7.23.9) - babel-plugin-polyfill-regenerator: 0.5.5(@babel/core@7.23.9) - core-js-compat: 3.35.1 + '@babel/plugin-transform-sticky-regex@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-template-literals@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-typeof-symbol@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-unicode-escapes@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-unicode-property-regex@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-unicode-regex@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-unicode-sets-regex@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/preset-env@7.25.8(@babel/core@7.25.8)': + dependencies: + '@babel/compat-data': 7.25.8 + '@babel/core': 7.25.8 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-validator-option': 7.25.7 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.8) + '@babel/plugin-syntax-import-assertions': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-syntax-import-attributes': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.25.8) + '@babel/plugin-transform-arrow-functions': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-async-generator-functions': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-async-to-generator': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-block-scoped-functions': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-block-scoping': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-class-properties': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-class-static-block': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-classes': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-computed-properties': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-destructuring': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-dotall-regex': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-duplicate-keys': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-dynamic-import': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-exponentiation-operator': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-export-namespace-from': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-for-of': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-function-name': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-json-strings': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-literals': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-logical-assignment-operators': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-member-expression-literals': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-modules-amd': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-modules-commonjs': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-modules-systemjs': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-modules-umd': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-named-capturing-groups-regex': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-new-target': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-nullish-coalescing-operator': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-numeric-separator': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-object-rest-spread': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-object-super': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-optional-catch-binding': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-optional-chaining': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-parameters': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-private-methods': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-private-property-in-object': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-property-literals': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-regenerator': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-reserved-words': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-shorthand-properties': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-spread': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-sticky-regex': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-template-literals': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-typeof-symbol': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-unicode-escapes': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-unicode-property-regex': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-unicode-regex': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-unicode-sets-regex': 7.25.7(@babel/core@7.25.8) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.25.8) + babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.25.8) + babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.25.8) + babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.25.8) + core-js-compat: 3.38.1 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.23.9)': + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/types': 7.23.6 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/types': 7.25.8 esutils: 2.0.3 - '@babel/regjsgen@0.8.0': {} - - '@babel/runtime@7.23.8': + '@babel/runtime@7.25.7': dependencies: regenerator-runtime: 0.14.1 - '@babel/template@7.22.15': - dependencies: - '@babel/code-frame': 7.23.5 - '@babel/parser': 7.23.6 - '@babel/types': 7.23.6 - - '@babel/template@7.23.9': + '@babel/template@7.25.7': dependencies: - '@babel/code-frame': 7.23.5 - '@babel/parser': 7.23.9 - '@babel/types': 7.23.9 + '@babel/code-frame': 7.25.7 + '@babel/parser': 7.25.8 + '@babel/types': 7.25.8 - '@babel/traverse@7.23.7': + '@babel/traverse@7.25.7': dependencies: - '@babel/code-frame': 7.23.5 - '@babel/generator': 7.23.6 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.6 - '@babel/types': 7.23.6 - debug: 4.3.4 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - - '@babel/traverse@7.23.9': - dependencies: - '@babel/code-frame': 7.23.5 - '@babel/generator': 7.23.6 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.9 - '@babel/types': 7.23.9 - debug: 4.3.4 + '@babel/code-frame': 7.25.7 + '@babel/generator': 7.25.7 + '@babel/parser': 7.25.8 + '@babel/template': 7.25.7 + '@babel/types': 7.25.8 + debug: 4.3.7 globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.23.6': + '@babel/types@7.25.8': dependencies: - '@babel/helper-string-parser': 7.23.4 - '@babel/helper-validator-identifier': 7.22.20 - to-fast-properties: 2.0.0 - - '@babel/types@7.23.9': - dependencies: - '@babel/helper-string-parser': 7.23.4 - '@babel/helper-validator-identifier': 7.22.20 + '@babel/helper-string-parser': 7.25.7 + '@babel/helper-validator-identifier': 7.25.7 to-fast-properties: 2.0.0 '@bundled-es-modules/cookie@2.0.0': @@ -6123,189 +6075,264 @@ snapshots: dependencies: statuses: 2.0.1 - '@csstools/css-parser-algorithms@2.5.0(@csstools/css-tokenizer@2.2.3)': + '@bundled-es-modules/tough-cookie@0.1.6': dependencies: - '@csstools/css-tokenizer': 2.2.3 + '@types/tough-cookie': 4.0.5 + tough-cookie: 4.1.4 - '@csstools/css-tokenizer@2.2.3': {} + '@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1)': + dependencies: + '@csstools/css-tokenizer': 2.4.1 - '@csstools/media-query-list-parser@2.1.7(@csstools/css-parser-algorithms@2.5.0(@csstools/css-tokenizer@2.2.3))(@csstools/css-tokenizer@2.2.3)': + '@csstools/css-tokenizer@2.4.1': {} + + '@csstools/media-query-list-parser@2.1.13(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1)': dependencies: - '@csstools/css-parser-algorithms': 2.5.0(@csstools/css-tokenizer@2.2.3) - '@csstools/css-tokenizer': 2.2.3 + '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) + '@csstools/css-tokenizer': 2.4.1 - '@csstools/selector-specificity@3.0.1(postcss-selector-parser@6.0.15)': + '@csstools/selector-specificity@3.1.1(postcss-selector-parser@6.1.2)': dependencies: - postcss-selector-parser: 6.0.15 + postcss-selector-parser: 6.1.2 - '@emotion/babel-plugin@11.11.0': + '@emotion/babel-plugin@11.12.0': dependencies: - '@babel/helper-module-imports': 7.22.15 - '@babel/runtime': 7.23.8 - '@emotion/hash': 0.9.1 - '@emotion/memoize': 0.8.1 - '@emotion/serialize': 1.1.3 + '@babel/helper-module-imports': 7.25.7 + '@babel/runtime': 7.25.7 + '@emotion/hash': 0.9.2 + '@emotion/memoize': 0.9.0 + '@emotion/serialize': 1.3.2 babel-plugin-macros: 3.1.0 convert-source-map: 1.9.0 escape-string-regexp: 4.0.0 find-root: 1.1.0 source-map: 0.5.7 stylis: 4.2.0 + transitivePeerDependencies: + - supports-color - '@emotion/cache@11.11.0': + '@emotion/cache@11.13.1': dependencies: - '@emotion/memoize': 0.8.1 - '@emotion/sheet': 1.2.2 - '@emotion/utils': 1.2.1 - '@emotion/weak-memoize': 0.3.1 + '@emotion/memoize': 0.9.0 + '@emotion/sheet': 1.4.0 + '@emotion/utils': 1.4.1 + '@emotion/weak-memoize': 0.4.0 stylis: 4.2.0 - '@emotion/hash@0.9.1': {} + '@emotion/hash@0.9.2': {} - '@emotion/is-prop-valid@0.8.8': + '@emotion/is-prop-valid@1.3.1': dependencies: - '@emotion/memoize': 0.7.4 - optional: true - - '@emotion/is-prop-valid@1.2.1': - dependencies: - '@emotion/memoize': 0.8.1 - - '@emotion/memoize@0.7.4': - optional: true + '@emotion/memoize': 0.9.0 - '@emotion/memoize@0.8.1': {} + '@emotion/memoize@0.9.0': {} - '@emotion/react@11.11.3(@types/react@18.2.48)(react@18.2.0)': + '@emotion/react@11.13.3(@types/react@18.3.11)(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.8 - '@emotion/babel-plugin': 11.11.0 - '@emotion/cache': 11.11.0 - '@emotion/serialize': 1.1.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) - '@emotion/utils': 1.2.1 - '@emotion/weak-memoize': 0.3.1 + '@babel/runtime': 7.25.7 + '@emotion/babel-plugin': 11.12.0 + '@emotion/cache': 11.13.1 + '@emotion/serialize': 1.3.2 + '@emotion/use-insertion-effect-with-fallbacks': 1.1.0(react@18.3.1) + '@emotion/utils': 1.4.1 + '@emotion/weak-memoize': 0.4.0 hoist-non-react-statics: 3.3.2 - react: 18.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 18.2.48 + '@types/react': 18.3.11 + transitivePeerDependencies: + - supports-color - '@emotion/serialize@1.1.3': + '@emotion/serialize@1.3.2': dependencies: - '@emotion/hash': 0.9.1 - '@emotion/memoize': 0.8.1 - '@emotion/unitless': 0.8.1 - '@emotion/utils': 1.2.1 + '@emotion/hash': 0.9.2 + '@emotion/memoize': 0.9.0 + '@emotion/unitless': 0.10.0 + '@emotion/utils': 1.4.1 csstype: 3.1.3 - '@emotion/sheet@1.2.2': {} + '@emotion/sheet@1.4.0': {} - '@emotion/styled@11.11.0(@emotion/react@11.11.3(@types/react@18.2.48)(react@18.2.0))(@types/react@18.2.48)(react@18.2.0)': + '@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.11)(react@18.3.1))(@types/react@18.3.11)(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.8 - '@emotion/babel-plugin': 11.11.0 - '@emotion/is-prop-valid': 1.2.1 - '@emotion/react': 11.11.3(@types/react@18.2.48)(react@18.2.0) - '@emotion/serialize': 1.1.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) - '@emotion/utils': 1.2.1 - react: 18.2.0 + '@babel/runtime': 7.25.7 + '@emotion/babel-plugin': 11.12.0 + '@emotion/is-prop-valid': 1.3.1 + '@emotion/react': 11.13.3(@types/react@18.3.11)(react@18.3.1) + '@emotion/serialize': 1.3.2 + '@emotion/use-insertion-effect-with-fallbacks': 1.1.0(react@18.3.1) + '@emotion/utils': 1.4.1 + react: 18.3.1 optionalDependencies: - '@types/react': 18.2.48 + '@types/react': 18.3.11 + transitivePeerDependencies: + - supports-color - '@emotion/unitless@0.8.1': {} + '@emotion/unitless@0.10.0': {} - '@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@18.2.0)': + '@emotion/use-insertion-effect-with-fallbacks@1.1.0(react@18.3.1)': dependencies: - react: 18.2.0 + react: 18.3.1 + + '@emotion/utils@1.4.1': {} - '@emotion/utils@1.2.1': {} + '@emotion/weak-memoize@0.4.0': {} + + '@esbuild/aix-ppc64@0.21.5': + optional: true - '@emotion/weak-memoize@0.3.1': {} + '@esbuild/aix-ppc64@0.24.0': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.24.0': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-arm@0.24.0': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/android-x64@0.24.0': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.24.0': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.24.0': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.24.0': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.24.0': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.24.0': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-arm@0.24.0': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.24.0': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.24.0': + optional: true - '@esbuild/aix-ppc64@0.19.12': + '@esbuild/linux-mips64el@0.21.5': optional: true - '@esbuild/android-arm64@0.19.12': + '@esbuild/linux-mips64el@0.24.0': optional: true - '@esbuild/android-arm@0.19.12': + '@esbuild/linux-ppc64@0.21.5': optional: true - '@esbuild/android-x64@0.19.12': + '@esbuild/linux-ppc64@0.24.0': optional: true - '@esbuild/darwin-arm64@0.19.12': + '@esbuild/linux-riscv64@0.21.5': optional: true - '@esbuild/darwin-x64@0.19.12': + '@esbuild/linux-riscv64@0.24.0': optional: true - '@esbuild/freebsd-arm64@0.19.12': + '@esbuild/linux-s390x@0.21.5': optional: true - '@esbuild/freebsd-x64@0.19.12': + '@esbuild/linux-s390x@0.24.0': optional: true - '@esbuild/linux-arm64@0.19.12': + '@esbuild/linux-x64@0.21.5': optional: true - '@esbuild/linux-arm@0.19.12': + '@esbuild/linux-x64@0.24.0': optional: true - '@esbuild/linux-ia32@0.19.12': + '@esbuild/netbsd-x64@0.21.5': optional: true - '@esbuild/linux-loong64@0.19.12': + '@esbuild/netbsd-x64@0.24.0': optional: true - '@esbuild/linux-mips64el@0.19.12': + '@esbuild/openbsd-arm64@0.24.0': optional: true - '@esbuild/linux-ppc64@0.19.12': + '@esbuild/openbsd-x64@0.21.5': optional: true - '@esbuild/linux-riscv64@0.19.12': + '@esbuild/openbsd-x64@0.24.0': optional: true - '@esbuild/linux-s390x@0.19.12': + '@esbuild/sunos-x64@0.21.5': optional: true - '@esbuild/linux-x64@0.19.12': + '@esbuild/sunos-x64@0.24.0': optional: true - '@esbuild/netbsd-x64@0.19.12': + '@esbuild/win32-arm64@0.21.5': optional: true - '@esbuild/openbsd-x64@0.19.12': + '@esbuild/win32-arm64@0.24.0': optional: true - '@esbuild/sunos-x64@0.19.12': + '@esbuild/win32-ia32@0.21.5': optional: true - '@esbuild/win32-arm64@0.19.12': + '@esbuild/win32-ia32@0.24.0': optional: true - '@esbuild/win32-ia32@0.19.12': + '@esbuild/win32-x64@0.21.5': optional: true - '@esbuild/win32-x64@0.19.12': + '@esbuild/win32-x64@0.24.0': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@8.56.0)': + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.1)': dependencies: - eslint: 8.56.0 + eslint: 8.57.1 eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.10.0': {} + '@eslint-community/regexpp@4.11.1': {} '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 - debug: 4.3.4 + debug: 4.3.7 espree: 9.6.1 globals: 13.24.0 - ignore: 5.3.0 + ignore: 5.3.2 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 @@ -6313,205 +6340,225 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@8.56.0': {} + '@eslint/js@8.57.1': {} - '@floating-ui/core@1.6.0': + '@floating-ui/core@1.6.8': dependencies: - '@floating-ui/utils': 0.2.1 + '@floating-ui/utils': 0.2.8 - '@floating-ui/dom@1.6.0': + '@floating-ui/dom@1.6.11': dependencies: - '@floating-ui/core': 1.6.0 - '@floating-ui/utils': 0.2.1 + '@floating-ui/core': 1.6.8 + '@floating-ui/utils': 0.2.8 - '@floating-ui/react-dom@2.0.7(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@floating-ui/react-dom@2.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@floating-ui/dom': 1.6.0 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + '@floating-ui/dom': 1.6.11 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - '@floating-ui/react@0.26.7(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@floating-ui/react@0.26.25(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@floating-ui/react-dom': 2.0.7(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@floating-ui/utils': 0.2.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@floating-ui/utils': 0.2.8 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) tabbable: 6.2.0 - '@floating-ui/utils@0.2.1': {} + '@floating-ui/utils@0.2.8': {} '@github/webauthn-json@2.1.1': {} - '@hookform/devtools@4.3.1(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@hookform/devtools@4.3.1(@types/react@18.3.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@emotion/react': 11.11.3(@types/react@18.2.48)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.3(@types/react@18.2.48)(react@18.2.0))(@types/react@18.2.48)(react@18.2.0) - '@types/lodash': 4.14.202 - little-state-machine: 4.8.0(react@18.2.0) + '@emotion/react': 11.13.3(@types/react@18.3.11)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.11)(react@18.3.1))(@types/react@18.3.11)(react@18.3.1) + '@types/lodash': 4.17.12 + little-state-machine: 4.8.0(react@18.3.1) lodash: 4.17.21 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-simple-animate: 3.5.2(react-dom@18.2.0(react@18.2.0)) - use-deep-compare-effect: 1.8.1(react@18.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-simple-animate: 3.5.2(react-dom@18.3.1(react@18.3.1)) + use-deep-compare-effect: 1.8.1(react@18.3.1) uuid: 8.3.2 transitivePeerDependencies: - '@types/react' + - supports-color - '@hookform/resolvers@3.3.4(react-hook-form@7.49.3(react@18.2.0))': + '@hookform/resolvers@3.9.0(react-hook-form@7.53.1(react@18.3.1))': dependencies: - react-hook-form: 7.49.3(react@18.2.0) + react-hook-form: 7.53.1(react@18.3.1) - '@humanwhocodes/config-array@0.11.14': + '@humanwhocodes/config-array@0.13.0': dependencies: - '@humanwhocodes/object-schema': 2.0.2 - debug: 4.3.4 + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.3.7 minimatch: 3.1.2 transitivePeerDependencies: - supports-color '@humanwhocodes/module-importer@1.0.1': {} - '@humanwhocodes/object-schema@2.0.2': {} + '@humanwhocodes/object-schema@2.0.3': {} '@hutson/parse-repository-url@3.0.2': {} - '@isaacs/cliui@8.0.2': + '@inquirer/confirm@4.0.1': dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 + '@inquirer/core': 9.2.1 + '@inquirer/type': 2.0.0 + + '@inquirer/core@9.2.1': + dependencies: + '@inquirer/figures': 1.0.7 + '@inquirer/type': 2.0.0 + '@types/mute-stream': 0.0.4 + '@types/node': 22.7.8 + '@types/wrap-ansi': 3.0.0 + ansi-escapes: 4.3.2 + cli-width: 4.1.0 + mute-stream: 1.0.0 + signal-exit: 4.1.0 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.2 + + '@inquirer/figures@1.0.7': {} - '@jridgewell/gen-mapping@0.3.3': + '@inquirer/type@2.0.0': dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.22 + mute-stream: 1.0.0 - '@jridgewell/resolve-uri@3.1.1': {} + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/set-array@1.1.2': {} + '@jridgewell/set-array@1.2.1': {} - '@jridgewell/source-map@0.3.5': + '@jridgewell/source-map@0.3.6': dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.22 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 - '@jridgewell/sourcemap-codec@1.4.15': {} + '@jridgewell/sourcemap-codec@1.5.0': {} - '@jridgewell/trace-mapping@0.3.22': + '@jridgewell/trace-mapping@0.3.25': dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 - '@ladle/react-context@1.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@ladle/react-context@1.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - '@ladle/react@4.0.2(@types/node@20.11.7)(@types/react@18.2.48)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.70.0)(terser@5.27.0)(typescript@5.3.3)': + '@ladle/react@4.1.2(@types/node@20.16.14)(@types/react@18.3.11)(acorn@8.13.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.80.3)(terser@5.36.0)(typescript@5.3.3)': dependencies: - '@babel/code-frame': 7.23.5 - '@babel/core': 7.23.9 - '@babel/generator': 7.23.6 - '@babel/parser': 7.23.6 - '@babel/template': 7.22.15 - '@babel/traverse': 7.23.7 - '@babel/types': 7.23.6 - '@ladle/react-context': 1.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@mdx-js/mdx': 3.0.0 - '@mdx-js/react': 3.0.0(@types/react@18.2.48)(react@18.2.0) - '@vitejs/plugin-react': 4.2.1(vite@5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0)) - '@vitejs/plugin-react-swc': 3.5.0(vite@5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0)) - axe-core: 4.8.3 + '@babel/code-frame': 7.25.7 + '@babel/core': 7.25.8 + '@babel/generator': 7.25.7 + '@babel/parser': 7.25.8 + '@babel/template': 7.25.7 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + '@ladle/react-context': 1.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mdx-js/mdx': 3.1.0(acorn@8.13.0) + '@mdx-js/react': 3.1.0(@types/react@18.3.11)(react@18.3.1) + '@vitejs/plugin-react': 4.3.3(vite@5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0)) + '@vitejs/plugin-react-swc': 3.7.1(vite@5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0)) + axe-core: 4.10.1 boxen: 7.1.1 - chokidar: 3.5.3 + chokidar: 3.6.0 classnames: 2.5.1 - commander: 11.1.0 + commander: 12.1.0 cross-spawn: 7.0.3 - debug: 4.3.4 - get-port: 7.0.0 - globby: 14.0.0 + debug: 4.3.7 + get-port: 7.1.0 + globby: 14.0.2 history: 5.3.0 - koa: 2.15.0 + koa: 2.15.3 koa-connect: 2.1.0 lodash.merge: 4.6.2 - msw: 2.1.4(typescript@5.3.3) - open: 9.1.0 - prism-react-renderer: 2.3.1(react@18.2.0) + msw: 2.4.13(typescript@5.3.3) + open: 10.1.0 + prism-react-renderer: 2.4.0(react@18.3.1) prop-types: 15.8.1 - query-string: 8.1.0 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-hotkeys-hook: 4.4.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react-inspector: 6.0.2(react@18.2.0) - rehype-class-names: 1.0.14 + query-string: 9.1.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-hotkeys-hook: 4.5.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-inspector: 6.0.2(react@18.3.1) + rehype-class-names: 2.0.0 rehype-raw: 7.0.0 remark-gfm: 4.0.0 source-map: 0.7.4 - vfile: 6.0.1 - vite: 5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0) - vite-tsconfig-paths: 4.3.1(typescript@5.3.3)(vite@5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0)) + vfile: 6.0.3 + vite: 5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0) + vite-tsconfig-paths: 4.3.2(typescript@5.3.3)(vite@5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0)) transitivePeerDependencies: - '@swc/helpers' - '@types/node' - '@types/react' + - acorn - less - lightningcss - sass + - sass-embedded - stylus - sugarss - supports-color - terser - typescript - '@mdx-js/mdx@3.0.0': + '@mdx-js/mdx@3.1.0(acorn@8.13.0)': dependencies: - '@types/estree': 1.0.5 - '@types/estree-jsx': 1.0.3 - '@types/hast': 3.0.3 - '@types/mdx': 2.0.10 + '@types/estree': 1.0.6 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.13 collapse-white-space: 2.1.0 devlop: 1.1.0 - estree-util-build-jsx: 3.0.1 estree-util-is-identifier-name: 3.0.0 - estree-util-to-js: 2.0.0 + estree-util-scope: 1.0.0 estree-walker: 3.0.3 - hast-util-to-estree: 3.1.0 - hast-util-to-jsx-runtime: 2.3.0 + hast-util-to-jsx-runtime: 2.3.2 markdown-extensions: 2.0.0 - periscopic: 3.1.0 - remark-mdx: 3.0.0 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.0(acorn@8.13.0) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.0 remark-parse: 11.0.0 - remark-rehype: 11.1.0 + remark-rehype: 11.1.1 source-map: 0.7.4 - unified: 11.0.4 + unified: 11.0.5 unist-util-position-from-estree: 2.0.0 unist-util-stringify-position: 4.0.0 unist-util-visit: 5.0.0 - vfile: 6.0.1 + vfile: 6.0.3 transitivePeerDependencies: + - acorn - supports-color - '@mdx-js/react@3.0.0(@types/react@18.2.48)(react@18.2.0)': + '@mdx-js/react@3.1.0(@types/react@18.3.11)(react@18.3.1)': dependencies: - '@types/mdx': 2.0.10 - '@types/react': 18.2.48 - react: 18.2.0 + '@types/mdx': 2.0.13 + '@types/react': 18.3.11 + react: 18.3.1 '@metamask/detect-provider@2.0.0': {} - '@mswjs/cookies@1.1.0': {} - - '@mswjs/interceptors@0.25.14': + '@mswjs/interceptors@0.36.5': dependencies: '@open-draft/deferred-promise': 2.2.0 '@open-draft/logger': 0.3.0 '@open-draft/until': 2.1.0 is-node-process: 1.2.0 - outvariant: 1.4.2 + outvariant: 1.4.3 strict-event-emitter: 0.5.1 '@noble/curves@1.2.0': @@ -6530,120 +6577,183 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.16.0 + fastq: 1.17.1 '@open-draft/deferred-promise@2.2.0': {} '@open-draft/logger@0.3.0': dependencies: is-node-process: 1.2.0 - outvariant: 1.4.2 + outvariant: 1.4.3 '@open-draft/until@2.1.0': {} - '@pkgjs/parseargs@0.11.0': + '@parcel/watcher-android-arm64@2.4.1': + optional: true + + '@parcel/watcher-darwin-arm64@2.4.1': + optional: true + + '@parcel/watcher-darwin-x64@2.4.1': + optional: true + + '@parcel/watcher-freebsd-x64@2.4.1': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.4.1': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.4.1': optional: true + '@parcel/watcher-linux-arm64-musl@2.4.1': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.4.1': + optional: true + + '@parcel/watcher-linux-x64-musl@2.4.1': + optional: true + + '@parcel/watcher-win32-arm64@2.4.1': + optional: true + + '@parcel/watcher-win32-ia32@2.4.1': + optional: true + + '@parcel/watcher-win32-x64@2.4.1': + optional: true + + '@parcel/watcher@2.4.1': + dependencies: + detect-libc: 1.0.3 + is-glob: 4.0.3 + micromatch: 4.0.8 + node-addon-api: 7.1.1 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.4.1 + '@parcel/watcher-darwin-arm64': 2.4.1 + '@parcel/watcher-darwin-x64': 2.4.1 + '@parcel/watcher-freebsd-x64': 2.4.1 + '@parcel/watcher-linux-arm-glibc': 2.4.1 + '@parcel/watcher-linux-arm64-glibc': 2.4.1 + '@parcel/watcher-linux-arm64-musl': 2.4.1 + '@parcel/watcher-linux-x64-glibc': 2.4.1 + '@parcel/watcher-linux-x64-musl': 2.4.1 + '@parcel/watcher-win32-arm64': 2.4.1 + '@parcel/watcher-win32-ia32': 2.4.1 + '@parcel/watcher-win32-x64': 2.4.1 + '@pkgr/core@0.1.1': {} '@reach/observe-rect@1.2.0': {} - '@react-rxjs/core@0.10.7(react@18.2.0)(rxjs@7.8.1)': + '@react-rxjs/core@0.10.7(react@18.3.1)(rxjs@7.8.1)': dependencies: '@rx-state/core': 0.1.4(rxjs@7.8.1) - react: 18.2.0 + react: 18.3.1 rxjs: 7.8.1 - use-sync-external-store: 1.2.0(react@18.2.0) + use-sync-external-store: 1.2.2(react@18.3.1) - '@remix-run/router@1.14.2': {} + '@remix-run/router@1.20.0': {} '@rollup/pluginutils@4.2.1': dependencies: estree-walker: 2.0.2 picomatch: 2.3.1 + '@rollup/pluginutils@5.1.2(@rollup/wasm-node@4.24.0)': + dependencies: + '@types/estree': 1.0.6 + estree-walker: 2.0.2 + picomatch: 2.3.1 + optionalDependencies: + rollup: '@rollup/wasm-node@4.24.0' + '@rollup/wasm-node@4.24.0': dependencies: '@types/estree': 1.0.6 optionalDependencies: fsevents: 2.3.3 + '@rtsao/scc@1.1.0': {} + '@rx-state/core@0.1.4(rxjs@7.8.1)': dependencies: rxjs: 7.8.1 - '@sindresorhus/merge-streams@1.0.0': {} + '@sindresorhus/merge-streams@2.3.0': {} - '@stablelib/base64@1.0.1': {} + '@stablelib/base64@2.0.0': {} - '@stablelib/binary@1.0.1': + '@stablelib/binary@2.0.0': dependencies: - '@stablelib/int': 1.0.1 + '@stablelib/int': 2.0.0 - '@stablelib/bytes@1.0.1': {} + '@stablelib/bytes@2.0.0': {} - '@stablelib/int@1.0.1': {} + '@stablelib/int@2.0.0': {} - '@stablelib/keyagreement@1.0.1': + '@stablelib/keyagreement@2.0.0': dependencies: - '@stablelib/bytes': 1.0.1 + '@stablelib/bytes': 2.0.0 - '@stablelib/random@1.0.2': + '@stablelib/random@2.0.0': dependencies: - '@stablelib/binary': 1.0.1 - '@stablelib/wipe': 1.0.1 + '@stablelib/binary': 2.0.0 + '@stablelib/wipe': 2.0.0 - '@stablelib/wipe@1.0.1': {} + '@stablelib/wipe@2.0.0': {} - '@stablelib/x25519@1.0.3': + '@stablelib/x25519@2.0.0': dependencies: - '@stablelib/keyagreement': 1.0.1 - '@stablelib/random': 1.0.2 - '@stablelib/wipe': 1.0.1 + '@stablelib/keyagreement': 2.0.0 + '@stablelib/random': 2.0.0 + '@stablelib/wipe': 2.0.0 - '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.23.9)': + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 + '@babel/core': 7.25.8 - '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.23.9)': + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 + '@babel/core': 7.25.8 - '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.23.9)': + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 + '@babel/core': 7.25.8 - '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.23.9)': + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 + '@babel/core': 7.25.8 - '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.23.9)': + '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 + '@babel/core': 7.25.8 - '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.23.9)': + '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 + '@babel/core': 7.25.8 - '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.23.9)': + '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 + '@babel/core': 7.25.8 - '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.23.9)': + '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 + '@babel/core': 7.25.8 - '@svgr/babel-preset@8.1.0(@babel/core@7.23.9)': + '@svgr/babel-preset@8.1.0(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.23.9 - '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.23.9) - '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.23.9) - '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.23.9) - '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.23.9) - '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.23.9) - '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.23.9) - '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.23.9) - '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.23.9) + '@babel/core': 7.25.8 + '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.25.8) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.25.8) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.25.8) + '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.25.8) + '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.25.8) + '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.25.8) + '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.25.8) + '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.25.8) '@svgr/cli@8.1.0(typescript@5.3.3)': dependencies: @@ -6663,8 +6773,8 @@ snapshots: '@svgr/core@8.1.0(typescript@5.3.3)': dependencies: - '@babel/core': 7.23.9 - '@svgr/babel-preset': 8.1.0(@babel/core@7.23.9) + '@babel/core': 7.25.8 + '@svgr/babel-preset': 8.1.0(@babel/core@7.25.8) camelcase: 6.3.0 cosmiconfig: 8.3.6(typescript@5.3.3) snake-case: 3.0.4 @@ -6674,13 +6784,13 @@ snapshots: '@svgr/hast-util-to-babel-ast@8.0.0': dependencies: - '@babel/types': 7.23.6 + '@babel/types': 7.25.8 entities: 4.5.0 '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.3.3))': dependencies: - '@babel/core': 7.23.9 - '@svgr/babel-preset': 8.1.0(@babel/core@7.23.9) + '@babel/core': 7.25.8 + '@svgr/babel-preset': 8.1.0(@babel/core@7.25.8) '@svgr/core': 8.1.0(typescript@5.3.3) '@svgr/hast-util-to-babel-ast': 8.0.0 svg-parser: 2.0.4 @@ -6698,120 +6808,122 @@ snapshots: '@svgr/core': 8.1.0(typescript@5.3.3) cosmiconfig: 8.3.6(typescript@5.3.3) deepmerge: 4.3.1 - svgo: 3.2.0 + svgo: 3.3.2 transitivePeerDependencies: - typescript - '@swc/core-darwin-arm64@1.3.106': + '@swc/core-darwin-arm64@1.7.39': optional: true - '@swc/core-darwin-x64@1.3.106': + '@swc/core-darwin-x64@1.7.39': optional: true - '@swc/core-linux-arm-gnueabihf@1.3.106': + '@swc/core-linux-arm-gnueabihf@1.7.39': optional: true - '@swc/core-linux-arm64-gnu@1.3.106': + '@swc/core-linux-arm64-gnu@1.7.39': optional: true - '@swc/core-linux-arm64-musl@1.3.106': + '@swc/core-linux-arm64-musl@1.7.39': optional: true - '@swc/core-linux-x64-gnu@1.3.106': + '@swc/core-linux-x64-gnu@1.7.39': optional: true - '@swc/core-linux-x64-musl@1.3.106': + '@swc/core-linux-x64-musl@1.7.39': optional: true - '@swc/core-win32-arm64-msvc@1.3.106': + '@swc/core-win32-arm64-msvc@1.7.39': optional: true - '@swc/core-win32-ia32-msvc@1.3.106': + '@swc/core-win32-ia32-msvc@1.7.39': optional: true - '@swc/core-win32-x64-msvc@1.3.106': + '@swc/core-win32-x64-msvc@1.7.39': optional: true - '@swc/core@1.3.106': + '@swc/core@1.7.39': dependencies: - '@swc/counter': 0.1.2 - '@swc/types': 0.1.5 + '@swc/counter': 0.1.3 + '@swc/types': 0.1.13 optionalDependencies: - '@swc/core-darwin-arm64': 1.3.106 - '@swc/core-darwin-x64': 1.3.106 - '@swc/core-linux-arm-gnueabihf': 1.3.106 - '@swc/core-linux-arm64-gnu': 1.3.106 - '@swc/core-linux-arm64-musl': 1.3.106 - '@swc/core-linux-x64-gnu': 1.3.106 - '@swc/core-linux-x64-musl': 1.3.106 - '@swc/core-win32-arm64-msvc': 1.3.106 - '@swc/core-win32-ia32-msvc': 1.3.106 - '@swc/core-win32-x64-msvc': 1.3.106 + '@swc/core-darwin-arm64': 1.7.39 + '@swc/core-darwin-x64': 1.7.39 + '@swc/core-linux-arm-gnueabihf': 1.7.39 + '@swc/core-linux-arm64-gnu': 1.7.39 + '@swc/core-linux-arm64-musl': 1.7.39 + '@swc/core-linux-x64-gnu': 1.7.39 + '@swc/core-linux-x64-musl': 1.7.39 + '@swc/core-win32-arm64-msvc': 1.7.39 + '@swc/core-win32-ia32-msvc': 1.7.39 + '@swc/core-win32-x64-msvc': 1.7.39 - '@swc/counter@0.1.2': {} + '@swc/counter@0.1.3': {} - '@swc/types@0.1.5': {} + '@swc/types@0.1.13': + dependencies: + '@swc/counter': 0.1.3 - '@tanstack/match-sorter-utils@8.11.7': + '@tanstack/match-sorter-utils@8.19.4': dependencies: - remove-accents: 0.4.2 + remove-accents: 0.5.0 '@tanstack/query-core@4.36.1': {} - '@tanstack/react-query-devtools@4.36.1(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@tanstack/react-query-devtools@4.36.1(@tanstack/react-query@4.36.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@tanstack/match-sorter-utils': 8.11.7 - '@tanstack/react-query': 4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + '@tanstack/match-sorter-utils': 8.19.4 + '@tanstack/react-query': 4.36.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) superjson: 1.13.3 - use-sync-external-store: 1.2.0(react@18.2.0) + use-sync-external-store: 1.2.2(react@18.3.1) - '@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@tanstack/react-query@4.36.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@tanstack/query-core': 4.36.1 - react: 18.2.0 - use-sync-external-store: 1.2.0(react@18.2.0) + react: 18.3.1 + use-sync-external-store: 1.2.2(react@18.3.1) optionalDependencies: - react-dom: 18.2.0(react@18.2.0) + react-dom: 18.3.1(react@18.3.1) - '@tanstack/react-virtual@3.0.0-beta.9(react@18.2.0)': + '@tanstack/react-virtual@3.0.0-beta.9(react@18.3.1)': dependencies: '@reach/observe-rect': 1.2.0 - react: 18.2.0 + react: 18.3.1 '@tanstack/virtual-core@3.0.0-beta.9': dependencies: '@reach/observe-rect': 1.2.0 - '@tauri-apps/api@1.5.3': {} + '@tauri-apps/api@1.6.0': {} '@trysound/sax@0.2.0': {} '@types/acorn@4.0.6': dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.23.6 - '@babel/types': 7.23.6 + '@babel/parser': 7.25.8 + '@babel/types': 7.25.8 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.5 + '@types/babel__traverse': 7.20.6 '@types/babel__generator@7.6.8': dependencies: - '@babel/types': 7.23.6 + '@babel/types': 7.25.8 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.23.6 - '@babel/types': 7.23.6 + '@babel/parser': 7.25.8 + '@babel/types': 7.25.8 - '@types/babel__traverse@7.20.5': + '@types/babel__traverse@7.20.6': dependencies: - '@babel/types': 7.23.6 + '@babel/types': 7.25.8 '@types/byte-size@8.1.2': {} @@ -6827,7 +6939,7 @@ snapshots: dependencies: '@types/d3-color': 3.1.3 - '@types/d3-path@3.0.2': {} + '@types/d3-path@3.1.0': {} '@types/d3-scale@4.0.8': dependencies: @@ -6835,7 +6947,7 @@ snapshots: '@types/d3-shape@3.1.6': dependencies: - '@types/d3-path': 3.0.2 + '@types/d3-path': 3.1.0 '@types/d3-time@3.0.3': {} @@ -6845,24 +6957,22 @@ snapshots: dependencies: '@types/ms': 0.7.34 - '@types/eslint@8.56.2': + '@types/eslint@8.56.12': dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 '@types/json-schema': 7.0.15 - '@types/estree-jsx@1.0.3': + '@types/estree-jsx@1.0.5': dependencies: - '@types/estree': 1.0.5 - - '@types/estree@1.0.5': {} + '@types/estree': 1.0.6 '@types/estree@1.0.6': {} '@types/file-saver@2.0.7': {} - '@types/hast@3.0.3': + '@types/hast@3.0.4': dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 '@types/history@4.7.11': {} @@ -6872,192 +6982,202 @@ snapshots: '@types/lodash-es@4.17.12': dependencies: - '@types/lodash': 4.14.202 + '@types/lodash': 4.17.12 - '@types/lodash@4.14.202': {} + '@types/lodash@4.17.12': {} - '@types/mdast@4.0.3': + '@types/mdast@4.0.4': dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 - '@types/mdx@2.0.10': {} + '@types/mdx@2.0.13': {} '@types/minimist@1.2.5': {} '@types/ms@0.7.34': {} - '@types/node@18.15.13': {} + '@types/mute-stream@0.0.4': + dependencies: + '@types/node': 20.16.14 + + '@types/node@20.16.14': + dependencies: + undici-types: 6.19.8 + + '@types/node@22.7.5': + dependencies: + undici-types: 6.19.8 - '@types/node@20.11.7': + '@types/node@22.7.8': dependencies: - undici-types: 5.26.5 + undici-types: 6.19.8 '@types/normalize-package-data@2.4.4': {} '@types/parse-json@4.0.2': {} - '@types/prismjs@1.26.3': {} + '@types/prismjs@1.26.4': {} - '@types/prop-types@15.7.11': {} + '@types/prop-types@15.7.13': {} - '@types/react-dom@18.2.18': + '@types/react-dom@18.3.1': dependencies: - '@types/react': 18.2.48 + '@types/react': 18.3.11 '@types/react-router-dom@5.3.3': dependencies: '@types/history': 4.7.11 - '@types/react': 18.2.48 + '@types/react': 18.3.11 '@types/react-router': 5.1.20 '@types/react-router@5.1.20': dependencies: '@types/history': 4.7.11 - '@types/react': 18.2.48 + '@types/react': 18.3.11 '@types/react-virtualized-auto-sizer@1.0.4': dependencies: - '@types/react': 18.2.48 + '@types/react': 18.3.11 '@types/react-window@1.8.8': dependencies: - '@types/react': 18.2.48 + '@types/react': 18.3.11 - '@types/react@18.2.48': + '@types/react@18.3.11': dependencies: - '@types/prop-types': 15.7.11 - '@types/scheduler': 0.16.8 + '@types/prop-types': 15.7.13 csstype: 3.1.3 - '@types/scheduler@0.16.8': {} + '@types/semver@7.5.8': {} - '@types/semver@7.5.6': {} + '@types/statuses@2.0.5': {} - '@types/statuses@2.0.4': {} + '@types/tough-cookie@4.0.5': {} - '@types/unist@2.0.10': {} + '@types/unist@2.0.11': {} - '@types/unist@3.0.2': {} + '@types/unist@3.0.3': {} - '@typescript-eslint/eslint-plugin@6.19.1(@typescript-eslint/parser@6.19.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3)': + '@types/wrap-ansi@3.0.0': {} + + '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3)': dependencies: - '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 6.19.1(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/scope-manager': 6.19.1 - '@typescript-eslint/type-utils': 6.19.1(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/utils': 6.19.1(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/visitor-keys': 6.19.1 - debug: 4.3.4 - eslint: 8.56.0 + '@eslint-community/regexpp': 4.11.1 + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.3.3) + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.1)(typescript@5.3.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.3.7 + eslint: 8.57.1 graphemer: 1.4.0 - ignore: 5.3.0 + ignore: 5.3.2 natural-compare: 1.4.0 - semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@5.3.3) + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.3.3) optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@6.19.1(eslint@8.56.0)(typescript@5.3.3)': + '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3)': dependencies: - '@typescript-eslint/scope-manager': 6.19.1 - '@typescript-eslint/types': 6.19.1 - '@typescript-eslint/typescript-estree': 6.19.1(typescript@5.3.3) - '@typescript-eslint/visitor-keys': 6.19.1 - debug: 4.3.4 - eslint: 8.56.0 + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.3.7 + eslint: 8.57.1 optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@6.19.1': + '@typescript-eslint/scope-manager@6.21.0': dependencies: - '@typescript-eslint/types': 6.19.1 - '@typescript-eslint/visitor-keys': 6.19.1 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 - '@typescript-eslint/type-utils@6.19.1(eslint@8.56.0)(typescript@5.3.3)': + '@typescript-eslint/type-utils@6.21.0(eslint@8.57.1)(typescript@5.3.3)': dependencies: - '@typescript-eslint/typescript-estree': 6.19.1(typescript@5.3.3) - '@typescript-eslint/utils': 6.19.1(eslint@8.56.0)(typescript@5.3.3) - debug: 4.3.4 - eslint: 8.56.0 - ts-api-utils: 1.0.3(typescript@5.3.3) + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.3.3) + debug: 4.3.7 + eslint: 8.57.1 + ts-api-utils: 1.3.0(typescript@5.3.3) optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@6.19.1': {} + '@typescript-eslint/types@6.21.0': {} - '@typescript-eslint/typescript-estree@6.19.1(typescript@5.3.3)': + '@typescript-eslint/typescript-estree@6.21.0(typescript@5.3.3)': dependencies: - '@typescript-eslint/types': 6.19.1 - '@typescript-eslint/visitor-keys': 6.19.1 - debug: 4.3.4 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.3.7 globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 - semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@5.3.3) + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.3.3) optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@6.19.1(eslint@8.56.0)(typescript@5.3.3)': + '@typescript-eslint/utils@6.21.0(eslint@8.57.1)(typescript@5.3.3)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) '@types/json-schema': 7.0.15 - '@types/semver': 7.5.6 - '@typescript-eslint/scope-manager': 6.19.1 - '@typescript-eslint/types': 6.19.1 - '@typescript-eslint/typescript-estree': 6.19.1(typescript@5.3.3) - eslint: 8.56.0 - semver: 7.5.4 + '@types/semver': 7.5.8 + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) + eslint: 8.57.1 + semver: 7.6.3 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/visitor-keys@6.19.1': + '@typescript-eslint/visitor-keys@6.21.0': dependencies: - '@typescript-eslint/types': 6.19.1 + '@typescript-eslint/types': 6.21.0 eslint-visitor-keys: 3.4.3 '@ungap/structured-clone@1.2.0': {} - '@vitejs/plugin-legacy@5.3.0(esbuild@0.19.12)(terser@5.27.0)(vite@5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0))': + '@vitejs/plugin-legacy@5.4.2(terser@5.36.0)(vite@5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0))': dependencies: - '@babel/core': 7.23.9 - '@babel/preset-env': 7.23.8(@babel/core@7.23.9) - browserslist: 4.22.2 - core-js: 3.35.1 - esbuild-plugin-browserslist: 0.10.0(browserslist@4.22.2)(esbuild@0.19.12) - magic-string: 0.30.5 + '@babel/core': 7.25.8 + '@babel/preset-env': 7.25.8(@babel/core@7.25.8) + browserslist: 4.24.2 + browserslist-to-esbuild: 2.1.1(browserslist@4.24.2) + core-js: 3.38.1 + magic-string: 0.30.12 regenerator-runtime: 0.14.1 - systemjs: 6.14.3 - terser: 5.27.0 - vite: 5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0) + systemjs: 6.15.1 + terser: 5.36.0 + vite: 5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0) transitivePeerDependencies: - - esbuild - supports-color - '@vitejs/plugin-react-swc@3.5.0(vite@5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0))': + '@vitejs/plugin-react-swc@3.7.1(vite@5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0))': dependencies: - '@swc/core': 1.3.106 - vite: 5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0) + '@swc/core': 1.7.39 + vite: 5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0) transitivePeerDependencies: - '@swc/helpers' - '@vitejs/plugin-react@4.2.1(vite@5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0))': + '@vitejs/plugin-react@4.3.3(vite@5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0))': dependencies: - '@babel/core': 7.23.9 - '@babel/plugin-transform-react-jsx-self': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.9) + '@babel/core': 7.25.8 + '@babel/plugin-transform-react-jsx-self': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-react-jsx-source': 7.25.7(@babel/core@7.25.8) '@types/babel__core': 7.20.5 - react-refresh: 0.14.0 - vite: 5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0) + react-refresh: 0.14.2 + vite: 5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0) transitivePeerDependencies: - supports-color @@ -7071,11 +7191,11 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 - acorn-jsx@5.3.2(acorn@8.11.3): + acorn-jsx@5.3.2(acorn@8.13.0): dependencies: - acorn: 8.11.3 + acorn: 8.13.0 - acorn@8.11.3: {} + acorn@8.13.0: {} add-stream@1.0.0: {} @@ -7088,12 +7208,12 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 - ajv@8.12.0: + ajv@8.17.1: dependencies: fast-deep-equal: 3.1.3 + fast-uri: 3.0.3 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - uri-js: 4.4.1 ansi-align@3.0.1: dependencies: @@ -7105,7 +7225,7 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.0.1: {} + ansi-regex@6.1.0: {} ansi-sequence-parser@1.1.1: {} @@ -7126,66 +7246,76 @@ snapshots: argparse@2.0.1: {} - aria-query@5.3.0: - dependencies: - dequal: 2.0.3 + aria-query@5.3.2: {} - array-buffer-byte-length@1.0.0: + array-buffer-byte-length@1.0.1: dependencies: - call-bind: 1.0.5 - is-array-buffer: 3.0.2 + call-bind: 1.0.7 + is-array-buffer: 3.0.4 array-ify@1.0.0: {} - array-includes@3.1.7: + array-includes@3.1.8: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 - get-intrinsic: 1.2.2 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 is-string: 1.0.7 array-union@2.1.0: {} - array.prototype.findlastindex@1.2.3: + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + + array.prototype.findlastindex@1.2.5: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 es-shim-unscopables: 1.0.2 - get-intrinsic: 1.2.2 array.prototype.flat@1.3.2: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.23.3 es-shim-unscopables: 1.0.2 array.prototype.flatmap@1.3.2: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.23.3 es-shim-unscopables: 1.0.2 - array.prototype.tosorted@1.1.2: + array.prototype.tosorted@1.1.4: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.23.3 + es-errors: 1.3.0 es-shim-unscopables: 1.0.2 - get-intrinsic: 1.2.2 - arraybuffer.prototype.slice@1.0.2: + arraybuffer.prototype.slice@1.0.3: dependencies: - array-buffer-byte-length: 1.0.0 - call-bind: 1.0.5 + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 - get-intrinsic: 1.2.2 - is-array-buffer: 3.0.2 - is-shared-array-buffer: 1.0.2 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 arrify@1.0.1: {} @@ -7193,69 +7323,63 @@ snapshots: astral-regex@2.0.0: {} - astring@1.8.6: {} - - asynciterator.prototype@1.0.0: - dependencies: - has-symbols: 1.0.3 + astring@1.9.0: {} asynckit@0.4.0: {} - autoprefixer@10.4.17(postcss@8.4.33): + autoprefixer@10.4.20(postcss@8.4.47): dependencies: - browserslist: 4.22.2 - caniuse-lite: 1.0.30001580 + browserslist: 4.24.2 + caniuse-lite: 1.0.30001669 fraction.js: 4.3.7 normalize-range: 0.1.2 - picocolors: 1.0.0 - postcss: 8.4.33 + picocolors: 1.1.1 + postcss: 8.4.47 postcss-value-parser: 4.2.0 - available-typed-arrays@1.0.5: {} - - axe-core@4.7.0: {} + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 - axe-core@4.8.3: {} + axe-core@4.10.1: {} - axios@1.6.7: + axios@1.7.7: dependencies: - follow-redirects: 1.15.5 - form-data: 4.0.0 + follow-redirects: 1.15.9 + form-data: 4.0.1 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug - axobject-query@3.2.1: - dependencies: - dequal: 2.0.3 + axobject-query@4.1.0: {} babel-plugin-macros@3.1.0: dependencies: - '@babel/runtime': 7.23.8 + '@babel/runtime': 7.25.7 cosmiconfig: 7.1.0 resolve: 1.22.8 - babel-plugin-polyfill-corejs2@0.4.8(@babel/core@7.23.9): + babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.25.8): dependencies: - '@babel/compat-data': 7.23.5 - '@babel/core': 7.23.9 - '@babel/helper-define-polyfill-provider': 0.5.0(@babel/core@7.23.9) + '@babel/compat-data': 7.25.8 + '@babel/core': 7.25.8 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.8) semver: 6.3.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.8.7(@babel/core@7.23.9): + babel-plugin-polyfill-corejs3@0.10.6(@babel/core@7.25.8): dependencies: - '@babel/core': 7.23.9 - '@babel/helper-define-polyfill-provider': 0.4.4(@babel/core@7.23.9) - core-js-compat: 3.35.1 + '@babel/core': 7.25.8 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.8) + core-js-compat: 3.38.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.5.5(@babel/core@7.23.9): + babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.25.8): dependencies: - '@babel/core': 7.23.9 - '@babel/helper-define-polyfill-provider': 0.5.0(@babel/core@7.23.9) + '@babel/core': 7.25.8 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.8) transitivePeerDependencies: - supports-color @@ -7265,21 +7389,11 @@ snapshots: balanced-match@2.0.0: {} - base64-js@1.5.1: {} - bcp-47-match@2.0.3: {} - big-integer@1.6.52: {} - bignumber.js@9.1.2: {} - binary-extensions@2.2.0: {} - - bl@4.1.0: - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 + binary-extensions@2.3.0: {} boolbase@1.0.0: {} @@ -7294,10 +7408,6 @@ snapshots: widest-line: 4.0.1 wrap-ansi: 8.1.0 - bplist-parser@0.2.0: - dependencies: - big-integer: 1.6.52 - brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -7311,36 +7421,38 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.22.2: + browserslist-to-esbuild@2.1.1(browserslist@4.24.2): dependencies: - caniuse-lite: 1.0.30001580 - electron-to-chromium: 1.4.645 - node-releases: 2.0.14 - update-browserslist-db: 1.0.13(browserslist@4.22.2) - - buffer-from@1.1.2: {} + browserslist: 4.24.2 + meow: 13.2.0 - buffer@5.7.1: + browserslist@4.24.2: dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 + caniuse-lite: 1.0.30001669 + electron-to-chromium: 1.5.42 + node-releases: 2.0.18 + update-browserslist-db: 1.1.1(browserslist@4.24.2) + + buffer-from@1.1.2: {} - bundle-name@3.0.0: + bundle-name@4.1.0: dependencies: - run-applescript: 5.0.0 + run-applescript: 7.0.0 - byte-size@8.1.1: {} + byte-size@9.0.0: {} cache-content-type@1.0.1: dependencies: mime-types: 2.1.35 - ylru: 1.3.2 + ylru: 1.4.0 - call-bind@1.0.5: + call-bind@1.0.7: dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 function-bind: 1.1.2 - get-intrinsic: 1.2.2 - set-function-length: 1.2.0 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 callsites@3.1.0: {} @@ -7356,7 +7468,7 @@ snapshots: camelcase@7.0.1: {} - caniuse-lite@1.0.30001580: {} + caniuse-lite@1.0.30001669: {} ccount@2.0.1: {} @@ -7381,9 +7493,7 @@ snapshots: character-reference-invalid@2.0.1: {} - chardet@0.7.0: {} - - chokidar@3.5.3: + chokidar@3.6.0: dependencies: anymatch: 3.1.3 braces: 3.0.3 @@ -7395,17 +7505,15 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + chokidar@4.0.1: + dependencies: + readdirp: 4.0.2 + classnames@2.5.1: {} cli-boxes@3.0.0: {} - cli-cursor@3.1.0: - dependencies: - restore-cursor: 3.1.0 - - cli-spinners@2.9.2: {} - - cli-width@3.0.0: {} + cli-width@4.1.0: {} cliui@6.0.0: dependencies: @@ -7425,9 +7533,7 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 - clone@1.0.4: {} - - clsx@2.1.0: {} + clsx@2.1.1: {} co@4.6.0: {} @@ -7453,7 +7559,7 @@ snapshots: comma-separated-tokens@2.0.3: {} - commander@11.1.0: {} + commander@12.1.0: {} commander@2.20.3: {} @@ -7475,14 +7581,12 @@ snapshots: readable-stream: 3.6.2 typedarray: 0.0.6 - concurrently@8.2.2: + concurrently@9.0.1: dependencies: chalk: 4.1.2 - date-fns: 2.30.0 lodash: 4.17.21 rxjs: 7.8.1 shell-quote: 1.8.1 - spawn-command: 0.0.2 supports-color: 8.1.1 tree-kill: 1.2.2 yargs: 17.7.2 @@ -7620,11 +7724,11 @@ snapshots: dependencies: is-what: 4.1.16 - core-js-compat@3.35.1: + core-js-compat@3.38.1: dependencies: - browserslist: 4.22.2 + browserslist: 4.24.2 - core-js@3.35.1: {} + core-js@3.38.1: {} core-util-is@1.0.3: {} @@ -7660,7 +7764,7 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - css-functions-list@3.2.1: {} + css-functions-list@3.2.3: {} css-select@5.1.0: dependencies: @@ -7670,17 +7774,22 @@ snapshots: domutils: 3.1.0 nth-check: 2.1.1 - css-selector-parser@3.0.4: {} + css-selector-parser@3.0.5: {} css-tree@2.2.1: dependencies: mdn-data: 2.0.28 - source-map-js: 1.0.2 + source-map-js: 1.2.1 css-tree@2.3.1: dependencies: mdn-data: 2.0.30 - source-map-js: 1.0.2 + source-map-js: 1.2.1 + + css-tree@3.0.0: + dependencies: + mdn-data: 2.10.0 + source-map-js: 1.2.1 css-what@6.1.0: {} @@ -7736,21 +7845,35 @@ snapshots: dashify@2.0.0: {} - date-fns@2.30.0: + data-view-buffer@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-length@1.0.1: dependencies: - '@babel/runtime': 7.23.8 + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-offset@1.0.0: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 dateformat@3.0.3: {} - dayjs@1.11.10: {} + dayjs@1.11.13: {} debug@3.2.7: dependencies: ms: 2.1.3 - debug@4.3.4: + debug@4.3.7: dependencies: - ms: 2.1.2 + ms: 2.1.3 decamelize-keys@1.1.1: dependencies: @@ -7773,34 +7896,25 @@ snapshots: deepmerge@4.3.1: {} - default-browser-id@3.0.0: - dependencies: - bplist-parser: 0.2.0 - untildify: 4.0.0 - - default-browser@4.0.0: - dependencies: - bundle-name: 3.0.0 - default-browser-id: 3.0.0 - execa: 7.2.0 - titleize: 3.0.0 + default-browser-id@5.0.0: {} - defaults@1.0.4: + default-browser@5.2.1: dependencies: - clone: 1.0.4 + bundle-name: 4.1.0 + default-browser-id: 5.0.0 - define-data-property@1.1.1: + define-data-property@1.1.4: dependencies: - get-intrinsic: 1.2.2 + es-define-property: 1.0.0 + es-errors: 1.3.0 gopd: 1.0.1 - has-property-descriptors: 1.0.1 define-lazy-prop@3.0.0: {} define-properties@1.2.1: dependencies: - define-data-property: 1.1.1 - has-property-descriptors: 1.0.1 + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 object-keys: 1.1.1 delayed-stream@1.0.0: {} @@ -7819,6 +7933,8 @@ snapshots: detect-indent@6.1.0: {} + detect-libc@1.0.3: {} + detect-newline@3.1.0: {} devlop@1.1.0: @@ -7841,9 +7957,10 @@ snapshots: dependencies: esutils: 2.0.3 - dom-helpers@3.4.0: + dom-helpers@5.2.1: dependencies: - '@babel/runtime': 7.23.8 + '@babel/runtime': 7.25.7 + csstype: 3.1.3 dom-serializer@2.0.0: dependencies: @@ -7866,7 +7983,7 @@ snapshots: dot-case@3.0.4: dependencies: no-case: 3.0.4 - tslib: 2.6.2 + tslib: 2.8.0 dot-prop@5.3.0: dependencies: @@ -7881,14 +7998,12 @@ snapshots: ee-first@1.1.1: {} - electron-to-chromium@1.4.645: {} + electron-to-chromium@1.5.42: {} emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} - encode-utf8@1.0.3: {} - encodeurl@1.0.2: {} entities@4.5.0: {} @@ -7899,74 +8014,91 @@ snapshots: dependencies: is-arrayish: 0.2.1 - es-abstract@1.22.3: - dependencies: - array-buffer-byte-length: 1.0.0 - arraybuffer.prototype.slice: 1.0.2 - available-typed-arrays: 1.0.5 - call-bind: 1.0.5 - es-set-tostringtag: 2.0.2 + es-abstract@1.23.3: + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 es-to-primitive: 1.2.1 function.prototype.name: 1.1.6 - get-intrinsic: 1.2.2 - get-symbol-description: 1.0.0 - globalthis: 1.0.3 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.4 gopd: 1.0.1 - has-property-descriptors: 1.0.1 - has-proto: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 has-symbols: 1.0.3 - hasown: 2.0.0 - internal-slot: 1.0.6 - is-array-buffer: 3.0.2 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 is-callable: 1.2.7 - is-negative-zero: 2.0.2 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 is-regex: 1.1.4 - is-shared-array-buffer: 1.0.2 + is-shared-array-buffer: 1.0.3 is-string: 1.0.7 - is-typed-array: 1.1.12 + is-typed-array: 1.1.13 is-weakref: 1.0.2 - object-inspect: 1.13.1 + object-inspect: 1.13.2 object-keys: 1.1.1 object.assign: 4.1.5 - regexp.prototype.flags: 1.5.1 - safe-array-concat: 1.1.0 - safe-regex-test: 1.0.2 - string.prototype.trim: 1.2.8 - string.prototype.trimend: 1.0.7 - string.prototype.trimstart: 1.0.7 - typed-array-buffer: 1.0.0 - typed-array-byte-length: 1.0.0 - typed-array-byte-offset: 1.0.0 - typed-array-length: 1.0.4 + regexp.prototype.flags: 1.5.3 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 unbox-primitive: 1.0.2 - which-typed-array: 1.1.13 + which-typed-array: 1.1.15 + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 - es-iterator-helpers@1.0.15: + es-errors@1.3.0: {} + + es-iterator-helpers@1.1.0: dependencies: - asynciterator.prototype: 1.0.0 - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 - es-set-tostringtag: 2.0.2 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-set-tostringtag: 2.0.3 function-bind: 1.1.2 - get-intrinsic: 1.2.2 - globalthis: 1.0.3 - has-property-descriptors: 1.0.1 - has-proto: 1.0.1 + get-intrinsic: 1.2.4 + globalthis: 1.0.4 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 has-symbols: 1.0.3 - internal-slot: 1.0.6 - iterator.prototype: 1.1.2 - safe-array-concat: 1.1.0 + internal-slot: 1.0.7 + iterator.prototype: 1.1.3 + safe-array-concat: 1.1.2 + + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 - es-set-tostringtag@2.0.2: + es-set-tostringtag@2.0.3: dependencies: - get-intrinsic: 1.2.2 - has-tostringtag: 1.0.0 - hasown: 2.0.0 + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 es-shim-unscopables@1.0.2: dependencies: - hasown: 2.0.0 + hasown: 2.0.2 es-to-primitive@1.2.1: dependencies: @@ -7974,42 +8106,74 @@ snapshots: is-date-object: 1.0.5 is-symbol: 1.0.4 - esbuild-plugin-browserslist@0.10.0(browserslist@4.22.2)(esbuild@0.19.12): + esast-util-from-estree@2.0.0: dependencies: - browserslist: 4.22.2 - debug: 4.3.4 - esbuild: 0.19.12 - zod: 3.22.4 - transitivePeerDependencies: - - supports-color + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 - esbuild@0.19.12: + esast-util-from-js@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + acorn: 8.13.0 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.2 + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + esbuild@0.24.0: optionalDependencies: - '@esbuild/aix-ppc64': 0.19.12 - '@esbuild/android-arm': 0.19.12 - '@esbuild/android-arm64': 0.19.12 - '@esbuild/android-x64': 0.19.12 - '@esbuild/darwin-arm64': 0.19.12 - '@esbuild/darwin-x64': 0.19.12 - '@esbuild/freebsd-arm64': 0.19.12 - '@esbuild/freebsd-x64': 0.19.12 - '@esbuild/linux-arm': 0.19.12 - '@esbuild/linux-arm64': 0.19.12 - '@esbuild/linux-ia32': 0.19.12 - '@esbuild/linux-loong64': 0.19.12 - '@esbuild/linux-mips64el': 0.19.12 - '@esbuild/linux-ppc64': 0.19.12 - '@esbuild/linux-riscv64': 0.19.12 - '@esbuild/linux-s390x': 0.19.12 - '@esbuild/linux-x64': 0.19.12 - '@esbuild/netbsd-x64': 0.19.12 - '@esbuild/openbsd-x64': 0.19.12 - '@esbuild/sunos-x64': 0.19.12 - '@esbuild/win32-arm64': 0.19.12 - '@esbuild/win32-ia32': 0.19.12 - '@esbuild/win32-x64': 0.19.12 - - escalade@3.1.1: {} + '@esbuild/aix-ppc64': 0.24.0 + '@esbuild/android-arm': 0.24.0 + '@esbuild/android-arm64': 0.24.0 + '@esbuild/android-x64': 0.24.0 + '@esbuild/darwin-arm64': 0.24.0 + '@esbuild/darwin-x64': 0.24.0 + '@esbuild/freebsd-arm64': 0.24.0 + '@esbuild/freebsd-x64': 0.24.0 + '@esbuild/linux-arm': 0.24.0 + '@esbuild/linux-arm64': 0.24.0 + '@esbuild/linux-ia32': 0.24.0 + '@esbuild/linux-loong64': 0.24.0 + '@esbuild/linux-mips64el': 0.24.0 + '@esbuild/linux-ppc64': 0.24.0 + '@esbuild/linux-riscv64': 0.24.0 + '@esbuild/linux-s390x': 0.24.0 + '@esbuild/linux-x64': 0.24.0 + '@esbuild/netbsd-x64': 0.24.0 + '@esbuild/openbsd-arm64': 0.24.0 + '@esbuild/openbsd-x64': 0.24.0 + '@esbuild/sunos-x64': 0.24.0 + '@esbuild/win32-arm64': 0.24.0 + '@esbuild/win32-ia32': 0.24.0 + '@esbuild/win32-x64': 0.24.0 + + escalade@3.2.0: {} escape-html@1.0.3: {} @@ -8019,116 +8183,120 @@ snapshots: escape-string-regexp@5.0.0: {} - eslint-config-prettier@9.1.0(eslint@8.56.0): + eslint-config-prettier@9.1.0(eslint@8.57.1): dependencies: - eslint: 8.56.0 + eslint: 8.57.1 eslint-import-resolver-node@0.3.9: dependencies: debug: 3.2.7 - is-core-module: 2.13.1 + is-core-module: 2.15.1 resolve: 1.22.8 transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.0(@typescript-eslint/parser@6.19.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@8.56.0): + eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 6.19.1(eslint@8.56.0)(typescript@5.3.3) - eslint: 8.56.0 + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.3.3) + eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.19.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1): dependencies: - array-includes: 3.1.7 - array.prototype.findlastindex: 1.2.3 + '@rtsao/scc': 1.1.0 + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 array.prototype.flat: 1.3.2 array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 - eslint: 8.56.0 + eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.19.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@8.56.0) - hasown: 2.0.0 - is-core-module: 2.13.1 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) + hasown: 2.0.2 + is-core-module: 2.15.1 is-glob: 4.0.3 minimatch: 3.1.2 - object.fromentries: 2.0.7 - object.groupby: 1.0.1 - object.values: 1.1.7 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.0 semver: 6.3.1 + string.prototype.trimend: 1.0.8 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 6.19.1(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.3.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-jsx-a11y@6.8.0(eslint@8.56.0): + eslint-plugin-jsx-a11y@6.10.1(eslint@8.57.1): dependencies: - '@babel/runtime': 7.23.8 - aria-query: 5.3.0 - array-includes: 3.1.7 + aria-query: 5.3.2 + array-includes: 3.1.8 array.prototype.flatmap: 1.3.2 ast-types-flow: 0.0.8 - axe-core: 4.7.0 - axobject-query: 3.2.1 + axe-core: 4.10.1 + axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - es-iterator-helpers: 1.0.15 - eslint: 8.56.0 - hasown: 2.0.0 + es-iterator-helpers: 1.1.0 + eslint: 8.57.1 + hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 minimatch: 3.1.2 - object.entries: 1.1.7 - object.fromentries: 2.0.7 + object.fromentries: 2.0.8 + safe-regex-test: 1.0.3 + string.prototype.includes: 2.0.1 - eslint-plugin-prettier@5.1.3(@types/eslint@8.56.2)(eslint-config-prettier@9.1.0(eslint@8.56.0))(eslint@8.56.0)(prettier@3.2.4): + eslint-plugin-prettier@5.2.1(@types/eslint@8.56.12)(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.3.3): dependencies: - eslint: 8.56.0 - prettier: 3.2.4 + eslint: 8.57.1 + prettier: 3.3.3 prettier-linter-helpers: 1.0.0 - synckit: 0.8.8 + synckit: 0.9.2 optionalDependencies: - '@types/eslint': 8.56.2 - eslint-config-prettier: 9.1.0(eslint@8.56.0) + '@types/eslint': 8.56.12 + eslint-config-prettier: 9.1.0(eslint@8.57.1) - eslint-plugin-react-hooks@4.6.0(eslint@8.56.0): + eslint-plugin-react-hooks@4.6.2(eslint@8.57.1): dependencies: - eslint: 8.56.0 + eslint: 8.57.1 - eslint-plugin-react-refresh@0.4.5(eslint@8.56.0): + eslint-plugin-react-refresh@0.4.13(eslint@8.57.1): dependencies: - eslint: 8.56.0 + eslint: 8.57.1 - eslint-plugin-react@7.33.2(eslint@8.56.0): + eslint-plugin-react@7.37.1(eslint@8.57.1): dependencies: - array-includes: 3.1.7 + array-includes: 3.1.8 + array.prototype.findlast: 1.2.5 array.prototype.flatmap: 1.3.2 - array.prototype.tosorted: 1.1.2 + array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 - es-iterator-helpers: 1.0.15 - eslint: 8.56.0 + es-iterator-helpers: 1.1.0 + eslint: 8.57.1 estraverse: 5.3.0 + hasown: 2.0.2 jsx-ast-utils: 3.3.5 minimatch: 3.1.2 - object.entries: 1.1.7 - object.fromentries: 2.0.7 - object.hasown: 1.1.3 - object.values: 1.1.7 + object.entries: 1.1.8 + object.fromentries: 2.0.8 + object.values: 1.2.0 prop-types: 15.8.1 resolve: 2.0.0-next.5 semver: 6.3.1 - string.prototype.matchall: 4.0.10 + string.prototype.matchall: 4.0.11 + string.prototype.repeat: 1.0.0 - eslint-plugin-simple-import-sort@10.0.0(eslint@8.56.0): + eslint-plugin-simple-import-sort@10.0.0(eslint@8.57.1): dependencies: - eslint: 8.56.0 + eslint: 8.57.1 eslint-scope@7.2.2: dependencies: @@ -8137,26 +8305,26 @@ snapshots: eslint-visitor-keys@3.4.3: {} - eslint@8.56.0: + eslint@8.57.1: dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) - '@eslint-community/regexpp': 4.10.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + '@eslint-community/regexpp': 4.11.1 '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.56.0 - '@humanwhocodes/config-array': 0.11.14 + '@eslint/js': 8.57.1 + '@humanwhocodes/config-array': 0.13.0 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 '@ungap/structured-clone': 1.2.0 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4 + debug: 4.3.7 doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 - esquery: 1.5.0 + esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 6.0.1 @@ -8164,7 +8332,7 @@ snapshots: glob-parent: 6.0.2 globals: 13.24.0 graphemer: 1.4.0 - ignore: 5.3.0 + ignore: 5.3.2 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 @@ -8174,7 +8342,7 @@ snapshots: lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 - optionator: 0.9.3 + optionator: 0.9.4 strip-ansi: 6.0.1 text-table: 0.2.0 transitivePeerDependencies: @@ -8182,11 +8350,11 @@ snapshots: espree@9.6.1: dependencies: - acorn: 8.11.3 - acorn-jsx: 5.3.2(acorn@8.11.3) + acorn: 8.13.0 + acorn-jsx: 5.3.2(acorn@8.13.0) eslint-visitor-keys: 3.4.3 - esquery@1.5.0: + esquery@1.6.0: dependencies: estraverse: 5.3.0 @@ -8198,45 +8366,50 @@ snapshots: estree-util-attach-comments@3.0.0: dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 estree-util-build-jsx@3.0.1: dependencies: - '@types/estree-jsx': 1.0.3 + '@types/estree-jsx': 1.0.5 devlop: 1.1.0 estree-util-is-identifier-name: 3.0.0 estree-walker: 3.0.3 estree-util-is-identifier-name@3.0.0: {} + estree-util-scope@1.0.0: + dependencies: + '@types/estree': 1.0.6 + devlop: 1.1.0 + estree-util-to-js@2.0.0: dependencies: - '@types/estree-jsx': 1.0.3 - astring: 1.8.6 + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 source-map: 0.7.4 estree-util-visit@2.0.0: dependencies: - '@types/estree-jsx': 1.0.3 - '@types/unist': 3.0.2 + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 estree-walker@2.0.2: {} estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 esutils@2.0.3: {} - ethers@6.10.0: + ethers@6.13.4: dependencies: - '@adraffy/ens-normalize': 1.10.0 + '@adraffy/ens-normalize': 1.10.1 '@noble/curves': 1.2.0 '@noble/hashes': 1.3.2 - '@types/node': 18.15.13 + '@types/node': 22.7.5 aes-js: 4.0.0-beta.5 - tslib: 2.4.0 - ws: 8.5.0 + tslib: 2.7.0 + ws: 8.17.1 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -8245,38 +8418,8 @@ snapshots: events@3.3.0: {} - execa@5.1.1: - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - - execa@7.2.0: - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 4.3.1 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.2.0 - onetime: 6.0.0 - signal-exit: 3.0.7 - strip-final-newline: 3.0.0 - extend@3.0.2: {} - external-editor@3.1.0: - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 - fast-deep-equal@3.1.3: {} fast-diff@1.3.0: {} @@ -8289,15 +8432,17 @@ snapshots: '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 - micromatch: 4.0.5 + micromatch: 4.0.8 fast-json-stable-stringify@2.1.0: {} fast-levenshtein@2.0.6: {} + fast-uri@3.0.3: {} + fastest-levenshtein@1.0.16: {} - fastq@1.16.0: + fastq@1.17.1: dependencies: reusify: 1.0.4 @@ -8311,7 +8456,7 @@ snapshots: file-entry-cache@8.0.0: dependencies: - flat-cache: 4.0.0 + flat-cache: 4.0.1 file-saver@2.0.5: {} @@ -8343,30 +8488,24 @@ snapshots: flat-cache@3.2.0: dependencies: - flatted: 3.2.9 + flatted: 3.3.1 keyv: 4.5.4 rimraf: 3.0.2 - flat-cache@4.0.0: + flat-cache@4.0.1: dependencies: - flatted: 3.2.9 + flatted: 3.3.1 keyv: 4.5.4 - rimraf: 5.0.5 - flatted@3.2.9: {} + flatted@3.3.1: {} - follow-redirects@1.15.5: {} + follow-redirects@1.15.9: {} for-each@0.3.3: dependencies: is-callable: 1.2.7 - foreground-child@3.1.1: - dependencies: - cross-spawn: 7.0.3 - signal-exit: 4.1.0 - - form-data@4.0.0: + form-data@4.0.1: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 @@ -8374,13 +8513,13 @@ snapshots: fraction.js@4.3.7: {} - framer-motion@11.0.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + framer-motion@11.11.9(@emotion/is-prop-valid@1.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - tslib: 2.6.2 + tslib: 2.8.0 optionalDependencies: - '@emotion/is-prop-valid': 0.8.8 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + '@emotion/is-prop-valid': 1.3.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) fresh@0.5.2: {} @@ -8393,9 +8532,9 @@ snapshots: function.prototype.name@1.1.6: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.23.3 functions-have-names: 1.2.3 functions-have-names@1.2.3: {} @@ -8404,12 +8543,13 @@ snapshots: get-caller-file@2.0.5: {} - get-intrinsic@1.2.2: + get-intrinsic@1.2.4: dependencies: + es-errors: 1.3.0 function-bind: 1.1.2 - has-proto: 1.0.1 + has-proto: 1.0.3 has-symbols: 1.0.3 - hasown: 2.0.0 + hasown: 2.0.2 get-pkg-repo@4.2.1: dependencies: @@ -8418,14 +8558,13 @@ snapshots: through2: 2.0.5 yargs: 16.2.0 - get-port@7.0.0: {} - - get-stream@6.0.1: {} + get-port@7.1.0: {} - get-symbol-description@1.0.0: + get-symbol-description@1.0.2: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 get-text-width@1.0.3: {} @@ -8459,14 +8598,6 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@10.3.10: - dependencies: - foreground-child: 3.1.1 - jackspeak: 2.3.6 - minimatch: 9.0.3 - minipass: 7.0.4 - path-scurry: 1.10.1 - glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -8500,24 +8631,25 @@ snapshots: dependencies: type-fest: 0.20.2 - globalthis@1.0.3: + globalthis@1.0.4: dependencies: define-properties: 1.2.1 + gopd: 1.0.1 globby@11.1.0: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 fast-glob: 3.3.2 - ignore: 5.3.0 + ignore: 5.3.2 merge2: 1.4.1 slash: 3.0.0 - globby@14.0.0: + globby@14.0.2: dependencies: - '@sindresorhus/merge-streams': 1.0.0 + '@sindresorhus/merge-streams': 2.3.0 fast-glob: 3.3.2 - ignore: 5.3.0 + ignore: 5.3.2 path-type: 5.0.0 slash: 5.1.0 unicorn-magic: 0.1.0 @@ -8528,13 +8660,13 @@ snapshots: gopd@1.0.1: dependencies: - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 graceful-fs@4.2.11: {} graphemer@1.4.0: {} - graphql@16.8.1: {} + graphql@16.9.0: {} handlebars@4.7.8: dependencies: @@ -8543,7 +8675,7 @@ snapshots: source-map: 0.6.1 wordwrap: 1.0.0 optionalDependencies: - uglify-js: 3.17.4 + uglify-js: 3.19.3 hard-rejection@2.1.0: {} @@ -8553,95 +8685,94 @@ snapshots: has-flag@4.0.0: {} - has-property-descriptors@1.0.1: + has-property-descriptors@1.0.2: dependencies: - get-intrinsic: 1.2.2 + es-define-property: 1.0.0 - has-proto@1.0.1: {} + has-proto@1.0.3: {} has-symbols@1.0.3: {} - has-tostringtag@1.0.0: + has-tostringtag@1.0.2: dependencies: has-symbols: 1.0.3 - hasown@2.0.0: + hasown@2.0.2: dependencies: function-bind: 1.1.2 hast-util-classnames@3.0.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 space-separated-tokens: 2.0.2 hast-util-from-parse5@8.0.1: dependencies: - '@types/hast': 3.0.3 - '@types/unist': 3.0.2 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 devlop: 1.1.0 hastscript: 8.0.0 - property-information: 6.4.1 - vfile: 6.0.1 - vfile-location: 5.0.2 + property-information: 6.5.0 + vfile: 6.0.3 + vfile-location: 5.0.3 web-namespaces: 2.0.1 hast-util-has-property@3.0.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 hast-util-parse-selector@4.0.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 - hast-util-raw@9.0.2: + hast-util-raw@9.0.4: dependencies: - '@types/hast': 3.0.3 - '@types/unist': 3.0.2 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 '@ungap/structured-clone': 1.2.0 hast-util-from-parse5: 8.0.1 hast-util-to-parse5: 8.0.0 html-void-elements: 3.0.0 - mdast-util-to-hast: 13.1.0 - parse5: 7.1.2 + mdast-util-to-hast: 13.2.0 + parse5: 7.2.0 unist-util-position: 5.0.0 unist-util-visit: 5.0.0 - vfile: 6.0.1 + vfile: 6.0.3 web-namespaces: 2.0.1 zwitch: 2.0.4 - hast-util-select@6.0.2: + hast-util-select@6.0.3: dependencies: - '@types/hast': 3.0.3 - '@types/unist': 3.0.2 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 bcp-47-match: 2.0.3 comma-separated-tokens: 2.0.3 - css-selector-parser: 3.0.4 + css-selector-parser: 3.0.5 devlop: 1.1.0 direction: 2.0.1 hast-util-has-property: 3.0.0 - hast-util-to-string: 3.0.0 + hast-util-to-string: 3.0.1 hast-util-whitespace: 3.0.0 - not: 0.1.0 nth-check: 2.1.1 - property-information: 6.4.1 + property-information: 6.5.0 space-separated-tokens: 2.0.2 unist-util-visit: 5.0.0 zwitch: 2.0.4 hast-util-to-estree@3.1.0: dependencies: - '@types/estree': 1.0.5 - '@types/estree-jsx': 1.0.3 - '@types/hast': 3.0.3 + '@types/estree': 1.0.6 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 comma-separated-tokens: 2.0.3 devlop: 1.1.0 estree-util-attach-comments: 3.0.0 estree-util-is-identifier-name: 3.0.0 hast-util-whitespace: 3.0.0 - mdast-util-mdx-expression: 2.0.0 - mdast-util-mdx-jsx: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.1.3 mdast-util-mdxjs-esm: 2.0.1 - property-information: 6.4.1 + property-information: 6.5.0 space-separated-tokens: 2.0.2 style-to-object: 0.4.4 unist-util-position: 5.0.0 @@ -8649,21 +8780,21 @@ snapshots: transitivePeerDependencies: - supports-color - hast-util-to-jsx-runtime@2.3.0: + hast-util-to-jsx-runtime@2.3.2: dependencies: - '@types/estree': 1.0.5 - '@types/hast': 3.0.3 - '@types/unist': 3.0.2 + '@types/estree': 1.0.6 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 comma-separated-tokens: 2.0.3 devlop: 1.1.0 estree-util-is-identifier-name: 3.0.0 hast-util-whitespace: 3.0.0 - mdast-util-mdx-expression: 2.0.0 - mdast-util-mdx-jsx: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.1.3 mdast-util-mdxjs-esm: 2.0.1 - property-information: 6.4.1 + property-information: 6.5.0 space-separated-tokens: 2.0.2 - style-to-object: 1.0.5 + style-to-object: 1.0.8 unist-util-position: 5.0.0 vfile-message: 4.0.2 transitivePeerDependencies: @@ -8671,37 +8802,37 @@ snapshots: hast-util-to-parse5@8.0.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 comma-separated-tokens: 2.0.3 devlop: 1.1.0 - property-information: 6.4.1 + property-information: 6.5.0 space-separated-tokens: 2.0.2 web-namespaces: 2.0.1 zwitch: 2.0.4 - hast-util-to-string@3.0.0: + hast-util-to-string@3.0.1: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 hast-util-whitespace@3.0.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 hastscript@8.0.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 comma-separated-tokens: 2.0.3 hast-util-parse-selector: 4.0.0 - property-information: 6.4.1 + property-information: 6.5.0 space-separated-tokens: 2.0.2 - headers-polyfill@4.0.2: {} + headers-polyfill@4.0.3: {} hex-rgb@5.0.0: {} history@5.3.0: dependencies: - '@babel/runtime': 7.23.8 + '@babel/runtime': 7.25.7 hoist-non-react-statics@3.3.2: dependencies: @@ -8713,22 +8844,24 @@ snapshots: dependencies: lru-cache: 6.0.0 - html-dom-parser@5.0.7: + html-dom-parser@5.0.10: dependencies: domhandler: 5.0.3 htmlparser2: 9.1.0 - html-react-parser@5.1.1(react@18.2.0): + html-react-parser@5.1.18(@types/react@18.3.11)(react@18.3.1): dependencies: domhandler: 5.0.3 - html-dom-parser: 5.0.7 - react: 18.2.0 + html-dom-parser: 5.0.10 + react: 18.3.1 react-property: 2.0.2 - style-to-js: 1.1.10 + style-to-js: 1.1.16 + optionalDependencies: + '@types/react': 18.3.11 html-tags@3.3.1: {} - html-url-attributes@3.0.0: {} + html-url-attributes@3.0.1: {} html-void-elements@3.0.0: {} @@ -8752,19 +8885,9 @@ snapshots: statuses: 1.5.0 toidentifier: 1.0.1 - human-signals@2.1.0: {} - - human-signals@4.3.1: {} + ignore@5.3.2: {} - iconv-lite@0.4.24: - dependencies: - safer-buffer: 2.1.2 - - ieee754@1.2.1: {} - - ignore@5.3.0: {} - - immutable@4.3.4: {} + immutable@4.3.7: {} import-fresh@3.3.0: dependencies: @@ -8786,31 +8909,13 @@ snapshots: inline-style-parser@0.1.1: {} - inline-style-parser@0.2.2: {} - - inquirer@8.2.6: - dependencies: - ansi-escapes: 4.3.2 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-width: 3.0.0 - external-editor: 3.1.0 - figures: 3.2.0 - lodash: 4.17.21 - mute-stream: 0.0.8 - ora: 5.4.1 - run-async: 2.4.1 - rxjs: 7.8.1 - string-width: 4.2.3 - strip-ansi: 6.0.1 - through: 2.3.8 - wrap-ansi: 6.2.0 + inline-style-parser@0.2.4: {} - internal-slot@1.0.6: + internal-slot@1.0.7: dependencies: - get-intrinsic: 1.2.2 - hasown: 2.0.0 - side-channel: 1.0.4 + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.6 internmap@2.0.3: {} @@ -8821,17 +8926,16 @@ snapshots: is-alphabetical: 2.0.1 is-decimal: 2.0.1 - is-array-buffer@3.0.2: + is-array-buffer@3.0.4: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 - is-typed-array: 1.1.12 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 is-arrayish@0.2.1: {} is-async-function@2.0.0: dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-bigint@1.0.4: dependencies: @@ -8839,42 +8943,42 @@ snapshots: is-binary-path@2.1.0: dependencies: - binary-extensions: 2.2.0 + binary-extensions: 2.3.0 is-boolean-object@1.1.2: dependencies: - call-bind: 1.0.5 - has-tostringtag: 1.0.0 - - is-buffer@2.0.5: {} + call-bind: 1.0.7 + has-tostringtag: 1.0.2 is-callable@1.2.7: {} - is-core-module@2.13.1: + is-core-module@2.15.1: dependencies: - hasown: 2.0.0 + hasown: 2.0.2 + + is-data-view@1.0.1: + dependencies: + is-typed-array: 1.1.13 is-date-object@1.0.5: dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-decimal@2.0.1: {} - is-docker@2.2.1: {} - is-docker@3.0.0: {} is-extglob@2.1.1: {} is-finalizationregistry@1.0.2: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 is-fullwidth-code-point@3.0.0: {} is-generator-function@1.0.10: dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-glob@4.0.3: dependencies: @@ -8886,17 +8990,15 @@ snapshots: dependencies: is-docker: 3.0.0 - is-interactive@1.0.0: {} - - is-map@2.0.2: {} + is-map@2.0.3: {} - is-negative-zero@2.0.2: {} + is-negative-zero@2.0.3: {} is-node-process@1.2.0: {} is-number-object@1.0.7: dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-number@7.0.0: {} @@ -8910,28 +9012,20 @@ snapshots: is-plain-object@5.0.0: {} - is-reference@3.0.2: - dependencies: - '@types/estree': 1.0.5 - is-regex@1.1.4: dependencies: - call-bind: 1.0.5 - has-tostringtag: 1.0.0 + call-bind: 1.0.7 + has-tostringtag: 1.0.2 - is-set@2.0.2: {} + is-set@2.0.3: {} - is-shared-array-buffer@1.0.2: + is-shared-array-buffer@1.0.3: dependencies: - call-bind: 1.0.5 - - is-stream@2.0.1: {} - - is-stream@3.0.0: {} + call-bind: 1.0.7 is-string@1.0.7: dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-symbol@1.0.4: dependencies: @@ -8941,28 +9035,26 @@ snapshots: dependencies: text-extensions: 1.9.0 - is-typed-array@1.1.12: + is-typed-array@1.1.13: dependencies: - which-typed-array: 1.1.13 + which-typed-array: 1.1.15 - is-unicode-supported@0.1.0: {} - - is-weakmap@2.0.1: {} + is-weakmap@2.0.2: {} is-weakref@1.0.2: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 - is-weakset@2.0.2: + is-weakset@2.0.3: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 is-what@4.1.16: {} - is-wsl@2.2.0: + is-wsl@3.1.0: dependencies: - is-docker: 2.2.1 + is-inside-container: 1.0.0 isarray@1.0.0: {} @@ -8970,21 +9062,15 @@ snapshots: isexe@2.0.0: {} - iterator.prototype@1.1.2: + iterator.prototype@1.1.3: dependencies: define-properties: 1.2.1 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 - reflect.getprototypeof: 1.0.4 - set-function-name: 2.0.1 + reflect.getprototypeof: 1.0.6 + set-function-name: 2.0.2 - itertools@2.2.3: {} - - jackspeak@2.3.6: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 + itertools@2.3.2: {} js-tokens@4.0.0: {} @@ -8992,9 +9078,7 @@ snapshots: dependencies: argparse: 2.0.1 - jsesc@0.5.0: {} - - jsesc@2.5.2: {} + jsesc@3.0.2: {} json-buffer@3.0.1: {} @@ -9016,16 +9100,16 @@ snapshots: json5@2.2.3: {} - jsonc-parser@3.2.1: {} + jsonc-parser@3.3.1: {} jsonparse@1.3.1: {} jsx-ast-utils@3.3.5: dependencies: - array-includes: 3.1.7 + array-includes: 3.1.8 array.prototype.flat: 1.3.2 object.assign: 4.1.5 - object.values: 1.1.7 + object.values: 1.2.0 keygrip@1.1.0: dependencies: @@ -9039,6 +9123,8 @@ snapshots: known-css-properties@0.29.0: {} + known-css-properties@0.34.0: {} + koa-compose@4.1.0: {} koa-connect@2.1.0: {} @@ -9048,14 +9134,14 @@ snapshots: co: 4.6.0 koa-compose: 4.1.0 - koa@2.15.0: + koa@2.15.3: dependencies: accepts: 1.3.8 cache-content-type: 1.0.1 content-disposition: 0.5.4 content-type: 1.0.5 cookies: 0.9.1 - debug: 4.3.4 + debug: 4.3.7 delegates: 1.0.0 depd: 2.0.0 destroy: 1.2.0 @@ -9076,11 +9162,11 @@ snapshots: transitivePeerDependencies: - supports-color - language-subtag-registry@0.3.22: {} + language-subtag-registry@0.3.23: {} language-tags@1.0.9: dependencies: - language-subtag-registry: 0.3.22 + language-subtag-registry: 0.3.23 levn@0.4.1: dependencies: @@ -9089,9 +9175,9 @@ snapshots: lines-and-columns@1.2.4: {} - little-state-machine@4.8.0(react@18.2.0): + little-state-machine@4.8.0(react@18.3.1): dependencies: - react: 18.2.0 + react: 18.3.1 load-json-file@4.0.0: dependencies: @@ -9130,11 +9216,6 @@ snapshots: lodash@4.17.21: {} - log-symbols@4.1.0: - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 - longest-streak@3.1.0: {} loose-envify@1.4.0: @@ -9143,9 +9224,7 @@ snapshots: lower-case@2.0.2: dependencies: - tslib: 2.6.2 - - lru-cache@10.1.0: {} + tslib: 2.8.0 lru-cache@5.1.1: dependencies: @@ -9157,9 +9236,9 @@ snapshots: lunr@2.3.9: {} - magic-string@0.30.5: + magic-string@0.30.12: dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/sourcemap-codec': 1.5.0 map-obj@1.0.1: {} @@ -9175,15 +9254,15 @@ snapshots: mdast-util-find-and-replace@3.0.1: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 escape-string-regexp: 5.0.0 unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 - mdast-util-from-markdown@2.0.0: + mdast-util-from-markdown@2.0.1: dependencies: - '@types/mdast': 4.0.3 - '@types/unist': 3.0.2 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 decode-named-character-reference: 1.0.2 devlop: 1.1.0 mdast-util-to-string: 4.0.0 @@ -9197,19 +9276,19 @@ snapshots: transitivePeerDependencies: - supports-color - mdast-util-gfm-autolink-literal@2.0.0: + mdast-util-gfm-autolink-literal@2.0.1: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 ccount: 2.0.1 devlop: 1.1.0 mdast-util-find-and-replace: 3.0.1 - micromark-util-character: 2.0.1 + micromark-util-character: 2.1.0 mdast-util-gfm-footnote@2.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.0 + mdast-util-from-markdown: 2.0.1 mdast-util-to-markdown: 2.1.0 micromark-util-normalize-identifier: 2.0.0 transitivePeerDependencies: @@ -9217,35 +9296,35 @@ snapshots: mdast-util-gfm-strikethrough@2.0.0: dependencies: - '@types/mdast': 4.0.3 - mdast-util-from-markdown: 2.0.0 + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.1 mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: - supports-color mdast-util-gfm-table@2.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 devlop: 1.1.0 markdown-table: 3.0.3 - mdast-util-from-markdown: 2.0.0 + mdast-util-from-markdown: 2.0.1 mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: - supports-color mdast-util-gfm-task-list-item@2.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.0 + mdast-util-from-markdown: 2.0.1 mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: - supports-color mdast-util-gfm@3.0.0: dependencies: - mdast-util-from-markdown: 2.0.0 - mdast-util-gfm-autolink-literal: 2.0.0 + mdast-util-from-markdown: 2.0.1 + mdast-util-gfm-autolink-literal: 2.0.1 mdast-util-gfm-footnote: 2.0.0 mdast-util-gfm-strikethrough: 2.0.0 mdast-util-gfm-table: 2.0.0 @@ -9254,30 +9333,29 @@ snapshots: transitivePeerDependencies: - supports-color - mdast-util-mdx-expression@2.0.0: + mdast-util-mdx-expression@2.0.1: dependencies: - '@types/estree-jsx': 1.0.3 - '@types/hast': 3.0.3 - '@types/mdast': 4.0.3 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.0 + mdast-util-from-markdown: 2.0.1 mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: - supports-color - mdast-util-mdx-jsx@3.0.0: + mdast-util-mdx-jsx@3.1.3: dependencies: - '@types/estree-jsx': 1.0.3 - '@types/hast': 3.0.3 - '@types/mdast': 4.0.3 - '@types/unist': 3.0.2 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 ccount: 2.0.1 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.0 + mdast-util-from-markdown: 2.0.1 mdast-util-to-markdown: 2.1.0 parse-entities: 4.0.1 - stringify-entities: 4.0.3 - unist-util-remove-position: 5.0.0 + stringify-entities: 4.0.4 unist-util-stringify-position: 4.0.0 vfile-message: 4.0.2 transitivePeerDependencies: @@ -9285,9 +9363,9 @@ snapshots: mdast-util-mdx@3.0.0: dependencies: - mdast-util-from-markdown: 2.0.0 - mdast-util-mdx-expression: 2.0.0 - mdast-util-mdx-jsx: 3.0.0 + mdast-util-from-markdown: 2.0.1 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.1.3 mdast-util-mdxjs-esm: 2.0.1 mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: @@ -9295,38 +9373,38 @@ snapshots: mdast-util-mdxjs-esm@2.0.1: dependencies: - '@types/estree-jsx': 1.0.3 - '@types/hast': 3.0.3 - '@types/mdast': 4.0.3 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.0 + mdast-util-from-markdown: 2.0.1 mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: - supports-color - mdast-util-phrasing@4.0.0: + mdast-util-phrasing@4.1.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 unist-util-is: 6.0.0 - mdast-util-to-hast@13.1.0: + mdast-util-to-hast@13.2.0: dependencies: - '@types/hast': 3.0.3 - '@types/mdast': 4.0.3 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 '@ungap/structured-clone': 1.2.0 devlop: 1.1.0 micromark-util-sanitize-uri: 2.0.0 trim-lines: 3.0.1 unist-util-position: 5.0.0 unist-util-visit: 5.0.0 - vfile: 6.0.1 + vfile: 6.0.3 mdast-util-to-markdown@2.1.0: dependencies: - '@types/mdast': 4.0.3 - '@types/unist': 3.0.2 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 longest-streak: 3.1.0 - mdast-util-phrasing: 4.0.0 + mdast-util-phrasing: 4.1.0 mdast-util-to-string: 4.0.0 micromark-util-decode-string: 2.0.0 unist-util-visit: 5.0.0 @@ -9334,17 +9412,21 @@ snapshots: mdast-util-to-string@4.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 mdn-data@2.0.28: {} mdn-data@2.0.30: {} + mdn-data@2.10.0: {} + + mdn-data@2.11.1: {} + media-typer@0.3.0: {} memoize-one@5.2.1: {} - meow@13.1.0: {} + meow@13.2.0: {} meow@8.1.2: dependencies: @@ -9360,11 +9442,9 @@ snapshots: type-fest: 0.18.1 yargs-parser: 20.2.9 - merge-stream@2.0.0: {} - merge2@1.4.1: {} - micromark-core-commonmark@2.0.0: + micromark-core-commonmark@2.0.1: dependencies: decode-named-character-reference: 1.0.2 devlop: 1.1.0 @@ -9373,35 +9453,35 @@ snapshots: micromark-factory-space: 2.0.0 micromark-factory-title: 2.0.0 micromark-factory-whitespace: 2.0.0 - micromark-util-character: 2.0.1 + micromark-util-character: 2.1.0 micromark-util-chunked: 2.0.0 micromark-util-classify-character: 2.0.0 micromark-util-html-tag-name: 2.0.0 micromark-util-normalize-identifier: 2.0.0 micromark-util-resolve-all: 2.0.0 - micromark-util-subtokenize: 2.0.0 + micromark-util-subtokenize: 2.0.1 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - micromark-extension-gfm-autolink-literal@2.0.0: + micromark-extension-gfm-autolink-literal@2.1.0: dependencies: - micromark-util-character: 2.0.1 + micromark-util-character: 2.1.0 micromark-util-sanitize-uri: 2.0.0 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - micromark-extension-gfm-footnote@2.0.0: + micromark-extension-gfm-footnote@2.1.0: dependencies: devlop: 1.1.0 - micromark-core-commonmark: 2.0.0 + micromark-core-commonmark: 2.0.1 micromark-factory-space: 2.0.0 - micromark-util-character: 2.0.1 + micromark-util-character: 2.1.0 micromark-util-normalize-identifier: 2.0.0 micromark-util-sanitize-uri: 2.0.0 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - micromark-extension-gfm-strikethrough@2.0.0: + micromark-extension-gfm-strikethrough@2.1.0: dependencies: devlop: 1.1.0 micromark-util-chunked: 2.0.0 @@ -9410,11 +9490,11 @@ snapshots: micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - micromark-extension-gfm-table@2.0.0: + micromark-extension-gfm-table@2.1.0: dependencies: devlop: 1.1.0 micromark-factory-space: 2.0.0 - micromark-util-character: 2.0.1 + micromark-util-character: 2.1.0 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 @@ -9422,45 +9502,46 @@ snapshots: dependencies: micromark-util-types: 2.0.0 - micromark-extension-gfm-task-list-item@2.0.1: + micromark-extension-gfm-task-list-item@2.1.0: dependencies: devlop: 1.1.0 micromark-factory-space: 2.0.0 - micromark-util-character: 2.0.1 + micromark-util-character: 2.1.0 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 micromark-extension-gfm@3.0.0: dependencies: - micromark-extension-gfm-autolink-literal: 2.0.0 - micromark-extension-gfm-footnote: 2.0.0 - micromark-extension-gfm-strikethrough: 2.0.0 - micromark-extension-gfm-table: 2.0.0 + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.0 micromark-extension-gfm-tagfilter: 2.0.0 - micromark-extension-gfm-task-list-item: 2.0.1 + micromark-extension-gfm-task-list-item: 2.1.0 micromark-util-combine-extensions: 2.0.0 micromark-util-types: 2.0.0 micromark-extension-mdx-expression@3.0.0: dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 devlop: 1.1.0 - micromark-factory-mdx-expression: 2.0.1 + micromark-factory-mdx-expression: 2.0.2 micromark-factory-space: 2.0.0 - micromark-util-character: 2.0.1 + micromark-util-character: 2.1.0 micromark-util-events-to-acorn: 2.0.2 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - micromark-extension-mdx-jsx@3.0.0: + micromark-extension-mdx-jsx@3.0.1: dependencies: '@types/acorn': 4.0.6 - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 devlop: 1.1.0 estree-util-is-identifier-name: 3.0.0 - micromark-factory-mdx-expression: 2.0.1 + micromark-factory-mdx-expression: 2.0.2 micromark-factory-space: 2.0.0 - micromark-util-character: 2.0.1 + micromark-util-character: 2.1.0 + micromark-util-events-to-acorn: 2.0.2 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 vfile-message: 4.0.2 @@ -9471,10 +9552,10 @@ snapshots: micromark-extension-mdxjs-esm@3.0.0: dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 devlop: 1.1.0 - micromark-core-commonmark: 2.0.0 - micromark-util-character: 2.0.1 + micromark-core-commonmark: 2.0.1 + micromark-util-character: 2.1.0 micromark-util-events-to-acorn: 2.0.2 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 @@ -9483,10 +9564,10 @@ snapshots: micromark-extension-mdxjs@3.0.0: dependencies: - acorn: 8.11.3 - acorn-jsx: 5.3.2(acorn@8.11.3) + acorn: 8.13.0 + acorn-jsx: 5.3.2(acorn@8.13.0) micromark-extension-mdx-expression: 3.0.0 - micromark-extension-mdx-jsx: 3.0.0 + micromark-extension-mdx-jsx: 3.0.1 micromark-extension-mdx-md: 2.0.0 micromark-extension-mdxjs-esm: 3.0.0 micromark-util-combine-extensions: 2.0.0 @@ -9494,22 +9575,23 @@ snapshots: micromark-factory-destination@2.0.0: dependencies: - micromark-util-character: 2.0.1 + micromark-util-character: 2.1.0 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 micromark-factory-label@2.0.0: dependencies: devlop: 1.1.0 - micromark-util-character: 2.0.1 + micromark-util-character: 2.1.0 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - micromark-factory-mdx-expression@2.0.1: + micromark-factory-mdx-expression@2.0.2: dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 devlop: 1.1.0 - micromark-util-character: 2.0.1 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 micromark-util-events-to-acorn: 2.0.2 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 @@ -9518,24 +9600,24 @@ snapshots: micromark-factory-space@2.0.0: dependencies: - micromark-util-character: 2.0.1 + micromark-util-character: 2.1.0 micromark-util-types: 2.0.0 micromark-factory-title@2.0.0: dependencies: micromark-factory-space: 2.0.0 - micromark-util-character: 2.0.1 + micromark-util-character: 2.1.0 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 micromark-factory-whitespace@2.0.0: dependencies: micromark-factory-space: 2.0.0 - micromark-util-character: 2.0.1 + micromark-util-character: 2.1.0 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - micromark-util-character@2.0.1: + micromark-util-character@2.1.0: dependencies: micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 @@ -9546,7 +9628,7 @@ snapshots: micromark-util-classify-character@2.0.0: dependencies: - micromark-util-character: 2.0.1 + micromark-util-character: 2.1.0 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 @@ -9562,7 +9644,7 @@ snapshots: micromark-util-decode-string@2.0.0: dependencies: decode-named-character-reference: 1.0.2 - micromark-util-character: 2.0.1 + micromark-util-character: 2.1.0 micromark-util-decode-numeric-character-reference: 2.0.1 micromark-util-symbol: 2.0.0 @@ -9571,8 +9653,8 @@ snapshots: micromark-util-events-to-acorn@2.0.2: dependencies: '@types/acorn': 4.0.6 - '@types/estree': 1.0.5 - '@types/unist': 3.0.2 + '@types/estree': 1.0.6 + '@types/unist': 3.0.3 devlop: 1.1.0 estree-util-visit: 2.0.0 micromark-util-symbol: 2.0.0 @@ -9591,11 +9673,11 @@ snapshots: micromark-util-sanitize-uri@2.0.0: dependencies: - micromark-util-character: 2.0.1 + micromark-util-character: 2.1.0 micromark-util-encode: 2.0.0 micromark-util-symbol: 2.0.0 - micromark-util-subtokenize@2.0.0: + micromark-util-subtokenize@2.0.1: dependencies: devlop: 1.1.0 micromark-util-chunked: 2.0.0 @@ -9609,12 +9691,12 @@ snapshots: micromark@4.0.0: dependencies: '@types/debug': 4.1.12 - debug: 4.3.4 + debug: 4.3.7 decode-named-character-reference: 1.0.2 devlop: 1.1.0 - micromark-core-commonmark: 2.0.0 + micromark-core-commonmark: 2.0.1 micromark-factory-space: 2.0.0 - micromark-util-character: 2.0.1 + micromark-util-character: 2.1.0 micromark-util-chunked: 2.0.0 micromark-util-combine-extensions: 2.0.0 micromark-util-decode-numeric-character-reference: 2.0.1 @@ -9622,13 +9704,13 @@ snapshots: micromark-util-normalize-identifier: 2.0.0 micromark-util-resolve-all: 2.0.0 micromark-util-sanitize-uri: 2.0.0 - micromark-util-subtokenize: 2.0.0 + micromark-util-subtokenize: 2.0.1 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 transitivePeerDependencies: - supports-color - micromatch@4.0.5: + micromatch@4.0.8: dependencies: braces: 3.0.3 picomatch: 2.3.1 @@ -9639,10 +9721,6 @@ snapshots: dependencies: mime-db: 1.52.0 - mimic-fn@2.1.0: {} - - mimic-fn@4.0.0: {} - min-indent@1.0.1: {} minimatch@3.1.2: @@ -9657,6 +9735,10 @@ snapshots: dependencies: brace-expansion: 2.0.1 + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + minimist-options@4.1.0: dependencies: arrify: 1.0.1 @@ -9665,38 +9747,33 @@ snapshots: minimist@1.2.8: {} - minipass@7.0.4: {} - modify-values@1.0.1: {} - ms@2.1.2: {} - ms@2.1.3: {} - msw@2.1.4(typescript@5.3.3): + msw@2.4.13(typescript@5.3.3): dependencies: '@bundled-es-modules/cookie': 2.0.0 '@bundled-es-modules/statuses': 1.0.1 - '@mswjs/cookies': 1.1.0 - '@mswjs/interceptors': 0.25.14 + '@bundled-es-modules/tough-cookie': 0.1.6 + '@inquirer/confirm': 4.0.1 + '@mswjs/interceptors': 0.36.5 '@open-draft/until': 2.1.0 '@types/cookie': 0.6.0 - '@types/statuses': 2.0.4 + '@types/statuses': 2.0.5 chalk: 4.1.2 - chokidar: 3.5.3 - graphql: 16.8.1 - headers-polyfill: 4.0.2 - inquirer: 8.2.6 + graphql: 16.9.0 + headers-polyfill: 4.0.3 is-node-process: 1.2.0 - outvariant: 1.4.2 - path-to-regexp: 6.2.1 + outvariant: 1.4.3 + path-to-regexp: 6.3.0 strict-event-emitter: 0.5.1 - type-fest: 4.10.1 + type-fest: 4.26.1 yargs: 17.7.2 optionalDependencies: typescript: 5.3.3 - mute-stream@0.0.8: {} + mute-stream@1.0.0: {} nanoid@3.3.7: {} @@ -9709,9 +9786,11 @@ snapshots: no-case@3.0.4: dependencies: lower-case: 2.0.2 - tslib: 2.6.2 + tslib: 2.8.0 - node-releases@2.0.14: {} + node-addon-api@7.1.1: {} + + node-releases@2.0.18: {} normalize-package-data@2.5.0: dependencies: @@ -9723,74 +9802,59 @@ snapshots: normalize-package-data@3.0.3: dependencies: hosted-git-info: 4.1.0 - is-core-module: 2.13.1 - semver: 7.5.4 + is-core-module: 2.15.1 + semver: 7.6.3 validate-npm-package-license: 3.0.4 normalize-path@3.0.0: {} normalize-range@0.1.2: {} - not@0.1.0: {} - - npm-run-path@4.0.1: - dependencies: - path-key: 3.1.1 - - npm-run-path@5.2.0: - dependencies: - path-key: 4.0.0 - nth-check@2.1.1: dependencies: boolbase: 1.0.0 - numbro@2.4.0: + numbro@2.5.0: dependencies: bignumber.js: 9.1.2 object-assign@4.1.1: {} - object-inspect@1.13.1: {} + object-inspect@1.13.2: {} object-keys@1.1.1: {} object.assign@4.1.5: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 has-symbols: 1.0.3 object-keys: 1.1.1 - object.entries@1.1.7: - dependencies: - call-bind: 1.0.5 - define-properties: 1.2.1 - es-abstract: 1.22.3 - - object.fromentries@2.0.7: + object.entries@1.1.8: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-object-atoms: 1.0.0 - object.groupby@1.0.1: + object.fromentries@2.0.8: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 - get-intrinsic: 1.2.2 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 - object.hasown@1.1.3: + object.groupby@1.0.3: dependencies: + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.23.3 - object.values@1.1.7: + object.values@1.2.0: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-object-atoms: 1.0.0 on-finished@2.4.1: dependencies: @@ -9800,47 +9864,25 @@ snapshots: dependencies: wrappy: 1.0.2 - onetime@5.1.2: - dependencies: - mimic-fn: 2.1.0 - - onetime@6.0.0: - dependencies: - mimic-fn: 4.0.0 - only@0.0.2: {} - open@9.1.0: + open@10.1.0: dependencies: - default-browser: 4.0.0 + default-browser: 5.2.1 define-lazy-prop: 3.0.0 is-inside-container: 1.0.0 - is-wsl: 2.2.0 + is-wsl: 3.1.0 - optionator@0.9.3: + optionator@0.9.4: dependencies: - '@aashutoshrathi/word-wrap': 1.2.6 deep-is: 0.1.4 fast-levenshtein: 2.0.6 levn: 0.4.1 prelude-ls: 1.2.1 type-check: 0.4.0 + word-wrap: 1.2.5 - ora@5.4.1: - dependencies: - bl: 4.1.0 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.9.2 - is-interactive: 1.0.0 - is-unicode-supported: 0.1.0 - log-symbols: 4.1.0 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - - os-tmpdir@1.0.2: {} - - outvariant@1.4.2: {} + outvariant@1.4.3: {} p-limit@1.3.0: dependencies: @@ -9880,7 +9922,7 @@ snapshots: parse-entities@4.0.1: dependencies: - '@types/unist': 2.0.10 + '@types/unist': 2.0.11 character-entities: 2.0.2 character-entities-legacy: 3.0.0 character-reference-invalid: 2.0.1 @@ -9896,12 +9938,12 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.23.5 + '@babel/code-frame': 7.25.7 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - parse5@7.1.2: + parse5@7.2.0: dependencies: entities: 4.5.0 @@ -9915,16 +9957,9 @@ snapshots: path-key@3.1.1: {} - path-key@4.0.0: {} - path-parse@1.0.7: {} - path-scurry@1.10.1: - dependencies: - lru-cache: 10.1.0 - minipass: 7.0.4 - - path-to-regexp@6.2.1: {} + path-to-regexp@6.3.0: {} path-type@3.0.0: dependencies: @@ -9934,13 +9969,7 @@ snapshots: path-type@5.0.0: {} - periscopic@3.1.0: - dependencies: - '@types/estree': 1.0.5 - estree-walker: 3.0.3 - is-reference: 3.0.2 - - picocolors@1.0.0: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -9950,30 +9979,32 @@ snapshots: pngjs@5.0.0: {} + possible-typed-array-names@1.0.0: {} + postcss-media-query-parser@0.2.3: {} - postcss-resolve-nested-selector@0.1.1: {} + postcss-resolve-nested-selector@0.1.6: {} - postcss-safe-parser@7.0.0(postcss@8.4.33): + postcss-safe-parser@7.0.1(postcss@8.4.47): dependencies: - postcss: 8.4.33 + postcss: 8.4.47 - postcss-scss@4.0.9(postcss@8.4.33): + postcss-scss@4.0.9(postcss@8.4.47): dependencies: - postcss: 8.4.33 + postcss: 8.4.47 - postcss-selector-parser@6.0.15: + postcss-selector-parser@6.1.2: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 postcss-value-parser@4.2.0: {} - postcss@8.4.33: + postcss@8.4.47: dependencies: nanoid: 3.3.7 - picocolors: 1.0.0 - source-map-js: 1.0.2 + picocolors: 1.1.1 + source-map-js: 1.2.1 prelude-ls@1.2.1: {} @@ -9983,13 +10014,13 @@ snapshots: prettier@2.8.8: {} - prettier@3.2.4: {} + prettier@3.3.3: {} - prism-react-renderer@2.3.1(react@18.2.0): + prism-react-renderer@2.4.0(react@18.3.1): dependencies: - '@types/prismjs': 1.26.3 - clsx: 2.1.0 - react: 18.2.0 + '@types/prismjs': 1.26.4 + clsx: 2.1.1 + react: 18.3.1 process-nextick-args@2.0.1: {} @@ -9999,147 +10030,148 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 - property-information@6.4.1: {} + property-information@6.5.0: {} proxy-from-env@1.1.0: {} + psl@1.9.0: {} + punycode@2.3.1: {} q@1.5.1: {} qr.js@0.0.0: {} - qrcode@1.5.3: + qrcode@1.5.4: dependencies: dijkstrajs: 1.0.3 - encode-utf8: 1.0.3 pngjs: 5.0.0 yargs: 15.4.1 - query-string@8.1.0: + query-string@9.1.1: dependencies: decode-uri-component: 0.4.1 filter-obj: 5.1.0 split-on-first: 3.0.0 + querystringify@2.2.0: {} + queue-microtask@1.2.3: {} quick-lru@4.0.1: {} - radash@11.0.0: {} + radash@12.1.0: {} - react-click-away-listener@2.2.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + react-click-away-listener@2.2.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - react-dom@18.2.0(react@18.2.0): + react-dom@18.3.1(react@18.3.1): dependencies: loose-envify: 1.4.0 - react: 18.2.0 - scheduler: 0.23.0 + react: 18.3.1 + scheduler: 0.23.2 - react-hook-form@7.49.3(react@18.2.0): + react-hook-form@7.53.1(react@18.3.1): dependencies: - react: 18.2.0 + react: 18.3.1 - react-hotkeys-hook@4.4.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + react-hotkeys-hook@4.5.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - react-idle-timer@5.7.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + react-idle-timer@5.7.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - react-inspector@6.0.2(react@18.2.0): + react-inspector@6.0.2(react@18.3.1): dependencies: - react: 18.2.0 + react: 18.3.1 react-is@16.13.1: {} - react-is@18.2.0: {} + react-is@18.3.1: {} - react-lifecycles-compat@3.0.4: {} - - react-loading-skeleton@3.3.1(react@18.2.0): + react-loading-skeleton@3.5.0(react@18.3.1): dependencies: - react: 18.2.0 + react: 18.3.1 - react-markdown@9.0.1(@types/react@18.2.48)(react@18.2.0): + react-markdown@9.0.1(@types/react@18.3.11)(react@18.3.1): dependencies: - '@types/hast': 3.0.3 - '@types/react': 18.2.48 + '@types/hast': 3.0.4 + '@types/react': 18.3.11 devlop: 1.1.0 - hast-util-to-jsx-runtime: 2.3.0 - html-url-attributes: 3.0.0 - mdast-util-to-hast: 13.1.0 - react: 18.2.0 + hast-util-to-jsx-runtime: 2.3.2 + html-url-attributes: 3.0.1 + mdast-util-to-hast: 13.2.0 + react: 18.3.1 remark-parse: 11.0.0 - remark-rehype: 11.1.0 - unified: 11.0.4 + remark-rehype: 11.1.1 + unified: 11.0.5 unist-util-visit: 5.0.0 - vfile: 6.0.1 + vfile: 6.0.3 transitivePeerDependencies: - supports-color react-property@2.0.2: {} - react-qr-code@2.0.12(react@18.2.0): + react-qr-code@2.0.15(react@18.3.1): dependencies: prop-types: 15.8.1 qr.js: 0.0.0 - react: 18.2.0 + react: 18.3.1 - react-refresh@0.14.0: {} + react-refresh@0.14.2: {} - react-router-dom@6.21.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + react-router-dom@6.27.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@remix-run/router': 1.14.2 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-router: 6.21.3(react@18.2.0) + '@remix-run/router': 1.20.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-router: 6.27.0(react@18.3.1) - react-router@6.21.3(react@18.2.0): + react-router@6.27.0(react@18.3.1): dependencies: - '@remix-run/router': 1.14.2 - react: 18.2.0 + '@remix-run/router': 1.20.0 + react: 18.3.1 - react-simple-animate@3.5.2(react-dom@18.2.0(react@18.2.0)): + react-simple-animate@3.5.2(react-dom@18.3.1(react@18.3.1)): dependencies: - react-dom: 18.2.0(react@18.2.0) + react-dom: 18.3.1(react@18.3.1) - react-smooth@2.0.5(prop-types@15.8.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + react-smooth@4.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: fast-equals: 5.0.1 prop-types: 15.8.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-transition-group: 2.9.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react-transition-group@2.9.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + react-transition-group@4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - dom-helpers: 3.4.0 + '@babel/runtime': 7.25.7 + dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-lifecycles-compat: 3.0.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - react-virtualized-auto-sizer@1.0.21(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + react-virtualized-auto-sizer@1.0.24(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - react-window@1.8.10(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + react-window@1.8.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.23.8 + '@babel/runtime': 7.25.7 memoize-one: 5.2.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - react@18.2.0: + react@18.3.1: dependencies: loose-envify: 1.4.0 @@ -10187,39 +10219,71 @@ snapshots: dependencies: picomatch: 2.3.1 + readdirp@4.0.2: {} + recharts-scale@0.4.5: dependencies: decimal.js-light: 2.5.1 - recharts@2.10.4(prop-types@15.8.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + recharts@2.13.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - clsx: 2.1.0 + clsx: 2.1.1 eventemitter3: 4.0.7 lodash: 4.17.21 - prop-types: 15.8.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-is: 16.13.1 - react-smooth: 2.0.5(prop-types@15.8.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-is: 18.3.1 + react-smooth: 4.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) recharts-scale: 0.4.5 - tiny-invariant: 1.3.1 - victory-vendor: 36.8.2 + tiny-invariant: 1.3.3 + victory-vendor: 36.9.2 + + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.6 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.0(acorn@8.13.0): + dependencies: + acorn-jsx: 5.3.2(acorn@8.13.0) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - acorn + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.6 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.6 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 redent@3.0.0: dependencies: indent-string: 4.0.0 strip-indent: 3.0.0 - reflect.getprototypeof@1.0.4: + reflect.getprototypeof@1.0.6: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 - get-intrinsic: 1.2.2 - globalthis: 1.0.3 - which-builtin-type: 1.1.3 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + globalthis: 1.0.4 + which-builtin-type: 1.1.4 - regenerate-unicode-properties@10.1.1: + regenerate-unicode-properties@10.2.0: dependencies: regenerate: 1.4.2 @@ -10229,52 +10293,63 @@ snapshots: regenerator-transform@0.15.2: dependencies: - '@babel/runtime': 7.23.8 + '@babel/runtime': 7.25.7 - regexp.prototype.flags@1.5.1: + regexp.prototype.flags@1.5.3: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - set-function-name: 2.0.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 - regexpu-core@5.3.2: + regexpu-core@6.1.1: dependencies: - '@babel/regjsgen': 0.8.0 regenerate: 1.4.2 - regenerate-unicode-properties: 10.1.1 - regjsparser: 0.9.1 + regenerate-unicode-properties: 10.2.0 + regjsgen: 0.8.0 + regjsparser: 0.11.1 unicode-match-property-ecmascript: 2.0.0 - unicode-match-property-value-ecmascript: 2.1.0 + unicode-match-property-value-ecmascript: 2.2.0 + + regjsgen@0.8.0: {} - regjsparser@0.9.1: + regjsparser@0.11.1: dependencies: - jsesc: 0.5.0 + jsesc: 3.0.2 - rehype-class-names@1.0.14: + rehype-class-names@2.0.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 hast-util-classnames: 3.0.0 - hast-util-select: 6.0.2 - unified: 10.1.2 + hast-util-select: 6.0.3 + unified: 11.0.5 rehype-raw@7.0.0: dependencies: - '@types/hast': 3.0.3 - hast-util-raw: 9.0.2 - vfile: 6.0.1 + '@types/hast': 3.0.4 + hast-util-raw: 9.0.4 + vfile: 6.0.3 + + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.6 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.0 + transitivePeerDependencies: + - supports-color remark-gfm@4.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 mdast-util-gfm: 3.0.0 micromark-extension-gfm: 3.0.0 remark-parse: 11.0.0 remark-stringify: 11.0.0 - unified: 11.0.4 + unified: 11.0.5 transitivePeerDependencies: - supports-color - remark-mdx@3.0.0: + remark-mdx@3.1.0: dependencies: mdast-util-mdx: 3.0.0 micromark-extension-mdxjs: 3.0.0 @@ -10283,28 +10358,28 @@ snapshots: remark-parse@11.0.0: dependencies: - '@types/mdast': 4.0.3 - mdast-util-from-markdown: 2.0.0 + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.1 micromark-util-types: 2.0.0 - unified: 11.0.4 + unified: 11.0.5 transitivePeerDependencies: - supports-color - remark-rehype@11.1.0: + remark-rehype@11.1.1: dependencies: - '@types/hast': 3.0.3 - '@types/mdast': 4.0.3 - mdast-util-to-hast: 13.1.0 - unified: 11.0.4 - vfile: 6.0.1 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.0 + unified: 11.0.5 + vfile: 6.0.3 remark-stringify@11.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 mdast-util-to-markdown: 2.1.0 - unified: 11.0.4 + unified: 11.0.5 - remove-accents@0.4.2: {} + remove-accents@0.5.0: {} require-directory@2.1.1: {} @@ -10312,47 +10387,37 @@ snapshots: require-main-filename@2.0.0: {} + requires-port@1.0.0: {} + resolve-from@4.0.0: {} resolve-from@5.0.0: {} resolve@1.22.8: dependencies: - is-core-module: 2.13.1 + is-core-module: 2.15.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 resolve@2.0.0-next.5: dependencies: - is-core-module: 2.13.1 + is-core-module: 2.15.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - restore-cursor@3.1.0: - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - reusify@1.0.4: {} rimraf@3.0.2: dependencies: glob: 7.2.3 - rimraf@5.0.5: - dependencies: - glob: 10.3.10 - - rollup-plugin-preserve-directives@0.3.1(@rollup/wasm-node@4.24.0): + rollup-plugin-preserve-directives@0.4.0(@rollup/wasm-node@4.24.0): dependencies: - magic-string: 0.30.5 + '@rollup/pluginutils': 5.1.2(@rollup/wasm-node@4.24.0) + magic-string: 0.30.12 rollup: '@rollup/wasm-node@4.24.0' - run-applescript@5.0.0: - dependencies: - execa: 5.1.1 - - run-async@2.4.1: {} + run-applescript@7.0.0: {} run-parallel@1.2.0: dependencies: @@ -10360,12 +10425,12 @@ snapshots: rxjs@7.8.1: dependencies: - tslib: 2.6.2 + tslib: 2.8.0 - safe-array-concat@1.1.0: + safe-array-concat@1.1.2: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 isarray: 2.0.5 @@ -10373,21 +10438,20 @@ snapshots: safe-buffer@5.2.1: {} - safe-regex-test@1.0.2: + safe-regex-test@1.0.3: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + es-errors: 1.3.0 is-regex: 1.1.4 - safer-buffer@2.1.2: {} - - sass@1.70.0: + sass@1.80.3: dependencies: - chokidar: 3.5.3 - immutable: 4.3.4 - source-map-js: 1.0.2 + '@parcel/watcher': 2.4.1 + chokidar: 4.0.1 + immutable: 4.3.7 + source-map-js: 1.2.1 - scheduler@0.23.0: + scheduler@0.23.2: dependencies: loose-envify: 1.4.0 @@ -10395,25 +10459,25 @@ snapshots: semver@6.3.1: {} - semver@7.5.4: - dependencies: - lru-cache: 6.0.0 + semver@7.6.3: {} set-blocking@2.0.0: {} - set-function-length@1.2.0: + set-function-length@1.2.2: dependencies: - define-data-property: 1.1.1 + define-data-property: 1.1.4 + es-errors: 1.3.0 function-bind: 1.1.2 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 gopd: 1.0.1 - has-property-descriptors: 1.0.1 + has-property-descriptors: 1.0.2 - set-function-name@2.0.1: + set-function-name@2.0.2: dependencies: - define-data-property: 1.1.1 + define-data-property: 1.1.4 + es-errors: 1.3.0 functions-have-names: 1.2.3 - has-property-descriptors: 1.0.1 + has-property-descriptors: 1.0.2 setprototypeof@1.2.0: {} @@ -10428,17 +10492,16 @@ snapshots: shiki@0.14.7: dependencies: ansi-sequence-parser: 1.1.1 - jsonc-parser: 3.2.1 + jsonc-parser: 3.3.1 vscode-oniguruma: 1.7.0 vscode-textmate: 8.0.0 - side-channel@1.0.4: + side-channel@1.0.6: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 - object-inspect: 1.13.1 - - signal-exit@3.0.7: {} + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.2 signal-exit@4.1.0: {} @@ -10455,9 +10518,9 @@ snapshots: snake-case@3.0.4: dependencies: dot-case: 3.0.4 - tslib: 2.6.2 + tslib: 2.8.0 - source-map-js@1.0.2: {} + source-map-js@1.2.1: {} source-map-support@0.5.21: dependencies: @@ -10472,21 +10535,19 @@ snapshots: space-separated-tokens@2.0.2: {} - spawn-command@0.0.2: {} - spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.16 + spdx-license-ids: 3.0.20 - spdx-exceptions@2.4.0: {} + spdx-exceptions@2.5.0: {} spdx-expression-parse@3.0.1: dependencies: - spdx-exceptions: 2.4.0 - spdx-license-ids: 3.0.16 + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.20 - spdx-license-ids@3.0.16: {} + spdx-license-ids@3.0.20: {} split-on-first@3.0.0: {} @@ -10511,7 +10572,7 @@ snapshots: figures: 3.2.0 find-up: 5.0.0 git-semver-tags: 4.1.1 - semver: 7.5.4 + semver: 7.6.3 stringify-package: 1.0.1 yargs: 16.2.0 @@ -10533,35 +10594,50 @@ snapshots: emoji-regex: 9.2.2 strip-ansi: 7.1.0 - string.prototype.matchall@4.0.10: + string.prototype.includes@2.0.1: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + + string.prototype.matchall@4.0.11: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 - get-intrinsic: 1.2.2 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + gopd: 1.0.1 has-symbols: 1.0.3 - internal-slot: 1.0.6 - regexp.prototype.flags: 1.5.1 - set-function-name: 2.0.1 - side-channel: 1.0.4 + internal-slot: 1.0.7 + regexp.prototype.flags: 1.5.3 + set-function-name: 2.0.2 + side-channel: 1.0.6 + + string.prototype.repeat@1.0.0: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.23.3 - string.prototype.trim@1.2.8: + string.prototype.trim@1.2.9: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 - string.prototype.trimend@1.0.7: + string.prototype.trimend@1.0.8: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-object-atoms: 1.0.0 - string.prototype.trimstart@1.0.7: + string.prototype.trimstart@1.0.8: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-object-atoms: 1.0.0 string_decoder@1.1.1: dependencies: @@ -10571,7 +10647,7 @@ snapshots: dependencies: safe-buffer: 5.2.1 - stringify-entities@4.0.3: + stringify-entities@4.0.4: dependencies: character-entities-html4: 2.1.0 character-entities-legacy: 3.0.0 @@ -10584,83 +10660,82 @@ snapshots: strip-ansi@7.1.0: dependencies: - ansi-regex: 6.0.1 + ansi-regex: 6.1.0 strip-bom@3.0.0: {} - strip-final-newline@2.0.0: {} - - strip-final-newline@3.0.0: {} - strip-indent@3.0.0: dependencies: min-indent: 1.0.1 strip-json-comments@3.1.1: {} - style-to-js@1.1.10: + style-to-js@1.1.16: dependencies: - style-to-object: 1.0.5 + style-to-object: 1.0.8 style-to-object@0.4.4: dependencies: inline-style-parser: 0.1.1 - style-to-object@1.0.5: + style-to-object@1.0.8: dependencies: - inline-style-parser: 0.2.2 + inline-style-parser: 0.2.4 stylelint-config-prettier-scss@1.0.0(stylelint@16.2.0(typescript@5.3.3)): dependencies: stylelint: 16.2.0(typescript@5.3.3) - stylelint-config-recommended-scss@14.0.0(postcss@8.4.33)(stylelint@16.2.0(typescript@5.3.3)): + stylelint-config-recommended-scss@14.1.0(postcss@8.4.47)(stylelint@16.2.0(typescript@5.3.3)): dependencies: - postcss-scss: 4.0.9(postcss@8.4.33) + postcss-scss: 4.0.9(postcss@8.4.47) stylelint: 16.2.0(typescript@5.3.3) - stylelint-config-recommended: 14.0.0(stylelint@16.2.0(typescript@5.3.3)) - stylelint-scss: 6.1.0(stylelint@16.2.0(typescript@5.3.3)) + stylelint-config-recommended: 14.0.1(stylelint@16.2.0(typescript@5.3.3)) + stylelint-scss: 6.8.1(stylelint@16.2.0(typescript@5.3.3)) optionalDependencies: - postcss: 8.4.33 + postcss: 8.4.47 - stylelint-config-recommended@14.0.0(stylelint@16.2.0(typescript@5.3.3)): + stylelint-config-recommended@14.0.1(stylelint@16.2.0(typescript@5.3.3)): dependencies: stylelint: 16.2.0(typescript@5.3.3) - stylelint-config-standard-scss@13.0.0(postcss@8.4.33)(stylelint@16.2.0(typescript@5.3.3)): + stylelint-config-standard-scss@13.1.0(postcss@8.4.47)(stylelint@16.2.0(typescript@5.3.3)): dependencies: stylelint: 16.2.0(typescript@5.3.3) - stylelint-config-recommended-scss: 14.0.0(postcss@8.4.33)(stylelint@16.2.0(typescript@5.3.3)) - stylelint-config-standard: 36.0.0(stylelint@16.2.0(typescript@5.3.3)) + stylelint-config-recommended-scss: 14.1.0(postcss@8.4.47)(stylelint@16.2.0(typescript@5.3.3)) + stylelint-config-standard: 36.0.1(stylelint@16.2.0(typescript@5.3.3)) optionalDependencies: - postcss: 8.4.33 + postcss: 8.4.47 - stylelint-config-standard@36.0.0(stylelint@16.2.0(typescript@5.3.3)): + stylelint-config-standard@36.0.1(stylelint@16.2.0(typescript@5.3.3)): dependencies: stylelint: 16.2.0(typescript@5.3.3) - stylelint-config-recommended: 14.0.0(stylelint@16.2.0(typescript@5.3.3)) + stylelint-config-recommended: 14.0.1(stylelint@16.2.0(typescript@5.3.3)) - stylelint-scss@6.1.0(stylelint@16.2.0(typescript@5.3.3)): + stylelint-scss@6.8.1(stylelint@16.2.0(typescript@5.3.3)): dependencies: - known-css-properties: 0.29.0 + css-tree: 3.0.0 + is-plain-object: 5.0.0 + known-css-properties: 0.34.0 + mdn-data: 2.11.1 postcss-media-query-parser: 0.2.3 - postcss-resolve-nested-selector: 0.1.1 - postcss-selector-parser: 6.0.15 + postcss-resolve-nested-selector: 0.1.6 + postcss-selector-parser: 6.1.2 postcss-value-parser: 4.2.0 stylelint: 16.2.0(typescript@5.3.3) stylelint@16.2.0(typescript@5.3.3): dependencies: - '@csstools/css-parser-algorithms': 2.5.0(@csstools/css-tokenizer@2.2.3) - '@csstools/css-tokenizer': 2.2.3 - '@csstools/media-query-list-parser': 2.1.7(@csstools/css-parser-algorithms@2.5.0(@csstools/css-tokenizer@2.2.3))(@csstools/css-tokenizer@2.2.3) - '@csstools/selector-specificity': 3.0.1(postcss-selector-parser@6.0.15) + '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) + '@csstools/css-tokenizer': 2.4.1 + '@csstools/media-query-list-parser': 2.1.13(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) + '@csstools/selector-specificity': 3.1.1(postcss-selector-parser@6.1.2) balanced-match: 2.0.0 colord: 2.9.3 cosmiconfig: 9.0.0(typescript@5.3.3) - css-functions-list: 3.2.1 + css-functions-list: 3.2.3 css-tree: 2.3.1 - debug: 4.3.4 + debug: 4.3.7 fast-glob: 3.3.2 fastest-levenshtein: 1.0.16 file-entry-cache: 8.0.0 @@ -10668,26 +10743,26 @@ snapshots: globby: 11.1.0 globjoin: 0.1.4 html-tags: 3.3.1 - ignore: 5.3.0 + ignore: 5.3.2 imurmurhash: 0.1.4 is-plain-object: 5.0.0 known-css-properties: 0.29.0 mathml-tag-names: 2.1.3 - meow: 13.1.0 - micromatch: 4.0.5 + meow: 13.2.0 + micromatch: 4.0.8 normalize-path: 3.0.0 - picocolors: 1.0.0 - postcss: 8.4.33 - postcss-resolve-nested-selector: 0.1.1 - postcss-safe-parser: 7.0.0(postcss@8.4.33) - postcss-selector-parser: 6.0.15 + picocolors: 1.1.1 + postcss: 8.4.47 + postcss-resolve-nested-selector: 0.1.6 + postcss-safe-parser: 7.0.1(postcss@8.4.47) + postcss-selector-parser: 6.1.2 postcss-value-parser: 4.2.0 resolve-from: 5.0.0 string-width: 4.2.3 strip-ansi: 7.1.0 - supports-hyperlinks: 3.0.0 + supports-hyperlinks: 3.1.0 svg-tags: 1.0.0 - table: 6.8.1 + table: 6.8.2 write-file-atomic: 5.0.1 transitivePeerDependencies: - supports-color @@ -10711,7 +10786,7 @@ snapshots: dependencies: has-flag: 4.0.0 - supports-hyperlinks@3.0.0: + supports-hyperlinks@3.1.0: dependencies: has-flag: 4.0.0 supports-color: 7.2.0 @@ -10722,7 +10797,7 @@ snapshots: svg-tags@1.0.0: {} - svgo@3.2.0: + svgo@3.3.2: dependencies: '@trysound/sax': 0.2.0 commander: 7.2.0 @@ -10730,29 +10805,29 @@ snapshots: css-tree: 2.3.1 css-what: 6.1.0 csso: 5.0.5 - picocolors: 1.0.0 + picocolors: 1.1.1 - synckit@0.8.8: + synckit@0.9.2: dependencies: '@pkgr/core': 0.1.1 - tslib: 2.6.2 + tslib: 2.8.0 - systemjs@6.14.3: {} + systemjs@6.15.1: {} tabbable@6.2.0: {} - table@6.8.1: + table@6.8.2: dependencies: - ajv: 8.12.0 + ajv: 8.17.1 lodash.truncate: 4.4.2 slice-ansi: 4.0.0 string-width: 4.2.3 strip-ansi: 6.0.1 - terser@5.27.0: + terser@5.36.0: dependencies: - '@jridgewell/source-map': 0.3.5 - acorn: 8.11.3 + '@jridgewell/source-map': 0.3.6 + acorn: 8.13.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -10771,13 +10846,7 @@ snapshots: through@2.3.8: {} - tiny-invariant@1.3.1: {} - - titleize@3.0.0: {} - - tmp@0.0.33: - dependencies: - os-tmpdir: 1.0.2 + tiny-invariant@1.3.3: {} to-fast-properties@2.0.0: {} @@ -10787,19 +10856,26 @@ snapshots: toidentifier@1.0.1: {} + tough-cookie@4.1.4: + dependencies: + psl: 1.9.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 + tree-kill@1.2.2: {} trim-lines@3.0.1: {} trim-newlines@3.0.1: {} - trough@2.1.0: {} + trough@2.2.0: {} - ts-api-utils@1.0.3(typescript@5.3.3): + ts-api-utils@1.3.0(typescript@5.3.3): dependencies: typescript: 5.3.3 - tsconfck@3.0.1(typescript@5.3.3): + tsconfck@3.1.4(typescript@5.3.3): optionalDependencies: typescript: 5.3.3 @@ -10810,9 +10886,9 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 - tslib@2.4.0: {} + tslib@2.7.0: {} - tslib@2.6.2: {} + tslib@2.8.0: {} tsscmp@1.0.6: {} @@ -10832,47 +10908,52 @@ snapshots: type-fest@2.19.0: {} - type-fest@4.10.1: {} + type-fest@4.26.1: {} type-is@1.6.18: dependencies: media-typer: 0.3.0 mime-types: 2.1.35 - typed-array-buffer@1.0.0: + typed-array-buffer@1.0.2: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 - is-typed-array: 1.1.12 + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 - typed-array-byte-length@1.0.0: + typed-array-byte-length@1.0.1: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 for-each: 0.3.3 - has-proto: 1.0.1 - is-typed-array: 1.1.12 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 - typed-array-byte-offset@1.0.0: + typed-array-byte-offset@1.0.2: dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.5 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 for-each: 0.3.3 - has-proto: 1.0.1 - is-typed-array: 1.1.12 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 - typed-array-length@1.0.4: + typed-array-length@1.0.6: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 for-each: 0.3.3 - is-typed-array: 1.1.12 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 typedarray@0.0.6: {} - typedoc@0.25.7(typescript@5.3.3): + typedoc@0.25.13(typescript@5.3.3): dependencies: lunr: 2.3.9 marked: 4.3.0 - minimatch: 9.0.3 + minimatch: 9.0.5 shiki: 0.14.7 typescript: 5.3.3 @@ -10880,121 +10961,107 @@ snapshots: dependencies: typescript: 5.3.3 - typescript-eslint-language-service@5.0.5(@typescript-eslint/parser@6.19.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3): + typescript-eslint-language-service@5.0.5(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3): dependencies: - '@typescript-eslint/parser': 6.19.1(eslint@8.56.0)(typescript@5.3.3) - eslint: 8.56.0 + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.3.3) + eslint: 8.57.1 typescript: 5.3.3 typescript@5.3.3: {} - uglify-js@3.17.4: + uglify-js@3.19.3: optional: true unbox-primitive@1.0.2: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 - undici-types@5.26.5: {} + undici-types@6.19.8: {} - unicode-canonical-property-names-ecmascript@2.0.0: {} + unicode-canonical-property-names-ecmascript@2.0.1: {} unicode-match-property-ecmascript@2.0.0: dependencies: - unicode-canonical-property-names-ecmascript: 2.0.0 + unicode-canonical-property-names-ecmascript: 2.0.1 unicode-property-aliases-ecmascript: 2.1.0 - unicode-match-property-value-ecmascript@2.1.0: {} + unicode-match-property-value-ecmascript@2.2.0: {} unicode-property-aliases-ecmascript@2.1.0: {} unicorn-magic@0.1.0: {} - unified@10.1.2: - dependencies: - '@types/unist': 2.0.10 - bail: 2.0.2 - extend: 3.0.2 - is-buffer: 2.0.5 - is-plain-obj: 4.1.0 - trough: 2.1.0 - vfile: 5.3.7 - - unified@11.0.4: + unified@11.0.5: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 bail: 2.0.2 devlop: 1.1.0 extend: 3.0.2 is-plain-obj: 4.1.0 - trough: 2.1.0 - vfile: 6.0.1 + trough: 2.2.0 + vfile: 6.0.3 unist-util-is@6.0.0: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 unist-util-position-from-estree@2.0.0: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 unist-util-position@5.0.0: dependencies: - '@types/unist': 3.0.2 - - unist-util-remove-position@5.0.0: - dependencies: - '@types/unist': 3.0.2 - unist-util-visit: 5.0.0 - - unist-util-stringify-position@3.0.3: - dependencies: - '@types/unist': 2.0.10 + '@types/unist': 3.0.3 unist-util-stringify-position@4.0.0: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 unist-util-visit-parents@6.0.1: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 unist-util-is: 6.0.0 unist-util-visit@5.0.0: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 - untildify@4.0.0: {} + universalify@0.2.0: {} - update-browserslist-db@1.0.13(browserslist@4.22.2): + update-browserslist-db@1.1.1(browserslist@4.24.2): dependencies: - browserslist: 4.22.2 - escalade: 3.1.1 - picocolors: 1.0.0 + browserslist: 4.24.2 + escalade: 3.2.0 + picocolors: 1.1.1 uri-js@4.4.1: dependencies: punycode: 2.3.1 - use-breakpoint@4.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + url-parse@1.5.10: + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + + use-breakpoint@4.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - use-deep-compare-effect@1.8.1(react@18.2.0): + use-deep-compare-effect@1.8.1(react@18.3.1): dependencies: - '@babel/runtime': 7.23.8 + '@babel/runtime': 7.25.7 dequal: 2.0.3 - react: 18.2.0 + react: 18.3.1 - use-sync-external-store@1.2.0(react@18.2.0): + use-sync-external-store@1.2.2(react@18.3.1): dependencies: - react: 18.2.0 + react: 18.3.1 util-deprecate@1.0.2: {} @@ -11007,35 +11074,22 @@ snapshots: vary@1.1.2: {} - vfile-location@5.0.2: - dependencies: - '@types/unist': 3.0.2 - vfile: 6.0.1 - - vfile-message@3.1.4: + vfile-location@5.0.3: dependencies: - '@types/unist': 2.0.10 - unist-util-stringify-position: 3.0.3 + '@types/unist': 3.0.3 + vfile: 6.0.3 vfile-message@4.0.2: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 unist-util-stringify-position: 4.0.0 - vfile@5.3.7: - dependencies: - '@types/unist': 2.0.10 - is-buffer: 2.0.5 - unist-util-stringify-position: 3.0.3 - vfile-message: 3.1.4 - - vfile@6.0.1: + vfile@6.0.3: dependencies: - '@types/unist': 3.0.2 - unist-util-stringify-position: 4.0.0 + '@types/unist': 3.0.3 vfile-message: 4.0.2 - victory-vendor@36.8.2: + victory-vendor@36.9.2: dependencies: '@types/d3-array': 3.2.1 '@types/d3-ease': 3.0.2 @@ -11052,48 +11106,44 @@ snapshots: d3-time: 3.1.0 d3-timer: 3.0.1 - vite-plugin-eslint@1.8.1(eslint@8.56.0)(vite@5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0)): + vite-plugin-eslint@1.8.1(eslint@8.57.1)(vite@5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0)): dependencies: '@rollup/pluginutils': 4.2.1 - '@types/eslint': 8.56.2 - eslint: 8.56.0 + '@types/eslint': 8.56.12 + eslint: 8.57.1 rollup: '@rollup/wasm-node@4.24.0' - vite: 5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0) + vite: 5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0) - vite-plugin-package-version@1.1.0(vite@5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0)): + vite-plugin-package-version@1.1.0(vite@5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0)): dependencies: - vite: 5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0) + vite: 5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0) - vite-tsconfig-paths@4.3.1(typescript@5.3.3)(vite@5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0)): + vite-tsconfig-paths@4.3.2(typescript@5.3.3)(vite@5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0)): dependencies: - debug: 4.3.4 + debug: 4.3.7 globrex: 0.1.2 - tsconfck: 3.0.1(typescript@5.3.3) + tsconfck: 3.1.4(typescript@5.3.3) optionalDependencies: - vite: 5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0) + vite: 5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0) transitivePeerDependencies: - supports-color - typescript - vite@5.0.12(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0): + vite@5.4.9(@types/node@20.16.14)(sass@1.80.3)(terser@5.36.0): dependencies: - esbuild: 0.19.12 - postcss: 8.4.33 + esbuild: 0.21.5 + postcss: 8.4.47 rollup: '@rollup/wasm-node@4.24.0' optionalDependencies: - '@types/node': 20.11.7 + '@types/node': 20.16.14 fsevents: 2.3.3 - sass: 1.70.0 - terser: 5.27.0 + sass: 1.80.3 + terser: 5.36.0 vscode-oniguruma@1.7.0: {} vscode-textmate@8.0.0: {} - wcwidth@1.0.1: - dependencies: - defaults: 1.0.4 - web-namespaces@2.0.1: {} which-boxed-primitive@1.0.2: @@ -11104,10 +11154,10 @@ snapshots: is-string: 1.0.7 is-symbol: 1.0.4 - which-builtin-type@1.1.3: + which-builtin-type@1.1.4: dependencies: function.prototype.name: 1.1.6 - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-async-function: 2.0.0 is-date-object: 1.0.5 is-finalizationregistry: 1.0.2 @@ -11116,25 +11166,25 @@ snapshots: is-weakref: 1.0.2 isarray: 2.0.5 which-boxed-primitive: 1.0.2 - which-collection: 1.0.1 - which-typed-array: 1.1.13 + which-collection: 1.0.2 + which-typed-array: 1.1.15 - which-collection@1.0.1: + which-collection@1.0.2: dependencies: - is-map: 2.0.2 - is-set: 2.0.2 - is-weakmap: 2.0.1 - is-weakset: 2.0.2 + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.3 which-module@2.0.1: {} - which-typed-array@1.1.13: + which-typed-array@1.1.15: dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.5 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 for-each: 0.3.3 gopd: 1.0.1 - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 which@1.3.1: dependencies: @@ -11148,6 +11198,8 @@ snapshots: dependencies: string-width: 5.1.2 + word-wrap@1.2.5: {} + wordwrap@1.0.0: {} wrap-ansi@6.2.0: @@ -11175,7 +11227,7 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 4.1.0 - ws@8.5.0: {} + ws@8.17.1: {} xtend@4.0.2: {} @@ -11215,7 +11267,7 @@ snapshots: yargs@16.2.0: dependencies: cliui: 7.0.4 - escalade: 3.1.1 + escalade: 3.2.0 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 @@ -11225,24 +11277,26 @@ snapshots: yargs@17.7.2: dependencies: cliui: 8.0.1 - escalade: 3.1.1 + escalade: 3.2.0 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 21.1.1 - ylru@1.3.2: {} + ylru@1.4.0: {} yocto-queue@0.1.0: {} - zod@3.22.4: {} + yoctocolors-cjs@2.1.2: {} + + zod@3.23.8: {} - zustand@4.5.0(@types/react@18.2.48)(react@18.2.0): + zustand@4.5.5(@types/react@18.3.11)(react@18.3.1): dependencies: - use-sync-external-store: 1.2.0(react@18.2.0) + use-sync-external-store: 1.2.2(react@18.3.1) optionalDependencies: - '@types/react': 18.2.48 - react: 18.2.0 + '@types/react': 18.3.11 + react: 18.3.1 zwitch@2.0.4: {} diff --git a/web/src/pwa/playstore.png b/web/src/pwa/playstore.png index 33b042ed1d305eeb0f86801fe97fe277f687eb06..570b08fb95f1845e28e8bf590274068e11d3115c 100644 GIT binary patch delta 35 pcmaFqdDnA-1(QnuMk^MD&0Y%qECSwpdSe)Xz|+;wWt~$(69D0Y3x@yz delta 48 zcmccX`OHr&FpbJ2NZuR8^iZB?U<&czk#O0DvSd1ylh5z+OMUuCUObn24YB6`waqCsFBd zu%DL~tVt*Uz#T6Q6#3@9e7eeJjbTVQcx6}lM_fdynwHjNW*A2a2-7c}LC9}~C4$;6 zuH`(ntz?BE_M4uzzkvDssR|=9$dA0a1eeN9S}q3C*in6&vSSwwT%3oYFF&jk#j9nn z@uS{Gc+_*YGbAc2Mz6M0~^E^Y*x3#foIGqf`<0HQ}?k!D~c3W zYw}F5L90NA+1j6+oLu|r1;u;vMr%?JH8@wAI)1<*qcVAP&zTfRS1{XHS%l+5pUB>C zR8xip54F=;DMVe6pu%79Q3WJNV;ntpCnL* zAi1IYYXAfS`9YTzL~Xo3y9XL4HzzCXo%_sgS6SQKwCa-wSC-WC8So=Nr5?ob>8oAz zWtHLd2<@0Bg^3383D$>@Cey%ziH_)j`SvPRJtn~a)LG~r--oqA${Bg6mlWy@-{CEP zCaC8u-Q}<(q><14mfKxOok&7lxfA=eUqf6A1vVP*=6?BHR!C1yJ`IX+1KEG{QDN5t zG_#^t4TLbRx5gP4DkCvu$LwF8zZ*r6l-xwu?3lOU`2x4+X?t<>!A8xDoPst6Qhs=O4Y1Fqjyh{L!Ep4(cuX!&Y2VwrefK6#K$UI3%`%6JcAJ@QgP zg)`kB{#g;&BiZA>I3{FM3MS|U)r%scxlk+&3BP|gkh7mY|7x3%V@rnZu}8hV{OESV z+kfm4Xb-W>-#Zs?48Fj46OwUzgj##^2Esfmk$>@uP&AOC!NVgYZ+N3rpWvz<4sxMj z;oExH`OtMzCsbvZI63mThXL2I0u9bAK;(0d22eoDp+XuSp^`u#bY4#HS9-8;ez2216JVaRliHN8$TG1H={z?zw@ME$uTE7u||o{OPc8A32A zU?~$q%ed0p#sZymNW%ABXL7=t$XO8dl~H4`ZVNKAN&E4%l4|un6e}Ck!dyUxsW@#B(~eOz>Lho4Pw~ zTn{{i;kOL|pJT@_a=aYBJd_F5ZTs4nMNQG~*2>?pxcK_Z_X`WThOmDo4V(0M>Frh+ zFF*?<@n*al9lYwMBW|<4bK3a_&4apgmEc5i3h1NaRqC59l*7gC9UV{+ki`jsn1niz z2>3F!p;sjK7(n~a3snTh+R_F~Ee|D~N{riM&3SiO`S#gM9nDJt^wL%)`S&Z=($)(SnOIEhcKrU;*=+c5|vv(0EFa_pppehkEdrN2TtL-a@R~fy5xe_*w>$sooc$|%p`e8g0$z4*f2o&)G-$yEmnGC*Rz!?>XrVjkSl#FS=@9pA zR)y>@F-Hg-&E6Nt(KJ80Zoc_nP@S3M1skShMp-${uMd?RKlmKg1(VEDym<*#eUW(( zROEU70L+$&yvZne73x(P+uO&QTLq$`M^e01h5^a1IhOO@S&cQ5*m`jOFeQ(!RIH8G zKDfDzYfgpC`P`(AhfGBK*F=u6cSO!P3w4RTRfwm_AVz@;Tkz$M8;lcHU} z&Ke5o>Qq{ttnlB%lgIZ7d9qh*Cnu**yGN4Y5fNe0G)3=Nj5LzBYb|^|V(7nUWlru1 zL^UE7y^p(eS-2Rf%()Z`KL_o(YGl&{qH+XPy=-`W@5FI?gwBl<+JOHY5T)RBj;3=T zqn~@&g#AytaCzqQb(E}Q$oup(x`*N334M4!IkjRYW@dI!6wq4rUjS+qnR88++E5A2T1tsRCieCwCH>ek{5?R9W`V=wWF-=&x~qoJUhh#-R;a}D1I3y0$IaA7EnJ{6`+GO!H#zs?lj7tY z9oa3-T_Q*9G_i2G?5`fVJiM{{C@eJkYJ_JP8prj45M*1lt&xxUo!7kFdXP$)nPwHzD?pK#l#_aoR?P@pBfxB zxY+Q)ZY?xI$-xod6mM&6dB6-+B9z>{RSy5I8{}29rF#5jEJ7)VsDqUqGcGZmQhMwD z>?PyRwo#>C2lQ8ceUghGD+A}cbU&7A_p)d2W?rrznjc1I+gsev5|eAR#{)&l8eD|` zu8bEh=5bo@Mjf!MCg2TXaR;K(0QF07QYzGJ+y}sa9*eW4S z(OXqJYfj;7UqQjlI?4dLA~cQrh%R@m*k-2IOV_PUJA$UVAVu_18u>B!brU^S=PxAp zP9&<<1HcZdf6U9qIh$WyT@mtmg+?SZJ3imyf%qPo+Ei6E+FUEr=pUGm-W*%k$TeSPPUEL{y{5LPj}^WR~A zaV5#0Web+{4evOx$-(bolymmT#FaDi>c)?zDKfqVaK_g-usnAQ+2;H9hY0VI!ZXKb zrHNRE_z$|ozX^aSUp&yZ$B6H1kx2OSFC1y#xmT@VWJ+5wC!o7Dta=qJ3)5_3YW1ZPV z^)bU3MbH*DJ4vJ3eRBwV)o$6v)*(AdgZ4GZSR6KVbV9JKoK@mU8hYm8xttz2%eU2& zHb2upUDcFIP{!=K>g40*%`4>em$ih(qGCcZZB*9$a?6S*V&VyjEgqhzwd}7ZiWiz1 zCT<%x(#$oTP=Z*Z)XYthVx5w*9}$*TxHIO3L1&bMC(_~F*)+Q6$PxkpbKa3*RO@s@ zN3RmEedRy$@I@}Z*5ZtqylR8;u+KI4cHHZvbYIyKIn9XcI9wFH)}^_bF|VpExs;G8 z3r2lPPgTC8G$?aqPR>yb&jnN8jbwuO`!;Qzp{ry2Lk1=NKD4CTkmZjHm~v(JCsbTQ zg>Ndf(RLeuSLT2+;o->zR8Z#6VN8jo1)(=$r6nC;ATXaVHduOAcw zl0gwK+hHeObxV;UgXr8Zwv?wvtjS{jyuM_xzP@{X?&DT=X7(E+xp%1vi4SaMX&z0) z-3H**{oS@g8jP?>OsiF;;v0)Hc3Vt@!ZaB8O|kyZj_0QjM$p}Grc&e=&irXEcYVYf z6P$1g_xEFUwLKEdVn*DCYzU0@Uw)M~5_@Z-P{6faUSH;SQbc^qBq_Ro+FE@JFVD3h z)MPMqMW^JJ7y~!JHBO;Z(aAg$F^ZC-7r|`;s4Xrn8!|M2g+L7jIgC+*b=Rg3&bb_> z3mhs6Gf}5VQKr=`>PLlc${CP`K!7)6<4H?MK;uV2=S|TWNBCv@Ymqfwv-Bv3#7O6IC)NT3dkj#C3PTf9!??No{Yh|T5Pu_=c$*k-s5kD^$PpW3aDK(e-wc6TDD^rEbEH?dcmC1fbK-tgk9htT{J(Xa&Jm*SI_f; zxjgGhb@QK(CiO`kNDD2;3IoChiSiOgb6G#fJU>fO#~ zNAx#tN_+0ZdHT*K#@|mLaY8^q^zAszbG*JnVI_irNOpG?7{RLIUv-}V`_!PP zAgE{(fzl}|@@o_-bhzW=V^+l8G47(7ur*tr^l>wevNo`7(ifSSOL{qONHX|Cmr4k4Gm3sGvXh; z=mUX1HEvb8-xt6L2S^V1(`Q<=*0EeH^l+(>T0_fw^nOt7!IDd3oJM1Yv$Xn|7?Fu! zFpT^Ynx7JPayE8r%yDr2?(qxwBjUf1;Q^=Pr_um9n4+yUwBS@ zv_Hxse?CJwUQ$WN1yp_f_^zCny5yp)XIYor8c;RC$nwLa=dU|Q9kKpBh?>O(Mn5yG zjVwHJ_Y;+sh4abcYc!g~RIb;t91u$hqaR1f_xS9V#xShMnLNnhHl2HpYS*4NPNygl zx4Wq?NnSDgKrnhqvQFV-2LbGP)zejEuz$a;N=Qi1Ii=;wRV$tRuH<@3`tq5C#+IB2 z`80a$?!J1al-BN?ve0e){mqWA^~;`V5G5mL-AzI&j_~!I{P)Yj`2K9+0^hfOQg%T8cyLAqN%Tjn^yz$h)3-BS_hW#+bD#R+G zaCFhZBz1dRO7F|{BjuTPSkxU{-5sY(>F1(HtCS z3lxkmtm3r9;lz$yfOXqeTFDW{it7%b@p}{8&)r)9*L>>D?|(tmsRKm`qUA(ONkl z`+W&svxnEzzTOXJUm0u47X@V35W%gg*}qK4#Xq^y1+#Od9;hHsX3cDcEYNy`zsuucV10^{;gI zmez%!9jCj%&keeYJ(T-%>ii=>}8H}av*&7DJmK)v~oRBIH?gH zq{m@QUMuHK4&79^#SEvZvj*-xG5V9fc0DrGo`(ZLV(+wCU4_lK4b%Y8HM8l!$pd-v z%+1|hLHN%U?(po#(?cg88Vx2QhN6t1C@k6Trnzo@b?CC zq9RWK5qyQmm%){glxP|zG&WwZmW&%$|9Gh@| z$J!tcH6GPu=xjh`a~X{i;clORq0M;ciY;0&2VQYI=&s z4kT}4^rfZOY+dAct#!L?%vT15fx)48qg}6A&sK4`N^{jQmo3QK!D8RQ9z&LHk~0Nh zE!h#fc;7>o#?rLHf`6MLGl`mDdDv4nLxml&o+ShsNV|V;#StmWiL@osf?xONEJds5 zhwNo1@1%s^M^{5|`DM#d&`&NQ*UQ`>Gk6p5VRIVr@I~-PwT*DNn~WP7IXV98?NF0L z?Hd4F<(@yiq-<=z!ca-cEqF&kz((FPg&Xm8YTTK~+RWI2$;QStLqTBPUq#29MTOJa z02lg#f>LwjNYJ#X*`B5%gg`T6L;RtOOXkn;0^U2TJ^*_MI1>F=OB)vOGtoKoB!BhK z$!8|>F32Ws!Q$ku9&3HI;nm`||0?5xb;sBc^z5O+J!k)?E!dPh;qNIu7-`cpY5^c& zdc7mNfI4fPYI3d{q!Y)erlp|m!tb2leT=jW!Zm(6*A_xiyYwWEd|Ig^~G86)3~AU^*7 zNC#U_s{tC?8>6BRt8%>y3``k)HDErN-@^{^+PyaNy$sp4E)KG$1y5pdFbszmRAW~( zrJU$SIM~S%pE_nz%dtc)2CnHx8j8sYD@_oqRq~fU2%DC+0C;9Z&+MMBybVv-SMjH@ z7}Eg?I0jpTONvi!4I3DUDmuiiNj++kDHk_9%}FQ9E0z0~XYYgW;A4ONVEtv=ZQ^yp z>0GBWBe4Sy%R)kND}*PC95~9gWz33Z>?fxEphVgYPZoH3*>7r9w$%|;g^_uQAC|sh z_FkuWGt(eI+u-K-XOl7sxp-`Og5pHTOjUvGXAx*0B&l}U)#{eg`AT=LIMF@5+-H8# zDel~3ENHksxxF`ewHb_AdzkwuM?G1gNR~{PrST3Ack(_#!BS;#9dB3LPz^@o8cnQV z_Kq=mv%=#sS@D8^;_V*mAD%}^U12!Yde>K_*Z(J~WS2`u=QHR9u~f#zYZr}~Iym!2 zzZ##~I2fAj!ph;p;(O9qZy&I(Ri$=%*QeJSI+RCth71}9JMy|fknGMmsd-xqs8TEL z#B`>NX>=Jx8Vt8vu6`wTI+)n$e+(*b;XxM53#vliS5b3LF<&43D!`vqgmae_kv-^- z=HYs}*w5?&$tYmQtNDSF?!pZ9T43X*ki$hxDr#PSyMn-D1p=$1Rmu{PwW%ZG)zCk>nPpCOG3SN|JU;_)56*%TkFIXcH(F)7+_fb*zp5CN zb1S4^f})$@_)#g%E5X#Vq^rk3g9%6F(&iNZGX~8^ak?4v)!xQF&By}%*iPZJEZbvi z>*5PYi{AC+sHP$q_?e3K?B+LD?csm zkl_puO>zE4PN)N87OsMeE%e3t>%y1u_C&q@KDhXl#klcsmX9~W8|tL9s$@VAs_1(G z3v-Cfo{Z9>1u+61lAlDLgaEI9Nqi!rnAn57Lpd^WNE4diotTE88(I?&-=RoQ_vYkd zD61{8P(yf^FE1n%t02Xoo6b@VX5#X8$L+0^! zt$?az6a@2e!|7BjEdVP!_ek~-fXG-54YP^2(^Fxa)DBMRpL*!0vv)Zoqp-nnD=fIa zG?smQ`fCqLZW1>3D9Xm~1Q=hi`q6O`V&Ggh+h;~s57|#lVc_9S^#5cfpAJC4^A}}h zRZ<(k&XN(5z(C!tkRSs?APd9<0a#>tLHX+Q97 zGIeMVliB2&KcEGXtSaSb<`o}q_WUP@UI!+qG-a0FUQASyiSyYz!^irF@)?&UO@qYX z^*_bJe4kU!iD75+>IRbMwN-no0!@|SV9dSbM)Hn!eH{bO>SjuscpQ({j8Ao2qbl6& zsGW+C{LGx_wawFq-&$jh;mjKE^%jK96p{k!dL)K(@mpJSw-Z@BVv3aP2NcX@(JZ}B zo@rQOoHA?@(w%50{C`{f_JnFc;Quh0SbAN1j@KQhhT6wH1*(eG^1={aA8&UUF6ZuX2yZI29=byGGP`3N~?_C}zeu zLT6Wa+jmuE!rQ>?6O!T|CM;ixJ2K%Mh>J6j2=!~z^IF#X(#+WmlSrt1-~A#HiL@q> z8PgS&cLI~9`RS)em7=dDC;86q3Ewe!0?EXn6?(8E`j`VzuQk{2{=j%<1-(YOU=k@| zc<5t-0$c#J0k3$SX84A^v$Hl*&|PnhY>{$xN*Ok}WTVnsCCs;OKm*oiqt>d-j62C+ z+!jz4ISts~5WjU&r8`nRa;?znY>1>6CEahkrZJ5Jnh%{VkoYZr{2`)Pd*VtsSeVAx z4|DNGo-l%0qo?}b;sTUMKA6oCbnLV-)(~eyno!y{!{^N|^TDht#JVXBWC}#B?d{Ae zS#3CsB8$`)h&tRr>|M(gqF2YV%1ry!jw{3yi)~GT5SNUB}oTFJIkBs3!bZ&{aV>vNW! zURL42*9Rb_*dp|fCys6l2?WR9Y4g@1W)cRgtKbpMow+L__G+VWtvnc3%uEf62UyBLx|H;1XkAkk+BhJ>Uk%jO zVIIiV0HMKP9)8CiMOapb66)(Ow20(wKs32j1Ugv{nUoGxCQ-USzP0N$i-k+*N}7M8vqgKMMRhk5 zOc-o513|{#U0UbN!_Uoe4ng&KbB?6l(|FfPmIlYlru6f&%#5t3FZ#oW_A2hK6g)W0 zrmv$1&I>}jCx%~S+eS+iFZN~zTwASImY&>GYOYP_AFN7T!}(@t_m;1Jlx9wOd3Gj` z+GUyfbi}TY3g4_%kkF}x#6{+}Dh(^e{Z1{xOp9j*_rnqLZTUO2HZBpJHZeEekBFb$ zmKfr6R8}!j)R+c_VF_x^HhVXxuV{*y8OfQd*Js(+FIZ`~tyq=*N#(sm5aY-uNp$)# zRzf+GX*Q7@oWbC?>2!Ts^lV8@y#Egs09FV< z`UvpbgaEv6K>++w{(<-x?myuFWcURBJN#dq|LEZVj@ZTGdWOnl$QrqG*=Bl|UQ%*4 z8&_d#1S(2dA)=nrfn9?5Ham-@DHh{r^%oMIH1I1(Q1QC6E1l&jRq+xG&O#FWk5Y>wY z@NeS&8}R>4_RbMbc{ap=)YLWKKa`J6zYl(n-4J?jq^B-Hl$X*ww01>cWRSeJRuX~# zOTMn6FaI!b^iN&exOJx=6hRW{BY8xS2U04t3GHDVqxI1s(RU=hVqVt0 zx1#g>g|)PO8(mr+b}lYnViwG+&h8G>U(GYt5)!#~5|U%PaYSLW^Ifl7$S^V$Bs~g$ z1ry^maUG!IT*oNv&7G|crk3fxG7wf|2>TL+aLPb`J~ep7L>&K72_{#eV`ir2`0^Vs zz_oox0aIK=Sz>AxLrx)b%Q0#Psw{UU61&k8c!yrhyA-x2m0Eok{q>DdzB7bvjgVr4fu*+W@{D#W$`~RnDH&CefL15fg$eWX&fw3dHo0Yu+xFBC<_&$2==<Dd&a6#vk zD%FiIev>a1nU$$0ut>Xh`)e&}b3X5W5~>|Rdf$!JHo;X;2-va~74=QAup^+1REIe5 zhrc+YN_s;@y}@thwhhbKSXce04C;TUY2)HlrRRvgHd%sIUBLETbygPS4A&F0N3@oo)`+4b-dIP=1+(wi6-6;5X_23|LMMHIC)#dwGJ zt7_aFTEr2j{-4&?;N^W+Y$!zKC;2z$_eKQ?9owV-a247QzEy8^$n#(6DRR`SH^$Av zWT|4UruC_E^;Qwm8&?3bu8h5@zP0q8o0T3v1MZ72KqLEw+02rOfgJvckM1v?>`TNP z0R+?-4cH9bz9!4bgwmaJkqu5MA#ucJbJy;!KQ@L4{aTa{ov+F@le^~cA}orz3~eop z$MY;HnFx&dKaiej)a1NzC@bPR_u$C-E>1JqtT9D!gFDkx+kok${-jc*=&q0vmm$iy&rXa}R%x%Yz-G+Szf9#{T?7H6n+%%+)wQ@~) z0JSW&EcFg$Cc<2A_pvwe=nc0aO*z|+4%CG>jzoFZ*1bp^2Y39G<<15r$tBLxN&hIgQ2OT!)W6D0E)fK>Vg3P!oPr%0024n z^;#9BLccb;hPy}s0FyRQNMr29CBgOI(d*AH(;DuJ-uDYTAxs6o0dw|H{b$HxQz8b|-iSD!34t>-K!YN}DZFTVT|29u=WKQQs}$@*+zjpSv0R?Gwgdd?1CxPg65vpXB4 zekJsEa9J_ve< z7Te_fK653YnbjKQCEcDqbLQ_h)UR0ReSdWIIo%}2xiG=Jol^9>`ioLpO>z(S0p~)4 zZ;Xoo%xL7_EDO;4{*cVuEV;SB`sz})(O>m?KFAk>GsQoEgjOYr^-49Ta28m#Q&W)b za40Ff_ucmZz3%MTp}a_{*7a62<))i(n*N)yyEJV*!GKuiQbXY><6SMgF;6muvs|76AF`0D{VR`Vqp9^~m zC}yi41WekwbP_Yb83d!q-@s++0pN`L8iKD;xiBSF1zM>;)6}#^Ddaay5oJ}#3O4dN z(FAmQYzBkRfuIeu^n)NuM zxOUA3?G}?cAJ0cu?nw=x$pZ>h*decM+VI@N_Q_j16YDj5L|+KCXB+31lTq!?PyD%P z)?2NNaCy(hVj_R`UL^~UE-K{DLfK7y0XV9My1Vd=v`!iz>D{g*EOKM>u_1g2Z z2RuByg{37K4Nb`Lu~lhlsR<@o__hpfE=c8<-3@()>O@}Uz43}is&B~HYvC)ix*Oin z;bBg3F>KSyxX$wOGA$F++yXdbaB(p$x7~W=u!&J`FcKv-^|n3lVv7?E8ynk?)n;Ye zKvGyyUa0qyN_t{z4{-Hzq7SXarZu}OlR09{Hi-1;n1)G(s_%w>_atUGDW~o+3mTizPjKsS z3o2TJ_kDzCes~z5l$5Z1ZgEiEnn;P!^hijA!Xrf(i@Rl>aApRLe9==bQMLXr_ed_37q{%v_7$2ex%)EDHe%3J_L%p0f zulZ~99hYDsMSizczHe}&Kl8-ScB6 zJr*AF3K^N5lQ-w#juv^=587{XCuhZ|+sI+lc*`O!c+M)b%tsen#>9j&C@6@Mib@{3 zN+=oRcA*zd$oD72+u50uj*gC!hK9vVNVe(=Q_kec%Gv#}QxY2J)AG&C%XQ0`+l)1< z-urr5zM!v5>IDf|k8v2PJ`Sxw;YxuQhA}E$(H(ta;?>5WN6BoX?HDb>9l%K z;^<(1kp)bb*vvtQyQMGl6A7lO@j1oN$Bfz=-33vV2_>MhF`iKPl`Gui*R5yV(#N^v zF6f>yMo>4{KYgTJ-Ti!%&Cx0P`Z~h$)p;09gI2&RH1A?JuIuv1V*qF&e zr7lNdQPGZLOS2j~JNsgdG0f+2#z&14bFMs;GVc5HP=~a%6{4lx*dNW%IKMI#GEsY) zRyarr)A!$QmR$I*-4EJq4yS+9en{cMQJhPDBD~{eUF6kQPHw4z6vaP78#d z3{Mbe+XPH6D~ElGCZh01>XuT;H;V=>_YOTY9_$FDp1F?;rVxEb?D4u3W4cH5FkmeP z)Q4M9@2|ZM$P=)6{i;i^nlYmmU`zei63v{S`Q0A5~A!pHlE!5mMk@IgZdH~aCwTFfSfwJAUA*af66#i=O7mBm%R z*DcjNe@~oC-*9*%G@msy=3vMsW_3F!A1o}oJYO2zE4yKwO@C#}%y;r<*mjcC#Ikc^~EK|LlSm7IlC66WF7 z)D3k5wvQFhpgm_|jSzJ|uoJRZoSytLGR>4#cXwoJjS zYm@}VM|fzcW0&_3y7AU|Cx2-Dc@D%CL8tN6K2m*B!yk_ivQ?R-9U6P94T?p$HEzMz zMK(@MMnlQn8wgM3=lwQ~S6AFos67ilU*i76r^hy;#g9H^ z%>3|NhA&DXJA>D3*xG?t!^s9K-@`*13G9z|>WbY_0b{&NOVJ&{Yq9a4QLF^mG4P85 z8}ot@rW&T=qRDvk*iMQvsfMYAD1>p)a9!13fD9M0w7~7==H|Hc*SMLOt}fB`RWtv| z`Nf60og6#@!X3&@iRY_kPH=mnV=%G56J4tpZtvV$-oHS0%;G8k_{{B8CCekni zh+~?4o|*+(5Br3LMXEQ3CjV+-X4Ag5<3FUX6(p$L_$qny`ZE-+RDl*zp6@+ zQ$D`lgqCf}MkdVrFKBKBSk-wN1BYtNQWH z2M#*mncKZ9H1wQ2S4nF8`p(p5v&{Eh*mL(NE6>P5m?G(dsnnx`;qLeV;T++)dTVOP zezWS}&SNjTyu7^FFf-|>>*2}Es##G^u2@1+($v7F!m=Dqx^>k5VVKmDW?fY1l#SmGN;vJE&^eKaBq zv#_AZ%F23pF?=3ACj@*}tJuAHKYmhiSC$<%IR;rwSeE`zp L3cyNH1ONX8+a$n< literal 20128 zcmeHv^;=X?+pcs;D%~L=(v8yHAe}=fEg>L1fOLs~0@5iUEnNc)r3exd(hNuo3_ZXA zXAi#L_sco|!FjnxxZHczUiH*{ujkpZy4os)_%!(U?%g9)Q&oI^?;aWw`1b}E8@Lkh z|F{bHgXtx&W`GO)1mV7jxp$B0o|>YZfuGf04o;BPCS!EhY#=j6tkheQzFdI{L=+&=yh&Wc9Hg!+)9;pbt6VXB6rK5=Ma zn$Xd2-$D^vKWwe7?;XPA(b;70KJSHqTRNJWiqD^uX=-Vak7_MsuyJtoE-hId`oF|h zyKAqyV)(#M4zaPZQCnXhICU}PbL-^f)DnCps;Q~@+R}K2JBF4`Lqo&zAZk1H-;laB z9*nubmfL*~J}zg+&?X@e2;u|m_vm4)2Ur6B9?Nvbzpl<*{&P7s@pREC%ck_Cz6jf zfL-ZsI=aPpf7B4v+uMG06fs+U+!sq>^bsI81 z{t3!A@hAyLSX$JyHW>JD0mr6_e$I79F6ernNy@)-Q!`{5}i*12Ti zh!#afwd*;4K_xtu?E`x*T;c@9O#i6KuMl`PJX)(1c{C%ZpMrS3u&>KPJ zvWPAM9?f1j|6|f9_6^SUzvu*O!xmPRutDqdVgHtmS>im1RqGhjSGBG&T`!e?+k?fV zdk=PHD(4NZ8|ppM4R&ECLH)@#j%z zp$aPku3AXkQqj(^Z}ct#A;(HoS@zu>W*YbDEwJl{vwZL*O@HR)^4iERuiD@V zO4a=vjI@)A+?PL(EqaNU;*w-8$o#ELv@HAo1xIyTQgj+fPLf`Uw76!uM@aNE~IR7H?^b*BL$ zK?2o6`*fCXWkf$&pJeZ37+v6;NOqA{(FeopdN{pLZ!wy?EYaKf1`9$&N=rATy%=wD zmIDi~3ss+3burREwrAje&jBmV8~jFA)3fVHh5bP)w&xW@Df(3i^v#Haxb+lqebi)6 z;rKy!7ff-OVeJ0rD88S98RmpCmNd&u%G>o(w_l*?SC0UV3>(J$ni`<}m5)da9g74k ze3leK7{4d2vi#V$)?-JzqtQ!cDUz`RgUB2*aH9W{YN?2(xGAu~@qOs`myn*U^qaSq zE2a^OeQN`;3T0P^&08klAOE5rNrfx;78G4|Wzb)+?x>qH=2+oynC(UX=s)#vy~dXG zmxP^UMv7;T;TEyMvZ(%m5UvxOB~hpq{Gi0d?eB84|I!WjgHHrsdR7p=j0M>rQ*oaV zLh^_Zh2UD-^OxN{Xl}6-ob#WZ*|_Yx82co9v)7iZ=QR#H%=d} zt0C|>`14OxPg=aO7wM6QBTx19uA1|b>jK!3mRHt)&8KSLT;f_(@>A(wiA8>zEUvLE z8m)@bfpuB*tQnz%GhYLJ7EfC2ka9f}EFD?%<5y}|Lp{Zfc#vQS4w+_xF0}qZ+LMfU z$>grW;B-dM(R^WPizXt_n8jYv+MPAn2nARKR89wN`T$d0PZ5_s{)O|Nh zfpQiPvCvJwn>YBf;ABq2u6HuKnh^ar!oMb)g>)+;Y8JC= zs$ni-GXyY#@A0GO%OS+Z#>T-`qtNxVaGl z!!^_b)wjwt+k^2z#BpgGTS0qa{+Z#&ii99s836%OnOme#WDU+{nkgG zlIW=R3oQaqcz6s&f)2;srf1T?Mo9RqYS9~ zLxkE)SzpWuIIXBFE&&07At8t-XfOFHa|HPiGH_v1YaOQk{<8MZWCPz3U*^da>j@tS zlCU@5ycu8uo^fYlW5eVz7dAe{!CLG}YWKy^o2e(NtQ72mip})3px-TR=ucc+SfIcE zOEO46ALKH*GyC%7)TbEYDuUE2QZC1C;qo5`XKS}FTUq{~EIOVNL4rcAMRY`vhAz{E z&LX~4#gB@j0)1Q;+6ebWoC|_XDL?S&n|(LQ5W7=xBVh2rqE|Ri7|*~(7{~R+HXTF) zKzVtCd}q*^TmzMB)m##=yga&M&o>Rm8+JALluH1UusD@~z<8NK$z$6>z__NTZT#WW zuY4Peqk)Ph+Som|#+Zd)J??~9IH$~5u&}avUSIkcG6uhiZ>bIp2>9ZR$Yed8(z=|} zx>~)RdvF}naQX_J0snUUNkFF1PAm;%E0+X%dwsrKPY%hbml6J3Fp12I`j%m0P-eoV ze-Zcbvp_;pY|1_hPw}TqLETPg^566GP9J-`7rI)^+v*UsXydXaZ*F^Az=SsCyN=`G zC#h?}wd>8+e#G0@99~l2`0G{C*>oK-2NG$M<{Dkr7JaYEE?4?la%&hRUBxdue$fVB zo_yCs*qXnBRk&R244%9Wkj{h7^s)#0p!OK`3%ULy-GLivSTU0iE@J;exf^qnyS3%G z&>l>%VgETsM_pMfNph3{=Ern;@bqJY%Bv)^Pwx1VrZWtF9q7_S< zVWzw?o~dttxlpWn*xDs9PCk*LrSMqn%oqa`U%F<8OU|7OU}>7VGBCDM>*Ij>2e~;4 z1efL5F!b2v(3PTP{rtqG>4hlVy?3JkEg~RhlvZ?CI|6CtCZzG0e^FlCH0V8t!@scw z?R`4`O4D5`aSJ$%Xz0wt&VZXBA4W(SY?CcWuUk9!FwEs5?u&haxmb0U_YFFzG4Jz>X=18;;HB;)s2j-BiE=w@ygiV^Vzi9p)Jv~pE3p70$v?3SR_ z$AvaT#^*F;e{7@Qb4Rb-s?L2jFl_J^>zh*p!DLf#E(wDfmkcXO|AY{t6(sXFR)@|J zK3@4=+vBYmi4F5qypPT(^)~EN<0K&rkAv2ZO=)T1g1|R9CZ%l8lJ>iAb@$f>oWH{? zunepr*rFN;Xa7>`!r%t!JN~ZU-i0kpkl+1N91&^~oK7CMZ zL)yu=3Ol^`U0W7;{%mYaPtgtw8%SAI3Kg!1T3(+%o@+W(KHp#TT1;}Bs4=XV7J|jQ zq3KnOR!8Mcu?9Q@3p{{`!^Dv8ENoBcw0U{`sOWGpdO3VQ+J3n0Re{xhuu8gu_h1-Q z>Y^D|7^GmsolZ8FmqXvwT-a=rmt$v@$6T)NwlS{0o>|(OEo7#1r|WLZa^kd0i}{eb z$6pS5YOy3v|FlMFJ+W}iT_!o`2@<_Lum&0!9LWov`fYCr9CnUuogU*Mjy$!h;{MD-Ne&A07An{sS|X zNst#NNXsw0G}KsY9U(MPKQFKe6W>_BI3V;0=p?0cdo^(C>;?bvAyZt)he%Y}w3mwq z`#U|3?Q?<RFXRT@`=g7bSyD`&4u)X31*gO~VZh}vh z5F~tcAmxGk@`s`BB9~Ry8!QL}{7Ka)MUl~Clc>+PM4f!BENteuivT7j8IE=CP_RJ& zWhBU&GCx%Fmr2UHHKUoxvawXU0fpAUp)p_f*JtrN@U>vo(M&S7pN{L|#af zVH%(Eh9L=DG~L@h%fK~3sM`EJ#OBSYvreQ8LCA7t9JPMn+H{wU^~m-Sm5?~SRKe|w2XY0_Ziq}1uE0|q%Rr?Ka1Sn z8+@e!WtO4|OXOhQQo;G()zgqYnI*pQz`Z;RW-QgoQ?9ok8Qa}!_QH~f=_9@vuQ(@7 zjFzk2p09K3wS&VQ+%46$HD$g3*a^GOQEfl(0?R+PW;aA65)!V298=h?tqKw_7MRR+ zN|Q-N|}wztNx$7nh?yPb@*9Zr8Sl zYq4_TlfDmAx-4@{5iVW5%f36-PzOtEp1rFJ7H7n9?YSKN|Du+23F|-B*6+_fHQR46 zcCuug3R=8^Fhs4|B6e|p*!;OqZ1KAmk2aXw_GZY&Pr5@^A2G;3;6>WDZyMfo7CkW#3{gduE~d}Y@N-^92Gj~_4<24^`~6y^JKKnw#bs0#zr|7J zS%`nWzSC<;gRtMC0@=i3BmD<2Zodsg>r8R~T}2H%doMwZ!J;(JLNni+HY| zD>$}#a+q1%P|Mt`CCwcq_6NS?vz?pd;nbhOFgkmrTl31dp_=`2v7YqiPt=p8pEjW1un;LSGINBt^^FuzjgRi#*(;6gTmCW<*$Cs`ordpnPOdbw`Fgb-6q- z2Xr#v_Jg6!e1rEUV=JEeg7juU4>v;^J)Ut=8HW!iU!68+k|k6GX&Wf98I~&h6H~F` zwUCoEGS?k);raox^^5VTTlQr7GB(De3w^{VyoXnVNB9%PHL=g1MT1(M4L`!&KWSW# z_i*`DL~%LKva{&XAk#S$=R)eD_)6X4sQA6nj}cU?s4KwlwK^GEfGjWs;xC%)WqXvdD1i0 ztum1>qhWC78aMY+smn-`1>K$H$#)|fot3u{@c9->`#ANfA1rH!B6JdO=nrif$%}=b zReCON(&)}&Owr%>IRC;&Mppst^xl9SiD|oqxxdEpc70CEB_}QJ$3^viK*%8I!@G&S zUFPv~$rNt?{J3CA`D-NUD`N)ozr|spV6`&c(y!ijC-;os$;h`VH(F=Cro=hVR{8Kv z;gjT+(I_2w(^j{qqOE~}F9ZeY;MuZrdA*zYotsZ)qi?-ebFwo}M8e&7&*;l^%fG54 ze4aV8Fg>IGsFB$-w-L)!?>6Cp_!mDv6h#x=c3{_rZR#V!!oqNaNus&~<0x$p8aFPUdYLIoMn%~ zWN>;1kAxY1Wbxaehu?v4)%+L|llC_}&!nU-nmS51Q=z5scvZ(^{yShI1Uyaaa#j@J z5k`Mt-Jv)7e?3y>_-!Pk*gx5(e}mk_x}!zn&`<*ao*|ciOmauw0sr9&vcf?l|c z7a$`!i7?x4z**4IRmFM$xL3qQHo==+XWxGNrh1=>KVRH}(Juj5N~M^4k$I=zi-ED? zci~!Y`Eddl?*VHq<1%FIoeEyXsJz)AK<QN5?=>YRjz8i!RVu*L9oxR3HfbT`HBx&Wo$R9z-i zoJjdj22TfIe3ERkfd2?!Lx$+qJ5jsN`JyY}bVM(M{aBFSay05TpJRGlJ!W{r5Z{(Q z15^LXRjF{(%M(2VOMXK(|7yVQWtYL<%QYs3ELs*3QM8XwiIi&|Z;ls@<0nWpQ@;WQ zJq`~>NOmCjoq&ahK0?2?9RrD3zrX1>zddiGO=GXW?8=V$9-z;yV-*jKy^b^`)lE-QQ+s=8C zn>+YFgw21?s>!r}2n#mjM>3ieeKD8RzUb?%h$WD(wg?63VooFuub6c*JX7abJAug> z9J<|C;WFKe3_r8l!-@;!KqGsfgc8KvX!tt!@r8OUbd-{}S`(n2tpB6@B>CB9#y!S- z_K5(O0Q#qnrSM~)@s%M!NG{bvQ7VX}vu*zKm!xGbbIZY7Xa=~!mM_=cJN}+;^n0PA z2XFAtl2L+xD$b4WGE*H{T3Wip#qQy@aulsp$N1MOkS&wm|UsA=Lj=QamS?a zGXo{t?THeSHU2(7Lf*TTsKM+r5gI4gfOYv{0~P=wBfd^t&iek)kGZ#z=v>k z5f348vISCU=hnp7UDqORWoL6F^-18Q&vTnhJ7fb|&)$&|L>IihboT}K#`tfSnU4~k zN_t16&)1uWZJI~ZcV{V7+x1M_czhHn<_w~?5#$2Y(O4O^Tm;4lxsbI*zSP5CjKMH( zf2?ffL8!wyiFgmy=g-QjI$HATeTJIZU~~ohGo@`|jEoHPZWcdsW!@)YT+45i@g6*& zqA6yPW=C^+zOTizXU%L6F(e52G06EyN;Jd9mdLC3Vc!5dGkp|)b5j^zN^*7zn!eK+ zXR(G1M{FJ;DPz`sAzJPXDu@XaC(`&$@aj9j;J>)DNi~`XQMudv^mEe=k#^zd<8&AS z({d}Yev=S%+_qJM=r|`_!Wd=eDWZ&1E5XmBI*})Bfx>%J)M=ZPc2gUU#cId&jZ_fa z1OI1~H@?R^*1rlD%LMa@hxX^=y4YV6ziv2k4o*L$e8R&S( zA=_lURFc!0SmEjKiQiu*;j!@fwC*;>V1dhYr!u!9Pjn^1u03HBvHhr?ymN))l+r`( z)9^n^ z89%WH1b3wb4-gD+0l}?l>W%){pcqe7O%psk)U%LSW`Ni$swV78oCA4PG5!Fik#nPw zHftR=$)l@&jFfsc5wdti#p0|vNXa0*B`t{E<;L*Dhx!?)+Wm%%`@WR5pcvHwBYo0N zYXouR?ZgbF8$h!BoB!=lWQgZ4zTbacLerK+NNdk25oW>)L#F^C114-@2LC2=d^>BI z3h#g0P^xvgglol5#+>-MP*0+}#Gb%_>###DWcusb@0%aClRI;SV34LF^s0Wmu<*n; zE6#Dtl)_$blmAQaJ(J*0MjnQ#A&(X89it>cDyCwe$ zW51hAfOY+pRTzIn5=dY^eF@#|bo0=6P%pBmjj9RfCQb$DOHS`Q5ov+)ov_@j5@9rj zMCKJP_jjBxlsI6#25}-6s67dRAZ-1?odx1RBBLHf=7DT2@&NWR_Mg!meIytOm$?Q& zPeoWODmV&-kk!`Ku2@{oWHsx#$pmBXOjjor>iXqbaZrLrthK5uv&cz4J~bj^s2pF(Eq~>bN;`~a7;qNuI5!Da`Iz{BFT)&xR06xT|Pn(b{#1S2J7^w^m0%MZ32cd?)9y|lD6PRlm$CboZH z2w5K@w`lPQV_oo12D~N{S|kZ@J`JEZ46Yy^bh-xPZn;2tgsl_68Oz5>*2|&%M}Jm# zlFW@N%s~&;OP3#r+V2Fotn>~QpK+DIUp|0PR$Fu=%*UcPNH_;hD`Oo)V~ZvyJ+e>m zy6v2Ns|{%jbNwo;(9%^3(8L49=xmpyG=5AtTFjGAJPmHS+m%(6@=1Fink*f&Upr?U zpC+~JPv3W+s)=)Un-*_!A?EFuLUTVbAnKfNQ1UU~dypLVzCFF}3@%YT_4lnOVX^V- zhD&VEPoFLu|4@mxW+${78iumu>tCt<+82jKOcsQYNG+H1p5dRn@yM^1n zn-WPx*S#d#6KKSYi%dD83a0hnBN1`$W-_CZ5aPzK&v3R|{4Yo#W}O7(Rm!%O>8~#m zO0qKeow@d>-QuaQB@41EtMKIzHamiJwT_Cg&ErZGI0!RVL3spF72Lr$bo9~(aiJ+G z+0cOgz1QM@asm42yRKq5$4NA>8wMjo(ruQ;=f43bWP~~NV=Yb!lcFDAT>S{)_x6={ z9kVp?KOOjUw(ep7i)Q#)Fu|**9g)!v=RJif^lq1!EOSE)jYCs|TQ+Vc*HhAct#iF> zqL`a3e+6E5w{IEEVj7R`4=yC8+iVz7oUse2);lNM`e)g$Ph8{jnxiWx+o*aSLJ?wf zGOr%x!$FIW;se=%kjfOLe>Eg94x1rk1)KGH>R(OEz3*f5iu6o2Xu!yDf{d0ILP!fq zSWOb`%F@ylRqY66=T(wyqf5I1v}UG*+f2f|w<3(%NZTZ~!jRT_1Lr`s5FDWa-u6g$ zd#K5(oj)_V$2rv?G$5wd-@^E&P%)J^W3HauVx$-5#rtsZ=ia~^j$y68tyr<;({}oza&1cBptHBVd%zZ2(WB6faSXhw))CCe#yA&MBYKg4T}!?7Dbp0uJnGiF zMW{lOX-~+({h;_!Kl2k_>LsbmA|<%MNB9*{UTpHd@`Ne5)@7F?E@MlOA0gzKpUR~< zJ_`#OY^j!Yi5r$QdcGu=o~t0xXedFY9+DV961x2(ZACXiLVZ4iRZ4`Kw9Zqte1=i_ zS_*KvzMZQmpolMv+In(Mq>$tB_>+!s){M(dB1JKVC?2WD%sbNp_s#1FlBWV}uLG@W z$*gqz68N|Gum{De^zlNvVda4}yu%6fRHtqjUABr0hk=*kDOMNzmvD zokF=?tBlJiN_83z7Q`D8@ca#B(`V6cNODc@l8HJm7q)N8uwKt}1eC8ED>@4>CmoV^ z#(4$l^Jfhm@jaYl4=sunTaG;{}&-2tgt@C0*4k6Lhi+6ki(S zVB#Qb2191_TGjMFP+}au4JLWM#$(Xd#;O9#vbv=&n#So_tRU^kwym}KA@N%SdRy&6 z{`Yr1ZJ--leweY;hsOJnAZw?F>g0r~_R;P_D-JY-mD^j2u&%aU@^c_~ z*1h+i5jLwP4(0?h`(+$X#y+tY5QeJ-2CrsY4ndzu%Qxm~%nqeA^e>ZU zKw2_a-Z1*dfNEYmKP43-LC|)EktFJOshZiWWWkquEEa{go*YKcJa1prJ=u=Re5A>R zM7Qv00WeE<1uF^`Nm77)hV!l;h(-~NJ>s`VmTp!k6wmB`ChCnSk?g%U6D!>vWBORRq(cOlWtdx{w@2@pO8N*HV^Xb4@;83b z@L(;R;>Ey-vS==To|nW|Lq-#0vWt8VA^X%`#CPGNe)NkBZ9Oy}E4eDWNq$KOT$7{7pNm*M?z8fBeG_w@vP`bv`8$5e)tU6I&JqWo#oC)@Rm zzH7M+D&oZcgo$Qsu;C1a7^mMjgVMDP(PmvAxE;z6Pp8TXXlgPgoOmx$B|gl6Es*3jWKn{N3@VjW#v zNm;>0tMbJ{W{Krt4^oquL@hKit#N1g0`q^Z2!2zI?fW=-20M{{+Tqzs_}qwLfVo_x zaM<_Sy4{!iC+PJ6Z6GK-vPOpJ-CTTw^y0Xk$*jXV7uP<%^zHE>%uc+|rkIe}(+J;-eMSvvNX6UH6RNJ78dfE zkw43}0`JkzWae9$3t5;^vVCwc?Z2xS!RwhTmB=9 zEgb~eLT~GKLvY}~i+LX#Kq7F`2*-TX=}pYyjrX3JJ|}at>B*=QCrfFKX{2dMdfP8azo;dehSj&f(W5-l}jSeqETB{3bR7Qqpd<#K9U%)lu1JUYNMV9;kI=QdmU8Q0sg zor+uGHZoQjAKsuPjO;p1-dIga?{mSA|KQEWW|n_8Y~)dw)Hfx-K}yGmy)c_U*N5%l zqY3?3bE}ZyYzFH7HqIc@_MvAaQS80jI&M-OgX&xWwsDeD&u6!nlRF>=SUi!2*S<{7 z7HIDCpR1*^DYj zi1U*UFM4LKplpUo#tXB<2X=4;BqDJL?Bbq$;Cy*tVu z<;}<|+}-E4NJ0UMlehOaCq^%Y^#G>C3X@;xjz;po;~U$8{k2J{8`5V&0bUKoSQ(%m zpabI;k^IDm@^J5yQS;D82x31>MI{BHm7vB6c&hU8??K5Z1eSm@4tdaYf&7ezC<2@F zFIMk>=S?gZ$T-hWHpPWQQ zMq&+*jM&)QW82x;O$`EB52vpj9m_6FkLSC)Wluv6c_>cLe{9s(HXom#N2jL#B4`)+ zcW59gAfSiU|MMsBJTj3+1Rppx;QNc*bP1uRrv6l%2OQKkGzdF}lol5=adF`RKPHeM z33knl_j_O{6zTzkMh2~ibN@>}*?JdRRK&V7RiOfN0niiyXV41Tk2LxuDN=#?;s z&qFj|1{XvdXM$!bD*QzybfeA?On-sFnI}HRY@Y;CarFC8Uetjqz!S%Rv(3C~&i@}o z@PzZz-D%1g*1y=>htw2!)I;@duzifY7rRc=&EM@%-l<`b>Jxr`5@u%RFDj#Pt1MDB zQE&F<*8Lpsa0O-m)}}zRtSFF=EtPYByz`4*vh9Zq{9);jZ?hx#avwF<)p0!^tdh>C zcNl$+n9VkoP8%FNihD73oUh6xhAxkAHx`3-G}*USeK8J6QXi7dS$@EYr29$Zf~bVm zN7Wdoi`b`O;sb}b4up9^ds4B?($S-vaDq1?>(gxc9_SAt&`|{ahy;Qo(5Q@mVRMH)QX%5T4C-8_`O?10+bM*PZS9w(80@oezh)w>s2hr0I4; zvf>E`(eK#_H832BLqdE&y z68wS3-)4}R!Pn5R=T$AercQ6tCE3`aW~O8FqNna6kBNberqcK z)jJVObNGq1O=cJ(!kdZ-k86TSUSH#>Nk%cNX@HEH?bj0m1=j6;kquQXP1)CG*a@1$ z*3@1P-HD6f1l~tpvl${m({LYCNQNjLXIkhpsLntnVTi4-tnlOJ-9#&^62n1S&j2il zr7v}imh6}F=#1GX=mg-dFyAgZqUN%$!;1v(j+q}6^S2TaxN4!FA4$P`RDyMT%b5~q zb#!+P5T2X-E(i*5%V+eB!e42EeQ@k=JaN@L)l@4M@Kf81t^3MS%Vwce$ztwIWw3KZ zt1(^EO$QM~?|ZGcxBPCvsptL{_}P2l$l>poLY;HLj2jyB;4#cE84}KRS zrCcy66JM(kz*Qa}iMGF}Eq|`|01gg+E0ze1S}w#6Va$ctX+DQl`a2iZ*lrKYcu29M zQx;~!dozYIu1+mAO{B^9lSK2US{ya0?PJ>OMBsAg1N>?s2|V?X-l$L$@%c<9Hh!X4 z0f9C%l3w_rXl4{pmwaNSnTh#9LzWjN^A!34Gkd8O?S{C}^KXq1-0J9oq^ZR~@h33V z?XhehBZ9KomCWO86ZgK=0(oE>GW^S8dx16=Hy0jjhPi3?aLbAp`j!D=dr+X{mr+L} zSoGPHyGBxHB%|~N-e(2&eD{7wWa}ykO|#fQA*fPdGkuAZwC#aZbhP?GDGphs+3H@C zp-l$eJD;vsim?>*<7L_5JBSh6q_xiEbFLuzsQUmLuv_aV;6$d&i)I>;M-d(TRBTP} zIoAh1m*{o~rHy$3-Oc=K2CXF*g8BEq5cUMMu2YWUOH%Ka!Lu>Di7Iw-=Van_uA-vK zV*Tb?k6@qX3gZIF#m&frwD0BMgCuhtj5NFF0?EhAJ8_;A6J3ry1-AstP>^Se$Zr3^ zLAYEQ28}HfYBWa3ylP{8v)>W_d8EVI=4DJ70Zy%0rDQ-uN}HT!rQY}rZ&V0{GHjRs z1z_et(f#pisiCj&zOe)qv;MurLk6x0Gdw~s84^+4bmJijxfF91e?Um<;P5-cNU5}$ z7OMSaiedf@Ij?1AVO(ph!6G5FX=>g>$Y^eCh&(62JLM8ia8s6D9hpaQOQmwN7(?J| zTO8Ml=iC&C{?_?ut*Wx8F7`?Zeyec?Xv=C}s`*;H4|clac`BI%KwG^$lD84CWtF z$Pvkw8Di+^>aav1fYQm)q|-`IbYI@6=EDKgjpeSz*-`)TTnZq204C_%50=TM`ve!h zF7Z&hbUK)9C)+Gtf0rUYUYhtTf^22i^CG~4IY>xIXlk&pPw{lf8aOGRYW6G22WqkY zGf%WBU=}$T+Hijw80yn04eX3kvC39~S9VjAx z3=~iiZ0jQ?PGZsHa&j(veo#8S`{(0~z2$zmGXf4~>(}>T6jjr$LHbP#A%D3;?1C_5 z`V0qsS@2~2_gH!MdDFl1A=4+BO)J!FWePUKg364Mz;CvNI0=zd2TG}?pfi<=@p=74 zzB}&HY3C;=Td8oRwEmdj@dQ4INY+XJXnA@0XhfIy_H+C$UHSK@3^*VokeMlBxlFIf zK_qCz0bWm&Q)AjoIbj@v&(VCeS7IU^T|)tBGpf1fal=eWO*Irj_Qz8ed2RkYBIS$X zDk;IJ6VQ{8o;JN-2Y(NoVOo)f>6dE5fV?eZDYxpykeUmsT(gshkX+I2ikCo%UPaeb zW021XNO+fEJN_xlct;JxWGO^KSLPSrO^x<3`A5tC15r^t@vk8q?%5ARK4-|0aRy*c zHhPZ8`4&=uO4L6(d^Of-DKc#z)jnH2w;gXbJyXn$w~Im_@w0# zJ4tWiL(OiK_zeC?6qfbfcb$iGT%PT5>%7&xOF27|m94+9D!8e(|PKWdr zy3@T_Hvo-Qc{h?w*+`$SCZv8&S>KX-_@9A!3MWM>{W;_TL`frvLI zjMJ@n@E_f~M!k>nc?5d@INr(FHygyiYBtDA#Ih z1c-8+B-%*xoRjFNOS}~KxXTi!<$V%t4xe*`^%Ebk>n}W>eGJ~(?FfJRi;DCsj*Al>LZeB4fzoYx~KjVKG8rmZ2 zqHfwQA?tO%7Hy)W z;ut(6daMp8I4153kuTER1rCPsqi*KG{m=g@Z&&Diuups@w(a7UI`w9*3j5NG%KM`` zGty8a1j>;YR9IojZ;7%}-%@1XXkFQ^S1K=UvincNA9(<^C(lPDYTV=B=m)vo&PYp( zu5a!or1ODt^>;T2$!7pYdkifsyRU{PWaQSxUMcS--#djS8VJ$Pq@St7>eK#JJ^Ck- zGExg@cjBuqYyR7G5%ZzpEM*|9LgP6YC_KHyH@}P~W>f}h8ebCL8|gzLkt-`J_Z%D? za`wXUP?(^*g5|v-q14lD%96~^OOrSsLYWHr^sGLwt9D+3qvoySjFeU4L(Yyw-1>>a7kRt9ZP-;_yViF7Jm*7 z;%IAYKLl47qbfLM^;mTc9@Y5gaw5~8G}f%z1GN+B&rBB*P_~*4y|)i7k3h?gH;rjJq0s;F{!wv3;*Tvh7~eJ z3x6Y`e=TS|N;kahFZ1hcFG^FT*^DplU|mC*rTXtuG){Hm_|M+M_0;e7KNccFjyJTX zP8vx`Nw+3S2nG_UF@UUGLuZwDbUg{wLU6>P9bl=bFmQ+>>gqf{ORXCs#M~Bizgs?$ zKZC(wE#PZO=jlp3PX%kB?wF5{Z#F3p?_X9LaBi4`A5wnsS`(<(a$+x!@k$JxT1?^B z6dgzgD&>;_7%IG-nv4D5ft|sV18f)WACyUKN6(~hZK>tad--2X1vES<=^SEC@URTE z+60n2g$AX&Qn~q2#w9 z&HU$|q3+jm2xQ_HERDzURbCGuj#iXV8Ly25^^I5aO@>-A-ba7bG_ynr0Z_?l_~jwH zb~diN`vK);y_GT|IXM}qNe)j;BwSrxHE5*}0iwOLU!#~PQO=je^nM)l5#4T8*RB5P z>LSCMOE2}7!Pm|&_IbH!?7@KZ&IC(l(`gi_mmHblq=wDgyjp+oKMg`2tyjqQxIqu?j-q`)r z=tlY1LBgvk3DyqoktZLh`ugsP5`B(oqYU%bz)-V}<@e!C6nrxf6CWf0cmggiNu<0n z?eW+U-F_fSH31w^8)H)3OT$a9StphUr5xl{tn7>#Tm#H@B*wfw)!Pny(By`Q3xXwB;78%N8bk~YI2@Z0-+;eW;2*f}!1U%t zx`??IjLw}K9+l_8@McZ~zvTVO#h007#)={))LpJ%#y$;^IUX@iVC>2r%x5 zYwa4e+xi3c5X9>n(vcY~;B@#<@hR>We7~po_=nB)=nNu21^-K1>DtemdB+An!U35o zn8PC^fjPMEbA5@xeuXcIkB!^7e~-;mOL(1sEVL6jEHOY_4=WDxLr&Y(tDVLHa!STLcOP2YI= zZ_z`YjyezaO!I|-r0Y_qwRk0}b28}doTso^?rb!q+F^XqhiIv*75{Kq8=7o}0YA<+ z`z^Wq6k!yI0}_>r+-U5QQ?F95O@PEsf-B(uf0u&rKy6kVIH$|0TAIeWx9Y5^Y zzU7mYyjpp1b?E5nBQ>!R6#n#8v_|mp%evdaS@CrQHoLIYyRf`syPXX^PWKl~>$TRw z2!NdHy}7=sm#Xt8zX1|#4`&_n$}^ApWmWZhDR~|P?xCB1`G)#Q0)dp24*i9TG%&HKf^Byu`qt8t~nn@e*q}r?!{a&UxiZY!E|A zxm(Jg8}f-d5o?o@_4N+Z6R%4Wj0$X<5gqe!k3;sL+;F(UXjSidNVekM=PJ^@c03hU zGdnkM#4Q+`y+eR7jeaRIIt%NsvmeV@P02+yZ1dE0T?w)J3BjfRc?D34FM~%wJWVi; z83JFC`*;#~zMoj25G}nMKC|F!70JhNpg#kTJn4t@5iTya`x@F|_l3#{yzcTp-td2%Z)3OD2M z>dkjCE;x1bn+)peT2t?ClFQ)Av@LxWJ#q97Hte1EJ~t#|&}E4#Ri&`gn5ruM9&y1{ z^NA>J_by5%3H!zI4k`v07#=cK_R*j;IR83W;HFhc94y=!uwgx_3-o%(nt;}^9&|tDYRHT9cRQFqceW7#t&@Uu|!RK z;?aS;4m@J8c(ef92uKE=&g4<#-zhIzT;?Py0rY0KMd-=)FT+OnJty{KvtG*J)73-i z5%%CZ_d}|DKVcwA&IREqh3b;?8EWa?9N&-M z%lRvLIJ<|A59)07+lQ#7vhx+QU(PD+SxiFf&5j-ijlW`QBbbCz*6+r$2OaWQL0BUI zB=^Jkg2F1sL+1|I3gZG|T__>J&Wt^1`>tCzz|FGvOb4760UF4E^2N+RArhZF4%?8P zUdc@a`F3BF4@${;({Jaeqn+cYfKCGB%F~qa-GJJ>w;e(%49cI&)%We8{4S95fwHDQ zKIpKslIp&N`?LIuq)t-rMb@ZnCPHV5Qu`}W@kb~W;4JW;GE2M!-qY}ZUsTa7F4||E zQEKXskg&J6|B}A!ahK*!#%YGhi7fPy_80zVz1iMB0$6FRa8%#G2UR55MV0-6f#ptr z?*YjmPcZ)TP2KxIm;Ebj|EZn?z7BPuzJoph=C%bgefh9CK1BmH9d~ZQp9111JwGrI z)%Wko!0(gyva+(FJ6H~L@nOPvKT^etRO9`Am<0uOFfcIG|FfS!TPEBX-(Wr}``_nr2Bo2Z*WGPw%o}1Qu--7s$EcUUE9dU1DQPQK%Ui$w EKk$?dhyVZp From 40eac1e2ddc08fe84b0480d628061aea512f98d4 Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Tue, 22 Oct 2024 10:27:45 +0200 Subject: [PATCH 13/26] gateway management frontend --- .../network/NetworkGateway/NetworkGateway.tsx | 47 +++++- .../NetworkGateway/components/GatewayCard.tsx | 84 ++++++++++ .../NetworkGateway/components/style.scss | 10 ++ .../NetworkGateway/modals/AddGatewayModal.tsx | 146 ++++++++++++++++++ .../modals/EditGatewayModal.tsx | 146 ++++++++++++++++++ .../modals/hooks/useAddGatewayModal.tsx | 31 ++++ .../modals/hooks/useEditGatewayModal.tsx | 30 ++++ .../network/NetworkGateway/modals/style.scss | 15 ++ .../pages/network/NetworkGateway/style.scss | 10 ++ web/src/shared/hooks/useApi.tsx | 23 +++ web/src/shared/mutations.ts | 2 + web/src/shared/queries.ts | 1 + web/src/shared/types.ts | 22 +++ 13 files changed, 560 insertions(+), 7 deletions(-) create mode 100644 web/src/pages/network/NetworkGateway/components/GatewayCard.tsx create mode 100644 web/src/pages/network/NetworkGateway/components/style.scss create mode 100644 web/src/pages/network/NetworkGateway/modals/AddGatewayModal.tsx create mode 100644 web/src/pages/network/NetworkGateway/modals/EditGatewayModal.tsx create mode 100644 web/src/pages/network/NetworkGateway/modals/hooks/useAddGatewayModal.tsx create mode 100644 web/src/pages/network/NetworkGateway/modals/hooks/useEditGatewayModal.tsx create mode 100644 web/src/pages/network/NetworkGateway/modals/style.scss diff --git a/web/src/pages/network/NetworkGateway/NetworkGateway.tsx b/web/src/pages/network/NetworkGateway/NetworkGateway.tsx index 9dc55208d..bebc5b972 100644 --- a/web/src/pages/network/NetworkGateway/NetworkGateway.tsx +++ b/web/src/pages/network/NetworkGateway/NetworkGateway.tsx @@ -20,13 +20,21 @@ import { useClipboard } from '../../../shared/hooks/useClipboard'; import { externalLink } from '../../../shared/links'; import { QueryKeys } from '../../../shared/queries'; import { useNetworkPageStore } from '../hooks/useNetworkPageStore'; +import { AddComponentBox } from '../../users/shared/components/AddComponentBox/AddComponentBox'; +import { useAddGatewayModal } from './modals/hooks/useAddGatewayModal'; +import { AddGatewayModal } from './modals/AddGatewayModal'; +import { GatewayCard } from './components/GatewayCard'; +import { EditGatewayModal } from './modals/EditGatewayModal'; export const NetworkGatewaySetup = () => { const { writeToClipboard } = useClipboard(); const selectedNetworkId = useNetworkPageStore((state) => state.selectedNetworkId); const { LL } = useI18nContext(); const { - network: { getNetworkToken }, + network: { + getNetworkToken, + gateway: { getAllGateways }, + }, } = useApi(); const { data: networkToken } = useQuery( @@ -38,9 +46,18 @@ export const NetworkGatewaySetup = () => { }, ); + const { data: gateways } = useQuery( + [QueryKeys.FETCH_ALL_GATEWAYS, selectedNetworkId], + () => getAllGateways(selectedNetworkId), + { + refetchOnMount: true, + refetchOnWindowFocus: false, + }, + ); + const command = useCallback(() => { // eslint-disable-next-line max-len - return `docker run -e DEFGUARD_TOKEN=${networkToken?.token} -e DEFGUARD_GRPC_URL=${networkToken?.grpc_url} --restart unless-stopped --network host --cap-add NET_ADMIN ghcr.io/defguard/gateway:latest`; + return `docker run -e DEFGUARD_TOKEN=${networkToken?.token} --restart unless-stopped --network host --cap-add NET_ADMIN ghcr.io/defguard/gateway:latest`; }, [networkToken]); const returnNetworkToken = useCallback(() => { @@ -78,8 +95,24 @@ export const NetworkGatewaySetup = () => { window.location.href = 'https://github.com/DefGuard/gateway/releases'; }; + const openAddGatewayModal = useAddGatewayModal((state) => state.open); + return (
+ + {/* */} +
+

Gateways

+
+
+ {gateways?.map((gateway) => )} + +

{LL.gatewaySetup.header.main()}

{/* {parse( @@ -97,8 +130,8 @@ export const NetworkGatewaySetup = () => { {networkToken ? LL.gatewaySetup.messages.authToken({ - setupGatewayDocs: externalLink.gitbook.setup.gateway, - }) + setupGatewayDocs: externalLink.gitbook.setup.gateway, + }) : LL.gatewaySetup.messages.createNetwork()} @@ -119,8 +152,8 @@ export const NetworkGatewaySetup = () => { {networkToken ? LL.gatewaySetup.messages.dockerBasedGatewaySetup({ - setupGatewayDocs: externalLink.gitbook.setup.gateway, - }) + setupGatewayDocs: externalLink.gitbook.setup.gateway, + }) : LL.gatewaySetup.messages.createNetwork()} @@ -154,7 +187,7 @@ export const NetworkGatewaySetup = () => { {LL.gatewaySetup.messages.oneLineInstall()} - + {/* */}
); }; diff --git a/web/src/pages/network/NetworkGateway/components/GatewayCard.tsx b/web/src/pages/network/NetworkGateway/components/GatewayCard.tsx new file mode 100644 index 000000000..3731163a4 --- /dev/null +++ b/web/src/pages/network/NetworkGateway/components/GatewayCard.tsx @@ -0,0 +1,84 @@ +import './style.scss'; + +import { Gateway } from '../../../../shared/types'; +import { EditButton } from '../../../../shared/defguard-ui/components/Layout/EditButton/EditButton'; +import { EditButtonOption } from '../../../../shared/defguard-ui/components/Layout/EditButton/EditButtonOption'; +import { EditButtonOptionStyleVariant } from '../../../../shared/defguard-ui/components/Layout/EditButton/types'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { MutationKeys } from '../../../../shared/mutations'; +import useApi from '../../../../shared/hooks/useApi'; +import { QueryKeys } from '../../../../shared/queries'; +import { useToaster } from '../../../../shared/hooks/useToaster'; +import { useI18nContext } from '../../../../i18n/i18n-react'; +// import { useEditGatewayModal } from '../modals/hooks/useEditGatewayModal'; + +interface Props { + gateway: Gateway; +} + +export const GatewayCard = ({ gateway }: Props) => { + const { + network: { + gateway: { deleteGateway2 }, + }, + } = useApi(); + const queryClient = useQueryClient(); + const toaster = useToaster(); + const { LL } = useI18nContext(); + + const { mutate, isLoading: deleteGatewayLoading } = useMutation( + [MutationKeys.DELETE_GATEWAY], + deleteGateway2, + { + onSuccess: (_data, variables) => { + queryClient.invalidateQueries([QueryKeys.FETCH_ALL_GATEWAYS]); + toaster.success('Gateway removed successfully'); + close(); + }, + onError: (err) => { + toaster.error(LL.messages.error()); + console.error(err); + }, + }, + ); + + // const openEditGatewayModal = useEditGatewayModal((state) => state.open); + // const setEditGatewayModal = useEditGatewayModal((state) => state.setState); + + return ( +
+
+
+

+ ID: {gateway.id} +

+
+
+

{gateway.url}

+
+
+
+ + { + // setEditGatewayModal({ + // gateway, + // visible: true, + // }); + // }} + /> + { + mutate({ + gatewayId: gateway.id, + }); + }} + /> + +
+
+ ); +}; diff --git a/web/src/pages/network/NetworkGateway/components/style.scss b/web/src/pages/network/NetworkGateway/components/style.scss new file mode 100644 index 000000000..2eb42110d --- /dev/null +++ b/web/src/pages/network/NetworkGateway/components/style.scss @@ -0,0 +1,10 @@ +.gateway-card { + border-radius: 15px; + border: 1px solid var(--border-primary); + background-color: var(--surface-default-modal); + box-sizing: border-box; + padding: 15px; + display: flex; + align-items: center; + justify-content: space-between; +} diff --git a/web/src/pages/network/NetworkGateway/modals/AddGatewayModal.tsx b/web/src/pages/network/NetworkGateway/modals/AddGatewayModal.tsx new file mode 100644 index 000000000..cd4f6d994 --- /dev/null +++ b/web/src/pages/network/NetworkGateway/modals/AddGatewayModal.tsx @@ -0,0 +1,146 @@ +import './style.scss'; + +import { ReactNode, useMemo } from 'react'; +import { shallow } from 'zustand/shallow'; +import { useI18nContext } from '../../../../i18n/i18n-react'; +import { useAddGatewayModal } from './hooks/useAddGatewayModal'; +import { ModalWithTitle } from '../../../../shared/defguard-ui/components/Layout/modals/ModalWithTitle/ModalWithTitle'; +import { FormInput } from '../../../../shared/defguard-ui/components/Form/FormInput/FormInput'; +import { z } from 'zod'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { SubmitErrorHandler, SubmitHandler, useForm } from 'react-hook-form'; +import { trimObjectStrings } from '../../../../shared/utils/trimObjectStrings'; +import { Button } from '../../../../shared/defguard-ui/components/Layout/Button/Button'; +import { + ButtonSize, + ButtonStyleVariant, +} from '../../../../shared/defguard-ui/components/Layout/Button/types'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { MutationKeys } from '../../../../shared/mutations'; +import useApi from '../../../../shared/hooks/useApi'; +import { QueryKeys } from '../../../../shared/queries'; +import { useToaster } from '../../../../shared/hooks/useToaster'; +import { useNetworkPageStore } from '../../hooks/useNetworkPageStore'; + +interface Inputs { + url: string; +} + +export const AddGatewayModal = () => { + const { LL } = useI18nContext(); + const { + network: { + gateway: { addGateway }, + }, + } = useApi(); + const [visible] = useAddGatewayModal( + (state) => [state.visible], + shallow, + ); + const [reset, close] = useAddGatewayModal( + (state) => [state.reset, state.close], + shallow, + ); + const selectedNetworkId = useNetworkPageStore((state) => state.selectedNetworkId); + + const zodSchema = useMemo( + () => + z.object({ + url: z.string().url(), + }), + [], + ); + + const { + control, + handleSubmit, + setValue, + getValues, + formState: { isValid }, + } = useForm({ + resolver: zodResolver(zodSchema), + mode: 'all', + defaultValues: { + url: '', + }, + }); + + const onInvalidSubmit: SubmitErrorHandler = (values) => { + const invalidFields = Object.keys(values) as (keyof Partial)[]; + const invalidFieldsValues = getValues(invalidFields); + invalidFields.forEach((key, index) => { + setValue(key, invalidFieldsValues[index], { + shouldTouch: true, + shouldValidate: true, + }); + }); + }; + + const queryClient = useQueryClient(); + const toaster = useToaster(); + + const { mutate, isLoading: addGatewayLoading } = useMutation( + [MutationKeys.ADD_GATEWAY], + addGateway, + { + onSuccess: (_data, _variables) => { + queryClient.invalidateQueries([QueryKeys.FETCH_ALL_GATEWAYS]); + toaster.success('Gateway added successfully'); + close(); + }, + onError: (err) => { + toaster.error(LL.messages.error()); + console.error(err); + }, + }, + ); + + const onValidSubmit: SubmitHandler = (values) => { + values = trimObjectStrings(values); + mutate({ + url: values.url, + networkId: selectedNetworkId, + }); + }; + + return ( + +
+ +
+
+ +
+ ); +}; diff --git a/web/src/pages/network/NetworkGateway/modals/EditGatewayModal.tsx b/web/src/pages/network/NetworkGateway/modals/EditGatewayModal.tsx new file mode 100644 index 000000000..a4d71d9e2 --- /dev/null +++ b/web/src/pages/network/NetworkGateway/modals/EditGatewayModal.tsx @@ -0,0 +1,146 @@ +import './style.scss'; + +import { ReactNode, useMemo } from 'react'; +import { shallow } from 'zustand/shallow'; +import { useI18nContext } from '../../../../i18n/i18n-react'; +import { useAddGatewayModal } from './hooks/useAddGatewayModal'; +import { ModalWithTitle } from '../../../../shared/defguard-ui/components/Layout/modals/ModalWithTitle/ModalWithTitle'; +import { FormInput } from '../../../../shared/defguard-ui/components/Form/FormInput/FormInput'; +import { z } from 'zod'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { SubmitErrorHandler, SubmitHandler, useForm } from 'react-hook-form'; +import { trimObjectStrings } from '../../../../shared/utils/trimObjectStrings'; +import { Button } from '../../../../shared/defguard-ui/components/Layout/Button/Button'; +import { + ButtonSize, + ButtonStyleVariant, +} from '../../../../shared/defguard-ui/components/Layout/Button/types'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { MutationKeys } from '../../../../shared/mutations'; +import useApi from '../../../../shared/hooks/useApi'; +import { QueryKeys } from '../../../../shared/queries'; +import { useToaster } from '../../../../shared/hooks/useToaster'; +import { useNetworkPageStore } from '../../hooks/useNetworkPageStore'; +import { useEditGatewayModal } from './hooks/useEditGatewayModal'; +import { Gateway } from '../../../../shared/types'; + +interface Inputs { + url: string; +} + +export const EditGatewayModal = () => { + const { LL } = useI18nContext(); + const { + network: { + gateway: { editGateway }, + }, + } = useApi(); + const [gateway, visible] = useEditGatewayModal( + (state) => [state.gateway, state.visible], + shallow, + ); + const [set, close] = useEditGatewayModal( + (state) => [state.setState, state.close], + shallow, + ); + + const zodSchema = useMemo( + () => + z.object({ + url: z.string().url(), + }), + [], + ); + + const { + control, + handleSubmit, + setValue, + getValues, + formState: { isValid }, + } = useForm({ + resolver: zodResolver(zodSchema), + mode: 'all', + defaultValues: { + url: gateway?.url || '', + }, + }); + + const onInvalidSubmit: SubmitErrorHandler = (values) => { + const invalidFields = Object.keys(values) as (keyof Partial)[]; + const invalidFieldsValues = getValues(invalidFields); + invalidFields.forEach((key, index) => { + setValue(key, invalidFieldsValues[index], { + shouldTouch: true, + shouldValidate: true, + }); + }); + }; + + const queryClient = useQueryClient(); + const toaster = useToaster(); + + const { mutate, isLoading: addGatewayLoading } = useMutation( + [MutationKeys.ADD_GATEWAY], + editGateway, + { + onSuccess: (_data, variables) => { + queryClient.invalidateQueries([QueryKeys.FETCH_ALL_GATEWAYS]); + toaster.success('Gateway added successfully'); + close(); + }, + onError: (err) => { + toaster.error(LL.messages.error()); + console.error(err); + }, + }, + ); + + const onValidSubmit: SubmitHandler = (values) => { + values = trimObjectStrings(values); + mutate({ + url: values.url, + gatewayId: gateway?.id, + }); + }; + + return ( + +
+ +
+
+ +
+ ); +}; diff --git a/web/src/pages/network/NetworkGateway/modals/hooks/useAddGatewayModal.tsx b/web/src/pages/network/NetworkGateway/modals/hooks/useAddGatewayModal.tsx new file mode 100644 index 000000000..5fc03419f --- /dev/null +++ b/web/src/pages/network/NetworkGateway/modals/hooks/useAddGatewayModal.tsx @@ -0,0 +1,31 @@ +import { createWithEqualityFn } from 'zustand/traditional'; + +const defaultValues: StoreValues = { + visible: false, + url: '', +}; + +export const useAddGatewayModal = createWithEqualityFn( + (set, get) => ({ + ...defaultValues, + open: () => set({ ...defaultValues, visible: true }), + close: () => set({ visible: false }), + setState: (values) => set((old) => ({ ...old, ...values })), + reset: () => set(defaultValues), + }), + Object.is, +); + +type Store = StoreValues & StoreMethods; + +type StoreValues = { + visible: boolean; + url: string; +}; + +type StoreMethods = { + open: () => void; + close: () => void; + reset: () => void; + setState: (values: Partial) => void; +}; diff --git a/web/src/pages/network/NetworkGateway/modals/hooks/useEditGatewayModal.tsx b/web/src/pages/network/NetworkGateway/modals/hooks/useEditGatewayModal.tsx new file mode 100644 index 000000000..d0dbd0ee3 --- /dev/null +++ b/web/src/pages/network/NetworkGateway/modals/hooks/useEditGatewayModal.tsx @@ -0,0 +1,30 @@ +import { createWithEqualityFn } from 'zustand/traditional'; +import { Gateway } from '../../../../../shared/types'; + +const defaultValues: StoreValues = { + visible: false, + gateway: undefined, +}; + +export const useEditGatewayModal = createWithEqualityFn( + (set) => ({ + ...defaultValues, + setState: (values) => set((old) => ({ ...old, ...values })), + open: (values) => set({ ...defaultValues, ...values }), + close: () => set({ visible: false }), + }), + Object.is, +); + +type StoreValues = { + visible: boolean; + gateway?: Gateway; +}; + +type StoreMethods = { + setState: (values: Partial) => void; + open: (values: Partial) => void; + close: () => void; +}; + +type Store = StoreValues & StoreMethods; diff --git a/web/src/pages/network/NetworkGateway/modals/style.scss b/web/src/pages/network/NetworkGateway/modals/style.scss new file mode 100644 index 000000000..3b9919800 --- /dev/null +++ b/web/src/pages/network/NetworkGateway/modals/style.scss @@ -0,0 +1,15 @@ +@use '@scssutils' as *; + +#add-user-modal { + overflow-x: hidden; + + &.step-0 { + @media (max-width: 635px) { + width: 100%; + } + + @media (min-width: 635px) { + width: auto; + } + } +} diff --git a/web/src/pages/network/NetworkGateway/style.scss b/web/src/pages/network/NetworkGateway/style.scss index 340a535c8..30131e462 100644 --- a/web/src/pages/network/NetworkGateway/style.scss +++ b/web/src/pages/network/NetworkGateway/style.scss @@ -4,6 +4,16 @@ flex-direction: column; row-gap: 20px; + & > section.gateway-list { + display: flex; + flex-direction: column; + row-gap: 20px; + + .add-component { + height: 80px; + } + } + & > section.header-section { h2, p { diff --git a/web/src/shared/hooks/useApi.tsx b/web/src/shared/hooks/useApi.tsx index 84a961c41..d6385938f 100644 --- a/web/src/shared/hooks/useApi.tsx +++ b/web/src/shared/hooks/useApi.tsx @@ -3,6 +3,7 @@ import { useEffect, useMemo } from 'react'; import { useI18nContext } from '../../i18n/i18n-react'; import { + AddGatewayRequest, AddOpenidClientRequest, AddUserRequest, AddWalletRequest, @@ -474,6 +475,22 @@ const useApi = (props?: HookProps): ApiHook => { return {}; }); + const getAllGateways: ApiHook['network']['gateway']['getAllGateways'] = (networkId) => + client + .get(`/network/${networkId}/all_gateways`) + .then(unpackRequest) + .then((data) => data?.gateways || []); + + const addGateway: ApiHook['network']['gateway']['addGateway'] = ( + data: AddGatewayRequest, + ) => client.post(`/network/${data.networkId}/gateway`, data).then(unpackRequest); + + const deleteGateway2: ApiHook['network']['gateway']['deleteGateway2'] = (data) => + client.delete(`/gateway/${data.gatewayId}`).then(unpackRequest); + + const editGateway: ApiHook['network']['gateway']['editGateway'] = (data) => + client.put(`/gateway/${data.gatewayId}`, data).then(unpackRequest); + useEffect(() => { client.interceptors.response.use( (res) => { @@ -561,6 +578,12 @@ const useApi = (props?: HookProps): ApiHook => { getNetworkStats, getGatewaysStatus, deleteGateway, + gateway: { + getAllGateways, + addGateway, + deleteGateway2, + editGateway, + }, }, auth: { login, diff --git a/web/src/shared/mutations.ts b/web/src/shared/mutations.ts index da00e7d9c..2166d3cec 100644 --- a/web/src/shared/mutations.ts +++ b/web/src/shared/mutations.ts @@ -48,4 +48,6 @@ export const MutationKeys = { CHANGE_NETWORK: 'CHANGE_NETWORK', IMPORT_NETWORK: 'IMPORT_NETWORK', CREATE_USER_DEVICES: 'CREATE_USER_DEVICES', + ADD_GATEWAY: 'ADD_GATEWAY', + DELETE_GATEWAY: 'DELETE_GATEWAY', }; diff --git a/web/src/shared/queries.ts b/web/src/shared/queries.ts index 0d539d21a..41f5259e6 100644 --- a/web/src/shared/queries.ts +++ b/web/src/shared/queries.ts @@ -30,4 +30,5 @@ export const QueryKeys = { FETCH_OPENID_INFO: 'FETCH_OPENID_INFO', FETCH_ENTERPRISE_STATUS: 'FETCH_ENTERPRISE_STATUS', FETCH_ENTERPRISE_SETTINGS: 'FETCH_ENTERPRISE_SETTINGS', + FETCH_ALL_GATEWAYS: 'FETCH_ALL_GATEWAYS', }; diff --git a/web/src/shared/types.ts b/web/src/shared/types.ts index fd02238e0..814285e67 100644 --- a/web/src/shared/types.ts +++ b/web/src/shared/types.ts @@ -117,6 +117,12 @@ export type GatewayStatus = { uid: string; }; +export type Gateway = { + id: number; + network_id: number; + url: string; +}; + export interface Network { id: number; name: string; @@ -377,6 +383,16 @@ export type DeleteGatewayRequest = { gatewayId: string; }; +export type AddGatewayRequest = { + networkId: number; + url: string; +}; + +export type EditGatewayRequest = { + gatewayId: number; + url: string; +}; + export type ChangePasswordSelfRequest = { old_password: string; new_password: string; @@ -506,6 +522,12 @@ export interface ApiHook { getNetworkStats: (data: GetNetworkStatsRequest) => Promise; getGatewaysStatus: (networkId: number) => Promise; deleteGateway: (data: DeleteGatewayRequest) => Promise; + gateway: { + deleteGateway2: (data: { gatewayId: number }) => Promise; + getAllGateways: (networkId: number) => Promise; + addGateway: (data: AddGatewayRequest) => Promise; + editGateway: (data: EditGatewayRequest) => Promise; + }; }; auth: { login: (data: LoginData) => Promise; From 2d87056e22eac0baab0998dc7af6bdcfbbefb24c Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Tue, 22 Oct 2024 11:07:08 +0200 Subject: [PATCH 14/26] gateway editing --- src/db/models/gateway.rs | 2 +- src/handlers/gateway.rs | 9 ++-- .../network/NetworkGateway/NetworkGateway.tsx | 17 +++---- .../NetworkGateway/components/GatewayCard.tsx | 21 ++++---- .../NetworkGateway/modals/AddGatewayModal.tsx | 22 ++++----- .../modals/EditGatewayModal.tsx | 49 +++++++++++-------- 6 files changed, 62 insertions(+), 58 deletions(-) diff --git a/src/db/models/gateway.rs b/src/db/models/gateway.rs index e403953fc..34be9775e 100644 --- a/src/db/models/gateway.rs +++ b/src/db/models/gateway.rs @@ -25,7 +25,7 @@ impl Gateway { pub async fn find_by_network_id(pool: &PgPool, network_id: Id) -> Result, SqlxError> { sqlx::query_as!( Self, - "SELECT * FROM gateway WHERE network_id = $1", + "SELECT * FROM gateway WHERE network_id = $1 ORDER BY id", network_id ) .fetch_all(pool) diff --git a/src/handlers/gateway.rs b/src/handlers/gateway.rs index f76da4d72..5f08d33f3 100644 --- a/src/handlers/gateway.rs +++ b/src/handlers/gateway.rs @@ -183,13 +183,16 @@ pub async fn update_gateway( gateway_id, session.user.username, gateway.url ); - gateway.save(&appstate.pool).await?; - - info!( + let msg = format!( "User {} has updated gateway with id {} to have url {}", session.user.username, gateway_id, data.url ); + gateway.url = data.url; + gateway.save(&appstate.pool).await?; + + info!("{msg}"); + Ok(ApiResponse { json: json!({}), status: StatusCode::OK, diff --git a/web/src/pages/network/NetworkGateway/NetworkGateway.tsx b/web/src/pages/network/NetworkGateway/NetworkGateway.tsx index bebc5b972..fae505d49 100644 --- a/web/src/pages/network/NetworkGateway/NetworkGateway.tsx +++ b/web/src/pages/network/NetworkGateway/NetworkGateway.tsx @@ -4,8 +4,8 @@ import { useQuery } from '@tanstack/react-query'; import { useCallback, useMemo } from 'react'; import ReactMarkdown from 'react-markdown'; +import parse from 'html-react-parser'; import { useI18nContext } from '../../../i18n/i18n-react'; -import { GatewaysStatus } from '../../../shared/components/network/GatewaysStatus/GatewaysStatus'; import { ActionButton } from '../../../shared/defguard-ui/components/Layout/ActionButton/ActionButton'; import { ActionButtonVariant } from '../../../shared/defguard-ui/components/Layout/ActionButton/types'; import { Button } from '../../../shared/defguard-ui/components/Layout/Button/Button'; @@ -19,12 +19,12 @@ import useApi from '../../../shared/hooks/useApi'; import { useClipboard } from '../../../shared/hooks/useClipboard'; import { externalLink } from '../../../shared/links'; import { QueryKeys } from '../../../shared/queries'; -import { useNetworkPageStore } from '../hooks/useNetworkPageStore'; import { AddComponentBox } from '../../users/shared/components/AddComponentBox/AddComponentBox'; -import { useAddGatewayModal } from './modals/hooks/useAddGatewayModal'; -import { AddGatewayModal } from './modals/AddGatewayModal'; +import { useNetworkPageStore } from '../hooks/useNetworkPageStore'; import { GatewayCard } from './components/GatewayCard'; +import { AddGatewayModal } from './modals/AddGatewayModal'; import { EditGatewayModal } from './modals/EditGatewayModal'; +import { useAddGatewayModal } from './modals/hooks/useAddGatewayModal'; export const NetworkGatewaySetup = () => { const { writeToClipboard } = useClipboard(); @@ -100,7 +100,7 @@ export const NetworkGatewaySetup = () => { return (
- {/* */} +

Gateways

@@ -109,17 +109,11 @@ export const NetworkGatewaySetup = () => {

{LL.gatewaySetup.header.main()}

- {/* {parse( - LL.gatewaySetup.messages.runCommand({ - setupGatewayDocs: externalLink.gitbook.setup.gateway, - }), - )} */} {LL.gatewaySetup.messages.runCommand({ setupGatewayDocs: externalLink.gitbook.setup.gateway, @@ -187,6 +181,7 @@ export const NetworkGatewaySetup = () => { {LL.gatewaySetup.messages.oneLineInstall()} + {/* TODO: Reflect gateway status in the gateway list above */} {/* */}
); diff --git a/web/src/pages/network/NetworkGateway/components/GatewayCard.tsx b/web/src/pages/network/NetworkGateway/components/GatewayCard.tsx index 3731163a4..9261d14ca 100644 --- a/web/src/pages/network/NetworkGateway/components/GatewayCard.tsx +++ b/web/src/pages/network/NetworkGateway/components/GatewayCard.tsx @@ -10,7 +10,7 @@ import useApi from '../../../../shared/hooks/useApi'; import { QueryKeys } from '../../../../shared/queries'; import { useToaster } from '../../../../shared/hooks/useToaster'; import { useI18nContext } from '../../../../i18n/i18n-react'; -// import { useEditGatewayModal } from '../modals/hooks/useEditGatewayModal'; +import { useEditGatewayModal } from '../modals/hooks/useEditGatewayModal'; interface Props { gateway: Gateway; @@ -26,11 +26,11 @@ export const GatewayCard = ({ gateway }: Props) => { const toaster = useToaster(); const { LL } = useI18nContext(); - const { mutate, isLoading: deleteGatewayLoading } = useMutation( + const { mutate } = useMutation( [MutationKeys.DELETE_GATEWAY], deleteGateway2, { - onSuccess: (_data, variables) => { + onSuccess: (_data, _variables) => { queryClient.invalidateQueries([QueryKeys.FETCH_ALL_GATEWAYS]); toaster.success('Gateway removed successfully'); close(); @@ -42,8 +42,7 @@ export const GatewayCard = ({ gateway }: Props) => { }, ); - // const openEditGatewayModal = useEditGatewayModal((state) => state.open); - // const setEditGatewayModal = useEditGatewayModal((state) => state.setState); + const setEditGatewayModal = useEditGatewayModal((state) => state.setState); return (
@@ -61,12 +60,12 @@ export const GatewayCard = ({ gateway }: Props) => { { - // setEditGatewayModal({ - // gateway, - // visible: true, - // }); - // }} + onClick={() => { + setEditGatewayModal({ + gateway, + visible: true, + }); + }} /> { controller={{ control, name: 'url' }} disabled={false} required - placeholder='e.g. http://192.168.0.1:50066/' + placeholder='e.g. http://127.0.0.1:50066/' />