{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://lumina.usefulweb.site/static/apps/lumina/compositor.schema.json",
  "title": "Lumina compositor graph",
  "type": "object",
  "required": [
    "format",
    "version",
    "nodes"
  ],
  "properties": {
    "format": {
      "const": "lumina-compositor"
    },
    "version": {
      "const": 1
    },
    "name": {
      "type": "string",
      "maxLength": 120
    },
    "width": {
      "type": "integer",
      "minimum": 0,
      "maximum": 16384,
      "description": "Canvas width in pixels; 0 = width of the main image."
    },
    "height": {
      "type": "integer",
      "minimum": 0,
      "maximum": 16384,
      "description": "Canvas height in pixels; 0 = height of the main image."
    },
    "nodes": {
      "type": "array",
      "maxItems": 64,
      "items": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "One of the images you provide, placed on the canvas.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "image"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "slot": {
                    "enum": [
                      "image",
                      "background",
                      "extra"
                    ],
                    "default": "image",
                    "description": "Image"
                  },
                  "fit": {
                    "enum": [
                      "cover",
                      "contain",
                      "stretch",
                      "none"
                    ],
                    "default": "cover",
                    "description": "Fit to canvas"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {}
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "A flat colour; an optional mask makes it a coloured matte (shadows, tints).",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "solid"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "color": {
                    "type": "string",
                    "pattern": "^#[0-9A-Fa-f]{6}$",
                    "default": "#202830",
                    "description": "Colour"
                  },
                  "alpha": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "default": 1,
                    "description": "Opacity"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "mask": {
                    "type": "string",
                    "description": "Alpha from mask (mask, optional): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Linear or radial gradient between two colours.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "gradient"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "shape": {
                    "enum": [
                      "linear",
                      "radial"
                    ],
                    "default": "linear",
                    "description": "Gradient shape"
                  },
                  "from": {
                    "type": "string",
                    "pattern": "^#[0-9A-Fa-f]{6}$",
                    "default": "#f4efe6",
                    "description": "Start colour"
                  },
                  "to": {
                    "type": "string",
                    "pattern": "^#[0-9A-Fa-f]{6}$",
                    "default": "#9aa7ad",
                    "description": "End colour"
                  },
                  "angle": {
                    "type": "number",
                    "minimum": -360,
                    "maximum": 360,
                    "default": 90,
                    "description": "Angle (degrees)"
                  },
                  "centerX": {
                    "type": "number",
                    "minimum": -1,
                    "maximum": 2,
                    "default": 0.5,
                    "description": "Centre X (fraction of width)"
                  },
                  "centerY": {
                    "type": "number",
                    "minimum": -1,
                    "maximum": 2,
                    "default": 0.5,
                    "description": "Centre Y (fraction of height)"
                  },
                  "radius": {
                    "type": "number",
                    "minimum": 0.01,
                    "maximum": 4,
                    "default": 1,
                    "description": "Radius (fraction of half diagonal)"
                  },
                  "interpolation": {
                    "enum": [
                      "srgb",
                      "linear"
                    ],
                    "default": "srgb",
                    "description": "Interpolate in"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {}
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Seeded smooth value noise (fractal), the same for the same seed.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "noise"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "seed": {
                    "type": [
                      "string",
                      "number"
                    ],
                    "default": "1",
                    "description": "Seed"
                  },
                  "scale": {
                    "type": "number",
                    "minimum": 1,
                    "maximum": 1024,
                    "default": 48,
                    "description": "Feature size (px)"
                  },
                  "octaves": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 6,
                    "default": 4,
                    "description": "Octaves"
                  },
                  "contrast": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 4,
                    "default": 1,
                    "description": "Contrast"
                  },
                  "brightness": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "default": 0.5,
                    "description": "Brightness"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {}
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "A line of text drawn with a system font (needs a browser canvas or the server text renderer).",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "text"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "text": {
                    "type": "string",
                    "maxLength": 500,
                    "default": "Lumina",
                    "description": "Text"
                  },
                  "x": {
                    "type": "number",
                    "minimum": -16384,
                    "maximum": 16384,
                    "default": 40,
                    "description": "X position (px)"
                  },
                  "y": {
                    "type": "number",
                    "minimum": -16384,
                    "maximum": 16384,
                    "default": 80,
                    "description": "Baseline Y (px)"
                  },
                  "size": {
                    "type": "number",
                    "minimum": 4,
                    "maximum": 1000,
                    "default": 48,
                    "description": "Font size (px)"
                  },
                  "color": {
                    "type": "string",
                    "pattern": "^#[0-9A-Fa-f]{6}$",
                    "default": "#ffffff",
                    "description": "Text colour"
                  },
                  "font": {
                    "enum": [
                      "sans-serif",
                      "serif",
                      "monospace"
                    ],
                    "default": "sans-serif",
                    "description": "Font family"
                  },
                  "weight": {
                    "enum": [
                      "normal",
                      "bold"
                    ],
                    "default": "bold",
                    "description": "Font weight"
                  },
                  "align": {
                    "enum": [
                      "start",
                      "center",
                      "end"
                    ],
                    "default": "start",
                    "description": "Alignment"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {}
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Translate, scale and rotate around a pivot with nearest, bilinear or bicubic resampling.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "transform"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "translateX": {
                    "type": "number",
                    "minimum": -16384,
                    "maximum": 16384,
                    "default": 0,
                    "description": "Move X (px)"
                  },
                  "translateY": {
                    "type": "number",
                    "minimum": -16384,
                    "maximum": 16384,
                    "default": 0,
                    "description": "Move Y (px)"
                  },
                  "scale": {
                    "type": "number",
                    "minimum": 0.01,
                    "maximum": 20,
                    "default": 1,
                    "description": "Scale"
                  },
                  "rotate": {
                    "type": "number",
                    "minimum": -360,
                    "maximum": 360,
                    "default": 0,
                    "description": "Rotate (degrees)"
                  },
                  "pivotX": {
                    "type": "number",
                    "minimum": -2,
                    "maximum": 3,
                    "default": 0.5,
                    "description": "Pivot X (fraction of width)"
                  },
                  "pivotY": {
                    "type": "number",
                    "minimum": -2,
                    "maximum": 3,
                    "default": 0.5,
                    "description": "Pivot Y (fraction of height)"
                  },
                  "filter": {
                    "enum": [
                      "bicubic",
                      "bilinear",
                      "nearest"
                    ],
                    "default": "bicubic",
                    "description": "Resampling"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Cuts out a rectangle; the result has the rectangle’s size.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "crop"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "x": {
                    "type": "integer",
                    "minimum": -16384,
                    "maximum": 16384,
                    "default": 0,
                    "description": "Left (px)"
                  },
                  "y": {
                    "type": "integer",
                    "minimum": -16384,
                    "maximum": 16384,
                    "default": 0,
                    "description": "Top (px)"
                  },
                  "width": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 16384,
                    "default": 512,
                    "description": "Width (px)"
                  },
                  "height": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 16384,
                    "default": 512,
                    "description": "Height (px)"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Separable Gaussian (radius = standard deviation) or box blur on premultiplied colour.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "blur"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "kind": {
                    "enum": [
                      "gaussian",
                      "box"
                    ],
                    "default": "gaussian",
                    "description": "Blur type"
                  },
                  "radius": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 200,
                    "default": 4,
                    "description": "Radius (px)"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  },
                  "mask": {
                    "type": "string",
                    "description": "Limit to mask (mask, optional): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Unsharp mask: adds the difference to a Gaussian blur.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "sharpen"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "amount": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 5,
                    "default": 0.8,
                    "description": "Amount"
                  },
                  "radius": {
                    "type": "number",
                    "minimum": 0.1,
                    "maximum": 50,
                    "default": 1.5,
                    "description": "Radius (px)"
                  },
                  "threshold": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "default": 0,
                    "description": "Threshold (0–1)"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  },
                  "mask": {
                    "type": "string",
                    "description": "Limit to mask (mask, optional): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Sobel gradient magnitude of the luma as a grey image.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "edges"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "strength": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 20,
                    "default": 1,
                    "description": "Strength"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Seeded grain, strongest in the midtones.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "grain"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "seed": {
                    "type": [
                      "string",
                      "number"
                    ],
                    "default": "7",
                    "description": "Seed"
                  },
                  "amount": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 0.5,
                    "default": 0.04,
                    "description": "Amount"
                  },
                  "size": {
                    "type": "number",
                    "minimum": 0.5,
                    "maximum": 16,
                    "default": 1.5,
                    "description": "Grain size (px)"
                  },
                  "mono": {
                    "type": "boolean",
                    "default": true,
                    "description": "Monochrome grain"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  },
                  "mask": {
                    "type": "string",
                    "description": "Limit to mask (mask, optional): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Darkens or brightens towards the corners in linear light.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "vignette"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "amount": {
                    "type": "number",
                    "minimum": -1,
                    "maximum": 1,
                    "default": 0.35,
                    "description": "Amount (negative brightens)"
                  },
                  "radius": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1.5,
                    "default": 0.55,
                    "description": "Start radius"
                  },
                  "softness": {
                    "type": "number",
                    "minimum": 0.01,
                    "maximum": 2,
                    "default": 0.5,
                    "description": "Softness"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Input black/white points, midtone gamma and output range on 0–255 encoded values.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "levels"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "inBlack": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 254,
                    "default": 0,
                    "description": "Input black"
                  },
                  "inWhite": {
                    "type": "number",
                    "minimum": 1,
                    "maximum": 255,
                    "default": 255,
                    "description": "Input white"
                  },
                  "gamma": {
                    "type": "number",
                    "minimum": 0.1,
                    "maximum": 10,
                    "default": 1,
                    "description": "Midtone gamma"
                  },
                  "outBlack": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 255,
                    "default": 0,
                    "description": "Output black"
                  },
                  "outWhite": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 255,
                    "default": 255,
                    "description": "Output white"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  },
                  "mask": {
                    "type": "string",
                    "description": "Limit to mask (mask, optional): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Monotone cubic curves through x,y points (0–255) for master, red, green and blue.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "curves"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "master": {
                    "type": "string",
                    "maxLength": 400,
                    "default": "0,0 255,255",
                    "description": "Master curve points"
                  },
                  "red": {
                    "type": "string",
                    "maxLength": 400,
                    "default": "0,0 255,255",
                    "description": "Red curve points"
                  },
                  "green": {
                    "type": "string",
                    "maxLength": 400,
                    "default": "0,0 255,255",
                    "description": "Green curve points"
                  },
                  "blue": {
                    "type": "string",
                    "maxLength": 400,
                    "default": "0,0 255,255",
                    "description": "Blue curve points"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  },
                  "mask": {
                    "type": "string",
                    "description": "Limit to mask (mask, optional): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Slope, offset, power per channel and saturation (ASC Color Decision List).",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "cdl"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "slope": {
                    "type": "array",
                    "minItems": 3,
                    "maxItems": 3,
                    "items": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 8
                    },
                    "default": [
                      1,
                      1,
                      1
                    ],
                    "description": "Slope (R, G, B)"
                  },
                  "offset": {
                    "type": "array",
                    "minItems": 3,
                    "maxItems": 3,
                    "items": {
                      "type": "number",
                      "minimum": -1,
                      "maximum": 1
                    },
                    "default": [
                      0,
                      0,
                      0
                    ],
                    "description": "Offset (R, G, B)"
                  },
                  "power": {
                    "type": "array",
                    "minItems": 3,
                    "maxItems": 3,
                    "items": {
                      "type": "number",
                      "minimum": 0.05,
                      "maximum": 8
                    },
                    "default": [
                      1,
                      1,
                      1
                    ],
                    "description": "Power (R, G, B)"
                  },
                  "saturation": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 4,
                    "default": 1,
                    "description": "Saturation"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  },
                  "mask": {
                    "type": "string",
                    "description": "Limit to mask (mask, optional): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Hue rotation and saturation and lightness changes in HSL.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "hsl"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "hue": {
                    "type": "number",
                    "minimum": -180,
                    "maximum": 180,
                    "default": 0,
                    "description": "Hue shift (degrees)"
                  },
                  "saturation": {
                    "type": "number",
                    "minimum": -100,
                    "maximum": 300,
                    "default": 0,
                    "description": "Saturation (%)"
                  },
                  "lightness": {
                    "type": "number",
                    "minimum": -100,
                    "maximum": 100,
                    "default": 0,
                    "description": "Lightness (%)"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  },
                  "mask": {
                    "type": "string",
                    "description": "Limit to mask (mask, optional): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Multiplies linear light by 2^stops.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "exposure"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "stops": {
                    "type": "number",
                    "minimum": -10,
                    "maximum": 10,
                    "default": 0,
                    "description": "Exposure (stops)"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  },
                  "mask": {
                    "type": "string",
                    "description": "Limit to mask (mask, optional): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Linear-light gains from a picked neutral colour or entered directly.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "whiteBalance"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "mode": {
                    "enum": [
                      "neutral",
                      "gains"
                    ],
                    "default": "neutral",
                    "description": "White balance method"
                  },
                  "neutral": {
                    "type": "string",
                    "pattern": "^#[0-9A-Fa-f]{6}$",
                    "default": "#c8c0b0",
                    "description": "Neutral colour in the photo"
                  },
                  "gains": {
                    "type": "array",
                    "minItems": 3,
                    "maxItems": 3,
                    "items": {
                      "type": "number",
                      "minimum": 0.05,
                      "maximum": 8
                    },
                    "default": [
                      1,
                      1,
                      1
                    ],
                    "description": "Gains (R, G, B)"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  },
                  "mask": {
                    "type": "string",
                    "description": "Limit to mask (mask, optional): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Applies a 1-D or 3-D .cube LUT with trilinear or tetrahedral interpolation.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "lut"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "cube": {
                    "type": "string",
                    "maxLength": 8000000,
                    "default": "",
                    "description": ".cube data"
                  },
                  "interpolation": {
                    "enum": [
                      "tetrahedral",
                      "trilinear"
                    ],
                    "default": "tetrahedral",
                    "description": "Interpolation"
                  },
                  "strength": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "default": 1,
                    "description": "Strength"
                  },
                  "space": {
                    "enum": [
                      "srgb",
                      "linear"
                    ],
                    "default": "srgb",
                    "description": "LUT input encoding"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  },
                  "mask": {
                    "type": "string",
                    "description": "Limit to mask (mask, optional): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Colour-difference keyer with un-mixing of the backing colour and spill suppression.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "chromaKey"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "key": {
                    "type": "string",
                    "pattern": "^#[0-9A-Fa-f]{6}$",
                    "default": "#00b140",
                    "description": "Screen colour"
                  },
                  "gain": {
                    "type": "number",
                    "minimum": 0.2,
                    "maximum": 4,
                    "default": 1,
                    "description": "Screen gain"
                  },
                  "clipBlack": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 0.99,
                    "default": 0,
                    "description": "Clip black"
                  },
                  "clipWhite": {
                    "type": "number",
                    "minimum": 0.01,
                    "maximum": 1,
                    "default": 1,
                    "description": "Clip white"
                  },
                  "spill": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "default": 1,
                    "description": "Spill suppression"
                  },
                  "balance": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "default": 0.5,
                    "description": "Red/blue balance"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Keeps pixels by brightness between a low and a high threshold.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "lumaKey"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "low": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "default": 0.6,
                    "description": "Low threshold (0–1)"
                  },
                  "high": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "default": 0.8,
                    "description": "High threshold (0–1)"
                  },
                  "invert": {
                    "type": "boolean",
                    "default": false,
                    "description": "Keep the dark parts"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Keeps what differs from a clean plate (the same shot without the subject).",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "differenceKey"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "threshold": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "default": 0.08,
                    "description": "Threshold (0–1)"
                  },
                  "softness": {
                    "type": "number",
                    "minimum": 0.001,
                    "maximum": 1,
                    "default": 0.1,
                    "description": "Softness (0–1)"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  },
                  "plate": {
                    "type": "string",
                    "description": "Clean plate (image): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Limits green or blue spill to the other channels.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "despill"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "screen": {
                    "enum": [
                      "green",
                      "blue"
                    ],
                    "default": "green",
                    "description": "Screen colour family"
                  },
                  "amount": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "default": 1,
                    "description": "Amount"
                  },
                  "limit": {
                    "enum": [
                      "average",
                      "max"
                    ],
                    "default": "average",
                    "description": "Spill limit"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Rectangle, ellipse or polygon with an anti-aliased, feathered edge.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "shapeMask"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "shape": {
                    "enum": [
                      "rect",
                      "ellipse",
                      "polygon"
                    ],
                    "default": "ellipse",
                    "description": "Shape"
                  },
                  "x": {
                    "type": "number",
                    "minimum": -16384,
                    "maximum": 16384,
                    "default": 0,
                    "description": "Left (px)"
                  },
                  "y": {
                    "type": "number",
                    "minimum": -16384,
                    "maximum": 16384,
                    "default": 0,
                    "description": "Top (px)"
                  },
                  "width": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 32768,
                    "default": 256,
                    "description": "Width (px)"
                  },
                  "height": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 32768,
                    "default": 256,
                    "description": "Height (px)"
                  },
                  "points": {
                    "type": "string",
                    "maxLength": 2000,
                    "default": "0,0 100,0 50,100",
                    "description": "Polygon points (x,y px)"
                  },
                  "feather": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 2000,
                    "default": 0,
                    "description": "Feather (px)"
                  },
                  "invert": {
                    "type": "boolean",
                    "default": false,
                    "description": "Invert"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {}
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Turns a painted or keyed image into a mask (alpha, luma or one channel).",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "maskFromImage"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "channel": {
                    "enum": [
                      "luminance",
                      "alpha",
                      "red",
                      "green",
                      "blue"
                    ],
                    "default": "luminance",
                    "description": "Channel"
                  },
                  "invert": {
                    "type": "boolean",
                    "default": false,
                    "description": "Invert"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Adds, subtracts, intersects or differences two masks.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "maskCombine"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "op": {
                    "enum": [
                      "add",
                      "subtract",
                      "intersect",
                      "difference",
                      "max",
                      "min"
                    ],
                    "default": "add",
                    "description": "Operation"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "a": {
                    "type": "string",
                    "description": "Mask A (mask): id of the source node"
                  },
                  "b": {
                    "type": "string",
                    "description": "Mask B (mask): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "One minus the mask.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "maskInvert"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {}
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Mask input (mask): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Dilates (positive) or erodes (negative) a mask with a square neighbourhood.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "maskGrow"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "radius": {
                    "type": "integer",
                    "minimum": -100,
                    "maximum": 100,
                    "default": 2,
                    "description": "Radius (px, negative shrinks)"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Mask input (mask): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Softens a mask with a Gaussian.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "maskBlur"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "radius": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 200,
                    "default": 3,
                    "description": "Radius (px)"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Mask input (mask): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Multiplies the image alpha by a mask, or replaces the alpha with it.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "setMatte"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "mode": {
                    "enum": [
                      "multiply",
                      "replace"
                    ],
                    "default": "multiply",
                    "description": "Mode"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  },
                  "mask": {
                    "type": "string",
                    "description": "Mask (mask): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "Porter–Duff compositing of a foreground with a background, with W3C blend modes.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "merge"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "operator": {
                    "enum": [
                      "over",
                      "under",
                      "in",
                      "mask",
                      "out",
                      "stencil",
                      "atop",
                      "dest-atop",
                      "xor",
                      "plus",
                      "copy",
                      "destination",
                      "clear"
                    ],
                    "default": "over",
                    "description": "Operator"
                  },
                  "blend": {
                    "enum": [
                      "normal",
                      "multiply",
                      "screen",
                      "overlay",
                      "soft-light",
                      "hard-light",
                      "add",
                      "difference",
                      "exclusion",
                      "darken",
                      "lighten",
                      "color-dodge",
                      "color-burn"
                    ],
                    "default": "normal",
                    "description": "Blend mode"
                  },
                  "opacity": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "default": 1,
                    "description": "Foreground opacity"
                  },
                  "space": {
                    "enum": [
                      "linear",
                      "srgb"
                    ],
                    "default": "linear",
                    "description": "Blend in"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "fg": {
                    "type": "string",
                    "description": "Foreground (A) (image): id of the source node"
                  },
                  "bg": {
                    "type": "string",
                    "description": "Background (B) (image): id of the source node"
                  },
                  "mask": {
                    "type": "string",
                    "description": "Mix mask (mask, optional): id of the source node"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "description": "The result of the graph; optionally flattened onto a colour.",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$"
              },
              "type": {
                "const": "output"
              },
              "label": {
                "type": "string",
                "maxLength": 80
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "flatten": {
                    "type": "boolean",
                    "default": false,
                    "description": "Flatten onto a background colour"
                  },
                  "background": {
                    "type": "string",
                    "pattern": "^#[0-9A-Fa-f]{6}$",
                    "default": "#ffffff",
                    "description": "Background colour"
                  }
                }
              },
              "inputs": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "in": {
                    "type": "string",
                    "description": "Image input (image): id of the source node"
                  }
                }
              }
            }
          }
        ]
      }
    }
  }
}
