diff --git a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/camera_control.kt b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/camera_control.kt index a6fb39a67..485493458 100644 --- a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/camera_control.kt +++ b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/camera_control.kt @@ -1,6 +1,3 @@ -/* camera_control.kt/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). */ -/* This copyright was auto-generated on Wed Sep 24 20:06:50 UTC 2025 */ - @file:OptIn(pbandk.PublicForGeneratedCode::class) package com.gopro.open_gopro.operations diff --git a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/cohn.kt b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/cohn.kt index b9e6ab202..98f1e20ea 100644 --- a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/cohn.kt +++ b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/cohn.kt @@ -1,6 +1,3 @@ -/* cohn.kt/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). */ -/* This copyright was auto-generated on Wed Sep 24 20:06:50 UTC 2025 */ - @file:OptIn(pbandk.PublicForGeneratedCode::class) package com.gopro.open_gopro.operations diff --git a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/live_streaming.kt b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/live_streaming.kt index 99eeb67f2..3c39b7dac 100644 --- a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/live_streaming.kt +++ b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/live_streaming.kt @@ -1,6 +1,3 @@ -/* live_streaming.kt/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). */ -/* This copyright was auto-generated on Wed Sep 24 20:06:50 UTC 2025 */ - @file:OptIn(pbandk.PublicForGeneratedCode::class) package com.gopro.open_gopro.operations diff --git a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/media.kt b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/media.kt index d003c96f4..b7b93481b 100644 --- a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/media.kt +++ b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/media.kt @@ -1,6 +1,3 @@ -/* media.kt/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). */ -/* This copyright was auto-generated on Wed Sep 24 20:06:50 UTC 2025 */ - @file:OptIn(pbandk.PublicForGeneratedCode::class) package com.gopro.open_gopro.operations diff --git a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/network_management.kt b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/network_management.kt index 71cdb60e8..3e44e5865 100644 --- a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/network_management.kt +++ b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/network_management.kt @@ -1,6 +1,3 @@ -/* network_management.kt/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). */ -/* This copyright was auto-generated on Wed Sep 24 20:06:50 UTC 2025 */ - @file:OptIn(pbandk.PublicForGeneratedCode::class) package com.gopro.open_gopro.operations diff --git a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/preset_status.kt b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/preset_status.kt index e5f45fa8f..d7a9632f5 100644 --- a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/preset_status.kt +++ b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/preset_status.kt @@ -1,6 +1,3 @@ -/* preset_status.kt/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). */ -/* This copyright was auto-generated on Wed Sep 24 20:06:50 UTC 2025 */ - @file:OptIn(pbandk.PublicForGeneratedCode::class) package com.gopro.open_gopro.operations @@ -118,12 +115,18 @@ public sealed class EnumPresetGroup(override val value: Int, override val name: internal object PRESET_GROUP_ID_TIMELAPSE : EnumPresetGroup(1002, "PRESET_GROUP_ID_TIMELAPSE") + internal object PRESET_GROUP_ID_GENERAL : EnumPresetGroup(2000, "PRESET_GROUP_ID_GENERAL") + internal class UNRECOGNIZED(value: Int) : EnumPresetGroup(value) internal companion object : pbandk.Message.Enum.Companion { internal val values: List by lazy { - listOf(PRESET_GROUP_ID_VIDEO, PRESET_GROUP_ID_PHOTO, PRESET_GROUP_ID_TIMELAPSE) + listOf( + PRESET_GROUP_ID_VIDEO, + PRESET_GROUP_ID_PHOTO, + PRESET_GROUP_ID_TIMELAPSE, + PRESET_GROUP_ID_GENERAL) } override fun fromValue(value: Int): com.gopro.open_gopro.operations.EnumPresetGroup = @@ -1152,6 +1155,8 @@ public data class PresetGroup( val canAddPreset: Boolean? = null, val icon: com.gopro.open_gopro.operations.EnumPresetGroupIcon? = null, val modeArray: List = emptyList(), + val customName: String? = null, + val activePresetId: Int? = null, override val unknownFields: Map = emptyMap() ) : pbandk.Message { override operator fun plus(other: pbandk.Message?): com.gopro.open_gopro.operations.PresetGroup = @@ -1177,7 +1182,7 @@ public data class PresetGroup( messageClass = com.gopro.open_gopro.operations.PresetGroup::class, messageCompanion = this, fields = - buildList(5) { + buildList(7) { add( pbandk.FieldDescriptor( messageDescriptor = this@Companion::descriptor, @@ -1239,6 +1244,22 @@ public data class PresetGroup( .Companion)), jsonName = "modeArray", value = com.gopro.open_gopro.operations.PresetGroup::modeArray)) + add( + pbandk.FieldDescriptor( + messageDescriptor = this@Companion::descriptor, + name = "custom_name", + number = 6, + type = pbandk.FieldDescriptor.Type.Primitive.String(hasPresence = true), + jsonName = "customName", + value = com.gopro.open_gopro.operations.PresetGroup::customName)) + add( + pbandk.FieldDescriptor( + messageDescriptor = this@Companion::descriptor, + name = "active_preset_id", + number = 7, + type = pbandk.FieldDescriptor.Type.Primitive.Int32(hasPresence = true), + jsonName = "activePresetId", + value = com.gopro.open_gopro.operations.PresetGroup::activePresetId)) }) } } @@ -1502,6 +1523,8 @@ private fun PresetGroup.protoMergeImpl(plus: pbandk.Message?): PresetGroup = canAddPreset = plus.canAddPreset ?: canAddPreset, icon = plus.icon ?: icon, modeArray = modeArray + plus.modeArray, + customName = plus.customName ?: customName, + activePresetId = plus.activePresetId ?: activePresetId, unknownFields = unknownFields + plus.unknownFields) } ?: this @@ -1512,6 +1535,8 @@ private fun PresetGroup.Companion.decodeWithImpl(u: pbandk.MessageDecoder): Pres var canAddPreset: Boolean? = null var icon: com.gopro.open_gopro.operations.EnumPresetGroupIcon? = null var modeArray: pbandk.ListWithSize.Builder? = null + var customName: String? = null + var activePresetId: Int? = null val unknownFields = u.readMessage(this) { _fieldNumber, _fieldValue -> @@ -1534,6 +1559,8 @@ private fun PresetGroup.Companion.decodeWithImpl(u: pbandk.MessageDecoder): Pres as kotlin.sequences.Sequence } + 6 -> customName = _fieldValue as String + 7 -> activePresetId = _fieldValue as Int } } @@ -1543,6 +1570,8 @@ private fun PresetGroup.Companion.decodeWithImpl(u: pbandk.MessageDecoder): Pres canAddPreset, icon, pbandk.ListWithSize.Builder.fixed(modeArray), + customName, + activePresetId, unknownFields) } diff --git a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/request_get_camera_capabilities.kt b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/request_get_camera_capabilities.kt new file mode 100644 index 000000000..f197824d7 --- /dev/null +++ b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/request_get_camera_capabilities.kt @@ -0,0 +1,248 @@ +@file:OptIn(pbandk.PublicForGeneratedCode::class) + +package com.gopro.open_gopro.operations + +@pbandk.Export +internal data class RequestGetCameraCapabilities( + override val unknownFields: Map = emptyMap() +) : pbandk.Message { + override operator fun plus( + other: pbandk.Message? + ): com.gopro.open_gopro.operations.RequestGetCameraCapabilities = protoMergeImpl(other) + + override val descriptor: + pbandk.MessageDescriptor + get() = Companion.descriptor + + override val protoSize: Int by lazy { super.protoSize } + + internal companion object : + pbandk.Message.Companion { + internal val defaultInstance: + com.gopro.open_gopro.operations.RequestGetCameraCapabilities by lazy { + com.gopro.open_gopro.operations.RequestGetCameraCapabilities() + } + + override fun decodeWith( + u: pbandk.MessageDecoder + ): com.gopro.open_gopro.operations.RequestGetCameraCapabilities = + com.gopro.open_gopro.operations.RequestGetCameraCapabilities.decodeWithImpl(u) + + override val descriptor: + pbandk.MessageDescriptor = + pbandk.MessageDescriptor( + fullName = "open_gopro.RequestGetCameraCapabilities", + messageClass = com.gopro.open_gopro.operations.RequestGetCameraCapabilities::class, + messageCompanion = this, + fields = buildList(0) {}) + } +} + +@pbandk.Export +internal data class ResponseGetCameraCapabilities( + val result: com.gopro.open_gopro.operations.EnumResultGeneric, + val schemaVersion: String, + val protocol: com.gopro.open_gopro.operations.ProtocolCapabilities? = null, + override val unknownFields: Map = emptyMap() +) : pbandk.Message { + override operator fun plus( + other: pbandk.Message? + ): com.gopro.open_gopro.operations.ResponseGetCameraCapabilities = protoMergeImpl(other) + + override val descriptor: + pbandk.MessageDescriptor + get() = Companion.descriptor + + override val protoSize: Int by lazy { super.protoSize } + + internal companion object : + pbandk.Message.Companion { + override fun decodeWith( + u: pbandk.MessageDecoder + ): com.gopro.open_gopro.operations.ResponseGetCameraCapabilities = + com.gopro.open_gopro.operations.ResponseGetCameraCapabilities.decodeWithImpl(u) + + override val descriptor: + pbandk.MessageDescriptor = + pbandk.MessageDescriptor( + fullName = "open_gopro.ResponseGetCameraCapabilities", + messageClass = com.gopro.open_gopro.operations.ResponseGetCameraCapabilities::class, + messageCompanion = this, + fields = + buildList(3) { + add( + pbandk.FieldDescriptor( + messageDescriptor = this@Companion::descriptor, + name = "result", + number = 1, + type = + pbandk.FieldDescriptor.Type.Enum( + enumCompanion = + com.gopro.open_gopro.operations.EnumResultGeneric.Companion, + hasPresence = true), + jsonName = "result", + value = + com.gopro.open_gopro.operations.ResponseGetCameraCapabilities:: + result)) + add( + pbandk.FieldDescriptor( + messageDescriptor = this@Companion::descriptor, + name = "schema_version", + number = 2, + type = pbandk.FieldDescriptor.Type.Primitive.String(hasPresence = true), + jsonName = "schemaVersion", + value = + com.gopro.open_gopro.operations.ResponseGetCameraCapabilities:: + schemaVersion)) + add( + pbandk.FieldDescriptor( + messageDescriptor = this@Companion::descriptor, + name = "protocol", + number = 3, + type = + pbandk.FieldDescriptor.Type.Message( + messageCompanion = + com.gopro.open_gopro.operations.ProtocolCapabilities + .Companion), + jsonName = "protocol", + value = + com.gopro.open_gopro.operations.ResponseGetCameraCapabilities:: + protocol)) + }) + } +} + +@pbandk.Export +internal data class ProtocolCapabilities( + val supports2byteIds: Boolean? = null, + override val unknownFields: Map = emptyMap() +) : pbandk.Message { + override operator fun plus( + other: pbandk.Message? + ): com.gopro.open_gopro.operations.ProtocolCapabilities = protoMergeImpl(other) + + override val descriptor: + pbandk.MessageDescriptor + get() = Companion.descriptor + + override val protoSize: Int by lazy { super.protoSize } + + internal companion object : + pbandk.Message.Companion { + internal val defaultInstance: com.gopro.open_gopro.operations.ProtocolCapabilities by lazy { + com.gopro.open_gopro.operations.ProtocolCapabilities() + } + + override fun decodeWith( + u: pbandk.MessageDecoder + ): com.gopro.open_gopro.operations.ProtocolCapabilities = + com.gopro.open_gopro.operations.ProtocolCapabilities.decodeWithImpl(u) + + override val descriptor: + pbandk.MessageDescriptor = + pbandk.MessageDescriptor( + fullName = "open_gopro.ProtocolCapabilities", + messageClass = com.gopro.open_gopro.operations.ProtocolCapabilities::class, + messageCompanion = this, + fields = + buildList(1) { + add( + pbandk.FieldDescriptor( + messageDescriptor = this@Companion::descriptor, + name = "supports_2byte_ids", + number = 1, + type = pbandk.FieldDescriptor.Type.Primitive.Bool(hasPresence = true), + jsonName = "supports2byteIds", + value = + com.gopro.open_gopro.operations.ProtocolCapabilities:: + supports2byteIds)) + }) + } +} + +@pbandk.Export +@pbandk.JsName("orDefaultForRequestGetCameraCapabilities") +internal fun RequestGetCameraCapabilities?.orDefault(): + com.gopro.open_gopro.operations.RequestGetCameraCapabilities = + this ?: RequestGetCameraCapabilities.defaultInstance + +private fun RequestGetCameraCapabilities.protoMergeImpl( + plus: pbandk.Message? +): RequestGetCameraCapabilities = + (plus as? RequestGetCameraCapabilities)?.let { + it.copy(unknownFields = unknownFields + plus.unknownFields) + } ?: this + +@Suppress("UNCHECKED_CAST") +private fun RequestGetCameraCapabilities.Companion.decodeWithImpl( + u: pbandk.MessageDecoder +): RequestGetCameraCapabilities { + + val unknownFields = u.readMessage(this) { _, _ -> } + + return RequestGetCameraCapabilities(unknownFields) +} + +private fun ResponseGetCameraCapabilities.protoMergeImpl( + plus: pbandk.Message? +): ResponseGetCameraCapabilities = + (plus as? ResponseGetCameraCapabilities)?.let { + it.copy( + protocol = protocol?.plus(plus.protocol) ?: plus.protocol, + unknownFields = unknownFields + plus.unknownFields) + } ?: this + +@Suppress("UNCHECKED_CAST") +private fun ResponseGetCameraCapabilities.Companion.decodeWithImpl( + u: pbandk.MessageDecoder +): ResponseGetCameraCapabilities { + var result: com.gopro.open_gopro.operations.EnumResultGeneric? = null + var schemaVersion: String? = null + var protocol: com.gopro.open_gopro.operations.ProtocolCapabilities? = null + + val unknownFields = + u.readMessage(this) { _fieldNumber, _fieldValue -> + when (_fieldNumber) { + 1 -> result = _fieldValue as com.gopro.open_gopro.operations.EnumResultGeneric + 2 -> schemaVersion = _fieldValue as String + 3 -> protocol = _fieldValue as com.gopro.open_gopro.operations.ProtocolCapabilities + } + } + + if (result == null) { + throw pbandk.InvalidProtocolBufferException.missingRequiredField("result") + } + if (schemaVersion == null) { + throw pbandk.InvalidProtocolBufferException.missingRequiredField("schema_version") + } + return ResponseGetCameraCapabilities(result!!, schemaVersion!!, protocol, unknownFields) +} + +@pbandk.Export +@pbandk.JsName("orDefaultForProtocolCapabilities") +internal fun ProtocolCapabilities?.orDefault(): + com.gopro.open_gopro.operations.ProtocolCapabilities = + this ?: ProtocolCapabilities.defaultInstance + +private fun ProtocolCapabilities.protoMergeImpl(plus: pbandk.Message?): ProtocolCapabilities = + (plus as? ProtocolCapabilities)?.let { + it.copy( + supports2byteIds = plus.supports2byteIds ?: supports2byteIds, + unknownFields = unknownFields + plus.unknownFields) + } ?: this + +@Suppress("UNCHECKED_CAST") +private fun ProtocolCapabilities.Companion.decodeWithImpl( + u: pbandk.MessageDecoder +): ProtocolCapabilities { + var supports2byteIds: Boolean? = null + + val unknownFields = + u.readMessage(this) { _fieldNumber, _fieldValue -> + when (_fieldNumber) { + 1 -> supports2byteIds = _fieldValue as Boolean + } + } + + return ProtocolCapabilities(supports2byteIds, unknownFields) +} diff --git a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/request_get_preset_status.kt b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/request_get_preset_status.kt index 1b5b40806..ada3d4bd3 100644 --- a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/request_get_preset_status.kt +++ b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/request_get_preset_status.kt @@ -1,6 +1,3 @@ -/* request_get_preset_status.kt/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). */ -/* This copyright was auto-generated on Wed Sep 24 20:06:50 UTC 2025 */ - @file:OptIn(pbandk.PublicForGeneratedCode::class) package com.gopro.open_gopro.operations diff --git a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/response_generic.kt b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/response_generic.kt index 434c9b868..64bb56875 100644 --- a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/response_generic.kt +++ b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/response_generic.kt @@ -1,6 +1,3 @@ -/* response_generic.kt/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). */ -/* This copyright was auto-generated on Wed Sep 24 20:06:50 UTC 2025 */ - @file:OptIn(pbandk.PublicForGeneratedCode::class) package com.gopro.open_gopro.operations diff --git a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/set_camera_control_status.kt b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/set_camera_control_status.kt index 959777f7f..06a2d5b0d 100644 --- a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/set_camera_control_status.kt +++ b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/set_camera_control_status.kt @@ -1,6 +1,3 @@ -/* set_camera_control_status.kt/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). */ -/* This copyright was auto-generated on Wed Sep 24 20:06:50 UTC 2025 */ - @file:OptIn(pbandk.PublicForGeneratedCode::class) package com.gopro.open_gopro.operations diff --git a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/turbo_transfer.kt b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/turbo_transfer.kt index ce5d0ce4f..98464c75d 100644 --- a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/turbo_transfer.kt +++ b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/operation/proto/turbo_transfer.kt @@ -1,6 +1,3 @@ -/* turbo_transfer.kt/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). */ -/* This copyright was auto-generated on Wed Sep 24 20:06:50 UTC 2025 */ - @file:OptIn(pbandk.PublicForGeneratedCode::class) package com.gopro.open_gopro.operations diff --git a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/queries/Settings.kt b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/queries/Settings.kt index 716001a06..242e15ef0 100644 --- a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/queries/Settings.kt +++ b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/entity/queries/Settings.kt @@ -65,7 +65,8 @@ enum class SettingId(override val value: UByte) : IValuedEnum { VIDEO_FRAMING(232U), MULTI_SHOT_FRAMING(233U), FRAME_RATE(234U), - AUTOMATIC_WI_FI_ACCESS_POINT(236U); + AUTOMATIC_WI_FI_ACCESS_POINT(236U), + AUTO_POWER_ON_USB(237U); @ExperimentalUnsignedTypes companion object : IUByteArrayCompanion { @@ -974,7 +975,8 @@ enum class SystemVideoMode(override val value: UByte) : IValuedEnum { */ enum class VideoBitRate(override val value: UByte) : IValuedEnum { STANDARD(0U), - HIGH(1U); + HIGH(1U), + MAX(2U); @ExperimentalUnsignedTypes companion object : IUByteArrayCompanion { @@ -1432,3 +1434,25 @@ enum class AutomaticWi_FiAccessPoint(override val value: UByte) : IValuedEnum { + OFF(0U), + ON(1U); + + @ExperimentalUnsignedTypes + companion object : IUByteArrayCompanion { + override fun fromUByteArray(value: UByteArray) = + AutoPowerOnUsb.entries.first { it.value == value.last() } + + override fun toUByteArray(value: AutoPowerOnUsb) = value.value.toUByteArray() + } +} diff --git a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/gopro/SettingsContainer.kt b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/gopro/SettingsContainer.kt index 7aba1182a..7c5201012 100644 --- a/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/gopro/SettingsContainer.kt +++ b/demos/kotlin/kmp_sdk/wsdk/src/commonMain/kotlin/com/gopro/open_gopro/gopro/SettingsContainer.kt @@ -490,4 +490,14 @@ class SettingsContainer internal constructor(marshaller: IOperationMarshaller) { */ val automaticWi_FiAccessPoint = Setting(SettingId.AUTOMATIC_WI_FI_ACCESS_POINT, AutomaticWi_FiAccessPoint, marshaller) + + /** + * Auto Power On USB + * + * Setting to automatically power on when the camera is connected to a power source. + * + * @see + * [Open GoPro Spec](https://gopro.github.io/OpenGoPro/ble/features/settings.html#auto-power-on-usb-237) + */ + val autoPowerOnUsb = Setting(SettingId.AUTO_POWER_ON_USB, AutoPowerOnUsb, marshaller) } diff --git a/demos/python/sdk_wireless_camera_control/AGENTS.md b/demos/python/sdk_wireless_camera_control/AGENTS.md new file mode 100644 index 000000000..5c1a9331e --- /dev/null +++ b/demos/python/sdk_wireless_camera_control/AGENTS.md @@ -0,0 +1,335 @@ +# AGENTS.md - AI Agent Guidelines for Open GoPro Python SDK + +This document provides guidelines for AI agents working on this Python SDK. + +## Project Overview + +**Open GoPro Python SDK** (`open_gopro`) is an asyncio-based Python library that provides an interface for controlling GoPro cameras via Bluetooth Low Energy (BLE) and WiFi/USB HTTP APIs. + +### Key Technologies + +- **Python**: 3.11 - 3.13 +- **Package Manager**: [Poetry](https://python-poetry.org/) +- **Task Runner**: [Poe the Poet](https://poethepoet.naber.io/) (via `poetry run poe `) +- **Testing**: pytest with pytest-asyncio +- **Type Checking**: mypy +- **Linting**: pylint +- **Formatting**: black, isort +- **Documentation**: Sphinx with Read the Docs theme + +### Project Structure + +``` +open_gopro/ # Main package source +├── api/ # BLE and HTTP command definitions +├── database/ # COHN database implementation +├── demos/ # CLI demo applications +├── domain/ # Interfaces, enums, exceptions +├── features/ # High-level feature implementations +├── models/ # Data models, proto definitions, constants +├── network/ # BLE and WiFi communication layers +├── parsers/ # Response parsing logic +└── util/ # Logging and utilities + +tests/ +├── unit/ # Unit tests (mocked dependencies) +├── e2e/ # End-to-end tests (requires real camera) +├── conftest.py # Shared pytest fixtures and mocks +└── mocks.py # Mock implementations for testing + +docs/ # Sphinx documentation source +``` + +## Development Setup + +### Initial Setup + +```bash +# Install Poetry if not already installed +curl -sSL https://install.python-poetry.org | python3 - + +# Install all dependencies including dev and gui extras +poetry install --all-extras + +# Activate the virtual environment +poetry shell +``` + +### Available Tasks + +View all available tasks: + +```bash +poetry run poe --help +``` + +Key tasks: + +| Task | Command | Description | +|------|---------|-------------| +| `format` | `poetry run poe format` | Format code with black and sort imports with isort | +| `lint` | `poetry run poe lint` | Format, type check (mypy), and lint (pylint) | +| `tests` | `poetry run poe tests` | Run unit tests with coverage | +| `docs` | `poetry run poe docs` | Validate docstrings and build Sphinx documentation | +| `docstrings` | `poetry run poe docstrings` | Check docstring style (pydocstyle) and validity (pydoclint) | +| `all` | `poetry run poe all` | Run format, lint, tests, docs, and license check | +| `clean` | `poetry run poe clean` | Clean all build artifacts and caches | + +## Unit Testing + +### Running Tests + +```bash +# Run all unit tests +poetry run poe tests + +# Run with pytest directly for more control +poetry run pytest tests/unit + +# Run a specific test file +poetry run pytest tests/unit/test_ble_commands.py + +# Run a specific test +poetry run pytest tests/unit/test_ble_commands.py::test_specific_name + +# Run with verbose output +poetry run pytest tests/unit -v + +# Run with specific log level +poetry run pytest tests/unit --log-cli-level=DEBUG +``` + +### Test Configuration + +- Tests use `pytest-asyncio` with `asyncio_mode = "auto"` - async tests are detected automatically +- Default timeout is 10 seconds per test +- Coverage threshold is **70%** minimum +- Test reports are generated in `.reports/` + +### Writing Tests + +- Unit tests go in `tests/unit/` +- Use fixtures from `tests/conftest.py` (e.g., `mock_wireless_gopro`, `mock_ble_communicator`) +- Mock implementations are in `tests/mocks.py` +- E2E tests require a physical camera and go in `tests/e2e/` + +Example test structure: + +```python +import pytest +from tests.mocks import MockWirelessGoPro + +@pytest.mark.asyncio +async def test_something(mock_wireless_gopro): + # Test implementation + result = await mock_wireless_gopro.some_method() + assert result is not None +``` + +## Linting and Code Quality + +### Pre-Commit Checklist + +**Always run before committing:** + +```bash +poetry run poe lint +``` + +This runs: +1. `black` - Code formatting +2. `isort` - Import sorting +3. `mypy` - Type checking +4. `pylint` - Code linting + +### Individual Checks + +```bash +# Format code only +poetry run poe format + +# Type checking only +poetry run poe _types + +# Pylint only +poetry run poe _pylint +``` + +### Code Style Guidelines + +- **Line length**: 120 characters (black configuration) +- **Import sorting**: black profile (isort) +- **Docstrings**: Google style convention +- **Type hints**: Required for all function signatures (mypy enforces) + +### Mypy Configuration + +- `disallow_untyped_defs = true` - All functions must have type hints +- `warn_unused_ignores = true` - Flag unnecessary type: ignore comments +- Uses `returns` plugin for functional error handling + +### Pylint Configuration + +- Ignores `tests/` and `proto/` directories +- Uses Google-style docstrings +- Max line length: 160 characters +- See `[tool.pylint.*]` sections in `pyproject.toml` for disabled checks + +## Documentation + +### Overview + +Documentation uses **Sphinx** with the **Read the Docs theme** and is published at: +https://gopro.github.io/OpenGoPro/python_sdk/ + +### Building Documentation + +```bash +# Full documentation build (validates docstrings first) +poetry run poe docs + +# Build Sphinx docs only +poetry run poe sphinx + +# Check docstrings only +poetry run poe docstrings +``` + +### Documentation Structure + +- `docs/index.rst` - Main landing page +- `docs/api.rst` - API reference (auto-generated from docstrings) +- `docs/quickstart.rst` - Quick start guide +- `docs/usage.rst` - Detailed usage examples +- Built output goes to `docs/build/` + +### Writing Docstrings + +Use **Google-style docstrings**: + +```python +def example_function(param1: str, param2: int) -> bool: + """Short description of the function. + + Longer description if needed, explaining the behavior + in more detail. + + Args: + param1: Description of param1 + param2: Description of param2 + + Returns: + Description of return value + + Raises: + ValueError: When something is invalid + """ +``` + +### Docstring Validation + +Two tools validate docstrings: +- **pydocstyle**: Checks style conformance to Google convention +- **pydoclint**: Validates docstring completeness and accuracy + +## Commits + +### Conventional Commits + +Use [Conventional Commits](https://www.conventionalcommits.org/) format: + +``` +[optional scope]: + +[optional body] + +[optional footer(s)] +``` + +### Commit Types + +| Type | Description | +|------|-------------| +| `feat` | New feature | +| `fix` | Bug fix | +| `docs` | Documentation changes | +| `style` | Formatting, no code change | +| `refactor` | Code restructuring without behavior change | +| `perf` | Performance improvement | +| `test` | Adding or updating tests | +| `chore` | Maintenance tasks, dependencies | +| `ci` | CI/CD changes | + +### Examples + +```bash +feat(ble): add support for new camera model +fix(wifi): handle connection timeout correctly +docs(api): update docstrings for http_commands +test(unit): add tests for response parsing +refactor(parsers): simplify JSON response handling +chore(deps): update bleak to 2.1.1 +``` + +### Commit Guidelines + +- Keep commits atomic and focused +- Write clear, descriptive commit messages +- Reference issue numbers when applicable: `fix(api): resolve timeout issue (#123)` +- Update `CHANGELOG.rst` for user-facing changes + +## CI/CD Integration + +### Nox Sessions + +The project uses [Nox](https://nox.thea.codes/) for CI testing across Python versions: + +```bash +# Run all nox sessions +nox + +# Run specific session +nox -s tests +nox -s lint +nox -s docs +``` + +### CI Workflow + +GitHub Actions runs: +1. `format` - Check code formatting +2. `lint` - Type checking and linting +3. `tests` - Unit tests across Python 3.11, 3.12, 3.13 +4. `docstrings` - Docstring validation +5. `docs` - Documentation build + +## Additional Notes + +### Error Handling + +The project uses the [`returns`](https://returns.readthedocs.io/) library for functional error handling. Many methods return `Result` types instead of raising exceptions. + +### Async/Await + +All camera communication is async. Use `async with` for GoPro connections: + +```python +async with WirelessGoPro() as gopro: + await gopro.ble_command.some_command() +``` + +### Protocol Buffers + +Proto files are in `open_gopro/models/proto/`. Generated `*_pb2.py` files should not be manually edited. + +### Dependencies + +- Check licenses before adding dependencies: `poetry run poe licenses` +- License report is saved to `thirdPartyDependencies.csv` + +### Common Issues + +1. **BLE connection issues**: Ensure Bluetooth is enabled and camera is discoverable +2. **Import errors**: Run `poetry install --all-extras` to install all dependencies +3. **Test timeouts**: Default timeout is 10s; use `@pytest.mark.timeout(30)` for longer tests +4. **Type errors**: The codebase uses strict typing; ensure all functions have type hints diff --git a/demos/python/sdk_wireless_camera_control/docs/changelog.rst b/demos/python/sdk_wireless_camera_control/docs/changelog.rst index 4703fc171..d2dc31bde 100644 --- a/demos/python/sdk_wireless_camera_control/docs/changelog.rst +++ b/demos/python/sdk_wireless_camera_control/docs/changelog.rst @@ -9,6 +9,10 @@ All notable changes to this project will be documented in this file. The format is based on `Keep a Changelog `_, and this project adheres to `Semantic Versioning `_. +0.23.0 (February-5-2026) +------------------------ +* Add Support for Lit Hero + 0.22.0 (September-23-2025) -------------------------- * Add Support for Max 2 diff --git a/demos/python/sdk_wireless_camera_control/docs/conf.py b/demos/python/sdk_wireless_camera_control/docs/conf.py index 172fd06bc..f786f7e62 100644 --- a/demos/python/sdk_wireless_camera_control/docs/conf.py +++ b/demos/python/sdk_wireless_camera_control/docs/conf.py @@ -121,6 +121,7 @@ def is_on(self) -> bool: ("py:class", "SyncFilter"), ("py:class", "AsyncFilter"), ("py:class", "ValueType"), + ("py:class", "CommandFactory"), ] nitpick_ignore_regex = [ (r"py:class", r".*proto\..+"), diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/api/ble_settings.py b/demos/python/sdk_wireless_camera_control/open_gopro/api/ble_settings.py index d9dc8a592..410058c41 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/api/ble_settings.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/api/ble_settings.py @@ -483,4 +483,14 @@ def __init__(self, communicator: GoProBle): See [Open GoPro Spec](https://gopro.github.io/OpenGoPro/ble/features/settings.html#automatic-wi-fi-access-point-236)""" + self.auto_power_on_usb: BleSetting[settings.AutoPowerOnUsb] = BleSetting[settings.AutoPowerOnUsb]( + communicator, SettingId.AUTO_POWER_ON_USB, settings.AutoPowerOnUsb + ) + + """Auto Power On USB + + Setting to automatically power on when the camera is connected to a power source. + + See [Open GoPro Spec](https://gopro.github.io/OpenGoPro/ble/features/settings.html#auto-power-on-usb-237)""" + super().__init__(communicator) diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/api/builders.py b/demos/python/sdk_wireless_camera_control/open_gopro/api/builders.py index 58fe8d183..02a52eb21 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/api/builders.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/api/builders.py @@ -241,7 +241,7 @@ def _build_data(self, **kwargs: Any) -> bytearray: for element in value: attr.append(element.value if isinstance(element, enum.Enum) else element) # type: ignore else: - attr.append(value.value if isinstance(value, enum.Enum) else value) # type:ignore + attr.append(value.value if isinstance(value, enum.Enum) else value) # type: ignore else: setattr(proto, attr_name, value) # Prepend headers and serialize @@ -339,15 +339,17 @@ async def wrapper( else GoProBle._CompositeRegisterType.ALL_SETTINGS ) try: + # Compute kwargs once, then pass factories that create fresh coroutines + command_kwargs = await wrapped(**kwargs) or kwargs return ResultE.from_value( await GoProCompositeObservable( gopro=instance._communicator, update=internal_update_type, - register_command=instance._communicator._send_ble_message( - register_message, **(await wrapped(**kwargs) or kwargs) + register_command=lambda: instance._communicator._send_ble_message( + register_message, **command_kwargs ), - unregister_command=instance._communicator._send_ble_message( - unregister_message, **(await wrapped(**kwargs) or kwargs) + unregister_command=lambda: instance._communicator._send_ble_message( + unregister_message, **command_kwargs ), ).start() ) @@ -604,8 +606,8 @@ async def get_value_observable(self) -> ResultE[GoProObservable[T]]: await GoProObservable[T]( gopro=self._communicator, update=self._identifier, - register_command=self._communicator._send_ble_message(register_message), - unregister_command=self._communicator._send_ble_message(unregister_message), + register_command=lambda: self._communicator._send_ble_message(register_message), + unregister_command=lambda: self._communicator._send_ble_message(unregister_message), ).start() ) @@ -631,8 +633,8 @@ async def get_capabilities_observable(self) -> ResultE[GoProObservable[list[T]]] await GoProObservable[list[T]]( gopro=self._communicator, update=self._identifier, - register_command=self._communicator._send_ble_message(register_message), - unregister_command=self._communicator._send_ble_message(unregister_message), + register_command=lambda: self._communicator._send_ble_message(register_message), + unregister_command=lambda: self._communicator._send_ble_message(unregister_message), ).start() ) @@ -741,8 +743,8 @@ async def get_value_observable(self) -> ResultE[GoProObservable[T]]: await GoProObservable[T]( gopro=self._communicator, update=self._identifier, - register_command=self._communicator._send_ble_message(register_message), - unregister_command=self._communicator._send_ble_message(unregister_message), + register_command=lambda: self._communicator._send_ble_message(register_message), + unregister_command=lambda: self._communicator._send_ble_message(unregister_message), ).start() ) diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/api/http_settings.py b/demos/python/sdk_wireless_camera_control/open_gopro/api/http_settings.py index e0a0bd486..df18133ee 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/api/http_settings.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/api/http_settings.py @@ -473,4 +473,14 @@ def __init__(self, communicator: GoProHttp): @see [Open GoPro Spec](https://gopro.github.io/OpenGoPro/ble/features/settings.html#automatic-wi-fi-access-point-236)""" + self.auto_power_on_usb: HttpSetting[settings.AutoPowerOnUsb] = HttpSetting[settings.AutoPowerOnUsb]( + communicator, SettingId.AUTO_POWER_ON_USB + ) + + """Auto Power On USB + + Setting to automatically power on when the camera is connected to a power source. + + @see [Open GoPro Spec](https://gopro.github.io/OpenGoPro/ble/features/settings.html#auto-power-on-usb-237)""" + super().__init__(communicator) diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/demos/cohn.py b/demos/python/sdk_wireless_camera_control/open_gopro/demos/cohn.py index 9ab90ba9e..7cfe3214a 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/demos/cohn.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/demos/cohn.py @@ -30,11 +30,9 @@ def dump_cohn_collateral(gopro: WirelessGoPro) -> None: gopro (WirelessGoPro): gopro to retrieve the credentials from """ assert gopro.cohn.credentials - console.print( - f"Sample curl command: {COHN_CURL_CMD_TEMPLATE.format( + console.print(f"Sample curl command: {COHN_CURL_CMD_TEMPLATE.format( password=gopro.cohn.credentials.password, - ip_addr=gopro.cohn.credentials.ip_address,)}" - ) + ip_addr=gopro.cohn.credentials.ip_address,)}") with open("cohn.crt", "w") as f: f.write(gopro.cohn.credentials.certificate) @@ -87,8 +85,7 @@ async def main(args: argparse.Namespace) -> None: def parse_arguments() -> argparse.Namespace: parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, - description=textwrap.dedent( - """\ + description=textwrap.dedent("""\ Open GoPro Camera on the Home Network (COHN) Utility ---------------------------------------------------- This utility is used to configure and demonstrate the Camera On the Home @@ -120,8 +117,7 @@ def parse_arguments() -> argparse.Namespace: Therefore, the general procedure for a freshly factory-reset camera is: 1. Use operation mode 1 to provision COHN 2. Use operation mode 2 to communicate with (only) COHN - """ - ), + """), ) parser.add_argument( "--ssid", diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/demos/dump_gatt.py b/demos/python/sdk_wireless_camera_control/open_gopro/demos/dump_gatt.py new file mode 100644 index 000000000..2da8942b8 --- /dev/null +++ b/demos/python/sdk_wireless_camera_control/open_gopro/demos/dump_gatt.py @@ -0,0 +1,55 @@ +# dump_gatt.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). +# This copyright was auto-generated on Sun Feb 9 2026 + +"""Entrypoint for dumping BLE GATT attribute table to CSV.""" + +import argparse +import asyncio +from pathlib import Path + +from rich.console import Console + +from open_gopro import WirelessGoPro +from open_gopro.util import add_cli_args_and_parse +from open_gopro.util.logger import setup_logging + +console = Console() + + +async def main(args: argparse.Namespace) -> None: + logger = setup_logging(__name__, args.log) + + gopro: WirelessGoPro | None = None + + try: + async with WirelessGoPro(args.identifier, interfaces={WirelessGoPro.Interface.BLE}) as gopro: + output_file = args.output + console.print(f"Dumping GATT attribute table to {output_file.absolute()}...") + gopro._ble.gatt_db.dump_to_csv(output_file) + console.print(f"Success!! :smiley: GATT table has been written to {output_file.absolute()}") + + except Exception as e: # pylint: disable = broad-except + logger.error(repr(e)) + + +def parse_arguments() -> argparse.Namespace: + parser = argparse.ArgumentParser( + description="Connect to a GoPro camera via BLE and dump the GATT attribute table to CSV." + ) + parser.add_argument( + "--output", + type=Path, + help="Where to write the CSV file. Defaults to 'gatt_attributes.csv'", + default=Path("gatt_attributes.csv"), + ) + + return add_cli_args_and_parse(parser) + + +# Needed for poetry scripts defined in pyproject.toml +def entrypoint() -> None: + asyncio.run(main(parse_arguments())) + + +if __name__ == "__main__": + entrypoint() diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/demos/gui/preview_stream.py b/demos/python/sdk_wireless_camera_control/open_gopro/demos/gui/preview_stream.py index 39fca2134..e6bdeddb9 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/demos/gui/preview_stream.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/demos/gui/preview_stream.py @@ -11,7 +11,7 @@ from returns.pipeline import is_successful from rich.console import Console -from open_gopro import WirelessGoPro +from open_gopro import WiredGoPro, WirelessGoPro from open_gopro.demos.gui.video_display import BufferlessVideoCapture from open_gopro.models import streaming from open_gopro.util import add_cli_args_and_parse @@ -24,7 +24,7 @@ async def main(args: argparse.Namespace) -> int: setup_logging(__name__, args.log) - async with WirelessGoPro(args.identifier) as gopro: + async with WiredGoPro(args.identifier) if args.wired else WirelessGoPro(args.identifier) as gopro: set_stream_logging_level(logging.WARNING) with console.status("Starting preview stream..."): @@ -65,6 +65,11 @@ def parse_arguments() -> argparse.Namespace: parser.add_argument( "--port", type=int, help="Port to use for livestream. Defaults to 8554 if not set", default=8554 ) + parser.add_argument( + "--wired", + action="store_true", + help="Set to use wired (USB) instead of wireless (BLE / WIFI) interface", + ) return add_cli_args_and_parse(parser, wifi=False) diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/demos/scanner.py b/demos/python/sdk_wireless_camera_control/open_gopro/demos/scanner.py index fe6390ec3..4ba1711f5 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/demos/scanner.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/demos/scanner.py @@ -6,7 +6,6 @@ import argparse import asyncio import enum -import sys from abc import ABC from dataclasses import dataclass from typing import Generic, TypeVar @@ -22,6 +21,9 @@ console = Console() +# Global shutdown event for graceful exit +shutdown_event: asyncio.Event + class NetworkType(enum.Enum): """Scan Response Network type""" @@ -84,9 +86,11 @@ async def scan_ble() -> None: unique_adv_data: set[GoProAdvData] = set() async with BleakScanner(service_uuids=["0000fea6-0000-1000-8000-00805f9b34fb"]) as scanner: - while True: + while not shutdown_event.is_set(): adv_data = AdvData() async for _, data in scanner.advertisement_data(): + if shutdown_event.is_set(): + return adv_data.update(data) if adv_data.local_name: # Once we've received the scan response... break @@ -105,7 +109,7 @@ async def scan_dns() -> None: """Scan for MDNS entries that match the GoPro service name""" unique_responses: set[str] = set() - while True: + while not shutdown_event.is_set(): try: response = await find_first_ip_addr(WiredGoPro._MDNS_SERVICE_NAME, 10) serial = response.name.split(".")[0] @@ -120,10 +124,13 @@ async def wait_for_exit() -> None: """Exit on enter""" await ainput("Press enter to exit\n") console.print("Exiting...") - sys.exit() + shutdown_event.set() async def main(_: argparse.Namespace) -> None: + global shutdown_event + shutdown_event = asyncio.Event() + await asyncio.gather( scan_ble(), # scan_wifi_ap(args.password, args.interface), diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/domain/gopro_observable.py b/demos/python/sdk_wireless_camera_control/open_gopro/domain/gopro_observable.py index 9f2307089..9129cf790 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/domain/gopro_observable.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/domain/gopro_observable.py @@ -7,7 +7,7 @@ import logging from types import TracebackType -from typing import Any, Coroutine, Generic, Self, TypeVar +from typing import Any, Callable, Coroutine, Generic, Self, TypeVar from open_gopro.domain.communicator_interface import BaseGoProCommunicator from open_gopro.domain.exceptions import GoProError @@ -20,6 +20,9 @@ logger = logging.getLogger(__name__) +# Type alias for command factories - callables that return fresh coroutines +CommandFactory = Callable[[], Coroutine[Any, Any, GoProResp[Any]]] + class GoproObserverDistinctInitial(Observable[T], Generic[I, T]): """Observable for asynchronous notifications where the initial notifications is a different type than proceeding notifications. @@ -27,21 +30,22 @@ class GoproObserverDistinctInitial(Observable[T], Generic[I, T]): Args: gopro (BaseGoProCommunicator): gopro camera to operate on update (UpdateType | BaseGoProCommunicator._CompositeRegisterType): the observable's update type - register_command (Coroutine[Any, Any, GoProResp[I]]): command to call to start receiving values - unregister_command (Coroutine[Any, Any, Any] | None): Command to call to stop receiving values. Defaults to None. + register_command (CommandFactory): factory that creates coroutine to start receiving values. + Must be a callable (e.g., lambda) that returns a fresh coroutine each time, NOT a raw coroutine. + unregister_command (CommandFactory | None): factory that creates coroutine to stop receiving values. Defaults to None. """ def __init__( self, gopro: BaseGoProCommunicator, update: UpdateType | BaseGoProCommunicator._CompositeRegisterType, - register_command: Coroutine[Any, Any, GoProResp[I]], - unregister_command: Coroutine[Any, Any, Any] | None = None, + register_command: CommandFactory, + unregister_command: CommandFactory | None = None, ) -> None: self._gopro = gopro self._update = update - self._register_command = register_command - self._unregister_command = unregister_command + self._register_command_factory = register_command + self._unregister_command_factory = unregister_command self._initial_response: I self._is_open = False super().__init__(debug_id=str(update)) @@ -82,7 +86,7 @@ async def start(self: Self) -> Self: Self: modified observable """ self._gopro._register_update(self._emit_value, self._update) - initial_response = await self._register_command + initial_response = await self._register_command_factory() if not initial_response.ok: raise GoProError(f"Failed to start receiving update ==> {self._update}") self._initial_response = initial_response.data @@ -92,8 +96,8 @@ async def start(self: Self) -> Self: async def stop(self) -> None: """Configure the camera to stop sending notifications""" self._gopro._unregister_update(self._emit_value, self._update) - if self._unregister_command: - await self._unregister_command + if self._unregister_command_factory: + await self._unregister_command_factory() self._is_open = False @@ -103,19 +107,11 @@ class GoProObservable(GoproObserverDistinctInitial[T, T]): Args: gopro (BaseGoProCommunicator): gopro camera to operate on update (UpdateType | BaseGoProCommunicator._CompositeRegisterType): the update's update type - register_command (Coroutine[Any, Any, GoProResp[T]]): command to call to start receiving notifications - unregister_command (Coroutine[Any, Any, Any] | None): Command to call to stop receiving notifications. Defaults to None. + register_command (CommandFactory): factory that creates coroutine to start receiving notifications. + Must be a callable (e.g., lambda) that returns a fresh coroutine each time, NOT a raw coroutine. + unregister_command (CommandFactory | None): factory that creates coroutine to stop receiving notifications. Defaults to None. """ - def __init__( - self, - gopro: BaseGoProCommunicator, - update: UpdateType | BaseGoProCommunicator._CompositeRegisterType, - register_command: Coroutine[Any, Any, GoProResp[T]], - unregister_command: Coroutine[Any, Any, Any] | None = None, - ) -> None: - super().__init__(gopro, update, register_command, unregister_command) - async def start(self: Self) -> Self: """Configure the camera to start receiving notifications. @@ -128,7 +124,7 @@ async def start(self: Self) -> Self: Self: modified observable """ self._gopro._register_update(self._emit_value, self._update) - initial_response = await self._register_command + initial_response = await self._register_command_factory() if not initial_response.ok: raise GoProError(f"Failed to start receiving updates ==> {self._update}") self._initial_response = initial_response.data @@ -143,8 +139,9 @@ class GoProCompositeObservable(GoProObservable[dict[UpdateType | BaseGoProCommun Args: gopro (BaseGoProCommunicator): gopro camera to operate on update (UpdateType | BaseGoProCommunicator._CompositeRegisterType): the updates's update type - register_command (Coroutine[Any, Any, GoProResp[T]]): command to call to start receiving notifications - unregister_command (Coroutine[Any, Any, Any] | None): Command to call to stop receiving notifications. Defaults to None. + register_command (CommandFactory): factory that creates coroutine to start receiving notifications. + Must be a callable (e.g., lambda) that returns a fresh coroutine each time, NOT a raw coroutine. + unregister_command (CommandFactory | None): factory that creates coroutine to stop receiving notifications. Defaults to None. """ async def _emit_value( diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/domain/observable.py b/demos/python/sdk_wireless_camera_control/open_gopro/domain/observable.py index 7aa5ecf2f..5df668e6a 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/domain/observable.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/domain/observable.py @@ -153,7 +153,6 @@ async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None: # self._condition.release() def __init__(self, capacity: int = 100, debug_id: str | None = None) -> None: - self._lock = asyncio.Condition() self._count = 0 self._capacity = capacity self._debug_id = debug_id or str(Observable.OBS_IDX) @@ -325,7 +324,8 @@ async def _get_next(self, uuid: UUID) -> T: for action in self._on_subscribe_actions: if iscoroutinefunction(action): await action() - action() + else: + action() # Acquire the condition and read the per-collector value async with self._shared_data: @@ -344,6 +344,6 @@ async def _get_next(self, uuid: UUID) -> T: self._mux_action(action, value) # type: ignore # Notify per-value actions for action in self._per_value_actions: # type: ignore - action(value) # type: ignore + self._mux_action(action, value) # type: ignore # We've made it! Return the continuing value return value diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/features/base_feature.py b/demos/python/sdk_wireless_camera_control/open_gopro/features/base_feature.py index 1797b664f..4ac1727f4 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/features/base_feature.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/features/base_feature.py @@ -2,6 +2,7 @@ # This copyright was auto-generated on Mon May 12 23:03:50 UTC 2025 """Functionality common to all features.""" + from __future__ import annotations import asyncio diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/features/cohn_feature.py b/demos/python/sdk_wireless_camera_control/open_gopro/features/cohn_feature.py index 4a2a92dda..89453fdc9 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/features/cohn_feature.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/features/cohn_feature.py @@ -59,13 +59,14 @@ async def open( # pylint: disable=arguments-differ logger.debug("Opening COHN") await super().open(loop, gopro, *args, **kwargs) assert self._gopro + gopro_ref = self._gopro # Capture for lambda to satisfy type checker if cohn_credentials: self.credentials = cohn_credentials self._ready_event = asyncio.Event() self._status_observable = GoProObservable( - gopro=self._gopro, + gopro=gopro_ref, update=ProtobufId(FeatureId.QUERY, ActionId.RESPONSE_GET_COHN_STATUS), - register_command=self._gopro.ble_command.cohn_get_status(register=True), + register_command=lambda: gopro_ref.ble_command.cohn_get_status(register=True), ).on_start(lambda _: self._ready_event.set()) self._status_task = asyncio.create_task(self._track_status()) logger.debug("COHN opened") @@ -99,10 +100,20 @@ async def _track_status(self) -> None: async for status in observable.observe(debug_id="Cohn Feature"): logger.debug(f"Feature Received COHN status: {status}") except GoProError as exc: - logger.warning(f"Failed to start COHN feature: {str(exc)}") + logger.warning(f"Failed to start COHN feature: {str(exc)}. Camera may not support COHN.") self._supported = False self._ready_event.set() + return # Exit - COHN is not supported on this camera + except asyncio.CancelledError: + logger.debug("COHN status tracking cancelled") + raise # Re-raise to properly cancel the task + except Exception as exc: # pylint: disable=broad-exception-caught + logger.error(f"Unexpected error in COHN status tracking: {repr(exc)}") + self._supported = False + self._ready_event.set() + await asyncio.sleep(1) # Backoff before retrying else: + logger.debug("Waiting for BLE connection before starting COHN status tracking") await asyncio.sleep(1) @property diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/features/streaming/preview_stream.py b/demos/python/sdk_wireless_camera_control/open_gopro/features/streaming/preview_stream.py index 40d70337c..6b1c2b448 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/features/streaming/preview_stream.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/features/streaming/preview_stream.py @@ -48,7 +48,7 @@ async def start(self, options: PreviewStreamOptions) -> ResultE[None]: # noqa: logger.info(f"Starting preview stream on port {self._current_options.port}") # Stop the preview stream if it is already running await self.gopro.http_command.set_preview_stream(mode=Toggle.DISABLE) - await self.gopro.ble_command.set_shutter(shutter=Toggle.DISABLE) + await self.gopro.http_command.set_shutter(shutter=Toggle.DISABLE) # Now start the preview stream response = await self.gopro.http_command.set_preview_stream(mode=Toggle.ENABLE, port=self._current_options.port) if response.ok: diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/gopro_wireless.py b/demos/python/sdk_wireless_camera_control/open_gopro/gopro_wireless.py index 2f1580617..e371ee574 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/gopro_wireless.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/gopro_wireless.py @@ -8,8 +8,7 @@ import asyncio import enum import logging -import queue -import traceback +from asyncio import Future from collections import defaultdict from copy import deepcopy from pathlib import Path @@ -62,7 +61,7 @@ from open_gopro.network.wifi.controller import WifiController from open_gopro.network.wifi.requests_session import create_less_strict_requests_session from open_gopro.parsers.response import BleRespBuilder -from open_gopro.util import SnapshotQueue, get_current_dst_aware_time, pretty_print +from open_gopro.util import get_current_dst_aware_time, pretty_print from open_gopro.util.logger import Logger logger = logging.getLogger(__name__) @@ -171,7 +170,9 @@ class WirelessGoPro(GoProBase[WirelessApi], GoProWirelessInterface): cohn_db (Path): Path to COHN Database. Defaults to Path("cohn_db.json"). interfaces (set[WirelessGoPro.Interface] | None): Wireless interfaces for which to attempt to establish communication channels. Defaults to None in which case both BLE and WiFi will be used. - **kwargs (Any): additional parameters for internal use / testing + **kwargs (Any): additional parameters for internal use / testing. Includes ``rich_gatt_querying`` + (bool, default False) which, if True, reads descriptor values during GATT discovery for richer + GATT CSV exports (may fail on some camera firmware due to a bleak/CoreBluetooth bug). Raises: ValueError: Invalid combination of arguments. @@ -218,6 +219,7 @@ def __init__( ble_adapter: type[BLEController] = kwargs.get("ble_adapter", BleakWrapperController) wifi_adapter: type[WifiController] = kwargs.get("wifi_adapter", WifiCli) + rich_gatt_querying: bool = kwargs.get("rich_gatt_querying", False) # Set up API delegate self._wireless_api = WirelessApi(self) self._keep_alive_interval: int = kwargs.get("keep_alive_interval", 3) @@ -226,7 +228,7 @@ def __init__( # Initialize GoPro Communication Client GoProWirelessInterface.__init__( self, - ble_controller=ble_adapter(self._handle_exception), + ble_controller=ble_adapter(self._handle_exception, rich_gatt_querying), wifi_controller=wifi_adapter(host_wifi_interface, password=host_sudo_password), disconnected_cb=self._disconnect_handler, notification_cb=self._notification_handler, @@ -246,10 +248,10 @@ def __init__( # Builders for currently accumulating synchronous responses, indexed by GoProUUID. This assumes there # can only be one active response per BleUUID self._active_builders: dict[BleUUID, BleRespBuilder] = {} - # Responses that we are waiting for. - self._sync_resp_wait_q: SnapshotQueue[ResponseType] = SnapshotQueue() - # Synchronous response that has been parsed and are ready for their sender to receive as the response. - self._sync_resp_ready_q: SnapshotQueue[GoProResp] = SnapshotQueue() + # Pending BLE requests: list of (identifier, Future) tuples. Responses are matched to the + # head of this list and delivered by resolving the Future directly. + self._pending_responses: list[tuple[ResponseType, asyncio.Future[GoProResp]]] = [] + self._pending_responses_lock: asyncio.Lock = asyncio.Lock() self._listeners: dict[UpdateType | GoProBle._CompositeRegisterType, set[UpdateCb]] = defaultdict(set) @@ -397,7 +399,15 @@ async def open(self, timeout: int = 15, retries: int = 5) -> None: logger.info("Performing initial camera configuration...") # TODO need to handle sending these if BLE does not exist - await self.ble_command.set_third_party_client_info() + # Some cameras will not reply to this. We can proceed functionally without it + try: + await self.ble_command.set_third_party_client_info() + except ResponseTimeout: + logger.info( + "Timed out while setting third-party client info; " + "this is expected for some cameras and will be ignored." + ) + # Set current dst-aware time. Don't assert on success since some old cameras don't support this command. dt, tz_offset, is_dst = get_current_dst_aware_time() await self.ble_command.set_date_time_tz_dst(date_time=dt, tz_offset=tz_offset, is_dst=is_dst) @@ -436,7 +446,6 @@ async def open(self, timeout: int = 15, retries: int = 5) -> None: except Exception as e: # pylint: disable=broad-exception-caught logger.error(f"Error while opening: {repr(e)}") - traceback.print_exc() await self.close() if retry >= RETRIES - 1: raise e @@ -695,32 +704,40 @@ async def _route_response(self, response: GoProResp) -> None: if response._is_query and not response._is_push and len(response.data) == 1: response.data = list(response.data.values())[0] - logger.trace(f"Route response {response.identifier} Waiting for sync resp wait q") # type: ignore - async with self._sync_resp_wait_q: - logger.trace(f"Route response {response.identifier} Acquired sync resp wait q") # type: ignore - head = await self._sync_resp_wait_q.peek_front() - # Check if this is the awaited synchronous response (id matches). Note! these have to come in order. - if (head == response.identifier) or ( - # There is a special case for an unsupported protobuf error response. It does not contain the feature ID so we - # have to match it by Feature ID / UUID. Feature ID's are not used across UUID's so we will only check for - # matching Feature ID(s) - isinstance(head, ProtobufId) - and ProtobufId(head.feature_id, None) - == response.identifier # Feature IDs match and response identifier does not contain Action ID - ): - logger.info(Logger.build_log_rx_str(original_response, asynchronous=False)) - # Dequeue it and put the response on the ready queue - logger.trace(f"Route response {response.identifier} read from sync resp wait q") # type: ignore - ephemeral_response = await self._sync_resp_wait_q.get() - logger.trace(f"Dequeued response {ephemeral_response}") # type: ignore - - logger.trace(f"Route response putting {response.identifier} on ready q") # type: ignore - await self._sync_resp_ready_q.put(response) - - # If this wasn't the awaited synchronous response... - else: + logger.trace(f"Route response {response.identifier}") # type: ignore + async with self._pending_responses_lock: + if not self._pending_responses: + # No pending requests - treat as async/push notification logger.info(Logger.build_log_rx_str(original_response, asynchronous=True)) - logger.trace(f"Route response {response.identifier} released sync resp wait q") # type: ignore + else: + # Search all pending requests for a matching identifier (not just head) + matched_index = None + matched_future = None + for i, (pending_id, pending_future) in enumerate(self._pending_responses): + if (pending_id == response.identifier) or ( + # Special case for unsupported protobuf error response.It does not contain the feature ID so we + # have to match it by Feature ID / UUID. Feature ID's are not used across UUID's so we will only check for + # matching Feature ID(s) + isinstance(pending_id, ProtobufId) + and ProtobufId(pending_id.feature_id, None) == response.identifier + ): + matched_index = i + matched_future = pending_future + break + + # If this wasn't the awaited synchronous response... + if matched_future is not None: + assert matched_index is not None # Always set together with matched_future + logger.info(Logger.build_log_rx_str(original_response, asynchronous=False)) + # Remove from pending and resolve the Future + self._pending_responses.pop(matched_index) + logger.trace(f"Resolving Future for {response.identifier}") # type: ignore + matched_future.set_result(response) + else: + # Identifier doesn't match any pending request - treat as async response + logger.info(Logger.build_log_rx_str(original_response, asynchronous=True)) + + logger.trace(f"Route response {response.identifier} done") # type: ignore if response._is_push: for update_id, value in response.data.items(): await self._notify_listeners(update_id, value) @@ -737,7 +754,8 @@ def _notification_handler(self, handle: int, data: bytearray) -> None: async def _async_notification_handler() -> None: # Responses we don't care about. For now, just the BLE-spec defined battery characteristic - if (uuid := self._ble.gatt_db.handle2uuid(handle)) == GoProUUID.BATT_LEVEL: + uuid = self._ble.gatt_db.handle2uuid(handle) + if uuid == GoProUUID.BATT_LEVEL: return logger.debug(f'Received response on BleUUID [{uuid}]: {data.hex(":")}') # Add to response dict if not already there @@ -783,9 +801,14 @@ def _disconnect_handler(self, _: Any) -> None: async def _send_ble_message( self, message: BleMessage, rules: MessageRules = MessageRules(), **kwargs: Any ) -> GoProResp: - # Store information on the response we are expecting - logger.trace(f"send {message._identifier} putting on sync wait q") # type: ignore - await self._sync_resp_wait_q.put(message._identifier) + # Create a Future to receive our response + response_future: Future[GoProResp] = asyncio.get_running_loop().create_future() + + # Register this request with its Future + async with self._pending_responses_lock: + logger.trace(f"send {message._identifier} registering pending response") # type: ignore + self._pending_responses.append((message._identifier, response_future)) + logger.info(Logger.build_log_tx_str(pretty_print(message._as_dict(**kwargs)))) # Fragment data and write it @@ -793,22 +816,18 @@ async def _send_ble_message( logger.debug(f"Writing to [{message._uuid.name}] UUID: {packet.hex(':')}") await self._ble.write(message._uuid, packet) - # Wait to be notified that response was received + # Wait for our specific Future to be resolved try: - logger.trace(f"send {message._identifier} Waiting to receive sync response from ready q") # type: ignore - response = await asyncio.wait_for(self._sync_resp_ready_q.get(), WirelessGoPro.WRITE_TIMEOUT) - logger.trace(f"{message._identifier} received response {response.identifier}") # type: ignore - if response.identifier != message._identifier: - error_message = f"[{message._identifier}] received incorrect response: [{response.identifier}]" - logger.error(error_message) - raise RuntimeError(error_message) + logger.trace(f"send {message._identifier} waiting for response via Future") # type: ignore + response = await asyncio.wait_for(response_future, WirelessGoPro.WRITE_TIMEOUT) + logger.trace(f"{message._identifier} received response {response.identifier}") # type: ignore except asyncio.TimeoutError as e: - logger.error( - f"Response timeout of {WirelessGoPro.WRITE_TIMEOUT} seconds when sending {message._identifier}!" - ) - raise ResponseTimeout(WirelessGoPro.WRITE_TIMEOUT) from e - except queue.Empty as e: - logger.error( + # Clean up our pending request on timeout + async with self._pending_responses_lock: + self._pending_responses = [ + (id_, fut) for id_, fut in self._pending_responses if fut is not response_future + ] + logger.warning( f"Response timeout of {WirelessGoPro.WRITE_TIMEOUT} seconds when sending {message._identifier}!" ) raise ResponseTimeout(WirelessGoPro.WRITE_TIMEOUT) from e @@ -850,15 +869,15 @@ def _handle_cohn(self, message: HttpMessage) -> HttpMessage: async def _get_json(self, message: HttpMessage, *args: Any, **kwargs: Any) -> GoProResp: # type: ignore[override] message = self._handle_cohn(message) - return await super()._get_json(*args, message=message, **kwargs) # type: ignore[call-arg] + return await super()._get_json(*args, message=message, **kwargs) # type: ignore[arg-type] async def _get_stream(self, message: HttpMessage, *args: Any, **kwargs: Any) -> GoProResp: # type: ignore[override] message = self._handle_cohn(message) - return await super()._get_stream(*args, message=message, **kwargs) # type: ignore[call-arg] + return await super()._get_stream(*args, message=message, **kwargs) # type: ignore[arg-type] async def _put_json(self, message: HttpMessage, *args: Any, **kwargs: Any) -> GoProResp: # type: ignore[override] message = self._handle_cohn(message) - return await super()._put_json(*args, message=message, **kwargs) # type: ignore[call-arg] + return await super()._put_json(*args, message=message, **kwargs) # type: ignore[arg-type] @GoProBase._ensure_opened((GoProMessageInterface.BLE,)) async def _open_wifi(self, timeout: int = 30, retries: int = 5) -> None: diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/models/constants/settings.py b/demos/python/sdk_wireless_camera_control/open_gopro/models/constants/settings.py index 24653766a..28cedddca 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/models/constants/settings.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/models/constants/settings.py @@ -69,6 +69,7 @@ class SettingId(GoProIntEnum): MULTI_SHOT_FRAMING = 233 FRAME_RATE = 234 AUTOMATIC_WI_FI_ACCESS_POINT = 236 + AUTO_POWER_ON_USB = 237 class VideoResolution(GoProIntEnum): @@ -547,6 +548,7 @@ class VideoBitRate(GoProIntEnum): STANDARD = 0 HIGH = 1 + MAX = 2 class BitDepth(GoProIntEnum): @@ -748,3 +750,10 @@ class AutomaticWi_FiAccessPoint(GoProIntEnum): OFF = 0 ON = 1 + + +class AutoPowerOnUsb(GoProIntEnum): + """See [Open GoPro Spec](https://gopro.github.io/OpenGoPro/ble/features/settings.html#auto-power-on-usb-237)""" + + OFF = 0 + ON = 1 diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/models/network_scan_responses.py b/demos/python/sdk_wireless_camera_control/open_gopro/models/network_scan_responses.py index 953cce5a6..fcda52773 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/models/network_scan_responses.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/models/network_scan_responses.py @@ -130,6 +130,7 @@ def default_decode(obj: Any) -> Any: 62: "C350", 64: "C352", 65: "C353", + 70: "C359", } diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/__init__.py b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/__init__.py index a16d0de19..ffe7fe032 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/__init__.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/__init__.py @@ -5,6 +5,7 @@ They are imported here so they can be imported from """ + from .camera_control_pb2 import RequestSetCameraName from .cohn_pb2 import ( EnumCOHNNetworkState, diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/camera_control_pb2.py b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/camera_control_pb2.py index 1d7fae0d3..60dcc03f4 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/camera_control_pb2.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/camera_control_pb2.py @@ -1,6 +1,3 @@ -# camera_control_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:46 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/cohn_pb2.py b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/cohn_pb2.py index 213b9eea1..fde3dbe3f 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/cohn_pb2.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/cohn_pb2.py @@ -1,6 +1,3 @@ -# cohn_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:46 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/live_streaming_pb2.py b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/live_streaming_pb2.py index 8dcd36f34..73a83daf6 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/live_streaming_pb2.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/live_streaming_pb2.py @@ -1,6 +1,3 @@ -# live_streaming_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:46 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/media_pb2.py b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/media_pb2.py index 93c71007a..da764d283 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/media_pb2.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/media_pb2.py @@ -1,6 +1,3 @@ -# media_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:46 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/network_management_pb2.py b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/network_management_pb2.py index 1050247b5..b05946dea 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/network_management_pb2.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/network_management_pb2.py @@ -1,6 +1,3 @@ -# network_management_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:46 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/preset_status_pb2.py b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/preset_status_pb2.py index 819b62386..d8d623c6f 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/preset_status_pb2.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/preset_status_pb2.py @@ -1,6 +1,3 @@ -# preset_status_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:46 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor @@ -12,22 +9,22 @@ from . import response_generic_pb2 as response__generic__pb2 DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x13preset_status.proto\x12\nopen_gopro\x1a\x16response_generic.proto"I\n\x12NotifyPresetStatus\x123\n\x12preset_group_array\x18\x01 \x03(\x0b2\x17.open_gopro.PresetGroup"\xc3\x02\n\x06Preset\x12\n\n\x02id\x18\x01 \x01(\x05\x12&\n\x04mode\x18\x02 \x01(\x0e2\x18.open_gopro.EnumFlatMode\x12-\n\x08title_id\x18\x03 \x01(\x0e2\x1b.open_gopro.EnumPresetTitle\x12\x14\n\x0ctitle_number\x18\x04 \x01(\x05\x12\x14\n\x0cuser_defined\x18\x05 \x01(\x08\x12(\n\x04icon\x18\x06 \x01(\x0e2\x1a.open_gopro.EnumPresetIcon\x120\n\rsetting_array\x18\x07 \x03(\x0b2\x19.open_gopro.PresetSetting\x12\x13\n\x0bis_modified\x18\x08 \x01(\x08\x12\x10\n\x08is_fixed\x18\t \x01(\x08\x12\x13\n\x0bcustom_name\x18\n \x01(\t\x12\x12\n\nis_visible\x18\x0b \x01(\x08"\x8c\x01\n\x19RequestCustomPresetUpdate\x12-\n\x08title_id\x18\x01 \x01(\x0e2\x1b.open_gopro.EnumPresetTitle\x12\x13\n\x0bcustom_name\x18\x02 \x01(\t\x12+\n\x07icon_id\x18\x03 \x01(\x0e2\x1a.open_gopro.EnumPresetIcon"9\n\x1aRequestPresetSetVisibility\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x0f\n\x07visible\x18\x02 \x01(\x08"\xd5\x01\n\x0bPresetGroup\x12\'\n\x02id\x18\x01 \x01(\x0e2\x1b.open_gopro.EnumPresetGroup\x12(\n\x0cpreset_array\x18\x02 \x03(\x0b2\x12.open_gopro.Preset\x12\x16\n\x0ecan_add_preset\x18\x03 \x01(\x08\x12-\n\x04icon\x18\x04 \x01(\x0e2\x1f.open_gopro.EnumPresetGroupIcon\x12,\n\nmode_array\x18\x05 \x03(\x0e2\x18.open_gopro.EnumFlatMode">\n\rPresetSetting\x12\n\n\x02id\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x05\x12\x12\n\nis_caption\x18\x03 \x01(\x08*\x9b\x05\n\x0cEnumFlatMode\x12\x1e\n\x11FLAT_MODE_UNKNOWN\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x12\x16\n\x12FLAT_MODE_PLAYBACK\x10\x04\x12\x13\n\x0fFLAT_MODE_SETUP\x10\x05\x12\x13\n\x0fFLAT_MODE_VIDEO\x10\x0c\x12\x1e\n\x1aFLAT_MODE_TIME_LAPSE_VIDEO\x10\r\x12\x15\n\x11FLAT_MODE_LOOPING\x10\x0f\x12\x1a\n\x16FLAT_MODE_PHOTO_SINGLE\x10\x10\x12\x13\n\x0fFLAT_MODE_PHOTO\x10\x11\x12\x19\n\x15FLAT_MODE_PHOTO_NIGHT\x10\x12\x12\x19\n\x15FLAT_MODE_PHOTO_BURST\x10\x13\x12\x1e\n\x1aFLAT_MODE_TIME_LAPSE_PHOTO\x10\x14\x12\x1f\n\x1bFLAT_MODE_NIGHT_LAPSE_PHOTO\x10\x15\x12\x1e\n\x1aFLAT_MODE_BROADCAST_RECORD\x10\x16\x12!\n\x1dFLAT_MODE_BROADCAST_BROADCAST\x10\x17\x12\x1d\n\x19FLAT_MODE_TIME_WARP_VIDEO\x10\x18\x12\x18\n\x14FLAT_MODE_LIVE_BURST\x10\x19\x12\x1f\n\x1bFLAT_MODE_NIGHT_LAPSE_VIDEO\x10\x1a\x12\x13\n\x0fFLAT_MODE_SLOMO\x10\x1b\x12\x12\n\x0eFLAT_MODE_IDLE\x10\x1c\x12\x1e\n\x1aFLAT_MODE_VIDEO_STAR_TRAIL\x10\x1d\x12"\n\x1eFLAT_MODE_VIDEO_LIGHT_PAINTING\x10\x1e\x12\x1f\n\x1bFLAT_MODE_VIDEO_LIGHT_TRAIL\x10\x1f\x12\x1f\n\x1bFLAT_MODE_VIDEO_BURST_SLOMO\x10 *i\n\x0fEnumPresetGroup\x12\x1a\n\x15PRESET_GROUP_ID_VIDEO\x10\xe8\x07\x12\x1a\n\x15PRESET_GROUP_ID_PHOTO\x10\xe9\x07\x12\x1e\n\x19PRESET_GROUP_ID_TIMELAPSE\x10\xea\x07*\xb5\x03\n\x13EnumPresetGroupIcon\x12\x1e\n\x1aPRESET_GROUP_VIDEO_ICON_ID\x10\x00\x12\x1e\n\x1aPRESET_GROUP_PHOTO_ICON_ID\x10\x01\x12"\n\x1ePRESET_GROUP_TIMELAPSE_ICON_ID\x10\x02\x12\'\n#PRESET_GROUP_LONG_BAT_VIDEO_ICON_ID\x10\x03\x12(\n$PRESET_GROUP_ENDURANCE_VIDEO_ICON_ID\x10\x04\x12"\n\x1ePRESET_GROUP_MAX_VIDEO_ICON_ID\x10\x05\x12"\n\x1ePRESET_GROUP_MAX_PHOTO_ICON_ID\x10\x06\x12&\n"PRESET_GROUP_MAX_TIMELAPSE_ICON_ID\x10\x07\x12%\n!PRESET_GROUP_ND_MOD_VIDEO_ICON_ID\x10\x08\x12%\n!PRESET_GROUP_ND_MOD_PHOTO_ICON_ID\x10\t\x12)\n%PRESET_GROUP_ND_MOD_TIMELAPSE_ICON_ID\x10\n*\xff\x12\n\x0eEnumPresetIcon\x12\x15\n\x11PRESET_ICON_VIDEO\x10\x00\x12\x18\n\x14PRESET_ICON_ACTIVITY\x10\x01\x12\x19\n\x15PRESET_ICON_CINEMATIC\x10\x02\x12\x15\n\x11PRESET_ICON_PHOTO\x10\x03\x12\x1a\n\x16PRESET_ICON_LIVE_BURST\x10\x04\x12\x15\n\x11PRESET_ICON_BURST\x10\x05\x12\x1b\n\x17PRESET_ICON_PHOTO_NIGHT\x10\x06\x12\x18\n\x14PRESET_ICON_TIMEWARP\x10\x07\x12\x19\n\x15PRESET_ICON_TIMELAPSE\x10\x08\x12\x1a\n\x16PRESET_ICON_NIGHTLAPSE\x10\t\x12\x15\n\x11PRESET_ICON_SNAIL\x10\n\x12\x17\n\x13PRESET_ICON_VIDEO_2\x10\x0b\x12\x17\n\x13PRESET_ICON_PHOTO_2\x10\r\x12\x18\n\x14PRESET_ICON_PANORAMA\x10\x0e\x12\x17\n\x13PRESET_ICON_BURST_2\x10\x0f\x12\x1a\n\x16PRESET_ICON_TIMEWARP_2\x10\x10\x12\x1b\n\x17PRESET_ICON_TIMELAPSE_2\x10\x11\x12\x16\n\x12PRESET_ICON_CUSTOM\x10\x12\x12\x13\n\x0fPRESET_ICON_AIR\x10\x13\x12\x14\n\x10PRESET_ICON_BIKE\x10\x14\x12\x14\n\x10PRESET_ICON_EPIC\x10\x15\x12\x16\n\x12PRESET_ICON_INDOOR\x10\x16\x12\x15\n\x11PRESET_ICON_MOTOR\x10\x17\x12\x17\n\x13PRESET_ICON_MOUNTED\x10\x18\x12\x17\n\x13PRESET_ICON_OUTDOOR\x10\x19\x12\x13\n\x0fPRESET_ICON_POV\x10\x1a\x12\x16\n\x12PRESET_ICON_SELFIE\x10\x1b\x12\x15\n\x11PRESET_ICON_SKATE\x10\x1c\x12\x14\n\x10PRESET_ICON_SNOW\x10\x1d\x12\x15\n\x11PRESET_ICON_TRAIL\x10\x1e\x12\x16\n\x12PRESET_ICON_TRAVEL\x10\x1f\x12\x15\n\x11PRESET_ICON_WATER\x10 \x12\x17\n\x13PRESET_ICON_LOOPING\x10!\x12\x15\n\x11PRESET_ICON_STARS\x10"\x12\x16\n\x12PRESET_ICON_ACTION\x10#\x12\x1a\n\x16PRESET_ICON_FOLLOW_CAM\x10$\x12\x14\n\x10PRESET_ICON_SURF\x10%\x12\x14\n\x10PRESET_ICON_CITY\x10&\x12\x15\n\x11PRESET_ICON_SHAKY\x10\'\x12\x16\n\x12PRESET_ICON_CHESTY\x10(\x12\x16\n\x12PRESET_ICON_HELMET\x10)\x12\x14\n\x10PRESET_ICON_BITE\x10*\x12 \n\x1cPRESET_ICON_CUSTOM_CINEMATIC\x10+\x12\x14\n\x10PRESET_ICON_VLOG\x10,\x12\x13\n\x0fPRESET_ICON_FPV\x10-\x12\x13\n\x0fPRESET_ICON_HDR\x10.\x12\x19\n\x15PRESET_ICON_LANDSCAPE\x10/\x12\x13\n\x0fPRESET_ICON_LOG\x100\x12\x1c\n\x18PRESET_ICON_CUSTOM_SLOMO\x101\x12\x16\n\x12PRESET_ICON_TRIPOD\x102\x12\x19\n\x15PRESET_ICON_MAX_VIDEO\x107\x12\x19\n\x15PRESET_ICON_MAX_PHOTO\x108\x12\x1c\n\x18PRESET_ICON_MAX_TIMEWARP\x109\x12\x15\n\x11PRESET_ICON_BASIC\x10:\x12\x1c\n\x18PRESET_ICON_ULTRA_SLO_MO\x10;\x12"\n\x1ePRESET_ICON_STANDARD_ENDURANCE\x10<\x12"\n\x1ePRESET_ICON_ACTIVITY_ENDURANCE\x10=\x12#\n\x1fPRESET_ICON_CINEMATIC_ENDURANCE\x10>\x12\x1f\n\x1bPRESET_ICON_SLOMO_ENDURANCE\x10?\x12\x1c\n\x18PRESET_ICON_STATIONARY_1\x10@\x12\x1c\n\x18PRESET_ICON_STATIONARY_2\x10A\x12\x1c\n\x18PRESET_ICON_STATIONARY_3\x10B\x12\x1c\n\x18PRESET_ICON_STATIONARY_4\x10C\x12"\n\x1ePRESET_ICON_SIMPLE_SUPER_PHOTO\x10F\x12"\n\x1ePRESET_ICON_SIMPLE_NIGHT_PHOTO\x10G\x12%\n!PRESET_ICON_HIGHEST_QUALITY_VIDEO\x10I\x12&\n"PRESET_ICON_STANDARD_QUALITY_VIDEO\x10J\x12#\n\x1fPRESET_ICON_BASIC_QUALITY_VIDEO\x10K\x12\x1a\n\x16PRESET_ICON_STAR_TRAIL\x10L\x12\x1e\n\x1aPRESET_ICON_LIGHT_PAINTING\x10M\x12\x1b\n\x17PRESET_ICON_LIGHT_TRAIL\x10N\x12\x1a\n\x16PRESET_ICON_FULL_FRAME\x10O\x12\x1e\n\x1aPRESET_ICON_EASY_MAX_VIDEO\x10P\x12\x1e\n\x1aPRESET_ICON_EASY_MAX_PHOTO\x10Q\x12!\n\x1dPRESET_ICON_EASY_MAX_TIMEWARP\x10R\x12#\n\x1fPRESET_ICON_EASY_MAX_STAR_TRAIL\x10S\x12\'\n#PRESET_ICON_EASY_MAX_LIGHT_PAINTING\x10T\x12$\n PRESET_ICON_EASY_MAX_LIGHT_TRAIL\x10U\x12\x1e\n\x1aPRESET_ICON_MAX_STAR_TRAIL\x10Y\x12"\n\x1ePRESET_ICON_MAX_LIGHT_PAINTING\x10Z\x12\x1f\n\x1bPRESET_ICON_MAX_LIGHT_TRAIL\x10[\x12%\n!PRESET_ICON_EASY_STANDARD_PROFILE\x10d\x12 \n\x1cPRESET_ICON_EASY_HDR_PROFILE\x10e\x12\x1b\n\x17PRESET_ICON_BURST_SLOMO\x10f\x12 \n\x1bPRESET_ICON_TIMELAPSE_PHOTO\x10\xe8\x07\x12!\n\x1cPRESET_ICON_NIGHTLAPSE_PHOTO\x10\xe9\x07*\x9f\x13\n\x0fEnumPresetTitle\x12\x19\n\x15PRESET_TITLE_ACTIVITY\x10\x00\x12\x19\n\x15PRESET_TITLE_STANDARD\x10\x01\x12\x1a\n\x16PRESET_TITLE_CINEMATIC\x10\x02\x12\x16\n\x12PRESET_TITLE_PHOTO\x10\x03\x12\x1b\n\x17PRESET_TITLE_LIVE_BURST\x10\x04\x12\x16\n\x12PRESET_TITLE_BURST\x10\x05\x12\x16\n\x12PRESET_TITLE_NIGHT\x10\x06\x12\x1a\n\x16PRESET_TITLE_TIME_WARP\x10\x07\x12\x1b\n\x17PRESET_TITLE_TIME_LAPSE\x10\x08\x12\x1c\n\x18PRESET_TITLE_NIGHT_LAPSE\x10\t\x12\x16\n\x12PRESET_TITLE_VIDEO\x10\n\x12\x16\n\x12PRESET_TITLE_SLOMO\x10\x0b\x12\x18\n\x14PRESET_TITLE_PHOTO_2\x10\r\x12\x19\n\x15PRESET_TITLE_PANORAMA\x10\x0e\x12\x1c\n\x18PRESET_TITLE_TIME_WARP_2\x10\x10\x12\x17\n\x13PRESET_TITLE_CUSTOM\x10\x12\x12\x14\n\x10PRESET_TITLE_AIR\x10\x13\x12\x15\n\x11PRESET_TITLE_BIKE\x10\x14\x12\x15\n\x11PRESET_TITLE_EPIC\x10\x15\x12\x17\n\x13PRESET_TITLE_INDOOR\x10\x16\x12\x16\n\x12PRESET_TITLE_MOTOR\x10\x17\x12\x18\n\x14PRESET_TITLE_MOUNTED\x10\x18\x12\x18\n\x14PRESET_TITLE_OUTDOOR\x10\x19\x12\x14\n\x10PRESET_TITLE_POV\x10\x1a\x12\x17\n\x13PRESET_TITLE_SELFIE\x10\x1b\x12\x16\n\x12PRESET_TITLE_SKATE\x10\x1c\x12\x15\n\x11PRESET_TITLE_SNOW\x10\x1d\x12\x16\n\x12PRESET_TITLE_TRAIL\x10\x1e\x12\x17\n\x13PRESET_TITLE_TRAVEL\x10\x1f\x12\x16\n\x12PRESET_TITLE_WATER\x10 \x12\x18\n\x14PRESET_TITLE_LOOPING\x10!\x12\x16\n\x12PRESET_TITLE_STARS\x10"\x12\x17\n\x13PRESET_TITLE_ACTION\x10#\x12\x1b\n\x17PRESET_TITLE_FOLLOW_CAM\x10$\x12\x15\n\x11PRESET_TITLE_SURF\x10%\x12\x15\n\x11PRESET_TITLE_CITY\x10&\x12\x16\n\x12PRESET_TITLE_SHAKY\x10\'\x12\x17\n\x13PRESET_TITLE_CHESTY\x10(\x12\x17\n\x13PRESET_TITLE_HELMET\x10)\x12\x15\n\x11PRESET_TITLE_BITE\x10*\x12!\n\x1dPRESET_TITLE_CUSTOM_CINEMATIC\x10+\x12\x15\n\x11PRESET_TITLE_VLOG\x10,\x12\x14\n\x10PRESET_TITLE_FPV\x10-\x12\x14\n\x10PRESET_TITLE_HDR\x10.\x12\x1a\n\x16PRESET_TITLE_LANDSCAPE\x10/\x12\x14\n\x10PRESET_TITLE_LOG\x100\x12\x1d\n\x19PRESET_TITLE_CUSTOM_SLOMO\x101\x12\x17\n\x13PRESET_TITLE_TRIPOD\x102\x12\x16\n\x12PRESET_TITLE_BASIC\x10:\x12\x1d\n\x19PRESET_TITLE_ULTRA_SLO_MO\x10;\x12#\n\x1fPRESET_TITLE_STANDARD_ENDURANCE\x10<\x12#\n\x1fPRESET_TITLE_ACTIVITY_ENDURANCE\x10=\x12$\n PRESET_TITLE_CINEMATIC_ENDURANCE\x10>\x12 \n\x1cPRESET_TITLE_SLOMO_ENDURANCE\x10?\x12\x1d\n\x19PRESET_TITLE_STATIONARY_1\x10@\x12\x1d\n\x19PRESET_TITLE_STATIONARY_2\x10A\x12\x1d\n\x19PRESET_TITLE_STATIONARY_3\x10B\x12\x1d\n\x19PRESET_TITLE_STATIONARY_4\x10C\x12\x1d\n\x19PRESET_TITLE_SIMPLE_VIDEO\x10D\x12!\n\x1dPRESET_TITLE_SIMPLE_TIME_WARP\x10E\x12#\n\x1fPRESET_TITLE_SIMPLE_SUPER_PHOTO\x10F\x12#\n\x1fPRESET_TITLE_SIMPLE_NIGHT_PHOTO\x10G\x12\'\n#PRESET_TITLE_SIMPLE_VIDEO_ENDURANCE\x10H\x12 \n\x1cPRESET_TITLE_HIGHEST_QUALITY\x10I\x12!\n\x1dPRESET_TITLE_EXTENDED_BATTERY\x10J\x12 \n\x1cPRESET_TITLE_LONGEST_BATTERY\x10K\x12\x1b\n\x17PRESET_TITLE_STAR_TRAIL\x10L\x12\x1f\n\x1bPRESET_TITLE_LIGHT_PAINTING\x10M\x12\x1c\n\x18PRESET_TITLE_LIGHT_TRAIL\x10N\x12\x1b\n\x17PRESET_TITLE_FULL_FRAME\x10O\x12\'\n#PRESET_TITLE_STANDARD_QUALITY_VIDEO\x10R\x12$\n PRESET_TITLE_BASIC_QUALITY_VIDEO\x10S\x12&\n"PRESET_TITLE_HIGHEST_QUALITY_VIDEO\x10]\x12)\n%PRESET_TITLE_USER_DEFINED_CUSTOM_NAME\x10^\x12&\n"PRESET_TITLE_EASY_STANDARD_PROFILE\x10c\x12!\n\x1dPRESET_TITLE_EASY_HDR_PROFILE\x10d\x12\x1c\n\x18PRESET_TITLE_BURST_SLOMO\x10j\x12\x1a\n\x16PRESET_TITLE_4_3_VIDEO\x10}\x12\x1b\n\x17PRESET_TITLE_16_9_VIDEO\x10~\x12\x1b\n\x17PRESET_TITLE_16_9_SLOMO\x10\x7f\x12"\n\x1dPRESET_TITLE_TIME_LAPSE_VIDEO\x10\x83\x01\x12"\n\x1dPRESET_TITLE_TIME_LAPSE_PHOTO\x10\x84\x01\x12#\n\x1ePRESET_TITLE_NIGHT_LAPSE_VIDEO\x10\x85\x01\x12#\n\x1ePRESET_TITLE_NIGHT_LAPSE_PHOTO\x10\x86\x01' + b'\n\x13preset_status.proto\x12\nopen_gopro\x1a\x16response_generic.proto"I\n\x12NotifyPresetStatus\x123\n\x12preset_group_array\x18\x01 \x03(\x0b2\x17.open_gopro.PresetGroup"\xc3\x02\n\x06Preset\x12\n\n\x02id\x18\x01 \x01(\x05\x12&\n\x04mode\x18\x02 \x01(\x0e2\x18.open_gopro.EnumFlatMode\x12-\n\x08title_id\x18\x03 \x01(\x0e2\x1b.open_gopro.EnumPresetTitle\x12\x14\n\x0ctitle_number\x18\x04 \x01(\x05\x12\x14\n\x0cuser_defined\x18\x05 \x01(\x08\x12(\n\x04icon\x18\x06 \x01(\x0e2\x1a.open_gopro.EnumPresetIcon\x120\n\rsetting_array\x18\x07 \x03(\x0b2\x19.open_gopro.PresetSetting\x12\x13\n\x0bis_modified\x18\x08 \x01(\x08\x12\x10\n\x08is_fixed\x18\t \x01(\x08\x12\x13\n\x0bcustom_name\x18\n \x01(\t\x12\x12\n\nis_visible\x18\x0b \x01(\x08"\x8c\x01\n\x19RequestCustomPresetUpdate\x12-\n\x08title_id\x18\x01 \x01(\x0e2\x1b.open_gopro.EnumPresetTitle\x12\x13\n\x0bcustom_name\x18\x02 \x01(\t\x12+\n\x07icon_id\x18\x03 \x01(\x0e2\x1a.open_gopro.EnumPresetIcon"9\n\x1aRequestPresetSetVisibility\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x0f\n\x07visible\x18\x02 \x01(\x08"\x84\x02\n\x0bPresetGroup\x12\'\n\x02id\x18\x01 \x01(\x0e2\x1b.open_gopro.EnumPresetGroup\x12(\n\x0cpreset_array\x18\x02 \x03(\x0b2\x12.open_gopro.Preset\x12\x16\n\x0ecan_add_preset\x18\x03 \x01(\x08\x12-\n\x04icon\x18\x04 \x01(\x0e2\x1f.open_gopro.EnumPresetGroupIcon\x12,\n\nmode_array\x18\x05 \x03(\x0e2\x18.open_gopro.EnumFlatMode\x12\x13\n\x0bcustom_name\x18\x06 \x01(\t\x12\x18\n\x10active_preset_id\x18\x07 \x01(\x05">\n\rPresetSetting\x12\n\n\x02id\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x05\x12\x12\n\nis_caption\x18\x03 \x01(\x08*\x9b\x05\n\x0cEnumFlatMode\x12\x1e\n\x11FLAT_MODE_UNKNOWN\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x12\x16\n\x12FLAT_MODE_PLAYBACK\x10\x04\x12\x13\n\x0fFLAT_MODE_SETUP\x10\x05\x12\x13\n\x0fFLAT_MODE_VIDEO\x10\x0c\x12\x1e\n\x1aFLAT_MODE_TIME_LAPSE_VIDEO\x10\r\x12\x15\n\x11FLAT_MODE_LOOPING\x10\x0f\x12\x1a\n\x16FLAT_MODE_PHOTO_SINGLE\x10\x10\x12\x13\n\x0fFLAT_MODE_PHOTO\x10\x11\x12\x19\n\x15FLAT_MODE_PHOTO_NIGHT\x10\x12\x12\x19\n\x15FLAT_MODE_PHOTO_BURST\x10\x13\x12\x1e\n\x1aFLAT_MODE_TIME_LAPSE_PHOTO\x10\x14\x12\x1f\n\x1bFLAT_MODE_NIGHT_LAPSE_PHOTO\x10\x15\x12\x1e\n\x1aFLAT_MODE_BROADCAST_RECORD\x10\x16\x12!\n\x1dFLAT_MODE_BROADCAST_BROADCAST\x10\x17\x12\x1d\n\x19FLAT_MODE_TIME_WARP_VIDEO\x10\x18\x12\x18\n\x14FLAT_MODE_LIVE_BURST\x10\x19\x12\x1f\n\x1bFLAT_MODE_NIGHT_LAPSE_VIDEO\x10\x1a\x12\x13\n\x0fFLAT_MODE_SLOMO\x10\x1b\x12\x12\n\x0eFLAT_MODE_IDLE\x10\x1c\x12\x1e\n\x1aFLAT_MODE_VIDEO_STAR_TRAIL\x10\x1d\x12"\n\x1eFLAT_MODE_VIDEO_LIGHT_PAINTING\x10\x1e\x12\x1f\n\x1bFLAT_MODE_VIDEO_LIGHT_TRAIL\x10\x1f\x12\x1f\n\x1bFLAT_MODE_VIDEO_BURST_SLOMO\x10 *\x87\x01\n\x0fEnumPresetGroup\x12\x1a\n\x15PRESET_GROUP_ID_VIDEO\x10\xe8\x07\x12\x1a\n\x15PRESET_GROUP_ID_PHOTO\x10\xe9\x07\x12\x1e\n\x19PRESET_GROUP_ID_TIMELAPSE\x10\xea\x07\x12\x1c\n\x17PRESET_GROUP_ID_GENERAL\x10\xd0\x0f*\xb5\x03\n\x13EnumPresetGroupIcon\x12\x1e\n\x1aPRESET_GROUP_VIDEO_ICON_ID\x10\x00\x12\x1e\n\x1aPRESET_GROUP_PHOTO_ICON_ID\x10\x01\x12"\n\x1ePRESET_GROUP_TIMELAPSE_ICON_ID\x10\x02\x12\'\n#PRESET_GROUP_LONG_BAT_VIDEO_ICON_ID\x10\x03\x12(\n$PRESET_GROUP_ENDURANCE_VIDEO_ICON_ID\x10\x04\x12"\n\x1ePRESET_GROUP_MAX_VIDEO_ICON_ID\x10\x05\x12"\n\x1ePRESET_GROUP_MAX_PHOTO_ICON_ID\x10\x06\x12&\n"PRESET_GROUP_MAX_TIMELAPSE_ICON_ID\x10\x07\x12%\n!PRESET_GROUP_ND_MOD_VIDEO_ICON_ID\x10\x08\x12%\n!PRESET_GROUP_ND_MOD_PHOTO_ICON_ID\x10\t\x12)\n%PRESET_GROUP_ND_MOD_TIMELAPSE_ICON_ID\x10\n*\xff\x12\n\x0eEnumPresetIcon\x12\x15\n\x11PRESET_ICON_VIDEO\x10\x00\x12\x18\n\x14PRESET_ICON_ACTIVITY\x10\x01\x12\x19\n\x15PRESET_ICON_CINEMATIC\x10\x02\x12\x15\n\x11PRESET_ICON_PHOTO\x10\x03\x12\x1a\n\x16PRESET_ICON_LIVE_BURST\x10\x04\x12\x15\n\x11PRESET_ICON_BURST\x10\x05\x12\x1b\n\x17PRESET_ICON_PHOTO_NIGHT\x10\x06\x12\x18\n\x14PRESET_ICON_TIMEWARP\x10\x07\x12\x19\n\x15PRESET_ICON_TIMELAPSE\x10\x08\x12\x1a\n\x16PRESET_ICON_NIGHTLAPSE\x10\t\x12\x15\n\x11PRESET_ICON_SNAIL\x10\n\x12\x17\n\x13PRESET_ICON_VIDEO_2\x10\x0b\x12\x17\n\x13PRESET_ICON_PHOTO_2\x10\r\x12\x18\n\x14PRESET_ICON_PANORAMA\x10\x0e\x12\x17\n\x13PRESET_ICON_BURST_2\x10\x0f\x12\x1a\n\x16PRESET_ICON_TIMEWARP_2\x10\x10\x12\x1b\n\x17PRESET_ICON_TIMELAPSE_2\x10\x11\x12\x16\n\x12PRESET_ICON_CUSTOM\x10\x12\x12\x13\n\x0fPRESET_ICON_AIR\x10\x13\x12\x14\n\x10PRESET_ICON_BIKE\x10\x14\x12\x14\n\x10PRESET_ICON_EPIC\x10\x15\x12\x16\n\x12PRESET_ICON_INDOOR\x10\x16\x12\x15\n\x11PRESET_ICON_MOTOR\x10\x17\x12\x17\n\x13PRESET_ICON_MOUNTED\x10\x18\x12\x17\n\x13PRESET_ICON_OUTDOOR\x10\x19\x12\x13\n\x0fPRESET_ICON_POV\x10\x1a\x12\x16\n\x12PRESET_ICON_SELFIE\x10\x1b\x12\x15\n\x11PRESET_ICON_SKATE\x10\x1c\x12\x14\n\x10PRESET_ICON_SNOW\x10\x1d\x12\x15\n\x11PRESET_ICON_TRAIL\x10\x1e\x12\x16\n\x12PRESET_ICON_TRAVEL\x10\x1f\x12\x15\n\x11PRESET_ICON_WATER\x10 \x12\x17\n\x13PRESET_ICON_LOOPING\x10!\x12\x15\n\x11PRESET_ICON_STARS\x10"\x12\x16\n\x12PRESET_ICON_ACTION\x10#\x12\x1a\n\x16PRESET_ICON_FOLLOW_CAM\x10$\x12\x14\n\x10PRESET_ICON_SURF\x10%\x12\x14\n\x10PRESET_ICON_CITY\x10&\x12\x15\n\x11PRESET_ICON_SHAKY\x10\'\x12\x16\n\x12PRESET_ICON_CHESTY\x10(\x12\x16\n\x12PRESET_ICON_HELMET\x10)\x12\x14\n\x10PRESET_ICON_BITE\x10*\x12 \n\x1cPRESET_ICON_CUSTOM_CINEMATIC\x10+\x12\x14\n\x10PRESET_ICON_VLOG\x10,\x12\x13\n\x0fPRESET_ICON_FPV\x10-\x12\x13\n\x0fPRESET_ICON_HDR\x10.\x12\x19\n\x15PRESET_ICON_LANDSCAPE\x10/\x12\x13\n\x0fPRESET_ICON_LOG\x100\x12\x1c\n\x18PRESET_ICON_CUSTOM_SLOMO\x101\x12\x16\n\x12PRESET_ICON_TRIPOD\x102\x12\x19\n\x15PRESET_ICON_MAX_VIDEO\x107\x12\x19\n\x15PRESET_ICON_MAX_PHOTO\x108\x12\x1c\n\x18PRESET_ICON_MAX_TIMEWARP\x109\x12\x15\n\x11PRESET_ICON_BASIC\x10:\x12\x1c\n\x18PRESET_ICON_ULTRA_SLO_MO\x10;\x12"\n\x1ePRESET_ICON_STANDARD_ENDURANCE\x10<\x12"\n\x1ePRESET_ICON_ACTIVITY_ENDURANCE\x10=\x12#\n\x1fPRESET_ICON_CINEMATIC_ENDURANCE\x10>\x12\x1f\n\x1bPRESET_ICON_SLOMO_ENDURANCE\x10?\x12\x1c\n\x18PRESET_ICON_STATIONARY_1\x10@\x12\x1c\n\x18PRESET_ICON_STATIONARY_2\x10A\x12\x1c\n\x18PRESET_ICON_STATIONARY_3\x10B\x12\x1c\n\x18PRESET_ICON_STATIONARY_4\x10C\x12"\n\x1ePRESET_ICON_SIMPLE_SUPER_PHOTO\x10F\x12"\n\x1ePRESET_ICON_SIMPLE_NIGHT_PHOTO\x10G\x12%\n!PRESET_ICON_HIGHEST_QUALITY_VIDEO\x10I\x12&\n"PRESET_ICON_STANDARD_QUALITY_VIDEO\x10J\x12#\n\x1fPRESET_ICON_BASIC_QUALITY_VIDEO\x10K\x12\x1a\n\x16PRESET_ICON_STAR_TRAIL\x10L\x12\x1e\n\x1aPRESET_ICON_LIGHT_PAINTING\x10M\x12\x1b\n\x17PRESET_ICON_LIGHT_TRAIL\x10N\x12\x1a\n\x16PRESET_ICON_FULL_FRAME\x10O\x12\x1e\n\x1aPRESET_ICON_EASY_MAX_VIDEO\x10P\x12\x1e\n\x1aPRESET_ICON_EASY_MAX_PHOTO\x10Q\x12!\n\x1dPRESET_ICON_EASY_MAX_TIMEWARP\x10R\x12#\n\x1fPRESET_ICON_EASY_MAX_STAR_TRAIL\x10S\x12\'\n#PRESET_ICON_EASY_MAX_LIGHT_PAINTING\x10T\x12$\n PRESET_ICON_EASY_MAX_LIGHT_TRAIL\x10U\x12\x1e\n\x1aPRESET_ICON_MAX_STAR_TRAIL\x10Y\x12"\n\x1ePRESET_ICON_MAX_LIGHT_PAINTING\x10Z\x12\x1f\n\x1bPRESET_ICON_MAX_LIGHT_TRAIL\x10[\x12%\n!PRESET_ICON_EASY_STANDARD_PROFILE\x10d\x12 \n\x1cPRESET_ICON_EASY_HDR_PROFILE\x10e\x12\x1b\n\x17PRESET_ICON_BURST_SLOMO\x10f\x12 \n\x1bPRESET_ICON_TIMELAPSE_PHOTO\x10\xe8\x07\x12!\n\x1cPRESET_ICON_NIGHTLAPSE_PHOTO\x10\xe9\x07*\x9f\x13\n\x0fEnumPresetTitle\x12\x19\n\x15PRESET_TITLE_ACTIVITY\x10\x00\x12\x19\n\x15PRESET_TITLE_STANDARD\x10\x01\x12\x1a\n\x16PRESET_TITLE_CINEMATIC\x10\x02\x12\x16\n\x12PRESET_TITLE_PHOTO\x10\x03\x12\x1b\n\x17PRESET_TITLE_LIVE_BURST\x10\x04\x12\x16\n\x12PRESET_TITLE_BURST\x10\x05\x12\x16\n\x12PRESET_TITLE_NIGHT\x10\x06\x12\x1a\n\x16PRESET_TITLE_TIME_WARP\x10\x07\x12\x1b\n\x17PRESET_TITLE_TIME_LAPSE\x10\x08\x12\x1c\n\x18PRESET_TITLE_NIGHT_LAPSE\x10\t\x12\x16\n\x12PRESET_TITLE_VIDEO\x10\n\x12\x16\n\x12PRESET_TITLE_SLOMO\x10\x0b\x12\x18\n\x14PRESET_TITLE_PHOTO_2\x10\r\x12\x19\n\x15PRESET_TITLE_PANORAMA\x10\x0e\x12\x1c\n\x18PRESET_TITLE_TIME_WARP_2\x10\x10\x12\x17\n\x13PRESET_TITLE_CUSTOM\x10\x12\x12\x14\n\x10PRESET_TITLE_AIR\x10\x13\x12\x15\n\x11PRESET_TITLE_BIKE\x10\x14\x12\x15\n\x11PRESET_TITLE_EPIC\x10\x15\x12\x17\n\x13PRESET_TITLE_INDOOR\x10\x16\x12\x16\n\x12PRESET_TITLE_MOTOR\x10\x17\x12\x18\n\x14PRESET_TITLE_MOUNTED\x10\x18\x12\x18\n\x14PRESET_TITLE_OUTDOOR\x10\x19\x12\x14\n\x10PRESET_TITLE_POV\x10\x1a\x12\x17\n\x13PRESET_TITLE_SELFIE\x10\x1b\x12\x16\n\x12PRESET_TITLE_SKATE\x10\x1c\x12\x15\n\x11PRESET_TITLE_SNOW\x10\x1d\x12\x16\n\x12PRESET_TITLE_TRAIL\x10\x1e\x12\x17\n\x13PRESET_TITLE_TRAVEL\x10\x1f\x12\x16\n\x12PRESET_TITLE_WATER\x10 \x12\x18\n\x14PRESET_TITLE_LOOPING\x10!\x12\x16\n\x12PRESET_TITLE_STARS\x10"\x12\x17\n\x13PRESET_TITLE_ACTION\x10#\x12\x1b\n\x17PRESET_TITLE_FOLLOW_CAM\x10$\x12\x15\n\x11PRESET_TITLE_SURF\x10%\x12\x15\n\x11PRESET_TITLE_CITY\x10&\x12\x16\n\x12PRESET_TITLE_SHAKY\x10\'\x12\x17\n\x13PRESET_TITLE_CHESTY\x10(\x12\x17\n\x13PRESET_TITLE_HELMET\x10)\x12\x15\n\x11PRESET_TITLE_BITE\x10*\x12!\n\x1dPRESET_TITLE_CUSTOM_CINEMATIC\x10+\x12\x15\n\x11PRESET_TITLE_VLOG\x10,\x12\x14\n\x10PRESET_TITLE_FPV\x10-\x12\x14\n\x10PRESET_TITLE_HDR\x10.\x12\x1a\n\x16PRESET_TITLE_LANDSCAPE\x10/\x12\x14\n\x10PRESET_TITLE_LOG\x100\x12\x1d\n\x19PRESET_TITLE_CUSTOM_SLOMO\x101\x12\x17\n\x13PRESET_TITLE_TRIPOD\x102\x12\x16\n\x12PRESET_TITLE_BASIC\x10:\x12\x1d\n\x19PRESET_TITLE_ULTRA_SLO_MO\x10;\x12#\n\x1fPRESET_TITLE_STANDARD_ENDURANCE\x10<\x12#\n\x1fPRESET_TITLE_ACTIVITY_ENDURANCE\x10=\x12$\n PRESET_TITLE_CINEMATIC_ENDURANCE\x10>\x12 \n\x1cPRESET_TITLE_SLOMO_ENDURANCE\x10?\x12\x1d\n\x19PRESET_TITLE_STATIONARY_1\x10@\x12\x1d\n\x19PRESET_TITLE_STATIONARY_2\x10A\x12\x1d\n\x19PRESET_TITLE_STATIONARY_3\x10B\x12\x1d\n\x19PRESET_TITLE_STATIONARY_4\x10C\x12\x1d\n\x19PRESET_TITLE_SIMPLE_VIDEO\x10D\x12!\n\x1dPRESET_TITLE_SIMPLE_TIME_WARP\x10E\x12#\n\x1fPRESET_TITLE_SIMPLE_SUPER_PHOTO\x10F\x12#\n\x1fPRESET_TITLE_SIMPLE_NIGHT_PHOTO\x10G\x12\'\n#PRESET_TITLE_SIMPLE_VIDEO_ENDURANCE\x10H\x12 \n\x1cPRESET_TITLE_HIGHEST_QUALITY\x10I\x12!\n\x1dPRESET_TITLE_EXTENDED_BATTERY\x10J\x12 \n\x1cPRESET_TITLE_LONGEST_BATTERY\x10K\x12\x1b\n\x17PRESET_TITLE_STAR_TRAIL\x10L\x12\x1f\n\x1bPRESET_TITLE_LIGHT_PAINTING\x10M\x12\x1c\n\x18PRESET_TITLE_LIGHT_TRAIL\x10N\x12\x1b\n\x17PRESET_TITLE_FULL_FRAME\x10O\x12\'\n#PRESET_TITLE_STANDARD_QUALITY_VIDEO\x10R\x12$\n PRESET_TITLE_BASIC_QUALITY_VIDEO\x10S\x12&\n"PRESET_TITLE_HIGHEST_QUALITY_VIDEO\x10]\x12)\n%PRESET_TITLE_USER_DEFINED_CUSTOM_NAME\x10^\x12&\n"PRESET_TITLE_EASY_STANDARD_PROFILE\x10c\x12!\n\x1dPRESET_TITLE_EASY_HDR_PROFILE\x10d\x12\x1c\n\x18PRESET_TITLE_BURST_SLOMO\x10j\x12\x1a\n\x16PRESET_TITLE_4_3_VIDEO\x10}\x12\x1b\n\x17PRESET_TITLE_16_9_VIDEO\x10~\x12\x1b\n\x17PRESET_TITLE_16_9_SLOMO\x10\x7f\x12"\n\x1dPRESET_TITLE_TIME_LAPSE_VIDEO\x10\x83\x01\x12"\n\x1dPRESET_TITLE_TIME_LAPSE_PHOTO\x10\x84\x01\x12#\n\x1ePRESET_TITLE_NIGHT_LAPSE_VIDEO\x10\x85\x01\x12#\n\x1ePRESET_TITLE_NIGHT_LAPSE_PHOTO\x10\x86\x01' ) _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "preset_status_pb2", globals()) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None - _ENUMFLATMODE._serialized_start = 943 - _ENUMFLATMODE._serialized_end = 1610 - _ENUMPRESETGROUP._serialized_start = 1612 - _ENUMPRESETGROUP._serialized_end = 1717 - _ENUMPRESETGROUPICON._serialized_start = 1720 - _ENUMPRESETGROUPICON._serialized_end = 2157 - _ENUMPRESETICON._serialized_start = 2160 - _ENUMPRESETICON._serialized_end = 4591 - _ENUMPRESETTITLE._serialized_start = 4594 - _ENUMPRESETTITLE._serialized_end = 7057 + _ENUMFLATMODE._serialized_start = 990 + _ENUMFLATMODE._serialized_end = 1657 + _ENUMPRESETGROUP._serialized_start = 1660 + _ENUMPRESETGROUP._serialized_end = 1795 + _ENUMPRESETGROUPICON._serialized_start = 1798 + _ENUMPRESETGROUPICON._serialized_end = 2235 + _ENUMPRESETICON._serialized_start = 2238 + _ENUMPRESETICON._serialized_end = 4669 + _ENUMPRESETTITLE._serialized_start = 4672 + _ENUMPRESETTITLE._serialized_end = 7135 _NOTIFYPRESETSTATUS._serialized_start = 59 _NOTIFYPRESETSTATUS._serialized_end = 132 _PRESET._serialized_start = 135 @@ -37,6 +34,6 @@ _REQUESTPRESETSETVISIBILITY._serialized_start = 603 _REQUESTPRESETSETVISIBILITY._serialized_end = 660 _PRESETGROUP._serialized_start = 663 - _PRESETGROUP._serialized_end = 876 - _PRESETSETTING._serialized_start = 878 - _PRESETSETTING._serialized_end = 940 + _PRESETGROUP._serialized_end = 923 + _PRESETSETTING._serialized_start = 925 + _PRESETSETTING._serialized_end = 987 diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/preset_status_pb2.pyi b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/preset_status_pb2.pyi index 79fd75f81..5e4ddc7a1 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/preset_status_pb2.pyi +++ b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/preset_status_pb2.pyi @@ -90,12 +90,14 @@ class _EnumPresetGroupEnumTypeWrapper( PRESET_GROUP_ID_VIDEO: _EnumPresetGroup.ValueType PRESET_GROUP_ID_PHOTO: _EnumPresetGroup.ValueType PRESET_GROUP_ID_TIMELAPSE: _EnumPresetGroup.ValueType + PRESET_GROUP_ID_GENERAL: _EnumPresetGroup.ValueType class EnumPresetGroup(_EnumPresetGroup, metaclass=_EnumPresetGroupEnumTypeWrapper): ... PRESET_GROUP_ID_VIDEO: EnumPresetGroup.ValueType PRESET_GROUP_ID_PHOTO: EnumPresetGroup.ValueType PRESET_GROUP_ID_TIMELAPSE: EnumPresetGroup.ValueType +PRESET_GROUP_ID_GENERAL: EnumPresetGroup.ValueType global___EnumPresetGroup = EnumPresetGroup class _EnumPresetGroupIcon: @@ -736,6 +738,8 @@ class PresetGroup(google.protobuf.message.Message): CAN_ADD_PRESET_FIELD_NUMBER: builtins.int ICON_FIELD_NUMBER: builtins.int MODE_ARRAY_FIELD_NUMBER: builtins.int + CUSTOM_NAME_FIELD_NUMBER: builtins.int + ACTIVE_PRESET_ID_FIELD_NUMBER: builtins.int id: global___EnumPresetGroup.ValueType "Preset Group ID" @@ -752,6 +756,10 @@ class PresetGroup(google.protobuf.message.Message): self, ) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[global___EnumFlatMode.ValueType]: """A list of flatmodes available for this preset group""" + custom_name: builtins.str + "Custom string name given to this preset group" + active_preset_id: builtins.int + "Active preset id in this group" def __init__( self, @@ -760,16 +768,34 @@ class PresetGroup(google.protobuf.message.Message): preset_array: collections.abc.Iterable[global___Preset] | None = ..., can_add_preset: builtins.bool | None = ..., icon: global___EnumPresetGroupIcon.ValueType | None = ..., - mode_array: collections.abc.Iterable[global___EnumFlatMode.ValueType] | None = ... + mode_array: collections.abc.Iterable[global___EnumFlatMode.ValueType] | None = ..., + custom_name: builtins.str | None = ..., + active_preset_id: builtins.int | None = ... ) -> None: ... def HasField( - self, field_name: typing_extensions.Literal["can_add_preset", b"can_add_preset", "icon", b"icon", "id", b"id"] + self, + field_name: typing_extensions.Literal[ + "active_preset_id", + b"active_preset_id", + "can_add_preset", + b"can_add_preset", + "custom_name", + b"custom_name", + "icon", + b"icon", + "id", + b"id", + ], ) -> builtins.bool: ... def ClearField( self, field_name: typing_extensions.Literal[ + "active_preset_id", + b"active_preset_id", "can_add_preset", b"can_add_preset", + "custom_name", + b"custom_name", "icon", b"icon", "id", diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/request_get_camera_capabilities_pb2.py b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/request_get_camera_capabilities_pb2.py new file mode 100644 index 000000000..8a37c0737 --- /dev/null +++ b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/request_get_camera_capabilities_pb2.py @@ -0,0 +1,23 @@ +"""Generated protocol buffer code.""" + +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder + +_sym_db = _symbol_database.Default() +from . import response_generic_pb2 as response__generic__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n%request_get_camera_capabilities.proto\x12\nopen_gopro\x1a\x16response_generic.proto"\x1e\n\x1cRequestGetCameraCapabilities"\x9a\x01\n\x1dResponseGetCameraCapabilities\x12-\n\x06result\x18\x01 \x02(\x0e2\x1d.open_gopro.EnumResultGeneric\x12\x16\n\x0eschema_version\x18\x02 \x02(\t\x122\n\x08protocol\x18\x03 \x01(\x0b2 .open_gopro.ProtocolCapabilities"9\n\x14ProtocolCapabilities\x12!\n\x12supports_2byte_ids\x18\x01 \x01(\x08:\x05false' +) +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "request_get_camera_capabilities_pb2", globals()) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + _REQUESTGETCAMERACAPABILITIES._serialized_start = 77 + _REQUESTGETCAMERACAPABILITIES._serialized_end = 107 + _RESPONSEGETCAMERACAPABILITIES._serialized_start = 110 + _RESPONSEGETCAMERACAPABILITIES._serialized_end = 264 + _PROTOCOLCAPABILITIES._serialized_start = 266 + _PROTOCOLCAPABILITIES._serialized_end = 323 diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/request_get_camera_capabilities_pb2.pyi b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/request_get_camera_capabilities_pb2.pyi new file mode 100644 index 000000000..3e67e343c --- /dev/null +++ b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/request_get_camera_capabilities_pb2.pyi @@ -0,0 +1,96 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +* +Defines the structure of protobuf messages for querying camera capabilities +""" + +import builtins +import google.protobuf.descriptor +import google.protobuf.message +from . import response_generic_pb2 +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class RequestGetCameraCapabilities(google.protobuf.message.Message): + """* + Get the camera capabilities + + Returns a @ref ResponseGetCameraCapabilities + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + def __init__(self) -> None: ... + +global___RequestGetCameraCapabilities = RequestGetCameraCapabilities + +@typing_extensions.final +class ResponseGetCameraCapabilities(google.protobuf.message.Message): + """* + Camera Capabilities + + Message is sent in response to a @ref RequestGetCameraCapabilities. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + RESULT_FIELD_NUMBER: builtins.int + SCHEMA_VERSION_FIELD_NUMBER: builtins.int + PROTOCOL_FIELD_NUMBER: builtins.int + result: response_generic_pb2.EnumResultGeneric.ValueType + "Generic pass/fail/error info" + schema_version: builtins.str + 'Capability schema version (e.g., "camera-capabilities/v1.0")' + + @property + def protocol(self) -> global___ProtocolCapabilities: + """Protocol-level capabilities""" + + def __init__( + self, + *, + result: response_generic_pb2.EnumResultGeneric.ValueType | None = ..., + schema_version: builtins.str | None = ..., + protocol: global___ProtocolCapabilities | None = ... + ) -> None: ... + def HasField( + self, + field_name: typing_extensions.Literal[ + "protocol", b"protocol", "result", b"result", "schema_version", b"schema_version" + ], + ) -> builtins.bool: ... + def ClearField( + self, + field_name: typing_extensions.Literal[ + "protocol", b"protocol", "result", b"result", "schema_version", b"schema_version" + ], + ) -> None: ... + +global___ResponseGetCameraCapabilities = ResponseGetCameraCapabilities + +@typing_extensions.final +class ProtocolCapabilities(google.protobuf.message.Message): + """* + Protocol capability information + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + SUPPORTS_2BYTE_IDS_FIELD_NUMBER: builtins.int + supports_2byte_ids: builtins.bool + "Does the camera support 2-byte setting/status IDs" + + def __init__(self, *, supports_2byte_ids: builtins.bool | None = ...) -> None: ... + def HasField( + self, field_name: typing_extensions.Literal["supports_2byte_ids", b"supports_2byte_ids"] + ) -> builtins.bool: ... + def ClearField( + self, field_name: typing_extensions.Literal["supports_2byte_ids", b"supports_2byte_ids"] + ) -> None: ... + +global___ProtocolCapabilities = ProtocolCapabilities diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/request_get_preset_status_pb2.py b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/request_get_preset_status_pb2.py index d636d7092..48ab677b6 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/request_get_preset_status_pb2.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/request_get_preset_status_pb2.py @@ -1,6 +1,3 @@ -# request_get_preset_status_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:46 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/response_generic_pb2.py b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/response_generic_pb2.py index 097536981..534196641 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/response_generic_pb2.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/response_generic_pb2.py @@ -1,6 +1,3 @@ -# response_generic_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:46 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/set_camera_control_status_pb2.py b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/set_camera_control_status_pb2.py index aa7e8adff..97b39bee8 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/set_camera_control_status_pb2.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/set_camera_control_status_pb2.py @@ -1,6 +1,3 @@ -# set_camera_control_status_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:46 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/turbo_transfer_pb2.py b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/turbo_transfer_pb2.py index 9ce43f3ee..c3a649b02 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/turbo_transfer_pb2.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/models/proto/turbo_transfer_pb2.py @@ -1,6 +1,3 @@ -# turbo_transfer_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:46 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/network/ble/adapters/bleak_wrapper.py b/demos/python/sdk_wireless_camera_control/open_gopro/network/ble/adapters/bleak_wrapper.py index 1d06dce45..fae2267aa 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/network/ble/adapters/bleak_wrapper.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/network/ble/adapters/bleak_wrapper.py @@ -71,10 +71,13 @@ class BleakWrapperController(BLEController[BleakDevice, bleak.BleakClient], Sing Args: exception_handler (Callable | None): Used to catch asyncio exceptions from other tasks. Defaults to None. + rich_gatt_querying (bool): If True, read descriptor values during GATT discovery. This provides + richer data for GATT CSV exports but may fail on some camera firmware. Defaults to False. """ - def __init__(self, exception_handler: Callable | None = None) -> None: - BLEController.__init__(self, exception_handler) + def __init__(self, exception_handler: Callable | None = None, rich_gatt_querying: bool = False) -> None: + BLEController.__init__(self, exception_handler, rich_gatt_querying) + self._ble_op_lock = asyncio.Lock() async def read(self, handle: bleak.BleakClient, uuid: BleUUID) -> bytearray: """Read data from a BleUUID. @@ -86,10 +89,11 @@ async def read(self, handle: bleak.BleakClient, uuid: BleUUID) -> bytearray: Returns: bytearray: read data """ - logger.debug(f"Reading from {uuid}") - response = await handle.read_gatt_char(uuid2bleak_string(uuid)) - logger.debug(f'Received response on BleUUID [{uuid}]: {response.hex( ":")}') - return response + async with self._ble_op_lock: + logger.debug(f"Reading from {uuid}") + response = await handle.read_gatt_char(uuid2bleak_string(uuid)) + logger.debug(f'Received response on BleUUID [{uuid}]: {response.hex(":")}') + return response async def write(self, handle: bleak.BleakClient, uuid: BleUUID, data: bytes) -> None: """Write data to a BleUUID. @@ -99,8 +103,9 @@ async def write(self, handle: bleak.BleakClient, uuid: BleUUID, data: bytes) -> uuid (BleUUID): characteristic BleUUID to write to data (bytes): data to write """ - logger.debug(f"Writing to {uuid}: {uuid.hex}") - await handle.write_gatt_char(uuid2bleak_string(uuid), data, response=True) + async with self._ble_op_lock: + logger.debug(f"Writing to {uuid}: {uuid.hex}") + await handle.write_gatt_char(uuid2bleak_string(uuid), data, response=True) async def scan( self, token: Pattern, timeout: int = 5, service_uuids: Optional[list[BleUUID]] = None @@ -375,15 +380,31 @@ def bleak_props_adapter(bleak_props: list[CharacteristicPropertyName]) -> CharPr # Get any descriptors if they exist descriptors: list[Descriptor] = [] for descriptor in char.descriptors: + descriptor_uuid = ( + uuids[descriptor.uuid] + if uuids and descriptor.uuid in uuids + else BleUUID(descriptor.description, hex=descriptor.uuid) + ) + # Only read descriptor values if rich_gatt_querying is enabled. + # Some camera firmware returns None for descriptor values, which causes + # bleak's CoreBluetooth backend to crash with an assertion error. + # Descriptor values are only used for GATT CSV export, not SDK operations. + descriptor_value: bytes | None = None + if self._rich_gatt_querying: + try: + descriptor_value = await handle.read_gatt_descriptor(descriptor.handle) + except Exception as e: # pylint: disable=broad-exception-caught + logger.warning( + f"Could not read descriptor value for [{descriptor_uuid.name}] " + f"(handle={descriptor.handle}, uuid={descriptor.uuid}) " + f"on characteristic [{char.uuid}]: {type(e).__name__}: {e}. " + f"This may indicate a camera firmware issue." + ) descriptors.append( Descriptor( handle=descriptor.handle, - uuid=( - uuids[descriptor.uuid] - if uuids and descriptor.uuid in uuids - else BleUUID(descriptor.description, hex=descriptor.uuid) - ), - value=await handle.read_gatt_descriptor(descriptor.handle), + uuid=descriptor_uuid, + value=descriptor_value, ) ) # Create new characteristic diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/network/ble/controller.py b/demos/python/sdk_wireless_camera_control/open_gopro/network/ble/controller.py index 91e37b39d..f32f4c8ba 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/network/ble/controller.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/network/ble/controller.py @@ -22,8 +22,9 @@ class BLEController(ABC, Generic[BleDevice, BleHandle]): """Interface definition for a BLE driver to be used by GoPro.""" - def __init__(self, exception_handler: Optional[Callable] = None) -> None: + def __init__(self, exception_handler: Optional[Callable] = None, rich_gatt_querying: bool = False) -> None: self._exception_handler = exception_handler + self._rich_gatt_querying = rich_gatt_querying @abstractmethod async def read(self, handle: BleHandle, uuid: BleUUID) -> bytes: diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/network/wifi/adapters/wireless.py b/demos/python/sdk_wireless_camera_control/open_gopro/network/wifi/adapters/wireless.py index c83c13ce6..24e5b5532 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/network/wifi/adapters/wireless.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/network/wifi/adapters/wireless.py @@ -727,10 +727,10 @@ def _sync_connect() -> bool: # Escape single quotes ssid = ssid.replace(r"'", '''"'"''') - # On macOS 15+, system_profiler redacts SSID names, so we skip explicit scanning - # and rely on networksetup's internal scanning when attempting to connect version = Version(platform.mac_ver()[0]) + if version < Version("15"): + # On macOS < 15, use system_profiler for scanning logger.info(f"Scanning for {ssid}...") start = time.time() discovered = False @@ -741,63 +741,77 @@ def _sync_connect() -> bool: r"\n\s+([\x20-\x7E]{1,32}):\n\s+PHY Mode:" ) # 0x20...0x7E --> ASCII for printable characters if ssid in sorted(regex.findall(response)): + discovered = True break time.sleep(1) - else: + if not discovered: logger.warning("Wifi Scan timed out") return False - else: - # On macOS 15+, we can't pre-scan due to SSID redaction, so we'll attempt - # connection directly. networksetup will scan internally and return error if not found. - logger.info(f"Attempting to connect to {ssid} without explicitly scanning first...") - # Check version once for use in connection logic - # If we're already connected, return (skip on macOS 15+ where current() can hang) - if version < Version("15"): + # If we're already connected, return if self.current()[0] == ssid: logger.info("Wifi already connected") return True - # Connect now that we found the ssid - logger.info(f"Connecting to {ssid}...") - response = cmd(f"networksetup -setairportnetwork '{self.interface}' '{ssid}' '{password}'") + # Connect now that we found the ssid + logger.info(f"Connecting to {ssid}...") + response = cmd(f"networksetup -setairportnetwork '{self.interface}' '{ssid}' '{password}'") - if "not find" in response.lower(): - logger.warning("Network was not found.") - return False - - # Check if we're on macOS 15+ where SSID verification doesn't work - if version >= Version("15"): - # On macOS 15+, we can't verify the SSID due to redaction, so we just - # check that we're connected to *some* network after a brief wait - logger.debug("macOS 15+: Skipping SSID verification, checking for any connection...") - time.sleep(2) # Give connection time to establish - current, state = self.current() - if state == SsidState.CONNECTED: - logger.info("Connected to network (SSID redacted by macOS)") - # Additional delay for network to be ready - time.sleep(3) - return True - else: - logger.warning("No connection established after networksetup command") + if "not find" in response.lower(): + logger.warning("Network was not found during connection attempt.") return False - # For macOS < 15, we can verify the actual SSID - # Now wait for network to actually establish - current = self.current()[0] - logger.debug(f"current wifi: {current}") - while current is not None and ssid not in current and timeout > 0: - time.sleep(1) + # Wait for network to actually establish current = self.current()[0] logger.debug(f"current wifi: {current}") - timeout -= 1 - if timeout == 0: - return False - - # There is some delay required here, presumably because the network is not ready. - time.sleep(5) + while current is not None and ssid not in current and timeout > 0: + time.sleep(1) + current = self.current()[0] + logger.debug(f"current wifi: {current}") + timeout -= 1 + if timeout == 0: + return False + + # There is some delay required here, presumably because the network is not ready. + time.sleep(5) + return True - return True + else: + # On macOS 15+, SSIDs are redacted in system tools, so we use retry-based connection. + # The GoPro's WiFi AP takes time to become discoverable after being enabled via BLE. + # We retry the networksetup command with delays between attempts. + logger.info(f"Attempting to connect to {ssid} (macOS 15+ with retry logic)...") + + # Internal retry loop with increasing delays + # The network typically becomes visible within 5-10 seconds of AP enable + max_internal_retries = 5 + retry_delays = [2, 3, 4, 5, 5] # seconds to wait before each retry + + for retry_attempt in range(max_internal_retries): + logger.info(f"Connection attempt {retry_attempt + 1}/{max_internal_retries}...") + response = cmd(f"networksetup -setairportnetwork '{self.interface}' '{ssid}' '{password}'") + + if "not find" not in response.lower(): + # Connection command succeeded (or at least didn't fail with "not found") + logger.debug("macOS 15+: Checking connection status...") + time.sleep(2) # Give connection time to establish + current, state = self.current() + if state == SsidState.CONNECTED: + logger.info("Connected to network (SSID redacted by macOS)") + # Additional delay for network interface to be fully ready + time.sleep(3) + return True + else: + logger.warning("networksetup succeeded but no connection established") + + # Network not found or connection failed - wait before retry + if retry_attempt < max_internal_retries - 1: + delay = retry_delays[retry_attempt] + logger.info(f"Network not yet visible, waiting {delay}s before retry...") + time.sleep(delay) + + logger.warning(f"Failed to connect to {ssid} after {max_internal_retries} attempts") + return False return await asyncio.to_thread(_sync_connect) diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/network/wifi/client.py b/demos/python/sdk_wireless_camera_control/open_gopro/network/wifi/client.py index d54201a2b..bb9f1e4c7 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/network/wifi/client.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/network/wifi/client.py @@ -68,7 +68,7 @@ def is_connected(self) -> bool: Returns: bool: True if yes, False if no """ - (ssid, state) = self._controller.current() + ssid, state = self._controller.current() # On modern macOS (15+), SSID may be None even when connected due to privacy redaction # So we primarily check the connection state return state is SsidState.CONNECTED diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/network/wifi/controller.py b/demos/python/sdk_wireless_camera_control/open_gopro/network/wifi/controller.py index c382258ce..bb81d56fe 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/network/wifi/controller.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/network/wifi/controller.py @@ -113,14 +113,12 @@ def interface(self, interface: Optional[str]) -> None: if detected_interfaces: self._interface = detected_interfaces[0] else: - raise InterfaceConfigFailure( - """ + raise InterfaceConfigFailure(""" Can't auto-assign Wifi interface because no suitable interface was found. Is there an available Wifi interface on this computer? To verify this, try: - MacOS: networksetup -listallhardwareports - Linux: nmcli dev - - Windows: netsh wlan show interfaces""" - ) + - Windows: netsh wlan show interfaces""") @abstractmethod def power(self, power: bool) -> bool: diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/util/__init__.py b/demos/python/sdk_wireless_camera_control/open_gopro/util/__init__.py index 93340973a..e512df219 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/util/__init__.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/util/__init__.py @@ -5,7 +5,6 @@ from .util import ( Singleton, - SnapshotQueue, add_cli_args_and_parse, ainput, cmd, diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/util/util.py b/demos/python/sdk_wireless_camera_control/open_gopro/util/util.py index 02c57535c..eb6d7f199 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/util/util.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/util/util.py @@ -14,7 +14,7 @@ from dataclasses import is_dataclass from datetime import datetime from pathlib import Path -from typing import TYPE_CHECKING, Any, Callable, Generic, TypeVar +from typing import TYPE_CHECKING, Any, Callable import pytz from construct import Container @@ -225,35 +225,6 @@ def cmd(command: str) -> str: return response -T = TypeVar("T") - - -class SnapshotQueue(asyncio.Queue, Generic[T]): - """A subclass of the default queue module to safely take a snapshot of the queue - - This is so we can access the elements (in a thread safe manner) without dequeuing them. - """ - - def __init__(self, maxsize: int = 0) -> None: - self._lock = asyncio.Lock() - super().__init__(maxsize) - - async def peek_front(self) -> T | None: - """Get the first element without dequeueing it - - Returns: - T | None: First element of None if the queue is empty - """ - return None if self.empty() else self._queue[0] # type: ignore - - async def __aenter__(self) -> SnapshotQueue[T]: - await self._lock.__aenter__() - return self - - async def __aexit__(self, exc_type: Any, exc: Any, tb: Any) -> None: - return await self._lock.__aexit__(exc_type, exc, tb) - - def add_cli_args_and_parse( parser: argparse.ArgumentParser, bluetooth: bool = True, diff --git a/demos/python/sdk_wireless_camera_control/poetry.lock b/demos/python/sdk_wireless_camera_control/poetry.lock index 908c9daa4..22596100d 100644 --- a/demos/python/sdk_wireless_camera_control/poetry.lock +++ b/demos/python/sdk_wireless_camera_control/poetry.lock @@ -38,14 +38,14 @@ files = [ [[package]] name = "astroid" -version = "4.0.1" +version = "4.0.4" description = "An abstract syntax tree for Python with inference support." optional = false python-versions = ">=3.10.0" groups = ["dev"] files = [ - {file = "astroid-4.0.1-py3-none-any.whl", hash = "sha256:37ab2f107d14dc173412327febf6c78d39590fdafcb44868f03b6c03452e3db0"}, - {file = "astroid-4.0.1.tar.gz", hash = "sha256:0d778ec0def05b935e198412e62f9bcca8b3b5c39fdbe50b0ba074005e477aab"}, + {file = "astroid-4.0.4-py3-none-any.whl", hash = "sha256:52f39653876c7dec3e3afd4c2696920e05c83832b9737afc21928f2d2eb7a753"}, + {file = "astroid-4.0.4.tar.gz", hash = "sha256:986fed8bcf79fb82c78b18a53352a0b287a73817d6dbcfba3162da36667c49a0"}, ] [[package]] @@ -111,14 +111,14 @@ type-checking = ["mypy (>=1.9,<2.0)", "types-docutils (>=0.20,<0.21)", "typing-e [[package]] name = "babel" -version = "2.17.0" +version = "2.18.0" description = "Internationalization utilities" optional = false python-versions = ">=3.8" groups = ["dev"] files = [ - {file = "babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2"}, - {file = "babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d"}, + {file = "babel-2.18.0-py3-none-any.whl", hash = "sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35"}, + {file = "babel-2.18.0.tar.gz", hash = "sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d"}, ] [package.extras] @@ -126,43 +126,48 @@ dev = ["backports.zoneinfo ; python_version < \"3.9\"", "freezegun (>=1.0,<2.0)" [[package]] name = "black" -version = "25.9.0" +version = "26.1.0" description = "The uncompromising code formatter." optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "black-25.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ce41ed2614b706fd55fd0b4a6909d06b5bab344ffbfadc6ef34ae50adba3d4f7"}, - {file = "black-25.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2ab0ce111ef026790e9b13bd216fa7bc48edd934ffc4cbf78808b235793cbc92"}, - {file = "black-25.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f96b6726d690c96c60ba682955199f8c39abc1ae0c3a494a9c62c0184049a713"}, - {file = "black-25.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:d119957b37cc641596063cd7db2656c5be3752ac17877017b2ffcdb9dfc4d2b1"}, - {file = "black-25.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:456386fe87bad41b806d53c062e2974615825c7a52159cde7ccaeb0695fa28fa"}, - {file = "black-25.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a16b14a44c1af60a210d8da28e108e13e75a284bf21a9afa6b4571f96ab8bb9d"}, - {file = "black-25.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aaf319612536d502fdd0e88ce52d8f1352b2c0a955cc2798f79eeca9d3af0608"}, - {file = "black-25.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:c0372a93e16b3954208417bfe448e09b0de5cc721d521866cd9e0acac3c04a1f"}, - {file = "black-25.9.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1b9dc70c21ef8b43248f1d86aedd2aaf75ae110b958a7909ad8463c4aa0880b0"}, - {file = "black-25.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8e46eecf65a095fa62e53245ae2795c90bdecabd53b50c448d0a8bcd0d2e74c4"}, - {file = "black-25.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9101ee58ddc2442199a25cb648d46ba22cd580b00ca4b44234a324e3ec7a0f7e"}, - {file = "black-25.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:77e7060a00c5ec4b3367c55f39cf9b06e68965a4f2e61cecacd6d0d9b7ec945a"}, - {file = "black-25.9.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0172a012f725b792c358d57fe7b6b6e8e67375dd157f64fa7a3097b3ed3e2175"}, - {file = "black-25.9.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3bec74ee60f8dfef564b573a96b8930f7b6a538e846123d5ad77ba14a8d7a64f"}, - {file = "black-25.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b756fc75871cb1bcac5499552d771822fd9db5a2bb8db2a7247936ca48f39831"}, - {file = "black-25.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:846d58e3ce7879ec1ffe816bb9df6d006cd9590515ed5d17db14e17666b2b357"}, - {file = "black-25.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ef69351df3c84485a8beb6f7b8f9721e2009e20ef80a8d619e2d1788b7816d47"}, - {file = "black-25.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e3c1f4cd5e93842774d9ee4ef6cd8d17790e65f44f7cdbaab5f2cf8ccf22a823"}, - {file = "black-25.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:154b06d618233fe468236ba1f0e40823d4eb08b26f5e9261526fde34916b9140"}, - {file = "black-25.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:e593466de7b998374ea2585a471ba90553283fb9beefcfa430d84a2651ed5933"}, - {file = "black-25.9.0-py3-none-any.whl", hash = "sha256:474b34c1342cdc157d307b56c4c65bce916480c4a8f6551fdc6bf9b486a7c4ae"}, - {file = "black-25.9.0.tar.gz", hash = "sha256:0474bca9a0dd1b51791fcc507a4e02078a1c63f6d4e4ae5544b9848c7adfb619"}, + {file = "black-26.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ca699710dece84e3ebf6e92ee15f5b8f72870ef984bf944a57a777a48357c168"}, + {file = "black-26.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5e8e75dabb6eb83d064b0db46392b25cabb6e784ea624219736e8985a6b3675d"}, + {file = "black-26.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eb07665d9a907a1a645ee41a0df8a25ffac8ad9c26cdb557b7b88eeeeec934e0"}, + {file = "black-26.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:7ed300200918147c963c87700ccf9966dceaefbbb7277450a8d646fc5646bf24"}, + {file = "black-26.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:c5b7713daea9bf943f79f8c3b46f361cc5229e0e604dcef6a8bb6d1c37d9df89"}, + {file = "black-26.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3cee1487a9e4c640dc7467aaa543d6c0097c391dc8ac74eb313f2fbf9d7a7cb5"}, + {file = "black-26.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d62d14ca31c92adf561ebb2e5f2741bf8dea28aef6deb400d49cca011d186c68"}, + {file = "black-26.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb1dafbbaa3b1ee8b4550a84425aac8874e5f390200f5502cf3aee4a2acb2f14"}, + {file = "black-26.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:101540cb2a77c680f4f80e628ae98bd2bd8812fb9d72ade4f8995c5ff019e82c"}, + {file = "black-26.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:6f3977a16e347f1b115662be07daa93137259c711e526402aa444d7a88fdc9d4"}, + {file = "black-26.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6eeca41e70b5f5c84f2f913af857cf2ce17410847e1d54642e658e078da6544f"}, + {file = "black-26.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dd39eef053e58e60204f2cdf059e2442e2eb08f15989eefe259870f89614c8b6"}, + {file = "black-26.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9459ad0d6cd483eacad4c6566b0f8e42af5e8b583cee917d90ffaa3778420a0a"}, + {file = "black-26.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:a19915ec61f3a8746e8b10adbac4a577c6ba9851fa4a9e9fbfbcf319887a5791"}, + {file = "black-26.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:643d27fb5facc167c0b1b59d0315f2674a6e950341aed0fc05cf307d22bf4954"}, + {file = "black-26.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ba1d768fbfb6930fc93b0ecc32a43d8861ded16f47a40f14afa9bb04ab93d304"}, + {file = "black-26.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2b807c240b64609cb0e80d2200a35b23c7df82259f80bef1b2c96eb422b4aac9"}, + {file = "black-26.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1de0f7d01cc894066a1153b738145b194414cc6eeaad8ef4397ac9abacf40f6b"}, + {file = "black-26.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:91a68ae46bf07868963671e4d05611b179c2313301bd756a89ad4e3b3db2325b"}, + {file = "black-26.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:be5e2fe860b9bd9edbf676d5b60a9282994c03fbbd40fe8f5e75d194f96064ca"}, + {file = "black-26.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:9dc8c71656a79ca49b8d3e2ce8103210c9481c57798b48deeb3a8bb02db5f115"}, + {file = "black-26.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b22b3810451abe359a964cc88121d57f7bce482b53a066de0f1584988ca36e79"}, + {file = "black-26.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:53c62883b3f999f14e5d30b5a79bd437236658ad45b2f853906c7cbe79de00af"}, + {file = "black-26.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:f016baaadc423dc960cdddf9acae679e71ee02c4c341f78f3179d7e4819c095f"}, + {file = "black-26.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:66912475200b67ef5a0ab665011964bf924745103f51977a78b4fb92a9fc1bf0"}, + {file = "black-26.1.0-py3-none-any.whl", hash = "sha256:1054e8e47ebd686e078c0bb0eaf31e6ce69c966058d122f2c0c950311f9f3ede"}, + {file = "black-26.1.0.tar.gz", hash = "sha256:d294ac3340eef9c9eb5d29288e96dc719ff269a88e27b396340459dd85da4c58"}, ] [package.dependencies] click = ">=8.0.0" mypy-extensions = ">=0.4.3" packaging = ">=22.0" -pathspec = ">=0.9.0" +pathspec = ">=1.0.0" platformdirs = ">=2" -pytokens = ">=0.1.10" +pytokens = ">=0.3.0" [package.extras] colorama = ["colorama (>=0.4.3)"] @@ -172,14 +177,14 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "bleak" -version = "1.1.1" +version = "2.1.1" description = "Bluetooth Low Energy platform Agnostic Klient" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "bleak-1.1.1-py3-none-any.whl", hash = "sha256:e601371396e357d95ee3c256db65b7da624c94ef6f051d47dfce93ea8361c22e"}, - {file = "bleak-1.1.1.tar.gz", hash = "sha256:eeef18053eb3bd569a25bff62cd4eb9ee56be4d84f5321023a7c4920943e6ccb"}, + {file = "bleak-2.1.1-py3-none-any.whl", hash = "sha256:61ac1925073b580c896a92a8c404088c5e5ec9dc3c5bd6fc17554a15779d83de"}, + {file = "bleak-2.1.1.tar.gz", hash = "sha256:4600cc5852f2392ce886547e127623f188e689489c5946d422172adf80635cf9"}, ] [package.dependencies] @@ -193,6 +198,7 @@ winrt-runtime = {version = ">=3.1", markers = "platform_system == \"Windows\""} "winrt-Windows.Devices.Bluetooth.Advertisement" = {version = ">=3.1", markers = "platform_system == \"Windows\""} "winrt-Windows.Devices.Bluetooth.GenericAttributeProfile" = {version = ">=3.1", markers = "platform_system == \"Windows\""} "winrt-Windows.Devices.Enumeration" = {version = ">=3.1", markers = "platform_system == \"Windows\""} +"winrt-Windows.Devices.Radios" = {version = ">=3.1", markers = "platform_system == \"Windows\""} "winrt-Windows.Foundation" = {version = ">=3.1", markers = "platform_system == \"Windows\""} "winrt-Windows.Foundation.Collections" = {version = ">=3.1", markers = "platform_system == \"Windows\""} "winrt-Windows.Storage.Streams" = {version = ">=3.1", markers = "platform_system == \"Windows\""} @@ -245,14 +251,14 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2025.10.5" +version = "2026.1.4" 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-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c"}, + {file = "certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120"}, ] [[package]] @@ -380,14 +386,14 @@ files = [ [[package]] name = "click" -version = "8.3.0" +version = "8.3.1" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.10" groups = ["dev"] 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] @@ -439,104 +445,118 @@ typing_extensions = ">=4.6.0" [[package]] name = "coverage" -version = "7.11.1" +version = "7.13.4" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "coverage-7.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:057c0aedcade895c0d25c06daff00fb381dea8089434ec916e59b051e5dead68"}, - {file = "coverage-7.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ea73d4b5a489ea60ebce592ea516089d2bee8b299fb465fdd295264da98b2480"}, - {file = "coverage-7.11.1-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:63f837e043f7f0788c2ce8fc6bbbcc3579f123af9cb284e1334099969222ceab"}, - {file = "coverage-7.11.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:086764f9fa6f4fa57035ed1c2387501c57092f2159bf1be0f090f85f9042ccf2"}, - {file = "coverage-7.11.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1a30a6ba3b668227d5a6f9f6ac2d875117af20f260ddc01619487174036a5583"}, - {file = "coverage-7.11.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:2663b19df42932a2cd66e62783f4bbbca047853ede893d48f3271c5e12c89246"}, - {file = "coverage-7.11.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b8c6570122b2eafaa5f4b54700b6f17ee10e23c5cf4292fa9b5a00e9dc279a74"}, - {file = "coverage-7.11.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:2cf57b5be59d36d133c06103f50c72bfdba7c7624d68b443b16a2d2d4eb40424"}, - {file = "coverage-7.11.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:f3f3eb204cbe221ef9209e34341b3d0bc32f4cf3c7c4f150db571e20b9963ecd"}, - {file = "coverage-7.11.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:57d36cb40ad55fe443bb2390c759c61b9fa3afc68d5446a2aaed1ad18fc92752"}, - {file = "coverage-7.11.1-cp310-cp310-win32.whl", hash = "sha256:999a82a2dec9e31df7cb49a17e6b564b76fab3f9cd76788280997b5a694b8025"}, - {file = "coverage-7.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:d47ad0fdc96d5772fcded1a57f042a72dba893a226d3efa5802d0bfa88e3a9a1"}, - {file = "coverage-7.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9f8be6327cb57e73f1933a111b31ca3e8db68eba70921244296cd9541f8405cf"}, - {file = "coverage-7.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3386b3d974eea5b8fbc31388c2847d5b3ce783aa001048c7c13ad0e0f9f97284"}, - {file = "coverage-7.11.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:dd5a0e53989aa0d2b94871ac9a990f7b6247c3afe49af77f8750d7bcf1e66efa"}, - {file = "coverage-7.11.1-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e17d99e4a9989ccc52d672543ed9d8741d90730ba331d452793be5733b4fee58"}, - {file = "coverage-7.11.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2ece0ace8d8fc20cc29e2108d4031517c03d9e08883f10c1df16bef84d469110"}, - {file = "coverage-7.11.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:54bf4a13bfcf6f07c4b7d83970074dc2fa8b5782e8dee962f5eb4dfbc3a275ef"}, - {file = "coverage-7.11.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b48e85160795648323fc3a9d8efe11be65a033b564e1db28b53866810da6cf35"}, - {file = "coverage-7.11.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4b77e7bb5765988a7a80463b999085cd66c6515113fc88b46910217f19ee99fe"}, - {file = "coverage-7.11.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:ce345819ddedcbe797d8ba824deeb0d55710037dfd47efd95709ab9e1b841e0c"}, - {file = "coverage-7.11.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:abde2bd52560527124d9e6515daa1f1e3c7e820a37af63d063723867775220aa"}, - {file = "coverage-7.11.1-cp311-cp311-win32.whl", hash = "sha256:049883a469ec823b1c9556050380e61f580d52f8abfc8be2071f3512a2bc3859"}, - {file = "coverage-7.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:784a9fe33335296857db05b97dcb16df811418515a2355fc4811b0c2b029b4be"}, - {file = "coverage-7.11.1-cp311-cp311-win_arm64.whl", hash = "sha256:2bcfeb983a53f0d3ee3ebc004827723d8accb619f64bf90aff73b7703dfe14bd"}, - {file = "coverage-7.11.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:421e2d237dcecdefa9b77cae1aa0dfff5c495f29e053e776172457e289976311"}, - {file = "coverage-7.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:08ef89c812072ecd52a862b46e131f75596475d23cc7f5a75410394341d4332f"}, - {file = "coverage-7.11.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bc6e0b2d6ed317810b4e435ffabc31b2d517d6ceb4183dfd6af4748c52d170eb"}, - {file = "coverage-7.11.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b59736704df8b1f8b1dafb36b16f2ef8a952e4410465634442459426bd2319ae"}, - {file = "coverage-7.11.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:843816452d8bfc4c2be72546b3b382850cb91150feaa963ec7d2b665ec9d4768"}, - {file = "coverage-7.11.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:19363046125d4a423c25d3d7c90bab3a0230932c16014198f87a6b3960c1b187"}, - {file = "coverage-7.11.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4e37486aed7045c280ebdc207026bdef9267730177d929a5e25250e1f33cc125"}, - {file = "coverage-7.11.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7c68180e67b4843674bfb1d3ec928ffcfc94081b5da959e616405eca51c23356"}, - {file = "coverage-7.11.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:cf825b60f94d1706c22d4887310db26cc3117d545ac6ad4229b4a0d718afcf9a"}, - {file = "coverage-7.11.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:437149272ff0440df66044bd6ee87cbc252463754ca43cafa496cfb2f57f56dd"}, - {file = "coverage-7.11.1-cp312-cp312-win32.whl", hash = "sha256:98ea0b8d1addfc333494c2248af367e8ecb27724a99804a18376b801f876da58"}, - {file = "coverage-7.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:7d49a473799e55a465bcadd19525977ab80031b8b86baaa622241808df4585cd"}, - {file = "coverage-7.11.1-cp312-cp312-win_arm64.whl", hash = "sha256:0c77e5951ab176a6ccb70c6f688fca2a7ac834753ba82ee4eb741be655f30b43"}, - {file = "coverage-7.11.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:da9930594ca99d66eb6f613d7beba850db2f8dfa86810ee35ae24e4d5f2bb97d"}, - {file = "coverage-7.11.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cc47a280dc014220b0fc6e5f55082a3f51854faf08fd9635b8a4f341c46c77d3"}, - {file = "coverage-7.11.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:74003324321bbf130939146886eddf92e48e616b5910215e79dea6edeb8ee7c8"}, - {file = "coverage-7.11.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:211f7996265daab60a8249af4ca6641b3080769cbedcffc42cc4841118f3a305"}, - {file = "coverage-7.11.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70619d194d8fea0cb028cb6bb9c85b519c7509c1d1feef1eea635183bc8ecd27"}, - {file = "coverage-7.11.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e0208bb59d441cfa3321569040f8e455f9261256e0df776c5462a1e5a9b31e13"}, - {file = "coverage-7.11.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:545714d8765bda1c51f8b1c96e0b497886a054471c68211e76ef49dd1468587d"}, - {file = "coverage-7.11.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d0a2b02c1e20158dd405054bcca87f91fd5b7605626aee87150819ea616edd67"}, - {file = "coverage-7.11.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e0f4aa986a4308a458e0fb572faa3eb3db2ea7ce294604064b25ab32b435a468"}, - {file = "coverage-7.11.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d51cc6687e8bbfd1e041f52baed0f979cd592242cf50bf18399a7e03afc82d88"}, - {file = "coverage-7.11.1-cp313-cp313-win32.whl", hash = "sha256:1b3067db3afe6deeca2b2c9f0ec23820d5f1bd152827acfadf24de145dfc5f66"}, - {file = "coverage-7.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:39a4c44b0cd40e3c9d89b2b7303ebd6ab9ae8a63f9e9a8c4d65a181a0b33aebe"}, - {file = "coverage-7.11.1-cp313-cp313-win_arm64.whl", hash = "sha256:a2e3560bf82fa8169a577e054cbbc29888699526063fee26ea59ea2627fd6e73"}, - {file = "coverage-7.11.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47a4f362a10285897ab3aa7a4b37d28213a4f2626823923613d6d7a3584dd79a"}, - {file = "coverage-7.11.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0df35fa7419ef571db9dacd50b0517bc54dbfe37eb94043b5fc3540bff276acd"}, - {file = "coverage-7.11.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e1a2c621d341c9d56f7917e56fbb56be4f73fe0d0e8dae28352fb095060fd467"}, - {file = "coverage-7.11.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6c354b111be9b2234d9573d75dd30ca4e414b7659c730e477e89be4f620b3fb5"}, - {file = "coverage-7.11.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4589bd44698728f600233fb2881014c9b8ec86637ef454c00939e779661dbe7e"}, - {file = "coverage-7.11.1-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c6956fc8754f2309131230272a7213a483a32ecbe29e2b9316d808a28f2f8ea1"}, - {file = "coverage-7.11.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:63926a97ed89dc6a087369b92dcb8b9a94cead46c08b33a7f1f4818cd8b6a3c3"}, - {file = "coverage-7.11.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:f5311ba00c53a7fb2b293fdc1f478b7286fe2a845a7ba9cda053f6e98178f0b4"}, - {file = "coverage-7.11.1-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:31bf5ffad84c974f9e72ac53493350f36b6fa396109159ec704210698f12860b"}, - {file = "coverage-7.11.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:227ee59fbc4a8c57a7383a1d7af6ca94a78ae3beee4045f38684548a8479a65b"}, - {file = "coverage-7.11.1-cp313-cp313t-win32.whl", hash = "sha256:a447d97b3ce680bb1da2e6bd822ebb71be6a1fb77ce2c2ad2fe4bd8aacec3058"}, - {file = "coverage-7.11.1-cp313-cp313t-win_amd64.whl", hash = "sha256:d6d11180437c67bde2248563a42b8e5bbf85c8df78fae13bf818ad17bfb15f02"}, - {file = "coverage-7.11.1-cp313-cp313t-win_arm64.whl", hash = "sha256:1e19a4c43d612760c6f7190411fb157e2d8a6dde00c91b941d43203bd3b17f6f"}, - {file = "coverage-7.11.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:0305463c45c5f21f0396cd5028de92b1f1387e2e0756a85dd3147daa49f7a674"}, - {file = "coverage-7.11.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fa4d468d5efa1eb6e3062be8bd5f45cbf28257a37b71b969a8c1da2652dfec77"}, - {file = "coverage-7.11.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d2b2f5fc8fe383cbf2d5c77d6c4b2632ede553bc0afd0cdc910fa5390046c290"}, - {file = "coverage-7.11.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bde6488c1ad509f4fb1a4f9960fd003d5a94adef61e226246f9699befbab3276"}, - {file = "coverage-7.11.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a69e0d6fa0b920fe6706a898c52955ec5bcfa7e45868215159f45fd87ea6da7c"}, - {file = "coverage-7.11.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:976e51e4a549b80e4639eda3a53e95013a14ff6ad69bb58ed604d34deb0e774c"}, - {file = "coverage-7.11.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d61fcc4d384c82971a3d9cf00d0872881f9ded19404c714d6079b7a4547e2955"}, - {file = "coverage-7.11.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:284c5df762b533fae3ebd764e3b81c20c1c9648d93ef34469759cb4e3dfe13d0"}, - {file = "coverage-7.11.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:bab32cb1d4ad2ac6dcc4e17eee5fa136c2a1d14ae914e4bce6c8b78273aece3c"}, - {file = "coverage-7.11.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:36f2fed9ce392ca450fb4e283900d0b41f05c8c5db674d200f471498be3ce747"}, - {file = "coverage-7.11.1-cp314-cp314-win32.whl", hash = "sha256:853136cecb92a5ba1cc8f61ec6ffa62ca3c88b4b386a6c835f8b833924f9a8c5"}, - {file = "coverage-7.11.1-cp314-cp314-win_amd64.whl", hash = "sha256:77443d39143e20927259a61da0c95d55ffc31cf43086b8f0f11a92da5260d592"}, - {file = "coverage-7.11.1-cp314-cp314-win_arm64.whl", hash = "sha256:829acb88fa47591a64bf5197e96a931ce9d4b3634c7f81a224ba3319623cdf6c"}, - {file = "coverage-7.11.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2ad1fe321d9522ea14399de83e75a11fb6a8887930c3679feb383301c28070d9"}, - {file = "coverage-7.11.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f69c332f0c3d1357c74decc9b1843fcd428cf9221bf196a20ad22aa1db3e1b6c"}, - {file = "coverage-7.11.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:576baeea4eebde684bf6c91c01e97171c8015765c8b2cfd4022a42b899897811"}, - {file = "coverage-7.11.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:28ad84c694fa86084cfd3c1eab4149844b8cb95bd8e5cbfc4a647f3ee2cce2b3"}, - {file = "coverage-7.11.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b1043ff958f09fc3f552c014d599f3c6b7088ba97d7bc1bd1cce8603cd75b520"}, - {file = "coverage-7.11.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c6681add5060c2742dafcf29826dff1ff8eef889a3b03390daeed84361c428bd"}, - {file = "coverage-7.11.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:773419b225ec9a75caa1e941dd0c83a91b92c2b525269e44e6ee3e4c630607db"}, - {file = "coverage-7.11.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a9cb272a0e0157dbb9b2fd0b201b759bd378a1a6138a16536c025c2ce4f7643b"}, - {file = "coverage-7.11.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:e09adb2a7811dc75998eef68f47599cf699e2b62eed09c9fefaeb290b3920f34"}, - {file = "coverage-7.11.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:1335fa8c2a2fea49924d97e1e3500cfe8d7c849f5369f26bb7559ad4259ccfab"}, - {file = "coverage-7.11.1-cp314-cp314t-win32.whl", hash = "sha256:4782d71d2a4fa7cef95e853b7097c8bbead4dbd0e6f9c7152a6b11a194b794db"}, - {file = "coverage-7.11.1-cp314-cp314t-win_amd64.whl", hash = "sha256:939f45e66eceb63c75e8eb8fc58bb7077c00f1a41b0e15c6ef02334a933cfe93"}, - {file = "coverage-7.11.1-cp314-cp314t-win_arm64.whl", hash = "sha256:01c575bdbef35e3f023b50a146e9a75c53816e4f2569109458155cd2315f87d9"}, - {file = "coverage-7.11.1-py3-none-any.whl", hash = "sha256:0fa848acb5f1da24765cee840e1afe9232ac98a8f9431c6112c15b34e880b9e8"}, - {file = "coverage-7.11.1.tar.gz", hash = "sha256:b4b3a072559578129a9e863082a2972a2abd8975bc0e2ec57da96afcd6580a8a"}, + {file = "coverage-7.13.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fc31c787a84f8cd6027eba44010517020e0d18487064cd3d8968941856d1415"}, + {file = "coverage-7.13.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a32ebc02a1805adf637fc8dec324b5cdacd2e493515424f70ee33799573d661b"}, + {file = "coverage-7.13.4-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e24f9156097ff9dc286f2f913df3a7f63c0e333dcafa3c196f2c18b4175ca09a"}, + {file = "coverage-7.13.4-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8041b6c5bfdc03257666e9881d33b1abc88daccaf73f7b6340fb7946655cd10f"}, + {file = "coverage-7.13.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a09cfa6a5862bc2fc6ca7c3def5b2926194a56b8ab78ffcf617d28911123012"}, + {file = "coverage-7.13.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:296f8b0af861d3970c2a4d8c91d48eb4dd4771bcef9baedec6a9b515d7de3def"}, + {file = "coverage-7.13.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e101609bcbbfb04605ea1027b10dc3735c094d12d40826a60f897b98b1c30256"}, + {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aa3feb8db2e87ff5e6d00d7e1480ae241876286691265657b500886c98f38bda"}, + {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4fc7fa81bbaf5a02801b65346c8b3e657f1d93763e58c0abdf7c992addd81a92"}, + {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:33901f604424145c6e9c2398684b92e176c0b12df77d52db81c20abd48c3794c"}, + {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:bb28c0f2cf2782508a40cec377935829d5fcc3ad9a3681375af4e84eb34b6b58"}, + {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9d107aff57a83222ddbd8d9ee705ede2af2cc926608b57abed8ef96b50b7e8f9"}, + {file = "coverage-7.13.4-cp310-cp310-win32.whl", hash = "sha256:a6f94a7d00eb18f1b6d403c91a88fd58cfc92d4b16080dfdb774afc8294469bf"}, + {file = "coverage-7.13.4-cp310-cp310-win_amd64.whl", hash = "sha256:2cb0f1e000ebc419632bbe04366a8990b6e32c4e0b51543a6484ffe15eaeda95"}, + {file = "coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d490ba50c3f35dd7c17953c68f3270e7ccd1c6642e2d2afe2d8e720b98f5a053"}, + {file = "coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11"}, + {file = "coverage-7.13.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3998e5a32e62fdf410c0dbd3115df86297995d6e3429af80b8798aad894ca7aa"}, + {file = "coverage-7.13.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8e264226ec98e01a8e1054314af91ee6cde0eacac4f465cc93b03dbe0bce2fd7"}, + {file = "coverage-7.13.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a3aa4e7b9e416774b21797365b358a6e827ffadaaca81b69ee02946852449f00"}, + {file = "coverage-7.13.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:71ca20079dd8f27fcf808817e281e90220475cd75115162218d0e27549f95fef"}, + {file = "coverage-7.13.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e2f25215f1a359ab17320b47bcdaca3e6e6356652e8256f2441e4ef972052903"}, + {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d65b2d373032411e86960604dc4edac91fdfb5dca539461cf2cbe78327d1e64f"}, + {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94eb63f9b363180aff17de3e7c8760c3ba94664ea2695c52f10111244d16a299"}, + {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e856bf6616714c3a9fbc270ab54103f4e685ba236fa98c054e8f87f266c93505"}, + {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:65dfcbe305c3dfe658492df2d85259e0d79ead4177f9ae724b6fb245198f55d6"}, + {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b507778ae8a4c915436ed5c2e05b4a6cecfa70f734e19c22a005152a11c7b6a9"}, + {file = "coverage-7.13.4-cp311-cp311-win32.whl", hash = "sha256:784fc3cf8be001197b652d51d3fd259b1e2262888693a4636e18879f613a62a9"}, + {file = "coverage-7.13.4-cp311-cp311-win_amd64.whl", hash = "sha256:2421d591f8ca05b308cf0092807308b2facbefe54af7c02ac22548b88b95c98f"}, + {file = "coverage-7.13.4-cp311-cp311-win_arm64.whl", hash = "sha256:79e73a76b854d9c6088fe5d8b2ebe745f8681c55f7397c3c0a016192d681045f"}, + {file = "coverage-7.13.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:02231499b08dabbe2b96612993e5fc34217cdae907a51b906ac7fca8027a4459"}, + {file = "coverage-7.13.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40aa8808140e55dc022b15d8aa7f651b6b3d68b365ea0398f1441e0b04d859c3"}, + {file = "coverage-7.13.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5b856a8ccf749480024ff3bd7310adaef57bf31fd17e1bfc404b7940b6986634"}, + {file = "coverage-7.13.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2c048ea43875fbf8b45d476ad79f179809c590ec7b79e2035c662e7afa3192e3"}, + {file = "coverage-7.13.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7b38448866e83176e28086674fe7368ab8590e4610fb662b44e345b86d63ffa"}, + {file = "coverage-7.13.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:de6defc1c9badbf8b9e67ae90fd00519186d6ab64e5cc5f3d21359c2a9b2c1d3"}, + {file = "coverage-7.13.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7eda778067ad7ffccd23ecffce537dface96212576a07924cbf0d8799d2ded5a"}, + {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e87f6c587c3f34356c3759f0420693e35e7eb0e2e41e4c011cb6ec6ecbbf1db7"}, + {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:8248977c2e33aecb2ced42fef99f2d319e9904a36e55a8a68b69207fb7e43edc"}, + {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:25381386e80ae727608e662474db537d4df1ecd42379b5ba33c84633a2b36d47"}, + {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:ee756f00726693e5ba94d6df2bdfd64d4852d23b09bb0bc700e3b30e6f333985"}, + {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fdfc1e28e7c7cdce44985b3043bc13bbd9c747520f94a4d7164af8260b3d91f0"}, + {file = "coverage-7.13.4-cp312-cp312-win32.whl", hash = "sha256:01d4cbc3c283a17fc1e42d614a119f7f438eabb593391283adca8dc86eff1246"}, + {file = "coverage-7.13.4-cp312-cp312-win_amd64.whl", hash = "sha256:9401ebc7ef522f01d01d45532c68c5ac40fb27113019b6b7d8b208f6e9baa126"}, + {file = "coverage-7.13.4-cp312-cp312-win_arm64.whl", hash = "sha256:b1ec7b6b6e93255f952e27ab58fbc68dcc468844b16ecbee881aeb29b6ab4d8d"}, + {file = "coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b66a2da594b6068b48b2692f043f35d4d3693fb639d5ea8b39533c2ad9ac3ab9"}, + {file = "coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3599eb3992d814d23b35c536c28df1a882caa950f8f507cef23d1cbf334995ac"}, + {file = "coverage-7.13.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:93550784d9281e374fb5a12bf1324cc8a963fd63b2d2f223503ef0fd4aa339ea"}, + {file = "coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b"}, + {file = "coverage-7.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7b322db1284a2ed3aa28ffd8ebe3db91c929b7a333c0820abec3d838ef5b3525"}, + {file = "coverage-7.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f4594c67d8a7c89cf922d9df0438c7c7bb022ad506eddb0fdb2863359ff78242"}, + {file = "coverage-7.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:53d133df809c743eb8bce33b24bcababb371f4441340578cd406e084d94a6148"}, + {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:76451d1978b95ba6507a039090ba076105c87cc76fc3efd5d35d72093964d49a"}, + {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7f57b33491e281e962021de110b451ab8a24182589be17e12a22c79047935e23"}, + {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1731dc33dc276dafc410a885cbf5992f1ff171393e48a21453b78727d090de80"}, + {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:bd60d4fe2f6fa7dff9223ca1bbc9f05d2b6697bc5961072e5d3b952d46e1b1ea"}, + {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9181a3ccead280b828fae232df12b16652702b49d41e99d657f46cc7b1f6ec7a"}, + {file = "coverage-7.13.4-cp313-cp313-win32.whl", hash = "sha256:f53d492307962561ac7de4cd1de3e363589b000ab69617c6156a16ba7237998d"}, + {file = "coverage-7.13.4-cp313-cp313-win_amd64.whl", hash = "sha256:e6f70dec1cc557e52df5306d051ef56003f74d56e9c4dd7ddb07e07ef32a84dd"}, + {file = "coverage-7.13.4-cp313-cp313-win_arm64.whl", hash = "sha256:fb07dc5da7e849e2ad31a5d74e9bece81f30ecf5a42909d0a695f8bd1874d6af"}, + {file = "coverage-7.13.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:40d74da8e6c4b9ac18b15331c4b5ebc35a17069410cad462ad4f40dcd2d50c0d"}, + {file = "coverage-7.13.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4223b4230a376138939a9173f1bdd6521994f2aff8047fae100d6d94d50c5a12"}, + {file = "coverage-7.13.4-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1d4be36a5114c499f9f1f9195e95ebf979460dbe2d88e6816ea202010ba1c34b"}, + {file = "coverage-7.13.4-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:200dea7d1e8095cc6e98cdabe3fd1d21ab17d3cee6dab00cadbb2fe35d9c15b9"}, + {file = "coverage-7.13.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8eb931ee8e6d8243e253e5ed7336deea6904369d2fd8ae6e43f68abbf167092"}, + {file = "coverage-7.13.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:75eab1ebe4f2f64d9509b984f9314d4aa788540368218b858dad56dc8f3e5eb9"}, + {file = "coverage-7.13.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c35eb28c1d085eb7d8c9b3296567a1bebe03ce72962e932431b9a61f28facf26"}, + {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:eb88b316ec33760714a4720feb2816a3a59180fd58c1985012054fa7aebee4c2"}, + {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7d41eead3cc673cbd38a4417deb7fd0b4ca26954ff7dc6078e33f6ff97bed940"}, + {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:fb26a934946a6afe0e326aebe0730cdff393a8bc0bbb65a2f41e30feddca399c"}, + {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:dae88bc0fc77edaa65c14be099bd57ee140cf507e6bfdeea7938457ab387efb0"}, + {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:845f352911777a8e722bfce168958214951e07e47e5d5d9744109fa5fe77f79b"}, + {file = "coverage-7.13.4-cp313-cp313t-win32.whl", hash = "sha256:2fa8d5f8de70688a28240de9e139fa16b153cc3cbb01c5f16d88d6505ebdadf9"}, + {file = "coverage-7.13.4-cp313-cp313t-win_amd64.whl", hash = "sha256:9351229c8c8407645840edcc277f4a2d44814d1bc34a2128c11c2a031d45a5dd"}, + {file = "coverage-7.13.4-cp313-cp313t-win_arm64.whl", hash = "sha256:30b8d0512f2dc8c8747557e8fb459d6176a2c9e5731e2b74d311c03b78451997"}, + {file = "coverage-7.13.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:300deaee342f90696ed186e3a00c71b5b3d27bffe9e827677954f4ee56969601"}, + {file = "coverage-7.13.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:29e3220258d682b6226a9b0925bc563ed9a1ebcff3cad30f043eceea7eaf2689"}, + {file = "coverage-7.13.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:391ee8f19bef69210978363ca930f7328081c6a0152f1166c91f0b5fdd2a773c"}, + {file = "coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129"}, + {file = "coverage-7.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78cdf0d578b15148b009ccf18c686aa4f719d887e76e6b40c38ffb61d264a552"}, + {file = "coverage-7.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:48685fee12c2eb3b27c62f2658e7ea21e9c3239cba5a8a242801a0a3f6a8c62a"}, + {file = "coverage-7.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4e83efc079eb39480e6346a15a1bcb3e9b04759c5202d157e1dd4303cd619356"}, + {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ecae9737b72408d6a950f7e525f30aca12d4bd8dd95e37342e5beb3a2a8c4f71"}, + {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ae4578f8528569d3cf303fef2ea569c7f4c4059a38c8667ccef15c6e1f118aa5"}, + {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:6fdef321fdfbb30a197efa02d48fcd9981f0d8ad2ae8903ac318adc653f5df98"}, + {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b0f6ccf3dbe577170bebfce1318707d0e8c3650003cb4b3a9dd744575daa8b5"}, + {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75fcd519f2a5765db3f0e391eb3b7d150cce1a771bf4c9f861aeab86c767a3c0"}, + {file = "coverage-7.13.4-cp314-cp314-win32.whl", hash = "sha256:8e798c266c378da2bd819b0677df41ab46d78065fb2a399558f3f6cae78b2fbb"}, + {file = "coverage-7.13.4-cp314-cp314-win_amd64.whl", hash = "sha256:245e37f664d89861cf2329c9afa2c1fe9e6d4e1a09d872c947e70718aeeac505"}, + {file = "coverage-7.13.4-cp314-cp314-win_arm64.whl", hash = "sha256:ad27098a189e5838900ce4c2a99f2fe42a0bf0c2093c17c69b45a71579e8d4a2"}, + {file = "coverage-7.13.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:85480adfb35ffc32d40918aad81b89c69c9cc5661a9b8a81476d3e645321a056"}, + {file = "coverage-7.13.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:79be69cf7f3bf9b0deeeb062eab7ac7f36cd4cc4c4dd694bd28921ba4d8596cc"}, + {file = "coverage-7.13.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:caa421e2684e382c5d8973ac55e4f36bed6821a9bad5c953494de960c74595c9"}, + {file = "coverage-7.13.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:14375934243ee05f56c45393fe2ce81fe5cc503c07cee2bdf1725fb8bef3ffaf"}, + {file = "coverage-7.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25a41c3104d08edb094d9db0d905ca54d0cd41c928bb6be3c4c799a54753af55"}, + {file = "coverage-7.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6f01afcff62bf9a08fb32b2c1d6e924236c0383c02c790732b6537269e466a72"}, + {file = "coverage-7.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eb9078108fbf0bcdde37c3f4779303673c2fa1fe8f7956e68d447d0dd426d38a"}, + {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0e086334e8537ddd17e5f16a344777c1ab8194986ec533711cbe6c41cde841b6"}, + {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:725d985c5ab621268b2edb8e50dfe57633dc69bda071abc470fed55a14935fd3"}, + {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:3c06f0f1337c667b971ca2f975523347e63ec5e500b9aa5882d91931cd3ef750"}, + {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:590c0ed4bf8e85f745e6b805b2e1c457b2e33d5255dd9729743165253bc9ad39"}, + {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:eb30bf180de3f632cd043322dad5751390e5385108b2807368997d1a92a509d0"}, + {file = "coverage-7.13.4-cp314-cp314t-win32.whl", hash = "sha256:c4240e7eded42d131a2d2c4dec70374b781b043ddc79a9de4d55ca71f8e98aea"}, + {file = "coverage-7.13.4-cp314-cp314t-win_amd64.whl", hash = "sha256:4c7d3cc01e7350f2f0f6f7036caaf5673fb56b6998889ccfe9e1c1fe75a9c932"}, + {file = "coverage-7.13.4-cp314-cp314t-win_arm64.whl", hash = "sha256:23e3f687cf945070d1c90f85db66d11e3025665d8dafa831301a0e0038f3db9b"}, + {file = "coverage-7.13.4-py3-none-any.whl", hash = "sha256:1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0"}, + {file = "coverage-7.13.4.tar.gz", hash = "sha256:e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91"}, ] [package.extras] @@ -560,62 +580,62 @@ setuptools = "*" [[package]] name = "dbus-fast" -version = "2.44.5" +version = "4.0.0" description = "A faster version of dbus-next" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main"] markers = "platform_system == \"Linux\"" files = [ - {file = "dbus_fast-2.44.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c66f60b7b5aef557b2d46da8041865fb7af39bc286e52a70ce0fd62c4fcf739c"}, - {file = "dbus_fast-2.44.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:71f169fd10ce694d6859038687fbfde735c7b0e57970d7b78442a7ef328e22cc"}, - {file = "dbus_fast-2.44.5-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:81746e4e53c44f13c1ddc50f6d1d61468f48a2f6968be996a3da9a4942254f46"}, - {file = "dbus_fast-2.44.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a4adcfcdceca850590d73e2d2fdac484cf3ae117abed5d74400291c873369ce7"}, - {file = "dbus_fast-2.44.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8b88989e6ee35acbc6a5085c7d52919776632839668d57fe01d8e66a965e6cf9"}, - {file = "dbus_fast-2.44.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dad1381d70e80d53aef444d02c7b827bb1203f0fd728e847c427acf87e2fbd0c"}, - {file = "dbus_fast-2.44.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:52c6733216c15df5d50987b4ee4465b91b767173c46165d1aac4aba4e2f110cf"}, - {file = "dbus_fast-2.44.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:094e7ace0bba438e465de108edd32c0e8f63371b5f54ae5393036acc0158dd18"}, - {file = "dbus_fast-2.44.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3e168b1dab2e0d7b7b8981d82c8535cb2a535320a947191a5fcbf605f22d6d76"}, - {file = "dbus_fast-2.44.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:111c0ddb941cbe39838ced83bd162d096dfabd78cfff6f15e5df281a7cf0100e"}, - {file = "dbus_fast-2.44.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:879bd6856e046feff3942bbc28b02ee47be6b5d5291c3823a8be47dc1a541e17"}, - {file = "dbus_fast-2.44.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90493cc36657977f70a12fd358e6655a3b159c29dc682343ba083e9ad25ece3a"}, - {file = "dbus_fast-2.44.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:86aa086c89ffc14941cb3877bafe9ee8cd79a565033f4526d866c7da2bbac257"}, - {file = "dbus_fast-2.44.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:af64f9d836adb3e759c9df40e3758f0c3a2f998f656ddd1992f17cc0516df30c"}, - {file = "dbus_fast-2.44.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:891102ad3e8aa1285e4558f80d33dbfdda92a9e77ed41c054f0eb63f99df57eb"}, - {file = "dbus_fast-2.44.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dff39ef89d97ef096569ad01f522e25c64702fde81dc7e3a4c859f2cb46ae23d"}, - {file = "dbus_fast-2.44.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44d3232fd70f4deffa509b9aec8b1143895382554cda6513c34f70fa0b2ccb0c"}, - {file = "dbus_fast-2.44.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0b247075d035c4f33a24ee35a81c1313c46a7712ebad959fa8850654d3d6d64f"}, - {file = "dbus_fast-2.44.5-cp313-cp313-manylinux_2_36_x86_64.whl", hash = "sha256:b5fea7b5ea19f83220752c8560c3b4c3b9ee79976cc02dec7be21f57c01c1338"}, - {file = "dbus_fast-2.44.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8546604aebd57f3928647b0e1ea32912c80ddcf7119a35dd57606bf3a38b8571"}, - {file = "dbus_fast-2.44.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:46ca373a4eb8f036597d25787f4410af7822ab37c5db7c44ac4bc18bb25b9d6f"}, - {file = "dbus_fast-2.44.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:db901e4edd3a89a7f2464be82f7993b36ca11b68ac78fa482e6d4787534584fd"}, - {file = "dbus_fast-2.44.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b9f49e3fe97a7de27b3bdb4d80b8bc40aa0827462988b790a9e007d40518b7e2"}, - {file = "dbus_fast-2.44.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b164214d2abc4b232c02100448bdf7a8858ac8da62c17cfe3ad54e05eae4b133"}, - {file = "dbus_fast-2.44.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:13ae2801d94bb782aad71c21542e90ba65bc86ccbcc365e52a473eba208aab54"}, - {file = "dbus_fast-2.44.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e3e24fd1fe09ddd87b6ce57fc99e9a95201ae4296d6518e3fb101df392e3dc85"}, - {file = "dbus_fast-2.44.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b1e1434d56a06a623f37805b8c54dbccc852d4cf690b03cb4e2b29fca3401d48"}, - {file = "dbus_fast-2.44.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:644a0ba6958550707ad56acd9654f1534fca16a6e1bf5f38f2f74a5370123584"}, - {file = "dbus_fast-2.44.5-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ad9b36518984a363cfa5eacbd4a2a82ce35a0d4cfcb9e43980c8df3d742121e9"}, - {file = "dbus_fast-2.44.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bdb8688394bb28b9535d38a1e7dfeed8143fd0ee09cb9aea07ff314fb5af55dc"}, - {file = "dbus_fast-2.44.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:2979c4b90596ddb72d2056de7cb47a2994143e805844732d96bcd882731b936b"}, - {file = "dbus_fast-2.44.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5240dbecd787cc05975418e86ccaad6d33552032e6582eb6c4bf711462a53e02"}, - {file = "dbus_fast-2.44.5-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:45b9da0723e3578960540d3be40fd97e6cedec28dc80070bda7621faba743d6c"}, - {file = "dbus_fast-2.44.5-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:273a8eb83feca276345249630c658b7a0c5ff68638da55d0dc1495947415836c"}, - {file = "dbus_fast-2.44.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9a937f70a2106d3495eaba661f124c26c40f7aa2f8010d132101f7ac9942cede"}, - {file = "dbus_fast-2.44.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb46db0db1315abe8c3b6fd5254d86b68fdeb1efd4350b962bd2adecc57b88e6"}, - {file = "dbus_fast-2.44.5.tar.gz", hash = "sha256:e9d738e3898e2d505d7f2d5d21949bd705d7cd3d7240dda5481bb1c5fd5e3da8"}, + {file = "dbus_fast-4.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7ea5e9021779388f6b0d93d1c7eaf619185afd99bbca772f0e1ecec2b55e8d17"}, + {file = "dbus_fast-4.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a29ad81e59b328c840c9020daa855971d8f345d2c2472e9d5b200b3c82fc734"}, + {file = "dbus_fast-4.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e3d62b7a0e392a80f61227c6f314e969dd5bec36e693723728908f8e8a172885"}, + {file = "dbus_fast-4.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:35bbeb692e60ff2a0eb3f97dc4b048e92fc7ddc8468ed7bd173bc5513d4690cc"}, + {file = "dbus_fast-4.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:dfa3cb3137c727ea50d89e9e4e4ce5042e28baf36fcc8b1e3c84dff50eee70aa"}, + {file = "dbus_fast-4.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e65a68793ce650d94ac86021a473988715197762b24c72c510833e9111c5170d"}, + {file = "dbus_fast-4.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:512f25a0705903047e9b55d2bc3724f06dcbfb77e0b13f10a7eb835679d3705c"}, + {file = "dbus_fast-4.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:28209c72c36f8e2bb2152c02598d353e9442d53d751efbf49870bc37ac3afcad"}, + {file = "dbus_fast-4.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:618931126219f23285b33b5825dc40cfb166c8e6554f800f7c53dfb5f368289b"}, + {file = "dbus_fast-4.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0615063551e8d4b34bee778885ab56be3ef168df38f9bfc4364d8c80687e2df4"}, + {file = "dbus_fast-4.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:621ad63b0599fc125d4574d358bbc642089c910dcc9e42ae23d32ab807c8e5af"}, + {file = "dbus_fast-4.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bfb269a9ed3b3ab29932b2948de52d7ea2eebfcad0c641ad6b25024b048d0b68"}, + {file = "dbus_fast-4.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aa367aaad3a868dfb9373eca8868a2a0810bac6cbe35b67460682127834c2460"}, + {file = "dbus_fast-4.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2283e9c22411b1307fa3e3586fd4b42b44cae90e8a39f4fb4942a97a885d437b"}, + {file = "dbus_fast-4.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a91ec3707b743c2e211fa9ecd08ee483c3af19a2028ad90d2911a7e17d20737"}, + {file = "dbus_fast-4.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d1b7274af1769359e8b02c546eb368f4cc43fce4ba4286ee97f357d395372492"}, + {file = "dbus_fast-4.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3b83681987b2986af050b728ecea5e230252c09db3c9593cead5b073f6391f41"}, + {file = "dbus_fast-4.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:191c9053c9d54356f0c5c202e2fab9ad2508b27b8b224a184cf367591a2586cb"}, + {file = "dbus_fast-4.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c34c748b71c6fc71e47ffe901ccfcd4a01e98d5fa80f98c732945da45d9fc614"}, + {file = "dbus_fast-4.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:39ac2e639833320678c2c4e64931b28a3e10c57111c8c24967f1a16de69b92b0"}, + {file = "dbus_fast-4.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ddd92e5179ca5af5348ac34fb6a7c279d1485a715d560bcb8ff8443296fb1aff"}, + {file = "dbus_fast-4.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9e53d7e19d2433f2ca1d811856e4b80a3b3126f361703e5caf6e7f086a03b994"}, + {file = "dbus_fast-4.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6b430760c925e0b695b6f1a3f21f6e57954807cab4704a3bc4bc5f311261016b"}, + {file = "dbus_fast-4.0.0-cp314-cp314-manylinux_2_41_x86_64.whl", hash = "sha256:2818d76da8291202779fe8cb23edc62488786eee791f332c2c40350552288d8b"}, + {file = "dbus_fast-4.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0b2aaf80991734e2bbff60b0f57b70322668acccb8bb15a0380ca80b8f8c5d72"}, + {file = "dbus_fast-4.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:93a864c9e39ab03988c95e2cd9368a4b6560887d53a197037dfc73e7d966b690"}, + {file = "dbus_fast-4.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f36526cb043ab630ee458b58965fcf1e6d51d742f11df8ba2756cc280a21899d"}, + {file = "dbus_fast-4.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c71b369f8fd743c0d03e5fd566ff5d886cb5ad7f3d187f36185a372096a2a096"}, + {file = "dbus_fast-4.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ffc16ee344e68a907a40327074bca736086897f2e783541086eedb5e6855f3f0"}, + {file = "dbus_fast-4.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1f8f4b0f8af730c39bbb83de1e299e706fbd7f7f3955764471213b013fa59516"}, + {file = "dbus_fast-4.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f6af190d8306f1bd506740c39701f5c211aa31ac660a3fcb401ebb97d33166c7"}, + {file = "dbus_fast-4.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:091f15fe7a2418b5b670f1edf0c15f6d7ed25886a089899e355bc3710972d731"}, + {file = "dbus_fast-4.0.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:89d040c5a9635b28319163c29ce1f251ed91070692a51f2db6ade06799e1b4ce"}, + {file = "dbus_fast-4.0.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:131b68cbc1862b4470fd94014a5709270cf5d018a68ddc5867a2e8cae19109a1"}, + {file = "dbus_fast-4.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:76d6f4e14e0c54461691c043508e0d0c1844ebc9470dfe7a1f50ead7f2ad59d8"}, + {file = "dbus_fast-4.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:8171360d891109b6c6d4195dcdf36248871c09b6729c666734a44226a57485d0"}, + {file = "dbus_fast-4.0.0.tar.gz", hash = "sha256:e1d3ee49a4a81524d7caaa2d5a31fc71075a1c977b661df958cee24bef86b8fe"}, ] [[package]] name = "dill" -version = "0.4.0" +version = "0.4.1" description = "serialize all of Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049"}, - {file = "dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0"}, + {file = "dill-0.4.1-py3-none-any.whl", hash = "sha256:1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d"}, + {file = "dill-0.4.1.tar.gz", hash = "sha256:423092df4182177d4d8ba8290c8a5b640c66ab35ec7da59ccfa00f6fa3eea5fa"}, ] [package.extras] @@ -817,18 +837,18 @@ dev = ["Sphinx (==8.1.3) ; python_version >= \"3.11\"", "build (==1.2.2) ; pytho [[package]] name = "markdown" -version = "3.10" +version = "3.10.2" description = "Python implementation of John Gruber's Markdown." optional = false python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "markdown-3.10-py3-none-any.whl", hash = "sha256:b5b99d6951e2e4948d939255596523444c0e677c669700b1d17aa4a8a464cb7c"}, - {file = "markdown-3.10.tar.gz", hash = "sha256:37062d4f2aa4b2b6b32aefb80faa300f82cc790cb949a35b8caede34f2b68c0e"}, + {file = "markdown-3.10.2-py3-none-any.whl", hash = "sha256:e91464b71ae3ee7afd3017d9f358ef0baf158fd9a298db92f1d4761133824c36"}, + {file = "markdown-3.10.2.tar.gz", hash = "sha256:994d51325d25ad8aa7ce4ebaec003febcce822c3f8c911e3b17c52f7f589f950"}, ] [package.extras] -docs = ["mdx_gh_links (>=0.2)", "mkdocs (>=1.6)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] +docs = ["mdx_gh_links (>=0.2)", "mkdocs (>=1.6)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python] (>=0.28.3)"] testing = ["coverage", "pyyaml"] [[package]] @@ -1052,101 +1072,119 @@ files = [ [[package]] name = "numpy" -version = "2.2.6" +version = "2.4.2" description = "Fundamental package for array computing in Python" optional = true -python-versions = ">=3.10" +python-versions = ">=3.11" groups = ["main"] markers = "extra == \"gui\"" files = [ - {file = "numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb"}, - {file = "numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90"}, - {file = "numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163"}, - {file = "numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf"}, - {file = "numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83"}, - {file = "numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915"}, - {file = "numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680"}, - {file = "numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289"}, - {file = "numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d"}, - {file = "numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3"}, - {file = "numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae"}, - {file = "numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a"}, - {file = "numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42"}, - {file = "numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491"}, - {file = "numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a"}, - {file = "numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf"}, - {file = "numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1"}, - {file = "numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab"}, - {file = "numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47"}, - {file = "numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303"}, - {file = "numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff"}, - {file = "numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c"}, - {file = "numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3"}, - {file = "numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282"}, - {file = "numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87"}, - {file = "numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249"}, - {file = "numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49"}, - {file = "numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de"}, - {file = "numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4"}, - {file = "numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2"}, - {file = "numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84"}, - {file = "numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b"}, - {file = "numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d"}, - {file = "numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566"}, - {file = "numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f"}, - {file = "numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f"}, - {file = "numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868"}, - {file = "numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d"}, - {file = "numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd"}, - {file = "numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c"}, - {file = "numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6"}, - {file = "numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda"}, - {file = "numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40"}, - {file = "numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8"}, - {file = "numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f"}, - {file = "numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa"}, - {file = "numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571"}, - {file = "numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1"}, - {file = "numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff"}, - {file = "numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06"}, - {file = "numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d"}, - {file = "numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db"}, - {file = "numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543"}, - {file = "numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00"}, - {file = "numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd"}, + {file = "numpy-2.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e7e88598032542bd49af7c4747541422884219056c268823ef6e5e89851c8825"}, + {file = "numpy-2.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7edc794af8b36ca37ef5fcb5e0d128c7e0595c7b96a2318d1badb6fcd8ee86b1"}, + {file = "numpy-2.4.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:6e9f61981ace1360e42737e2bae58b27bf28a1b27e781721047d84bd754d32e7"}, + {file = "numpy-2.4.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:cb7bbb88aa74908950d979eeaa24dbdf1a865e3c7e45ff0121d8f70387b55f73"}, + {file = "numpy-2.4.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f069069931240b3fc703f1e23df63443dbd6390614c8c44a87d96cd0ec81eb1"}, + {file = "numpy-2.4.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c02ef4401a506fb60b411467ad501e1429a3487abca4664871d9ae0b46c8ba32"}, + {file = "numpy-2.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2653de5c24910e49c2b106499803124dde62a5a1fe0eedeaecf4309a5f639390"}, + {file = "numpy-2.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1ae241bbfc6ae276f94a170b14785e561cb5e7f626b6688cf076af4110887413"}, + {file = "numpy-2.4.2-cp311-cp311-win32.whl", hash = "sha256:df1b10187212b198dd45fa943d8985a3c8cf854aed4923796e0e019e113a1bda"}, + {file = "numpy-2.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:b9c618d56a29c9cb1c4da979e9899be7578d2e0b3c24d52079c166324c9e8695"}, + {file = "numpy-2.4.2-cp311-cp311-win_arm64.whl", hash = "sha256:47c5a6ed21d9452b10227e5e8a0e1c22979811cad7dcc19d8e3e2fb8fa03f1a3"}, + {file = "numpy-2.4.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:21982668592194c609de53ba4933a7471880ccbaadcc52352694a59ecc860b3a"}, + {file = "numpy-2.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40397bda92382fcec844066efb11f13e1c9a3e2a8e8f318fb72ed8b6db9f60f1"}, + {file = "numpy-2.4.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:b3a24467af63c67829bfaa61eecf18d5432d4f11992688537be59ecd6ad32f5e"}, + {file = "numpy-2.4.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:805cc8de9fd6e7a22da5aed858e0ab16be5a4db6c873dde1d7451c541553aa27"}, + {file = "numpy-2.4.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d82351358ffbcdcd7b686b90742a9b86632d6c1c051016484fa0b326a0a1548"}, + {file = "numpy-2.4.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e35d3e0144137d9fdae62912e869136164534d64a169f86438bc9561b6ad49f"}, + {file = "numpy-2.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:adb6ed2ad29b9e15321d167d152ee909ec73395901b70936f029c3bc6d7f4460"}, + {file = "numpy-2.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8906e71fd8afcb76580404e2a950caef2685df3d2a57fe82a86ac8d33cc007ba"}, + {file = "numpy-2.4.2-cp312-cp312-win32.whl", hash = "sha256:ec055f6dae239a6299cace477b479cca2fc125c5675482daf1dd886933a1076f"}, + {file = "numpy-2.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:209fae046e62d0ce6435fcfe3b1a10537e858249b3d9b05829e2a05218296a85"}, + {file = "numpy-2.4.2-cp312-cp312-win_arm64.whl", hash = "sha256:fbde1b0c6e81d56f5dccd95dd4a711d9b95df1ae4009a60887e56b27e8d903fa"}, + {file = "numpy-2.4.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:25f2059807faea4b077a2b6837391b5d830864b3543627f381821c646f31a63c"}, + {file = "numpy-2.4.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bd3a7a9f5847d2fb8c2c6d1c862fa109c31a9abeca1a3c2bd5a64572955b2979"}, + {file = "numpy-2.4.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:8e4549f8a3c6d13d55041925e912bfd834285ef1dd64d6bc7d542583355e2e98"}, + {file = "numpy-2.4.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:aea4f66ff44dfddf8c2cffd66ba6538c5ec67d389285292fe428cb2c738c8aef"}, + {file = "numpy-2.4.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3cd545784805de05aafe1dde61752ea49a359ccba9760c1e5d1c88a93bbf2b7"}, + {file = "numpy-2.4.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0d9b7c93578baafcbc5f0b83eaf17b79d345c6f36917ba0c67f45226911d499"}, + {file = "numpy-2.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f74f0f7779cc7ae07d1810aab8ac6b1464c3eafb9e283a40da7309d5e6e48fbb"}, + {file = "numpy-2.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c7ac672d699bf36275c035e16b65539931347d68b70667d28984c9fb34e07fa7"}, + {file = "numpy-2.4.2-cp313-cp313-win32.whl", hash = "sha256:8e9afaeb0beff068b4d9cd20d322ba0ee1cecfb0b08db145e4ab4dd44a6b5110"}, + {file = "numpy-2.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:7df2de1e4fba69a51c06c28f5a3de36731eb9639feb8e1cf7e4a7b0daf4cf622"}, + {file = "numpy-2.4.2-cp313-cp313-win_arm64.whl", hash = "sha256:0fece1d1f0a89c16b03442eae5c56dc0be0c7883b5d388e0c03f53019a4bfd71"}, + {file = "numpy-2.4.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5633c0da313330fd20c484c78cdd3f9b175b55e1a766c4a174230c6b70ad8262"}, + {file = "numpy-2.4.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d9f64d786b3b1dd742c946c42d15b07497ed14af1a1f3ce840cce27daa0ce913"}, + {file = "numpy-2.4.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:b21041e8cb6a1eb5312dd1d2f80a94d91efffb7a06b70597d44f1bd2dfc315ab"}, + {file = "numpy-2.4.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:00ab83c56211a1d7c07c25e3217ea6695e50a3e2f255053686b081dc0b091a82"}, + {file = "numpy-2.4.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fb882da679409066b4603579619341c6d6898fc83a8995199d5249f986e8e8f"}, + {file = "numpy-2.4.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:66cb9422236317f9d44b67b4d18f44efe6e9c7f8794ac0462978513359461554"}, + {file = "numpy-2.4.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:0f01dcf33e73d80bd8dc0f20a71303abbafa26a19e23f6b68d1aa9990af90257"}, + {file = "numpy-2.4.2-cp313-cp313t-win32.whl", hash = "sha256:52b913ec40ff7ae845687b0b34d8d93b60cb66dcee06996dd5c99f2fc9328657"}, + {file = "numpy-2.4.2-cp313-cp313t-win_amd64.whl", hash = "sha256:5eea80d908b2c1f91486eb95b3fb6fab187e569ec9752ab7d9333d2e66bf2d6b"}, + {file = "numpy-2.4.2-cp313-cp313t-win_arm64.whl", hash = "sha256:fd49860271d52127d61197bb50b64f58454e9f578cb4b2c001a6de8b1f50b0b1"}, + {file = "numpy-2.4.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:444be170853f1f9d528428eceb55f12918e4fda5d8805480f36a002f1415e09b"}, + {file = "numpy-2.4.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d1240d50adff70c2a88217698ca844723068533f3f5c5fa6ee2e3220e3bdb000"}, + {file = "numpy-2.4.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:7cdde6de52fb6664b00b056341265441192d1291c130e99183ec0d4b110ff8b1"}, + {file = "numpy-2.4.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:cda077c2e5b780200b6b3e09d0b42205a3d1c68f30c6dceb90401c13bff8fe74"}, + {file = "numpy-2.4.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d30291931c915b2ab5717c2974bb95ee891a1cf22ebc16a8006bd59cd210d40a"}, + {file = "numpy-2.4.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bba37bc29d4d85761deed3954a1bc62be7cf462b9510b51d367b769a8c8df325"}, + {file = "numpy-2.4.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b2f0073ed0868db1dcd86e052d37279eef185b9c8db5bf61f30f46adac63c909"}, + {file = "numpy-2.4.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7f54844851cdb630ceb623dcec4db3240d1ac13d4990532446761baede94996a"}, + {file = "numpy-2.4.2-cp314-cp314-win32.whl", hash = "sha256:12e26134a0331d8dbd9351620f037ec470b7c75929cb8a1537f6bfe411152a1a"}, + {file = "numpy-2.4.2-cp314-cp314-win_amd64.whl", hash = "sha256:068cdb2d0d644cdb45670810894f6a0600797a69c05f1ac478e8d31670b8ee75"}, + {file = "numpy-2.4.2-cp314-cp314-win_arm64.whl", hash = "sha256:6ed0be1ee58eef41231a5c943d7d1375f093142702d5723ca2eb07db9b934b05"}, + {file = "numpy-2.4.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:98f16a80e917003a12c0580f97b5f875853ebc33e2eaa4bccfc8201ac6869308"}, + {file = "numpy-2.4.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:20abd069b9cda45874498b245c8015b18ace6de8546bf50dfa8cea1696ed06ef"}, + {file = "numpy-2.4.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:e98c97502435b53741540a5717a6749ac2ada901056c7db951d33e11c885cc7d"}, + {file = "numpy-2.4.2-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:da6cad4e82cb893db4b69105c604d805e0c3ce11501a55b5e9f9083b47d2ffe8"}, + {file = "numpy-2.4.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e4424677ce4b47fe73c8b5556d876571f7c6945d264201180db2dc34f676ab5"}, + {file = "numpy-2.4.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2b8f157c8a6f20eb657e240f8985cc135598b2b46985c5bccbde7616dc9c6b1e"}, + {file = "numpy-2.4.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5daf6f3914a733336dab21a05cdec343144600e964d2fcdabaac0c0269874b2a"}, + {file = "numpy-2.4.2-cp314-cp314t-win32.whl", hash = "sha256:8c50dd1fc8826f5b26a5ee4d77ca55d88a895f4e4819c7ecc2a9f5905047a443"}, + {file = "numpy-2.4.2-cp314-cp314t-win_amd64.whl", hash = "sha256:fcf92bee92742edd401ba41135185866f7026c502617f422eb432cfeca4fe236"}, + {file = "numpy-2.4.2-cp314-cp314t-win_arm64.whl", hash = "sha256:1f92f53998a17265194018d1cc321b2e96e900ca52d54c7c77837b71b9465181"}, + {file = "numpy-2.4.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:89f7268c009bc492f506abd6f5265defa7cb3f7487dc21d357c3d290add45082"}, + {file = "numpy-2.4.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:e6dee3bb76aa4009d5a912180bf5b2de012532998d094acee25d9cb8dee3e44a"}, + {file = "numpy-2.4.2-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:cd2bd2bbed13e213d6b55dc1d035a4f91748a7d3edc9480c13898b0353708920"}, + {file = "numpy-2.4.2-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:cf28c0c1d4c4bf00f509fa7eb02c58d7caf221b50b467bcb0d9bbf1584d5c821"}, + {file = "numpy-2.4.2-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e04ae107ac591763a47398bb45b568fc38f02dbc4aa44c063f67a131f99346cb"}, + {file = "numpy-2.4.2-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:602f65afdef699cda27ec0b9224ae5dc43e328f4c24c689deaf77133dbee74d0"}, + {file = "numpy-2.4.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:be71bf1edb48ebbbf7f6337b5bfd2f895d1902f6335a5830b20141fc126ffba0"}, + {file = "numpy-2.4.2.tar.gz", hash = "sha256:659a6107e31a83c4e33f763942275fd278b21d095094044eb35569e86a21ddae"}, ] [[package]] name = "opencv-python" -version = "4.12.0.88" +version = "4.13.0.92" description = "Wrapper package for OpenCV python bindings." optional = true python-versions = ">=3.6" groups = ["main"] markers = "extra == \"gui\"" files = [ - {file = "opencv-python-4.12.0.88.tar.gz", hash = "sha256:8b738389cede219405f6f3880b851efa3415ccd674752219377353f017d2994d"}, - {file = "opencv_python-4.12.0.88-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:f9a1f08883257b95a5764bf517a32d75aec325319c8ed0f89739a57fae9e92a5"}, - {file = "opencv_python-4.12.0.88-cp37-abi3-macosx_13_0_x86_64.whl", hash = "sha256:812eb116ad2b4de43ee116fcd8991c3a687f099ada0b04e68f64899c09448e81"}, - {file = "opencv_python-4.12.0.88-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:51fd981c7df6af3e8f70b1556696b05224c4e6b6777bdd2a46b3d4fb09de1a92"}, - {file = "opencv_python-4.12.0.88-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:092c16da4c5a163a818f120c22c5e4a2f96e0db4f24e659c701f1fe629a690f9"}, - {file = "opencv_python-4.12.0.88-cp37-abi3-win32.whl", hash = "sha256:ff554d3f725b39878ac6a2e1fa232ec509c36130927afc18a1719ebf4fbf4357"}, - {file = "opencv_python-4.12.0.88-cp37-abi3-win_amd64.whl", hash = "sha256:d98edb20aa932fd8ebd276a72627dad9dc097695b3d435a4257557bbb49a79d2"}, + {file = "opencv_python-4.13.0.92-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:caf60c071ec391ba51ed00a4a920f996d0b64e3e46068aac1f646b5de0326a19"}, + {file = "opencv_python-4.13.0.92-cp37-abi3-macosx_14_0_x86_64.whl", hash = "sha256:5868a8c028a0b37561579bfb8ac1875babdc69546d236249fff296a8c010ccf9"}, + {file = "opencv_python-4.13.0.92-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0bc2596e68f972ca452d80f444bc404e08807d021fbba40df26b61b18e01838a"}, + {file = "opencv_python-4.13.0.92-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:402033cddf9d294693094de5ef532339f14ce821da3ad7df7c9f6e8316da32cf"}, + {file = "opencv_python-4.13.0.92-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:bccaabf9eb7f897ca61880ce2869dcd9b25b72129c28478e7f2a5e8dee945616"}, + {file = "opencv_python-4.13.0.92-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:620d602b8f7d8b8dab5f4b99c6eb353e78d3fb8b0f53db1bd258bb1aa001c1d5"}, + {file = "opencv_python-4.13.0.92-cp37-abi3-win32.whl", hash = "sha256:372fe164a3148ac1ca51e5f3ad0541a4a276452273f503441d718fab9c5e5f59"}, + {file = "opencv_python-4.13.0.92-cp37-abi3-win_amd64.whl", hash = "sha256:423d934c9fafb91aad38edf26efb46da91ffbc05f3f59c4b0c72e699720706f5"}, ] [package.dependencies] -numpy = {version = ">=2,<2.3.0", markers = "python_version >= \"3.9\""} +numpy = {version = ">=2", markers = "python_version >= \"3.9\""} [[package]] name = "packaging" -version = "25.0" +version = "26.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" groups = ["main", "dev"] files = [ - {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, - {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, + {file = "packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"}, + {file = "packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4"}, ] [[package]] @@ -1163,16 +1201,22 @@ files = [ [[package]] name = "pathspec" -version = "0.12.1" +version = "1.0.4" description = "Utility library for gitignore style pattern matching of file paths." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["main", "dev"] files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, + {file = "pathspec-1.0.4-py3-none-any.whl", hash = "sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723"}, + {file = "pathspec-1.0.4.tar.gz", hash = "sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645"}, ] +[package.extras] +hyperscan = ["hyperscan (>=0.7)"] +optional = ["typing-extensions (>=4)"] +re2 = ["google-re2 (>=1.1)"] +tests = ["pytest (>=9)", "typing-extensions (>=4.15)"] + [[package]] name = "pexpect" version = "4.9.0" @@ -1190,104 +1234,104 @@ ptyprocess = ">=0.5" [[package]] name = "pillow" -version = "12.0.0" +version = "12.1.0" description = "Python Imaging Library (fork)" optional = true python-versions = ">=3.10" groups = ["main"] markers = "extra == \"gui\"" files = [ - {file = "pillow-12.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:3adfb466bbc544b926d50fe8f4a4e6abd8c6bffd28a26177594e6e9b2b76572b"}, - {file = "pillow-12.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1ac11e8ea4f611c3c0147424eae514028b5e9077dd99ab91e1bd7bc33ff145e1"}, - {file = "pillow-12.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d49e2314c373f4c2b39446fb1a45ed333c850e09d0c59ac79b72eb3b95397363"}, - {file = "pillow-12.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c7b2a63fd6d5246349f3d3f37b14430d73ee7e8173154461785e43036ffa96ca"}, - {file = "pillow-12.0.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d64317d2587c70324b79861babb9c09f71fbb780bad212018874b2c013d8600e"}, - {file = "pillow-12.0.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d77153e14b709fd8b8af6f66a3afbb9ed6e9fc5ccf0b6b7e1ced7b036a228782"}, - {file = "pillow-12.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:32ed80ea8a90ee3e6fa08c21e2e091bba6eda8eccc83dbc34c95169507a91f10"}, - {file = "pillow-12.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c828a1ae702fc712978bda0320ba1b9893d99be0badf2647f693cc01cf0f04fa"}, - {file = "pillow-12.0.0-cp310-cp310-win32.whl", hash = "sha256:bd87e140e45399c818fac4247880b9ce719e4783d767e030a883a970be632275"}, - {file = "pillow-12.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:455247ac8a4cfb7b9bc45b7e432d10421aea9fc2e74d285ba4072688a74c2e9d"}, - {file = "pillow-12.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:6ace95230bfb7cd79ef66caa064bbe2f2a1e63d93471c3a2e1f1348d9f22d6b7"}, - {file = "pillow-12.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0fd00cac9c03256c8b2ff58f162ebcd2587ad3e1f2e397eab718c47e24d231cc"}, - {file = "pillow-12.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3475b96f5908b3b16c47533daaa87380c491357d197564e0ba34ae75c0f3257"}, - {file = "pillow-12.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:110486b79f2d112cf6add83b28b627e369219388f64ef2f960fef9ebaf54c642"}, - {file = "pillow-12.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5269cc1caeedb67e6f7269a42014f381f45e2e7cd42d834ede3c703a1d915fe3"}, - {file = "pillow-12.0.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa5129de4e174daccbc59d0a3b6d20eaf24417d59851c07ebb37aeb02947987c"}, - {file = "pillow-12.0.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bee2a6db3a7242ea309aa7ee8e2780726fed67ff4e5b40169f2c940e7eb09227"}, - {file = "pillow-12.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:90387104ee8400a7b4598253b4c406f8958f59fcf983a6cea2b50d59f7d63d0b"}, - {file = "pillow-12.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc91a56697869546d1b8f0a3ff35224557ae7f881050e99f615e0119bf934b4e"}, - {file = "pillow-12.0.0-cp311-cp311-win32.whl", hash = "sha256:27f95b12453d165099c84f8a8bfdfd46b9e4bda9e0e4b65f0635430027f55739"}, - {file = "pillow-12.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:b583dc9070312190192631373c6c8ed277254aa6e6084b74bdd0a6d3b221608e"}, - {file = "pillow-12.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:759de84a33be3b178a64c8ba28ad5c135900359e85fb662bc6e403ad4407791d"}, - {file = "pillow-12.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:53561a4ddc36facb432fae7a9d8afbfaf94795414f5cdc5fc52f28c1dca90371"}, - {file = "pillow-12.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:71db6b4c1653045dacc1585c1b0d184004f0d7e694c7b34ac165ca70c0838082"}, - {file = "pillow-12.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2fa5f0b6716fc88f11380b88b31fe591a06c6315e955c096c35715788b339e3f"}, - {file = "pillow-12.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:82240051c6ca513c616f7f9da06e871f61bfd7805f566275841af15015b8f98d"}, - {file = "pillow-12.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55f818bd74fe2f11d4d7cbc65880a843c4075e0ac7226bc1a23261dbea531953"}, - {file = "pillow-12.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b87843e225e74576437fd5b6a4c2205d422754f84a06942cfaf1dc32243e45a8"}, - {file = "pillow-12.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c607c90ba67533e1b2355b821fef6764d1dd2cbe26b8c1005ae84f7aea25ff79"}, - {file = "pillow-12.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:21f241bdd5080a15bc86d3466a9f6074a9c2c2b314100dd896ac81ee6db2f1ba"}, - {file = "pillow-12.0.0-cp312-cp312-win32.whl", hash = "sha256:dd333073e0cacdc3089525c7df7d39b211bcdf31fc2824e49d01c6b6187b07d0"}, - {file = "pillow-12.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:9fe611163f6303d1619bbcb653540a4d60f9e55e622d60a3108be0d5b441017a"}, - {file = "pillow-12.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:7dfb439562f234f7d57b1ac6bc8fe7f838a4bd49c79230e0f6a1da93e82f1fad"}, - {file = "pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0869154a2d0546545cde61d1789a6524319fc1897d9ee31218eae7a60ccc5643"}, - {file = "pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a7921c5a6d31b3d756ec980f2f47c0cfdbce0fc48c22a39347a895f41f4a6ea4"}, - {file = "pillow-12.0.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:1ee80a59f6ce048ae13cda1abf7fbd2a34ab9ee7d401c46be3ca685d1999a399"}, - {file = "pillow-12.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c50f36a62a22d350c96e49ad02d0da41dbd17ddc2e29750dbdba4323f85eb4a5"}, - {file = "pillow-12.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5193fde9a5f23c331ea26d0cf171fbf67e3f247585f50c08b3e205c7aeb4589b"}, - {file = "pillow-12.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bde737cff1a975b70652b62d626f7785e0480918dece11e8fef3c0cf057351c3"}, - {file = "pillow-12.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a6597ff2b61d121172f5844b53f21467f7082f5fb385a9a29c01414463f93b07"}, - {file = "pillow-12.0.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b817e7035ea7f6b942c13aa03bb554fc44fea70838ea21f8eb31c638326584e"}, - {file = "pillow-12.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f4f1231b7dec408e8670264ce63e9c71409d9583dd21d32c163e25213ee2a344"}, - {file = "pillow-12.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e51b71417049ad6ab14c49608b4a24d8fb3fe605e5dfabfe523b58064dc3d27"}, - {file = "pillow-12.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d120c38a42c234dc9a8c5de7ceaaf899cf33561956acb4941653f8bdc657aa79"}, - {file = "pillow-12.0.0-cp313-cp313-win32.whl", hash = "sha256:4cc6b3b2efff105c6a1656cfe59da4fdde2cda9af1c5e0b58529b24525d0a098"}, - {file = "pillow-12.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:4cf7fed4b4580601c4345ceb5d4cbf5a980d030fd5ad07c4d2ec589f95f09905"}, - {file = "pillow-12.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:9f0b04c6b8584c2c193babcccc908b38ed29524b29dd464bc8801bf10d746a3a"}, - {file = "pillow-12.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7fa22993bac7b77b78cae22bad1e2a987ddf0d9015c63358032f84a53f23cdc3"}, - {file = "pillow-12.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f135c702ac42262573fe9714dfe99c944b4ba307af5eb507abef1667e2cbbced"}, - {file = "pillow-12.0.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c85de1136429c524e55cfa4e033b4a7940ac5c8ee4d9401cc2d1bf48154bbc7b"}, - {file = "pillow-12.0.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38df9b4bfd3db902c9c2bd369bcacaf9d935b2fff73709429d95cc41554f7b3d"}, - {file = "pillow-12.0.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d87ef5795da03d742bf49439f9ca4d027cde49c82c5371ba52464aee266699a"}, - {file = "pillow-12.0.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aff9e4d82d082ff9513bdd6acd4f5bd359f5b2c870907d2b0a9c5e10d40c88fe"}, - {file = "pillow-12.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8d8ca2b210ada074d57fcee40c30446c9562e542fc46aedc19baf758a93532ee"}, - {file = "pillow-12.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:99a7f72fb6249302aa62245680754862a44179b545ded638cf1fef59befb57ef"}, - {file = "pillow-12.0.0-cp313-cp313t-win32.whl", hash = "sha256:4078242472387600b2ce8d93ade8899c12bf33fa89e55ec89fe126e9d6d5d9e9"}, - {file = "pillow-12.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2c54c1a783d6d60595d3514f0efe9b37c8808746a66920315bfd34a938d7994b"}, - {file = "pillow-12.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:26d9f7d2b604cd23aba3e9faf795787456ac25634d82cd060556998e39c6fa47"}, - {file = "pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:beeae3f27f62308f1ddbcfb0690bf44b10732f2ef43758f169d5e9303165d3f9"}, - {file = "pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:d4827615da15cd59784ce39d3388275ec093ae3ee8d7f0c089b76fa87af756c2"}, - {file = "pillow-12.0.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:3e42edad50b6909089750e65c91aa09aaf1e0a71310d383f11321b27c224ed8a"}, - {file = "pillow-12.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e5d8efac84c9afcb40914ab49ba063d94f5dbdf5066db4482c66a992f47a3a3b"}, - {file = "pillow-12.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:266cd5f2b63ff316d5a1bba46268e603c9caf5606d44f38c2873c380950576ad"}, - {file = "pillow-12.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58eea5ebe51504057dd95c5b77d21700b77615ab0243d8152793dc00eb4faf01"}, - {file = "pillow-12.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f13711b1a5ba512d647a0e4ba79280d3a9a045aaf7e0cc6fbe96b91d4cdf6b0c"}, - {file = "pillow-12.0.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6846bd2d116ff42cba6b646edf5bf61d37e5cbd256425fa089fee4ff5c07a99e"}, - {file = "pillow-12.0.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c98fa880d695de164b4135a52fd2e9cd7b7c90a9d8ac5e9e443a24a95ef9248e"}, - {file = "pillow-12.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa3ed2a29a9e9d2d488b4da81dcb54720ac3104a20bf0bd273f1e4648aff5af9"}, - {file = "pillow-12.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d034140032870024e6b9892c692fe2968493790dd57208b2c37e3fb35f6df3ab"}, - {file = "pillow-12.0.0-cp314-cp314-win32.whl", hash = "sha256:1b1b133e6e16105f524a8dec491e0586d072948ce15c9b914e41cdadd209052b"}, - {file = "pillow-12.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:8dc232e39d409036af549c86f24aed8273a40ffa459981146829a324e0848b4b"}, - {file = "pillow-12.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:d52610d51e265a51518692045e372a4c363056130d922a7351429ac9f27e70b0"}, - {file = "pillow-12.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1979f4566bb96c1e50a62d9831e2ea2d1211761e5662afc545fa766f996632f6"}, - {file = "pillow-12.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b2e4b27a6e15b04832fe9bf292b94b5ca156016bbc1ea9c2c20098a0320d6cf6"}, - {file = "pillow-12.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fb3096c30df99fd01c7bf8e544f392103d0795b9f98ba71a8054bcbf56b255f1"}, - {file = "pillow-12.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7438839e9e053ef79f7112c881cef684013855016f928b168b81ed5835f3e75e"}, - {file = "pillow-12.0.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d5c411a8eaa2299322b647cd932586b1427367fd3184ffbb8f7a219ea2041ca"}, - {file = "pillow-12.0.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7e091d464ac59d2c7ad8e7e08105eaf9dafbc3883fd7265ffccc2baad6ac925"}, - {file = "pillow-12.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:792a2c0be4dcc18af9d4a2dfd8a11a17d5e25274a1062b0ec1c2d79c76f3e7f8"}, - {file = "pillow-12.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:afbefa430092f71a9593a99ab6a4e7538bc9eabbf7bf94f91510d3503943edc4"}, - {file = "pillow-12.0.0-cp314-cp314t-win32.whl", hash = "sha256:3830c769decf88f1289680a59d4f4c46c72573446352e2befec9a8512104fa52"}, - {file = "pillow-12.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:905b0365b210c73afb0ebe9101a32572152dfd1c144c7e28968a331b9217b94a"}, - {file = "pillow-12.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:99353a06902c2e43b43e8ff74ee65a7d90307d82370604746738a1e0661ccca7"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b22bd8c974942477156be55a768f7aa37c46904c175be4e158b6a86e3a6b7ca8"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:805ebf596939e48dbb2e4922a1d3852cfc25c38160751ce02da93058b48d252a"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cae81479f77420d217def5f54b5b9d279804d17e982e0f2fa19b1d1e14ab5197"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aeaefa96c768fc66818730b952a862235d68825c178f1b3ffd4efd7ad2edcb7c"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09f2d0abef9e4e2f349305a4f8cc784a8a6c2f58a8c4892eea13b10a943bd26e"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bdee52571a343d721fb2eb3b090a82d959ff37fc631e3f70422e0c2e029f3e76"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b290fd8aa38422444d4b50d579de197557f182ef1068b75f5aa8558638b8d0a5"}, - {file = "pillow-12.0.0.tar.gz", hash = "sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353"}, + {file = "pillow-12.1.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:fb125d860738a09d363a88daa0f59c4533529a90e564785e20fe875b200b6dbd"}, + {file = "pillow-12.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cad302dc10fac357d3467a74a9561c90609768a6f73a1923b0fd851b6486f8b0"}, + {file = "pillow-12.1.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a40905599d8079e09f25027423aed94f2823adaf2868940de991e53a449e14a8"}, + {file = "pillow-12.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:92a7fe4225365c5e3a8e598982269c6d6698d3e783b3b1ae979e7819f9cd55c1"}, + {file = "pillow-12.1.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f10c98f49227ed8383d28174ee95155a675c4ed7f85e2e573b04414f7e371bda"}, + {file = "pillow-12.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8637e29d13f478bc4f153d8daa9ffb16455f0a6cb287da1b432fdad2bfbd66c7"}, + {file = "pillow-12.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:21e686a21078b0f9cb8c8a961d99e6a4ddb88e0fc5ea6e130172ddddc2e5221a"}, + {file = "pillow-12.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2415373395a831f53933c23ce051021e79c8cd7979822d8cc478547a3f4da8ef"}, + {file = "pillow-12.1.0-cp310-cp310-win32.whl", hash = "sha256:e75d3dba8fc1ddfec0cd752108f93b83b4f8d6ab40e524a95d35f016b9683b09"}, + {file = "pillow-12.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:64efdf00c09e31efd754448a383ea241f55a994fd079866b92d2bbff598aad91"}, + {file = "pillow-12.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:f188028b5af6b8fb2e9a76ac0f841a575bd1bd396e46ef0840d9b88a48fdbcea"}, + {file = "pillow-12.1.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:a83e0850cb8f5ac975291ebfc4170ba481f41a28065277f7f735c202cd8e0af3"}, + {file = "pillow-12.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b6e53e82ec2db0717eabb276aa56cf4e500c9a7cec2c2e189b55c24f65a3e8c0"}, + {file = "pillow-12.1.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:40a8e3b9e8773876d6e30daed22f016509e3987bab61b3b7fe309d7019a87451"}, + {file = "pillow-12.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:800429ac32c9b72909c671aaf17ecd13110f823ddb7db4dfef412a5587c2c24e"}, + {file = "pillow-12.1.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b022eaaf709541b391ee069f0022ee5b36c709df71986e3f7be312e46f42c84"}, + {file = "pillow-12.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f345e7bc9d7f368887c712aa5054558bad44d2a301ddf9248599f4161abc7c0"}, + {file = "pillow-12.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d70347c8a5b7ccd803ec0c85c8709f036e6348f1e6a5bf048ecd9c64d3550b8b"}, + {file = "pillow-12.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1fcc52d86ce7a34fd17cb04e87cfdb164648a3662a6f20565910a99653d66c18"}, + {file = "pillow-12.1.0-cp311-cp311-win32.whl", hash = "sha256:3ffaa2f0659e2f740473bcf03c702c39a8d4b2b7ffc629052028764324842c64"}, + {file = "pillow-12.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:806f3987ffe10e867bab0ddad45df1148a2b98221798457fa097ad85d6e8bc75"}, + {file = "pillow-12.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:9f5fefaca968e700ad1a4a9de98bf0869a94e397fe3524c4c9450c1445252304"}, + {file = "pillow-12.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a332ac4ccb84b6dde65dbace8431f3af08874bf9770719d32a635c4ef411b18b"}, + {file = "pillow-12.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:907bfa8a9cb790748a9aa4513e37c88c59660da3bcfffbd24a7d9e6abf224551"}, + {file = "pillow-12.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:efdc140e7b63b8f739d09a99033aa430accce485ff78e6d311973a67b6bf3208"}, + {file = "pillow-12.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bef9768cab184e7ae6e559c032e95ba8d07b3023c289f79a2bd36e8bf85605a5"}, + {file = "pillow-12.1.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:742aea052cf5ab5034a53c3846165bc3ce88d7c38e954120db0ab867ca242661"}, + {file = "pillow-12.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a6dfc2af5b082b635af6e08e0d1f9f1c4e04d17d4e2ca0ef96131e85eda6eb17"}, + {file = "pillow-12.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:609e89d9f90b581c8d16358c9087df76024cf058fa693dd3e1e1620823f39670"}, + {file = "pillow-12.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:43b4899cfd091a9693a1278c4982f3e50f7fb7cff5153b05174b4afc9593b616"}, + {file = "pillow-12.1.0-cp312-cp312-win32.whl", hash = "sha256:aa0c9cc0b82b14766a99fbe6084409972266e82f459821cd26997a488a7261a7"}, + {file = "pillow-12.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:d70534cea9e7966169ad29a903b99fc507e932069a881d0965a1a84bb57f6c6d"}, + {file = "pillow-12.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:65b80c1ee7e14a87d6a068dd3b0aea268ffcabfe0498d38661b00c5b4b22e74c"}, + {file = "pillow-12.1.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:7b5dd7cbae20285cdb597b10eb5a2c13aa9de6cde9bb64a3c1317427b1db1ae1"}, + {file = "pillow-12.1.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:29a4cef9cb672363926f0470afc516dbf7305a14d8c54f7abbb5c199cd8f8179"}, + {file = "pillow-12.1.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:681088909d7e8fa9e31b9799aaa59ba5234c58e5e4f1951b4c4d1082a2e980e0"}, + {file = "pillow-12.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:983976c2ab753166dc66d36af6e8ec15bb511e4a25856e2227e5f7e00a160587"}, + {file = "pillow-12.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:db44d5c160a90df2d24a24760bbd37607d53da0b34fb546c4c232af7192298ac"}, + {file = "pillow-12.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6b7a9d1db5dad90e2991645874f708e87d9a3c370c243c2d7684d28f7e133e6b"}, + {file = "pillow-12.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6258f3260986990ba2fa8a874f8b6e808cf5abb51a94015ca3dc3c68aa4f30ea"}, + {file = "pillow-12.1.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e115c15e3bc727b1ca3e641a909f77f8ca72a64fff150f666fcc85e57701c26c"}, + {file = "pillow-12.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6741e6f3074a35e47c77b23a4e4f2d90db3ed905cb1c5e6e0d49bff2045632bc"}, + {file = "pillow-12.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:935b9d1aed48fcfb3f838caac506f38e29621b44ccc4f8a64d575cb1b2a88644"}, + {file = "pillow-12.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5fee4c04aad8932da9f8f710af2c1a15a83582cfb884152a9caa79d4efcdbf9c"}, + {file = "pillow-12.1.0-cp313-cp313-win32.whl", hash = "sha256:a786bf667724d84aa29b5db1c61b7bfdde380202aaca12c3461afd6b71743171"}, + {file = "pillow-12.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:461f9dfdafa394c59cd6d818bdfdbab4028b83b02caadaff0ffd433faf4c9a7a"}, + {file = "pillow-12.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:9212d6b86917a2300669511ed094a9406888362e085f2431a7da985a6b124f45"}, + {file = "pillow-12.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:00162e9ca6d22b7c3ee8e61faa3c3253cd19b6a37f126cad04f2f88b306f557d"}, + {file = "pillow-12.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7d6daa89a00b58c37cb1747ec9fb7ac3bc5ffd5949f5888657dfddde6d1312e0"}, + {file = "pillow-12.1.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e2479c7f02f9d505682dc47df8c0ea1fc5e264c4d1629a5d63fe3e2334b89554"}, + {file = "pillow-12.1.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f188d580bd870cda1e15183790d1cc2fa78f666e76077d103edf048eed9c356e"}, + {file = "pillow-12.1.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0fde7ec5538ab5095cc02df38ee99b0443ff0e1c847a045554cf5f9af1f4aa82"}, + {file = "pillow-12.1.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ed07dca4a8464bada6139ab38f5382f83e5f111698caf3191cb8dbf27d908b4"}, + {file = "pillow-12.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f45bd71d1fa5e5749587613037b172e0b3b23159d1c00ef2fc920da6f470e6f0"}, + {file = "pillow-12.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:277518bf4fe74aa91489e1b20577473b19ee70fb97c374aa50830b279f25841b"}, + {file = "pillow-12.1.0-cp313-cp313t-win32.whl", hash = "sha256:7315f9137087c4e0ee73a761b163fc9aa3b19f5f606a7fc08d83fd3e4379af65"}, + {file = "pillow-12.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:0ddedfaa8b5f0b4ffbc2fa87b556dc59f6bb4ecb14a53b33f9189713ae8053c0"}, + {file = "pillow-12.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:80941e6d573197a0c28f394753de529bb436b1ca990ed6e765cf42426abc39f8"}, + {file = "pillow-12.1.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:5cb7bc1966d031aec37ddb9dcf15c2da5b2e9f7cc3ca7c54473a20a927e1eb91"}, + {file = "pillow-12.1.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:97e9993d5ed946aba26baf9c1e8cf18adbab584b99f452ee72f7ee8acb882796"}, + {file = "pillow-12.1.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:414b9a78e14ffeb98128863314e62c3f24b8a86081066625700b7985b3f529bd"}, + {file = "pillow-12.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e6bdb408f7c9dd2a5ff2b14a3b0bb6d4deb29fb9961e6eb3ae2031ae9a5cec13"}, + {file = "pillow-12.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3413c2ae377550f5487991d444428f1a8ae92784aac79caa8b1e3b89b175f77e"}, + {file = "pillow-12.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e5dcbe95016e88437ecf33544ba5db21ef1b8dd6e1b434a2cb2a3d605299e643"}, + {file = "pillow-12.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d0a7735df32ccbcc98b98a1ac785cc4b19b580be1bdf0aeb5c03223220ea09d5"}, + {file = "pillow-12.1.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c27407a2d1b96774cbc4a7594129cc027339fd800cd081e44497722ea1179de"}, + {file = "pillow-12.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15c794d74303828eaa957ff8070846d0efe8c630901a1c753fdc63850e19ecd9"}, + {file = "pillow-12.1.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c990547452ee2800d8506c4150280757f88532f3de2a58e3022e9b179107862a"}, + {file = "pillow-12.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b63e13dd27da389ed9475b3d28510f0f954bca0041e8e551b2a4eb1eab56a39a"}, + {file = "pillow-12.1.0-cp314-cp314-win32.whl", hash = "sha256:1a949604f73eb07a8adab38c4fe50791f9919344398bdc8ac6b307f755fc7030"}, + {file = "pillow-12.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:4f9f6a650743f0ddee5593ac9e954ba1bdbc5e150bc066586d4f26127853ab94"}, + {file = "pillow-12.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:808b99604f7873c800c4840f55ff389936ef1948e4e87645eaf3fccbc8477ac4"}, + {file = "pillow-12.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bc11908616c8a283cf7d664f77411a5ed2a02009b0097ff8abbba5e79128ccf2"}, + {file = "pillow-12.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:896866d2d436563fa2a43a9d72f417874f16b5545955c54a64941e87c1376c61"}, + {file = "pillow-12.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8e178e3e99d3c0ea8fc64b88447f7cac8ccf058af422a6cedc690d0eadd98c51"}, + {file = "pillow-12.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:079af2fb0c599c2ec144ba2c02766d1b55498e373b3ac64687e43849fbbef5bc"}, + {file = "pillow-12.1.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bdec5e43377761c5dbca620efb69a77f6855c5a379e32ac5b158f54c84212b14"}, + {file = "pillow-12.1.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:565c986f4b45c020f5421a4cea13ef294dde9509a8577f29b2fc5edc7587fff8"}, + {file = "pillow-12.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:43aca0a55ce1eefc0aefa6253661cb54571857b1a7b2964bd8a1e3ef4b729924"}, + {file = "pillow-12.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0deedf2ea233722476b3a81e8cdfbad786f7adbed5d848469fa59fe52396e4ef"}, + {file = "pillow-12.1.0-cp314-cp314t-win32.whl", hash = "sha256:b17fbdbe01c196e7e159aacb889e091f28e61020a8abeac07b68079b6e626988"}, + {file = "pillow-12.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27b9baecb428899db6c0de572d6d305cfaf38ca1596b5c0542a5182e3e74e8c6"}, + {file = "pillow-12.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:f61333d817698bdcdd0f9d7793e365ac3d2a21c1f1eb02b32ad6aefb8d8ea831"}, + {file = "pillow-12.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ca94b6aac0d7af2a10ba08c0f888b3d5114439b6b3ef39968378723622fed377"}, + {file = "pillow-12.1.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:351889afef0f485b84078ea40fe33727a0492b9af3904661b0abbafee0355b72"}, + {file = "pillow-12.1.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bb0984b30e973f7e2884362b7d23d0a348c7143ee559f38ef3eaab640144204c"}, + {file = "pillow-12.1.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:84cabc7095dd535ca934d57e9ce2a72ffd216e435a84acb06b2277b1de2689bd"}, + {file = "pillow-12.1.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53d8b764726d3af1a138dd353116f774e3862ec7e3794e0c8781e30db0f35dfc"}, + {file = "pillow-12.1.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5da841d81b1a05ef940a8567da92decaa15bc4d7dedb540a8c219ad83d91808a"}, + {file = "pillow-12.1.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:75af0b4c229ac519b155028fa1be632d812a519abba9b46b20e50c6caa184f19"}, + {file = "pillow-12.1.0.tar.gz", hash = "sha256:5c5ae0a06e9ea030ab786b0251b32c7e4ce10e58d983c0d5c56029455180b5b9"}, ] [package.extras] @@ -1300,14 +1344,14 @@ xmp = ["defusedxml"] [[package]] name = "platformdirs" -version = "4.5.0" +version = "4.5.1" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3"}, - {file = "platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312"}, + {file = "platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31"}, + {file = "platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda"}, ] [package.extras] @@ -1333,41 +1377,41 @@ testing = ["coverage", "pytest", "pytest-benchmark"] [[package]] name = "poethepoet" -version = "0.37.0" +version = "0.41.0" description = "A task runner that works well with poetry and uv." optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "poethepoet-0.37.0-py3-none-any.whl", hash = "sha256:861790276315abcc8df1b4bd60e28c3d48a06db273edd3092f3c94e1a46e5e22"}, - {file = "poethepoet-0.37.0.tar.gz", hash = "sha256:73edf458707c674a079baa46802e21455bda3a7f82a408e58c31b9f4fe8e933d"}, + {file = "poethepoet-0.41.0-py3-none-any.whl", hash = "sha256:4bab9fd8271664c5d21407e8f12827daeb6aa484dc6cc7620f0c3b4e62b42ee4"}, + {file = "poethepoet-0.41.0.tar.gz", hash = "sha256:dcaad621dc061f6a90b17d091bebb9ca043d67bfe9bd6aa4185aea3ebf7ff3e6"}, ] [package.dependencies] pastel = ">=0.2.1,<0.3.0" -pyyaml = ">=6.0.2,<7.0" +pyyaml = ">=6.0.3,<7.0" [package.extras] poetry-plugin = ["poetry (>=1.2.0,<3.0.0) ; python_version < \"4.0\""] [[package]] name = "protobuf" -version = "6.33.0" +version = "6.33.5" description = "" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "protobuf-6.33.0-cp310-abi3-win32.whl", hash = "sha256:d6101ded078042a8f17959eccd9236fb7a9ca20d3b0098bbcb91533a5680d035"}, - {file = "protobuf-6.33.0-cp310-abi3-win_amd64.whl", hash = "sha256:9a031d10f703f03768f2743a1c403af050b6ae1f3480e9c140f39c45f81b13ee"}, - {file = "protobuf-6.33.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:905b07a65f1a4b72412314082c7dbfae91a9e8b68a0cc1577515f8df58ecf455"}, - {file = "protobuf-6.33.0-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e0697ece353e6239b90ee43a9231318302ad8353c70e6e45499fa52396debf90"}, - {file = "protobuf-6.33.0-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:e0a1715e4f27355afd9570f3ea369735afc853a6c3951a6afe1f80d8569ad298"}, - {file = "protobuf-6.33.0-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:35be49fd3f4fefa4e6e2aacc35e8b837d6703c37a2168a55ac21e9b1bc7559ef"}, - {file = "protobuf-6.33.0-cp39-cp39-win32.whl", hash = "sha256:cd33a8e38ea3e39df66e1bbc462b076d6e5ba3a4ebbde58219d777223a7873d3"}, - {file = "protobuf-6.33.0-cp39-cp39-win_amd64.whl", hash = "sha256:c963e86c3655af3a917962c9619e1a6b9670540351d7af9439d06064e3317cc9"}, - {file = "protobuf-6.33.0-py3-none-any.whl", hash = "sha256:25c9e1963c6734448ea2d308cfa610e692b801304ba0908d7bfa564ac5132995"}, - {file = "protobuf-6.33.0.tar.gz", hash = "sha256:140303d5c8d2037730c548f8c7b93b20bb1dc301be280c378b82b8894589c954"}, + {file = "protobuf-6.33.5-cp310-abi3-win32.whl", hash = "sha256:d71b040839446bac0f4d162e758bea99c8251161dae9d0983a3b88dee345153b"}, + {file = "protobuf-6.33.5-cp310-abi3-win_amd64.whl", hash = "sha256:3093804752167bcab3998bec9f1048baae6e29505adaf1afd14a37bddede533c"}, + {file = "protobuf-6.33.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:a5cb85982d95d906df1e2210e58f8e4f1e3cdc088e52c921a041f9c9a0386de5"}, + {file = "protobuf-6.33.5-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:9b71e0281f36f179d00cbcb119cb19dec4d14a81393e5ea220f64b286173e190"}, + {file = "protobuf-6.33.5-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8afa18e1d6d20af15b417e728e9f60f3aa108ee76f23c3b2c07a2c3b546d3afd"}, + {file = "protobuf-6.33.5-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:cbf16ba3350fb7b889fca858fb215967792dc125b35c7976ca4818bee3521cf0"}, + {file = "protobuf-6.33.5-cp39-cp39-win32.whl", hash = "sha256:a3157e62729aafb8df6da2c03aa5c0937c7266c626ce11a278b6eb7963c4e37c"}, + {file = "protobuf-6.33.5-cp39-cp39-win_amd64.whl", hash = "sha256:8f04fa32763dcdb4973d537d6b54e615cc61108c7cb38fe59310c3192d29510a"}, + {file = "protobuf-6.33.5-py3-none-any.whl", hash = "sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02"}, + {file = "protobuf-6.33.5.tar.gz", hash = "sha256:6ddcac2a081f8b7b9642c09406bc6a4290128fce5f471cddd165960bb9119e5c"}, ] [[package]] @@ -1384,14 +1428,14 @@ files = [ [[package]] name = "pydantic" -version = "2.12.4" +version = "2.12.5" description = "Data validation using Python type hints" optional = false python-versions = ">=3.9" groups = ["main", "dev"] files = [ - {file = "pydantic-2.12.4-py3-none-any.whl", hash = "sha256:92d3d202a745d46f9be6df459ac5a064fdaa3c1c4cd8adcfa332ccf3c05f871e"}, - {file = "pydantic-2.12.4.tar.gz", hash = "sha256:0f8cb9555000a4b5b617f66bfd2566264c4984b27589d3b845685983e8ea85ac"}, + {file = "pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d"}, + {file = "pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49"}, ] [package.dependencies] @@ -1540,14 +1584,14 @@ typing-extensions = ">=4.14.1" [[package]] name = "pydantic-settings" -version = "2.11.0" +version = "2.12.0" description = "Settings management using Pydantic" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "pydantic_settings-2.11.0-py3-none-any.whl", hash = "sha256:fe2cea3413b9530d10f3a5875adffb17ada5c1e1bab0b2885546d7310415207c"}, - {file = "pydantic_settings-2.11.0.tar.gz", hash = "sha256:d0e87a1c7d33593beb7194adb8470fc426e95ba02af83a0f23474a04c9a08180"}, + {file = "pydantic_settings-2.12.0-py3-none-any.whl", hash = "sha256:fddb9fd99a5b18da837b29710391e945b1e30c135477f484084ee513adb93809"}, + {file = "pydantic_settings-2.12.0.tar.gz", hash = "sha256:005538ef951e3c2a68e1c08b292b5f2e71490def8589d4221b95dab00dafcfd0"}, ] [package.dependencies] @@ -1564,14 +1608,14 @@ yaml = ["pyyaml (>=6.0.1)"] [[package]] name = "pydoclint" -version = "0.8.1" +version = "0.8.3" description = "A Python docstring linter that checks arguments, returns, yields, and raises sections" optional = false python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "pydoclint-0.8.1-py3-none-any.whl", hash = "sha256:48e4f95031e50bf4d5b266484b07a959ed185f16305129a570bc7db2b4648f4c"}, - {file = "pydoclint-0.8.1.tar.gz", hash = "sha256:1febdefb0d8d4373604dd9750435b7bf181e0c17b9fcf69c4c20f05d0aa569f4"}, + {file = "pydoclint-0.8.3-py3-none-any.whl", hash = "sha256:5fc9b82d0d515afce0908cb70e8ff695a68b19042785c248c4f227ad66b4a164"}, + {file = "pydoclint-0.8.3.tar.gz", hash = "sha256:0c69c0ed92c6f6b5aec2a14371bbd9e0a77980da8e2fa0f708092aa06b3b20b3"}, ] [package.dependencies] @@ -1616,18 +1660,18 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pylint" -version = "4.0.2" +version = "4.0.4" description = "python code static checker" optional = false python-versions = ">=3.10.0" groups = ["dev"] files = [ - {file = "pylint-4.0.2-py3-none-any.whl", hash = "sha256:9627ccd129893fb8ee8e8010261cb13485daca83e61a6f854a85528ee579502d"}, - {file = "pylint-4.0.2.tar.gz", hash = "sha256:9c22dfa52781d3b79ce86ab2463940f874921a3e5707bcfc98dd0c019945014e"}, + {file = "pylint-4.0.4-py3-none-any.whl", hash = "sha256:63e06a37d5922555ee2c20963eb42559918c20bd2b21244e4ef426e7c43b92e0"}, + {file = "pylint-4.0.4.tar.gz", hash = "sha256:d9b71674e19b1c36d79265b5887bf8e55278cbe236c9e95d22dc82cf044fdbd2"}, ] [package.dependencies] -astroid = ">=4.0.1,<=4.1.dev0" +astroid = ">=4.0.2,<=4.1.dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = [ {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, @@ -1644,90 +1688,90 @@ testutils = ["gitpython (>3)"] [[package]] name = "pyobjc-core" -version = "12.0" +version = "12.1" description = "Python<->ObjC Interoperability Module" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["main"] markers = "platform_system == \"Darwin\"" files = [ - {file = "pyobjc_core-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:beb665937b0df76412dfd08c6518925806e41536307629a859105270e3a5e6c9"}, - {file = "pyobjc_core-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:dd4962aceb0f9a0ee510e11ced449323db85e42664ac9ade53ad1cc2394dc248"}, - {file = "pyobjc_core-12.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1675dbb700b6bb6e3f3c9ce3f5401947e0193e16085eeb70e9160c6c6fc1ace5"}, - {file = "pyobjc_core-12.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c44b76d8306a130c9eb0cb79d86fd6675c8ba3e5b458e78095d271a10cd38b6a"}, - {file = "pyobjc_core-12.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:5c617551e0ab860c49229fcec0135a5cde702485f22254ddc17205eb24b7fc55"}, - {file = "pyobjc_core-12.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c2709ff43ac5c2e9e2c574ae515d3aa0e470345847a4d96c5d4a04b1b86e966d"}, - {file = "pyobjc_core-12.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:eb6b987e53291e7cafd8f71a80a2dd44d7afec4202a143a3e47b75cb9cdb5716"}, - {file = "pyobjc_core-12.0.tar.gz", hash = "sha256:7e05c805a776149a937b61b892a0459895d32d9002bedc95ce2be31ef1e37a29"}, + {file = "pyobjc_core-12.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:93418e79c1655f66b4352168f8c85c942707cb1d3ea13a1da3e6f6a143bacda7"}, + {file = "pyobjc_core-12.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c918ebca280925e7fcb14c5c43ce12dcb9574a33cccb889be7c8c17f3bcce8b6"}, + {file = "pyobjc_core-12.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:818bcc6723561f207e5b5453efe9703f34bc8781d11ce9b8be286bb415eb4962"}, + {file = "pyobjc_core-12.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:01c0cf500596f03e21c23aef9b5f326b9fb1f8f118cf0d8b66749b6cf4cbb37a"}, + {file = "pyobjc_core-12.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:177aaca84bb369a483e4961186704f64b2697708046745f8167e818d968c88fc"}, + {file = "pyobjc_core-12.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:844515f5d86395b979d02152576e7dee9cc679acc0b32dc626ef5bda315eaa43"}, + {file = "pyobjc_core-12.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:453b191df1a4b80e756445b935491b974714456ae2cbae816840bd96f86db882"}, + {file = "pyobjc_core-12.1.tar.gz", hash = "sha256:2bb3903f5387f72422145e1466b3ac3f7f0ef2e9960afa9bcd8961c5cbf8bd21"}, ] [[package]] name = "pyobjc-framework-cocoa" -version = "12.0" +version = "12.1" description = "Wrappers for the Cocoa frameworks on macOS" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main"] markers = "platform_system == \"Darwin\"" files = [ - {file = "pyobjc_framework_cocoa-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fe453a559be779fb4bc730b2f6686c5c78eb1898a7291964bc289f96506879b6"}, - {file = "pyobjc_framework_cocoa-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ae041b7c64a8fa93f0e06728681f7ad657ef2c92dcfdf8abc073d89fb6e3910b"}, - {file = "pyobjc_framework_cocoa-12.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ed99d53a91f9feb9452ba8942cd09d86727f6dd2d56ecfd9b885ddbd4259ebdd"}, - {file = "pyobjc_framework_cocoa-12.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:13e573f5093f4158f305b1bac5e1f783881ce2f5f4a69f3c80cb000f76731259"}, - {file = "pyobjc_framework_cocoa-12.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:3b167793cd1b509eaf693140ace9be1f827a2c8686fceb8c599907661f608bc2"}, - {file = "pyobjc_framework_cocoa-12.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:a2b6fb9ab3e5ab6db04dfa17828a97894e7da85dd8600885c72a0c2c2214d618"}, - {file = "pyobjc_framework_cocoa-12.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:32ff10250a57f72a0b6eca85b790dcc87548ff71d33d0436ffb69680d5e2f308"}, - {file = "pyobjc_framework_cocoa-12.0.tar.gz", hash = "sha256:02d69305b698015a20fcc8e1296e1528e413d8cf9fdcd590478d359386d76e8a"}, + {file = "pyobjc_framework_cocoa-12.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9b880d3bdcd102809d704b6d8e14e31611443aa892d9f60e8491e457182fdd48"}, + {file = "pyobjc_framework_cocoa-12.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f52228bcf38da64b77328787967d464e28b981492b33a7675585141e1b0a01e6"}, + {file = "pyobjc_framework_cocoa-12.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:547c182837214b7ec4796dac5aee3aa25abc665757b75d7f44f83c994bcb0858"}, + {file = "pyobjc_framework_cocoa-12.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5a3dcd491cacc2f5a197142b3c556d8aafa3963011110102a093349017705118"}, + {file = "pyobjc_framework_cocoa-12.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:914b74328c22d8ca261d78c23ef2befc29776e0b85555973927b338c5734ca44"}, + {file = "pyobjc_framework_cocoa-12.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:03342a60fc0015bcdf9b93ac0b4f457d3938e9ef761b28df9564c91a14f0129a"}, + {file = "pyobjc_framework_cocoa-12.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:6ba1dc1bfa4da42d04e93d2363491275fb2e2be5c20790e561c8a9e09b8cf2cc"}, + {file = "pyobjc_framework_cocoa-12.1.tar.gz", hash = "sha256:5556c87db95711b985d5efdaaf01c917ddd41d148b1e52a0c66b1a2e2c5c1640"}, ] [package.dependencies] -pyobjc-core = ">=12.0" +pyobjc-core = ">=12.1" [[package]] name = "pyobjc-framework-corebluetooth" -version = "12.0" +version = "12.1" description = "Wrappers for the framework CoreBluetooth on macOS" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main"] markers = "platform_system == \"Darwin\"" files = [ - {file = "pyobjc_framework_corebluetooth-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9ef4e511c7cf2c25a6ae9193c57f66e78de97db3153e732252a579d24fd796d3"}, - {file = "pyobjc_framework_corebluetooth-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ab59e55ab6c71fcbe747359eb1119771021231fade3c5ceae6e8a5d542e32450"}, - {file = "pyobjc_framework_corebluetooth-12.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0b5b3b276efb08a1615932327c2f79781cf57d3c46a45a373e6e630cd36f5106"}, - {file = "pyobjc_framework_corebluetooth-12.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba02d0a6257cb08a86198e70cb8c0113c81abf5f919be9078912af8eaf6688ae"}, - {file = "pyobjc_framework_corebluetooth-12.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:7696dbb61074ac657d213717869c93e6c3910369255f426844b85f4b039fb58c"}, - {file = "pyobjc_framework_corebluetooth-12.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:a50ff5e5ef5df8fd2b275fadbd51f44cec45ba78948a86339e89315909d82bd6"}, - {file = "pyobjc_framework_corebluetooth-12.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:000d3a863fcd119dbdc6682ebe4cc559e2569ec367a7417ac2635c3f411f7697"}, - {file = "pyobjc_framework_corebluetooth-12.0.tar.gz", hash = "sha256:61ae2a56c3dcb8b7307d833e7d913bd7c063d11a1ea931158facceb38aae21d3"}, + {file = "pyobjc_framework_corebluetooth-12.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:937849f4d40a33afbcc56cbe90c8d1fbf30fb27a962575b9fb7e8e2c61d3c551"}, + {file = "pyobjc_framework_corebluetooth-12.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:37e6456c8a076bd5a2bdd781d0324edd5e7397ef9ac9234a97433b522efb13cf"}, + {file = "pyobjc_framework_corebluetooth-12.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:fe72c9732ee6c5c793b9543f08c1f5bdd98cd95dfc9d96efd5708ec9d6eeb213"}, + {file = "pyobjc_framework_corebluetooth-12.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5a894f695e6c672f0260327103a31ad8b98f8d4fb9516a0383db79a82a7e58dc"}, + {file = "pyobjc_framework_corebluetooth-12.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:1daf07a0047c3ed89fab84ad5f6769537306733b6a6e92e631581a0f419e3f32"}, + {file = "pyobjc_framework_corebluetooth-12.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:15ba5207ca626dffe57ccb7c1beaf01f93930159564211cb97d744eaf0d812aa"}, + {file = "pyobjc_framework_corebluetooth-12.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:e5385195bd365a49ce70e2fb29953681eefbe68a7b15ecc2493981d2fb4a02b1"}, + {file = "pyobjc_framework_corebluetooth-12.1.tar.gz", hash = "sha256:8060c1466d90bbb9100741a1091bb79975d9ba43911c9841599879fc45c2bbe0"}, ] [package.dependencies] -pyobjc-core = ">=12.0" -pyobjc-framework-Cocoa = ">=12.0" +pyobjc-core = ">=12.1" +pyobjc-framework-Cocoa = ">=12.1" [[package]] name = "pyobjc-framework-libdispatch" -version = "12.0" +version = "12.1" description = "Wrappers for libdispatch on macOS" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main"] markers = "platform_system == \"Darwin\"" files = [ - {file = "pyobjc_framework_libdispatch-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8bebd8599909f2aabbeebd5d2a9a394b636a3b887b64ec8025b4d3bcfb15703f"}, - {file = "pyobjc_framework_libdispatch-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ea093cd250105726aff61df189daa893e6f7bd43f8865bb6e612deeec233d374"}, - {file = "pyobjc_framework_libdispatch-12.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:631db409f99302f58aa97bb395f2220bd6b2676d6ef4621802f7abd7c23786e8"}, - {file = "pyobjc_framework_libdispatch-12.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:006d492b469b2a1fe3da7df9687f2638d832ef76333e5f7c6ab023bf25703fbf"}, - {file = "pyobjc_framework_libdispatch-12.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:bb73f193fab434bd89b4d92d062a645b0068f6a3af50e00df3bc789f94927db6"}, - {file = "pyobjc_framework_libdispatch-12.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:ce51a4e729c3d549b512721bef502f5a5bdb2cc61902a4046ec8e1807064e5bb"}, - {file = "pyobjc_framework_libdispatch-12.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:cf3b4befc34a143969db6a0dfcfebaea484c8c3ec527cd73676880b06b5348fc"}, - {file = "pyobjc_framework_libdispatch-12.0.tar.gz", hash = "sha256:2ef31c02670c377d9e2875e74053087b1d96b240d2fc8721cc4c665c05394b3a"}, + {file = "pyobjc_framework_libdispatch-12.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:50a81a29506f0e35b4dc313f97a9d469f7b668dae3ba597bb67bbab94de446bd"}, + {file = "pyobjc_framework_libdispatch-12.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:954cc2d817b71383bd267cc5cd27d83536c5f879539122353ca59f1c945ac706"}, + {file = "pyobjc_framework_libdispatch-12.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0e9570d7a9a3136f54b0b834683bf3f206acd5df0e421c30f8fd4f8b9b556789"}, + {file = "pyobjc_framework_libdispatch-12.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:58ffce5e6bcd7456b4311009480b195b9f22107b7682fb0835d4908af5a68ad0"}, + {file = "pyobjc_framework_libdispatch-12.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e9f49517e253716e40a0009412151f527005eec0b9a2311ac63ecac1bdf02332"}, + {file = "pyobjc_framework_libdispatch-12.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:0ebfd9e4446ab6528126bff25cfb09e4213ddf992b3208978911cfd3152e45f5"}, + {file = "pyobjc_framework_libdispatch-12.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:23fc9915cba328216b6a736c7a48438a16213f16dfb467f69506300b95938cc7"}, + {file = "pyobjc_framework_libdispatch-12.1.tar.gz", hash = "sha256:4035535b4fae1b5e976f3e0e38b6e3442ffea1b8aa178d0ca89faa9b8ecdea41"}, ] [package.dependencies] -pyobjc-core = ">=12.0" -pyobjc-framework-Cocoa = ">=12.0" +pyobjc-core = ">=12.1" +pyobjc-framework-Cocoa = ">=12.1" [[package]] name = "pytest" @@ -1753,18 +1797,18 @@ dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests [[package]] name = "pytest-asyncio" -version = "1.2.0" +version = "1.3.0" description = "Pytest support for asyncio" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "pytest_asyncio-1.2.0-py3-none-any.whl", hash = "sha256:8e17ae5e46d8e7efe51ab6494dd2010f4ca8dae51652aa3c8d55acf50bfb2e99"}, - {file = "pytest_asyncio-1.2.0.tar.gz", hash = "sha256:c609a64a2a8768462d0c99811ddb8bd2583c33fd33cf7f21af1c142e824ffb57"}, + {file = "pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5"}, + {file = "pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5"}, ] [package.dependencies] -pytest = ">=8.2,<9" +pytest = ">=8.2,<10" typing-extensions = {version = ">=4.12", markers = "python_version < \"3.13\""} [package.extras] @@ -1793,24 +1837,24 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] [[package]] name = "pytest-html" -version = "4.1.1" +version = "4.2.0" description = "pytest plugin for generating HTML reports" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "pytest_html-4.1.1-py3-none-any.whl", hash = "sha256:c8152cea03bd4e9bee6d525573b67bbc6622967b72b9628dda0ea3e2a0b5dd71"}, - {file = "pytest_html-4.1.1.tar.gz", hash = "sha256:70a01e8ae5800f4a074b56a4cb1025c8f4f9b038bba5fe31e3c98eb996686f07"}, + {file = "pytest_html-4.2.0-py3-none-any.whl", hash = "sha256:ff5caf3e17a974008e5816edda61168e6c3da442b078a44f8744865862a85636"}, + {file = "pytest_html-4.2.0.tar.gz", hash = "sha256:b6a88cba507500d8709959201e2e757d3941e859fd17cfd4ed87b16fc0c67912"}, ] [package.dependencies] -jinja2 = ">=3.0.0" -pytest = ">=7.0.0" -pytest-metadata = ">=2.0.0" +jinja2 = ">=3" +pytest = ">=7" +pytest-metadata = ">=2" [package.extras] -docs = ["pip-tools (>=6.13.0)"] -test = ["assertpy (>=1.1)", "beautifulsoup4 (>=4.11.1)", "black (>=22.1.0)", "flake8 (>=4.0.1)", "pre-commit (>=2.17.0)", "pytest-mock (>=3.7.0)", "pytest-rerunfailures (>=11.1.2)", "pytest-xdist (>=2.4.0)", "selenium (>=4.3.0)", "tox (>=3.24.5)"] +docs = ["pip-tools (>=6.13)"] +test = ["assertpy (>=1.1)", "beautifulsoup4 (>=4.11.1)", "black (>=22.1)", "flake8 (>=4.0.1)", "pre-commit (>=2.17)", "pytest-mock (>=3.7)", "pytest-rerunfailures (>=11.1.2)", "pytest-xdist (>=2.4)", "selenium (>=4.3)", "tox (>=3.24.5)"] [[package]] name = "pytest-metadata" @@ -1862,14 +1906,54 @@ cli = ["click (>=5.0)"] [[package]] name = "pytokens" -version = "0.3.0" +version = "0.4.1" description = "A Fast, spec compliant Python 3.14+ tokenizer that runs on older Pythons." optional = false python-versions = ">=3.8" groups = ["dev"] files = [ - {file = "pytokens-0.3.0-py3-none-any.whl", hash = "sha256:95b2b5eaf832e469d141a378872480ede3f251a5a5041b8ec6e581d3ac71bbf3"}, - {file = "pytokens-0.3.0.tar.gz", hash = "sha256:2f932b14ed08de5fcf0b391ace2642f858f1394c0857202959000b68ed7a458a"}, + {file = "pytokens-0.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a44ed93ea23415c54f3face3b65ef2b844d96aeb3455b8a69b3df6beab6acc5"}, + {file = "pytokens-0.4.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:add8bf86b71a5d9fb5b89f023a80b791e04fba57960aa790cc6125f7f1d39dfe"}, + {file = "pytokens-0.4.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:670d286910b531c7b7e3c0b453fd8156f250adb140146d234a82219459b9640c"}, + {file = "pytokens-0.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4e691d7f5186bd2842c14813f79f8884bb03f5995f0575272009982c5ac6c0f7"}, + {file = "pytokens-0.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:27b83ad28825978742beef057bfe406ad6ed524b2d28c252c5de7b4a6dd48fa2"}, + {file = "pytokens-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d70e77c55ae8380c91c0c18dea05951482e263982911fc7410b1ffd1dadd3440"}, + {file = "pytokens-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a58d057208cb9075c144950d789511220b07636dd2e4708d5645d24de666bdc"}, + {file = "pytokens-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b49750419d300e2b5a3813cf229d4e5a4c728dae470bcc89867a9ad6f25a722d"}, + {file = "pytokens-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9907d61f15bf7261d7e775bd5d7ee4d2930e04424bab1972591918497623a16"}, + {file = "pytokens-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:ee44d0f85b803321710f9239f335aafe16553b39106384cef8e6de40cb4ef2f6"}, + {file = "pytokens-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:140709331e846b728475786df8aeb27d24f48cbcf7bcd449f8de75cae7a45083"}, + {file = "pytokens-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d6c4268598f762bc8e91f5dbf2ab2f61f7b95bdc07953b602db879b3c8c18e1"}, + {file = "pytokens-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:24afde1f53d95348b5a0eb19488661147285ca4dd7ed752bbc3e1c6242a304d1"}, + {file = "pytokens-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5ad948d085ed6c16413eb5fec6b3e02fa00dc29a2534f088d3302c47eb59adf9"}, + {file = "pytokens-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:3f901fe783e06e48e8cbdc82d631fca8f118333798193e026a50ce1b3757ea68"}, + {file = "pytokens-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8bdb9d0ce90cbf99c525e75a2fa415144fd570a1ba987380190e8b786bc6ef9b"}, + {file = "pytokens-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5502408cab1cb18e128570f8d598981c68a50d0cbd7c61312a90507cd3a1276f"}, + {file = "pytokens-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29d1d8fb1030af4d231789959f21821ab6325e463f0503a61d204343c9b355d1"}, + {file = "pytokens-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:970b08dd6b86058b6dc07efe9e98414f5102974716232d10f32ff39701e841c4"}, + {file = "pytokens-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:9bd7d7f544d362576be74f9d5901a22f317efc20046efe2034dced238cbbfe78"}, + {file = "pytokens-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4a14d5f5fc78ce85e426aa159489e2d5961acf0e47575e08f35584009178e321"}, + {file = "pytokens-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f50fd18543be72da51dd505e2ed20d2228c74e0464e4262e4899797803d7fa"}, + {file = "pytokens-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc74c035f9bfca0255c1af77ddd2d6ae8419012805453e4b0e7513e17904545d"}, + {file = "pytokens-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f66a6bbe741bd431f6d741e617e0f39ec7257ca1f89089593479347cc4d13324"}, + {file = "pytokens-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:b35d7e5ad269804f6697727702da3c517bb8a5228afa450ab0fa787732055fc9"}, + {file = "pytokens-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8fcb9ba3709ff77e77f1c7022ff11d13553f3c30299a9fe246a166903e9091eb"}, + {file = "pytokens-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:79fc6b8699564e1f9b521582c35435f1bd32dd06822322ec44afdeba666d8cb3"}, + {file = "pytokens-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d31b97b3de0f61571a124a00ffe9a81fb9939146c122c11060725bd5aea79975"}, + {file = "pytokens-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:967cf6e3fd4adf7de8fc73cd3043754ae79c36475c1c11d514fc72cf5490094a"}, + {file = "pytokens-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:584c80c24b078eec1e227079d56dc22ff755e0ba8654d8383b2c549107528918"}, + {file = "pytokens-0.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:da5baeaf7116dced9c6bb76dc31ba04a2dc3695f3d9f74741d7910122b456edc"}, + {file = "pytokens-0.4.1-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:11edda0942da80ff58c4408407616a310adecae1ddd22eef8c692fe266fa5009"}, + {file = "pytokens-0.4.1-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0fc71786e629cef478cbf29d7ea1923299181d0699dbe7c3c0f4a583811d9fc1"}, + {file = "pytokens-0.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:dcafc12c30dbaf1e2af0490978352e0c4041a7cde31f4f81435c2a5e8b9cabb6"}, + {file = "pytokens-0.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:42f144f3aafa5d92bad964d471a581651e28b24434d184871bd02e3a0d956037"}, + {file = "pytokens-0.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:34bcc734bd2f2d5fe3b34e7b3c0116bfb2397f2d9666139988e7a3eb5f7400e3"}, + {file = "pytokens-0.4.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:941d4343bf27b605e9213b26bfa1c4bf197c9c599a9627eb7305b0defcfe40c1"}, + {file = "pytokens-0.4.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3ad72b851e781478366288743198101e5eb34a414f1d5627cdd585ca3b25f1db"}, + {file = "pytokens-0.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:682fa37ff4d8e95f7df6fe6fe6a431e8ed8e788023c6bcc0f0880a12eab80ad1"}, + {file = "pytokens-0.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:30f51edd9bb7f85c748979384165601d028b84f7bd13fe14d3e065304093916a"}, + {file = "pytokens-0.4.1-py3-none-any.whl", hash = "sha256:26cef14744a8385f35d0e095dc8b3a7583f6c953c2e3d269c7f82484bf5ad2de"}, + {file = "pytokens-0.4.1.tar.gz", hash = "sha256:292052fe80923aae2260c073f822ceba21f3872ced9a68bb7953b348e561179a"}, ] [package.extras] @@ -1994,14 +2078,14 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "requests-cache" -version = "1.2.1" +version = "1.3.0" description = "A persistent cache for python requests" optional = false python-versions = ">=3.8" groups = ["dev"] files = [ - {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, - {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, + {file = "requests_cache-1.3.0-py3-none-any.whl", hash = "sha256:f09f27bbf100c250886acf13a9db35b53cf2852fddd71977b47c71ea7d90dbba"}, + {file = "requests_cache-1.3.0.tar.gz", hash = "sha256:070e357ccef11a300ccef4294a85de1ab265833c5d9c9538b26cd7ba4085d54a"}, ] [package.dependencies] @@ -2009,15 +2093,12 @@ attrs = ">=21.2" cattrs = ">=22.2" platformdirs = ">=2.5" requests = ">=2.22" -url-normalize = ">=1.4" +url-normalize = ">=2.0" urllib3 = ">=1.25.5" [package.extras] -all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] -bson = ["bson (>=0.5)"] -docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"] +all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "orjson (>=3.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"] -json = ["ujson (>=5.4)"] mongodb = ["pymongo (>=3)"] redis = ["redis (>=3)"] security = ["itsdangerous (>=2.0)"] @@ -2078,14 +2159,14 @@ compatible-mypy = ["mypy (>=1.12,<1.18)"] [[package]] name = "rich" -version = "14.2.0" +version = "14.3.2" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.8.0" groups = ["main", "dev"] files = [ - {file = "rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd"}, - {file = "rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4"}, + {file = "rich-14.3.2-py3-none-any.whl", hash = "sha256:08e67c3e90884651da3239ea668222d19bea7b589149d8014a21c633420dbb69"}, + {file = "rich-14.3.2.tar.gz", hash = "sha256:e712f11c1a562a11843306f5ed999475f09ac31ffb64281f73ab29ffdda8b3b8"}, ] [package.dependencies] @@ -2096,41 +2177,52 @@ pygments = ">=2.13.0,<3.0.0" jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] -name = "roman-numerals-py" -version = "3.1.0" +name = "roman-numerals" +version = "4.1.0" description = "Manipulate well-formed Roman numerals" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "roman_numerals_py-3.1.0-py3-none-any.whl", hash = "sha256:9da2ad2fb670bcf24e81070ceb3be72f6c11c440d73bd579fbeca1e9f330954c"}, - {file = "roman_numerals_py-3.1.0.tar.gz", hash = "sha256:be4bf804f083a4ce001b5eb7e3c0862479d10f94c936f6c4e5f250aa5ff5bd2d"}, + {file = "roman_numerals-4.1.0-py3-none-any.whl", hash = "sha256:647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7"}, + {file = "roman_numerals-4.1.0.tar.gz", hash = "sha256:1af8b147eb1405d5839e78aeb93131690495fe9da5c91856cb33ad55a7f1e5b2"}, ] -[package.extras] -lint = ["mypy (==1.15.0)", "pyright (==1.1.394)", "ruff (==0.9.7)"] -test = ["pytest (>=8)"] +[[package]] +name = "roman-numerals-py" +version = "4.1.0" +description = "This package is deprecated, switch to roman-numerals." +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "roman_numerals_py-4.1.0-py3-none-any.whl", hash = "sha256:553114c1167141c1283a51743759723ecd05604a1b6b507225e91dc1a6df0780"}, + {file = "roman_numerals_py-4.1.0.tar.gz", hash = "sha256:f5d7b2b4ca52dd855ef7ab8eb3590f428c0b1ea480736ce32b01fef2a5f8daf9"}, +] + +[package.dependencies] +roman-numerals = "4.1.0" [[package]] name = "setuptools" -version = "80.9.0" +version = "82.0.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922"}, - {file = "setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c"}, + {file = "setuptools-82.0.0-py3-none-any.whl", hash = "sha256:70b18734b607bd1da571d097d236cfcfacaf01de45717d59e6e04b96877532e0"}, + {file = "setuptools-82.0.0.tar.gz", hash = "sha256:22e0a2d69474c6ae4feb01951cb69d515ed23728cf96d05513d36e42b62b37cb"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.8.0) ; sys_platform != \"cygwin\""] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.13.0) ; sys_platform != \"cygwin\""] core = ["importlib_metadata (>=6) ; python_version < \"3.10\"", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib_metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.14.*)", "pytest-mypy"] +type = ["importlib_metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.18.*)", "pytest-mypy"] [[package]] name = "snowballstemmer" @@ -2182,19 +2274,19 @@ test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "pytest-xdis [[package]] name = "sphinx-rtd-theme" -version = "3.0.2" +version = "3.1.0" description = "Read the Docs theme for Sphinx" optional = false python-versions = ">=3.8" groups = ["dev"] files = [ - {file = "sphinx_rtd_theme-3.0.2-py2.py3-none-any.whl", hash = "sha256:422ccc750c3a3a311de4ae327e82affdaf59eb695ba4936538552f3b00f4ee13"}, - {file = "sphinx_rtd_theme-3.0.2.tar.gz", hash = "sha256:b7457bc25dda723b20b086a670b9953c859eab60a2a03ee8eb2bb23e176e5f85"}, + {file = "sphinx_rtd_theme-3.1.0-py2.py3-none-any.whl", hash = "sha256:1785824ae8e6632060490f67cf3a72d404a85d2d9fc26bce3619944de5682b89"}, + {file = "sphinx_rtd_theme-3.1.0.tar.gz", hash = "sha256:b44276f2c276e909239a4f6c955aa667aaafeb78597923b1c60babc76db78e4c"}, ] [package.dependencies] -docutils = ">0.18,<0.22" -sphinx = ">=6,<9" +docutils = ">0.18,<0.23" +sphinx = ">=6,<10" sphinxcontrib-jquery = ">=4,<5" [package.extras] @@ -2329,66 +2421,71 @@ files = [ [[package]] name = "tomli" -version = "2.3.0" +version = "2.4.0" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" groups = ["dev"] files = [ - {file = "tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45"}, - {file = "tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba"}, - {file = "tomli-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf"}, - {file = "tomli-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441"}, - {file = "tomli-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845"}, - {file = "tomli-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c"}, - {file = "tomli-2.3.0-cp311-cp311-win32.whl", hash = "sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456"}, - {file = "tomli-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be"}, - {file = "tomli-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac"}, - {file = "tomli-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22"}, - {file = "tomli-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f"}, - {file = "tomli-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52"}, - {file = "tomli-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8"}, - {file = "tomli-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6"}, - {file = "tomli-2.3.0-cp312-cp312-win32.whl", hash = "sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876"}, - {file = "tomli-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878"}, - {file = "tomli-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b"}, - {file = "tomli-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae"}, - {file = "tomli-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b"}, - {file = "tomli-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf"}, - {file = "tomli-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f"}, - {file = "tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05"}, - {file = "tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606"}, - {file = "tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999"}, - {file = "tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e"}, - {file = "tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3"}, - {file = "tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc"}, - {file = "tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0"}, - {file = "tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879"}, - {file = "tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005"}, - {file = "tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463"}, - {file = "tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8"}, - {file = "tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77"}, - {file = "tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf"}, - {file = "tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530"}, - {file = "tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b"}, - {file = "tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67"}, - {file = "tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f"}, - {file = "tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0"}, - {file = "tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba"}, - {file = "tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b"}, - {file = "tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549"}, + {file = "tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867"}, + {file = "tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9"}, + {file = "tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95"}, + {file = "tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76"}, + {file = "tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d"}, + {file = "tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576"}, + {file = "tomli-2.4.0-cp311-cp311-win32.whl", hash = "sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a"}, + {file = "tomli-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa"}, + {file = "tomli-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614"}, + {file = "tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1"}, + {file = "tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8"}, + {file = "tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a"}, + {file = "tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1"}, + {file = "tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b"}, + {file = "tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51"}, + {file = "tomli-2.4.0-cp312-cp312-win32.whl", hash = "sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729"}, + {file = "tomli-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da"}, + {file = "tomli-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3"}, + {file = "tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0"}, + {file = "tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e"}, + {file = "tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4"}, + {file = "tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e"}, + {file = "tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c"}, + {file = "tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f"}, + {file = "tomli-2.4.0-cp313-cp313-win32.whl", hash = "sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86"}, + {file = "tomli-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87"}, + {file = "tomli-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132"}, + {file = "tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6"}, + {file = "tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc"}, + {file = "tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66"}, + {file = "tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d"}, + {file = "tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702"}, + {file = "tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8"}, + {file = "tomli-2.4.0-cp314-cp314-win32.whl", hash = "sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776"}, + {file = "tomli-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475"}, + {file = "tomli-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2"}, + {file = "tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9"}, + {file = "tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0"}, + {file = "tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df"}, + {file = "tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d"}, + {file = "tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f"}, + {file = "tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b"}, + {file = "tomli-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087"}, + {file = "tomli-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd"}, + {file = "tomli-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4"}, + {file = "tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a"}, + {file = "tomli-2.4.0.tar.gz", hash = "sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c"}, ] [[package]] name = "tomlkit" -version = "0.13.3" +version = "0.14.0" description = "Style preserving TOML library" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0"}, - {file = "tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1"}, + {file = "tomlkit-0.14.0-py3-none-any.whl", hash = "sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680"}, + {file = "tomlkit-0.14.0.tar.gz", hash = "sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064"}, ] [[package]] @@ -2404,38 +2501,38 @@ files = [ [[package]] name = "types-protobuf" -version = "6.32.1.20251105" +version = "6.32.1.20251210" description = "Typing stubs for protobuf" optional = false python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "types_protobuf-6.32.1.20251105-py3-none-any.whl", hash = "sha256:a15109d38f7cfefd2539ef86d3f93a6a41c7cad53924f8aa1a51eaddbb72a660"}, - {file = "types_protobuf-6.32.1.20251105.tar.gz", hash = "sha256:641002611ff87dd9fedc38a39a29cacb9907ae5ce61489b53e99ca2074bef764"}, + {file = "types_protobuf-6.32.1.20251210-py3-none-any.whl", hash = "sha256:2641f78f3696822a048cfb8d0ff42ccd85c25f12f871fbebe86da63793692140"}, + {file = "types_protobuf-6.32.1.20251210.tar.gz", hash = "sha256:c698bb3f020274b1a2798ae09dc773728ce3f75209a35187bd11916ebfde6763"}, ] [[package]] name = "types-pytz" -version = "2025.2.0.20250809" +version = "2025.2.0.20251108" description = "Typing stubs for pytz" optional = false python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "types_pytz-2025.2.0.20250809-py3-none-any.whl", hash = "sha256:4f55ed1b43e925cf851a756fe1707e0f5deeb1976e15bf844bcaa025e8fbd0db"}, - {file = "types_pytz-2025.2.0.20250809.tar.gz", hash = "sha256:222e32e6a29bb28871f8834e8785e3801f2dc4441c715cd2082b271eecbe21e5"}, + {file = "types_pytz-2025.2.0.20251108-py3-none-any.whl", hash = "sha256:0f1c9792cab4eb0e46c52f8845c8f77cf1e313cb3d68bf826aa867fe4717d91c"}, + {file = "types_pytz-2025.2.0.20251108.tar.gz", hash = "sha256:fca87917836ae843f07129567b74c1929f1870610681b4c92cb86a3df5817bdb"}, ] [[package]] name = "types-requests" -version = "2.32.4.20250913" +version = "2.32.4.20260107" description = "Typing stubs for requests" optional = false python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "types_requests-2.32.4.20250913-py3-none-any.whl", hash = "sha256:78c9c1fffebbe0fa487a418e0fa5252017e9c60d1a2da394077f1780f655d7e1"}, - {file = "types_requests-2.32.4.20250913.tar.gz", hash = "sha256:abd6d4f9ce3a9383f269775a9835a4c24e5cd6b9f647d64f88aa4613c33def5d"}, + {file = "types_requests-2.32.4.20260107-py3-none-any.whl", hash = "sha256:b703fe72f8ce5b31ef031264fe9395cac8f46a04661a79f7ed31a80fb308730d"}, + {file = "types_requests-2.32.4.20260107.tar.gz", hash = "sha256:018a11ac158f801bfa84857ddec1650750e393df8a004a8a9ae2a9bec6fcb24f"}, ] [package.dependencies] @@ -2485,15 +2582,15 @@ typing-extensions = ">=4.12.0" [[package]] name = "tzdata" -version = "2025.2" +version = "2025.3" description = "Provider of IANA time zone data" optional = false python-versions = ">=2" groups = ["main"] markers = "platform_system == \"Windows\"" files = [ - {file = "tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"}, - {file = "tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"}, + {file = "tzdata-2025.3-py2.py3-none-any.whl", hash = "sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1"}, + {file = "tzdata-2025.3.tar.gz", hash = "sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7"}, ] [[package]] @@ -2534,49 +2631,48 @@ dev = ["mypy", "pre-commit", "pytest", "pytest-cov", "pytest-socket", "ruff"] [[package]] name = "urllib3" -version = "2.5.0" +version = "2.6.3" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" groups = ["main", "dev"] files = [ - {file = "urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"}, - {file = "urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760"}, + {file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}, + {file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"}, ] [package.extras] -brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] +brotli = ["brotli (>=1.2.0) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=1.2.0.0) ; platform_python_implementation != \"CPython\""] h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] +zstd = ["backports-zstd (>=1.0.0) ; python_version < \"3.14\""] [[package]] name = "uv" -version = "0.9.7" +version = "0.10.0" description = "An extremely fast Python package and project manager, written in Rust." optional = false python-versions = ">=3.8" groups = ["dev"] files = [ - {file = "uv-0.9.7-py3-none-linux_armv6l.whl", hash = "sha256:134e0daac56f9e399ccdfc9e4635bc0a13c234cad9224994c67bae462e07399a"}, - {file = "uv-0.9.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:1aaf79b4234400e9e2fbf5b50b091726ccbb0b6d4d032edd3dfd4c9673d89dca"}, - {file = "uv-0.9.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:0fdbfad5b367e7a3968264af6da5bbfffd4944a90319042f166e8df1a2d9de09"}, - {file = "uv-0.9.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:635e82c2d0d8b001618af82e4f2724350f15814f6462a71b3ebd44adec21f03c"}, - {file = "uv-0.9.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:56a440ccde7624a7bc070e1c2492b358c67aea9b8f17bc243ea27c5871c8d02c"}, - {file = "uv-0.9.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b5f1fb8203a77853db176000e8f30d5815ab175dc46199db059f97a72fc51110"}, - {file = "uv-0.9.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:bb8bfcc2897f7653522abc2cae80233af756ad857bfbbbbe176f79460cbba417"}, - {file = "uv-0.9.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:89697fa0d7384ba047daf75df844ee7800235105e41d08e0c876861a2b4aa90e"}, - {file = "uv-0.9.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c9810ee8173dce129c49b338d5e97f3d7c7e9435f73e0b9b26c2f37743d3bb9e"}, - {file = "uv-0.9.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cf6bc2482d1293cc630f66b862b494c09acda9b7faff7307ef52667a2b3ad49"}, - {file = "uv-0.9.7-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:7019f4416925f4091b9d28c1cf3e8444cf910c4ede76bdf1f6b9a56ca5f97985"}, - {file = "uv-0.9.7-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:edd768f6730bba06aa10fdbd80ee064569f7236806f636bf65b68136a430aad0"}, - {file = "uv-0.9.7-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:d6e5fe28ca05a4b576c0e8da5f69251dc187a67054829cfc4afb2bfa1767114b"}, - {file = "uv-0.9.7-py3-none-musllinux_1_1_i686.whl", hash = "sha256:34fe0af83fcafb9e2b786f4bd633a06c878d548a7c479594ffb5607db8778471"}, - {file = "uv-0.9.7-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:777bb1de174319245a35e4f805d3b4484d006ebedae71d3546f95e7c28a5f436"}, - {file = "uv-0.9.7-py3-none-win32.whl", hash = "sha256:bcf878528bd079fe8ae15928b5dfa232fac8b0e1854a2102da6ae1a833c31276"}, - {file = "uv-0.9.7-py3-none-win_amd64.whl", hash = "sha256:62b315f62669899076a1953fba6baf50bd2b57f66f656280491331dcedd7e6c6"}, - {file = "uv-0.9.7-py3-none-win_arm64.whl", hash = "sha256:d13da6521d4e841b1e0a9fda82e793dcf8458a323a9e8955f50903479d0bfa97"}, - {file = "uv-0.9.7.tar.gz", hash = "sha256:555ee72146b8782c73d755e4a21c9885c6bfc81db0ffca2220d52dddae007eb7"}, + {file = "uv-0.10.0-py3-none-linux_armv6l.whl", hash = "sha256:38dc0ccbda6377eb94095688c38e5001b8b40dfce14b9654949c1f0b6aa889df"}, + {file = "uv-0.10.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:a165582c1447691109d49d09dccb065d2a23852ff42bf77824ff169909aa85da"}, + {file = "uv-0.10.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:aefea608971f4f23ac3dac2006afb8eb2b2c1a2514f5fee1fac18e6c45fd70c4"}, + {file = "uv-0.10.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:d4b621bcc5d0139502789dc299bae8bf55356d07b95cb4e57e50e2afcc5f43e1"}, + {file = "uv-0.10.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:b4bea728a6b64826d0091f95f28de06dd2dc786384b3d336a90297f123b4da0e"}, + {file = "uv-0.10.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bc0cc2a4bcf9efbff9a57e2aed21c2d4b5a7ec2cc0096e0c33d7b53da17f6a3b"}, + {file = "uv-0.10.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:070ca2f0e8c67ca9a8f70ce403c956b7ed9d51e0c2e9dbbcc4efa5e0a2483f79"}, + {file = "uv-0.10.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8070c66149c06f9b39092a06f593a2241345ea2b1d42badc6f884c2cc089a1b1"}, + {file = "uv-0.10.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3db1d5390b3a624de672d7b0f9c9d8197693f3b2d3d9c4d9e34686dcbc34197a"}, + {file = "uv-0.10.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82b46db718763bf742e986ebbc7a30ca33648957a0dcad34382970b992f5e900"}, + {file = "uv-0.10.0-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:eb95d28590edd73b8fdd80c27d699c45c52f8305170c6a90b830caf7f36670a4"}, + {file = "uv-0.10.0-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:5871eef5046a81df3f1636a3d2b4ccac749c23c7f4d3a4bae5496cb2876a1814"}, + {file = "uv-0.10.0-py3-none-musllinux_1_1_i686.whl", hash = "sha256:1af0ec125a07edb434dfaa98969f6184c1313dbec2860c3c5ce2d533b257132a"}, + {file = "uv-0.10.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:45909b9a734250da05b10101e0a067e01ffa2d94bbb07de4b501e3cee4ae0ff3"}, + {file = "uv-0.10.0-py3-none-win32.whl", hash = "sha256:d5498851b1f07aa9c9af75578b2029a11743cb933d741f84dcbb43109a968c29"}, + {file = "uv-0.10.0-py3-none-win_amd64.whl", hash = "sha256:edd469425cd62bcd8c8cc0226c5f9043a94e37ed869da8268c80fdbfd3e5015e"}, + {file = "uv-0.10.0-py3-none-win_arm64.whl", hash = "sha256:e90c509749b3422eebb54057434b7119892330d133b9690a88f8a6b0f3116be3"}, + {file = "uv-0.10.0.tar.gz", hash = "sha256:ad01dd614a4bb8eb732da31ade41447026427397c5ad171cc98bd59579ef57ea"}, ] [[package]] @@ -2772,6 +2868,42 @@ winrt-runtime = ">=3.2.1.0,<3.3.0.0" [package.extras] all = ["winrt-Windows.ApplicationModel.Background[all] (>=3.2.1.0,<3.3.0.0)", "winrt-Windows.Foundation.Collections[all] (>=3.2.1.0,<3.3.0.0)", "winrt-Windows.Foundation[all] (>=3.2.1.0,<3.3.0.0)", "winrt-Windows.Security.Credentials[all] (>=3.2.1.0,<3.3.0.0)", "winrt-Windows.Storage.Streams[all] (>=3.2.1.0,<3.3.0.0)", "winrt-Windows.UI.Popups[all] (>=3.2.1.0,<3.3.0.0)", "winrt-Windows.UI[all] (>=3.2.1.0,<3.3.0.0)"] +[[package]] +name = "winrt-windows-devices-radios" +version = "3.2.1" +description = "Python projection of Windows Runtime (WinRT) APIs" +optional = false +python-versions = ">=3.9" +groups = ["main"] +markers = "platform_system == \"Windows\"" +files = [ + {file = "winrt_windows_devices_radios-3.2.1-cp310-cp310-win32.whl", hash = "sha256:f97766fd551d06c102155d51b2922f96663dee045e1f8d57177def0a2149cb78"}, + {file = "winrt_windows_devices_radios-3.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:104b737fa1279a3b6a88ba3c6236157afc1de03c472657c45e5176ad7a209e23"}, + {file = "winrt_windows_devices_radios-3.2.1-cp310-cp310-win_arm64.whl", hash = "sha256:55b02877d2de06ca6f0f6140611a9af9d0c65710e28f1afdeaac1040433b1837"}, + {file = "winrt_windows_devices_radios-3.2.1-cp311-cp311-win32.whl", hash = "sha256:7c02790472414b6cda00d24a8cd23bca18e4b7474ddad4f9264f4484b891807e"}, + {file = "winrt_windows_devices_radios-3.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:f87745486d313ba1e7562ca97f25ad436ec01ad4b3b9ea349fb6b6f25cb41104"}, + {file = "winrt_windows_devices_radios-3.2.1-cp311-cp311-win_arm64.whl", hash = "sha256:6cee6f946ff3a3571850d1ca745edaee7c331d06ca321873e650779654effc4a"}, + {file = "winrt_windows_devices_radios-3.2.1-cp312-cp312-win32.whl", hash = "sha256:c3e683ce682338a5a5ed465f735e223ba7a22f16d0bbea2d070962bc7657edbb"}, + {file = "winrt_windows_devices_radios-3.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:a116e552a3f38607b9be558fb2e7de9b4450d1f9080069944d74d80cdda1873e"}, + {file = "winrt_windows_devices_radios-3.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:4c28822f9251c9d547324f596b5c2581f050254ded05e5b786c650a3502744c1"}, + {file = "winrt_windows_devices_radios-3.2.1-cp313-cp313-win32.whl", hash = "sha256:ae4a0065927fcd2d10215223f8a46be6fb89bad71cb4edd25dae3d01c137b3a8"}, + {file = "winrt_windows_devices_radios-3.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:bf1a975f46a2aa271ffea1340be0c7e64985050d07433e701343dddc22a72290"}, + {file = "winrt_windows_devices_radios-3.2.1-cp313-cp313-win_arm64.whl", hash = "sha256:10b298ed154c5824cea2de174afce1694ed2aabfb58826de814074027ffef96f"}, + {file = "winrt_windows_devices_radios-3.2.1-cp314-cp314-win32.whl", hash = "sha256:21452e1cae50e44cd1d5e78159e1b9986ac3389b66458ad89caa196ce5eca2d6"}, + {file = "winrt_windows_devices_radios-3.2.1-cp314-cp314-win_amd64.whl", hash = "sha256:6a8413e586fe597c6849607885cca7e0549da33ae5699165d11f7911534c6eaf"}, + {file = "winrt_windows_devices_radios-3.2.1-cp314-cp314-win_arm64.whl", hash = "sha256:39129fd9d09103adb003575f59881c1a5a70a43310547850150b46c6f4020312"}, + {file = "winrt_windows_devices_radios-3.2.1-cp39-cp39-win32.whl", hash = "sha256:59b868d45ff22afad21b0b0d1466ec43e54543c4e4c6f1efcc2d4adc77053bd5"}, + {file = "winrt_windows_devices_radios-3.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:dbfcbb977f60f19c852204987ace0cd6f7a432d735882a45b3074fdbfd3fdb5a"}, + {file = "winrt_windows_devices_radios-3.2.1-cp39-cp39-win_arm64.whl", hash = "sha256:659e07e6aa5542587ccfc4d4e2cc6e1ef0869606c867a3e95fc82cc8aeaf1f81"}, + {file = "winrt_windows_devices_radios-3.2.1.tar.gz", hash = "sha256:4dc9b9d1501846049eb79428d64ec698d6476c27a357999b78a8331072e18a0b"}, +] + +[package.dependencies] +winrt-runtime = ">=3.2.1.0,<3.3.0.0" + +[package.extras] +all = ["winrt-Windows.Foundation.Collections[all] (>=3.2.1.0,<3.3.0.0)", "winrt-Windows.Foundation[all] (>=3.2.1.0,<3.3.0.0)"] + [[package]] name = "winrt-windows-foundation" version = "3.2.1" @@ -2882,119 +3014,86 @@ all = ["winrt-Windows.Foundation.Collections[all] (>=3.2.1.0,<3.3.0.0)", "winrt- [[package]] name = "wrapt" -version = "2.0.1" +version = "2.1.1" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["main"] files = [ - {file = "wrapt-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:64b103acdaa53b7caf409e8d45d39a8442fe6dcfec6ba3f3d141e0cc2b5b4dbd"}, - {file = "wrapt-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:91bcc576260a274b169c3098e9a3519fb01f2989f6d3d386ef9cbf8653de1374"}, - {file = "wrapt-2.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ab594f346517010050126fcd822697b25a7031d815bb4fbc238ccbe568216489"}, - {file = "wrapt-2.0.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:36982b26f190f4d737f04a492a68accbfc6fa042c3f42326fdfbb6c5b7a20a31"}, - {file = "wrapt-2.0.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:23097ed8bc4c93b7bf36fa2113c6c733c976316ce0ee2c816f64ca06102034ef"}, - {file = "wrapt-2.0.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8bacfe6e001749a3b64db47bcf0341da757c95959f592823a93931a422395013"}, - {file = "wrapt-2.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8ec3303e8a81932171f455f792f8df500fc1a09f20069e5c16bd7049ab4e8e38"}, - {file = "wrapt-2.0.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:3f373a4ab5dbc528a94334f9fe444395b23c2f5332adab9ff4ea82f5a9e33bc1"}, - {file = "wrapt-2.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f49027b0b9503bf6c8cdc297ca55006b80c2f5dd36cecc72c6835ab6e10e8a25"}, - {file = "wrapt-2.0.1-cp310-cp310-win32.whl", hash = "sha256:8330b42d769965e96e01fa14034b28a2a7600fbf7e8f0cc90ebb36d492c993e4"}, - {file = "wrapt-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:1218573502a8235bb8a7ecaed12736213b22dcde9feab115fa2989d42b5ded45"}, - {file = "wrapt-2.0.1-cp310-cp310-win_arm64.whl", hash = "sha256:eda8e4ecd662d48c28bb86be9e837c13e45c58b8300e43ba3c9b4fa9900302f7"}, - {file = "wrapt-2.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0e17283f533a0d24d6e5429a7d11f250a58d28b4ae5186f8f47853e3e70d2590"}, - {file = "wrapt-2.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85df8d92158cb8f3965aecc27cf821461bb5f40b450b03facc5d9f0d4d6ddec6"}, - {file = "wrapt-2.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c1be685ac7700c966b8610ccc63c3187a72e33cab53526a27b2a285a662cd4f7"}, - {file = "wrapt-2.0.1-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:df0b6d3b95932809c5b3fecc18fda0f1e07452d05e2662a0b35548985f256e28"}, - {file = "wrapt-2.0.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4da7384b0e5d4cae05c97cd6f94faaf78cc8b0f791fc63af43436d98c4ab37bb"}, - {file = "wrapt-2.0.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ec65a78fbd9d6f083a15d7613b2800d5663dbb6bb96003899c834beaa68b242c"}, - {file = "wrapt-2.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7de3cc939be0e1174969f943f3b44e0d79b6f9a82198133a5b7fc6cc92882f16"}, - {file = "wrapt-2.0.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:fb1a5b72cbd751813adc02ef01ada0b0d05d3dcbc32976ce189a1279d80ad4a2"}, - {file = "wrapt-2.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3fa272ca34332581e00bf7773e993d4f632594eb2d1b0b162a9038df0fd971dd"}, - {file = "wrapt-2.0.1-cp311-cp311-win32.whl", hash = "sha256:fc007fdf480c77301ab1afdbb6ab22a5deee8885f3b1ed7afcb7e5e84a0e27be"}, - {file = "wrapt-2.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:47434236c396d04875180171ee1f3815ca1eada05e24a1ee99546320d54d1d1b"}, - {file = "wrapt-2.0.1-cp311-cp311-win_arm64.whl", hash = "sha256:837e31620e06b16030b1d126ed78e9383815cbac914693f54926d816d35d8edf"}, - {file = "wrapt-2.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1fdbb34da15450f2b1d735a0e969c24bdb8d8924892380126e2a293d9902078c"}, - {file = "wrapt-2.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3d32794fe940b7000f0519904e247f902f0149edbe6316c710a8562fb6738841"}, - {file = "wrapt-2.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:386fb54d9cd903ee0012c09291336469eb7b244f7183d40dc3e86a16a4bace62"}, - {file = "wrapt-2.0.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7b219cb2182f230676308cdcacd428fa837987b89e4b7c5c9025088b8a6c9faf"}, - {file = "wrapt-2.0.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:641e94e789b5f6b4822bb8d8ebbdfc10f4e4eae7756d648b717d980f657a9eb9"}, - {file = "wrapt-2.0.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fe21b118b9f58859b5ebaa4b130dee18669df4bd111daad082b7beb8799ad16b"}, - {file = "wrapt-2.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:17fb85fa4abc26a5184d93b3efd2dcc14deb4b09edcdb3535a536ad34f0b4dba"}, - {file = "wrapt-2.0.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:b89ef9223d665ab255ae42cc282d27d69704d94be0deffc8b9d919179a609684"}, - {file = "wrapt-2.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a453257f19c31b31ba593c30d997d6e5be39e3b5ad9148c2af5a7314061c63eb"}, - {file = "wrapt-2.0.1-cp312-cp312-win32.whl", hash = "sha256:3e271346f01e9c8b1130a6a3b0e11908049fe5be2d365a5f402778049147e7e9"}, - {file = "wrapt-2.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:2da620b31a90cdefa9cd0c2b661882329e2e19d1d7b9b920189956b76c564d75"}, - {file = "wrapt-2.0.1-cp312-cp312-win_arm64.whl", hash = "sha256:aea9c7224c302bc8bfc892b908537f56c430802560e827b75ecbde81b604598b"}, - {file = "wrapt-2.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:47b0f8bafe90f7736151f61482c583c86b0693d80f075a58701dd1549b0010a9"}, - {file = "wrapt-2.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:cbeb0971e13b4bd81d34169ed57a6dda017328d1a22b62fda45e1d21dd06148f"}, - {file = "wrapt-2.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb7cffe572ad0a141a7886a1d2efa5bef0bf7fe021deeea76b3ab334d2c38218"}, - {file = "wrapt-2.0.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c8d60527d1ecfc131426b10d93ab5d53e08a09c5fa0175f6b21b3252080c70a9"}, - {file = "wrapt-2.0.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c654eafb01afac55246053d67a4b9a984a3567c3808bb7df2f8de1c1caba2e1c"}, - {file = "wrapt-2.0.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:98d873ed6c8b4ee2418f7afce666751854d6d03e3c0ec2a399bb039cd2ae89db"}, - {file = "wrapt-2.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c9e850f5b7fc67af856ff054c71690d54fa940c3ef74209ad9f935b4f66a0233"}, - {file = "wrapt-2.0.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e505629359cb5f751e16e30cf3f91a1d3ddb4552480c205947da415d597f7ac2"}, - {file = "wrapt-2.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2879af909312d0baf35f08edeea918ee3af7ab57c37fe47cb6a373c9f2749c7b"}, - {file = "wrapt-2.0.1-cp313-cp313-win32.whl", hash = "sha256:d67956c676be5a24102c7407a71f4126d30de2a569a1c7871c9f3cabc94225d7"}, - {file = "wrapt-2.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:9ca66b38dd642bf90c59b6738af8070747b610115a39af2498535f62b5cdc1c3"}, - {file = "wrapt-2.0.1-cp313-cp313-win_arm64.whl", hash = "sha256:5a4939eae35db6b6cec8e7aa0e833dcca0acad8231672c26c2a9ab7a0f8ac9c8"}, - {file = "wrapt-2.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a52f93d95c8d38fed0669da2ebdb0b0376e895d84596a976c15a9eb45e3eccb3"}, - {file = "wrapt-2.0.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4e54bbf554ee29fcceee24fa41c4d091398b911da6e7f5d7bffda963c9aed2e1"}, - {file = "wrapt-2.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:908f8c6c71557f4deaa280f55d0728c3bca0960e8c3dd5ceeeafb3c19942719d"}, - {file = "wrapt-2.0.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e2f84e9af2060e3904a32cea9bb6db23ce3f91cfd90c6b426757cf7cc01c45c7"}, - {file = "wrapt-2.0.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e3612dc06b436968dfb9142c62e5dfa9eb5924f91120b3c8ff501ad878f90eb3"}, - {file = "wrapt-2.0.1-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6d2d947d266d99a1477cd005b23cbd09465276e302515e122df56bb9511aca1b"}, - {file = "wrapt-2.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:7d539241e87b650cbc4c3ac9f32c8d1ac8a54e510f6dca3f6ab60dcfd48c9b10"}, - {file = "wrapt-2.0.1-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:4811e15d88ee62dbf5c77f2c3ff3932b1e3ac92323ba3912f51fc4016ce81ecf"}, - {file = "wrapt-2.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c1c91405fcf1d501fa5d55df21e58ea49e6b879ae829f1039faaf7e5e509b41e"}, - {file = "wrapt-2.0.1-cp313-cp313t-win32.whl", hash = "sha256:e76e3f91f864e89db8b8d2a8311d57df93f01ad6bb1e9b9976d1f2e83e18315c"}, - {file = "wrapt-2.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:83ce30937f0ba0d28818807b303a412440c4b63e39d3d8fc036a94764b728c92"}, - {file = "wrapt-2.0.1-cp313-cp313t-win_arm64.whl", hash = "sha256:4b55cacc57e1dc2d0991dbe74c6419ffd415fb66474a02335cb10efd1aa3f84f"}, - {file = "wrapt-2.0.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:5e53b428f65ece6d9dad23cb87e64506392b720a0b45076c05354d27a13351a1"}, - {file = "wrapt-2.0.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ad3ee9d0f254851c71780966eb417ef8e72117155cff04821ab9b60549694a55"}, - {file = "wrapt-2.0.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d7b822c61ed04ee6ad64bc90d13368ad6eb094db54883b5dde2182f67a7f22c0"}, - {file = "wrapt-2.0.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7164a55f5e83a9a0b031d3ffab4d4e36bbec42e7025db560f225489fa929e509"}, - {file = "wrapt-2.0.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e60690ba71a57424c8d9ff28f8d006b7ad7772c22a4af432188572cd7fa004a1"}, - {file = "wrapt-2.0.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3cd1a4bd9a7a619922a8557e1318232e7269b5fb69d4ba97b04d20450a6bf970"}, - {file = "wrapt-2.0.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b4c2e3d777e38e913b8ce3a6257af72fb608f86a1df471cb1d4339755d0a807c"}, - {file = "wrapt-2.0.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3d366aa598d69416b5afedf1faa539fac40c1d80a42f6b236c88c73a3c8f2d41"}, - {file = "wrapt-2.0.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c235095d6d090aa903f1db61f892fffb779c1eaeb2a50e566b52001f7a0f66ed"}, - {file = "wrapt-2.0.1-cp314-cp314-win32.whl", hash = "sha256:bfb5539005259f8127ea9c885bdc231978c06b7a980e63a8a61c8c4c979719d0"}, - {file = "wrapt-2.0.1-cp314-cp314-win_amd64.whl", hash = "sha256:4ae879acc449caa9ed43fc36ba08392b9412ee67941748d31d94e3cedb36628c"}, - {file = "wrapt-2.0.1-cp314-cp314-win_arm64.whl", hash = "sha256:8639b843c9efd84675f1e100ed9e99538ebea7297b62c4b45a7042edb84db03e"}, - {file = "wrapt-2.0.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:9219a1d946a9b32bb23ccae66bdb61e35c62773ce7ca6509ceea70f344656b7b"}, - {file = "wrapt-2.0.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:fa4184e74197af3adad3c889a1af95b53bb0466bced92ea99a0c014e48323eec"}, - {file = "wrapt-2.0.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c5ef2f2b8a53b7caee2f797ef166a390fef73979b15778a4a153e4b5fedce8fa"}, - {file = "wrapt-2.0.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e042d653a4745be832d5aa190ff80ee4f02c34b21f4b785745eceacd0907b815"}, - {file = "wrapt-2.0.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2afa23318136709c4b23d87d543b425c399887b4057936cd20386d5b1422b6fa"}, - {file = "wrapt-2.0.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6c72328f668cf4c503ffcf9434c2b71fdd624345ced7941bc6693e61bbe36bef"}, - {file = "wrapt-2.0.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3793ac154afb0e5b45d1233cb94d354ef7a983708cc3bb12563853b1d8d53747"}, - {file = "wrapt-2.0.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:fec0d993ecba3991645b4857837277469c8cc4c554a7e24d064d1ca291cfb81f"}, - {file = "wrapt-2.0.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:949520bccc1fa227274da7d03bf238be15389cd94e32e4297b92337df9b7a349"}, - {file = "wrapt-2.0.1-cp314-cp314t-win32.whl", hash = "sha256:be9e84e91d6497ba62594158d3d31ec0486c60055c49179edc51ee43d095f79c"}, - {file = "wrapt-2.0.1-cp314-cp314t-win_amd64.whl", hash = "sha256:61c4956171c7434634401db448371277d07032a81cc21c599c22953374781395"}, - {file = "wrapt-2.0.1-cp314-cp314t-win_arm64.whl", hash = "sha256:35cdbd478607036fee40273be8ed54a451f5f23121bd9d4be515158f9498f7ad"}, - {file = "wrapt-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:90897ea1cf0679763b62e79657958cd54eae5659f6360fc7d2ccc6f906342183"}, - {file = "wrapt-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:50844efc8cdf63b2d90cd3d62d4947a28311e6266ce5235a219d21b195b4ec2c"}, - {file = "wrapt-2.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49989061a9977a8cbd6d20f2efa813f24bf657c6990a42967019ce779a878dbf"}, - {file = "wrapt-2.0.1-cp38-cp38-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:09c7476ab884b74dce081ad9bfd07fe5822d8600abade571cb1f66d5fc915af6"}, - {file = "wrapt-2.0.1-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1a8a09a004ef100e614beec82862d11fc17d601092c3599afd22b1f36e4137e"}, - {file = "wrapt-2.0.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:89a82053b193837bf93c0f8a57ded6e4b6d88033a499dadff5067e912c2a41e9"}, - {file = "wrapt-2.0.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f26f8e2ca19564e2e1fdbb6a0e47f36e0efbab1acc31e15471fad88f828c75f6"}, - {file = "wrapt-2.0.1-cp38-cp38-win32.whl", hash = "sha256:115cae4beed3542e37866469a8a1f2b9ec549b4463572b000611e9946b86e6f6"}, - {file = "wrapt-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:c4012a2bd37059d04f8209916aa771dfb564cccb86079072bdcd48a308b6a5c5"}, - {file = "wrapt-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:68424221a2dc00d634b54f92441914929c5ffb1c30b3b837343978343a3512a3"}, - {file = "wrapt-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6bd1a18f5a797fe740cb3d7a0e853a8ce6461cc62023b630caec80171a6b8097"}, - {file = "wrapt-2.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fb3a86e703868561c5cad155a15c36c716e1ab513b7065bd2ac8ed353c503333"}, - {file = "wrapt-2.0.1-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5dc1b852337c6792aa111ca8becff5bacf576bf4a0255b0f05eb749da6a1643e"}, - {file = "wrapt-2.0.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c046781d422f0830de6329fa4b16796096f28a92c8aef3850674442cdcb87b7f"}, - {file = "wrapt-2.0.1-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f73f9f7a0ebd0db139253d27e5fc8d2866ceaeef19c30ab5d69dcbe35e1a6981"}, - {file = "wrapt-2.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b667189cf8efe008f55bbda321890bef628a67ab4147ebf90d182f2dadc78790"}, - {file = "wrapt-2.0.1-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:a9a83618c4f0757557c077ef71d708ddd9847ed66b7cc63416632af70d3e2308"}, - {file = "wrapt-2.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1e9b121e9aeb15df416c2c960b8255a49d44b4038016ee17af03975992d03931"}, - {file = "wrapt-2.0.1-cp39-cp39-win32.whl", hash = "sha256:1f186e26ea0a55f809f232e92cc8556a0977e00183c3ebda039a807a42be1494"}, - {file = "wrapt-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:bf4cb76f36be5de950ce13e22e7fdf462b35b04665a12b64f3ac5c1bbbcf3728"}, - {file = "wrapt-2.0.1-cp39-cp39-win_arm64.whl", hash = "sha256:d6cc985b9c8b235bd933990cdbf0f891f8e010b65a3911f7a55179cd7b0fc57b"}, - {file = "wrapt-2.0.1-py3-none-any.whl", hash = "sha256:4d2ce1bf1a48c5277d7969259232b57645aae5686dba1eaeade39442277afbca"}, - {file = "wrapt-2.0.1.tar.gz", hash = "sha256:9c9c635e78497cacb81e84f8b11b23e0aacac7a136e73b8e5b2109a1d9fc468f"}, + {file = "wrapt-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7e927375e43fd5a985b27a8992327c22541b6dede1362fc79df337d26e23604f"}, + {file = "wrapt-2.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c99544b6a7d40ca22195563b6d8bc3986ee8bb82f272f31f0670fe9440c869"}, + {file = "wrapt-2.1.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b2be3fa5f4efaf16ee7c77d0556abca35f5a18ad4ac06f0ef3904c3399010ce9"}, + {file = "wrapt-2.1.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:67c90c1ae6489a6cb1a82058902caa8006706f7b4e8ff766f943e9d2c8e608d0"}, + {file = "wrapt-2.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:05c0db35ccffd7480143e62df1e829d101c7b86944ae3be7e4869a7efa621f53"}, + {file = "wrapt-2.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0c2ec9f616755b2e1e0bf4d0961f59bb5c2e7a77407e7e2c38ef4f7d2fdde12c"}, + {file = "wrapt-2.1.1-cp310-cp310-win32.whl", hash = "sha256:203ba6b3f89e410e27dbd30ff7dccaf54dcf30fda0b22aa1b82d560c7f9fe9a1"}, + {file = "wrapt-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:6f9426d9cfc2f8732922fc96198052e55c09bb9db3ddaa4323a18e055807410e"}, + {file = "wrapt-2.1.1-cp310-cp310-win_arm64.whl", hash = "sha256:69c26f51b67076b40714cff81bdd5826c0b10c077fb6b0678393a6a2f952a5fc"}, + {file = "wrapt-2.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6c366434a7fb914c7a5de508ed735ef9c133367114e1a7cb91dfb5cd806a1549"}, + {file = "wrapt-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5d6a2068bd2e1e19e5a317c8c0b288267eec4e7347c36bc68a6e378a39f19ee7"}, + {file = "wrapt-2.1.1-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:891ab4713419217b2aed7dd106c9200f64e6a82226775a0d2ebd6bef2ebd1747"}, + {file = "wrapt-2.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8ef36a0df38d2dc9d907f6617f89e113c5892e0a35f58f45f75901af0ce7d81"}, + {file = "wrapt-2.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:76e9af3ebd86f19973143d4d592cbf3e970cf3f66ddee30b16278c26ae34b8ab"}, + {file = "wrapt-2.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ff562067485ebdeaef2fa3fe9b1876bc4e7b73762e0a01406ad81e2076edcebf"}, + {file = "wrapt-2.1.1-cp311-cp311-win32.whl", hash = "sha256:9e60a30aa0909435ec4ea2a3c53e8e1b50ac9f640c0e9fe3f21fd248a22f06c5"}, + {file = "wrapt-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:7d79954f51fcf84e5ec4878ab4aea32610d70145c5bbc84b3370eabfb1e096c2"}, + {file = "wrapt-2.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:d3ffc6b0efe79e08fd947605fd598515aebefe45e50432dc3b5cd437df8b1ada"}, + {file = "wrapt-2.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ab8e3793b239db021a18782a5823fcdea63b9fe75d0e340957f5828ef55fcc02"}, + {file = "wrapt-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7c0300007836373d1c2df105b40777986accb738053a92fe09b615a7a4547e9f"}, + {file = "wrapt-2.1.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2b27c070fd1132ab23957bcd4ee3ba707a91e653a9268dc1afbd39b77b2799f7"}, + {file = "wrapt-2.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b0e36d845e8b6f50949b6b65fc6cd279f47a1944582ed4ec8258cd136d89a64"}, + {file = "wrapt-2.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4aeea04a9889370fcfb1ef828c4cc583f36a875061505cd6cd9ba24d8b43cc36"}, + {file = "wrapt-2.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d88b46bb0dce9f74b6817bc1758ff2125e1ca9e1377d62ea35b6896142ab6825"}, + {file = "wrapt-2.1.1-cp312-cp312-win32.whl", hash = "sha256:63decff76ca685b5c557082dfbea865f3f5f6d45766a89bff8dc61d336348833"}, + {file = "wrapt-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:b828235d26c1e35aca4107039802ae4b1411be0fe0367dd5b7e4d90e562fcbcd"}, + {file = "wrapt-2.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:75128507413a9f1bcbe2db88fd18fbdbf80f264b82fa33a6996cdeaf01c52352"}, + {file = "wrapt-2.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ce9646e17fa7c3e2e7a87e696c7de66512c2b4f789a8db95c613588985a2e139"}, + {file = "wrapt-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:428cfc801925454395aa468ba7ddb3ed63dc0d881df7b81626cdd433b4e2b11b"}, + {file = "wrapt-2.1.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5797f65e4d58065a49088c3b32af5410751cd485e83ba89e5a45e2aa8905af98"}, + {file = "wrapt-2.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a2db44a71202c5ae4bb5f27c6d3afbc5b23053f2e7e78aa29704541b5dad789"}, + {file = "wrapt-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8d5350c3590af09c1703dd60ec78a7370c0186e11eaafb9dda025a30eee6492d"}, + {file = "wrapt-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2d9b076411bed964e752c01b49fd224cc385f3a96f520c797d38412d70d08359"}, + {file = "wrapt-2.1.1-cp313-cp313-win32.whl", hash = "sha256:0bb7207130ce6486727baa85373503bf3334cc28016f6928a0fa7e19d7ecdc06"}, + {file = "wrapt-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:cbfee35c711046b15147b0ae7db9b976f01c9520e6636d992cd9e69e5e2b03b1"}, + {file = "wrapt-2.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:7d2756061022aebbf57ba14af9c16e8044e055c22d38de7bf40d92b565ecd2b0"}, + {file = "wrapt-2.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4814a3e58bc6971e46baa910ecee69699110a2bf06c201e24277c65115a20c20"}, + {file = "wrapt-2.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:106c5123232ab9b9f4903692e1fa0bdc231510098f04c13c3081f8ad71c3d612"}, + {file = "wrapt-2.1.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1a40b83ff2535e6e56f190aff123821eea89a24c589f7af33413b9c19eb2c738"}, + {file = "wrapt-2.1.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:789cea26e740d71cf1882e3a42bb29052bc4ada15770c90072cb47bf73fb3dbf"}, + {file = "wrapt-2.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ba49c14222d5e5c0ee394495a8655e991dc06cbca5398153aefa5ac08cd6ccd7"}, + {file = "wrapt-2.1.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ac8cda531fe55be838a17c62c806824472bb962b3afa47ecbd59b27b78496f4e"}, + {file = "wrapt-2.1.1-cp313-cp313t-win32.whl", hash = "sha256:b8af75fe20d381dd5bcc9db2e86a86d7fcfbf615383a7147b85da97c1182225b"}, + {file = "wrapt-2.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:45c5631c9b6c792b78be2d7352129f776dd72c605be2c3a4e9be346be8376d83"}, + {file = "wrapt-2.1.1-cp313-cp313t-win_arm64.whl", hash = "sha256:da815b9263947ac98d088b6414ac83507809a1d385e4632d9489867228d6d81c"}, + {file = "wrapt-2.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:9aa1765054245bb01a37f615503290d4e207e3fd59226e78341afb587e9c1236"}, + {file = "wrapt-2.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:feff14b63a6d86c1eee33a57f77573649f2550935981625be7ff3cb7342efe05"}, + {file = "wrapt-2.1.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:81fc5f22d5fcfdbabde96bb3f5379b9f4476d05c6d524d7259dc5dfb501d3281"}, + {file = "wrapt-2.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:951b228ecf66def855d22e006ab9a1fc12535111ae7db2ec576c728f8ddb39e8"}, + {file = "wrapt-2.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0ddf582a95641b9a8c8bd643e83f34ecbbfe1b68bc3850093605e469ab680ae3"}, + {file = "wrapt-2.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:fc5c500966bf48913f795f1984704e6d452ba2414207b15e1f8c339a059d5b16"}, + {file = "wrapt-2.1.1-cp314-cp314-win32.whl", hash = "sha256:4aa4baadb1f94b71151b8e44a0c044f6af37396c3b8bcd474b78b49e2130a23b"}, + {file = "wrapt-2.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:860e9d3fd81816a9f4e40812f28be4439ab01f260603c749d14be3c0a1170d19"}, + {file = "wrapt-2.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:3c59e103017a2c1ea0ddf589cbefd63f91081d7ce9d491d69ff2512bb1157e23"}, + {file = "wrapt-2.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:9fa7c7e1bee9278fc4f5dd8275bc8d25493281a8ec6c61959e37cc46acf02007"}, + {file = "wrapt-2.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:39c35e12e8215628984248bd9c8897ce0a474be2a773db207eb93414219d8469"}, + {file = "wrapt-2.1.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:94ded4540cac9125eaa8ddf5f651a7ec0da6f5b9f248fe0347b597098f8ec14c"}, + {file = "wrapt-2.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:da0af328373f97ed9bdfea24549ac1b944096a5a71b30e41c9b8b53ab3eec04a"}, + {file = "wrapt-2.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:4ad839b55f0bf235f8e337ce060572d7a06592592f600f3a3029168e838469d3"}, + {file = "wrapt-2.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0d89c49356e5e2a50fa86b40e0510082abcd0530f926cbd71cf25bee6b9d82d7"}, + {file = "wrapt-2.1.1-cp314-cp314t-win32.whl", hash = "sha256:f4c7dd22cf7f36aafe772f3d88656559205c3af1b7900adfccb70edeb0d2abc4"}, + {file = "wrapt-2.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:f76bc12c583ab01e73ba0ea585465a41e48d968f6d1311b4daec4f8654e356e3"}, + {file = "wrapt-2.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:7ea74fc0bec172f1ae5f3505b6655c541786a5cabe4bbc0d9723a56ac32eb9b9"}, + {file = "wrapt-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e03b3d486eb39f5d3f562839f59094dcee30c4039359ea15768dc2214d9e07c"}, + {file = "wrapt-2.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0fdf3073f488ce4d929929b7799e3b8c52b220c9eb3f4a5a51e2dc0e8ff07881"}, + {file = "wrapt-2.1.1-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0cb4f59238c6625fae2eeb72278da31c9cfba0ff4d9cbe37446b73caa0e9bcf7"}, + {file = "wrapt-2.1.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f794a1c148871b714cb566f5466ec8288e0148a1c417550983864b3981737cd"}, + {file = "wrapt-2.1.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:95ef3866631c6da9ce1fc0f1e17b90c4c0aa6d041fc70a11bc90733aee122e1a"}, + {file = "wrapt-2.1.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:66bc1b2446f01cbbd3c56b79a3a8435bcd4178ac4e06b091913f7751a7f528b8"}, + {file = "wrapt-2.1.1-cp39-cp39-win32.whl", hash = "sha256:1b9e08e57cabc32972f7c956d10e85093c5da9019faa24faf411e7dd258e528c"}, + {file = "wrapt-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:e75ad48c3cca739f580b5e14c052993eb644c7fa5b4c90aa51193280b30875ae"}, + {file = "wrapt-2.1.1-cp39-cp39-win_arm64.whl", hash = "sha256:9ccd657873b7f964711447d004563a2bc08d1476d7a1afcad310f3713e6f50f4"}, + {file = "wrapt-2.1.1-py3-none-any.whl", hash = "sha256:3b0f4629eb954394a3d7c7a1c8cca25f0b07cefe6aa8545e862e9778152de5b7"}, + {file = "wrapt-2.1.1.tar.gz", hash = "sha256:5fdcb09bf6db023d88f312bd0767594b414655d58090fc1c46b3414415f67fac"}, ] [package.extras] @@ -3091,4 +3190,4 @@ gui = ["Pillow", "opencv-python"] [metadata] lock-version = "2.1" python-versions = ">=3.11,<3.14" -content-hash = "b07a806d9692d29ae5b21dcf3643a41d71efcb081918f194e49762a1c9b4e827" +content-hash = "07331d3861224dbf9eb2c6e57647392d0040419ec0d779fcf13b788b7b6900cf" diff --git a/demos/python/sdk_wireless_camera_control/pyproject.toml b/demos/python/sdk_wireless_camera_control/pyproject.toml index 4c3153af6..7c52d87d6 100644 --- a/demos/python/sdk_wireless_camera_control/pyproject.toml +++ b/demos/python/sdk_wireless_camera_control/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "open_gopro" -version = "0.22.0" +version = "0.23.0" description = "Open GoPro API and Examples" authors = ["Tim Camise "] readme = "README.md" @@ -32,6 +32,7 @@ gopro-livestream = "open_gopro.demos.gui.livestream:entrypoint" gopro-preview-stream = "open_gopro.demos.gui.preview_stream:entrypoint" gopro-cohn = "open_gopro.demos.cohn:entrypoint" gopro-scan = "open_gopro.demos.scanner:entrypoint" +gopro-dump-gatt = "open_gopro.demos.dump_gatt:entrypoint" [build-system] requires = ["poetry-core>=1.0.0"] @@ -39,7 +40,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry.dependencies] python = ">=3.11,<3.14" -bleak = "=1.1.1" +bleak = "=2.1.1" construct = "^2" wrapt = "^2" requests = "^2" diff --git a/demos/python/sdk_wireless_camera_control/tests/mocks.py b/demos/python/sdk_wireless_camera_control/tests/mocks.py index 85fea177a..fff2503ef 100644 --- a/demos/python/sdk_wireless_camera_control/tests/mocks.py +++ b/demos/python/sdk_wireless_camera_control/tests/mocks.py @@ -6,9 +6,10 @@ import re from dataclasses import dataclass, field from pathlib import Path -from typing import Any, Generic, Optional, Pattern, TypeVar +from typing import Any, AsyncGenerator, Generic, Optional, Pattern, TypeVar import requests +from returns.result import Success from open_gopro import WiredGoPro, WirelessGoPro from open_gopro.api import ( @@ -256,6 +257,45 @@ def ok(self) -> bool: return self.status is ErrorCode.SUCCESS if self.status else True +class MockGoProObservable(Generic[T]): + """Mock observable that doesn't make BLE calls. + + Used to avoid sending actual BLE messages during test open(). + """ + + def __init__(self) -> None: + self._is_open = False + + async def start(self) -> "MockGoProObservable[T]": + self._is_open = True + return self + + async def stop(self) -> None: + self._is_open = False + + async def __aenter__(self) -> "MockGoProObservable[T]": + if not self._is_open: + await self.start() + return self + + async def __aexit__(self, *args: Any) -> None: + if self._is_open: + await self.stop() + + def observe(self, replay: int = 1, debug_id: str | None = None) -> AsyncGenerator[T, None]: + """Yields nothing - doesn't provide any status updates""" + + async def _empty_generator() -> AsyncGenerator[T, None]: + # Block forever (or until cancelled) to simulate waiting for updates + try: + await asyncio.Event().wait() + except asyncio.CancelledError: + return + yield # type: ignore # Makes this a generator + + return _empty_generator() + + # Create a context manager class to mock GoproObserverDistinctInitial class MockObserver(Generic[T, T2]): initial_response: Any = None @@ -444,23 +484,15 @@ def __init__(self) -> None: ) self._test_version = "2.0" self._api.ble_command.get_open_gopro_api_version = self._mock_get_version - self.ble_status.encoding.register_value_update = self._mock_register_encoding - self.ble_status.busy.register_value_update = self._mock_register_busy + self._api.ble_status.encoding.get_value_observable = self._mock_get_encoding_observable + self._api.ble_status.busy.get_value_observable = self._mock_get_busy_observable self.ble_setting.led.set = self._mock_led_set self._open_wifi = self._mock_open_wifi self.ble_command.set_pairing_complete = self._mock_pairing_complete - self._sync_resp_ready_q.get = self._mock_q_get + self.ble_command.set_third_party_client_info = self._mock_empty_return + self.ble_command.set_date_time_tz_dst = self._mock_empty_return self.generic_spy: asyncio.Queue[Any] = asyncio.Queue() - async def _mock_q_get(self, *args, **kwargs): - current = await self._sync_resp_wait_q.get() - return GoProResp( - protocol=GoProResp.Protocol.BLE, - status=ErrorCode.SUCCESS, - identifier=current, - data=True, - ) - async def _mock_led_set(self, *args): await self.generic_spy.put(args) return mock_good_response @@ -471,11 +503,16 @@ async def _mock_open_wifi(self, *args): async def _mock_pairing_complete(self) -> MockGoproResp: return MockGoproResp() - async def _mock_register_encoding(self, *args): - return MockGoproResp({StatusId.ENCODING: 1}) + async def _mock_empty_return(self, *args, **kwargs) -> MockGoproResp: + return MockGoproResp() + + async def _mock_get_encoding_observable(self): + """Return a mock observable for encoding status""" + return Success(MockGoProObservable()) - async def _mock_register_busy(self, *args): - return MockGoproResp({StatusId.BUSY: 1}) + async def _mock_get_busy_observable(self): + """Return a mock observable for busy status""" + return Success(MockGoProObservable()) async def mock_handle2uuid(self, *args): return GoProUUID.CQ_QUERY_RESP diff --git a/demos/python/sdk_wireless_camera_control/tests/unit/test_bleak_wrapper.py b/demos/python/sdk_wireless_camera_control/tests/unit/test_bleak_wrapper.py index e0caa542f..70a7af24b 100644 --- a/demos/python/sdk_wireless_camera_control/tests/unit/test_bleak_wrapper.py +++ b/demos/python/sdk_wireless_camera_control/tests/unit/test_bleak_wrapper.py @@ -213,3 +213,77 @@ async def read_gatt_descriptor(self, *args): assert len(gatt_db.services) == 1 assert len(gatt_db.characteristics) == 1 assert len(list(gatt_db.characteristics.values())[0].descriptors) == 1 + + +async def test_concurrent_writes_to_same_characteristic(mock_bleak_wrapper: BleakWrapperController, monkeypatch): + """Test that concurrent writes to the same characteristic both complete. + + Verifies the contract that when two writes to the same characteristic are issued + concurrently, both writes must complete successfully without any being orphaned. + """ + completed_writes = [] + + @dataclass + class MockBleakClient: + async def write_gatt_char(self, uuid: str, data: bytes, response: bool = False): + # Simulate BLE write taking some time + await asyncio.sleep(0.05) + completed_writes.append(data) + + client = MockBleakClient() + test_uuid = GoProUUID.CQ_QUERY + + # Launch two concurrent writes to the same characteristic + async def write_1(): + await mock_bleak_wrapper.write(client, test_uuid, b"data1") + + async def write_2(): + await mock_bleak_wrapper.write(client, test_uuid, b"data2") + + # Both writes should complete without error + await asyncio.gather(write_1(), write_2()) + + # Verify both writes completed (order may vary, but both must finish) + assert b"data1" in completed_writes + assert b"data2" in completed_writes + assert len(completed_writes) == 2 + + +async def test_ble_writes_are_serialized(mock_bleak_wrapper: BleakWrapperController, monkeypatch): + """Test that BLE writes are serialized (not concurrent) via lock. + + This ensures the lock is working - writes should execute in sequence, + not overlap. + """ + execution_log = [] + + @dataclass + class MockBleakClient: + async def write_gatt_char(self, uuid: str, data: bytes, response: bool = False): + execution_log.append(f"write_start:{data}") + await asyncio.sleep(0.02) # Simulate BLE latency + execution_log.append(f"write_end:{data}") + + client = MockBleakClient() + test_uuid = GoProUUID.CQ_QUERY + + # Launch concurrent writes + await asyncio.gather( + mock_bleak_wrapper.write(client, test_uuid, b"A"), + mock_bleak_wrapper.write(client, test_uuid, b"B"), + ) + + # With serialization, writes should NOT interleave + # Either: start_A, end_A, start_B, end_B OR start_B, end_B, start_A, end_A + assert len(execution_log) == 4 + + # Check that writes don't interleave (start-end pairs are adjacent) + if execution_log[0] == "write_start:b'A'": + assert execution_log[1] == "write_end:b'A'" + assert execution_log[2] == "write_start:b'B'" + assert execution_log[3] == "write_end:b'B'" + else: + assert execution_log[0] == "write_start:b'B'" + assert execution_log[1] == "write_end:b'B'" + assert execution_log[2] == "write_start:b'A'" + assert execution_log[3] == "write_end:b'A'" diff --git a/demos/python/sdk_wireless_camera_control/tests/unit/test_observables.py b/demos/python/sdk_wireless_camera_control/tests/unit/test_observables.py index 7d1db124f..3320d721c 100644 --- a/demos/python/sdk_wireless_camera_control/tests/unit/test_observables.py +++ b/demos/python/sdk_wireless_camera_control/tests/unit/test_observables.py @@ -456,7 +456,7 @@ async def test_status_observable_basic(mock_wireless_gopro_basic: MockWirelessGo await GoProObservable( gopro=mock_wireless_gopro_basic, update=StatusId.ENCODING, - register_command=mock_wireless_gopro_basic.mock_gopro_resp(True), + register_command=lambda: mock_wireless_gopro_basic.mock_gopro_resp(True), ) .on_subscribe(lambda: started.set()) .start() @@ -498,7 +498,7 @@ async def test_status_observable_different_initial_response(mock_wireless_gopro_ await GoproObserverDistinctInitial( gopro=mock_wireless_gopro_basic, update=StatusId.ENCODING, - register_command=mock_wireless_gopro_basic.ble_command.get_open_gopro_api_version(), + register_command=lambda: mock_wireless_gopro_basic.ble_command.get_open_gopro_api_version(), ) .on_subscribe(lambda: started.set()) .start() @@ -534,3 +534,453 @@ async def receive_values(): # THEN assert values == ["2.0", True, False, True, False] + + +############################################################################### +# Observer lifecycle and error handling tests +############################################################################### + + +async def test_observer_aclose_removes_observer(): + # GIVEN + observable = Observable[int]() + observer = observable.observe(replay=Observable.REPLAY_ALL) + + # WHEN + await observable.emit(0) + _ = await anext(observer) # Activates the observer + await observer.aclose() + + # THEN - observer should be removed from the observable + async with observable._shared_data: + assert observer._uuid not in observable._shared_data.q_dict + assert not observer._is_active + + +async def test_observer_aclose_is_idempotent(): + # GIVEN + observable = Observable[int]() + observer = observable.observe(replay=Observable.REPLAY_ALL) + + # WHEN + await observable.emit(0) + _ = await anext(observer) + await observer.aclose() + await observer.aclose() # Should not raise + + # THEN + assert not observer._is_active + + +async def test_observer_athrow_stops_iteration(): + # GIVEN + observable = Observable[int]() + observer = observable.observe(replay=Observable.REPLAY_ALL) + + # WHEN + await observable.emit(0) + _ = await anext(observer) + + # THEN + with pytest.raises(ValueError, match="test error"): + await observer.athrow(ValueError, ValueError("test error")) + + assert not observer._is_active + + +async def test_observer_athrow_before_activation_raises_stop_iteration(): + # GIVEN + observable = Observable[int]() + observer = observable.observe() + + # WHEN / THEN + with pytest.raises(StopAsyncIteration): + await observer.athrow(ValueError) + + +async def test_observer_asend_advances_iterator(): + """Test that asend advances the iterator to the next value (same as anext).""" + # GIVEN + observable = Observable[int]() + observer = observable.observe(replay=Observable.REPLAY_ALL) + + # WHEN - emit values first so they're in the cache + await observable.emit(0) + await observable.emit(1) + await observable.emit(2) + + # Get first value via anext + first = await anext(observer) + assert first == 0 + + # Use asend to get the next value (asend(None) is equivalent to anext per AsyncGenerator protocol) + second = await observer.asend(None) + + # THEN + assert second == 1 + + +async def test_observer_asend_before_activation_raises_stop_iteration(): + # GIVEN + observable = Observable[int]() + observer = observable.observe() + + # WHEN / THEN + with pytest.raises(StopAsyncIteration): + await observer.asend(None) + + +############################################################################### +# Cache and capacity tests +############################################################################### + + +async def test_observable_capacity_overflow_keeps_most_recent(): + # GIVEN + capacity = 3 + observable = Observable[int](capacity=capacity) + + # WHEN - emit more than capacity + for i in range(10): + await observable.emit(i) + + # THEN - only most recent 'capacity' values should be cached + observer = observable.observe(replay=Observable.REPLAY_ALL) + values = [] + for _ in range(capacity): + values.append(await anext(observer)) + + assert values == [7, 8, 9] + assert len(observable._shared_data.cache) == capacity + + +async def test_replay_partial_cache(): + # GIVEN + observable = Observable[int]() + for i in range(5): + await observable.emit(i) + + # WHEN - request replay of 2 + observer = observable.observe(replay=2) + + # THEN + values = [] + values.append(await anext(observer)) + values.append(await anext(observer)) + assert values == [3, 4] + + +async def test_replay_more_than_cache_gets_all(): + # GIVEN + observable = Observable[int]() + await observable.emit(0) + await observable.emit(1) + + # WHEN - request replay of 10 but only 2 exist + observer = observable.observe(replay=10) + + # THEN + values = [] + values.append(await anext(observer)) + values.append(await anext(observer)) + assert values == [0, 1] + + +############################################################################### +# Concurrent operations and deadlock prevention tests +############################################################################### + + +async def test_concurrent_emit_and_observe_no_deadlock(): + # GIVEN + observable = Observable[int]() + results: list[int] = [] + num_values = 100 + + # WHEN - concurrent emit and observe + async def emitter(): + for i in range(num_values): + await observable.emit(i) + await asyncio.sleep(0) # Yield to allow observer to run + + async def collector(): + observer = observable.observe(replay=Observable.REPLAY_ALL) + async for value in islice(observer, num_values): + results.append(value) + + # THEN - should complete without deadlock + try: + async with asyncio.timeout(5): + async with asyncio.TaskGroup() as tg: + tg.create_task(emitter()) + tg.create_task(collector()) + except TimeoutError: + pytest.fail("Deadlock detected: concurrent emit and observe timed out") + + assert len(results) == num_values + assert results == list(range(num_values)) + + +async def test_multiple_observers_different_replay_no_deadlock(): + # GIVEN + observable = Observable[int]() + results1: list[int] = [] + results2: list[int] = [] + results3: list[int] = [] + + # WHEN - emit values, then create observers with different replay + for i in range(10): + await observable.emit(i) + + observer1 = observable.observe(replay=0) + observer2 = observable.observe(replay=5) + observer3 = observable.observe(replay=Observable.REPLAY_ALL) + + # Collect replayed values + async def collect_with_timeout(observer, results, count): + try: + async with asyncio.timeout(1): + async for value in islice(observer, count): + results.append(value) + except TimeoutError: + pass + + # observer1 shouldn't get any replayed values, so it would timeout waiting + # observers 2 and 3 should get their replayed values immediately + + async with asyncio.TaskGroup() as tg: + tg.create_task(collect_with_timeout(observer2, results2, 5)) + tg.create_task(collect_with_timeout(observer3, results3, 10)) + + # THEN + assert results1 == [] # No replay + assert results2 == [5, 6, 7, 8, 9] # Last 5 values + assert results3 == list(range(10)) # All values + + +async def test_observer_close_during_emit_no_deadlock(): + # GIVEN + observable = Observable[int]() + observer = observable.observe(replay=Observable.REPLAY_ALL) + collected: list[int] = [] + + # WHEN + await observable.emit(0) + collected.append(await anext(observer)) + + # Close observer while emitting in background + async def close_soon(): + await asyncio.sleep(0.01) + await observer.aclose() + + async def emit_many(): + for i in range(1, 100): + await observable.emit(i) + await asyncio.sleep(0.001) + + # THEN - should not deadlock + try: + async with asyncio.timeout(2): + await asyncio.gather(close_soon(), emit_many()) + except TimeoutError: + pytest.fail("Deadlock detected during close while emitting") + + +async def test_rapid_subscribe_unsubscribe_no_deadlock(): + # GIVEN + observable = Observable[int]() + subscribe_count = 50 + + # WHEN - rapidly create and close observers + async def subscribe_and_close(): + observer = observable.observe(replay=Observable.REPLAY_ALL) + await observable.emit(1) + _ = await anext(observer) + await observer.aclose() + + # THEN - should complete without deadlock + try: + async with asyncio.timeout(5): + for _ in range(subscribe_count): + await subscribe_and_close() + except TimeoutError: + pytest.fail("Deadlock detected during rapid subscribe/unsubscribe") + + +async def test_concurrent_observers_with_slow_consumer_no_deadlock(): + # GIVEN + observable = Observable[int]() + fast_results: list[int] = [] + slow_results: list[int] = [] + num_values = 20 + + # WHEN - one fast consumer, one slow consumer + started = asyncio.Event() + + async def emitter(): + await started.wait() + for i in range(num_values): + await observable.emit(i) + await asyncio.sleep(0.001) + + async def fast_consumer(): + started.set() + observer = observable.observe(replay=Observable.REPLAY_ALL) + async for value in islice(observer, num_values): + fast_results.append(value) + + async def slow_consumer(): + await started.wait() + observer = observable.observe(replay=Observable.REPLAY_ALL) + async for value in islice(observer, num_values): + await asyncio.sleep(0.01) # Slow processing + slow_results.append(value) + + # THEN - should complete without deadlock + try: + async with asyncio.timeout(10): + async with asyncio.TaskGroup() as tg: + tg.create_task(emitter()) + tg.create_task(fast_consumer()) + tg.create_task(slow_consumer()) + except TimeoutError: + pytest.fail("Deadlock detected with slow consumer") + + assert fast_results == list(range(num_values)) + assert slow_results == list(range(num_values)) + + +############################################################################### +# on_subscribe and on_start action tests +############################################################################### + + +async def test_on_subscribe_async_action(): + # GIVEN + subscribe_event = asyncio.Event() + started = asyncio.Event() + + async def async_subscribe_action(): + subscribe_event.set() + + observable = Observable[int]().on_subscribe(async_subscribe_action).on_subscribe(lambda: started.set()) + observer = observable.observe() + + # WHEN + async def emit_values(): + await started.wait() + await observable.emit(0) + + async with asyncio.TaskGroup() as tg: + tg.create_task(emit_values()) + result = tg.create_task(anext(observer)) + + # Note: The current implementation has a bug where async on_subscribe is awaited + # but sync is also called (we fixed this). This test verifies the fix. + assert result.result() == 0 + + +async def test_on_start_called_only_once(): + # GIVEN + call_count = 0 + + def increment_count(_): + nonlocal call_count + call_count += 1 + + started = asyncio.Event() + observable = Observable[int]().on_subscribe(lambda: started.set()).on_start(increment_count) + observer = observable.observe() + + # WHEN + async def emit_values(): + await started.wait() + for i in range(5): + await observable.emit(i) + + async with asyncio.TaskGroup() as tg: + tg.create_task(emit_values()) + collected = tg.create_task(collect_n(observer, 5)) + + # THEN - on_start should be called only once (for the first value) + assert collected.result() == [0, 1, 2, 3, 4] + assert call_count == 1 + + +############################################################################### +# Error propagation tests +############################################################################### + + +async def test_observer_handles_exception_in_iteration(): + # GIVEN + observable = Observable[int]() + observer = observable.observe(replay=Observable.REPLAY_ALL) + + # WHEN + await observable.emit(0) + await observable.emit(1) + + # Simulate an error during processing + values = [] + try: + async for value in observer: + values.append(value) + if value == 1: + raise ValueError("Processing error") + except ValueError: + pass + + # THEN - observer should be cleaned up + await observer.aclose() + assert not observer._is_active + + +async def test_get_next_with_unregistered_observer_raises(): + # GIVEN + observable = Observable[int]() + from uuid import uuid1 + + fake_uuid = uuid1() + + # WHEN / THEN + with pytest.raises(RuntimeError, match="Observer has not been added"): + await observable._get_next(fake_uuid) + + +############################################################################### +# Current value and state tests +############################################################################### + + +async def test_current_value_is_none_initially(): + # GIVEN + observable = Observable[int]() + + # THEN + assert observable.current is None + + +async def test_current_value_updates_on_emit(): + # GIVEN + observable = Observable[int]() + + # WHEN + await observable.emit(42) + await observable.emit(100) + + # THEN + assert observable.current == 100 + + +############################################################################### +# Helper functions +############################################################################### + + +async def collect_n(observer, n: int) -> list: + """Helper to collect n values from an observer""" + values = [] + async for value in islice(observer, n): + values.append(value) + return values diff --git a/demos/python/sdk_wireless_camera_control/tests/unit/test_wireless_gopro.py b/demos/python/sdk_wireless_camera_control/tests/unit/test_wireless_gopro.py index 21bd98ee5..cddd7afbb 100644 --- a/demos/python/sdk_wireless_camera_control/tests/unit/test_wireless_gopro.py +++ b/demos/python/sdk_wireless_camera_control/tests/unit/test_wireless_gopro.py @@ -163,12 +163,13 @@ async def test_route_all_data(mock_wireless_gopro_basic: WirelessGoPro): ) # WHEN - # Make it appear to be the synchronous response - await mock_wireless_gopro_basic._sync_resp_wait_q.put(mock_response) - # Route the mock response + # Create a Future and register it as pending + future: asyncio.Future[GoProResp] = asyncio.Future() + mock_wireless_gopro_basic._pending_responses.append((QueryCmdId.GET_SETTING_VAL, future)) + # Route the mock response - this should resolve the Future await mock_wireless_gopro_basic._route_response(mock_response) - # Get the routed response - routed_response = await mock_wireless_gopro_basic._sync_resp_ready_q.get() + # Get the routed response from the resolved Future + routed_response = await future # THEN assert routed_response.data == mock_data @@ -187,17 +188,157 @@ async def test_route_individual_data(mock_wireless_gopro_basic: WirelessGoPro): ) # WHEN - # Make it appear to be the synchronous response - await mock_wireless_gopro_basic._sync_resp_wait_q.put(mock_response) - # Route the mock response + # Create a Future and register it as pending + future: asyncio.Future[GoProResp] = asyncio.Future() + mock_wireless_gopro_basic._pending_responses.append((QueryCmdId.GET_SETTING_VAL, future)) + # Route the mock response - this should resolve the Future await mock_wireless_gopro_basic._route_response(mock_response) - # Get the routed response - routed_response = await mock_wireless_gopro_basic._sync_resp_ready_q.get() + # Get the routed response from the resolved Future + routed_response = await future # THEN assert routed_response.data == 1 +async def test_concurrent_ble_messages_receive_correct_responses(mock_wireless_gopro_basic: WirelessGoPro): + """Test that concurrent BLE message senders receive their own responses, not each other's. + + With the Future-based approach, each sender creates and awaits its own Future. + When _route_response resolves a Future, only the sender waiting on that specific + Future receives the response - eliminating the race condition. + """ + mock_wireless_gopro_basic._loop = asyncio.get_running_loop() + + # GIVEN two different request identifiers + request_1_id = QueryCmdId.GET_SETTING_VAL # Sender 1's request + request_2_id = QueryCmdId.GET_STATUS_VAL # Sender 2's request + + response_for_sender_1 = GoProResp( + protocol=GoProResp.Protocol.BLE, + status=ErrorCode.SUCCESS, + data={"setting": "value"}, + identifier=request_1_id, + ) + response_for_sender_2 = GoProResp( + protocol=GoProResp.Protocol.BLE, + status=ErrorCode.SUCCESS, + data={"status": "value"}, + identifier=request_2_id, + ) + + # Track which response each simulated sender receives + received_responses: dict[str, GoProResp] = {} + + # Coordination events to precisely control timing + sender1_registered = asyncio.Event() + sender2_registered = asyncio.Event() + + # Create Futures for each sender + future_1: asyncio.Future[GoProResp] = asyncio.Future() + future_2: asyncio.Future[GoProResp] = asyncio.Future() + + async def simulate_sender_1(): + """Sender 1: registers first, awaits its own Future""" + # Register our Future in the pending list FIRST + mock_wireless_gopro_basic._pending_responses.append((request_1_id, future_1)) + sender1_registered.set() + # Wait for sender 2 to also register + await sender2_registered.wait() + # Await our own Future - only we will receive this response + response = await asyncio.wait_for(future_1, timeout=2) + received_responses["sender1"] = response + + async def simulate_sender_2(): + """Sender 2: registers second, awaits its own Future""" + # Wait for sender 1 to register + await sender1_registered.wait() + # Register our Future in the pending list SECOND + mock_wireless_gopro_basic._pending_responses.append((request_2_id, future_2)) + sender2_registered.set() + # Await our own Future - only we will receive this response + response = await asyncio.wait_for(future_2, timeout=2) + received_responses["sender2"] = response + + # Start both senders + task1 = asyncio.create_task(simulate_sender_1()) + task2 = asyncio.create_task(simulate_sender_2()) + + # Wait for both to be registered and waiting + await sender2_registered.wait() + await asyncio.sleep(0.01) # Ensure both are blocked awaiting their Futures + + # WHEN: Route response for sender 1 (matches head of pending list: request_1_id) + # This resolves future_1 directly - only sender 1 will wake up + await mock_wireless_gopro_basic._route_response(response_for_sender_1) + + # Then route response for sender 2 (now matches new head: request_2_id) + # This resolves future_2 directly - only sender 2 will wake up + await mock_wireless_gopro_basic._route_response(response_for_sender_2) + + # Wait for both senders to complete + await asyncio.gather(task1, task2) + + # THEN: Each sender receives ITS OWN response + # With Direct Future resolution, this PASSES because: + # - Each sender awaits its own Future + # - _route_response resolves the specific Future for the matching identifier + # - No race condition - responses go directly to the correct sender + assert ( + received_responses["sender1"].identifier == request_1_id + ), f"Sender 1 (expecting {request_1_id}) received wrong response: {received_responses['sender1'].identifier}" + assert ( + received_responses["sender2"].identifier == request_2_id + ), f"Sender 2 (expecting {request_2_id}) received wrong response: {received_responses['sender2'].identifier}" + + +async def test_out_of_order_ble_responses_routed_correctly(mock_wireless_gopro_basic: WirelessGoPro): + """Test that responses arriving out of order are still routed to the correct sender. + + Scenario: A slow command (e.g., COHN) is pending at the head, then a fast command's + response arrives. The fast response should match its sender, not be treated as async. + + Current bug: _route_response only checks the head, so the fast response gets + misrouted as async because it doesn't match the slow command at the head. + """ + mock_wireless_gopro_basic._loop = asyncio.get_running_loop() + + # GIVEN: Two requests registered - slow command first, fast command second + slow_request_id = QueryCmdId.GET_SETTING_VAL # Simulates slow COHN-like command + fast_request_id = QueryCmdId.GET_STATUS_VAL # Simulates fast LED-like command + + future_slow: asyncio.Future[GoProResp] = asyncio.Future() + future_fast: asyncio.Future[GoProResp] = asyncio.Future() + + # Register slow command first (at head of queue) + mock_wireless_gopro_basic._pending_responses.append((slow_request_id, future_slow)) + # Register fast command second (behind slow command) + mock_wireless_gopro_basic._pending_responses.append((fast_request_id, future_fast)) + + # Response for fast command (arrives first, out of order) + fast_response = GoProResp( + protocol=GoProResp.Protocol.BLE, + status=ErrorCode.SUCCESS, + data={"status": "fast_value"}, + identifier=fast_request_id, + ) + + # WHEN: Fast response arrives while slow command is still at head + await mock_wireless_gopro_basic._route_response(fast_response) + + # THEN: Fast response should resolve the fast Future (not be treated as async) + assert future_fast.done(), "Fast response should have resolved the fast Future" + assert future_fast.result().identifier == fast_request_id + # Note: _route_response unwraps single-value dicts for query responses + assert future_fast.result().data == "fast_value" + + # AND: Slow Future should still be pending + assert not future_slow.done(), "Slow Future should still be pending" + + # AND: Pending responses should only have the slow request left + assert len(mock_wireless_gopro_basic._pending_responses) == 1 + assert mock_wireless_gopro_basic._pending_responses[0][0] == slow_request_id + + async def test_get_update_unregister(mock_wireless_gopro_basic: WirelessGoPro): event = asyncio.Event() mock_wireless_gopro_basic._loop = asyncio.get_running_loop() @@ -248,9 +389,19 @@ async def set_disconnect_event(): await mock_wireless_gopro._update_internal_state(update=StatusId.BUSY, value=False) assert await mock_wireless_gopro.is_ready + async def provide_response(): + """Simulate the response being routed by resolving the pending Future""" + # Wait a bit for the BLE command to register its Future + await asyncio.sleep(0.1) + # Get the pending Future and resolve it with a mock response + if mock_wireless_gopro._pending_responses: + _, future = mock_wireless_gopro._pending_responses[0] + mock_wireless_gopro._pending_responses.pop(0) + future.set_result(mock_good_response) + results = await asyncio.gather( mock_wireless_gopro.ble_command.enable_wifi_ap(enable=False), - mock_wireless_gopro._sync_resp_ready_q.put(mock_good_response), + provide_response(), ) assert results[0].ok diff --git a/demos/python/sdk_wireless_camera_control/thirdPartyDependencies.csv b/demos/python/sdk_wireless_camera_control/thirdPartyDependencies.csv index 7d05cfbed..9a05ed91d 100644 --- a/demos/python/sdk_wireless_camera_control/thirdPartyDependencies.csv +++ b/demos/python/sdk_wireless_camera_control/thirdPartyDependencies.csv @@ -1,37 +1,37 @@ name,version,size,homePage,author,license,licenseCompat,errorCode,namever annotated-types,0.7.0,36468,UNKNOWN,UNKNOWN,MIT LICENSE,True,0,annotated-types-0.7.0 asyncstdlib,3.13.1,142529,UNKNOWN,UNKNOWN,MIT LICENSE,True,0,asyncstdlib-3.13.1 -bleak,1.1.1,471223,UNKNOWN,Henrik Blidh,MIT LICENSE,True,0,bleak-1.1.1 -certifi,2025.10.5,298671,https://github.com/certifi/python-certifi,Kenneth Reitz,MOZILLA PUBLIC LICENSE 2.0 _MPL 2.0_,True,0,certifi-2025.10.5 -charset-normalizer,3.4.4,747872,UNKNOWN,UNKNOWN,MIT,True,0,charset-normalizer-3.4.4 +bleak,2.1.1,488732,UNKNOWN,Henrik Blidh,MIT,True,0,bleak-2.1.1 +certifi,2026.1.4,278258,https://github.com/certifi/python-certifi,Kenneth Reitz,MOZILLA PUBLIC LICENSE 2.0 _MPL 2.0_,True,0,certifi-2026.1.4 +charset-normalizer,3.4.4,747880,UNKNOWN,UNKNOWN,MIT,True,0,charset-normalizer-3.4.4 construct,2.10.70,305145,http://construct.readthedocs.org,"Arkadiusz Bulski, Tomer Filiba, Corbin Simpson",MIT LICENSE,True,0,construct-2.10.70 idna,3.11,353148,UNKNOWN,UNKNOWN,BSD-3-CLAUSE,True,0,idna-3.11 ifaddr,0.2.0,25179,https://github.com/pydron/ifaddr,Stefan C. Mueller,MIT LICENSE,True,0,ifaddr-0.2.0 -markdown-it-py,4.0.0,223806,UNKNOWN,UNKNOWN,MIT LICENSE,True,0,markdown-it-py-4.0.0 +markdown-it-py,4.0.0,223814,UNKNOWN,UNKNOWN,MIT LICENSE,True,0,markdown-it-py-4.0.0 mdurl,0.1.2,22532,UNKNOWN,UNKNOWN,MIT LICENSE,True,0,mdurl-0.1.2 -mypy,1.17.1,45136285,UNKNOWN,UNKNOWN,MIT LICENSE,True,0,mypy-1.17.1 +mypy,1.17.1,45136325,UNKNOWN,UNKNOWN,MIT LICENSE,True,0,mypy-1.17.1 mypy-extensions,1.1.0,10152,UNKNOWN,UNKNOWN,,False,0,mypy-extensions-1.1.0 -packaging,25.0,236496,UNKNOWN,UNKNOWN,APACHE SOFTWARE LICENSE;; BSD LICENSE,True,0,packaging-25.0 -pathspec,0.12.1,101741,UNKNOWN,UNKNOWN,MOZILLA PUBLIC LICENSE 2.0 _MPL 2.0_,True,0,pathspec-0.12.1 +packaging,26.0,274986,UNKNOWN,UNKNOWN,APACHE-2.0;; BSD-2-CLAUSE,True,0,packaging-26.0 +pathspec,1.0.4,153559,UNKNOWN,UNKNOWN,MOZILLA PUBLIC LICENSE 2.0 _MPL 2.0_,True,0,pathspec-1.0.4 pexpect,4.9.0,189532,https://pexpect.readthedocs.io/,Noah Spurrier; Thomas Kluyver; Jeff Quast,ISC LICENSE _ISCL_,True,0,pexpect-4.9.0 -protobuf,6.33.0,1575235,https://developers.google.com/protocol-buffers/,protobuf@googlegroups.com,3-CLAUSE BSD LICENSE,True,0,protobuf-6.33.0 +protobuf,6.33.5,1576462,https://developers.google.com/protocol-buffers/,protobuf@googlegroups.com,3-CLAUSE BSD LICENSE,True,0,protobuf-6.33.5 ptyprocess,0.7.0,39299,https://github.com/pexpect/ptyprocess,Thomas Kluyver,ISC LICENSE _ISCL_,True,0,ptyprocess-0.7.0 -pydantic,2.12.4,1841817,UNKNOWN,UNKNOWN,MIT,True,0,pydantic-2.12.4 +pydantic,2.12.5,1842130,UNKNOWN,UNKNOWN,MIT,True,0,pydantic-2.12.5 pydantic-core,2.41.5,4433293,https://github.com/pydantic/pydantic-core,UNKNOWN,MIT,True,0,pydantic-core-2.41.5 -pygments,2.19.2,4467119,UNKNOWN,UNKNOWN,BSD LICENSE,True,0,pygments-2.19.2 -pyobjc-core,12.0,2330535,https://github.com/ronaldoussoren/pyobjc,"Ronald Oussoren, bbum, SteveM, LeleG, many others stretching back through the reaches of time...",MIT,True,0,pyobjc-core-12.0 -pyobjc-framework-cocoa,12.0,2555660,https://github.com/ronaldoussoren/pyobjc,Ronald Oussoren,MIT,True,0,pyobjc-framework-cocoa-12.0 -pyobjc-framework-corebluetooth,12.0,109919,https://github.com/ronaldoussoren/pyobjc,Ronald Oussoren,MIT,True,0,pyobjc-framework-corebluetooth-12.0 -pyobjc-framework-libdispatch,12.0,186647,https://github.com/ronaldoussoren/pyobjc,Ronald Oussoren,MIT,True,0,pyobjc-framework-libdispatch-12.0 +pygments,2.19.2,4467127,UNKNOWN,UNKNOWN,BSD LICENSE,True,0,pygments-2.19.2 +pyobjc-core,12.1,2295639,https://github.com/ronaldoussoren/pyobjc,"Ronald Oussoren, bbum, SteveM, LeleG, many others stretching back through the reaches of time...",MIT,True,0,pyobjc-core-12.1 +pyobjc-framework-cocoa,12.1,2556409,https://github.com/ronaldoussoren/pyobjc,Ronald Oussoren,MIT,True,0,pyobjc-framework-cocoa-12.1 +pyobjc-framework-corebluetooth,12.1,109868,https://github.com/ronaldoussoren/pyobjc,Ronald Oussoren,MIT,True,0,pyobjc-framework-corebluetooth-12.1 +pyobjc-framework-libdispatch,12.1,186596,https://github.com/ronaldoussoren/pyobjc,Ronald Oussoren,MIT,True,0,pyobjc-framework-libdispatch-12.1 pytz,2025.2,957593,http://pythonhosted.org/pytz,Stuart Bishop,MIT LICENSE,True,0,pytz-2025.2 requests,2.32.5,202514,https://requests.readthedocs.io,Kenneth Reitz,APACHE SOFTWARE LICENSE,True,0,requests-2.32.5 returns,0.26.0,546444,https://returns.readthedocs.io,sobolevn,BSD LICENSE,True,0,returns-0.26.0 -rich,14.2.0,954430,https://github.com/Textualize/rich,Will McGugan,MIT LICENSE,True,0,rich-14.2.0 +rich,14.3.2,1235145,https://github.com/Textualize/rich,Will McGugan,MIT LICENSE,True,0,rich-14.3.2 tinydb,4.8.2,75569,https://github.com/msiemens/tinydb,Markus Siemens,MIT LICENSE,True,0,tinydb-4.8.2 typing-extensions,4.15.0,177718,UNKNOWN,UNKNOWN,PSF-2.0,True,0,typing-extensions-4.15.0 typing-inspection,0.4.2,52842,UNKNOWN,UNKNOWN,MIT,True,0,typing-inspection-0.4.2 tzlocal,5.3.1,61311,UNKNOWN,UNKNOWN,MIT LICENSE,True,0,tzlocal-5.3.1 -urllib3,2.5.0,421384,UNKNOWN,UNKNOWN,MIT,True,0,urllib3-2.5.0 -wrapt,2.0.1,324285,https://github.com/GrahamDumpleton/wrapt,Graham Dumpleton,COPYRIGHT _C_ 2013-2025_ GRAHAM DUMPLETON,True,0,wrapt-2.0.1 +urllib3,2.6.3,430021,UNKNOWN,UNKNOWN,MIT,True,0,urllib3-2.6.3 +wrapt,2.1.1,325896,UNKNOWN,UNKNOWN,BSD-2-CLAUSE,True,0,wrapt-2.1.1 zeroconf,0.148.0,5140733,UNKNOWN,Paul Scott-Murphy,LGPL-2.1-OR-LATER,True,0,zeroconf-0.148.0 diff --git a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/camera_control_pb2.py b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/camera_control_pb2.py index 1a00de486..05ab35dbf 100644 --- a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/camera_control_pb2.py +++ b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/camera_control_pb2.py @@ -1,6 +1,3 @@ -# camera_control_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:47 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf.internal import builder as _builder diff --git a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/cohn_pb2.py b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/cohn_pb2.py index 169052cd7..5c0e666e3 100644 --- a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/cohn_pb2.py +++ b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/cohn_pb2.py @@ -1,6 +1,3 @@ -# cohn_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:47 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf.internal import builder as _builder diff --git a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/live_streaming_pb2.py b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/live_streaming_pb2.py index e680bbb9e..8bf49e1b5 100644 --- a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/live_streaming_pb2.py +++ b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/live_streaming_pb2.py @@ -1,6 +1,3 @@ -# live_streaming_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:47 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf.internal import builder as _builder diff --git a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/media_pb2.py b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/media_pb2.py index 27ae344c9..57bb24f0e 100644 --- a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/media_pb2.py +++ b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/media_pb2.py @@ -1,6 +1,3 @@ -# media_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:47 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf.internal import builder as _builder diff --git a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/network_management_pb2.py b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/network_management_pb2.py index 6f8bd9e5c..91f8c5fa2 100644 --- a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/network_management_pb2.py +++ b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/network_management_pb2.py @@ -1,6 +1,3 @@ -# network_management_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:47 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf.internal import builder as _builder diff --git a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/preset_status_pb2.py b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/preset_status_pb2.py index e6a189c70..034ccc622 100644 --- a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/preset_status_pb2.py +++ b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/preset_status_pb2.py @@ -1,6 +1,3 @@ -# preset_status_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:47 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf.internal import builder as _builder @@ -12,22 +9,22 @@ from . import response_generic_pb2 as response__generic__pb2 DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x13preset_status.proto\x12\nopen_gopro\x1a\x16response_generic.proto"I\n\x12NotifyPresetStatus\x123\n\x12preset_group_array\x18\x01 \x03(\x0b2\x17.open_gopro.PresetGroup"\xc3\x02\n\x06Preset\x12\n\n\x02id\x18\x01 \x01(\x05\x12&\n\x04mode\x18\x02 \x01(\x0e2\x18.open_gopro.EnumFlatMode\x12-\n\x08title_id\x18\x03 \x01(\x0e2\x1b.open_gopro.EnumPresetTitle\x12\x14\n\x0ctitle_number\x18\x04 \x01(\x05\x12\x14\n\x0cuser_defined\x18\x05 \x01(\x08\x12(\n\x04icon\x18\x06 \x01(\x0e2\x1a.open_gopro.EnumPresetIcon\x120\n\rsetting_array\x18\x07 \x03(\x0b2\x19.open_gopro.PresetSetting\x12\x13\n\x0bis_modified\x18\x08 \x01(\x08\x12\x10\n\x08is_fixed\x18\t \x01(\x08\x12\x13\n\x0bcustom_name\x18\n \x01(\t\x12\x12\n\nis_visible\x18\x0b \x01(\x08"\x8c\x01\n\x19RequestCustomPresetUpdate\x12-\n\x08title_id\x18\x01 \x01(\x0e2\x1b.open_gopro.EnumPresetTitle\x12\x13\n\x0bcustom_name\x18\x02 \x01(\t\x12+\n\x07icon_id\x18\x03 \x01(\x0e2\x1a.open_gopro.EnumPresetIcon"9\n\x1aRequestPresetSetVisibility\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x0f\n\x07visible\x18\x02 \x01(\x08"\xd5\x01\n\x0bPresetGroup\x12\'\n\x02id\x18\x01 \x01(\x0e2\x1b.open_gopro.EnumPresetGroup\x12(\n\x0cpreset_array\x18\x02 \x03(\x0b2\x12.open_gopro.Preset\x12\x16\n\x0ecan_add_preset\x18\x03 \x01(\x08\x12-\n\x04icon\x18\x04 \x01(\x0e2\x1f.open_gopro.EnumPresetGroupIcon\x12,\n\nmode_array\x18\x05 \x03(\x0e2\x18.open_gopro.EnumFlatMode">\n\rPresetSetting\x12\n\n\x02id\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x05\x12\x12\n\nis_caption\x18\x03 \x01(\x08*\x9b\x05\n\x0cEnumFlatMode\x12\x1e\n\x11FLAT_MODE_UNKNOWN\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x12\x16\n\x12FLAT_MODE_PLAYBACK\x10\x04\x12\x13\n\x0fFLAT_MODE_SETUP\x10\x05\x12\x13\n\x0fFLAT_MODE_VIDEO\x10\x0c\x12\x1e\n\x1aFLAT_MODE_TIME_LAPSE_VIDEO\x10\r\x12\x15\n\x11FLAT_MODE_LOOPING\x10\x0f\x12\x1a\n\x16FLAT_MODE_PHOTO_SINGLE\x10\x10\x12\x13\n\x0fFLAT_MODE_PHOTO\x10\x11\x12\x19\n\x15FLAT_MODE_PHOTO_NIGHT\x10\x12\x12\x19\n\x15FLAT_MODE_PHOTO_BURST\x10\x13\x12\x1e\n\x1aFLAT_MODE_TIME_LAPSE_PHOTO\x10\x14\x12\x1f\n\x1bFLAT_MODE_NIGHT_LAPSE_PHOTO\x10\x15\x12\x1e\n\x1aFLAT_MODE_BROADCAST_RECORD\x10\x16\x12!\n\x1dFLAT_MODE_BROADCAST_BROADCAST\x10\x17\x12\x1d\n\x19FLAT_MODE_TIME_WARP_VIDEO\x10\x18\x12\x18\n\x14FLAT_MODE_LIVE_BURST\x10\x19\x12\x1f\n\x1bFLAT_MODE_NIGHT_LAPSE_VIDEO\x10\x1a\x12\x13\n\x0fFLAT_MODE_SLOMO\x10\x1b\x12\x12\n\x0eFLAT_MODE_IDLE\x10\x1c\x12\x1e\n\x1aFLAT_MODE_VIDEO_STAR_TRAIL\x10\x1d\x12"\n\x1eFLAT_MODE_VIDEO_LIGHT_PAINTING\x10\x1e\x12\x1f\n\x1bFLAT_MODE_VIDEO_LIGHT_TRAIL\x10\x1f\x12\x1f\n\x1bFLAT_MODE_VIDEO_BURST_SLOMO\x10 *i\n\x0fEnumPresetGroup\x12\x1a\n\x15PRESET_GROUP_ID_VIDEO\x10\xe8\x07\x12\x1a\n\x15PRESET_GROUP_ID_PHOTO\x10\xe9\x07\x12\x1e\n\x19PRESET_GROUP_ID_TIMELAPSE\x10\xea\x07*\xb5\x03\n\x13EnumPresetGroupIcon\x12\x1e\n\x1aPRESET_GROUP_VIDEO_ICON_ID\x10\x00\x12\x1e\n\x1aPRESET_GROUP_PHOTO_ICON_ID\x10\x01\x12"\n\x1ePRESET_GROUP_TIMELAPSE_ICON_ID\x10\x02\x12\'\n#PRESET_GROUP_LONG_BAT_VIDEO_ICON_ID\x10\x03\x12(\n$PRESET_GROUP_ENDURANCE_VIDEO_ICON_ID\x10\x04\x12"\n\x1ePRESET_GROUP_MAX_VIDEO_ICON_ID\x10\x05\x12"\n\x1ePRESET_GROUP_MAX_PHOTO_ICON_ID\x10\x06\x12&\n"PRESET_GROUP_MAX_TIMELAPSE_ICON_ID\x10\x07\x12%\n!PRESET_GROUP_ND_MOD_VIDEO_ICON_ID\x10\x08\x12%\n!PRESET_GROUP_ND_MOD_PHOTO_ICON_ID\x10\t\x12)\n%PRESET_GROUP_ND_MOD_TIMELAPSE_ICON_ID\x10\n*\xff\x12\n\x0eEnumPresetIcon\x12\x15\n\x11PRESET_ICON_VIDEO\x10\x00\x12\x18\n\x14PRESET_ICON_ACTIVITY\x10\x01\x12\x19\n\x15PRESET_ICON_CINEMATIC\x10\x02\x12\x15\n\x11PRESET_ICON_PHOTO\x10\x03\x12\x1a\n\x16PRESET_ICON_LIVE_BURST\x10\x04\x12\x15\n\x11PRESET_ICON_BURST\x10\x05\x12\x1b\n\x17PRESET_ICON_PHOTO_NIGHT\x10\x06\x12\x18\n\x14PRESET_ICON_TIMEWARP\x10\x07\x12\x19\n\x15PRESET_ICON_TIMELAPSE\x10\x08\x12\x1a\n\x16PRESET_ICON_NIGHTLAPSE\x10\t\x12\x15\n\x11PRESET_ICON_SNAIL\x10\n\x12\x17\n\x13PRESET_ICON_VIDEO_2\x10\x0b\x12\x17\n\x13PRESET_ICON_PHOTO_2\x10\r\x12\x18\n\x14PRESET_ICON_PANORAMA\x10\x0e\x12\x17\n\x13PRESET_ICON_BURST_2\x10\x0f\x12\x1a\n\x16PRESET_ICON_TIMEWARP_2\x10\x10\x12\x1b\n\x17PRESET_ICON_TIMELAPSE_2\x10\x11\x12\x16\n\x12PRESET_ICON_CUSTOM\x10\x12\x12\x13\n\x0fPRESET_ICON_AIR\x10\x13\x12\x14\n\x10PRESET_ICON_BIKE\x10\x14\x12\x14\n\x10PRESET_ICON_EPIC\x10\x15\x12\x16\n\x12PRESET_ICON_INDOOR\x10\x16\x12\x15\n\x11PRESET_ICON_MOTOR\x10\x17\x12\x17\n\x13PRESET_ICON_MOUNTED\x10\x18\x12\x17\n\x13PRESET_ICON_OUTDOOR\x10\x19\x12\x13\n\x0fPRESET_ICON_POV\x10\x1a\x12\x16\n\x12PRESET_ICON_SELFIE\x10\x1b\x12\x15\n\x11PRESET_ICON_SKATE\x10\x1c\x12\x14\n\x10PRESET_ICON_SNOW\x10\x1d\x12\x15\n\x11PRESET_ICON_TRAIL\x10\x1e\x12\x16\n\x12PRESET_ICON_TRAVEL\x10\x1f\x12\x15\n\x11PRESET_ICON_WATER\x10 \x12\x17\n\x13PRESET_ICON_LOOPING\x10!\x12\x15\n\x11PRESET_ICON_STARS\x10"\x12\x16\n\x12PRESET_ICON_ACTION\x10#\x12\x1a\n\x16PRESET_ICON_FOLLOW_CAM\x10$\x12\x14\n\x10PRESET_ICON_SURF\x10%\x12\x14\n\x10PRESET_ICON_CITY\x10&\x12\x15\n\x11PRESET_ICON_SHAKY\x10\'\x12\x16\n\x12PRESET_ICON_CHESTY\x10(\x12\x16\n\x12PRESET_ICON_HELMET\x10)\x12\x14\n\x10PRESET_ICON_BITE\x10*\x12 \n\x1cPRESET_ICON_CUSTOM_CINEMATIC\x10+\x12\x14\n\x10PRESET_ICON_VLOG\x10,\x12\x13\n\x0fPRESET_ICON_FPV\x10-\x12\x13\n\x0fPRESET_ICON_HDR\x10.\x12\x19\n\x15PRESET_ICON_LANDSCAPE\x10/\x12\x13\n\x0fPRESET_ICON_LOG\x100\x12\x1c\n\x18PRESET_ICON_CUSTOM_SLOMO\x101\x12\x16\n\x12PRESET_ICON_TRIPOD\x102\x12\x19\n\x15PRESET_ICON_MAX_VIDEO\x107\x12\x19\n\x15PRESET_ICON_MAX_PHOTO\x108\x12\x1c\n\x18PRESET_ICON_MAX_TIMEWARP\x109\x12\x15\n\x11PRESET_ICON_BASIC\x10:\x12\x1c\n\x18PRESET_ICON_ULTRA_SLO_MO\x10;\x12"\n\x1ePRESET_ICON_STANDARD_ENDURANCE\x10<\x12"\n\x1ePRESET_ICON_ACTIVITY_ENDURANCE\x10=\x12#\n\x1fPRESET_ICON_CINEMATIC_ENDURANCE\x10>\x12\x1f\n\x1bPRESET_ICON_SLOMO_ENDURANCE\x10?\x12\x1c\n\x18PRESET_ICON_STATIONARY_1\x10@\x12\x1c\n\x18PRESET_ICON_STATIONARY_2\x10A\x12\x1c\n\x18PRESET_ICON_STATIONARY_3\x10B\x12\x1c\n\x18PRESET_ICON_STATIONARY_4\x10C\x12"\n\x1ePRESET_ICON_SIMPLE_SUPER_PHOTO\x10F\x12"\n\x1ePRESET_ICON_SIMPLE_NIGHT_PHOTO\x10G\x12%\n!PRESET_ICON_HIGHEST_QUALITY_VIDEO\x10I\x12&\n"PRESET_ICON_STANDARD_QUALITY_VIDEO\x10J\x12#\n\x1fPRESET_ICON_BASIC_QUALITY_VIDEO\x10K\x12\x1a\n\x16PRESET_ICON_STAR_TRAIL\x10L\x12\x1e\n\x1aPRESET_ICON_LIGHT_PAINTING\x10M\x12\x1b\n\x17PRESET_ICON_LIGHT_TRAIL\x10N\x12\x1a\n\x16PRESET_ICON_FULL_FRAME\x10O\x12\x1e\n\x1aPRESET_ICON_EASY_MAX_VIDEO\x10P\x12\x1e\n\x1aPRESET_ICON_EASY_MAX_PHOTO\x10Q\x12!\n\x1dPRESET_ICON_EASY_MAX_TIMEWARP\x10R\x12#\n\x1fPRESET_ICON_EASY_MAX_STAR_TRAIL\x10S\x12\'\n#PRESET_ICON_EASY_MAX_LIGHT_PAINTING\x10T\x12$\n PRESET_ICON_EASY_MAX_LIGHT_TRAIL\x10U\x12\x1e\n\x1aPRESET_ICON_MAX_STAR_TRAIL\x10Y\x12"\n\x1ePRESET_ICON_MAX_LIGHT_PAINTING\x10Z\x12\x1f\n\x1bPRESET_ICON_MAX_LIGHT_TRAIL\x10[\x12%\n!PRESET_ICON_EASY_STANDARD_PROFILE\x10d\x12 \n\x1cPRESET_ICON_EASY_HDR_PROFILE\x10e\x12\x1b\n\x17PRESET_ICON_BURST_SLOMO\x10f\x12 \n\x1bPRESET_ICON_TIMELAPSE_PHOTO\x10\xe8\x07\x12!\n\x1cPRESET_ICON_NIGHTLAPSE_PHOTO\x10\xe9\x07*\x9f\x13\n\x0fEnumPresetTitle\x12\x19\n\x15PRESET_TITLE_ACTIVITY\x10\x00\x12\x19\n\x15PRESET_TITLE_STANDARD\x10\x01\x12\x1a\n\x16PRESET_TITLE_CINEMATIC\x10\x02\x12\x16\n\x12PRESET_TITLE_PHOTO\x10\x03\x12\x1b\n\x17PRESET_TITLE_LIVE_BURST\x10\x04\x12\x16\n\x12PRESET_TITLE_BURST\x10\x05\x12\x16\n\x12PRESET_TITLE_NIGHT\x10\x06\x12\x1a\n\x16PRESET_TITLE_TIME_WARP\x10\x07\x12\x1b\n\x17PRESET_TITLE_TIME_LAPSE\x10\x08\x12\x1c\n\x18PRESET_TITLE_NIGHT_LAPSE\x10\t\x12\x16\n\x12PRESET_TITLE_VIDEO\x10\n\x12\x16\n\x12PRESET_TITLE_SLOMO\x10\x0b\x12\x18\n\x14PRESET_TITLE_PHOTO_2\x10\r\x12\x19\n\x15PRESET_TITLE_PANORAMA\x10\x0e\x12\x1c\n\x18PRESET_TITLE_TIME_WARP_2\x10\x10\x12\x17\n\x13PRESET_TITLE_CUSTOM\x10\x12\x12\x14\n\x10PRESET_TITLE_AIR\x10\x13\x12\x15\n\x11PRESET_TITLE_BIKE\x10\x14\x12\x15\n\x11PRESET_TITLE_EPIC\x10\x15\x12\x17\n\x13PRESET_TITLE_INDOOR\x10\x16\x12\x16\n\x12PRESET_TITLE_MOTOR\x10\x17\x12\x18\n\x14PRESET_TITLE_MOUNTED\x10\x18\x12\x18\n\x14PRESET_TITLE_OUTDOOR\x10\x19\x12\x14\n\x10PRESET_TITLE_POV\x10\x1a\x12\x17\n\x13PRESET_TITLE_SELFIE\x10\x1b\x12\x16\n\x12PRESET_TITLE_SKATE\x10\x1c\x12\x15\n\x11PRESET_TITLE_SNOW\x10\x1d\x12\x16\n\x12PRESET_TITLE_TRAIL\x10\x1e\x12\x17\n\x13PRESET_TITLE_TRAVEL\x10\x1f\x12\x16\n\x12PRESET_TITLE_WATER\x10 \x12\x18\n\x14PRESET_TITLE_LOOPING\x10!\x12\x16\n\x12PRESET_TITLE_STARS\x10"\x12\x17\n\x13PRESET_TITLE_ACTION\x10#\x12\x1b\n\x17PRESET_TITLE_FOLLOW_CAM\x10$\x12\x15\n\x11PRESET_TITLE_SURF\x10%\x12\x15\n\x11PRESET_TITLE_CITY\x10&\x12\x16\n\x12PRESET_TITLE_SHAKY\x10\'\x12\x17\n\x13PRESET_TITLE_CHESTY\x10(\x12\x17\n\x13PRESET_TITLE_HELMET\x10)\x12\x15\n\x11PRESET_TITLE_BITE\x10*\x12!\n\x1dPRESET_TITLE_CUSTOM_CINEMATIC\x10+\x12\x15\n\x11PRESET_TITLE_VLOG\x10,\x12\x14\n\x10PRESET_TITLE_FPV\x10-\x12\x14\n\x10PRESET_TITLE_HDR\x10.\x12\x1a\n\x16PRESET_TITLE_LANDSCAPE\x10/\x12\x14\n\x10PRESET_TITLE_LOG\x100\x12\x1d\n\x19PRESET_TITLE_CUSTOM_SLOMO\x101\x12\x17\n\x13PRESET_TITLE_TRIPOD\x102\x12\x16\n\x12PRESET_TITLE_BASIC\x10:\x12\x1d\n\x19PRESET_TITLE_ULTRA_SLO_MO\x10;\x12#\n\x1fPRESET_TITLE_STANDARD_ENDURANCE\x10<\x12#\n\x1fPRESET_TITLE_ACTIVITY_ENDURANCE\x10=\x12$\n PRESET_TITLE_CINEMATIC_ENDURANCE\x10>\x12 \n\x1cPRESET_TITLE_SLOMO_ENDURANCE\x10?\x12\x1d\n\x19PRESET_TITLE_STATIONARY_1\x10@\x12\x1d\n\x19PRESET_TITLE_STATIONARY_2\x10A\x12\x1d\n\x19PRESET_TITLE_STATIONARY_3\x10B\x12\x1d\n\x19PRESET_TITLE_STATIONARY_4\x10C\x12\x1d\n\x19PRESET_TITLE_SIMPLE_VIDEO\x10D\x12!\n\x1dPRESET_TITLE_SIMPLE_TIME_WARP\x10E\x12#\n\x1fPRESET_TITLE_SIMPLE_SUPER_PHOTO\x10F\x12#\n\x1fPRESET_TITLE_SIMPLE_NIGHT_PHOTO\x10G\x12\'\n#PRESET_TITLE_SIMPLE_VIDEO_ENDURANCE\x10H\x12 \n\x1cPRESET_TITLE_HIGHEST_QUALITY\x10I\x12!\n\x1dPRESET_TITLE_EXTENDED_BATTERY\x10J\x12 \n\x1cPRESET_TITLE_LONGEST_BATTERY\x10K\x12\x1b\n\x17PRESET_TITLE_STAR_TRAIL\x10L\x12\x1f\n\x1bPRESET_TITLE_LIGHT_PAINTING\x10M\x12\x1c\n\x18PRESET_TITLE_LIGHT_TRAIL\x10N\x12\x1b\n\x17PRESET_TITLE_FULL_FRAME\x10O\x12\'\n#PRESET_TITLE_STANDARD_QUALITY_VIDEO\x10R\x12$\n PRESET_TITLE_BASIC_QUALITY_VIDEO\x10S\x12&\n"PRESET_TITLE_HIGHEST_QUALITY_VIDEO\x10]\x12)\n%PRESET_TITLE_USER_DEFINED_CUSTOM_NAME\x10^\x12&\n"PRESET_TITLE_EASY_STANDARD_PROFILE\x10c\x12!\n\x1dPRESET_TITLE_EASY_HDR_PROFILE\x10d\x12\x1c\n\x18PRESET_TITLE_BURST_SLOMO\x10j\x12\x1a\n\x16PRESET_TITLE_4_3_VIDEO\x10}\x12\x1b\n\x17PRESET_TITLE_16_9_VIDEO\x10~\x12\x1b\n\x17PRESET_TITLE_16_9_SLOMO\x10\x7f\x12"\n\x1dPRESET_TITLE_TIME_LAPSE_VIDEO\x10\x83\x01\x12"\n\x1dPRESET_TITLE_TIME_LAPSE_PHOTO\x10\x84\x01\x12#\n\x1ePRESET_TITLE_NIGHT_LAPSE_VIDEO\x10\x85\x01\x12#\n\x1ePRESET_TITLE_NIGHT_LAPSE_PHOTO\x10\x86\x01' + b'\n\x13preset_status.proto\x12\nopen_gopro\x1a\x16response_generic.proto"I\n\x12NotifyPresetStatus\x123\n\x12preset_group_array\x18\x01 \x03(\x0b2\x17.open_gopro.PresetGroup"\xc3\x02\n\x06Preset\x12\n\n\x02id\x18\x01 \x01(\x05\x12&\n\x04mode\x18\x02 \x01(\x0e2\x18.open_gopro.EnumFlatMode\x12-\n\x08title_id\x18\x03 \x01(\x0e2\x1b.open_gopro.EnumPresetTitle\x12\x14\n\x0ctitle_number\x18\x04 \x01(\x05\x12\x14\n\x0cuser_defined\x18\x05 \x01(\x08\x12(\n\x04icon\x18\x06 \x01(\x0e2\x1a.open_gopro.EnumPresetIcon\x120\n\rsetting_array\x18\x07 \x03(\x0b2\x19.open_gopro.PresetSetting\x12\x13\n\x0bis_modified\x18\x08 \x01(\x08\x12\x10\n\x08is_fixed\x18\t \x01(\x08\x12\x13\n\x0bcustom_name\x18\n \x01(\t\x12\x12\n\nis_visible\x18\x0b \x01(\x08"\x8c\x01\n\x19RequestCustomPresetUpdate\x12-\n\x08title_id\x18\x01 \x01(\x0e2\x1b.open_gopro.EnumPresetTitle\x12\x13\n\x0bcustom_name\x18\x02 \x01(\t\x12+\n\x07icon_id\x18\x03 \x01(\x0e2\x1a.open_gopro.EnumPresetIcon"9\n\x1aRequestPresetSetVisibility\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x0f\n\x07visible\x18\x02 \x01(\x08"\x84\x02\n\x0bPresetGroup\x12\'\n\x02id\x18\x01 \x01(\x0e2\x1b.open_gopro.EnumPresetGroup\x12(\n\x0cpreset_array\x18\x02 \x03(\x0b2\x12.open_gopro.Preset\x12\x16\n\x0ecan_add_preset\x18\x03 \x01(\x08\x12-\n\x04icon\x18\x04 \x01(\x0e2\x1f.open_gopro.EnumPresetGroupIcon\x12,\n\nmode_array\x18\x05 \x03(\x0e2\x18.open_gopro.EnumFlatMode\x12\x13\n\x0bcustom_name\x18\x06 \x01(\t\x12\x18\n\x10active_preset_id\x18\x07 \x01(\x05">\n\rPresetSetting\x12\n\n\x02id\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x05\x12\x12\n\nis_caption\x18\x03 \x01(\x08*\x9b\x05\n\x0cEnumFlatMode\x12\x1e\n\x11FLAT_MODE_UNKNOWN\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x12\x16\n\x12FLAT_MODE_PLAYBACK\x10\x04\x12\x13\n\x0fFLAT_MODE_SETUP\x10\x05\x12\x13\n\x0fFLAT_MODE_VIDEO\x10\x0c\x12\x1e\n\x1aFLAT_MODE_TIME_LAPSE_VIDEO\x10\r\x12\x15\n\x11FLAT_MODE_LOOPING\x10\x0f\x12\x1a\n\x16FLAT_MODE_PHOTO_SINGLE\x10\x10\x12\x13\n\x0fFLAT_MODE_PHOTO\x10\x11\x12\x19\n\x15FLAT_MODE_PHOTO_NIGHT\x10\x12\x12\x19\n\x15FLAT_MODE_PHOTO_BURST\x10\x13\x12\x1e\n\x1aFLAT_MODE_TIME_LAPSE_PHOTO\x10\x14\x12\x1f\n\x1bFLAT_MODE_NIGHT_LAPSE_PHOTO\x10\x15\x12\x1e\n\x1aFLAT_MODE_BROADCAST_RECORD\x10\x16\x12!\n\x1dFLAT_MODE_BROADCAST_BROADCAST\x10\x17\x12\x1d\n\x19FLAT_MODE_TIME_WARP_VIDEO\x10\x18\x12\x18\n\x14FLAT_MODE_LIVE_BURST\x10\x19\x12\x1f\n\x1bFLAT_MODE_NIGHT_LAPSE_VIDEO\x10\x1a\x12\x13\n\x0fFLAT_MODE_SLOMO\x10\x1b\x12\x12\n\x0eFLAT_MODE_IDLE\x10\x1c\x12\x1e\n\x1aFLAT_MODE_VIDEO_STAR_TRAIL\x10\x1d\x12"\n\x1eFLAT_MODE_VIDEO_LIGHT_PAINTING\x10\x1e\x12\x1f\n\x1bFLAT_MODE_VIDEO_LIGHT_TRAIL\x10\x1f\x12\x1f\n\x1bFLAT_MODE_VIDEO_BURST_SLOMO\x10 *\x87\x01\n\x0fEnumPresetGroup\x12\x1a\n\x15PRESET_GROUP_ID_VIDEO\x10\xe8\x07\x12\x1a\n\x15PRESET_GROUP_ID_PHOTO\x10\xe9\x07\x12\x1e\n\x19PRESET_GROUP_ID_TIMELAPSE\x10\xea\x07\x12\x1c\n\x17PRESET_GROUP_ID_GENERAL\x10\xd0\x0f*\xb5\x03\n\x13EnumPresetGroupIcon\x12\x1e\n\x1aPRESET_GROUP_VIDEO_ICON_ID\x10\x00\x12\x1e\n\x1aPRESET_GROUP_PHOTO_ICON_ID\x10\x01\x12"\n\x1ePRESET_GROUP_TIMELAPSE_ICON_ID\x10\x02\x12\'\n#PRESET_GROUP_LONG_BAT_VIDEO_ICON_ID\x10\x03\x12(\n$PRESET_GROUP_ENDURANCE_VIDEO_ICON_ID\x10\x04\x12"\n\x1ePRESET_GROUP_MAX_VIDEO_ICON_ID\x10\x05\x12"\n\x1ePRESET_GROUP_MAX_PHOTO_ICON_ID\x10\x06\x12&\n"PRESET_GROUP_MAX_TIMELAPSE_ICON_ID\x10\x07\x12%\n!PRESET_GROUP_ND_MOD_VIDEO_ICON_ID\x10\x08\x12%\n!PRESET_GROUP_ND_MOD_PHOTO_ICON_ID\x10\t\x12)\n%PRESET_GROUP_ND_MOD_TIMELAPSE_ICON_ID\x10\n*\xff\x12\n\x0eEnumPresetIcon\x12\x15\n\x11PRESET_ICON_VIDEO\x10\x00\x12\x18\n\x14PRESET_ICON_ACTIVITY\x10\x01\x12\x19\n\x15PRESET_ICON_CINEMATIC\x10\x02\x12\x15\n\x11PRESET_ICON_PHOTO\x10\x03\x12\x1a\n\x16PRESET_ICON_LIVE_BURST\x10\x04\x12\x15\n\x11PRESET_ICON_BURST\x10\x05\x12\x1b\n\x17PRESET_ICON_PHOTO_NIGHT\x10\x06\x12\x18\n\x14PRESET_ICON_TIMEWARP\x10\x07\x12\x19\n\x15PRESET_ICON_TIMELAPSE\x10\x08\x12\x1a\n\x16PRESET_ICON_NIGHTLAPSE\x10\t\x12\x15\n\x11PRESET_ICON_SNAIL\x10\n\x12\x17\n\x13PRESET_ICON_VIDEO_2\x10\x0b\x12\x17\n\x13PRESET_ICON_PHOTO_2\x10\r\x12\x18\n\x14PRESET_ICON_PANORAMA\x10\x0e\x12\x17\n\x13PRESET_ICON_BURST_2\x10\x0f\x12\x1a\n\x16PRESET_ICON_TIMEWARP_2\x10\x10\x12\x1b\n\x17PRESET_ICON_TIMELAPSE_2\x10\x11\x12\x16\n\x12PRESET_ICON_CUSTOM\x10\x12\x12\x13\n\x0fPRESET_ICON_AIR\x10\x13\x12\x14\n\x10PRESET_ICON_BIKE\x10\x14\x12\x14\n\x10PRESET_ICON_EPIC\x10\x15\x12\x16\n\x12PRESET_ICON_INDOOR\x10\x16\x12\x15\n\x11PRESET_ICON_MOTOR\x10\x17\x12\x17\n\x13PRESET_ICON_MOUNTED\x10\x18\x12\x17\n\x13PRESET_ICON_OUTDOOR\x10\x19\x12\x13\n\x0fPRESET_ICON_POV\x10\x1a\x12\x16\n\x12PRESET_ICON_SELFIE\x10\x1b\x12\x15\n\x11PRESET_ICON_SKATE\x10\x1c\x12\x14\n\x10PRESET_ICON_SNOW\x10\x1d\x12\x15\n\x11PRESET_ICON_TRAIL\x10\x1e\x12\x16\n\x12PRESET_ICON_TRAVEL\x10\x1f\x12\x15\n\x11PRESET_ICON_WATER\x10 \x12\x17\n\x13PRESET_ICON_LOOPING\x10!\x12\x15\n\x11PRESET_ICON_STARS\x10"\x12\x16\n\x12PRESET_ICON_ACTION\x10#\x12\x1a\n\x16PRESET_ICON_FOLLOW_CAM\x10$\x12\x14\n\x10PRESET_ICON_SURF\x10%\x12\x14\n\x10PRESET_ICON_CITY\x10&\x12\x15\n\x11PRESET_ICON_SHAKY\x10\'\x12\x16\n\x12PRESET_ICON_CHESTY\x10(\x12\x16\n\x12PRESET_ICON_HELMET\x10)\x12\x14\n\x10PRESET_ICON_BITE\x10*\x12 \n\x1cPRESET_ICON_CUSTOM_CINEMATIC\x10+\x12\x14\n\x10PRESET_ICON_VLOG\x10,\x12\x13\n\x0fPRESET_ICON_FPV\x10-\x12\x13\n\x0fPRESET_ICON_HDR\x10.\x12\x19\n\x15PRESET_ICON_LANDSCAPE\x10/\x12\x13\n\x0fPRESET_ICON_LOG\x100\x12\x1c\n\x18PRESET_ICON_CUSTOM_SLOMO\x101\x12\x16\n\x12PRESET_ICON_TRIPOD\x102\x12\x19\n\x15PRESET_ICON_MAX_VIDEO\x107\x12\x19\n\x15PRESET_ICON_MAX_PHOTO\x108\x12\x1c\n\x18PRESET_ICON_MAX_TIMEWARP\x109\x12\x15\n\x11PRESET_ICON_BASIC\x10:\x12\x1c\n\x18PRESET_ICON_ULTRA_SLO_MO\x10;\x12"\n\x1ePRESET_ICON_STANDARD_ENDURANCE\x10<\x12"\n\x1ePRESET_ICON_ACTIVITY_ENDURANCE\x10=\x12#\n\x1fPRESET_ICON_CINEMATIC_ENDURANCE\x10>\x12\x1f\n\x1bPRESET_ICON_SLOMO_ENDURANCE\x10?\x12\x1c\n\x18PRESET_ICON_STATIONARY_1\x10@\x12\x1c\n\x18PRESET_ICON_STATIONARY_2\x10A\x12\x1c\n\x18PRESET_ICON_STATIONARY_3\x10B\x12\x1c\n\x18PRESET_ICON_STATIONARY_4\x10C\x12"\n\x1ePRESET_ICON_SIMPLE_SUPER_PHOTO\x10F\x12"\n\x1ePRESET_ICON_SIMPLE_NIGHT_PHOTO\x10G\x12%\n!PRESET_ICON_HIGHEST_QUALITY_VIDEO\x10I\x12&\n"PRESET_ICON_STANDARD_QUALITY_VIDEO\x10J\x12#\n\x1fPRESET_ICON_BASIC_QUALITY_VIDEO\x10K\x12\x1a\n\x16PRESET_ICON_STAR_TRAIL\x10L\x12\x1e\n\x1aPRESET_ICON_LIGHT_PAINTING\x10M\x12\x1b\n\x17PRESET_ICON_LIGHT_TRAIL\x10N\x12\x1a\n\x16PRESET_ICON_FULL_FRAME\x10O\x12\x1e\n\x1aPRESET_ICON_EASY_MAX_VIDEO\x10P\x12\x1e\n\x1aPRESET_ICON_EASY_MAX_PHOTO\x10Q\x12!\n\x1dPRESET_ICON_EASY_MAX_TIMEWARP\x10R\x12#\n\x1fPRESET_ICON_EASY_MAX_STAR_TRAIL\x10S\x12\'\n#PRESET_ICON_EASY_MAX_LIGHT_PAINTING\x10T\x12$\n PRESET_ICON_EASY_MAX_LIGHT_TRAIL\x10U\x12\x1e\n\x1aPRESET_ICON_MAX_STAR_TRAIL\x10Y\x12"\n\x1ePRESET_ICON_MAX_LIGHT_PAINTING\x10Z\x12\x1f\n\x1bPRESET_ICON_MAX_LIGHT_TRAIL\x10[\x12%\n!PRESET_ICON_EASY_STANDARD_PROFILE\x10d\x12 \n\x1cPRESET_ICON_EASY_HDR_PROFILE\x10e\x12\x1b\n\x17PRESET_ICON_BURST_SLOMO\x10f\x12 \n\x1bPRESET_ICON_TIMELAPSE_PHOTO\x10\xe8\x07\x12!\n\x1cPRESET_ICON_NIGHTLAPSE_PHOTO\x10\xe9\x07*\x9f\x13\n\x0fEnumPresetTitle\x12\x19\n\x15PRESET_TITLE_ACTIVITY\x10\x00\x12\x19\n\x15PRESET_TITLE_STANDARD\x10\x01\x12\x1a\n\x16PRESET_TITLE_CINEMATIC\x10\x02\x12\x16\n\x12PRESET_TITLE_PHOTO\x10\x03\x12\x1b\n\x17PRESET_TITLE_LIVE_BURST\x10\x04\x12\x16\n\x12PRESET_TITLE_BURST\x10\x05\x12\x16\n\x12PRESET_TITLE_NIGHT\x10\x06\x12\x1a\n\x16PRESET_TITLE_TIME_WARP\x10\x07\x12\x1b\n\x17PRESET_TITLE_TIME_LAPSE\x10\x08\x12\x1c\n\x18PRESET_TITLE_NIGHT_LAPSE\x10\t\x12\x16\n\x12PRESET_TITLE_VIDEO\x10\n\x12\x16\n\x12PRESET_TITLE_SLOMO\x10\x0b\x12\x18\n\x14PRESET_TITLE_PHOTO_2\x10\r\x12\x19\n\x15PRESET_TITLE_PANORAMA\x10\x0e\x12\x1c\n\x18PRESET_TITLE_TIME_WARP_2\x10\x10\x12\x17\n\x13PRESET_TITLE_CUSTOM\x10\x12\x12\x14\n\x10PRESET_TITLE_AIR\x10\x13\x12\x15\n\x11PRESET_TITLE_BIKE\x10\x14\x12\x15\n\x11PRESET_TITLE_EPIC\x10\x15\x12\x17\n\x13PRESET_TITLE_INDOOR\x10\x16\x12\x16\n\x12PRESET_TITLE_MOTOR\x10\x17\x12\x18\n\x14PRESET_TITLE_MOUNTED\x10\x18\x12\x18\n\x14PRESET_TITLE_OUTDOOR\x10\x19\x12\x14\n\x10PRESET_TITLE_POV\x10\x1a\x12\x17\n\x13PRESET_TITLE_SELFIE\x10\x1b\x12\x16\n\x12PRESET_TITLE_SKATE\x10\x1c\x12\x15\n\x11PRESET_TITLE_SNOW\x10\x1d\x12\x16\n\x12PRESET_TITLE_TRAIL\x10\x1e\x12\x17\n\x13PRESET_TITLE_TRAVEL\x10\x1f\x12\x16\n\x12PRESET_TITLE_WATER\x10 \x12\x18\n\x14PRESET_TITLE_LOOPING\x10!\x12\x16\n\x12PRESET_TITLE_STARS\x10"\x12\x17\n\x13PRESET_TITLE_ACTION\x10#\x12\x1b\n\x17PRESET_TITLE_FOLLOW_CAM\x10$\x12\x15\n\x11PRESET_TITLE_SURF\x10%\x12\x15\n\x11PRESET_TITLE_CITY\x10&\x12\x16\n\x12PRESET_TITLE_SHAKY\x10\'\x12\x17\n\x13PRESET_TITLE_CHESTY\x10(\x12\x17\n\x13PRESET_TITLE_HELMET\x10)\x12\x15\n\x11PRESET_TITLE_BITE\x10*\x12!\n\x1dPRESET_TITLE_CUSTOM_CINEMATIC\x10+\x12\x15\n\x11PRESET_TITLE_VLOG\x10,\x12\x14\n\x10PRESET_TITLE_FPV\x10-\x12\x14\n\x10PRESET_TITLE_HDR\x10.\x12\x1a\n\x16PRESET_TITLE_LANDSCAPE\x10/\x12\x14\n\x10PRESET_TITLE_LOG\x100\x12\x1d\n\x19PRESET_TITLE_CUSTOM_SLOMO\x101\x12\x17\n\x13PRESET_TITLE_TRIPOD\x102\x12\x16\n\x12PRESET_TITLE_BASIC\x10:\x12\x1d\n\x19PRESET_TITLE_ULTRA_SLO_MO\x10;\x12#\n\x1fPRESET_TITLE_STANDARD_ENDURANCE\x10<\x12#\n\x1fPRESET_TITLE_ACTIVITY_ENDURANCE\x10=\x12$\n PRESET_TITLE_CINEMATIC_ENDURANCE\x10>\x12 \n\x1cPRESET_TITLE_SLOMO_ENDURANCE\x10?\x12\x1d\n\x19PRESET_TITLE_STATIONARY_1\x10@\x12\x1d\n\x19PRESET_TITLE_STATIONARY_2\x10A\x12\x1d\n\x19PRESET_TITLE_STATIONARY_3\x10B\x12\x1d\n\x19PRESET_TITLE_STATIONARY_4\x10C\x12\x1d\n\x19PRESET_TITLE_SIMPLE_VIDEO\x10D\x12!\n\x1dPRESET_TITLE_SIMPLE_TIME_WARP\x10E\x12#\n\x1fPRESET_TITLE_SIMPLE_SUPER_PHOTO\x10F\x12#\n\x1fPRESET_TITLE_SIMPLE_NIGHT_PHOTO\x10G\x12\'\n#PRESET_TITLE_SIMPLE_VIDEO_ENDURANCE\x10H\x12 \n\x1cPRESET_TITLE_HIGHEST_QUALITY\x10I\x12!\n\x1dPRESET_TITLE_EXTENDED_BATTERY\x10J\x12 \n\x1cPRESET_TITLE_LONGEST_BATTERY\x10K\x12\x1b\n\x17PRESET_TITLE_STAR_TRAIL\x10L\x12\x1f\n\x1bPRESET_TITLE_LIGHT_PAINTING\x10M\x12\x1c\n\x18PRESET_TITLE_LIGHT_TRAIL\x10N\x12\x1b\n\x17PRESET_TITLE_FULL_FRAME\x10O\x12\'\n#PRESET_TITLE_STANDARD_QUALITY_VIDEO\x10R\x12$\n PRESET_TITLE_BASIC_QUALITY_VIDEO\x10S\x12&\n"PRESET_TITLE_HIGHEST_QUALITY_VIDEO\x10]\x12)\n%PRESET_TITLE_USER_DEFINED_CUSTOM_NAME\x10^\x12&\n"PRESET_TITLE_EASY_STANDARD_PROFILE\x10c\x12!\n\x1dPRESET_TITLE_EASY_HDR_PROFILE\x10d\x12\x1c\n\x18PRESET_TITLE_BURST_SLOMO\x10j\x12\x1a\n\x16PRESET_TITLE_4_3_VIDEO\x10}\x12\x1b\n\x17PRESET_TITLE_16_9_VIDEO\x10~\x12\x1b\n\x17PRESET_TITLE_16_9_SLOMO\x10\x7f\x12"\n\x1dPRESET_TITLE_TIME_LAPSE_VIDEO\x10\x83\x01\x12"\n\x1dPRESET_TITLE_TIME_LAPSE_PHOTO\x10\x84\x01\x12#\n\x1ePRESET_TITLE_NIGHT_LAPSE_VIDEO\x10\x85\x01\x12#\n\x1ePRESET_TITLE_NIGHT_LAPSE_PHOTO\x10\x86\x01' ) _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "preset_status_pb2", globals()) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None - _ENUMFLATMODE._serialized_start = 943 - _ENUMFLATMODE._serialized_end = 1610 - _ENUMPRESETGROUP._serialized_start = 1612 - _ENUMPRESETGROUP._serialized_end = 1717 - _ENUMPRESETGROUPICON._serialized_start = 1720 - _ENUMPRESETGROUPICON._serialized_end = 2157 - _ENUMPRESETICON._serialized_start = 2160 - _ENUMPRESETICON._serialized_end = 4591 - _ENUMPRESETTITLE._serialized_start = 4594 - _ENUMPRESETTITLE._serialized_end = 7057 + _ENUMFLATMODE._serialized_start = 990 + _ENUMFLATMODE._serialized_end = 1657 + _ENUMPRESETGROUP._serialized_start = 1660 + _ENUMPRESETGROUP._serialized_end = 1795 + _ENUMPRESETGROUPICON._serialized_start = 1798 + _ENUMPRESETGROUPICON._serialized_end = 2235 + _ENUMPRESETICON._serialized_start = 2238 + _ENUMPRESETICON._serialized_end = 4669 + _ENUMPRESETTITLE._serialized_start = 4672 + _ENUMPRESETTITLE._serialized_end = 7135 _NOTIFYPRESETSTATUS._serialized_start = 59 _NOTIFYPRESETSTATUS._serialized_end = 132 _PRESET._serialized_start = 135 @@ -37,6 +34,6 @@ _REQUESTPRESETSETVISIBILITY._serialized_start = 603 _REQUESTPRESETSETVISIBILITY._serialized_end = 660 _PRESETGROUP._serialized_start = 663 - _PRESETGROUP._serialized_end = 876 - _PRESETSETTING._serialized_start = 878 - _PRESETSETTING._serialized_end = 940 + _PRESETGROUP._serialized_end = 923 + _PRESETSETTING._serialized_start = 925 + _PRESETSETTING._serialized_end = 987 diff --git a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/preset_status_pb2.pyi b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/preset_status_pb2.pyi index 79fd75f81..5e4ddc7a1 100644 --- a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/preset_status_pb2.pyi +++ b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/preset_status_pb2.pyi @@ -90,12 +90,14 @@ class _EnumPresetGroupEnumTypeWrapper( PRESET_GROUP_ID_VIDEO: _EnumPresetGroup.ValueType PRESET_GROUP_ID_PHOTO: _EnumPresetGroup.ValueType PRESET_GROUP_ID_TIMELAPSE: _EnumPresetGroup.ValueType + PRESET_GROUP_ID_GENERAL: _EnumPresetGroup.ValueType class EnumPresetGroup(_EnumPresetGroup, metaclass=_EnumPresetGroupEnumTypeWrapper): ... PRESET_GROUP_ID_VIDEO: EnumPresetGroup.ValueType PRESET_GROUP_ID_PHOTO: EnumPresetGroup.ValueType PRESET_GROUP_ID_TIMELAPSE: EnumPresetGroup.ValueType +PRESET_GROUP_ID_GENERAL: EnumPresetGroup.ValueType global___EnumPresetGroup = EnumPresetGroup class _EnumPresetGroupIcon: @@ -736,6 +738,8 @@ class PresetGroup(google.protobuf.message.Message): CAN_ADD_PRESET_FIELD_NUMBER: builtins.int ICON_FIELD_NUMBER: builtins.int MODE_ARRAY_FIELD_NUMBER: builtins.int + CUSTOM_NAME_FIELD_NUMBER: builtins.int + ACTIVE_PRESET_ID_FIELD_NUMBER: builtins.int id: global___EnumPresetGroup.ValueType "Preset Group ID" @@ -752,6 +756,10 @@ class PresetGroup(google.protobuf.message.Message): self, ) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[global___EnumFlatMode.ValueType]: """A list of flatmodes available for this preset group""" + custom_name: builtins.str + "Custom string name given to this preset group" + active_preset_id: builtins.int + "Active preset id in this group" def __init__( self, @@ -760,16 +768,34 @@ class PresetGroup(google.protobuf.message.Message): preset_array: collections.abc.Iterable[global___Preset] | None = ..., can_add_preset: builtins.bool | None = ..., icon: global___EnumPresetGroupIcon.ValueType | None = ..., - mode_array: collections.abc.Iterable[global___EnumFlatMode.ValueType] | None = ... + mode_array: collections.abc.Iterable[global___EnumFlatMode.ValueType] | None = ..., + custom_name: builtins.str | None = ..., + active_preset_id: builtins.int | None = ... ) -> None: ... def HasField( - self, field_name: typing_extensions.Literal["can_add_preset", b"can_add_preset", "icon", b"icon", "id", b"id"] + self, + field_name: typing_extensions.Literal[ + "active_preset_id", + b"active_preset_id", + "can_add_preset", + b"can_add_preset", + "custom_name", + b"custom_name", + "icon", + b"icon", + "id", + b"id", + ], ) -> builtins.bool: ... def ClearField( self, field_name: typing_extensions.Literal[ + "active_preset_id", + b"active_preset_id", "can_add_preset", b"can_add_preset", + "custom_name", + b"custom_name", "icon", b"icon", "id", diff --git a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/request_get_camera_capabilities_pb2.py b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/request_get_camera_capabilities_pb2.py new file mode 100644 index 000000000..7a2149225 --- /dev/null +++ b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/request_get_camera_capabilities_pb2.py @@ -0,0 +1,23 @@ +"""Generated protocol buffer code.""" + +from google.protobuf.internal import builder as _builder +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database + +_sym_db = _symbol_database.Default() +from . import response_generic_pb2 as response__generic__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n%request_get_camera_capabilities.proto\x12\nopen_gopro\x1a\x16response_generic.proto"\x1e\n\x1cRequestGetCameraCapabilities"\x9a\x01\n\x1dResponseGetCameraCapabilities\x12-\n\x06result\x18\x01 \x02(\x0e2\x1d.open_gopro.EnumResultGeneric\x12\x16\n\x0eschema_version\x18\x02 \x02(\t\x122\n\x08protocol\x18\x03 \x01(\x0b2 .open_gopro.ProtocolCapabilities"9\n\x14ProtocolCapabilities\x12!\n\x12supports_2byte_ids\x18\x01 \x01(\x08:\x05false' +) +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "request_get_camera_capabilities_pb2", globals()) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + _REQUESTGETCAMERACAPABILITIES._serialized_start = 77 + _REQUESTGETCAMERACAPABILITIES._serialized_end = 107 + _RESPONSEGETCAMERACAPABILITIES._serialized_start = 110 + _RESPONSEGETCAMERACAPABILITIES._serialized_end = 264 + _PROTOCOLCAPABILITIES._serialized_start = 266 + _PROTOCOLCAPABILITIES._serialized_end = 323 diff --git a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/request_get_camera_capabilities_pb2.pyi b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/request_get_camera_capabilities_pb2.pyi new file mode 100644 index 000000000..3e67e343c --- /dev/null +++ b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/request_get_camera_capabilities_pb2.pyi @@ -0,0 +1,96 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +* +Defines the structure of protobuf messages for querying camera capabilities +""" + +import builtins +import google.protobuf.descriptor +import google.protobuf.message +from . import response_generic_pb2 +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class RequestGetCameraCapabilities(google.protobuf.message.Message): + """* + Get the camera capabilities + + Returns a @ref ResponseGetCameraCapabilities + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + def __init__(self) -> None: ... + +global___RequestGetCameraCapabilities = RequestGetCameraCapabilities + +@typing_extensions.final +class ResponseGetCameraCapabilities(google.protobuf.message.Message): + """* + Camera Capabilities + + Message is sent in response to a @ref RequestGetCameraCapabilities. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + RESULT_FIELD_NUMBER: builtins.int + SCHEMA_VERSION_FIELD_NUMBER: builtins.int + PROTOCOL_FIELD_NUMBER: builtins.int + result: response_generic_pb2.EnumResultGeneric.ValueType + "Generic pass/fail/error info" + schema_version: builtins.str + 'Capability schema version (e.g., "camera-capabilities/v1.0")' + + @property + def protocol(self) -> global___ProtocolCapabilities: + """Protocol-level capabilities""" + + def __init__( + self, + *, + result: response_generic_pb2.EnumResultGeneric.ValueType | None = ..., + schema_version: builtins.str | None = ..., + protocol: global___ProtocolCapabilities | None = ... + ) -> None: ... + def HasField( + self, + field_name: typing_extensions.Literal[ + "protocol", b"protocol", "result", b"result", "schema_version", b"schema_version" + ], + ) -> builtins.bool: ... + def ClearField( + self, + field_name: typing_extensions.Literal[ + "protocol", b"protocol", "result", b"result", "schema_version", b"schema_version" + ], + ) -> None: ... + +global___ResponseGetCameraCapabilities = ResponseGetCameraCapabilities + +@typing_extensions.final +class ProtocolCapabilities(google.protobuf.message.Message): + """* + Protocol capability information + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + SUPPORTS_2BYTE_IDS_FIELD_NUMBER: builtins.int + supports_2byte_ids: builtins.bool + "Does the camera support 2-byte setting/status IDs" + + def __init__(self, *, supports_2byte_ids: builtins.bool | None = ...) -> None: ... + def HasField( + self, field_name: typing_extensions.Literal["supports_2byte_ids", b"supports_2byte_ids"] + ) -> builtins.bool: ... + def ClearField( + self, field_name: typing_extensions.Literal["supports_2byte_ids", b"supports_2byte_ids"] + ) -> None: ... + +global___ProtocolCapabilities = ProtocolCapabilities diff --git a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/request_get_preset_status_pb2.py b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/request_get_preset_status_pb2.py index ae8932c6d..a9ebdf87f 100644 --- a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/request_get_preset_status_pb2.py +++ b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/request_get_preset_status_pb2.py @@ -1,6 +1,3 @@ -# request_get_preset_status_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:47 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf.internal import builder as _builder diff --git a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/response_generic_pb2.py b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/response_generic_pb2.py index 69ec37033..7af4a3e16 100644 --- a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/response_generic_pb2.py +++ b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/response_generic_pb2.py @@ -1,6 +1,3 @@ -# response_generic_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:47 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf.internal import builder as _builder diff --git a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/set_camera_control_status_pb2.py b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/set_camera_control_status_pb2.py index f688608b5..071d5595f 100644 --- a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/set_camera_control_status_pb2.py +++ b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/set_camera_control_status_pb2.py @@ -1,6 +1,3 @@ -# set_camera_control_status_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:47 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf.internal import builder as _builder diff --git a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/turbo_transfer_pb2.py b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/turbo_transfer_pb2.py index 54e25d103..d33378d63 100644 --- a/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/turbo_transfer_pb2.py +++ b/demos/python/tutorial/tutorial_modules/tutorial_5_ble_protobuf/proto/turbo_transfer_pb2.py @@ -1,6 +1,3 @@ -# turbo_transfer_pb2.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). -# This copyright was auto-generated on Wed Sep 24 20:06:47 UTC 2025 - """Generated protocol buffer code.""" from google.protobuf.internal import builder as _builder diff --git a/protobuf/preset_status.proto b/protobuf/preset_status.proto index 341e462e1..d05a11f3e 100644 --- a/protobuf/preset_status.proto +++ b/protobuf/preset_status.proto @@ -46,6 +46,7 @@ enum EnumPresetGroup { PRESET_GROUP_ID_VIDEO = 1000; PRESET_GROUP_ID_PHOTO = 1001; PRESET_GROUP_ID_TIMELAPSE = 1002; + PRESET_GROUP_ID_GENERAL = 2000; } enum EnumPresetGroupIcon { @@ -338,11 +339,13 @@ message RequestPresetSetVisibility { * Preset Group meta information and contained Presets */ message PresetGroup { - optional EnumPresetGroup id = 1; // Preset Group ID - repeated Preset preset_array = 2; // Array of Presets contained in this Preset Group - optional bool can_add_preset = 3; // Is there room in the group to add additional Presets? - optional EnumPresetGroupIcon icon = 4; // The icon to display for this preset group - repeated EnumFlatMode mode_array = 5; // A list of flatmodes available for this preset group + optional EnumPresetGroup id = 1; // Preset Group ID + repeated Preset preset_array = 2; // Array of Presets contained in this Preset Group + optional bool can_add_preset = 3; // Is there room in the group to add additional Presets? + optional EnumPresetGroupIcon icon = 4; // The icon to display for this preset group + repeated EnumFlatMode mode_array = 5; // A list of flatmodes available for this preset group + optional string custom_name = 6; // Custom string name given to this preset group + optional int32 active_preset_id = 7; // Active preset id in this group } /** diff --git a/protobuf/request_get_camera_capabilities.proto b/protobuf/request_get_camera_capabilities.proto new file mode 100644 index 000000000..478865b4c --- /dev/null +++ b/protobuf/request_get_camera_capabilities.proto @@ -0,0 +1,42 @@ +/* request_get_camera_capabilities.proto/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). */ +/* This copyright was auto-generated on Mon Nov 4 18:00:55 UTC 2024 */ + +/*********************************************************************************************************************** + * + * This file is automatically generated!!! Do not modify manually. + * + **********************************************************************************************************************/ + +/** + * Defines the structure of protobuf messages for querying camera capabilities + */ + +syntax = "proto2"; +package open_gopro; + +import "response_generic.proto"; + +/** + * Get the camera capabilities + * + * Returns a @ref ResponseGetCameraCapabilities + */ +message RequestGetCameraCapabilities {} + +/** + * Camera Capabilities + * + * Message is sent in response to a @ref RequestGetCameraCapabilities. + */ +message ResponseGetCameraCapabilities { + required EnumResultGeneric result = 1; // Generic pass/fail/error info + required string schema_version = 2; // Capability schema version (e.g., "camera-capabilities/v1.0") + optional ProtocolCapabilities protocol = 3; // Protocol-level capabilities +} + +/** + * Protocol capability information + */ +message ProtocolCapabilities { + optional bool supports_2byte_ids = 1 [ default = false ]; // Does the camera support 2-byte setting/status IDs +} diff --git a/tools/windows_rndis_driver/GoProWebcam.inf b/tools/windows_rndis_driver/GoProWebcam.inf new file mode 100644 index 000000000..17e4c3c75 --- /dev/null +++ b/tools/windows_rndis_driver/GoProWebcam.inf @@ -0,0 +1,70 @@ +; Remote NDIS template device setup file +; Copyright (c) Microsoft Corporation +; +; This is the template for the INF installation script for the RNDIS-over-USB +; host driver that leverages the newer NDIS 6.x miniport (rndismp6.sys) for +; improved performance. This INF works for Windows 7, Windows Server 2008 R2, +; and later operating systems on x86, amd64 and ia64 platforms. + +[Version] +Signature = "$Windows NT$" +Class = Net +ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318} +Provider = %Microsoft% +DriverVer = 03/11/2026,1.2.0004.00004 +CatalogFile = goprowebcam.cat + +[Manufacturer] +%Microsoft% = RndisDevices,NTx86,NTamd64,NTia64 + +; Decoration for x86 architecture +[RndisDevices.NTx86] +%RndisDevice% = RNDIS.NT.6.0, USB\VID_2672&PID_0050,USB\VID_2672&PID_0052,USB\VID_2672&PID_005b&REV_0409 + +; Decoration for x64 architecture +[RndisDevices.NTamd64] +%RndisDevice% = RNDIS.NT.6.0, USB\VID_2672&PID_0050,USB\VID_2672&PID_0052,USB\VID_2672&PID_005b&REV_0409 + +; Decoration for ia64 architecture +[RndisDevices.NTia64] +%RndisDevice% = RNDIS.NT.6.0, USB\VID_2672&PID_0050,USB\VID_2672&PID_0052,USB\VID_2672&PID_005b&REV_0409 + +;@@@ This is the common setting for setup +[ControlFlags] +ExcludeFromSelect=* + +; DDInstall section +; References the in-build Netrndis.inf +[RNDIS.NT.6.0] +Characteristics = 0x84 ; NCF_PHYSICAL + NCF_HAS_UI +BusType = 15 +; NEVER REMOVE THE FOLLOWING REFERENCE FOR NETRNDIS.INF +include = netrndis.inf +needs = usbrndis6.ndi +AddReg = Rndis_AddReg +*IfType = 6 ; IF_TYPE_ETHERNET_CSMACD. +*MediaType = 16 ; NdisMediumNative802_11 +*PhysicalMediaType = 14 ; NdisPhysicalMedium802_3 + +; DDInstal.Services section +[RNDIS.NT.6.0.Services] +include = netrndis.inf +needs = usbrndis6.ndi.Services + +; Optional registry settings. You can modify as needed. +[RNDIS_AddReg] +HKR, NDI\params\RndisProperty, ParamDesc, 0, %Rndis_Property% +HKR, NDI\params\RndisProperty, type, 0, "edit" +HKR, NDI\params\RndisProperty, LimitText, 0, "12" +HKR, NDI\params\RndisProperty, UpperCase, 0, "1" +HKR, NDI\params\RndisProperty, default, 0, " " +HKR, NDI\params\RndisProperty, optional, 0, "1" + +; No sys copyfiles - the sys files are already in-build +; (part of the operating system). + +; Modify these strings for your device as needed. +[Strings] +Microsoft = "GoPro" +RndisDevice = "GoPro RNDIS Device" +Rndis_Property = "GoProConnect" \ No newline at end of file diff --git a/tools/windows_rndis_driver/README.md b/tools/windows_rndis_driver/README.md new file mode 100644 index 000000000..d1a933eff --- /dev/null +++ b/tools/windows_rndis_driver/README.md @@ -0,0 +1,26 @@ +# Windows RNDIS Driver for LIT HERO + +This directory hosts the Windows USB ethernet (RNDIS) driver files required for LIT HERO cameras when using Open GoPro over USB. + +## When this is needed + +Use this driver if you are on Windows and connecting to a LIT HERO camera via USB for Open GoPro development. + +## Files + +- `GoProWebcam.inf` +- `goprowebcam.cat` + +Keep these files together in the same directory during installation. + +## Installation + +1. Right-click `GoProWebcam.inf`. +2. Select **Install**. + +## Compatibility + +This driver package works with both camera USB modes: + +- MTP +- GoPro Connect diff --git a/tools/windows_rndis_driver/goprowebcam.cat b/tools/windows_rndis_driver/goprowebcam.cat new file mode 100644 index 000000000..b8c734c42 Binary files /dev/null and b/tools/windows_rndis_driver/goprowebcam.cat differ