{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "CRSProf Canonical Schema",
  "description": "Canonical CRSProf model centered on ordered segments.",
  "type": "object",
  "properties": {
    "version": {
      "type": "integer",
      "enum": [1, 2],
      "description": "Schema version for the canonical CRSProf format."
    },
    "event": {
      "$ref": "#/definitions/event"
    },
    "semantics": {
      "$ref": "#/definitions/semantics"
    },
    "gpx": {
      "type": "object",
      "properties": {
        "reference": {
          "$ref": "#/definitions/gpx_source"
        },
        "execution": {
          "$ref": "#/definitions/gpx_source"
        }
      },
      "required": [
        "reference"
      ],
      "additionalProperties": false
    },
    "options": {
      "type": "object",
      "properties": {
        "analysis": {
          "$ref": "#/definitions/analysis_options"
        },
        "reference": {
          "$ref": "#/definitions/reference_options"
        },
        "execution": {
          "$ref": "#/definitions/execution_options"
        },
        "estimation": {
          "$ref": "#/definitions/estimation_options"
        }
      },
      "additionalProperties": false
    },
    "annotations": {
      "$ref": "#/definitions/annotations"
    },
    "segments": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/segment"
      }
    },
    "indexes": {
      "$ref": "#/definitions/indexes"
    }
  },
  "required": [
    "version",
    "gpx",
    "segments"
  ],
  "allOf": [
    {
      "if": {
        "properties": {
          "gpx": {
            "required": ["execution"]
          }
        },
        "required": ["gpx"]
      },
      "then": {
        "required": ["options"],
        "properties": {
          "options": {
            "required": ["execution"],
            "properties": {
              "execution": {
                "required": [
                  "moving_threshold",
                  "auto_stop_threshold",
                  "auto_stop_merge_distance"
                ]
              }
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "segments": {
            "contains": {
              "required": ["execution"]
            }
          }
        },
        "required": ["segments"]
      },
      "then": {
        "required": ["options"],
        "properties": {
          "options": {
            "required": ["execution"],
            "properties": {
              "execution": {
                "required": [
                  "moving_threshold",
                  "auto_stop_threshold",
                  "auto_stop_merge_distance"
                ]
              }
            }
          }
        }
      }
    }
  ],
  "additionalProperties": false,
  "definitions": {
    "semantics": {
      "type": "object",
      "properties": {
        "profile": {
          "type": "string",
          "enum": [
            "course_profiler_v1"
          ]
        },
        "schema_url": {
          "type": "string"
        },
        "interpretation_url": {
          "type": "string"
        }
      },
      "required": [
        "profile"
      ],
      "additionalProperties": false
    },
    "link": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string"
        },
        "url": {
          "type": "string",
          "minLength": 1
        },
        "tooltip": {
          "type": "string"
        }
      },
      "required": [
        "type",
        "url"
      ],
      "additionalProperties": false
    },
    "annotations": {
      "type": "object",
      "properties": {
        "ranges": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/range_annotation"
          }
        }
      },
      "additionalProperties": false
    },
    "range_annotation": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "start": {
          "type": "number",
          "minimum": 0
        },
        "end": {
          "type": "number",
          "minimum": 0
        },
        "gain": {
          "type": "number",
          "minimum": 0
        },
        "loss": {
          "type": "number",
          "minimum": 0
        },
        "elapsed": {
          "type": "number",
          "minimum": 0
        },
        "text": {
          "type": "string"
        },
        "color": {
          "type": "string"
        }
      },
      "required": [
        "start",
        "end",
        "gain",
        "loss"
      ],
      "additionalProperties": false
    },
    "event": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "course": {
          "type": "string"
        },
        "types": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "uniqueItems": true
        },
        "date": {
          "type": "string"
        },
        "time": {
          "type": "string",
          "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
        },
        "location": {
          "type": "string"
        },
        "country": {
          "type": "string"
        },
        "organizer": {
          "$ref": "#/definitions/event_organizer"
        },
        "competitions": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/event_competition"
          }
        },
        "links": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/link"
          }
        }
      },
      "additionalProperties": false
    },
    "event_organizer": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "url": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "event_competition": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "url": {
          "type": "string"
        },
        "country": {
          "type": "string"
        },
        "season": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "track": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "type": {
          "type": "string"
        },
        "start_time": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "point": {
      "type": "object",
      "properties": {
        "distance": {
          "type": "number"
        },
        "elevation": {
          "type": "number"
        },
        "lat": {
          "type": "number"
        },
        "lon": {
          "type": "number"
        },
        "time": {
          "type": "number"
        },
        "hr": {
          "type": "number"
        },
        "cad": {
          "type": "number"
        }
      },
      "required": [
        "distance",
        "elevation",
        "lat",
        "lon"
      ],
      "additionalProperties": false
    },
    "gpx_source": {
      "type": "object",
      "properties": {
        "track": {
          "$ref": "#/definitions/track"
        },
        "points": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/point"
          }
        }
      },
      "required": [
        "points"
      ],
      "additionalProperties": false
    },
    "analysis_options": {
      "type": "object",
      "properties": {
        "include_routes": {
          "type": "boolean"
        },
        "include_waypoints": {
          "type": "boolean"
        },
        "distance_algorithm": {
          "type": "string"
        },
        "gap_algorithm": {
          "type": "string"
        },
        "use_3d": {
          "type": "boolean"
        },
        "elevation_threshold": {
          "type": "number"
        },
        "smoothing_window": {
          "type": "integer"
        }
      },
      "additionalProperties": false
    },
    "reference_segmentation_options": {
      "type": "object",
      "properties": {
        "enabled": {
          "type": "boolean"
        },
        "algorithm": {
          "type": "string"
        },
        "flat_grade": {
          "type": "number"
        },
        "slope_change_threshold": {
          "type": "number"
        },
        "flat_max_elevation_delta": {
          "type": [
            "number",
            "null"
          ]
        },
        "minimum_distance": {
          "type": "number"
        },
        "flexible_minimum_distance": {
          "type": "boolean"
        },
        "flexible_flat_max_elevation_delta": {
          "type": "boolean"
        }
      },
      "additionalProperties": false
    },
    "reference_options": {
      "type": "object",
      "properties": {
        "segmentation": {
          "$ref": "#/definitions/reference_segmentation_options"
        }
      },
      "additionalProperties": false
    },
    "execution_options": {
      "type": "object",
      "properties": {
        "moving_threshold": {
          "type": "number"
        },
        "auto_stop_threshold": {
          "type": "number"
        },
        "auto_stop_merge_distance": {
          "type": "number"
        }
      },
      "additionalProperties": false
    },
    "checkpoint_window": {
      "type": "object",
      "properties": {
        "split_index": {
          "type": "integer",
          "minimum": 0
        },
        "min_elapsed": {
          "type": "number",
          "minimum": 0
        },
        "max_elapsed": {
          "type": "number",
          "minimum": 0
        },
        "enabled": {
          "type": "boolean"
        },
        "rule": {
          "type": "string",
          "enum": [
            "hard",
            "soft"
          ]
        }
      },
      "required": [
        "split_index"
      ],
      "additionalProperties": false
    },
    "estimation_options": {
      "type": "object",
      "properties": {
        "pace": {
          "type": "number"
        },
        "pace_distance_reference": {
          "type": "number"
        },
        "pace_distance_exponent": {
          "type": "number"
        },
        "use_tech": {
          "type": "boolean"
        },
        "tech_mode": {
          "type": "string",
          "enum": [
            "none",
            "user_defined",
            "inferred"
          ]
        },
        "fatigue_factor": {
          "type": "number"
        },
        "fatigue_model": {
          "type": "string",
          "enum": [
            "exponent",
            "progressive_kick",
            "history_adaptive_phases",
            "load_first_adaptive"
          ]
        },
        "fatigue_phase_profile": {
          "type": "array",
          "minItems": 5,
          "maxItems": 5,
          "items": {
            "type": "number"
          }
        },
        "hike_grade_threshold": {
          "type": "number"
        },
        "use_altitude": {
          "type": "boolean"
        },
        "use_weather": {
          "type": "boolean"
        },
        "checkpoint_windows": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/checkpoint_window"
          }
        }
      },
      "additionalProperties": false
    },
    "load_channel": {
      "type": "object",
      "properties": {
        "start": {
          "type": "number"
        },
        "delta": {
          "type": "number"
        }
      },
      "required": [
        "start",
        "delta"
      ],
      "additionalProperties": false
    },
    "technical_metrics": {
      "type": "object",
      "properties": {
        "vam": {
          "type": "number"
        },
        "descent_stress": {
          "type": "number"
        },
        "climb_efficiency": {
          "type": "number"
        }
      },
      "additionalProperties": false
    },
    "execution_metrics": {
      "type": "object",
      "properties": {
        "motion": {
          "type": "object",
          "properties": {
            "locomotion": {
              "type": "string",
              "enum": [
                "run",
                "hike",
                "walk",
                "stop"
              ]
            }
          },
          "required": [
            "locomotion"
          ],
          "additionalProperties": false
        },
        "physiological": {
          "type": "object",
          "properties": {
            "avg_hr": {
              "type": "number"
            },
            "avg_cad": {
              "type": "number"
            }
          },
          "additionalProperties": false
        },
        "load": {
          "type": "object",
          "properties": {
            "metabolic": {
              "$ref": "#/definitions/load_channel"
            },
            "muscular": {
              "$ref": "#/definitions/load_channel"
            }
          },
          "additionalProperties": false
        },
        "technical": {
          "$ref": "#/definitions/technical_metrics"
        }
      },
      "required": [
        "motion"
      ],
      "additionalProperties": false
    },
    "plan_overlay": {
      "type": "object",
      "properties": {
        "elapsed": {
          "type": "number",
          "minimum": 0
        },
        "grade_adjusted": {
          "type": "number",
          "minimum": 0
        },
        "metrics": {
          "$ref": "#/definitions/plan_metrics"
        }
      },
      "required": [
        "elapsed"
      ],
      "additionalProperties": false
    },
    "plan_metrics": {
      "type": "object",
      "properties": {
        "motion": {
          "type": "object",
          "properties": {
            "locomotion": {
              "type": "string",
              "enum": [
                "run",
                "hike",
                "walk",
                "stop"
              ]
            }
          },
          "required": [
            "locomotion"
          ],
          "additionalProperties": false
        },
        "load": {
          "type": "object",
          "properties": {
            "metabolic": {
              "$ref": "#/definitions/load_channel"
            },
            "muscular": {
              "$ref": "#/definitions/load_channel"
            }
          },
          "additionalProperties": false
        },
        "technical": {
          "$ref": "#/definitions/technical_metrics"
        }
      },
      "additionalProperties": false
    },
    "execution_overlay": {
      "type": "object",
      "properties": {
        "elapsed_start": {
          "type": "number",
          "minimum": 0
        },
        "elapsed": {
          "type": "number",
          "minimum": 0
        },
        "moving": {
          "type": "number",
          "minimum": 0
        },
        "grade_adjusted": {
          "type": "number",
          "minimum": 0
        },
        "distance": {
          "type": "number",
          "minimum": 0
        },
        "gain": {
          "type": "number",
          "minimum": 0
        },
        "loss": {
          "type": "number",
          "minimum": 0
        },
        "metrics": {
          "$ref": "#/definitions/execution_metrics"
        }
      },
      "required": [
        "elapsed_start",
        "elapsed",
        "metrics"
      ],
      "additionalProperties": false
    },
    "segment": {
      "type": "object",
      "properties": {
        "index": {
          "type": "integer"
        },
        "start": {
          "type": "number",
          "minimum": 0
        },
        "distance": {
          "type": "number",
          "minimum": 0
        },
        "gain": {
          "type": "number",
          "minimum": 0
        },
        "loss": {
          "type": "number",
          "minimum": 0
        },
        "name": {
          "type": "string"
        },
        "note": {
          "type": "string"
        },
        "resources": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "water",
              "water_source",
              "drinks",
              "fruit",
              "food",
              "toilet",
              "medic",
              "chrono",
              "crew",
              "pacer",
              "car",
              "bus",
              "ambulance",
              "shuttle",
              "drop_bag",
              "withdrawal",
              "binoculars",
              "hot_meal",
              "tent",
              "showers",
              "changing_room",
              "physiotherapy",
              "rest_area",
              "start_flag",
              "finish_flag"
            ]
          }
        },
        "cutoff": {
          "type": "string"
        },
        "split_separator": {
          "type": "boolean"
        },
        "links": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/link"
          }
        },
        "tech": {
          "type": "number"
        },
        "plan": {
          "$ref": "#/definitions/plan_overlay"
        },
        "execution": {
          "$ref": "#/definitions/execution_overlay"
        }
      },
      "required": [
        "index",
        "start",
        "distance",
        "gain",
        "loss"
      ],
      "additionalProperties": false
    },
    "indexes": {
      "type": "object",
      "properties": {
        "course": {
          "type": "object",
          "properties": {
            "score": {
              "type": "number"
            },
            "weighted_distance_km": {
              "type": "number"
            },
            "climb_penalty": {
              "type": "number"
            },
            "climb_multiplier": {
              "type": "number"
            },
            "surface_factor": {
              "type": "number"
            },
            "surface_label": {
              "type": "string"
            },
            "surface_source": {
              "type": "string",
              "enum": [
                "event",
                "inferred",
                "default"
              ]
            },
            "altitude_factor": {
              "type": "number"
            },
            "altitude_fraction": {
              "type": "number"
            },
            "altitude_tranches": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "min_meters": {
                    "type": "number"
                  },
                  "max_meters": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "distance_meters": {
                    "type": "number"
                  },
                  "distance_fraction": {
                    "type": "number"
                  }
                },
                "required": [
                  "min_meters",
                  "distance_meters",
                  "distance_fraction"
                ],
                "additionalProperties": false
              }
            }
          },
          "required": [
            "score"
          ],
          "additionalProperties": false
        },
        "ability": {
          "type": "number"
        },
        "completion": {
          "type": "number"
        },
        "performance": {
          "type": "object",
          "properties": {
            "score": {
              "type": "number"
            }
          },
          "required": [
            "score"
          ],
          "additionalProperties": false
        }
      },
      "additionalProperties": false
    }
  }
}
