{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://sfcr.dev/sfcr-notebook.schema.json",
  "title": "SFCR Notebook Document",
  "type": "object",
  "additionalProperties": false,
  "required": ["id", "title", "metadata", "cells"],
  "properties": {
    "id": {
      "type": "string",
      "minLength": 1
    },
    "title": {
      "type": "string",
      "minLength": 1
    },
    "metadata": {
      "type": "object",
      "additionalProperties": false,
      "required": ["version"],
      "properties": {
        "version": {
          "const": 1
        },
        "template": {
          "type": "string"
        },
        "sourceFileName": {
          "type": "string",
          "minLength": 1
        },
        "timeAxis": {
          "type": "object",
          "additionalProperties": false,
          "required": ["startYear"],
          "properties": {
            "startYear": {
              "type": "integer"
            }
          }
        }
      }
    },
    "cells": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/cell"
      }
    }
  },
  "$defs": {
    "cellBase": {
      "type": "object",
      "required": ["id", "type", "title"],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1
        },
        "type": {
          "type": "string",
          "minLength": 1
        },
        "title": {
          "type": "string",
          "minLength": 1
        },
        "description": {
          "type": "string"
        },
        "note": {
          "type": "string"
        },
        "more": {
          "type": "string"
        },
        "collapsed": {
          "type": "boolean"
        }
      }
    },
    "unitMeta": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "displayUnit": {
          "type": "string"
        },
        "stockFlow": {
          "enum": ["stock", "flow", "aux"]
        },
        "signature": {
          "type": "object",
          "additionalProperties": {
            "type": "number"
          }
        },
        "units": {
          "type": "object",
          "additionalProperties": {
            "type": "number"
          }
        }
      }
    },
    "chartAxisRange": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "includeZero": { "type": "boolean" },
        "min": { "type": "number" },
        "max": { "type": "number" }
      }
    },
    "chartAxisLabel": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "title": { "type": "string" },
        "unit": { "type": "string" }
      }
    },
    "chartSeriesSpec": {
      "type": "object",
      "additionalProperties": false,
      "required": ["expression"],
      "properties": {
        "expression": { "type": "string", "minLength": 1 },
        "label": { "type": "string" },
        "range": { "$ref": "#/$defs/chartAxisRange" },
        "unit": { "type": "string" },
        "sourceRunCellId": { "type": "string" }
      }
    },
    "rowComment": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "kind", "text"],
      "properties": {
        "id": { "type": "string" },
        "kind": { "const": "comment" },
        "text": { "type": "string" }
      }
    },
    "equation": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "name", "expression"],
      "properties": {
        "id": { "type": "string" },
        "name": { "type": "string" },
        "desc": { "type": "string" },
        "expression": { "type": "string" },
        "role": {
          "type": "string"
        },
        "unitMeta": {
          "$ref": "#/$defs/unitMeta"
        }
      }
    },
    "equationListItem": {
      "oneOf": [{ "$ref": "#/$defs/equation" }, { "$ref": "#/$defs/rowComment" }]
    },
    "externalListItem": {
      "oneOf": [{ "$ref": "#/$defs/external" }, { "$ref": "#/$defs/rowComment" }]
    },
    "initialValueListItem": {
      "oneOf": [{ "$ref": "#/$defs/initialValue" }, { "$ref": "#/$defs/rowComment" }]
    },
    "external": {
      "type": "object",
      "additionalProperties": false,
      "required": ["name", "kind", "valueText"],
      "properties": {
        "id": { "type": "string" },
        "name": { "type": "string" },
        "desc": { "type": "string" },
        "kind": {
          "enum": ["constant", "series", "coefficient"]
        },
        "valueText": { "type": "string" },
        "observed": { "type": "boolean" },
        "unitMeta": {
          "$ref": "#/$defs/unitMeta"
        }
      }
    },
    "initialValue": {
      "type": "object",
      "additionalProperties": false,
      "required": ["name", "valueText"],
      "properties": {
        "id": { "type": "string" },
        "name": { "type": "string" },
        "desc": { "type": "string" },
        "valueText": { "type": "string" },
        "enabled": { "type": "boolean" }
      }
    },
    "matrixRow": {
      "type": "object",
      "additionalProperties": false,
      "required": ["label", "values"],
      "properties": {
        "band": { "type": "string" },
        "label": { "type": "string" },
        "role": {
          "type": "string",
          "enum": ["flow", "initial"]
        },
        "values": {
          "type": "array",
          "items": { "type": "string" }
        }
      }
    },
    "matrixColumnTreeNode": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "label"],
      "properties": {
        "id": { "type": "string", "minLength": 1 },
        "label": { "type": "string", "minLength": 1 },
        "variable": { "type": "string" },
        "children": {
          "type": "array",
          "items": { "$ref": "#/$defs/matrixColumnTreeNode" }
        }
      }
    },
    "shockVariable": {
      "type": "object",
      "additionalProperties": false,
      "required": ["kind"],
      "properties": {
        "kind": {
          "enum": ["constant", "series"]
        },
        "value": { "type": "number" },
        "values": {
          "type": "array",
          "items": { "type": "number" }
        }
      },
      "allOf": [
        {
          "if": {
            "properties": {
              "kind": { "const": "constant" }
            }
          },
          "then": {
            "required": ["value"]
          }
        },
        {
          "if": {
            "properties": {
              "kind": { "const": "series" }
            }
          },
          "then": {
            "required": ["values"]
          }
        }
      ]
    },
    "scenario": {
      "type": "object",
      "additionalProperties": false,
      "required": ["shocks"],
      "properties": {
        "shocks": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": ["variables"],
            "anyOf": [
              { "required": ["rangeInclusive"] },
              { "required": ["startPeriodInclusive", "endPeriodInclusive"] }
            ],
            "properties": {
              "rangeInclusive": {
                "type": "array",
                "items": { "type": "integer" },
                "minItems": 2,
                "maxItems": 2
              },
              "startPeriodInclusive": { "type": "integer" },
              "endPeriodInclusive": { "type": "integer" },
              "variables": {
                "type": "object",
                "additionalProperties": {
                  "$ref": "#/$defs/shockVariable"
                }
              }
            }
          }
        }
      }
    },
    "sequenceSource": {
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "required": ["kind", "source"],
          "properties": {
            "kind": { "const": "plantuml" },
            "source": { "type": "string" }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": ["kind", "matrixCellId"],
          "properties": {
            "kind": { "const": "matrix" },
            "matrixCellId": { "type": "string" },
            "sourceRunCellId": { "type": "string" },
            "includeZeroFlows": { "type": "boolean" },
            "aliases": {
              "type": "object",
              "additionalProperties": { "type": "string" }
            }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": ["kind"],
          "properties": {
            "kind": { "const": "dependency" },
            "modelId": { "type": "string" },
            "sourceModelId": { "type": "string" },
            "sourceModelCellId": { "type": "string" },
            "stripSectorSource": { "enum": ["columns", "sectors"] },
            "showAccountingStrips": { "type": "boolean" },
            "ignoreInferredBandsForPlacement": { "type": "boolean" },
            "showExogenous": { "type": "boolean" },
            "showDebugOverlay": { "type": "boolean" },
            "stripMapping": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "transactionMatrixCellId": { "type": "string" },
                "balanceMatrixCellId": { "type": "string" }
              }
            }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": ["kind"],
          "properties": {
            "kind": { "const": "cld" },
            "modelId": { "type": "string" },
            "sourceModelId": { "type": "string" },
            "sourceModelCellId": { "type": "string" }
          }
        }
      ]
    },
    "sankeySource": {
      "type": "object",
      "additionalProperties": false,
      "required": ["kind", "matrixCellId"],
      "properties": {
        "kind": { "const": "matrix" },
        "matrixCellId": { "type": "string" },
        "sourceRunCellId": { "type": "string" },
        "includeZeroFlows": { "type": "boolean" }
      }
    },
    "cell": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "type", "title"],
      "properties": {
        "id": { "type": "string", "minLength": 1 },
        "type": {
          "enum": [
            "markdown",
            "equations",
            "solver",
            "externals",
            "observed",
            "initial-values",
            "run",
            "chart",
            "chart-grid",
            "table",
            "matrix",
            "sequence",
            "sankey"
          ]
        },
        "title": { "type": "string", "minLength": 1 },
        "collapsed": { "type": "boolean" },
        "description": { "type": "string" },
        "note": { "type": "string" },
        "more": { "type": "string" },
        "participantColumnOrder": {
          "type": "array",
          "items": { "type": "string" }
        },
        "source": {},
        "modelId": { "type": "string" },
        "equations": {
          "type": "array",
          "items": { "$ref": "#/$defs/equationListItem" }
        },
        "options": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "solverMethod",
            "toleranceText",
            "maxIterations",
            "defaultInitialValueText",
            "hiddenLeftVariable",
            "hiddenRightVariable",
            "hiddenToleranceText",
            "relativeHiddenTolerance"
          ],
          "properties": {
            "periods": { "type": "integer", "minimum": 1 },
            "solverMethod": { "enum": ["GAUSS_SEIDEL", "BROYDEN", "NEWTON"] },
            "toleranceText": { "type": "string" },
            "maxIterations": { "type": "integer", "minimum": 1 },
            "defaultInitialValueText": { "type": "string" },
            "hiddenLeftVariable": { "type": "string" },
            "hiddenRightVariable": { "type": "string" },
            "hiddenToleranceText": { "type": "string" },
            "relativeHiddenTolerance": { "type": "boolean" }
          }
        },
        "externals": {
          "type": "array",
          "items": { "$ref": "#/$defs/externalListItem" }
        },
        "initialValues": {
          "type": "array",
          "items": { "$ref": "#/$defs/initialValueListItem" }
        },
        "sourceModelCellId": { "type": "string" },
        "sourceModelId": { "type": "string" },
        "baselineRunCellId": { "type": "string" },
        "baselineStartPeriod": { "type": "integer" },
        "mode": { "enum": ["baseline", "scenario"] },
        "simType": { "enum": ["DYNAMIC", "STATIC"] },
        "exogenize": {
          "type": "array",
          "items": {
            "oneOf": [
              { "type": "string" },
              {
                "type": "object",
                "properties": {
                  "name": { "type": "string" },
                  "throughPeriod": { "type": "integer", "minimum": 1 }
                },
                "required": ["name"],
                "additionalProperties": false
              }
            ]
          }
        },
        "externalOverrides": {
          "type": "array",
          "items": { "$ref": "#/$defs/externalListItem" }
        },
        "scenario": { "$ref": "#/$defs/scenario" },
        "resultKey": { "type": "string" },
        "periods": { "type": "integer", "minimum": 1 },
        "sourceRunCellId": { "type": "string" },
        "variables": {
          "type": "array",
          "items": { "type": "string" },
          "minItems": 1
        },
        "series": {
          "type": "array",
          "items": { "$ref": "#/$defs/chartSeriesSpec" },
          "minItems": 1
        },
        "axisMode": { "enum": ["shared", "separate"] },
        "axisGroups": {
          "type": "array",
          "items": {
            "type": "array",
            "items": { "type": "string" },
            "minItems": 1
          },
          "minItems": 1
        },
        "axisSnapTolarance": { "type": "number" },
        "niceScale": { "type": "boolean" },
        "compareMode": { "enum": ["levels", "relative", "percent"] },
        "referenceTrace": { "enum": ["none", "baseline", "previous-run", "observed"] },
        "referenceTraces": {
          "type": "array",
          "items": { "enum": ["baseline", "previous-run", "observed"] },
          "minItems": 1,
          "uniqueItems": true
        },
        "showScenarioShocks": { "oneOf": [{ "type": "boolean" }, { "const": "auto" }] },
        "yAxisTickCount": { "type": "integer", "minimum": 1 },
        "axisFontSize": { "type": "integer", "minimum": 8 },
        "yAxis": { "$ref": "#/$defs/chartAxisLabel" },
        "xAxis": { "$ref": "#/$defs/chartAxisLabel" },
        "sharedRange": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "includeZero": { "type": "boolean" },
            "min": { "type": "number" },
            "max": { "type": "number" }
          }
        },
        "seriesRanges": {
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "includeZero": { "type": "boolean" },
              "min": { "type": "number" },
              "max": { "type": "number" }
            }
          }
        },
        "timeRangeInclusive": {
          "type": "array",
          "items": { "type": "integer" },
          "minItems": 2,
          "maxItems": 2
        },
        "gridColumns": { "type": "integer", "minimum": 1 },
        "charts": {
          "type": "array",
          "items": { "$ref": "#/$defs/cell" }
        },
        "accountingKind": {
          "type": "string",
          "enum": ["balance-sheet", "transaction-flow", "account-transactions", "input-output"]
        },
        "columns": {
          "type": "array",
          "items": { "type": "string" }
        },
        "columnTree": {
          "type": "array",
          "items": { "$ref": "#/$defs/matrixColumnTreeNode" }
        },
        "columnBadges": {
          "type": "array",
          "items": { "type": "string" }
        },
        "variables": {
          "type": "array",
          "items": { "type": "string" }
        },
        "sectors": {
          "type": "array",
          "items": { "type": "string" }
        },
        "rows": {
          "type": "array",
          "items": { "$ref": "#/$defs/matrixRow" }
        }
      },
      "allOf": [
        {
          "if": { "properties": { "type": { "const": "markdown" } } },
          "then": {
            "required": ["source"],
            "properties": { "source": { "type": "string" } }
          }
        },
        {
          "if": { "properties": { "type": { "const": "equations" } } },
          "then": { "required": ["modelId", "equations"] }
        },
        {
          "if": { "properties": { "type": { "const": "solver" } } },
          "then": { "required": ["modelId", "options"] }
        },
        {
          "if": { "properties": { "type": { "const": "externals" } } },
          "then": { "required": ["modelId", "externals"] }
        },
        {
          "if": { "properties": { "type": { "const": "observed" } } },
          "then": { "required": ["modelId", "externals"] }
        },
        {
          "if": { "properties": { "type": { "const": "initial-values" } } },
          "then": { "required": ["modelId", "initialValues"] }
        },
        {
          "if": { "properties": { "type": { "const": "run" } } },
          "then": { "required": ["mode", "resultKey", "periods"] }
        },
        {
          "if": { "properties": { "type": { "const": "chart" } } },
          "then": {
            "required": ["sourceRunCellId"],
            "anyOf": [
              { "required": ["variables"] },
              { "required": ["series"] }
            ]
          }
        },
        {
          "if": { "properties": { "type": { "const": "chart-grid" } } },
          "then": { "required": ["gridColumns", "charts"] }
        },
        {
          "if": { "properties": { "type": { "const": "table" } } },
          "then": { "required": ["sourceRunCellId", "variables"] }
        },
        {
          "if": { "properties": { "type": { "const": "matrix" } } },
          "then": { "required": ["columns", "rows"] }
        },
        {
          "if": { "properties": { "type": { "const": "sequence" } } },
          "then": {
            "required": ["source"],
            "properties": { "source": { "$ref": "#/$defs/sequenceSource" } }
          }
        },
        {
          "if": { "properties": { "type": { "const": "sankey" } } },
          "then": {
            "required": ["source"],
            "properties": { "source": { "$ref": "#/$defs/sankeySource" } }
          }
        }
      ]
    }
  }
}
