{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"$id": "https://2timer.app/omd/schemas/meet-display-v1.schema.json",
	"title": "Open Meet Display message, version 1",
	"description": "One Open Meet Display message: a complete snapshot of what one display target should show. It checks every 1.x message. Receivers must ignore fields they do not recognise, so every object allows additional properties, and a kind this schema does not list is checked against the envelope only. Every value is a display string; a field with no value is left out, and a receiver treats a missing field and a null one alike.",
	"type": "object",
	"required": ["omd", "meet", "display"],
	"properties": {
		"omd": {
			"type": "object",
			"description": "What this message is and who wrote it.",
			"required": ["version", "kind", "generator", "sent_at"],
			"properties": {
				"version": {
					"type": "string",
					"pattern": "^1\\.\\d+$",
					"description": "MAJOR.MINOR. A receiver reads any 1.x message."
				},
				"kind": {
					"type": "string",
					"description": "start_list, results, team_scores, announcement, or clear. Open: accept and ignore a kind you do not show."
				},
				"generator": { "$ref": "#/$defs/generator" },
				"sent_at": {
					"type": "string",
					"format": "date-time",
					"description": "When the producer built the message, ISO 8601 UTC."
				}
			}
		},
		"meet": {
			"type": "object",
			"required": ["name", "start_date", "end_date", "sport"],
			"properties": {
				"id": { "$ref": "#/$defs/text", "description": "The meet's stable identity." },
				"name": { "type": "string" },
				"start_date": { "$ref": "#/$defs/date" },
				"end_date": { "$ref": "#/$defs/date" },
				"sport": {
					"type": "string",
					"description": "OMX's sports: xc, tf-indoor, tf-outdoor, run. Open."
				}
			}
		},
		"display": {
			"type": "object",
			"required": ["target", "mode"],
			"properties": {
				"target": { "type": "string", "minLength": 1 },
				"mode": { "type": "string", "description": "replace in 1.x." },
				"connection_id": {
					"$ref": "#/$defs/text",
					"description": "The producer connection that sent the message. A label, not a credential."
				}
			}
		}
	},
	"allOf": [
		{
			"if": {
				"required": ["omd"],
				"properties": {
					"omd": {
						"required": ["kind"],
						"properties": { "kind": { "const": "start_list" } }
					}
				}
			},
			"then": {
				"required": ["event", "start_list"],
				"properties": {
					"event": { "$ref": "#/$defs/event" },
					"start_list": { "$ref": "#/$defs/eventRows" }
				}
			}
		},
		{
			"if": {
				"required": ["omd"],
				"properties": {
					"omd": {
						"required": ["kind"],
						"properties": { "kind": { "const": "results" } }
					}
				}
			},
			"then": {
				"required": ["event", "results"],
				"properties": {
					"event": { "$ref": "#/$defs/event" },
					"results": { "$ref": "#/$defs/eventRows" }
				}
			}
		},
		{
			"if": {
				"required": ["omd"],
				"properties": {
					"omd": { "required": ["kind"], "properties": { "kind": { "const": "team_scores" } } }
				}
			},
			"then": {
				"required": ["team_scores"],
				"properties": {
					"event": { "$ref": "#/$defs/event" },
					"team_scores": { "$ref": "#/$defs/teamScores" }
				},
				"if": {
					"properties": { "team_scores": { "properties": { "scope": { "const": "event" } } } }
				},
				"then": { "required": ["event"] }
			}
		},
		{
			"if": {
				"required": ["omd"],
				"properties": {
					"omd": { "required": ["kind"], "properties": { "kind": { "const": "announcement" } } }
				}
			},
			"then": {
				"required": ["announcement"],
				"properties": { "announcement": { "$ref": "#/$defs/announcement" } }
			}
		}
	],
	"$defs": {
		"date": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
		"text": { "type": ["string", "null"] },
		"eventRows": {
			"type": "object",
			"required": ["rows"],
			"properties": {
				"rows": { "type": "array", "items": { "$ref": "#/$defs/eventRow" } }
			}
		},
		"generator": {
			"type": "object",
			"description": "The product that wrote this JSON, in the same shape as OMX's generator.",
			"required": ["id", "name"],
			"properties": {
				"id": {
					"type": "string",
					"minLength": 1,
					"description": "A short name the product picks for itself, once, and never changes."
				},
				"name": { "type": "string", "minLength": 1, "description": "The product's name." },
				"version": { "$ref": "#/$defs/text", "description": "The product's version." }
			}
		},
		"team": {
			"type": ["object", "null"],
			"required": ["name"],
			"properties": {
				"name": { "type": "string" },
				"short_name": {
					"$ref": "#/$defs/text",
					"description": "What fits on a narrow board, such as the team's code."
				}
			}
		},
		"event": {
			"type": "object",
			"required": ["name"],
			"properties": {
				"id": { "$ref": "#/$defs/text" },
				"number": { "$ref": "#/$defs/text" },
				"name": { "type": "string" },
				"code": {
					"$ref": "#/$defs/text",
					"description": "OMX's event code, such as 100, 4X400, or LJ. Left out when OMX has none."
				},
				"round": { "$ref": "#/$defs/text" },
				"round_label": { "$ref": "#/$defs/text" },
				"section_name": { "$ref": "#/$defs/text" },
				"gender": {
					"$ref": "#/$defs/text",
					"description": "M, F, X (non-binary), or C (everyone: mixed, combined, or co-ed), as in OMX. Open: show an unknown value as text."
				},
				"entry_type": { "$ref": "#/$defs/text" },
				"wind": { "$ref": "#/$defs/text" }
			}
		},
		"eventRow": {
			"type": "object",
			"required": ["participant_name"],
			"properties": {
				"entry_id": { "$ref": "#/$defs/text" },
				"start_assignment": { "$ref": "#/$defs/text" },
				"participant_name": { "type": "string" },
				"bib": { "$ref": "#/$defs/text" },
				"team": { "$ref": "#/$defs/team" },
				"relay_legs": { "type": ["array", "null"], "items": { "type": "string" } },
				"seed": { "$ref": "#/$defs/text" },
				"result": { "$ref": "#/$defs/text" },
				"status": {
					"$ref": "#/$defs/text",
					"description": "dnf, dns, dq, fs, scr, or nr; exh is reserved. A row with a place has none. Open."
				},
				"place": { "$ref": "#/$defs/text" },
				"wind": { "$ref": "#/$defs/text" },
				"points": { "$ref": "#/$defs/text" },
				"scoring_role": { "$ref": "#/$defs/text" },
				"multi_points": { "$ref": "#/$defs/text" }
			}
		},
		"teamScores": {
			"type": "object",
			"required": ["scope", "gender", "rows"],
			"properties": {
				"scope": { "type": "string", "description": "meet or event. Open." },
				"division_name": { "$ref": "#/$defs/text" },
				"gender": {
					"$ref": "#/$defs/text",
					"description": "Whose standings these are, always present: M, F, or X for one gender, C for standings that count every gender together. Open."
				},
				"rows": {
					"type": "array",
					"items": {
						"type": "object",
						"required": ["place", "team", "points"],
						"properties": {
							"place": { "type": "string" },
							"team": { "$ref": "#/$defs/team" },
							"points": { "type": "string" }
						}
					}
				}
			}
		},
		"announcement": {
			"type": "object",
			"required": ["message"],
			"properties": {
				"title": { "$ref": "#/$defs/text" },
				"message": { "type": "string", "minLength": 1 },
				"priority": { "$ref": "#/$defs/text" },
				"expires_at": { "type": ["string", "null"], "format": "date-time" }
			}
		}
	}
}
