Compare commits

..

1 Commits

Author SHA1 Message Date
renovate[bot] 091fd4e66c ⬆️(dependencies) update django to v5.2.17 2026-09-01 02:05:53 +00:00
48 changed files with 1051 additions and 2758 deletions
+1 -14
View File
@@ -8,21 +8,9 @@ and this project adheres to
## [Unreleased] ## [Unreleased]
### Added
- ✨(frontend) add 1080p sending resolution option #1660
- ✨(backend) add Traefik support via configurable media-auth url header #1649
### Changed ### Changed
- (dev) pin LiveKit server to v1.13.6 - (frontend) close side panel with Escape key #1507
### Fixed
- 🐛(backend) allow any printable ASCII characters in user sub field #1673
- 🐛(frontend) keep the sending resolution picked while the camera is off #1667
## [1.30.0] - 2026-09-01
### Added ### Added
@@ -39,7 +27,6 @@ and this project adheres to
- ⬆️(frontend) upgrade @fontsource/opendyslexic from 5.2.5 to 5.3.0 - ⬆️(frontend) upgrade @fontsource/opendyslexic from 5.2.5 to 5.3.0
- ⬆️(addons) upgrade core-js from 3.49.0 to 3.50.0 - ⬆️(addons) upgrade core-js from 3.49.0 to 3.50.0
- ♻️(backend) factorize s3 client creation in utils - ♻️(backend) factorize s3 client creation in utils
- ♿️(frontend) close side panel with Escape key #1507
### Fixed ### Fixed
-2
View File
@@ -16,8 +16,6 @@ the following command inside your docker container:
## [Unreleased] ## [Unreleased]
## v1.30.0
### Removing S3 storage-event webhooks for recordings ### Removing S3 storage-event webhooks for recordings
Recordings were previously confirmed as saved by an S3 storage-event webhook posting to `/api/v1.0/recordings/storage-hook/`. That endpoint has been removed: recordings are now always finalized from LiveKit's own `egress_ended` webhook, which has been the default path since v1.22.0. Recordings were previously confirmed as saved by an S3 storage-event webhook posting to `/api/v1.0/recordings/storage-hook/`. That endpoint has been removed: recordings are now always finalized from LiveKit's own `egress_ended` webhook, which has been the default path since v1.22.0.
-7
View File
@@ -110,12 +110,6 @@ cd -
# Update summary pyproject.toml # Update summary pyproject.toml
update_python_version "summary" update_python_version "summary"
# Run uv lock in summary
print_info "Running uv lock in summary..."
cd "src/summary"
uv lock
cd -
# Update agents pyproject.toml # Update agents pyproject.toml
update_python_version "agents" update_python_version "agents"
@@ -169,7 +163,6 @@ echo " - src/mail/package.json"
echo " - src/backend/pyproject.toml" echo " - src/backend/pyproject.toml"
echo " - src/backend/uv.lock" echo " - src/backend/uv.lock"
echo " - src/summary/pyproject.toml" echo " - src/summary/pyproject.toml"
echo " - src/summary/uv.lock"
echo " - src/agents/pyproject.toml" echo " - src/agents/pyproject.toml"
echo " - src/agents/uv.lock" echo " - src/agents/uv.lock"
echo " - CHANGELOG.md" echo " - CHANGELOG.md"
+1 -3
View File
@@ -207,14 +207,12 @@ services:
- kc_postgresql - kc_postgresql
livekit: livekit:
image: livekit/livekit-server:v1.13.6 image: livekit/livekit-server
entrypoint: /livekit-server --dev --bind 0.0.0.0 --config ./config.yaml entrypoint: /livekit-server --dev --bind 0.0.0.0 --config ./config.yaml
ports: ports:
- "7880:7880" - "7880:7880"
- "7881:7881" - "7881:7881"
- "7882:7882/udp" - "7882:7882/udp"
- "3478:3478/udp"
- "30000-30100:30000-30100/udp"
volumes: volumes:
- ./docker/livekit/config/livekit-server.yaml:/config.yaml - ./docker/livekit/config/livekit-server.yaml:/config.yaml
depends_on: depends_on:
-1
View File
@@ -65,7 +65,6 @@ RUN apk update && apk upgrade \
musl \ musl \
musl-utils \ musl-utils \
zlib>=1.3.2-r0 \ zlib>=1.3.2-r0 \
libexpat>=2.8.4-r0 \
&& apk del curl && apk del curl
USER nginx USER nginx
+1 -1
View File
@@ -1,4 +1,4 @@
FROM livekit/livekit-server:v1.13.6 FROM livekit/livekit-server:v1.9.4
# We inject the nip.io certificate manually because the livekit chart doesn't support volume mounting # We inject the nip.io certificate manually because the livekit chart doesn't support volume mounting
COPY rootCA.pem /etc/ssl/certs/ COPY rootCA.pem /etc/ssl/certs/
-13
View File
@@ -8,16 +8,3 @@ webhook:
api_key: devkey api_key: devkey
urls: urls:
- http://app-dev:8000/api/v1.0/rooms/webhooks-livekit/ - http://app-dev:8000/api/v1.0/rooms/webhooks-livekit/
turn:
enabled: true
domain: turn.127.0.0.1.nip.io
udp_port: 3478
tls_port: 0
external_tls: false
relay_range_start: 30000
relay_range_end: 30100
allow_restricted_peer_cidrs:
- 192.168.0.0/16
- 172.16.0.0/12
+168 -189
View File
@@ -524,11 +524,14 @@ wheels = [
[[package]] [[package]]
name = "click" name = "click"
version = "8.5.0" version = "8.4.2"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/c7/0e/7fa0ef50764b67090eca4114772a2abf8b6148198475e54c660b97caeee6/click-8.5.0.tar.gz", hash = "sha256:ba0d2089de75ea0310e2dde03160e6ca10009947fb95a182f9b54021bb272e34", size = 382235, upload-time = "2026-08-26T13:33:14.56Z" } dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/76/d4/81420972a676e8ffea40450d8c8c92943e7218a78fe9b64359836cc9876b/click-8.4.2.tar.gz", hash = "sha256:9a6cea6e60b17ebe0a44c5cc636d94f09bd66142c1cd7d8b4cd731c4917a15f6", size = 338000, upload-time = "2026-06-24T17:45:15.148Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/58/50/6c0d534c5f134586a8e1ba4e330569e32f057e33372ae556463212fb4cd3/click-8.5.0-py3-none-any.whl", hash = "sha256:255bc9599cf7748b4b1a446ccc735421bd08a2ae529a8b88597d3de5664ee360", size = 125251, upload-time = "2026-08-26T13:33:12.928Z" }, { url = "https://files.pythonhosted.org/packages/fb/e2/79c688af8b210d232694e31e59da9f6ec747bae31c3f5946e4e9b98860d5/click-8.4.2-py3-none-any.whl", hash = "sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76", size = 119243, upload-time = "2026-06-24T17:45:13.73Z" },
] ]
[[package]] [[package]]
@@ -669,43 +672,43 @@ wheels = [
[[package]] [[package]]
name = "grpcio" name = "grpcio"
version = "1.83.1" version = "1.83.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "typing-extensions" }, { name = "typing-extensions" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/e2/b1/46539f5050d7c316a13396d185451f95084a74ddc68b12d818595bef0377/grpcio-1.83.1.tar.gz", hash = "sha256:9cee6fcbf2eb57c4b49451787bfa87be8efc1ca02a0b327dd4b54d44502e362b", size = 13445033, upload-time = "2026-08-28T07:09:11.464Z" } sdist = { url = "https://files.pythonhosted.org/packages/0c/98/304898ac4e04e2d5e4e4c2eadc178b1f2a16d5f4bc2f91306c87d64680b9/grpcio-1.83.0.tar.gz", hash = "sha256:7674587248fbbb2ac6e4eecf83a8a0f3d91a928f941de571acfd3a2f007fbc24", size = 13428824, upload-time = "2026-07-23T15:20:37.759Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/85/9e/a3ba13e08bbee5bf6e57597dfe4823961fd7e94c0b8afe3a4bb7dca639f3/grpcio-1.83.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:5acd14c6ddf047de62cbf8745b11103ea91abbf57d1b8edd5395ccd9fcd13abb", size = 6303170, upload-time = "2026-08-28T07:08:08.188Z" }, { url = "https://files.pythonhosted.org/packages/15/2b/51e32514a4e9b715375c99721aadff0f24164cc2049b8269eda4de82a814/grpcio-1.83.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:28f6c35ac8fcf10e4594f138e468f194360089dde40d126a7033e863fc479930", size = 6303167, upload-time = "2026-07-23T15:19:33.78Z" },
{ url = "https://files.pythonhosted.org/packages/1c/ae/65ce56a2527faa17d02cba4c2231c74047ad898be339486ba87f093bfb66/grpcio-1.83.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:16138031a47b771860a16a975b53087f4fd5bbdbb2c03a188c5d90ad65d2bdae", size = 12165806, upload-time = "2026-08-28T07:08:10.309Z" }, { url = "https://files.pythonhosted.org/packages/39/33/b5b50fc2c6fbe350e04814047bb2d409feec7b36ef8b170254c050e06bc0/grpcio-1.83.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:33898e6a28e4ae598f1577cb1c4fec2a15c033d0ec52b9b45a09610dd045b9da", size = 12160538, upload-time = "2026-07-23T15:19:35.958Z" },
{ url = "https://files.pythonhosted.org/packages/4e/91/40432480088a2243d360864de072ed5b78c4ebbaabd29c28918f1e1b1454/grpcio-1.83.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5ccc26715fd4defca5e129e280dd883b1737b65045ec50ffe22ce42104089519", size = 6872490, upload-time = "2026-08-28T07:08:12.355Z" }, { url = "https://files.pythonhosted.org/packages/7b/5f/734e72e7b9f79bcf0b2c270b8d3bca0e4ebb97a27a50d06240b145f6d41e/grpcio-1.83.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6fb8a1dd0c6f0f931e69e9d0dc6d1c406ed2a44fa963414eafba07b7fb685d16", size = 6869310, upload-time = "2026-07-23T15:19:38.607Z" },
{ url = "https://files.pythonhosted.org/packages/c8/62/3da2300c8c79fd20a78a8a4bb6251e5068d9af33bc8fd389b98fec35e8a3/grpcio-1.83.1-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:b74f2a1d9ab1dfa3e263ef33d581613679b78d0884babf11671af26e45570ead", size = 7618367, upload-time = "2026-08-28T07:08:14.025Z" }, { url = "https://files.pythonhosted.org/packages/a4/17/a1735f215b2a5cd43c38b79eac072ad197e61be9829905b6b29550abd0db/grpcio-1.83.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:2b5e75c34842cd9c1b95285ca395c6a569664b81e3ffa6b714125922942abaaf", size = 7613472, upload-time = "2026-07-23T15:19:40.645Z" },
{ url = "https://files.pythonhosted.org/packages/bc/19/9fc702e31a631262d7a752fa699f6022821e707fefc8bff49b1550a57729/grpcio-1.83.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:72578aa07a4008f17521ef52debcc3acfd1e2c5426243bc3ffb56a38bfe610b7", size = 7040936, upload-time = "2026-08-28T07:08:15.963Z" }, { url = "https://files.pythonhosted.org/packages/b2/78/c9e81f806ac704b6b145cb01628db398985b1f8dfdc10e23b55fb0902b3d/grpcio-1.83.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aeb339838db07600481ef869507279b75326c75eac6d10f7afa62a0da1d2bcdd", size = 7040616, upload-time = "2026-07-23T15:19:42.349Z" },
{ url = "https://files.pythonhosted.org/packages/ec/56/95933cc44cba2429765fa065c951dd529e5771b119d9d2481b4646f1d6a5/grpcio-1.83.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c12e1fc59c6dc26d10d9144453ddc6cbfe4cd4c31e874ed2d0132f88e685eb8b", size = 7573096, upload-time = "2026-08-28T07:08:17.729Z" }, { url = "https://files.pythonhosted.org/packages/9a/ba/94cd5af859876049d340480acbb61a959096c84b567f215534faa78d0424/grpcio-1.83.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f47d62808b4c0a97b78bff88a6d4ca283a2a492b9a04a87d814af95ca3b9c19c", size = 7570491, upload-time = "2026-07-23T15:19:44.357Z" },
{ url = "https://files.pythonhosted.org/packages/ac/80/af63359da06b016de48cb111f144703a10043850dafa43ae0a038907b9e8/grpcio-1.83.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4910b62f7d12197160bfb7de06d876d64dd12d43483e8292f98f49ca09b628d9", size = 8609442, upload-time = "2026-08-28T07:08:19.777Z" }, { url = "https://files.pythonhosted.org/packages/3e/15/108d30d5a5c964312ae8b9cb0e8cc5b3c1cc68d8f757cca52b3565534d26/grpcio-1.83.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:62003babc444a606dcd1f009cd16391ce23669ae4ad6ec267a873da7937a69f5", size = 8605036, upload-time = "2026-07-23T15:19:46.454Z" },
{ url = "https://files.pythonhosted.org/packages/3d/fa/f0586c56bdfb8a7a2adda01e0ac2413447cde3141ab09411a5d5afdcffd3/grpcio-1.83.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9e703effe3ae779925c82ac24fdb82cf4105e1096810151ed9501c5f34546b9c", size = 7984321, upload-time = "2026-08-28T07:08:22.114Z" }, { url = "https://files.pythonhosted.org/packages/ea/23/3828ae13c3db8233d123ad612747665817b952d8a954f32390230b582336/grpcio-1.83.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1aa567f8c3f19850ffd5d2858c9a8ea7c80f0db6c01186b71eb31e923ec984f5", size = 7981587, upload-time = "2026-07-23T15:19:48.913Z" },
{ url = "https://files.pythonhosted.org/packages/25/8a/14ec05669f9eb295801e26c2ea8c561a1b786b0e3557c2c22131165ab010/grpcio-1.83.1-cp312-cp312-win32.whl", hash = "sha256:a2aea8bd6e0a34f12cbaddb7bb70bec836818789fa5c7ab7572c6b745396a2d4", size = 4395604, upload-time = "2026-08-28T07:08:24.08Z" }, { url = "https://files.pythonhosted.org/packages/17/5b/77af31228f55f55a2a5112bb0077ad0a1c4d23dbb0c2853a62475bbdcc14/grpcio-1.83.0-cp312-cp312-win32.whl", hash = "sha256:cb2906c61db4f9c64cc360054b5df70eeb81846228e9e56a4944bd415a63dadc", size = 4394004, upload-time = "2026-07-23T15:19:50.618Z" },
{ url = "https://files.pythonhosted.org/packages/e9/37/8c2f7cc16089e36a3fbacaacc7a3d043912aa0d2dfae5556f6450414ea6e/grpcio-1.83.1-cp312-cp312-win_amd64.whl", hash = "sha256:583bf2e8255040a4a312f9572dfe62a05271437b149550e1a536d5c47d2d1e8a", size = 5161512, upload-time = "2026-08-28T07:08:25.81Z" }, { url = "https://files.pythonhosted.org/packages/c0/da/f706e39550e7a3732ce2b9c5926107a93d74a802775b19b642a6df27dc96/grpcio-1.83.0-cp312-cp312-win_amd64.whl", hash = "sha256:1c699bbb20f143c8f2bff219de578aa2dc1f919399d67dc702b038b986ee62df", size = 5158525, upload-time = "2026-07-23T15:19:52.246Z" },
{ url = "https://files.pythonhosted.org/packages/7c/fd/d1fc58933bf88c9209f89dc570c810f1aa57cb04b3459cf2b26f61e32112/grpcio-1.83.1-cp313-cp313-linux_armv7l.whl", hash = "sha256:8d228e253b77865efcbdd7b5894ca882c9e0ea98c02b7d20582e61ded8dfd4b5", size = 6305628, upload-time = "2026-08-28T07:08:27.872Z" }, { url = "https://files.pythonhosted.org/packages/56/eb/135daaa713f32d33b8f99b4153b3f8dc3b2a124996ac15581bf9ebdad3c3/grpcio-1.83.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:6662f3b1e07cc7493d437351860dc867bddc6a93c83ecf33bbfdaf0c217ab2d0", size = 6304480, upload-time = "2026-07-23T15:19:53.962Z" },
{ url = "https://files.pythonhosted.org/packages/c4/49/0b40bae059c619505c9b751cee6caa208e4904e290aaefa1728c4c2c67a5/grpcio-1.83.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:0468b627f2987c9a77f7580030207cbd85457ffe52998beff4f0b5c38c58a72c", size = 12156839, upload-time = "2026-08-28T07:08:30.191Z" }, { url = "https://files.pythonhosted.org/packages/8f/a1/121806ce69f23138dabe06aa595b0e5f1ae051a37e4c1954eed7d692c800/grpcio-1.83.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:74fe6f9e8a35c7dbf32255ee154d15e3e5338a81ed39173d079d594d2e544cd1", size = 12154419, upload-time = "2026-07-23T15:19:56.3Z" },
{ url = "https://files.pythonhosted.org/packages/61/4b/e8c0d635da0ee5ddd9950c8d540f5dcdd0ef1854a382cc55496a487a8d31/grpcio-1.83.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a6a282e81530cead60bbd752cc04950a57f224379e9821495d6a35bd5ce9b1f4", size = 6877036, upload-time = "2026-08-28T07:08:32.285Z" }, { url = "https://files.pythonhosted.org/packages/b0/e8/d0389e09cd6b4c4d3089b92967ae4e3ffd64795bd349bf2f85cd6656d3da/grpcio-1.83.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:10b3fa0475eb572c9a81a6fe37fa16a9c500c0c91cfc148cac15692b7e3c2867", size = 6873200, upload-time = "2026-07-23T15:19:58.701Z" },
{ url = "https://files.pythonhosted.org/packages/c5/d4/760a33f339a7dd3d5f4b3e0e9bec5472d95592a80f887b2e9dab4e41cfbc/grpcio-1.83.1-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:947d945f52e8ecf3cafd2bb7113502a16ccfda3e12c854443094de32d83ad432", size = 7624404, upload-time = "2026-08-28T07:08:34.194Z" }, { url = "https://files.pythonhosted.org/packages/f8/51/f464c1d211fa50d5adbabe1b2e519948d99c13757052bfc9ea7afa28e284/grpcio-1.83.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:5f20a988480b0f28207f057f7f7ae1313393c3cef0adcfeae8248f9947eaf881", size = 7618811, upload-time = "2026-07-23T15:20:00.733Z" },
{ url = "https://files.pythonhosted.org/packages/54/ec/bd798654b06fb42a92b57d1dc1b530084fa89ed442806fcd0a833a36f9b3/grpcio-1.83.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:55656318d5dd387077396dffb929171ca3966e24bfead9a6c5dba9f889062cb4", size = 7042942, upload-time = "2026-08-28T07:08:36.208Z" }, { url = "https://files.pythonhosted.org/packages/e8/c0/539fe0832f2dd6500a28f5263071623fb34e8d4867aec632ccf81bd21156/grpcio-1.83.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7bd82671b39065ba18cd536e9cd45b27ff649053f81ddd2c6a966d595067080f", size = 7042310, upload-time = "2026-07-23T15:20:02.675Z" },
{ url = "https://files.pythonhosted.org/packages/08/b0/c00f86614566dd0961825cf0f43d4f96a74371d9d95f952bcbc4b86d9a27/grpcio-1.83.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9daf5acf4fc9d5f5627229969c2580a91e511779d76e4ccdeb9f4770f05d8bc2", size = 7576937, upload-time = "2026-08-28T07:08:38.041Z" }, { url = "https://files.pythonhosted.org/packages/8c/ca/ccf617d37ffa72567fa8e005ec7090c99da922799be2fb9847c8b21ca18c/grpcio-1.83.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bc60215b5cb9fc8ca72942c498b551ac2305bd08f6ef8d4e3f0d21b64fbecd61", size = 7575412, upload-time = "2026-07-23T15:20:04.712Z" },
{ url = "https://files.pythonhosted.org/packages/b1/38/85eff43a5c89dc666a252b5c9f8e9ab03f89e11c95b6263d2933f08fdbe7/grpcio-1.83.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7b94174cbca93316888f805efbeb08f1c020f7b7493d2d50cc4f6b64ebb7e8bd", size = 8608391, upload-time = "2026-08-28T07:08:40.092Z" }, { url = "https://files.pythonhosted.org/packages/eb/b9/fd8d5245f823a8e0fd35d90e20ea3aa4acd47f8d5318fa8df307df52dec6/grpcio-1.83.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f1c3e5689d4b90987b1d72022bcfe866a9a3dc66197484cf856d96b6150e7f45", size = 8604248, upload-time = "2026-07-23T15:20:06.77Z" },
{ url = "https://files.pythonhosted.org/packages/35/4e/82835483e2f812494be865e7965c0d626cb9e71ab0d83a420d75aea4ad67/grpcio-1.83.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:65c5a7210911ffe0f67b1cdc5308f9854b6d1f1b345e3e49ab7cac1ba50fa346", size = 7980060, upload-time = "2026-08-28T07:08:42.434Z" }, { url = "https://files.pythonhosted.org/packages/14/1e/f37632fc11db72dfa4bba86c3a43e54358e53030df111ecae5e91a733ad6/grpcio-1.83.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a21cb4eeeba124443f399be2e8b624943cde864dcbe588cb42e5c483a52a906c", size = 7977458, upload-time = "2026-07-23T15:20:09.109Z" },
{ url = "https://files.pythonhosted.org/packages/b2/b7/68a98bef733fef704fbcfb3957c8dba67e3e38ca7a7fea851195bc97c648/grpcio-1.83.1-cp313-cp313-win32.whl", hash = "sha256:179368d9361854616ce6f397d4716e07480129652752fcbcfc5a7260455ad6f2", size = 4395226, upload-time = "2026-08-28T07:08:44.463Z" }, { url = "https://files.pythonhosted.org/packages/93/b6/d70b69ae5c0cfc341b9ba474980e4ed99cbf05c0e4a14e9eee8cb73db0a5/grpcio-1.83.0-cp313-cp313-win32.whl", hash = "sha256:8fe04f1050a59f875601eb55d42b4f66946fe89817f967e34db1462ccd07dadf", size = 4393993, upload-time = "2026-07-23T15:20:11.017Z" },
{ url = "https://files.pythonhosted.org/packages/85/a0/df4de3b51d37ac8fb0320bb9668381ce2bd3b7aa990880bfc56a8a26f665/grpcio-1.83.1-cp313-cp313-win_amd64.whl", hash = "sha256:2e57af456385491a76e13c4aada8c8f43a8e47051e06ea97a9dbe2a49654e6db", size = 5160273, upload-time = "2026-08-28T07:08:46.216Z" }, { url = "https://files.pythonhosted.org/packages/0f/13/45d4cccb555cf4c476226979bf3d2fd0b0254216f7564c3a053e35117efc/grpcio-1.83.0-cp313-cp313-win_amd64.whl", hash = "sha256:6e01ecd9d8ef280abe1365138a4dc318f9a5287f4cb1b41d07816f796653f735", size = 5159650, upload-time = "2026-07-23T15:20:12.979Z" },
{ url = "https://files.pythonhosted.org/packages/42/9c/484d981d8b90c4e6abf3030bd2ed747e84d1eb192b3ec9cbb41e0b73e4bf/grpcio-1.83.1-cp314-cp314-linux_armv7l.whl", hash = "sha256:8b3c87ca908296bf125f841d3e1a2225a2b39aaa8ed7a57e7ccde465ee519bab", size = 6306089, upload-time = "2026-08-28T07:08:48.379Z" }, { url = "https://files.pythonhosted.org/packages/9c/60/f2cca8147ea213d3e43ae9158d03ad04e020fdf32ff027253e1fe93f921d/grpcio-1.83.0-cp314-cp314-linux_armv7l.whl", hash = "sha256:3f351629f6ae16ecc0ec3553e586a6763ffd9f6114044286d0cbec3e09241bfa", size = 6305607, upload-time = "2026-07-23T15:20:15.353Z" },
{ url = "https://files.pythonhosted.org/packages/84/01/0afec1c92e4f292f74a44ecf75eabbf40903125b8c4df103c9868d6338da/grpcio-1.83.1-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:c0f3f20c90e72a171917ae65706500b096a1c3eb5f162c3ce702a2e25635f132", size = 12170381, upload-time = "2026-08-28T07:08:50.653Z" }, { url = "https://files.pythonhosted.org/packages/d0/ab/d3874931d123a95e83a3ebf8aa04537988fb62425cedb8bf3cefc5ad41b2/grpcio-1.83.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:d05ff664100d429335b93c91b8b34ddf9e94a112205e7fa06dede309e44a4e4c", size = 12166617, upload-time = "2026-07-23T15:20:17.435Z" },
{ url = "https://files.pythonhosted.org/packages/c7/5a/e9a2383804433a0a61d6d93777ad321c7f36ac1cfdaa4c6d1a7c9ac846b7/grpcio-1.83.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:81bbf35a46bf8cad2dfbb2eccc19c711befb58b288acb534bbcd0d74283202a6", size = 6883286, upload-time = "2026-08-28T07:08:53.654Z" }, { url = "https://files.pythonhosted.org/packages/92/ff/6f18f9426b69306f4e00a9add3b0ee2748da8aad53836ef80cab0d62d04f/grpcio-1.83.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7936f2a56cf04f6514705c0fedf400971de01b6aa1719327e4718f410a765e2b", size = 6880213, upload-time = "2026-07-23T15:20:19.98Z" },
{ url = "https://files.pythonhosted.org/packages/63/e7/f8ca8f76994e14c70b9a0052e82f10de497a23db450c36379c9716ebfc4d/grpcio-1.83.1-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:215cec07d11176507387bda4bf2751816e880f9bff8dc1ca524bfbb8ed8f2fad", size = 7624293, upload-time = "2026-08-28T07:08:55.709Z" }, { url = "https://files.pythonhosted.org/packages/70/21/706d1147c6b93b98f179240c13991fbcc56880eba0c868abb1ad40d8a0a6/grpcio-1.83.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:b0a0be840e51b6b7ee9df9269770faf77bdf4b771053c257c21d12bad607714c", size = 7618335, upload-time = "2026-07-23T15:20:22.161Z" },
{ url = "https://files.pythonhosted.org/packages/bb/7a/4b672814b0cd0fe63bdd735379d88b165759f3144ab023ad8ec5fc4d53ac/grpcio-1.83.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:abce7d43ec29cd39230fa8339de1a07643b55adc412a454850fbd875349950ff", size = 7044346, upload-time = "2026-08-28T07:08:57.802Z" }, { url = "https://files.pythonhosted.org/packages/74/04/1a8443c889115ec9e213a213e86bc93a71ee9088027e5befa09aaa0edd9d/grpcio-1.83.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:009667eaf3dcd5224c713589cdc98e7ca4ed0ff0b61132c6b276e930eb83a2df", size = 7043416, upload-time = "2026-07-23T15:20:24.209Z" },
{ url = "https://files.pythonhosted.org/packages/50/b8/d89fe60e4239ad51be333dd9cc703741d449a35064e51f8a0b5bfa755432/grpcio-1.83.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e256f95a40e3b0183a98556fb7164d24b97eeb353123ccabfcba94712b35ee2a", size = 7584187, upload-time = "2026-08-28T07:08:59.867Z" }, { url = "https://files.pythonhosted.org/packages/86/c6/94e0fee5b12bc1da1370185b680988db6f739d19b42d9959db01a7ea50bf/grpcio-1.83.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:bb669918fd88936b15599caff4160a77ab74bdeb25f2231f6e45b61282d6107b", size = 7583253, upload-time = "2026-07-23T15:20:26.313Z" },
{ url = "https://files.pythonhosted.org/packages/dc/b2/b290d7402633d9166e4dd47e6f5f74a24ce10a8340b84455896ebc349f85/grpcio-1.83.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:2110059146fb0ea216e1ffddb29377b5cc2fd412a5b0a92e102616bd5edf18c2", size = 8608730, upload-time = "2026-08-28T07:09:02.592Z" }, { url = "https://files.pythonhosted.org/packages/a0/97/de1ccb671fb85575bc5192faedf9ecdbdf5b390d2e6584dcf552bcbd370e/grpcio-1.83.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:c19b454d3d3f28db81f2c7c4dbaee96e7f6fd149721733ffe79d6bc530f17404", size = 8605102, upload-time = "2026-07-23T15:20:28.437Z" },
{ url = "https://files.pythonhosted.org/packages/f5/44/fa89e44d1b5cf5b9fa71b2fd7abf506f182fd43917231a92fbf1ea326b02/grpcio-1.83.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20d944d967843f8183f9f23d5916388362e5f8eeeae855bbe4354d906dc9f31b", size = 7983283, upload-time = "2026-08-28T07:09:05.087Z" }, { url = "https://files.pythonhosted.org/packages/17/0f/0e0ec749a7034ffcbaa050e39779872950ead90c22e7e0116be3f28b2b46/grpcio-1.83.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:61007cd08640abc5c54547ee32505474c482cd733a53cb87551ea81faa6350af", size = 7979826, upload-time = "2026-07-23T15:20:31.182Z" },
{ url = "https://files.pythonhosted.org/packages/ce/b8/9db73ed1f35ffa76124ac574bf296d06a359798dfd6b50d382f2b8a060a1/grpcio-1.83.1-cp314-cp314-win32.whl", hash = "sha256:623c87c6d4a1cb30d82c4e896f95477050f2e01b4a1f8cf91ff2b1abdf89c457", size = 4474327, upload-time = "2026-08-28T07:09:07.179Z" }, { url = "https://files.pythonhosted.org/packages/83/fa/c3fda157287f64bc65acee6c5aa90c41acf9e0d3a8e69a265eecff6d00a1/grpcio-1.83.0-cp314-cp314-win32.whl", hash = "sha256:32e11c37f5285b0c6fa3042c05fe06903696689749833fc64e67dec71b9bbe33", size = 4471765, upload-time = "2026-07-23T15:20:33.195Z" },
{ url = "https://files.pythonhosted.org/packages/65/22/fc9a622d885a7a37ff972a12faaef443d74e47407181da70d0ab62ab41f0/grpcio-1.83.1-cp314-cp314-win_amd64.whl", hash = "sha256:47e6934ad38779271e2e7cc5f78a63a407cf3d98114c65c1fdbcd3f5a716f29b", size = 5302032, upload-time = "2026-08-28T07:09:09.285Z" }, { url = "https://files.pythonhosted.org/packages/a1/00/b1b26431c9d54eee11724fd6e5585473a2ed47fbc1fb95e5204906a642ce/grpcio-1.83.0-cp314-cp314-win_amd64.whl", hash = "sha256:2bb48cb5e6dd005ca12b89ce4b6ac0b48ff3112c747542ee7986ef611a8ca6d9", size = 5298932, upload-time = "2026-07-23T15:20:35.48Z" },
] ]
[[package]] [[package]]
@@ -950,7 +953,7 @@ codecs = [
[[package]] [[package]]
name = "livekit-api" name = "livekit-api"
version = "1.2.1" version = "1.2.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "aiohttp" }, { name = "aiohttp" },
@@ -959,9 +962,9 @@ dependencies = [
{ name = "pyjwt" }, { name = "pyjwt" },
{ name = "types-protobuf" }, { name = "types-protobuf" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/da/0d/ff9502faa5e9785563e9648313a030fab65ed7f6ff8cf52d7bc6c9e01c97/livekit_api-1.2.1.tar.gz", hash = "sha256:eee78dba493b736bc8422660debc7cf89340f1b80c63890a36a18d99c938045c", size = 21780, upload-time = "2026-08-27T14:06:57.419Z" } sdist = { url = "https://files.pythonhosted.org/packages/f3/19/36ff6712ec638a4b7dad4d8f03795952e401dc31db0b04cddec7892650da/livekit_api-1.2.0.tar.gz", hash = "sha256:a89817b3bca9584873786ff07209839308217537a42f95ecb2609aafaa109ddc", size = 20778, upload-time = "2026-07-11T23:20:54.781Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/a1/c8/bc29cf16427fc446aa4487c552503cef42eebfcb920902bb54b7180e40d3/livekit_api-1.2.1-py3-none-any.whl", hash = "sha256:aa15b0a194c9e8167d4261bc61381682df23f98bc6d77760fcded93d2ce4b4ca", size = 27586, upload-time = "2026-08-27T14:06:56.286Z" }, { url = "https://files.pythonhosted.org/packages/bf/e7/8926f16d4bc1b2e0ae46d4a507321bb899396d263a757f1adaabcd3b3867/livekit_api-1.2.0-py3-none-any.whl", hash = "sha256:307f8e5cfb0358c3ca091814ab768af55896022151bcd7f951954ccefa036a24", size = 26499, upload-time = "2026-07-11T23:20:53.736Z" },
] ]
[[package]] [[package]]
@@ -1056,15 +1059,15 @@ wheels = [
[[package]] [[package]]
name = "livekit-protocol" name = "livekit-protocol"
version = "1.1.26" version = "1.1.24"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "protobuf" }, { name = "protobuf" },
{ name = "types-protobuf" }, { name = "types-protobuf" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/e8/49/733f3655717bd1bdccfbb4ab958ac7f51d7e17d37e61b98de2f6b2e0c107/livekit_protocol-1.1.26.tar.gz", hash = "sha256:de8d291abb2efd026fbe23394ee4c05358195f09102d3c13335978ba04d7bdb8", size = 123833, upload-time = "2026-08-28T17:15:50.225Z" } sdist = { url = "https://files.pythonhosted.org/packages/d7/dc/65c106d689916e78e47d79d4f890f6e83b680442c67ed4909b44425084ea/livekit_protocol-1.1.24.tar.gz", hash = "sha256:b0a5699d3a4c4e42c3d37416dc3ed3c817c527c317c4cf3351d0bbe52887b9d4", size = 122624, upload-time = "2026-08-20T22:07:24.06Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/37/a9/b9a9a04b921b1aaef9312c3a16523cd4ddb508dcc4be18ca0e300b750b7e/livekit_protocol-1.1.26-py3-none-any.whl", hash = "sha256:37db1272487518df2ce3e13624a5217d1e158c6832fe01166bb3fb1875a8ddd9", size = 150535, upload-time = "2026-08-28T17:15:48.535Z" }, { url = "https://files.pythonhosted.org/packages/88/1f/e06cbbaea37bbe12cab1d169767f3fff9b385b019e6bdcd02fb9c94df63d/livekit_protocol-1.1.24-py3-none-any.whl", hash = "sha256:794463c4ed209fc884194470595052de652477d92b10d81bb5b0f9dcf53050f9", size = 149448, upload-time = "2026-08-20T22:07:22.699Z" },
] ]
[[package]] [[package]]
@@ -1106,76 +1109,54 @@ wheels = [
[[package]] [[package]]
name = "msgpack" name = "msgpack"
version = "1.2.2" version = "1.2.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/6d/44/ea2100ec54d30c46ee9dba10a3bfb79b655e96c6df237238a3234c75869b/msgpack-1.2.2.tar.gz", hash = "sha256:9eb0b0e602064527a045ea28c4f174ed69383587e29cebe28947e3b84106eb2a", size = 187025, upload-time = "2026-08-27T10:03:47.793Z" } sdist = { url = "https://files.pythonhosted.org/packages/31/f9/c0a1c127f9049db9155afc316952ea571720dd01833ff5e4d7e8e6352dbb/msgpack-1.2.1.tar.gz", hash = "sha256:04c721c2c7448767e9e3f2520a475663d8ee0f09c31890f6d2bd70fd636a9647", size = 183960, upload-time = "2026-06-18T16:13:52.594Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/31/78/90c15bebb1a72667349ca62d4507e9d9369e7f8f76b95f490b823d3622e5/msgpack-1.2.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a4348705be86e029d04e741cf9ed0dfe03e942d7d3b92e838fa80d3aa2c3ebc", size = 84275, upload-time = "2026-08-27T10:02:07.106Z" }, { url = "https://files.pythonhosted.org/packages/bc/dd/9e8cbd8f5582ca4b590336f2b91ee5662f6a6ca562b565abaf696a0f81ff/msgpack-1.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2ef59c659f289eddf8aa6623823f19fa2f40a4029266889eac7a2505dd210c35", size = 83531, upload-time = "2026-06-18T16:12:58.249Z" },
{ url = "https://files.pythonhosted.org/packages/88/88/c2b6d8e81571da87aa232c0e34a3f3a0e618e6235892065ec82d1d81fc7a/msgpack-1.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0a652ceeededf71d3fa40c303a02a149d42338d310162367b91c539d4bd6e0a3", size = 83970, upload-time = "2026-08-27T10:02:08.488Z" }, { url = "https://files.pythonhosted.org/packages/50/2e/ebdb85a8da151397a2790363676b7ed7c125924fe618e4c6d8befb0cc62c/msgpack-1.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d3567748a5107cb40cdf66a275430c2f87c07777698f4bfd25c35f44d533258c", size = 82657, upload-time = "2026-06-18T16:12:59.396Z" },
{ url = "https://files.pythonhosted.org/packages/da/c0/d3ede9f5d16acb4c05a9281859f1e99ef9f877a928eb78454c37f70db001/msgpack-1.2.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90986cc9aab9d7d1d8f38bcbf65d3f7ac83bdd90c35765db7d691b4829698cba", size = 409401, upload-time = "2026-08-27T10:02:09.877Z" }, { url = "https://files.pythonhosted.org/packages/26/aa/753ad8b007b464e1d8aa0c8e650b9c5f4f725e658fc5ac8a7635c55b7f6e/msgpack-1.2.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:60926b75d00c8e816ef98f3034f484a8bc64242d66839cef4cf7e503142316a0", size = 410634, upload-time = "2026-06-18T16:13:00.383Z" },
{ url = "https://files.pythonhosted.org/packages/41/f0/29f591bea185616cf417645ac03bd3ad9b317483ad8572160e325f7fe777/msgpack-1.2.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:77c2e018417dc1d66f235e383877ee885b60ade9d29e494dd581e08af2cb1923", size = 420619, upload-time = "2026-08-27T10:02:11.526Z" }, { url = "https://files.pythonhosted.org/packages/6a/fd/6adabd4f6d5e686f97dd02ce7fce3fe4cf672cbac36b8f67ff4040e8ad8b/msgpack-1.2.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:020e881a764b20d8d7ca1a54fc01b8175519d108e3c3f194fddc200bda95951a", size = 419989, upload-time = "2026-06-18T16:13:01.776Z" },
{ url = "https://files.pythonhosted.org/packages/4e/8e/c70c8c9180c5ddf4440eb8658ebead98e22e7686fbf84f6b165031430750/msgpack-1.2.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0e91332144f69bc3018c91232fac26da580ef748fb8eaddd7914d4458001cc4f", size = 379747, upload-time = "2026-08-27T10:02:13.345Z" }, { url = "https://files.pythonhosted.org/packages/5a/cc/85039b7b0eb168aaad7383a23c97e291a11f08351cb45a606ce865e4e3f1/msgpack-1.2.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4202c74688ca06591f78cb18988228bd4cca2cc75d57b60008372892d2f1e6e6", size = 377544, upload-time = "2026-06-18T16:13:03.637Z" },
{ url = "https://files.pythonhosted.org/packages/50/9a/f10ce11fa62700c9ab87a22e65b9ca272f7f673ddd31aeb2de6ae272ad35/msgpack-1.2.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e915d390d7068b257ca8b62f3fc59fad135c8631d1017ab03b0b924b07c5367", size = 398944, upload-time = "2026-08-27T10:02:15.006Z" }, { url = "https://files.pythonhosted.org/packages/ed/bf/35963899493b32030c85fc513b723ae66144ac70c11ebc52e889e16e3d99/msgpack-1.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8b267ce94efb76fbd1b3373511420074ee3187f0f7811bf394531de13294735a", size = 400842, upload-time = "2026-06-18T16:13:05.012Z" },
{ url = "https://files.pythonhosted.org/packages/82/fe/d7be978456ff8552e69a8e270d882e7530e01513c096b293d83df03753ea/msgpack-1.2.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:c522420d78db2431887d45b518e304d86e27b9ad0b30f24e3806a6ad5d8bdbfc", size = 373979, upload-time = "2026-08-27T10:02:16.618Z" }, { url = "https://files.pythonhosted.org/packages/a6/df/8e2ac970c8f99264cd9997d1c73df5466bc19da3301d7dc5500862a9b089/msgpack-1.2.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:e4f1d0f8f98ade9634e01fb704a408f9336c0a8f1117b369f5db83dc7551d8b1", size = 374108, upload-time = "2026-06-18T16:13:06.232Z" },
{ url = "https://files.pythonhosted.org/packages/be/af/91b0d8d3fb3063e259daee3ea8515cea6282f68f4b0e5f0b6fea25762c6e/msgpack-1.2.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4b554d8164ebb526892194f71dcd96ef1fefe0c250087498785d3ffc04a80be3", size = 417781, upload-time = "2026-08-27T10:02:18.293Z" }, { url = "https://files.pythonhosted.org/packages/17/dd/fa8bd265110dfa51c20cb529f9e6d240a16fafe7e645004c6af2d01353ba/msgpack-1.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f02cf17a6ca1abe29b5f980644f7551f94d71f2011509b26d8625ce038f0df64", size = 414939, upload-time = "2026-06-18T16:13:07.478Z" },
{ url = "https://files.pythonhosted.org/packages/8e/3c/ce8e9efe1fd9e95c78b3705e4300ba7feba3dc6c00fb76259895db155518/msgpack-1.2.2-cp312-cp312-win32.whl", hash = "sha256:0e3315de5a4b2920ccef48d96b4448025e064a10d0f5a250f6584477d839c8d4", size = 65267, upload-time = "2026-08-27T10:02:19.869Z" }, { url = "https://files.pythonhosted.org/packages/2e/b9/8377a5ad8953fc0437c70cc98d9ae29f27fe5ac5109fbec0812085865735/msgpack-1.2.1-cp312-cp312-win32.whl", hash = "sha256:0c0d9802354507bcba62af19c17918e3eb437cc25e6f50657d511b5856a77aac", size = 64504, upload-time = "2026-06-18T16:13:08.822Z" },
{ url = "https://files.pythonhosted.org/packages/85/98/a33b8b4af14e3476bb0da1b8c36ef7a0f28dcf95db1c5e68ff88cb89d591/msgpack-1.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:b68614fba0570349833b7dd999ff0aed4e5cc8d9eb6e3a7d4527be33c65e33d3", size = 72275, upload-time = "2026-08-27T10:02:21.141Z" }, { url = "https://files.pythonhosted.org/packages/57/7f/ce1e377df7e62461fefd9eb23bfb93a4a523f40a517b377b8f844d836828/msgpack-1.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:5c24aa15d5963051e1a5c62b12c50cd705992502b5ec1f3bece6046f33c9fc24", size = 71421, upload-time = "2026-06-18T16:13:09.828Z" },
{ url = "https://files.pythonhosted.org/packages/df/5e/2f323a33a6aba5bd4b2d8b430e4fab21d92cd91c093b49ee287bc166ee54/msgpack-1.2.2-cp312-cp312-win_arm64.whl", hash = "sha256:59d5b93efa45fd09f620d0c9ba81cde339a2c9937af3eea42ee9653094ce6640", size = 65488, upload-time = "2026-08-27T10:02:22.575Z" }, { url = "https://files.pythonhosted.org/packages/8f/32/ebfe84c9929f08f188d56c7a2fd913406a9ddad76a634697c1c43b8112e6/msgpack-1.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:4227224aaec8f7fbcbfbd4272319347b2bb4030366502600f8c45588c5187b07", size = 64775, upload-time = "2026-06-18T16:13:11.056Z" },
{ url = "https://files.pythonhosted.org/packages/1f/eb/42f31c5a48811787ff59a9869721f70a49654d65ab6c455f4463c39b044e/msgpack-1.2.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8b2a281b556f120a43e591ea39915741b7ad54d4727b9c4350a0a11692252533", size = 83911, upload-time = "2026-08-27T10:02:24.06Z" }, { url = "https://files.pythonhosted.org/packages/b0/ac/dcddcab6f6c20ecb387ca5e980371cdb3f87ff69aeca388be97eebc4c074/msgpack-1.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0a70e3cf2804a300d921bb0940426e35f4e489a23adfb77a808892241db0a064", size = 83151, upload-time = "2026-06-18T16:13:12.173Z" },
{ url = "https://files.pythonhosted.org/packages/33/54/10c6c16ddba8a5112e3680176b838e3694e4aad7284f9daa6d6d70d98817/msgpack-1.2.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1e8cdd1f3e7cc52c751092a9bf740e81e6919ab109cd376ae2d965dad0bbae34", size = 83734, upload-time = "2026-08-27T10:02:25.613Z" }, { url = "https://files.pythonhosted.org/packages/64/71/fbcfa83a1d6a9c6091942d1cfd070962244664b87427a9a49a6897b1b219/msgpack-1.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:491cc39455ca765fad51fb451bf2915eb2cf41192ab5801ce8d67c1d614fe056", size = 82351, upload-time = "2026-06-18T16:13:13.194Z" },
{ url = "https://files.pythonhosted.org/packages/d7/75/35823e4419df8792191b2a17ae3fe71b41d02c162b2c491c94d1a87f0caa/msgpack-1.2.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1814f92306ae7862908e9ece7cfd90e0dc87ded3e89b6ae7ffdd1175d6376fdc", size = 405635, upload-time = "2026-08-27T10:02:27.012Z" }, { url = "https://files.pythonhosted.org/packages/e3/10/ddf7b06db879e8792d13934ddda09ff20bd2a583fd84c9b59aae9b0e650b/msgpack-1.2.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f310233ef7fb9c14e201c93639fe5f5260b005f56f0b29048e999c30935596cc", size = 407518, upload-time = "2026-06-18T16:13:14.233Z" },
{ url = "https://files.pythonhosted.org/packages/6e/d3/6592e4064619b04f2dd0054c5fa13e37e3d55eb26044483d871fadb2f46b/msgpack-1.2.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d24b38a825bcca41bb956de50eb98451ef291304a8607fad99e619043d3e79b9", size = 417332, upload-time = "2026-08-27T10:02:28.776Z" }, { url = "https://files.pythonhosted.org/packages/79/d3/36a46a8ed992b781acbc05928bd5bee3c810cb0c3563bf81a7b0c04a1a76/msgpack-1.2.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:787c9bebb5833e8f6fc8abca3c0597683d8d87f56a8842b6b89c75a5f3176e2d", size = 416405, upload-time = "2026-06-18T16:13:15.435Z" },
{ url = "https://files.pythonhosted.org/packages/e3/a1/b21c6818a545e9a4a976ac954a5c250eecde9a02e0ec82f415473dab1324/msgpack-1.2.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:34e83e345194a2a51d8bd447dea9de2104f91e75b247f4735f14f04529f0746b", size = 374378, upload-time = "2026-08-27T10:02:30.678Z" }, { url = "https://files.pythonhosted.org/packages/f9/84/e8e9598b557c0ba6ddae901a73780a4c75ac667dddf59414b1e56a42fb34/msgpack-1.2.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dc871b997a9370d855b7394465f2f350e847a5b806dd38dcc9c989e7d87da155", size = 376257, upload-time = "2026-06-18T16:13:17.022Z" },
{ url = "https://files.pythonhosted.org/packages/03/8b/7ada15c7b64151d6dbb562d1b091520efb2c37acf2403b1d4ae13797b27d/msgpack-1.2.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:682804bf31e43d46e51a9a33bd575b51e839d715ce6bd5612c055f7b28ad637b", size = 395809, upload-time = "2026-08-27T10:02:32.322Z" }, { url = "https://files.pythonhosted.org/packages/40/16/738fe6d875ad7e2a9429c165322a4ec088f4f273cdfae63d96a89c467961/msgpack-1.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:85f57e960d877f2977f6430896191b04a21f8901b3b4baf2e4604329f4db5402", size = 397469, upload-time = "2026-06-18T16:13:18.287Z" },
{ url = "https://files.pythonhosted.org/packages/bb/f7/96283e50f7020df4dfeacc55612b7a210c8cdf0dda48bc262f1f9b3e4c49/msgpack-1.2.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:9b659d77f8726fa5e7038967dda6b68d53cf34472c094cfa5b845454713b90d5", size = 373495, upload-time = "2026-08-27T10:02:33.832Z" }, { url = "https://files.pythonhosted.org/packages/ca/be/6d5952df75a7f24f35833af764c3a6860780364cb3a0030beb8099e1b2b4/msgpack-1.2.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:1233ee2dd0cefba127583de50ea654677277047d238303521db35def3d7b2e7c", size = 372802, upload-time = "2026-06-18T16:13:19.685Z" },
{ url = "https://files.pythonhosted.org/packages/cc/fe/1548dede9d9ca482f2d424a2e110a9705d4e02627a16b8bc8d10ce0208a2/msgpack-1.2.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4d9a562aec0a92fe536da2e533d313b3d2a6b929157b1dec7ff623446dc0a8ab", size = 414360, upload-time = "2026-08-27T10:02:35.396Z" }, { url = "https://files.pythonhosted.org/packages/e1/39/e2ef7dbf0473bcb8dc7c50bf782a892d67414877b63e47fc88eb189ef5e6/msgpack-1.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e3dc2feb0876209d9c38aa56cb1de169bd6c4348f1aa48271f241226590993e6", size = 411273, upload-time = "2026-06-18T16:13:21.028Z" },
{ url = "https://files.pythonhosted.org/packages/77/9d/4419b8f86c219174b1fb8bbd7faaf84a548935f7b1916d028401b9433417/msgpack-1.2.2-cp313-cp313-win32.whl", hash = "sha256:a4161eee7799863aee237c35c90427861f7b994416dd81ae829f560b0a81bdcd", size = 65196, upload-time = "2026-08-27T10:02:37.007Z" }, { url = "https://files.pythonhosted.org/packages/ef/c5/133f4512a56e983a93445c836c9d94d88f3bc2e0980ff4b9e577bd8416ce/msgpack-1.2.1-cp313-cp313-win32.whl", hash = "sha256:6d09badf350af2be9d189184e04e64cf54ad93569ab3d96fca58bd3e84aad707", size = 64471, upload-time = "2026-06-18T16:13:22.293Z" },
{ url = "https://files.pythonhosted.org/packages/3c/f8/593f5caf0dacab41cde1564c5f0419e61af55ec9628006205e8fd5eb5e03/msgpack-1.2.2-cp313-cp313-win_amd64.whl", hash = "sha256:b07c03f0da7e5279170df7745ddc732d526c8a198208936ec1a95c11ed2b2d5f", size = 72203, upload-time = "2026-08-27T10:02:38.28Z" }, { url = "https://files.pythonhosted.org/packages/e2/98/577e10b055096a7dd40732358cabaf7180a20c79ed1dcdbb618e4b9deac7/msgpack-1.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:33f14fba63278b714efe6ad07e50ea5f03d91537aa6a1c5f1ceca4cf44013ca9", size = 71274, upload-time = "2026-06-18T16:13:23.455Z" },
{ url = "https://files.pythonhosted.org/packages/bc/9e/c6ef92046b4a2bbb9d3aa0cb581cbf4a4051afccf6e5fb301a1bd3086f39/msgpack-1.2.2-cp313-cp313-win_arm64.whl", hash = "sha256:d13d07efbf655f9ae7a2352b630c52727b359005b21ba08a507585c9ac8c0896", size = 65435, upload-time = "2026-08-27T10:02:39.534Z" }, { url = "https://files.pythonhosted.org/packages/ba/ee/0c0048e7cfbef23c6a94791b8959ab28155232e7956de8a305b5ff588f05/msgpack-1.2.1-cp313-cp313-win_arm64.whl", hash = "sha256:afc5febcd4c99effbc02b528e49d6fd0760b2b7d48c05239e345a5fa6e743d9a", size = 64795, upload-time = "2026-06-18T16:13:24.687Z" },
{ url = "https://files.pythonhosted.org/packages/5e/50/3e92c403346652cabd08cb8faceef847bae917ea3b3c81b64a5b6d09ed41/msgpack-1.2.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e497ee34e8a3342bbde51b27c22d8db05a651df3361dd3daef5b3ab0d66f3e04", size = 84315, upload-time = "2026-08-27T10:02:41.181Z" }, { url = "https://files.pythonhosted.org/packages/77/58/cce442852c6b9e1639c7c8ac8fd9143121cb32dab0f308df4d1426a8eb9c/msgpack-1.2.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:05f340e47e7e47d2da8db9b53e1bb1d294369e9ef45a747441309f6650b8351d", size = 83610, upload-time = "2026-06-18T16:13:25.724Z" },
{ url = "https://files.pythonhosted.org/packages/b6/dc/8efe6dd96a12ab043930cb4cffb40b6e7f061491d6ec7a3d2b75ef1fda42/msgpack-1.2.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0dd9173c5ebaf5ecc5ca86e7ae1db92934e1d57b856f3dd90698941431f4fd77", size = 84634, upload-time = "2026-08-27T10:02:42.621Z" }, { url = "https://files.pythonhosted.org/packages/60/5c/15b4c7a0182f75ffa90751958ba36a9c01cafee367d49a3edc10ed140b01/msgpack-1.2.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:810b916696c86ef0deb3b74588480224df4c1b071136c34183e4a2a4284d7ac7", size = 83138, upload-time = "2026-06-18T16:13:26.781Z" },
{ url = "https://files.pythonhosted.org/packages/1b/89/996573095bf7b038c04dd65ddbc4f1a4d381b0f7a44ff9186f3c7b8325c2/msgpack-1.2.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8dc4487097571f7311188c3eca2a3e86cd1f1db4c37c7a017bcc3fd38486cbfe", size = 404194, upload-time = "2026-08-27T10:02:44.096Z" }, { url = "https://files.pythonhosted.org/packages/b8/a6/99e58722feaffc5f2fbcc0c8c0d1451ab9f84097f7af87291b46af2390f4/msgpack-1.2.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ca0dacff965c47afdc3749a8469d7302a8f801d6a28758d55120d75e66ce6889", size = 406090, upload-time = "2026-06-18T16:13:28.072Z" },
{ url = "https://files.pythonhosted.org/packages/b6/4e/46f5a5d949dbd054dab60cb15aac7ac6ae6774c134532893414689bf2f53/msgpack-1.2.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73b0e05c32c3cfc3cd84994908e57430c0ebc6813abf905d3f18ff115d54df3f", size = 412343, upload-time = "2026-08-27T10:02:45.747Z" }, { url = "https://files.pythonhosted.org/packages/19/03/8c63e8cf52958534ef688625965ab04c269a6cadd8caef16758b380a821a/msgpack-1.2.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e2bf9280bceb5efca998435904b5d3e9fdbcc11d90dc9df30aec7973252b720", size = 412106, upload-time = "2026-06-18T16:13:29.427Z" },
{ url = "https://files.pythonhosted.org/packages/da/e8/739a94197358a313307e6e9e7d8d22ef66add39222de911a44161aa96920/msgpack-1.2.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:aa1120c653b76d8eafa50423b5eba06b5c9737f8692c74fa3afe03e84b8978ea", size = 372620, upload-time = "2026-08-27T10:02:47.578Z" }, { url = "https://files.pythonhosted.org/packages/63/d2/155d9e71b40e41fd934bc0c48b9b2770f22263e1ac20aad8e29fdca7be3f/msgpack-1.2.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:aa6c4be5d1c02a42b066ca6ddb71adf36432868fdcdb6ee87e634e86e0674190", size = 374851, upload-time = "2026-06-18T16:13:30.631Z" },
{ url = "https://files.pythonhosted.org/packages/03/d4/09b92e1fcdccea9466bfae45455367ac52362ae445d96a602e51b7a8df73/msgpack-1.2.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ccfd880988f8438d1c91c77d7edc58e70f4d2012e999167bc154c64c6f06ea6b", size = 394603, upload-time = "2026-08-27T10:02:49.172Z" }, { url = "https://files.pythonhosted.org/packages/98/48/deaf2326262a8d5ea3295ce9649912ecd3f551ba7ec8e33c665d2ba583f3/msgpack-1.2.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec0e675d59150a6269ddc9139087c722292664a37d071a849c05c473350f1f2d", size = 396168, upload-time = "2026-06-18T16:13:31.977Z" },
{ url = "https://files.pythonhosted.org/packages/47/db/d11bd6f258a60703dcdc7a3772818ad0c2f602ee4c2acfb24088c6c3ebc3/msgpack-1.2.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:6195257a107bf25872ef84aab7295078271eea3ac6413f0506b631f6c9586ed5", size = 372666, upload-time = "2026-08-27T10:02:50.886Z" }, { url = "https://files.pythonhosted.org/packages/10/2a/b4410f906c2ec0008f1608d3ab5143afc3ad3f4e6da0fed3ea2231d0bef4/msgpack-1.2.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:dd3bfe82d53edfe4b7fc9a7ec9761e23a7a5b1dac22264505af428253c29ed24", size = 371959, upload-time = "2026-06-18T16:13:33.282Z" },
{ url = "https://files.pythonhosted.org/packages/71/cf/fbbbac0c6e5fbb9d51abc23e3b5fe8620f5c01e0588797cf664a623bb9e1/msgpack-1.2.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b8dd6c71d20c28d2d0eb0c51e7cccf3584afde3b1364f6629596186c9025bd54", size = 410889, upload-time = "2026-08-27T10:02:52.51Z" }, { url = "https://files.pythonhosted.org/packages/59/86/1edc67270099a528fa2093ea60fe191233cd238e4bd30cfacf7db79fc959/msgpack-1.2.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5ad5467fc3f68b5468e06c5f788d712e9f8ffc8b0cd1bcb160c105c1ee92dae7", size = 408457, upload-time = "2026-06-18T16:13:34.567Z" },
{ url = "https://files.pythonhosted.org/packages/94/60/8366558da954095e04e7fbc351f9387d87a682feaee9a235ceda966f794b/msgpack-1.2.2-cp314-cp314-win32.whl", hash = "sha256:d242f3c4ccf55b056e6cf901720dccde58f1df117898f2bbf3bcd6e38ec7c248", size = 66774, upload-time = "2026-08-27T10:02:53.984Z" }, { url = "https://files.pythonhosted.org/packages/82/90/8b630fef07d8c5ab457b71ff2c217910c83d333c7a68472c186e87cc504a/msgpack-1.2.1-cp314-cp314-win32.whl", hash = "sha256:98b58bdb89c46190e4609bb36abe17c6d4105ad13f9c5f8f6f64d320f8ced3fb", size = 65942, upload-time = "2026-06-18T16:13:36.056Z" },
{ url = "https://files.pythonhosted.org/packages/4b/3d/1ce873c8057c65e4fbb076ffe1c99c9ae39d90a00a2540d7b06c652a292f/msgpack-1.2.2-cp314-cp314-win_amd64.whl", hash = "sha256:1510f24612d4b983dff6935d9273e02c320cfd525727fbcb58836a75f589fdbc", size = 73424, upload-time = "2026-08-27T10:02:55.277Z" }, { url = "https://files.pythonhosted.org/packages/16/f1/467b81e98b24dd3885d7b1857728797b4ffc76a7a7483af4fb321a07de3c/msgpack-1.2.1-cp314-cp314-win_amd64.whl", hash = "sha256:74847557e28ce71bd3c438a447ca90e4b507e997ddbdef8a12a7b283b86c156b", size = 72627, upload-time = "2026-06-18T16:13:37.079Z" },
{ url = "https://files.pythonhosted.org/packages/d5/55/e36f2a33e38657f33850d74e0bf256838a0d45802c298cc501a32bffcc08/msgpack-1.2.2-cp314-cp314-win_arm64.whl", hash = "sha256:7826f16edc763e768404f55605ef85dfcf5857e729c1ed29e0d7c180be4fe6d8", size = 67657, upload-time = "2026-08-27T10:02:56.493Z" }, { url = "https://files.pythonhosted.org/packages/a7/1d/5d8c4c89985feb6acefb82a09e501c60392261856d2408d20bfe4f0360b1/msgpack-1.2.1-cp314-cp314-win_arm64.whl", hash = "sha256:b50b727bd652bdc37d950336c848ef20ec54a4cafc38dce19b1cd86ad625d0f7", size = 66908, upload-time = "2026-06-18T16:13:38.23Z" },
{ url = "https://files.pythonhosted.org/packages/64/58/7e764b957bae80ae281a9cb28761068c8bae8d5c6ac0873e43cc69d176c7/msgpack-1.2.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:f466049b8e1ec0854287bbe9a074316826fe0e08dcf707245f98b1ae49e92650", size = 86594, upload-time = "2026-08-27T10:02:57.796Z" }, { url = "https://files.pythonhosted.org/packages/1b/02/ad2afb678b4de94496cd432b581759b756a92c1192d8c767edd6b132efdc/msgpack-1.2.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:8d00f177ca88a77c1cf848d204a38f249751650b601cb6532acc68805d8a8273", size = 86000, upload-time = "2026-06-18T16:13:39.44Z" },
{ url = "https://files.pythonhosted.org/packages/ae/f0/250f5985b6ee533e60d357571a808aaae03c54118294dc3db7158e27feb1/msgpack-1.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1f6b6f8deb07d49090e1808c6ef9cb7d23ca17bef3aa6ed3e5e03df16606e60c", size = 87374, upload-time = "2026-08-27T10:02:59.256Z" }, { url = "https://files.pythonhosted.org/packages/54/74/0b797484013128837f3b1cbb6cea019277c4de4e377dc512b4d9a0f92940/msgpack-1.2.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5bb9c386f0a329c035ddbab4b72d1028bf9627add8dda41070288563d57ed1b1", size = 86544, upload-time = "2026-06-18T16:13:40.447Z" },
{ url = "https://files.pythonhosted.org/packages/bd/2c/126ec8f187877c5f688631c543d1d3a3d75b2e66b83fb9de3ed7c13a39b6/msgpack-1.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b542ffc0a5c531eedc40419f291f1bd659aa8d4223408a5b51c88a2796083fd3", size = 428157, upload-time = "2026-08-27T10:03:00.9Z" }, { url = "https://files.pythonhosted.org/packages/a9/b4/b774d7eb95561739907fec675582f83203cf41c597a418c2589b4bfb8e9d/msgpack-1.2.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:20466cca18c49c7292a8984bc15d65857b171e7264bdcb5f96baf8be238791fc", size = 427661, upload-time = "2026-06-18T16:13:41.574Z" },
{ url = "https://files.pythonhosted.org/packages/95/21/d2d81d50aaedb14147d01f22094185794db3ad8a8791b60afacba0627c89/msgpack-1.2.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d095df2627e5dd59ac7b0c5ad627a671c76e6020171e03cbe4621a61f0562c3", size = 426669, upload-time = "2026-08-27T10:03:02.457Z" }, { url = "https://files.pythonhosted.org/packages/b2/f9/3243191dc9937e00756c8bc1b0272fed8f23758e43df2a3b46f533e5090f/msgpack-1.2.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:196300e7e5d6e74d50f1607ab9c06c4a1484c383cd22defd727902591f7e8dde", size = 426375, upload-time = "2026-06-18T16:13:42.936Z" },
{ url = "https://files.pythonhosted.org/packages/c6/fc/f7d484ee5b572719608e7ffad569bea22ff11309a96ca2fae85eec94226b/msgpack-1.2.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ffdd2f4950daf7815490f23087963e3420175b9609520b7ff5df64d351159c22", size = 380625, upload-time = "2026-08-27T10:03:04.244Z" }, { url = "https://files.pythonhosted.org/packages/23/c7/1693111db9944ba4ad4b67a1e788400d78a0b6af7a6523dc7e4e58f8274b/msgpack-1.2.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:575957e79cd51903a4e8495a242442949641e08f1efd5197b43bebd3ea7682b4", size = 380495, upload-time = "2026-06-18T16:13:44.306Z" },
{ url = "https://files.pythonhosted.org/packages/0a/c4/b924cbd5516676f4e612329f18602a833bd055ffbe27f808eeba0f01bfea/msgpack-1.2.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:652d1bf13d01bac8fd569def0fe76745e55bcda01e30aa6332d5947ea3788839", size = 411328, upload-time = "2026-08-27T10:03:05.869Z" }, { url = "https://files.pythonhosted.org/packages/3e/2b/92f86956a0c13e8662f7e2ad630c4eb4db07497b967589bd5245e018b2c1/msgpack-1.2.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8c2ed1e48cc0f460bf3c7780e7137ff21a4e18433451916f2442c1b21036cd7d", size = 410897, upload-time = "2026-06-18T16:13:45.629Z" },
{ url = "https://files.pythonhosted.org/packages/27/9d/0c1d9683a951a80f270c3b7dac1022c18b9307617344dd44d904135d5e12/msgpack-1.2.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:9bf452ff4d4981f25a18e9476e002bcc9263e7928024aa4d7148e25f7be3f929", size = 377892, upload-time = "2026-08-27T10:03:07.37Z" }, { url = "https://files.pythonhosted.org/packages/da/ea/1479f72d200313a76fc2f823a79d1e07ed052ab7b8a0280640aa7b95de42/msgpack-1.2.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:5f6277e5f783c36786a145e0247fc189a03f35f84b251646e53592d2bc12b355", size = 378519, upload-time = "2026-06-18T16:13:46.998Z" },
{ url = "https://files.pythonhosted.org/packages/06/bb/bf22338cdd22e0b40c8f28468cea5f3d9c320244c095d8303364bc012c41/msgpack-1.2.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:55faa6f8395e23b848c535ad5dcb96b3462f37f5e7f4ac500d500434f7345da7", size = 419426, upload-time = "2026-08-27T10:03:09Z" }, { url = "https://files.pythonhosted.org/packages/f5/4d/fa006060ffa1011d32bfae826fe766fe73e02982183601633b7121058ab3/msgpack-1.2.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f9389552ecf4784886345ead0647e4edc96bee37cbab05b75540f542f766c48c", size = 419815, upload-time = "2026-06-18T16:13:48.205Z" },
{ url = "https://files.pythonhosted.org/packages/7d/42/6d02c19a01abd8d7ce817c321d2ee6af1a8e24d584dca619d1b6576a83bf/msgpack-1.2.2-cp314-cp314t-win32.whl", hash = "sha256:419a45c67a5c04213172a14b1864657e014665b77d7081b107a51707923dd39e", size = 71810, upload-time = "2026-08-27T10:03:10.498Z" }, { url = "https://files.pythonhosted.org/packages/2f/e1/aab6c946570496b78e67804721f3d5e2d62a93081b9b37df77764ef56347/msgpack-1.2.1-cp314-cp314t-win32.whl", hash = "sha256:c1c79a604a2969a868a78b6ebd27a887e00c624f14f66b3038e0590cb23332d1", size = 70914, upload-time = "2026-06-18T16:13:49.385Z" },
{ url = "https://files.pythonhosted.org/packages/af/df/fda3a204415dab0a8c0db5461ef7205416ea52bd8581c5cafd361be07f3b/msgpack-1.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:935b1cfad9b908b0fa845010f4271df4c2f04e1cd26e3f18acd61a45f93c9e36", size = 78919, upload-time = "2026-08-27T10:03:12.016Z" }, { url = "https://files.pythonhosted.org/packages/13/0a/e608956488a2af014cfe6e3d665e090b8ee42aa14b07f8f95b8880d66b09/msgpack-1.2.1-cp314-cp314t-win_amd64.whl", hash = "sha256:f12038a35fabd52e56a3547bab42401af49a45caa6dd00b34c44de235bc93ee2", size = 77999, upload-time = "2026-06-18T16:13:50.467Z" },
{ url = "https://files.pythonhosted.org/packages/63/d4/4b4b0ef25a86deca91feaf7252ca885ba4f2ada40461379120122a04fe96/msgpack-1.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:11e8c421e117d1c36728b423d0402555cccbf0c6f53e288f0e75b6b12100d70f", size = 71925, upload-time = "2026-08-27T10:03:13.332Z" }, { url = "https://files.pythonhosted.org/packages/d2/8a/27e2e57055176e366a46b85d02d68e7a5bcfbdd8474c9706375d965f24d3/msgpack-1.2.1-cp314-cp314t-win_arm64.whl", hash = "sha256:0adcf06ffde0777c0e1a9b771a2b1c4226ba1bbf748c8efcc02fcdeca3299107", size = 71160, upload-time = "2026-06-18T16:13:51.498Z" },
{ url = "https://files.pythonhosted.org/packages/3b/92/4b44bc8f3243ef8cf9cb5368c17a299d45b9df858f6dfdd98a0482dbbb37/msgpack-1.2.2-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:e1b99ad34613d5f8477fa5cf99bc4eaeaf27965588007c102370cd9a78fe9de5", size = 84293, upload-time = "2026-08-27T10:03:14.718Z" },
{ url = "https://files.pythonhosted.org/packages/80/05/c992bb65744665a41b5bf531fc0e1619bae0901f57738228ded90023c151/msgpack-1.2.2-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:0fbc1bed8a535389b41882cfae66376e248cd1680eaa94fd83193c73e1d24986", size = 84490, upload-time = "2026-08-27T10:03:16.12Z" },
{ url = "https://files.pythonhosted.org/packages/d7/bf/7f53b9e6709a4df7f9b9b81dc65f9dfaa32caf65bee94986ec2cb8fa07f1/msgpack-1.2.2-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:06d95f61de7afe4f4ff908a6feebfcb070d0582ac87c9cf3cedf8551cf634516", size = 405332, upload-time = "2026-08-27T10:03:17.692Z" },
{ url = "https://files.pythonhosted.org/packages/d2/5a/305c4dca14b50d0b51fb88ef04ec125b8f0be3e2ce730dcc62dbaa651cc5/msgpack-1.2.2-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b5c696ae7cd7166b3657261adb855b461ff31f07823fdbae9de8bf80adfccc21", size = 416798, upload-time = "2026-08-27T10:03:19.389Z" },
{ url = "https://files.pythonhosted.org/packages/7a/df/a645102b4cdfd9a94201cac4e900e9c1429fc16d86aa311c06eef82528c9/msgpack-1.2.2-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0708afbf6a9587f0bfe479a9825c141d14d91e2f6a5c8103cf28bc96f4edb5d9", size = 377312, upload-time = "2026-08-27T10:03:20.928Z" },
{ url = "https://files.pythonhosted.org/packages/f4/26/c56d8d086d3fb1077bb48092b158b5ea2eee08b279e10c191275f13bc980/msgpack-1.2.2-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:226a62ffe99fe54c5c61d910ec64c3449b7766c3280bd286bf6c94838dde239a", size = 395182, upload-time = "2026-08-27T10:03:22.571Z" },
{ url = "https://files.pythonhosted.org/packages/4d/b5/3d46ba367a565e536d8d2a61eebcee71b1dc803da3ce74a22313b573d6fa/msgpack-1.2.2-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:9fd7f32e2f0fb334e7ecc5adb5cf0458785bd3a9d9d86f950e1715f101cebce5", size = 377945, upload-time = "2026-08-27T10:03:24.151Z" },
{ url = "https://files.pythonhosted.org/packages/a5/2c/d5d2df273ed5306357da25b69400fd8d7a53c4d87d8976604b677484d61c/msgpack-1.2.2-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:9db1ba1c1e6a84245a9dd866265b56b8a1e9461549cc72ed296d8cbfbd32961b", size = 413341, upload-time = "2026-08-27T10:03:25.85Z" },
{ url = "https://files.pythonhosted.org/packages/1b/fb/32613bced3cad47b40b1b73dd04d687121349d83f748efc2575929121903/msgpack-1.2.2-cp315-cp315-win32.whl", hash = "sha256:e2eb7ea0ac3911a7aac9d8aaa36d40f216d99455b3274cd3fac38181bcd910cf", size = 66730, upload-time = "2026-08-27T10:03:27.294Z" },
{ url = "https://files.pythonhosted.org/packages/74/56/d86171f7251015e9312e5a7f9fdd4cf89752fc2114b88fed453d2a040c66/msgpack-1.2.2-cp315-cp315-win_amd64.whl", hash = "sha256:9352e6cdb510a7b1a5d3ccaccec730e82e50cf3484a3af7bdaab19e23b9589ff", size = 73477, upload-time = "2026-08-27T10:03:28.615Z" },
{ url = "https://files.pythonhosted.org/packages/13/1a/56b90f6defef61700b86baca3637c15f62ac0f9b21ab0f16613ab9d1f101/msgpack-1.2.2-cp315-cp315-win_arm64.whl", hash = "sha256:29cc2d5291711a52956a79a51f41c732329df39ad727c886bd8f0b5b9237a808", size = 67660, upload-time = "2026-08-27T10:03:29.895Z" },
{ url = "https://files.pythonhosted.org/packages/cd/20/12751ca0d8ec874701b54c392c2b19f51af8dd1de40a92a10e356f0aaf58/msgpack-1.2.2-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:d886baa46b2532135e7320067e6a44edb09ba5883a6096b0f9c044533984b8a8", size = 86462, upload-time = "2026-08-27T10:03:31.348Z" },
{ url = "https://files.pythonhosted.org/packages/91/4c/cf6d12a3d709fe5f9771dd917c35e6ebcd55597a5b792287382fde056c95/msgpack-1.2.2-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:53679573c75cce5f82359e0bd4e6a97809a6b9a9b7a48fd1ba592f4a82cddc84", size = 87412, upload-time = "2026-08-27T10:03:32.74Z" },
{ url = "https://files.pythonhosted.org/packages/ca/0d/0aac5752d1708dcb458f8754db34a4999514db3df2d2b798b9381293f638/msgpack-1.2.2-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d3c247d457ae9079974c7ce3c665396754a6d2baff7eaa51332212a8a5a3f13b", size = 422057, upload-time = "2026-08-27T10:03:34.124Z" },
{ url = "https://files.pythonhosted.org/packages/81/30/70f281a3685b04aaf235a5237da11b978a02a865a5a479186205177ad676/msgpack-1.2.2-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:352ed831042549cca8be23780e1fe7c9177e65ff02bf183509c4b4d33f671782", size = 422696, upload-time = "2026-08-27T10:03:35.862Z" },
{ url = "https://files.pythonhosted.org/packages/8a/6d/f76e8425efb0aa38988cd778ae290bfa120491d80d26872d88bb52fedb3f/msgpack-1.2.2-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f80361592c13d7226b4379c8941529b63fe1a9d0e05d2de8f3306b70e522b53f", size = 376495, upload-time = "2026-08-27T10:03:37.339Z" },
{ url = "https://files.pythonhosted.org/packages/95/77/0809aa9b52b2868f7d01862dc14073708f0440421a65197b48453480034c/msgpack-1.2.2-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:68df2947921d449f6dcfeafd86cb2cdde13327a8b447534bbe4ee5aaf32a5695", size = 404683, upload-time = "2026-08-27T10:03:38.87Z" },
{ url = "https://files.pythonhosted.org/packages/02/d2/4e5ac915ba120172d210ef00165c5e6276c8a65db3a4a5cf36e946b83e23/msgpack-1.2.2-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:51dd39d23cfdea0400ed3ff2d29d1e83bd951d3aea79dc89be5b701a09edfe23", size = 375087, upload-time = "2026-08-27T10:03:40.486Z" },
{ url = "https://files.pythonhosted.org/packages/cb/e3/8051d53e5495c87c6cf27eb42fb680361017037f87f322bdaf525f71e4a2/msgpack-1.2.2-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:b13b59e66f107cca1ba708dd5307179870ca1b15b19fcee7ccf722e5308d9212", size = 414421, upload-time = "2026-08-27T10:03:42.308Z" },
{ url = "https://files.pythonhosted.org/packages/ba/4e/13783aa7c17414d7186c72c49bc718366f75e49f0ea58d4f81cb63ac3187/msgpack-1.2.2-cp315-cp315t-win32.whl", hash = "sha256:8c6321a414f8b4a8dc43976b2fa8349156434ca9adedd9a187b796f7e1d3d3fc", size = 71790, upload-time = "2026-08-27T10:03:43.715Z" },
{ url = "https://files.pythonhosted.org/packages/5e/9d/1d02994c7ae2603c98100984428ff0f67443572133bc18eca6058f732c1b/msgpack-1.2.2-cp315-cp315t-win_amd64.whl", hash = "sha256:6f53285f20d592ed309ee19e509cc4c77a3bda1db02ad67e8a0949bb227a5a6d", size = 78766, upload-time = "2026-08-27T10:03:45.036Z" },
{ url = "https://files.pythonhosted.org/packages/60/54/89ed16e6f966a050dc78b0e94a545025211b07ce9f4bdfe07dff70c03fc2/msgpack-1.2.2-cp315-cp315t-win_arm64.whl", hash = "sha256:a378e12ccc06d76efde115caf4073b7e5ff3cc18291d1341f9e65fb882e3f754", size = 71819, upload-time = "2026-08-27T10:03:46.375Z" },
] ]
[[package]] [[package]]
@@ -1393,7 +1374,7 @@ wheels = [
[[package]] [[package]]
name = "openai" name = "openai"
version = "3.6.0" version = "3.3.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "anyio" }, { name = "anyio" },
@@ -1403,9 +1384,9 @@ dependencies = [
{ name = "sniffio" }, { name = "sniffio" },
{ name = "typing-extensions" }, { name = "typing-extensions" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/ac/76/913b755a1a6b54e2d9140eb8d488aa0d47c7359b1d7eac5e864cb7913bbf/openai-3.6.0.tar.gz", hash = "sha256:18fe3f6e96390ef41ee27b152fc9effefca321c33673bd9b956a572493d3ab9b", size = 1455376, upload-time = "2026-08-28T22:29:18.268Z" } sdist = { url = "https://files.pythonhosted.org/packages/7d/9c/ba0c292b4032ede74c249ca314ad64eb1bb5a03a843f6e01facb02f80cd8/openai-3.3.1.tar.gz", hash = "sha256:6f22807de1a976c932cecda620e8172a8c3fdbaeed29c7f21564e0c2410edf56", size = 1282113, upload-time = "2026-08-19T16:31:35.006Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/a1/94/805b87ecc951c49ec8f247f5e8eb324ab064bd2ad73b6a0e704dd49aa073/openai-3.6.0-py3-none-any.whl", hash = "sha256:508e2158bf971687f953b62e44b02f207792c815aac306816386d7ba34d37f5f", size = 1699841, upload-time = "2026-08-28T22:29:16.436Z" }, { url = "https://files.pythonhosted.org/packages/6a/db/2b7a1b3de659bb82aef979116c74e809982b13e42c057759767552b5155f/openai-3.3.1-py3-none-any.whl", hash = "sha256:9652df7fdf8ee6f5bd58e0a12f2b1d414a18e0f06bb7a9a57c8643a5f5469bd3", size = 1690337, upload-time = "2026-08-19T16:31:32.812Z" },
] ]
[[package]] [[package]]
@@ -1717,7 +1698,7 @@ wheels = [
[[package]] [[package]]
name = "pydantic" name = "pydantic"
version = "2.13.5" version = "2.13.4"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "annotated-types" }, { name = "annotated-types" },
@@ -1725,84 +1706,84 @@ dependencies = [
{ name = "typing-extensions" }, { name = "typing-extensions" },
{ name = "typing-inspection" }, { name = "typing-inspection" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/53/ef/fc4f868f4e2cee79f863883abffceff107875f569b848507319842d2a681/pydantic-2.13.5.tar.gz", hash = "sha256:51a9c5f7b2f8e636f04c6cada605d9b6a3bf1348fdf945a3d8869b19bba0ee08", size = 845750, upload-time = "2026-08-28T14:04:00.916Z" } sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/eb/47/c95ffc2009878c7aac0c5e08528022dcb885933252a88b5f170058014464/pydantic-2.13.5-py3-none-any.whl", hash = "sha256:346a034f080da3755d8e9cb5e00e8b07de1d39e4f6e2c87d8ab7cafa0b269a73", size = 472589, upload-time = "2026-08-28T14:03:59.136Z" }, { url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload-time = "2026-05-06T13:43:02.641Z" },
] ]
[[package]] [[package]]
name = "pydantic-core" name = "pydantic-core"
version = "2.46.5" version = "2.46.4"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "typing-extensions" }, { name = "typing-extensions" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/af/f9/8a06bea35ef8daf588f707784c973a7046e0034c8d8cfb08828eeffb8b75/pydantic_core-2.46.5.tar.gz", hash = "sha256:10416c15b8839ecc4ef4d0885da76da6fd0f67333a0eb8aff6d93c4b8f2910fc", size = 472262, upload-time = "2026-08-28T10:01:31.677Z" } sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/82/3f/76358795aa7a8c6d4f36e2cb828ad1c90ee118e1393a9281664f5aade9d4/pydantic_core-2.46.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b9fe6fb92520e3fd61f2e49000b6911b188824f089b75973ea06d6267f0b476d", size = 2076516, upload-time = "2026-08-28T09:58:21.576Z" }, { url = "https://files.pythonhosted.org/packages/ce/8c/af022f0af448d7747c5154288d46b5f2bc5f17366eaa0e23e9aa04d59f3b/pydantic_core-2.46.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2", size = 2106158, upload-time = "2026-05-06T13:38:57.215Z" },
{ url = "https://files.pythonhosted.org/packages/db/50/26b091836076ce4cb2fac264186936acc069e0595772cfd02a563bc4761a/pydantic_core-2.46.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a39ac25a9a2fa4072efdb429833c4a4c8009a51ff9eea3eeae131713cd27991e", size = 1922874, upload-time = "2026-08-28T09:58:23.766Z" }, { url = "https://files.pythonhosted.org/packages/19/95/6195171e385007300f0f5574592e467c568becce2d937a0b6804f218bc49/pydantic_core-2.46.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f", size = 1951724, upload-time = "2026-05-06T13:37:02.697Z" },
{ url = "https://files.pythonhosted.org/packages/09/f0/2a8ce3849e299d44e2d2c196b6082643a3235565a735cb51db7a6261f614/pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fdc8b93a41521988916eeaa271173fcca7fa0803d62f87675aac8dcec1c8e29", size = 1951772, upload-time = "2026-08-28T09:58:25.435Z" }, { url = "https://files.pythonhosted.org/packages/8e/bc/f47d1ff9cbb1620e1b5b697eef06010035735f07820180e74178226b27b3/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7", size = 1975742, upload-time = "2026-05-06T13:37:09.448Z" },
{ url = "https://files.pythonhosted.org/packages/87/46/ac0dc8bdd9e6048183a14eb127764e7ad9240021c17513074a4711b0e31e/pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b98134087d9de723658d17a42c7d0da8d6e2ef08015dee7dc93889047315f5e4", size = 2031832, upload-time = "2026-08-28T09:58:27.102Z" }, { url = "https://files.pythonhosted.org/packages/5b/11/9b9a5b0306345664a2da6410877af6e8082481b5884b3ddd78d47c6013ce/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7", size = 2052418, upload-time = "2026-05-06T13:37:38.234Z" },
{ url = "https://files.pythonhosted.org/packages/c4/c2/339de5bef7be36301a2231eaa52e62163742c2281f11b5f4892bc79785cd/pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e652ab17569c94bff5475520f907b7148b8c24036a8ebbe5cf7cf7493d28579a", size = 2208645, upload-time = "2026-08-28T09:58:28.948Z" }, { url = "https://files.pythonhosted.org/packages/f1/b7/a65fec226f5d78fc39f4a13c4cc0c768c22b113438f60c14adc9d2865038/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712", size = 2232274, upload-time = "2026-05-06T13:38:27.753Z" },
{ url = "https://files.pythonhosted.org/packages/7b/a0/9ff22b797724262da14427abaed4dd1d864a139693fc5e7809114376a716/pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d925f3d9afd05a8c0fb3a1031463a8d59ebe5e2afad297e29c78be19e13b4e62", size = 2265935, upload-time = "2026-08-28T09:58:30.625Z" }, { url = "https://files.pythonhosted.org/packages/68/f0/92039db98b907ef49269a8271f67db9cb78ae2fc68062ef7e4e77adb5f61/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4", size = 2309940, upload-time = "2026-05-06T13:38:05.353Z" },
{ url = "https://files.pythonhosted.org/packages/c0/a4/eb9409ec0736e50aa70a412f16c204ed149516846912f7e6724d4c73ee53/pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fc5be0abd4a407e200d844b404e33639a554e7bd0d448e7b9ae181be4789ac2", size = 2066284, upload-time = "2026-08-28T09:58:32.289Z" }, { url = "https://files.pythonhosted.org/packages/5f/97/2aab507d3d00ca626e8e57c1eac6a79e4e5fbcc63eb99733ff55d1717f65/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce", size = 2094516, upload-time = "2026-05-06T13:39:10.577Z" },
{ url = "https://files.pythonhosted.org/packages/c0/02/7f6156ffc926857f1c37c07d9a388682865a81830ab6a1b637082c25e399/pydantic_core-2.46.5-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:816ff0a6550ffc06c098ccd2e0698600f9aa7da192a79eaa6f9af504a35db869", size = 2105889, upload-time = "2026-08-28T09:58:33.986Z" }, { url = "https://files.pythonhosted.org/packages/22/37/a8aca44d40d737dde2bc05b3c6c07dff0de07ce6f82e9f3167aeaf4d5dea/pydantic_core-2.46.4-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987", size = 2136854, upload-time = "2026-05-06T13:40:22.59Z" },
{ url = "https://files.pythonhosted.org/packages/92/b1/e781d357ebe09fc929f995700f1b3503e8897f1cece183ecb1300d4d67e9/pydantic_core-2.46.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c7ea57fc63aa7da93a1bd2d644e6577befae10c52c4e36377635eea1056a74f5", size = 2158006, upload-time = "2026-08-28T09:58:35.647Z" }, { url = "https://files.pythonhosted.org/packages/24/99/fcef1b79238c06a8cbec70819ac722ba76e02bc8ada9b0fd66eba40da01b/pydantic_core-2.46.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b", size = 2180306, upload-time = "2026-05-06T13:40:10.666Z" },
{ url = "https://files.pythonhosted.org/packages/70/0a/644597d84ab400e50609c192120b85c9681c22d3a20461b9060a79be0a7a/pydantic_core-2.46.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:efd62a42486f1bda5d24cb4f63d15a3c7768375fe83d36f9417b4ad7a2fb20b3", size = 2158408, upload-time = "2026-08-28T09:58:37.38Z" }, { url = "https://files.pythonhosted.org/packages/ae/6c/fc44000918855b42779d007ae63b0532794739027b2f417321cddbc44f6a/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458", size = 2190044, upload-time = "2026-05-06T13:40:43.231Z" },
{ url = "https://files.pythonhosted.org/packages/1e/ee/ca3b7b3a4b3769ffe9ce9432a7c9be755de9593a46d3b0d54d0409323e44/pydantic_core-2.46.5-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:2bc9419666990c06d7397831f2126a1ecc3594aaa3ff7de5bf2d066802f4e07b", size = 2309609, upload-time = "2026-08-28T09:58:39.22Z" }, { url = "https://files.pythonhosted.org/packages/6b/65/d9cadc9f1920d7a127ad2edba16c1db7916e59719285cd6c94600b0080ba/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b", size = 2329133, upload-time = "2026-05-06T13:39:57.365Z" },
{ url = "https://files.pythonhosted.org/packages/ce/52/39fa1f451486019524ca685020390e7ca351832fd874530ba30c8628e6dc/pydantic_core-2.46.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:18a09e1e1011b462f2e32774f25859ef1223d5c2b0546a633cf56654710721e0", size = 2342618, upload-time = "2026-08-28T09:58:40.89Z" }, { url = "https://files.pythonhosted.org/packages/d0/cf/c873d91679f3a30bcf5e7ac280ce5573483e72295307685120d0d5ad3416/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c", size = 2374464, upload-time = "2026-05-06T13:38:06.976Z" },
{ url = "https://files.pythonhosted.org/packages/81/5e/468fc630568c61dcef3cd47ad32ffbeed9af643f49208d1ea86ab4f890c4/pydantic_core-2.46.5-cp312-cp312-win32.whl", hash = "sha256:5cb482e9e84c851f4e623fe4acc1ced89168cf1fe18f7089db4548c8f5bbb65b", size = 1939475, upload-time = "2026-08-28T09:58:42.591Z" }, { url = "https://files.pythonhosted.org/packages/47/bd/6f2fc8188f31bf10590f1e98e7b306336161fac930a8c514cd7bd828c7dc/pydantic_core-2.46.4-cp312-cp312-win32.whl", hash = "sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894", size = 1974823, upload-time = "2026-05-06T13:40:47.985Z" },
{ url = "https://files.pythonhosted.org/packages/cf/c9/4c19f41b84cf6b622a72fbeed7665b25d47a187d68d47d0d430c07f23268/pydantic_core-2.46.5-cp312-cp312-win_amd64.whl", hash = "sha256:5e81740c09e310f5aa5cbd3e434a01c154d4bef93241c7877b39f211d2b78ba8", size = 2043140, upload-time = "2026-08-28T09:58:44.272Z" }, { url = "https://files.pythonhosted.org/packages/40/8c/985c1d41ea1107c2534abd9870e4ed5c8e7669b5c308297835c001e7a1c4/pydantic_core-2.46.4-cp312-cp312-win_amd64.whl", hash = "sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89", size = 2072919, upload-time = "2026-05-06T13:39:21.153Z" },
{ url = "https://files.pythonhosted.org/packages/af/dd/0c1a050299147c746e5256db16d645ab5efd4f78c59937d581a0524e74a2/pydantic_core-2.46.5-cp312-cp312-win_arm64.whl", hash = "sha256:f7b0ec93a2893de856652154d73b7ba622f26fa97726487dcac373de5f4c6084", size = 1997729, upload-time = "2026-08-28T09:58:46.13Z" }, { url = "https://files.pythonhosted.org/packages/c4/ba/f463d006e0c47373ca7ec5e1a261c59dc01ef4d62b2657af925fb0deee3a/pydantic_core-2.46.4-cp312-cp312-win_arm64.whl", hash = "sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a", size = 2027604, upload-time = "2026-05-06T13:39:03.753Z" },
{ url = "https://files.pythonhosted.org/packages/f5/37/5abe39a8372a61d3dc3c1338fc504281c01b32fdb3169cd7187153b56d3e/pydantic_core-2.46.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:b7ca9034437b6022f941f4857459562ee00a560b97e7cce8a0ec5a74fc6766e0", size = 2075885, upload-time = "2026-08-28T09:58:47.856Z" }, { url = "https://files.pythonhosted.org/packages/51/a2/5d30b469c5267a17b39dec53208222f76a8d351dfac4af661888c5aee77d/pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008", size = 2106306, upload-time = "2026-05-06T13:37:48.029Z" },
{ url = "https://files.pythonhosted.org/packages/21/43/6323b1f8b217780454c61304bcd2b38ae4762f50754414124603ccc90bb2/pydantic_core-2.46.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f332f0e72a5a0400141f830744e141bf9f97917878dbe968669e8a7fefea78ff", size = 1922768, upload-time = "2026-08-28T09:58:49.58Z" }, { url = "https://files.pythonhosted.org/packages/c1/81/4fa520eaffa8bd7d1525e644cd6d39e7d60b1592bc5b516693c7340b50f1/pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4", size = 1951906, upload-time = "2026-05-06T13:37:17.012Z" },
{ url = "https://files.pythonhosted.org/packages/0f/a3/c05ca796e1197618a774b01e596aeedfefc2f7d8c01ae3054e910b120e8a/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:193375f3548919d3f0b60936ca113ada3e38f264f91b9b8e0508efaad57be931", size = 1951241, upload-time = "2026-08-28T09:58:51.511Z" }, { url = "https://files.pythonhosted.org/packages/03/d5/fd02da45b659668b05923b17ba3a0100a0a3d5541e3bd8fcc4ecb711309e/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76", size = 1976802, upload-time = "2026-05-06T13:37:35.113Z" },
{ url = "https://files.pythonhosted.org/packages/68/32/33bc39ac705c52cffc908e8389f9754fdb208aea5c69cceddf4eb3ce99af/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:79bdfa52f843137045b2d081cc05c120ba6665d29b7559c2c47690906f39279f", size = 2031975, upload-time = "2026-08-28T09:58:53.166Z" }, { url = "https://files.pythonhosted.org/packages/21/f2/95727e1368be3d3ed485eaab7adbd7dda408f33f7a36e8b48e0144002b91/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3", size = 2052446, upload-time = "2026-05-06T13:37:12.313Z" },
{ url = "https://files.pythonhosted.org/packages/b0/70/2333e885c0f6a67bc105c5916965dac9b57f2718ee20d81d1a06a4ebdc13/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:24922243639cbdac66c75fcb6fd6495a9cb52b213d62f9a0d16f0310b1ff8038", size = 2208542, upload-time = "2026-08-28T09:58:55.017Z" }, { url = "https://files.pythonhosted.org/packages/9c/86/5d99feea3f77c7234b8718075b23db11532773c1a0dbd9b9490215dc2eeb/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76", size = 2232757, upload-time = "2026-05-06T13:39:01.149Z" },
{ url = "https://files.pythonhosted.org/packages/f7/ea/296debfb4264207bbda5936133892e027c0a58875ad53ebd512fba8ec3a2/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c76fe65e607be28c7fd4d56fc3c42b1583aa058ce3408b7ad0fd540171d31f9f", size = 2264692, upload-time = "2026-08-28T09:58:56.767Z" }, { url = "https://files.pythonhosted.org/packages/d2/3a/508ac615935ef7588cf6d9e9b91309fdc2da751af865e02a9098de88258c/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4", size = 2309275, upload-time = "2026-05-06T13:37:41.406Z" },
{ url = "https://files.pythonhosted.org/packages/d3/f2/9e4de77a6271e07a76d2d58b11c091a979c191ed2939bf80067568b369d2/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f7b393a8b3da82f5c1fc0751e6d01ac6c55b93c18226a60bdfba4a724efafd1", size = 2066633, upload-time = "2026-08-28T09:58:58.531Z" }, { url = "https://files.pythonhosted.org/packages/07/f8/41db9de19d7987d6b04715a02b3b40aea467000275d9d758ffaa31af7d50/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a", size = 2094467, upload-time = "2026-05-06T13:39:18.847Z" },
{ url = "https://files.pythonhosted.org/packages/8d/db/f9e9d0c97445987b2084823d5c240de88087338f04fc2cfaa2df186b8049/pydantic_core-2.46.5-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:7ac031912d54f3d83ef3b3eb98dfabc1608802e2202263d25957eeed40b94761", size = 2105235, upload-time = "2026-08-28T09:59:00.421Z" }, { url = "https://files.pythonhosted.org/packages/2c/e2/f35033184cb11d0052daf4416e8e10a502ea2ac006fc4f459aee872727d1/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262", size = 2134417, upload-time = "2026-05-06T13:40:17.944Z" },
{ url = "https://files.pythonhosted.org/packages/07/c5/79169b047b3b2c3e99e04bc76372af9637e0bf6db638274fa927df96369e/pydantic_core-2.46.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:837b396ca3d7b74091ca623f6cbd8351bd42d670a79c2683e79fb089f06a2de5", size = 2157367, upload-time = "2026-08-28T09:59:02.442Z" }, { url = "https://files.pythonhosted.org/packages/7e/7b/6ceeb1cc90e193862f444ebe373d8fdf613f0a82572dde03fb10734c6c71/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e", size = 2179782, upload-time = "2026-05-06T13:40:32.618Z" },
{ url = "https://files.pythonhosted.org/packages/26/b5/ba6057afb7c291bd449f51b867f95aef2072941c4ce4e5c31d6ffd132d3b/pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:5ee239d575f80b08eca11f6e20f90c4c695de7825c67eefe6091fbf20dda648e", size = 2158420, upload-time = "2026-08-28T09:59:04.2Z" }, { url = "https://files.pythonhosted.org/packages/5a/f2/c8d7773ede6af08036423a00ae0ceffce266c3c52a096c435d68c896083f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd", size = 2188782, upload-time = "2026-05-06T13:36:51.018Z" },
{ url = "https://files.pythonhosted.org/packages/6e/28/2057abecaafdc22912afa819603a51f0a62d40643b7c4871c51721fea9be/pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:e80675d75ae2cd14372cb65cad5400d9347a3d3f6c13000183f22dfd027283ed", size = 2309588, upload-time = "2026-08-28T09:59:06.048Z" }, { url = "https://files.pythonhosted.org/packages/59/31/0c864784e31f09f05cdd87606f08923b9c9e7f6e51dd27f20f62f975ce9f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be", size = 2328334, upload-time = "2026-05-06T13:40:37.764Z" },
{ url = "https://files.pythonhosted.org/packages/71/9d/881156dc404e27479c4246128d73538464cab4a239bec61995e227644c30/pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:9c4b71f10dd532fb7a5cbc8f58707779e64f03a258c2bf8bfbaecfcd9970b519", size = 2341866, upload-time = "2026-08-28T09:59:08.539Z" }, { url = "https://files.pythonhosted.org/packages/c2/eb/4f6c8a41efa30baa755590f4141abf3a8c370fab610915733e74134a7270/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d", size = 2372986, upload-time = "2026-05-06T13:39:34.152Z" },
{ url = "https://files.pythonhosted.org/packages/5a/38/d66f443a259f84d13babdceae568e572b0ed26da17ca5d0a649ebb110a67/pydantic_core-2.46.5-cp313-cp313-win32.whl", hash = "sha256:97bf8de4d541598c94a59344eeb988a94c08ff76b5723c41f6567ec18c7892ea", size = 1938580, upload-time = "2026-08-28T09:59:10.402Z" }, { url = "https://files.pythonhosted.org/packages/5b/24/b375a480d53113860c299764bfe9f349a3dc9108b3adc0d7f0d786492ebf/pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb", size = 1973693, upload-time = "2026-05-06T13:37:55.072Z" },
{ url = "https://files.pythonhosted.org/packages/2c/1e/1d5371213f4cc9a7ed70c0bfcc7911de22311ee99a662a56077d7292d2ac/pydantic_core-2.46.5-cp313-cp313-win_amd64.whl", hash = "sha256:15f4a94963c95accac15b7b657bb177d3ad82bb90b0d0526d9a9b85079925db5", size = 2041980, upload-time = "2026-08-28T09:59:12.396Z" }, { url = "https://files.pythonhosted.org/packages/7e/e8/cff247591966f2d22ec8c003cd7587e27b7ba7b81ab2fb888e3ab75dc285/pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292", size = 2071819, upload-time = "2026-05-06T13:38:49.139Z" },
{ url = "https://files.pythonhosted.org/packages/5a/48/4222d90b1c67568bace4dec6dca6271449c66de3595d72b6d098f5fde597/pydantic_core-2.46.5-cp313-cp313-win_arm64.whl", hash = "sha256:d22a945598fb91236b4dd793a6e42e4f3dd7740bb5aace5ebd7d4c08d13bb575", size = 1997213, upload-time = "2026-08-28T09:59:14.245Z" }, { url = "https://files.pythonhosted.org/packages/c6/1a/f4aee670d5670e9e148e0c82c7db98d780be566c6e6a97ee8035528ca0b3/pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d", size = 2027411, upload-time = "2026-05-06T13:40:45.796Z" },
{ url = "https://files.pythonhosted.org/packages/8e/8a/14596f2a8367da50cf7cbac48169ee5d9c8e11d486a3b527082384630c72/pydantic_core-2.46.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:c1c43ad4339643d70ebb8124e1305a7dab423001eff58bb41a0f731adbc98355", size = 2074081, upload-time = "2026-08-28T09:59:16.141Z" }, { url = "https://files.pythonhosted.org/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb", size = 2102079, upload-time = "2026-05-06T13:38:41.019Z" },
{ url = "https://files.pythonhosted.org/packages/ae/d5/d8a4eb6d6c7f66b91dd37c576d76e9e60fba900caf5372c17bcf949febc2/pydantic_core-2.46.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1a353f84de772f423b5ffb11d7ae352fbbef0f446f3c0b0af0f8236d7233606e", size = 1920497, upload-time = "2026-08-28T09:59:18.065Z" }, { url = "https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462", size = 1952179, upload-time = "2026-05-06T13:36:59.812Z" },
{ url = "https://files.pythonhosted.org/packages/8e/26/092079428f86e927e030b2c0ced87df69dbb1c875cdeaa67bf42ea2be746/pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5086029a57366b8cf81b130a43908738095c270c21a8d7f0e8bdfdb89718e2f3", size = 1952130, upload-time = "2026-08-28T09:59:20.476Z" }, { url = "https://files.pythonhosted.org/packages/95/30/5211a831ae054928054b2f79731661087a2bc5c01e825c672b3a4a8f1b3e/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9", size = 1978926, upload-time = "2026-05-06T13:37:39.933Z" },
{ url = "https://files.pythonhosted.org/packages/08/c3/8ec0e290a9ebaebd64047bf5fda94be835c6b1551b02437e4b76778fbcd7/pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46c25dda9d092a06c08db76ffe0a197107904d0dfac653f7d5306bbcd6d6119c", size = 2026371, upload-time = "2026-08-28T09:59:22.227Z" }, { url = "https://files.pythonhosted.org/packages/57/e9/689668733b1eb67adeef047db3c2e8788fcf65a7fd9c9e2b46b7744fe245/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4", size = 2046785, upload-time = "2026-05-06T13:38:01.995Z" },
{ url = "https://files.pythonhosted.org/packages/01/72/4fd20ad520fb8da0157f95b27a7eb05a72790ef08138e7701ac972c342ea/pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:37ea7b83c935e5b0d68c9449b82651accf78a10828b2c02b2f2d9e9496446c21", size = 2202822, upload-time = "2026-08-28T09:59:24.277Z" }, { url = "https://files.pythonhosted.org/packages/60/d9/6715260422ff50a2109878fd24d948a6c3446bb2664f34ee78cd972b3acd/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914", size = 2228733, upload-time = "2026-05-06T13:40:50.371Z" },
{ url = "https://files.pythonhosted.org/packages/31/b0/d16e0771206b29314f0d52198b720be21e8a99ab2bf11e3bc0d7c9cebdff/pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e64e88d5585bea9ce95861079de72006c7fa6d3df4e3a3b65ba31eb979c15c9f", size = 2262756, upload-time = "2026-08-28T09:59:26.608Z" }, { url = "https://files.pythonhosted.org/packages/18/ae/fdb2f64316afca925640f8e70bb1a564b0ec2721c1389e25b8eb4bf9a299/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28", size = 2307534, upload-time = "2026-05-06T13:37:21.531Z" },
{ url = "https://files.pythonhosted.org/packages/2c/9b/59634b7ac631c63b2a37760eb6943af3e29573d6b59a4abc5e7f019d4cee/pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54d510bac3ee52247af28ed4bb18a1e799f040ac60fd2bf5ccd4c92f1fbe786f", size = 2068352, upload-time = "2026-08-28T09:59:29.044Z" }, { url = "https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b", size = 2099732, upload-time = "2026-05-06T13:39:31.942Z" },
{ url = "https://files.pythonhosted.org/packages/08/7c/570abb1ad2155348dc754ea91be22e5aaa18eb6d69a6068f7c6f2679a6ed/pydantic_core-2.46.5-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:a2a5e1d0ff29adddc9f6d6821a66302e4493f8ca898b715b6b1182c2c201ea0a", size = 2104777, upload-time = "2026-08-28T09:59:30.95Z" }, { url = "https://files.pythonhosted.org/packages/06/d5/ee5a3366637fee41dee51a1fc91562dcf12ddbc68fda34e6b253da2324bb/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c", size = 2129627, upload-time = "2026-05-06T13:37:25.033Z" },
{ url = "https://files.pythonhosted.org/packages/8e/25/5bf74adc65a1ac5b7be3f6cb0bcb5433615c1598a801c19d830d84c98ded/pydantic_core-2.46.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:03b9666e41e35d8909852ba191a0607520f81b74eaf12ccf8737005dbb313821", size = 2156312, upload-time = "2026-08-28T09:59:32.604Z" }, { url = "https://files.pythonhosted.org/packages/94/33/2414be571d2c6a6c4d08be21f9292b6d3fdb08949a97b6dfe985017821db/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb", size = 2179141, upload-time = "2026-05-06T13:37:14.046Z" },
{ url = "https://files.pythonhosted.org/packages/90/6a/2ef38830675e050121040618135564ed56b860b45433b02d9b4ebece46f3/pydantic_core-2.46.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:a91c17edf6eea2402cb5457b4c89e99bc5ed1004aa34c4adf1d4258c1a5c22c2", size = 2150067, upload-time = "2026-08-28T09:59:34.453Z" }, { url = "https://files.pythonhosted.org/packages/7b/79/7daa95be995be0eecc4cf75064cb33f9bbbfe3fe0158caf2f0d4a996a5c7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898", size = 2184325, upload-time = "2026-05-06T13:36:53.615Z" },
{ url = "https://files.pythonhosted.org/packages/90/ef/a7dbb03a14a64c2a4621f989c615ed9a892535a6cad938fc27079f919d80/pydantic_core-2.46.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b49924c73a235e969511bf2aabdff3beebf9820931f646c80274d5d780010c47", size = 2304516, upload-time = "2026-08-28T09:59:36.194Z" }, { url = "https://files.pythonhosted.org/packages/9f/cb/d0a382f5c0de8a222dc61c65348e0ce831b1f68e0a018450d31c2cace3a5/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e", size = 2323990, upload-time = "2026-05-06T13:40:29.971Z" },
{ url = "https://files.pythonhosted.org/packages/68/f8/6bb4c4b80e8a6fde1904c64a51c62a1d04fcdfa3ea521a66b2ddefa1d885/pydantic_core-2.46.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:2cbd9a5eff05e51c447c34dfa4632145b26b09120cf04bd0c871e44c1a5e1c9a", size = 2335223, upload-time = "2026-08-28T09:59:37.931Z" }, { url = "https://files.pythonhosted.org/packages/05/db/d9ba624cc4a5aced1598e88c04fdbd8310c8a69b9d38b9a3d39ce3a61ed7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519", size = 2369978, upload-time = "2026-05-06T13:37:23.027Z" },
{ url = "https://files.pythonhosted.org/packages/2a/80/f46b8c681195190b2c1f1c7c0a81abce60663e987613e09ef64d433dd96b/pydantic_core-2.46.5-cp314-cp314-win32.whl", hash = "sha256:2d5d76654becf5efd62c9e51c3756c67b49498b0c9a40884934c40807adbd074", size = 1934827, upload-time = "2026-08-28T09:59:39.836Z" }, { url = "https://files.pythonhosted.org/packages/f2/20/d15df15ba918c423461905802bfd2981c3af0bfa0e40d05e13edbfa48bc3/pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4", size = 1966354, upload-time = "2026-05-06T13:38:03.499Z" },
{ url = "https://files.pythonhosted.org/packages/f7/3c/60674207246bc0a4009d2391b7c7251c7159f279c8d2ab8aae8ef46f3dee/pydantic_core-2.46.5-cp314-cp314-win_amd64.whl", hash = "sha256:fa10ef4112775900e7a0661068635eb67b2ab824fbde764de6e0e21982a93db0", size = 2042648, upload-time = "2026-08-28T09:59:41.792Z" }, { url = "https://files.pythonhosted.org/packages/fc/b6/6b8de4c0a7d7ab3004c439c80c5c1e0a3e8d78bbae19379b01960383d9e5/pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac", size = 2072238, upload-time = "2026-05-06T13:39:40.807Z" },
{ url = "https://files.pythonhosted.org/packages/69/0c/117c562c7c1babdf44576b72a5e496906506c93690387ecfbca7c729ae2e/pydantic_core-2.46.5-cp314-cp314-win_arm64.whl", hash = "sha256:045ab3b6d308439e32b81cc173bba5b9018bc6ed896afd0c65b3b009b1699af5", size = 1989652, upload-time = "2026-08-28T09:59:43.702Z" }, { url = "https://files.pythonhosted.org/packages/32/36/51eb763beec1f4cf59b1db243a7dcc39cbb41230f050a09b9d69faaf0a48/pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a", size = 2018251, upload-time = "2026-05-06T13:37:26.72Z" },
{ url = "https://files.pythonhosted.org/packages/e8/66/9336ae58f9eb68c41d121894e52c4c89eccb07eb8f602a04ee9c3f37736a/pydantic_core-2.46.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8816f3d218beb4b787de5c9759c259b8fa61f9dec42dc7811f320a33771778b7", size = 2065829, upload-time = "2026-08-28T09:59:45.364Z" }, { url = "https://files.pythonhosted.org/packages/e8/91/855af51d625b23aa987116a19e231d2aaef9c4a415273ddc189b79a45fee/pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0", size = 2099593, upload-time = "2026-05-06T13:39:47.682Z" },
{ url = "https://files.pythonhosted.org/packages/c5/02/bc19b47a96c2d3109760711acf22369e56bd7e405ca52f7ade164d2ead57/pydantic_core-2.46.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:bce57638e08ac148e5778cce7feb968307a727d66f8e2274a543d0cf0c9ad6a3", size = 1905716, upload-time = "2026-08-28T09:59:47.18Z" }, { url = "https://files.pythonhosted.org/packages/fb/1b/8784a54c65edb5f49f0a14d6977cf1b209bba85a4c77445b255c2de58ab3/pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d", size = 1935226, upload-time = "2026-05-06T13:40:40.428Z" },
{ url = "https://files.pythonhosted.org/packages/52/a4/70b47c0509923dd98ccfed04fb3e32ea3849c82a0ff2205bb41009b43c00/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:976e1128455aa595ea04c79ccfedff1aaeab96ee013fcc916bed120c4f0ad94f", size = 1934216, upload-time = "2026-08-28T09:59:49.241Z" }, { url = "https://files.pythonhosted.org/packages/e8/e7/1955d28d1afc56dd4b3ad7cc0cf39df1b9852964cf16e5d13912756d6d6b/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b", size = 1974605, upload-time = "2026-05-06T13:37:32.029Z" },
{ url = "https://files.pythonhosted.org/packages/52/ab/aa03b65f7bb198585edf806b906c3223ecf1795543e39e23aec4cce27ad2/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7b891faeedeafba41b2983e5001a81b6a915b69544c7e7570d1989ce1c36ac7", size = 2010635, upload-time = "2026-08-28T09:59:51.692Z" }, { url = "https://files.pythonhosted.org/packages/93/e2/3fedbf0ba7a22850e6e9fd78117f1c0f10f950182344d8a6c535d468fdd8/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000", size = 2030777, upload-time = "2026-05-06T13:38:55.239Z" },
{ url = "https://files.pythonhosted.org/packages/3c/8b/0da06343f30b84ec549aafd309c6456223d5dc8bd36af504c573faad561d/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5f194189415698233dd1114a093a9b56e61e2c57e11b469be3b0506f46f0771c", size = 2209369, upload-time = "2026-08-28T09:59:53.582Z" }, { url = "https://files.pythonhosted.org/packages/f8/61/46be275fcaaba0b4f5b9669dd852267ce1ff616592dccf7a7845588df091/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e", size = 2236641, upload-time = "2026-05-06T13:37:08.096Z" },
{ url = "https://files.pythonhosted.org/packages/d6/5b/844c4defaa34a3df66eb9257087d121d70c201298b96abdf9f492fc2f1bf/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:82a36973cf8a2ef5406f4fe2edbf8ed0c99629535d959e0b100c76a32535a111", size = 2253238, upload-time = "2026-08-28T09:59:55.484Z" }, { url = "https://files.pythonhosted.org/packages/60/db/12e93e46a8bac9988be3c016860f83293daea8c716c029c9ace279036f2f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd", size = 2286404, upload-time = "2026-05-06T13:40:20.221Z" },
{ url = "https://files.pythonhosted.org/packages/f4/64/a4e536cb16d7f61a7fd3120b46c577fc7fa7325992f69c4f52bc786d77d8/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdbb78909f52b981d3b2d56b97328d71eb0b974c36bd77c920123a7ebb192829", size = 2065740, upload-time = "2026-08-28T09:59:58.038Z" }, { url = "https://files.pythonhosted.org/packages/e2/4a/4d8b19008f38d31c53b8219cfedc2e3d5de5fe99d90076b7e767de29274f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3", size = 2109219, upload-time = "2026-05-06T13:38:12.153Z" },
{ url = "https://files.pythonhosted.org/packages/5f/75/aaa38c6bc2d085f6605b34eabdc6a8a4e0b2e61fc9c8e6e52b28e97b3125/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:52e24eacdb536cade636aa90fb851835222becff8484b7001fdc78cb0290f2aa", size = 2087425, upload-time = "2026-08-28T09:59:59.898Z" }, { url = "https://files.pythonhosted.org/packages/88/70/3cbc40978fefb7bb09c6708d40d4ad1a5d70fd7213c3d17f971de868ec1f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7", size = 2110594, upload-time = "2026-05-06T13:40:02.971Z" },
{ url = "https://files.pythonhosted.org/packages/55/ae/fcab4cfc39aba3689e1d20c8b5250ad280957022c09af2ed9cd585602a5e/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:37ae34309d7bd8c0d61ab839668058f2a7962ea1fc51d105d2db228fe0618034", size = 2139306, upload-time = "2026-08-28T10:00:03.057Z" }, { url = "https://files.pythonhosted.org/packages/9d/20/b8d36736216e29491125531685b2f9e61aa5b4b2599893f8268551da3338/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff", size = 2159542, upload-time = "2026-05-06T13:39:27.506Z" },
{ url = "https://files.pythonhosted.org/packages/2d/f4/f1d03a4bc9d9acbc62f4d742b8a319af52f71885079868b2ff8e48a651ee/pydantic_core-2.46.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:0cdbada856a1c69a7624a64d3d9aefe79300bd6ef827b43a4f265010b9b55184", size = 2144589, upload-time = "2026-08-28T10:00:05.645Z" }, { url = "https://files.pythonhosted.org/packages/1d/a2/367df868eb584dacf6bf82a389272406d7178e301c4ac82545ab98bc2dd9/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424", size = 2168146, upload-time = "2026-05-06T13:38:31.93Z" },
{ url = "https://files.pythonhosted.org/packages/83/f3/7a53bb1356de514a4cd295f25b6ac39237895620c0462d2592b76c16e114/pydantic_core-2.46.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:545f26c504b27c3758439a5e6d9349931f0a04f855668d5fe323c89e82300a38", size = 2288882, upload-time = "2026-08-28T10:00:07.931Z" }, { url = "https://files.pythonhosted.org/packages/c1/b8/4460f77f7e201893f649a29ab355dddd3beee8a97bcb1a320db414f9a06e/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6", size = 2306309, upload-time = "2026-05-06T13:37:44.717Z" },
{ url = "https://files.pythonhosted.org/packages/cd/94/5a81583660c175c59d49ffb09f4b3a44debeaf86a19fca664ae1cdd9ee32/pydantic_core-2.46.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:ff218293c9c806138dca139765e3b067621be52bcd93cdc14c7711be7ddc90a9", size = 2335210, upload-time = "2026-08-28T10:00:10.177Z" }, { url = "https://files.pythonhosted.org/packages/64/c4/be2639293acd87dc8ddbcec41a73cee9b2ebf996fe6d892a1a74e88ad3f7/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565", size = 2369736, upload-time = "2026-05-06T13:37:05.645Z" },
{ url = "https://files.pythonhosted.org/packages/5a/9f/5d685c2693b972d1a59c998586e8823712b66603aeff47ee60a4bdaafd37/pydantic_core-2.46.5-cp314-cp314t-win32.whl", hash = "sha256:97cf3eb53a8cccacf9d46686a0926186c9bfb5574f2ed66d3639d5fe117cd3a9", size = 1921180, upload-time = "2026-08-28T10:00:12.35Z" }, { url = "https://files.pythonhosted.org/packages/30/a6/9f9f380dbb301f67023bf8f707aaa75daadf84f7152d95c410fd7e81d994/pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02", size = 1955575, upload-time = "2026-05-06T13:38:51.116Z" },
{ url = "https://files.pythonhosted.org/packages/70/12/5c94ee16d65a37a15f9e869f5e6256df111154491173801a4c5e800ab548/pydantic_core-2.46.5-cp314-cp314t-win_amd64.whl", hash = "sha256:d2f9fc07a8042a8f95925b35c4f04f469707c981fc33245b6ca187cf5d2dd290", size = 2020515, upload-time = "2026-08-28T10:00:14.774Z" }, { url = "https://files.pythonhosted.org/packages/40/1f/f1eb9eb350e795d1af8586289746f5c5677d16043040d63710e22abc43c9/pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5", size = 2051624, upload-time = "2026-05-06T13:38:21.672Z" },
{ url = "https://files.pythonhosted.org/packages/63/19/67830dda664e6bdf9285ee2e40f355d0d7d6b92aa0c42e8d217bb8d33d36/pydantic_core-2.46.5-cp314-cp314t-win_arm64.whl", hash = "sha256:acf8a67ba51f4ca9ddbd0e6b3000a65ac51ab734661778b3e7ba64d99a710f2f", size = 1989276, upload-time = "2026-08-28T10:00:16.984Z" }, { url = "https://files.pythonhosted.org/packages/f6/d2/42dd53d0a85c27606f316d3aa5d2869c4e8470a5ed6dec30e4a1abe19192/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596", size = 2017325, upload-time = "2026-05-06T13:40:52.723Z" },
{ url = "https://files.pythonhosted.org/packages/df/dd/053c2e4303f791f3b8f8a14ab0b22008e8eb21d868c0c90b4f9be705b76a/pydantic_core-2.46.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:013d6f3483d81e02e7c328831808f336c8596ee33b4bd4026b9ffb1e960b8942", size = 2062540, upload-time = "2026-08-28T10:01:00.318Z" }, { url = "https://files.pythonhosted.org/packages/9d/1d/8987ad40f65ae1432753072f214fb5c74fe47ffbd0698bb9cbbb585664f8/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7", size = 2095527, upload-time = "2026-05-06T13:39:52.283Z" },
{ url = "https://files.pythonhosted.org/packages/d7/dd/a18df751a5e37dd51bfad7f68e766999125bebe68c9e1d10a493ad01bd63/pydantic_core-2.46.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:e9c134bb666dd54b778b9fc0d2b50cbb7f979b9e3716f26a88c9ab3b6fc1dd0f", size = 1902040, upload-time = "2026-08-28T10:01:02.529Z" }, { url = "https://files.pythonhosted.org/packages/64/d3/84c282a7eee1d3ac4c0377546ef5a1ea436ce26840d9ac3b7ed54a377507/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df", size = 1936024, upload-time = "2026-05-06T13:40:15.671Z" },
{ url = "https://files.pythonhosted.org/packages/b7/13/01d40f9d07ce8a779fd6e0bd8ad4fba91309500dd67b869e2e219d261a6d/pydantic_core-2.46.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:347ec774390c87326a2e4929d58d3f7e8763a104d5d35f4cd595a4c952366433", size = 1967479, upload-time = "2026-08-28T10:01:05.004Z" }, { url = "https://files.pythonhosted.org/packages/d7/ca/eac61596cdeb4d7e174d3dc0bd8a6238f14f75f97a24e7b7db4c7e7340a0/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526", size = 1990696, upload-time = "2026-05-06T13:38:34.717Z" },
{ url = "https://files.pythonhosted.org/packages/fa/04/c81d4841331c2178b6fb09ae225425e110ed72d990c9fe556c4ec03d1013/pydantic_core-2.46.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e24d8f05fa2d28513d94e877e9c75ad66175376209b3977f916e240e623193c", size = 2111034, upload-time = "2026-08-28T10:01:07.345Z" }, { url = "https://files.pythonhosted.org/packages/fa/c3/7c8b240552251faf6b3a957db200fcfbbcec36763c050428b601e0c9b83b/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0", size = 2147590, upload-time = "2026-05-06T13:39:29.883Z" },
] ]
[[package]] [[package]]
@@ -1989,7 +1970,7 @@ wheels = [
[[package]] [[package]]
name = "typer" name = "typer"
version = "0.27.2" version = "0.27.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "annotated-doc" }, { name = "annotated-doc" },
@@ -1997,18 +1978,18 @@ dependencies = [
{ name = "rich" }, { name = "rich" },
{ name = "shellingham" }, { name = "shellingham" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/16/f7/57713ba479fd405eb76de31404b2c744c289e336b2d999511ebf51e496f7/typer-0.27.2.tar.gz", hash = "sha256:269b7eb9d3c202ca84b4bc9618cb04ebb43d3d4d1e567e4c768607232c05f945", size = 204045, upload-time = "2026-08-28T10:26:55.046Z" } sdist = { url = "https://files.pythonhosted.org/packages/ae/40/4a3db7990d1f62a53182aa96eaef57aeb2886a27f90a195bc66713565d31/typer-0.27.1.tar.gz", hash = "sha256:a79bef8469a79c45498e7b814ecf8d603cc7644e9acbd9e19cac0334240b18df", size = 203994, upload-time = "2026-08-03T14:41:03.438Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/dc/bf/205d0004930ede8f542fb58f601526fccf4ae7626075ca1e6c4de5d3d652/typer-0.27.2-py3-none-any.whl", hash = "sha256:b3a5fc4342d5fc8fda8fc3010b1cf117e9249aab7fae800c2eff62fd3842d97d", size = 123130, upload-time = "2026-08-28T10:26:53.752Z" }, { url = "https://files.pythonhosted.org/packages/43/89/9518bc0c3929bee36b3a4a8e3daddd6e03f92f9961c66d4983b837160543/typer-0.27.1-py3-none-any.whl", hash = "sha256:53150287edd11baeb4e4722c8e394fcdf8181c0ae89485cba8d25c778d5edd56", size = 122874, upload-time = "2026-08-03T14:41:04.391Z" },
] ]
[[package]] [[package]]
name = "types-protobuf" name = "types-protobuf"
version = "7.35.1.20260827" version = "7.35.1.20260826"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/44/07/541ffc94a4baee7d92ec91d91018aa684f97ece608b74619863e3cfd9cb3/types_protobuf-7.35.1.20260827.tar.gz", hash = "sha256:5a98c18177cfd968d6a0de55ecfc4221aa829ef88bcd86104298e028516b04af", size = 69646, upload-time = "2026-08-27T12:06:04.93Z" } sdist = { url = "https://files.pythonhosted.org/packages/5a/8d/63939858680cda558e43de17822e1bcdf74fb3d1cdf5a80ce7a90a0c2a0f/types_protobuf-7.35.1.20260826.tar.gz", hash = "sha256:e7083f061500bcbf6d1f32eb83dfff0983d1583b028ae7a791dbe33f47e8bf3a", size = 69626, upload-time = "2026-08-26T02:54:39.711Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/01/e2/7ce7c4802bcf3732155dedc23fe3d2b506a387d6b42da61261886f42af80/types_protobuf-7.35.1.20260827-py3-none-any.whl", hash = "sha256:7cc452a012678a6a889287d4cb702ea54b9f90a6ab0f3aa4c019d21f3ae7529b", size = 86412, upload-time = "2026-08-27T12:06:03.826Z" }, { url = "https://files.pythonhosted.org/packages/fe/a8/24fa08c2b9307ead7e9c3565de007e47315ca396c78e9cc1350643737052/types_protobuf-7.35.1.20260826-py3-none-any.whl", hash = "sha256:49adc6d989e146b7b2ba4498aeae36937619d4b95a21cd20025fc88b2cd29b62", size = 86412, upload-time = "2026-08-26T02:54:38.673Z" },
] ]
[[package]] [[package]]
@@ -2131,7 +2112,6 @@ wheels = [
name = "websockets" name = "websockets"
version = "17.1" version = "17.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/18/72/fba934cb3dff7a85d811820efffcd141ddd52b5a2a01637f64551373ff4d/websockets-17.1.tar.gz", hash = "sha256:acfea4c20bf54384883ea33b1240fc1db4f52e190823a4e2b334bc3e8bfca96a", size = 187520, upload-time = "2026-08-26T17:25:33.063Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/a6/0d/098f23c4c858e5de9459ffc554fa07d5493fbcfca7f040b5800cf1cecc35/websockets-17.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:76dd004f59115087c7b700474cb18f01325e37250032e19396c08ae41448e4b3", size = 217015, upload-time = "2026-08-26T14:55:45.194Z" }, { url = "https://files.pythonhosted.org/packages/a6/0d/098f23c4c858e5de9459ffc554fa07d5493fbcfca7f040b5800cf1cecc35/websockets-17.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:76dd004f59115087c7b700474cb18f01325e37250032e19396c08ae41448e4b3", size = 217015, upload-time = "2026-08-26T14:55:45.194Z" },
{ url = "https://files.pythonhosted.org/packages/13/86/bc1317b1a4d8c4688e2a7e564b5e004dab44c2534d7ca05de6ae9a863fca/websockets-17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:581fa678ef46f4277cc8491312468e582f8ad609dbab907ba6096a08c6a0ff98", size = 214692, upload-time = "2026-08-26T14:55:46.366Z" }, { url = "https://files.pythonhosted.org/packages/13/86/bc1317b1a4d8c4688e2a7e564b5e004dab44c2534d7ca05de6ae9a863fca/websockets-17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:581fa678ef46f4277cc8491312468e582f8ad609dbab907ba6096a08c6a0ff98", size = 214692, upload-time = "2026-08-26T14:55:46.366Z" },
@@ -2253,7 +2233,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/4e/f5/99857c3dd9676749f33e3668665a34ad6099505fb8d75eb084f49f7807a9/websockets-17.1-cp315-cp315t-win32.whl", hash = "sha256:f78a3ffb1994304db2c0c4588e4d1a518079b557054fa3bb985a6f5e50ff49a3", size = 217130, upload-time = "2026-08-26T14:58:20.037Z" }, { url = "https://files.pythonhosted.org/packages/4e/f5/99857c3dd9676749f33e3668665a34ad6099505fb8d75eb084f49f7807a9/websockets-17.1-cp315-cp315t-win32.whl", hash = "sha256:f78a3ffb1994304db2c0c4588e4d1a518079b557054fa3bb985a6f5e50ff49a3", size = 217130, upload-time = "2026-08-26T14:58:20.037Z" },
{ url = "https://files.pythonhosted.org/packages/2c/84/77599922ab441bfe61508f97dab2c71f8e114d31793993ea54011db16199/websockets-17.1-cp315-cp315t-win_amd64.whl", hash = "sha256:ad68c28a27246fed109a4409393d677b7e1388345cbbd2f5aee5c182d8506110", size = 217448, upload-time = "2026-08-26T14:58:21.382Z" }, { url = "https://files.pythonhosted.org/packages/2c/84/77599922ab441bfe61508f97dab2c71f8e114d31793993ea54011db16199/websockets-17.1-cp315-cp315t-win_amd64.whl", hash = "sha256:ad68c28a27246fed109a4409393d677b7e1388345cbbd2f5aee5c182d8506110", size = 217448, upload-time = "2026-08-26T14:58:21.382Z" },
{ url = "https://files.pythonhosted.org/packages/ce/3c/8b9a225b523f06a9389be81f1b0ab07c49bec6014742e6aa359c1f920f1f/websockets-17.1-cp315-cp315t-win_arm64.whl", hash = "sha256:e552e0037230ac16e5f568de7012041344d1b18c9feed30ec2891b8eba55af81", size = 217372, upload-time = "2026-08-26T14:58:22.807Z" }, { url = "https://files.pythonhosted.org/packages/ce/3c/8b9a225b523f06a9389be81f1b0ab07c49bec6014742e6aa359c1f920f1f/websockets-17.1-cp315-cp315t-win_arm64.whl", hash = "sha256:e552e0037230ac16e5f568de7012041344d1b18c9feed30ec2891b8eba55af81", size = 217372, upload-time = "2026-08-26T14:58:22.807Z" },
{ url = "https://files.pythonhosted.org/packages/41/63/23572870e01836a98346075b9e17a8bc24a6ddd9800a3204ceee58677f3c/websockets-17.1-py3-none-any.whl", hash = "sha256:f221081107b8c48184d99f7019604486376e7ef826037e70aad6b02540732c23", size = 211134, upload-time = "2026-08-26T17:25:31.397Z" },
] ]
[[package]] [[package]]
+7 -17
View File
@@ -1076,10 +1076,9 @@ class RecordingViewSet(
def _auth_get_original_url(self, request): def _auth_get_original_url(self, request):
""" """
Extracts and parses the original URL from the configured header. Extracts and parses the original URL from the "HTTP_X_ORIGINAL_URL" header.
Raises PermissionDenied if the header is missing. Raises PermissionDenied if the header is missing.
The original url is passed by the reverse proxy in the header named by the The original url is passed by nginx in the "HTTP_X_ORIGINAL_URL" header.
MEDIA_AUTH_ORIGINAL_URL_HEADER setting, which defaults to "HTTP_X_ORIGINAL_URL".
See corresponding ingress configuration in Helm chart and read about the See corresponding ingress configuration in Helm chart and read about the
nginx.ingress.kubernetes.io/auth-url annotation to understand how the Nginx ingress nginx.ingress.kubernetes.io/auth-url annotation to understand how the Nginx ingress
is configured to do this. is configured to do this.
@@ -1089,13 +1088,9 @@ class RecordingViewSet(
reasons. reasons.
""" """
# Extract the original URL from the request header # Extract the original URL from the request header
original_url = request.META.get(settings.MEDIA_AUTH_ORIGINAL_URL_HEADER) original_url = request.META.get("HTTP_X_ORIGINAL_URL")
if not original_url: if not original_url:
logger.warning( logger.warning("Missing HTTP_X_ORIGINAL_URL header in subrequest")
"Missing %s header in subrequest. Set MEDIA_AUTH_ORIGINAL_URL_HEADER "
"to the header your reverse proxy sends.",
settings.MEDIA_AUTH_ORIGINAL_URL_HEADER,
)
raise drf_exceptions.PermissionDenied() raise drf_exceptions.PermissionDenied()
logger.debug("Original url: '%s'", original_url) logger.debug("Original url: '%s'", original_url)
@@ -1420,8 +1415,7 @@ class FileViewSet(
Authorize access based on the original URL of an Nginx subrequest Authorize access based on the original URL of an Nginx subrequest
and user permissions. Returns a dictionary of URL parameters if authorized. and user permissions. Returns a dictionary of URL parameters if authorized.
The original url is passed by the reverse proxy in the header named by the The original url is passed by nginx in the "HTTP_X_ORIGINAL_URL" header.
MEDIA_AUTH_ORIGINAL_URL_HEADER setting, which defaults to "HTTP_X_ORIGINAL_URL".
See corresponding ingress configuration in Helm chart and read about the See corresponding ingress configuration in Helm chart and read about the
nginx.ingress.kubernetes.io/auth-url annotation to understand how the Nginx ingress nginx.ingress.kubernetes.io/auth-url annotation to understand how the Nginx ingress
is configured to do this. is configured to do this.
@@ -1440,13 +1434,9 @@ class FileViewSet(
- PermissionDenied if authorization fails. - PermissionDenied if authorization fails.
""" """
# Extract the original URL from the request header # Extract the original URL from the request header
original_url = request.META.get(settings.MEDIA_AUTH_ORIGINAL_URL_HEADER) original_url = request.META.get("HTTP_X_ORIGINAL_URL")
if not original_url: if not original_url:
logger.warning( logger.warning("Missing HTTP_X_ORIGINAL_URL header in subrequest")
"Missing %s header in subrequest. Set MEDIA_AUTH_ORIGINAL_URL_HEADER "
"to the header your reverse proxy sends.",
settings.MEDIA_AUTH_ORIGINAL_URL_HEADER,
)
raise drf_exceptions.PermissionDenied() raise drf_exceptions.PermissionDenied()
parsed_url = urlparse(original_url) parsed_url = urlparse(original_url)
+1 -19
View File
@@ -3,11 +3,7 @@
import contextlib import contextlib
from django.conf import settings from django.conf import settings
from django.core.exceptions import ( from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation
ImproperlyConfigured,
SuspiciousOperation,
ValidationError,
)
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from lasuite.oidc_login.backends import ( from lasuite.oidc_login.backends import (
@@ -21,7 +17,6 @@ from core.services.marketing import (
ContactData, ContactData,
get_marketing_service, get_marketing_service,
) )
from core.validators import sub_validator
class OIDCAuthenticationBackend(LaSuiteOIDCAuthenticationBackend): class OIDCAuthenticationBackend(LaSuiteOIDCAuthenticationBackend):
@@ -89,19 +84,6 @@ class OIDCAuthenticationBackend(LaSuiteOIDCAuthenticationBackend):
def get_existing_user(self, sub, email): def get_existing_user(self, sub, email):
"""Fetch existing user by sub or email.""" """Fetch existing user by sub or email."""
sub = str(sub)
try:
sub_validator(sub)
except ValidationError as err:
raise SuspiciousOperation(
"User info contained an invalid sub claim"
) from err
if len(sub) > 255:
raise SuspiciousOperation("User info contained an invalid sub claim")
try: try:
return User.objects.get(sub=sub) return User.objects.get(sub=sub)
except User.DoesNotExist: except User.DoesNotExist:
+1 -3
View File
@@ -8,8 +8,6 @@ import uuid
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
import core.validators
class Migration(migrations.Migration): class Migration(migrations.Migration):
@@ -43,7 +41,7 @@ class Migration(migrations.Migration):
('id', models.UUIDField(default=uuid.uuid4, editable=False, help_text='primary key for the record as UUID', primary_key=True, serialize=False, verbose_name='id')), ('id', models.UUIDField(default=uuid.uuid4, editable=False, help_text='primary key for the record as UUID', primary_key=True, serialize=False, verbose_name='id')),
('created_at', models.DateTimeField(auto_now_add=True, help_text='date and time at which a record was created', verbose_name='created on')), ('created_at', models.DateTimeField(auto_now_add=True, help_text='date and time at which a record was created', verbose_name='created on')),
('updated_at', models.DateTimeField(auto_now=True, help_text='date and time at which a record was last updated', verbose_name='updated on')), ('updated_at', models.DateTimeField(auto_now=True, help_text='date and time at which a record was last updated', verbose_name='updated on')),
('sub', models.CharField(blank=True, help_text='Optional for pending users; required upon account activation. 255 characters or fewer. Printable ASCII characters only.', max_length=255, null=True, unique=True, validators=[core.validators.sub_validator], verbose_name='sub')), ('sub', models.CharField(blank=True, help_text='Optional for pending users; required upon account activation. 255 characters or fewer. Letters, numbers, and @/./+/-/_ characters only.', max_length=255, null=True, unique=True, validators=[django.core.validators.RegexValidator(message='Enter a valid sub. This value may contain only letters, numbers, and @/./+/-/_ characters.', regex='^[\\w.@+-]+\\Z')], verbose_name='sub')),
('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='identity email address')), ('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='identity email address')),
('admin_email', models.EmailField(blank=True, max_length=254, null=True, unique=True, verbose_name='admin email address')), ('admin_email', models.EmailField(blank=True, max_length=254, null=True, unique=True, verbose_name='admin email address')),
('language', models.CharField(choices=settings.LANGUAGES, default=settings.LANGUAGE_CODE, help_text='The language in which the user wants to see the interface.', max_length=10, verbose_name='language')), ('language', models.CharField(choices=settings.LANGUAGES, default=settings.LANGUAGE_CODE, help_text='The language in which the user wants to see the interface.', max_length=10, verbose_name='language')),
+9 -2
View File
@@ -27,7 +27,6 @@ from timezone_field import TimeZoneField
from . import fields, utils from . import fields, utils
from .recording.enums import FileExtension from .recording.enums import FileExtension
from .validators import sub_validator
logger = getLogger(__name__) logger = getLogger(__name__)
@@ -146,11 +145,19 @@ class BaseModel(models.Model):
class User(AbstractBaseUser, BaseModel, auth_models.PermissionsMixin): class User(AbstractBaseUser, BaseModel, auth_models.PermissionsMixin):
"""User model to work with OIDC only authentication.""" """User model to work with OIDC only authentication."""
sub_validator = validators.RegexValidator(
regex=r"^[\w.@+-]+\Z",
message=_(
"Enter a valid sub. This value may contain only letters, "
"numbers, and @/./+/-/_ characters."
),
)
sub = models.CharField( sub = models.CharField(
_("sub"), _("sub"),
help_text=_( help_text=_(
"Optional for pending users; required upon account activation. " "Optional for pending users; required upon account activation. "
"255 characters or fewer. Printable ASCII characters only." "255 characters or fewer. Letters, numbers, and @/./+/-/_ characters only."
), ),
max_length=255, max_length=255,
unique=True, unique=True,
@@ -40,111 +40,6 @@ def test_authentication_getter_existing_user(monkeypatch):
assert user == db_user assert user == db_user
@pytest.mark.parametrize(
"sub",
[
# NUL (U+0000) passes str.isascii() but PostgreSQL text fields
# cannot store or compare it (DataError)
"auth0|abc\x00def",
# lone surrogates cannot be encoded to UTF-8 for the DB lookup
# (UnicodeEncodeError), which runs before any model validation
"bad\ud800sub",
# plainly invalid subs would otherwise escape as ValidationError
# on user creation, which mozilla-django-oidc does not catch
"\u00e9milie",
"a" * 256,
# ASCII control characters are rejected by policy
"tab\tsub",
"del\x7fsub",
],
)
def test_authentication_getter_invalid_sub_rejected_cleanly(monkeypatch, sub):
"""
Subs that can never be persisted should be rejected with
SuspiciousOperation (turned into a clean authentication failure by
mozilla-django-oidc) instead of leaking DataError, UnicodeEncodeError
or ValidationError as a server error.
"""
klass = OIDCAuthenticationBackend()
def get_userinfo_mocked(*args):
return {"sub": sub, "email": "john@example.com"}
monkeypatch.setattr(OIDCAuthenticationBackend, "get_userinfo", get_userinfo_mocked)
with pytest.raises(
SuspiciousOperation,
match="User info contained an invalid sub claim",
):
klass.get_or_create_user(access_token="test-token", id_token=None, payload=None)
assert models.User.objects.exists() is False
def test_authentication_getter_numeric_sub(monkeypatch):
"""
Some providers serialize the sub as a JSON number. It should keep working
(CharField coerces it to a string on save) and must not crash the early
sub checks in get_existing_user.
"""
klass = OIDCAuthenticationBackend()
def get_userinfo_mocked(*args):
return {"sub": 12345, "email": "john@example.com"}
monkeypatch.setattr(OIDCAuthenticationBackend, "get_userinfo", get_userinfo_mocked)
user = klass.get_or_create_user(
access_token="test-token", id_token=None, payload=None
)
assert user.sub == "12345"
assert models.User.objects.count() == 1
def test_authentication_getter_new_user_auth0_pipe_sub(monkeypatch):
"""
A first login with an Auth0-style sub containing a pipe ("provider|user-id")
should create the user instead of raising a ValidationError.
Regression test for https://github.com/suitenumerique/meet/issues/[XXX].
"""
klass = OIDCAuthenticationBackend()
def get_userinfo_mocked(*args):
return {"sub": "auth0|644c0bc8f1874ef6d339fb34", "email": "john@example.com"}
monkeypatch.setattr(OIDCAuthenticationBackend, "get_userinfo", get_userinfo_mocked)
user = klass.get_or_create_user(
access_token="test-token", id_token=None, payload=None
)
assert user.sub == "auth0|644c0bc8f1874ef6d339fb34"
assert user.email == "john@example.com"
assert models.User.objects.count() == 1
def test_authentication_getter_existing_user_auth0_pipe_sub(monkeypatch):
"""
A returning user with an Auth0-style pipe sub should be matched by sub,
not duplicated or rejected.
"""
klass = OIDCAuthenticationBackend()
db_user = UserFactory(sub="auth0|644c0bc8f1874ef6d339fb34")
def get_userinfo_mocked(*args):
return {"sub": db_user.sub}
monkeypatch.setattr(OIDCAuthenticationBackend, "get_userinfo", get_userinfo_mocked)
user = klass.get_or_create_user(
access_token="test-token", id_token=None, payload=None
)
assert user == db_user
assert models.User.objects.count() == 1
def test_authentication_getter_new_user_no_email(monkeypatch): def test_authentication_getter_new_user_no_email(monkeypatch):
""" """
If no user matches, a user should be created. If no user matches, a user should be created.
@@ -7,7 +7,6 @@ from urllib.parse import quote, urlparse
from django.conf import settings from django.conf import settings
from django.core.files.storage import default_storage from django.core.files.storage import default_storage
from django.test import override_settings
from django.utils import timezone from django.utils import timezone
import pytest import pytest
@@ -144,59 +143,3 @@ def test_api_files_media_auth_own_file_deleted():
) )
assert response.status_code == 403 assert response.status_code == 403
@override_settings(MEDIA_AUTH_ORIGINAL_URL_HEADER="HTTP_X_FORWARDED_URI")
def test_api_files_media_auth_custom_original_url_header():
"""
Authorization should honour the configured original-url header.
Covers the attachment subrequest path, which resolves the header separately
from the recording one. Reverse proxies other than nginx-ingress use
different headers: Traefik's ForwardAuth sends X-Forwarded-Uri and cannot
emit X-Original-URL at all.
"""
user = factories.UserFactory()
file = factories.FileFactory(
type=models.FileTypeChoices.BACKGROUND_IMAGE,
update_upload_state=models.FileUploadStateChoices.READY,
creator=user,
)
client = APIClient()
client.force_login(user)
default_storage.save(file.file_key, BytesIO(b"my prose"))
original_url = f"http://localhost/media/{file.file_key:s}"
response = client.get(
"/api/v1.0/files/media-auth/", HTTP_X_FORWARDED_URI=original_url
)
assert response.status_code == 200
assert "AWS4-HMAC-SHA256 Credential=" in response["Authorization"]
@override_settings(MEDIA_AUTH_ORIGINAL_URL_HEADER="HTTP_X_FORWARDED_URI")
def test_api_files_media_auth_default_header_ignored_when_reconfigured():
"""
Only the configured header should be honoured, never a hardcoded fallback.
"""
user = factories.UserFactory()
file = factories.FileFactory(
type=models.FileTypeChoices.BACKGROUND_IMAGE,
update_upload_state=models.FileUploadStateChoices.READY,
creator=user,
)
client = APIClient()
client.force_login(user)
original_url = f"http://localhost/media/{file.file_key:s}"
response = client.get(
"/api/v1.0/files/media-auth/", HTTP_X_ORIGINAL_URL=original_url
)
assert response.status_code == 403
@@ -8,7 +8,6 @@ from uuid import uuid4
from django.conf import settings from django.conf import settings
from django.core.files.storage import default_storage from django.core.files.storage import default_storage
from django.test import override_settings
from django.utils import timezone from django.utils import timezone
import pytest import pytest
@@ -283,63 +282,3 @@ def test_api_recordings_media_auth_success_administrator(mode):
timeout=1, timeout=1,
) )
assert response.content.decode("utf-8") == "my prose" assert response.content.decode("utf-8") == "my prose"
def test_api_recordings_media_auth_missing_header():
"""
Test that a subrequest without the configured original-url header is rejected.
"""
user = UserFactory()
client = APIClient()
client.force_login(user)
response = client.get("/api/v1.0/recordings/media-auth/")
assert response.status_code == 403
@override_settings(MEDIA_AUTH_ORIGINAL_URL_HEADER="HTTP_X_FORWARDED_URI")
def test_api_recordings_media_auth_custom_original_url_header():
"""
Test that the header carrying the original URL can be configured.
Reverse proxies other than nginx-ingress use different headers: Traefik's
ForwardAuth sends X-Forwarded-Uri and cannot emit X-Original-URL at all.
"""
user = UserFactory()
client = APIClient()
client.force_login(user)
original_url = f"http://localhost/media/recordings/{uuid4()!s}.mp4"
response = client.get(
"/api/v1.0/recordings/media-auth/", HTTP_X_FORWARDED_URI=original_url
)
# The header was read and parsed: we get as far as looking the recording up,
# rather than being rejected for a missing header.
assert response.status_code == 404
@override_settings(MEDIA_AUTH_ORIGINAL_URL_HEADER="HTTP_X_FORWARDED_URI")
def test_api_recordings_media_auth_default_header_ignored_when_reconfigured():
"""
Test that only the configured header is honoured.
Guards against the header being read from a hardcoded name in parallel with
the setting.
"""
user = UserFactory()
client = APIClient()
client.force_login(user)
original_url = f"http://localhost/media/recordings/{uuid4()!s}.mp4"
response = client.get(
"/api/v1.0/recordings/media-auth/", HTTP_X_ORIGINAL_URL=original_url
)
assert response.status_code == 403
@@ -26,64 +26,6 @@ def test_models_users_id_unique():
factories.UserFactory(id=user.id) factories.UserFactory(id=user.id)
@pytest.mark.parametrize(
"sub,is_valid",
[
# cases from suitenumerique/docs PR #1295 (same validator)
("valid_sub.@+-:=/", True),
("invalid süb", False),
(12345, True),
# Auth0 emits "provider|user-id" subject identifiers
("auth0|644c0bc8f1874ef6d339fb34", True),
("google-oauth2|103547991597142817347", True),
# Keycloak-style UUID
("f:550e8400-e29b-41d4-a716-446655440000:jdoe", True),
# base64/URN-style identifiers
("dGVzdC1zdWItdmFsdWU=", True),
("urn:example:user/42", True),
# legacy format still accepted
("user@example.com", True),
# space (U+0020) is printable ASCII and remains allowed
("sub with space", True),
# non-ASCII values are rejected
("émilie", False),
# ASCII control characters (U+0000-U+001F, U+007F) are rejected:
# NUL passes isascii() but cannot be stored in PostgreSQL text
# fields, and the others invite log injection and interop issues
("nul\x00sub", False),
("\x00", False),
("tab\tsub", False),
("newline\nsub", False),
("del\x7fsub", False),
],
)
def test_models_users_sub_validator(sub, is_valid):
"""
The "sub" field should accept any ASCII string as required by
OpenID Connect Core 1.0 §2 and RFC 7519 §4.1.2, and reject non-ASCII values.
"""
user = factories.UserFactory()
user.sub = sub
if is_valid:
user.full_clean()
else:
with pytest.raises(
ValidationError,
match="Enter a valid sub. This value should be printable ASCII only.",
):
user.full_clean()
def test_models_users_sub_max_length():
"""The "sub" field should enforce the 255 ASCII characters limit of OIDC Core 1.0 §2."""
user = factories.UserFactory(sub="a" * 255)
assert user.sub == "a" * 255
user.sub = "a" * 256
with pytest.raises(ValidationError, match="at most 255 characters"):
user.full_clean()
def test_models_users_send_mail_main_existing(): def test_models_users_send_mail_main_existing():
"""The "email_user' method should send mail to the user's email address.""" """The "email_user' method should send mail to the user's email address."""
user = factories.UserFactory() user = factories.UserFactory()
-23
View File
@@ -1,23 +0,0 @@
"""Custom validators for the core app."""
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
def sub_validator(value):
"""Validate that the sub is printable ASCII only.
OpenID Connect Core 1.0 (section 2) allows any ASCII (RFC 20) string of
at most 255 characters, so no character whitelist is applied: providers
legitimately emit "|" (Auth0), ":" (Keycloak), "=", "/", etc. As a
deliberate hardening beyond the spec, ASCII control characters
(U+0000-U+001F and U+007F) are rejected: no known provider emits them,
NUL cannot be stored in PostgreSQL text fields, and the others invite
log-injection and interoperability issues. For str values,
``isprintable()`` is false exactly for those control characters, while
space (U+0020) remains allowed.
"""
if not value.isascii() or not value.isprintable():
raise ValidationError(
_("Enter a valid sub. This value should be printable ASCII only.")
)
+159 -186
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-02 22:52+0000\n" "POT-Creation-Date: 2026-07-02 10:47+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -51,11 +51,11 @@ msgstr ""
msgid "File preview" msgid "File preview"
msgstr "" msgstr ""
#: core/admin.py:300 core/admin.py:450 #: core/admin.py:300 core/admin.py:443
msgid "No owner" msgid "No owner"
msgstr "Kein Eigentümer" msgstr "Kein Eigentümer"
#: core/admin.py:303 core/admin.py:453 #: core/admin.py:303 core/admin.py:446
msgid "Multiple owners" msgid "Multiple owners"
msgstr "Mehrere Eigentümer" msgstr "Mehrere Eigentümer"
@@ -98,11 +98,11 @@ msgstr "%(count)s Aufnahme(n) erfolgreich als Fehler beim Stoppen markiert
msgid "Skipped %(count)s recording(s) with an ineligible status." msgid "Skipped %(count)s recording(s) with an ineligible status."
msgstr "%(count)s abgelaufene Aufnahme(n) übersprungen." msgstr "%(count)s abgelaufene Aufnahme(n) übersprungen."
#: core/admin.py:517 #: core/admin.py:510
msgid "No scopes" msgid "No scopes"
msgstr "Keine Scopes" msgstr "Keine Scopes"
#: core/admin.py:519 #: core/admin.py:512
msgid "Scopes" msgid "Scopes"
msgstr "Scopes" msgstr "Scopes"
@@ -110,201 +110,185 @@ msgstr "Scopes"
msgid "Creator is me" msgid "Creator is me"
msgstr "Ersteller bin ich" msgstr "Ersteller bin ich"
#: core/api/serializers.py:108 #: core/api/serializers.py:89
msgid "You must be administrator or owner of a room to add accesses to it." msgid "You must be administrator or owner of a room to add accesses to it."
msgstr "" msgstr ""
"Sie müssen Administrator oder Eigentümer eines Raums sein, um Zugriffe " "Sie müssen Administrator oder Eigentümer eines Raums sein, um Zugriffe "
"hinzuzufügen." "hinzuzufügen."
#: core/api/serializers.py:560 #: core/api/serializers.py:534
msgid "This file extension is not allowed." msgid "This file extension is not allowed."
msgstr "Diese Dateiendung ist nicht erlaubt." msgstr "Diese Dateiendung ist nicht erlaubt."
#: core/api/viewsets.py:1268 #: core/api/viewsets.py:1222
msgid "You have reached the maximum number of files for this type." msgid "You have reached the maximum number of files for this type."
msgstr "Sie haben die maximale Anzahl an Dateien dieses Typs erreicht." msgstr "Sie haben die maximale Anzahl an Dateien dieses Typs erreicht."
#: core/models.py:38 #: core/models.py:37
msgid "Member" msgid "Member"
msgstr "Mitglied" msgstr "Mitglied"
#: core/models.py:39 #: core/models.py:38
msgid "Administrator" msgid "Administrator"
msgstr "Administrator" msgstr "Administrator"
#: core/models.py:40 #: core/models.py:39
msgid "Owner" msgid "Owner"
msgstr "Eigentümer" msgstr "Eigentümer"
#: core/models.py:56 #: core/models.py:55
msgid "Initiated" msgid "Initiated"
msgstr "Gestartet" msgstr "Gestartet"
#: core/models.py:57 #: core/models.py:56
msgid "Active" msgid "Active"
msgstr "Aktiv" msgstr "Aktiv"
#: core/models.py:58 #: core/models.py:57
msgid "Stopped" msgid "Stopped"
msgstr "Beendet" msgstr "Beendet"
#: core/models.py:59 #: core/models.py:58
msgid "Saved" msgid "Saved"
msgstr "Gespeichert" msgstr "Gespeichert"
#: core/models.py:60 #: core/models.py:59
msgid "Aborted" msgid "Aborted"
msgstr "Abgebrochen" msgstr "Abgebrochen"
#: core/models.py:61 #: core/models.py:60
msgid "Failed to Start" msgid "Failed to Start"
msgstr "Start fehlgeschlagen" msgstr "Start fehlgeschlagen"
#: core/models.py:62 #: core/models.py:61
msgid "Failed to Stop" msgid "Failed to Stop"
msgstr "Stopp fehlgeschlagen" msgstr "Stopp fehlgeschlagen"
#: core/models.py:63 #: core/models.py:62
msgid "Notification succeeded" msgid "Notification succeeded"
msgstr "Benachrichtigung erfolgreich" msgstr "Benachrichtigung erfolgreich"
#: core/models.py:66 #: core/models.py:65
msgid "External process successful" msgid "External process successful"
msgstr "Externer Prozess erfolgreich" msgstr "Externer Prozess erfolgreich"
#: core/models.py:68 #: core/models.py:67
msgid "External process failed" msgid "External process failed"
msgstr "Externer Prozess fehlgeschlagen" msgstr "Externer Prozess fehlgeschlagen"
#: core/models.py:97 #: core/models.py:96
msgid "SCREEN_RECORDING" msgid "SCREEN_RECORDING"
msgstr "BILDSCHIRMAUFZEICHNUNG" msgstr "BILDSCHIRMAUFZEICHNUNG"
#: core/models.py:98 #: core/models.py:97
msgid "TRANSCRIPT" msgid "TRANSCRIPT"
msgstr "TRANSKRIPT" msgstr "TRANSKRIPT"
#: core/models.py:104 #: core/models.py:103
msgid "Public Access" msgid "Public Access"
msgstr "Öffentlicher Zugriff" msgstr "Öffentlicher Zugriff"
#: core/models.py:105 #: core/models.py:104
msgid "Trusted Access" msgid "Trusted Access"
msgstr "Vertrauenswürdiger Zugriff" msgstr "Vertrauenswürdiger Zugriff"
#: core/models.py:106 #: core/models.py:105
msgid "Restricted Access" msgid "Restricted Access"
msgstr "Eingeschränkter Zugriff" msgstr "Eingeschränkter Zugriff"
#: core/models.py:118 #: core/models.py:117
msgid "id" msgid "id"
msgstr "ID" msgstr "ID"
#: core/models.py:119 #: core/models.py:118
msgid "primary key for the record as UUID" msgid "primary key for the record as UUID"
msgstr "Primärschlüssel des Eintrags als UUID" msgstr "Primärschlüssel des Eintrags als UUID"
#: core/models.py:125 #: core/models.py:124
msgid "created on" msgid "created on"
msgstr "erstellt am" msgstr "erstellt am"
#: core/models.py:126 #: core/models.py:125
msgid "date and time at which a record was created" msgid "date and time at which a record was created"
msgstr "Datum und Uhrzeit der Erstellung eines Eintrags" msgstr "Datum und Uhrzeit der Erstellung eines Eintrags"
#: core/models.py:131 #: core/models.py:130
msgid "updated on" msgid "updated on"
msgstr "aktualisiert am" msgstr "aktualisiert am"
#: core/models.py:132 #: core/models.py:131
msgid "date and time at which a record was last updated" msgid "date and time at which a record was last updated"
msgstr "Datum und Uhrzeit der letzten Aktualisierung eines Eintrags" msgstr "Datum und Uhrzeit der letzten Aktualisierung eines Eintrags"
#: core/models.py:150 #: core/models.py:151
msgid ""
"Enter a valid sub. This value may contain only letters, numbers, and @/./+/-/"
"_ characters."
msgstr ""
"Geben Sie einen gültigen Sub ein. Dieser Wert darf nur Buchstaben, Zahlen "
"und die Zeichen @/./+/-/_ enthalten."
#: core/models.py:157
msgid "sub" msgid "sub"
msgstr "Sub" msgstr "Sub"
#: core/models.py:152 #: core/models.py:159
msgid "" msgid ""
"Optional for pending users; required upon account activation. 255 characters " "Optional for pending users; required upon account activation. 255 characters "
"or fewer. Printable ASCII characters only." "or fewer. Letters, numbers, and @/./+/-/_ characters only."
msgstr "" msgstr ""
"Optional für ausstehende Benutzer; erforderlich nach Kontoaktivierung. " "Optional für ausstehende Benutzer; erforderlich nach Kontoaktivierung. "
"Maximal 255 Zeichen. Nur druckbare ASCII-Zeichen erlaubt." "Maximal 255 Zeichen. Nur Buchstaben, Zahlen und @/./+/-/_ Zeichen erlaubt."
#: core/validators.py:22 #: core/models.py:168
msgid "Enter a valid sub. This value should be printable ASCII only."
msgstr "Geben Sie einen gültigen sub ein. Dieser Wert darf nur druckbare ASCII-Zeichen enthalten."
#: core/models.py:161
msgid "identity email address" msgid "identity email address"
msgstr "Identitäts-E-Mail-Adresse" msgstr "Identitäts-E-Mail-Adresse"
#: core/models.py:166 #: core/models.py:173
msgid "admin email address" msgid "admin email address"
msgstr "Administrator-E-Mail-Adresse" msgstr "Administrator-E-Mail-Adresse"
#: core/models.py:168 #: core/models.py:175
msgid "full name" msgid "full name"
msgstr "Vollständiger Name" msgstr "Vollständiger Name"
#: core/models.py:170 #: core/models.py:177
msgid "short name" msgid "short name"
msgstr "Kurzname" msgstr "Kurzname"
#: core/models.py:176 #: core/models.py:183
msgid "language" msgid "language"
msgstr "Sprache" msgstr "Sprache"
#: core/models.py:177 #: core/models.py:184
msgid "The language in which the user wants to see the interface." msgid "The language in which the user wants to see the interface."
msgstr "Die Sprache, in der der Benutzer die Oberfläche sehen möchte." msgstr "Die Sprache, in der der Benutzer die Oberfläche sehen möchte."
#: core/models.py:183 #: core/models.py:190
msgid "The timezone in which the user wants to see times." msgid "The timezone in which the user wants to see times."
msgstr "Die Zeitzone, in der der Benutzer die Zeiten sehen möchte." msgstr "Die Zeitzone, in der der Benutzer die Zeiten sehen möchte."
#: core/models.py:190 #: core/models.py:193
msgid "default room access level"
msgstr ""
#: core/models.py:192
msgid ""
"Access level applied by default to new rooms created by this user. When "
"empty, the instance default is used."
msgstr ""
#: core/models.py:199
#, fuzzy
#| msgid "Visio room configuration"
msgid "default room configuration"
msgstr "Visio-Raumkonfiguration"
#: core/models.py:201
msgid "Configurations applied by default to new rooms created by this user."
msgstr ""
#: core/models.py:205
msgid "device" msgid "device"
msgstr "Gerät" msgstr "Gerät"
#: core/models.py:207 #: core/models.py:195
msgid "Whether the user is a device or a real user." msgid "Whether the user is a device or a real user."
msgstr "Ob es sich um ein Gerät oder einen echten Benutzer handelt." msgstr "Ob es sich um ein Gerät oder einen echten Benutzer handelt."
#: core/models.py:210 #: core/models.py:198
msgid "staff status" msgid "staff status"
msgstr "Mitarbeiterstatus" msgstr "Mitarbeiterstatus"
#: core/models.py:212 #: core/models.py:200
msgid "Whether the user can log into this admin site." msgid "Whether the user can log into this admin site."
msgstr "Ob der Benutzer sich bei dieser Admin-Seite anmelden kann." msgstr "Ob der Benutzer sich bei dieser Admin-Seite anmelden kann."
#: core/models.py:215 #: core/models.py:203
msgid "active" msgid "active"
msgstr "aktiv" msgstr "aktiv"
#: core/models.py:218 #: core/models.py:206
msgid "" msgid ""
"Whether this user should be treated as active. Unselect this instead of " "Whether this user should be treated as active. Unselect this instead of "
"deleting accounts." "deleting accounts."
@@ -312,66 +296,66 @@ msgstr ""
"Ob dieser Benutzer als aktiv behandelt werden soll. Deaktivieren Sie dies " "Ob dieser Benutzer als aktiv behandelt werden soll. Deaktivieren Sie dies "
"anstelle des Löschens des Kontos." "anstelle des Löschens des Kontos."
#: core/models.py:231 #: core/models.py:219
msgid "user" msgid "user"
msgstr "Benutzer" msgstr "Benutzer"
#: core/models.py:232 #: core/models.py:220
msgid "users" msgid "users"
msgstr "Benutzer" msgstr "Benutzer"
#: core/models.py:298 #: core/models.py:286
msgid "Resource" msgid "Resource"
msgstr "Ressource" msgstr "Ressource"
#: core/models.py:299 #: core/models.py:287
msgid "Resources" msgid "Resources"
msgstr "Ressourcen" msgstr "Ressourcen"
#: core/models.py:357 #: core/models.py:345
msgid "Resource access" msgid "Resource access"
msgstr "Ressourcenzugriff" msgstr "Ressourcenzugriff"
#: core/models.py:358 #: core/models.py:346
msgid "Resource accesses" msgid "Resource accesses"
msgstr "Ressourcenzugriffe" msgstr "Ressourcenzugriffe"
#: core/models.py:364 #: core/models.py:352
msgid "Resource access with this User and Resource already exists." msgid "Resource access with this User and Resource already exists."
msgstr "" msgstr ""
"Ein Ressourcenzugriff mit diesem Benutzer und dieser Ressource existiert " "Ein Ressourcenzugriff mit diesem Benutzer und dieser Ressource existiert "
"bereits." "bereits."
#: core/models.py:421 #: core/models.py:409
msgid "Visio room configuration" msgid "Visio room configuration"
msgstr "Visio-Raumkonfiguration" msgstr "Visio-Raumkonfiguration"
#: core/models.py:422 #: core/models.py:410
msgid "Values for Visio parameters to configure the room." msgid "Values for Visio parameters to configure the room."
msgstr "Werte für Visio-Parameter zur Konfiguration des Raums." msgstr "Werte für Visio-Parameter zur Konfiguration des Raums."
#: core/models.py:429 #: core/models.py:417
msgid "Room PIN code" msgid "Room PIN code"
msgstr "PIN-Code für den Raum" msgstr "PIN-Code für den Raum"
#: core/models.py:430 #: core/models.py:418
msgid "Unique n-digit code that identifies this room in telephony mode." msgid "Unique n-digit code that identifies this room in telephony mode."
msgstr "" msgstr ""
"Eindeutiger n-stelliger Code, der diesen Raum im Telephonmodus identifiziert." "Eindeutiger n-stelliger Code, der diesen Raum im Telephonmodus identifiziert."
#: core/models.py:436 core/models.py:597 #: core/models.py:424 core/models.py:578
msgid "Room" msgid "Room"
msgstr "Raum" msgstr "Raum"
#: core/models.py:437 #: core/models.py:425
msgid "Rooms" msgid "Rooms"
msgstr "Räume" msgstr "Räume"
#: core/models.py:608 #: core/models.py:589
msgid "Worker ID" msgid "Worker ID"
msgstr "Worker-ID" msgstr "Worker-ID"
#: core/models.py:610 #: core/models.py:591
msgid "" msgid ""
"Enter an identifier for the worker recording.This ID is retained even when " "Enter an identifier for the worker recording.This ID is retained even when "
"the worker stops, allowing for easy tracking." "the worker stops, allowing for easy tracking."
@@ -380,153 +364,153 @@ msgstr ""
"erhalten, auch wenn der Worker stoppt, was ein einfaches Nachverfolgen " "erhalten, auch wenn der Worker stoppt, was ein einfaches Nachverfolgen "
"ermöglicht." "ermöglicht."
#: core/models.py:618 #: core/models.py:599
msgid "Recording mode" msgid "Recording mode"
msgstr "Aufzeichnungsmodus" msgstr "Aufzeichnungsmodus"
#: core/models.py:619 #: core/models.py:600
msgid "Defines the mode of recording being called." msgid "Defines the mode of recording being called."
msgstr "Definiert den aufgerufenen Aufzeichnungsmodus." msgstr "Definiert den aufgerufenen Aufzeichnungsmodus."
#: core/models.py:624 core/models.py:625 #: core/models.py:605 core/models.py:606
msgid "Recording options" msgid "Recording options"
msgstr "Aufnahmeoptionen" msgstr "Aufnahmeoptionen"
#: core/models.py:632 #: core/models.py:613
msgid "External Process ID" msgid "External Process ID"
msgstr "External Process ID" msgstr "External Process ID"
#: core/models.py:633 #: core/models.py:614
msgid "ID of the external process associated with the recording." msgid "ID of the external process associated with the recording."
msgstr "ID des externen Prozesses, der mit der Aufzeichnung verknüpft ist" msgstr "ID des externen Prozesses, der mit der Aufzeichnung verknüpft ist"
#: core/models.py:639 #: core/models.py:620
msgid "Recording" msgid "Recording"
msgstr "Aufzeichnung" msgstr "Aufzeichnung"
#: core/models.py:640 #: core/models.py:621
msgid "Recordings" msgid "Recordings"
msgstr "Aufzeichnungen" msgstr "Aufzeichnungen"
#: core/models.py:750 #: core/models.py:731
msgid "Recording/user relation" msgid "Recording/user relation"
msgstr "Beziehung Aufzeichnung/Benutzer" msgstr "Beziehung Aufzeichnung/Benutzer"
#: core/models.py:751 #: core/models.py:732
msgid "Recording/user relations" msgid "Recording/user relations"
msgstr "Beziehungen Aufzeichnung/Benutzer" msgstr "Beziehungen Aufzeichnung/Benutzer"
#: core/models.py:757 #: core/models.py:738
msgid "This user is already in this recording." msgid "This user is already in this recording."
msgstr "Dieser Benutzer ist bereits Teil dieser Aufzeichnung." msgstr "Dieser Benutzer ist bereits Teil dieser Aufzeichnung."
#: core/models.py:763 #: core/models.py:744
msgid "This team is already in this recording." msgid "This team is already in this recording."
msgstr "Dieses Team ist bereits Teil dieser Aufzeichnung." msgstr "Dieses Team ist bereits Teil dieser Aufzeichnung."
#: core/models.py:769 #: core/models.py:750
msgid "Either user or team must be set, not both." msgid "Either user or team must be set, not both."
msgstr "Entweder Benutzer oder Team muss festgelegt werden, nicht beides." msgstr "Entweder Benutzer oder Team muss festgelegt werden, nicht beides."
#: core/models.py:786 #: core/models.py:767
msgid "Create rooms" msgid "Create rooms"
msgstr "Räume erstellen" msgstr "Räume erstellen"
#: core/models.py:787 #: core/models.py:768
msgid "List rooms" msgid "List rooms"
msgstr "Räume auflisten" msgstr "Räume auflisten"
#: core/models.py:788 #: core/models.py:769
msgid "Retrieve room details" msgid "Retrieve room details"
msgstr "Raumdetails abrufen" msgstr "Raumdetails abrufen"
#: core/models.py:789 #: core/models.py:770
msgid "Update rooms" msgid "Update rooms"
msgstr "Räume aktualisieren" msgstr "Räume aktualisieren"
#: core/models.py:790 #: core/models.py:771
msgid "Delete rooms" msgid "Delete rooms"
msgstr "Räume löschen" msgstr "Räume löschen"
#: core/models.py:803 #: core/models.py:784
msgid "Application name" msgid "Application name"
msgstr "Anwendungsname" msgstr "Anwendungsname"
#: core/models.py:804 #: core/models.py:785
msgid "Descriptive name for this application." msgid "Descriptive name for this application."
msgstr "Beschreibender Name für diese Anwendung." msgstr "Beschreibender Name für diese Anwendung."
#: core/models.py:814 #: core/models.py:795
msgid "Hashed on Save. Copy it now if this is a new secret." msgid "Hashed on Save. Copy it now if this is a new secret."
msgstr "" msgstr ""
"Beim Speichern gehasht. Jetzt kopieren, wenn dies ein neues Geheimnis ist." "Beim Speichern gehasht. Jetzt kopieren, wenn dies ein neues Geheimnis ist."
#: core/models.py:825 #: core/models.py:806
msgid "Application" msgid "Application"
msgstr "Anwendung" msgstr "Anwendung"
#: core/models.py:826 #: core/models.py:807
msgid "Applications" msgid "Applications"
msgstr "Anwendungen" msgstr "Anwendungen"
#: core/models.py:849 #: core/models.py:830
msgid "Enter a valid domain" msgid "Enter a valid domain"
msgstr "Geben Sie eine gültige Domain ein" msgstr "Geben Sie eine gültige Domain ein"
#: core/models.py:852 #: core/models.py:833
msgid "Domain" msgid "Domain"
msgstr "Domain" msgstr "Domain"
#: core/models.py:853 #: core/models.py:834
msgid "Email domain this application can act on behalf of." msgid "Email domain this application can act on behalf of."
msgstr "E-Mail-Domain, im Namen der diese Anwendung handeln kann." msgstr "E-Mail-Domain, im Namen der diese Anwendung handeln kann."
#: core/models.py:865 #: core/models.py:846
msgid "Application domain" msgid "Application domain"
msgstr "Anwendungsdomain" msgstr "Anwendungsdomain"
#: core/models.py:866 #: core/models.py:847
msgid "Application domains" msgid "Application domains"
msgstr "Anwendungsdomains" msgstr "Anwendungsdomains"
#: core/models.py:884 #: core/models.py:865
msgid "Pending" msgid "Pending"
msgstr "Ausstehend" msgstr "Ausstehend"
#: core/models.py:885 #: core/models.py:866
msgid "Analyzing" msgid "Analyzing"
msgstr "" msgstr ""
#: core/models.py:892 #: core/models.py:873
msgid "Ready" msgid "Ready"
msgstr "Bereit" msgstr "Bereit"
#: core/models.py:898 #: core/models.py:879
msgid "Background image" msgid "Background image"
msgstr "Hintergrundbild" msgstr "Hintergrundbild"
#: core/models.py:910 #: core/models.py:891
msgid "title" msgid "title"
msgstr "Titel" msgstr "Titel"
#: core/models.py:934 #: core/models.py:915
msgid "Malware detection info when the analysis status is unsafe." msgid "Malware detection info when the analysis status is unsafe."
msgstr "" msgstr ""
"Informationen zur Malware-Erkennung, wenn der Analyse-Status unsicher ist." "Informationen zur Malware-Erkennung, wenn der Analyse-Status unsicher ist."
#: core/models.py:939 #: core/models.py:920
msgid "File" msgid "File"
msgstr "Datei" msgstr "Datei"
#: core/models.py:940 #: core/models.py:921
msgid "Files" msgid "Files"
msgstr "Dateien" msgstr "Dateien"
#: core/models.py:1060 #: core/models.py:1041
msgid "This file is already hard deleted." msgid "This file is already hard deleted."
msgstr "Diese Datei wurde bereits endgültig gelöscht." msgstr "Diese Datei wurde bereits endgültig gelöscht."
#: core/models.py:1070 #: core/models.py:1051
#, fuzzy #, fuzzy
#| msgid "To hard delete a file, it must first be soft deleted." #| msgid "To hard delete a file, it must first be soft deleted."
msgid "To hard delete a file, it must first be soft deleted." msgid "To hard delete a file, it must first be soft deleted."
@@ -534,15 +518,15 @@ msgstr ""
"Um eine Datei endgültig zu löschen, muss sie zuvor weich gelöscht worden " "Um eine Datei endgültig zu löschen, muss sie zuvor weich gelöscht worden "
"sein." "sein."
#: core/recording/event/notification.py:124 #: core/recording/event/notification.py:123
msgid "Your recording is ready" msgid "Your recording is ready"
msgstr "Ihre Aufzeichnung ist bereit" msgstr "Ihre Aufzeichnung ist bereit"
#: core/recording/event/notification.py:195 #: core/recording/event/notification.py:194
msgid "Transcription" msgid "Transcription"
msgstr "Transkription" msgstr "Transkription"
#: core/recording/event/notification.py:206 #: core/recording/event/notification.py:204
#, python-brace-format #, python-brace-format
msgid "Meeting \"{room}\" on {room_recording_date} at {room_recording_time}" msgid "Meeting \"{room}\" on {room_recording_date} at {room_recording_time}"
msgstr "" msgstr ""
@@ -553,25 +537,25 @@ msgstr ""
msgid "Video call in progress: {sender.email} is waiting for you to connect" msgid "Video call in progress: {sender.email} is waiting for you to connect"
msgstr "Videoanruf läuft: {sender.email} wartet auf Ihre Teilnahme" msgstr "Videoanruf läuft: {sender.email} wartet auf Ihre Teilnahme"
#: core/templates/mail/html/invitation.html:151 #: core/templates/mail/html/invitation.html:159
#: core/templates/mail/html/screen_recording.html:151 #: core/templates/mail/html/screen_recording.html:159
#: core/templates/mail/text/invitation.txt:4 #: core/templates/mail/text/invitation.txt:3
#: core/templates/mail/text/screen_recording.txt:4 #: core/templates/mail/text/screen_recording.txt:3
msgid "Logo email" msgid "Logo email"
msgstr "Logo-E-Mail" msgstr "Logo-E-Mail"
#: core/templates/mail/html/invitation.html:181 #: core/templates/mail/html/invitation.html:189
#: core/templates/mail/text/invitation.txt:6 #: core/templates/mail/text/invitation.txt:5
msgid "invites you to join an ongoing video call" msgid "invites you to join an ongoing video call"
msgstr "lädt Sie zu einem laufenden Videoanruf ein" msgstr "lädt Sie zu einem laufenden Videoanruf ein"
#: core/templates/mail/html/invitation.html:192 #: core/templates/mail/html/invitation.html:200
#: core/templates/mail/text/invitation.txt:8 #: core/templates/mail/text/invitation.txt:7
msgid "JOIN THE CALL" msgid "JOIN THE CALL"
msgstr "AM ANRUF TEILNEHMEN" msgstr "AM ANRUF TEILNEHMEN"
#: core/templates/mail/html/invitation.html:219 #: core/templates/mail/html/invitation.html:227
#: core/templates/mail/text/invitation.txt:14 #: core/templates/mail/text/invitation.txt:13
msgid "" msgid ""
"If you can't click the button, copy and paste the URL into your browser to " "If you can't click the button, copy and paste the URL into your browser to "
"join the call." "join the call."
@@ -579,47 +563,41 @@ msgstr ""
"Wenn Sie den Button nicht anklicken können, kopieren Sie die URL und fügen " "Wenn Sie den Button nicht anklicken können, kopieren Sie die URL und fügen "
"Sie sie in Ihren Browser ein, um am Anruf teilzunehmen." "Sie sie in Ihren Browser ein, um am Anruf teilzunehmen."
#: core/templates/mail/html/invitation.html:227 #: core/templates/mail/html/invitation.html:235
#: core/templates/mail/text/invitation.txt:16 #: core/templates/mail/text/invitation.txt:15
msgid "Tips for a better experience:" msgid "Tips for a better experience:"
msgstr "Tipps für ein besseres Erlebnis:" msgstr "Tipps für ein besseres Erlebnis:"
#: core/templates/mail/html/invitation.html:229 #: core/templates/mail/html/invitation.html:237
#: core/templates/mail/text/invitation.txt:18 #: core/templates/mail/text/invitation.txt:17
msgid "Use Chrome or Firefox for better call quality" msgid "Use Chrome or Firefox for better call quality"
msgstr "Verwenden Sie Chrome oder Firefox für eine bessere Anrufqualität" msgstr "Verwenden Sie Chrome oder Firefox für eine bessere Anrufqualität"
#: core/templates/mail/html/invitation.html:230 #: core/templates/mail/html/invitation.html:238
#: core/templates/mail/text/invitation.txt:19 #: core/templates/mail/text/invitation.txt:18
msgid "Test your microphone and camera before joining" msgid "Test your microphone and camera before joining"
msgstr "Testen Sie Ihr Mikrofon und Ihre Kamera vor dem Beitritt" msgstr "Testen Sie Ihr Mikrofon und Ihre Kamera vor dem Beitritt"
#: core/templates/mail/html/invitation.html:231 #: core/templates/mail/html/invitation.html:239
#: core/templates/mail/text/invitation.txt:20 #: core/templates/mail/text/invitation.txt:19
msgid "Make sure you have a stable internet connection" msgid "Make sure you have a stable internet connection"
msgstr "Stellen Sie sicher, dass Sie eine stabile Internetverbindung haben" msgstr "Stellen Sie sicher, dass Sie eine stabile Internetverbindung haben"
#: core/templates/mail/html/invitation.html:240 #: core/templates/mail/html/invitation.html:248
#: core/templates/mail/html/screen_recording.html:237 #: core/templates/mail/html/screen_recording.html:245
#: core/templates/mail/text/invitation.txt:22 #: core/templates/mail/text/invitation.txt:21
#: core/templates/mail/text/screen_recording.txt:24 #: core/templates/mail/text/screen_recording.txt:23
#, python-format #, python-format
msgid " Thank you for using %(brandname)s. " msgid " Thank you for using %(brandname)s. "
msgstr " Vielen Dank für die Nutzung von %(brandname)s. " msgstr " Vielen Dank für die Nutzung von %(brandname)s. "
#: core/templates/mail/html/invitation.html:271 #: core/templates/mail/html/screen_recording.html:188
#, python-format #: core/templates/mail/text/screen_recording.txt:6
msgid ""
"This mail has been sent to %(email)s by <a href=\"%(href)s\">%(name)s</a>"
msgstr ""
#: core/templates/mail/html/screen_recording.html:180
#: core/templates/mail/text/screen_recording.txt:7
msgid "Your recording is ready!" msgid "Your recording is ready!"
msgstr "Ihre Aufzeichnung ist fertig!" msgstr "Ihre Aufzeichnung ist fertig!"
#: core/templates/mail/html/screen_recording.html:187 #: core/templates/mail/html/screen_recording.html:195
#: core/templates/mail/text/screen_recording.txt:9 #: core/templates/mail/text/screen_recording.txt:8
#, python-format #, python-format
msgid "" msgid ""
" Your recording of \"%(room_name)s\" on %(recording_date)s at " " Your recording of \"%(room_name)s\" on %(recording_date)s at "
@@ -628,14 +606,14 @@ msgstr ""
" Ihre Aufzeichnung von \"%(room_name)s\" am %(recording_date)s um " " Ihre Aufzeichnung von \"%(room_name)s\" am %(recording_date)s um "
"%(recording_time)s steht nun zum Herunterladen bereit. " "%(recording_time)s steht nun zum Herunterladen bereit. "
#: core/templates/mail/html/screen_recording.html:187 #: core/templates/mail/html/screen_recording.html:195
#: core/templates/mail/text/screen_recording.txt:9 #: core/templates/mail/text/screen_recording.txt:8
#, python-format #, python-format
msgid " The recording will expire in %(days)s days. " msgid " The recording will expire in %(days)s days. "
msgstr " Die Aufzeichnung wird in %(days)s Tagen ablaufen. " msgstr " Die Aufzeichnung wird in %(days)s Tagen ablaufen. "
#: core/templates/mail/html/screen_recording.html:192 #: core/templates/mail/html/screen_recording.html:200
#: core/templates/mail/text/screen_recording.txt:10 #: core/templates/mail/text/screen_recording.txt:9
msgid "" msgid ""
" Sharing the recording via link is not yet available. Only organizers can " " Sharing the recording via link is not yet available. Only organizers can "
"download it. " "download it. "
@@ -643,33 +621,33 @@ msgstr ""
" Die Freigabe der Aufzeichnung per Link ist noch nicht verfügbar. Nur " " Die Freigabe der Aufzeichnung per Link ist noch nicht verfügbar. Nur "
"Organisatoren können sie herunterladen. " "Organisatoren können sie herunterladen. "
#: core/templates/mail/html/screen_recording.html:198 #: core/templates/mail/html/screen_recording.html:206
#: core/templates/mail/text/screen_recording.txt:12 #: core/templates/mail/text/screen_recording.txt:11
msgid "To keep this recording permanently:" msgid "To keep this recording permanently:"
msgstr "So speichern Sie diese Aufzeichnung dauerhaft:" msgstr "So speichern Sie diese Aufzeichnung dauerhaft:"
#: core/templates/mail/html/screen_recording.html:200 #: core/templates/mail/html/screen_recording.html:208
#, python-format #, python-format
msgid "Click the \"<a href=\"%(link)s\">Open</a>\" link below " msgid "Click the \"<a href=\"%(link)s\">Open</a>\" link below "
msgstr "Klicken Sie auf den Link „<a href=\"%(link)s\">Öffnen</a>\" unten " msgstr "Klicken Sie auf den Link „<a href=\"%(link)s\">Öffnen</a>\" unten "
#: core/templates/mail/html/screen_recording.html:201 #: core/templates/mail/html/screen_recording.html:209
#: core/templates/mail/text/screen_recording.txt:15 #: core/templates/mail/text/screen_recording.txt:14
msgid "Use the \"Download\" button in the interface " msgid "Use the \"Download\" button in the interface "
msgstr "Verwenden Sie den Button „Herunterladen“ in der Oberfläche " msgstr "Verwenden Sie den Button „Herunterladen“ in der Oberfläche "
#: core/templates/mail/html/screen_recording.html:202 #: core/templates/mail/html/screen_recording.html:210
#: core/templates/mail/text/screen_recording.txt:16 #: core/templates/mail/text/screen_recording.txt:15
msgid "Save the file to your preferred location" msgid "Save the file to your preferred location"
msgstr "Speichern Sie die Datei an einem gewünschten Ort" msgstr "Speichern Sie die Datei an einem gewünschten Ort"
#: core/templates/mail/html/screen_recording.html:213 #: core/templates/mail/html/screen_recording.html:221
#: core/templates/mail/text/screen_recording.txt:18 #: core/templates/mail/text/screen_recording.txt:17
msgid "Open" msgid "Open"
msgstr "Öffnen" msgstr "Öffnen"
#: core/templates/mail/html/screen_recording.html:222 #: core/templates/mail/html/screen_recording.html:230
#: core/templates/mail/text/screen_recording.txt:20 #: core/templates/mail/text/screen_recording.txt:19
#, python-format #, python-format
msgid "" msgid ""
" If you have any questions or need assistance, please contact our support " " If you have any questions or need assistance, please contact our support "
@@ -678,33 +656,28 @@ msgstr ""
" Wenn Sie Fragen haben oder Unterstützung benötigen, wenden Sie sich bitte " " Wenn Sie Fragen haben oder Unterstützung benötigen, wenden Sie sich bitte "
"an unser Support-Team unter %(support_email)s. " "an unser Support-Team unter %(support_email)s. "
#: core/templates/mail/text/invitation.txt:24 #: core/templates/mail/text/screen_recording.txt:13
#, python-format
msgid "This mail has been sent to %(email)s by %(name)s [%(href)s]"
msgstr ""
#: core/templates/mail/text/screen_recording.txt:14
#, fuzzy, python-format #, fuzzy, python-format
#| msgid "Click the \"<a href=\"%(link)s\">Open</a>\" link below " #| msgid "Click the \"<a href=\"%(link)s\">Open</a>\" link below "
msgid "Click the \"Open [%(link)s]\" link below " msgid "Click the \"Open [%(link)s]\" link below "
msgstr "Klicken Sie auf den Link „<a href=\"%(link)s\">Öffnen</a>\" unten " msgstr "Klicken Sie auf den Link „<a href=\"%(link)s\">Öffnen</a>\" unten "
#: meet/settings.py:238 #: meet/settings.py:228
msgid "English" msgid "English"
msgstr "Englisch" msgstr "Englisch"
#: meet/settings.py:239 #: meet/settings.py:229
msgid "French" msgid "French"
msgstr "Französisch" msgstr "Französisch"
#: meet/settings.py:240 #: meet/settings.py:230
msgid "Dutch" msgid "Dutch"
msgstr "Niederländisch" msgstr "Niederländisch"
#: meet/settings.py:241 #: meet/settings.py:231
msgid "German" msgid "German"
msgstr "Deutsch" msgstr "Deutsch"
#: meet/settings.py:242 #: meet/settings.py:233
msgid "Spanish" msgid "Spanish"
msgstr "Spanisch" msgstr "Spanisch"
+160 -187
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-02 22:52+0000\n" "POT-Creation-Date: 2026-07-02 10:47+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -51,11 +51,11 @@ msgstr ""
msgid "File preview" msgid "File preview"
msgstr "" msgstr ""
#: core/admin.py:300 core/admin.py:450 #: core/admin.py:300 core/admin.py:443
msgid "No owner" msgid "No owner"
msgstr "No owner" msgstr "No owner"
#: core/admin.py:303 core/admin.py:453 #: core/admin.py:303 core/admin.py:446
msgid "Multiple owners" msgid "Multiple owners"
msgstr "Multiple owners" msgstr "Multiple owners"
@@ -98,11 +98,11 @@ msgstr "%(count)s recording(s) successfully marked as 'Failed to Stop'."
msgid "Skipped %(count)s recording(s) with an ineligible status." msgid "Skipped %(count)s recording(s) with an ineligible status."
msgstr "Skipped %(count)s expired recording(s)." msgstr "Skipped %(count)s expired recording(s)."
#: core/admin.py:517 #: core/admin.py:510
msgid "No scopes" msgid "No scopes"
msgstr "No scopes" msgstr "No scopes"
#: core/admin.py:519 #: core/admin.py:512
msgid "Scopes" msgid "Scopes"
msgstr "Scopes" msgstr "Scopes"
@@ -110,199 +110,183 @@ msgstr "Scopes"
msgid "Creator is me" msgid "Creator is me"
msgstr "Creator is me" msgstr "Creator is me"
#: core/api/serializers.py:108 #: core/api/serializers.py:89
msgid "You must be administrator or owner of a room to add accesses to it." msgid "You must be administrator or owner of a room to add accesses to it."
msgstr "You must be administrator or owner of a room to add accesses to it." msgstr "You must be administrator or owner of a room to add accesses to it."
#: core/api/serializers.py:560 #: core/api/serializers.py:534
msgid "This file extension is not allowed." msgid "This file extension is not allowed."
msgstr "This file extension is not allowed." msgstr "This file extension is not allowed."
#: core/api/viewsets.py:1268 #: core/api/viewsets.py:1222
msgid "You have reached the maximum number of files for this type." msgid "You have reached the maximum number of files for this type."
msgstr "You have reached the maximum number of files for this type." msgstr "You have reached the maximum number of files for this type."
#: core/models.py:38 #: core/models.py:37
msgid "Member" msgid "Member"
msgstr "Member" msgstr "Member"
#: core/models.py:39 #: core/models.py:38
msgid "Administrator" msgid "Administrator"
msgstr "Administrator" msgstr "Administrator"
#: core/models.py:40 #: core/models.py:39
msgid "Owner" msgid "Owner"
msgstr "Owner" msgstr "Owner"
#: core/models.py:56 #: core/models.py:55
msgid "Initiated" msgid "Initiated"
msgstr "Initiated" msgstr "Initiated"
#: core/models.py:57 #: core/models.py:56
msgid "Active" msgid "Active"
msgstr "Active" msgstr "Active"
#: core/models.py:58 #: core/models.py:57
msgid "Stopped" msgid "Stopped"
msgstr "Stopped" msgstr "Stopped"
#: core/models.py:59 #: core/models.py:58
msgid "Saved" msgid "Saved"
msgstr "Saved" msgstr "Saved"
#: core/models.py:60 #: core/models.py:59
msgid "Aborted" msgid "Aborted"
msgstr "Aborted" msgstr "Aborted"
#: core/models.py:61 #: core/models.py:60
msgid "Failed to Start" msgid "Failed to Start"
msgstr "Failed to Start" msgstr "Failed to Start"
#: core/models.py:62 #: core/models.py:61
msgid "Failed to Stop" msgid "Failed to Stop"
msgstr "Failed to Stop" msgstr "Failed to Stop"
#: core/models.py:63 #: core/models.py:62
msgid "Notification succeeded" msgid "Notification succeeded"
msgstr "Notification succeeded" msgstr "Notification succeeded"
#: core/models.py:66 #: core/models.py:65
msgid "External process successful" msgid "External process successful"
msgstr "External process successful" msgstr "External process successful"
#: core/models.py:68 #: core/models.py:67
msgid "External process failed" msgid "External process failed"
msgstr "External process failed" msgstr "External process failed"
#: core/models.py:97 #: core/models.py:96
msgid "SCREEN_RECORDING" msgid "SCREEN_RECORDING"
msgstr "SCREEN_RECORDING" msgstr "SCREEN_RECORDING"
#: core/models.py:98 #: core/models.py:97
msgid "TRANSCRIPT" msgid "TRANSCRIPT"
msgstr "TRANSCRIPT" msgstr "TRANSCRIPT"
#: core/models.py:104 #: core/models.py:103
msgid "Public Access" msgid "Public Access"
msgstr "Public Access" msgstr "Public Access"
#: core/models.py:105 #: core/models.py:104
msgid "Trusted Access" msgid "Trusted Access"
msgstr "Trusted Access" msgstr "Trusted Access"
#: core/models.py:106 #: core/models.py:105
msgid "Restricted Access" msgid "Restricted Access"
msgstr "Restricted Access" msgstr "Restricted Access"
#: core/models.py:118 #: core/models.py:117
msgid "id" msgid "id"
msgstr "id" msgstr "id"
#: core/models.py:119 #: core/models.py:118
msgid "primary key for the record as UUID" msgid "primary key for the record as UUID"
msgstr "primary key for the record as UUID" msgstr "primary key for the record as UUID"
#: core/models.py:125 #: core/models.py:124
msgid "created on" msgid "created on"
msgstr "created on" msgstr "created on"
#: core/models.py:126 #: core/models.py:125
msgid "date and time at which a record was created" msgid "date and time at which a record was created"
msgstr "date and time at which a record was created" msgstr "date and time at which a record was created"
#: core/models.py:131 #: core/models.py:130
msgid "updated on" msgid "updated on"
msgstr "updated on" msgstr "updated on"
#: core/models.py:132 #: core/models.py:131
msgid "date and time at which a record was last updated" msgid "date and time at which a record was last updated"
msgstr "date and time at which a record was last updated" msgstr "date and time at which a record was last updated"
#: core/models.py:150 #: core/models.py:151
msgid ""
"Enter a valid sub. This value may contain only letters, numbers, and @/./+/-/"
"_ characters."
msgstr ""
"Enter a valid sub. This value may contain only letters, numbers, and @/./+/-/"
"_ characters."
#: core/models.py:157
msgid "sub" msgid "sub"
msgstr "sub" msgstr "sub"
#: core/models.py:152 #: core/models.py:159
msgid "" msgid ""
"Optional for pending users; required upon account activation. 255 characters " "Optional for pending users; required upon account activation. 255 characters "
"or fewer. Printable ASCII characters only." "or fewer. Letters, numbers, and @/./+/-/_ characters only."
msgstr "" msgstr ""
"Optional for pending users; required upon account activation. 255 characters " "Required. 255 characters or fewer. Letters, numbers, and @/./+/-/_ "
"or fewer. Printable ASCII characters only." "characters only."
#: core/validators.py:22 #: core/models.py:168
msgid "Enter a valid sub. This value should be printable ASCII only."
msgstr "Enter a valid sub. This value should be printable ASCII only."
#: core/models.py:161
msgid "identity email address" msgid "identity email address"
msgstr "identity email address" msgstr "identity email address"
#: core/models.py:166 #: core/models.py:173
msgid "admin email address" msgid "admin email address"
msgstr "admin email address" msgstr "admin email address"
#: core/models.py:168 #: core/models.py:175
msgid "full name" msgid "full name"
msgstr "full name" msgstr "full name"
#: core/models.py:170 #: core/models.py:177
msgid "short name" msgid "short name"
msgstr "short name" msgstr "short name"
#: core/models.py:176 #: core/models.py:183
msgid "language" msgid "language"
msgstr "language" msgstr "language"
#: core/models.py:177 #: core/models.py:184
msgid "The language in which the user wants to see the interface." msgid "The language in which the user wants to see the interface."
msgstr "The language in which the user wants to see the interface." msgstr "The language in which the user wants to see the interface."
#: core/models.py:183 #: core/models.py:190
msgid "The timezone in which the user wants to see times." msgid "The timezone in which the user wants to see times."
msgstr "The timezone in which the user wants to see times." msgstr "The timezone in which the user wants to see times."
#: core/models.py:190 #: core/models.py:193
msgid "default room access level"
msgstr ""
#: core/models.py:192
msgid ""
"Access level applied by default to new rooms created by this user. When "
"empty, the instance default is used."
msgstr ""
#: core/models.py:199
#, fuzzy
#| msgid "Visio room configuration"
msgid "default room configuration"
msgstr "Visio room configuration"
#: core/models.py:201
msgid "Configurations applied by default to new rooms created by this user."
msgstr ""
#: core/models.py:205
msgid "device" msgid "device"
msgstr "device" msgstr "device"
#: core/models.py:207 #: core/models.py:195
msgid "Whether the user is a device or a real user." msgid "Whether the user is a device or a real user."
msgstr "Whether the user is a device or a real user." msgstr "Whether the user is a device or a real user."
#: core/models.py:210 #: core/models.py:198
msgid "staff status" msgid "staff status"
msgstr "staff status" msgstr "staff status"
#: core/models.py:212 #: core/models.py:200
msgid "Whether the user can log into this admin site." msgid "Whether the user can log into this admin site."
msgstr "Whether the user can log into this admin site." msgstr "Whether the user can log into this admin site."
#: core/models.py:215 #: core/models.py:203
msgid "active" msgid "active"
msgstr "active" msgstr "active"
#: core/models.py:218 #: core/models.py:206
msgid "" msgid ""
"Whether this user should be treated as active. Unselect this instead of " "Whether this user should be treated as active. Unselect this instead of "
"deleting accounts." "deleting accounts."
@@ -310,63 +294,63 @@ msgstr ""
"Whether this user should be treated as active. Unselect this instead of " "Whether this user should be treated as active. Unselect this instead of "
"deleting accounts." "deleting accounts."
#: core/models.py:231 #: core/models.py:219
msgid "user" msgid "user"
msgstr "user" msgstr "user"
#: core/models.py:232 #: core/models.py:220
msgid "users" msgid "users"
msgstr "users" msgstr "users"
#: core/models.py:298 #: core/models.py:286
msgid "Resource" msgid "Resource"
msgstr "Resource" msgstr "Resource"
#: core/models.py:299 #: core/models.py:287
msgid "Resources" msgid "Resources"
msgstr "Resources" msgstr "Resources"
#: core/models.py:357 #: core/models.py:345
msgid "Resource access" msgid "Resource access"
msgstr "Resource access" msgstr "Resource access"
#: core/models.py:358 #: core/models.py:346
msgid "Resource accesses" msgid "Resource accesses"
msgstr "Resource accesses" msgstr "Resource accesses"
#: core/models.py:364 #: core/models.py:352
msgid "Resource access with this User and Resource already exists." msgid "Resource access with this User and Resource already exists."
msgstr "Resource access with this User and Resource already exists." msgstr "Resource access with this User and Resource already exists."
#: core/models.py:421 #: core/models.py:409
msgid "Visio room configuration" msgid "Visio room configuration"
msgstr "Visio room configuration" msgstr "Visio room configuration"
#: core/models.py:422 #: core/models.py:410
msgid "Values for Visio parameters to configure the room." msgid "Values for Visio parameters to configure the room."
msgstr "Values for Visio parameters to configure the room." msgstr "Values for Visio parameters to configure the room."
#: core/models.py:429 #: core/models.py:417
msgid "Room PIN code" msgid "Room PIN code"
msgstr "Room PIN code" msgstr "Room PIN code"
#: core/models.py:430 #: core/models.py:418
msgid "Unique n-digit code that identifies this room in telephony mode." msgid "Unique n-digit code that identifies this room in telephony mode."
msgstr "Unique n-digit code that identifies this room in telephony mode." msgstr "Unique n-digit code that identifies this room in telephony mode."
#: core/models.py:436 core/models.py:597 #: core/models.py:424 core/models.py:578
msgid "Room" msgid "Room"
msgstr "Room" msgstr "Room"
#: core/models.py:437 #: core/models.py:425
msgid "Rooms" msgid "Rooms"
msgstr "Rooms" msgstr "Rooms"
#: core/models.py:608 #: core/models.py:589
msgid "Worker ID" msgid "Worker ID"
msgstr "Worker ID" msgstr "Worker ID"
#: core/models.py:610 #: core/models.py:591
msgid "" msgid ""
"Enter an identifier for the worker recording.This ID is retained even when " "Enter an identifier for the worker recording.This ID is retained even when "
"the worker stops, allowing for easy tracking." "the worker stops, allowing for easy tracking."
@@ -374,171 +358,171 @@ msgstr ""
"Enter an identifier for the worker recording.This ID is retained even when " "Enter an identifier for the worker recording.This ID is retained even when "
"the worker stops, allowing for easy tracking." "the worker stops, allowing for easy tracking."
#: core/models.py:618 #: core/models.py:599
msgid "Recording mode" msgid "Recording mode"
msgstr "Recording mode" msgstr "Recording mode"
#: core/models.py:619 #: core/models.py:600
msgid "Defines the mode of recording being called." msgid "Defines the mode of recording being called."
msgstr "Defines the mode of recording being called." msgstr "Defines the mode of recording being called."
#: core/models.py:624 core/models.py:625 #: core/models.py:605 core/models.py:606
msgid "Recording options" msgid "Recording options"
msgstr "Recording options" msgstr "Recording options"
#: core/models.py:632 #: core/models.py:613
msgid "External Process ID" msgid "External Process ID"
msgstr "External Process ID" msgstr "External Process ID"
#: core/models.py:633 #: core/models.py:614
msgid "ID of the external process associated with the recording." msgid "ID of the external process associated with the recording."
msgstr "ID of the external process associated with the recording." msgstr "ID of the external process associated with the recording."
#: core/models.py:639 #: core/models.py:620
msgid "Recording" msgid "Recording"
msgstr "Recording" msgstr "Recording"
#: core/models.py:640 #: core/models.py:621
msgid "Recordings" msgid "Recordings"
msgstr "Recordings" msgstr "Recordings"
#: core/models.py:750 #: core/models.py:731
msgid "Recording/user relation" msgid "Recording/user relation"
msgstr "Recording/user relation" msgstr "Recording/user relation"
#: core/models.py:751 #: core/models.py:732
msgid "Recording/user relations" msgid "Recording/user relations"
msgstr "Recording/user relations" msgstr "Recording/user relations"
#: core/models.py:757 #: core/models.py:738
msgid "This user is already in this recording." msgid "This user is already in this recording."
msgstr "This user is already in this recording." msgstr "This user is already in this recording."
#: core/models.py:763 #: core/models.py:744
msgid "This team is already in this recording." msgid "This team is already in this recording."
msgstr "This team is already in this recording." msgstr "This team is already in this recording."
#: core/models.py:769 #: core/models.py:750
msgid "Either user or team must be set, not both." msgid "Either user or team must be set, not both."
msgstr "Either user or team must be set, not both." msgstr "Either user or team must be set, not both."
#: core/models.py:786 #: core/models.py:767
#, fuzzy #, fuzzy
#| msgid "created on" #| msgid "created on"
msgid "Create rooms" msgid "Create rooms"
msgstr "Create rooms" msgstr "Create rooms"
#: core/models.py:787 #: core/models.py:768
msgid "List rooms" msgid "List rooms"
msgstr "List rooms" msgstr "List rooms"
#: core/models.py:788 #: core/models.py:769
msgid "Retrieve room details" msgid "Retrieve room details"
msgstr "Retrieve room details" msgstr "Retrieve room details"
#: core/models.py:789 #: core/models.py:770
#, fuzzy #, fuzzy
#| msgid "updated on" #| msgid "updated on"
msgid "Update rooms" msgid "Update rooms"
msgstr "Update rooms" msgstr "Update rooms"
#: core/models.py:790 #: core/models.py:771
msgid "Delete rooms" msgid "Delete rooms"
msgstr "Delete rooms" msgstr "Delete rooms"
#: core/models.py:803 #: core/models.py:784
msgid "Application name" msgid "Application name"
msgstr "Application name" msgstr "Application name"
#: core/models.py:804 #: core/models.py:785
msgid "Descriptive name for this application." msgid "Descriptive name for this application."
msgstr "Descriptive name for this application." msgstr "Descriptive name for this application."
#: core/models.py:814 #: core/models.py:795
msgid "Hashed on Save. Copy it now if this is a new secret." msgid "Hashed on Save. Copy it now if this is a new secret."
msgstr "Hashed on Save. Copy it now if this is a new secret." msgstr "Hashed on Save. Copy it now if this is a new secret."
#: core/models.py:825 #: core/models.py:806
msgid "Application" msgid "Application"
msgstr "Application" msgstr "Application"
#: core/models.py:826 #: core/models.py:807
msgid "Applications" msgid "Applications"
msgstr "Applications" msgstr "Applications"
#: core/models.py:849 #: core/models.py:830
msgid "Enter a valid domain" msgid "Enter a valid domain"
msgstr "Enter a valid domain" msgstr "Enter a valid domain"
#: core/models.py:852 #: core/models.py:833
msgid "Domain" msgid "Domain"
msgstr "Domain" msgstr "Domain"
#: core/models.py:853 #: core/models.py:834
msgid "Email domain this application can act on behalf of." msgid "Email domain this application can act on behalf of."
msgstr "Email domain this application can act on behalf of." msgstr "Email domain this application can act on behalf of."
#: core/models.py:865 #: core/models.py:846
msgid "Application domain" msgid "Application domain"
msgstr "Application domain" msgstr "Application domain"
#: core/models.py:866 #: core/models.py:847
msgid "Application domains" msgid "Application domains"
msgstr "Application domains" msgstr "Application domains"
#: core/models.py:884 #: core/models.py:865
#, fuzzy #, fuzzy
#| msgid "Recording" #| msgid "Recording"
msgid "Pending" msgid "Pending"
msgstr "Pending" msgstr "Pending"
#: core/models.py:885 #: core/models.py:866
msgid "Analyzing" msgid "Analyzing"
msgstr "" msgstr ""
#: core/models.py:892 #: core/models.py:873
msgid "Ready" msgid "Ready"
msgstr "Ready" msgstr "Ready"
#: core/models.py:898 #: core/models.py:879
msgid "Background image" msgid "Background image"
msgstr "Background image" msgstr "Background image"
#: core/models.py:910 #: core/models.py:891
msgid "title" msgid "title"
msgstr "title" msgstr "title"
#: core/models.py:934 #: core/models.py:915
msgid "Malware detection info when the analysis status is unsafe." msgid "Malware detection info when the analysis status is unsafe."
msgstr "Malware detection info when the analysis status is unsafe." msgstr "Malware detection info when the analysis status is unsafe."
#: core/models.py:939 #: core/models.py:920
msgid "File" msgid "File"
msgstr "File" msgstr "File"
#: core/models.py:940 #: core/models.py:921
msgid "Files" msgid "Files"
msgstr "Files" msgstr "Files"
#: core/models.py:1060 #: core/models.py:1041
#, fuzzy #, fuzzy
#| msgid "This user is already in this recording." #| msgid "This user is already in this recording."
msgid "This file is already hard deleted." msgid "This file is already hard deleted."
msgstr "This file is already hard deleted." msgstr "This file is already hard deleted."
#: core/models.py:1070 #: core/models.py:1051
msgid "To hard delete a file, it must first be soft deleted." msgid "To hard delete a file, it must first be soft deleted."
msgstr "To hard delete a file, it must first be soft deleted." msgstr "To hard delete a file, it must first be soft deleted."
#: core/recording/event/notification.py:124 #: core/recording/event/notification.py:123
msgid "Your recording is ready" msgid "Your recording is ready"
msgstr "Your recording is ready" msgstr "Your recording is ready"
#: core/recording/event/notification.py:195 #: core/recording/event/notification.py:194
msgid "Transcription" msgid "Transcription"
msgstr "Transcription" msgstr "Transcription"
#: core/recording/event/notification.py:206 #: core/recording/event/notification.py:204
#, python-brace-format #, python-brace-format
msgid "Meeting \"{room}\" on {room_recording_date} at {room_recording_time}" msgid "Meeting \"{room}\" on {room_recording_date} at {room_recording_time}"
msgstr "Meeting \"{room}\" on {room_recording_date} at {room_recording_time}" msgstr "Meeting \"{room}\" on {room_recording_date} at {room_recording_time}"
@@ -548,25 +532,25 @@ msgstr "Meeting \"{room}\" on {room_recording_date} at {room_recording_time}"
msgid "Video call in progress: {sender.email} is waiting for you to connect" msgid "Video call in progress: {sender.email} is waiting for you to connect"
msgstr "Video call in progress: {sender.email} is waiting for you to connect" msgstr "Video call in progress: {sender.email} is waiting for you to connect"
#: core/templates/mail/html/invitation.html:151 #: core/templates/mail/html/invitation.html:159
#: core/templates/mail/html/screen_recording.html:151 #: core/templates/mail/html/screen_recording.html:159
#: core/templates/mail/text/invitation.txt:4 #: core/templates/mail/text/invitation.txt:3
#: core/templates/mail/text/screen_recording.txt:4 #: core/templates/mail/text/screen_recording.txt:3
msgid "Logo email" msgid "Logo email"
msgstr "Logo email" msgstr "Logo email"
#: core/templates/mail/html/invitation.html:181 #: core/templates/mail/html/invitation.html:189
#: core/templates/mail/text/invitation.txt:6 #: core/templates/mail/text/invitation.txt:5
msgid "invites you to join an ongoing video call" msgid "invites you to join an ongoing video call"
msgstr "invites you to join an ongoing video call" msgstr "invites you to join an ongoing video call"
#: core/templates/mail/html/invitation.html:192 #: core/templates/mail/html/invitation.html:200
#: core/templates/mail/text/invitation.txt:8 #: core/templates/mail/text/invitation.txt:7
msgid "JOIN THE CALL" msgid "JOIN THE CALL"
msgstr "JOIN THE CALL" msgstr "JOIN THE CALL"
#: core/templates/mail/html/invitation.html:219 #: core/templates/mail/html/invitation.html:227
#: core/templates/mail/text/invitation.txt:14 #: core/templates/mail/text/invitation.txt:13
msgid "" msgid ""
"If you can't click the button, copy and paste the URL into your browser to " "If you can't click the button, copy and paste the URL into your browser to "
"join the call." "join the call."
@@ -574,47 +558,41 @@ msgstr ""
"If you can't click the button, copy and paste the URL into your browser to " "If you can't click the button, copy and paste the URL into your browser to "
"join the call." "join the call."
#: core/templates/mail/html/invitation.html:227 #: core/templates/mail/html/invitation.html:235
#: core/templates/mail/text/invitation.txt:16 #: core/templates/mail/text/invitation.txt:15
msgid "Tips for a better experience:" msgid "Tips for a better experience:"
msgstr "Tips for a better experience:" msgstr "Tips for a better experience:"
#: core/templates/mail/html/invitation.html:229 #: core/templates/mail/html/invitation.html:237
#: core/templates/mail/text/invitation.txt:18 #: core/templates/mail/text/invitation.txt:17
msgid "Use Chrome or Firefox for better call quality" msgid "Use Chrome or Firefox for better call quality"
msgstr "Use Chrome or Firefox for better call quality" msgstr "Use Chrome or Firefox for better call quality"
#: core/templates/mail/html/invitation.html:230 #: core/templates/mail/html/invitation.html:238
#: core/templates/mail/text/invitation.txt:19 #: core/templates/mail/text/invitation.txt:18
msgid "Test your microphone and camera before joining" msgid "Test your microphone and camera before joining"
msgstr "Test your microphone and camera before joining" msgstr "Test your microphone and camera before joining"
#: core/templates/mail/html/invitation.html:231 #: core/templates/mail/html/invitation.html:239
#: core/templates/mail/text/invitation.txt:20 #: core/templates/mail/text/invitation.txt:19
msgid "Make sure you have a stable internet connection" msgid "Make sure you have a stable internet connection"
msgstr "Make sure you have a stable internet connection" msgstr "Make sure you have a stable internet connection"
#: core/templates/mail/html/invitation.html:240 #: core/templates/mail/html/invitation.html:248
#: core/templates/mail/html/screen_recording.html:237 #: core/templates/mail/html/screen_recording.html:245
#: core/templates/mail/text/invitation.txt:22 #: core/templates/mail/text/invitation.txt:21
#: core/templates/mail/text/screen_recording.txt:24 #: core/templates/mail/text/screen_recording.txt:23
#, python-format #, python-format
msgid " Thank you for using %(brandname)s. " msgid " Thank you for using %(brandname)s. "
msgstr " Thank you for using %(brandname)s. " msgstr " Thank you for using %(brandname)s. "
#: core/templates/mail/html/invitation.html:271 #: core/templates/mail/html/screen_recording.html:188
#, python-format #: core/templates/mail/text/screen_recording.txt:6
msgid ""
"This mail has been sent to %(email)s by <a href=\"%(href)s\">%(name)s</a>"
msgstr ""
#: core/templates/mail/html/screen_recording.html:180
#: core/templates/mail/text/screen_recording.txt:7
msgid "Your recording is ready!" msgid "Your recording is ready!"
msgstr "Your recording is ready!" msgstr "Your recording is ready!"
#: core/templates/mail/html/screen_recording.html:187 #: core/templates/mail/html/screen_recording.html:195
#: core/templates/mail/text/screen_recording.txt:9 #: core/templates/mail/text/screen_recording.txt:8
#, python-format #, python-format
msgid "" msgid ""
" Your recording of \"%(room_name)s\" on %(recording_date)s at " " Your recording of \"%(room_name)s\" on %(recording_date)s at "
@@ -623,14 +601,14 @@ msgstr ""
" Your recording of \"%(room_name)s\" on %(recording_date)s at " " Your recording of \"%(room_name)s\" on %(recording_date)s at "
"%(recording_time)s is now ready to download. " "%(recording_time)s is now ready to download. "
#: core/templates/mail/html/screen_recording.html:187 #: core/templates/mail/html/screen_recording.html:195
#: core/templates/mail/text/screen_recording.txt:9 #: core/templates/mail/text/screen_recording.txt:8
#, python-format #, python-format
msgid " The recording will expire in %(days)s days. " msgid " The recording will expire in %(days)s days. "
msgstr " The recording will expire in %(days)s days. " msgstr " The recording will expire in %(days)s days. "
#: core/templates/mail/html/screen_recording.html:192 #: core/templates/mail/html/screen_recording.html:200
#: core/templates/mail/text/screen_recording.txt:10 #: core/templates/mail/text/screen_recording.txt:9
msgid "" msgid ""
" Sharing the recording via link is not yet available. Only organizers can " " Sharing the recording via link is not yet available. Only organizers can "
"download it. " "download it. "
@@ -638,33 +616,33 @@ msgstr ""
" Sharing the recording via link is not yet available. Only organizers can " " Sharing the recording via link is not yet available. Only organizers can "
"download it. " "download it. "
#: core/templates/mail/html/screen_recording.html:198 #: core/templates/mail/html/screen_recording.html:206
#: core/templates/mail/text/screen_recording.txt:12 #: core/templates/mail/text/screen_recording.txt:11
msgid "To keep this recording permanently:" msgid "To keep this recording permanently:"
msgstr "To keep this recording permanently:" msgstr "To keep this recording permanently:"
#: core/templates/mail/html/screen_recording.html:200 #: core/templates/mail/html/screen_recording.html:208
#, python-format #, python-format
msgid "Click the \"<a href=\"%(link)s\">Open</a>\" link below " msgid "Click the \"<a href=\"%(link)s\">Open</a>\" link below "
msgstr "Click the \"<a href=\"%(link)s\">Open</a>\" link below " msgstr "Click the \"<a href=\"%(link)s\">Open</a>\" link below "
#: core/templates/mail/html/screen_recording.html:201 #: core/templates/mail/html/screen_recording.html:209
#: core/templates/mail/text/screen_recording.txt:15 #: core/templates/mail/text/screen_recording.txt:14
msgid "Use the \"Download\" button in the interface " msgid "Use the \"Download\" button in the interface "
msgstr "Use the \"Download\" button in the interface " msgstr "Use the \"Download\" button in the interface "
#: core/templates/mail/html/screen_recording.html:202 #: core/templates/mail/html/screen_recording.html:210
#: core/templates/mail/text/screen_recording.txt:16 #: core/templates/mail/text/screen_recording.txt:15
msgid "Save the file to your preferred location" msgid "Save the file to your preferred location"
msgstr "Save the file to your preferred location" msgstr "Save the file to your preferred location"
#: core/templates/mail/html/screen_recording.html:213 #: core/templates/mail/html/screen_recording.html:221
#: core/templates/mail/text/screen_recording.txt:18 #: core/templates/mail/text/screen_recording.txt:17
msgid "Open" msgid "Open"
msgstr "Open" msgstr "Open"
#: core/templates/mail/html/screen_recording.html:222 #: core/templates/mail/html/screen_recording.html:230
#: core/templates/mail/text/screen_recording.txt:20 #: core/templates/mail/text/screen_recording.txt:19
#, python-format #, python-format
msgid "" msgid ""
" If you have any questions or need assistance, please contact our support " " If you have any questions or need assistance, please contact our support "
@@ -673,33 +651,28 @@ msgstr ""
" If you have any questions or need assistance, please contact our support " " If you have any questions or need assistance, please contact our support "
"team at %(support_email)s. " "team at %(support_email)s. "
#: core/templates/mail/text/invitation.txt:24 #: core/templates/mail/text/screen_recording.txt:13
#, python-format
msgid "This mail has been sent to %(email)s by %(name)s [%(href)s]"
msgstr ""
#: core/templates/mail/text/screen_recording.txt:14
#, fuzzy, python-format #, fuzzy, python-format
#| msgid "Click the \"<a href=\"%(link)s\">Open</a>\" link below " #| msgid "Click the \"<a href=\"%(link)s\">Open</a>\" link below "
msgid "Click the \"Open [%(link)s]\" link below " msgid "Click the \"Open [%(link)s]\" link below "
msgstr "Click the \"<a href=\"%(link)s\">Open</a>\" link below " msgstr "Click the \"<a href=\"%(link)s\">Open</a>\" link below "
#: meet/settings.py:238 #: meet/settings.py:228
msgid "English" msgid "English"
msgstr "English" msgstr "English"
#: meet/settings.py:239 #: meet/settings.py:229
msgid "French" msgid "French"
msgstr "French" msgstr "French"
#: meet/settings.py:240 #: meet/settings.py:230
msgid "Dutch" msgid "Dutch"
msgstr "Dutch" msgstr "Dutch"
#: meet/settings.py:241 #: meet/settings.py:231
msgid "German" msgid "German"
msgstr "German" msgstr "German"
#: meet/settings.py:242 #: meet/settings.py:233
msgid "Spanish" msgid "Spanish"
msgstr "Spanish" msgstr "Spanish"
+174 -229
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-02 22:52+0000\n" "POT-Creation-Date: 2026-07-02 10:47+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -41,20 +41,20 @@ msgstr "Eliminar Salas"
msgid "Derived info" msgid "Derived info"
msgstr "" msgstr ""
# 'Marcas de tiempo' is a bad translation for spanish
#: core/admin.py:237 #: core/admin.py:237
# 'Marcas de tiempo' is a bad translation for spanish
msgid "Timestamps" msgid "Timestamps"
msgstr "" msgstr ""
#: core/admin.py:240 #: core/admin.py:240
msgid "File preview" msgid "File preview"
msgstr "Vista previa" msgstr "Vista previa"
#: core/admin.py:300 core/admin.py:450 #: core/admin.py:300 core/admin.py:443
msgid "No owner" msgid "No owner"
msgstr "Sin propietario" msgstr "Sin propietario"
#: core/admin.py:303 core/admin.py:453 #: core/admin.py:303 core/admin.py:446
msgid "Multiple owners" msgid "Multiple owners"
msgstr "Varios propietarios" msgstr "Varios propietarios"
@@ -89,19 +89,18 @@ msgstr "Marcar las grabaciones seleccionadas como «Error al detener»"
#: core/admin.py:386 #: core/admin.py:386
#, python-format #, python-format
msgid "%(count)s recording(s) successfully marked as 'Failed to Stop'." msgid "%(count)s recording(s) successfully marked as 'Failed to Stop'."
msgstr "" msgstr "%(count)s grabación(es) marcada(s) correctamente como «Error al detener»."
"%(count)s grabación(es) marcada(s) correctamente como «Error al detener»."
#: core/admin.py:394 #: core/admin.py:394
#, python-format #, python-format
msgid "Skipped %(count)s recording(s) with an ineligible status." msgid "Skipped %(count)s recording(s) with an ineligible status."
msgstr "Se han omitido %(count)s grabación(es) con un estado no elegible." msgstr "Se han omitido %(count)s grabación(es) con un estado no elegible."
#: core/admin.py:517 #: core/admin.py:510
msgid "No scopes" msgid "No scopes"
msgstr "" msgstr ""
#: core/admin.py:519 #: core/admin.py:512
msgid "Scopes" msgid "Scopes"
msgstr "Ámbitos" msgstr "Ámbitos"
@@ -109,599 +108,545 @@ msgstr "Ámbitos"
msgid "Creator is me" msgid "Creator is me"
msgstr "Yo soy el creador" msgstr "Yo soy el creador"
#: core/api/serializers.py:108 #: core/api/serializers.py:89
msgid "You must be administrator or owner of a room to add accesses to it." msgid "You must be administrator or owner of a room to add accesses to it."
msgstr "" msgstr "Debes ser administrador o propietario de una reunión para añadirle accesos."
"Debes ser administrador o propietario de una reunión para añadirle accesos."
#: core/api/serializers.py:560 #: core/api/serializers.py:534
msgid "This file extension is not allowed." msgid "This file extension is not allowed."
msgstr "Esta extensión de archivo no está permitida." msgstr "Esta extensión de archivo no está permitida."
#: core/api/viewsets.py:1268 #: core/api/viewsets.py:1222
msgid "You have reached the maximum number of files for this type." msgid "You have reached the maximum number of files for this type."
msgstr "Has alcanzado el número máximo de archivos de este tipo." msgstr "Has alcanzado el número máximo de archivos de este tipo."
#: core/models.py:38 #: core/models.py:37
msgid "Member" msgid "Member"
msgstr "Miembro" msgstr "Miembro"
#: core/models.py:39 #: core/models.py:38
msgid "Administrator" msgid "Administrator"
msgstr "Administrador" msgstr "Administrador"
#: core/models.py:40 #: core/models.py:39
msgid "Owner" msgid "Owner"
msgstr "Propietario" msgstr "Propietario"
#: core/models.py:55
# To check here and following lines for gender agreement (Masculine/Feminine) # To check here and following lines for gender agreement (Masculine/Feminine)
#: core/models.py:56
msgid "Initiated" msgid "Initiated"
msgstr "Iniciada" msgstr "Iniciada"
#: core/models.py:57 #: core/models.py:56
msgid "Active" msgid "Active"
msgstr "Activa" msgstr "Activa"
#: core/models.py:58 #: core/models.py:57
msgid "Stopped" msgid "Stopped"
msgstr "Detenida" msgstr "Detenida"
#: core/models.py:59 #: core/models.py:58
msgid "Saved" msgid "Saved"
msgstr "Guardada" msgstr "Guardada"
#: core/models.py:60 #: core/models.py:59
msgid "Aborted" msgid "Aborted"
msgstr "Cancelada" msgstr "Cancelada"
#: core/models.py:61 #: core/models.py:60
msgid "Failed to Start" msgid "Failed to Start"
msgstr "Error al iniciar" msgstr "Error al iniciar"
#: core/models.py:62 #: core/models.py:61
msgid "Failed to Stop" msgid "Failed to Stop"
msgstr "Error al detener" msgstr "Error al detener"
#: core/models.py:63 #: core/models.py:62
msgid "Notification succeeded" msgid "Notification succeeded"
msgstr "Notificado correctamente" msgstr "Notificado correctamente"
#: core/models.py:66 #: core/models.py:65
msgid "External process successful" msgid "External process successful"
msgstr "Proceso externo finalizado correctamente" msgstr "Proceso externo finalizado correctamente"
#: core/models.py:68 #: core/models.py:67
msgid "External process failed" msgid "External process failed"
msgstr "Error en el Proceso externo" msgstr "Error en el Proceso externo"
#: core/models.py:97 #: core/models.py:96
msgid "SCREEN_RECORDING" msgid "SCREEN_RECORDING"
msgstr "GRABACIÓN_DE_PANTALLA" msgstr "GRABACIÓN_DE_PANTALLA"
#: core/models.py:98 #: core/models.py:97
msgid "TRANSCRIPT" msgid "TRANSCRIPT"
msgstr "TRANSCRIPCIÓN" msgstr "TRANSCRIPCIÓN"
#: core/models.py:104 #: core/models.py:103
msgid "Public Access" msgid "Public Access"
msgstr "Acceso público" msgstr "Acceso público"
#: core/models.py:105 #: core/models.py:104
msgid "Trusted Access" msgid "Trusted Access"
msgstr "Acceso usuarios autorizados" msgstr "Acceso usuarios autorizados"
#: core/models.py:106 #: core/models.py:105
msgid "Restricted Access" msgid "Restricted Access"
msgstr "Acceso restringido" msgstr "Acceso restringido"
#: core/models.py:118 #: core/models.py:117
msgid "id" msgid "id"
msgstr "id" msgstr "id"
#: core/models.py:119 #: core/models.py:118
msgid "primary key for the record as UUID" msgid "primary key for the record as UUID"
msgstr "clave primaria del registro en forma de UUID" msgstr "clave primaria del registro en forma de UUID"
#: core/models.py:125 #: core/models.py:124
msgid "created on" msgid "created on"
msgstr "creado el" msgstr "creado el"
#: core/models.py:126 #: core/models.py:125
msgid "date and time at which a record was created" msgid "date and time at which a record was created"
msgstr "fecha y hora en que se creó un registro" msgstr "fecha y hora en que se creó un registro"
#: core/models.py:131 #: core/models.py:130
msgid "updated on" msgid "updated on"
msgstr "actualizado el" msgstr "actualizado el"
#: core/models.py:132 #: core/models.py:131
msgid "date and time at which a record was last updated" msgid "date and time at which a record was last updated"
msgstr "fecha y hora de la última actualización de un registro" msgstr "fecha y hora de la última actualización de un registro"
#: core/models.py:150 #: core/models.py:151
msgid ""
"Enter a valid sub. This value may contain only letters, numbers, and @/./+/-/"
"_ characters."
msgstr "Introduce un sub válido. Este valor solo puede contener letras, números y los caracteres @/./+/-/_."
#: core/models.py:157
msgid "sub" msgid "sub"
msgstr "sub" msgstr "sub"
#: core/models.py:152 #: core/models.py:159
msgid "" msgid ""
"Optional for pending users; required upon account activation. 255 characters " "Optional for pending users; required upon account activation. 255 characters "
"or fewer. Printable ASCII characters only." "or fewer. Letters, numbers, and @/./+/-/_ characters only."
msgstr "" msgstr "Opcional para los usuarios pendientes; obligatorio al activar la cuenta. 255 caracteres como máximo. Solo letras, números y los caracteres @/./+/-/_."
"Opcional para los usuarios pendientes; obligatorio al activar la cuenta. "
"255 caracteres como máximo. Solo caracteres ASCII imprimibles."
#: core/validators.py:22 #: core/models.py:168
msgid "Enter a valid sub. This value should be printable ASCII only."
msgstr "Introduzca un sub válido. Este valor solo debe contener caracteres ASCII imprimibles."
#: core/models.py:161
msgid "identity email address" msgid "identity email address"
msgstr "dirección de correo electrónico" msgstr "dirección de correo electrónico"
#: core/models.py:166 #: core/models.py:173
msgid "admin email address" msgid "admin email address"
msgstr "dirección de correo electrónico de administrador" msgstr "dirección de correo electrónico de administrador"
#: core/models.py:168 #: core/models.py:175
msgid "full name" msgid "full name"
msgstr "nombre completo" msgstr "nombre completo"
#: core/models.py:170 #: core/models.py:177
msgid "short name" msgid "short name"
msgstr "nombre corto" msgstr "nombre corto"
#: core/models.py:176 #: core/models.py:183
msgid "language" msgid "language"
msgstr "idioma" msgstr "idioma"
#: core/models.py:177 #: core/models.py:184
msgid "The language in which the user wants to see the interface." msgid "The language in which the user wants to see the interface."
msgstr "El idioma preferido de interfaz." msgstr "El idioma preferido de interfaz."
#: core/models.py:183 #: core/models.py:190
msgid "The timezone in which the user wants to see times." msgid "The timezone in which the user wants to see times."
msgstr "La zona horaria en la que el usuario quiere ver las horas." msgstr "La zona horaria en la que el usuario quiere ver las horas."
#: core/models.py:190 #: core/models.py:193
msgid "default room access level"
msgstr ""
#: core/models.py:192
msgid ""
"Access level applied by default to new rooms created by this user. When "
"empty, the instance default is used."
msgstr ""
#: core/models.py:199
#, fuzzy
#| msgid "Visio room configuration"
msgid "default room configuration"
msgstr "Configuración de la videoconferencia"
#: core/models.py:201
msgid "Configurations applied by default to new rooms created by this user."
msgstr ""
#: core/models.py:205
msgid "device" msgid "device"
msgstr "dispositivo" msgstr "dispositivo"
#: core/models.py:207 #: core/models.py:195
msgid "Whether the user is a device or a real user." msgid "Whether the user is a device or a real user."
msgstr "Si el usuario es un dispositivo o un usuario real." msgstr "Si el usuario es un dispositivo o un usuario real."
#: core/models.py:210 #: core/models.py:198
msgid "staff status" msgid "staff status"
msgstr "estado del personal" msgstr "estado del personal"
#: core/models.py:212 #: core/models.py:200
msgid "Whether the user can log into this admin site." msgid "Whether the user can log into this admin site."
msgstr "Si el usuario puede acceder a este sitio de administración." msgstr "Si el usuario puede acceder a este sitio de administración."
#: core/models.py:215 #: core/models.py:203
msgid "active" msgid "active"
msgstr "activo" msgstr "activo"
#: core/models.py:218 #: core/models.py:206
msgid "" msgid ""
"Whether this user should be treated as active. Unselect this instead of " "Whether this user should be treated as active. Unselect this instead of "
"deleting accounts." "deleting accounts."
msgstr "" msgstr "Si este usuario debe considerarse activo. Desmarca esta opción en lugar de eliminar cuentas."
"Si este usuario debe considerarse activo. Desmarca esta opción en lugar de "
"eliminar cuentas."
#: core/models.py:231 #: core/models.py:219
msgid "user" msgid "user"
msgstr "usuario" msgstr "usuario"
#: core/models.py:232 #: core/models.py:220
msgid "users" msgid "users"
msgstr "usuarios" msgstr "usuarios"
#: core/models.py:298 #: core/models.py:286
msgid "Resource" msgid "Resource"
msgstr "Recurso" msgstr "Recurso"
#: core/models.py:299 #: core/models.py:287
msgid "Resources" msgid "Resources"
msgstr "Recursos" msgstr "Recursos"
#: core/models.py:357 #: core/models.py:345
msgid "Resource access" msgid "Resource access"
msgstr "Acceso a recursos" msgstr "Acceso a recursos"
#: core/models.py:358 #: core/models.py:346
msgid "Resource accesses" msgid "Resource accesses"
msgstr "Accesos a recursos" msgstr "Accesos a recursos"
#: core/models.py:364 #: core/models.py:352
msgid "Resource access with this User and Resource already exists." msgid "Resource access with this User and Resource already exists."
msgstr "Ya existe un acceso al recurso con este usuario y este recurso." msgstr "Ya existe un acceso al recurso con este usuario y este recurso."
#: core/models.py:421 #: core/models.py:409
msgid "Visio room configuration" msgid "Visio room configuration"
msgstr "Configuración de la videoconferencia" msgstr "Configuración de la videoconferencia"
#: core/models.py:422 #: core/models.py:410
msgid "Values for Visio parameters to configure the room." msgid "Values for Visio parameters to configure the room."
msgstr "" msgstr "Valores de los parámetros de videoconferencia para configurar la reunión."
"Valores de los parámetros de videoconferencia para configurar la reunión."
#: core/models.py:429 #: core/models.py:417
msgid "Room PIN code" msgid "Room PIN code"
msgstr "Código PIN de la reunión" msgstr "Código PIN de la reunión"
#: core/models.py:430 #: core/models.py:418
msgid "Unique n-digit code that identifies this room in telephony mode." msgid "Unique n-digit code that identifies this room in telephony mode."
msgstr "" msgstr "Código único de n dígitos que identifica esta reunión en modo telefónico."
"Código único de n dígitos que identifica esta reunión en modo telefónico."
#: core/models.py:436 core/models.py:597 #: core/models.py:424 core/models.py:578
msgid "Room" msgid "Room"
msgstr "Reunión" msgstr "Reunión"
#: core/models.py:437 #: core/models.py:425
msgid "Rooms" msgid "Rooms"
msgstr "Reuniones" msgstr "Reuniones"
#: core/models.py:608 #: core/models.py:589
msgid "Worker ID" msgid "Worker ID"
msgstr "ID del worker" msgstr "ID del worker"
#: core/models.py:610 #: core/models.py:591
msgid "" msgid ""
"Enter an identifier for the worker recording.This ID is retained even when " "Enter an identifier for the worker recording.This ID is retained even when "
"the worker stops, allowing for easy tracking." "the worker stops, allowing for easy tracking."
msgstr "" msgstr "Introduce un identificador para la grabación del worker. Este identificador se conserva incluso cuando el worker se detiene, lo que permite un seguimiento sencillo."
"Introduce un identificador para la grabación del worker. Este identificador "
"se conserva incluso cuando el worker se detiene, lo que permite un "
"seguimiento sencillo."
#: core/models.py:618 #: core/models.py:599
msgid "Recording mode" msgid "Recording mode"
msgstr "Modo de grabación" msgstr "Modo de grabación"
#: core/models.py:619 #: core/models.py:600
msgid "Defines the mode of recording being called." msgid "Defines the mode of recording being called."
msgstr "Define el modo de grabación a utilizar." msgstr "Define el modo de grabación a utilizar."
#: core/models.py:624 core/models.py:625 #: core/models.py:605 core/models.py:606
msgid "Recording options" msgid "Recording options"
msgstr "Opciones de grabación" msgstr "Opciones de grabación"
#: core/models.py:632 #: core/models.py:613
msgid "External Process ID" msgid "External Process ID"
msgstr "ID del proceso externo" msgstr "ID del proceso externo"
#: core/models.py:633 #: core/models.py:614
msgid "ID of the external process associated with the recording." msgid "ID of the external process associated with the recording."
msgstr "ID del proceso externo asociado a la grabación." msgstr "ID del proceso externo asociado a la grabación."
#: core/models.py:639 #: core/models.py:620
msgid "Recording" msgid "Recording"
msgstr "Grabación" msgstr "Grabación"
#: core/models.py:640 #: core/models.py:621
msgid "Recordings" msgid "Recordings"
msgstr "Grabaciones" msgstr "Grabaciones"
#: core/models.py:750 #: core/models.py:731
msgid "Recording/user relation" msgid "Recording/user relation"
msgstr "Relación grabación/usuario" msgstr "Relación grabación/usuario"
#: core/models.py:751 #: core/models.py:732
msgid "Recording/user relations" msgid "Recording/user relations"
msgstr "Relaciones grabación/usuario" msgstr "Relaciones grabación/usuario"
#: core/models.py:757 #: core/models.py:738
msgid "This user is already in this recording." msgid "This user is already in this recording."
msgstr "Este usuario ya está en esta grabación." msgstr "Este usuario ya está en esta grabación."
#: core/models.py:763 #: core/models.py:744
msgid "This team is already in this recording." msgid "This team is already in this recording."
msgstr "Este equipo ya está en esta grabación." msgstr "Este equipo ya está en esta grabación."
#: core/models.py:769 #: core/models.py:750
msgid "Either user or team must be set, not both." msgid "Either user or team must be set, not both."
msgstr "Debe definirse el usuario o el equipo, pero no ambos." msgstr "Debe definirse el usuario o el equipo, pero no ambos."
#: core/models.py:786 #: core/models.py:767
msgid "Create rooms" msgid "Create rooms"
msgstr "Crear reunión" msgstr "Crear reunión"
#: core/models.py:787 #: core/models.py:768
msgid "List rooms" msgid "List rooms"
msgstr "Listar reuniones" msgstr "Listar reuniones"
#: core/models.py:788 #: core/models.py:769
msgid "Retrieve room details" msgid "Retrieve room details"
msgstr "Ver los detalles de una reunión" msgstr "Ver los detalles de una reunión"
#: core/models.py:789 #: core/models.py:770
msgid "Update rooms" msgid "Update rooms"
msgstr "Actualizar las reuniones" msgstr "Actualizar las reuniones"
#: core/models.py:790 #: core/models.py:771
msgid "Delete rooms" msgid "Delete rooms"
msgstr "Eliminar las reuniones" msgstr "Eliminar las reuniones"
#: core/models.py:803 #: core/models.py:784
msgid "Application name" msgid "Application name"
msgstr "Nombre de la aplicación" msgstr "Nombre de la aplicación"
#: core/models.py:804 #: core/models.py:785
msgid "Descriptive name for this application." msgid "Descriptive name for this application."
msgstr "Nombre descriptivo de esta aplicación." msgstr "Nombre descriptivo de esta aplicación."
#: core/models.py:814 #: core/models.py:795
msgid "Hashed on Save. Copy it now if this is a new secret." msgid "Hashed on Save. Copy it now if this is a new secret."
msgstr "Se cifra al guardar. Cópialo ahora si se trata de un secreto nuevo." msgstr "Se cifra al guardar. Cópialo ahora si se trata de un secreto nuevo."
#: core/models.py:825 #: core/models.py:806
msgid "Application" msgid "Application"
msgstr "Aplicación" msgstr "Aplicación"
#: core/models.py:826 #: core/models.py:807
msgid "Applications" msgid "Applications"
msgstr "Aplicaciones" msgstr "Aplicaciones"
#: core/models.py:849 #: core/models.py:830
msgid "Enter a valid domain" msgid "Enter a valid domain"
msgstr "Introduce un dominio válido" msgstr "Introduce un dominio válido"
#: core/models.py:852 #: core/models.py:833
msgid "Domain" msgid "Domain"
msgstr "Dominio" msgstr "Dominio"
#: core/models.py:853 #: core/models.py:834
msgid "Email domain this application can act on behalf of." msgid "Email domain this application can act on behalf of."
msgstr "" msgstr "Dominio de correo electrónico en cuyo nombre puede actuar esta aplicación."
"Dominio de correo electrónico en cuyo nombre puede actuar esta aplicación."
#: core/models.py:865 #: core/models.py:846
msgid "Application domain" msgid "Application domain"
msgstr "Dominio de aplicación" msgstr "Dominio de aplicación"
#: core/models.py:866 #: core/models.py:847
msgid "Application domains" msgid "Application domains"
msgstr "Dominios de aplicación" msgstr "Dominios de aplicación"
#: core/models.py:884 #: core/models.py:865
msgid "Pending" msgid "Pending"
msgstr "Pendiente" msgstr "Pendiente"
#: core/models.py:885 #: core/models.py:866
msgid "Analyzing" msgid "Analyzing"
msgstr "Analizando" msgstr "Analizando"
#: core/models.py:892 #: core/models.py:873
msgid "Ready" msgid "Ready"
msgstr "Listo" msgstr "Listo"
#: core/models.py:898 #: core/models.py:879
msgid "Background image" msgid "Background image"
msgstr "Imagen de fondo" msgstr "Imagen de fondo"
#: core/models.py:910 #: core/models.py:891
msgid "title" msgid "title"
msgstr "título" msgstr "título"
#: core/models.py:934 #: core/models.py:915
msgid "Malware detection info when the analysis status is unsafe." msgid "Malware detection info when the analysis status is unsafe."
msgstr "" msgstr "Información sobre la detección de malware cuando el estado del análisis no es seguro."
"Información sobre la detección de malware cuando el estado del análisis no "
"es seguro."
#: core/models.py:939 #: core/models.py:920
msgid "File" msgid "File"
msgstr "Archivo" msgstr "Archivo"
#: core/models.py:940 #: core/models.py:921
msgid "Files" msgid "Files"
msgstr "Archivos" msgstr "Archivos"
#: core/models.py:1060 #: core/models.py:1041
msgid "This file is already hard deleted." msgid "This file is already hard deleted."
msgstr "Este archivo ya se ha eliminado definitivamente." msgstr "Este archivo ya se ha eliminado definitivamente."
#: core/models.py:1070 #: core/models.py:1051
msgid "To hard delete a file, it must first be soft deleted." msgid "To hard delete a file, it must first be soft deleted."
msgstr "" msgstr "Para eliminar definitivamente un archivo, primero debe haberse marcado como eliminado."
"Para eliminar definitivamente un archivo, primero debe haberse marcado como "
"eliminado."
#: core/recording/event/notification.py:124 #: core/recording/event/notification.py:123
msgid "Your recording is ready" msgid "Your recording is ready"
msgstr "Tu grabación está lista" msgstr "Tu grabación está lista"
#: core/recording/event/notification.py:195 #: core/recording/event/notification.py:194
msgid "Transcription" msgid "Transcription"
msgstr "Transcripción" msgstr "Transcripción"
#: core/recording/event/notification.py:206 #: core/recording/event/notification.py:204
#, python-brace-format #, python-brace-format
msgid "Meeting \"{room}\" on {room_recording_date} at {room_recording_time}" msgid "Meeting \"{room}\" on {room_recording_date} at {room_recording_time}"
msgstr "" msgstr "Reunión \"{room}\" del {room_recording_date} a las {room_recording_time}"
"Reunión \"{room}\" del {room_recording_date} a las {room_recording_time}"
#: core/services/invitation.py:44 #: core/services/invitation.py:44
#, python-brace-format #, python-brace-format
msgid "Video call in progress: {sender.email} is waiting for you to connect" msgid "Video call in progress: {sender.email} is waiting for you to connect"
msgstr "Videollamada en curso: {sender.email} está esperando a que te conectes" msgstr "Videollamada en curso: {sender.email} está esperando a que te conectes"
#: core/templates/mail/html/invitation.html:151 #: core/templates/mail/html/invitation.html:159
#: core/templates/mail/html/screen_recording.html:151 #: core/templates/mail/html/screen_recording.html:159
#: core/templates/mail/text/invitation.txt:4 #: core/templates/mail/text/invitation.txt:3
#: core/templates/mail/text/screen_recording.txt:4 #: core/templates/mail/text/screen_recording.txt:3
msgid "Logo email" msgid "Logo email"
msgstr "Logotipo del correo" msgstr "Logotipo del correo"
#: core/templates/mail/html/invitation.html:181 #: core/templates/mail/html/invitation.html:189
#: core/templates/mail/text/invitation.txt:6 #: core/templates/mail/text/invitation.txt:5
msgid "invites you to join an ongoing video call" msgid "invites you to join an ongoing video call"
msgstr "te invita a unirte a una videollamada en curso" msgstr "te invita a unirte a una videollamada en curso"
#: core/templates/mail/html/invitation.html:192 #: core/templates/mail/html/invitation.html:200
#: core/templates/mail/text/invitation.txt:8 #: core/templates/mail/text/invitation.txt:7
msgid "JOIN THE CALL" msgid "JOIN THE CALL"
msgstr "UNIRSE A LA LLAMADA" msgstr "UNIRSE A LA LLAMADA"
#: core/templates/mail/html/invitation.html:219 #: core/templates/mail/html/invitation.html:227
#: core/templates/mail/text/invitation.txt:14 #: core/templates/mail/text/invitation.txt:13
msgid "" msgid ""
"If you can't click the button, copy and paste the URL into your browser to " "If you can't click the button, copy and paste the URL into your browser to "
"join the call." "join the call."
msgstr "" msgstr "Si no puedes hacer clic en el botón, copia y pega la URL en tu navegador para unirte a la llamada."
"Si no puedes hacer clic en el botón, copia y pega la URL en tu navegador "
"para unirte a la llamada."
#: core/templates/mail/html/invitation.html:227 #: core/templates/mail/html/invitation.html:235
#: core/templates/mail/text/invitation.txt:16 #: core/templates/mail/text/invitation.txt:15
msgid "Tips for a better experience:" msgid "Tips for a better experience:"
msgstr "Consejos para una mejor experiencia:" msgstr "Consejos para una mejor experiencia:"
#: core/templates/mail/html/invitation.html:229 #: core/templates/mail/html/invitation.html:237
#: core/templates/mail/text/invitation.txt:18 #: core/templates/mail/text/invitation.txt:17
msgid "Use Chrome or Firefox for better call quality" msgid "Use Chrome or Firefox for better call quality"
msgstr "Usa Chrome o Firefox para una mejor calidad de llamada" msgstr "Usa Chrome o Firefox para una mejor calidad de llamada"
#: core/templates/mail/html/invitation.html:230 #: core/templates/mail/html/invitation.html:238
#: core/templates/mail/text/invitation.txt:19 #: core/templates/mail/text/invitation.txt:18
msgid "Test your microphone and camera before joining" msgid "Test your microphone and camera before joining"
msgstr "Prueba tu micrófono y tu cámara antes de unirte" msgstr "Prueba tu micrófono y tu cámara antes de unirte"
#: core/templates/mail/html/invitation.html:231 #: core/templates/mail/html/invitation.html:239
#: core/templates/mail/text/invitation.txt:20 #: core/templates/mail/text/invitation.txt:19
msgid "Make sure you have a stable internet connection" msgid "Make sure you have a stable internet connection"
msgstr "Asegúrate de tener una conexión a internet estable" msgstr "Asegúrate de tener una conexión a internet estable"
#: core/templates/mail/html/invitation.html:240 #: core/templates/mail/html/invitation.html:248
#: core/templates/mail/html/screen_recording.html:237 #: core/templates/mail/html/screen_recording.html:245
#: core/templates/mail/text/invitation.txt:22 #: core/templates/mail/text/invitation.txt:21
#: core/templates/mail/text/screen_recording.txt:24 #: core/templates/mail/text/screen_recording.txt:23
#, python-format #, python-format
msgid " Thank you for using %(brandname)s. " msgid " Thank you for using %(brandname)s. "
msgstr " Gracias por usar %(brandname)s. " msgstr " Gracias por usar %(brandname)s. "
#: core/templates/mail/html/invitation.html:271 #: core/templates/mail/html/screen_recording.html:188
#, python-format #: core/templates/mail/text/screen_recording.txt:6
msgid ""
"This mail has been sent to %(email)s by <a href=\"%(href)s\">%(name)s</a>"
msgstr ""
#: core/templates/mail/html/screen_recording.html:180
#: core/templates/mail/text/screen_recording.txt:7
msgid "Your recording is ready!" msgid "Your recording is ready!"
msgstr "¡Tu grabación está lista!" msgstr "¡Tu grabación está lista!"
#: core/templates/mail/html/screen_recording.html:187 #: core/templates/mail/html/screen_recording.html:195
#: core/templates/mail/text/screen_recording.txt:9 #: core/templates/mail/text/screen_recording.txt:8
#, python-format #, python-format
msgid "" msgid ""
" Your recording of \"%(room_name)s\" on %(recording_date)s at " " Your recording of \"%(room_name)s\" on %(recording_date)s at "
"%(recording_time)s is now ready to download. " "%(recording_time)s is now ready to download. "
msgstr "" msgstr " Tu grabación de \"%(room_name)s\" del %(recording_date)s a las %(recording_time)s ya está lista para descargar. "
" Tu grabación de \"%(room_name)s\" del %(recording_date)s a las "
"%(recording_time)s ya está lista para descargar. "
#: core/templates/mail/html/screen_recording.html:187 #: core/templates/mail/html/screen_recording.html:195
#: core/templates/mail/text/screen_recording.txt:9 #: core/templates/mail/text/screen_recording.txt:8
#, python-format #, python-format
msgid " The recording will expire in %(days)s days. " msgid " The recording will expire in %(days)s days. "
msgstr " La grabación caducará dentro de %(days)s días. " msgstr " La grabación caducará dentro de %(days)s días. "
#: core/templates/mail/html/screen_recording.html:192 #: core/templates/mail/html/screen_recording.html:200
#: core/templates/mail/text/screen_recording.txt:10 #: core/templates/mail/text/screen_recording.txt:9
msgid "" msgid ""
" Sharing the recording via link is not yet available. Only organizers can " " Sharing the recording via link is not yet available. Only organizers can "
"download it. " "download it. "
msgstr "" msgstr " Compartir la grabación mediante un enlace todavía no está disponible. Solo los organizadores pueden descargarla. "
" Compartir la grabación mediante un enlace todavía no está disponible. Solo "
"los organizadores pueden descargarla. "
#: core/templates/mail/html/screen_recording.html:198 #: core/templates/mail/html/screen_recording.html:206
#: core/templates/mail/text/screen_recording.txt:12 #: core/templates/mail/text/screen_recording.txt:11
msgid "To keep this recording permanently:" msgid "To keep this recording permanently:"
msgstr "Para conservar esta grabación de forma permanente:" msgstr "Para conservar esta grabación de forma permanente:"
#: core/templates/mail/html/screen_recording.html:200 #: core/templates/mail/html/screen_recording.html:208
#, python-format #, python-format
msgid "Click the \"<a href=\"%(link)s\">Open</a>\" link below " msgid "Click the \"<a href=\"%(link)s\">Open</a>\" link below "
msgstr "" msgstr "Haz clic en el enlace \"<a href=\"%(link)s\">Abrir</a>\" que aparece abajo "
"Haz clic en el enlace \"<a href=\"%(link)s\">Abrir</a>\" que aparece abajo "
#: core/templates/mail/html/screen_recording.html:201 #: core/templates/mail/html/screen_recording.html:209
#: core/templates/mail/text/screen_recording.txt:15 #: core/templates/mail/text/screen_recording.txt:14
msgid "Use the \"Download\" button in the interface " msgid "Use the \"Download\" button in the interface "
msgstr "Usa el botón \"Descargar\" de la interfaz " msgstr "Usa el botón \"Descargar\" de la interfaz "
#: core/templates/mail/html/screen_recording.html:202 #: core/templates/mail/html/screen_recording.html:210
#: core/templates/mail/text/screen_recording.txt:16 #: core/templates/mail/text/screen_recording.txt:15
msgid "Save the file to your preferred location" msgid "Save the file to your preferred location"
msgstr "Guarda el archivo en la ubicación que prefieras" msgstr "Guarda el archivo en la ubicación que prefieras"
#: core/templates/mail/html/screen_recording.html:213 #: core/templates/mail/html/screen_recording.html:221
#: core/templates/mail/text/screen_recording.txt:18 #: core/templates/mail/text/screen_recording.txt:17
msgid "Open" msgid "Open"
msgstr "Abrir" msgstr "Abrir"
#: core/templates/mail/html/screen_recording.html:222 #: core/templates/mail/html/screen_recording.html:230
#: core/templates/mail/text/screen_recording.txt:20 #: core/templates/mail/text/screen_recording.txt:19
#, python-format #, python-format
msgid "" msgid ""
" If you have any questions or need assistance, please contact our support " " If you have any questions or need assistance, please contact our support "
"team at %(support_email)s. " "team at %(support_email)s. "
msgstr "" msgstr " Si tienes alguna pregunta o necesitas ayuda, ponte en contacto con nuestro equipo de soporte en %(support_email)s. "
" Si tienes alguna pregunta o necesitas ayuda, ponte en contacto con nuestro "
"equipo de soporte en %(support_email)s. "
#: core/templates/mail/text/invitation.txt:24 #: core/templates/mail/text/screen_recording.txt:13
#, python-format
msgid "This mail has been sent to %(email)s by %(name)s [%(href)s]"
msgstr ""
#: core/templates/mail/text/screen_recording.txt:14
#, python-format #, python-format
msgid "Click the \"Open [%(link)s]\" link below " msgid "Click the \"Open [%(link)s]\" link below "
msgstr "Haz clic en el enlace \"Abrir [%(link)s]\" que aparece abajo " msgstr "Haz clic en el enlace \"Abrir [%(link)s]\" que aparece abajo "
#: meet/settings.py:238 #: meet/settings.py:228
msgid "English" msgid "English"
msgstr "Inglés" msgstr "Inglés"
#: meet/settings.py:239 #: meet/settings.py:229
msgid "French" msgid "French"
msgstr "Francés" msgstr "Francés"
#: meet/settings.py:240 #: meet/settings.py:230
msgid "Dutch" msgid "Dutch"
msgstr "Neerlandés" msgstr "Neerlandés"
#: meet/settings.py:241 #: meet/settings.py:231
msgid "German" msgid "German"
msgstr "Alemán" msgstr "Alemán"
#: meet/settings.py:242 #: meet/settings.py:233
msgid "Spanish" msgid "Spanish"
msgstr "Español" msgstr "Español"
+160 -187
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-02 22:52+0000\n" "POT-Creation-Date: 2026-07-02 10:47+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: antoine.lebaud@mail.numerique.gouv.fr\n" "Last-Translator: antoine.lebaud@mail.numerique.gouv.fr\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -51,11 +51,11 @@ msgstr ""
msgid "File preview" msgid "File preview"
msgstr "" msgstr ""
#: core/admin.py:300 core/admin.py:450 #: core/admin.py:300 core/admin.py:443
msgid "No owner" msgid "No owner"
msgstr "Pas de propriétaire" msgstr "Pas de propriétaire"
#: core/admin.py:303 core/admin.py:453 #: core/admin.py:303 core/admin.py:446
msgid "Multiple owners" msgid "Multiple owners"
msgstr "Plusieurs propriétaires" msgstr "Plusieurs propriétaires"
@@ -99,11 +99,11 @@ msgstr ""
msgid "Skipped %(count)s recording(s) with an ineligible status." msgid "Skipped %(count)s recording(s) with an ineligible status."
msgstr "%(count)s enregistrement(s) avec un statut inéligible ignoré(s)." msgstr "%(count)s enregistrement(s) avec un statut inéligible ignoré(s)."
#: core/admin.py:517 #: core/admin.py:510
msgid "No scopes" msgid "No scopes"
msgstr "Aucun scopes" msgstr "Aucun scopes"
#: core/admin.py:519 #: core/admin.py:512
msgid "Scopes" msgid "Scopes"
msgstr "Scopes" msgstr "Scopes"
@@ -111,203 +111,187 @@ msgstr "Scopes"
msgid "Creator is me" msgid "Creator is me"
msgstr "Je suis le créateur" msgstr "Je suis le créateur"
#: core/api/serializers.py:108 #: core/api/serializers.py:89
msgid "You must be administrator or owner of a room to add accesses to it." msgid "You must be administrator or owner of a room to add accesses to it."
msgstr "" msgstr ""
"Vous devez être administrateur ou propriétaire d'une salle pour y ajouter " "Vous devez être administrateur ou propriétaire d'une salle pour y ajouter "
"des accès." "des accès."
#: core/api/serializers.py:560 #: core/api/serializers.py:534
msgid "This file extension is not allowed." msgid "This file extension is not allowed."
msgstr "Cette extension n'est pas autorisée" msgstr "Cette extension n'est pas autorisée"
#: core/api/viewsets.py:1268 #: core/api/viewsets.py:1222
msgid "You have reached the maximum number of files for this type." msgid "You have reached the maximum number of files for this type."
msgstr "Vous avez atteint le nombre maximum de fichiers de ce type" msgstr "Vous avez atteint le nombre maximum de fichiers de ce type"
#: core/models.py:38 #: core/models.py:37
msgid "Member" msgid "Member"
msgstr "Membre" msgstr "Membre"
#: core/models.py:39 #: core/models.py:38
msgid "Administrator" msgid "Administrator"
msgstr "Administrateur" msgstr "Administrateur"
#: core/models.py:40 #: core/models.py:39
msgid "Owner" msgid "Owner"
msgstr "Propriétaire" msgstr "Propriétaire"
#: core/models.py:56 #: core/models.py:55
msgid "Initiated" msgid "Initiated"
msgstr "Initié" msgstr "Initié"
#: core/models.py:57 #: core/models.py:56
msgid "Active" msgid "Active"
msgstr "Actif" msgstr "Actif"
#: core/models.py:58 #: core/models.py:57
msgid "Stopped" msgid "Stopped"
msgstr "Arrêté" msgstr "Arrêté"
#: core/models.py:59 #: core/models.py:58
msgid "Saved" msgid "Saved"
msgstr "Enregistré" msgstr "Enregistré"
#: core/models.py:60 #: core/models.py:59
msgid "Aborted" msgid "Aborted"
msgstr "Abandonné" msgstr "Abandonné"
#: core/models.py:61 #: core/models.py:60
msgid "Failed to Start" msgid "Failed to Start"
msgstr "Échec au démarrage" msgstr "Échec au démarrage"
#: core/models.py:62 #: core/models.py:61
msgid "Failed to Stop" msgid "Failed to Stop"
msgstr "Échec à l'arrêt" msgstr "Échec à l'arrêt"
#: core/models.py:63 #: core/models.py:62
msgid "Notification succeeded" msgid "Notification succeeded"
msgstr "Notification réussie" msgstr "Notification réussie"
#: core/models.py:66 #: core/models.py:65
msgid "External process successful" msgid "External process successful"
msgstr "Traitement externe : succès" msgstr "Traitement externe : succès"
#: core/models.py:68 #: core/models.py:67
msgid "External process failed" msgid "External process failed"
msgstr "Traitement externe : erreur" msgstr "Traitement externe : erreur"
#: core/models.py:97 #: core/models.py:96
msgid "SCREEN_RECORDING" msgid "SCREEN_RECORDING"
msgstr "ENREGISTREMENT_ÉCRAN" msgstr "ENREGISTREMENT_ÉCRAN"
#: core/models.py:98 #: core/models.py:97
msgid "TRANSCRIPT" msgid "TRANSCRIPT"
msgstr "TRANSCRIPTION" msgstr "TRANSCRIPTION"
#: core/models.py:104 #: core/models.py:103
msgid "Public Access" msgid "Public Access"
msgstr "Accès public" msgstr "Accès public"
#: core/models.py:105 #: core/models.py:104
msgid "Trusted Access" msgid "Trusted Access"
msgstr "Accès de confiance" msgstr "Accès de confiance"
#: core/models.py:106 #: core/models.py:105
msgid "Restricted Access" msgid "Restricted Access"
msgstr "Accès restreint" msgstr "Accès restreint"
#: core/models.py:118 #: core/models.py:117
msgid "id" msgid "id"
msgstr "id" msgstr "id"
#: core/models.py:119 #: core/models.py:118
msgid "primary key for the record as UUID" msgid "primary key for the record as UUID"
msgstr "clé primaire pour l'enregistrement sous forme d'UUID" msgstr "clé primaire pour l'enregistrement sous forme d'UUID"
#: core/models.py:125 #: core/models.py:124
msgid "created on" msgid "created on"
msgstr "créé le" msgstr "créé le"
#: core/models.py:126 #: core/models.py:125
msgid "date and time at which a record was created" msgid "date and time at which a record was created"
msgstr "date et heure auxquelles un enregistrement a été créé" msgstr "date et heure auxquelles un enregistrement a été créé"
#: core/models.py:131 #: core/models.py:130
msgid "updated on" msgid "updated on"
msgstr "mis à jour le" msgstr "mis à jour le"
#: core/models.py:132 #: core/models.py:131
msgid "date and time at which a record was last updated" msgid "date and time at which a record was last updated"
msgstr "" msgstr ""
"date et heure auxquelles un enregistrement a été mis à jour pour la dernière " "date et heure auxquelles un enregistrement a été mis à jour pour la dernière "
"fois" "fois"
#: core/models.py:150 #: core/models.py:151
msgid ""
"Enter a valid sub. This value may contain only letters, numbers, and @/./+/-/"
"_ characters."
msgstr ""
"Entrez un sub valide. Cette valeur ne peut contenir que des lettres, des "
"chiffres et les caractères @/./+/-/_."
#: core/models.py:157
msgid "sub" msgid "sub"
msgstr "sub" msgstr "sub"
#: core/models.py:152 #: core/models.py:159
msgid "" msgid ""
"Optional for pending users; required upon account activation. 255 characters " "Optional for pending users; required upon account activation. 255 characters "
"or fewer. Printable ASCII characters only." "or fewer. Letters, numbers, and @/./+/-/_ characters only."
msgstr "" msgstr ""
"Facultatif pour les utilisateurs en attente ; obligatoire lors de lactivation " "Optionnel pour les utilisateurs en attente ; requis lors de l'activation du "
"du compte. 255 caractères maximum. Caractères ASCII imprimables uniquement." "compte. 255 caractères maximum. Lettres, chiffres et @/./+/-/_ uniquement."
#: core/validators.py:22 #: core/models.py:168
msgid "Enter a valid sub. This value should be printable ASCII only."
msgstr "Saisissez un sub valide. Cette valeur ne doit contenir que des caractères ASCII imprimables."
#: core/models.py:161
msgid "identity email address" msgid "identity email address"
msgstr "adresse e-mail d'identité" msgstr "adresse e-mail d'identité"
#: core/models.py:166 #: core/models.py:173
msgid "admin email address" msgid "admin email address"
msgstr "adresse e-mail d'administrateur" msgstr "adresse e-mail d'administrateur"
#: core/models.py:168 #: core/models.py:175
msgid "full name" msgid "full name"
msgstr "nom complet" msgstr "nom complet"
#: core/models.py:170 #: core/models.py:177
msgid "short name" msgid "short name"
msgstr "nom court" msgstr "nom court"
#: core/models.py:176 #: core/models.py:183
msgid "language" msgid "language"
msgstr "langue" msgstr "langue"
#: core/models.py:177 #: core/models.py:184
msgid "The language in which the user wants to see the interface." msgid "The language in which the user wants to see the interface."
msgstr "La langue dans laquelle l'utilisateur souhaite voir l'interface." msgstr "La langue dans laquelle l'utilisateur souhaite voir l'interface."
#: core/models.py:183 #: core/models.py:190
msgid "The timezone in which the user wants to see times." msgid "The timezone in which the user wants to see times."
msgstr "Le fuseau horaire dans lequel l'utilisateur souhaite voir les heures." msgstr "Le fuseau horaire dans lequel l'utilisateur souhaite voir les heures."
#: core/models.py:190 #: core/models.py:193
msgid "default room access level"
msgstr ""
#: core/models.py:192
msgid ""
"Access level applied by default to new rooms created by this user. When "
"empty, the instance default is used."
msgstr ""
#: core/models.py:199
#, fuzzy
#| msgid "Visio room configuration"
msgid "default room configuration"
msgstr "Configuration de la salle de visioconférence"
#: core/models.py:201
msgid "Configurations applied by default to new rooms created by this user."
msgstr ""
#: core/models.py:205
msgid "device" msgid "device"
msgstr "appareil" msgstr "appareil"
#: core/models.py:207 #: core/models.py:195
msgid "Whether the user is a device or a real user." msgid "Whether the user is a device or a real user."
msgstr "Si l'utilisateur est un appareil ou un utilisateur réel." msgstr "Si l'utilisateur est un appareil ou un utilisateur réel."
#: core/models.py:210 #: core/models.py:198
msgid "staff status" msgid "staff status"
msgstr "statut du personnel" msgstr "statut du personnel"
#: core/models.py:212 #: core/models.py:200
msgid "Whether the user can log into this admin site." msgid "Whether the user can log into this admin site."
msgstr "Si l'utilisateur peut se connecter à ce site d'administration." msgstr "Si l'utilisateur peut se connecter à ce site d'administration."
#: core/models.py:215 #: core/models.py:203
msgid "active" msgid "active"
msgstr "actif" msgstr "actif"
#: core/models.py:218 #: core/models.py:206
msgid "" msgid ""
"Whether this user should be treated as active. Unselect this instead of " "Whether this user should be treated as active. Unselect this instead of "
"deleting accounts." "deleting accounts."
@@ -315,65 +299,65 @@ msgstr ""
"Si cet utilisateur doit être traité comme actif. Désélectionnez cette option " "Si cet utilisateur doit être traité comme actif. Désélectionnez cette option "
"au lieu de supprimer des comptes." "au lieu de supprimer des comptes."
#: core/models.py:231 #: core/models.py:219
msgid "user" msgid "user"
msgstr "utilisateur" msgstr "utilisateur"
#: core/models.py:232 #: core/models.py:220
msgid "users" msgid "users"
msgstr "utilisateurs" msgstr "utilisateurs"
#: core/models.py:298 #: core/models.py:286
msgid "Resource" msgid "Resource"
msgstr "Ressource" msgstr "Ressource"
#: core/models.py:299 #: core/models.py:287
msgid "Resources" msgid "Resources"
msgstr "Ressources" msgstr "Ressources"
#: core/models.py:357 #: core/models.py:345
msgid "Resource access" msgid "Resource access"
msgstr "Accès aux ressources" msgstr "Accès aux ressources"
#: core/models.py:358 #: core/models.py:346
msgid "Resource accesses" msgid "Resource accesses"
msgstr "Accès aux ressources" msgstr "Accès aux ressources"
#: core/models.py:364 #: core/models.py:352
msgid "Resource access with this User and Resource already exists." msgid "Resource access with this User and Resource already exists."
msgstr "" msgstr ""
"L'accès à la ressource avec cet utilisateur et cette ressource existe déjà." "L'accès à la ressource avec cet utilisateur et cette ressource existe déjà."
#: core/models.py:421 #: core/models.py:409
msgid "Visio room configuration" msgid "Visio room configuration"
msgstr "Configuration de la salle de visioconférence" msgstr "Configuration de la salle de visioconférence"
#: core/models.py:422 #: core/models.py:410
msgid "Values for Visio parameters to configure the room." msgid "Values for Visio parameters to configure the room."
msgstr "Valeurs des paramètres de visioconférence pour configurer la salle." msgstr "Valeurs des paramètres de visioconférence pour configurer la salle."
#: core/models.py:429 #: core/models.py:417
msgid "Room PIN code" msgid "Room PIN code"
msgstr "Code PIN de la salle" msgstr "Code PIN de la salle"
#: core/models.py:430 #: core/models.py:418
msgid "Unique n-digit code that identifies this room in telephony mode." msgid "Unique n-digit code that identifies this room in telephony mode."
msgstr "" msgstr ""
"Code unique à n chiffres qui identifie cette salle en mode téléphonique." "Code unique à n chiffres qui identifie cette salle en mode téléphonique."
#: core/models.py:436 core/models.py:597 #: core/models.py:424 core/models.py:578
msgid "Room" msgid "Room"
msgstr "Salle" msgstr "Salle"
#: core/models.py:437 #: core/models.py:425
msgid "Rooms" msgid "Rooms"
msgstr "Salles" msgstr "Salles"
#: core/models.py:608 #: core/models.py:589
msgid "Worker ID" msgid "Worker ID"
msgstr "ID du Worker" msgstr "ID du Worker"
#: core/models.py:610 #: core/models.py:591
msgid "" msgid ""
"Enter an identifier for the worker recording.This ID is retained even when " "Enter an identifier for the worker recording.This ID is retained even when "
"the worker stops, allowing for easy tracking." "the worker stops, allowing for easy tracking."
@@ -381,170 +365,170 @@ msgstr ""
"Entrez un identifiant pour l'enregistrement du Worker. Cet identifiant est " "Entrez un identifiant pour l'enregistrement du Worker. Cet identifiant est "
"conservé même lorsque le Worker s'arrête, permettant un suivi facile." "conservé même lorsque le Worker s'arrête, permettant un suivi facile."
#: core/models.py:618 #: core/models.py:599
msgid "Recording mode" msgid "Recording mode"
msgstr "Mode d'enregistrement" msgstr "Mode d'enregistrement"
#: core/models.py:619 #: core/models.py:600
msgid "Defines the mode of recording being called." msgid "Defines the mode of recording being called."
msgstr "Définit le mode d'enregistrement appelé." msgstr "Définit le mode d'enregistrement appelé."
#: core/models.py:624 core/models.py:625 #: core/models.py:605 core/models.py:606
msgid "Recording options" msgid "Recording options"
msgstr "Options d'enregistrement" msgstr "Options d'enregistrement"
#: core/models.py:632 #: core/models.py:613
msgid "External Process ID" msgid "External Process ID"
msgstr "ID Traitement externe" msgstr "ID Traitement externe"
#: core/models.py:633 #: core/models.py:614
msgid "ID of the external process associated with the recording." msgid "ID of the external process associated with the recording."
msgstr "ID du traitement externe associé avec l'enregistrement." msgstr "ID du traitement externe associé avec l'enregistrement."
#: core/models.py:639 #: core/models.py:620
msgid "Recording" msgid "Recording"
msgstr "Enregistrement" msgstr "Enregistrement"
#: core/models.py:640 #: core/models.py:621
msgid "Recordings" msgid "Recordings"
msgstr "Enregistrements" msgstr "Enregistrements"
#: core/models.py:750 #: core/models.py:731
msgid "Recording/user relation" msgid "Recording/user relation"
msgstr "Relation enregistrement/utilisateur" msgstr "Relation enregistrement/utilisateur"
#: core/models.py:751 #: core/models.py:732
msgid "Recording/user relations" msgid "Recording/user relations"
msgstr "Relations enregistrement/utilisateur" msgstr "Relations enregistrement/utilisateur"
#: core/models.py:757 #: core/models.py:738
msgid "This user is already in this recording." msgid "This user is already in this recording."
msgstr "Cet utilisateur est déjà dans cet enregistrement." msgstr "Cet utilisateur est déjà dans cet enregistrement."
#: core/models.py:763 #: core/models.py:744
msgid "This team is already in this recording." msgid "This team is already in this recording."
msgstr "Cette équipe est déjà dans cet enregistrement." msgstr "Cette équipe est déjà dans cet enregistrement."
#: core/models.py:769 #: core/models.py:750
msgid "Either user or team must be set, not both." msgid "Either user or team must be set, not both."
msgstr "Soit l'utilisateur, soit l'équipe doit être défini, pas les deux." msgstr "Soit l'utilisateur, soit l'équipe doit être défini, pas les deux."
#: core/models.py:786 #: core/models.py:767
msgid "Create rooms" msgid "Create rooms"
msgstr "Créer des salles" msgstr "Créer des salles"
#: core/models.py:787 #: core/models.py:768
msgid "List rooms" msgid "List rooms"
msgstr "Lister les salles" msgstr "Lister les salles"
#: core/models.py:788 #: core/models.py:769
msgid "Retrieve room details" msgid "Retrieve room details"
msgstr "Afficher les détails dune salle" msgstr "Afficher les détails dune salle"
#: core/models.py:789 #: core/models.py:770
msgid "Update rooms" msgid "Update rooms"
msgstr "Mettre à jour les salles" msgstr "Mettre à jour les salles"
#: core/models.py:790 #: core/models.py:771
msgid "Delete rooms" msgid "Delete rooms"
msgstr "Supprimer les salles" msgstr "Supprimer les salles"
#: core/models.py:803 #: core/models.py:784
msgid "Application name" msgid "Application name"
msgstr "Nom de lapplication" msgstr "Nom de lapplication"
#: core/models.py:804 #: core/models.py:785
msgid "Descriptive name for this application." msgid "Descriptive name for this application."
msgstr "Nom descriptif de cette application." msgstr "Nom descriptif de cette application."
#: core/models.py:814 #: core/models.py:795
msgid "Hashed on Save. Copy it now if this is a new secret." msgid "Hashed on Save. Copy it now if this is a new secret."
msgstr "" msgstr ""
"Haché lors de lenregistrement. Copiez-le maintenant sil sagit dun " "Haché lors de lenregistrement. Copiez-le maintenant sil sagit dun "
"nouveau secret." "nouveau secret."
#: core/models.py:825 #: core/models.py:806
msgid "Application" msgid "Application"
msgstr "Application" msgstr "Application"
#: core/models.py:826 #: core/models.py:807
msgid "Applications" msgid "Applications"
msgstr "Applications" msgstr "Applications"
#: core/models.py:849 #: core/models.py:830
msgid "Enter a valid domain" msgid "Enter a valid domain"
msgstr "Saisissez un domaine valide" msgstr "Saisissez un domaine valide"
#: core/models.py:852 #: core/models.py:833
msgid "Domain" msgid "Domain"
msgstr "Domaine" msgstr "Domaine"
#: core/models.py:853 #: core/models.py:834
msgid "Email domain this application can act on behalf of." msgid "Email domain this application can act on behalf of."
msgstr "Domaine de messagerie au nom duquel cette application peut agir." msgstr "Domaine de messagerie au nom duquel cette application peut agir."
#: core/models.py:865 #: core/models.py:846
msgid "Application domain" msgid "Application domain"
msgstr "Domaine dapplication" msgstr "Domaine dapplication"
#: core/models.py:866 #: core/models.py:847
msgid "Application domains" msgid "Application domains"
msgstr "Domaines dapplication" msgstr "Domaines dapplication"
#: core/models.py:884 #: core/models.py:865
msgid "Pending" msgid "Pending"
msgstr "En attente" msgstr "En attente"
#: core/models.py:885 #: core/models.py:866
msgid "Analyzing" msgid "Analyzing"
msgstr "" msgstr ""
#: core/models.py:892 #: core/models.py:873
msgid "Ready" msgid "Ready"
msgstr "Prêt" msgstr "Prêt"
#: core/models.py:898 #: core/models.py:879
msgid "Background image" msgid "Background image"
msgstr "Image de fond" msgstr "Image de fond"
#: core/models.py:910 #: core/models.py:891
msgid "title" msgid "title"
msgstr "Titre" msgstr "Titre"
#: core/models.py:934 #: core/models.py:915
msgid "Malware detection info when the analysis status is unsafe." msgid "Malware detection info when the analysis status is unsafe."
msgstr "" msgstr ""
"Information concernant la détection de Malware cand le statut n'est pas sain" "Information concernant la détection de Malware cand le statut n'est pas sain"
#: core/models.py:939 #: core/models.py:920
msgid "File" msgid "File"
msgstr "Fichier" msgstr "Fichier"
#: core/models.py:940 #: core/models.py:921
msgid "Files" msgid "Files"
msgstr "Fichiers" msgstr "Fichiers"
#: core/models.py:1060 #: core/models.py:1041
#, fuzzy #, fuzzy
#| msgid "This user is already in this recording." #| msgid "This user is already in this recording."
msgid "This file is already hard deleted." msgid "This file is already hard deleted."
msgstr "Ce fichier a été supprimé." msgstr "Ce fichier a été supprimé."
#: core/models.py:1070 #: core/models.py:1051
msgid "To hard delete a file, it must first be soft deleted." msgid "To hard delete a file, it must first be soft deleted."
msgstr "" msgstr ""
"Pour supprimer définitivement un fichier il doit d'abord avoir été marqué " "Pour supprimer définitivement un fichier il doit d'abord avoir été marqué "
"comme supprimé (soft delete)" "comme supprimé (soft delete)"
#: core/recording/event/notification.py:124 #: core/recording/event/notification.py:123
msgid "Your recording is ready" msgid "Your recording is ready"
msgstr "Votre enregistrement est prêt" msgstr "Votre enregistrement est prêt"
#: core/recording/event/notification.py:195 #: core/recording/event/notification.py:194
msgid "Transcription" msgid "Transcription"
msgstr "Transcription" msgstr "Transcription"
#: core/recording/event/notification.py:206 #: core/recording/event/notification.py:204
#, python-brace-format #, python-brace-format
msgid "Meeting \"{room}\" on {room_recording_date} at {room_recording_time}" msgid "Meeting \"{room}\" on {room_recording_date} at {room_recording_time}"
msgstr "Réunion \"{room}\" du {room_recording_date} à {room_recording_time}" msgstr "Réunion \"{room}\" du {room_recording_date} à {room_recording_time}"
@@ -554,25 +538,25 @@ msgstr "Réunion \"{room}\" du {room_recording_date} à {room_recording_time}"
msgid "Video call in progress: {sender.email} is waiting for you to connect" msgid "Video call in progress: {sender.email} is waiting for you to connect"
msgstr "Appel vidéo en cours : {sender.email} attend que vous vous connectiez" msgstr "Appel vidéo en cours : {sender.email} attend que vous vous connectiez"
#: core/templates/mail/html/invitation.html:151 #: core/templates/mail/html/invitation.html:159
#: core/templates/mail/html/screen_recording.html:151 #: core/templates/mail/html/screen_recording.html:159
#: core/templates/mail/text/invitation.txt:4 #: core/templates/mail/text/invitation.txt:3
#: core/templates/mail/text/screen_recording.txt:4 #: core/templates/mail/text/screen_recording.txt:3
msgid "Logo email" msgid "Logo email"
msgstr "Logo email" msgstr "Logo email"
#: core/templates/mail/html/invitation.html:181 #: core/templates/mail/html/invitation.html:189
#: core/templates/mail/text/invitation.txt:6 #: core/templates/mail/text/invitation.txt:5
msgid "invites you to join an ongoing video call" msgid "invites you to join an ongoing video call"
msgstr "vous invite à rejoindre un appel vidéo en cours" msgstr "vous invite à rejoindre un appel vidéo en cours"
#: core/templates/mail/html/invitation.html:192 #: core/templates/mail/html/invitation.html:200
#: core/templates/mail/text/invitation.txt:8 #: core/templates/mail/text/invitation.txt:7
msgid "JOIN THE CALL" msgid "JOIN THE CALL"
msgstr "REJOINDRE L'APPEL" msgstr "REJOINDRE L'APPEL"
#: core/templates/mail/html/invitation.html:219 #: core/templates/mail/html/invitation.html:227
#: core/templates/mail/text/invitation.txt:14 #: core/templates/mail/text/invitation.txt:13
msgid "" msgid ""
"If you can't click the button, copy and paste the URL into your browser to " "If you can't click the button, copy and paste the URL into your browser to "
"join the call." "join the call."
@@ -580,47 +564,41 @@ msgstr ""
"Si vous ne pouvez pas cliquer sur le bouton, copiez et collez l'URL dans " "Si vous ne pouvez pas cliquer sur le bouton, copiez et collez l'URL dans "
"votre navigateur pour rejoindre l'appel." "votre navigateur pour rejoindre l'appel."
#: core/templates/mail/html/invitation.html:227 #: core/templates/mail/html/invitation.html:235
#: core/templates/mail/text/invitation.txt:16 #: core/templates/mail/text/invitation.txt:15
msgid "Tips for a better experience:" msgid "Tips for a better experience:"
msgstr "Conseils pour une meilleure expérience :" msgstr "Conseils pour une meilleure expérience :"
#: core/templates/mail/html/invitation.html:229 #: core/templates/mail/html/invitation.html:237
#: core/templates/mail/text/invitation.txt:18 #: core/templates/mail/text/invitation.txt:17
msgid "Use Chrome or Firefox for better call quality" msgid "Use Chrome or Firefox for better call quality"
msgstr "Utilisez Chrome ou Firefox pour une meilleure qualité d'appel" msgstr "Utilisez Chrome ou Firefox pour une meilleure qualité d'appel"
#: core/templates/mail/html/invitation.html:230 #: core/templates/mail/html/invitation.html:238
#: core/templates/mail/text/invitation.txt:19 #: core/templates/mail/text/invitation.txt:18
msgid "Test your microphone and camera before joining" msgid "Test your microphone and camera before joining"
msgstr "Testez votre microphone et votre caméra avant de rejoindre" msgstr "Testez votre microphone et votre caméra avant de rejoindre"
#: core/templates/mail/html/invitation.html:231 #: core/templates/mail/html/invitation.html:239
#: core/templates/mail/text/invitation.txt:20 #: core/templates/mail/text/invitation.txt:19
msgid "Make sure you have a stable internet connection" msgid "Make sure you have a stable internet connection"
msgstr "Assurez-vous d'avoir une connexion Internet stable" msgstr "Assurez-vous d'avoir une connexion Internet stable"
#: core/templates/mail/html/invitation.html:240 #: core/templates/mail/html/invitation.html:248
#: core/templates/mail/html/screen_recording.html:237 #: core/templates/mail/html/screen_recording.html:245
#: core/templates/mail/text/invitation.txt:22 #: core/templates/mail/text/invitation.txt:21
#: core/templates/mail/text/screen_recording.txt:24 #: core/templates/mail/text/screen_recording.txt:23
#, python-format #, python-format
msgid " Thank you for using %(brandname)s. " msgid " Thank you for using %(brandname)s. "
msgstr " Merci d'utiliser %(brandname)s. " msgstr " Merci d'utiliser %(brandname)s. "
#: core/templates/mail/html/invitation.html:271 #: core/templates/mail/html/screen_recording.html:188
#, python-format #: core/templates/mail/text/screen_recording.txt:6
msgid ""
"This mail has been sent to %(email)s by <a href=\"%(href)s\">%(name)s</a>"
msgstr ""
#: core/templates/mail/html/screen_recording.html:180
#: core/templates/mail/text/screen_recording.txt:7
msgid "Your recording is ready!" msgid "Your recording is ready!"
msgstr "Votre enregistrement est prêt !" msgstr "Votre enregistrement est prêt !"
#: core/templates/mail/html/screen_recording.html:187 #: core/templates/mail/html/screen_recording.html:195
#: core/templates/mail/text/screen_recording.txt:9 #: core/templates/mail/text/screen_recording.txt:8
#, python-format #, python-format
msgid "" msgid ""
" Your recording of \"%(room_name)s\" on %(recording_date)s at " " Your recording of \"%(room_name)s\" on %(recording_date)s at "
@@ -629,14 +607,14 @@ msgstr ""
" Votre enregistrement de \"%(room_name)s\" du %(recording_date)s à " " Votre enregistrement de \"%(room_name)s\" du %(recording_date)s à "
"%(recording_time)s est maintenant prêt à être téléchargé. " "%(recording_time)s est maintenant prêt à être téléchargé. "
#: core/templates/mail/html/screen_recording.html:187 #: core/templates/mail/html/screen_recording.html:195
#: core/templates/mail/text/screen_recording.txt:9 #: core/templates/mail/text/screen_recording.txt:8
#, python-format #, python-format
msgid " The recording will expire in %(days)s days. " msgid " The recording will expire in %(days)s days. "
msgstr " L'enregistrement expirera dans %(days)s jours. " msgstr " L'enregistrement expirera dans %(days)s jours. "
#: core/templates/mail/html/screen_recording.html:192 #: core/templates/mail/html/screen_recording.html:200
#: core/templates/mail/text/screen_recording.txt:10 #: core/templates/mail/text/screen_recording.txt:9
msgid "" msgid ""
" Sharing the recording via link is not yet available. Only organizers can " " Sharing the recording via link is not yet available. Only organizers can "
"download it. " "download it. "
@@ -644,33 +622,33 @@ msgstr ""
"Le partage de l'enregistrement via lien n'est pas encore disponible. Seuls " "Le partage de l'enregistrement via lien n'est pas encore disponible. Seuls "
"les organisateurs peuvent le télécharger." "les organisateurs peuvent le télécharger."
#: core/templates/mail/html/screen_recording.html:198 #: core/templates/mail/html/screen_recording.html:206
#: core/templates/mail/text/screen_recording.txt:12 #: core/templates/mail/text/screen_recording.txt:11
msgid "To keep this recording permanently:" msgid "To keep this recording permanently:"
msgstr "Pour conserver cet enregistrement de façon permanente :" msgstr "Pour conserver cet enregistrement de façon permanente :"
#: core/templates/mail/html/screen_recording.html:200 #: core/templates/mail/html/screen_recording.html:208
#, python-format #, python-format
msgid "Click the \"<a href=\"%(link)s\">Open</a>\" link below " msgid "Click the \"<a href=\"%(link)s\">Open</a>\" link below "
msgstr "Cliquez sur le lien \"<a href=\"%(link)s\">Ouvrir</a>\" ci-dessous " msgstr "Cliquez sur le lien \"<a href=\"%(link)s\">Ouvrir</a>\" ci-dessous "
#: core/templates/mail/html/screen_recording.html:201 #: core/templates/mail/html/screen_recording.html:209
#: core/templates/mail/text/screen_recording.txt:15 #: core/templates/mail/text/screen_recording.txt:14
msgid "Use the \"Download\" button in the interface " msgid "Use the \"Download\" button in the interface "
msgstr "Utilisez le bouton \"Télécharger\" dans l'interface " msgstr "Utilisez le bouton \"Télécharger\" dans l'interface "
#: core/templates/mail/html/screen_recording.html:202 #: core/templates/mail/html/screen_recording.html:210
#: core/templates/mail/text/screen_recording.txt:16 #: core/templates/mail/text/screen_recording.txt:15
msgid "Save the file to your preferred location" msgid "Save the file to your preferred location"
msgstr "Enregistrez le fichier à l'emplacement de votre choix" msgstr "Enregistrez le fichier à l'emplacement de votre choix"
#: core/templates/mail/html/screen_recording.html:213 #: core/templates/mail/html/screen_recording.html:221
#: core/templates/mail/text/screen_recording.txt:18 #: core/templates/mail/text/screen_recording.txt:17
msgid "Open" msgid "Open"
msgstr "Ouvrir" msgstr "Ouvrir"
#: core/templates/mail/html/screen_recording.html:222 #: core/templates/mail/html/screen_recording.html:230
#: core/templates/mail/text/screen_recording.txt:20 #: core/templates/mail/text/screen_recording.txt:19
#, python-format #, python-format
msgid "" msgid ""
" If you have any questions or need assistance, please contact our support " " If you have any questions or need assistance, please contact our support "
@@ -679,33 +657,28 @@ msgstr ""
" Si vous avez des questions ou besoin d'assistance, veuillez contacter notre " " Si vous avez des questions ou besoin d'assistance, veuillez contacter notre "
"équipe d'assistance à %(support_email)s. " "équipe d'assistance à %(support_email)s. "
#: core/templates/mail/text/invitation.txt:24 #: core/templates/mail/text/screen_recording.txt:13
#, python-format
msgid "This mail has been sent to %(email)s by %(name)s [%(href)s]"
msgstr ""
#: core/templates/mail/text/screen_recording.txt:14
#, fuzzy, python-format #, fuzzy, python-format
#| msgid "Click the \"<a href=\"%(link)s\">Open</a>\" link below " #| msgid "Click the \"<a href=\"%(link)s\">Open</a>\" link below "
msgid "Click the \"Open [%(link)s]\" link below " msgid "Click the \"Open [%(link)s]\" link below "
msgstr "Cliquez sur le lien \"<a href=\"%(link)s\">Ouvrir</a>\" ci-dessous " msgstr "Cliquez sur le lien \"<a href=\"%(link)s\">Ouvrir</a>\" ci-dessous "
#: meet/settings.py:238 #: meet/settings.py:228
msgid "English" msgid "English"
msgstr "Anglais" msgstr "Anglais"
#: meet/settings.py:239 #: meet/settings.py:229
msgid "French" msgid "French"
msgstr "Français" msgstr "Français"
#: meet/settings.py:240 #: meet/settings.py:230
msgid "Dutch" msgid "Dutch"
msgstr "Néerlandais" msgstr "Néerlandais"
#: meet/settings.py:241 #: meet/settings.py:231
msgid "German" msgid "German"
msgstr "Allemand" msgstr "Allemand"
#: meet/settings.py:242 #: meet/settings.py:233
msgid "Spanish" msgid "Spanish"
msgstr "Espagnol" msgstr "Espagnol"
+160 -187
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-02 22:52+0000\n" "POT-Creation-Date: 2026-07-02 10:47+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -51,11 +51,11 @@ msgstr ""
msgid "File preview" msgid "File preview"
msgstr "" msgstr ""
#: core/admin.py:300 core/admin.py:450 #: core/admin.py:300 core/admin.py:443
msgid "No owner" msgid "No owner"
msgstr "Geen eigenaar" msgstr "Geen eigenaar"
#: core/admin.py:303 core/admin.py:453 #: core/admin.py:303 core/admin.py:446
msgid "Multiple owners" msgid "Multiple owners"
msgstr "Meerdere eigenaren" msgstr "Meerdere eigenaren"
@@ -98,11 +98,11 @@ msgstr "%(count)s opname(s) succesvol gemarkeerd als 'Mislukt bij stoppen'."
msgid "Skipped %(count)s recording(s) with an ineligible status." msgid "Skipped %(count)s recording(s) with an ineligible status."
msgstr "%(count)s opname(s) met een niet-toegestane status overgeslagen." msgstr "%(count)s opname(s) met een niet-toegestane status overgeslagen."
#: core/admin.py:517 #: core/admin.py:510
msgid "No scopes" msgid "No scopes"
msgstr "Geen scopes" msgstr "Geen scopes"
#: core/admin.py:519 #: core/admin.py:512
msgid "Scopes" msgid "Scopes"
msgstr "Scopes" msgstr "Scopes"
@@ -110,200 +110,184 @@ msgstr "Scopes"
msgid "Creator is me" msgid "Creator is me"
msgstr "Maker ben ik" msgstr "Maker ben ik"
#: core/api/serializers.py:108 #: core/api/serializers.py:89
msgid "You must be administrator or owner of a room to add accesses to it." msgid "You must be administrator or owner of a room to add accesses to it."
msgstr "" msgstr ""
"Je moet beheerder of eigenaar van een ruimte zijn om toegang toe te voegen." "Je moet beheerder of eigenaar van een ruimte zijn om toegang toe te voegen."
#: core/api/serializers.py:560 #: core/api/serializers.py:534
msgid "This file extension is not allowed." msgid "This file extension is not allowed."
msgstr "Deze bestandsextensie is niet toegestaan." msgstr "Deze bestandsextensie is niet toegestaan."
#: core/api/viewsets.py:1268 #: core/api/viewsets.py:1222
msgid "You have reached the maximum number of files for this type." msgid "You have reached the maximum number of files for this type."
msgstr "Het maximale aantal bestanden voor dit type is bereikt." msgstr "Het maximale aantal bestanden voor dit type is bereikt."
#: core/models.py:38 #: core/models.py:37
msgid "Member" msgid "Member"
msgstr "Lid" msgstr "Lid"
#: core/models.py:39 #: core/models.py:38
msgid "Administrator" msgid "Administrator"
msgstr "Beheerder" msgstr "Beheerder"
#: core/models.py:40 #: core/models.py:39
msgid "Owner" msgid "Owner"
msgstr "Eigenaar" msgstr "Eigenaar"
#: core/models.py:56 #: core/models.py:55
msgid "Initiated" msgid "Initiated"
msgstr "Gestart" msgstr "Gestart"
#: core/models.py:57 #: core/models.py:56
msgid "Active" msgid "Active"
msgstr "Actief" msgstr "Actief"
#: core/models.py:58 #: core/models.py:57
msgid "Stopped" msgid "Stopped"
msgstr "Gestopt" msgstr "Gestopt"
#: core/models.py:59 #: core/models.py:58
msgid "Saved" msgid "Saved"
msgstr "Opgeslagen" msgstr "Opgeslagen"
#: core/models.py:60 #: core/models.py:59
msgid "Aborted" msgid "Aborted"
msgstr "Afgebroken" msgstr "Afgebroken"
#: core/models.py:61 #: core/models.py:60
msgid "Failed to Start" msgid "Failed to Start"
msgstr "Starten mislukt" msgstr "Starten mislukt"
#: core/models.py:62 #: core/models.py:61
msgid "Failed to Stop" msgid "Failed to Stop"
msgstr "Stoppen mislukt" msgstr "Stoppen mislukt"
#: core/models.py:63 #: core/models.py:62
msgid "Notification succeeded" msgid "Notification succeeded"
msgstr "Notificatie geslaagd" msgstr "Notificatie geslaagd"
#: core/models.py:66 #: core/models.py:65
msgid "External process successful" msgid "External process successful"
msgstr "Externe procedure succesvol" msgstr "Externe procedure succesvol"
#: core/models.py:68 #: core/models.py:67
msgid "External process failed" msgid "External process failed"
msgstr "Het externe proces is mislukt." msgstr "Het externe proces is mislukt."
#: core/models.py:97 #: core/models.py:96
msgid "SCREEN_RECORDING" msgid "SCREEN_RECORDING"
msgstr "SCHERM_OPNAME" msgstr "SCHERM_OPNAME"
#: core/models.py:98 #: core/models.py:97
msgid "TRANSCRIPT" msgid "TRANSCRIPT"
msgstr "TRANSCRIPT" msgstr "TRANSCRIPT"
#: core/models.py:104 #: core/models.py:103
msgid "Public Access" msgid "Public Access"
msgstr "Openbare toegang" msgstr "Openbare toegang"
#: core/models.py:105 #: core/models.py:104
msgid "Trusted Access" msgid "Trusted Access"
msgstr "Vertrouwde toegang" msgstr "Vertrouwde toegang"
#: core/models.py:106 #: core/models.py:105
msgid "Restricted Access" msgid "Restricted Access"
msgstr "Beperkte toegang" msgstr "Beperkte toegang"
#: core/models.py:118 #: core/models.py:117
msgid "id" msgid "id"
msgstr "id" msgstr "id"
#: core/models.py:119 #: core/models.py:118
msgid "primary key for the record as UUID" msgid "primary key for the record as UUID"
msgstr "primaire sleutel voor het record als UUID" msgstr "primaire sleutel voor het record als UUID"
#: core/models.py:125 #: core/models.py:124
msgid "created on" msgid "created on"
msgstr "aangemaakt op" msgstr "aangemaakt op"
#: core/models.py:126 #: core/models.py:125
msgid "date and time at which a record was created" msgid "date and time at which a record was created"
msgstr "datum en tijd waarop een record werd aangemaakt" msgstr "datum en tijd waarop een record werd aangemaakt"
#: core/models.py:131 #: core/models.py:130
msgid "updated on" msgid "updated on"
msgstr "bijgewerkt op" msgstr "bijgewerkt op"
#: core/models.py:132 #: core/models.py:131
msgid "date and time at which a record was last updated" msgid "date and time at which a record was last updated"
msgstr "datum en tijd waarop een record voor het laatst werd bijgewerkt" msgstr "datum en tijd waarop een record voor het laatst werd bijgewerkt"
#: core/models.py:150 #: core/models.py:151
msgid ""
"Enter a valid sub. This value may contain only letters, numbers, and @/./+/-/"
"_ characters."
msgstr ""
"Voer een geldige sub in. Deze waarde mag alleen letters, cijfers en @/./+/-/"
"_ tekens bevatten."
#: core/models.py:157
msgid "sub" msgid "sub"
msgstr "sub" msgstr "sub"
#: core/models.py:152 #: core/models.py:159
msgid "" msgid ""
"Optional for pending users; required upon account activation. 255 characters " "Optional for pending users; required upon account activation. 255 characters "
"or fewer. Printable ASCII characters only." "or fewer. Letters, numbers, and @/./+/-/_ characters only."
msgstr "" msgstr ""
"Optioneel voor gebruikers in afwachting; verplicht bij het activeren van het " "Optioneel voor gebruikers in afwachting; vereist bij accountactivering. "
"account. Maximaal 255 tekens. Alleen afdrukbare ASCII-tekens." "Maximum 255 tekens. Alleen letters, cijfers en @/./+/-/_ toegestaan."
#: core/validators.py:22 #: core/models.py:168
msgid "Enter a valid sub. This value should be printable ASCII only."
msgstr "Voer een geldige sub in. Deze waarde mag alleen afdrukbare ASCII-tekens bevatten."
#: core/models.py:161
msgid "identity email address" msgid "identity email address"
msgstr "identiteit e-mailadres" msgstr "identiteit e-mailadres"
#: core/models.py:166 #: core/models.py:173
msgid "admin email address" msgid "admin email address"
msgstr "beheerder e-mailadres" msgstr "beheerder e-mailadres"
#: core/models.py:168 #: core/models.py:175
msgid "full name" msgid "full name"
msgstr "volledige naam" msgstr "volledige naam"
#: core/models.py:170 #: core/models.py:177
msgid "short name" msgid "short name"
msgstr "korte naam" msgstr "korte naam"
#: core/models.py:176 #: core/models.py:183
msgid "language" msgid "language"
msgstr "taal" msgstr "taal"
#: core/models.py:177 #: core/models.py:184
msgid "The language in which the user wants to see the interface." msgid "The language in which the user wants to see the interface."
msgstr "De taal waarin de gebruiker de interface wil zien." msgstr "De taal waarin de gebruiker de interface wil zien."
#: core/models.py:183 #: core/models.py:190
msgid "The timezone in which the user wants to see times." msgid "The timezone in which the user wants to see times."
msgstr "De tijdzone waarin de gebruiker tijden wil zien." msgstr "De tijdzone waarin de gebruiker tijden wil zien."
#: core/models.py:190 #: core/models.py:193
msgid "default room access level"
msgstr ""
#: core/models.py:192
msgid ""
"Access level applied by default to new rooms created by this user. When "
"empty, the instance default is used."
msgstr ""
#: core/models.py:199
#, fuzzy
#| msgid "Visio room configuration"
msgid "default room configuration"
msgstr "Visio-ruimteconfiguratie"
#: core/models.py:201
msgid "Configurations applied by default to new rooms created by this user."
msgstr ""
#: core/models.py:205
msgid "device" msgid "device"
msgstr "apparaat" msgstr "apparaat"
#: core/models.py:207 #: core/models.py:195
msgid "Whether the user is a device or a real user." msgid "Whether the user is a device or a real user."
msgstr "Of de gebruiker een apparaat is of een echte gebruiker." msgstr "Of de gebruiker een apparaat is of een echte gebruiker."
#: core/models.py:210 #: core/models.py:198
msgid "staff status" msgid "staff status"
msgstr "personeelsstatus" msgstr "personeelsstatus"
#: core/models.py:212 #: core/models.py:200
msgid "Whether the user can log into this admin site." msgid "Whether the user can log into this admin site."
msgstr "Of de gebruiker kan inloggen op deze beheersite." msgstr "Of de gebruiker kan inloggen op deze beheersite."
#: core/models.py:215 #: core/models.py:203
msgid "active" msgid "active"
msgstr "actief" msgstr "actief"
#: core/models.py:218 #: core/models.py:206
msgid "" msgid ""
"Whether this user should be treated as active. Unselect this instead of " "Whether this user should be treated as active. Unselect this instead of "
"deleting accounts." "deleting accounts."
@@ -311,64 +295,64 @@ msgstr ""
"Of deze gebruiker als actief moet worden behandeld. Deselecteer dit in " "Of deze gebruiker als actief moet worden behandeld. Deselecteer dit in "
"plaats van accounts te verwijderen." "plaats van accounts te verwijderen."
#: core/models.py:231 #: core/models.py:219
msgid "user" msgid "user"
msgstr "gebruiker" msgstr "gebruiker"
#: core/models.py:232 #: core/models.py:220
msgid "users" msgid "users"
msgstr "gebruikers" msgstr "gebruikers"
#: core/models.py:298 #: core/models.py:286
msgid "Resource" msgid "Resource"
msgstr "Bron" msgstr "Bron"
#: core/models.py:299 #: core/models.py:287
msgid "Resources" msgid "Resources"
msgstr "Bronnen" msgstr "Bronnen"
#: core/models.py:357 #: core/models.py:345
msgid "Resource access" msgid "Resource access"
msgstr "Brontoegang" msgstr "Brontoegang"
#: core/models.py:358 #: core/models.py:346
msgid "Resource accesses" msgid "Resource accesses"
msgstr "Brontoegangsrechten" msgstr "Brontoegangsrechten"
#: core/models.py:364 #: core/models.py:352
msgid "Resource access with this User and Resource already exists." msgid "Resource access with this User and Resource already exists."
msgstr "Brontoegang met deze gebruiker en bron bestaat al." msgstr "Brontoegang met deze gebruiker en bron bestaat al."
#: core/models.py:421 #: core/models.py:409
msgid "Visio room configuration" msgid "Visio room configuration"
msgstr "Visio-ruimteconfiguratie" msgstr "Visio-ruimteconfiguratie"
#: core/models.py:422 #: core/models.py:410
msgid "Values for Visio parameters to configure the room." msgid "Values for Visio parameters to configure the room."
msgstr "Waarden voor Visio-parameters om de ruimte te configureren." msgstr "Waarden voor Visio-parameters om de ruimte te configureren."
#: core/models.py:429 #: core/models.py:417
msgid "Room PIN code" msgid "Room PIN code"
msgstr "Pincode van de kamer" msgstr "Pincode van de kamer"
#: core/models.py:430 #: core/models.py:418
msgid "Unique n-digit code that identifies this room in telephony mode." msgid "Unique n-digit code that identifies this room in telephony mode."
msgstr "" msgstr ""
"Unieke n-cijferige code die deze kamer identificeert in telefonie-modus." "Unieke n-cijferige code die deze kamer identificeert in telefonie-modus."
#: core/models.py:436 core/models.py:597 #: core/models.py:424 core/models.py:578
msgid "Room" msgid "Room"
msgstr "Ruimte" msgstr "Ruimte"
#: core/models.py:437 #: core/models.py:425
msgid "Rooms" msgid "Rooms"
msgstr "Ruimtes" msgstr "Ruimtes"
#: core/models.py:608 #: core/models.py:589
msgid "Worker ID" msgid "Worker ID"
msgstr "Worker ID" msgstr "Worker ID"
#: core/models.py:610 #: core/models.py:591
msgid "" msgid ""
"Enter an identifier for the worker recording.This ID is retained even when " "Enter an identifier for the worker recording.This ID is retained even when "
"the worker stops, allowing for easy tracking." "the worker stops, allowing for easy tracking."
@@ -376,152 +360,152 @@ msgstr ""
"Voer een identificatie in voor de worker-opname. Deze ID blijft behouden, " "Voer een identificatie in voor de worker-opname. Deze ID blijft behouden, "
"zelfs wanneer de worker stopt, waardoor eenvoudige tracking mogelijk is." "zelfs wanneer de worker stopt, waardoor eenvoudige tracking mogelijk is."
#: core/models.py:618 #: core/models.py:599
msgid "Recording mode" msgid "Recording mode"
msgstr "Opnamemodus" msgstr "Opnamemodus"
#: core/models.py:619 #: core/models.py:600
msgid "Defines the mode of recording being called." msgid "Defines the mode of recording being called."
msgstr "Definieert de modus van opname die wordt aangeroepen." msgstr "Definieert de modus van opname die wordt aangeroepen."
#: core/models.py:624 core/models.py:625 #: core/models.py:605 core/models.py:606
msgid "Recording options" msgid "Recording options"
msgstr "Opnameopties" msgstr "Opnameopties"
#: core/models.py:632 #: core/models.py:613
msgid "External Process ID" msgid "External Process ID"
msgstr "Externe proces-ID" msgstr "Externe proces-ID"
#: core/models.py:633 #: core/models.py:614
msgid "ID of the external process associated with the recording." msgid "ID of the external process associated with the recording."
msgstr "ID van het externe proces dat aan de opname is gekoppeld." msgstr "ID van het externe proces dat aan de opname is gekoppeld."
#: core/models.py:639 #: core/models.py:620
msgid "Recording" msgid "Recording"
msgstr "Opname" msgstr "Opname"
#: core/models.py:640 #: core/models.py:621
msgid "Recordings" msgid "Recordings"
msgstr "Opnames" msgstr "Opnames"
#: core/models.py:750 #: core/models.py:731
msgid "Recording/user relation" msgid "Recording/user relation"
msgstr "Opname/gebruiker-relatie" msgstr "Opname/gebruiker-relatie"
#: core/models.py:751 #: core/models.py:732
msgid "Recording/user relations" msgid "Recording/user relations"
msgstr "Opname/gebruiker-relaties" msgstr "Opname/gebruiker-relaties"
#: core/models.py:757 #: core/models.py:738
msgid "This user is already in this recording." msgid "This user is already in this recording."
msgstr "Deze gebruiker is al in deze opname." msgstr "Deze gebruiker is al in deze opname."
#: core/models.py:763 #: core/models.py:744
msgid "This team is already in this recording." msgid "This team is already in this recording."
msgstr "Dit team is al in deze opname." msgstr "Dit team is al in deze opname."
#: core/models.py:769 #: core/models.py:750
msgid "Either user or team must be set, not both." msgid "Either user or team must be set, not both."
msgstr "Ofwel gebruiker of team moet worden ingesteld, niet beide." msgstr "Ofwel gebruiker of team moet worden ingesteld, niet beide."
#: core/models.py:786 #: core/models.py:767
msgid "Create rooms" msgid "Create rooms"
msgstr "Ruimtes aanmaken" msgstr "Ruimtes aanmaken"
#: core/models.py:787 #: core/models.py:768
msgid "List rooms" msgid "List rooms"
msgstr "Ruimtes weergeven" msgstr "Ruimtes weergeven"
#: core/models.py:788 #: core/models.py:769
msgid "Retrieve room details" msgid "Retrieve room details"
msgstr "Details van een ruimte ophalen" msgstr "Details van een ruimte ophalen"
#: core/models.py:789 #: core/models.py:770
msgid "Update rooms" msgid "Update rooms"
msgstr "Ruimtes bijwerken" msgstr "Ruimtes bijwerken"
#: core/models.py:790 #: core/models.py:771
msgid "Delete rooms" msgid "Delete rooms"
msgstr "Ruimtes verwijderen" msgstr "Ruimtes verwijderen"
#: core/models.py:803 #: core/models.py:784
msgid "Application name" msgid "Application name"
msgstr "Naam van de applicatie" msgstr "Naam van de applicatie"
#: core/models.py:804 #: core/models.py:785
msgid "Descriptive name for this application." msgid "Descriptive name for this application."
msgstr "Beschrijvende naam voor deze applicatie." msgstr "Beschrijvende naam voor deze applicatie."
#: core/models.py:814 #: core/models.py:795
msgid "Hashed on Save. Copy it now if this is a new secret." msgid "Hashed on Save. Copy it now if this is a new secret."
msgstr "" msgstr ""
"Wordt gehasht bij het opslaan. Kopieer het nu als dit een nieuw geheim is." "Wordt gehasht bij het opslaan. Kopieer het nu als dit een nieuw geheim is."
#: core/models.py:825 #: core/models.py:806
msgid "Application" msgid "Application"
msgstr "Applicatie" msgstr "Applicatie"
#: core/models.py:826 #: core/models.py:807
msgid "Applications" msgid "Applications"
msgstr "Applicaties" msgstr "Applicaties"
#: core/models.py:849 #: core/models.py:830
msgid "Enter a valid domain" msgid "Enter a valid domain"
msgstr "Voer een geldig domein in" msgstr "Voer een geldig domein in"
#: core/models.py:852 #: core/models.py:833
msgid "Domain" msgid "Domain"
msgstr "Domein" msgstr "Domein"
#: core/models.py:853 #: core/models.py:834
msgid "Email domain this application can act on behalf of." msgid "Email domain this application can act on behalf of."
msgstr "E-maildomein namens welke deze applicatie kan handelen." msgstr "E-maildomein namens welke deze applicatie kan handelen."
#: core/models.py:865 #: core/models.py:846
msgid "Application domain" msgid "Application domain"
msgstr "Applicatiedomein" msgstr "Applicatiedomein"
#: core/models.py:866 #: core/models.py:847
msgid "Application domains" msgid "Application domains"
msgstr "Applicatiedomeinen" msgstr "Applicatiedomeinen"
#: core/models.py:884 #: core/models.py:865
msgid "Pending" msgid "Pending"
msgstr "In afwachting" msgstr "In afwachting"
#: core/models.py:885 #: core/models.py:866
msgid "Analyzing" msgid "Analyzing"
msgstr "" msgstr ""
#: core/models.py:892 #: core/models.py:873
msgid "Ready" msgid "Ready"
msgstr "Klaar" msgstr "Klaar"
#: core/models.py:898 #: core/models.py:879
msgid "Background image" msgid "Background image"
msgstr "Achtergrondafbeelding" msgstr "Achtergrondafbeelding"
#: core/models.py:910 #: core/models.py:891
msgid "title" msgid "title"
msgstr "Titel" msgstr "Titel"
#: core/models.py:934 #: core/models.py:915
msgid "Malware detection info when the analysis status is unsafe." msgid "Malware detection info when the analysis status is unsafe."
msgstr "Informatie over malwaredetectie wanneer de analysestatus onveilig is." msgstr "Informatie over malwaredetectie wanneer de analysestatus onveilig is."
#: core/models.py:939 #: core/models.py:920
msgid "File" msgid "File"
msgstr "Bestand" msgstr "Bestand"
#: core/models.py:940 #: core/models.py:921
msgid "Files" msgid "Files"
msgstr "Bestanden" msgstr "Bestanden"
#: core/models.py:1060 #: core/models.py:1041
msgid "This file is already hard deleted." msgid "This file is already hard deleted."
msgstr "Dit bestand is al definitief verwijderd." msgstr "Dit bestand is al definitief verwijderd."
#: core/models.py:1070 #: core/models.py:1051
#, fuzzy #, fuzzy
#| msgid "To hard delete a file, it must first be soft deleted." #| msgid "To hard delete a file, it must first be soft deleted."
msgid "To hard delete a file, it must first be soft deleted." msgid "To hard delete a file, it must first be soft deleted."
@@ -529,15 +513,15 @@ msgstr ""
"Om een bestand definitief te verwijderen, moet het eerst zacht verwijderd " "Om een bestand definitief te verwijderen, moet het eerst zacht verwijderd "
"zijn." "zijn."
#: core/recording/event/notification.py:124 #: core/recording/event/notification.py:123
msgid "Your recording is ready" msgid "Your recording is ready"
msgstr "Je opname is klaar" msgstr "Je opname is klaar"
#: core/recording/event/notification.py:195 #: core/recording/event/notification.py:194
msgid "Transcription" msgid "Transcription"
msgstr "Transcriptie" msgstr "Transcriptie"
#: core/recording/event/notification.py:206 #: core/recording/event/notification.py:204
#, python-brace-format #, python-brace-format
msgid "Meeting \"{room}\" on {room_recording_date} at {room_recording_time}" msgid "Meeting \"{room}\" on {room_recording_date} at {room_recording_time}"
msgstr "" msgstr ""
@@ -548,25 +532,25 @@ msgstr ""
msgid "Video call in progress: {sender.email} is waiting for you to connect" msgid "Video call in progress: {sender.email} is waiting for you to connect"
msgstr "Video-oproep bezig: {sender.email} wacht op je verbinding" msgstr "Video-oproep bezig: {sender.email} wacht op je verbinding"
#: core/templates/mail/html/invitation.html:151 #: core/templates/mail/html/invitation.html:159
#: core/templates/mail/html/screen_recording.html:151 #: core/templates/mail/html/screen_recording.html:159
#: core/templates/mail/text/invitation.txt:4 #: core/templates/mail/text/invitation.txt:3
#: core/templates/mail/text/screen_recording.txt:4 #: core/templates/mail/text/screen_recording.txt:3
msgid "Logo email" msgid "Logo email"
msgstr "Logo e-mail" msgstr "Logo e-mail"
#: core/templates/mail/html/invitation.html:181 #: core/templates/mail/html/invitation.html:189
#: core/templates/mail/text/invitation.txt:6 #: core/templates/mail/text/invitation.txt:5
msgid "invites you to join an ongoing video call" msgid "invites you to join an ongoing video call"
msgstr "nodigt je uit om deel te nemen aan een lopende video-oproep" msgstr "nodigt je uit om deel te nemen aan een lopende video-oproep"
#: core/templates/mail/html/invitation.html:192 #: core/templates/mail/html/invitation.html:200
#: core/templates/mail/text/invitation.txt:8 #: core/templates/mail/text/invitation.txt:7
msgid "JOIN THE CALL" msgid "JOIN THE CALL"
msgstr "NEEM DEEL AAN DE OPROEP" msgstr "NEEM DEEL AAN DE OPROEP"
#: core/templates/mail/html/invitation.html:219 #: core/templates/mail/html/invitation.html:227
#: core/templates/mail/text/invitation.txt:14 #: core/templates/mail/text/invitation.txt:13
msgid "" msgid ""
"If you can't click the button, copy and paste the URL into your browser to " "If you can't click the button, copy and paste the URL into your browser to "
"join the call." "join the call."
@@ -574,47 +558,41 @@ msgstr ""
"Als je niet op de knop kunt klikken, kopieer en plak dan de URL in je " "Als je niet op de knop kunt klikken, kopieer en plak dan de URL in je "
"browser om deel te nemen aan de oproep." "browser om deel te nemen aan de oproep."
#: core/templates/mail/html/invitation.html:227 #: core/templates/mail/html/invitation.html:235
#: core/templates/mail/text/invitation.txt:16 #: core/templates/mail/text/invitation.txt:15
msgid "Tips for a better experience:" msgid "Tips for a better experience:"
msgstr "Tips voor een betere ervaring:" msgstr "Tips voor een betere ervaring:"
#: core/templates/mail/html/invitation.html:229 #: core/templates/mail/html/invitation.html:237
#: core/templates/mail/text/invitation.txt:18 #: core/templates/mail/text/invitation.txt:17
msgid "Use Chrome or Firefox for better call quality" msgid "Use Chrome or Firefox for better call quality"
msgstr "Gebruik Chrome of Firefox voor betere gesprekskwaliteit" msgstr "Gebruik Chrome of Firefox voor betere gesprekskwaliteit"
#: core/templates/mail/html/invitation.html:230 #: core/templates/mail/html/invitation.html:238
#: core/templates/mail/text/invitation.txt:19 #: core/templates/mail/text/invitation.txt:18
msgid "Test your microphone and camera before joining" msgid "Test your microphone and camera before joining"
msgstr "Test je microfoon en camera voordat je deelneemt" msgstr "Test je microfoon en camera voordat je deelneemt"
#: core/templates/mail/html/invitation.html:231 #: core/templates/mail/html/invitation.html:239
#: core/templates/mail/text/invitation.txt:20 #: core/templates/mail/text/invitation.txt:19
msgid "Make sure you have a stable internet connection" msgid "Make sure you have a stable internet connection"
msgstr "Zorg ervoor dat je een stabiele internetverbinding hebt" msgstr "Zorg ervoor dat je een stabiele internetverbinding hebt"
#: core/templates/mail/html/invitation.html:240 #: core/templates/mail/html/invitation.html:248
#: core/templates/mail/html/screen_recording.html:237 #: core/templates/mail/html/screen_recording.html:245
#: core/templates/mail/text/invitation.txt:22 #: core/templates/mail/text/invitation.txt:21
#: core/templates/mail/text/screen_recording.txt:24 #: core/templates/mail/text/screen_recording.txt:23
#, python-format #, python-format
msgid " Thank you for using %(brandname)s. " msgid " Thank you for using %(brandname)s. "
msgstr " Bedankt voor het gebruik van %(brandname)s. " msgstr " Bedankt voor het gebruik van %(brandname)s. "
#: core/templates/mail/html/invitation.html:271 #: core/templates/mail/html/screen_recording.html:188
#, python-format #: core/templates/mail/text/screen_recording.txt:6
msgid ""
"This mail has been sent to %(email)s by <a href=\"%(href)s\">%(name)s</a>"
msgstr ""
#: core/templates/mail/html/screen_recording.html:180
#: core/templates/mail/text/screen_recording.txt:7
msgid "Your recording is ready!" msgid "Your recording is ready!"
msgstr "Je opname is klaar!" msgstr "Je opname is klaar!"
#: core/templates/mail/html/screen_recording.html:187 #: core/templates/mail/html/screen_recording.html:195
#: core/templates/mail/text/screen_recording.txt:9 #: core/templates/mail/text/screen_recording.txt:8
#, python-format #, python-format
msgid "" msgid ""
" Your recording of \"%(room_name)s\" on %(recording_date)s at " " Your recording of \"%(room_name)s\" on %(recording_date)s at "
@@ -623,14 +601,14 @@ msgstr ""
" Je opname van \"%(room_name)s\" op %(recording_date)s om %(recording_time)s " " Je opname van \"%(room_name)s\" op %(recording_date)s om %(recording_time)s "
"is nu klaar om te downloaden. " "is nu klaar om te downloaden. "
#: core/templates/mail/html/screen_recording.html:187 #: core/templates/mail/html/screen_recording.html:195
#: core/templates/mail/text/screen_recording.txt:9 #: core/templates/mail/text/screen_recording.txt:8
#, python-format #, python-format
msgid " The recording will expire in %(days)s days. " msgid " The recording will expire in %(days)s days. "
msgstr " De opname verloopt over %(days)s dagen. " msgstr " De opname verloopt over %(days)s dagen. "
#: core/templates/mail/html/screen_recording.html:192 #: core/templates/mail/html/screen_recording.html:200
#: core/templates/mail/text/screen_recording.txt:10 #: core/templates/mail/text/screen_recording.txt:9
msgid "" msgid ""
" Sharing the recording via link is not yet available. Only organizers can " " Sharing the recording via link is not yet available. Only organizers can "
"download it. " "download it. "
@@ -638,33 +616,33 @@ msgstr ""
"Het delen van de opname via een link is nog niet beschikbaar. Alleen " "Het delen van de opname via een link is nog niet beschikbaar. Alleen "
"organisatoren kunnen deze downloaden." "organisatoren kunnen deze downloaden."
#: core/templates/mail/html/screen_recording.html:198 #: core/templates/mail/html/screen_recording.html:206
#: core/templates/mail/text/screen_recording.txt:12 #: core/templates/mail/text/screen_recording.txt:11
msgid "To keep this recording permanently:" msgid "To keep this recording permanently:"
msgstr "Om deze opname permanent te bewaren:" msgstr "Om deze opname permanent te bewaren:"
#: core/templates/mail/html/screen_recording.html:200 #: core/templates/mail/html/screen_recording.html:208
#, python-format #, python-format
msgid "Click the \"<a href=\"%(link)s\">Open</a>\" link below " msgid "Click the \"<a href=\"%(link)s\">Open</a>\" link below "
msgstr "Klik op de \"<a href=\"%(link)s\">Openen</a>\"-link hieronder " msgstr "Klik op de \"<a href=\"%(link)s\">Openen</a>\"-link hieronder "
#: core/templates/mail/html/screen_recording.html:201 #: core/templates/mail/html/screen_recording.html:209
#: core/templates/mail/text/screen_recording.txt:15 #: core/templates/mail/text/screen_recording.txt:14
msgid "Use the \"Download\" button in the interface " msgid "Use the \"Download\" button in the interface "
msgstr "Gebruik de \"Download\"-knop in de interface " msgstr "Gebruik de \"Download\"-knop in de interface "
#: core/templates/mail/html/screen_recording.html:202 #: core/templates/mail/html/screen_recording.html:210
#: core/templates/mail/text/screen_recording.txt:16 #: core/templates/mail/text/screen_recording.txt:15
msgid "Save the file to your preferred location" msgid "Save the file to your preferred location"
msgstr "Sla het bestand op naar je gewenste locatie" msgstr "Sla het bestand op naar je gewenste locatie"
#: core/templates/mail/html/screen_recording.html:213 #: core/templates/mail/html/screen_recording.html:221
#: core/templates/mail/text/screen_recording.txt:18 #: core/templates/mail/text/screen_recording.txt:17
msgid "Open" msgid "Open"
msgstr "Openen" msgstr "Openen"
#: core/templates/mail/html/screen_recording.html:222 #: core/templates/mail/html/screen_recording.html:230
#: core/templates/mail/text/screen_recording.txt:20 #: core/templates/mail/text/screen_recording.txt:19
#, python-format #, python-format
msgid "" msgid ""
" If you have any questions or need assistance, please contact our support " " If you have any questions or need assistance, please contact our support "
@@ -673,33 +651,28 @@ msgstr ""
" Als je vragen hebt of hulp nodig hebt, neem dan contact op met ons support " " Als je vragen hebt of hulp nodig hebt, neem dan contact op met ons support "
"team via %(support_email)s. " "team via %(support_email)s. "
#: core/templates/mail/text/invitation.txt:24 #: core/templates/mail/text/screen_recording.txt:13
#, python-format
msgid "This mail has been sent to %(email)s by %(name)s [%(href)s]"
msgstr ""
#: core/templates/mail/text/screen_recording.txt:14
#, fuzzy, python-format #, fuzzy, python-format
#| msgid "Click the \"<a href=\"%(link)s\">Open</a>\" link below " #| msgid "Click the \"<a href=\"%(link)s\">Open</a>\" link below "
msgid "Click the \"Open [%(link)s]\" link below " msgid "Click the \"Open [%(link)s]\" link below "
msgstr "Klik op de \"<a href=\"%(link)s\">Openen</a>\"-link hieronder " msgstr "Klik op de \"<a href=\"%(link)s\">Openen</a>\"-link hieronder "
#: meet/settings.py:238 #: meet/settings.py:228
msgid "English" msgid "English"
msgstr "Engels" msgstr "Engels"
#: meet/settings.py:239 #: meet/settings.py:229
msgid "French" msgid "French"
msgstr "Frans" msgstr "Frans"
#: meet/settings.py:240 #: meet/settings.py:230
msgid "Dutch" msgid "Dutch"
msgstr "Nederlands" msgstr "Nederlands"
#: meet/settings.py:241 #: meet/settings.py:231
msgid "German" msgid "German"
msgstr "Duits" msgstr "Duits"
#: meet/settings.py:242 #: meet/settings.py:233
msgid "Spanish" msgid "Spanish"
msgstr "Spaans" msgstr "Spaans"
-9
View File
@@ -129,15 +129,6 @@ class Base(Configuration):
MEDIA_BASE_URL = values.Value( MEDIA_BASE_URL = values.Value(
"", environ_name="MEDIA_BASE_URL", environ_prefix=None "", environ_name="MEDIA_BASE_URL", environ_prefix=None
) )
# Header the reverse proxy uses to pass the original request URL to the
# media-auth subrequest views. nginx-ingress sends X-Original-URL, which is
# the default. Other proxies use different headers -- Traefik's ForwardAuth,
# for instance, sends X-Forwarded-Uri and cannot emit X-Original-URL at all.
MEDIA_AUTH_ORIGINAL_URL_HEADER = values.Value(
default="HTTP_X_ORIGINAL_URL",
environ_name="MEDIA_AUTH_ORIGINAL_URL_HEADER",
environ_prefix=None,
)
SITE_ID = 1 SITE_ID = 1
+2 -2
View File
@@ -7,7 +7,7 @@ build-backend = "uv_build"
[project] [project]
name = "meet" name = "meet"
version = "1.30.0" version = "1.29.0"
authors = [{ "name" = "DINUM", "email" = "dev@mail.numerique.gouv.fr" }] authors = [{ "name" = "DINUM", "email" = "dev@mail.numerique.gouv.fr" }]
classifiers = [ classifiers = [
"Development Status :: 5 - Production/Stable", "Development Status :: 5 - Production/Stable",
@@ -40,7 +40,7 @@ dependencies = [
"django-storages[s3]==1.14.6", "django-storages[s3]==1.14.6",
"django-timezone-field>=5.1", "django-timezone-field>=5.1",
"django-pydantic-field==0.5.4", "django-pydantic-field==0.5.4",
"django==5.2.16", "django==5.2.17",
"djangorestframework==3.17.1", "djangorestframework==3.17.1",
"drf_spectacular==0.30.0", "drf_spectacular==0.30.0",
"dockerflow==2026.3.4", "dockerflow==2026.3.4",
+5 -5
View File
@@ -586,16 +586,16 @@ wheels = [
[[package]] [[package]]
name = "django" name = "django"
version = "5.2.16" version = "5.2.17"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "asgiref" }, { name = "asgiref" },
{ name = "sqlparse" }, { name = "sqlparse" },
{ name = "tzdata", marker = "sys_platform == 'win32'" }, { name = "tzdata", marker = "sys_platform == 'win32'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/a9/26/889449d521ae508b26de715954faecd8bcf3f740affb81b2d146a83b42a5/django-5.2.16.tar.gz", hash = "sha256:59ea02020c3136fce14bef0bbece21a10a4febef5eed1c51c22ae468efa22200", size = 10890894, upload-time = "2026-07-07T13:52:17.005Z" } sdist = { url = "https://files.pythonhosted.org/packages/d5/d8/43e9d000519adceb189620b6869ff88031e046df91c2e9da72f8f6918399/django-5.2.17.tar.gz", hash = "sha256:9d4d93be539a18ab80d058eb515900e10951e04c537c5a6b394fc49528d3251f", size = 10889740, upload-time = "2026-08-04T15:04:03.173Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/4e/13/1e5e3e4c15dcecb04281b3cb2a46a4670e1cef131068e202f6040df19224/django-5.2.16-py3-none-any.whl", hash = "sha256:04f354bf9d807a86ad1a8392fe3808d362358a8eafc322848e0e43e59b24371d", size = 8311943, upload-time = "2026-07-07T13:52:11.223Z" }, { url = "https://files.pythonhosted.org/packages/df/f8/ce120525ca78f12b07daf65786679c5d0b54a75285a8958d3ae55e39da35/django-5.2.17-py3-none-any.whl", hash = "sha256:f04fb3b36ee119e1af4fa1d397d5fd6cf12700f49321e84d4f4c642c5b1973db", size = 8315563, upload-time = "2026-08-04T15:03:59.1Z" },
] ]
[[package]] [[package]]
@@ -1187,7 +1187,7 @@ wheels = [
[[package]] [[package]]
name = "meet" name = "meet"
version = "1.30.0" version = "1.29.0"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "aiohttp" }, { name = "aiohttp" },
@@ -1262,7 +1262,7 @@ requires-dist = [
{ name = "celery", extras = ["redis"], specifier = "==5.6.3" }, { name = "celery", extras = ["redis"], specifier = "==5.6.3" },
{ name = "cryptography", specifier = "==50.0.0" }, { name = "cryptography", specifier = "==50.0.0" },
{ name = "dj-database-url", specifier = "==3.1.2" }, { name = "dj-database-url", specifier = "==3.1.2" },
{ name = "django", specifier = "==5.2.16" }, { name = "django", specifier = "==5.2.17" },
{ name = "django-configurations", specifier = "==2.5.1" }, { name = "django-configurations", specifier = "==2.5.1" },
{ name = "django-cors-headers", specifier = "==4.9.0" }, { name = "django-cors-headers", specifier = "==4.9.0" },
{ name = "django-countries", specifier = "==9.0.0" }, { name = "django-countries", specifier = "==9.0.0" },
-1
View File
@@ -53,7 +53,6 @@ RUN apk update && apk upgrade \
musl \ musl \
musl-utils \ musl-utils \
zlib>=1.3.2-r0 \ zlib>=1.3.2-r0 \
libexpat>=2.8.4-r0 \
&& apk del curl && apk del curl
USER nginx USER nginx
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "meet", "name": "meet",
"version": "1.30.0", "version": "1.29.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "meet", "name": "meet",
"version": "1.30.0", "version": "1.29.0",
"dependencies": { "dependencies": {
"@fontsource-variable/atkinson-hyperlegible-next": "5.3.0", "@fontsource-variable/atkinson-hyperlegible-next": "5.3.0",
"@fontsource-variable/lexend": "5.3.0", "@fontsource-variable/lexend": "5.3.0",
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "meet", "name": "meet",
"private": true, "private": true,
"version": "1.30.0", "version": "1.29.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "panda codegen && vite", "dev": "panda codegen && vite",
@@ -1,595 +0,0 @@
import { CSSProperties, useState } from 'react'
import { useConnectionState, useRoomContext } from '@livekit/components-react'
import { ConnectionState } from 'livekit-client'
import { StatsSnapshot, TrackRow, useWebRTCStats } from './useWebRTCStats'
import { readRoomConfig } from './roomConfig'
import {
forceTransport,
releaseForcedTransport,
Scenario,
SCENARIOS,
setDownlinkCap,
setUplinkCap,
stepBitrate,
TransportMode,
transportModeFromRoute,
} from './simulation'
const SANS =
"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
const MONO = 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace'
const COLOR = {
text: '#e8e8e8',
muted: '#9a9a9a',
faint: '#6f6f6f',
hairline: '#2c2d31',
border: '#3d3e44',
surface: '#1b1c1e',
chartBg: '#141517',
down: '#f6821f',
up: '#5a9cf8',
ok: '#10b981',
bad: '#f05a4a',
busy: '#e5a13c',
}
const stateColor = (state: ConnectionState): string => {
switch (state) {
case ConnectionState.Connected:
return COLOR.ok
case ConnectionState.Reconnecting:
case ConnectionState.SignalReconnecting:
return COLOR.busy
case ConnectionState.Connecting:
return COLOR.up
case ConnectionState.Disconnected:
return COLOR.bad
}
}
const styles: Record<string, CSSProperties> = {
toggle: {
position: 'fixed',
bottom: 12,
right: 12,
zIndex: 9999,
fontFamily: SANS,
fontSize: 12,
lineHeight: 1,
padding: '8px 12px',
borderRadius: 999,
borderWidth: 1,
borderStyle: 'solid',
borderColor: COLOR.border,
background: COLOR.surface,
color: COLOR.text,
cursor: 'pointer',
boxShadow: '0 2px 10px #0006',
},
panel: {
position: 'fixed',
bottom: 12,
right: 12,
zIndex: 9999,
width: 460,
maxWidth: 'calc(100vw - 24px)',
maxHeight: 'calc(100vh - 24px)',
overflowY: 'auto',
fontFamily: SANS,
fontSize: 11,
lineHeight: 1.5,
color: COLOR.text,
background: COLOR.surface,
borderWidth: 1,
borderStyle: 'solid',
borderColor: COLOR.border,
borderRadius: 10,
padding: 14,
boxShadow: '0 10px 34px #00000080',
},
sectionTitle: {
margin: '14px 0 5px',
color: COLOR.faint,
textTransform: 'uppercase',
letterSpacing: 1.2,
fontSize: 9,
fontWeight: 600,
display: 'flex',
justifyContent: 'space-between',
},
metricsLine: {
display: 'flex',
alignItems: 'center',
gap: 16,
margin: '0 0 10px',
paddingBottom: 10,
borderBottom: `1px solid ${COLOR.hairline}`,
fontVariantNumeric: 'tabular-nums',
},
legend: {
display: 'flex',
gap: 12,
marginTop: 3,
color: COLOR.faint,
fontSize: 10,
},
list: {
display: 'flex',
flexDirection: 'column',
maxHeight: '400px',
overflowY: 'auto',
},
configList: { display: 'flex', flexWrap: 'wrap' },
configRow: {
display: 'flex',
gap: 6,
flex: '0 0 50%',
minWidth: 0,
boxSizing: 'border-box',
padding: '1px 8px 1px 0',
},
configLabel: {
color: COLOR.muted,
flex: '0 0 45%',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
},
configValue: {
flex: 1,
minWidth: 0,
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
},
trackRow: {
display: 'flex',
gap: 8,
padding: '3px 0',
borderBottom: `1px solid ${COLOR.hairline}`,
alignItems: 'baseline',
},
trackLabel: {
flex: '0 0 34%',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
},
trackCodec: {
flex: '0 0 11%',
fontFamily: MONO,
fontSize: 10,
color: COLOR.muted,
},
trackKbps: {
flex: '0 0 9%',
textAlign: 'right',
fontVariantNumeric: 'tabular-nums',
},
trackDetail: {
flex: 1,
minWidth: 0,
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
},
mono: { fontFamily: MONO, fontSize: 10, color: COLOR.muted },
button: {
fontFamily: SANS,
fontSize: 11,
padding: '3px 9px',
borderRadius: 5,
borderWidth: 1,
borderStyle: 'solid',
borderColor: COLOR.border,
background: '#232428',
color: COLOR.text,
cursor: 'pointer',
},
buttonActive: { borderColor: COLOR.down, color: COLOR.down },
buttonDisabled: { color: COLOR.faint, cursor: 'not-allowed' },
row: { display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' },
stepperValue: {
minWidth: 92,
textAlign: 'center',
borderWidth: 1,
borderStyle: 'solid',
borderColor: COLOR.hairline,
borderRadius: 4,
padding: '2px 6px',
background: COLOR.chartBg,
fontVariantNumeric: 'tabular-nums',
},
close: {
background: 'none',
border: 'none',
color: COLOR.faint,
cursor: 'pointer',
fontSize: 14,
},
}
const Sparkline = ({ history }: { history: StatsSnapshot[] }) => {
const width = 430
const height = 54
const max = Math.max(...history.map((s) => Math.max(s.upKbps, s.downKbps)), 1)
const points = (pick: (s: StatsSnapshot) => number) =>
history
.map(
(s, i) =>
`${((i / Math.max(history.length - 1, 1)) * width).toFixed(1)},${(
height -
(pick(s) / max) * (height - 6) -
3
).toFixed(1)}`
)
.join(' ')
return (
<>
<svg
width={width}
height={height}
role="img"
aria-label="Bandwidth over the last minute"
style={{
display: 'block',
background: COLOR.chartBg,
borderRadius: 6,
border: `1px solid ${COLOR.hairline}`,
}}
>
{history.length >= 2 && (
<>
<polyline
points={points((s) => s.downKbps)}
fill="none"
stroke={COLOR.down}
strokeWidth="1.5"
/>
<polyline
points={points((s) => s.upKbps)}
fill="none"
stroke={COLOR.up}
strokeWidth="1.5"
/>
</>
)}
</svg>
{/* Legend outside the plot: text over the lines was unreadable. */}
<div style={styles.legend}>
<span>
<span style={{ color: COLOR.down }}></span> down
</span>
<span>
<span style={{ color: COLOR.up }}></span> up
</span>
<span>last 60s · max {Math.round(max)} kbps</span>
</div>
</>
)
}
const CapStepper = ({
label,
hint,
valueKbps,
onChange,
}: {
label: string
hint: string
valueKbps: number | null
onChange: (kbps: number | null) => void
}) => (
<div style={styles.row}>
<span style={{ flex: '0 0 70px' }}>{label}</span>
<button
type="button"
style={styles.button}
aria-label={`Decrease ${label} bandwidth`}
onClick={() => onChange(stepBitrate(valueKbps, 'decrease'))}
>
</button>
<span
style={{
...styles.stepperValue,
...(valueKbps !== null ? { color: COLOR.down } : {}),
}}
>
{valueKbps === null ? 'unlimited' : `${valueKbps} kbps`}
</span>
<button
type="button"
style={styles.button}
aria-label={`Increase ${label} bandwidth`}
onClick={() => onChange(stepBitrate(valueKbps, 'increase'))}
>
+
</button>
<span style={styles.mono}>{hint}</span>
</div>
)
const TrackList = ({ title, rows }: { title: string; rows: TrackRow[] }) => (
<>
<div style={styles.sectionTitle}>
<span>
{title} ({rows.length})
</span>
<span>
{Math.round(rows.reduce((sum, t) => sum + t.kbps, 0))} kbps media
</span>
</div>
<div style={styles.list}>
{rows.map((track) => (
<div key={track.key} style={styles.trackRow}>
<span style={styles.trackLabel}>{track.label}</span>
<span style={styles.trackCodec}>{track.codec ?? ''}</span>
<span style={styles.trackKbps}>{Math.round(track.kbps)}</span>
<span style={styles.trackDetail}>
{[
track.res,
track.fps !== undefined && `${Math.round(track.fps)}fps`,
]
.filter(Boolean)
.join(' · ')}
</span>
</div>
))}
{rows.length === 0 && <span style={{ color: COLOR.faint }}>none</span>}
</div>
</>
)
const MeetDevtools = () => {
const room = useRoomContext()
const connState = useConnectionState(room)
const [open, setOpen] = useState(false)
const [firedScenario, setFiredScenario] = useState<string>()
const [uplinkCap, setUplinkCapState] = useState<number | null>(null)
const [downlinkCap, setDownlinkCapState] = useState<number | null>(null)
const { snapshot, history } = useWebRTCStats(room, open)
const transportMode: TransportMode = transportModeFromRoute(snapshot?.route)
const fireScenario = (scenario: Scenario) => {
setFiredScenario(scenario.id)
scenario.run(room).catch((e) => {
console.warn('[MeetDevtools] simulateScenario failed', e)
})
window.setTimeout(
() =>
setFiredScenario((current) =>
current === scenario.id ? undefined : current
),
1200
)
}
if (!open) {
return (
<button
type="button"
style={styles.toggle}
onClick={() => setOpen(true)}
aria-label="Open WebRTC devtools"
>
<span style={{ color: stateColor(connState) }}></span> rtc
</button>
)
}
const config = readRoomConfig(room)
const published = snapshot?.tracks.filter((t) => t.dir === 'up') ?? []
const subscribed = snapshot?.tracks.filter((t) => t.dir === 'down') ?? []
const turnProtocols = snapshot?.turnProtocols ?? []
const transports: Array<{
mode: TransportMode
label: string
requires?: string
title: string
}> = [
{
mode: 'auto',
label: 'auto (udp)',
title:
'clears the server-cached transport preference and relay-only policy, then full reconnect',
},
{
mode: 'tcp',
label: 'tcp',
title: 'force-tcp — server prefers TCP candidates (ICE/TCP)',
},
{
mode: 'turn-udp',
label: 'turn:udp',
requires: 'udp',
title:
'client-side: iceTransportPolicy relay + full reconnect (no server hook exists)',
},
{
mode: 'turn-tcp',
label: 'turn:tcp',
requires: 'tcp',
title: 'force-tcp — lands on TURN/TCP when it is the TCP path',
},
{
mode: 'turn-tls',
label: 'turn:tls',
requires: 'tls',
title: 'force-tls — server switches you to TURN over TLS',
},
]
return (
<section style={styles.panel} aria-label="WebRTC devtools">
<div style={styles.metricsLine}>
<span>
<span style={{ color: COLOR.down }}></span> {snapshot?.downKbps ?? 0}{' '}
kbps
</span>
<span>
<span style={{ color: COLOR.up }}></span> {snapshot?.upKbps ?? 0}{' '}
kbps
</span>
<span style={{ color: COLOR.muted }}>
rtt{' '}
<span style={{ color: COLOR.text }}>{snapshot?.rttMs ?? ''}</span> ms
</span>
<span style={{ color: COLOR.muted }}>
jitter{' '}
<span style={{ color: COLOR.text }}>{snapshot?.jitterMs ?? ''}</span>{' '}
ms
</span>
<span
style={{
color: stateColor(connState),
fontSize: 10,
marginLeft: 'auto',
}}
>
{connState}
</span>
<button
type="button"
style={styles.close}
onClick={() => setOpen(false)}
aria-label="Close WebRTC devtools"
>
</button>
</div>
<Sparkline history={history} />
<div style={styles.sectionTitle}>room configuration (live)</div>
<div style={styles.configList}>
{config.map((entry) => (
<div key={entry.label} style={styles.configRow}>
<span
style={{
color:
entry.on === undefined
? COLOR.faint
: entry.on
? COLOR.ok
: COLOR.bad,
}}
>
</span>
<span style={styles.configLabel}>{entry.label}</span>
<span style={styles.configValue} title={entry.value}>
{entry.value}
</span>
</div>
))}
</div>
<TrackList title="published ↑" rows={published} />
<TrackList title="subscribed ↓" rows={subscribed} />
<div style={styles.sectionTitle}>bandwidth</div>
<div style={{ ...styles.list, gap: 4 }}>
<CapStepper
label="uplink"
hint="encoder cap (setParameters)"
valueKbps={uplinkCap}
onChange={(kbps) => {
setUplinkCapState(kbps)
void setUplinkCap(room, kbps)
}}
/>
<CapStepper
label="downlink"
hint="SFU limit (subscriber-bandwidth)"
valueKbps={downlinkCap}
onChange={(kbps) => {
setDownlinkCapState(kbps)
void setDownlinkCap(room, kbps).catch((e) =>
console.warn('[MeetDevtools] downlink cap failed', e)
)
}}
/>
</div>
<div style={styles.sectionTitle}>transport</div>
<div style={styles.row}>
{transports.map(({ mode, label, requires, title }) => {
const available = !requires || turnProtocols.includes(requires)
const active = transportMode === mode
const clickable = available && !active
return (
<button
key={mode}
type="button"
aria-pressed={active}
disabled={!clickable}
title={available ? title : `${title} — not configured`}
style={{
...styles.button,
...(clickable || active ? {} : styles.buttonDisabled),
...(active ? styles.buttonActive : {}),
}}
onClick={() => {
if (!clickable) return
void (
mode === 'auto'
? releaseForcedTransport(room)
: forceTransport(
room,
mode as 'tcp' | 'turn-udp' | 'turn-tcp' | 'turn-tls'
)
).catch((e) =>
console.warn('[MeetDevtools] transport change failed', e)
)
}}
>
{requires && (
<span style={{ color: available ? COLOR.ok : COLOR.faint }}>
{' '}
</span>
)}
{label}
</button>
)
})}
<span style={styles.mono}>
route:{' '}
{snapshot?.route
? [
snapshot.route.protocol,
snapshot.route.type,
snapshot.route.relayProtocol &&
`relay:${snapshot.route.relayProtocol}`,
]
.filter(Boolean)
.join('·')
: ''}
</span>
</div>
<div style={styles.sectionTitle}>connection scenarios</div>
<div style={styles.row}>
{SCENARIOS.map((scenario) => (
<button
key={scenario.id}
type="button"
title={`${scenario.side}-side simulation — momentary, watch the state dot`}
style={{
...styles.button,
...(firedScenario === scenario.id ? styles.buttonActive : {}),
}}
onClick={() => fireScenario(scenario)}
>
{scenario.side === 'server' ? '☁ ' : ''}
{scenario.label}
</button>
))}
</div>
</section>
)
}
export default MeetDevtools
@@ -1,14 +0,0 @@
import { lazy, Suspense } from 'react'
const LazyPanel = import.meta.env.DEV
? lazy(() => import('./MeetDevtools'))
: null
export const MeetDevtools = () => {
if (!LazyPanel) return null
return (
<Suspense fallback={null}>
<LazyPanel />
</Suspense>
)
}
@@ -1,88 +0,0 @@
import { Room } from 'livekit-client'
export type ConfigEntry = {
label: string
value: string
/** true = feature actively on, false = off, undefined = informational */
on?: boolean
}
const formatBackupCodec = (backup: unknown): string => {
if (backup === undefined || backup === true) return 'auto'
if (backup === false) return 'off'
if (typeof backup === 'object' && backup !== null && 'codec' in backup) {
return String((backup as { codec: unknown }).codec)
}
return String(backup)
}
export const readRoomConfig = (room: Room): ConfigEntry[] => {
const options = room.options
const publish = options.publishDefaults
const adaptive = options.adaptiveStream
const entries: ConfigEntry[] = [
{
label: 'adaptiveStream',
value:
typeof adaptive === 'object'
? JSON.stringify(adaptive)
: String(!!adaptive),
on: !!adaptive,
},
{
label: 'dynacast',
value: String(!!options.dynacast),
on: !!options.dynacast,
},
{
label: 'e2ee',
value: String(room.isE2EEEnabled),
on: room.isE2EEEnabled,
},
{
label: 'videoCodec',
value: publish?.videoCodec ?? 'default',
},
{
label: 'backupCodec',
value: formatBackupCodec(publish?.backupCodec),
},
{
label: 'simulcast',
value: String(publish?.simulcast ?? true),
on: publish?.simulcast ?? true,
},
{
label: 'audio dtx',
value: String(publish?.dtx ?? true),
on: publish?.dtx ?? true,
},
{
label: 'audio red',
value: String(publish?.red ?? true),
on: publish?.red ?? true,
},
{
label: 'quality (local)',
value: room.localParticipant.connectionQuality,
},
]
const server = room.serverInfo
if (server) {
entries.push({
label: 'server',
value: [
server.version && `v${server.version}`,
server.region,
server.protocol !== undefined && `proto ${server.protocol}`,
server.edition !== undefined && `edition ${server.edition}`,
]
.filter(Boolean)
.join(' · '),
})
}
return entries
}
@@ -1,192 +0,0 @@
import { Room, Track } from 'livekit-client'
// Transitive dependency of livekit-client (pinned by it); used only to
// build the one signal request room.simulateScenario cannot express.
import { SimulateScenario } from '@livekit/protocol'
/** Shared bandwidth ladder for the /+ steppers; null = unlimited. */
export const BITRATE_LADDER_KBPS: Array<number | null> = [
null,
2000,
1000,
600,
300,
150,
]
export const stepBitrate = (
current: number | null,
direction: 'decrease' | 'increase'
): number | null => {
const index = BITRATE_LADDER_KBPS.indexOf(current)
const safeIndex = index === -1 ? 0 : index
const next =
direction === 'decrease'
? Math.min(safeIndex + 1, BITRATE_LADDER_KBPS.length - 1)
: Math.max(safeIndex - 1, 0)
return BITRATE_LADDER_KBPS[next]
}
const savedEncodings = new WeakMap<RTCRtpSender, Array<number | undefined>>()
export const setUplinkCap = async (
room: Room,
kbps: number | null
): Promise<void> => {
const senders: RTCRtpSender[] = []
room.localParticipant.trackPublications.forEach((pub) => {
const track = pub.track
if (track?.kind === Track.Kind.Video && track.sender) {
senders.push(track.sender)
}
})
for (const sender of senders) {
const params = sender.getParameters()
if (!params.encodings || params.encodings.length === 0) continue
if (kbps === null) {
const original = savedEncodings.get(sender)
params.encodings.forEach((encoding, i) => {
encoding.maxBitrate = original?.[i]
})
savedEncodings.delete(sender)
} else {
if (!savedEncodings.has(sender)) {
savedEncodings.set(
sender,
params.encodings.map((encoding) => encoding.maxBitrate)
)
}
const activeCount =
params.encodings.filter((encoding) => encoding.active !== false)
.length || 1
// Split the budget across active simulcast layers / SVC encoding.
const perEncoding = Math.max(
30_000,
Math.floor((kbps * 1000) / activeCount)
)
params.encodings.forEach((encoding) => {
encoding.maxBitrate = perEncoding
})
}
try {
await sender.setParameters(params)
} catch (e) {
console.warn('[MeetDevtools] setParameters failed', e)
}
}
}
export const setDownlinkCap = (
room: Room,
kbps: number | null
): Promise<void> =>
room.simulateScenario('subscriber-bandwidth', kbps === null ? 0 : kbps * 1000)
export type Scenario = {
id: string
label: string
/** where the simulation happens */
side: 'client' | 'server'
run: (room: Room) => Promise<void>
}
export const SCENARIOS: Scenario[] = [
{
id: 'resume',
label: 'reconnect (resume)',
side: 'client',
// Replays a signaling WebSocket loss; media keeps flowing, client resumes.
run: (room) => room.simulateScenario('signal-reconnect'),
},
{
id: 'resume-fail',
label: 'reconnect (resume fails)',
side: 'client',
// Same, but the next resume attempt fails → exercises the retry ladder.
run: (room) => room.simulateScenario('resume-reconnect'),
},
{
id: 'full-reconnect',
label: 'full reconnect',
side: 'client',
// Complete rejoin with brand-new peer connections.
run: (room) => room.simulateScenario('full-reconnect'),
},
{
id: 'migration',
label: 'server migration',
side: 'server',
run: (room) => room.simulateScenario('migration'),
},
{
id: 'node-failure',
label: 'SFU node failure',
side: 'server',
run: (room) => room.simulateScenario('node-failure'),
},
{
id: 'server-leave',
label: 'server disconnect',
side: 'server',
// Server-initiated leave: the closest thing to "you got kicked".
run: (room) => room.simulateScenario('server-leave'),
},
]
export type TransportMode =
| 'auto'
| 'tcp'
| 'turn-udp'
| 'turn-tcp'
| 'turn-tls'
const clearServerTransportPreference = (room: Room): Promise<void> =>
room.engine.client.sendSimulateScenario(
new SimulateScenario({
scenario: { case: 'switchCandidateProtocol', value: 0 },
})
)
const setRelayOnly = (room: Room, relay: boolean) => {
room.engine.rtcConfig = {
...room.engine.rtcConfig,
iceTransportPolicy: relay ? 'relay' : 'all',
}
}
const settle = () => new Promise((resolve) => setTimeout(resolve, 300))
export const forceTransport = async (
room: Room,
mode: 'tcp' | 'turn-udp' | 'turn-tcp' | 'turn-tls'
): Promise<void> => {
if (mode === 'turn-udp') {
await clearServerTransportPreference(room)
setRelayOnly(room, true)
await settle()
return room.simulateScenario('full-reconnect')
}
setRelayOnly(room, false)
return room.simulateScenario(mode === 'turn-tls' ? 'force-tls' : 'force-tcp')
}
export const releaseForcedTransport = async (room: Room): Promise<void> => {
setRelayOnly(room, false)
await clearServerTransportPreference(room)
await settle()
await room.simulateScenario('full-reconnect')
}
export const transportModeFromRoute = (route?: {
protocol?: string
relayProtocol?: string
}): TransportMode => {
// relayProtocol is the client→TURN leg; protocol alone means no relay.
if (route?.relayProtocol === 'tls') return 'turn-tls'
if (route?.relayProtocol === 'tcp') return 'turn-tcp'
if (route?.relayProtocol === 'udp') return 'turn-udp'
if (route?.protocol === 'tcp') return 'tcp'
return 'auto'
}
@@ -1,243 +0,0 @@
import { useEffect, useRef, useState } from 'react'
import { Room } from 'livekit-client'
export type TrackRow = {
key: string
dir: 'up' | 'down'
label: string
codec?: string
kbps: number
fps?: number
res?: string
}
export type StatsSnapshot = {
ts: number
/** wire totals from transport stats (includes headers, RTCP, FEC) */
upKbps: number
downKbps: number
rttMs?: number
/** worst inbound RTP jitter across subscribed tracks */
jitterMs?: number
availableOutKbps?: number
/** selected ICE route of the publisher transport (measured, not assumed) */
route?: { protocol?: string; type?: string; relayProtocol?: string }
/**
* relayProtocol values of gathered relay local candidates — i.e. which
* client→TURN transports are actually configured (udp/tcp/tls). Empty
* when no TURN server is configured.
*/
turnProtocols: string[]
tracks: TrackRow[]
}
type StatDict = Record<string, unknown>
type Counters = Record<string, number>
const asNumber = (v: unknown): number | undefined =>
typeof v === 'number' && Number.isFinite(v) ? v : undefined
const asString = (v: unknown): string | undefined =>
typeof v === 'string' ? v : undefined
const shortCodec = (mimeType?: string) =>
mimeType ? mimeType.replace(/^(audio|video)\//, '') : undefined
const buildTrackLabels = (room: Room) => {
const labels = new Map<string, string>()
room.localParticipant.trackPublications.forEach((pub) => {
const id = pub.track?.mediaStreamTrack?.id
if (id) labels.set(id, `local ${pub.source}`)
})
room.remoteParticipants.forEach((participant) => {
// Keep rows scannable: participant names capped at 10 chars.
const rawName = participant.name || participant.identity
const name = rawName.length > 10 ? `${rawName.slice(0, 10)}.` : rawName
participant.trackPublications.forEach((pub) => {
const id = pub.track?.mediaStreamTrack?.id
if (id) labels.set(id, `${name} ${pub.source}`)
})
})
return labels
}
export const useWebRTCStats = (
room: Room,
enabled: boolean,
intervalMs = 1000
) => {
// Single source of truth: the snapshot is just the last history entry.
const [history, setHistory] = useState<StatsSnapshot[]>([])
const prevRef = useRef(new Map<string, Counters>())
useEffect(() => {
if (!enabled) return
let cancelled = false
const prev = prevRef.current
/** Per-stat counter deltas; returns 0 on the first sighting. */
const deltas = (key: string, now: Counters): Counters => {
const before = prev.get(key)
prev.set(key, now)
const out: Counters = {}
for (const [name, value] of Object.entries(now)) {
out[name] = before?.[name] !== undefined ? value - before[name] : 0
}
return out
}
const collect = async () => {
const reports: Array<{ pc: 'pub' | 'sub'; report: RTCStatsReport }> = []
try {
// Not public API — see file header.
const manager = room.engine?.pcManager
const pub = await manager?.publisher?.getStats()
if (pub) reports.push({ pc: 'pub', report: pub })
const sub = await manager?.subscriber?.getStats()
if (sub) reports.push({ pc: 'sub', report: sub })
} catch {
// Engine not ready or SDK internals changed; panel shows nothing.
}
if (cancelled || reports.length === 0) return
const labels = buildTrackLabels(room)
const tracks: TrackRow[] = []
let upKbps = 0
let downKbps = 0
let rttMs: number | undefined
let jitterMs: number | undefined
let availableOutKbps: number | undefined
let route: StatsSnapshot['route']
const turnProtocols = new Set<string>()
for (const { pc, report } of reports) {
const byId = new Map<string, StatDict>()
report.forEach((stat) => byId.set(stat.id as string, stat as StatDict))
report.forEach((raw) => {
const stat = raw as StatDict
const type = asString(stat.type)
const ts = asNumber(stat.timestamp) ?? Date.now()
const key = `${pc}:${asString(stat.id) ?? ''}`
if (
type === 'local-candidate' &&
asString(stat.candidateType) === 'relay'
) {
// Relay candidates are only gathered when a TURN server is
// configured and reachable; relayProtocol says how the client
// reaches it (udp/tcp/tls).
turnProtocols.add(
asString(stat.relayProtocol) ?? asString(stat.protocol) ?? 'udp'
)
}
if (type === 'transport') {
const d = deltas(key, {
sent: asNumber(stat.bytesSent) ?? 0,
received: asNumber(stat.bytesReceived) ?? 0,
ts,
})
if (d.ts > 0) {
upKbps += Math.max(0, (d.sent * 8) / d.ts)
downKbps += Math.max(0, (d.received * 8) / d.ts)
}
}
if (type === 'candidate-pair' && stat.nominated === true) {
const rtt = asNumber(stat.currentRoundTripTime)
if (rtt !== undefined) rttMs = Math.round(rtt * 1000)
const available = asNumber(stat.availableOutgoingBitrate)
if (available !== undefined && pc === 'pub') {
availableOutKbps = Math.round(available / 1000)
}
if (pc === 'pub') {
const local = byId.get(asString(stat.localCandidateId) ?? '')
route = {
protocol: asString(local?.protocol),
type: asString(local?.candidateType),
relayProtocol: asString(local?.relayProtocol),
}
}
}
if (type === 'outbound-rtp' || type === 'inbound-rtp') {
const isUp = type === 'outbound-rtp'
if (!isUp) {
const jitter = asNumber(stat.jitter)
if (jitter !== undefined) {
const ms = Math.round(jitter * 1000)
if (jitterMs === undefined || ms > jitterMs) jitterMs = ms
}
}
const d = deltas(key, {
bytes: asNumber(isUp ? stat.bytesSent : stat.bytesReceived) ?? 0,
ts,
})
const kbps = d.ts > 0 ? Math.max(0, (d.bytes * 8) / d.ts) : 0
// Resolve codec + source track.
const codecStat = byId.get(asString(stat.codecId) ?? '')
let msTrackId = asString(stat.trackIdentifier)
if (!msTrackId && isUp) {
const mediaSource = byId.get(asString(stat.mediaSourceId) ?? '')
msTrackId = asString(mediaSource?.trackIdentifier)
}
const rid = asString(stat.rid)
const baseLabel =
(msTrackId && labels.get(msTrackId)) ??
`${asString(stat.kind) ?? 'media'} ssrc ${asNumber(stat.ssrc) ?? '?'}`
const width = asNumber(stat.frameWidth)
const height = asNumber(stat.frameHeight)
tracks.push({
key,
dir: isUp ? 'up' : 'down',
label: rid ? `${baseLabel} [${rid}]` : baseLabel,
codec: shortCodec(asString(codecStat?.mimeType)),
kbps,
fps: asNumber(stat.framesPerSecond),
res: width && height ? `${width}x${height}` : undefined,
})
}
})
}
// Stable order (direction, then label): sorting by bitrate would
// reshuffle rows on every tick as kbps fluctuates.
tracks.sort((a, b) =>
a.dir === b.dir
? a.label.localeCompare(b.label)
: a.dir === 'up'
? -1
: 1
)
const next: StatsSnapshot = {
ts: Date.now(),
upKbps: Math.round(upKbps),
downKbps: Math.round(downKbps),
rttMs,
jitterMs,
availableOutKbps,
route,
turnProtocols: Array.from(turnProtocols).sort(),
tracks,
}
setHistory((h) => [...h.slice(-59), next])
}
void collect()
const id = window.setInterval(() => void collect(), intervalMs)
return () => {
cancelled = true
window.clearInterval(id)
}
}, [room, enabled, intervalMs])
return { snapshot: history[history.length - 1], history }
}
@@ -43,7 +43,6 @@ import { useSnapshot } from 'valtio'
import { userPreferencesStore } from '@/stores/userPreferences' import { userPreferencesStore } from '@/stores/userPreferences'
import { userStore } from '@/stores/user' import { userStore } from '@/stores/user'
import { WatchMediaDeviceErrors } from './WatchMediaDeviceErrors' import { WatchMediaDeviceErrors } from './WatchMediaDeviceErrors'
import { MeetDevtools } from '@/features/devtools'
import { VOICE_AUDIO_CONSTRAINTS } from '@/features/rooms/livekit/utils/constants' import { VOICE_AUDIO_CONSTRAINTS } from '@/features/rooms/livekit/utils/constants'
export const Conference = ({ export const Conference = ({
@@ -299,7 +298,6 @@ export const Conference = ({
<VideoConference /> <VideoConference />
{!isMobile && <InviteDialog mode={mode} />} {!isMobile && <InviteDialog mode={mode} />}
<PictureInPictureConference /> <PictureInPictureConference />
<MeetDevtools />
</LiveKitRoom> </LiveKitRoom>
</Screen> </Screen>
</QueryAware> </QueryAware>
@@ -2,7 +2,7 @@ import { useTranslation } from 'react-i18next'
import { useTrackToggle, UseTrackToggleProps } from '@livekit/components-react' import { useTrackToggle, UseTrackToggleProps } from '@livekit/components-react'
import { Button, Popover } from '@/primitives' import { Button, Popover } from '@/primitives'
import { RiArrowUpSLine, RiImageCircleAiFill } from '@remixicon/react' import { RiArrowUpSLine, RiImageCircleAiFill } from '@remixicon/react'
import { Track, type VideoCaptureOptions, VideoPresets } from 'livekit-client' import { Track, type VideoCaptureOptions } from 'livekit-client'
import { ToggleDevice } from './ToggleDevice' import { ToggleDevice } from './ToggleDevice'
import { css } from '@/styled-system/css' import { css } from '@/styled-system/css'
@@ -57,8 +57,7 @@ export const VideoDeviceControl = ({
}: VideoDeviceControlProps) => { }: VideoDeviceControlProps) => {
const { t } = useTranslation('rooms', { keyPrefix: 'selectDevice' }) const { t } = useTranslation('rooms', { keyPrefix: 'selectDevice' })
const { videoDeviceId, processorConfig, videoPublishResolution } = const { videoDeviceId, processorConfig } = useSnapshot(userChoicesStore)
useSnapshot(userChoicesStore)
const onChange = React.useCallback( const onChange = React.useCallback(
(enabled: boolean, isUserInitiated: boolean) => (enabled: boolean, isUserInitiated: boolean) =>
@@ -98,9 +97,6 @@ export const VideoDeviceControl = ({
await toggle(!trackProps.enabled, { await toggle(!trackProps.enabled, {
processor: processor, processor: processor,
...(videoPublishResolution && {
resolution: VideoPresets[videoPublishResolution].resolution,
}),
} as VideoCaptureOptions) } as VideoCaptureOptions)
} }
@@ -18,7 +18,6 @@ import {
saveVideoPublishResolution, saveVideoPublishResolution,
saveVideoSubscribeQuality, saveVideoSubscribeQuality,
userChoicesStore, userChoicesStore,
VIDEO_RESOLUTIONS,
VideoResolution, VideoResolution,
} from '@/stores/userChoices' } from '@/stores/userChoices'
import { RowWrapper } from './layout/RowWrapper' import { RowWrapper } from './layout/RowWrapper'
@@ -33,8 +32,7 @@ const EMPTY_PROPS = {}
export const VideoTab = ({ id }: VideoTabProps) => { export const VideoTab = ({ id }: VideoTabProps) => {
const { t } = useTranslation('settings', { keyPrefix: 'video' }) const { t } = useTranslation('settings', { keyPrefix: 'video' })
const room = useRoomContext() const { localParticipant, remoteParticipants } = useRoomContext()
const { localParticipant, remoteParticipants } = room
const { const {
videoDeviceId, videoDeviceId,
@@ -71,21 +69,20 @@ export const VideoTab = ({ id }: VideoTabProps) => {
isDisabled: true, isDisabled: true,
} }
const handleVideoResolutionChange = async (key: VideoResolution) => { const handleVideoResolutionChange = async (key: 'h720' | 'h360' | 'h180') => {
saveVideoPublishResolution(key) const videoPublication = localParticipant.getTrackPublication(
const videoTrack = localParticipant.getTrackPublication(
Track.Source.Camera Track.Source.Camera
)?.track )
if (!videoTrack) { const videoTrack = videoPublication?.track
return if (videoTrack) {
saveVideoPublishResolution(key)
await videoTrack.restartTrack({
resolution: VideoPresets[key].resolution,
deviceId: { exact: videoDeviceId },
processor:
BackgroundProcessorFactory.fromProcessorConfig(processorConfig),
})
} }
await videoTrack.restartTrack({
resolution: VideoPresets[key].resolution,
deviceId: { exact: videoDeviceId },
processor:
BackgroundProcessorFactory.fromProcessorConfig(processorConfig),
})
} }
/** /**
@@ -125,13 +122,20 @@ export const VideoTab = ({ id }: VideoTabProps) => {
}, [videoDeviceId, videoElement]) }, [videoDeviceId, videoElement])
const resolutionItems = useMemo(() => { const resolutionItems = useMemo(() => {
const labels: Record<VideoResolution, string> = { return [
h1080: `${t('resolution.publish.items.veryHigh')} (1080p)`, {
h720: `${t('resolution.publish.items.high')} (720p)`, value: 'h720',
h360: `${t('resolution.publish.items.medium')} (360p)`, label: `${t('resolution.publish.items.high')} (720p)`,
h180: `${t('resolution.publish.items.low')} (180p)`, },
} {
return VIDEO_RESOLUTIONS.map((value) => ({ value, label: labels[value] })) value: 'h360',
label: `${t('resolution.publish.items.medium')} (360p)`,
},
{
value: 'h180',
label: `${t('resolution.publish.items.low')} (180p)`,
},
]
}, [t]) }, [t])
const videoQualityItems = useMemo(() => { const videoQualityItems = useMemo(() => {
@@ -56,7 +56,6 @@
"publish": { "publish": {
"label": "Wähle die maximale Auflösung beim Senden", "label": "Wähle die maximale Auflösung beim Senden",
"items": { "items": {
"veryHigh": "Sehr hohe Auflösung",
"high": "Hohe Auflösung", "high": "Hohe Auflösung",
"medium": "Mittlere Auflösung", "medium": "Mittlere Auflösung",
"low": "Niedrige Auflösung" "low": "Niedrige Auflösung"
@@ -56,7 +56,6 @@
"publish": { "publish": {
"label": "Select your sending resolution (max.)", "label": "Select your sending resolution (max.)",
"items": { "items": {
"veryHigh": "Very high definition",
"high": "High definition", "high": "High definition",
"medium": "Standard definition", "medium": "Standard definition",
"low": "Low definition" "low": "Low definition"
@@ -56,7 +56,6 @@
"publish": { "publish": {
"label": "Selecciona tu resolución de envío (máx.)", "label": "Selecciona tu resolución de envío (máx.)",
"items": { "items": {
"veryHigh": "Muy alta definición",
"high": "Alta definición", "high": "Alta definición",
"medium": "Definición estándar", "medium": "Definición estándar",
"low": "Baja definición" "low": "Baja definición"
@@ -56,7 +56,6 @@
"publish": { "publish": {
"label": "Sélectionner votre résolution d'envoi (max.)", "label": "Sélectionner votre résolution d'envoi (max.)",
"items": { "items": {
"veryHigh": "Très haute définition",
"high": "Haute définition", "high": "Haute définition",
"medium": "Définition standard", "medium": "Définition standard",
"low": "Basse définition" "low": "Basse définition"
@@ -56,7 +56,6 @@
"publish": { "publish": {
"label": "Selecteer uw verzendresolutie (max.)", "label": "Selecteer uw verzendresolutie (max.)",
"items": { "items": {
"veryHigh": "Zeer hoge definitie",
"high": "Hoge definitie", "high": "Hoge definitie",
"medium": "Standaarddefinitie", "medium": "Standaarddefinitie",
"low": "Lage definitie" "low": "Lage definitie"
+2 -11
View File
@@ -10,12 +10,7 @@ import {
} from '@livekit/components-core' } from '@livekit/components-core'
import { VideoQuality } from 'livekit-client' import { VideoQuality } from 'livekit-client'
export const VIDEO_RESOLUTIONS = ['h1080', 'h720', 'h360', 'h180'] as const export type VideoResolution = 'h720' | 'h360' | 'h180'
export type VideoResolution = (typeof VIDEO_RESOLUTIONS)[number]
const isVideoResolution = (value: unknown): value is VideoResolution =>
VIDEO_RESOLUTIONS.includes(value as VideoResolution)
export type LocalUserChoices = Omit<LocalUserChoicesLK, 'username'> & { export type LocalUserChoices = Omit<LocalUserChoicesLK, 'username'> & {
processorConfig?: ProcessorConfig processorConfig?: ProcessorConfig
@@ -26,17 +21,13 @@ export type LocalUserChoices = Omit<LocalUserChoicesLK, 'username'> & {
} }
function getUserChoicesState(): LocalUserChoices { function getUserChoicesState(): LocalUserChoices {
const stored: LocalUserChoices = { return {
noiseReductionEnabled: false, noiseReductionEnabled: false,
audioOutputDeviceId: 'default', // Use 'default' to match LiveKit's standard device selection behavior audioOutputDeviceId: 'default', // Use 'default' to match LiveKit's standard device selection behavior
videoPublishResolution: 'h720', videoPublishResolution: 'h720',
videoSubscribeQuality: VideoQuality.HIGH, videoSubscribeQuality: VideoQuality.HIGH,
...loadUserChoices(), ...loadUserChoices(),
} }
if (!isVideoResolution(stored.videoPublishResolution)) {
stored.videoPublishResolution = 'h720'
}
return stored
} }
export const userChoicesStore = proxy<LocalUserChoices>(getUserChoicesState()) export const userChoicesStore = proxy<LocalUserChoices>(getUserChoicesState())
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "mail_mjml", "name": "mail_mjml",
"version": "1.30.0", "version": "1.29.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "mail_mjml", "name": "mail_mjml",
"version": "1.30.0", "version": "1.29.0",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@html-to/text-cli": "0.6.1", "@html-to/text-cli": "0.6.1",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "mail_mjml", "name": "mail_mjml",
"version": "1.30.0", "version": "1.29.0",
"description": "An util to generate html and text django's templates from mjml templates", "description": "An util to generate html and text django's templates from mjml templates",
"type": "module", "type": "module",
"dependencies": { "dependencies": {
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "sdk", "name": "sdk",
"version": "1.30.0", "version": "1.29.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "sdk", "name": "sdk",
"version": "1.30.0", "version": "1.29.0",
"license": "ISC", "license": "ISC",
"workspaces": [ "workspaces": [
"./library", "./library",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "sdk", "name": "sdk",
"version": "1.30.0", "version": "1.29.0",
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"description": "", "description": "",
+1 -1
View File
@@ -1,7 +1,7 @@
[project] [project]
name = "summary" name = "summary"
version = "1.30.0" version = "1.29.0"
requires-python = ">=3.13" requires-python = ">=3.13"
dependencies = [ dependencies = [
"fastapi[standard]>=0.105.0", "fastapi[standard]>=0.105.0",
+1 -1
View File
@@ -1507,7 +1507,7 @@ wheels = [
[[package]] [[package]]
name = "summary" name = "summary"
version = "1.30.0" version = "1.26.0"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "celery" }, { name = "celery" },