{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "properties": {
    "frame": {
      "$ref": "#/definitions/Frame"
    },
    "consolidated": {
      "$ref": "#/definitions/ConsolidatedTrack"
    }
  },
  "definitions": {
    "ObjectClassification": {
      "anyOf": [
        {
          "$ref": "#/definitions/Animal"
        },
        {
          "$ref": "#/definitions/Bag"
        },
        {
          "$ref": "#/definitions/Backpack"
        },
        {
          "$ref": "#/definitions/Bike"
        },
        {
          "$ref": "#/definitions/Bus"
        },
        {
          "$ref": "#/definitions/Car"
        },
        {
          "$ref": "#/definitions/Face"
        },
        {
          "$ref": "#/definitions/Human"
        },
        {
          "$ref": "#/definitions/LicensePlate"
        },
        {
          "$ref": "#/definitions/Suitcase"
        },
        {
          "$ref": "#/definitions/Truck"
        },
        {
          "$ref": "#/definitions/Vehicle"
        }
      ]
    },
    "Animal": {
      "type": "object",
      "properties": {
        "type": {
          "const": "Animal",
          "$ref": "#/definitions/String"
        },
        "score": {
          "$ref": "#/definitions/Float"
        }
      },
      "required": ["type", "score"],
      "additionalProperties": false
    },
    "String": {
      "type": "string",
      "title": "String",
      "description": "The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text."
    },
    "Float": {
      "type": "number",
      "title": "Float",
      "description": "The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point)."
    },
    "Bag": {
      "type": "object",
      "properties": {
        "type": {
          "const": "Bag",
          "$ref": "#/definitions/String"
        },
        "score": {
          "$ref": "#/definitions/Float"
        }
      },
      "required": ["type", "score"],
      "additionalProperties": false
    },
    "Backpack": {
      "type": "object",
      "properties": {
        "type": {
          "const": "Backpack",
          "$ref": "#/definitions/String"
        },
        "score": {
          "$ref": "#/definitions/Float"
        }
      },
      "required": ["type", "score"],
      "additionalProperties": false
    },
    "Suitcase": {
      "type": "object",
      "properties": {
        "type": {
          "const": "Suitcase",
          "$ref": "#/definitions/String"
        },
        "score": {
          "$ref": "#/definitions/Float"
        }
      },
      "required": ["type", "score"],
      "additionalProperties": false
    },
    "Bike": {
      "type": "object",
      "properties": {
        "type": {
          "const": "Bike",
          "$ref": "#/definitions/String"
        },
        "score": {
          "$ref": "#/definitions/Float"
        }
      },
      "required": ["type", "score"],
      "additionalProperties": false
    },
    "Bus": {
      "type": "object",
      "properties": {
        "type": {
          "const": "Bus",
          "$ref": "#/definitions/String"
        },
        "score": {
          "$ref": "#/definitions/Float"
        },
        "colors": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Color"
          }
        }
      },
      "required": ["type", "score"],
      "additionalProperties": false
    },
    "Car": {
      "type": "object",
      "properties": {
        "type": {
          "const": "Car",
          "$ref": "#/definitions/String"
        },
        "score": {
          "$ref": "#/definitions/Float"
        },
        "colors": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Color"
          }
        }
      },
      "required": ["type", "score"],
      "additionalProperties": false
    },
    "Face": {
      "type": "object",
      "properties": {
        "type": {
          "const": "Face",
          "$ref": "#/definitions/String"
        },
        "score": {
          "$ref": "#/definitions/Float"
        },
        "hat": {
          "$ref": "#/definitions/Hat"
        }
      },
      "required": ["type", "score"],
      "additionalProperties": false
    },
    "Human": {
      "type": "object",
      "properties": {
        "type": {
          "const": "Human",
          "$ref": "#/definitions/String"
        },
        "score": {
          "$ref": "#/definitions/Float"
        },
        "upper_clothing_colors": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Color"
          }
        },
        "lower_clothing_colors": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Color"
          }
        }
      },
      "required": ["type", "score"],
      "additionalProperties": false
    },
    "LicensePlate": {
      "type": "object",
      "properties": {
        "type": {
          "const": "LicensePlate",
          "$ref": "#/definitions/String"
        },
        "score": {
          "$ref": "#/definitions/Float"
        },
        "country_code": {
          "$ref": "#/definitions/String"
        },
        "plate_number": {
          "$ref": "#/definitions/String"
        }
      },
      "required": ["type", "score"],
      "additionalProperties": false
    },
    "Truck": {
      "type": "object",
      "properties": {
        "type": {
          "const": "Truck",
          "$ref": "#/definitions/String"
        },
        "score": {
          "$ref": "#/definitions/Float"
        },
        "colors": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Color"
          }
        }
      },
      "required": ["type", "score"],
      "additionalProperties": false
    },
    "Vehicle": {
      "type": "object",
      "properties": {
        "type": {
          "const": "Vehicle",
          "$ref": "#/definitions/String"
        },
        "score": {
          "$ref": "#/definitions/Float"
        },
        "colors": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Color"
          }
        }
      },
      "required": ["type", "score"],
      "additionalProperties": false
    },
    "Frame": {
      "type": "object",
      "properties": {
        "timestamp": {
          "description": "According to format: YYYY-MM-DDTHH:MM:SS.MMMMMMZ",
          "$ref": "#/definitions/String"
        },
        "observations": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/TrackedObjectObservation"
          }
        },
        "operations": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Operation"
          }
        }
      },
      "required": ["timestamp", "observations", "operations"],
      "additionalProperties": false
    },
    "TrackEndReason": {
      "type": "string",
      "anyOf": [
        {
          "enum": ["Completed"],
          "title": "Completed"
        },
        {
          "enum": ["Invalid"],
          "title": "Invalid"
        }
      ],
      "description": "No more updates for this track after its ended.\n\nCompleted: Track ended successfully\nInvalid: Remove all previous instances of this object"
    },
    "ConsolidatedTrack": {
      "type": "object",
      "properties": {
        "id": {
          "$ref": "#/definitions/ID"
        },
        "classes": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/ObjectClassification"
          }
        },
        "start_time": {
          "$ref": "#/definitions/String"
        },
        "end_time": {
          "description": "Last observation timestamp. Only set when track has ended.",
          "$ref": "#/definitions/String"
        },
        "end_reason": {
          "description": "Reason for ending track, if no end_reason interpret as Completed",
          "$ref": "#/definitions/TrackEndReason"
        },
        "duration": {
          "description": "last observation monotime - first observation monotime. In seconds",
          "$ref": "#/definitions/Float"
        },
        "observations": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/TrackedObjectObservation"
          }
        },
        "image": {
          "$ref": "#/definitions/Image"
        },
        "maximum_speed": {
          "description": "The maximum relative speed of the object compared to the device in m/s.",
          "$ref": "#/definitions/Float"
        },
        "minimum_speed": {
          "description": "The minimum relative speed of the object compared to the device in m/s.",
          "$ref": "#/definitions/Float"
        }
      },
      "required": ["id", "start_time", "duration"],
      "description": "A summary of a number of observations that with high confidence appears to be\nthe same physical object based on both spatio-temporal movement and\nclassification/appearance.",
      "additionalProperties": false
    },
    "ID": {
      "type": "string",
      "title": "ID",
      "description": "The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `\"4\"`) or integer (such as `4`) input value will be accepted as an ID."
    },
    "TrackedObjectObservation": {
      "type": "object",
      "properties": {
        "timestamp": {
          "$ref": "#/definitions/String"
        },
        "track_id": {
          "$ref": "#/definitions/ID"
        },
        "velocity": {
          "description": "The velocity in the image of the object, in normalized coordinates.",
          "$ref": "#/definitions/ImageVelocity"
        },
        "bounding_box": {
          "description": "Bounding box describes an object's surrounding rectangle.",
          "$ref": "#/definitions/BoundingBox"
        },
        "class": {
          "$ref": "#/definitions/ObjectClassification"
        },
        "classes": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/ObjectClassification"
          }
        },
        "image": {
          "description": "Image cropped around the detected object.",
          "$ref": "#/definitions/Image"
        },
        "world_position": {
          "description": "The position of the object relative to the device channel that made this\ndetection.",
          "$ref": "#/definitions/SphericalCoordinate"
        },
        "world_velocity": {
          "description": "The velocity of the object relative to the device channel that made this\ndetection.",
          "$ref": "#/definitions/SphericalCoordinate"
        },
        "geoposition": {
          "description": "The geographic position of the object.",
          "$ref": "#/definitions/GeographicPosition"
        }
      },
      "required": ["bounding_box", "timestamp"],
      "description": "The detection contains information that corresponds approximately to a single\nframe. Interpolation between frames and similar operations may be present but\ndata is not aggregated over multiple frames.",
      "additionalProperties": false
    },
    "Operation": {
      "anyOf": [
        {
          "$ref": "#/definitions/DeleteOperation"
        },
        {
          "$ref": "#/definitions/RenameOperation"
        }
      ]
    },
    "DeleteOperation": {
      "type": "object",
      "properties": {
        "type": {
          "const": "DeleteOperation",
          "$ref": "#/definitions/String"
        },
        "id": {
          "$ref": "#/definitions/ID"
        }
      },
      "required": ["type", "id"],
      "description": "Operation signaling that an object id will not reappear in future observations.",
      "additionalProperties": false
    },
    "RenameOperation": {
      "type": "object",
      "properties": {
        "type": {
          "const": "RenameOperation",
          "$ref": "#/definitions/String"
        },
        "from": {
          "$ref": "#/definitions/ID"
        },
        "to": {
          "$ref": "#/definitions/ID"
        }
      },
      "required": ["type", "from", "to"],
      "description": "Operation signaling that the from id should be renamed to the to id in all\nprevious instances of TrackedObjectObservation that contain the from id.",
      "additionalProperties": false
    },
    "BoundingBox": {
      "type": "object",
      "properties": {
        "left": {
          "$ref": "#/definitions/Float"
        },
        "top": {
          "$ref": "#/definitions/Float"
        },
        "right": {
          "$ref": "#/definitions/Float"
        },
        "bottom": {
          "$ref": "#/definitions/Float"
        }
      },
      "required": ["left", "top", "right", "bottom"],
      "description": "The coordinate system used in Axis Metadata Format is normalised image\ncoordinates: The x-axis pointing to the right and the y-axis pointing down,\nwith the upper left hand corner as (0,0) and the lower right hand corner as\n(1,1). Thus all coordinates have positive values inside the image. This\nrepresents how many digital image libraries handles image coordinates.",
      "additionalProperties": false
    },
    "ImageVelocity": {
      "type": "object",
      "properties": {
        "vx": {
          "$ref": "#/definitions/Float"
        },
        "vy": {
          "$ref": "#/definitions/Float"
        }
      },
      "required": ["vx", "vy"],
      "description": "A velocity in image space. The velocity unit is in normalised image units per\nsecond (see the documentation for BoundingBox).",
      "additionalProperties": false
    },
    "GeographicPosition": {
      "type": "object",
      "properties": {
        "latitude": {
          "$ref": "#/definitions/Float"
        },
        "longitude": {
          "$ref": "#/definitions/Float"
        },
        "elevation": {
          "$ref": "#/definitions/Float"
        }
      },
      "required": ["latitude", "longitude"],
      "description": "A type representing a geographic position (geolocation) on Earth, with an\noptional elevation component.\n\nThe longitude and latitude are given in degrees as defined by the Global\nPosition System (GPS) and WGS84. The latitude is 0\u00b0 at the equator, increasing\nnorthwards. The longitude is defined to be 0\u00b0 at the IERS prime meridian,\nincreasing eastwards. The elevation, if present, is specified in meters.",
      "additionalProperties": false
    },
    "SphericalCoordinate": {
      "type": "object",
      "properties": {
        "r": {
          "$ref": "#/definitions/Float"
        },
        "azimuth": {
          "$ref": "#/definitions/Float"
        },
        "elevation": {
          "$ref": "#/definitions/Float"
        }
      },
      "required": ["r", "azimuth", "elevation"],
      "description": "Represents a vector described in spherical coordinates.\n\nFor a vector that represents a position or velocity relative to the device, the\ncoordinate system used is the same as defined in the ONVIF Analytics Service\nSpecification:\n\n  - The device is placed in origin of a right-handed coordinate system where\n    the positive X axis is rightwards relative to the device, the positive Y\n    axis points away from the device, and the positive Z axis points upwards.\n\n  - The magnitude (r) is given in SI units: meters for a position, and meters\n    per second for a velocity.\n\n  - The elevation angle (\u03b8) is the vertical angle from the X-Y plane spanning\n    from -90 to 90 degrees and increasing upwards. The value 0\u00b0 indicates no\n    relative elevation difference (level in the X-Y plane).\n\n  - The azimuth angle (\u03c6) is the rotation angle around the Z axis, spanning\n    from -180 to 180 degrees and increasing counterclockwise, i.e. rightwards\n    as seen from the device. The value 0\u00b0 indicates straight ahead.",
      "additionalProperties": false
    },
    "Image": {
      "type": "object",
      "properties": {
        "timestamp": {
          "description": "According to format: YYYY-MM-DDTHH:MM:SS.MMMMMMZ",
          "$ref": "#/definitions/String"
        },
        "bounding_box": {
          "description": "Bounding box for image crop. Note that the image crop may not be the same as\nthe detection bounding box since there may be a margin.",
          "$ref": "#/definitions/BoundingBox"
        },
        "data": {
          "description": "Image payload. Base64 encoded when serialized to json.",
          "$ref": "#/definitions/String"
        }
      },
      "required": ["bounding_box", "data"],
      "description": "Cropped image",
      "additionalProperties": false
    },
    "ColorName": {
      "type": "string",
      "anyOf": [
        {
          "enum": ["Beige"],
          "title": "Beige"
        },
        {
          "enum": ["Black"],
          "title": "Black"
        },
        {
          "enum": ["Blue"],
          "title": "Blue"
        },
        {
          "enum": ["Gray"],
          "title": "Gray"
        },
        {
          "enum": ["Green"],
          "title": "Green"
        },
        {
          "enum": ["Red"],
          "title": "Red"
        },
        {
          "enum": ["White"],
          "title": "White"
        },
        {
          "enum": ["Yellow"],
          "title": "Yellow"
        }
      ]
    },
    "Color": {
      "type": "object",
      "properties": {
        "name": {
          "$ref": "#/definitions/ColorName"
        },
        "score": {
          "$ref": "#/definitions/Float"
        }
      },
      "required": ["name", "score"],
      "additionalProperties": false
    },
    "HatName": {
      "type": "string",
      "anyOf": [
        {
          "enum": ["HardHat"],
          "title": "HardHat"
        },
        {
          "enum": ["Other"],
          "title": "Other"
        }
      ]
    },
    "Hat": {
      "type": "object",
      "properties": {
        "name": {
          "$ref": "#/definitions/HatName"
        },
        "score": {
          "$ref": "#/definitions/Float"
        }
      },
      "required": ["name", "score"],
      "additionalProperties": false
    },
    "Boolean": {
      "type": "boolean",
      "title": "Boolean",
      "description": "The `Boolean` scalar type represents `true` or `false`."
    }
  },
  "type": "object",
  "additionalProperties": false
}
