{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://raw.githubusercontent.com/j2inn/hayson/master/hayson-json-schema.json",
  "anyOf": [
    {
      "$ref": "#/definitions/hval"
    }
  ],
  "definitions": {
    "grid": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "_kind",
        "meta"
      ],
      "properties": {
        "_kind": {
          "type": "string",
          "enum": [
            "grid"
          ]
        },
        "meta": {
          "$ref": "#/definitions/gridMeta"
        },
        "cols": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/gridColumn"
          }
        },
        "rows": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/dict"
          }
        }
      }
    },
    "gridMeta": {
      "allOf": [
        {
          "$ref": "#/definitions/dict"
        }
      ],
      "type": "object",
      "required": [
        "ver"
      ],
      "properties": {
        "ver": {
          "type": "string",
          "enum": [
            "3.0"
          ]
        }
      }
    },
    "gridColumn": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "name"
      ],
      "properties": {
        "name": {
          "type": "string"
        },
        "meta": {
          "$ref": "#/definitions/dict"
        }
      }
    },
    "dict": {
      "type": "object",
      "properties": {
        "_kind": {
          "type": "string",
          "enum": [
            "dict"
          ]
        }
      },
      "additionalProperties": false,
      "patternProperties": {
        "^[a-z][0-9a-zA-Z_]*": {
          "$ref": "#/definitions/hval"
        }
      }
    },
    "list": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/hval"
      }
    },
    "hval": {
      "oneOf": [
        {
          "type": "string"
        },
        {
          "type": "number"
        },
        {
          "type": "boolean"
        },
        {
          "$ref": "#/definitions/marker"
        },
        {
          "$ref": "#/definitions/remove"
        },
        {
          "$ref": "#/definitions/na"
        },
        {
          "$ref": "#/definitions/number"
        },
        {
          "$ref": "#/definitions/numberSpecial"
        },
        {
          "$ref": "#/definitions/symbol"
        },
        {
          "$ref": "#/definitions/ref"
        },
        {
          "$ref": "#/definitions/uri"
        },
        {
          "$ref": "#/definitions/date"
        },
        {
          "$ref": "#/definitions/time"
        },
        {
          "$ref": "#/definitions/dateTime"
        },
        {
          "$ref": "#/definitions/dict"
        },
        {
          "$ref": "#/definitions/list"
        },
        {
          "$ref": "#/definitions/grid"
        },
        {
          "$ref": "#/definitions/coord"
        },
        {
          "$ref": "#/definitions/xstr"
        }
      ]
    },
    "marker": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "_kind"
      ],
      "properties": {
        "_kind": {
          "type": "string",
          "enum": [
            "marker"
          ]
        }
      }
    },
    "remove": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "_kind"
      ],
      "properties": {
        "_kind": {
          "type": "string",
          "enum": [
            "remove"
          ]
        }
      }
    },
    "na": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "_kind"
      ],
      "properties": {
        "_kind": {
          "type": "string",
          "enum": [
            "na"
          ]
        }
      }
    },
    "number": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "_kind",
        "val"
      ],
      "properties": {
        "_kind": {
          "type": "string",
          "enum": [
            "number"
          ]
        },
        "val": {
          "type": "number"
        },
        "unit": {
          "type": "string",
          "pattern": "^([a-zA-Z%_/$]|[\\x80-\\xFFFF])+$"
        }
      }
    },
    "numberSpecial": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "_kind",
        "val"
      ],
      "properties": {
        "_kind": {
          "type": "string",
          "enum": [
            "number"
          ]
        },
        "val": {
          "type": "string",
          "enum": [
            "INF",
            "-INF",
            "NaN"
          ]
        }
      }
    },
    "uri": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "_kind",
        "val"
      ],
      "properties": {
        "_kind": {
          "type": "string",
          "enum": [
            "uri"
          ]
        },
        "val": {
          "type": "string"
        }
      }
    },
    "ref": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "_kind",
        "val"
      ],
      "properties": {
        "_kind": {
          "type": "string",
          "enum": [
            "ref"
          ]
        },
        "val": {
          "type": "string",
          "pattern": "^[0-9a-zA-Z_:\\-.~]+$"
        },
        "dis": {
          "type": "string"
        }
      }
    },
    "symbol": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "_kind",
        "val"
      ],
      "properties": {
        "_kind": {
          "type": "string",
          "enum": [
            "symbol"
          ]
        },
        "val": {
          "type": "string",
          "pattern": "^[0-9a-zA-Z_:\\-.~]+$"
        }
      }
    },
    "date": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "_kind",
        "val"
      ],
      "properties": {
        "_kind": {
          "type": "string",
          "enum": [
            "date"
          ]
        },
        "val": {
          "type": "string",
          "format": "date"
        }
      }
    },
    "time": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "_kind",
        "val"
      ],
      "properties": {
        "_kind": {
          "type": "string",
          "enum": [
            "time"
          ]
        },
        "val": {
          "type": "string",
          "pattern": "^(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\\.[0-9]+)?$"
        }
      }
    },
    "dateTime": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "_kind",
        "val"
      ],
      "properties": {
        "_kind": {
          "type": "string",
          "enum": [
            "dateTime"
          ]
        },
        "val": {
          "type": "string",
          "pattern": "^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\\.[0-9]+)?(Z|[-+](2[0-3]|[01][0-9]):[0-5][0-9])?$"
        },
        "tz": {
          "type": "string",
          "minLength": 1
        }
      }
    },
    "coord": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "_kind",
        "lat",
        "lng"
      ],
      "properties": {
        "_kind": {
          "type": "string",
          "enum": [
            "coord"
          ]
        },
        "lat": {
          "type": "number"
        },
        "lng": {
          "type": "number"
        }
      }
    },
    "xstr": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "_kind",
        "type",
        "val"
      ],
      "properties": {
        "_kind": {
          "type": "string",
          "enum": [
            "xstr"
          ]
        },
        "type": {
          "type": "string",
          "pattern": "^[A-Z][a-zA-Z0-9_]*$"
        },
        "val": {
          "type": "string"
        }
      }
    }
  }
}