Merge branch 'master' into 0.16.0

This commit is contained in:
João Vitória Silva
2025-11-15 23:01:25 +00:00
218 changed files with 3380 additions and 1646 deletions

1
.gitignore vendored
View File

@@ -4,6 +4,7 @@ docker-compose.yml
.env
# aux folder
.garminconnect
aux_scripts/.garminconnect
# Python

View File

@@ -82,12 +82,13 @@ def init_api(email, password):
date = get_date()
date_object = datetime.datetime.strptime(date, "%d-%m-%Y")
date_string = date_object.strftime("%Y-%m-%d")
if not api:
api = init_api(email, password)
if api:
garmin_bc = api.get_body_composition(date_object, date_object)
garmin_bc = api.get_body_composition(date_string, date_string)
if garmin_bc is None:
# Log an informational event if no body composition were found

View File

@@ -541,12 +541,11 @@ async def read_activities_user_activities_refresh(
if garmin_activities is not None:
activities.extend(garmin_activities)
# Check if activities is None and return None if it is
if activities is None:
return None
# Filter out None values from the activities list
activities = [activity for activity in activities if activity is not None]
# Return the activities
return activities
# Return the activities or None if the list is empty
return activities if activities else None
@router.get(

View File

@@ -59,9 +59,7 @@ class Activity(BaseModel):
tracker_manufacturer: str | None = None
tracker_model: str | None = None
model_config = {
"from_attributes": True
}
model_config = {"from_attributes": True}
class ActivityDistances(BaseModel):
@@ -82,6 +80,7 @@ class ActivityEdit(BaseModel):
name: str
activity_type: int
visibility: int | None = None
is_hidden: bool | None = None
gear_id: int | None = None
hide_start_time: bool | None = None
hide_location: bool | None = None

View File

@@ -87,6 +87,7 @@ ACTIVITY_ID_TO_NAME = {
38: "Soccer",
39: "Padel",
40: "Treadmill",
41: "Cardio training",
# Add other mappings as needed based on the full list in define_activity_type comments if required
# "AlpineSki",
# "BackcountrySki",
@@ -213,6 +214,7 @@ ACTIVITY_NAME_TO_ID.update(
"padelball": 39,
"paddelball": 39,
"treadmill": 40,
"cardio_training": 41,
}
)

View File

@@ -360,8 +360,8 @@ def edit_user(user_id: int, user: users_schema.UserRead, db: Session):
height_before = db_user.height
# If the user photo path is different, delete the user photo in the filesystem
if db_user.photo_path != user.photo_path:
# Check if the photo_path is being updated
if user.photo_path:
# Delete the user photo in the filesystem
users_utils.delete_user_photo_filesystem(db_user.id)

View File

@@ -34,24 +34,28 @@ class Language(Enum):
CATALAN: Catalan language code ("ca-ES").
CHINESE_SIMPLIFIED: Simplified Chinese language code ("cn").
CHINESE_TRADITIONAL: Traditional Chinese language code ("tw").
DUTCH: Dutch language code ("nl").
GERMAN: German language code ("de").
FRENCH: French language code ("fr").
GALICIAN: Galician language code ("gl").
SPANISH: Spanish language code ("es").
ITALIAN: Italian language code ("it").
DUTCH: Dutch language code ("nl").
PORTUGUESE: Portuguese language code ("pt").
SLOVENIAN: Slovenian language code ("sl").
SPANISH: Spanish language code ("es").
ENGLISH_USA: US English language code ("us").
"""
CATALAN = "ca"
CHINESE_SIMPLIFIED = "cn"
CHINESE_TRADITIONAL = "tw"
DUTCH = "nl"
GERMAN = "de"
FRENCH = "fr"
GALICIAN = "gl"
SPANISH = "es"
ITALIAN = "it"
DUTCH = "nl"
PORTUGUESE = "pt"
SLOVENIAN = "sl"
SPANISH = "es"
ENGLISH_USA = "us"

View File

@@ -49,6 +49,7 @@ class ActivityType(IntEnum):
SWIM (3): Swimming activities.
WALK (4): Walking or hiking activities.
STRENGTH (5): Strength or resistance training sessions.
CARDIO (6): Cardiovascular training activities.
"""
RUN = 1
@@ -56,6 +57,7 @@ class ActivityType(IntEnum):
SWIM = 3
WALK = 4
STRENGTH = 5
CARDIO = 6
class GoalType(IntEnum):

View File

@@ -85,10 +85,11 @@ def calculate_goal_progress_by_activity_type(
user_goals_schema.ActivityType.BIKE: [4, 5, 6, 7, 27, 28, 29, 35, 36],
user_goals_schema.ActivityType.SWIM: [8, 9],
user_goals_schema.ActivityType.WALK: [11, 12],
user_goals_schema.ActivityType.CARDIO: [20, 41],
}
DEFAULT_TYPES = (19, 20)
DEFAULT_TYPES = (10, 19)
# Get activity types based on goal.activity_type, default to [10, 19, 20]
# Get activity types based on goal.activity_type, default to [10, 19]
activity_types = TYPE_MAP.get(goal.activity_type, DEFAULT_TYPES)
# Fetch all activities in a single query

390
backend/poetry.lock generated
View File

@@ -2,14 +2,14 @@
[[package]]
name = "alembic"
version = "1.17.1"
version = "1.17.2"
description = "A database migration tool for SQLAlchemy."
optional = false
python-versions = ">=3.10"
groups = ["main"]
files = [
{file = "alembic-1.17.1-py3-none-any.whl", hash = "sha256:cbc2386e60f89608bb63f30d2d6cc66c7aaed1fe105bd862828600e5ad167023"},
{file = "alembic-1.17.1.tar.gz", hash = "sha256:8a289f6778262df31571d29cca4c7fbacd2f0f582ea0816f4c399b6da7528486"},
{file = "alembic-1.17.2-py3-none-any.whl", hash = "sha256:f483dd1fe93f6c5d49217055e4d15b905b425b6af906746abb35b69c1996c4e6"},
{file = "alembic-1.17.2.tar.gz", hash = "sha256:bbe9751705c5e0f14877f02d46c53d10885e377e3d90eda810a016f9baa19e8e"},
]
[package.dependencies]
@@ -355,14 +355,14 @@ virtualenv = ["virtualenv (>=20.11) ; python_version < \"3.10\"", "virtualenv (>
[[package]]
name = "cachecontrol"
version = "0.14.3"
version = "0.14.4"
description = "httplib2 caching for requests"
optional = false
python-versions = ">=3.9"
python-versions = ">=3.10"
groups = ["main"]
files = [
{file = "cachecontrol-0.14.3-py3-none-any.whl", hash = "sha256:b35e44a3113f17d2a31c1e6b27b9de6d4405f84ae51baa8c1d3cc5b633010cae"},
{file = "cachecontrol-0.14.3.tar.gz", hash = "sha256:73e7efec4b06b20d9267b441c1f733664f989fb8688391b670ca812d70795d11"},
{file = "cachecontrol-0.14.4-py3-none-any.whl", hash = "sha256:b7ac014ff72ee199b5f8af1de29d60239954f223e948196fa3d84adaffc71d2b"},
{file = "cachecontrol-0.14.4.tar.gz", hash = "sha256:e6220afafa4c22a47dd0badb319f84475d79108100d04e26e8542ef7d3ab05a1"},
]
[package.dependencies]
@@ -371,20 +371,20 @@ msgpack = ">=0.5.2,<2.0.0"
requests = ">=2.16.0"
[package.extras]
dev = ["CacheControl[filecache,redis]", "build", "cherrypy", "codespell[tomli]", "furo", "mypy", "pytest", "pytest-cov", "ruff", "sphinx", "sphinx-copybutton", "tox", "types-redis", "types-requests"]
dev = ["cachecontrol[filecache,redis]", "cheroot (>=11.1.2)", "cherrypy", "codespell", "furo", "mypy", "pytest", "pytest-cov", "ruff", "sphinx", "sphinx-copybutton", "types-redis", "types-requests"]
filecache = ["filelock (>=3.8.0)"]
redis = ["redis (>=2.10.5)"]
[[package]]
name = "certifi"
version = "2025.10.5"
version = "2025.11.12"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.7"
groups = ["main", "dev"]
files = [
{file = "certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de"},
{file = "certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43"},
{file = "certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b"},
{file = "certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316"},
]
[[package]]
@@ -608,14 +608,14 @@ rapidfuzz = ">=3.0.0,<4.0.0"
[[package]]
name = "click"
version = "8.3.0"
version = "8.3.1"
description = "Composable command line interface toolkit"
optional = false
python-versions = ">=3.10"
groups = ["main"]
files = [
{file = "click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc"},
{file = "click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4"},
{file = "click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6"},
{file = "click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a"},
]
[package.dependencies]
@@ -943,43 +943,43 @@ wmi = ["wmi (>=1.5.1) ; platform_system == \"Windows\""]
[[package]]
name = "dulwich"
version = "0.24.8"
version = "0.24.10"
description = "Python Git Library"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "dulwich-0.24.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:661af1fa3852d970fef68b0ab431f0bd488c3f94306e89244c173c4e6abb978e"},
{file = "dulwich-0.24.8-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:1bac020051cf228b33c787294e17ac80a284e028c3749437ee72577ee04e1cd9"},
{file = "dulwich-0.24.8-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:97f7c64b02fbd366c36557aa2e8642fc686aaec7d6569bc1460d0b38a63169f9"},
{file = "dulwich-0.24.8-cp310-cp310-win32.whl", hash = "sha256:f7519f3b8c66ba2e4ea66f47c2156a66cefedce2a121ac3227e030abe95698f3"},
{file = "dulwich-0.24.8-cp310-cp310-win_amd64.whl", hash = "sha256:a60f8a5d718c7cc1f60bb931cc915311fd5198d85d68dde0ef3c569311c14a70"},
{file = "dulwich-0.24.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07aa6e7d41358fcba2a8ac53731e1b8ab201cac7a192ec678ef0da34c7643cf1"},
{file = "dulwich-0.24.8-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:0e9aacbbb0b0cf4b3fecac2c29ddd4d4e36f03ced30851889c193986e8bb327e"},
{file = "dulwich-0.24.8-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8eca5242f8aed324394c95ecd13a0a66d2a0c31c2556f0a52e7bb8dd67edef20"},
{file = "dulwich-0.24.8-cp311-cp311-win32.whl", hash = "sha256:108c74b329599931bfe66c4a34fb9312cd8136053cbfc04e7007e7c34081c6b7"},
{file = "dulwich-0.24.8-cp311-cp311-win_amd64.whl", hash = "sha256:efbf0f29d8d3d56a098e2b4a9260bdfa5f313142180a882c7b28e648d9b5ca9e"},
{file = "dulwich-0.24.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8ac85e3ea42878fa91b6a9282652327df54f5abea4aaf674036e1000608a15f0"},
{file = "dulwich-0.24.8-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:b31e08bcd0a4eb29915987fa5273a827cccca7ee83eb27ef17bd5899f5668055"},
{file = "dulwich-0.24.8-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:267e79367cd6f438091248c1e826c6cf7abd84d5b641b9fe46fbc4d9119e11ed"},
{file = "dulwich-0.24.8-cp312-cp312-win32.whl", hash = "sha256:6a51a41e858e0427b14bb19df7ac1207275dd6b5cc1976f54710bf15cb4c5614"},
{file = "dulwich-0.24.8-cp312-cp312-win_amd64.whl", hash = "sha256:6016e3f7a0f1dd5e19df14b772cb8f42bfde0cd55c504642c05e1e8328de21e3"},
{file = "dulwich-0.24.8-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:19be46710a9d810a66d4a925754abf3818ba22d61134e7d7e1d7b1585c9445b6"},
{file = "dulwich-0.24.8-cp313-cp313-android_21_x86_64.whl", hash = "sha256:17d8223cc69cf79ddd7a2f0893e223708f7efc2ea372f919ddcc0d852b3f5d06"},
{file = "dulwich-0.24.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a0a780b512d4144336eac2f1f6b982eb78c313442e88ba0db853a224e2b918ef"},
{file = "dulwich-0.24.8-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:2e3a9a713fda94f3216da4743db3cc8d670330f44c4d98580ac4600242dba2c4"},
{file = "dulwich-0.24.8-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:b03474c16bcfa3524241b4ae89007931d79ac37c0b19e059133a6e63b7039845"},
{file = "dulwich-0.24.8-cp313-cp313-win32.whl", hash = "sha256:ec0f62538b6fb26cdd1b2fb70788ccfdb17df26a4ba1ca70e623e196c4004f5c"},
{file = "dulwich-0.24.8-cp313-cp313-win_amd64.whl", hash = "sha256:16e335bce0d5192d476db0ca81de1f90fb56863ad7d0b985b0333a8194c73c64"},
{file = "dulwich-0.24.8-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:19855e8a0ce299cdcdafdc8bc4f6653bea9e02124a5022e13cda8103fb36912d"},
{file = "dulwich-0.24.8-cp314-cp314-android_24_x86_64.whl", hash = "sha256:da03c7a6629b7ed37e7139739a175f2c9678080a45444418c54ab28d2ec6524b"},
{file = "dulwich-0.24.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f7a0d2cef91cf92a44071daa92639f648ab756d3db63a99e37d3a08ebacf69f3"},
{file = "dulwich-0.24.8-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:5593a7216b27412333b99b2e1851bcc2485485d5c4694430aa86d34a36f08d63"},
{file = "dulwich-0.24.8-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:ea6c63d3e40fc321ec7c5673b92be036b57aba7802c7e94a18f61451af382de0"},
{file = "dulwich-0.24.8-cp39-cp39-win32.whl", hash = "sha256:a6055b12cf2b90a0b4c21d38594f2681667d26bb0c135dfc36c2ea6de7458a37"},
{file = "dulwich-0.24.8-cp39-cp39-win_amd64.whl", hash = "sha256:138fd2480c1db43f372d52e4e6ed050c15f92ffbeeab9a0877dceb9801c65d2a"},
{file = "dulwich-0.24.8-py3-none-any.whl", hash = "sha256:6ffdd616135bcb31eb2edcccf82d4408720f1db69f596f687ffa2d26c2f5e6f4"},
{file = "dulwich-0.24.8.tar.gz", hash = "sha256:c9f4748bbcca56fb57458c71c0d30e2351ac15e0583d428c739c09228be68f05"},
{file = "dulwich-0.24.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1f511f7afe1f36e37193214e4e069685d7d0378e756cc96a2fcb138bdf9fefca"},
{file = "dulwich-0.24.10-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:2a56f9838e5d2414a2b57bab370b73b9803fefd98836ef841f0fd489b5cc1349"},
{file = "dulwich-0.24.10-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:90b24c0827299cfb53c4f4d4fedc811be5c4b10c11172ff6e5a5c52277fe0b3a"},
{file = "dulwich-0.24.10-cp310-cp310-win32.whl", hash = "sha256:0dfae8c59b97964a907fdf4c5809154a18fd8c55f2eb6d8fd1607464165a9aa2"},
{file = "dulwich-0.24.10-cp310-cp310-win_amd64.whl", hash = "sha256:0e1601789554e3d15b294356c78a5403521c27d5460e64dbbc44ffd5b10af4c3"},
{file = "dulwich-0.24.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fbf94fa73211d2f029751a72e1ca3a2fd35c6f5d9bb434acdf10a4a79ca322dd"},
{file = "dulwich-0.24.10-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:b715a9f85ed71bef8027275c1bded064e4925071ae8c8a8d9a20c67b31faf3cd"},
{file = "dulwich-0.24.10-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:858fae0c7121715282a993abb1919385a28e1a9c4f136f568748d283c2ba874f"},
{file = "dulwich-0.24.10-cp311-cp311-win32.whl", hash = "sha256:393e9c3cdd382cff20b5beb66989376d6da69e3b0dfec046a884707ab5d27ac9"},
{file = "dulwich-0.24.10-cp311-cp311-win_amd64.whl", hash = "sha256:470d6cd8207e1a5ff1fb34c4c6fac2ec9a96d618f7062e5fb96c5260927bb9a7"},
{file = "dulwich-0.24.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5c724e5fc67c45f3c813f2630795ac388e3e6310534212f799a7a6bf230648c8"},
{file = "dulwich-0.24.10-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:6a25ca1605a94090514af408f9df64427281aefbb726f542e97d86d3a7c8ec18"},
{file = "dulwich-0.24.10-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d9793fc1e42149a650a017dc8ce38485368a41729b9937e1dfcfedd0591ebe9d"},
{file = "dulwich-0.24.10-cp312-cp312-win32.whl", hash = "sha256:1601bfea3906b52c924fae5b6ba32a0b087fb8fae927607e6b5381e6f7559611"},
{file = "dulwich-0.24.10-cp312-cp312-win_amd64.whl", hash = "sha256:f7bfa9f0bfae57685754b163eef6641609047460939d28052e3beeb63efa6795"},
{file = "dulwich-0.24.10-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:843de5f678436a27b33aea0f2b87fd0453afdd0135f885a3ca44bc3147846dd2"},
{file = "dulwich-0.24.10-cp313-cp313-android_21_x86_64.whl", hash = "sha256:4914abb6408a719b7a1f7d9a182d1efd92c326e178b440faf582df50f9f032db"},
{file = "dulwich-0.24.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ce6e05ec50f258ccd14d83114eb32cc5bb241ae4a8c7199d014fd7568de285b1"},
{file = "dulwich-0.24.10-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:3581ae0af33f28e6c0834d2f41ca67ca81cd92a589e6a5f985e6c64373232958"},
{file = "dulwich-0.24.10-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:019af16c850ae85254289f9633a29dea02f45351c4182ea20b0c1394c074a13b"},
{file = "dulwich-0.24.10-cp313-cp313-win32.whl", hash = "sha256:4b5c225477a529e1d4a2b5e51272a418177e34803938391ce41b7573b2e5b0d0"},
{file = "dulwich-0.24.10-cp313-cp313-win_amd64.whl", hash = "sha256:752c32d517dc608dbb8414061eaaec8ac8a05591b29531f81a83336b018b26c6"},
{file = "dulwich-0.24.10-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:44f62e0244531a8c43ca7771e201ec9e7f6a2fb27f8c3c623939bc03c1f50423"},
{file = "dulwich-0.24.10-cp314-cp314-android_24_x86_64.whl", hash = "sha256:e2eda4a634d6f1ac4c0d4786f8772495c8840dfc2b3e595507376bf5e5b0f9c5"},
{file = "dulwich-0.24.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1b19af8a3ab051003ba05f15fc5c0d6f0d427e795639490790f34ec0558e99e3"},
{file = "dulwich-0.24.10-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:90028182b9a47ea4efed51c81298f3a98e279d7bf5c1f91c47101927a309ee45"},
{file = "dulwich-0.24.10-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:8df79c8080471f363e4dfcfc4e0d2e61e6da73af1fd7d31cb6ae0d34af45a6b4"},
{file = "dulwich-0.24.10-cp39-cp39-win32.whl", hash = "sha256:f102c38207540fa485e85e0b763ce3725a2d49d846dbf316ed271e27fd85ff21"},
{file = "dulwich-0.24.10-cp39-cp39-win_amd64.whl", hash = "sha256:c262ffc94338999e7808b434dccafaccd572d03b42d4ef140059d4b7cad765a3"},
{file = "dulwich-0.24.10-py3-none-any.whl", hash = "sha256:15b32f8c3116a1c0a042dde8da96f65a607e263e860ee42b3d4a98ce2c2f4a06"},
{file = "dulwich-0.24.10.tar.gz", hash = "sha256:30e028979b6fa7220c913da9c786026611c10746c06496149742602b36a11f6b"},
]
[package.dependencies]
@@ -1080,14 +1080,14 @@ files = [
[[package]]
name = "findpython"
version = "0.7.0"
version = "0.7.1"
description = "A utility to find python versions on your system"
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "findpython-0.7.0-py3-none-any.whl", hash = "sha256:f53cfcc29536f5b83c962cf922bba8ff6d6a3c2a05fda6a45aa58a47d005d8fc"},
{file = "findpython-0.7.0.tar.gz", hash = "sha256:8b31647c76352779a3c1a0806699b68e6a7bdc0b5c2ddd9af2a07a0d40c673dc"},
{file = "findpython-0.7.1-py3-none-any.whl", hash = "sha256:1b78b1ff6e886cbddeffe80f8ecdbf2b8b061169bbd18b673070e26b644c51ac"},
{file = "findpython-0.7.1.tar.gz", hash = "sha256:9f29e6a3dabdb75f2b39c949772c0ed26eab15308006669f3478cdab0d867c78"},
]
[package.dependencies]
@@ -1159,14 +1159,14 @@ test = ["pytest", "pytest-cov", "pytest-mpl", "pytest-subtests"]
[[package]]
name = "garminconnect"
version = "0.2.30"
version = "0.2.34"
description = "Python 3 API wrapper for Garmin Connect"
optional = false
python-versions = ">=3.10"
groups = ["main"]
files = [
{file = "garminconnect-0.2.30-py3-none-any.whl", hash = "sha256:9256c1084853e016557c3669ae1180dc4cc15f2f722ab606fba0ecfa68fb2121"},
{file = "garminconnect-0.2.30.tar.gz", hash = "sha256:15098c26ddb6651d9e11fee4acb8ae6faa5d089d5a0034fe0499c3f39afd5eb4"},
{file = "garminconnect-0.2.34-py3-none-any.whl", hash = "sha256:347fdca2ddcba50c62583b5d64fd1696cf8956e246b4a860641520726eb00874"},
{file = "garminconnect-0.2.34.tar.gz", hash = "sha256:cc58b28b4dd65142f325f061e31afc8ec6b3b1414ad8fbeb47c025608aa16f5f"},
]
[package.dependencies]
@@ -1233,14 +1233,14 @@ timezone = ["pytz"]
[[package]]
name = "googleapis-common-protos"
version = "1.71.0"
version = "1.72.0"
description = "Common protobufs used in Google APIs"
optional = false
python-versions = ">=3.7"
groups = ["main"]
files = [
{file = "googleapis_common_protos-1.71.0-py3-none-any.whl", hash = "sha256:59034a1d849dc4d18971997a72ac56246570afdd17f9369a0ff68218d50ab78c"},
{file = "googleapis_common_protos-1.71.0.tar.gz", hash = "sha256:1aec01e574e29da63c80ba9f7bbf1ccfaacf1da877f23609fe236ca7c72a2e2e"},
{file = "googleapis_common_protos-1.72.0-py3-none-any.whl", hash = "sha256:4299c5a82d5ae1a9702ada957347726b167f9f8d1fc352477702a1e851ff4038"},
{file = "googleapis_common_protos-1.72.0.tar.gz", hash = "sha256:e55a601c1b32b52d7a3e65f43563e2aa61bcd737998ee672ac9b951cd49319f5"},
]
[package.dependencies]
@@ -1681,14 +1681,14 @@ trio = ["trio"]
[[package]]
name = "joserfc"
version = "1.4.0"
version = "1.4.1"
description = "The ultimate Python library for JOSE RFCs, including JWS, JWE, JWK, JWA, JWT"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "joserfc-1.4.0-py3-none-any.whl", hash = "sha256:46917e6b53f1ec0c7e20d34d6f3e6c27da0fa43d0d4ebfb89aada7c86582933a"},
{file = "joserfc-1.4.0.tar.gz", hash = "sha256:e8c2f327bf10a937d284d57e9f8aec385381e5e5850469b50a7dade1aba59759"},
{file = "joserfc-1.4.1-py3-none-any.whl", hash = "sha256:0c7424194bdf79a398afca5e247ac058f6f731d5e7e8d55228cf7d2e069d2d46"},
{file = "joserfc-1.4.1.tar.gz", hash = "sha256:d8e9d1530e36ca3281df901ccae7723ed37c7ce93eb3cf6244c4f67afe0c0545"},
]
[package.dependencies]
@@ -1776,14 +1776,14 @@ testing = ["pytest"]
[[package]]
name = "markdown"
version = "3.9"
version = "3.10"
description = "Python implementation of John Gruber's Markdown."
optional = false
python-versions = ">=3.9"
python-versions = ">=3.10"
groups = ["main"]
files = [
{file = "markdown-3.9-py3-none-any.whl", hash = "sha256:9f4d91ed810864ea88a6f32c07ba8bee1346c0cc1f6b1f9f6c822f2a9667d280"},
{file = "markdown-3.9.tar.gz", hash = "sha256:d2900fe1782bd33bdbbd56859defef70c2e78fc46668f8eb9df3128138f2cb6a"},
{file = "markdown-3.10-py3-none-any.whl", hash = "sha256:b5b99d6951e2e4948d939255596523444c0e677c669700b1d17aa4a8a464cb7c"},
{file = "markdown-3.10.tar.gz", hash = "sha256:37062d4f2aa4b2b6b32aefb80faa300f82cc790cb949a35b8caede34f2b68c0e"},
]
[package.extras]
@@ -2429,14 +2429,14 @@ xmp = ["defusedxml"]
[[package]]
name = "pint"
version = "0.25.1"
version = "0.25.2"
description = "Physical quantities module"
optional = false
python-versions = ">=3.11"
groups = ["main"]
files = [
{file = "pint-0.25.1-py3-none-any.whl", hash = "sha256:b13dc42d0effa2d98b621b06eb0f2990d262c655c8893f6d40a74c334f9aa6b4"},
{file = "pint-0.25.1.tar.gz", hash = "sha256:34e6f89bfbfca94f29bde65c9ea42c1c56e05426692c655a3ee6f3ca2a92d252"},
{file = "pint-0.25.2-py3-none-any.whl", hash = "sha256:ca35ab1d8eeeb6f7d9942b3cb5f34ca42b61cdd5fb3eae79531553dcca04dda7"},
{file = "pint-0.25.2.tar.gz", hash = "sha256:85a45d1da8fe9c9f7477fed8aef59ad2b939af3d6611507e1a9cbdacdcd3450a"},
]
[package.dependencies]
@@ -2757,20 +2757,20 @@ files = [
[[package]]
name = "pydantic"
version = "2.12.3"
version = "2.12.4"
description = "Data validation using Python type hints"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "pydantic-2.12.3-py3-none-any.whl", hash = "sha256:6986454a854bc3bc6e5443e1369e06a3a456af9d339eda45510f517d9ea5c6bf"},
{file = "pydantic-2.12.3.tar.gz", hash = "sha256:1da1c82b0fc140bb0103bc1441ffe062154c8d38491189751ee00fd8ca65ce74"},
{file = "pydantic-2.12.4-py3-none-any.whl", hash = "sha256:92d3d202a745d46f9be6df459ac5a064fdaa3c1c4cd8adcfa332ccf3c05f871e"},
{file = "pydantic-2.12.4.tar.gz", hash = "sha256:0f8cb9555000a4b5b617f66bfd2566264c4984b27589d3b845685983e8ea85ac"},
]
[package.dependencies]
annotated-types = ">=0.6.0"
email-validator = {version = ">=2.0.0", optional = true, markers = "extra == \"email\""}
pydantic-core = "2.41.4"
pydantic-core = "2.41.5"
typing-extensions = ">=4.14.1"
typing-inspection = ">=0.4.2"
@@ -2780,129 +2780,133 @@ timezone = ["tzdata ; python_version >= \"3.9\" and platform_system == \"Windows
[[package]]
name = "pydantic-core"
version = "2.41.4"
version = "2.41.5"
description = "Core functionality for Pydantic validation and serialization"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "pydantic_core-2.41.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2442d9a4d38f3411f22eb9dd0912b7cbf4b7d5b6c92c4173b75d3e1ccd84e36e"},
{file = "pydantic_core-2.41.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:30a9876226dda131a741afeab2702e2d127209bde3c65a2b8133f428bc5d006b"},
{file = "pydantic_core-2.41.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d55bbac04711e2980645af68b97d445cdbcce70e5216de444a6c4b6943ebcccd"},
{file = "pydantic_core-2.41.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e1d778fb7849a42d0ee5927ab0f7453bf9f85eef8887a546ec87db5ddb178945"},
{file = "pydantic_core-2.41.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1b65077a4693a98b90ec5ad8f203ad65802a1b9b6d4a7e48066925a7e1606706"},
{file = "pydantic_core-2.41.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:62637c769dee16eddb7686bf421be48dfc2fae93832c25e25bc7242e698361ba"},
{file = "pydantic_core-2.41.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dfe3aa529c8f501babf6e502936b9e8d4698502b2cfab41e17a028d91b1ac7b"},
{file = "pydantic_core-2.41.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ca2322da745bf2eeb581fc9ea3bbb31147702163ccbcbf12a3bb630e4bf05e1d"},
{file = "pydantic_core-2.41.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e8cd3577c796be7231dcf80badcf2e0835a46665eaafd8ace124d886bab4d700"},
{file = "pydantic_core-2.41.4-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:1cae8851e174c83633f0833e90636832857297900133705ee158cf79d40f03e6"},
{file = "pydantic_core-2.41.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a26d950449aae348afe1ac8be5525a00ae4235309b729ad4d3399623125b43c9"},
{file = "pydantic_core-2.41.4-cp310-cp310-win32.whl", hash = "sha256:0cf2a1f599efe57fa0051312774280ee0f650e11152325e41dfd3018ef2c1b57"},
{file = "pydantic_core-2.41.4-cp310-cp310-win_amd64.whl", hash = "sha256:a8c2e340d7e454dc3340d3d2e8f23558ebe78c98aa8f68851b04dcb7bc37abdc"},
{file = "pydantic_core-2.41.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:28ff11666443a1a8cf2a044d6a545ebffa8382b5f7973f22c36109205e65dc80"},
{file = "pydantic_core-2.41.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:61760c3925d4633290292bad462e0f737b840508b4f722247d8729684f6539ae"},
{file = "pydantic_core-2.41.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eae547b7315d055b0de2ec3965643b0ab82ad0106a7ffd29615ee9f266a02827"},
{file = "pydantic_core-2.41.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ef9ee5471edd58d1fcce1c80ffc8783a650e3e3a193fe90d52e43bb4d87bff1f"},
{file = "pydantic_core-2.41.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:15dd504af121caaf2c95cb90c0ebf71603c53de98305621b94da0f967e572def"},
{file = "pydantic_core-2.41.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a926768ea49a8af4d36abd6a8968b8790f7f76dd7cbd5a4c180db2b4ac9a3a2"},
{file = "pydantic_core-2.41.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6916b9b7d134bff5440098a4deb80e4cb623e68974a87883299de9124126c2a8"},
{file = "pydantic_core-2.41.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5cf90535979089df02e6f17ffd076f07237efa55b7343d98760bde8743c4b265"},
{file = "pydantic_core-2.41.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7533c76fa647fade2d7ec75ac5cc079ab3f34879626dae5689b27790a6cf5a5c"},
{file = "pydantic_core-2.41.4-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:37e516bca9264cbf29612539801ca3cd5d1be465f940417b002905e6ed79d38a"},
{file = "pydantic_core-2.41.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0c19cb355224037c83642429b8ce261ae108e1c5fbf5c028bac63c77b0f8646e"},
{file = "pydantic_core-2.41.4-cp311-cp311-win32.whl", hash = "sha256:09c2a60e55b357284b5f31f5ab275ba9f7f70b7525e18a132ec1f9160b4f1f03"},
{file = "pydantic_core-2.41.4-cp311-cp311-win_amd64.whl", hash = "sha256:711156b6afb5cb1cb7c14a2cc2c4a8b4c717b69046f13c6b332d8a0a8f41ca3e"},
{file = "pydantic_core-2.41.4-cp311-cp311-win_arm64.whl", hash = "sha256:6cb9cf7e761f4f8a8589a45e49ed3c0d92d1d696a45a6feaee8c904b26efc2db"},
{file = "pydantic_core-2.41.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ab06d77e053d660a6faaf04894446df7b0a7e7aba70c2797465a0a1af00fc887"},
{file = "pydantic_core-2.41.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c53ff33e603a9c1179a9364b0a24694f183717b2e0da2b5ad43c316c956901b2"},
{file = "pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:304c54176af2c143bd181d82e77c15c41cbacea8872a2225dd37e6544dce9999"},
{file = "pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:025ba34a4cf4fb32f917d5d188ab5e702223d3ba603be4d8aca2f82bede432a4"},
{file = "pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b9f5f30c402ed58f90c70e12eff65547d3ab74685ffe8283c719e6bead8ef53f"},
{file = "pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd96e5d15385d301733113bcaa324c8bcf111275b7675a9c6e88bfb19fc05e3b"},
{file = "pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98f348cbb44fae6e9653c1055db7e29de67ea6a9ca03a5fa2c2e11a47cff0e47"},
{file = "pydantic_core-2.41.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec22626a2d14620a83ca583c6f5a4080fa3155282718b6055c2ea48d3ef35970"},
{file = "pydantic_core-2.41.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3a95d4590b1f1a43bf33ca6d647b990a88f4a3824a8c4572c708f0b45a5290ed"},
{file = "pydantic_core-2.41.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:f9672ab4d398e1b602feadcffcdd3af44d5f5e6ddc15bc7d15d376d47e8e19f8"},
{file = "pydantic_core-2.41.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:84d8854db5f55fead3b579f04bda9a36461dab0730c5d570e1526483e7bb8431"},
{file = "pydantic_core-2.41.4-cp312-cp312-win32.whl", hash = "sha256:9be1c01adb2ecc4e464392c36d17f97e9110fbbc906bcbe1c943b5b87a74aabd"},
{file = "pydantic_core-2.41.4-cp312-cp312-win_amd64.whl", hash = "sha256:d682cf1d22bab22a5be08539dca3d1593488a99998f9f412137bc323179067ff"},
{file = "pydantic_core-2.41.4-cp312-cp312-win_arm64.whl", hash = "sha256:833eebfd75a26d17470b58768c1834dfc90141b7afc6eb0429c21fc5a21dcfb8"},
{file = "pydantic_core-2.41.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:85e050ad9e5f6fe1004eec65c914332e52f429bc0ae12d6fa2092407a462c746"},
{file = "pydantic_core-2.41.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e7393f1d64792763a48924ba31d1e44c2cfbc05e3b1c2c9abb4ceeadd912cced"},
{file = "pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94dab0940b0d1fb28bcab847adf887c66a27a40291eedf0b473be58761c9799a"},
{file = "pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:de7c42f897e689ee6f9e93c4bec72b99ae3b32a2ade1c7e4798e690ff5246e02"},
{file = "pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:664b3199193262277b8b3cd1e754fb07f2c6023289c815a1e1e8fb415cb247b1"},
{file = "pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d95b253b88f7d308b1c0b417c4624f44553ba4762816f94e6986819b9c273fb2"},
{file = "pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1351f5bbdbbabc689727cb91649a00cb9ee7203e0a6e54e9f5ba9e22e384b84"},
{file = "pydantic_core-2.41.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1affa4798520b148d7182da0615d648e752de4ab1a9566b7471bc803d88a062d"},
{file = "pydantic_core-2.41.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7b74e18052fea4aa8dea2fb7dbc23d15439695da6cbe6cfc1b694af1115df09d"},
{file = "pydantic_core-2.41.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:285b643d75c0e30abda9dc1077395624f314a37e3c09ca402d4015ef5979f1a2"},
{file = "pydantic_core-2.41.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:f52679ff4218d713b3b33f88c89ccbf3a5c2c12ba665fb80ccc4192b4608dbab"},
{file = "pydantic_core-2.41.4-cp313-cp313-win32.whl", hash = "sha256:ecde6dedd6fff127c273c76821bb754d793be1024bc33314a120f83a3c69460c"},
{file = "pydantic_core-2.41.4-cp313-cp313-win_amd64.whl", hash = "sha256:d081a1f3800f05409ed868ebb2d74ac39dd0c1ff6c035b5162356d76030736d4"},
{file = "pydantic_core-2.41.4-cp313-cp313-win_arm64.whl", hash = "sha256:f8e49c9c364a7edcbe2a310f12733aad95b022495ef2a8d653f645e5d20c1564"},
{file = "pydantic_core-2.41.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ed97fd56a561f5eb5706cebe94f1ad7c13b84d98312a05546f2ad036bafe87f4"},
{file = "pydantic_core-2.41.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a870c307bf1ee91fc58a9a61338ff780d01bfae45922624816878dce784095d2"},
{file = "pydantic_core-2.41.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d25e97bc1f5f8f7985bdc2335ef9e73843bb561eb1fa6831fdfc295c1c2061cf"},
{file = "pydantic_core-2.41.4-cp313-cp313t-win_amd64.whl", hash = "sha256:d405d14bea042f166512add3091c1af40437c2e7f86988f3915fabd27b1e9cd2"},
{file = "pydantic_core-2.41.4-cp313-cp313t-win_arm64.whl", hash = "sha256:19f3684868309db5263a11bace3c45d93f6f24afa2ffe75a647583df22a2ff89"},
{file = "pydantic_core-2.41.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:e9205d97ed08a82ebb9a307e92914bb30e18cdf6f6b12ca4bedadb1588a0bfe1"},
{file = "pydantic_core-2.41.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:82df1f432b37d832709fbcc0e24394bba04a01b6ecf1ee87578145c19cde12ac"},
{file = "pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc3b4cc4539e055cfa39a3763c939f9d409eb40e85813257dcd761985a108554"},
{file = "pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b1eb1754fce47c63d2ff57fdb88c351a6c0150995890088b33767a10218eaa4e"},
{file = "pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e6ab5ab30ef325b443f379ddb575a34969c333004fca5a1daa0133a6ffaad616"},
{file = "pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:31a41030b1d9ca497634092b46481b937ff9397a86f9f51bd41c4767b6fc04af"},
{file = "pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a44ac1738591472c3d020f61c6df1e4015180d6262ebd39bf2aeb52571b60f12"},
{file = "pydantic_core-2.41.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d72f2b5e6e82ab8f94ea7d0d42f83c487dc159c5240d8f83beae684472864e2d"},
{file = "pydantic_core-2.41.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:c4d1e854aaf044487d31143f541f7aafe7b482ae72a022c664b2de2e466ed0ad"},
{file = "pydantic_core-2.41.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b568af94267729d76e6ee5ececda4e283d07bbb28e8148bb17adad93d025d25a"},
{file = "pydantic_core-2.41.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:6d55fb8b1e8929b341cc313a81a26e0d48aa3b519c1dbaadec3a6a2b4fcad025"},
{file = "pydantic_core-2.41.4-cp314-cp314-win32.whl", hash = "sha256:5b66584e549e2e32a1398df11da2e0a7eff45d5c2d9db9d5667c5e6ac764d77e"},
{file = "pydantic_core-2.41.4-cp314-cp314-win_amd64.whl", hash = "sha256:557a0aab88664cc552285316809cab897716a372afaf8efdbef756f8b890e894"},
{file = "pydantic_core-2.41.4-cp314-cp314-win_arm64.whl", hash = "sha256:3f1ea6f48a045745d0d9f325989d8abd3f1eaf47dd00485912d1a3a63c623a8d"},
{file = "pydantic_core-2.41.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6c1fe4c5404c448b13188dd8bd2ebc2bdd7e6727fa61ff481bcc2cca894018da"},
{file = "pydantic_core-2.41.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:523e7da4d43b113bf8e7b49fa4ec0c35bf4fe66b2230bfc5c13cc498f12c6c3e"},
{file = "pydantic_core-2.41.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5729225de81fb65b70fdb1907fcf08c75d498f4a6f15af005aabb1fdadc19dfa"},
{file = "pydantic_core-2.41.4-cp314-cp314t-win_amd64.whl", hash = "sha256:de2cfbb09e88f0f795fd90cf955858fc2c691df65b1f21f0aa00b99f3fbc661d"},
{file = "pydantic_core-2.41.4-cp314-cp314t-win_arm64.whl", hash = "sha256:d34f950ae05a83e0ede899c595f312ca976023ea1db100cd5aa188f7005e3ab0"},
{file = "pydantic_core-2.41.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:646e76293345954acea6966149683047b7b2ace793011922208c8e9da12b0062"},
{file = "pydantic_core-2.41.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cc8e85a63085a137d286e2791037f5fdfff0aabb8b899483ca9c496dd5797338"},
{file = "pydantic_core-2.41.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:692c622c8f859a17c156492783902d8370ac7e121a611bd6fe92cc71acf9ee8d"},
{file = "pydantic_core-2.41.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d1e2906efb1031a532600679b424ef1d95d9f9fb507f813951f23320903adbd7"},
{file = "pydantic_core-2.41.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e04e2f7f8916ad3ddd417a7abdd295276a0bf216993d9318a5d61cc058209166"},
{file = "pydantic_core-2.41.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df649916b81822543d1c8e0e1d079235f68acdc7d270c911e8425045a8cfc57e"},
{file = "pydantic_core-2.41.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66c529f862fdba70558061bb936fe00ddbaaa0c647fd26e4a4356ef1d6561891"},
{file = "pydantic_core-2.41.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3b4c5a1fd3a311563ed866c2c9b62da06cb6398bee186484ce95c820db71cb"},
{file = "pydantic_core-2.41.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6e0fc40d84448f941df9b3334c4b78fe42f36e3bf631ad54c3047a0cdddc2514"},
{file = "pydantic_core-2.41.4-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:44e7625332683b6c1c8b980461475cde9595eff94447500e80716db89b0da005"},
{file = "pydantic_core-2.41.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:170ee6835f6c71081d031ef1c3b4dc4a12b9efa6a9540f93f95b82f3c7571ae8"},
{file = "pydantic_core-2.41.4-cp39-cp39-win32.whl", hash = "sha256:3adf61415efa6ce977041ba9745183c0e1f637ca849773afa93833e04b163feb"},
{file = "pydantic_core-2.41.4-cp39-cp39-win_amd64.whl", hash = "sha256:a238dd3feee263eeaeb7dc44aea4ba1364682c4f9f9467e6af5596ba322c2332"},
{file = "pydantic_core-2.41.4-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:a1b2cfec3879afb742a7b0bcfa53e4f22ba96571c9e54d6a3afe1052d17d843b"},
{file = "pydantic_core-2.41.4-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:d175600d975b7c244af6eb9c9041f10059f20b8bbffec9e33fdd5ee3f67cdc42"},
{file = "pydantic_core-2.41.4-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f184d657fa4947ae5ec9c47bd7e917730fa1cbb78195037e32dcbab50aca5ee"},
{file = "pydantic_core-2.41.4-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ed810568aeffed3edc78910af32af911c835cc39ebbfacd1f0ab5dd53028e5c"},
{file = "pydantic_core-2.41.4-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:4f5d640aeebb438517150fdeec097739614421900e4a08db4a3ef38898798537"},
{file = "pydantic_core-2.41.4-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:4a9ab037b71927babc6d9e7fc01aea9e66dc2a4a34dff06ef0724a4049629f94"},
{file = "pydantic_core-2.41.4-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4dab9484ec605c3016df9ad4fd4f9a390bc5d816a3b10c6550f8424bb80b18c"},
{file = "pydantic_core-2.41.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8a5028425820731d8c6c098ab642d7b8b999758e24acae03ed38a66eca8335"},
{file = "pydantic_core-2.41.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:1e5ab4fc177dd41536b3c32b2ea11380dd3d4619a385860621478ac2d25ceb00"},
{file = "pydantic_core-2.41.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:3d88d0054d3fa11ce936184896bed3c1c5441d6fa483b498fac6a5d0dd6f64a9"},
{file = "pydantic_core-2.41.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b2a054a8725f05b4b6503357e0ac1c4e8234ad3b0c2ac130d6ffc66f0e170e2"},
{file = "pydantic_core-2.41.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0d9db5a161c99375a0c68c058e227bee1d89303300802601d76a3d01f74e258"},
{file = "pydantic_core-2.41.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:6273ea2c8ffdac7b7fda2653c49682db815aebf4a89243a6feccf5e36c18c347"},
{file = "pydantic_core-2.41.4-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:4c973add636efc61de22530b2ef83a65f39b6d6f656df97f678720e20de26caa"},
{file = "pydantic_core-2.41.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b69d1973354758007f46cf2d44a4f3d0933f10b6dc9bf15cf1356e037f6f731a"},
{file = "pydantic_core-2.41.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3619320641fd212aaf5997b6ca505e97540b7e16418f4a241f44cdf108ffb50d"},
{file = "pydantic_core-2.41.4-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:491535d45cd7ad7e4a2af4a5169b0d07bebf1adfd164b0368da8aa41e19907a5"},
{file = "pydantic_core-2.41.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:54d86c0cada6aba4ec4c047d0e348cbad7063b87ae0f005d9f8c9ad04d4a92a2"},
{file = "pydantic_core-2.41.4-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eca1124aced216b2500dc2609eade086d718e8249cb9696660ab447d50a758bd"},
{file = "pydantic_core-2.41.4-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6c9024169becccf0cb470ada03ee578d7348c119a0d42af3dcf9eda96e3a247c"},
{file = "pydantic_core-2.41.4-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:26895a4268ae5a2849269f4991cdc97236e4b9c010e51137becf25182daac405"},
{file = "pydantic_core-2.41.4-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:ca4df25762cf71308c446e33c9b1fdca2923a3f13de616e2a949f38bf21ff5a8"},
{file = "pydantic_core-2.41.4-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:5a28fcedd762349519276c36634e71853b4541079cab4acaaac60c4421827308"},
{file = "pydantic_core-2.41.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c173ddcd86afd2535e2b695217e82191580663a1d1928239f877f5a1649ef39f"},
{file = "pydantic_core-2.41.4.tar.gz", hash = "sha256:70e47929a9d4a1905a67e4b687d5946026390568a8e952b92824118063cee4d5"},
{file = "pydantic_core-2.41.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146"},
{file = "pydantic_core-2.41.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2"},
{file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97"},
{file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9"},
{file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52"},
{file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941"},
{file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a"},
{file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c"},
{file = "pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2"},
{file = "pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556"},
{file = "pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49"},
{file = "pydantic_core-2.41.5-cp310-cp310-win32.whl", hash = "sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba"},
{file = "pydantic_core-2.41.5-cp310-cp310-win_amd64.whl", hash = "sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9"},
{file = "pydantic_core-2.41.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6"},
{file = "pydantic_core-2.41.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b"},
{file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a"},
{file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8"},
{file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e"},
{file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1"},
{file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b"},
{file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b"},
{file = "pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284"},
{file = "pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594"},
{file = "pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e"},
{file = "pydantic_core-2.41.5-cp311-cp311-win32.whl", hash = "sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b"},
{file = "pydantic_core-2.41.5-cp311-cp311-win_amd64.whl", hash = "sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe"},
{file = "pydantic_core-2.41.5-cp311-cp311-win_arm64.whl", hash = "sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f"},
{file = "pydantic_core-2.41.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7"},
{file = "pydantic_core-2.41.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0"},
{file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69"},
{file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75"},
{file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05"},
{file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc"},
{file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c"},
{file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5"},
{file = "pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c"},
{file = "pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294"},
{file = "pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1"},
{file = "pydantic_core-2.41.5-cp312-cp312-win32.whl", hash = "sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d"},
{file = "pydantic_core-2.41.5-cp312-cp312-win_amd64.whl", hash = "sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815"},
{file = "pydantic_core-2.41.5-cp312-cp312-win_arm64.whl", hash = "sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3"},
{file = "pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9"},
{file = "pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34"},
{file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0"},
{file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33"},
{file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e"},
{file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2"},
{file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586"},
{file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d"},
{file = "pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740"},
{file = "pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e"},
{file = "pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858"},
{file = "pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36"},
{file = "pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11"},
{file = "pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd"},
{file = "pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a"},
{file = "pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14"},
{file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1"},
{file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66"},
{file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869"},
{file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2"},
{file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375"},
{file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553"},
{file = "pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90"},
{file = "pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07"},
{file = "pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb"},
{file = "pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23"},
{file = "pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf"},
{file = "pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0"},
{file = "pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a"},
{file = "pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3"},
{file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c"},
{file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612"},
{file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d"},
{file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9"},
{file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660"},
{file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9"},
{file = "pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3"},
{file = "pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf"},
{file = "pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470"},
{file = "pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa"},
{file = "pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c"},
{file = "pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008"},
{file = "pydantic_core-2.41.5-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf"},
{file = "pydantic_core-2.41.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5"},
{file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d"},
{file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60"},
{file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82"},
{file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5"},
{file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3"},
{file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425"},
{file = "pydantic_core-2.41.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504"},
{file = "pydantic_core-2.41.5-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5"},
{file = "pydantic_core-2.41.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3"},
{file = "pydantic_core-2.41.5-cp39-cp39-win32.whl", hash = "sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460"},
{file = "pydantic_core-2.41.5-cp39-cp39-win_amd64.whl", hash = "sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b"},
{file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034"},
{file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c"},
{file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2"},
{file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad"},
{file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd"},
{file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc"},
{file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56"},
{file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b"},
{file = "pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8"},
{file = "pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a"},
{file = "pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b"},
{file = "pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2"},
{file = "pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093"},
{file = "pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a"},
{file = "pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963"},
{file = "pydantic_core-2.41.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a"},
{file = "pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26"},
{file = "pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808"},
{file = "pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc"},
{file = "pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1"},
{file = "pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84"},
{file = "pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770"},
{file = "pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f"},
{file = "pydantic_core-2.41.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51"},
{file = "pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e"},
]
[package.dependencies]
@@ -3368,15 +3372,15 @@ fastapi = ["fastapi (>=0.110,<1.0)"]
[[package]]
name = "secretstorage"
version = "3.4.0"
version = "3.4.1"
description = "Python bindings to FreeDesktop.org Secret Service API"
optional = false
python-versions = ">=3.10"
groups = ["main"]
markers = "sys_platform == \"linux\""
files = [
{file = "secretstorage-3.4.0-py3-none-any.whl", hash = "sha256:0e3b6265c2c63509fb7415717607e4b2c9ab767b7f344a57473b779ca13bd02e"},
{file = "secretstorage-3.4.0.tar.gz", hash = "sha256:c46e216d6815aff8a8a18706a2fbfd8d53fcbb0dce99301881687a1b0289ef7c"},
{file = "secretstorage-3.4.1-py3-none-any.whl", hash = "sha256:c55d57b4da3de568d8c3af89dad244ab24c35ca1da8625fc1b550edf005ebc41"},
{file = "secretstorage-3.4.1.tar.gz", hash = "sha256:a799acf5be9fb93db609ebaa4ab6e8f1f3ed5ae640e0fa732bfea59e9c3b50e8"},
]
[package.dependencies]
@@ -3629,14 +3633,14 @@ files = [
[[package]]
name = "trove-classifiers"
version = "2025.9.11.17"
version = "2025.11.14.15"
description = "Canonical source for classifiers on PyPI (pypi.org)."
optional = false
python-versions = "*"
groups = ["main"]
files = [
{file = "trove_classifiers-2025.9.11.17-py3-none-any.whl", hash = "sha256:5d392f2d244deb1866556457d6f3516792124a23d1c3a463a2e8668a5d1c15dd"},
{file = "trove_classifiers-2025.9.11.17.tar.gz", hash = "sha256:931ca9841a5e9c9408bc2ae67b50d28acf85bef56219b56860876dd1f2d024dd"},
{file = "trove_classifiers-2025.11.14.15-py3-none-any.whl", hash = "sha256:d1dac259c1e908939862e3331177931c6df0a37af2c1a8debcc603d9115fcdd9"},
{file = "trove_classifiers-2025.11.14.15.tar.gz", hash = "sha256:6b60f49d40bbd895bc61d8dc414fc2f2286d70eb72ed23548db8cf94f62804ca"},
]
[[package]]

View File

@@ -282,6 +282,7 @@ The table bellow details the activity types supported by Endurain.
| Stand up paddling | 32 |
| Surf | 33 |
| Soccer | 38 |
| Cardio training | 41 |
## Supported gear types

View File

@@ -105,6 +105,7 @@ Currently supported in:
- GALICIAN (GL)
- Dutch (NL) [@woutvanderaa](https://github.com/woutvanderaa)
- Portuguese (PT)
- Slovenian (SL) [@thehijacker](https://github.com/thehijacker)
- Spanish (ES) [@rgmelkor](https://github.com/rgmelkor) and [@tinchodin](https://github.com/tinchodin)
- English (US)

File diff suppressed because it is too large Load Diff

View File

@@ -22,6 +22,7 @@
"bootstrap": "^5.3.3",
"chart.js": "^4.4.6",
"chartjs-plugin-datalabels": "^2.2.0",
"chartjs-plugin-zoom": "^2.2.0",
"flag-icons": "^7.2.3",
"leaflet": "^1.9.4",
"luxon": "^3.5.0",

View File

@@ -79,7 +79,6 @@
</a>
</li>
</ul>
<p class="mt-2">{{ $t('activityMandAbovePillsComponent.labelDownsampling') }}</p>
</div>
<div class="col">
<div if="activity">

View File

@@ -232,19 +232,35 @@ const initMap = () => {
attribution: '© OpenStreetMap contributors'
}).addTo(leafletMap.value)
L.polyline(latlngs, { color: 'blue' }).addTo(leafletMap.value)
const polyline = L.polyline(latlngs, {
color: '#2563eb',
weight: 4,
opacity: 0.8,
lineJoin: 'round',
lineCap: 'round'
}).addTo(leafletMap.value)
// Fit map to polyline bounds
if (latlngs.length > 0) {
leafletMap.value.fitBounds(latlngs)
// Add start and end markers
// Add start marker with custom styling
L.marker(latlngs[0], {
icon: L.divIcon({ className: 'bg-success dot' })
icon: L.divIcon({
className: 'start-marker',
iconSize: [16, 16],
iconAnchor: [8, 8]
})
}).addTo(leafletMap.value)
// Add end marker with custom styling
L.marker(latlngs[latlngs.length - 1], {
icon: L.divIcon({ className: 'bg-danger dot' })
icon: L.divIcon({
className: 'end-marker',
iconSize: [16, 16],
iconAnchor: [8, 8]
})
}).addTo(leafletMap.value)
}
}
@@ -260,3 +276,29 @@ watch(
{ deep: true }
)
</script>
<style scoped>
/* Start marker - green dot */
:deep(.start-marker) {
width: 16px;
height: 16px;
border-radius: 50%;
background-color: #28a745;
border: 3px solid white;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
margin-left: -8px;
margin-top: -8px;
}
/* End marker - red dot */
:deep(.end-marker) {
width: 16px;
height: 16px;
border-radius: 50%;
background-color: #dc3545;
border: 3px solid white;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
margin-left: -8px;
margin-top: -8px;
}
</style>

View File

@@ -9,7 +9,8 @@ import { useI18n } from 'vue-i18n'
import { useAuthStore } from '@/stores/authStore'
import { useServerSettingsStore } from '@/stores/serverSettingsStore'
import { Chart, registerables } from 'chart.js'
Chart.register(...registerables)
import zoomPlugin from 'chartjs-plugin-zoom'
Chart.register(...registerables, zoomPlugin)
import {
formatAverageSpeedMetric,
@@ -41,6 +42,74 @@ export default {
const chartCanvas = ref(null)
const units = ref(1)
let myChart = null
// Function to create gradient fill for chart
function createGradient(ctx, chartArea, graphSelection) {
if (!chartArea) {
const colors = getGraphColors(graphSelection)
return colors.gradientStart
}
const colors = getGraphColors(graphSelection)
const gradient = ctx.createLinearGradient(0, chartArea.top, 0, chartArea.bottom)
gradient.addColorStop(0, colors.gradientStart) // More opaque at top
gradient.addColorStop(1, colors.gradientEnd) // Transparent at bottom
return gradient
}
// Function to format pace values as MM:SS
function formatPaceForTooltip(value) {
if (value === null || value === undefined) return 'N/A'
const totalMinutes = Math.floor(value)
let seconds = Math.round((value - totalMinutes) * 60)
// Handle case where seconds round to 60 (should be next minute)
let minutes = totalMinutes
if (seconds >= 60) {
minutes += 1
seconds = 0
}
return `${minutes}:${seconds.toString().padStart(2, '0')}`
}
// Function to get colors based on graph type
function getGraphColors(graphSelection) {
const colors = {
hr: {
border: 'rgba(239, 68, 68, 0.8)', // Red
gradientStart: 'rgba(239, 68, 68, 0.4)',
gradientEnd: 'rgba(239, 68, 68, 0.0)'
},
power: {
border: 'rgba(251, 191, 36, 0.8)', // Yellow/Gold
gradientStart: 'rgba(251, 191, 36, 0.4)',
gradientEnd: 'rgba(251, 191, 36, 0.0)'
},
cad: {
border: 'rgba(168, 85, 247, 0.8)', // Purple
gradientStart: 'rgba(168, 85, 247, 0.4)',
gradientEnd: 'rgba(168, 85, 247, 0.0)'
},
ele: {
border: 'rgba(34, 197, 94, 0.8)', // Green
gradientStart: 'rgba(34, 197, 94, 0.4)',
gradientEnd: 'rgba(34, 197, 94, 0.0)'
},
vel: {
border: 'rgba(59, 130, 246, 0.8)', // Blue
gradientStart: 'rgba(59, 130, 246, 0.4)',
gradientEnd: 'rgba(59, 130, 246, 0.0)'
},
pace: {
border: 'rgba(236, 72, 153, 0.8)', // Pink
gradientStart: 'rgba(236, 72, 153, 0.4)',
gradientEnd: 'rgba(236, 72, 153, 0.0)'
}
}
return colors[graphSelection] || colors.vel // Default to blue
}
const computedChartData = computed(() => {
const data = []
let label = ''
@@ -116,19 +185,36 @@ export default {
roundValues = false
for (const paceData of stream.stream_waypoints) {
if (paceData.pace === 0 || paceData.pace === null) {
data.push(0)
// Use null so Chart.js will gap missing/invalid pace points
data.push(null)
} else {
// Compute converted pace (minutes per km or per mile for running, minutes per 100m/100yd for swimming)
let converted = null
if (activityTypeIsRunning(props.activity)) {
if (Number(units.value) === 1) {
data.push((paceData.pace * 1000) / 60)
converted = (paceData.pace * 1000) / 60 // min/km
} else {
data.push((paceData.pace * 1609.34) / 60)
converted = (paceData.pace * 1609.34) / 60 // min/mile
}
// Apply a hard cap: ignore implausible paces > 20 min/km (or equivalent in min/mile)
const threshold = Number(units.value) === 1 ? 20 : 20 * 1.60934
if (converted > threshold || Number.isNaN(converted)) {
data.push(null)
} else {
data.push(converted)
}
} else if (activityTypeIsSwimming(props.activity)) {
if (Number(units.value) === 1) {
data.push((paceData.pace * 100) / 60)
converted = (paceData.pace * 100) / 60 // min/100m
} else {
data.push((paceData.pace * 100 * 0.9144) / 60)
converted = (paceData.pace * 100 * 0.9144) / 60 // min/100yd
}
// Apply a hard cap for swimming: ignore implausible paces > 10 min/100m (or equivalent in min/100yd)
const swimThreshold = Number(units.value) === 1 ? 10 : 10 * 1.0936
if (converted > swimThreshold || Number.isNaN(converted)) {
data.push(null)
} else {
data.push(converted)
}
}
}
@@ -149,11 +235,8 @@ export default {
}
}
const dataDS = downsampleData(data, 200, roundValues)
const cadDataDS = downsampleData(cadData, 200, true)
const totalDistance = props.activity.distance / 1000
const numberOfDataPoints = dataDS.length
const numberOfDataPoints = data.length
const distanceInterval = totalDistance / numberOfDataPoints
for (let i = 0; i < numberOfDataPoints; i++) {
@@ -172,24 +255,84 @@ export default {
}
}
// Calculate average and max/min for reference lines (excluding null values)
const validData = data.filter((v) => v !== null && !Number.isNaN(v))
let avgValue = null
let extremeValue = null
let extremeLabel = ''
if (validData.length > 0) {
avgValue = validData.reduce((a, b) => a + b, 0) / validData.length
// For pace, show minimum (best/fastest). For others, show maximum (best/highest)
if (props.graphSelection === 'pace') {
extremeValue = Math.min(...validData)
extremeLabel = 'Best'
} else {
extremeValue = Math.max(...validData)
extremeLabel = 'Maximum'
}
}
const datasets = [
{
label: label,
data: dataDS,
data: data,
yAxisID: 'y',
backgroundColor: 'transparent',
borderColor: 'rgba(54, 162, 235, 0.8)',
fill: true,
fillColor: 'rgba(54, 162, 235, 0.2)'
backgroundColor: function (context) {
const chart = context.chart
const { ctx, chartArea } = chart
if (!chartArea) {
const colors = getGraphColors(props.graphSelection)
return colors.gradientStart
}
return createGradient(ctx, chartArea, props.graphSelection)
},
borderColor: getGraphColors(props.graphSelection).border,
fill: props.graphSelection === 'pace' ? 'start' : true, // For pace, fill from line to top (outside)
pointHoverRadius: 4,
pointHoverBackgroundColor: getGraphColors(props.graphSelection).border
}
]
// Add average reference line if we have valid data
if (avgValue !== null) {
datasets.push({
label: t('generalItems.labelAverage'),
data: Array(data.length).fill(avgValue),
yAxisID: 'y',
borderColor: 'rgba(156, 163, 175, 0.6)', // Gray color
borderWidth: 2,
borderDash: [10, 5], // Dashed line
fill: false,
pointRadius: 0,
pointHoverRadius: 0,
tension: 0
})
}
// Add extreme value reference line if we have valid data (max for most, min/best for pace)
if (extremeValue !== null) {
datasets.push({
label: extremeLabel,
data: Array(data.length).fill(extremeValue),
yAxisID: 'y',
borderColor: 'rgba(220, 38, 38, 0.5)', // Red color, more transparent
borderWidth: 1.5,
borderDash: [5, 5], // Shorter dashes
fill: false,
pointRadius: 0,
pointHoverRadius: 0,
tension: 0
})
}
// Only push laps 'background shading' if there is cadence data and indoor swimming activity
if (cadDataDS.length > 0 && props.activity.activity_type === 8) {
if (cadData.length > 0 && props.activity.activity_type === 8) {
datasets.push({
type: 'bar',
label: t('generalItems.labelLaps'),
data: cadDataDS.map((d) => (d === 0 ? 0 : 1)),
data: cadData.map((d) => (d === 0 ? 0 : 1)),
yAxisID: 'y1',
backgroundColor: 'rgba(0, 0, 0, 0.2)',
fill: true,
@@ -208,46 +351,77 @@ export default {
watch(
computedChartData,
(newChartData) => {
if (myChart.value) {
myChart.value.data.datasets = newChartData.datasets
if (myChart) {
myChart.data.datasets = newChartData.datasets
myChart.data.labels = newChartData.labels
myChart.value.update()
// Ensure pace graphs are inverted so lower min/km/min/100m appear higher
if (myChart.options && myChart.options.scales && myChart.options.scales.y) {
myChart.options.scales.y.reverse = props.graphSelection === 'pace'
}
myChart.update()
}
},
{ deep: true }
)
function downsampleData(data, threshold, roundValues) {
if (data.length <= threshold) {
return data
}
// Custom crosshair plugin
const crosshairPlugin = {
id: 'customCrosshair',
afterDraw: (chart) => {
if (chart.tooltip?._active && chart.tooltip._active.length) {
const ctx = chart.ctx
const activePoint = chart.tooltip._active[0]
const x = activePoint.element.x
const topY = chart.scales.y.top
const bottomY = chart.scales.y.bottom
const factor = Math.ceil(data.length / threshold)
const downsampledData = []
for (let i = 0; i < data.length; i += factor) {
const chunk = data.slice(i, i + factor)
const average = chunk.reduce((a, b) => a + b) / chunk.length
if (roundValues) {
downsampledData.push(Number.parseInt(average))
} else {
downsampledData.push(average)
// Draw vertical line
ctx.save()
ctx.beginPath()
ctx.setLineDash([5, 5])
ctx.moveTo(x, topY)
ctx.lineTo(x, bottomY)
ctx.lineWidth = 1
ctx.strokeStyle = 'rgba(0, 0, 0, 0.3)'
ctx.stroke()
ctx.restore()
}
}
return downsampledData
}
onMounted(() => {
myChart = new Chart(chartCanvas.value.getContext('2d'), {
type: 'line',
data: computedChartData.value,
plugins: [crosshairPlugin],
options: {
responsive: true,
animation: false, // Disable animations for faster rendering with many points
interaction: {
mode: 'index', // Show tooltip for all datasets at the same x position
intersect: false // Don't require hovering exactly on a point
},
elements: {
point: {
radius: 0, // Hide points by default (keeps line visible)
hitRadius: 10, // Large invisible hover area for easier interaction
hoverRadius: 4 // Show small point when hovering
},
line: {
tension: 0.4 // Smooth curves instead of straight lines (0 = angular, 0.4 = smooth)
}
},
scales: {
y: {
beginAtZero: false,
position: 'left'
position: 'left',
// Reverse the y-axis for pace so that lower times plot higher
reverse: props.graphSelection === 'pace',
grid: {
lineWidth: 1,
drawBorder: true,
borderWidth: 1
}
},
y1: {
beginAtZero: true,
@@ -255,7 +429,81 @@ export default {
display: false
},
x: {
autoSkip: true
ticks: {
maxTicksLimit: 10, // Limit x-axis labels to approximately 10 for better readability
autoSkip: true
},
grid: {
lineWidth: 1,
drawBorder: true,
borderWidth: 1
}
}
},
plugins: {
tooltip: {
enabled: true,
callbacks: {
title: function (context) {
// Show the distance label as the title
return context[0].label
},
label: function (context) {
const label = context.dataset.label || ''
let value = context.parsed.y
if (value === null || value === undefined) {
return `${label}: N/A`
}
// Format based on the type of data
if (props.graphSelection === 'pace') {
// Format pace as MM:SS
const formatted = formatPaceForTooltip(value)
return `${label}: ${formatted}`
} else if (props.graphSelection === 'hr') {
// Heart rate - whole number
return `${label}: ${Math.round(value)}`
} else if (props.graphSelection === 'power') {
// Power - whole number
return `${label}: ${Math.round(value)} W`
} else if (props.graphSelection === 'cad') {
// Cadence/Stroke Rate - whole number
return `${label}: ${Math.round(value)}`
} else if (props.graphSelection === 'ele') {
// Elevation - 1 decimal
return `${label}: ${value.toFixed(1)}`
} else if (props.graphSelection === 'vel') {
// Velocity - 1 decimal
return `${label}: ${value.toFixed(1)}`
}
return `${label}: ${value}`
}
}
},
zoom: {
pan: {
enabled: true,
mode: 'x', // Only pan horizontally
modifierKey: 'shift' // Hold shift to pan
},
zoom: {
wheel: {
enabled: true, // Enable zoom with mouse wheel
speed: 0.1
},
pinch: {
enabled: true // Enable pinch zoom on touch devices
},
mode: 'x' // Only zoom horizontally
},
limits: {
x: {
min: 'original', // Can't pan/zoom beyond original data
max: 'original'
}
}
}
}
}
@@ -263,8 +511,8 @@ export default {
})
onUnmounted(() => {
if (myChart.value) {
myChart.value.destroy()
if (myChart) {
myChart.destroy()
}
})

View File

@@ -195,6 +195,7 @@
activity.activity_type != 18 &&
activity.activity_type != 19 &&
activity.activity_type != 20 &&
activity.activity_type != 41 &&
activityTypeNotRacquet(activity)
"
>
@@ -237,6 +238,7 @@
activity.activity_type != 18 &&
activity.activity_type != 19 &&
activity.activity_type != 20 &&
activity.activity_type != 41 &&
activityTypeNotRacquet(activity)
"
>
@@ -265,6 +267,7 @@
activity.activity_type != 18 &&
activity.activity_type != 19 &&
activity.activity_type != 20 &&
activity.activity_type != 41 &&
activityTypeNotRacquet(activity)
"
>

View File

@@ -18,7 +18,8 @@
v-if="
(activity.activity_type === 10 ||
activity.activity_type === 19 ||
activity.activity_type === 20) &&
activity.activity_type === 20 ||
activity.activity_type === 41) &&
activityActivityWorkoutSteps &&
activityActivityWorkoutSteps.length > 0
"
@@ -29,7 +30,8 @@
v-if="
(activity.activity_type === 10 ||
activity.activity_type === 19 ||
activity.activity_type === 20) &&
activity.activity_type === 20 ||
activity.activity_type === 41) &&
activityActivityWorkoutSteps &&
activityActivityWorkoutSteps.length > 0
"
@@ -96,7 +98,8 @@
v-if="
(activity.activity_type === 10 ||
activity.activity_type === 19 ||
activity.activity_type === 20) &&
activity.activity_type === 20 ||
activity.activity_type === 41) &&
activityActivityWorkoutSteps &&
activityActivityWorkoutSteps.length > 0
"
@@ -114,7 +117,8 @@
v-if="
(activity.activity_type === 10 ||
activity.activity_type === 19 ||
activity.activity_type === 20) &&
activity.activity_type === 20 ||
activity.activity_type === 41) &&
activityActivityWorkoutSteps &&
activityActivityWorkoutSteps.length > 0
"
@@ -203,7 +207,8 @@
v-if="
(activity.activity_type === 10 ||
activity.activity_type === 19 ||
activity.activity_type === 20) &&
activity.activity_type === 20 ||
activity.activity_type === 41) &&
activityActivitySets &&
activityActivitySets.length > 0
"
@@ -240,7 +245,8 @@
v-if="
(activity.activity_type === 10 ||
activity.activity_type === 19 ||
activity.activity_type === 20) &&
activity.activity_type === 20 ||
activity.activity_type === 41) &&
activityActivitySets &&
activityActivitySets.length > 0
"

View File

@@ -136,6 +136,9 @@
<option value="20">
{{ $t('editActivityModalComponent.modalEditActivityTypeOption20') }}
</option>
<option value="41">
{{ $t('editActivityModalComponent.modalEditActivityTypeOption41') }}
</option>
<hr />
<option value="11">
{{ $t('editActivityModalComponent.modalEditActivityTypeOption11') }}

View File

@@ -9,10 +9,11 @@
>
<span
:class="'fi fi-' + currentLanguage"
v-if="currentLanguage !== 'ca' && currentLanguage !== 'gl'"
v-if="currentLanguage !== 'ca' && currentLanguage !== 'gl' && currentLanguage !== 'sl'"
></span>
<span class="fi fi-es-ct" v-else-if="currentLanguage === 'ca'"></span>
<span class="fi fi-es-ga" v-else-if="currentLanguage === 'gl'"></span>
<span class="fi fi-si" v-else-if="currentLanguage === 'sl'"></span>
</a>
<!-- dropdown menu -->
@@ -26,10 +27,11 @@
<span class="me-2">{{ language.label }}</span>
<span
:class="'fi fi-' + language.value"
v-if="language.value !== 'ca' && language.value !== 'gl'"
v-if="language.value !== 'ca' && language.value !== 'gl' && language.value !== 'sl'"
></span>
<span class="fi fi-es-ct" v-else-if="language.value === 'ca'"></span>
<span class="fi fi-es-ga" v-else-if="language.value === 'gl'"></span>
<span class="fi fi-si" v-else-if="language.value === 'sl'"></span>
<span v-if="currentLanguage === language.value" class="ms-3"
><font-awesome-icon :icon="['fas', 'check']"
/></span>
@@ -80,6 +82,7 @@ const languages = computed<Language[]>(() => [
{ value: 'it', label: t('generalItems.languageOption11') },
{ value: 'nl', label: t('generalItems.languageOption6') },
{ value: 'pt', label: t('generalItems.languageOption3') },
{ value: 'sl', label: t('generalItems.languageOption12') },
{ value: 'es', label: t('generalItems.languageOption7') },
{ value: 'us', label: t('generalItems.languageOption1') }
])

View File

@@ -34,6 +34,7 @@ export default {
{ value: 'it', label: t('generalItems.languageOption11') },
{ value: 'nl', label: t('generalItems.languageOption6') },
{ value: 'pt', label: t('generalItems.languageOption3') },
{ value: 'sl', label: t('generalItems.languageOption12') },
{ value: 'es', label: t('generalItems.languageOption7') },
{ value: 'us', label: t('generalItems.languageOption1') }
])

View File

@@ -16,8 +16,8 @@
</div>
<div class="d-flex align-items-center">
<!-- import button -->
<a href="#" class="btn btn-primary" role="button" @click="submitBulkImport">{{
$t('settingsImportZone.buttonBulkImport') }}
<a href="#" class="btn btn-primary" role="button" @click="submitBulkImport"
>{{ $t('settingsImportZone.buttonBulkImport') }}
</a>
</div>
</li>
@@ -35,16 +35,27 @@
</div>
<div class="d-flex align-items-center">
<div class="dropdown">
<a class="btn btn-secondary dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown"
aria-expanded="false">
<a
class="btn btn-secondary dropdown-toggle"
href="#"
role="button"
data-bs-toggle="dropdown"
aria-expanded="false"
>
{{ $t('settingsImportZone.importTitle') }}
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" @click="submitStravaBikesImport">{{
$t("settingsImportZone.stravaGearImportbuttonBikes") }}</a></li>
<li><a class="dropdown-item" @click="submitStravaShoesImport">{{
$t("settingsImportZone.stravaImportbuttonShoes") }}</a></li>
<li>
<a class="dropdown-item" @click="submitStravaBikesImport">{{
$t('settingsImportZone.stravaGearImportbuttonBikes')
}}</a>
</li>
<li>
<a class="dropdown-item" @click="submitStravaShoesImport">{{
$t('settingsImportZone.stravaImportbuttonShoes')
}}</a>
</li>
</ul>
</div>
</div>
@@ -90,14 +101,12 @@ async function submitStravaShoesImport() {
// Set the loading message
const notification = push.promise(t('settingsImportZone.loadingMessageStravaShoesImport'))
try {
await stravaService.importShoes();
await stravaService.importShoes()
// Resolve the loading message with a success message
notification.resolve(t("settingsImportZone.successMessageStravaShoesImport"));
notification.resolve(t('settingsImportZone.successMessageStravaShoesImport'))
} catch (error) {
// Reject the loading message with an error message
notification.reject(
`${t("settingsImportZone.errorMessageUnableToImportShoes")} - ${error}`,
);
notification.reject(`${t('settingsImportZone.errorMessageUnableToImportShoes')} - ${error}`)
}
}
</script>

View File

@@ -81,6 +81,9 @@ function updateGoalList(goalDeletedId) {
}
function addGoalList(createdGoal) {
if (!Array.isArray(goalsArray.value)) {
goalsArray.value = []
}
goalsArray.value.unshift(createdGoal)
}

View File

@@ -76,6 +76,9 @@
<option :value="5">
{{ $t('goalsAddEditGoalModalComponent.activityTypeStrength') }}
</option>
<option :value="6">
{{ $t('goalsAddEditGoalModalComponent.activityTypeCardio') }}
</option>
</select>
<!-- goal type fields -->
<label for="goalTypeAddEdit"

View File

@@ -43,6 +43,9 @@
<span v-if="goal.activity_type == 5">{{
$t('goalsAddEditGoalModalComponent.activityTypeStrength')
}}</span>
<span v-if="goal.activity_type == 6">{{
$t('goalsAddEditGoalModalComponent.activityTypeCardio')
}}</span>
</div>
<span v-if="goal.interval == 'daily'">{{
$t('goalsAddEditGoalModalComponent.intervalOption1')

View File

@@ -173,6 +173,9 @@
<span v-if="authStore.user.preferred_language == 'pt'">{{
$t('generalItems.languageOption3')
}}</span>
<span v-if="authStore.user.preferred_language == 'sl'">{{
$t('generalItems.languageOption12')
}}</span>
<span v-if="authStore.user.preferred_language == 'es'">{{
$t('generalItems.languageOption7')
}}</span>

View File

@@ -334,6 +334,7 @@
<option value="it">{{ $t('generalItems.languageOption11') }}</option>
<option value="nl">{{ $t('generalItems.languageOption6') }}</option>
<option value="pt">{{ $t('generalItems.languageOption3') }}</option>
<option value="sl">{{ $t('generalItems.languageOption12') }}</option>
<option value="es">{{ $t('generalItems.languageOption7') }}</option>
<option value="us">{{ $t('generalItems.languageOption1') }}</option>
</select>
@@ -696,6 +697,11 @@ async function submitEditUserForm() {
photo_path: newEditUserPhotoPath.value,
active: newEditUserActive.value
}
if (props.action === 'profile') {
await profile.editProfile(data)
} else {
await users.editUser(data.id, data)
}
if (newEditUserPhotoFile.value) {
try {
if (props.action === 'profile') {
@@ -709,11 +715,6 @@ async function submitEditUserForm() {
)
}
}
if (props.action === 'profile') {
await profile.editProfile(data)
} else {
await users.editUser(data.id, data)
}
if (props.action === 'edit') {
emit('editedUser', data)
}

View File

@@ -19,6 +19,9 @@
<span v-if="goal.activity_type == 5">{{
$t('userGoalsStatsComponent.activityTypeStrength')
}}</span>
<span v-if="goal.activity_type == 6">{{
$t('userGoalsStatsComponent.activityTypeCardio')
}}</span>
<span> | </span>
<span v-if="goal.interval == 'daily'">{{
$t('userGoalsStatsComponent.intervalOption1')

View File

@@ -39,5 +39,6 @@
"soccer": "Futbol",
"padel": "Pàdel",
"treadmillRun": "Correr en cinta",
"cardioTraining": "Cardio training",
"labelWorkout": " entrenament"
}
}

View File

@@ -47,6 +47,7 @@
"modalEditActivityTypeOption38": "Futbol",
"modalEditActivityTypeOption39": "Pàdel",
"modalEditActivityTypeOption40": "Correr en cinta",
"modalEditActivityTypeOption41": "Cardio training",
"modalEditActivityVisibilityLabel": "Visibilitat",
"modalEditActivityVisibilityOption0": "Públic",
"modalEditActivityVisibilityOption1": "Seguidors",
@@ -66,4 +67,4 @@
"modalEditActivityHideGearLabel": "Amaga equipament",
"successActivityEdit": "Activitat editada correctament",
"errorActivityEdit": "Error editant activitat"
}
}

View File

@@ -1,18 +1,18 @@
{
"bulkImportIntegrationTitle": "Importació massiva",
"bulkImportIntegrationBody": "Importació massiva d'activitats (des de fitxers desats a la carpeta activity_files/bulk_import)",
"buttonBulkImport": "Importar activitats",
"loadingMessageBulkImport": "Important activitats des de fitxers...",
"errorMessageUnableToImportActivities": "Error important activitats",
"importTitle": "Importa",
"stravaGearImportTitle": "Importació d'equipament d'Strava",
"stravaGearImportBody": "Importar equipament des d'una exportació massiva d'Strava (a la carpeta data/activity_files/bulk_import)",
"stravaGearImportbuttonBikes": "Importar bicis d'Strava",
"loadingMessageStravaBikesImport": "Important bicis d'Strava desde fitxer...",
"successMessageStravaBikesImport": "Bicis d'Strava importades correctament",
"errorMessageUnableToImportBikes": "Error important bicis d'Strava",
"stravaImportbuttonShoes": "Importar bambes d'Strava",
"loadingMessageStravaShoesImport": "Important bambes d'Strava des de fitxer...",
"successMessageStravaShoesImport": "Bambes d'Strava importades correctament",
"errorMessageUnableToImportShoes": "Error important bambes d'Strava"
"bulkImportIntegrationTitle": "Importació massiva",
"bulkImportIntegrationBody": "Importació massiva d'activitats (des de fitxers desats a la carpeta activity_files/bulk_import)",
"buttonBulkImport": "Importar activitats",
"loadingMessageBulkImport": "Important activitats des de fitxers...",
"errorMessageUnableToImportActivities": "Error important activitats",
"importTitle": "Importa",
"stravaGearImportTitle": "Importació d'equipament d'Strava",
"stravaGearImportBody": "Importar equipament des d'una exportació massiva d'Strava (a la carpeta data/activity_files/bulk_import)",
"stravaGearImportbuttonBikes": "Importar bicis d'Strava",
"loadingMessageStravaBikesImport": "Important bicis d'Strava desde fitxer...",
"successMessageStravaBikesImport": "Bicis d'Strava importades correctament",
"errorMessageUnableToImportBikes": "Error important bicis d'Strava",
"stravaImportbuttonShoes": "Importar bambes d'Strava",
"loadingMessageStravaShoesImport": "Important bambes d'Strava des de fitxer...",
"successMessageStravaShoesImport": "Bambes d'Strava importades correctament",
"errorMessageUnableToImportShoes": "Error important bambes d'Strava"
}

View File

@@ -5,6 +5,7 @@
"activityTypeSwim": "Natació",
"activityTypeWalk": "Caminar",
"activityTypeStrength": "Força",
"activityTypeCardio": "Cardio",
"intervalOption1": "Diari",
"intervalOption2": "Setmanal",
"intervalOption3": "Mensual",

View File

@@ -17,6 +17,7 @@
"languageOption9": "Xinès (Tradicional)",
"languageOption10": "Gallec (GL)",
"languageOption11": "Italià (IT)",
"languageOption12": "Slovenian (SL)",
"firstDayOfWeekOption0": "Diumenge",
"firstDayOfWeekOption1": "Dilluns",
"firstDayOfWeekOption2": "Dimarts",

View File

@@ -20,6 +20,7 @@
"searchSelectActivityType14": "Surf",
"searchSelectActivityType15": "Patinatge sobre gel",
"searchSelectActivityType16": "Futbol",
"searchSelectActivityType17": "Cardio",
"searchSelectGearType0": "Tot",
"searchSelectGearType1": "Bici",
"searchSelectGearType2": "Sabatilles",

View File

@@ -38,6 +38,7 @@
"iceSkate": "滑冰",
"soccer": "足球",
"padel": "配斗球",
"treadmillRun": "Treadmill run",
"treadmillRun": "跑步机跑",
"cardioTraining": "Cardio training",
"labelWorkout": " 运动"
}
}

View File

@@ -1,13 +1,13 @@
{
"labelGear": "Gear",
"labelGearNotSet": "Not set",
"modalLabelDeleteGear": "Delete gear from activity",
"modalLabelDeleteGearBody": "Are you sure you want to remove the gear from the activity?",
"modalLabelDeleteGearButton": "Delete gear",
"successMessageGearAdded": "Gear added to activity",
"successMessageGearDeleted": "Gear deleted from activity",
"errorMessageDeleteGear": "Error deleting gear from activity",
"errorMessageActivityNotFound": "Activity not found",
"alertPrivacyMessage": "You have hidden information in this activity. You can see it, but others cannot.",
"isHiddenMessage": "This activity is hidden. Probably because it is a duplicate or was hidden by the user."
"labelGear": "装备",
"labelGearNotSet": "未设置",
"modalLabelDeleteGear": "从活动中移除装备",
"modalLabelDeleteGearBody": "确定要从该活动中移除装备吗?",
"modalLabelDeleteGearButton": "移除装备",
"successMessageGearAdded": "装备已添加到活动",
"successMessageGearDeleted": "装备已从活动中移除",
"errorMessageDeleteGear": "从活动中移除装备时出错",
"errorMessageActivityNotFound": "未找到活动",
"alertPrivacyMessage": "此活动中包含隐藏信息,仅你可见,其他人无法查看。",
"isHiddenMessage": "此活动已被隐藏,可能是重复活动或由用户手动隐藏。"
}

View File

@@ -6,26 +6,26 @@
"buttonDeleteActivity": "删除活动",
"buttonEditActivity": "编辑活动",
"buttonAddActivityMedia": "添加媒体",
"modalDeleteBody1": "Are you sure you want to delete activity ",
"modalDeleteBody2": "This action cannot be undone.",
"modalAddMediaTitle": "Add media",
"modalAddMediaBody": "Upload .png, .jpg or .jpeg file",
"processingMediaUpload": "Processing media upload...",
"successMediaUpload": "Media uploaded successfully",
"errorMediaUpload": "Error uploading media",
"labelVirtual": "(Virtual) ",
"privateNotes": "Private notes",
"activityDistance": "Distance",
"activityTime": "Time",
"activityPace": "Pace",
"activityAvgHR": "Avg HR",
"activityMaxHR": "Max HR",
"activityAvgPower": "Avg power",
"activityAvgSpeed": "Avg speed",
"activityEleGain": "Ele gain",
"activityEleLoss": "Ele loss",
"activityCalories": "Calories",
"activityNoData": "No data",
"errorFetchingUserById": "Error fetching user by id",
"errorDeletingActivity": "Error deleting activity"
"modalDeleteBody1": "你确定要删除这个媒体文件吗 ",
"modalDeleteBody2": "无法撤消此操作。",
"modalAddMediaTitle": "添加媒体",
"modalAddMediaBody": "上传 .png.jpg .jpeg 文件",
"processingMediaUpload": "正在处理媒体上传……",
"successMediaUpload": "媒体已成功上传",
"errorMediaUpload": "上传媒体时出错",
"labelVirtual": "(虚拟活动) ",
"privateNotes": "私密笔记",
"activityDistance": "距离",
"activityTime": "时间",
"activityPace": "配速",
"activityAvgHR": "平均心率",
"activityMaxHR": "最大心率",
"activityAvgPower": "平均功率",
"activityAvgSpeed": "平均速度",
"activityEleGain": "累计爬升高度",
"activityEleLoss": "累计下降高度",
"activityCalories": "卡路里",
"activityNoData": "没有数据",
"errorFetchingUserById": "从 id 获取用户时出错",
"errorDeletingActivity": "删除活动时发生错误"
}

View File

@@ -1,20 +1,20 @@
{
"labelWorkoutStepType": "Step type",
"labelWorkoutStepTime": "Step time",
"labelWorkoutStepReps": "Step reps",
"labelWorkoutStepIntensity": "Intensity",
"labelWorkoutStepNotes": "Notes",
"labelWorkoutStepExerciseName": "Step name",
"labelWorkoutStepExerciseWeight": "Weight",
"labelWorkoutStepSwimStroke": "Step swim stroke",
"labelWorkoutSetType": "Set type",
"labelWorkoutSetTime": "Set time",
"labelWorkoutSetReps": "Set reps",
"labelWorkoutSetExerciseName": "Set name",
"labelWorkoutSetExerciseWeight": "Set weight",
"labelWorkoutSetTypeMobile": "Type",
"labelWorkoutSetTimeMobile": "Time",
"labelWorkoutSetRepsMobile": "Reps",
"labelWorkoutSetExerciseNameMobile": "Name",
"labelWorkoutSetExerciseWeightMobile": "Weight"
"labelWorkoutStepType": "训练步骤类型",
"labelWorkoutStepTime": "训练时长",
"labelWorkoutStepReps": "重复次数",
"labelWorkoutStepIntensity": "训练负荷水平",
"labelWorkoutStepNotes": "备注",
"labelWorkoutStepExerciseName": "步骤名称",
"labelWorkoutStepExerciseWeight": "训练重量",
"labelWorkoutStepSwimStroke": "游泳姿势",
"labelWorkoutSetType": "组类型",
"labelWorkoutSetTime": "组时长",
"labelWorkoutSetReps": "组重复次数",
"labelWorkoutSetExerciseName": "组名称",
"labelWorkoutSetExerciseWeight": "组重量",
"labelWorkoutSetTypeMobile": "类型",
"labelWorkoutSetTimeMobile": "时长",
"labelWorkoutSetRepsMobile": "重复次数",
"labelWorkoutSetExerciseNameMobile": "名称",
"labelWorkoutSetExerciseWeightMobile": "训练重量"
}

View File

@@ -24,7 +24,7 @@
"modalEditActivityTypeOption15": "高山滑雪",
"modalEditActivityTypeOption16": "越野滑雪",
"modalEditActivityTypeOption17": "单板滑雪",
"modalEditActivityTypeOption18": "Transition",
"modalEditActivityTypeOption18": "换项",
"modalEditActivityTypeOption19": "传统力量训练",
"modalEditActivityTypeOption20": "克罗斯菲特",
"modalEditActivityTypeOption21": "网球",
@@ -46,7 +46,8 @@
"modalEditActivityTypeOption37": "滑冰",
"modalEditActivityTypeOption38": "足球",
"modalEditActivityTypeOption39": "配斗球",
"modalEditActivityTypeOption40": "Treadmill run",
"modalEditActivityTypeOption40": "跑步机跑",
"modalEditActivityTypeOption41": "Cardio training",
"modalEditActivityVisibilityLabel": "可见性",
"modalEditActivityVisibilityOption0": "公开",
"modalEditActivityVisibilityOption1": "粉丝",
@@ -66,4 +67,4 @@
"modalEditActivityHideGearLabel": "隐藏装备",
"successActivityEdit": "活动编辑成功",
"errorActivityEdit": "活动编辑失败"
}
}

View File

@@ -1,16 +1,16 @@
{
"requestAccepted": "Accepted",
"requestPending": "Request pending",
"followingModalTitle": "Delete following",
"followingModalBody": "Are you sure you want to delete following user ",
"followerModalTitle": "Delete follower",
"followerModalBody": "Are you sure you want to delete follower user ",
"followerAcceptModalTitle": "Accept user request",
"followerAcceptModalBody": "Are you sure you want to accept follow request from user ",
"followerDeclineModalTitle": "Decline user request ",
"followerDeclineModalBody": "Are you sure you want to decline follow request from user ",
"errorDeleteFollowing": "Error deleting following",
"errorDeleteFollower": "Error deleting follower",
"errorUpdateFollower": "Error updating follower",
"errorFetchingFollowersDetails": "Error fetching followers details"
"requestAccepted": "已接受",
"requestPending": "请求待处理",
"followingModalTitle": "取消关注",
"followingModalBody": "确定要取消关注该用户吗?",
"followerModalTitle": "删除粉丝",
"followerModalBody": "确定要删除该粉丝吗?",
"followerAcceptModalTitle": "接受关注请求",
"followerAcceptModalBody": "确定要接受该用户的关注请求吗?",
"followerDeclineModalTitle": "拒绝关注请求",
"followerDeclineModalBody": "确定要拒绝该用户的关注请求吗?",
"errorDeleteFollowing": "取消关注时出错",
"errorDeleteFollower": "删除粉丝时出错",
"errorUpdateFollower": "更新粉丝信息时出错",
"errorFetchingFollowersDetails": "获取粉丝详情时出错"
}

View File

@@ -1,19 +1,19 @@
{
"addEditGearComponentModalAddTitle": "Add gear component",
"addEditGearComponentModalEditTitle": "Edit gear component",
"addEditGearComponentModalAddEditTypeLabel": "Type",
"addEditGearComponentModalAddEditBrandLabel": "Brand",
"addEditGearComponentModalAddEditModelLabel": "Model",
"addEditGearComponentModalAddEditPurchaseDateLabel": "Purchase date",
"addEditGearComponentModalAddEditExpectedDistanceLabel": "Expected distance",
"addEditGearComponentModalAddEditExpectedTimeLabel": "Expected time",
"addEditGearComponentModalAddEditPurchaseValueLabel": "Purchase value",
"addEditGearComponentModalAddEditRetiredDateLabel": "Retired date",
"addEditGearComponentModalAddEditIsActiveLabel": "Is active",
"successGearComponentAdded": "Gear component added successfully",
"successGearComponentEdited": "Gear component edited successfully",
"errorGearComponentAdd": "Error adding gear component",
"gearComponentListGearEditSuccessMessage": "Gear component edited successfully",
"gearComponentListGearEditErrorMessage": "Error editing gear component",
"retiredDateAfterPurchaseDateError": "Retired date must be after purchase date"
"addEditGearComponentModalAddTitle": "添加装备部件",
"addEditGearComponentModalEditTitle": "编辑装备部件",
"addEditGearComponentModalAddEditTypeLabel": "类型",
"addEditGearComponentModalAddEditBrandLabel": "品牌",
"addEditGearComponentModalAddEditModelLabel": "型号",
"addEditGearComponentModalAddEditPurchaseDateLabel": "购买日期",
"addEditGearComponentModalAddEditExpectedDistanceLabel": "预期距离",
"addEditGearComponentModalAddEditExpectedTimeLabel": "预期时间",
"addEditGearComponentModalAddEditPurchaseValueLabel": "购买价格",
"addEditGearComponentModalAddEditRetiredDateLabel": "退役日期",
"addEditGearComponentModalAddEditIsActiveLabel": "活跃",
"successGearComponentAdded": "装备部件添加成功",
"successGearComponentEdited": "装备部件修改成功",
"errorGearComponentAdd": "添加装备部件时出错",
"gearComponentListGearEditSuccessMessage": "装备部件编辑成功",
"gearComponentListGearEditErrorMessage": "编辑装备部件时出错",
"retiredDateAfterPurchaseDateError": "退役日期必须晚于购买日期"
}

View File

@@ -1,79 +1,79 @@
{
"gearComponentBackTire": "Back tire",
"gearComponentFrontTire": "Front tire",
"gearComponentBackTube": "Back tube",
"gearComponentFrontTube": "Front tube",
"gearComponentBackWheelValve": "Back wheel valve",
"gearComponentFrontWheelValve": "Front wheel valve",
"gearComponentBackTubelessSealant": "Back tubeless sealant",
"gearComponentBackTubelessRimTape": "Back tubeless rim tape",
"gearComponentFrontTubelessSealant": "Front tubeless sealant",
"gearComponentFrontTubelessRimTape": "Front tubeless rim tape",
"gearComponentBackWheel": "Back wheel",
"gearComponentFrontWheel": "Front wheel",
"gearComponentBackBreakRotor": "Back brake rotor",
"gearComponentFrontBreakRotor": "Front brake rotor",
"gearComponentBackBreakPads": "Back brake pads",
"gearComponentFrontBreakPads": "Front brake pads",
"gearComponentBackBreakOil": "Back brake oil",
"gearComponentFrontBreakOil": "Front brake oil",
"gearComponentCrankLeftPowerMeter": "Crank left power meter",
"gearComponentCrankRightPowerMeter": "Crank right power meter",
"gearComponentCranksetPowerMeter": "Crankset power meter",
"gearComponentPedalsLeftPowerMeter": "Pedals left power meter",
"gearComponentPedalsRightPowerMeter": "Pedals right power meter",
"gearComponentPedalsPowerMeter": "Pedals power meter",
"gearComponentPedals": "Pedals",
"gearComponentCrankset": "Crankset",
"gearComponentCassette": "Cassette",
"gearComponentChain": "Chain",
"gearComponentFrontShifter": "Front shifter",
"gearComponentFrontDerailleur": "Front derailleur",
"gearComponentRearShifter": "Rear shifter",
"gearComponentRearDerailleur": "Rear derailleur",
"gearComponentBottomBracket": "Bottom bracket",
"gearComponentBottleCage": "Bottle cage",
"gearComponentHandlebar": "Handlebar",
"gearComponentHeadset": "Headset",
"gearComponentComputerMount": "Computer mount",
"gearComponentHandlebarTape": "Handlebar tape",
"gearComponentGrips": "Grips",
"gearComponentStem": "Stem",
"gearComponentSeatpost": "Seatpost",
"gearComponentSaddle": "Saddle",
"gearComponentFork": "Fork",
"gearComponentFrame": "Frame",
"gearComponentCleats": "Cleats",
"gearComponentInsoles": "Insoles",
"gearComponentLaces": "Laces",
"gearComponentBaseGrip": "Base grip",
"gearComponentBumpers": "Bumpers",
"gearComponentGrommets": "Grommets",
"gearComponentOverGrip": "Over grip",
"gearComponentStrings": "Strings",
"gearComponentSail": "Sail",
"gearComponentBoard": "Board",
"gearComponentMast": "Mast",
"gearComponentBoom": "Boom",
"gearComponentMastExtension": "Mast extension",
"gearComponentMastBase": "Mast base",
"gearComponentMastUniversalJoint": "Mast universal joint",
"gearComponentFin": "Fin",
"gearComponentFootstraps": "Footstraps",
"gearComponentHarnessLines": "Harness lines",
"gearComponentRiggingLines": "Rigging lines",
"gearComponentFootpad": "Footpad",
"gearComponentImpactVest": "Impact vest",
"gearComponentLifeguardVest": "Lifeguard vest",
"gearComponentHelmet": "Helmet",
"gearComponentWing": "Wing",
"gearComponentFrontFoil": "Front foil",
"gearComponentStabilizer": "Stabilizer",
"gearComponentFuselage": "Fuselage",
"gearComponentOf": " of ",
"gearComponentListGearComponentIsInactiveBadge": "Inactive",
"gearComponentListModalDeleteGearComponentTitle": "Delete gear component",
"gearComponentListModalDeleteGearComponentBody": "Are you sure you want to delete gear component ",
"gearComponentListGearDeleteSuccessMessage": "Gear component deleted successfully",
"gearComponentListGearDeleteErrorMessage": "Error deleting gear component"
"gearComponentBackTire": "后轮胎",
"gearComponentFrontTire": "前轮胎",
"gearComponentBackTube": "后轮胎",
"gearComponentFrontTube": "前内胎",
"gearComponentBackWheelValve": "后轮气嘴",
"gearComponentFrontWheelValve": "前轮气嘴",
"gearComponentBackTubelessSealant": "后真空胎密封液",
"gearComponentBackTubelessRimTape": "后真空胎圈带",
"gearComponentFrontTubelessSealant": "前真空胎密封液",
"gearComponentFrontTubelessRimTape": "前真空胎圈带",
"gearComponentBackWheel": "后轮组",
"gearComponentFrontWheel": "前轮组",
"gearComponentBackBreakRotor": "后刹车碟片",
"gearComponentFrontBreakRotor": "前刹车碟片",
"gearComponentBackBreakPads": "后刹车片",
"gearComponentFrontBreakPads": "前刹车片",
"gearComponentBackBreakOil": "后刹车油",
"gearComponentFrontBreakOil": "前刹车油",
"gearComponentCrankLeftPowerMeter": "左曲柄功率计",
"gearComponentCrankRightPowerMeter": "右曲柄功率计",
"gearComponentCranksetPowerMeter": "曲柄组功率计",
"gearComponentPedalsLeftPowerMeter": "左踏板功率计",
"gearComponentPedalsRightPowerMeter": "右踏板功率计",
"gearComponentPedalsPowerMeter": "踏板功率计",
"gearComponentPedals": "踏板",
"gearComponentCrankset": "曲柄组",
"gearComponentCassette": "飞轮",
"gearComponentChain": "链条",
"gearComponentFrontShifter": "前变速手柄",
"gearComponentFrontDerailleur": "前变速器",
"gearComponentRearShifter": "后变速手柄",
"gearComponentRearDerailleur": "后变速器",
"gearComponentBottomBracket": "中轴",
"gearComponentBottleCage": "水壶架",
"gearComponentHandlebar": "车把",
"gearComponentHeadset": "转向组",
"gearComponentComputerMount": "码表支架",
"gearComponentHandlebarTape": "把带",
"gearComponentGrips": "把套",
"gearComponentStem": "把立",
"gearComponentSeatpost": "坐管",
"gearComponentSaddle": "车座",
"gearComponentFork": "前叉",
"gearComponentFrame": "车架",
"gearComponentCleats": "锁片",
"gearComponentInsoles": "鞋垫",
"gearComponentLaces": "鞋带",
"gearComponentBaseGrip": "底握把",
"gearComponentBumpers": "防撞条",
"gearComponentGrommets": "孔环",
"gearComponentOverGrip": "外层握把",
"gearComponentStrings": "拍弦",
"gearComponentSail": "",
"gearComponentBoard": "",
"gearComponentMast": "桅杆",
"gearComponentBoom": "横杆",
"gearComponentMastExtension": "桅杆延长件",
"gearComponentMastBase": "桅杆底座",
"gearComponentMastUniversalJoint": "桅杆万向接头",
"gearComponentFin": "尾翼",
"gearComponentFootstraps": "脚带",
"gearComponentHarnessLines": "吊带绳",
"gearComponentRiggingLines": "索具绳",
"gearComponentFootpad": "脚垫",
"gearComponentImpactVest": "防撞背心",
"gearComponentLifeguardVest": "救生衣",
"gearComponentHelmet": "头盔",
"gearComponentWing": "",
"gearComponentFrontFoil": "前翼",
"gearComponentStabilizer": "稳定翼",
"gearComponentFuselage": "机身",
"gearComponentOf": " ",
"gearComponentListGearComponentIsInactiveBadge": "未启用",
"gearComponentListModalDeleteGearComponentTitle": "删除装备部件",
"gearComponentListModalDeleteGearComponentBody": "确定要删除装备部件 ",
"gearComponentListGearDeleteSuccessMessage": "装备部件删除成功",
"gearComponentListGearDeleteErrorMessage": "删除装备部件时出错"
}

View File

@@ -1,29 +1,29 @@
{
"addEditGearModalEditTitle": "Edit gear",
"addEditGearModalAddTitle": "Add gear",
"addEditGearModalAddBrandLabel": "Brand",
"addEditGearModalAddModelLabel": "Model",
"addEditGearModalAddNicknameLabel": "Nickname",
"addEditGearModalAddTypeLabel": "Gear type",
"addEditGearModalAddTypeOption1": "Bike",
"addEditGearModalAddTypeOption2": "Shoes",
"addEditGearModalAddTypeOption3": "Wetsuit",
"addEditGearModalAddTypeOption4": "Racquet",
"addEditGearModalAddTypeOption5": "Skis",
"addEditGearModalAddTypeOption6": "Snowboard",
"addEditGearModalAddTypeOption7": "Windsurf",
"addEditGearModalAddTypeOption8": "Water sports board",
"addEditGearModalAddDateLabel": "Created date",
"addEditGearModalAddIsActiveLabel": "Is active",
"addEditGearModalAddIsActiveOption1": "Active",
"addEditGearModalAddIsActiveOption0": "Inactive",
"addEditGearModalAddIsInitialKmsLabel": "Initial kms",
"addEditGearModalAddIsInitialMilesLabel": "Initial miles",
"addEditGearModalAddEditPurchaseValueLabel": "Purchase value",
"errorNicknameAlreadyExistsFeedback": "Nickname already exists",
"errorNotPossibleToGetGearByNickname": "Is was not possible to get gear by nickname for validation",
"successGearAdded": "Gear added successfully",
"errorGearAdd": "Error adding gear",
"successGearEdited": "Gear edited successfully",
"errorGearEdit": "Error editing gear"
"addEditGearModalEditTitle": "编辑装备",
"addEditGearModalAddTitle": "添加装备",
"addEditGearModalAddBrandLabel": "品牌",
"addEditGearModalAddModelLabel": "型号",
"addEditGearModalAddNicknameLabel": "昵称",
"addEditGearModalAddTypeLabel": "装备类型",
"addEditGearModalAddTypeOption1": "自行车",
"addEditGearModalAddTypeOption2": "鞋子",
"addEditGearModalAddTypeOption3": "潜水服",
"addEditGearModalAddTypeOption4": "球拍",
"addEditGearModalAddTypeOption5": "滑雪板",
"addEditGearModalAddTypeOption6": "单板滑雪板",
"addEditGearModalAddTypeOption7": "帆板",
"addEditGearModalAddTypeOption8": "水上运动板",
"addEditGearModalAddDateLabel": "创建日期",
"addEditGearModalAddIsActiveLabel": "活跃",
"addEditGearModalAddIsActiveOption1": "启用中",
"addEditGearModalAddIsActiveOption0": "未启用",
"addEditGearModalAddIsInitialKmsLabel": "初始公里数",
"addEditGearModalAddIsInitialMilesLabel": "初始英里数",
"addEditGearModalAddEditPurchaseValueLabel": "购买价格",
"errorNicknameAlreadyExistsFeedback": "昵称已经存在",
"errorNotPossibleToGetGearByNickname": "无法通过昵称获取装备以进行验证",
"successGearAdded": "装备添加成功",
"errorGearAdd": "添加装备时出错",
"successGearEdited": "装备编辑成功",
"errorGearEdit": "编辑装备时出错"
}

View File

@@ -1,16 +1,16 @@
{
"gearListTypeLabel": "Type",
"gearListTypeOption1": "Bike",
"gearListTypeOption2": "Shoes",
"gearListTypeOption3": "Wetsuit",
"gearListTypeOption4": "Racquet",
"gearListTypeOption5": "Skis",
"gearListTypeOption6": "Snowboard",
"gearListTypeOption7": "Windsurf",
"gearListTypeOption8": "Water sports board",
"gearListGearIsInactiveBadge": "Inactive",
"gearListModalDeleteGearTitle": "Delete gear",
"gearListModalDeleteGearBody": "Are you sure you want to delete gear ",
"gearListGearDeleteSuccessMessage": "Gear deleted successfully",
"gearListGearDeleteErrorMessage": "Error deleting gear"
"gearListTypeLabel": "类型",
"gearListTypeOption1": "自行车",
"gearListTypeOption2": "鞋子",
"gearListTypeOption3": "潜水服",
"gearListTypeOption4": "球拍",
"gearListTypeOption5": "滑雪板",
"gearListTypeOption6": "单板滑雪板",
"gearListTypeOption7": "帆板",
"gearListTypeOption8": "水上运动板",
"gearListGearIsInactiveBadge": "未启用",
"gearListModalDeleteGearTitle": "移除装备",
"gearListModalDeleteGearBody": "确定要删除此装备吗?",
"gearListGearDeleteSuccessMessage": "装备已成功删除",
"gearListGearDeleteErrorMessage": "删除装备时出错"
}

View File

@@ -1,13 +1,13 @@
{
"weight": "Weight",
"noWeightData": "No weight data",
"noWeightTarget": "No weight target",
"noHeightDefined": "No height defined for user",
"weight": "体重",
"noWeightData": "没有体重数据",
"noWeightTarget": "没有体量目标",
"noHeightDefined": "用户未设置身高",
"bmi": "BMI",
"bmiUnderweight": "Underweight",
"bmiNormalWeight": "Normal weight",
"bmiOverweight": "Overweight",
"bmiObesityClass1": "Obesity (Class 1)",
"bmiObesityClass2": "Obesity (Class 2)",
"bmiObesityClass3": "Extreme Obesity (Class 3)"
"bmiUnderweight": "偏瘦",
"bmiNormalWeight": "正常体重",
"bmiOverweight": "超重",
"bmiObesityClass1": "一级肥胖",
"bmiObesityClass2": "二级肥胖",
"bmiObesityClass3": "三级肥胖(极度肥胖)"
}

View File

@@ -1,4 +1,4 @@
{
"dashboardSection": "Dashboard",
"weightSection": "Weight"
"dashboardSection": "仪表板",
"weightSection": "体重"
}

View File

@@ -1,8 +1,8 @@
{
"addWeightModalTitle": "Add weight",
"editWeightModalTitle": "Edit weight",
"addWeightWeightLabel": "Weight",
"addWeightDateLabel": "Date",
"successAddWeight": "Weight added",
"errorAddWeight": "Error adding weight"
"addWeightModalTitle": "添加体重",
"editWeightModalTitle": "编辑体重",
"addWeightWeightLabel": "体重",
"addWeightDateLabel": "日期",
"successAddWeight": "体重已添加",
"errorAddWeight": "添加体重时出错"
}

View File

@@ -1,9 +1,9 @@
{
"labelGarminConnect": "Garmin Connect",
"modalDeleteWeightTitle": "Delete weight",
"modalDeleteWeightBody": "Are you sure you want to delete weight entry for ",
"successDeleteWeight": "Weight deleted",
"errorDeleteWeight": "It was not possible to delete weight entry",
"successEditWeight": "Weight edited",
"errorEditWeight": "It was not possible to edit weight entry"
"modalDeleteWeightTitle": "删除体重记录",
"modalDeleteWeightBody": "确定要删除此体重记录吗?",
"successDeleteWeight": "体重记录已删除",
"errorDeleteWeight": "无法删除体重记录",
"successEditWeight": "体重记录已编辑",
"errorEditWeight": "无法编辑体重记录"
}

View File

@@ -1,6 +1,6 @@
{
"buttonAddWeight": "Add weight",
"labelNumberOfHealthDataWeight1": "There is a total of ",
"labelNumberOfHealthDataWeight2": " weight measure(s) inserted (",
"labelNumberOfHealthDataWeight3": " loaded):"
"buttonAddWeight": "添加体重",
"labelNumberOfHealthDataWeight1": "共有",
"labelNumberOfHealthDataWeight2": "条体重记录(",
"labelNumberOfHealthDataWeight3": "条已加载):"
}

View File

@@ -1,7 +1,7 @@
{
"home": "Home",
"gear": "Gear",
"health": "Health",
"alerts": "Alerts",
"menu": "Menu"
"home": "首页",
"gear": "装备",
"health": "健康",
"alerts": "警告",
"menu": "菜单"
}

View File

@@ -1,13 +1,13 @@
{
"search": "Search",
"activities": "Activities",
"activitiesList": "List",
"summary": "Summary",
"gear": "Gear",
"health": "Health",
"profile": "Profile",
"settings": "Settings",
"login": "Login",
"logout": "Logout",
"errorLogout": "Error logging out"
"search": "搜索",
"activities": "活动",
"activitiesList": "列表",
"summary": "摘要",
"gear": "装备",
"health": "健康",
"profile": "个人资料",
"settings": "设置",
"login": "登录",
"logout": "注销",
"errorLogout": "注销错误"
}

View File

@@ -1,4 +1,4 @@
{
"title": "Ops...",
"subtitle": "No records found"
"title": "糟糕……",
"subtitle": "未找到任何记录"
}

View File

@@ -1,4 +1,4 @@
{
"title": "New sign-up request",
"subTitle": " has requested to sign-up"
"title": "新的注册请求",
"subTitle": " 已请求注册"
}

View File

@@ -1,6 +1,6 @@
{
"errorFetchingNotificationsPagination": "Error fetching notifications with pagination",
"errorFetchingNotificationsNumber": "Error fetching notifications number",
"errorFetchingNotificationById": "Error fetching notification by ID",
"errorFetchingMessageFromWebSocket": "Error fetching message from WebSocket"
"errorFetchingNotificationsPagination": "获取带分页的通知时出错",
"errorFetchingNotificationsNumber": "获取通知数量时出错",
"errorFetchingNotificationById": "根据 ID 获取通知时出错",
"errorFetchingMessageFromWebSocket": " WebSocket 获取消息时出错"
}

View File

@@ -1,4 +1,4 @@
{
"newAcceptedRequestTitle": "New accepted request",
"newAcceptedRequestSubTitle": " has accepted your follow request"
"newAcceptedRequestTitle": "新的关注请求已被接受",
"newAcceptedRequestSubTitle": "已接受了你的关注请求"
}

View File

@@ -1,4 +1,4 @@
{
"newActivityDuplicateStartTimeTitle": "New activity with duplicated start time",
"newActivityDuplicateStartTimeSubTitle": "A new activity has been added with a start time that overlaps with an existing activity. Please review it"
"newActivityDuplicateStartTimeTitle": "新活动的开始时间重复",
"newActivityDuplicateStartTimeSubTitle": "新增的活动开始时间与现有活动重叠,请检查确认。"
}

View File

@@ -1,4 +1,4 @@
{
"newActivityTitle": "New activity",
"newActivitySubTitle": "Good job! A new activity has been added!"
"newActivityTitle": "‎新活动‎",
"newActivitySubTitle": "干得好!一个新的活动已添加!"
}

View File

@@ -1,4 +1,4 @@
{
"newFollowerRequestTitle": "New follower request",
"newFollowerRequestSubTitle": "You have a new follower request from "
"newFollowerRequestTitle": "新的关注请求",
"newFollowerRequestSubTitle": "您有一个新的关注请求来自 "
}

View File

@@ -1,3 +1,3 @@
{
"formLabel": "Language"
"formLabel": "语言"
}

View File

@@ -1,6 +1,6 @@
{
"formLabel": "Theme",
"themeLight": "Light",
"themeDark": "Dark",
"themeAuto": "Auto"
"formLabel": "主题",
"themeLight": "浅色",
"themeDark": "深色",
"themeAuto": "自动"
}

View File

@@ -1,18 +1,18 @@
{
"bulkImportIntegrationTitle": "Bulk import",
"bulkImportIntegrationBody": "Bulk import activities from files (in the data/activity_files/bulk_import folder)",
"buttonBulkImport": "Import activities",
"loadingMessageBulkImport": "Importing activities from files...",
"errorMessageUnableToImportActivities": "An error occurred while importing activities",
"importTitle": "Import",
"stravaGearImportTitle": "Strava gear import",
"stravaGearImportBody": "Import gear from a Strava bulk export (in the data/activity_files/bulk_import folder)",
"stravaGearImportbuttonBikes": "Import Strava bikes",
"loadingMessageStravaBikesImport": "Importing Strava bikes from file...",
"successMessageStravaBikesImport": "Strava bikes imported successfully",
"errorMessageUnableToImportBikes": "An error occurred while importing Strava bikes",
"stravaImportbuttonShoes": "Import Strava shoes",
"loadingMessageStravaShoesImport": "Importing Strava shoes from file...",
"successMessageStravaShoesImport": "Strava shoes imported successfully",
"errorMessageUnableToImportShoes": "An error occurred while importing Strava shoes"
"bulkImportIntegrationTitle": "批量导入",
"bulkImportIntegrationBody": "从文件批量导入活动记录(位于 data/activity_files/bulk_import 文件夹)",
"buttonBulkImport": "导入活动",
"loadingMessageBulkImport": "正在从文件导入活动……",
"errorMessageUnableToImportActivities": "导入活动时发生错误",
"importTitle": "导入",
"stravaGearImportTitle": "Strava 装备导入",
"stravaGearImportBody": "从 Strava 批量导出文件导入装备(位于 data/activity_files/bulk_import 文件夹)",
"stravaGearImportbuttonBikes": "导入 Strava 自行车",
"loadingMessageStravaBikesImport": "正在从文件导入 Strava 自行车……",
"successMessageStravaBikesImport": "Strava 自行车导入成功",
"errorMessageUnableToImportBikes": "导入 Strava 自行车时发生错误",
"stravaImportbuttonShoes": "导入 Strava 跑鞋",
"loadingMessageStravaShoesImport": "正在从文件导入 Strava 跑鞋……",
"successMessageStravaShoesImport": "Strava 跑鞋导入成功",
"errorMessageUnableToImportShoes": "导入 Strava 跑鞋时发生错误"
}

View File

@@ -1,14 +1,14 @@
{
"garminConnectAuthModalTitle": "Link Garmin Connect account",
"garminConnectAuthModalUsernameLabel": "Garmin Connect email",
"garminConnectAuthModalUsernamePlaceholder": "Garmin Connect email",
"garminConnectAuthModalPasswordLabel": "Garmin Connect password",
"garminConnectAuthModalPasswordPlaceholder": "Garmin Connect password",
"garminConnectAuthModalMfaCodeLabel": "MFA code",
"garminConnectAuthModalMfaCodePlaceholder": "MFA code",
"buttonSubmitMfaCode": "Submit MFA code",
"garminConnectAuthModalLoginButton": "Login",
"processingMessageLinkGarminConnect": "Linking Garmin Connect account...",
"successMessageLinkGarminConnect": "Garmin Connect account linked",
"errorMessageUnableToLinkGarminConnect": "Unable to link Garmin Connect account"
"garminConnectAuthModalTitle": "连接 Garmin Connect 账户",
"garminConnectAuthModalUsernameLabel": "Garmin Connect 邮箱",
"garminConnectAuthModalUsernamePlaceholder": "Garmin Connect 邮箱",
"garminConnectAuthModalPasswordLabel": "Garmin Connect 密码",
"garminConnectAuthModalPasswordPlaceholder": "Garmin Connect 密码",
"garminConnectAuthModalMfaCodeLabel": "两步验证代码",
"garminConnectAuthModalMfaCodePlaceholder": "两步验证代码",
"buttonSubmitMfaCode": "提交两步验证代码",
"garminConnectAuthModalLoginButton": "登录",
"processingMessageLinkGarminConnect": "正在连接 Garmin Connect 账户……",
"successMessageLinkGarminConnect": "Garmin Connect 账户已连接",
"errorMessageUnableToLinkGarminConnect": "无法连接 Garmin Connect 账户"
}

View File

@@ -1,47 +1,47 @@
{
"stravaIntegrationTitle": "Strava",
"stravaIntegrationBody": "Strava is an American internet service for tracking physical exercise which incorporates social network features.",
"buttonConnect": "Connect",
"buttonDropdownOptions": "Options",
"modalRetrieveActivitiesByDaysTitle": "Retrieve activities by days",
"modalRetrieveActivitiesByDateRangeTitle": "Retrieve activities by date range",
"modalRetrieveActivitiesByDaysLabel": "Days",
"modalRetrieveActivitiesByDaysPlaceholder": "Days",
"modalRetrieveButton": "Retrieve",
"buttonRetrieveGear": "Retrieve gear",
"buttonRelink": "Relink",
"buttonUnlink": "Unlink",
"modalRetrieveClientIdTitle": "Connect Strava",
"modalRetrieveClientIdLabel": "Client ID",
"modalRetrieveClientSecretLabel": "Client secret",
"errorMessageUnableToLinkStrava": "Unable to link Strava account",
"errorMessageUnableToUnsetStravaClientSettings": "Unable to unset Strava client and state settings after linking error",
"successMessageStravaAccountLinked": "Strava account linked",
"errorMessageUnableToUnSetStravaState": "Unable to unset Strava state",
"errorMessageUnableToGetStravaActivities": "Unable to get Strava activities",
"errorMessageUnableToGetStravaGear": "Unable to get Strava gear",
"loadingMessageRetrievingStravaActivities": "Retrieving Strava activities",
"loadingMessageRetrievingStravaGear": "Retrieving Strava gear",
"processingMessageUnlinkStrava": "Unlinking Strava account...",
"successMessageStravaUnlinked": "Strava account unlinked",
"errorMessageUnableToUnlinkStrava": "Unable to unlink Strava account",
"modalUnlinkStravaTitle": "Unlink Strava",
"modalUnlinkStravaBody": "Are you sure you want to unlink your Strava account? Unlinking your Strava account will remove all your Strava activities and gear from Endurain.",
"stravaIntegrationBody": "Strava 是一家美国的互联网服务平台,用于记录身体锻炼,并融合了社交网络功能。",
"buttonConnect": "连接",
"buttonDropdownOptions": "选项",
"modalRetrieveActivitiesByDaysTitle": "按天获取活动数据",
"modalRetrieveActivitiesByDateRangeTitle": "按日期范围获取活动数据",
"modalRetrieveActivitiesByDaysLabel": "天数",
"modalRetrieveActivitiesByDaysPlaceholder": "请输入天数",
"modalRetrieveButton": "获取",
"buttonRetrieveGear": "获取装备数据",
"buttonRelink": "重新连接",
"buttonUnlink": "解除连接",
"modalRetrieveClientIdTitle": "连接 Strava",
"modalRetrieveClientIdLabel": "客户端 ID",
"modalRetrieveClientSecretLabel": "客户端密钥",
"errorMessageUnableToLinkStrava": "无法连接 Strava 账户",
"errorMessageUnableToUnsetStravaClientSettings": "在连接出错后无法清除 Strava 客户端和状态设置",
"successMessageStravaAccountLinked": "Strava 账户连接成功",
"errorMessageUnableToUnSetStravaState": "无法清除 Strava 状态",
"errorMessageUnableToGetStravaActivities": "无法获取 Strava 活动数据",
"errorMessageUnableToGetStravaGear": "无法获取 Strava 装备数据",
"loadingMessageRetrievingStravaActivities": "正在获取 Strava 活动数据",
"loadingMessageRetrievingStravaGear": "正在获取 Strava 装备数据",
"processingMessageUnlinkStrava": "正在解除 Strava 账户连接……",
"successMessageStravaUnlinked": "Strava 账户已解除连接",
"errorMessageUnableToUnlinkStrava": "无法解除 Strava 账户连接",
"modalUnlinkStravaTitle": "解除 Strava 连接",
"modalUnlinkStravaBody": "确定要解除 Strava 账户连接吗?解除连接后,来自 Strava 的所有活动和装备数据将从 Endurain 中删除。",
"garminConnectIntegrationTitle": "Garmin Connect",
"garminConnectIntegrationBody": "Garmin Connect is a health and fitness activity platform for users of Garmin devices",
"loadingMessageRetrievingGarminConnectActivities": "Retrieving Garmin Connect activities",
"errorMessageUnableToGetGarminConnectActivitiesDays": "Unable to get Garmin Connect activities by days",
"errorMessageUnableToGetGarminConnectActivitiesDataRange": "Unable to get Garmin Connect activities using data range",
"modalUnlinkGarminConnectTitle": "Unlink Garmin Connect",
"modalUnlinkGarminConnectBody": "Are you sure you want to unlink your Garmin Connect account?",
"processingMessageUnlinkGarminConnect": "Unlinking Garmin Connect account...",
"successMessageGarminConnectUnlinked": "Garmin Connect account unlinked",
"errorMessageUnableToUnlinkGarminConnect": "Unable to unlink Garmin Connect account",
"errorMessageUnableToGetGarminConnectGear": "Unable to get Garmin Connect gear",
"loadingMessageRetrievingGarminConnectGear": "Retrieving Garmin Connect gear",
"modalRetrieveHealthDataByDaysTitle": "Retrieve health data by days",
"modalRetrieveHealthDataByDateRangeTitle": "Retrieve health data by date range",
"errorMessageUnableToGetGarminConnectHealthDataDays": "Unable to get Garmin Connect health data by days",
"errorMessageUnableToGetGarminConnectHealthDataDateRange": "Unable to get Garmin Connect health data using date range",
"loadingMessageRetrievingGarminConnectHealthData": "Retrieving Garmin Connect health data"
"garminConnectIntegrationBody": "Garmin Connect 是 Garmin 设备用户的健康与健身活动平台",
"loadingMessageRetrievingGarminConnectActivities": "正在获取 Garmin Connect 活动数据",
"errorMessageUnableToGetGarminConnectActivitiesDays": "无法按天获取 Garmin Connect 活动数据",
"errorMessageUnableToGetGarminConnectActivitiesDataRange": "无法按日期范围获取 Garmin Connect 活动数据",
"modalUnlinkGarminConnectTitle": "解除 Garmin Connect 连接",
"modalUnlinkGarminConnectBody": "确定要解除 Garmin Connect 账户连接吗?",
"processingMessageUnlinkGarminConnect": "正在解除 Garmin Connect 账户连接……",
"successMessageGarminConnectUnlinked": "Garmin Connect 账户已解除连接",
"errorMessageUnableToUnlinkGarminConnect": "无法解除 Garmin Connect 账户连接",
"errorMessageUnableToGetGarminConnectGear": "无法获取 Garmin Connect 装备数据",
"loadingMessageRetrievingGarminConnectGear": "正在获取 Garmin Connect 装备数据",
"modalRetrieveHealthDataByDaysTitle": "按天获取健康数据",
"modalRetrieveHealthDataByDateRangeTitle": "按日期范围获取健康数据",
"errorMessageUnableToGetGarminConnectHealthDataDays": "无法按天获取 Garmin Connect 健康数据",
"errorMessageUnableToGetGarminConnectHealthDataDateRange": "无法按日期范围获取 Garmin Connect 健康数据",
"loadingMessageRetrievingGarminConnectHealthData": "正在获取 Garmin Connect 健康数据"
}

View File

@@ -1,31 +1,31 @@
{
"subtitleChangePassword": "Change password",
"changeUserPasswordBodyLabel": "Change password for user ",
"changeUserPasswordPasswordLabel": "New password",
"changeUserPasswordPasswordConfirmationLabel": "Confirm new password",
"changeUserPasswordFeedbackLabel": "Password does not meet requirements",
"changeUserPasswordPasswordsDoNotMatchFeedbackLabel": "Passwords do not match",
"subtitleMFA": "Multi-Factor Authentication (MFA)",
"mfaDisabledDescription": "MFA is currently disabled. Enable it to add an extra layer of security to your account.",
"mfaEnabledDescription": "MFA is currently enabled. Your account is protected with two-factor authentication.",
"enableMFAButton": "Enable MFA",
"disableMFAButton": "Disable MFA",
"mfaSetupModalTitle": "Setup Multi-Factor Authentication",
"mfaSetupInstructions": "Scan the QR code below with your authenticator app (Google Authenticator, Authy, etc.) or manually enter the secret:",
"mfaSecretLabel": "Secret Key",
"mfaVerificationCodeLabel": "Verification Code",
"mfaVerificationCodePlaceholder": "Enter 6-digit code",
"mfaDisableModalTitle": "Disable Multi-Factor Authentication",
"mfaDisableConfirmation": "Are you sure you want to disable MFA? This will reduce your account security.",
"mfaEnabledSuccess": "MFA enabled successfully",
"mfaDisabledSuccess": "MFA disabled successfully",
"errorLoadMFAStatus": "Error loading MFA status",
"errorSetupMFA": "Error setting up MFA",
"errorEnableMFA": "Error enabling MFA",
"errorDisableMFA": "Error disabling MFA",
"subtitleMySessions": "My sessions",
"userChangePasswordSuccessMessage": "Password changed successfully",
"userChangePasswordErrorMessage": "Error changing password",
"successDeleteSession": "Session deleted successfully",
"errorDeleteSession": "Error deleting session"
"subtitleChangePassword": "修改密码",
"changeUserPasswordBodyLabel": "为用户修改密码 ",
"changeUserPasswordPasswordLabel": "新密码",
"changeUserPasswordPasswordConfirmationLabel": "确认新密码",
"changeUserPasswordFeedbackLabel": "密码不符合要求",
"changeUserPasswordPasswordsDoNotMatchFeedbackLabel": "两次输入的密码不一致",
"subtitleMFA": "多重身份验证 (MFA)",
"mfaDisabledDescription": "当前未启用多重身份验证。启用后可为您的账户增加一层安全保护。",
"mfaEnabledDescription": "已启用多重身份验证,您的账户已通过双重验证进行保护。",
"enableMFAButton": "启用 MFA",
"disableMFAButton": "停用多重身份验证(MFA",
"mfaSetupModalTitle": "设置多重身份验证",
"mfaSetupInstructions": "使用您的身份验证应用(如 Google AuthenticatorAuthy 等)扫描下方二维码,或手动输入密钥:",
"mfaSecretLabel": "密钥",
"mfaVerificationCodeLabel": "验证码",
"mfaVerificationCodePlaceholder": "请输入 6 位验证码",
"mfaDisableModalTitle": "停用多重身份验证",
"mfaDisableConfirmation": "确定要停用多重身份验证吗?这将降低账户安全性。",
"mfaEnabledSuccess": "多重身份验证已成功启用",
"mfaDisabledSuccess": "多重身份验证已成功停用",
"errorLoadMFAStatus": "加载多重身份验证状态时出错",
"errorSetupMFA": "设置多重身份验证时出错",
"errorEnableMFA": "启用多重身份验证时出错",
"errorDisableMFA": "停用多重身份验证时出错",
"subtitleMySessions": "我的会话",
"userChangePasswordSuccessMessage": "密码修改成功",
"userChangePasswordErrorMessage": "修改密码时出错",
"successDeleteSession": "会话删除成功",
"errorDeleteSession": "删除会话时出错"
}

View File

@@ -1,29 +1,29 @@
{
"defaultsTitle": "Defaults",
"unitsLabel": "Default units",
"unitsMetric": "Metric",
"unitsImperial": "Imperial",
"currencyLabel": "Default currency",
"numRecordsLabel": "Number of records per page",
"signupTitle": "Sign-up",
"adminApprovalLabel": "Admin approval",
"emailConfirmationLabel": "Email confirmation",
"publicShareableLinksLabel": "Public shareable links",
"enabledLabel": "Enabled",
"serverSettingsPublicShareableLinksEnabledWarningAlert": "Enabling this will make all publicly posted activities viewable without authentication.",
"publicShareableLinksShowUserInfoLabel": "Show user info",
"serverSettingsPublicShareableLinksShowUserWarningAlert": "Enabling this will display user information on all public links",
"photosLabel": "Photos",
"loginPhotoLabel": "Login photo",
"buttonAddPhoto": "Add photo",
"logonPhotoAddLabel": "Login page photo (.png) with a size of 1000x1000 pixels.",
"processingPhotoUpload": "Processing photo upload",
"successPhotoUpload": "Photo uploaded successfully",
"buttonDeleteLoginPhoto": "Delete login photo",
"modalDeleteLoginPhotoBody": "Are you sure you want to delete the login photo?",
"processingPhotoDelete": "Processing photo delete",
"successPhotoDelete": "Photo deleted successfully",
"successUpdateServerSettings": "Server settings updated successfully",
"errorUpdateServerSettings": "Error updating server settings",
"errorFetchingServerSettings": "Error fetching server settings"
"defaultsTitle": "默认设置",
"unitsLabel": "默认单位制",
"unitsMetric": "公制",
"unitsImperial": "英制",
"currencyLabel": "默认货币",
"numRecordsLabel": "每页显示记录数",
"signupTitle": "注册设置",
"adminApprovalLabel": "管理员审核",
"emailConfirmationLabel": "邮箱验证",
"publicShareableLinksLabel": "公开分享链接",
"enabledLabel": "启用",
"serverSettingsPublicShareableLinksEnabledWarningAlert": "启用此选项后,所有公开发布的活动将可在未登录的情况下被查看。",
"publicShareableLinksShowUserInfoLabel": "显示用户信息",
"serverSettingsPublicShareableLinksShowUserWarningAlert": "启用此选项后,所有公开链接将显示用户信息",
"photosLabel": "图片设置",
"loginPhotoLabel": "登录页图片",
"buttonAddPhoto": "添加图片",
"logonPhotoAddLabel": "登录页图片(.png 格式,尺寸为 1000x1000 像素)。",
"processingPhotoUpload": "正在上传图片",
"successPhotoUpload": "图片上传成功",
"buttonDeleteLoginPhoto": "删除登录页图片",
"modalDeleteLoginPhotoBody": "确定要删除登录页图片吗?",
"processingPhotoDelete": "正在删除图片",
"successPhotoDelete": "图片删除成功",
"successUpdateServerSettings": "服务器设置更新成功",
"errorUpdateServerSettings": "更新服务器设置时出错",
"errorFetchingServerSettings": "获取服务器设置时出错"
}

View File

@@ -1,10 +1,10 @@
{
"usersSection": "Users",
"serverSettingsSection": "Server Settings",
"generalSection": "General",
"myProfileSection": "My Profile",
"myGoals": "My Goals",
"securitySection": "Security",
"integrationsSection": "Integrations",
"importSection": "Import"
"usersSection": "用户",
"serverSettingsSection": "服务器设置",
"generalSection": "通用设置",
"myProfileSection": "我的资料",
"myGoals": "我的目标",
"securitySection": "安全设置",
"integrationsSection": "服务集成",
"importSection": "数据导入"
}

View File

@@ -1,7 +1,7 @@
{
"addNewGoal": "Add new goal",
"labelNumberOfGoals1": "You have ",
"labelNumberOfGoals2": " goal(s) set:",
"successGoalDeleted": "Goal deleted successfully",
"errorFetchingGoals": "Error fetching goals"
"addNewGoal": "添加新的目标",
"labelNumberOfGoals1": "你有 ",
"labelNumberOfGoals2": "个目标设置:",
"successGoalDeleted": "目标删除完成",
"errorFetchingGoals": "获取目标信息时出错"
}

View File

@@ -1,89 +1,89 @@
{
"titleProfileInfo": "My profile",
"buttonDeleteProfilePhoto": "Delete",
"modalDeleteProfilePhotoBody": "Are you sure you want to delete your profile photo?",
"buttonEditProfile": "Profile",
"usernameLabel": "Username",
"emailLabel": "Email",
"cityLabel": "City",
"birthdayLabel": "Birthday",
"genderLabel": "Gender",
"genderOption1": "Male",
"genderOption2": "Female",
"genderOption3": "Unspecified",
"unitsLabel": "Units",
"unitsOption1": "Metric",
"unitsOption2": "Imperial",
"currencyLabel": "Currency",
"heightLabel": "Height",
"preferredLanguageLabel": "Preferred language",
"firstDayOfWeekLabel": "First day of week",
"accessTypeLabel": "Access type",
"accessTypeOption1": "Regular user",
"accessTypeOption2": "Administrator",
"userPhotoDeleteSuccess": "Profile photo deleted successfully",
"userPhotoDeleteError": "Error deleting profile photo",
"titleDefaultGear": "Default gear",
"subTitleShoeActivities": "Shoe activities",
"subTitleRun": "Run",
"subTitleTrailRun": "Trail run",
"subTitleVirtualRun": "Virtual run",
"subTitleWalk": "Walk",
"subTitleHike": "Hike",
"subTitleBikeActivities": "Bike activities",
"subTitleBike": "Bike",
"subTitleMTBBike": "MTB bike",
"subTitleGravelBike": "Gravel bike",
"subTitleVirtualBike": "Virtual bike",
"subTitleWaterActivities": "Water activities",
"subTitleSwim": "Open water swim",
"subTitleWindsurf": "Windsurf",
"subTitleRacquetActivities": "Racquet activities",
"subTitleTennis": "Tennis",
"subTitleSnowActivities": "Snow activities",
"subTitleAlpineSki": "Alpine ski",
"subTitleNordicSki": "Nordic ski",
"subTitleSnowboard": "Snowboard",
"selectOptionNotDefined": "Not defined",
"titlePrivacy": "Privacy",
"defaultActivityVisibility": "Default activity visibility",
"privacyOption1": "Public",
"privacyOption2": "Followers",
"privacyOption3": "Private",
"defaultActivityStartTime": "Hide activity start time",
"defaultActivityLocation": "Hide activity location",
"defaultActivityMap": "Hide activity map",
"defaultActivityHeartRate": "Hide activity heart rate",
"defaultActivityPower": "Hide activity power",
"defaultActivityCadence": "Hide activity cadence",
"defaultActivityElevation": "Hide activity elevation",
"defaultActivitySpeed": "Hide activity speed",
"defaultActivityPace": "Hide activity pace",
"defaultActivityLaps": "Hide activity laps",
"defaultActivitySetsSteps": "Hide activity sets/steps",
"defaultActivityGear": "Hide activity gear",
"buttonChangeDefaultActivityVisibility": "Change default visibility",
"buttonChangeUserActivitiesVisibility": "Change activities visibility",
"changeUserActivitiesVisibilityModalVisibilityLabel": "Visibility",
"changeUserActivitiesVisibilityModalButton": "Change",
"successUpdateUserActivitiesVisibility": "Activities visibility updated successfully",
"errorUpdateUserActivitiesVisibility": "Error updating activities visibility",
"errorUnableToGetGear": "Unable to get gear",
"errorUnableToGetDefaultGear": "Unable to get default gear",
"successUpdateDefaultGear": "Default gear updated successfully",
"errorUpdateDefaultGear": "Error updating default gear",
"successUpdateUserPrivacySettings": "User privacy settings updated successfully",
"errorUpdateUserPrivacySettings": "Error updating user privacy settings",
"titleExportData": "Export and import data",
"labelPasswordDisclaimer": "User password is not included in the import/export process. After import, update your password on security section.",
"buttonExportData": "Export data",
"buttonImportData": "Import data",
"modalImportTitle": "Import backup file",
"modalImportBody": "Select the .zip file you previously exported to restore your data.",
"exportLoading": "Exporting data, this may take a few minutes...",
"exportSuccess": "Export completed successfully",
"exportError": "Error exporting data",
"importLoading": "Importing data, this may take a few minutes...",
"importSuccess": "Import completed",
"importError": "Error importing data"
"titleProfileInfo": "我的资料",
"buttonDeleteProfilePhoto": "删除",
"modalDeleteProfilePhotoBody": "确定要删除头像吗?",
"buttonEditProfile": "编辑资料",
"usernameLabel": "用户名",
"emailLabel": "电子邮箱",
"cityLabel": "城市",
"birthdayLabel": "生日",
"genderLabel": "性別",
"genderOption1": "",
"genderOption2": "",
"genderOption3": "未指定",
"unitsLabel": "单位",
"unitsOption1": "公制",
"unitsOption2": "英制",
"currencyLabel": "货币",
"heightLabel": "身高",
"preferredLanguageLabel": "首选语言",
"firstDayOfWeekLabel": "每周的第一天",
"accessTypeLabel": "账户类型",
"accessTypeOption1": "普通用户",
"accessTypeOption2": "管理员",
"userPhotoDeleteSuccess": "头像删除成功",
"userPhotoDeleteError": "删除头像时出错",
"titleDefaultGear": "默认装备",
"subTitleShoeActivities": "跑鞋活动",
"subTitleRun": "跑步",
"subTitleTrailRun": "越野跑",
"subTitleVirtualRun": "虚拟跑",
"subTitleWalk": "步行",
"subTitleHike": "徒步",
"subTitleBikeActivities": "骑行活动",
"subTitleBike": "公路骑行",
"subTitleMTBBike": "山地骑行",
"subTitleGravelBike": "砾石骑行",
"subTitleVirtualBike": "虚拟骑行",
"subTitleWaterActivities": "水上活动",
"subTitleSwim": "公开水域游泳",
"subTitleWindsurf": "帆板运动",
"subTitleRacquetActivities": "球拍运动",
"subTitleTennis": "网球",
"subTitleSnowActivities": "雪上活动",
"subTitleAlpineSki": "高山滑雪",
"subTitleNordicSki": "越野滑雪",
"subTitleSnowboard": "单板滑雪",
"selectOptionNotDefined": "未定义",
"titlePrivacy": "隐私设置",
"defaultActivityVisibility": "默认活动可见性",
"privacyOption1": "公开",
"privacyOption2": "仅粉丝可见",
"privacyOption3": "私密",
"defaultActivityStartTime": "隐藏活动开始时间",
"defaultActivityLocation": "隐藏活动位置",
"defaultActivityMap": "隐藏活动地图",
"defaultActivityHeartRate": "隐藏心率数据",
"defaultActivityPower": "隐藏功率数据",
"defaultActivityCadence": "隐藏步频/踏频",
"defaultActivityElevation": "隐藏海拔数据",
"defaultActivitySpeed": "隐藏速度数据",
"defaultActivityPace": "隐藏配速数据",
"defaultActivityLaps": "隐藏分段数据",
"defaultActivitySetsSteps": "隐藏组数/步数",
"defaultActivityGear": "隐藏使用装备",
"buttonChangeDefaultActivityVisibility": "更改默认可见性",
"buttonChangeUserActivitiesVisibility": "更改活动可见性",
"changeUserActivitiesVisibilityModalVisibilityLabel": "可见性",
"changeUserActivitiesVisibilityModalButton": "更改",
"successUpdateUserActivitiesVisibility": "活动可见性更新成功",
"errorUpdateUserActivitiesVisibility": "更新活动可见性时出错",
"errorUnableToGetGear": "无法获取装备信息",
"errorUnableToGetDefaultGear": "无法获取默认装备",
"successUpdateDefaultGear": "默认装备更新成功",
"errorUpdateDefaultGear": "更新默认装备时出错",
"successUpdateUserPrivacySettings": "隐私设置更新成功",
"errorUpdateUserPrivacySettings": "更新隐私设置时出错",
"titleExportData": "数据导出与导入",
"labelPasswordDisclaimer": "用户密码不会包含在导入/导出过程中。导入完成后,请在安全设置中重新更新密码。",
"buttonExportData": "导出数据",
"buttonImportData": "导入数据",
"modalImportTitle": "导入备份文件",
"modalImportBody": "请选择之前导出的 .zip 文件以恢复数据。",
"exportLoading": "正在导出数据,这可能需要几分钟时间……",
"exportSuccess": "数据导出成功",
"exportError": "导出数据时出错",
"importLoading": "正在导入数据,这可能需要几分钟时间……",
"importSuccess": "数据导入完成",
"importError": "导入数据时出错"
}

View File

@@ -1,5 +1,5 @@
{
"badgeCurrentSession": "Current Session",
"modalDeleteSessionTitle": "Delete Session",
"modalDeleteSessionBody": "Are you sure you want to delete session "
"badgeCurrentSession": "当前会话",
"modalDeleteSessionTitle": "删除会话",
"modalDeleteSessionBody": "确定要删除此会话吗?"
}

View File

@@ -1,52 +1,52 @@
{
"addEditUserModalAddTitle": "Add user",
"addEditUserModalEditTitle": "Edit user",
"addEditUserModalEditProfileTitle": "Edit profile",
"addEditUserModalDeleteUserPhotoButton": "Delete photo",
"addEditUserModalUserPhotoLabel": "User photo",
"addEditUserModalUsernameLabel": "Username",
"addEditUserModalUsernamePlaceholder": "Username (max 45 characters)",
"addEditUserModalErrorUsernameExists": "Username already exists",
"addEditUserModalNameLabel": "Name",
"addEditUserModalNamePlaceholder": "Name (max 45 characters)",
"addEditUserModalEmailLabel": "Email",
"addEditUserModalEmailPlaceholder": "Email (max 45 characters)",
"addEditUserModalErrorEmailInvalid": "Email is not valid",
"addEditUserModalErrorEmailExists": "Email already exists",
"addEditUserModalPasswordLabel": "Password",
"addEditUserModalPasswordPlaceholder": "Password",
"addEditUserModalErrorPasswordInvalid": "Password does not meet requirements",
"addEditUserModalCityLabel": "City",
"addEditUserModalCityPlaceholder": "City (max 45 characters)",
"addEditUserModalBirthdayLabel": "Birthday",
"addEditUserModalGenderLabel": "Gender",
"addEditUserModalUnitsLabel": "Units",
"addEditUserModalUnitsOption1": "Metric",
"addEditUserModalUnitsOption2": "Imperial",
"addEditUserModalCurrencyLabel": "Currency",
"addEditUserModalHeightLabel": "Height",
"addEditUserModalHeightPlaceholder": "Height",
"addEditUserModalFeetValidationLabel": "Invalid height. Please enter a valid height in feet.",
"addEditUserModalInchesValidationLabel": "Invalid height. Please enter a valid height in inches.",
"addEditUserModalUserPreferredLanguageLabel": "Preferred language",
"addEditUserModalUserFirstDayOfWeekLabel": "First day of week",
"addEditUserModalUserTypeLabel": "Access type",
"addEditUserModalUserTypeOption1": "Regular user",
"addEditUserModalUserTypeOption2": "Administrator",
"addEditUserModalIsActiveLabel": "Is active",
"addEditUserModalIsActiveOption1": "Yes",
"addEditUserModalIsActiveOption2": "No",
"addEditUserModalDefaultActivityVisibilityLabel": "Default activity visibility",
"addEditUserModalDefaultActivityVisibilityOption1": "Public",
"addEditUserModalDefaultActivityVisibilityOption2": "Followers",
"addEditUserModalDefaultActivityVisibilityOption3": "Private",
"addEditUserModalErrorFetchingUserByUsername": "Error fetching user by username",
"addEditUserModalErrorFetchingUserByEmail": "Error fetching user by email",
"addEditUserModalSuccessDeleteUserPhoto": "User photo deleted successfully",
"addEditUserModalErrorDeleteUserPhoto": "Error deleting user photo",
"addEditUserModalErrorUploadingUserPhoto": "Error uploading user photo",
"addEditUserModalSuccessAddUser": "User added successfully",
"addEditUserModalErrorAddUser": "Error adding user",
"addEditUserModalSuccessEditUser": "User edited successfully",
"addEditUserModalErrorEditUser": "Error editing user"
"addEditUserModalAddTitle": "添加用户",
"addEditUserModalEditTitle": "编辑用户",
"addEditUserModalEditProfileTitle": "编辑个人资料",
"addEditUserModalDeleteUserPhotoButton": "删除照片",
"addEditUserModalUserPhotoLabel": "用户照片",
"addEditUserModalUsernameLabel": "用户名",
"addEditUserModalUsernamePlaceholder": "用户名(最大 45 个字符)",
"addEditUserModalErrorUsernameExists": "用户名已存在",
"addEditUserModalNameLabel": "姓名",
"addEditUserModalNamePlaceholder": "姓名(最大 45 个字符)",
"addEditUserModalEmailLabel": "电子邮箱",
"addEditUserModalEmailPlaceholder": "电子邮箱(最大 45 个字符)",
"addEditUserModalErrorEmailInvalid": "电子邮箱地址无效",
"addEditUserModalErrorEmailExists": "电子邮箱已经存在",
"addEditUserModalPasswordLabel": "密码",
"addEditUserModalPasswordPlaceholder": "密码",
"addEditUserModalErrorPasswordInvalid": "密码不符合要求",
"addEditUserModalCityLabel": "城市",
"addEditUserModalCityPlaceholder": "城市(最大 45 个字符)",
"addEditUserModalBirthdayLabel": "生日",
"addEditUserModalGenderLabel": "性別",
"addEditUserModalUnitsLabel": "单位",
"addEditUserModalUnitsOption1": "公制",
"addEditUserModalUnitsOption2": "英制",
"addEditUserModalCurrencyLabel": "货币",
"addEditUserModalHeightLabel": "身高",
"addEditUserModalHeightPlaceholder": "身高",
"addEditUserModalFeetValidationLabel": "身高无效。请输入以英尺为单位的有效身高。",
"addEditUserModalInchesValidationLabel": "身高无效。请输入以英寸为单位的有效身高。",
"addEditUserModalUserPreferredLanguageLabel": "首选语言",
"addEditUserModalUserFirstDayOfWeekLabel": "每周的第一天",
"addEditUserModalUserTypeLabel": "访问类型",
"addEditUserModalUserTypeOption1": "普通用户",
"addEditUserModalUserTypeOption2": "管理员",
"addEditUserModalIsActiveLabel": "活跃",
"addEditUserModalIsActiveOption1": "",
"addEditUserModalIsActiveOption2": "",
"addEditUserModalDefaultActivityVisibilityLabel": "默认活动可见性",
"addEditUserModalDefaultActivityVisibilityOption1": "公开",
"addEditUserModalDefaultActivityVisibilityOption2": "粉丝",
"addEditUserModalDefaultActivityVisibilityOption3": "私密",
"addEditUserModalErrorFetchingUserByUsername": "根据用户名获取用户时出错",
"addEditUserModalErrorFetchingUserByEmail": "根据邮箱获取用户时出错",
"addEditUserModalSuccessDeleteUserPhoto": "用户头像删除成功",
"addEditUserModalErrorDeleteUserPhoto": "删除用户头像时出错",
"addEditUserModalErrorUploadingUserPhoto": "上传用户头像时出错",
"addEditUserModalSuccessAddUser": "用户添加成功",
"addEditUserModalErrorAddUser": "添加用户时出错",
"addEditUserModalSuccessEditUser": "用户编辑成功",
"addEditUserModalErrorEditUser": "编辑用户时出错"
}

View File

@@ -1,10 +1,10 @@
{
"modalChangeUserPasswordTitle": "Change user password",
"modalChangeUserPasswordBodyLabel": "Change password for user ",
"modalChangeUserPasswordPasswordLabel": "New password",
"modalChangeUserPasswordPasswordConfirmationLabel": "Confirm new password",
"modalChangeUserPasswordFeedbackLabel": "Password does not meet requirements",
"modalChangeUserPasswordPasswordsDoNotMatchFeedbackLabel": "Passwords do not match",
"userChangePasswordSuccessMessage": "Password changed successfully",
"userChangePasswordErrorMessage": "Error changing password"
"modalChangeUserPasswordTitle": "修改用户密码",
"modalChangeUserPasswordBodyLabel": "为用户修改密码",
"modalChangeUserPasswordPasswordLabel": "新密码",
"modalChangeUserPasswordPasswordConfirmationLabel": "确认新密码",
"modalChangeUserPasswordFeedbackLabel": "密码不符合要求",
"modalChangeUserPasswordPasswordsDoNotMatchFeedbackLabel": "两次输入的密码不一致",
"userChangePasswordSuccessMessage": "密码修改成功",
"userChangePasswordErrorMessage": "修改密码时出错"
}

View File

@@ -25,4 +25,4 @@
"userIdpsLoadErrorMessage": "加载身份提供商时出错",
"userIdpDeleteSuccessMessage": "身份提供商已成功解除链接",
"userIdpDeleteErrorMessage": "解除身份提供商链接时出错"
}
}

View File

@@ -1,7 +1,7 @@
{
"passwordRequirementsTitle": "Password requirements includes:",
"passwordCharacters": "- 8 characters;",
"passwordCapitalLetters": "- 1 capital letter;",
"passwordNumbers": "- 1 number;",
"passwordSpecialCharacters": "- 1 special character;"
"passwordRequirementsTitle": "密码必须符合以下要求:",
"passwordCharacters": "- 至少 8 个字符;",
"passwordCapitalLetters": "- 至少 1 个大写字母;",
"passwordNumbers": "- 至少 1 个数字;",
"passwordSpecialCharacters": "- 至少 1 个特殊字符;"
}

View File

@@ -1,10 +1,10 @@
{
"buttonAddUser": "Add user",
"labelSearchUsersByUsername": "Search users by username",
"labelNumberOfUsers1": "There is a total of ",
"labelNumberOfUsers2": " user(s) (",
"labelNumberOfUsers3": " loaded):",
"successUserAdded": "User added successfully",
"successUserDeleted": "User deleted successfully",
"errorFetchingUsers": "Error fetching users"
"buttonAddUser": "添加用户",
"labelSearchUsersByUsername": "按用户名搜索用户",
"labelNumberOfUsers1": "共计 ",
"labelNumberOfUsers2": " 位用户(",
"labelNumberOfUsers3": " 已加载):",
"successUserAdded": "用户添加成功",
"successUserDeleted": "用户删除成功",
"errorFetchingUsers": "获取用户列表时出错"
}

View File

@@ -1,4 +1,4 @@
{
"thisWeekDistancesTitle": "Week top 3",
"thisMonthDistancesTitle": "Month top 3"
"thisWeekDistancesTitle": "周前三",
"thisMonthDistancesTitle": "月前三"
}

View File

@@ -1,13 +1,14 @@
{
"title": "Goals",
"activityTypeRun": "Run",
"activityTypeBike": "Bike",
"activityTypeSwim": "Swim",
"activityTypeWalk": "Walk",
"activityTypeStrength": "Strength",
"intervalOption1": "Daily",
"intervalOption2": "Weekly",
"intervalOption3": "Monthly",
"intervalOption4": "Yearly",
"activities": "activities"
"title": "目标",
"activityTypeRun": "跑步",
"activityTypeBike": "自行车",
"activityTypeSwim": "游泳",
"activityTypeWalk": "步行",
"activityTypeStrength": "力量",
"activityTypeCardio": "Cardio",
"intervalOption1": "每天",
"intervalOption2": "每周",
"intervalOption3": "每月",
"intervalOption4": "每年",
"activities": "活动"
}

View File

@@ -1,8 +1,8 @@
{
"title1": "Handling verify email",
"title2": "Please wait while your email is being verified. Do not refresh this page.",
"emailVerified": "Email verified successfully!",
"tokenNotFound": "Token not found",
"tokenExpired": "Token expired",
"verificationFailed": "Email verification failed"
"title1": "正在处理邮箱验证",
"title2": "正在验证您的邮箱,请稍候。请勿刷新此页面。",
"emailVerified": "邮箱验证成功!",
"tokenNotFound": "验证令牌未找到",
"tokenExpired": "验证令牌已过期",
"verificationFailed": "邮箱验证失败"
}

View File

@@ -1,31 +1,31 @@
{
"buttonAddComponent": "Add component",
"buttonEditGear": "Edit gear",
"buttonDeleteGear": "Delete gear",
"modalDeleteGearBody1": "Are you sure you want to delete gear",
"modalDeleteGearBody2": "This action cannot be undone.",
"gearIsActiveBadge": "Active",
"gearIsInactiveBadge": "Inactive",
"gearTypeOption1": "Bike",
"gearTypeOption2": "Shoes",
"gearTypeOption3": "Wetsuit",
"gearTypeOption4": "Racquet",
"gearTypeOption5": "Skis",
"gearTypeOption6": "Snowboard",
"gearTypeOption7": "Windsurf",
"gearTypeOption8": "Water sports board",
"buttonAddComponent": "添加部件",
"buttonEditGear": "编辑装备",
"buttonDeleteGear": "移除装备",
"modalDeleteGearBody1": "确定要删除此装备吗?",
"modalDeleteGearBody2": "此操作无法撤销。",
"gearIsActiveBadge": "启用中",
"gearIsInactiveBadge": "未启用",
"gearTypeOption1": "自行车",
"gearTypeOption2": "鞋子",
"gearTypeOption3": "潜水服",
"gearTypeOption4": "球拍",
"gearTypeOption5": "滑雪板",
"gearTypeOption6": "单板滑雪板",
"gearTypeOption7": "帆板",
"gearTypeOption8": "水上运动板",
"gearFromStrava": "Strava",
"gearFromGarminConnect": "Garmin Connect",
"labelBrand": "Brand",
"labelModel": "Model",
"labelPurchaseValue": "Purchase value",
"labelTotalCost": "Total cost",
"labelDistance": "Distance",
"labelTime": "Time",
"titleComponents": "Components",
"showInactiveComponents": "Show inactive",
"title": "Activities",
"successGearEdited": "Gear edited successfully",
"errorGearDelete": "Error deleting gear",
"errorFetchingGears": "Error fetching gears"
"labelBrand": "品牌",
"labelModel": "型号",
"labelPurchaseValue": "购买价格",
"labelTotalCost": "总费用",
"labelDistance": "距离",
"labelTime": "时间",
"titleComponents": "组件",
"showInactiveComponents": "显示未启用",
"title": "活动",
"successGearEdited": "装备编辑成功",
"errorGearDelete": "删除装备时出错",
"errorFetchingGears": "获取装备信息时出错"
}

View File

@@ -1,13 +1,13 @@
{
"title": "Gear",
"buttonAddGear": "Add Gear",
"subTitleSearchGearByNickname": "Search gear by nickname",
"placeholderSearchGearByNickname": "Nickname",
"buttonSearchGear": "Search Gear",
"displayUserNumberOfGears1": "There is a total of ",
"displayUserNumberOfGears2": " gear(s) (",
"displayUserNumberOfGears3": " loaded):",
"successGearDeleted": "Gear deleted successfully",
"errorGearNotFound": "Gear not found",
"errorFetchingGears": "Error fetching gears"
"title": "装备",
"buttonAddGear": "添加装备",
"subTitleSearchGearByNickname": "按昵称搜索装备",
"placeholderSearchGearByNickname": "昵称",
"buttonSearchGear": "搜索装备",
"displayUserNumberOfGears1": "共有",
"displayUserNumberOfGears2": "装备",
"displayUserNumberOfGears3": "已载入",
"successGearDeleted": "装备已成功删除",
"errorGearNotFound": "未发现装备",
"errorFetchingGears": "获取装备信息时出错"
}

View File

@@ -1,79 +1,80 @@
{
"buttonBack": "Back",
"buttonClose": "Close",
"true": "True",
"false": "False",
"yes": "Yes",
"no": "No",
"ofWithSpaces": " of ",
"languageOption1": "English (US)",
"languageOption2": "Catalan (CA)",
"languageOption3": "Portuguese (PT)",
"languageOption4": "German (DE)",
"languageOption5": "French (FR)",
"languageOption6": "Dutch (NL)",
"languageOption7": "Spanish (ES)",
"languageOption8": "Chinese (Simplified)",
"languageOption9": "Chinese (Traditional)",
"languageOption10": "Galician (GL)",
"languageOption11": "Italian (IT)",
"firstDayOfWeekOption0": "Sunday",
"firstDayOfWeekOption1": "Monday",
"firstDayOfWeekOption2": "Tuesday",
"firstDayOfWeekOption3": "Wednesday",
"firstDayOfWeekOption4": "Thursday",
"firstDayOfWeekOption5": "Friday",
"firstDayOfWeekOption6": "Saturday",
"buttonlistAll": "List all",
"requiredField": "Required fields",
"labelNotApplicable": "N/A",
"labelNoData": "No data",
"unitsCm": "cm",
"unitsCms": "cms",
"unitsM": "m",
"unitsKm": "km",
"unitsKmH": "km/h",
"unitsKg": "kg",
"labelWeightInKg": "Weight in kg",
"unitsInches": "inches",
"unitsFeet": "feet",
"unitsFeetShort": "ft",
"unitsFeetInches": "feet, inches",
"unitsMiles": "mi",
"unitsYards": "yd",
"unitsMph": "mph",
"unitsLbs": "lbs",
"labelWeightInLbs": "Weight in lbs",
"unitsCalories": "kcal",
"unitsBpm": "bpm",
"labelHRinBpm": "Heart rate in bpm",
"unitsWattsShort": "W",
"labelPowerInWatts": "Power in watts",
"labelCadenceInRpm": "Cadence in rpm",
"unitsSpm": "spm",
"labelElevationInMeters": "Elevation in meters",
"labelElevationInFeet": "Elevation in feet",
"labelVelocityInKmH": "Speed in km/h",
"labelVelocityInMph": "Speed in mph",
"labelPaceInMinKm": "Pace in min/km",
"labelPaceInMin100m": "Pace in min/100m",
"labelPaceInMinMile": "Pace in min/mile",
"labelPaceInMin100yd": "Pace in min/100yd",
"labelLaps": "Laps",
"labelRest": "Rest",
"labelStrokeRateInSpm": "Stroke rate in spm",
"startDateLabel": "Start date",
"endDateLabel": "End date",
"cancel": "Cancel",
"loading": "Loading",
"betaTag": " (Beta)",
"currencyEuro": "Euro",
"buttonBack": "返回",
"buttonClose": "关闭",
"true": "",
"false": "",
"yes": "",
"no": "",
"ofWithSpaces": "",
"languageOption1": "英语(美国)",
"languageOption2": "加泰罗尼亚语",
"languageOption3": "葡萄牙语",
"languageOption4": "德语",
"languageOption5": "法语",
"languageOption6": "荷兰语",
"languageOption7": "西班牙语",
"languageOption8": "中文(简体)",
"languageOption9": "中文(繁体)",
"languageOption10": "加利西亚语",
"languageOption11": "意大利语",
"languageOption12": "Slovenian (SL)",
"firstDayOfWeekOption0": "星期日",
"firstDayOfWeekOption1": "星期一",
"firstDayOfWeekOption2": "星期二",
"firstDayOfWeekOption3": "星期三",
"firstDayOfWeekOption4": "星期四",
"firstDayOfWeekOption5": "星期五",
"firstDayOfWeekOption6": "星期六",
"buttonlistAll": "列出全部",
"requiredField": "必填字段",
"labelNotApplicable": "不适用",
"labelNoData": "无数据",
"unitsCm": "厘米",
"unitsCms": "厘米",
"unitsM": "",
"unitsKm": "公里",
"unitsKmH": "公里/小时",
"unitsKg": "千克",
"labelWeightInKg": "体重(千克)",
"unitsInches": "英寸",
"unitsFeet": "英尺",
"unitsFeetShort": "英尺",
"unitsFeetInches": "英尺,英寸",
"unitsMiles": "英里",
"unitsYards": "",
"unitsMph": "英里/小时",
"unitsLbs": "磅",
"labelWeightInLbs": "体重(磅)",
"unitsCalories": "卡路里",
"unitsBpm": "次/分钟",
"labelHRinBpm": "心率(次/分)",
"unitsWattsShort": "瓦",
"labelPowerInWatts": "功率(瓦)",
"labelCadenceInRpm": "踏频(转/分)",
"unitsSpm": "步/分",
"labelElevationInMeters": "海拔(米)",
"labelElevationInFeet": "海拔(英尺)",
"labelVelocityInKmH": "速度(千米/小时)",
"labelVelocityInMph": "速度(英里/小时)",
"labelPaceInMinKm": "配速(分/公里)",
"labelPaceInMin100m": "配速(分/100 米)",
"labelPaceInMinMile": "配速(分/英里)",
"labelPaceInMin100yd": "配速(分/100 码)",
"labelLaps": "圈数",
"labelRest": "休息",
"labelStrokeRateInSpm": "划频(次/分)",
"startDateLabel": "开始日期",
"endDateLabel": "结束日期",
"cancel": "取消",
"loading": "正在加载",
"betaTag": " (测试版)",
"currencyEuro": "欧元",
"currencyEuroSymbol": "€",
"currencyDollar": "US Dollar",
"currencyDollar": "美元",
"currencyDollarSymbol": "$",
"currencyPound": "British Pound",
"currencyPound": "英镑",
"currencyPoundSymbol": "£",
"genderMale": "Male",
"genderFemale": "Female",
"genderUnspecified": "Unspecified"
"genderMale": "",
"genderFemale": "",
"genderUnspecified": "未指定"
}

View File

@@ -1,18 +1,18 @@
{
"title": "Endurain",
"buttonAddActivity": "Add Activity",
"fieldLabelUploadFileType": "Upload .gpx, .fit, .tcx or .gz file",
"radioUserActivities": "My activities",
"radioFollowerActivities": "Followers activities",
"pillIsHidden": "Hidden",
"successActivityAdded": "Activity added successfully",
"errorActivityAdded": "Error adding activity",
"refreshingActivities": "Refreshing activities from linked services",
"successActivitiesRefreshed": "Activities refreshed successfully",
"errorActivityNotFound": "Activity not found",
"processingActivity": "Processing activity",
"successActivityDeleted": "Activity deleted successfully",
"errorFetchingUserStats": "Error fetching user stats",
"errorFetchingUserActivities": "Error fetching user activities",
"errorFetchingMedia": "Error fetching media for activity"
"buttonAddActivity": "添加活动",
"fieldLabelUploadFileType": "上传 .gpx.fit.tcx .gz 文件",
"radioUserActivities": "我的活动",
"radioFollowerActivities": "粉丝活动",
"pillIsHidden": "隐藏",
"successActivityAdded": "活动添加成功",
"errorActivityAdded": "活动添加失败",
"refreshingActivities": "正在从已关联的第三方服务刷新(或同步)活动数据",
"successActivitiesRefreshed": "活动数据已成功刷新完成",
"errorActivityNotFound": "未找到活动",
"processingActivity": "正在处理活动",
"successActivityDeleted": "活动删除成功",
"errorFetchingUserStats": "获取用户统计数据时出错",
"errorFetchingUserActivities": "获取用户活动列表(运动记录)失败",
"errorFetchingMedia": "获取活动关联的媒体(图片、视频、地图快照)失败"
}

View File

@@ -5,7 +5,7 @@
"error403": "你没有权限访问该资源",
"error500": "无法连接到服务器。请稍后再试",
"errorUndefined": "无法连接到服务器。请稍后再试",
"subtitle": "Sign-in below",
"subtitle": "在下方登录",
"username": "用户名",
"password": "密码",
"mfaCode": "两步验证代码",

View File

@@ -20,6 +20,7 @@
"searchSelectActivityType14": "冲浪",
"searchSelectActivityType15": "滑冰",
"searchSelectActivityType16": "足球",
"searchSelectActivityType17": "Cardio",
"searchSelectGearType0": "全部",
"searchSelectGearType1": "自行车",
"searchSelectGearType2": "鞋子",

View File

@@ -1,3 +1,3 @@
{
"title": "Settings"
"title": "设置"
}

View File

@@ -1,33 +1,33 @@
{
"title": "Sign up",
"subtitle": "Create your account below",
"name": "Full name",
"username": "Username",
"email": "Email address",
"password": "Password",
"optionalFields": " Optional fields",
"preferredLanguage": "Preferred language",
"city": "City",
"birthdate": "Birth date",
"gender": "Gender",
"units": "Units",
"metric": "Metric",
"imperial": "Imperial",
"height": "Height",
"firstDayOfWeek": "First day of week",
"currency": "Currency",
"signUpButton": "Create account",
"alreadyHaveAccount": "Already have an account? Sign in",
"success": "Sign-up successful",
"errorNameRequired": "Full name is required",
"errorUsernameRequired": "Username is required",
"errorEmailRequired": "Email address is required",
"errorEmailInvalid": "Please enter a valid email address",
"errorPasswordRequired": "Password is required",
"errorPasswordTooShort": "Password must be at least 8 characters long",
"errorUserExists": "A user with this email or username already exists",
"errorSignupDisabled": "Sign-up is not enabled on this server",
"errorValidation": "Please check your input and try again",
"errorGeneral": "An error occurred during sign-up",
"signupDisabled": "User sign-up is not enabled on this server"
"title": "注册",
"subtitle": "请在下方创建您的账户",
"name": "姓名",
"username": "用户名",
"email": "电子邮箱",
"password": "密码",
"optionalFields": "可选项",
"preferredLanguage": "首选语言",
"city": "城市",
"birthdate": "出生日期",
"gender": "性別",
"units": "单位",
"metric": "公制",
"imperial": "英制",
"height": "身高",
"firstDayOfWeek": "每周的第一天",
"currency": "货币",
"signUpButton": "创建帐户",
"alreadyHaveAccount": "已有账户?请登录",
"success": "注册成功",
"errorNameRequired": "姓名为必填项",
"errorUsernameRequired": "用户名为必填项",
"errorEmailRequired": "电子邮箱为必填项",
"errorEmailInvalid": "请输入有效的电子邮箱地址",
"errorPasswordRequired": "密码为必填项",
"errorPasswordTooShort": "密码长度至少为 8 个字符",
"errorUserExists": "该邮箱或用户名已被使用",
"errorSignupDisabled": "此服务器未启用注册功能",
"errorValidation": "请检查您的输入后重试",
"errorGeneral": "注册过程中发生错误",
"signupDisabled": "此服务器未启用用户注册功能"
}

View File

@@ -1,4 +1,4 @@
{
"stravaCallbackViewTitle1": "Handling Strava callback",
"stravaCallbackViewTitle2": "Please wait while Strava is being linked to your account. Do not refresh this page."
"stravaCallbackViewTitle1": "正在处理 Strava 回调",
"stravaCallbackViewTitle2": "请稍候,正在将 Strava 账户与您的账户关联。请不要刷新此页面。"
}

View File

@@ -1,44 +1,44 @@
{
"title": "Activity summary",
"filterLabelActivityType": "Type",
"filterOptionAllTypes": "All types",
"labelViewType": "View by",
"optionDaily": "Daily",
"optionWeekly": "Weekly",
"optionMonthly": "Monthly",
"optionYearly": "Yearly",
"optionLifetime": "Lifetime",
"labelSelectWeek": "Week",
"labelSelectMonth": "Month",
"labelSelectYear": "Year",
"labelSelectPeriod": "Period",
"buttonPreviousPeriod": "Previous",
"buttonNextPeriod": "Next",
"headerSummaryFor": "Summary for {period}",
"headerBreakdown": "Breakdown",
"headerActivitiesInPeriod": "Activities in period",
"errorLoadingActivityTypes": "Error loading activity types",
"errorLoadingSummary": "Error loading summary",
"errorLoadingSummaryLoad": "Error loading summary on page load",
"errorFetchingActivities": "Error fetching activities",
"noDataForPeriod": "No data for this period.",
"colDay": "Day",
"colWeekNum": "Week #",
"colMonth": "Month",
"colDistance": "Distance",
"colDuration": "Duration",
"colElevation": "Elevation",
"colCalories": "Calories",
"colActivities": "Activities",
"metricTotalDistance": "Total distance",
"metricTotalDuration": "Total duration",
"metricTotalElevation": "Total elevation",
"metricTotalCalories": "Total calories",
"metricTotalActivities": "Total activities",
"invalidYearSelected": "Invalid year selected",
"headerTypeBreakdown": "Breakdown by type",
"colActivityType": "Type",
"headerYear": "Year {year}",
"headerWeekStarting": "Week of {date}",
"colYear": "Year"
"title": "活动摘要",
"filterLabelActivityType": "类型",
"filterOptionAllTypes": "所有类型",
"labelViewType": "查看方式",
"optionDaily": "每天",
"optionWeekly": "每周",
"optionMonthly": "每月",
"optionYearly": "每年",
"optionLifetime": "终生",
"labelSelectWeek": "",
"labelSelectMonth": "",
"labelSelectYear": "",
"labelSelectPeriod": "周期",
"buttonPreviousPeriod": "上一个",
"buttonNextPeriod": "下一个",
"headerSummaryFor": "{period} 摘要",
"headerBreakdown": "明细",
"headerActivitiesInPeriod": "所述期间的活动",
"errorLoadingActivityTypes": "加载活动类型时出错",
"errorLoadingSummary": "加载摘要出错",
"errorLoadingSummaryLoad": "在页面加载时加载摘要出错",
"errorFetchingActivities": "获取活动时出错",
"noDataForPeriod": "此期间没有数据",
"colDay": "",
"colWeekNum": "",
"colMonth": "",
"colDistance": "距离",
"colDuration": "经过时间",
"colElevation": "海拔",
"colCalories": "卡路里",
"colActivities": "活动",
"metricTotalDistance": "总距离",
"metricTotalDuration": "总时长",
"metricTotalElevation": "总海拔",
"metricTotalCalories": "总卡路里",
"metricTotalActivities": "总活动",
"invalidYearSelected": "选定的年份无效",
"headerTypeBreakdown": "按类型分类",
"colActivityType": "类型",
"headerYear": "{year}",
"headerWeekStarting": "{date}",
"colYear": ""
}

View File

@@ -1,32 +1,32 @@
{
"thisMonthActivitiesNumber": "This month activities",
"userFollowing": "Following",
"userFollowers": "Followers",
"navigationActivities": "Activities",
"navigationFollowing": "Following",
"navigationFollowers": "Followers",
"navigationUserSettings": "User settings",
"navigationFollow": "Follow",
"modalFollowUserTitle": "Follow user",
"modalFollowUserBody": "Are you sure you want to follow user ",
"errorUnableToSendFollow": "Unable to send follow request to user",
"successFollowRequestSent": "Follow request sent",
"navigationRequestSent": "Request sent",
"modalCancelFollowRequestTitle": "Cancel follow request",
"modalCancelFollowRequestBody": "Are you sure you want to cancel follow request for user ",
"errorUnableToCancelFollowRequest": "Unable to cancel follow request for user",
"successFollowRequestCancelled": "Follow request cancelled",
"navigationUnfollow": "Unfollow",
"modalUnfollowUserTitle": "Unfollow user",
"modalUnfollowUserBody": "Are you sure you want to unfollow user ",
"errorUnableToUnfollow": "Unable to unfollow user",
"successUserUnfollowed": "User unfollowed",
"activitiesPaginationWeek0": "This week",
"activitiesPaginationWeek51": "One year ago",
"successFollowingDeleted": "Following deleted",
"successFollowerDeleted": "Follower deleted",
"successFollowerAccepted": "Follower accepted",
"errorFetchingUserStats": "Error fetching user stats",
"errorFetchingUserFollowers": "Error fetching user followers",
"errorFetchingUserActivities": "Error fetching user activities"
"thisMonthActivitiesNumber": "本月动态",
"userFollowing": "关注的人",
"userFollowers": "粉丝",
"navigationActivities": "活动",
"navigationFollowing": "关注的人",
"navigationFollowers": "粉丝",
"navigationUserSettings": "用户设置",
"navigationFollow": "关注",
"modalFollowUserTitle": "关注用户",
"modalFollowUserBody": "您确定要关注该用户吗 ",
"errorUnableToSendFollow": "无法向该用户发送关注请求",
"successFollowRequestSent": "关注请求已发送",
"navigationRequestSent": "请求已发送",
"modalCancelFollowRequestTitle": "取消关注请求",
"modalCancelFollowRequestBody": "您确定要取消对该用户的关注请求吗?",
"errorUnableToCancelFollowRequest": "无法取消对该用户的关注请求",
"successFollowRequestCancelled": "关注请求已取消",
"navigationUnfollow": "取消关注",
"modalUnfollowUserTitle": "取消关注该用户",
"modalUnfollowUserBody": "您确定要取消关注该用户吗 ",
"errorUnableToUnfollow": "无法取消关注该用户",
"successUserUnfollowed": "已取消关注",
"activitiesPaginationWeek0": "这周",
"activitiesPaginationWeek51": "一年前",
"successFollowingDeleted": "关注列表中的用户已删除",
"successFollowerDeleted": "粉丝已移除",
"successFollowerAccepted": "关注请求已通过",
"errorFetchingUserStats": "获取用户统计数据失败",
"errorFetchingUserFollowers": "获取用户粉丝列表失败",
"errorFetchingUserActivities": "获取用户动态失败"
}

View File

@@ -39,5 +39,6 @@
"soccer": "Soccer",
"padel": "Padel",
"treadmillRun": "Treadmill run",
"cardioTraining": "Cardio training",
"labelWorkout": " Workout"
}
}

View File

@@ -43,10 +43,11 @@
"modalEditActivityTypeOption34": "Laufbahnlauf",
"modalEditActivityTypeOption35": "E-Bike Fahrt",
"modalEditActivityTypeOption36": "E-MTB Fahrt",
"modalEditActivityTypeOption37": "Ice skate",
"modalEditActivityTypeOption38": "Soccer",
"modalEditActivityTypeOption37": "Eislaufen",
"modalEditActivityTypeOption38": "Fussball",
"modalEditActivityTypeOption39": "Padel",
"modalEditActivityTypeOption40": "Treadmill run",
"modalEditActivityTypeOption40": "Laufbandlauf",
"modalEditActivityTypeOption41": "Cardio training",
"modalEditActivityVisibilityLabel": "Sichtbarkeit",
"modalEditActivityVisibilityOption0": "Öffentlich",
"modalEditActivityVisibilityOption1": "Follower",
@@ -66,4 +67,4 @@
"modalEditActivityHideGearLabel": "Ausrüstung ausblenden",
"successActivityEdit": "Aktivität erfolgreich bearbeitet",
"errorActivityEdit": "Fehler beim Bearbeiten der Aktivität"
}
}

View File

@@ -1,18 +1,18 @@
{
"bulkImportIntegrationTitle": "Bulk import",
"bulkImportIntegrationBody": "Massenimport von Aktivitäten aus Dateien (die im Ordner activity_files/bulk_import-Ordner gespeichert sind)",
"buttonBulkImport": "Import activities",
"loadingMessageBulkImport": "Importing activities from files...",
"errorMessageUnableToImportActivities": "An error occurred while importing activities",
"importTitle": "Import",
"stravaGearImportTitle": "Strava gear import",
"stravaGearImportBody": "Importiere Ausrüstung aus einem Strava Bulk Export (in den Daten/activity_files/bulk_import Ordner)",
"stravaGearImportbuttonBikes": "Import Strava bikes",
"loadingMessageStravaBikesImport": "Importing Strava bikes from file...",
"successMessageStravaBikesImport": "Strava bikes imported successfully",
"errorMessageUnableToImportBikes": "An error occurred while importing Strava bikes",
"stravaImportbuttonShoes": "Import Strava shoes",
"loadingMessageStravaShoesImport": "Importing Strava shoes from file...",
"successMessageStravaShoesImport": "Strava shoes imported successfully",
"errorMessageUnableToImportShoes": "An error occurred while importing Strava shoes"
"bulkImportIntegrationTitle": "Bulk import",
"bulkImportIntegrationBody": "Massenimport von Aktivitäten aus Dateien (die im Ordner activity_files/bulk_import-Ordner gespeichert sind)",
"buttonBulkImport": "Import activities",
"loadingMessageBulkImport": "Importing activities from files...",
"errorMessageUnableToImportActivities": "An error occurred while importing activities",
"importTitle": "Import",
"stravaGearImportTitle": "Strava gear import",
"stravaGearImportBody": "Importiere Ausrüstung aus einem Strava Bulk Export (in den Daten/activity_files/bulk_import Ordner)",
"stravaGearImportbuttonBikes": "Import Strava bikes",
"loadingMessageStravaBikesImport": "Importing Strava bikes from file...",
"successMessageStravaBikesImport": "Strava bikes imported successfully",
"errorMessageUnableToImportBikes": "An error occurred while importing Strava bikes",
"stravaImportbuttonShoes": "Import Strava shoes",
"loadingMessageStravaShoesImport": "Importing Strava shoes from file...",
"successMessageStravaShoesImport": "Strava shoes imported successfully",
"errorMessageUnableToImportShoes": "An error occurred while importing Strava shoes"
}

View File

@@ -5,6 +5,7 @@
"activityTypeSwim": "Schwimmen",
"activityTypeWalk": "Gehen",
"activityTypeStrength": "Kraftsport",
"activityTypeCardio": "Cardio",
"intervalOption1": "Täglich",
"intervalOption2": "Wöchentlich",
"intervalOption3": "Monatlich",

View File

@@ -13,10 +13,11 @@
"languageOption5": "Französisch (FR)",
"languageOption6": "Niederländisch (NL)",
"languageOption7": "Spanisch (ES)",
"languageOption8": "Chinese (Simplified)",
"languageOption9": "Chinese (Traditional)",
"languageOption8": "Chinesisch (vereinfacht)",
"languageOption9": "Chinesisch (traditionell)",
"languageOption10": "Galician (GL)",
"languageOption11": "Italienisch (IT)",
"languageOption12": "Slovenian (SL)",
"firstDayOfWeekOption0": "Sonntag",
"firstDayOfWeekOption1": "Montag",
"firstDayOfWeekOption2": "Dienstag",
@@ -73,7 +74,7 @@
"currencyDollarSymbol": "$",
"currencyPound": "Britisches Pfund",
"currencyPoundSymbol": "£",
"genderMale": "Male",
"genderFemale": "Female",
"genderUnspecified": "Unspecified"
"genderMale": "Männlich",
"genderFemale": "Weiblich",
"genderUnspecified": "Keine Angabe"
}

View File

@@ -30,7 +30,7 @@
"forgotPasswordModalRequestError": "Anfrage zur Passwortzurücksetzung konnte nicht verarbeitet werden",
"forgotPasswordModalEmailNotConfigured": "Der E-Mail-Dienst ist nicht konfiguriert. Bitte wenden Sie sich an den Administrator",
"forgotPasswordModalUnableToSendEmail": "E-Mail kann nicht gesendet werden. Bitte versuchen Sie es später erneut oder wenden Sie sich an den Administrator",
"signUpLink": "Don't have an account? Sign up",
"signUpLink": "Kein Konto? Jetzt registrieren",
"emailVerificationSent": "Please check your email for verification instructions",
"adminApprovalRequired": "Your account is pending admin approval",
"verifyEmailInvalidLink": "Invalid email verification link"

View File

@@ -20,6 +20,7 @@
"searchSelectActivityType14": "Surfen",
"searchSelectActivityType15": "Ice skate",
"searchSelectActivityType16": "Soccer",
"searchSelectActivityType17": "Cardio",
"searchSelectGearType0": "Alle",
"searchSelectGearType1": "Fahrrad",
"searchSelectGearType2": "Schuhe",

View File

@@ -39,5 +39,6 @@
"soccer": "Soccer",
"padel": "Padel",
"treadmillRun": "Treadmill run",
"cardioTraining": "Cardio training",
"labelWorkout": " entrenamiento"
}
}

View File

@@ -47,6 +47,7 @@
"modalEditActivityTypeOption38": "Soccer",
"modalEditActivityTypeOption39": "Padel",
"modalEditActivityTypeOption40": "Treadmill run",
"modalEditActivityTypeOption41": "Cardio training",
"modalEditActivityVisibilityLabel": "Visibilidad",
"modalEditActivityVisibilityOption0": "Público",
"modalEditActivityVisibilityOption1": "Seguidores",
@@ -66,4 +67,4 @@
"modalEditActivityHideGearLabel": "Ocultar equipo",
"successActivityEdit": "Actividad editada correctamente",
"errorActivityEdit": "Error al editar actividad"
}
}

View File

@@ -1,18 +1,18 @@
{
"bulkImportIntegrationTitle": "Bulk import",
"bulkImportIntegrationBody": "Bulk import activities from files (in the data/activity_files/bulk_import folder)",
"buttonBulkImport": "Import activities",
"loadingMessageBulkImport": "Importing activities from files...",
"errorMessageUnableToImportActivities": "An error occurred while importing activities",
"importTitle": "Import",
"stravaGearImportTitle": "Strava gear import",
"stravaGearImportBody": "Import gear from a Strava bulk export (in the data/activity_files/bulk_import folder)",
"stravaGearImportbuttonBikes": "Import Strava bikes",
"loadingMessageStravaBikesImport": "Importing Strava bikes from file...",
"successMessageStravaBikesImport": "Strava bikes imported successfully",
"errorMessageUnableToImportBikes": "An error occurred while importing Strava bikes",
"stravaImportbuttonShoes": "Import Strava shoes",
"loadingMessageStravaShoesImport": "Importing Strava shoes from file...",
"successMessageStravaShoesImport": "Strava shoes imported successfully",
"errorMessageUnableToImportShoes": "An error occurred while importing Strava shoes"
"bulkImportIntegrationTitle": "Bulk import",
"bulkImportIntegrationBody": "Bulk import activities from files (in the data/activity_files/bulk_import folder)",
"buttonBulkImport": "Import activities",
"loadingMessageBulkImport": "Importing activities from files...",
"errorMessageUnableToImportActivities": "An error occurred while importing activities",
"importTitle": "Import",
"stravaGearImportTitle": "Strava gear import",
"stravaGearImportBody": "Import gear from a Strava bulk export (in the data/activity_files/bulk_import folder)",
"stravaGearImportbuttonBikes": "Import Strava bikes",
"loadingMessageStravaBikesImport": "Importing Strava bikes from file...",
"successMessageStravaBikesImport": "Strava bikes imported successfully",
"errorMessageUnableToImportBikes": "An error occurred while importing Strava bikes",
"stravaImportbuttonShoes": "Import Strava shoes",
"loadingMessageStravaShoesImport": "Importing Strava shoes from file...",
"successMessageStravaShoesImport": "Strava shoes imported successfully",
"errorMessageUnableToImportShoes": "An error occurred while importing Strava shoes"
}

View File

@@ -5,6 +5,7 @@
"activityTypeSwim": "Swim",
"activityTypeWalk": "Walk",
"activityTypeStrength": "Strength",
"activityTypeCardio": "Cardio",
"intervalOption1": "Daily",
"intervalOption2": "Weekly",
"intervalOption3": "Monthly",

Some files were not shown because too many files have changed in this diff Show More