# coding: utf-8

"""
    Intervals.icu API

    No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)

    The version of the OpenAPI document: v1.0.0
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


from __future__ import annotations
import pprint
import re  # noqa: F401
import json

from datetime import datetime
from pydantic import BaseModel, ConfigDict, StrictBool, StrictBytes, StrictFloat, StrictInt, StrictStr, field_validator
from typing import Any, ClassVar, Dict, List, Optional, Union
from intervals_icu_client.models.attachment import Attachment
from intervals_icu_client.models.hr_recovery import HRRecovery
from intervals_icu_client.models.icu_achievement import IcuAchievement
from intervals_icu_client.models.ignore import Ignore
from intervals_icu_client.models.interval import Interval
from intervals_icu_client.models.interval_group import IntervalGroup
from intervals_icu_client.models.strava_gear import StravaGear
from intervals_icu_client.models.zone_set import ZoneSet
from intervals_icu_client.models.zone_time import ZoneTime
from typing import Optional, Set
from typing_extensions import Self

class ActivityWithIntervals(BaseModel):
    """
    ActivityWithIntervals
    """ # noqa: E501
    id: Optional[StrictStr] = None
    start_date_local: Optional[StrictStr] = None
    type: Optional[StrictStr] = None
    icu_ignore_time: Optional[StrictBool] = None
    icu_pm_cp: Optional[StrictInt] = None
    icu_pm_w_prime: Optional[StrictInt] = None
    icu_pm_p_max: Optional[StrictInt] = None
    icu_pm_ftp: Optional[StrictInt] = None
    icu_pm_ftp_secs: Optional[StrictInt] = None
    icu_pm_ftp_watts: Optional[StrictInt] = None
    icu_ignore_power: Optional[StrictBool] = None
    icu_rolling_cp: Optional[Union[StrictFloat, StrictInt]] = None
    icu_rolling_w_prime: Optional[Union[StrictFloat, StrictInt]] = None
    icu_rolling_p_max: Optional[Union[StrictFloat, StrictInt]] = None
    icu_rolling_ftp: Optional[StrictInt] = None
    icu_rolling_ftp_delta: Optional[StrictInt] = None
    icu_training_load: Optional[StrictInt] = None
    icu_atl: Optional[Union[StrictFloat, StrictInt]] = None
    icu_ctl: Optional[Union[StrictFloat, StrictInt]] = None
    ss_p_max: Optional[Union[StrictFloat, StrictInt]] = None
    ss_w_prime: Optional[Union[StrictFloat, StrictInt]] = None
    ss_cp: Optional[Union[StrictFloat, StrictInt]] = None
    paired_event_id: Optional[StrictInt] = None
    icu_ftp: Optional[StrictInt] = None
    icu_joules: Optional[StrictInt] = None
    icu_recording_time: Optional[StrictInt] = None
    elapsed_time: Optional[StrictInt] = None
    icu_weighted_avg_watts: Optional[StrictInt] = None
    carbs_used: Optional[StrictInt] = None
    name: Optional[StrictStr] = None
    description: Optional[StrictStr] = None
    start_date: Optional[StrictStr] = None
    distance: Optional[Union[StrictFloat, StrictInt]] = None
    icu_distance: Optional[Union[StrictFloat, StrictInt]] = None
    moving_time: Optional[StrictInt] = None
    coasting_time: Optional[StrictInt] = None
    total_elevation_gain: Optional[Union[StrictFloat, StrictInt]] = None
    total_elevation_loss: Optional[Union[StrictFloat, StrictInt]] = None
    timezone: Optional[StrictStr] = None
    trainer: Optional[StrictBool] = None
    sub_type: Optional[StrictStr] = None
    commute: Optional[StrictBool] = None
    race: Optional[StrictBool] = None
    max_speed: Optional[Union[StrictFloat, StrictInt]] = None
    average_speed: Optional[Union[StrictFloat, StrictInt]] = None
    device_watts: Optional[StrictBool] = None
    has_heartrate: Optional[StrictBool] = None
    max_heartrate: Optional[StrictInt] = None
    average_heartrate: Optional[StrictInt] = None
    average_cadence: Optional[Union[StrictFloat, StrictInt]] = None
    calories: Optional[StrictInt] = None
    average_temp: Optional[Union[StrictFloat, StrictInt]] = None
    min_temp: Optional[StrictInt] = None
    max_temp: Optional[StrictInt] = None
    avg_lr_balance: Optional[Union[StrictFloat, StrictInt]] = None
    gap: Optional[Union[StrictFloat, StrictInt]] = None
    gap_model: Optional[StrictStr] = None
    use_elevation_correction: Optional[StrictBool] = None
    gear: Optional[StravaGear] = None
    perceived_exertion: Optional[Union[StrictFloat, StrictInt]] = None
    device_name: Optional[StrictStr] = None
    power_meter: Optional[StrictStr] = None
    power_meter_serial: Optional[StrictStr] = None
    power_meter_battery: Optional[StrictStr] = None
    crank_length: Optional[Union[StrictFloat, StrictInt]] = None
    external_id: Optional[StrictStr] = None
    file_sport_index: Optional[StrictInt] = None
    file_type: Optional[StrictStr] = None
    icu_athlete_id: Optional[StrictStr] = None
    created: Optional[datetime] = None
    icu_sync_date: Optional[datetime] = None
    analyzed: Optional[datetime] = None
    icu_w_prime: Optional[StrictInt] = None
    p_max: Optional[StrictInt] = None
    threshold_pace: Optional[Union[StrictFloat, StrictInt]] = None
    icu_hr_zones: Optional[List[StrictInt]] = None
    pace_zones: Optional[List[Union[StrictFloat, StrictInt]]] = None
    lthr: Optional[StrictInt] = None
    icu_resting_hr: Optional[StrictInt] = None
    icu_weight: Optional[Union[StrictFloat, StrictInt]] = None
    icu_power_zones: Optional[List[StrictInt]] = None
    icu_sweet_spot_min: Optional[StrictInt] = None
    icu_sweet_spot_max: Optional[StrictInt] = None
    icu_power_spike_threshold: Optional[StrictInt] = None
    trimp: Optional[Union[StrictFloat, StrictInt]] = None
    icu_warmup_time: Optional[StrictInt] = None
    icu_cooldown_time: Optional[StrictInt] = None
    icu_chat_id: Optional[StrictInt] = None
    icu_ignore_hr: Optional[StrictBool] = None
    ignore_velocity: Optional[StrictBool] = None
    ignore_pace: Optional[StrictBool] = None
    ignore_parts: Optional[List[Ignore]] = None
    icu_training_load_data: Optional[StrictInt] = None
    interval_summary: Optional[List[StrictStr]] = None
    skyline_chart_bytes: Optional[List[Union[StrictBytes, StrictStr]]] = None
    stream_types: Optional[List[StrictStr]] = None
    has_weather: Optional[StrictBool] = None
    has_segments: Optional[StrictBool] = None
    power_field_names: Optional[List[StrictStr]] = None
    power_field: Optional[StrictStr] = None
    icu_zone_times: Optional[List[ZoneTime]] = None
    icu_hr_zone_times: Optional[List[StrictInt]] = None
    pace_zone_times: Optional[List[StrictInt]] = None
    gap_zone_times: Optional[List[StrictInt]] = None
    use_gap_zone_times: Optional[StrictBool] = None
    custom_zones: Optional[List[ZoneSet]] = None
    tiz_order: Optional[StrictStr] = None
    polarization_index: Optional[Union[StrictFloat, StrictInt]] = None
    icu_achievements: Optional[List[IcuAchievement]] = None
    icu_intervals_edited: Optional[StrictBool] = None
    lock_intervals: Optional[StrictBool] = None
    icu_lap_count: Optional[StrictInt] = None
    icu_joules_above_ftp: Optional[StrictInt] = None
    icu_max_wbal_depletion: Optional[StrictInt] = None
    icu_hrr: Optional[HRRecovery] = None
    icu_sync_error: Optional[StrictStr] = None
    icu_color: Optional[StrictStr] = None
    icu_power_hr_z2: Optional[Union[StrictFloat, StrictInt]] = None
    icu_power_hr_z2_mins: Optional[StrictInt] = None
    icu_cadence_z2: Optional[StrictInt] = None
    icu_rpe: Optional[StrictInt] = None
    feel: Optional[StrictInt] = None
    kg_lifted: Optional[Union[StrictFloat, StrictInt]] = None
    decoupling: Optional[Union[StrictFloat, StrictInt]] = None
    icu_median_time_delta: Optional[StrictInt] = None
    p30s_exponent: Optional[Union[StrictFloat, StrictInt]] = None
    workout_shift_secs: Optional[StrictInt] = None
    strava_id: Optional[StrictStr] = None
    lengths: Optional[StrictInt] = None
    pool_length: Optional[Union[StrictFloat, StrictInt]] = None
    compliance: Optional[Union[StrictFloat, StrictInt]] = None
    coach_tick: Optional[StrictInt] = None
    source: Optional[StrictStr] = None
    oauth_client_id: Optional[StrictInt] = None
    oauth_client_name: Optional[StrictStr] = None
    average_altitude: Optional[Union[StrictFloat, StrictInt]] = None
    min_altitude: Optional[Union[StrictFloat, StrictInt]] = None
    max_altitude: Optional[Union[StrictFloat, StrictInt]] = None
    power_load: Optional[StrictInt] = None
    hr_load: Optional[StrictInt] = None
    pace_load: Optional[StrictInt] = None
    hr_load_type: Optional[StrictStr] = None
    pace_load_type: Optional[StrictStr] = None
    tags: Optional[List[StrictStr]] = None
    attachments: Optional[List[Attachment]] = None
    recording_stops: Optional[List[StrictInt]] = None
    average_weather_temp: Optional[Union[StrictFloat, StrictInt]] = None
    min_weather_temp: Optional[Union[StrictFloat, StrictInt]] = None
    max_weather_temp: Optional[Union[StrictFloat, StrictInt]] = None
    average_feels_like: Optional[Union[StrictFloat, StrictInt]] = None
    min_feels_like: Optional[Union[StrictFloat, StrictInt]] = None
    max_feels_like: Optional[Union[StrictFloat, StrictInt]] = None
    average_wind_speed: Optional[Union[StrictFloat, StrictInt]] = None
    average_wind_gust: Optional[Union[StrictFloat, StrictInt]] = None
    prevailing_wind_deg: Optional[StrictInt] = None
    headwind_percent: Optional[Union[StrictFloat, StrictInt]] = None
    tailwind_percent: Optional[Union[StrictFloat, StrictInt]] = None
    average_clouds: Optional[StrictInt] = None
    max_rain: Optional[Union[StrictFloat, StrictInt]] = None
    max_snow: Optional[Union[StrictFloat, StrictInt]] = None
    carbs_ingested: Optional[StrictInt] = None
    route_id: Optional[StrictInt] = None
    pace: Optional[Union[StrictFloat, StrictInt]] = None
    athlete_max_hr: Optional[StrictInt] = None
    group: Optional[StrictStr] = None
    icu_intensity: Optional[Union[StrictFloat, StrictInt]] = None
    icu_efficiency_factor: Optional[Union[StrictFloat, StrictInt]] = None
    icu_power_hr: Optional[Union[StrictFloat, StrictInt]] = None
    session_rpe: Optional[StrictInt] = None
    average_stride: Optional[Union[StrictFloat, StrictInt]] = None
    icu_average_watts: Optional[StrictInt] = None
    icu_variability_index: Optional[Union[StrictFloat, StrictInt]] = None
    strain_score: Optional[Union[StrictFloat, StrictInt]] = None
    icu_intervals: Optional[List[Interval]] = None
    icu_groups: Optional[List[IntervalGroup]] = None
    __properties: ClassVar[List[str]] = ["id", "start_date_local", "type", "icu_ignore_time", "icu_pm_cp", "icu_pm_w_prime", "icu_pm_p_max", "icu_pm_ftp", "icu_pm_ftp_secs", "icu_pm_ftp_watts", "icu_ignore_power", "icu_rolling_cp", "icu_rolling_w_prime", "icu_rolling_p_max", "icu_rolling_ftp", "icu_rolling_ftp_delta", "icu_training_load", "icu_atl", "icu_ctl", "ss_p_max", "ss_w_prime", "ss_cp", "paired_event_id", "icu_ftp", "icu_joules", "icu_recording_time", "elapsed_time", "icu_weighted_avg_watts", "carbs_used", "name", "description", "start_date", "distance", "icu_distance", "moving_time", "coasting_time", "total_elevation_gain", "total_elevation_loss", "timezone", "trainer", "sub_type", "commute", "race", "max_speed", "average_speed", "device_watts", "has_heartrate", "max_heartrate", "average_heartrate", "average_cadence", "calories", "average_temp", "min_temp", "max_temp", "avg_lr_balance", "gap", "gap_model", "use_elevation_correction", "gear", "perceived_exertion", "device_name", "power_meter", "power_meter_serial", "power_meter_battery", "crank_length", "external_id", "file_sport_index", "file_type", "icu_athlete_id", "created", "icu_sync_date", "analyzed", "icu_w_prime", "p_max", "threshold_pace", "icu_hr_zones", "pace_zones", "lthr", "icu_resting_hr", "icu_weight", "icu_power_zones", "icu_sweet_spot_min", "icu_sweet_spot_max", "icu_power_spike_threshold", "trimp", "icu_warmup_time", "icu_cooldown_time", "icu_chat_id", "icu_ignore_hr", "ignore_velocity", "ignore_pace", "ignore_parts", "icu_training_load_data", "interval_summary", "skyline_chart_bytes", "stream_types", "has_weather", "has_segments", "power_field_names", "power_field", "icu_zone_times", "icu_hr_zone_times", "pace_zone_times", "gap_zone_times", "use_gap_zone_times", "custom_zones", "tiz_order", "polarization_index", "icu_achievements", "icu_intervals_edited", "lock_intervals", "icu_lap_count", "icu_joules_above_ftp", "icu_max_wbal_depletion", "icu_hrr", "icu_sync_error", "icu_color", "icu_power_hr_z2", "icu_power_hr_z2_mins", "icu_cadence_z2", "icu_rpe", "feel", "kg_lifted", "decoupling", "icu_median_time_delta", "p30s_exponent", "workout_shift_secs", "strava_id", "lengths", "pool_length", "compliance", "coach_tick", "source", "oauth_client_id", "oauth_client_name", "average_altitude", "min_altitude", "max_altitude", "power_load", "hr_load", "pace_load", "hr_load_type", "pace_load_type", "tags", "attachments", "recording_stops", "average_weather_temp", "min_weather_temp", "max_weather_temp", "average_feels_like", "min_feels_like", "max_feels_like", "average_wind_speed", "average_wind_gust", "prevailing_wind_deg", "headwind_percent", "tailwind_percent", "average_clouds", "max_rain", "max_snow", "carbs_ingested", "route_id", "pace", "athlete_max_hr", "group", "icu_intensity", "icu_efficiency_factor", "icu_power_hr", "session_rpe", "average_stride", "icu_average_watts", "icu_variability_index", "strain_score", "icu_intervals", "icu_groups"]

    @field_validator('sub_type')
    def sub_type_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['NONE', 'COMMUTE', 'WARMUP', 'COOLDOWN', 'RACE']):
            raise ValueError("must be one of enum values ('NONE', 'COMMUTE', 'WARMUP', 'COOLDOWN', 'RACE')")
        return value

    @field_validator('gap_model')
    def gap_model_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['NONE', 'STRAVA_RUN']):
            raise ValueError("must be one of enum values ('NONE', 'STRAVA_RUN')")
        return value

    @field_validator('tiz_order')
    def tiz_order_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['POWER_HR_PACE', 'POWER_PACE_HR', 'HR_POWER_PACE', 'HR_PACE_POWER', 'PACE_POWER_HR', 'PACE_HR_POWER']):
            raise ValueError("must be one of enum values ('POWER_HR_PACE', 'POWER_PACE_HR', 'HR_POWER_PACE', 'HR_PACE_POWER', 'PACE_POWER_HR', 'PACE_HR_POWER')")
        return value

    @field_validator('source')
    def source_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['STRAVA', 'UPLOAD', 'MANUAL', 'GARMIN_CONNECT', 'OAUTH_CLIENT', 'DROPBOX', 'POLAR', 'SUUNTO', 'COROS', 'WAHOO', 'ZWIFT', 'ZEPP', 'CONCEPT2']):
            raise ValueError("must be one of enum values ('STRAVA', 'UPLOAD', 'MANUAL', 'GARMIN_CONNECT', 'OAUTH_CLIENT', 'DROPBOX', 'POLAR', 'SUUNTO', 'COROS', 'WAHOO', 'ZWIFT', 'ZEPP', 'CONCEPT2')")
        return value

    @field_validator('hr_load_type')
    def hr_load_type_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['AVG_HR', 'HR_ZONES', 'HRSS']):
            raise ValueError("must be one of enum values ('AVG_HR', 'HR_ZONES', 'HRSS')")
        return value

    @field_validator('pace_load_type')
    def pace_load_type_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['SWIM', 'RUN']):
            raise ValueError("must be one of enum values ('SWIM', 'RUN')")
        return value

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )


    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of ActivityWithIntervals from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        """
        excluded_fields: Set[str] = set([
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of gear
        if self.gear:
            _dict['gear'] = self.gear.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in ignore_parts (list)
        _items = []
        if self.ignore_parts:
            for _item_ignore_parts in self.ignore_parts:
                if _item_ignore_parts:
                    _items.append(_item_ignore_parts.to_dict())
            _dict['ignore_parts'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in icu_zone_times (list)
        _items = []
        if self.icu_zone_times:
            for _item_icu_zone_times in self.icu_zone_times:
                if _item_icu_zone_times:
                    _items.append(_item_icu_zone_times.to_dict())
            _dict['icu_zone_times'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in custom_zones (list)
        _items = []
        if self.custom_zones:
            for _item_custom_zones in self.custom_zones:
                if _item_custom_zones:
                    _items.append(_item_custom_zones.to_dict())
            _dict['custom_zones'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in icu_achievements (list)
        _items = []
        if self.icu_achievements:
            for _item_icu_achievements in self.icu_achievements:
                if _item_icu_achievements:
                    _items.append(_item_icu_achievements.to_dict())
            _dict['icu_achievements'] = _items
        # override the default output from pydantic by calling `to_dict()` of icu_hrr
        if self.icu_hrr:
            _dict['icu_hrr'] = self.icu_hrr.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in attachments (list)
        _items = []
        if self.attachments:
            for _item_attachments in self.attachments:
                if _item_attachments:
                    _items.append(_item_attachments.to_dict())
            _dict['attachments'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in icu_intervals (list)
        _items = []
        if self.icu_intervals:
            for _item_icu_intervals in self.icu_intervals:
                if _item_icu_intervals:
                    _items.append(_item_icu_intervals.to_dict())
            _dict['icu_intervals'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in icu_groups (list)
        _items = []
        if self.icu_groups:
            for _item_icu_groups in self.icu_groups:
                if _item_icu_groups:
                    _items.append(_item_icu_groups.to_dict())
            _dict['icu_groups'] = _items
        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of ActivityWithIntervals from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "id": obj.get("id"),
            "start_date_local": obj.get("start_date_local"),
            "type": obj.get("type"),
            "icu_ignore_time": obj.get("icu_ignore_time"),
            "icu_pm_cp": obj.get("icu_pm_cp"),
            "icu_pm_w_prime": obj.get("icu_pm_w_prime"),
            "icu_pm_p_max": obj.get("icu_pm_p_max"),
            "icu_pm_ftp": obj.get("icu_pm_ftp"),
            "icu_pm_ftp_secs": obj.get("icu_pm_ftp_secs"),
            "icu_pm_ftp_watts": obj.get("icu_pm_ftp_watts"),
            "icu_ignore_power": obj.get("icu_ignore_power"),
            "icu_rolling_cp": obj.get("icu_rolling_cp"),
            "icu_rolling_w_prime": obj.get("icu_rolling_w_prime"),
            "icu_rolling_p_max": obj.get("icu_rolling_p_max"),
            "icu_rolling_ftp": obj.get("icu_rolling_ftp"),
            "icu_rolling_ftp_delta": obj.get("icu_rolling_ftp_delta"),
            "icu_training_load": obj.get("icu_training_load"),
            "icu_atl": obj.get("icu_atl"),
            "icu_ctl": obj.get("icu_ctl"),
            "ss_p_max": obj.get("ss_p_max"),
            "ss_w_prime": obj.get("ss_w_prime"),
            "ss_cp": obj.get("ss_cp"),
            "paired_event_id": obj.get("paired_event_id"),
            "icu_ftp": obj.get("icu_ftp"),
            "icu_joules": obj.get("icu_joules"),
            "icu_recording_time": obj.get("icu_recording_time"),
            "elapsed_time": obj.get("elapsed_time"),
            "icu_weighted_avg_watts": obj.get("icu_weighted_avg_watts"),
            "carbs_used": obj.get("carbs_used"),
            "name": obj.get("name"),
            "description": obj.get("description"),
            "start_date": obj.get("start_date"),
            "distance": obj.get("distance"),
            "icu_distance": obj.get("icu_distance"),
            "moving_time": obj.get("moving_time"),
            "coasting_time": obj.get("coasting_time"),
            "total_elevation_gain": obj.get("total_elevation_gain"),
            "total_elevation_loss": obj.get("total_elevation_loss"),
            "timezone": obj.get("timezone"),
            "trainer": obj.get("trainer"),
            "sub_type": obj.get("sub_type"),
            "commute": obj.get("commute"),
            "race": obj.get("race"),
            "max_speed": obj.get("max_speed"),
            "average_speed": obj.get("average_speed"),
            "device_watts": obj.get("device_watts"),
            "has_heartrate": obj.get("has_heartrate"),
            "max_heartrate": obj.get("max_heartrate"),
            "average_heartrate": obj.get("average_heartrate"),
            "average_cadence": obj.get("average_cadence"),
            "calories": obj.get("calories"),
            "average_temp": obj.get("average_temp"),
            "min_temp": obj.get("min_temp"),
            "max_temp": obj.get("max_temp"),
            "avg_lr_balance": obj.get("avg_lr_balance"),
            "gap": obj.get("gap"),
            "gap_model": obj.get("gap_model"),
            "use_elevation_correction": obj.get("use_elevation_correction"),
            "gear": StravaGear.from_dict(obj["gear"]) if obj.get("gear") is not None else None,
            "perceived_exertion": obj.get("perceived_exertion"),
            "device_name": obj.get("device_name"),
            "power_meter": obj.get("power_meter"),
            "power_meter_serial": obj.get("power_meter_serial"),
            "power_meter_battery": obj.get("power_meter_battery"),
            "crank_length": obj.get("crank_length"),
            "external_id": obj.get("external_id"),
            "file_sport_index": obj.get("file_sport_index"),
            "file_type": obj.get("file_type"),
            "icu_athlete_id": obj.get("icu_athlete_id"),
            "created": obj.get("created"),
            "icu_sync_date": obj.get("icu_sync_date"),
            "analyzed": obj.get("analyzed"),
            "icu_w_prime": obj.get("icu_w_prime"),
            "p_max": obj.get("p_max"),
            "threshold_pace": obj.get("threshold_pace"),
            "icu_hr_zones": obj.get("icu_hr_zones"),
            "pace_zones": obj.get("pace_zones"),
            "lthr": obj.get("lthr"),
            "icu_resting_hr": obj.get("icu_resting_hr"),
            "icu_weight": obj.get("icu_weight"),
            "icu_power_zones": obj.get("icu_power_zones"),
            "icu_sweet_spot_min": obj.get("icu_sweet_spot_min"),
            "icu_sweet_spot_max": obj.get("icu_sweet_spot_max"),
            "icu_power_spike_threshold": obj.get("icu_power_spike_threshold"),
            "trimp": obj.get("trimp"),
            "icu_warmup_time": obj.get("icu_warmup_time"),
            "icu_cooldown_time": obj.get("icu_cooldown_time"),
            "icu_chat_id": obj.get("icu_chat_id"),
            "icu_ignore_hr": obj.get("icu_ignore_hr"),
            "ignore_velocity": obj.get("ignore_velocity"),
            "ignore_pace": obj.get("ignore_pace"),
            "ignore_parts": [Ignore.from_dict(_item) for _item in obj["ignore_parts"]] if obj.get("ignore_parts") is not None else None,
            "icu_training_load_data": obj.get("icu_training_load_data"),
            "interval_summary": obj.get("interval_summary"),
            "skyline_chart_bytes": obj.get("skyline_chart_bytes"),
            "stream_types": obj.get("stream_types"),
            "has_weather": obj.get("has_weather"),
            "has_segments": obj.get("has_segments"),
            "power_field_names": obj.get("power_field_names"),
            "power_field": obj.get("power_field"),
            "icu_zone_times": [ZoneTime.from_dict(_item) for _item in obj["icu_zone_times"]] if obj.get("icu_zone_times") is not None else None,
            "icu_hr_zone_times": obj.get("icu_hr_zone_times"),
            "pace_zone_times": obj.get("pace_zone_times"),
            "gap_zone_times": obj.get("gap_zone_times"),
            "use_gap_zone_times": obj.get("use_gap_zone_times"),
            "custom_zones": [ZoneSet.from_dict(_item) for _item in obj["custom_zones"]] if obj.get("custom_zones") is not None else None,
            "tiz_order": obj.get("tiz_order"),
            "polarization_index": obj.get("polarization_index"),
            "icu_achievements": [IcuAchievement.from_dict(_item) for _item in obj["icu_achievements"]] if obj.get("icu_achievements") is not None else None,
            "icu_intervals_edited": obj.get("icu_intervals_edited"),
            "lock_intervals": obj.get("lock_intervals"),
            "icu_lap_count": obj.get("icu_lap_count"),
            "icu_joules_above_ftp": obj.get("icu_joules_above_ftp"),
            "icu_max_wbal_depletion": obj.get("icu_max_wbal_depletion"),
            "icu_hrr": HRRecovery.from_dict(obj["icu_hrr"]) if obj.get("icu_hrr") is not None else None,
            "icu_sync_error": obj.get("icu_sync_error"),
            "icu_color": obj.get("icu_color"),
            "icu_power_hr_z2": obj.get("icu_power_hr_z2"),
            "icu_power_hr_z2_mins": obj.get("icu_power_hr_z2_mins"),
            "icu_cadence_z2": obj.get("icu_cadence_z2"),
            "icu_rpe": obj.get("icu_rpe"),
            "feel": obj.get("feel"),
            "kg_lifted": obj.get("kg_lifted"),
            "decoupling": obj.get("decoupling"),
            "icu_median_time_delta": obj.get("icu_median_time_delta"),
            "p30s_exponent": obj.get("p30s_exponent"),
            "workout_shift_secs": obj.get("workout_shift_secs"),
            "strava_id": obj.get("strava_id"),
            "lengths": obj.get("lengths"),
            "pool_length": obj.get("pool_length"),
            "compliance": obj.get("compliance"),
            "coach_tick": obj.get("coach_tick"),
            "source": obj.get("source"),
            "oauth_client_id": obj.get("oauth_client_id"),
            "oauth_client_name": obj.get("oauth_client_name"),
            "average_altitude": obj.get("average_altitude"),
            "min_altitude": obj.get("min_altitude"),
            "max_altitude": obj.get("max_altitude"),
            "power_load": obj.get("power_load"),
            "hr_load": obj.get("hr_load"),
            "pace_load": obj.get("pace_load"),
            "hr_load_type": obj.get("hr_load_type"),
            "pace_load_type": obj.get("pace_load_type"),
            "tags": obj.get("tags"),
            "attachments": [Attachment.from_dict(_item) for _item in obj["attachments"]] if obj.get("attachments") is not None else None,
            "recording_stops": obj.get("recording_stops"),
            "average_weather_temp": obj.get("average_weather_temp"),
            "min_weather_temp": obj.get("min_weather_temp"),
            "max_weather_temp": obj.get("max_weather_temp"),
            "average_feels_like": obj.get("average_feels_like"),
            "min_feels_like": obj.get("min_feels_like"),
            "max_feels_like": obj.get("max_feels_like"),
            "average_wind_speed": obj.get("average_wind_speed"),
            "average_wind_gust": obj.get("average_wind_gust"),
            "prevailing_wind_deg": obj.get("prevailing_wind_deg"),
            "headwind_percent": obj.get("headwind_percent"),
            "tailwind_percent": obj.get("tailwind_percent"),
            "average_clouds": obj.get("average_clouds"),
            "max_rain": obj.get("max_rain"),
            "max_snow": obj.get("max_snow"),
            "carbs_ingested": obj.get("carbs_ingested"),
            "route_id": obj.get("route_id"),
            "pace": obj.get("pace"),
            "athlete_max_hr": obj.get("athlete_max_hr"),
            "group": obj.get("group"),
            "icu_intensity": obj.get("icu_intensity"),
            "icu_efficiency_factor": obj.get("icu_efficiency_factor"),
            "icu_power_hr": obj.get("icu_power_hr"),
            "session_rpe": obj.get("session_rpe"),
            "average_stride": obj.get("average_stride"),
            "icu_average_watts": obj.get("icu_average_watts"),
            "icu_variability_index": obj.get("icu_variability_index"),
            "strain_score": obj.get("strain_score"),
            "icu_intervals": [Interval.from_dict(_item) for _item in obj["icu_intervals"]] if obj.get("icu_intervals") is not None else None,
            "icu_groups": [IntervalGroup.from_dict(_item) for _item in obj["icu_groups"]] if obj.get("icu_groups") is not None else None
        })
        return _obj


