{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://cinemaswearstats.com/data/schema.json",
  "title": "Cinema Swear Stats dataset schema",
  "description": "Schema for the downloadable dataset wrapper, film aggregates, and future scene-level language events.",
  "type": "object",
  "required": [
    "version",
    "captured_at",
    "source",
    "films"
  ],
  "properties": {
    "version": {
      "type": "string"
    },
    "generated": {
      "type": "string",
      "format": "date"
    },
    "captured_at": {
      "type": "string",
      "format": "date"
    },
    "source": {
      "type": "string",
      "format": "uri"
    },
    "license_note": {
      "type": "string"
    },
    "methodology": {
      "type": "object"
    },
    "films": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/film"
      }
    }
  },
  "$defs": {
    "film": {
      "type": "object",
      "required": [
        "id",
        "rank",
        "title",
        "year",
        "count",
        "runtime",
        "computed_rate",
        "source_rate",
        "reference_status",
        "source_url",
        "captured_at"
      ],
      "properties": {
        "id": {
          "type": "string"
        },
        "slug": {
          "type": "string"
        },
        "rank": {
          "type": "integer",
          "minimum": 1
        },
        "title": {
          "type": "string",
          "minLength": 1
        },
        "year": {
          "type": "integer",
          "minimum": 1900,
          "maximum": 2100
        },
        "count": {
          "type": "integer",
          "minimum": 0
        },
        "runtime": {
          "type": "integer",
          "minimum": 1
        },
        "rate": {
          "type": "number",
          "minimum": 0
        },
        "computed_rate": {
          "type": "number",
          "minimum": 0
        },
        "source_rate": {
          "type": "number",
          "minimum": 0
        },
        "rate_delta": {
          "type": "number"
        },
        "rate_discrepancy": {
          "type": "boolean"
        },
        "reference_status": {
          "enum": [
            "cited",
            "citation-needed",
            "uncited"
          ]
        },
        "word": {
          "type": "string"
        },
        "source": {
          "type": "string"
        },
        "source_url": {
          "type": "string",
          "format": "uri"
        },
        "source_status": {
          "type": "string"
        },
        "captured_at": {
          "type": "string",
          "format": "date"
        },
        "language_events": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/languageEvent"
          }
        }
      }
    },
    "languageEvent": {
      "type": "object",
      "required": [
        "word",
        "normalized_word"
      ],
      "properties": {
        "word": {
          "type": "string"
        },
        "normalized_word": {
          "type": "string"
        },
        "timestamp_seconds": {
          "type": [
            "number",
            "null"
          ],
          "minimum": 0
        },
        "speaker": {
          "type": [
            "string",
            "null"
          ]
        },
        "actor": {
          "type": [
            "string",
            "null"
          ]
        },
        "context": {
          "type": [
            "string",
            "null"
          ]
        },
        "censorship": {
          "type": [
            "string",
            "null"
          ]
        },
        "cut": {
          "type": [
            "string",
            "null"
          ]
        },
        "confidence": {
          "type": [
            "number",
            "null"
          ],
          "minimum": 0,
          "maximum": 1
        },
        "source_url": {
          "type": [
            "string",
            "null"
          ],
          "format": "uri"
        },
        "source_note": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    }
  }
}
