{
    "$schema": "http://json-schema.org/draft-06/schema#",
    "title": "Treemap Configuration Schema",
    "description": "JSON schema for a treemap configuration object, targeting the treemap renderer module.",
    "type": "object",
    "properties": {

        "topology": { "type": "object",  "properties": {

                "format": { "type": "string", "enum": [ "interleaved", "tupled" ], "default": "interleaved" },

                "semantics": { "type": "string", "enum": [ "parent-id-id", "parent-index-id" ], "default": "parent-id-id" },

                "edges": { "type": "array", "items": { "anyOf": [
                            { "type": "integer", "minimum": -1 },
                            { "type": "array", "items": { "type": "integer", "minimum": -1 }, "minItems": 2, "maxItems": 2, "uniqueItems": true } ],
                            "minItems": 0 } }
            },
            "required": [ "edges" ],
            "additionalProperties": false
        },

        "buffers": { "type": "array", "items": { "type": "object", "properties": {

                    "identifier": { "type": "string" },

                    "type": { "type": "string", "enum": [ "numbers", "uint8", "uint16", "int16", "uint32", "int32", "float32", "float64" ] },

                    "encoding": { "type": "string", "enum": [ "base64", "native" ], "default": "native" },

                    "data": { "anyOf": [
                        { "type": "array", "items": { "type": "number" } },
                        { "type": "Uint8Array" },
                        { "type": "Uint16Array" },
                        { "type": "Int16Array" },
                        { "type": "Uint32Array" },
                        { "type": "Int32Array" },
                        { "type": "Float32Array" },
                        { "type": "Float64Array" }
                    ] },

                    "linearization": { "anyOf": [
                        { "type": "string", "enum": [ "topology", "identity" ] },
                        { "type": "object", "properties": {
                                "type": { "type": "string", "enum": [ "id-mapping", "index-mapping" ] },
                                "mapping": { "type": "array", "items": { "type": "integer" } }
                            },
                            "required": [ "type", "mapping" ],
                            "additionalProperties": false
                        } ], "default": "topology"
                    }
                },
                "required": [ "identifier", "type", "data" ],
                "additionalProperties": false
            }
        },

        "bufferViews": { "type": "array", "items": { "type": "object", "properties": {

                    "identifier": { "type": "string" },

                    "source": { "$ref": "/BufferReference" },

                    "transformations": { "type": "array", "items": { "anyOf": [
                                { "type": "object", "properties": {
                                        "type": { "type": "string", "enum": [ "propagate-up" ]},
                                        "operation": { "type": "string", "enum": [ "average", "sum", "min", "max", "median", "closest-to-zero", "closest-to-infinity" ]},
                                        "weight": { "$ref": "/BufferReference" }
                                    },
                                    "required": [ "type", "operation" ],
                                    "additionalProperties": false
                                },
                                { "type": "object", "properties": {
                                        "type": { "type": "string", "enum": [ "fill-invalid" ]},
                                        "value": { "type": "number" },
                                        "invalidValue": { "anyOf": [
                                                { "type": "number" },
                                                { "type": "null" }
                                            ]
                                        }
                                    },
                                    "required": [ "type", "value" ],
                                    "additionalProperties": false
                                },
                                { "type": "object", "properties": {
                                        "type": { "type": "string", "enum": [ "mask" ]},
                                        "value": { "type": "number" }
                                    },
                                    "required": [ "type", "value" ],
                                    "additionalProperties": false
                                },
                                { "type": "object", "properties": {
                                        "type": { "type": "string", "enum": [ "clamp" ]},
                                        "min": { "type": "number" },
                                        "max": { "type": "number" }
                                    },
                                    "required": [ "type", "min", "max" ],
                                    "additionalProperties": false
                                },
                                { "type": "object", "properties": {
                                        "type": { "type": "string", "enum": [ "clamp" ]},
                                        "range": { "type": "array", "items": { "type": "number" }, "minItems": 2, "maxItems": 2 }
                                    },
                                    "required": [ "type", "range" ],
                                    "additionalProperties": false
                                },
                                { "type": "object", "properties": {
                                        "type": { "type": "string", "enum": [ "range-transform" ]},
                                        "sourceRange": { "type": "array", "items": { "type": "number" }, "minItems": 2, "maxItems": 2 },
                                        "targetRange": { "type": "array", "items": { "type": "number" }, "minItems": 2, "maxItems": 2 }
                                    },
                                    "required": [ "type", "sourceRange", "targetRange" ],
                                    "additionalProperties": false
                                },
                                { "type": "object", "properties": {
                                        "type": { "type": "string", "enum": [ "normalize" ]},
                                        "operation": { "type": "string", "enum": [ "zero-to-max", "min-to-max", "sign-agnostic-max", "diverging" ] },
                                        "neutralElement": {"type": "number"}
                                    },
                                    "required": [ "type", "operation" ],
                                    "additionalProperties": false
                                },
                                { "type": "object", "properties": {
                                        "type": { "type": "string", "enum": [ "threshold" ]},
                                        "value": { "type": "number" }
                                    },
                                    "required": [ "type", "value" ],
                                    "additionalProperties": false
                                },
                                { "type": "object", "properties": {
                                        "type": { "type": "string", "enum": [ "compare" ]},
                                        "value": { "type": "number" }
                                    },
                                    "required": [ "type", "value" ],
                                    "additionalProperties": false
                                },
                                { "type": "object", "properties": {
                                        "type": { "type": "string", "enum": [ "transform" ]},
                                        "operation": { "type": "string", "enum": [ "add", "subtract", "multiply", "divide", "inverse", "pow", "nth-root",
                                            "log", "square", "square-root", "as-multiplier", "as-remainder", "abs" ] },
                                        "parameter": { "type": "number", "default": 0.0 },
                                        "buffer": { "$ref": "/BufferReference" }
                                    },
                                    "required": [ "type", "operation" ],
                                    "additionalProperties": false
                                },
                                { "type": "object", "properties": {
                                        "type": { "type": "string", "enum": [ "discretize" ]},
                                        "operation": { "type": "string", "enum": [ "quantiles", "quartiles" ] }
                                    },
                                    "required": [ "type", "operation" ],
                                    "additionalProperties": false
                                },
                                { "type": "object", "properties": {
                                        "type": { "type": "string", "enum": [ "discretize" ]},
                                        "percentiles": { "type": "array", "items": { "type":"number" } }
                                    },
                                    "required": [ "type", "percentiles" ],
                                    "additionalProperties": false
                                },
                                { "type": "object", "properties": {
                                        "type": { "type": "string", "enum": [ "callback" ]},
                                        "iteration": { "type": "string", "enum": [ "top-down", "bottom-up", "depth-first", "leaves" ] }
                                    },
                                    "required": [ "type", "iteration", "operation" ],
                                    "additionalProperties": true
                                }
                            ]
                        }
                    }
                },
                "required": [ "identifier", "source" ],
                "additionalProperties": false
            }
        },


        "colors": { "type": "array", "items": { "oneOf": [
            { "type": "object", "properties": {

                "identifier": { "type": "string" },
                "colorspace": { "type": "string", "enum": [ "rgb", "hsl", "lab", "cmyk", "hex" ],
                    "description": "The color space is based on supported webgl-operate color spaces.",
                    "default": "hex" },

                "value": { "oneOf": [
                    { "type": "array", "minItems": 3, "maxItems": 5, "items": { "type": "number", "minimum": 0.0, "maximum": 1.0 } },
                    { "type": "string", "pattern": "^(#|0x)?(([0-9a-f]{3}){1,2}|([0-9a-f]{4}){1,2})$" } ] },

                "values": { "type": "array", "minItems": 2, "items": { "oneOf": [
                    { "type": "array", "minItems": 3, "maxItems": 5, "items": { "type": "number", "minimum": 0.0, "maximum": 1.0 } },
                    { "type": "string", "pattern": "^(#|0x)?(([0-9a-f]{3}){1,2}|([0-9a-f]{4}){1,2})$" } ] } }
                },

                "required": [ "identifier", "colorspace" ],
                "oneOf": [ { "type": "object", "required": [ "value" ] },
                        { "type": "object", "required": [ "values" ] } ],

                "additionalProperties": false
            },
            { "type": "object", "properties": {

                "identifier": { "type": "string" },
                "preset": { "type": "string", "description": "The preset from a webgl-operate Color Scheme Preset file." },
                "steps": { "type": "number", "minimum": 3, "maximum": 12, "default": 5 } },

                "required": [ "identifier", "preset" ],

                "additionalProperties": false
            } ] }
        },


        "layout": { "type": "object", "properties": {

                "algorithm": { "type": "string", "enum": [ "strip", "snake", "codecity" ] },

                "weight": { "$ref": "/BufferReference" },

                "aspectRatio": { "type": "number", "exclusiveMinimum": 0.0,
                    "default": 1.0 },

                "sort": { "type": "object", "properties": {

                        "algorithm": { "type": "string", "enum": [ "ascending", "descending", "keep"],
                            "default": "keep" },

                        "key": { "anyOf": [
                            { "type": "string", "enum": [ "identity", "weight" ] },
                            { "$ref": "/BufferReference" } ],
                            "default": "identity" }
                    },
                    "required": [ "algorithm" ],
                    "additionalProperties": false
                },

                "siblingMargin": { "type": "object", "properties": {

                        "type": { "type": "string", "enum": [ "relative", "absolute" ],
                            "default": "relative" },

                        "value": { "anyOf": [ { "$ref": "/BufferReference" }, { "type": "number", "minimum": 0.0 } ],
                            "default": 0.0 }
                    },
                    "required": [ "type", "value" ],
                    "additionalProperties": false
                },

                "parentPadding": { "type": "object", "properties": {

                        "type": { "type": "string", "enum": [ "relative", "absolute", "mixed"],
                            "default": "relative" },

                        "value": { "anyOf": [
                            { "$ref": "/BufferReference" },
                            { "type": "number", "minimum": 0.0 },
                            { "type": "array", "items": { "type": "number", "minimum": 0 }, "minItems": 1 } ],
                            "default": 0.0 }
                    },
                    "required": [ "type", "value" ],
                    "additionalProperties": false
                },

                "accessoryPadding": { "type": "object", "properties": {

                        "type": { "type": "string", "enum": [ "relative", "absolute"],
                            "default": "absolute" },

                        "direction": { "type": "string", "enum": [ "top", "left", "bottom", "right" ],
                            "default": "bottom" },

                        "value": { "anyOf": [
                            { "type": "number", "minimum": 0 },
                            { "type": "array", "items": { "type": "number", "minimum": 0 }, "minItems": 1 } ] },

                        "relativeAreaThreshold": { "anyOf": [
                            { "type": "number", "minimum": 0 },
                            { "type": "array", "items": { "type": "number", "minimum": 0 }, "minItems": 1 } ],
                            "default": 0.0 },

                        "targetAspectRatio": { "anyOf": [
                            { "type": "number", "minimum": 0 },
                            { "type": "null" } ],
                            "default": null
                        }
                    },
                    "required": [ "value" ],
                    "additionalProperties": false
                }
            },
            "required": [ "algorithm", "weight" ],
            "additionalProperties": false
        },


        "geometry": { "type": "object", "properties": {

                "parentLayer": { "type": "object", "properties": {
                        "colorMap": { "$ref": "/ColorReference", "default": "color:inner" },
                        "showRoot": { "type": "boolean", "default": false }
                    },
                    "additionalProperties": false
                },

                "leafLayer": { "type": "object", "properties": {
                        "colorMap": { "$ref": "/ColorReference", "default": "color:leaf" },
                        "height": { "$ref": "/BufferReference" },
                        "colors": { "$ref": "/BufferReference" },
                        "colorsNormalized": { "type": "boolean", "default": false }
                    },
                    "additionalProperties": false
                },

                "auxiliary" : { "$ref": "/ColorReference", "default": "color:auxiliary" },

                "emphasis": { "type": "object", "properties": {
                        "outline":   { "type": "array", "items": { "type": "integer",  "minimum": 0 }, "uniqueItems": true },
                        "highlight": { "type": "array", "items": { "type": "integer",  "minimum": 0 }, "uniqueItems": true },

                        "color": { "$ref": "/ColorReference", "default": "color:emphasis" },
                        "outlineWidth": { "type": "number", "minimum": 0.0, "description": "unit: device-independent pixel",
                            "default": 1.60 }
                    },
                    "additionalProperties": false
                },

                "heightScale": { "anyOf": [
                    { "type": "string", "enum": [ "SomethingInverseSqrt" ] },
                    { "type": "number" } ], "default": 0.125 },

                "outlineWidth": { "type": "number", "minimum": 0.0, "description": "unit: native pixel",
                    "default": 0.80 }

            },
            "required": [],
            "additionalProperties": false
        },

        "labels": { "type": "object", "properties": {
                "names": { "anyOf": [
                    { "$ref": "/BufferReference" },
                    {
                        "type": "object",
                        "additionalProperties": { "type": "string" }
                    }
                ] },
                "additionallyLabelSet": { "type": "array", "items": { "type": "number", "minimum": 0 }, "default": [] },
                "innerNodeLayerRange": { "type": "array", "items": { "type": "number", "minimum": 0 }, "minItems": 2, "maxItems": 2, "default": [1, 2] },
                "numTopInnerNodes": { "type": "number", "minimum": 0, "default": 0 },
                "numTopWeightNodes": { "type": "number", "minimum": 0, "default": 0 },
                "numTopHeightNodes": { "type": "number", "minimum": 0, "default": 0 },
                "numTopColorNodes": { "type": "number", "minimum": 0, "default": 0 }
            },
            "required": []
        }

    },
    "required": [ "topology", "layout" ],
    "additionalProperties": false
}
