{
  "$ref": "#/definitions/Choices",
  "definitions": {
    "Choices": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "pattern": "^[a-z0-9-]+$",
            "description": "Stable slug identifier, lowercase, e.g. \"ods\", \"ano\", \"spolu\". Should remain stable across election cycles. Used as the foreign key in PollResult.choice_id, DerivedResult.choice_id, and Estimate.choice_id across all pipeline layers."
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "description": "Canonical display name in the primary language of the region. Use `names` for multilingual variants."
          },
          "short_name": {
            "type": "string",
            "minLength": 1,
            "description": "Abbreviated name for charts and tables, e.g. \"ODS\", \"SPOLU\"."
          },
          "names": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "minLength": 1
            },
            "propertyNames": {
              "pattern": "^[a-z]{2}(-[A-Z]{2})?$"
            },
            "description": "Optional multilingual name map (BCP 47 locale → string). Example: { \"cs\": \"Občanská demokratická strana\", \"en\": \"Civic Democratic Party\" }"
          },
          "region": {
            "anyOf": [
              {
                "type": "string",
                "minLength": 1
              },
              {
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1
                }
              }
            ],
            "description": "Region(s) this choice is active in. ISO 3166-1 alpha-2 (country) or ISO 3166-2 (sub-national) codes."
          },
          "color": {
            "type": "string",
            "description": "Primary brand color. Canonical form: CSS hex (#rrggbb or #rrggbbaa)."
          },
          "logo_url": {
            "type": "string",
            "format": "uri",
            "description": "URL to the choice's logo (SVG or PNG preferred)."
          },
          "type": {
            "type": "string",
            "description": "Entity type. Canonical values: \"party\", \"coalition\". Other values allowed."
          },
          "members": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1
            },
            "description": "IDs of constituent choices (for coalitions). References other Choice.id values."
          },
          "member_shares": {
            "type": "object",
            "additionalProperties": {
              "type": "number",
              "minimum": 0
            },
            "propertyNames": {
              "minLength": 1
            },
            "description": "Fractional split weights for each member (values 0–1, sum ≈ 1). Used as the default distribution key when a poll reports only the aggregate coalition value. Example (SPOLU 2025 seats): { \"ods\": 0.67, \"top-09\": 0.19, \"kdu-csl\": 0.14 }"
          },
          "historical_results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "election_id": {
                  "type": "string",
                  "minLength": 1,
                  "description": "Identifier for the election, e.g. \"cz-parliament-2021\"."
                },
                "choice_id": {
                  "type": "string",
                  "minLength": 1,
                  "description": "The choice_id as it appeared in that election. Omit when identical to the current Choice.id. Use when the party ran under a different name/coalition (e.g. storing ODS's 2021 result on the SPOLU coalition choice)."
                },
                "values": {
                  "type": "object",
                  "additionalProperties": {
                    "type": [
                      "string",
                      "number",
                      "null"
                    ]
                  },
                  "description": "Flexible numeric or string values for this election result. Recommended keys: \"percent\", \"seats\", \"rank\", \"votes\". Example: { \"percent\": 27.7, \"seats\": 71 }"
                }
              },
              "required": [
                "election_id",
                "values"
              ],
              "additionalProperties": false,
              "description": "One previous-election result stored on a Choice.\n\nLayer: reference data (embedded in Choice)\n\nUsed to track what a party, coalition, or candidate achieved in past elections, even if the choice ran under a different ID at the time."
            },
            "description": "Historical election results for this choice."
          },
          "extras": {
            "type": "object",
            "additionalProperties": {},
            "description": "Extension point for additional fields."
          }
        },
        "required": [
          "id",
          "name",
          "short_name"
        ],
        "additionalProperties": false,
        "description": "Any entity that can appear in poll results: party, coalition, or independent grouping.\n\nLayer: reference data\n\nChoice.id is the stable key used across all pipeline layers: PollResult.choice_id (source), DerivedResult.choice_id (compute), Estimate.choice_id (aggregate)."
      },
      "description": "Array of Choice objects."
    }
  },
  "$schema": "http://json-schema.org/draft-07/schema#"
}