{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://json.schemastore.org/mapehr.json",
  "$comment": "https://mapehr.com",
  "title": "MapEHR Mapping",
  "description": "Mapping for MapEHR.com v0.3.0",
  "type": "object",
  "properties": {
    "define": {
      "$ref": "#/definitions/define",
      "description": "Define keys used in the rules. Example: weight: http://loinc.org/29463-7"
    },
    "vars": {
      "$ref": "#/definitions/vars",
      "description": "Define variables used in the rules. Example: default_bmi: randomNormalDistribution((27.6863+25.4960)/2, sqrt(18.65))"
    },
    "rules": {
      "$ref": "#/definitions/rules",
      "description": "Rules for LOINC codes, archetypes, templates."
    },
    "keep_missing_target_elements": {
      "type": "boolean",
      "description": "Keep the target elements for which there is not source data."
    }
  },
  "additionalProperties": false,
  "definitions": {
    "rules": {
      "description": "Rules for a LOINC codes, archetypes, templates.",
      "type": "object",
      "patternProperties": {
        "^.+$": {
          "$comment": "Rules for a LOINC codes, archetypes, templates.",
          "$ref": "#/definitions/rule",
          "description": "Rules for a LOINC codes, archetypes, templates."
        }
      },
      "additionalProperties": false
    },
    "rule": {
      "title": "Rule for a LOINC code or archetype.",
      "type": "object",
      "patternProperties": {
        "^.+$": {
          "$ref": "#/definitions/rule_code",
          "description": "Rule for a LOINC code, archetype, template."
        }
      },
      "additionalProperties": false
    },
    "rule_code": {
      "type": "object",
      "anyOf": [
        {
          "properties": {
            "uri": {
              "type": "string",
              "description": "Full URI for this rule."
            },
            "name": {
              "type": "string",
              "description": "Name for this rule."
            },
            "description": {
              "type": "string",
              "description": "Description for this rule."
            },
            "keep_missing_target_elements": {
              "type": "boolean",
              "description": "Keep the target elements for which there is not source data."
            },
            "formats": {
              "$ref": "#/definitions/rule_formats",
              "description": "Models for formats from/to which to map values."
            },
            "map": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/map"
              },
              "title": "Map values for elements."
            },
            "define": {
              "$ref": "#/definitions/define",
              "description": "Define keys used in the rules. Example: weight: http://loinc.org/29463-7"
            },
            "vars": {
              "$ref": "#/definitions/vars",
              "description": "Define variables used in the rules. Example: default_bmi: randomNormalDistribution((27.6863+25.4960)/2, sqrt(18.65))"
            }
          },
          "additionalProperties": false,
          "required": ["map"]
        },
        {
          "properties": {
            "uri": {
              "type": "string",
              "description": "Full URI for this rule."
            },
            "name": {
              "type": "string",
              "description": "Name for this rule."
            },
            "description": {
              "type": "string",
              "description": "Description for this rule."
            },
            "keep_missing_target_elements": {
              "type": "boolean",
              "description": "Keep the target elements for which there is not source data."
            },
            "set": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/set"
              },
              "title": "Set values of elements."
            },
            "define": {
              "$ref": "#/definitions/define",
              "description": "Define keys used in the rules. Example: weight: http://loinc.org/29463-7"
            },
            "vars": {
              "$ref": "#/definitions/vars",
              "description": "Define variables used in the rules. Example: default_bmi: randomNormalDistribution((27.6863+25.4960)/2, sqrt(18.65))"
            },
            "choices": {
              "$ref": "#/definitions/choices",
              "description": "Define a list of choices from which a random item will be used."
            }
          },
          "additionalProperties": false,
          "required": ["set"]
        }
      ]
    },
    "rule_formats": {
      "type": "object",
      "patternProperties": {
        "^(fhir)$": {
          "$ref": "#/definitions/rule_format",
          "description": "Mapping format (e.g. FHIR)."
        }
      },
      "additionalProperties": false
    },
    "rule_format": {
      "type": "object",
      "properties": {
        "uri": {
          "type": "string",
          "description": "Full URI for the model in this format."
        },
        "name": {
          "type": "string",
          "description": "Name for the model in this format."
        },
        "description": {
          "type": "string",
          "description": "Description for the model in this format."
        },
        "resource": {
          "type": "string",
          "description": "Resource name for the model in this format."
        }
      },
      "additionalProperties": false
    },
    "map": {
      "type": "object",
      "properties": {
        "attribute": {
          "type": "string",
          "description": "Used to specify an RM attribute."
        },
        "path": {
          "type": "string",
          "description": "Used to specify an ADL path."
        },
        "element": {
          "$ref": "#/definitions/element",
          "description": "An RM element."
        },
        "elements": {
          "$ref": "#/definitions/elements",
          "description": "RM elements."
        },
        "formats": {
          "$ref": "#/definitions/map_formats",
          "description": "Define formats from/to which the data will be mapped."
        },
        "define": {
          "$ref": "#/definitions/define",
          "description": "Define keys used in the rules. Example: weight: http://loinc.org/29463-7"
        },
        "vars": {
          "$ref": "#/definitions/vars",
          "description": "Define variables used in the rules. Example: default_bmi: randomNormalDistribution((27.6863+25.4960)/2, sqrt(18.65))"
        }
      },
      "additionalProperties": false
    },
    "map_formats": {
      "type": "object",
      "patternProperties": {
        "^(fhir)$": {
          "$ref": "#/definitions/map_format_item",
          "description": "Mapping format (e.g. FHIR)."
        }
      },
      "additionalProperties": false
    },
    "map_format_item": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/map_format"
      },
      "title": "Values of elements for the format."
    },
    "map_format": {
      "type": "object",
      "properties": {
        "attribute": {
          "type": "string",
          "description": "Used to specify an attribute to the element."
        },
        "path": {
          "type": "string",
          "description": "Used to specify a path to the element."
        },
        "element": {
          "$ref": "#/definitions/map_format_element",
          "description": "Format element."
        },
        "elements": {
          "$ref": "#/definitions/map_format_elements",
          "description": "Format elements."
        },
        "define": {
          "$ref": "#/definitions/define",
          "description": "Define keys used in the rules. Example: weight: http://loinc.org/29463-7"
        },
        "vars": {
          "$ref": "#/definitions/vars",
          "description": "Define variables used in the rules. Example: default_bmi: randomNormalDistribution((27.6863+25.4960)/2, sqrt(18.65))"
        }
      },
      "additionalProperties": false
    },
    "map_format_elements": {
      "type": "object",
      "patternProperties": {
        "^.+$": {
          "oneOf": [
            {
              "$ref": "#/definitions/map_format_element",
              "description": "Format element."
            },
            {
              "type": "null",
              "description": "Leave it empty if you just need to reference this element."
            }
          ]
        }
      },
      "additionalProperties": false
    },
    "map_format_element": {
      "type": "object",
      "properties": {
        "attribute": {
          "type": "string",
          "description": "Used to specify an attribute."
        },
        "path": {
          "type": "string",
          "description": "Used to specify a path."
        },
        "elements": {
          "$ref": "#/definitions/map_format_elements",
          "description": "Format elements."
        },
        "one_of": {
          "$ref": "#/definitions/one_of",
          "description": "List of keys to look for."
        }
      },
      "additionalProperties": false
    },
    "one_of": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "set": {
      "type": "object",
      "properties": {
        "attribute": {
          "type": "string",
          "description": "Used to specify an RM attribute."
        },
        "path": {
          "type": "string",
          "description": "Used to specify an ADL path."
        },
        "attributes": {
          "$ref": "#/definitions/attributes",
          "description": "RM type attributes."
        },
        "element": {
          "$ref": "#/definitions/element",
          "description": "An RM element."
        },
        "elements": {
          "$ref": "#/definitions/elements",
          "description": "RM elements."
        },
        "define": {
          "$ref": "#/definitions/define",
          "description": "Define keys used in the rules. Example: weight: http://loinc.org/29463-7"
        },
        "vars": {
          "$ref": "#/definitions/vars",
          "description": "Define variables used in the rules. Example: default_bmi: randomNormalDistribution((27.6863+25.4960)/2, sqrt(18.65))"
        },
        "choices": {
          "$ref": "#/definitions/choices",
          "description": "Define a list of choices from which a random item will be used."
        },
        "value_intervals": {
          "$ref": "#/definitions/value_intervals",
          "description": "Value intervals for each key (e.g. units)."
        },
        "interpretation_intervals": {
          "$ref": "#/definitions/interpretation_intervals",
          "description": "Interpretation intervals for each key (e.g. units)."
        }
      },
      "additionalProperties": false
    },
    "elements": {
      "type": "object",
      "patternProperties": {
        "^.+$": {
          "oneOf": [
            {
              "$ref": "#/definitions/element",
              "description": "An RM element."
            },
            {
              "type": "null",
              "description": "Leave it empty if you just need to reference this element in a formula."
            }
          ]
        }
      },
      "additionalProperties": false
    },
    "element": {
      "title": "An RM element.",
      "type": "object",
      "properties": {
        "attribute": {
          "type": "string",
          "description": "Used to specify an RM attribute."
        },
        "path": {
          "type": "string",
          "description": "Used to specify an ADL path."
        },
        "elements": {
          "$ref": "#/definitions/elements",
          "description": "RM elements."
        },
        "value": {
          "type": "string",
          "description": "Value of the element. Can use formulas."
        },
        "value_type": {
          "type": "string",
          "description": "RM type of the element."
        },
        "value_interval": {
          "type": "string",
          "description": "Value interval."
        },
        "value_intervals": {
          "$ref": "#/definitions/value_intervals",
          "description": "Value intervals for each key (e.g. units)."
        },
        "choice_key": {
          "type": "string",
          "description": "The name of the key in the choices to use for this element."
        },
        "interpretation_interval": {
          "$ref": "#/definitions/interpretation_interval",
          "description": "Interpretation interval for the value."
        },
        "interpretation_intervals": {
          "$ref": "#/definitions/interpretation_intervals",
          "description": "Interpretation intervals for each key (e.g. units)."
        }
      },
      "additionalProperties": false
    },
    "value_intervals": {
      "type": "object",
      "patternProperties": {
        "^.+$": {
          "$ref": "#/definitions/value_interval"
        }
      },
      "additionalProperties": false
    },
    "value_interval": {
      "title": "Interval as [low]..[high]. Example: 1..10",
      "type": "string"
    },
    "interpretation_intervals": {
      "type": "object",
      "patternProperties": {
        "^.+$": {
          "$ref": "#/definitions/interpretation_interval"
        }
      },
      "additionalProperties": false
    },
    "interpretation_interval": {
      "type": "object",
      "properties": {
        "low": {
          "type": "number",
          "description": "Low value of the interpretation interval."
        },
        "high": {
          "type": "number",
          "description": "High value of the interpretation interval."
        }
      },
      "additionalProperties": false,
      "required": ["low", "high"]
    },
    "attributes": {
      "type": "object",
      "patternProperties": {
        "^.+$": {
          "$ref": "#/definitions/attribute",
          "description": "An RM type attributes."
        }
      },
      "additionalProperties": false
    },
    "attribute": {
      "type": "object",
      "properties": {
        "attributes": {
          "$ref": "#/definitions/attributes",
          "description": "RM type attributes."
        },
        "elements": {
          "$ref": "#/definitions/elements",
          "description": "RM elements for the RM type attribute."
        },
        "define": {
          "$ref": "#/definitions/define",
          "description": "Define keys used in the rules. Example: weight: http://loinc.org/29463-7"
        },
        "vars": {
          "$ref": "#/definitions/vars",
          "description": "Define variables used in the rules. Example: default_bmi: randomNormalDistribution((27.6863+25.4960)/2, sqrt(18.65))"
        },
        "choices": {
          "$ref": "#/definitions/choices",
          "description": "Define a list of choices from which a random item will be used."
        },
        "value": {
          "type": "string",
          "description": "Value of the attribute. Can use formulas."
        },
        "value_type": {
          "type": "string",
          "description": "RM type of the attribute."
        },
        "value_interval": {
          "type": "string",
          "description": "Value interval."
        },
        "value_intervals": {
          "$ref": "#/definitions/value_intervals",
          "description": "Value intervals for each key (e.g. units)."
        },
        "choice_key": {
          "type": "string",
          "description": "The name of the key in the choices to use for this attribute."
        },
        "interpretation_interval": {
          "$ref": "#/definitions/interpretation_interval",
          "description": "Interpretation interval for the value."
        },
        "interpretation_intervals": {
          "$ref": "#/definitions/interpretation_intervals",
          "description": "Interpretation intervals for each key (e.g. units)."
        }
      },
      "additionalProperties": false
    },
    "choices": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/choices_map"
      }
    },
    "choices_map": {
      "$ref": "#/definitions/choices_map_entry"
    },
    "choices_map_entry": {
      "type": "object",
      "patternProperties": {
        "^.+$": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "number"
            },
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/choices_map_entry"
            }
          ]
        }
      },
      "additionalProperties": false
    },
    "define": {
      "type": "object",
      "patternProperties": {
        "^.+$": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "vars": {
      "type": "object",
      "patternProperties": {
        "^.+$": {
          "type": "string"
        }
      },
      "additionalProperties": false
    }
  }
}
