{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://raw.githubusercontent.com/arthurafarias/vscode-extension-ui-designer/master/schemas/design-1.0.schema.json",
  "$comment": "Milestone 0.0 draft (SRS PLT-4): written by hand from FMT-001 (planning.pb issue #2). From 0.1 on it is replaced by the schema generated from the core's TypeScript types. `x-merge` marks the merge-patch semantics of object properties (FMT-001 5.9).",
  "title": "SoftForge UI Designer design file, format 1.0",
  "description": "A `.design` file (FMT-001): one design document (pages, layers, components, styles, variables, prototype flows, comments, named versions) as plain UTF-8 JSON. `tree` is the document at the last consolidation; `wal` is the write-append list of events since then, one per line. To change the design, append events to `wal` (or use the `ud` command); never edit `tree`. Property names are the Figma Plugin API names. Unknown members are kept and unknown operations are valid (they are skipped by readers).",
  "$ref": "#/$defs/designFile",
  "$defs": {
    "fractionalIndex": {
      "description": "Fractional index (4.3, DOC-3): a non-empty string over `0-9`, `A-Z`, `a-z`. Siblings are ordered by plain string comparison (code point by code point, a prefix before a longer string), ties by id. Ascending is back to front (first painted first) and, in auto layout, flow order. Writers generate a key between the neighbours (e.g. with `fractional-indexing`'s `generateKeyBetween`); readers never parse a key.",
      "type": "string",
      "minLength": 1,
      "pattern": "^[0-9A-Za-z]+$"
    },
    "nodeId": {
      "description": "Node id (Appendix A): `nd-` and 12 random lowercase hex digits, e.g. `nd-3f9a0c1e7b2d`. Made by the writer of the event that creates the node, never reused. `nd:<hex>` with a colon is accepted as input by `ud` and is never written to the file (5.5).",
      "type": "string",
      "pattern": "^nd-[0-9a-f]{12}$"
    },
    "pageId": {
      "description": "Page id: `pg-` and 12 random lowercase hex digits (Appendix A).",
      "type": "string",
      "pattern": "^pg-[0-9a-f]{12}$"
    },
    "qualifiedId": {
      "description": "Qualified id of something in a library (4.11): the library id, a slash and the id inside the library, e.g. `lib-1f3b5d7a9c0e/nd-8a3f1c5e7b92`. Accepted wherever the local id would be: `componentId`, style ids, variable aliases, `boundVariables`.",
      "type": "string",
      "pattern": "^lib-[0-9a-f]{12}/[a-z]+-[0-9a-f]{12}$"
    },
    "timestamp": {
      "description": "A UTC timestamp with milliseconds, `YYYY-MM-DDTHH:MM:SS.sssZ` (5.6), e.g. `2026-10-06T09:12:30.412Z`. Readers compare timestamps as text, so never write an offset or leave out the milliseconds.",
      "type": "string",
      "format": "date-time",
      "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{3}Z$"
    },
    "treeHash": {
      "description": "A tree hash (6.9): `sha256:` and the 64 lowercase hex digits of the SHA-256 of the canonical tree. Names a document state across branches (`--if-version`, named versions, `library.acceptedHash`).",
      "type": "string",
      "pattern": "^sha256:[0-9a-f]{64}$"
    },
    "assetHash": {
      "description": "Content hash of a file in the assets folder (8.2): `sha256-` and the 64 lowercase hex digits of the SHA-256 of its bytes. The file is `<hash>.<ext>` in `<name>.design.assets/`.",
      "type": "string",
      "pattern": "^sha256-[0-9a-f]{64}$"
    },
    "documentId": {
      "description": "Document id: `doc-` and 12 random lowercase hex digits. Never changes, also not when the file is renamed or moved; libraries and `ud://` links refer to it.",
      "type": "string",
      "pattern": "^doc-[0-9a-f]{12}$"
    },
    "styleId": {
      "description": "Style id: `st-` and 12 random lowercase hex digits.",
      "type": "string",
      "pattern": "^st-[0-9a-f]{12}$"
    },
    "variableCollectionId": {
      "description": "Variable collection id: `vc-` and 12 random lowercase hex digits.",
      "type": "string",
      "pattern": "^vc-[0-9a-f]{12}$"
    },
    "modeId": {
      "description": "Mode id: `md-` and 12 random lowercase hex digits.",
      "type": "string",
      "pattern": "^md-[0-9a-f]{12}$"
    },
    "variableId": {
      "description": "Variable id: `vr-` and 12 random lowercase hex digits.",
      "type": "string",
      "pattern": "^vr-[0-9a-f]{12}$"
    },
    "libraryId": {
      "description": "Library reference id: `lib-` and 12 random lowercase hex digits.",
      "type": "string",
      "pattern": "^lib-[0-9a-f]{12}$"
    },
    "flowId": {
      "description": "Prototype flow id: `fl-` and 12 random lowercase hex digits.",
      "type": "string",
      "pattern": "^fl-[0-9a-f]{12}$"
    },
    "commentId": {
      "description": "Comment id: `cn-` and 12 random lowercase hex digits.",
      "type": "string",
      "pattern": "^cn-[0-9a-f]{12}$"
    },
    "versionId": {
      "description": "Named version id: `vs-` and 12 random lowercase hex digits.",
      "type": "string",
      "pattern": "^vs-[0-9a-f]{12}$"
    },
    "groupId": {
      "description": "Event group id (5.7): `tx-` and 12 random lowercase hex digits.",
      "type": "string",
      "pattern": "^tx-[0-9a-f]{12}$"
    },
    "annotationCategoryId": {
      "description": "Annotation category id: `an-` and 12 random lowercase hex digits for a category added by a user, or one of the built-in ids `behaviour`, `accessibility`, `interaction` (4.2).",
      "type": "string",
      "pattern": "^(an-[0-9a-f]{12}|behaviour|accessibility|interaction)$"
    },
    "nodeRef": {
      "description": "A node id, or the derived id of an instance sublayer: `<instance id>/<override path>`, e.g. `nd-e7a9c1b3d5f0/nd-2b7d9e4f6a10` (4.8). The derived form is also the `parent` of slot content.",
      "type": "string",
      "pattern": "^nd-[0-9a-f]{12}(/nd-[0-9a-f]{12})*$"
    },
    "overridePath": {
      "description": "Override path (4.8): the ids of the nodes from the main component down to a sublayer, joined by `/`, e.g. `nd-2b7d9e4f6a10` or `nd-5a1c3e7f9b20/nd-0d2f4b6a8c1e`. Never empty.",
      "type": "string",
      "pattern": "^nd-[0-9a-f]{12}(/nd-[0-9a-f]{12})*$"
    },
    "componentRef": {
      "description": "A main component (or variant): a node id, or a qualified id `lib-…/nd-…` for a library component (4.11).",
      "type": "string",
      "pattern": "^(lib-[0-9a-f]{12}/)?nd-[0-9a-f]{12}$"
    },
    "styleRef": {
      "description": "A style: a style id, or a qualified id `lib-…/st-…` for a library style (4.11).",
      "type": "string",
      "pattern": "^(lib-[0-9a-f]{12}/)?st-[0-9a-f]{12}$"
    },
    "variableRef": {
      "description": "A variable: a variable id, or a qualified id `lib-…/vr-…` for a library variable (4.11).",
      "type": "string",
      "pattern": "^(lib-[0-9a-f]{12}/)?vr-[0-9a-f]{12}$"
    },
    "variableCollectionRef": {
      "description": "A variable collection: a collection id, or (assumed by this draft) a qualified id `lib-…/vc-…` for a library collection.",
      "type": "string",
      "pattern": "^(lib-[0-9a-f]{12}/)?vc-[0-9a-f]{12}$"
    },
    "modeRef": {
      "description": "A mode: a mode id, or (assumed by this draft) a qualified id `lib-…/md-…` for a mode of a library collection.",
      "type": "string",
      "pattern": "^(lib-[0-9a-f]{12}/)?md-[0-9a-f]{12}$"
    },
    "componentPropertyKey": {
      "description": "Component property key (4.8): a variant property is its plain name (`Size`); any other property is `<name>#<4 hex digits>` (`Label#a41c`), the suffix chosen at random when the property is created so that renaming keeps the key.",
      "type": "string",
      "minLength": 1
    },
    "rgb": {
      "description": "An RGB colour without alpha (4.7.1): floats from 0 to 1 in the document's colour profile. Used by `SOLID` paints, whose transparency is the paint's `opacity`. A reader that finds `a` multiplies it into the paint's `opacity`.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "r": {
          "description": "Red, 0 to 1.",
          "type": "number",
          "minimum": 0,
          "maximum": 1
        },
        "g": {
          "description": "Green, 0 to 1.",
          "type": "number",
          "minimum": 0,
          "maximum": 1
        },
        "b": {
          "description": "Blue, 0 to 1.",
          "type": "number",
          "minimum": 0,
          "maximum": 1
        }
      },
      "required": [
        "r",
        "g",
        "b"
      ]
    },
    "color": {
      "description": "A colour with alpha (4.7.1), `{\"r\": 0.231, \"g\": 0.357, \"b\": 0.965, \"a\": 1}`: floats from 0 to 1 in the document's colour profile. Used by gradient stops, effects, layout grids and `COLOR` variable values.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "r": {
          "description": "Red, 0 to 1.",
          "type": "number",
          "minimum": 0,
          "maximum": 1
        },
        "g": {
          "description": "Green, 0 to 1.",
          "type": "number",
          "minimum": 0,
          "maximum": 1
        },
        "b": {
          "description": "Blue, 0 to 1.",
          "type": "number",
          "minimum": 0,
          "maximum": 1
        },
        "a": {
          "description": "Alpha, 0 to 1.",
          "type": "number",
          "minimum": 0,
          "maximum": 1
        }
      },
      "required": [
        "r",
        "g",
        "b",
        "a"
      ]
    },
    "variableAlias": {
      "description": "A reference to a variable, Figma's shape `{\"type\": \"VARIABLE_ALIAS\", \"id\": \"vr-…\"}` (4.4.5, 4.10). Replaced whole by a patch.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "type": {
          "description": "Always `VARIABLE_ALIAS`.",
          "const": "VARIABLE_ALIAS"
        },
        "id": {
          "description": "The variable: `vr-…`, or `lib-…/vr-…` for a library variable.",
          "$ref": "#/$defs/variableRef"
        }
      },
      "required": [
        "type",
        "id"
      ]
    },
    "paint": {
      "description": "A paint (4.7.2), Figma's shape: `SOLID`, a gradient or `IMAGE`, with optional `visible`, `opacity` and `blendMode`. Paints live in arrays (`fills`, `strokes`, `backgrounds`, `paints`), which a patch replaces as a whole. A paint bound to a variable keeps its plain colour as the fallback (4.7.3).",
      "type": "object",
      "additionalProperties": true,
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "description": "Kind of paint.",
          "type": "string",
          "enum": [
            "SOLID",
            "GRADIENT_LINEAR",
            "GRADIENT_RADIAL",
            "GRADIENT_ANGULAR",
            "GRADIENT_DIAMOND",
            "IMAGE"
          ]
        },
        "visible": {
          "description": "Shown. Default `true`.",
          "type": "boolean"
        },
        "opacity": {
          "description": "Opacity of the paint, 0 to 1. Default `1`.",
          "type": "number",
          "minimum": 0,
          "maximum": 1
        },
        "blendMode": {
          "description": "Blend mode. Default `\"NORMAL\"`.",
          "type": "string",
          "enum": [
            "PASS_THROUGH",
            "NORMAL",
            "DARKEN",
            "MULTIPLY",
            "LINEAR_BURN",
            "COLOR_BURN",
            "LIGHTEN",
            "SCREEN",
            "LINEAR_DODGE",
            "COLOR_DODGE",
            "OVERLAY",
            "SOFT_LIGHT",
            "HARD_LIGHT",
            "DIFFERENCE",
            "EXCLUSION",
            "HUE",
            "SATURATION",
            "COLOR",
            "LUMINOSITY"
          ]
        }
      },
      "allOf": [
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "const": "SOLID"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "required": [
              "color"
            ],
            "properties": {
              "color": {
                "description": "`{r,g,b}` without `a`; transparency is the paint's `opacity` (4.7.1).",
                "$ref": "#/$defs/rgb",
                "x-merge": "replace"
              },
              "boundVariables": {
                "description": "Bindings of this entry's members to variables (`color`). Lives inside an array entry, so it is replaced with the whole array.",
                "type": "object",
                "additionalProperties": {
                  "description": "The variable the member is bound to.",
                  "$ref": "#/$defs/variableAlias",
                  "x-merge": "replace"
                },
                "x-merge": "replace"
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "enum": [
                  "GRADIENT_LINEAR",
                  "GRADIENT_RADIAL",
                  "GRADIENT_ANGULAR",
                  "GRADIENT_DIAMOND"
                ]
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "required": [
              "gradientTransform",
              "gradientStops"
            ],
            "properties": {
              "gradientTransform": {
                "description": "2×3 matrix `[[a,b,c],[d,e,f]]` in the node's unit square (STY-2).",
                "type": "array",
                "minItems": 2,
                "maxItems": 2,
                "items": {
                  "description": "A row of the matrix.",
                  "type": "array",
                  "minItems": 3,
                  "maxItems": 3,
                  "items": {
                    "description": "A matrix entry.",
                    "type": "number"
                  }
                }
              },
              "gradientStops": {
                "description": "The stops of the gradient.",
                "type": "array",
                "items": {
                  "description": "A gradient stop.",
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "position": {
                      "description": "Position along the gradient, 0 to 1.",
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "color": {
                      "description": "Colour of the stop, with `a`.",
                      "$ref": "#/$defs/color",
                      "x-merge": "replace"
                    },
                    "boundVariables": {
                      "description": "Bindings of this entry's members to variables (`color`). Lives inside an array entry, so it is replaced with the whole array.",
                      "type": "object",
                      "additionalProperties": {
                        "description": "The variable the member is bound to.",
                        "$ref": "#/$defs/variableAlias",
                        "x-merge": "replace"
                      },
                      "x-merge": "replace"
                    }
                  },
                  "required": [
                    "position",
                    "color"
                  ]
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "const": "IMAGE"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "required": [
              "imageHash"
            ],
            "properties": {
              "imageHash": {
                "description": "Content hash of the image file in the assets folder (section 8). Required.",
                "$ref": "#/$defs/assetHash"
              },
              "scaleMode": {
                "description": "Scale mode (STY-3). Default `\"FILL\"`.",
                "type": "string",
                "enum": [
                  "FILL",
                  "FIT",
                  "CROP",
                  "TILE"
                ]
              },
              "imageTransform": {
                "description": "Crop rectangle, a 2×3 matrix, for `CROP`. Default identity.",
                "type": "array",
                "minItems": 2,
                "maxItems": 2,
                "items": {
                  "description": "A row of the matrix.",
                  "type": "array",
                  "minItems": 3,
                  "maxItems": 3,
                  "items": {
                    "description": "A matrix entry.",
                    "type": "number"
                  }
                }
              },
              "scalingFactor": {
                "description": "Tile scale, for `TILE`. Default `1`.",
                "type": "number"
              },
              "rotation": {
                "description": "Rotation of the image in degrees: `0`, `90`, `180` or `270`. Default `0`.",
                "enum": [
                  0,
                  90,
                  180,
                  270
                ]
              },
              "filters": {
                "description": "Image adjustments, numbers from -1 to 1. Default all `0`. Inside an array entry, so replaced with the array.",
                "type": "object",
                "additionalProperties": true,
                "properties": {
                  "exposure": {
                    "description": "Exposure, -1 to 1.",
                    "type": "number",
                    "minimum": -1,
                    "maximum": 1
                  },
                  "contrast": {
                    "description": "Contrast, -1 to 1.",
                    "type": "number",
                    "minimum": -1,
                    "maximum": 1
                  },
                  "saturation": {
                    "description": "Saturation, -1 to 1.",
                    "type": "number",
                    "minimum": -1,
                    "maximum": 1
                  },
                  "temperature": {
                    "description": "Temperature, -1 to 1.",
                    "type": "number",
                    "minimum": -1,
                    "maximum": 1
                  },
                  "tint": {
                    "description": "Tint, -1 to 1.",
                    "type": "number",
                    "minimum": -1,
                    "maximum": 1
                  },
                  "highlights": {
                    "description": "Highlights, -1 to 1.",
                    "type": "number",
                    "minimum": -1,
                    "maximum": 1
                  },
                  "shadows": {
                    "description": "Shadows, -1 to 1.",
                    "type": "number",
                    "minimum": -1,
                    "maximum": 1
                  }
                },
                "x-merge": "replace"
              }
            }
          }
        }
      ]
    },
    "effect": {
      "description": "An effect (4.7.5, STY-6, STY-9), Figma's shape: `DROP_SHADOW` and `INNER_SHADOW` (`color`, `offset`, `radius`, `spread`, `blendMode`, `visible`; drop shadows also `showShadowBehindNode`), `LAYER_BLUR` and `BACKGROUND_BLUR` (`radius`, `visible`, `blurType`; progressive also `startRadius`, `startOffset`, `endOffset`), `NOISE` (`noiseSize`, `density`, `noiseType`, `color`, `secondaryColor`, `opacity`, `blendMode`, `visible`) and `TEXTURE` (`noiseSize`, `radius`, `clipToShape`, `visible`).",
      "type": "object",
      "additionalProperties": true,
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "description": "Kind of effect.",
          "type": "string",
          "enum": [
            "DROP_SHADOW",
            "INNER_SHADOW",
            "LAYER_BLUR",
            "BACKGROUND_BLUR",
            "NOISE",
            "TEXTURE"
          ]
        },
        "radius": {
          "description": "Blur radius, px; `TEXTURE`: displacement, px (0–20).",
          "type": "number",
          "minimum": 0
        },
        "visible": {
          "description": "Shown. Default `true`.",
          "type": "boolean"
        },
        "boundVariables": {
          "description": "Bindings of this entry's members to variables (`color`, `radius`, `spread`, `offsetX`, `offsetY`). Lives inside an array entry, so it is replaced with the whole array.",
          "type": "object",
          "additionalProperties": {
            "description": "The variable the member is bound to.",
            "$ref": "#/$defs/variableAlias",
            "x-merge": "replace"
          },
          "x-merge": "replace"
        }
      },
      "allOf": [
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "enum": [
                  "DROP_SHADOW",
                  "INNER_SHADOW"
                ]
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "color": {
                "description": "Shadow colour, with `a`.",
                "$ref": "#/$defs/color",
                "x-merge": "replace"
              },
              "offset": {
                "description": "Shadow offset `{x, y}`, px.",
                "type": "object",
                "additionalProperties": true,
                "properties": {
                  "x": {
                    "description": "Horizontal component, px.",
                    "type": "number"
                  },
                  "y": {
                    "description": "Vertical component, px.",
                    "type": "number"
                  }
                },
                "required": [
                  "x",
                  "y"
                ],
                "x-merge": "replace"
              },
              "spread": {
                "description": "Spread, px.",
                "type": "number"
              },
              "blendMode": {
                "description": "Blend mode of the shadow.",
                "type": "string",
                "enum": [
                  "PASS_THROUGH",
                  "NORMAL",
                  "DARKEN",
                  "MULTIPLY",
                  "LINEAR_BURN",
                  "COLOR_BURN",
                  "LIGHTEN",
                  "SCREEN",
                  "LINEAR_DODGE",
                  "COLOR_DODGE",
                  "OVERLAY",
                  "SOFT_LIGHT",
                  "HARD_LIGHT",
                  "DIFFERENCE",
                  "EXCLUSION",
                  "HUE",
                  "SATURATION",
                  "COLOR",
                  "LUMINOSITY"
                ]
              },
              "showShadowBehindNode": {
                "description": "`DROP_SHADOW` only: show the shadow behind a translucent node.",
                "type": "boolean"
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "enum": [
                  "LAYER_BLUR",
                  "BACKGROUND_BLUR"
                ]
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "blurType": {
                "description": "STY-9: `NORMAL` (default), or `PROGRESSIVE`: the radius goes linearly from `startRadius` at `startOffset` to `radius` at `endOffset`.",
                "type": "string",
                "enum": [
                  "NORMAL",
                  "PROGRESSIVE"
                ]
              },
              "startRadius": {
                "description": "`PROGRESSIVE`: blur radius at `startOffset`, px. Default `0`.",
                "type": "number",
                "minimum": 0
              },
              "startOffset": {
                "description": "`PROGRESSIVE`: where the blur is `startRadius`, in the node's box. Default `{\"x\": 0, \"y\": 0}`.",
                "type": "object",
                "additionalProperties": true,
                "properties": {
                  "x": {
                    "description": "Horizontal position in the node's box, 0 (left) to 1 (right).",
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1
                  },
                  "y": {
                    "description": "Vertical position in the node's box, 0 (top) to 1 (bottom).",
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1
                  }
                },
                "required": [
                  "x",
                  "y"
                ],
                "x-merge": "replace"
              },
              "endOffset": {
                "description": "`PROGRESSIVE`: where the blur reaches `radius`, in the node's box. Default `{\"x\": 0, \"y\": 1}`.",
                "type": "object",
                "additionalProperties": true,
                "properties": {
                  "x": {
                    "description": "Horizontal position in the node's box, 0 (left) to 1 (right).",
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1
                  },
                  "y": {
                    "description": "Vertical position in the node's box, 0 (top) to 1 (bottom).",
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1
                  }
                },
                "required": [
                  "x",
                  "y"
                ],
                "x-merge": "replace"
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "const": "NOISE"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "blendMode": {
                "description": "Blend mode of the grain. Default `NORMAL`.",
                "type": "string",
                "enum": [
                  "PASS_THROUGH",
                  "NORMAL",
                  "DARKEN",
                  "MULTIPLY",
                  "LINEAR_BURN",
                  "COLOR_BURN",
                  "LIGHTEN",
                  "SCREEN",
                  "LINEAR_DODGE",
                  "COLOR_DODGE",
                  "OVERLAY",
                  "SOFT_LIGHT",
                  "HARD_LIGHT",
                  "DIFFERENCE",
                  "EXCLUSION",
                  "HUE",
                  "SATURATION",
                  "COLOR",
                  "LUMINOSITY"
                ]
              },
              "noiseSize": {
                "description": "Grain size, px per grain, 1–10. Default `2`.",
                "type": "number",
                "minimum": 1,
                "maximum": 10
              },
              "density": {
                "description": "Share of the area covered by grains, 0–1. Default `0.5`.",
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "noiseType": {
                "description": "`MONOTONE`: grains of `color`; `DUOTONE`: `color` grains on `secondaryColor`; `MULTITONE`: grains of hues around `color`. Default `MONOTONE`.",
                "type": "string",
                "enum": [
                  "MONOTONE",
                  "DUOTONE",
                  "MULTITONE"
                ]
              },
              "color": {
                "description": "Grain colour, with `a`. Default black at 25 %.",
                "$ref": "#/$defs/color",
                "x-merge": "replace"
              },
              "secondaryColor": {
                "description": "`DUOTONE`: the colour between the grains, with `a`. Default white at 25 %.",
                "$ref": "#/$defs/color",
                "x-merge": "replace"
              },
              "opacity": {
                "description": "Opacity of the whole noise, 0–1. Default `1`.",
                "type": "number",
                "minimum": 0,
                "maximum": 1
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "const": "TEXTURE"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "noiseSize": {
                "description": "Grain size of the displacement field, px, 1–10. Default `2`.",
                "type": "number",
                "minimum": 1,
                "maximum": 10
              },
              "radius": {
                "description": "Displacement, px, 0–20. Default `4`.",
                "type": "number",
                "minimum": 0,
                "maximum": 20
              },
              "clipToShape": {
                "description": "Displaced pixels stay inside the node's shape. Default `true`.",
                "type": "boolean"
              }
            }
          }
        }
      ]
    },
    "layoutGrid": {
      "description": "A layout grid (LAY-8), Figma's shape: `{pattern, alignment, count, gutterSize, offset, sectionSize, visible, color}`.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "pattern": {
          "description": "Columns, rows or a uniform grid.",
          "type": "string",
          "enum": [
            "COLUMNS",
            "ROWS",
            "GRID"
          ]
        },
        "alignment": {
          "description": "Alignment of columns or rows.",
          "type": "string",
          "enum": [
            "MIN",
            "MAX",
            "CENTER",
            "STRETCH"
          ]
        },
        "count": {
          "description": "Number of columns or rows.",
          "type": "integer",
          "minimum": 1
        },
        "gutterSize": {
          "description": "Gutter between columns or rows. In px.",
          "type": "number"
        },
        "offset": {
          "description": "Offset from the frame edge. In px.",
          "type": "number"
        },
        "sectionSize": {
          "description": "Size of a column, a row or a grid cell. In px.",
          "type": "number"
        },
        "visible": {
          "description": "Shown on the canvas.",
          "type": "boolean"
        },
        "color": {
          "description": "Colour of the guides, with `a`.",
          "$ref": "#/$defs/color",
          "x-merge": "replace"
        },
        "boundVariables": {
          "description": "Bindings of this entry's members to variables (`gutterSize`, `count`, `offset`, `sectionSize`). Lives inside an array entry, so it is replaced with the whole array.",
          "type": "object",
          "additionalProperties": {
            "description": "The variable the member is bound to.",
            "$ref": "#/$defs/variableAlias",
            "x-merge": "replace"
          },
          "x-merge": "replace"
        }
      },
      "required": [
        "pattern"
      ]
    },
    "exportSetting": {
      "description": "An export setting (EXP-1), Figma's shape.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "format": {
          "description": "Output format.",
          "type": "string",
          "enum": [
            "PNG",
            "JPG",
            "WEBP",
            "SVG",
            "PDF"
          ]
        },
        "suffix": {
          "description": "Suffix added to the file name, e.g. `@2x`.",
          "type": "string"
        },
        "constraint": {
          "description": "Size of the output.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "type": {
              "description": "Scale factor, or a fixed width or height.",
              "type": "string",
              "enum": [
                "SCALE",
                "WIDTH",
                "HEIGHT"
              ]
            },
            "value": {
              "description": "The scale, or the width or height in px.",
              "type": "number"
            }
          },
          "required": [
            "type",
            "value"
          ],
          "x-merge": "replace"
        },
        "contentsOnly": {
          "description": "Export only the node's contents (Figma).",
          "type": "boolean"
        },
        "useAbsoluteBounds": {
          "description": "Use the node's full bounds rather than its rendered bounds.",
          "type": "boolean"
        },
        "svgOutlineText": {
          "description": "SVG: outline text.",
          "type": "boolean"
        },
        "svgIdAttribute": {
          "description": "SVG: write layer names as `id` attributes.",
          "type": "boolean"
        },
        "svgSimplifyStroke": {
          "description": "SVG: simplify strokes.",
          "type": "boolean"
        }
      },
      "required": [
        "format"
      ]
    },
    "reactionAction": {
      "description": "One action of a reaction (4.4.7), Figma's shape.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "type": {
          "description": "Kind of action.",
          "type": "string",
          "enum": [
            "NODE",
            "BACK",
            "CLOSE",
            "URL",
            "SET_VARIABLE",
            "SET_VARIABLE_MODE",
            "CONDITIONAL"
          ]
        },
        "destinationId": {
          "description": "`NODE`: the destination node. A `destinationId` that names no node makes the action inert; the reader keeps it and `ud lint` reports it.",
          "$ref": "#/$defs/nodeRef"
        },
        "navigation": {
          "description": "`NODE`: how to go to the destination.",
          "type": "string",
          "enum": [
            "NAVIGATE",
            "CHANGE_TO",
            "OVERLAY",
            "SWAP",
            "SCROLL_TO"
          ]
        },
        "transition": {
          "description": "Transition; absent is instant.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "type": {
              "description": "Kind of transition.",
              "type": "string",
              "enum": [
                "DISSOLVE",
                "SMART_ANIMATE",
                "MOVE_IN",
                "MOVE_OUT",
                "PUSH",
                "SLIDE_IN",
                "SLIDE_OUT",
                "SCROLL_ANIMATE"
              ]
            },
            "easing": {
              "description": "Easing of the transition.",
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "type": {
                  "description": "Easing curve.",
                  "type": "string",
                  "enum": [
                    "LINEAR",
                    "EASE_IN",
                    "EASE_OUT",
                    "EASE_IN_AND_OUT",
                    "EASE_IN_BACK",
                    "EASE_OUT_BACK",
                    "EASE_IN_AND_OUT_BACK",
                    "CUSTOM_CUBIC_BEZIER",
                    "GENTLE",
                    "QUICK",
                    "BOUNCY",
                    "SLOW",
                    "CUSTOM_SPRING"
                  ]
                },
                "easingFunctionCubicBezier": {
                  "description": "`CUSTOM_CUBIC_BEZIER`: the control points.",
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "x1": {
                      "description": "First control point x.",
                      "type": "number"
                    },
                    "y1": {
                      "description": "First control point y.",
                      "type": "number"
                    },
                    "x2": {
                      "description": "Second control point x.",
                      "type": "number"
                    },
                    "y2": {
                      "description": "Second control point y.",
                      "type": "number"
                    }
                  },
                  "x-merge": "replace"
                },
                "easingFunctionSpring": {
                  "description": "`CUSTOM_SPRING`: the spring.",
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "mass": {
                      "description": "Mass.",
                      "type": "number"
                    },
                    "stiffness": {
                      "description": "Stiffness.",
                      "type": "number"
                    },
                    "damping": {
                      "description": "Damping.",
                      "type": "number"
                    },
                    "initialVelocity": {
                      "description": "Initial velocity.",
                      "type": "number"
                    }
                  },
                  "x-merge": "replace"
                }
              },
              "required": [
                "type"
              ],
              "x-merge": "replace"
            },
            "duration": {
              "description": "Duration in seconds.",
              "type": "number",
              "minimum": 0
            },
            "direction": {
              "description": "Direction, for the transitions that have one.",
              "type": "string",
              "enum": [
                "LEFT",
                "RIGHT",
                "TOP",
                "BOTTOM"
              ]
            },
            "matchLayers": {
              "description": "Match layers by name, for the transitions that have it.",
              "type": "boolean"
            }
          },
          "required": [
            "type"
          ],
          "x-merge": "replace"
        },
        "preserveScrollPosition": {
          "description": "`NODE`: keep the scroll position.",
          "type": "boolean"
        },
        "url": {
          "description": "`URL`: the address to open.",
          "type": "string"
        },
        "openInNewTab": {
          "description": "`URL`: open in a new tab (Figma).",
          "type": "boolean"
        },
        "variableId": {
          "description": "`SET_VARIABLE`: the variable to set.",
          "$ref": "#/$defs/variableRef"
        },
        "variableValue": {
          "description": "`SET_VARIABLE`: the value to set, Figma's `VariableData` shape.",
          "x-merge": "replace"
        },
        "variableCollectionId": {
          "description": "`SET_VARIABLE_MODE`: the collection.",
          "$ref": "#/$defs/variableCollectionRef"
        },
        "variableModeId": {
          "description": "`SET_VARIABLE_MODE`: the mode to switch to.",
          "$ref": "#/$defs/modeRef"
        },
        "conditionalBlocks": {
          "description": "`CONDITIONAL`: the blocks, Figma's shape.",
          "type": "array",
          "items": {
            "description": "A conditional block, Figma's shape.",
            "type": "object",
            "x-merge": "replace"
          }
        }
      },
      "required": [
        "type"
      ]
    },
    "reaction": {
      "description": "A prototype reaction (PRO-1 – PRO-4), Figma's shape: a trigger and its actions. Durations and delays are in seconds.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "trigger": {
          "description": "What starts the reaction.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "type": {
              "description": "Kind of trigger.",
              "type": "string",
              "enum": [
                "ON_CLICK",
                "ON_HOVER",
                "WHILE_HOVERING",
                "ON_PRESS",
                "WHILE_PRESSING",
                "ON_DRAG",
                "ON_KEY_DOWN",
                "MOUSE_ENTER",
                "MOUSE_LEAVE",
                "MOUSE_DOWN",
                "MOUSE_UP",
                "AFTER_TIMEOUT"
              ]
            },
            "keyCodes": {
              "description": "`ON_KEY_DOWN`: the key codes.",
              "type": "array",
              "items": {
                "description": "A key code.",
                "type": "integer"
              }
            },
            "device": {
              "description": "`ON_KEY_DOWN`: the input device (Figma's values, e.g. `KEYBOARD`).",
              "type": "string"
            },
            "timeout": {
              "description": "`AFTER_TIMEOUT`: seconds.",
              "type": "number",
              "minimum": 0
            },
            "delay": {
              "description": "`MOUSE_*` triggers: delay in seconds (Figma).",
              "type": "number",
              "minimum": 0
            }
          },
          "required": [
            "type"
          ],
          "x-merge": "replace"
        },
        "actions": {
          "description": "What happens, in order.",
          "type": "array",
          "items": {
            "description": "An action.",
            "$ref": "#/$defs/reactionAction",
            "x-merge": "replace"
          }
        }
      },
      "required": [
        "trigger",
        "actions"
      ]
    },
    "styledRun": {
      "description": "A styled run (TXT-2): a range of the text whose properties differ from the node-level values. Carries only the properties that differ. A reader that finds runs beyond the end of the text cuts them and drops empty ones (9.2).",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "start": {
          "description": "First UTF-16 code unit of the range.",
          "type": "integer",
          "minimum": 0
        },
        "end": {
          "description": "End of the range in UTF-16 code units, exclusive.",
          "type": "integer",
          "minimum": 0
        },
        "fontName": {
          "description": "Font family and style. Default `{\"family\":\"Inter\",\"style\":\"Regular\"}`. Replaced whole by a patch.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "family": {
              "description": "Font family, e.g. `\"Inter\"`.",
              "type": "string"
            },
            "style": {
              "description": "Figma's style name, e.g. `\"Semi Bold\"` (CMD-15).",
              "type": "string"
            }
          },
          "required": [
            "family",
            "style"
          ],
          "x-merge": "replace"
        },
        "fontSize": {
          "description": "Font size. Default `12`. In px.",
          "type": "number",
          "minimum": 0
        },
        "fontVariations": {
          "description": "Variable font axes, a map of axis tag to number, e.g. `{\"wght\": 550, \"opsz\": 14}` (TXT-4). Our own. Default `{}`. Merges per axis.",
          "type": "object",
          "additionalProperties": {
            "description": "Axis value.",
            "type": "number"
          },
          "x-merge": "merge"
        },
        "letterSpacing": {
          "description": "Letter spacing, `{unit: \"PIXELS\" or \"PERCENT\", value}`. Default `{\"unit\":\"PERCENT\",\"value\":0}`. Replaced whole by a patch.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "unit": {
              "description": "Unit of `value`.",
              "type": "string",
              "enum": [
                "PIXELS",
                "PERCENT"
              ]
            },
            "value": {
              "description": "The spacing.",
              "type": "number"
            }
          },
          "required": [
            "unit",
            "value"
          ],
          "x-merge": "replace"
        },
        "lineHeight": {
          "description": "Line height, `{unit: \"AUTO\"}` or `{unit: \"PIXELS\" or \"PERCENT\", value}`. Default `{\"unit\":\"AUTO\"}`. Replaced whole by a patch.",
          "type": "object",
          "additionalProperties": true,
          "required": [
            "unit"
          ],
          "properties": {
            "unit": {
              "description": "Unit: `AUTO`, or `PIXELS` / `PERCENT` with a `value`.",
              "type": "string",
              "enum": [
                "AUTO",
                "PIXELS",
                "PERCENT"
              ]
            },
            "value": {
              "description": "The line height; absent for `AUTO`.",
              "type": "number"
            }
          },
          "if": {
            "type": "object",
            "properties": {
              "unit": {
                "enum": [
                  "PIXELS",
                  "PERCENT"
                ]
              }
            },
            "required": [
              "unit"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "value": {
                "description": "Required for `PIXELS` and `PERCENT`.",
                "type": "number"
              }
            },
            "required": [
              "value"
            ]
          },
          "x-merge": "replace"
        },
        "textCase": {
          "description": "Text case. Default `\"ORIGINAL\"`.",
          "type": "string",
          "enum": [
            "ORIGINAL",
            "UPPER",
            "LOWER",
            "TITLE",
            "SMALL_CAPS",
            "SMALL_CAPS_FORCED"
          ]
        },
        "textDecoration": {
          "description": "Text decoration. Default `\"NONE\"`.",
          "type": "string",
          "enum": [
            "NONE",
            "UNDERLINE",
            "STRIKETHROUGH"
          ]
        },
        "fills": {
          "description": "Fills of the range.",
          "type": "array",
          "items": {
            "description": "A paint.",
            "$ref": "#/$defs/paint"
          }
        },
        "fillStyleId": {
          "description": "Paint style of the range's fills.",
          "$ref": "#/$defs/styleRef"
        },
        "textStyleId": {
          "description": "Text style of the range.",
          "$ref": "#/$defs/styleRef"
        },
        "hyperlink": {
          "description": "A link, `{type: \"URL\" or \"NODE\", value}`. Absent by default. Replaced whole by a patch.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "type": {
              "description": "Link to a URL or to a node.",
              "type": "string",
              "enum": [
                "URL",
                "NODE"
              ]
            },
            "value": {
              "description": "The URL, or the node id.",
              "type": "string"
            }
          },
          "required": [
            "type",
            "value"
          ],
          "x-merge": "replace"
        },
        "openTypeFeatures": {
          "description": "OpenType features, a map of feature tag to boolean, e.g. `{\"TNUM\": true, \"LIGA\": false, \"SS01\": true}` (TXT-4). Default `{}`. Merges per feature.",
          "type": "object",
          "additionalProperties": {
            "description": "On or off.",
            "type": "boolean"
          },
          "x-merge": "merge"
        },
        "boundVariables": {
          "description": "Bindings of the range's properties to variables (VAR-4), Figma's shape: a map of property name to `{\"type\":\"VARIABLE_ALIAS\",\"id\":\"vr-…\"}`. The plain value stays written next to the binding and is the fallback when the variable is missing (4.4.5). Default `{}`. Merges per property.",
          "type": "object",
          "additionalProperties": {
            "description": "The variable the property is bound to.",
            "$ref": "#/$defs/variableAlias",
            "x-merge": "replace"
          },
          "x-merge": "merge"
        },
        "listOptions": {
          "description": "Whole paragraphs only: list style.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "type": {
              "description": "Kind of list.",
              "type": "string",
              "enum": [
                "ORDERED",
                "UNORDERED",
                "NONE"
              ]
            }
          },
          "required": [
            "type"
          ],
          "x-merge": "replace"
        },
        "indentation": {
          "description": "Whole paragraphs only: list indentation level.",
          "type": "integer",
          "minimum": 0
        },
        "paragraphSpacing": {
          "description": "Space after a paragraph. Default `0`. In px.",
          "type": "number"
        },
        "paragraphIndent": {
          "description": "Indent of the first line of a paragraph. Default `0`. In px.",
          "type": "number"
        }
      },
      "required": [
        "start",
        "end"
      ]
    },
    "vectorNetwork": {
      "description": "A vector network (4.6.4, DRW-4), Figma's shape. Coordinates are px in the node's own coordinate system. The whole network is one property: an edit replaces it.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "vertices": {
          "description": "The vertices.",
          "type": "array",
          "items": {
            "description": "A vertex.",
            "type": "object",
            "additionalProperties": true,
            "properties": {
              "x": {
                "description": "x, px, in the node's own coordinates.",
                "type": "number"
              },
              "y": {
                "description": "y, px, in the node's own coordinates.",
                "type": "number"
              },
              "strokeCap": {
                "description": "Cap at this vertex.",
                "type": "string",
                "enum": [
                  "NONE",
                  "ROUND",
                  "SQUARE",
                  "ARROW_LINES",
                  "ARROW_EQUILATERAL",
                  "TRIANGLE_FILLED",
                  "CIRCLE_FILLED",
                  "DIAMOND_FILLED"
                ]
              },
              "strokeJoin": {
                "description": "Join at this vertex.",
                "type": "string",
                "enum": [
                  "MITER",
                  "BEVEL",
                  "ROUND"
                ]
              },
              "cornerRadius": {
                "description": "Corner radius at this vertex. In px.",
                "type": "number"
              },
              "handleMirroring": {
                "description": "How the handles at this vertex mirror each other.",
                "type": "string",
                "enum": [
                  "NONE",
                  "ANGLE",
                  "ANGLE_AND_LENGTH"
                ]
              }
            },
            "required": [
              "x",
              "y"
            ]
          }
        },
        "segments": {
          "description": "The segments.",
          "type": "array",
          "items": {
            "description": "A segment between two vertices. A vertex used by more than two segments is a branch.",
            "type": "object",
            "additionalProperties": true,
            "properties": {
              "start": {
                "description": "Index of the start vertex.",
                "type": "integer",
                "minimum": 0
              },
              "end": {
                "description": "Index of the end vertex.",
                "type": "integer",
                "minimum": 0
              },
              "tangentStart": {
                "description": "Handle offset at the start; absent for a straight segment.",
                "type": "object",
                "additionalProperties": true,
                "properties": {
                  "x": {
                    "description": "Horizontal component, px.",
                    "type": "number"
                  },
                  "y": {
                    "description": "Vertical component, px.",
                    "type": "number"
                  }
                },
                "required": [
                  "x",
                  "y"
                ],
                "x-merge": "replace"
              },
              "tangentEnd": {
                "description": "Handle offset at the end; absent for a straight segment.",
                "type": "object",
                "additionalProperties": true,
                "properties": {
                  "x": {
                    "description": "Horizontal component, px.",
                    "type": "number"
                  },
                  "y": {
                    "description": "Vertical component, px.",
                    "type": "number"
                  }
                },
                "required": [
                  "x",
                  "y"
                ],
                "x-merge": "replace"
              }
            },
            "required": [
              "start",
              "end"
            ]
          }
        },
        "regions": {
          "description": "Closed areas.",
          "type": "array",
          "items": {
            "description": "A closed area. An area in no region is not filled.",
            "type": "object",
            "additionalProperties": true,
            "properties": {
              "windingRule": {
                "description": "Fill rule.",
                "type": "string",
                "enum": [
                  "NONZERO",
                  "EVENODD"
                ]
              },
              "loops": {
                "description": "The loops of the region.",
                "type": "array",
                "items": {
                  "description": "A loop of segment indexes.",
                  "type": "array",
                  "items": {
                    "description": "A segment index.",
                    "type": "integer",
                    "minimum": 0
                  }
                }
              },
              "fills": {
                "description": "Fills of the region.",
                "type": "array",
                "items": {
                  "description": "A paint.",
                  "$ref": "#/$defs/paint"
                }
              },
              "fillStyleId": {
                "description": "Paint style of the region.",
                "$ref": "#/$defs/styleRef"
              }
            },
            "required": [
              "loops"
            ]
          }
        }
      },
      "required": [
        "vertices",
        "segments"
      ]
    },
    "componentPropertyDefinition": {
      "description": "A component property definition (CMP-5), Figma's shape: `{\"type\": \"VARIANT\", \"defaultValue\": \"md\", \"variantOptions\": [...]}`, `{\"type\": \"TEXT\", \"defaultValue\": \"Button\"}`, `{\"type\": \"BOOLEAN\", \"defaultValue\": false}`, `{\"type\": \"INSTANCE_SWAP\", \"defaultValue\": \"nd-…\", \"preferredValues\": [...]}`, `{\"type\": \"SLOT\"}`. `component.property.set` replaces a definition whole.",
      "type": "object",
      "additionalProperties": true,
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "description": "Kind of property.",
          "type": "string",
          "enum": [
            "BOOLEAN",
            "TEXT",
            "INSTANCE_SWAP",
            "VARIANT",
            "SLOT"
          ]
        },
        "defaultValue": {
          "description": "Default value: a boolean for `BOOLEAN`, a string for `TEXT` and `VARIANT`, a component id for `INSTANCE_SWAP`. Absent for `SLOT`.",
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "boolean"
            }
          ]
        },
        "description": {
          "description": "Documentation of the property.",
          "type": "string"
        },
        "variantOptions": {
          "description": "`VARIANT`: the values. Derived from the variants' names and written only by consolidation.",
          "type": "array",
          "items": {
            "description": "A value.",
            "type": "string"
          }
        },
        "preferredValues": {
          "description": "`INSTANCE_SWAP`: components offered first.",
          "type": "array",
          "items": {
            "description": "A preferred value.",
            "type": "object",
            "additionalProperties": true,
            "properties": {
              "type": {
                "description": "Kind of preferred value.",
                "type": "string",
                "enum": [
                  "COMPONENT",
                  "COMPONENT_SET"
                ]
              },
              "key": {
                "description": "The component or set id (or qualified id).",
                "type": "string"
              }
            },
            "required": [
              "type",
              "key"
            ]
          }
        }
      },
      "allOf": [
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "const": "BOOLEAN"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "defaultValue": {
                "description": "Default of a boolean property.",
                "type": "boolean"
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "enum": [
                  "TEXT",
                  "VARIANT"
                ]
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "defaultValue": {
                "description": "Default of a text or variant property.",
                "type": "string"
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "const": "INSTANCE_SWAP"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "defaultValue": {
                "description": "Default component of an instance-swap property.",
                "$ref": "#/$defs/componentRef"
              }
            }
          }
        }
      ]
    },
    "textProperties": {
      "description": "The text properties of a `TEXT` node (4.6.6), also used by the nested `text` of connectors and sticky notes.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "characters": {
          "description": "The text (TXT-1). Line breaks and paragraph breaks are `\\n` (Figma's model). Default `\"\"`. A writer that changes the text writes `styledRuns` in the same `set`.",
          "type": "string"
        },
        "fontName": {
          "description": "Font family and style. Default `{\"family\":\"Inter\",\"style\":\"Regular\"}`. Replaced whole by a patch.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "family": {
              "description": "Font family, e.g. `\"Inter\"`.",
              "type": "string"
            },
            "style": {
              "description": "Figma's style name, e.g. `\"Semi Bold\"` (CMD-15).",
              "type": "string"
            }
          },
          "required": [
            "family",
            "style"
          ],
          "x-merge": "replace"
        },
        "fontSize": {
          "description": "Font size. Default `12`. In px.",
          "type": "number",
          "minimum": 0
        },
        "fontVariations": {
          "description": "Variable font axes, a map of axis tag to number, e.g. `{\"wght\": 550, \"opsz\": 14}` (TXT-4). Our own. Default `{}`. Merges per axis.",
          "type": "object",
          "additionalProperties": {
            "description": "Axis value.",
            "type": "number"
          },
          "x-merge": "merge"
        },
        "letterSpacing": {
          "description": "Letter spacing, `{unit: \"PIXELS\" or \"PERCENT\", value}`. Default `{\"unit\":\"PERCENT\",\"value\":0}`. Replaced whole by a patch.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "unit": {
              "description": "Unit of `value`.",
              "type": "string",
              "enum": [
                "PIXELS",
                "PERCENT"
              ]
            },
            "value": {
              "description": "The spacing.",
              "type": "number"
            }
          },
          "required": [
            "unit",
            "value"
          ],
          "x-merge": "replace"
        },
        "lineHeight": {
          "description": "Line height, `{unit: \"AUTO\"}` or `{unit: \"PIXELS\" or \"PERCENT\", value}`. Default `{\"unit\":\"AUTO\"}`. Replaced whole by a patch.",
          "type": "object",
          "additionalProperties": true,
          "required": [
            "unit"
          ],
          "properties": {
            "unit": {
              "description": "Unit: `AUTO`, or `PIXELS` / `PERCENT` with a `value`.",
              "type": "string",
              "enum": [
                "AUTO",
                "PIXELS",
                "PERCENT"
              ]
            },
            "value": {
              "description": "The line height; absent for `AUTO`.",
              "type": "number"
            }
          },
          "if": {
            "type": "object",
            "properties": {
              "unit": {
                "enum": [
                  "PIXELS",
                  "PERCENT"
                ]
              }
            },
            "required": [
              "unit"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "value": {
                "description": "Required for `PIXELS` and `PERCENT`.",
                "type": "number"
              }
            },
            "required": [
              "value"
            ]
          },
          "x-merge": "replace"
        },
        "textCase": {
          "description": "Text case. Default `\"ORIGINAL\"`.",
          "type": "string",
          "enum": [
            "ORIGINAL",
            "UPPER",
            "LOWER",
            "TITLE",
            "SMALL_CAPS",
            "SMALL_CAPS_FORCED"
          ]
        },
        "textDecoration": {
          "description": "Text decoration. Default `\"NONE\"`.",
          "type": "string",
          "enum": [
            "NONE",
            "UNDERLINE",
            "STRIKETHROUGH"
          ]
        },
        "textAlignHorizontal": {
          "description": "Horizontal alignment (TXT-3). Default `\"LEFT\"`.",
          "type": "string",
          "enum": [
            "LEFT",
            "CENTER",
            "RIGHT",
            "JUSTIFIED"
          ]
        },
        "textAlignVertical": {
          "description": "Vertical alignment. Default `\"TOP\"`.",
          "type": "string",
          "enum": [
            "TOP",
            "CENTER",
            "BOTTOM"
          ]
        },
        "textAutoResize": {
          "description": "Auto-resize mode (TXT-1). With `WIDTH_AND_HEIGHT` or `HEIGHT` the geometry is derived and not stored (4.5). Default `\"WIDTH_AND_HEIGHT\"`.",
          "type": "string",
          "enum": [
            "NONE",
            "WIDTH_AND_HEIGHT",
            "HEIGHT",
            "TRUNCATE"
          ]
        },
        "textTruncation": {
          "description": "Ellipsis. Default `\"DISABLED\"`.",
          "type": "string",
          "enum": [
            "DISABLED",
            "ENDING"
          ]
        },
        "maxLines": {
          "description": "Lines before the ellipsis. Absent by default.",
          "type": "integer",
          "minimum": 1
        },
        "paragraphSpacing": {
          "description": "Space after a paragraph. Default `0`. In px.",
          "type": "number"
        },
        "paragraphIndent": {
          "description": "Indent of the first line of a paragraph. Default `0`. In px.",
          "type": "number"
        },
        "listSpacing": {
          "description": "Space between list items. Default `0`. In px.",
          "type": "number"
        },
        "hangingPunctuation": {
          "description": "Hanging punctuation. Default `false`.",
          "type": "boolean"
        },
        "hangingList": {
          "description": "Hanging list markers. Default `false`.",
          "type": "boolean"
        },
        "leadingTrim": {
          "description": "Leading trim (TXT-3). Default `\"NONE\"`.",
          "type": "string",
          "enum": [
            "NONE",
            "CAP_HEIGHT"
          ]
        },
        "openTypeFeatures": {
          "description": "OpenType features, a map of feature tag to boolean, e.g. `{\"TNUM\": true, \"LIGA\": false, \"SS01\": true}` (TXT-4). Default `{}`. Merges per feature.",
          "type": "object",
          "additionalProperties": {
            "description": "On or off.",
            "type": "boolean"
          },
          "x-merge": "merge"
        },
        "hyperlink": {
          "description": "A link, `{type: \"URL\" or \"NODE\", value}`. Absent by default. Replaced whole by a patch.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "type": {
              "description": "Link to a URL or to a node.",
              "type": "string",
              "enum": [
                "URL",
                "NODE"
              ]
            },
            "value": {
              "description": "The URL, or the node id.",
              "type": "string"
            }
          },
          "required": [
            "type",
            "value"
          ],
          "x-merge": "replace"
        },
        "textStyleId": {
          "description": "Text style (4.9). The plain text values stay written next to it as the fallback (4.4.5). Absent by default.",
          "$ref": "#/$defs/styleRef"
        },
        "styledRuns": {
          "description": "Ranges whose properties differ from the node-level values (TXT-2), sorted by `start`, not overlapping. Default `[]`. Replaced whole by a patch.",
          "type": "array",
          "items": {
            "description": "One run.",
            "$ref": "#/$defs/styledRun"
          }
        }
      }
    },
    "nodeFields": {
      "description": "The members of a node: the shared properties (4.4) and, per `type`, the type-specific ones (4.6). A property a type does not have is kept but ignored, so it is not rejected. Used by `node` and `nodeInput`.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "type": {
          "description": "Node type (4.6). Fixed when the node is created; changed only by `component.create` and `instance.detach`. A reader keeps a node of an unknown type as a placeholder (9.1).",
          "type": "string",
          "enum": [
            "FRAME",
            "GROUP",
            "SECTION",
            "RECTANGLE",
            "ELLIPSE",
            "LINE",
            "POLYGON",
            "STAR",
            "VECTOR",
            "BOOLEAN_OPERATION",
            "TEXT",
            "COMPONENT",
            "COMPONENT_SET",
            "INSTANCE",
            "SLOT",
            "SLICE",
            "CONNECTOR",
            "STICKY"
          ]
        },
        "name": {
          "description": "Layer name. Default by type and content (DOC-6).",
          "type": "string"
        },
        "parent": {
          "description": "The page or node that contains this node (4.3): a page id for a top-level node, a node id, or the derived id of an instance slot for slot content (4.8). Changed only by `node.move`.",
          "anyOf": [
            {
              "$ref": "#/$defs/pageId"
            },
            {
              "$ref": "#/$defs/nodeRef"
            }
          ]
        },
        "index": {
          "description": "Position among the children of `parent` (4.3). Changed only by `node.move` and `node.reorder`.",
          "$ref": "#/$defs/fractionalIndex"
        },
        "visible": {
          "description": "Shown or hidden. Default `true`.",
          "type": "boolean"
        },
        "locked": {
          "description": "Locked against selection on the canvas. Default `false`.",
          "type": "boolean"
        },
        "x": {
          "description": "Position of the node's origin in its parent's coordinate system (the parent frame, or for children of a `GROUP` or `BOOLEAN_OPERATION` the nearest ancestor frame or the page). Default `0`. Not stored for children in auto layout flow (4.5). In px.",
          "type": "number"
        },
        "y": {
          "description": "Vertical position, as `x`. Default `0`. In px.",
          "type": "number"
        },
        "width": {
          "description": "Width. Default `100`. Not stored where derived: hug and fill axes, groups, booleans, auto-sized text (4.5). For a `LINE`, the length. In px.",
          "type": "number",
          "minimum": 0
        },
        "height": {
          "description": "Height. Default `100`. Not stored where derived (4.5). `0` for a `LINE`. In px.",
          "type": "number",
          "minimum": 0
        },
        "rotation": {
          "description": "Counter-clockwise rotation about the node's origin, in degrees, in (-180, 180], as Figma. Default `0`.",
          "type": "number",
          "exclusiveMinimum": -180,
          "maximum": 180
        },
        "flipX": {
          "description": "Mirrored along the node's own vertical axis. Default `false`. Not in Figma; the Plugin API layer composes `relativeTransform` from `x`, `y`, `rotation`, `flipX`, `flipY`.",
          "type": "boolean"
        },
        "flipY": {
          "description": "Mirrored along the node's own horizontal axis. Default `false`.",
          "type": "boolean"
        },
        "description": {
          "description": "Free text (DOC-4); for components, the documentation shown in the Assets panel. Default `\"\"`.",
          "type": "string"
        },
        "documentationLinks": {
          "description": "Links of a component (CMP-7). Default `[]`.",
          "type": "array",
          "items": {
            "description": "A link.",
            "type": "object",
            "additionalProperties": true,
            "properties": {
              "uri": {
                "description": "The link.",
                "type": "string",
                "format": "uri"
              }
            },
            "required": [
              "uri"
            ]
          }
        },
        "constraints": {
          "description": "Constraints (LAY-1), `{horizontal, vertical}`. Default `{\"horizontal\":\"MIN\",\"vertical\":\"MIN\"}`. Merges per member.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "horizontal": {
              "description": "`MIN` (left), `MAX` (right), `STRETCH` (left and right), `CENTER`, `SCALE`.",
              "type": "string",
              "enum": [
                "MIN",
                "MAX",
                "STRETCH",
                "CENTER",
                "SCALE"
              ]
            },
            "vertical": {
              "description": "The same for top and bottom.",
              "type": "string",
              "enum": [
                "MIN",
                "MAX",
                "STRETCH",
                "CENTER",
                "SCALE"
              ]
            }
          },
          "x-merge": "merge"
        },
        "layoutPositioning": {
          "description": "In an auto layout parent: in flow, or absolutely positioned with constraints (LAY-5). Default `\"AUTO\"`.",
          "type": "string",
          "enum": [
            "AUTO",
            "ABSOLUTE"
          ]
        },
        "layoutSizingHorizontal": {
          "description": "Horizontal sizing (LAY-3). `HUG` only for auto layout frames and text; `FILL` only for children of auto layout frames. Default `\"FIXED\"`.",
          "type": "string",
          "enum": [
            "FIXED",
            "HUG",
            "FILL"
          ]
        },
        "layoutSizingVertical": {
          "description": "Vertical sizing (LAY-3). Default `\"FIXED\"`.",
          "type": "string",
          "enum": [
            "FIXED",
            "HUG",
            "FILL"
          ]
        },
        "minWidth": {
          "description": "Minimum width (LAY-3). Absent by default. In px.",
          "type": "number",
          "minimum": 0
        },
        "maxWidth": {
          "description": "Maximum width. Absent by default. In px.",
          "type": "number",
          "minimum": 0
        },
        "minHeight": {
          "description": "Minimum height. Absent by default. In px.",
          "type": "number",
          "minimum": 0
        },
        "maxHeight": {
          "description": "Maximum height. Absent by default. In px.",
          "type": "number",
          "minimum": 0
        },
        "gridRowAnchorIndex": {
          "description": "Row of a child in a grid auto layout (LAY-4). Auto-placed by default.",
          "type": "integer",
          "minimum": 0
        },
        "gridColumnAnchorIndex": {
          "description": "Column of a child in a grid auto layout. Auto-placed by default.",
          "type": "integer",
          "minimum": 0
        },
        "gridRowSpan": {
          "description": "Rows spanned. Default `1`.",
          "type": "integer",
          "minimum": 1
        },
        "gridColumnSpan": {
          "description": "Columns spanned. Default `1`.",
          "type": "integer",
          "minimum": 1
        },
        "gridChildHorizontalAlign": {
          "description": "Horizontal alignment within the cell. Default `\"AUTO\"`.",
          "type": "string",
          "enum": [
            "AUTO",
            "MIN",
            "CENTER",
            "MAX"
          ]
        },
        "gridChildVerticalAlign": {
          "description": "Vertical alignment within the cell. Default `\"AUTO\"`.",
          "type": "string",
          "enum": [
            "AUTO",
            "MIN",
            "CENTER",
            "MAX"
          ]
        },
        "scrollBehavior": {
          "description": "Behaviour when the parent frame scrolls in a prototype (PRO-5). Default `\"SCROLLS\"`.",
          "type": "string",
          "enum": [
            "SCROLLS",
            "FIXED",
            "STICKY_SCROLLS"
          ]
        },
        "layoutMode": {
          "description": "Auto layout direction (LAY-2, LAY-4). Default `\"NONE\"`.",
          "type": "string",
          "enum": [
            "NONE",
            "HORIZONTAL",
            "VERTICAL",
            "GRID"
          ]
        },
        "layoutWrap": {
          "description": "Wrap for `HORIZONTAL`. Default `\"NO_WRAP\"`.",
          "type": "string",
          "enum": [
            "NO_WRAP",
            "WRAP"
          ]
        },
        "itemSpacing": {
          "description": "Gap between items. Default `0`. In px.",
          "type": "number"
        },
        "counterAxisSpacing": {
          "description": "Gap between rows when wrapping. Default `0`. In px.",
          "type": "number"
        },
        "paddingLeft": {
          "description": "Left padding. Default `0`. In px.",
          "type": "number"
        },
        "paddingRight": {
          "description": "Right padding. Default `0`. In px.",
          "type": "number"
        },
        "paddingTop": {
          "description": "Top padding. Default `0`. In px.",
          "type": "number"
        },
        "paddingBottom": {
          "description": "Bottom padding. Default `0`. In px.",
          "type": "number"
        },
        "primaryAxisAlignItems": {
          "description": "Alignment along the direction; `SPACE_BETWEEN` is gap \"auto\". Default `\"MIN\"`.",
          "type": "string",
          "enum": [
            "MIN",
            "CENTER",
            "MAX",
            "SPACE_BETWEEN"
          ]
        },
        "counterAxisAlignItems": {
          "description": "Alignment across the direction. Default `\"MIN\"`.",
          "type": "string",
          "enum": [
            "MIN",
            "CENTER",
            "MAX",
            "BASELINE"
          ]
        },
        "counterAxisAlignContent": {
          "description": "Distribution of wrapped rows. Default `\"AUTO\"`.",
          "type": "string",
          "enum": [
            "AUTO",
            "SPACE_BETWEEN"
          ]
        },
        "itemReverseZIndex": {
          "description": "First item painted on top (LAY-2). Default `false`.",
          "type": "boolean"
        },
        "strokesIncludedInLayout": {
          "description": "Strokes count in the box (LAY-6). Default `false`.",
          "type": "boolean"
        },
        "gridRowCount": {
          "description": "Rows of a grid auto layout (LAY-4). Default `1`.",
          "type": "integer",
          "minimum": 1
        },
        "gridColumnCount": {
          "description": "Columns of a grid auto layout. Default `1`.",
          "type": "integer",
          "minimum": 1
        },
        "gridRowGap": {
          "description": "Gap between rows. Default `0`. In px.",
          "type": "number"
        },
        "gridColumnGap": {
          "description": "Gap between columns. Default `0`. In px.",
          "type": "number"
        },
        "gridRowSizes": {
          "description": "Row track sizes. Default one `FLEX` 1 per track.",
          "type": "array",
          "items": {
            "description": "A track size.",
            "type": "object",
            "additionalProperties": true,
            "properties": {
              "type": {
                "description": "Kind of track size; `FLEX` is a fraction (`fr`).",
                "type": "string",
                "enum": [
                  "FIXED",
                  "FLEX",
                  "HUG"
                ]
              },
              "value": {
                "description": "The size, px for `FIXED`, a fraction for `FLEX`.",
                "type": "number"
              }
            },
            "required": [
              "type"
            ]
          }
        },
        "gridColumnSizes": {
          "description": "Column track sizes. Default one `FLEX` 1 per track.",
          "type": "array",
          "items": {
            "description": "A track size.",
            "type": "object",
            "additionalProperties": true,
            "properties": {
              "type": {
                "description": "Kind of track size; `FLEX` is a fraction (`fr`).",
                "type": "string",
                "enum": [
                  "FIXED",
                  "FLEX",
                  "HUG"
                ]
              },
              "value": {
                "description": "The size, px for `FIXED`, a fraction for `FLEX`.",
                "type": "number"
              }
            },
            "required": [
              "type"
            ]
          }
        },
        "layoutGrids": {
          "description": "Column, row and uniform guides (LAY-8). Default `[]`.",
          "type": "array",
          "items": {
            "description": "A layout grid.",
            "$ref": "#/$defs/layoutGrid"
          }
        },
        "gridStyleId": {
          "description": "Layout grid style (4.9). Absent by default.",
          "$ref": "#/$defs/styleRef"
        },
        "clipsContent": {
          "description": "Clip children to the frame, respecting corner radius (STY-8). Default `true` for frames, `false` for components and instances.",
          "type": "boolean"
        },
        "overflowDirection": {
          "description": "Prototype scrolling (PRO-5). Default `\"NONE\"`.",
          "type": "string",
          "enum": [
            "NONE",
            "HORIZONTAL",
            "VERTICAL",
            "BOTH"
          ]
        },
        "overlayPositionType": {
          "description": "Where the frame shows when opened as an overlay (PRO-4), Figma's values. Default `\"CENTER\"`.",
          "type": "string",
          "enum": [
            "CENTER",
            "TOP_LEFT",
            "TOP_CENTER",
            "TOP_RIGHT",
            "BOTTOM_LEFT",
            "BOTTOM_CENTER",
            "BOTTOM_RIGHT",
            "MANUAL"
          ]
        },
        "overlayBackground": {
          "description": "Background behind the frame when opened as an overlay, Figma's shape. Default `{\"type\":\"NONE\"}`.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "type": {
              "description": "No background, or a solid colour.",
              "type": "string",
              "enum": [
                "NONE",
                "SOLID_COLOR"
              ]
            },
            "color": {
              "description": "`SOLID_COLOR`: the colour, with `a`.",
              "$ref": "#/$defs/color",
              "x-merge": "replace"
            }
          },
          "required": [
            "type"
          ],
          "x-merge": "replace"
        },
        "overlayBackgroundInteraction": {
          "description": "What a click outside the overlay does, Figma's values. Default `\"NONE\"`.",
          "type": "string",
          "enum": [
            "NONE",
            "CLOSE_ON_CLICK_OUTSIDE"
          ]
        },
        "opacity": {
          "description": "Layer opacity, 0 to 1 (STY-7). Default `1`.",
          "type": "number",
          "minimum": 0,
          "maximum": 1
        },
        "blendMode": {
          "description": "Figma's `BlendMode`. Default `\"PASS_THROUGH\"` for frames, groups, sections, components, instances; `\"NORMAL\"` otherwise.",
          "type": "string",
          "enum": [
            "PASS_THROUGH",
            "NORMAL",
            "DARKEN",
            "MULTIPLY",
            "LINEAR_BURN",
            "COLOR_BURN",
            "LIGHTEN",
            "SCREEN",
            "LINEAR_DODGE",
            "COLOR_DODGE",
            "OVERLAY",
            "SOFT_LIGHT",
            "HARD_LIGHT",
            "DIFFERENCE",
            "EXCLUSION",
            "HUE",
            "SATURATION",
            "COLOR",
            "LUMINOSITY"
          ]
        },
        "fills": {
          "description": "Fills, bottom first (STY-1). Default `[]`, except one white `SOLID` for frames and components created by the Frame tool. Replaced whole by a patch.",
          "type": "array",
          "items": {
            "description": "A paint.",
            "$ref": "#/$defs/paint"
          }
        },
        "fillStyleId": {
          "description": "Paint style for the fills (4.9). The plain `fills` stay written as the fallback. Absent by default.",
          "$ref": "#/$defs/styleRef"
        },
        "strokes": {
          "description": "Strokes (STY-5). Default `[]`.",
          "type": "array",
          "items": {
            "description": "A paint.",
            "$ref": "#/$defs/paint"
          }
        },
        "strokeStyleId": {
          "description": "Paint style for the strokes. Absent by default.",
          "$ref": "#/$defs/styleRef"
        },
        "strokeWeight": {
          "description": "Weight of all sides. Default `1`. In px.",
          "type": "number",
          "minimum": 0
        },
        "strokeTopWeight": {
          "description": "Top stroke weight of frames and rectangles. Default `strokeWeight`. In px.",
          "type": "number",
          "minimum": 0
        },
        "strokeRightWeight": {
          "description": "Right stroke weight. Default `strokeWeight`. In px.",
          "type": "number",
          "minimum": 0
        },
        "strokeBottomWeight": {
          "description": "Bottom stroke weight. Default `strokeWeight`. In px.",
          "type": "number",
          "minimum": 0
        },
        "strokeLeftWeight": {
          "description": "Left stroke weight. Default `strokeWeight`. In px.",
          "type": "number",
          "minimum": 0
        },
        "strokeAlign": {
          "description": "Stroke position. Default `\"INSIDE\"` for closed shapes, `\"CENTER\"` for lines and open vectors.",
          "type": "string",
          "enum": [
            "INSIDE",
            "CENTER",
            "OUTSIDE"
          ]
        },
        "strokeCap": {
          "description": "Caps of open paths. Default `\"NONE\"`. Per-vertex caps are in the vector network.",
          "type": "string",
          "enum": [
            "NONE",
            "ROUND",
            "SQUARE",
            "ARROW_LINES",
            "ARROW_EQUILATERAL",
            "TRIANGLE_FILLED",
            "CIRCLE_FILLED",
            "DIAMOND_FILLED"
          ]
        },
        "strokeJoin": {
          "description": "Joins. Default `\"MITER\"`.",
          "type": "string",
          "enum": [
            "MITER",
            "BEVEL",
            "ROUND"
          ]
        },
        "strokeMiterLimit": {
          "description": "Miter limit. Default `4`.",
          "type": "number",
          "minimum": 0
        },
        "dashPattern": {
          "description": "Dash and gap lengths; empty is solid. Default `[]`.",
          "type": "array",
          "items": {
            "description": "A dash or gap length, px.",
            "type": "number",
            "minimum": 0
          }
        },
        "effects": {
          "description": "Shadows and blurs, in order (STY-6). Default `[]`.",
          "type": "array",
          "items": {
            "description": "An effect.",
            "$ref": "#/$defs/effect"
          }
        },
        "effectStyleId": {
          "description": "Effect style. Absent by default.",
          "$ref": "#/$defs/styleRef"
        },
        "cornerRadius": {
          "description": "All corners of a rectangle, frame, component, instance, polygon or star. Default `0`. In px.",
          "type": "number",
          "minimum": 0
        },
        "topLeftRadius": {
          "description": "Top-left corner (DRW-3). Default `cornerRadius`; written only when the corners differ, and wins over `cornerRadius` for its corner. In px.",
          "type": "number",
          "minimum": 0
        },
        "topRightRadius": {
          "description": "Top-right corner. Default `cornerRadius`. In px.",
          "type": "number",
          "minimum": 0
        },
        "bottomRightRadius": {
          "description": "Bottom-right corner. Default `cornerRadius`. In px.",
          "type": "number",
          "minimum": 0
        },
        "bottomLeftRadius": {
          "description": "Bottom-left corner. Default `cornerRadius`. In px.",
          "type": "number",
          "minimum": 0
        },
        "cornerSmoothing": {
          "description": "Smooth corners (squircle), 0 to 1; 0.6 is iOS style (DRW-3). Default `0`.",
          "type": "number",
          "minimum": 0,
          "maximum": 1
        },
        "isMask": {
          "description": "This node masks the siblings above it, up to the end of the parent (DRW-8). Default `false`.",
          "type": "boolean"
        },
        "maskType": {
          "description": "How the mask applies. Default `\"ALPHA\"`.",
          "type": "string",
          "enum": [
            "ALPHA",
            "VECTOR",
            "LUMINANCE"
          ]
        },
        "boundVariables": {
          "description": "Bindings of the node's properties to variables (VAR-4), Figma's shape: a map of property name to `{\"type\":\"VARIABLE_ALIAS\",\"id\":\"vr-…\"}`. The plain value stays written next to the binding and is the fallback when the variable is missing (4.4.5). Default `{}`. Merges per property.",
          "type": "object",
          "additionalProperties": {
            "description": "The variable the property is bound to.",
            "$ref": "#/$defs/variableAlias",
            "x-merge": "replace"
          },
          "x-merge": "merge"
        },
        "explicitVariableModes": {
          "description": "Modes chosen on this node, for it and its descendants (VAR-6): a map of variable collection id to mode id. Default `{}`. Merges per collection.",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/variableCollectionRef"
          },
          "additionalProperties": {
            "description": "The mode chosen for that collection.",
            "$ref": "#/$defs/modeRef"
          },
          "x-merge": "merge"
        },
        "componentPropertyReferences": {
          "description": "Properties of a layer inside a component that are driven by a component property (CMP-5): `{\"characters\": \"Label#a41c\", \"visible\": \"Show icon#5d02\", \"mainComponent\": \"Icon#77b0\"}`. Default `{}`. Merges per property.",
          "type": "object",
          "additionalProperties": {
            "description": "The component property that drives it.",
            "$ref": "#/$defs/componentPropertyKey"
          },
          "x-merge": "merge"
        },
        "exportSettings": {
          "description": "Export settings (EXP-1), Figma's shape. Default `[]`.",
          "type": "array",
          "items": {
            "description": "An export setting.",
            "$ref": "#/$defs/exportSetting"
          }
        },
        "reactions": {
          "description": "Prototype interactions (PRO-1 – PRO-4), Figma's shape. Default `[]`.",
          "type": "array",
          "items": {
            "description": "A reaction.",
            "$ref": "#/$defs/reaction"
          }
        },
        "devStatus": {
          "description": "Developer status (DEV-5, DOC-8) on frames, sections and components. Absent by default. Replaced whole by a patch.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "type": {
              "description": "The status.",
              "type": "string",
              "enum": [
                "READY_FOR_DEV",
                "COMPLETED"
              ]
            },
            "description": {
              "description": "Note for developers.",
              "type": "string"
            },
            "at": {
              "description": "When the status was set; writers copy the event's `at`.",
              "$ref": "#/$defs/timestamp"
            }
          },
          "required": [
            "type"
          ],
          "x-merge": "replace"
        },
        "annotations": {
          "description": "Annotations attached to the node (DEV-7). Default `[]`.",
          "type": "array",
          "items": {
            "description": "An annotation, Figma's shape.",
            "type": "object",
            "additionalProperties": true,
            "properties": {
              "label": {
                "description": "Plain text of the annotation.",
                "type": "string"
              },
              "labelMarkdown": {
                "description": "The annotation as Markdown.",
                "type": "string"
              },
              "properties": {
                "description": "Properties pinned to the annotation.",
                "type": "array",
                "items": {
                  "description": "A pinned property.",
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "type": {
                      "description": "A property to show, e.g. `width`.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "type"
                  ]
                }
              },
              "categoryId": {
                "description": "Category of the annotation (`document.annotationCategories`).",
                "$ref": "#/$defs/annotationCategoryId"
              }
            }
          }
        },
        "accessibility": {
          "description": "Accessibility metadata (DEV-8). Our own; Figma has no equivalent. Default `{}`. Merges per member.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "role": {
              "description": "Accessibility role.",
              "type": "string"
            },
            "name": {
              "description": "Accessible name.",
              "type": "string"
            },
            "description": {
              "description": "Accessible description.",
              "type": "string"
            },
            "headingLevel": {
              "description": "Heading level, 1 to 6.",
              "type": "integer",
              "minimum": 1,
              "maximum": 6
            },
            "focusOrder": {
              "description": "Position in the focus order.",
              "type": "integer"
            },
            "altText": {
              "description": "Alternative text.",
              "type": "string"
            },
            "decorative": {
              "description": "Decorative: hidden from assistive technology.",
              "type": "boolean"
            }
          },
          "x-merge": "merge"
        },
        "codeMap": {
          "description": "The code component this component or component set maps to (DEV-4). Mappings in the `ud.codeMap` setting override the file. Absent by default. Replaced whole by a patch.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "component": {
              "description": "Name of the code component.",
              "type": "string"
            },
            "source": {
              "description": "Source file of the code component, relative to the workspace.",
              "type": "string"
            },
            "language": {
              "description": "Language of the source, e.g. `tsx`.",
              "type": "string"
            },
            "props": {
              "description": "Map of component property key to code prop.",
              "type": "object",
              "additionalProperties": {
                "description": "How one component property maps to a code prop.",
                "type": "object",
                "additionalProperties": true,
                "properties": {
                  "prop": {
                    "description": "Name of the code prop.",
                    "type": "string"
                  },
                  "values": {
                    "description": "Map of design value to code value.",
                    "type": "object",
                    "additionalProperties": {
                      "description": "The code value.",
                      "type": "string"
                    },
                    "x-merge": "replace"
                  },
                  "when": {
                    "description": "Value of the design property for which the prop is passed."
                  }
                },
                "required": [
                  "prop"
                ],
                "x-merge": "replace"
              },
              "x-merge": "replace"
            }
          },
          "x-merge": "replace"
        },
        "traces": {
          "description": "Project Board items (INT-1) and Software Board elements (INT-4) this node realises, e.g. `{\"file\": \"planning.pb\", \"item\": \"REQ-12\"}` or `{\"kind\": \"uml\", \"file\": \"ui-designer.uml\", \"item\": \"el-…\"}`. Default `[]`.",
          "type": "array",
          "items": {
            "description": "A trace link.",
            "type": "object",
            "additionalProperties": true,
            "properties": {
              "kind": {
                "description": "What the trace points at: `pb`, an item of a Project Board file (INT-1), or `uml`, an element of a Software Board model (INT-4). Absent means `pb`.",
                "type": "string",
                "enum": [
                  "pb",
                  "uml"
                ]
              },
              "file": {
                "description": "Project Board file (`.pb`) or Software Board model (`.uml`), relative to the design file.",
                "type": "string"
              },
              "item": {
                "description": "The item it realises: `REQ-12`, `#12` (pb), or an element id `el-…` (uml).",
                "type": "string"
              }
            },
            "required": [
              "file",
              "item"
            ]
          }
        },
        "pluginData": {
          "description": "Private data of plugins and scripts (4.4.10): a map of plugin id to a map of key to string. `setPluginData(key, value)` in the Plugin API writes `pluginData[<plugin id>][key]`. Scripts run by `use_figma` have the plugin id `ud`. Merges per key, so two branches that write different keys both survive.",
          "type": "object",
          "additionalProperties": {
            "description": "The keys and values written by one plugin or script.",
            "type": "object",
            "additionalProperties": {
              "description": "A value. Values are strings, as in Figma; setting a value to `\"\"` removes the key (in a merge patch the key is set to `null`).",
              "type": "string"
            },
            "x-merge": "merge"
          },
          "x-merge": "merge"
        },
        "sharedPluginData": {
          "description": "Data shared between plugins (4.4.10): a map of namespace to a map of key to string, written by `setSharedPluginData(namespace, key, value)`. Merges per key.",
          "type": "object",
          "additionalProperties": {
            "description": "The keys and values of one namespace.",
            "type": "object",
            "additionalProperties": {
              "description": "A value, a string as in Figma. `\"\"` removes the key.",
              "type": "string"
            },
            "x-merge": "merge"
          },
          "x-merge": "merge"
        }
      },
      "allOf": [
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "const": "TEXT"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/textProperties"
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "const": "SECTION"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "sectionContentsHidden": {
                "description": "Contents hidden on the canvas.",
                "type": "boolean"
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "const": "ELLIPSE"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "arcData": {
                "description": "Arc (DRW-3), Figma's shape `{\"startingAngle\": 0, \"endingAngle\": 6.2831853, \"innerRadius\": 0}`. The angles are in radians, the only angle of the format not in degrees. Default a full ellipse. Replaced whole by a patch.",
                "type": "object",
                "additionalProperties": true,
                "properties": {
                  "startingAngle": {
                    "description": "Start angle in radians.",
                    "type": "number"
                  },
                  "endingAngle": {
                    "description": "End angle in radians.",
                    "type": "number"
                  },
                  "innerRadius": {
                    "description": "Inner radius ratio, 0 to 1 (donuts).",
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1
                  }
                },
                "x-merge": "replace"
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "const": "POLYGON"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "pointCount": {
                "description": "Number of points, 3 or more. Default 3.",
                "type": "integer",
                "minimum": 3
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "const": "STAR"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "pointCount": {
                "description": "Number of points, 3 or more. Default 5.",
                "type": "integer",
                "minimum": 3
              },
              "innerRadius": {
                "description": "Ratio of inner to outer radius, 0 to 1. Default 0.38.",
                "type": "number",
                "minimum": 0,
                "maximum": 1
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "const": "TEXT"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "textPath": {
                "description": "Text on a path (TXT-8), a UI Designer extension of 4.11 stored on the node like a frame's `guides`: the text is one auto-width line whose glyphs follow `path`; characters past its end are hidden. Absent by default. Replaced whole by a patch.",
                "type": "object",
                "additionalProperties": true,
                "properties": {
                  "source": {
                    "description": "The layer whose outline was copied into `path`: a `LINE`, `ELLIPSE`, `VECTOR`, `STAR`, `POLYGON`, `RECTANGLE` or `BOOLEAN_OPERATION`. The copy is refreshed when the source changes while both are on the same page; a deleted source leaves it as it was. Absent when the path was given as data.",
                    "$ref": "#/$defs/nodeRef"
                  },
                  "path": {
                    "description": "SVG path data in the text node's own coordinate space (writers store absolute `M`, `L`, `C`, `Z`).",
                    "type": "string",
                    "minLength": 1
                  },
                  "startOffset": {
                    "description": "Distance along the path where the text starts. Default `0`. In px.",
                    "type": "number"
                  },
                  "side": {
                    "description": "Side of the path the glyphs stand on, relative to its direction (`RIGHT` walks the path backwards). Default `\"LEFT\"`.",
                    "type": "string",
                    "enum": [
                      "LEFT",
                      "RIGHT"
                    ]
                  },
                  "align": {
                    "description": "Where the line sits on the path. Default `\"START\"`.",
                    "type": "string",
                    "enum": [
                      "START",
                      "CENTER",
                      "END"
                    ]
                  }
                },
                "required": [
                  "path"
                ],
                "x-merge": "replace"
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "const": "VECTOR"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "vectorNetwork": {
                "description": "The vector network (DRW-4). One property: an edit replaces it.",
                "$ref": "#/$defs/vectorNetwork",
                "x-merge": "replace"
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "const": "BOOLEAN_OPERATION"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "booleanOperation": {
                "description": "The operation (DRW-5). Default `\"UNION\"`.",
                "type": "string",
                "enum": [
                  "UNION",
                  "SUBTRACT",
                  "INTERSECT",
                  "EXCLUDE"
                ]
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "enum": [
                  "COMPONENT",
                  "COMPONENT_SET"
                ]
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "componentPropertyDefinitions": {
                "description": "Component property definitions (CMP-5), keyed by property key. On the component, or on the set for variants. Default `{}`. Merges per key.",
                "type": "object",
                "propertyNames": {
                  "$ref": "#/$defs/componentPropertyKey"
                },
                "additionalProperties": {
                  "description": "One definition.",
                  "$ref": "#/$defs/componentPropertyDefinition",
                  "x-merge": "replace"
                },
                "x-merge": "merge"
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "const": "INSTANCE"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "componentId": {
                "description": "The main component, or a variant of a set; `lib-…/nd-…` for a library component (4.11). Required.",
                "$ref": "#/$defs/componentRef"
              },
              "libraryId": {
                "description": "Listed among the instance properties in 4.6 but not defined by FMT-001; a qualified `componentId` already names the library.",
                "$ref": "#/$defs/libraryId"
              },
              "componentProperties": {
                "description": "Component property values that differ from the definitions' defaults, `{\"Label#a41c\": \"Sign in\", \"Size\": \"lg\"}`. Plain values; the Plugin API layer adds `type`. Default `{}`. Merges per key.",
                "type": "object",
                "propertyNames": {
                  "$ref": "#/$defs/componentPropertyKey"
                },
                "additionalProperties": {
                  "description": "The value.",
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "boolean"
                    }
                  ]
                },
                "x-merge": "merge"
              },
              "overrides": {
                "description": "Changed properties of sublayers, keyed by override path (4.8). An override whose path matches no layer is kept but dormant. Default `{}`. Merges per path.",
                "type": "object",
                "propertyNames": {
                  "$ref": "#/$defs/overridePath"
                },
                "additionalProperties": {
                  "description": "A merge patch of the sublayer's properties: only what differs. `componentId` swaps a nested instance (CMP-3, CMP-6).",
                  "$ref": "#/$defs/nodePatch",
                  "x-merge": "merge"
                },
                "x-merge": "merge"
              }
            },
            "required": [
              "componentId"
            ]
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "const": "SLOT"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "slotPropertyKey": {
                "description": "Key of the `SLOT` component property that exposes this slot (CMP-5).",
                "$ref": "#/$defs/componentPropertyKey"
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "const": "CONNECTOR"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "connectorStart": {
                "description": "The start of the connector: `{\"endpointNodeId\": id, \"magnet\": …}` or `{\"position\": {x, y}}`. Replaced whole by a patch.",
                "type": "object",
                "additionalProperties": true,
                "properties": {
                  "endpointNodeId": {
                    "description": "The node the connector attaches to.",
                    "$ref": "#/$defs/nodeRef"
                  },
                  "magnet": {
                    "description": "Where on the node it attaches.",
                    "type": "string",
                    "enum": [
                      "AUTO",
                      "TOP",
                      "LEFT",
                      "BOTTOM",
                      "RIGHT",
                      "CENTER"
                    ]
                  },
                  "position": {
                    "description": "A free position on the canvas.",
                    "type": "object",
                    "additionalProperties": true,
                    "properties": {
                      "x": {
                        "description": "Horizontal component, px.",
                        "type": "number"
                      },
                      "y": {
                        "description": "Vertical component, px.",
                        "type": "number"
                      }
                    },
                    "required": [
                      "x",
                      "y"
                    ],
                    "x-merge": "replace"
                  }
                },
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "endpointNodeId": {
                        "description": "`endpointNodeId`, as declared above; required in this alternative."
                      }
                    },
                    "required": [
                      "endpointNodeId"
                    ]
                  },
                  {
                    "type": "object",
                    "properties": {
                      "position": {
                        "description": "`position`, as declared above; required in this alternative."
                      }
                    },
                    "required": [
                      "position"
                    ]
                  }
                ],
                "x-merge": "replace"
              },
              "connectorEnd": {
                "description": "The end of the connector: `{\"endpointNodeId\": id, \"magnet\": …}` or `{\"position\": {x, y}}`. Replaced whole by a patch.",
                "type": "object",
                "additionalProperties": true,
                "properties": {
                  "endpointNodeId": {
                    "description": "The node the connector attaches to.",
                    "$ref": "#/$defs/nodeRef"
                  },
                  "magnet": {
                    "description": "Where on the node it attaches.",
                    "type": "string",
                    "enum": [
                      "AUTO",
                      "TOP",
                      "LEFT",
                      "BOTTOM",
                      "RIGHT",
                      "CENTER"
                    ]
                  },
                  "position": {
                    "description": "A free position on the canvas.",
                    "type": "object",
                    "additionalProperties": true,
                    "properties": {
                      "x": {
                        "description": "Horizontal component, px.",
                        "type": "number"
                      },
                      "y": {
                        "description": "Vertical component, px.",
                        "type": "number"
                      }
                    },
                    "required": [
                      "x",
                      "y"
                    ],
                    "x-merge": "replace"
                  }
                },
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "endpointNodeId": {
                        "description": "`endpointNodeId`, as declared above; required in this alternative."
                      }
                    },
                    "required": [
                      "endpointNodeId"
                    ]
                  },
                  {
                    "type": "object",
                    "properties": {
                      "position": {
                        "description": "`position`, as declared above; required in this alternative."
                      }
                    },
                    "required": [
                      "position"
                    ]
                  }
                ],
                "x-merge": "replace"
              },
              "connectorLineType": {
                "description": "Line type.",
                "type": "string",
                "enum": [
                  "ELBOWED",
                  "STRAIGHT",
                  "CURVED"
                ]
              },
              "connectorStartStrokeCap": {
                "description": "Cap at the start.",
                "type": "string",
                "enum": [
                  "NONE",
                  "ROUND",
                  "SQUARE",
                  "ARROW_LINES",
                  "ARROW_EQUILATERAL",
                  "TRIANGLE_FILLED",
                  "CIRCLE_FILLED",
                  "DIAMOND_FILLED"
                ]
              },
              "connectorEndStrokeCap": {
                "description": "Cap at the end.",
                "type": "string",
                "enum": [
                  "NONE",
                  "ROUND",
                  "SQUARE",
                  "ARROW_LINES",
                  "ARROW_EQUILATERAL",
                  "TRIANGLE_FILLED",
                  "CIRCLE_FILLED",
                  "DIAMOND_FILLED"
                ]
              },
              "text": {
                "description": "A nested text object with `characters` and text properties (4.6.8). Merges per member (assumed by this draft).",
                "type": "object",
                "additionalProperties": true,
                "$ref": "#/$defs/textProperties",
                "x-merge": "merge"
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "const": "STICKY"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "text": {
                "description": "A nested text object with `characters` and text properties (4.6.8). Merges per member (assumed by this draft).",
                "type": "object",
                "additionalProperties": true,
                "$ref": "#/$defs/textProperties",
                "x-merge": "merge"
              },
              "authorVisible": {
                "description": "Show the author.",
                "type": "boolean"
              },
              "authorName": {
                "description": "Name of the author.",
                "type": "string"
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "type": {
                "const": "COMPONENT_SET"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "type": "object",
            "properties": {},
            "description": "`COMPONENT_SET` has only `COMPONENT` children (checked by readers, not by this schema)."
          }
        }
      ]
    },
    "node": {
      "description": "A node (layer) in `tree.nodes` (4.3 – 4.8). The key of the map is its id; the object does not repeat it. Every node has `type`, `parent` and `index`; `name` and the other properties take their defaults when absent, and properties equal to their default are not written. Derived values (4.5) are never written.",
      "type": "object",
      "$ref": "#/$defs/nodeFields",
      "required": [
        "type",
        "parent",
        "index"
      ],
      "properties": {
        "type": {
          "description": "`type`, as declared in `nodeFields`; required here."
        },
        "parent": {
          "description": "`parent`, as declared in `nodeFields`; required here."
        },
        "index": {
          "description": "`index`, as declared in `nodeFields`; required here."
        }
      }
    },
    "nodeInput": {
      "description": "A node in a `node.create`, `instance.detach` or `component.combine` event (5.11.2): a node with its `id`. Its parent exists already or is earlier in the same array. Members left out take their defaults.",
      "type": "object",
      "$ref": "#/$defs/nodeFields",
      "properties": {
        "id": {
          "description": "The id of the new node, made by the writer. Never reused.",
          "$ref": "#/$defs/nodeId"
        },
        "type": {
          "description": "`type`, as declared in `nodeFields`; required here."
        },
        "parent": {
          "description": "`parent`, as declared in `nodeFields`; required here."
        },
        "index": {
          "description": "`index`, as declared in `nodeFields`; required here."
        }
      },
      "required": [
        "id",
        "type",
        "parent",
        "index"
      ]
    },
    "nodePatch": {
      "description": "A merge patch of a node's stored properties (5.9, RFC 7396): the `set` of `node.update`, `component.create` and `instance.detach`, the `set` of `instance.override`, and each entry of `overrides`. Every property is optional and nullable: a value sets it, `null` unsets it (back to its default), objects marked `\"x-merge\": \"merge\"` merge recursively, arrays and objects marked `\"x-merge\": \"replace\"` are replaced whole. Members the schema does not know are kept.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "name": {
          "description": "Layer name. Default by type and content (DOC-6). `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        },
        "visible": {
          "description": "Shown or hidden. Default `true`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "boolean"
            }
          ]
        },
        "locked": {
          "description": "Locked against selection on the canvas. Default `false`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "boolean"
            }
          ]
        },
        "x": {
          "description": "Position of the node's origin in its parent's coordinate system (the parent frame, or for children of a `GROUP` or `BOOLEAN_OPERATION` the nearest ancestor frame or the page). Default `0`. Not stored for children in auto layout flow (4.5). In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number"
            }
          ]
        },
        "y": {
          "description": "Vertical position, as `x`. Default `0`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number"
            }
          ]
        },
        "width": {
          "description": "Width. Default `100`. Not stored where derived: hug and fill axes, groups, booleans, auto-sized text (4.5). For a `LINE`, the length. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0
            }
          ]
        },
        "height": {
          "description": "Height. Default `100`. Not stored where derived (4.5). `0` for a `LINE`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0
            }
          ]
        },
        "rotation": {
          "description": "Counter-clockwise rotation about the node's origin, in degrees, in (-180, 180], as Figma. Default `0`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "exclusiveMinimum": -180,
              "maximum": 180
            }
          ]
        },
        "flipX": {
          "description": "Mirrored along the node's own vertical axis. Default `false`. Not in Figma; the Plugin API layer composes `relativeTransform` from `x`, `y`, `rotation`, `flipX`, `flipY`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "boolean"
            }
          ]
        },
        "flipY": {
          "description": "Mirrored along the node's own horizontal axis. Default `false`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "boolean"
            }
          ]
        },
        "description": {
          "description": "Free text (DOC-4); for components, the documentation shown in the Assets panel. Default `\"\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        },
        "documentationLinks": {
          "description": "Links of a component (CMP-7). Default `[]`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "A link.",
                "type": "object",
                "additionalProperties": true,
                "properties": {
                  "uri": {
                    "description": "The link.",
                    "type": "string",
                    "format": "uri"
                  }
                },
                "required": [
                  "uri"
                ]
              }
            }
          ]
        },
        "constraints": {
          "description": "Constraints (LAY-1), `{horizontal, vertical}`. Default `{\"horizontal\":\"MIN\",\"vertical\":\"MIN\"}`. Merges per member. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "horizontal": {
                  "description": "`MIN` (left), `MAX` (right), `STRETCH` (left and right), `CENTER`, `SCALE`. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "string",
                      "enum": [
                        "MIN",
                        "MAX",
                        "STRETCH",
                        "CENTER",
                        "SCALE"
                      ]
                    }
                  ]
                },
                "vertical": {
                  "description": "The same for top and bottom. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "string",
                      "enum": [
                        "MIN",
                        "MAX",
                        "STRETCH",
                        "CENTER",
                        "SCALE"
                      ]
                    }
                  ]
                }
              }
            }
          ]
        },
        "layoutPositioning": {
          "description": "In an auto layout parent: in flow, or absolutely positioned with constraints (LAY-5). Default `\"AUTO\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "AUTO",
                "ABSOLUTE"
              ]
            }
          ]
        },
        "layoutSizingHorizontal": {
          "description": "Horizontal sizing (LAY-3). `HUG` only for auto layout frames and text; `FILL` only for children of auto layout frames. Default `\"FIXED\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "FIXED",
                "HUG",
                "FILL"
              ]
            }
          ]
        },
        "layoutSizingVertical": {
          "description": "Vertical sizing (LAY-3). Default `\"FIXED\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "FIXED",
                "HUG",
                "FILL"
              ]
            }
          ]
        },
        "minWidth": {
          "description": "Minimum width (LAY-3). Absent by default. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0
            }
          ]
        },
        "maxWidth": {
          "description": "Maximum width. Absent by default. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0
            }
          ]
        },
        "minHeight": {
          "description": "Minimum height. Absent by default. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0
            }
          ]
        },
        "maxHeight": {
          "description": "Maximum height. Absent by default. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0
            }
          ]
        },
        "gridRowAnchorIndex": {
          "description": "Row of a child in a grid auto layout (LAY-4). Auto-placed by default. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "integer",
              "minimum": 0
            }
          ]
        },
        "gridColumnAnchorIndex": {
          "description": "Column of a child in a grid auto layout. Auto-placed by default. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "integer",
              "minimum": 0
            }
          ]
        },
        "gridRowSpan": {
          "description": "Rows spanned. Default `1`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "integer",
              "minimum": 1
            }
          ]
        },
        "gridColumnSpan": {
          "description": "Columns spanned. Default `1`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "integer",
              "minimum": 1
            }
          ]
        },
        "gridChildHorizontalAlign": {
          "description": "Horizontal alignment within the cell. Default `\"AUTO\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "AUTO",
                "MIN",
                "CENTER",
                "MAX"
              ]
            }
          ]
        },
        "gridChildVerticalAlign": {
          "description": "Vertical alignment within the cell. Default `\"AUTO\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "AUTO",
                "MIN",
                "CENTER",
                "MAX"
              ]
            }
          ]
        },
        "scrollBehavior": {
          "description": "Behaviour when the parent frame scrolls in a prototype (PRO-5). Default `\"SCROLLS\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "SCROLLS",
                "FIXED",
                "STICKY_SCROLLS"
              ]
            }
          ]
        },
        "layoutMode": {
          "description": "Auto layout direction (LAY-2, LAY-4). Default `\"NONE\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "NONE",
                "HORIZONTAL",
                "VERTICAL",
                "GRID"
              ]
            }
          ]
        },
        "layoutWrap": {
          "description": "Wrap for `HORIZONTAL`. Default `\"NO_WRAP\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "NO_WRAP",
                "WRAP"
              ]
            }
          ]
        },
        "itemSpacing": {
          "description": "Gap between items. Default `0`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number"
            }
          ]
        },
        "counterAxisSpacing": {
          "description": "Gap between rows when wrapping. Default `0`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number"
            }
          ]
        },
        "paddingLeft": {
          "description": "Left padding. Default `0`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number"
            }
          ]
        },
        "paddingRight": {
          "description": "Right padding. Default `0`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number"
            }
          ]
        },
        "paddingTop": {
          "description": "Top padding. Default `0`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number"
            }
          ]
        },
        "paddingBottom": {
          "description": "Bottom padding. Default `0`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number"
            }
          ]
        },
        "primaryAxisAlignItems": {
          "description": "Alignment along the direction; `SPACE_BETWEEN` is gap \"auto\". Default `\"MIN\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "MIN",
                "CENTER",
                "MAX",
                "SPACE_BETWEEN"
              ]
            }
          ]
        },
        "counterAxisAlignItems": {
          "description": "Alignment across the direction. Default `\"MIN\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "MIN",
                "CENTER",
                "MAX",
                "BASELINE"
              ]
            }
          ]
        },
        "counterAxisAlignContent": {
          "description": "Distribution of wrapped rows. Default `\"AUTO\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "AUTO",
                "SPACE_BETWEEN"
              ]
            }
          ]
        },
        "itemReverseZIndex": {
          "description": "First item painted on top (LAY-2). Default `false`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "boolean"
            }
          ]
        },
        "strokesIncludedInLayout": {
          "description": "Strokes count in the box (LAY-6). Default `false`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "boolean"
            }
          ]
        },
        "gridRowCount": {
          "description": "Rows of a grid auto layout (LAY-4). Default `1`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "integer",
              "minimum": 1
            }
          ]
        },
        "gridColumnCount": {
          "description": "Columns of a grid auto layout. Default `1`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "integer",
              "minimum": 1
            }
          ]
        },
        "gridRowGap": {
          "description": "Gap between rows. Default `0`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number"
            }
          ]
        },
        "gridColumnGap": {
          "description": "Gap between columns. Default `0`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number"
            }
          ]
        },
        "gridRowSizes": {
          "description": "Row track sizes. Default one `FLEX` 1 per track. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "A track size.",
                "type": "object",
                "additionalProperties": true,
                "properties": {
                  "type": {
                    "description": "Kind of track size; `FLEX` is a fraction (`fr`).",
                    "type": "string",
                    "enum": [
                      "FIXED",
                      "FLEX",
                      "HUG"
                    ]
                  },
                  "value": {
                    "description": "The size, px for `FIXED`, a fraction for `FLEX`.",
                    "type": "number"
                  }
                },
                "required": [
                  "type"
                ]
              }
            }
          ]
        },
        "gridColumnSizes": {
          "description": "Column track sizes. Default one `FLEX` 1 per track. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "A track size.",
                "type": "object",
                "additionalProperties": true,
                "properties": {
                  "type": {
                    "description": "Kind of track size; `FLEX` is a fraction (`fr`).",
                    "type": "string",
                    "enum": [
                      "FIXED",
                      "FLEX",
                      "HUG"
                    ]
                  },
                  "value": {
                    "description": "The size, px for `FIXED`, a fraction for `FLEX`.",
                    "type": "number"
                  }
                },
                "required": [
                  "type"
                ]
              }
            }
          ]
        },
        "layoutGrids": {
          "description": "Column, row and uniform guides (LAY-8). Default `[]`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "A layout grid.",
                "$ref": "#/$defs/layoutGrid"
              }
            }
          ]
        },
        "gridStyleId": {
          "description": "Layout grid style (4.9). Absent by default. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/styleRef"
            }
          ]
        },
        "clipsContent": {
          "description": "Clip children to the frame, respecting corner radius (STY-8). Default `true` for frames, `false` for components and instances. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "boolean"
            }
          ]
        },
        "overflowDirection": {
          "description": "Prototype scrolling (PRO-5). Default `\"NONE\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "NONE",
                "HORIZONTAL",
                "VERTICAL",
                "BOTH"
              ]
            }
          ]
        },
        "overlayPositionType": {
          "description": "Where the frame shows when opened as an overlay (PRO-4), Figma's values. Default `\"CENTER\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "CENTER",
                "TOP_LEFT",
                "TOP_CENTER",
                "TOP_RIGHT",
                "BOTTOM_LEFT",
                "BOTTOM_CENTER",
                "BOTTOM_RIGHT",
                "MANUAL"
              ]
            }
          ]
        },
        "overlayBackground": {
          "description": "Background behind the frame when opened as an overlay, Figma's shape. Default `{\"type\":\"NONE\"}`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "type": {
                  "description": "No background, or a solid colour.",
                  "type": "string",
                  "enum": [
                    "NONE",
                    "SOLID_COLOR"
                  ]
                },
                "color": {
                  "description": "`SOLID_COLOR`: the colour, with `a`.",
                  "$ref": "#/$defs/color",
                  "x-merge": "replace"
                }
              },
              "required": [
                "type"
              ]
            }
          ],
          "x-merge": "replace"
        },
        "overlayBackgroundInteraction": {
          "description": "What a click outside the overlay does, Figma's values. Default `\"NONE\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "NONE",
                "CLOSE_ON_CLICK_OUTSIDE"
              ]
            }
          ]
        },
        "opacity": {
          "description": "Layer opacity, 0 to 1 (STY-7). Default `1`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0,
              "maximum": 1
            }
          ]
        },
        "blendMode": {
          "description": "Figma's `BlendMode`. Default `\"PASS_THROUGH\"` for frames, groups, sections, components, instances; `\"NORMAL\"` otherwise. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "PASS_THROUGH",
                "NORMAL",
                "DARKEN",
                "MULTIPLY",
                "LINEAR_BURN",
                "COLOR_BURN",
                "LIGHTEN",
                "SCREEN",
                "LINEAR_DODGE",
                "COLOR_DODGE",
                "OVERLAY",
                "SOFT_LIGHT",
                "HARD_LIGHT",
                "DIFFERENCE",
                "EXCLUSION",
                "HUE",
                "SATURATION",
                "COLOR",
                "LUMINOSITY"
              ]
            }
          ]
        },
        "fills": {
          "description": "Fills, bottom first (STY-1). Default `[]`, except one white `SOLID` for frames and components created by the Frame tool. Replaced whole by a patch. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "A paint.",
                "$ref": "#/$defs/paint"
              }
            }
          ]
        },
        "fillStyleId": {
          "description": "Paint style for the fills (4.9). The plain `fills` stay written as the fallback. Absent by default. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/styleRef"
            }
          ]
        },
        "strokes": {
          "description": "Strokes (STY-5). Default `[]`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "A paint.",
                "$ref": "#/$defs/paint"
              }
            }
          ]
        },
        "strokeStyleId": {
          "description": "Paint style for the strokes. Absent by default. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/styleRef"
            }
          ]
        },
        "strokeWeight": {
          "description": "Weight of all sides. Default `1`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0
            }
          ]
        },
        "strokeTopWeight": {
          "description": "Top stroke weight of frames and rectangles. Default `strokeWeight`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0
            }
          ]
        },
        "strokeRightWeight": {
          "description": "Right stroke weight. Default `strokeWeight`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0
            }
          ]
        },
        "strokeBottomWeight": {
          "description": "Bottom stroke weight. Default `strokeWeight`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0
            }
          ]
        },
        "strokeLeftWeight": {
          "description": "Left stroke weight. Default `strokeWeight`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0
            }
          ]
        },
        "strokeAlign": {
          "description": "Stroke position. Default `\"INSIDE\"` for closed shapes, `\"CENTER\"` for lines and open vectors. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "INSIDE",
                "CENTER",
                "OUTSIDE"
              ]
            }
          ]
        },
        "strokeCap": {
          "description": "Caps of open paths. Default `\"NONE\"`. Per-vertex caps are in the vector network. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "NONE",
                "ROUND",
                "SQUARE",
                "ARROW_LINES",
                "ARROW_EQUILATERAL",
                "TRIANGLE_FILLED",
                "CIRCLE_FILLED",
                "DIAMOND_FILLED"
              ]
            }
          ]
        },
        "strokeJoin": {
          "description": "Joins. Default `\"MITER\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "MITER",
                "BEVEL",
                "ROUND"
              ]
            }
          ]
        },
        "strokeMiterLimit": {
          "description": "Miter limit. Default `4`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0
            }
          ]
        },
        "dashPattern": {
          "description": "Dash and gap lengths; empty is solid. Default `[]`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "A dash or gap length, px.",
                "type": "number",
                "minimum": 0
              }
            }
          ]
        },
        "effects": {
          "description": "Shadows and blurs, in order (STY-6). Default `[]`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "An effect.",
                "$ref": "#/$defs/effect"
              }
            }
          ]
        },
        "effectStyleId": {
          "description": "Effect style. Absent by default. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/styleRef"
            }
          ]
        },
        "cornerRadius": {
          "description": "All corners of a rectangle, frame, component, instance, polygon or star. Default `0`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0
            }
          ]
        },
        "topLeftRadius": {
          "description": "Top-left corner (DRW-3). Default `cornerRadius`; written only when the corners differ, and wins over `cornerRadius` for its corner. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0
            }
          ]
        },
        "topRightRadius": {
          "description": "Top-right corner. Default `cornerRadius`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0
            }
          ]
        },
        "bottomRightRadius": {
          "description": "Bottom-right corner. Default `cornerRadius`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0
            }
          ]
        },
        "bottomLeftRadius": {
          "description": "Bottom-left corner. Default `cornerRadius`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0
            }
          ]
        },
        "cornerSmoothing": {
          "description": "Smooth corners (squircle), 0 to 1; 0.6 is iOS style (DRW-3). Default `0`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0,
              "maximum": 1
            }
          ]
        },
        "isMask": {
          "description": "This node masks the siblings above it, up to the end of the parent (DRW-8). Default `false`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "boolean"
            }
          ]
        },
        "maskType": {
          "description": "How the mask applies. Default `\"ALPHA\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "ALPHA",
                "VECTOR",
                "LUMINANCE"
              ]
            }
          ]
        },
        "boundVariables": {
          "description": "Bindings of the node's properties to variables (VAR-4), Figma's shape: a map of property name to `{\"type\":\"VARIABLE_ALIAS\",\"id\":\"vr-…\"}`. The plain value stays written next to the binding and is the fallback when the variable is missing (4.4.5). Default `{}`. Merges per property. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "The variable the property is bound to. `null` unsets it.",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/$defs/variableAlias"
                  }
                ],
                "x-merge": "replace"
              }
            }
          ]
        },
        "explicitVariableModes": {
          "description": "Modes chosen on this node, for it and its descendants (VAR-6): a map of variable collection id to mode id. Default `{}`. Merges per collection. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "propertyNames": {
                "$ref": "#/$defs/variableCollectionRef"
              },
              "additionalProperties": {
                "description": "The mode chosen for that collection. `null` unsets it.",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/$defs/modeRef"
                  }
                ]
              }
            }
          ]
        },
        "componentPropertyReferences": {
          "description": "Properties of a layer inside a component that are driven by a component property (CMP-5): `{\"characters\": \"Label#a41c\", \"visible\": \"Show icon#5d02\", \"mainComponent\": \"Icon#77b0\"}`. Default `{}`. Merges per property. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "The component property that drives it. `null` unsets it.",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/$defs/componentPropertyKey"
                  }
                ]
              }
            }
          ]
        },
        "exportSettings": {
          "description": "Export settings (EXP-1), Figma's shape. Default `[]`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "An export setting.",
                "$ref": "#/$defs/exportSetting"
              }
            }
          ]
        },
        "reactions": {
          "description": "Prototype interactions (PRO-1 – PRO-4), Figma's shape. Default `[]`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "A reaction.",
                "$ref": "#/$defs/reaction"
              }
            }
          ]
        },
        "devStatus": {
          "description": "Developer status (DEV-5, DOC-8) on frames, sections and components. Absent by default. Replaced whole by a patch. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "type": {
                  "description": "The status.",
                  "type": "string",
                  "enum": [
                    "READY_FOR_DEV",
                    "COMPLETED"
                  ]
                },
                "description": {
                  "description": "Note for developers.",
                  "type": "string"
                },
                "at": {
                  "description": "When the status was set; writers copy the event's `at`.",
                  "$ref": "#/$defs/timestamp"
                }
              },
              "required": [
                "type"
              ]
            }
          ],
          "x-merge": "replace"
        },
        "annotations": {
          "description": "Annotations attached to the node (DEV-7). Default `[]`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "An annotation, Figma's shape.",
                "type": "object",
                "additionalProperties": true,
                "properties": {
                  "label": {
                    "description": "Plain text of the annotation.",
                    "type": "string"
                  },
                  "labelMarkdown": {
                    "description": "The annotation as Markdown.",
                    "type": "string"
                  },
                  "properties": {
                    "description": "Properties pinned to the annotation.",
                    "type": "array",
                    "items": {
                      "description": "A pinned property.",
                      "type": "object",
                      "additionalProperties": true,
                      "properties": {
                        "type": {
                          "description": "A property to show, e.g. `width`.",
                          "type": "string"
                        }
                      },
                      "required": [
                        "type"
                      ]
                    }
                  },
                  "categoryId": {
                    "description": "Category of the annotation (`document.annotationCategories`).",
                    "$ref": "#/$defs/annotationCategoryId"
                  }
                }
              }
            }
          ]
        },
        "accessibility": {
          "description": "Accessibility metadata (DEV-8). Our own; Figma has no equivalent. Default `{}`. Merges per member. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "role": {
                  "description": "Accessibility role. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "string"
                    }
                  ]
                },
                "name": {
                  "description": "Accessible name. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "string"
                    }
                  ]
                },
                "description": {
                  "description": "Accessible description. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "string"
                    }
                  ]
                },
                "headingLevel": {
                  "description": "Heading level, 1 to 6. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 6
                    }
                  ]
                },
                "focusOrder": {
                  "description": "Position in the focus order. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "integer"
                    }
                  ]
                },
                "altText": {
                  "description": "Alternative text. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "string"
                    }
                  ]
                },
                "decorative": {
                  "description": "Decorative: hidden from assistive technology. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "boolean"
                    }
                  ]
                }
              }
            }
          ]
        },
        "codeMap": {
          "description": "The code component this component or component set maps to (DEV-4). Mappings in the `ud.codeMap` setting override the file. Absent by default. Replaced whole by a patch. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "component": {
                  "description": "Name of the code component.",
                  "type": "string"
                },
                "source": {
                  "description": "Source file of the code component, relative to the workspace.",
                  "type": "string"
                },
                "language": {
                  "description": "Language of the source, e.g. `tsx`.",
                  "type": "string"
                },
                "props": {
                  "description": "Map of component property key to code prop.",
                  "type": "object",
                  "additionalProperties": {
                    "description": "How one component property maps to a code prop.",
                    "type": "object",
                    "additionalProperties": true,
                    "properties": {
                      "prop": {
                        "description": "Name of the code prop.",
                        "type": "string"
                      },
                      "values": {
                        "description": "Map of design value to code value.",
                        "type": "object",
                        "additionalProperties": {
                          "description": "The code value.",
                          "type": "string"
                        },
                        "x-merge": "replace"
                      },
                      "when": {
                        "description": "Value of the design property for which the prop is passed."
                      }
                    },
                    "required": [
                      "prop"
                    ],
                    "x-merge": "replace"
                  },
                  "x-merge": "replace"
                }
              }
            }
          ],
          "x-merge": "replace"
        },
        "traces": {
          "description": "Project Board items (INT-1) and Software Board elements (INT-4) this node realises, e.g. `{\"file\": \"planning.pb\", \"item\": \"REQ-12\"}` or `{\"kind\": \"uml\", \"file\": \"ui-designer.uml\", \"item\": \"el-…\"}`. Default `[]`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "A trace link.",
                "type": "object",
                "additionalProperties": true,
                "properties": {
                  "kind": {
                    "description": "What the trace points at: `pb`, an item of a Project Board file (INT-1), or `uml`, an element of a Software Board model (INT-4). Absent means `pb`.",
                    "type": "string",
                    "enum": [
                      "pb",
                      "uml"
                    ]
                  },
                  "file": {
                    "description": "Project Board file (`.pb`) or Software Board model (`.uml`), relative to the design file.",
                    "type": "string"
                  },
                  "item": {
                    "description": "The item it realises: `REQ-12`, `#12` (pb), or an element id `el-…` (uml).",
                    "type": "string"
                  }
                },
                "required": [
                  "file",
                  "item"
                ]
              }
            }
          ]
        },
        "pluginData": {
          "description": "Private data of plugins and scripts (4.4.10): a map of plugin id to a map of key to string. `setPluginData(key, value)` in the Plugin API writes `pluginData[<plugin id>][key]`. Scripts run by `use_figma` have the plugin id `ud`. Merges per key, so two branches that write different keys both survive. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "The keys and values written by one plugin or script. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
                "x-merge": "merge",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "object",
                    "additionalProperties": {
                      "description": "A value. Values are strings, as in Figma; setting a value to `\"\"` removes the key (in a merge patch the key is set to `null`). `null` unsets it.",
                      "anyOf": [
                        {
                          "type": "null"
                        },
                        {
                          "type": "string"
                        }
                      ]
                    }
                  }
                ]
              }
            }
          ]
        },
        "sharedPluginData": {
          "description": "Data shared between plugins (4.4.10): a map of namespace to a map of key to string, written by `setSharedPluginData(namespace, key, value)`. Merges per key. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "The keys and values of one namespace. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
                "x-merge": "merge",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "object",
                    "additionalProperties": {
                      "description": "A value, a string as in Figma. `\"\"` removes the key. `null` unsets it.",
                      "anyOf": [
                        {
                          "type": "null"
                        },
                        {
                          "type": "string"
                        }
                      ]
                    }
                  }
                ]
              }
            }
          ]
        },
        "characters": {
          "description": "The text (TXT-1). Line breaks and paragraph breaks are `\\n` (Figma's model). Default `\"\"`. A writer that changes the text writes `styledRuns` in the same `set`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        },
        "fontName": {
          "description": "Font family and style. Default `{\"family\":\"Inter\",\"style\":\"Regular\"}`. Replaced whole by a patch. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "family": {
                  "description": "Font family, e.g. `\"Inter\"`.",
                  "type": "string"
                },
                "style": {
                  "description": "Figma's style name, e.g. `\"Semi Bold\"` (CMD-15).",
                  "type": "string"
                }
              },
              "required": [
                "family",
                "style"
              ]
            }
          ],
          "x-merge": "replace"
        },
        "fontSize": {
          "description": "Font size. Default `12`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0
            }
          ]
        },
        "fontVariations": {
          "description": "Variable font axes, a map of axis tag to number, e.g. `{\"wght\": 550, \"opsz\": 14}` (TXT-4). Our own. Default `{}`. Merges per axis. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "Axis value. `null` unsets it.",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "number"
                  }
                ]
              }
            }
          ]
        },
        "letterSpacing": {
          "description": "Letter spacing, `{unit: \"PIXELS\" or \"PERCENT\", value}`. Default `{\"unit\":\"PERCENT\",\"value\":0}`. Replaced whole by a patch. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "unit": {
                  "description": "Unit of `value`.",
                  "type": "string",
                  "enum": [
                    "PIXELS",
                    "PERCENT"
                  ]
                },
                "value": {
                  "description": "The spacing.",
                  "type": "number"
                }
              },
              "required": [
                "unit",
                "value"
              ]
            }
          ],
          "x-merge": "replace"
        },
        "lineHeight": {
          "description": "Line height, `{unit: \"AUTO\"}` or `{unit: \"PIXELS\" or \"PERCENT\", value}`. Default `{\"unit\":\"AUTO\"}`. Replaced whole by a patch. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "required": [
                "unit"
              ],
              "properties": {
                "unit": {
                  "description": "Unit: `AUTO`, or `PIXELS` / `PERCENT` with a `value`.",
                  "type": "string",
                  "enum": [
                    "AUTO",
                    "PIXELS",
                    "PERCENT"
                  ]
                },
                "value": {
                  "description": "The line height; absent for `AUTO`.",
                  "type": "number"
                }
              },
              "if": {
                "type": "object",
                "properties": {
                  "unit": {
                    "enum": [
                      "PIXELS",
                      "PERCENT"
                    ]
                  }
                },
                "required": [
                  "unit"
                ]
              },
              "then": {
                "type": "object",
                "properties": {
                  "value": {
                    "description": "Required for `PIXELS` and `PERCENT`.",
                    "type": "number"
                  }
                },
                "required": [
                  "value"
                ]
              }
            }
          ],
          "x-merge": "replace"
        },
        "textCase": {
          "description": "Text case. Default `\"ORIGINAL\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "ORIGINAL",
                "UPPER",
                "LOWER",
                "TITLE",
                "SMALL_CAPS",
                "SMALL_CAPS_FORCED"
              ]
            }
          ]
        },
        "textDecoration": {
          "description": "Text decoration. Default `\"NONE\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "NONE",
                "UNDERLINE",
                "STRIKETHROUGH"
              ]
            }
          ]
        },
        "textAlignHorizontal": {
          "description": "Horizontal alignment (TXT-3). Default `\"LEFT\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "LEFT",
                "CENTER",
                "RIGHT",
                "JUSTIFIED"
              ]
            }
          ]
        },
        "textAlignVertical": {
          "description": "Vertical alignment. Default `\"TOP\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "TOP",
                "CENTER",
                "BOTTOM"
              ]
            }
          ]
        },
        "textAutoResize": {
          "description": "Auto-resize mode (TXT-1). With `WIDTH_AND_HEIGHT` or `HEIGHT` the geometry is derived and not stored (4.5). Default `\"WIDTH_AND_HEIGHT\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "NONE",
                "WIDTH_AND_HEIGHT",
                "HEIGHT",
                "TRUNCATE"
              ]
            }
          ]
        },
        "textTruncation": {
          "description": "Ellipsis. Default `\"DISABLED\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "DISABLED",
                "ENDING"
              ]
            }
          ]
        },
        "maxLines": {
          "description": "Lines before the ellipsis. Absent by default. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "integer",
              "minimum": 1
            }
          ]
        },
        "paragraphSpacing": {
          "description": "Space after a paragraph. Default `0`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number"
            }
          ]
        },
        "paragraphIndent": {
          "description": "Indent of the first line of a paragraph. Default `0`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number"
            }
          ]
        },
        "listSpacing": {
          "description": "Space between list items. Default `0`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number"
            }
          ]
        },
        "hangingPunctuation": {
          "description": "Hanging punctuation. Default `false`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "boolean"
            }
          ]
        },
        "hangingList": {
          "description": "Hanging list markers. Default `false`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "boolean"
            }
          ]
        },
        "leadingTrim": {
          "description": "Leading trim (TXT-3). Default `\"NONE\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "NONE",
                "CAP_HEIGHT"
              ]
            }
          ]
        },
        "openTypeFeatures": {
          "description": "OpenType features, a map of feature tag to boolean, e.g. `{\"TNUM\": true, \"LIGA\": false, \"SS01\": true}` (TXT-4). Default `{}`. Merges per feature. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "On or off. `null` unsets it.",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "boolean"
                  }
                ]
              }
            }
          ]
        },
        "hyperlink": {
          "description": "A link, `{type: \"URL\" or \"NODE\", value}`. Absent by default. Replaced whole by a patch. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "type": {
                  "description": "Link to a URL or to a node.",
                  "type": "string",
                  "enum": [
                    "URL",
                    "NODE"
                  ]
                },
                "value": {
                  "description": "The URL, or the node id.",
                  "type": "string"
                }
              },
              "required": [
                "type",
                "value"
              ]
            }
          ],
          "x-merge": "replace"
        },
        "textStyleId": {
          "description": "Text style (4.9). The plain text values stay written next to it as the fallback (4.4.5). Absent by default. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/styleRef"
            }
          ]
        },
        "styledRuns": {
          "description": "Ranges whose properties differ from the node-level values (TXT-2), sorted by `start`, not overlapping. Default `[]`. Replaced whole by a patch. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "One run.",
                "$ref": "#/$defs/styledRun"
              }
            }
          ]
        },
        "sectionContentsHidden": {
          "description": "Contents hidden on the canvas. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "boolean"
            }
          ]
        },
        "arcData": {
          "description": "Arc (DRW-3), Figma's shape `{\"startingAngle\": 0, \"endingAngle\": 6.2831853, \"innerRadius\": 0}`. The angles are in radians, the only angle of the format not in degrees. Default a full ellipse. Replaced whole by a patch. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "startingAngle": {
                  "description": "Start angle in radians.",
                  "type": "number"
                },
                "endingAngle": {
                  "description": "End angle in radians.",
                  "type": "number"
                },
                "innerRadius": {
                  "description": "Inner radius ratio, 0 to 1 (donuts).",
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1
                }
              }
            }
          ],
          "x-merge": "replace"
        },
        "pointCount": {
          "description": "Number of points, 3 or more. Default 5. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "integer",
              "minimum": 3
            }
          ]
        },
        "innerRadius": {
          "description": "Ratio of inner to outer radius, 0 to 1. Default 0.38. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0,
              "maximum": 1
            }
          ]
        },
        "textPath": {
          "description": "Text on a path (TXT-8), a UI Designer extension of 4.11 stored on the node like a frame's `guides`: the text is one auto-width line whose glyphs follow `path`; characters past its end are hidden. Absent by default. Replaced whole by a patch. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "source": {
                  "description": "The layer whose outline was copied into `path`: a `LINE`, `ELLIPSE`, `VECTOR`, `STAR`, `POLYGON`, `RECTANGLE` or `BOOLEAN_OPERATION`. The copy is refreshed when the source changes while both are on the same page; a deleted source leaves it as it was. Absent when the path was given as data.",
                  "$ref": "#/$defs/nodeRef"
                },
                "path": {
                  "description": "SVG path data in the text node's own coordinate space (writers store absolute `M`, `L`, `C`, `Z`).",
                  "type": "string",
                  "minLength": 1
                },
                "startOffset": {
                  "description": "Distance along the path where the text starts. Default `0`. In px.",
                  "type": "number"
                },
                "side": {
                  "description": "Side of the path the glyphs stand on, relative to its direction (`RIGHT` walks the path backwards). Default `\"LEFT\"`.",
                  "type": "string",
                  "enum": [
                    "LEFT",
                    "RIGHT"
                  ]
                },
                "align": {
                  "description": "Where the line sits on the path. Default `\"START\"`.",
                  "type": "string",
                  "enum": [
                    "START",
                    "CENTER",
                    "END"
                  ]
                }
              },
              "required": [
                "path"
              ]
            }
          ],
          "x-merge": "replace"
        },
        "vectorNetwork": {
          "description": "The vector network (DRW-4). One property: an edit replaces it. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/vectorNetwork"
            }
          ],
          "x-merge": "replace"
        },
        "booleanOperation": {
          "description": "The operation (DRW-5). Default `\"UNION\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "UNION",
                "SUBTRACT",
                "INTERSECT",
                "EXCLUDE"
              ]
            }
          ]
        },
        "componentPropertyDefinitions": {
          "description": "Component property definitions (CMP-5), keyed by property key. On the component, or on the set for variants. Default `{}`. Merges per key. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "propertyNames": {
                "$ref": "#/$defs/componentPropertyKey"
              },
              "additionalProperties": {
                "description": "One definition. `null` unsets it.",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/$defs/componentPropertyDefinition"
                  }
                ],
                "x-merge": "replace"
              }
            }
          ]
        },
        "componentId": {
          "description": "The main component, or a variant of a set; `lib-…/nd-…` for a library component (4.11). Required. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/componentRef"
            }
          ]
        },
        "libraryId": {
          "description": "Listed among the instance properties in 4.6 but not defined by FMT-001; a qualified `componentId` already names the library. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/libraryId"
            }
          ]
        },
        "componentProperties": {
          "description": "Component property values that differ from the definitions' defaults, `{\"Label#a41c\": \"Sign in\", \"Size\": \"lg\"}`. Plain values; the Plugin API layer adds `type`. Default `{}`. Merges per key. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "propertyNames": {
                "$ref": "#/$defs/componentPropertyKey"
              },
              "additionalProperties": {
                "description": "The value. `null` unsets it.",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "boolean"
                      }
                    ]
                  }
                ]
              }
            }
          ]
        },
        "overrides": {
          "description": "Changed properties of sublayers, keyed by override path (4.8). An override whose path matches no layer is kept but dormant. Default `{}`. Merges per path. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "propertyNames": {
                "$ref": "#/$defs/overridePath"
              },
              "additionalProperties": {
                "description": "A merge patch of the sublayer's properties: only what differs. `componentId` swaps a nested instance (CMP-3, CMP-6). `null` unsets it.",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/$defs/nodePatch"
                  }
                ],
                "x-merge": "merge"
              }
            }
          ]
        },
        "slotPropertyKey": {
          "description": "Key of the `SLOT` component property that exposes this slot (CMP-5). `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/componentPropertyKey"
            }
          ]
        },
        "connectorStart": {
          "description": "The start of the connector: `{\"endpointNodeId\": id, \"magnet\": …}` or `{\"position\": {x, y}}`. Replaced whole by a patch. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "endpointNodeId": {
                  "description": "The node the connector attaches to.",
                  "$ref": "#/$defs/nodeRef"
                },
                "magnet": {
                  "description": "Where on the node it attaches.",
                  "type": "string",
                  "enum": [
                    "AUTO",
                    "TOP",
                    "LEFT",
                    "BOTTOM",
                    "RIGHT",
                    "CENTER"
                  ]
                },
                "position": {
                  "description": "A free position on the canvas.",
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "x": {
                      "description": "Horizontal component, px.",
                      "type": "number"
                    },
                    "y": {
                      "description": "Vertical component, px.",
                      "type": "number"
                    }
                  },
                  "required": [
                    "x",
                    "y"
                  ],
                  "x-merge": "replace"
                }
              },
              "anyOf": [
                {
                  "type": "object",
                  "properties": {
                    "endpointNodeId": {
                      "description": "`endpointNodeId`, as declared above; required in this alternative."
                    }
                  },
                  "required": [
                    "endpointNodeId"
                  ]
                },
                {
                  "type": "object",
                  "properties": {
                    "position": {
                      "description": "`position`, as declared above; required in this alternative."
                    }
                  },
                  "required": [
                    "position"
                  ]
                }
              ]
            }
          ],
          "x-merge": "replace"
        },
        "connectorEnd": {
          "description": "The end of the connector: `{\"endpointNodeId\": id, \"magnet\": …}` or `{\"position\": {x, y}}`. Replaced whole by a patch. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "endpointNodeId": {
                  "description": "The node the connector attaches to.",
                  "$ref": "#/$defs/nodeRef"
                },
                "magnet": {
                  "description": "Where on the node it attaches.",
                  "type": "string",
                  "enum": [
                    "AUTO",
                    "TOP",
                    "LEFT",
                    "BOTTOM",
                    "RIGHT",
                    "CENTER"
                  ]
                },
                "position": {
                  "description": "A free position on the canvas.",
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "x": {
                      "description": "Horizontal component, px.",
                      "type": "number"
                    },
                    "y": {
                      "description": "Vertical component, px.",
                      "type": "number"
                    }
                  },
                  "required": [
                    "x",
                    "y"
                  ],
                  "x-merge": "replace"
                }
              },
              "anyOf": [
                {
                  "type": "object",
                  "properties": {
                    "endpointNodeId": {
                      "description": "`endpointNodeId`, as declared above; required in this alternative."
                    }
                  },
                  "required": [
                    "endpointNodeId"
                  ]
                },
                {
                  "type": "object",
                  "properties": {
                    "position": {
                      "description": "`position`, as declared above; required in this alternative."
                    }
                  },
                  "required": [
                    "position"
                  ]
                }
              ]
            }
          ],
          "x-merge": "replace"
        },
        "connectorLineType": {
          "description": "Line type. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "ELBOWED",
                "STRAIGHT",
                "CURVED"
              ]
            }
          ]
        },
        "connectorStartStrokeCap": {
          "description": "Cap at the start. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "NONE",
                "ROUND",
                "SQUARE",
                "ARROW_LINES",
                "ARROW_EQUILATERAL",
                "TRIANGLE_FILLED",
                "CIRCLE_FILLED",
                "DIAMOND_FILLED"
              ]
            }
          ]
        },
        "connectorEndStrokeCap": {
          "description": "Cap at the end. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "NONE",
                "ROUND",
                "SQUARE",
                "ARROW_LINES",
                "ARROW_EQUILATERAL",
                "TRIANGLE_FILLED",
                "CIRCLE_FILLED",
                "DIAMOND_FILLED"
              ]
            }
          ]
        },
        "text": {
          "description": "A nested text object with `characters` and text properties (4.6.8). Merges per member (assumed by this draft). In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "characters": {
                  "description": "The text (TXT-1). Line breaks and paragraph breaks are `\\n` (Figma's model). Default `\"\"`. A writer that changes the text writes `styledRuns` in the same `set`. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "string"
                    }
                  ]
                },
                "fontName": {
                  "description": "Font family and style. Default `{\"family\":\"Inter\",\"style\":\"Regular\"}`. Replaced whole by a patch. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "object",
                      "additionalProperties": true,
                      "properties": {
                        "family": {
                          "description": "Font family, e.g. `\"Inter\"`.",
                          "type": "string"
                        },
                        "style": {
                          "description": "Figma's style name, e.g. `\"Semi Bold\"` (CMD-15).",
                          "type": "string"
                        }
                      },
                      "required": [
                        "family",
                        "style"
                      ]
                    }
                  ],
                  "x-merge": "replace"
                },
                "fontSize": {
                  "description": "Font size. Default `12`. In px. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "number",
                      "minimum": 0
                    }
                  ]
                },
                "fontVariations": {
                  "description": "Variable font axes, a map of axis tag to number, e.g. `{\"wght\": 550, \"opsz\": 14}` (TXT-4). Our own. Default `{}`. Merges per axis. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
                  "x-merge": "merge",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "object",
                      "additionalProperties": {
                        "description": "Axis value. `null` unsets it.",
                        "anyOf": [
                          {
                            "type": "null"
                          },
                          {
                            "type": "number"
                          }
                        ]
                      }
                    }
                  ]
                },
                "letterSpacing": {
                  "description": "Letter spacing, `{unit: \"PIXELS\" or \"PERCENT\", value}`. Default `{\"unit\":\"PERCENT\",\"value\":0}`. Replaced whole by a patch. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "object",
                      "additionalProperties": true,
                      "properties": {
                        "unit": {
                          "description": "Unit of `value`.",
                          "type": "string",
                          "enum": [
                            "PIXELS",
                            "PERCENT"
                          ]
                        },
                        "value": {
                          "description": "The spacing.",
                          "type": "number"
                        }
                      },
                      "required": [
                        "unit",
                        "value"
                      ]
                    }
                  ],
                  "x-merge": "replace"
                },
                "lineHeight": {
                  "description": "Line height, `{unit: \"AUTO\"}` or `{unit: \"PIXELS\" or \"PERCENT\", value}`. Default `{\"unit\":\"AUTO\"}`. Replaced whole by a patch. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "object",
                      "additionalProperties": true,
                      "required": [
                        "unit"
                      ],
                      "properties": {
                        "unit": {
                          "description": "Unit: `AUTO`, or `PIXELS` / `PERCENT` with a `value`.",
                          "type": "string",
                          "enum": [
                            "AUTO",
                            "PIXELS",
                            "PERCENT"
                          ]
                        },
                        "value": {
                          "description": "The line height; absent for `AUTO`.",
                          "type": "number"
                        }
                      },
                      "if": {
                        "type": "object",
                        "properties": {
                          "unit": {
                            "enum": [
                              "PIXELS",
                              "PERCENT"
                            ]
                          }
                        },
                        "required": [
                          "unit"
                        ]
                      },
                      "then": {
                        "type": "object",
                        "properties": {
                          "value": {
                            "description": "Required for `PIXELS` and `PERCENT`.",
                            "type": "number"
                          }
                        },
                        "required": [
                          "value"
                        ]
                      }
                    }
                  ],
                  "x-merge": "replace"
                },
                "textCase": {
                  "description": "Text case. Default `\"ORIGINAL\"`. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "string",
                      "enum": [
                        "ORIGINAL",
                        "UPPER",
                        "LOWER",
                        "TITLE",
                        "SMALL_CAPS",
                        "SMALL_CAPS_FORCED"
                      ]
                    }
                  ]
                },
                "textDecoration": {
                  "description": "Text decoration. Default `\"NONE\"`. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "string",
                      "enum": [
                        "NONE",
                        "UNDERLINE",
                        "STRIKETHROUGH"
                      ]
                    }
                  ]
                },
                "textAlignHorizontal": {
                  "description": "Horizontal alignment (TXT-3). Default `\"LEFT\"`. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "string",
                      "enum": [
                        "LEFT",
                        "CENTER",
                        "RIGHT",
                        "JUSTIFIED"
                      ]
                    }
                  ]
                },
                "textAlignVertical": {
                  "description": "Vertical alignment. Default `\"TOP\"`. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "string",
                      "enum": [
                        "TOP",
                        "CENTER",
                        "BOTTOM"
                      ]
                    }
                  ]
                },
                "textAutoResize": {
                  "description": "Auto-resize mode (TXT-1). With `WIDTH_AND_HEIGHT` or `HEIGHT` the geometry is derived and not stored (4.5). Default `\"WIDTH_AND_HEIGHT\"`. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "string",
                      "enum": [
                        "NONE",
                        "WIDTH_AND_HEIGHT",
                        "HEIGHT",
                        "TRUNCATE"
                      ]
                    }
                  ]
                },
                "textTruncation": {
                  "description": "Ellipsis. Default `\"DISABLED\"`. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "string",
                      "enum": [
                        "DISABLED",
                        "ENDING"
                      ]
                    }
                  ]
                },
                "maxLines": {
                  "description": "Lines before the ellipsis. Absent by default. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "integer",
                      "minimum": 1
                    }
                  ]
                },
                "paragraphSpacing": {
                  "description": "Space after a paragraph. Default `0`. In px. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "number"
                    }
                  ]
                },
                "paragraphIndent": {
                  "description": "Indent of the first line of a paragraph. Default `0`. In px. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "number"
                    }
                  ]
                },
                "listSpacing": {
                  "description": "Space between list items. Default `0`. In px. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "number"
                    }
                  ]
                },
                "hangingPunctuation": {
                  "description": "Hanging punctuation. Default `false`. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "boolean"
                    }
                  ]
                },
                "hangingList": {
                  "description": "Hanging list markers. Default `false`. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "boolean"
                    }
                  ]
                },
                "leadingTrim": {
                  "description": "Leading trim (TXT-3). Default `\"NONE\"`. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "string",
                      "enum": [
                        "NONE",
                        "CAP_HEIGHT"
                      ]
                    }
                  ]
                },
                "openTypeFeatures": {
                  "description": "OpenType features, a map of feature tag to boolean, e.g. `{\"TNUM\": true, \"LIGA\": false, \"SS01\": true}` (TXT-4). Default `{}`. Merges per feature. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
                  "x-merge": "merge",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "object",
                      "additionalProperties": {
                        "description": "On or off. `null` unsets it.",
                        "anyOf": [
                          {
                            "type": "null"
                          },
                          {
                            "type": "boolean"
                          }
                        ]
                      }
                    }
                  ]
                },
                "hyperlink": {
                  "description": "A link, `{type: \"URL\" or \"NODE\", value}`. Absent by default. Replaced whole by a patch. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "object",
                      "additionalProperties": true,
                      "properties": {
                        "type": {
                          "description": "Link to a URL or to a node.",
                          "type": "string",
                          "enum": [
                            "URL",
                            "NODE"
                          ]
                        },
                        "value": {
                          "description": "The URL, or the node id.",
                          "type": "string"
                        }
                      },
                      "required": [
                        "type",
                        "value"
                      ]
                    }
                  ],
                  "x-merge": "replace"
                },
                "textStyleId": {
                  "description": "Text style (4.9). The plain text values stay written next to it as the fallback (4.4.5). Absent by default. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "$ref": "#/$defs/styleRef"
                    }
                  ]
                },
                "styledRuns": {
                  "description": "Ranges whose properties differ from the node-level values (TXT-2), sorted by `start`, not overlapping. Default `[]`. Replaced whole by a patch. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "array",
                      "items": {
                        "description": "One run.",
                        "$ref": "#/$defs/styledRun"
                      }
                    }
                  ]
                }
              }
            }
          ]
        },
        "authorVisible": {
          "description": "Show the author. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "boolean"
            }
          ]
        },
        "authorName": {
          "description": "Name of the author. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        },
        "id": {
          "description": "The id cannot be changed.",
          "not": {}
        },
        "type": {
          "description": "Cannot be set by a patch; ignored with a warning (`type` changes only through `component.create` and `instance.detach`).",
          "not": {}
        },
        "parent": {
          "description": "Cannot be set by a patch; ignored with a warning. Use `node.move`.",
          "not": {}
        },
        "index": {
          "description": "Cannot be set by a patch; ignored with a warning. Use `node.move` or `node.reorder`.",
          "not": {}
        }
      }
    },
    "document": {
      "description": "Document metadata (4.2).",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "id": {
          "description": "Identity of the document. Required. Never changes.",
          "$ref": "#/$defs/documentId"
        },
        "name": {
          "description": "Display name. Default the file name without `.design`.",
          "type": "string"
        },
        "createdAt": {
          "description": "When the document was created.",
          "$ref": "#/$defs/timestamp"
        },
        "updatedAt": {
          "description": "The latest `at` folded into the tree. Derived on read; written by consolidation.",
          "$ref": "#/$defs/timestamp"
        },
        "colorProfile": {
          "description": "Colour profile of the document (STY-4); colour values are in this space. Default `\"SRGB\"`.",
          "type": "string",
          "enum": [
            "SRGB",
            "DISPLAY_P3"
          ]
        },
        "library": {
          "description": "Present when the file publishes a library (VAR-7). Absent by default. Merges per member (assumed by this draft).",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "name": {
              "description": "Name of the published library.",
              "type": "string"
            },
            "description": {
              "description": "Description of the published library.",
              "type": "string"
            }
          },
          "x-merge": "merge"
        },
        "annotationCategories": {
          "description": "Categories of annotations (DEV-7): a map of category id to `{label, color, index}`. Default the three built-in categories `behaviour`, `accessibility`, `interaction`. Merges per category (assumed by this draft).",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/annotationCategoryId"
          },
          "additionalProperties": {
            "description": "An annotation category. Merges per member (assumed by this draft).",
            "type": "object",
            "additionalProperties": true,
            "properties": {
              "label": {
                "description": "Label of the category.",
                "type": "string"
              },
              "color": {
                "description": "Colour of the category (FMT-001 does not give its shape; Figma uses a colour name).",
                "type": "string"
              },
              "index": {
                "description": "Order among the categories.",
                "$ref": "#/$defs/fractionalIndex"
              }
            },
            "x-merge": "merge"
          },
          "x-merge": "merge"
        },
        "codeSyntaxPlatforms": {
          "description": "Platforms offered in variable code syntax (VAR-5). Default `[\"WEB\",\"ANDROID\",\"iOS\"]`.",
          "type": "array",
          "items": {
            "description": "A platform name.",
            "type": "string"
          }
        },
        "pluginData": {
          "description": "Private data of plugins and scripts (4.4.10): a map of plugin id to a map of key to string. `setPluginData(key, value)` in the Plugin API writes `pluginData[<plugin id>][key]`. Scripts run by `use_figma` have the plugin id `ud`. Merges per key, so two branches that write different keys both survive.",
          "type": "object",
          "additionalProperties": {
            "description": "The keys and values written by one plugin or script.",
            "type": "object",
            "additionalProperties": {
              "description": "A value. Values are strings, as in Figma; setting a value to `\"\"` removes the key (in a merge patch the key is set to `null`).",
              "type": "string"
            },
            "x-merge": "merge"
          },
          "x-merge": "merge"
        },
        "sharedPluginData": {
          "description": "Data shared between plugins (4.4.10): a map of namespace to a map of key to string, written by `setSharedPluginData(namespace, key, value)`. Merges per key.",
          "type": "object",
          "additionalProperties": {
            "description": "The keys and values of one namespace.",
            "type": "object",
            "additionalProperties": {
              "description": "A value, a string as in Figma. `\"\"` removes the key.",
              "type": "string"
            },
            "x-merge": "merge"
          },
          "x-merge": "merge"
        }
      },
      "required": [
        "id"
      ]
    },
    "documentPatch": {
      "description": "A merge patch of `document` (5.9), the `set` of `document.update`.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "name": {
          "description": "Display name. Default the file name without `.design`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        },
        "createdAt": {
          "description": "When the document was created. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/timestamp"
            }
          ]
        },
        "updatedAt": {
          "description": "The latest `at` folded into the tree. Derived on read; written by consolidation. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/timestamp"
            }
          ]
        },
        "colorProfile": {
          "description": "Colour profile of the document (STY-4); colour values are in this space. Default `\"SRGB\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "SRGB",
                "DISPLAY_P3"
              ]
            }
          ]
        },
        "library": {
          "description": "Present when the file publishes a library (VAR-7). Absent by default. Merges per member (assumed by this draft). In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "name": {
                  "description": "Name of the published library. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "string"
                    }
                  ]
                },
                "description": {
                  "description": "Description of the published library. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "string"
                    }
                  ]
                }
              }
            }
          ]
        },
        "annotationCategories": {
          "description": "Categories of annotations (DEV-7): a map of category id to `{label, color, index}`. Default the three built-in categories `behaviour`, `accessibility`, `interaction`. Merges per category (assumed by this draft). In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "propertyNames": {
                "$ref": "#/$defs/annotationCategoryId"
              },
              "additionalProperties": {
                "description": "An annotation category. Merges per member (assumed by this draft). In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
                "x-merge": "merge",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "object",
                    "additionalProperties": true,
                    "properties": {
                      "label": {
                        "description": "Label of the category. `null` unsets it.",
                        "anyOf": [
                          {
                            "type": "null"
                          },
                          {
                            "type": "string"
                          }
                        ]
                      },
                      "color": {
                        "description": "Colour of the category (FMT-001 does not give its shape; Figma uses a colour name). `null` unsets it.",
                        "anyOf": [
                          {
                            "type": "null"
                          },
                          {
                            "type": "string"
                          }
                        ]
                      },
                      "index": {
                        "description": "Order among the categories. `null` unsets it.",
                        "anyOf": [
                          {
                            "type": "null"
                          },
                          {
                            "$ref": "#/$defs/fractionalIndex"
                          }
                        ]
                      }
                    }
                  }
                ]
              }
            }
          ]
        },
        "codeSyntaxPlatforms": {
          "description": "Platforms offered in variable code syntax (VAR-5). Default `[\"WEB\",\"ANDROID\",\"iOS\"]`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "A platform name.",
                "type": "string"
              }
            }
          ]
        },
        "pluginData": {
          "description": "Private data of plugins and scripts (4.4.10): a map of plugin id to a map of key to string. `setPluginData(key, value)` in the Plugin API writes `pluginData[<plugin id>][key]`. Scripts run by `use_figma` have the plugin id `ud`. Merges per key, so two branches that write different keys both survive. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "The keys and values written by one plugin or script. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
                "x-merge": "merge",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "object",
                    "additionalProperties": {
                      "description": "A value. Values are strings, as in Figma; setting a value to `\"\"` removes the key (in a merge patch the key is set to `null`). `null` unsets it.",
                      "anyOf": [
                        {
                          "type": "null"
                        },
                        {
                          "type": "string"
                        }
                      ]
                    }
                  }
                ]
              }
            }
          ]
        },
        "sharedPluginData": {
          "description": "Data shared between plugins (4.4.10): a map of namespace to a map of key to string, written by `setSharedPluginData(namespace, key, value)`. Merges per key. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "The keys and values of one namespace. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
                "x-merge": "merge",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "object",
                    "additionalProperties": {
                      "description": "A value, a string as in Figma. `\"\"` removes the key. `null` unsets it.",
                      "anyOf": [
                        {
                          "type": "null"
                        },
                        {
                          "type": "string"
                        }
                      ]
                    }
                  }
                ]
              }
            }
          ]
        },
        "id": {
          "description": "The document id never changes.",
          "not": {}
        }
      }
    },
    "page": {
      "description": "A page (4.2) in `tree.pages`, keyed by its id. Pages are not nodes; the top-level nodes of a page have the page id as `parent`. A document has at least one page.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "id": {
          "description": "Same as the key of `tree.pages`.",
          "$ref": "#/$defs/pageId"
        },
        "type": {
          "description": "Always `\"PAGE\"`; present for symmetry with nodes.",
          "const": "PAGE"
        },
        "name": {
          "description": "Page name. Default `\"Page\"`.",
          "type": "string"
        },
        "index": {
          "description": "Order among pages (4.3). Required.",
          "$ref": "#/$defs/fractionalIndex"
        },
        "backgrounds": {
          "description": "Canvas background (DOC-1), Figma's name and shape. Default `[{\"type\":\"SOLID\",\"color\":{\"r\":0.96,\"g\":0.96,\"b\":0.96}}]`.",
          "type": "array",
          "items": {
            "description": "A paint.",
            "$ref": "#/$defs/paint"
          }
        },
        "explicitVariableModes": {
          "description": "Modes chosen for the whole page (VAR-6): a map of variable collection id to mode id. Default `{}`. Merges per collection.",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/variableCollectionRef"
          },
          "additionalProperties": {
            "description": "The mode chosen for that collection.",
            "$ref": "#/$defs/modeRef"
          },
          "x-merge": "merge"
        },
        "prototypeBackgrounds": {
          "description": "Background behind frames in the preview player. Default `[]`.",
          "type": "array",
          "items": {
            "description": "A paint.",
            "$ref": "#/$defs/paint"
          }
        },
        "guides": {
          "description": "Ruler guides on the canvas. Default `[]`.",
          "type": "array",
          "items": {
            "description": "A ruler guide.",
            "type": "object",
            "additionalProperties": true,
            "properties": {
              "axis": {
                "description": "The axis.",
                "type": "string",
                "enum": [
                  "X",
                  "Y"
                ]
              },
              "offset": {
                "description": "Offset on the axis, px.",
                "type": "number"
              }
            },
            "required": [
              "axis",
              "offset"
            ]
          }
        },
        "pluginData": {
          "description": "Private data of plugins and scripts (4.4.10): a map of plugin id to a map of key to string. `setPluginData(key, value)` in the Plugin API writes `pluginData[<plugin id>][key]`. Scripts run by `use_figma` have the plugin id `ud`. Merges per key, so two branches that write different keys both survive.",
          "type": "object",
          "additionalProperties": {
            "description": "The keys and values written by one plugin or script.",
            "type": "object",
            "additionalProperties": {
              "description": "A value. Values are strings, as in Figma; setting a value to `\"\"` removes the key (in a merge patch the key is set to `null`).",
              "type": "string"
            },
            "x-merge": "merge"
          },
          "x-merge": "merge"
        },
        "sharedPluginData": {
          "description": "Data shared between plugins (4.4.10): a map of namespace to a map of key to string, written by `setSharedPluginData(namespace, key, value)`. Merges per key.",
          "type": "object",
          "additionalProperties": {
            "description": "The keys and values of one namespace.",
            "type": "object",
            "additionalProperties": {
              "description": "A value, a string as in Figma. `\"\"` removes the key.",
              "type": "string"
            },
            "x-merge": "merge"
          },
          "x-merge": "merge"
        }
      },
      "required": [
        "index"
      ]
    },
    "pagePatch": {
      "description": "A merge patch of a page (5.9), the `set` of `page.update`.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "type": {
          "description": "Always `\"PAGE\"`; present for symmetry with nodes. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "const": "PAGE"
            }
          ]
        },
        "name": {
          "description": "Page name. Default `\"Page\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        },
        "index": {
          "description": "Order among pages (4.3). Required. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/fractionalIndex"
            }
          ]
        },
        "backgrounds": {
          "description": "Canvas background (DOC-1), Figma's name and shape. Default `[{\"type\":\"SOLID\",\"color\":{\"r\":0.96,\"g\":0.96,\"b\":0.96}}]`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "A paint.",
                "$ref": "#/$defs/paint"
              }
            }
          ]
        },
        "explicitVariableModes": {
          "description": "Modes chosen for the whole page (VAR-6): a map of variable collection id to mode id. Default `{}`. Merges per collection. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "propertyNames": {
                "$ref": "#/$defs/variableCollectionRef"
              },
              "additionalProperties": {
                "description": "The mode chosen for that collection. `null` unsets it.",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/$defs/modeRef"
                  }
                ]
              }
            }
          ]
        },
        "prototypeBackgrounds": {
          "description": "Background behind frames in the preview player. Default `[]`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "A paint.",
                "$ref": "#/$defs/paint"
              }
            }
          ]
        },
        "guides": {
          "description": "Ruler guides on the canvas. Default `[]`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "A ruler guide.",
                "type": "object",
                "additionalProperties": true,
                "properties": {
                  "axis": {
                    "description": "The axis.",
                    "type": "string",
                    "enum": [
                      "X",
                      "Y"
                    ]
                  },
                  "offset": {
                    "description": "Offset on the axis, px.",
                    "type": "number"
                  }
                },
                "required": [
                  "axis",
                  "offset"
                ]
              }
            }
          ]
        },
        "pluginData": {
          "description": "Private data of plugins and scripts (4.4.10): a map of plugin id to a map of key to string. `setPluginData(key, value)` in the Plugin API writes `pluginData[<plugin id>][key]`. Scripts run by `use_figma` have the plugin id `ud`. Merges per key, so two branches that write different keys both survive. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "The keys and values written by one plugin or script. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
                "x-merge": "merge",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "object",
                    "additionalProperties": {
                      "description": "A value. Values are strings, as in Figma; setting a value to `\"\"` removes the key (in a merge patch the key is set to `null`). `null` unsets it.",
                      "anyOf": [
                        {
                          "type": "null"
                        },
                        {
                          "type": "string"
                        }
                      ]
                    }
                  }
                ]
              }
            }
          ]
        },
        "sharedPluginData": {
          "description": "Data shared between plugins (4.4.10): a map of namespace to a map of key to string, written by `setSharedPluginData(namespace, key, value)`. Merges per key. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "The keys and values of one namespace. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
                "x-merge": "merge",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "object",
                    "additionalProperties": {
                      "description": "A value, a string as in Figma. `\"\"` removes the key. `null` unsets it.",
                      "anyOf": [
                        {
                          "type": "null"
                        },
                        {
                          "type": "string"
                        }
                      ]
                    }
                  }
                ]
              }
            }
          ]
        },
        "id": {
          "description": "The id cannot be changed.",
          "not": {}
        }
      }
    },
    "style": {
      "description": "A style (4.9, VAR-1) in `tree.styles`, keyed by `st-` id. Text styles carry the text properties of 4.6.6 (`fontName`, `fontSize`, `fontVariations`, `letterSpacing`, `lineHeight`, `paragraphSpacing`, `paragraphIndent`, `textCase`, `textDecoration`, `leadingTrim`, `openTypeFeatures`). Nodes refer to it and keep the plain values as the fallback.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "type": {
          "description": "Figma's `StyleType`. Required; `style.update` cannot change it.",
          "type": "string",
          "enum": [
            "PAINT",
            "TEXT",
            "EFFECT",
            "GRID"
          ]
        },
        "name": {
          "description": "Name; groups by `/`: `Brand/Primary`. Required.",
          "type": "string"
        },
        "index": {
          "description": "Order among styles of the same type. Required.",
          "$ref": "#/$defs/fractionalIndex"
        },
        "description": {
          "description": "Description. Default `\"\"`.",
          "type": "string"
        },
        "paints": {
          "description": "`PAINT` styles: the paints. Default `[]`.",
          "type": "array",
          "items": {
            "description": "A paint.",
            "$ref": "#/$defs/paint"
          }
        },
        "fontName": {
          "description": "Font family and style. Default `{\"family\":\"Inter\",\"style\":\"Regular\"}`. Replaced whole by a patch.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "family": {
              "description": "Font family, e.g. `\"Inter\"`.",
              "type": "string"
            },
            "style": {
              "description": "Figma's style name, e.g. `\"Semi Bold\"` (CMD-15).",
              "type": "string"
            }
          },
          "required": [
            "family",
            "style"
          ],
          "x-merge": "replace"
        },
        "fontSize": {
          "description": "Font size. Default `12`. In px.",
          "type": "number",
          "minimum": 0
        },
        "fontVariations": {
          "description": "Variable font axes, a map of axis tag to number, e.g. `{\"wght\": 550, \"opsz\": 14}` (TXT-4). Our own. Default `{}`. Merges per axis.",
          "type": "object",
          "additionalProperties": {
            "description": "Axis value.",
            "type": "number"
          },
          "x-merge": "merge"
        },
        "letterSpacing": {
          "description": "Letter spacing, `{unit: \"PIXELS\" or \"PERCENT\", value}`. Default `{\"unit\":\"PERCENT\",\"value\":0}`. Replaced whole by a patch.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "unit": {
              "description": "Unit of `value`.",
              "type": "string",
              "enum": [
                "PIXELS",
                "PERCENT"
              ]
            },
            "value": {
              "description": "The spacing.",
              "type": "number"
            }
          },
          "required": [
            "unit",
            "value"
          ],
          "x-merge": "replace"
        },
        "lineHeight": {
          "description": "Line height, `{unit: \"AUTO\"}` or `{unit: \"PIXELS\" or \"PERCENT\", value}`. Default `{\"unit\":\"AUTO\"}`. Replaced whole by a patch.",
          "type": "object",
          "additionalProperties": true,
          "required": [
            "unit"
          ],
          "properties": {
            "unit": {
              "description": "Unit: `AUTO`, or `PIXELS` / `PERCENT` with a `value`.",
              "type": "string",
              "enum": [
                "AUTO",
                "PIXELS",
                "PERCENT"
              ]
            },
            "value": {
              "description": "The line height; absent for `AUTO`.",
              "type": "number"
            }
          },
          "if": {
            "type": "object",
            "properties": {
              "unit": {
                "enum": [
                  "PIXELS",
                  "PERCENT"
                ]
              }
            },
            "required": [
              "unit"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "value": {
                "description": "Required for `PIXELS` and `PERCENT`.",
                "type": "number"
              }
            },
            "required": [
              "value"
            ]
          },
          "x-merge": "replace"
        },
        "textCase": {
          "description": "Text case. Default `\"ORIGINAL\"`.",
          "type": "string",
          "enum": [
            "ORIGINAL",
            "UPPER",
            "LOWER",
            "TITLE",
            "SMALL_CAPS",
            "SMALL_CAPS_FORCED"
          ]
        },
        "textDecoration": {
          "description": "Text decoration. Default `\"NONE\"`.",
          "type": "string",
          "enum": [
            "NONE",
            "UNDERLINE",
            "STRIKETHROUGH"
          ]
        },
        "paragraphSpacing": {
          "description": "Space after a paragraph. Default `0`. In px.",
          "type": "number"
        },
        "paragraphIndent": {
          "description": "Indent of the first line of a paragraph. Default `0`. In px.",
          "type": "number"
        },
        "leadingTrim": {
          "description": "Leading trim (TXT-3). Default `\"NONE\"`.",
          "type": "string",
          "enum": [
            "NONE",
            "CAP_HEIGHT"
          ]
        },
        "openTypeFeatures": {
          "description": "OpenType features, a map of feature tag to boolean, e.g. `{\"TNUM\": true, \"LIGA\": false, \"SS01\": true}` (TXT-4). Default `{}`. Merges per feature.",
          "type": "object",
          "additionalProperties": {
            "description": "On or off.",
            "type": "boolean"
          },
          "x-merge": "merge"
        },
        "effects": {
          "description": "`EFFECT` styles: the effects. Default `[]`.",
          "type": "array",
          "items": {
            "description": "An effect.",
            "$ref": "#/$defs/effect"
          }
        },
        "layoutGrids": {
          "description": "`GRID` styles: the layout grids. Default `[]`.",
          "type": "array",
          "items": {
            "description": "A layout grid.",
            "$ref": "#/$defs/layoutGrid"
          }
        },
        "boundVariables": {
          "description": "Bindings of the style's values to variables (VAR-4), Figma's shape: a map of property name to `{\"type\":\"VARIABLE_ALIAS\",\"id\":\"vr-…\"}`. The plain value stays written next to the binding and is the fallback when the variable is missing (4.4.5). Default `{}`. Merges per property.",
          "type": "object",
          "additionalProperties": {
            "description": "The variable the property is bound to.",
            "$ref": "#/$defs/variableAlias",
            "x-merge": "replace"
          },
          "x-merge": "merge"
        },
        "hiddenFromPublishing": {
          "description": "Not offered by the library. Default `false`.",
          "type": "boolean"
        },
        "pluginData": {
          "description": "Private data of plugins and scripts (4.4.10): a map of plugin id to a map of key to string. `setPluginData(key, value)` in the Plugin API writes `pluginData[<plugin id>][key]`. Scripts run by `use_figma` have the plugin id `ud`. Merges per key, so two branches that write different keys both survive.",
          "type": "object",
          "additionalProperties": {
            "description": "The keys and values written by one plugin or script.",
            "type": "object",
            "additionalProperties": {
              "description": "A value. Values are strings, as in Figma; setting a value to `\"\"` removes the key (in a merge patch the key is set to `null`).",
              "type": "string"
            },
            "x-merge": "merge"
          },
          "x-merge": "merge"
        },
        "sharedPluginData": {
          "description": "Data shared between plugins (4.4.10): a map of namespace to a map of key to string, written by `setSharedPluginData(namespace, key, value)`. Merges per key.",
          "type": "object",
          "additionalProperties": {
            "description": "The keys and values of one namespace.",
            "type": "object",
            "additionalProperties": {
              "description": "A value, a string as in Figma. `\"\"` removes the key.",
              "type": "string"
            },
            "x-merge": "merge"
          },
          "x-merge": "merge"
        }
      },
      "required": [
        "type",
        "name",
        "index"
      ]
    },
    "stylePatch": {
      "description": "A merge patch of a style (5.9), the `set` of `style.update`. `index` may be set to reorder; a `type` different from the style's makes the event skipped.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "type": {
          "description": "Figma's `StyleType`. Required; `style.update` cannot change it. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "PAINT",
                "TEXT",
                "EFFECT",
                "GRID"
              ]
            }
          ]
        },
        "name": {
          "description": "Name; groups by `/`: `Brand/Primary`. Required. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        },
        "index": {
          "description": "Order among styles of the same type. Required. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/fractionalIndex"
            }
          ]
        },
        "description": {
          "description": "Description. Default `\"\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        },
        "paints": {
          "description": "`PAINT` styles: the paints. Default `[]`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "A paint.",
                "$ref": "#/$defs/paint"
              }
            }
          ]
        },
        "fontName": {
          "description": "Font family and style. Default `{\"family\":\"Inter\",\"style\":\"Regular\"}`. Replaced whole by a patch. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "family": {
                  "description": "Font family, e.g. `\"Inter\"`.",
                  "type": "string"
                },
                "style": {
                  "description": "Figma's style name, e.g. `\"Semi Bold\"` (CMD-15).",
                  "type": "string"
                }
              },
              "required": [
                "family",
                "style"
              ]
            }
          ],
          "x-merge": "replace"
        },
        "fontSize": {
          "description": "Font size. Default `12`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number",
              "minimum": 0
            }
          ]
        },
        "fontVariations": {
          "description": "Variable font axes, a map of axis tag to number, e.g. `{\"wght\": 550, \"opsz\": 14}` (TXT-4). Our own. Default `{}`. Merges per axis. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "Axis value. `null` unsets it.",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "number"
                  }
                ]
              }
            }
          ]
        },
        "letterSpacing": {
          "description": "Letter spacing, `{unit: \"PIXELS\" or \"PERCENT\", value}`. Default `{\"unit\":\"PERCENT\",\"value\":0}`. Replaced whole by a patch. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "unit": {
                  "description": "Unit of `value`.",
                  "type": "string",
                  "enum": [
                    "PIXELS",
                    "PERCENT"
                  ]
                },
                "value": {
                  "description": "The spacing.",
                  "type": "number"
                }
              },
              "required": [
                "unit",
                "value"
              ]
            }
          ],
          "x-merge": "replace"
        },
        "lineHeight": {
          "description": "Line height, `{unit: \"AUTO\"}` or `{unit: \"PIXELS\" or \"PERCENT\", value}`. Default `{\"unit\":\"AUTO\"}`. Replaced whole by a patch. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "required": [
                "unit"
              ],
              "properties": {
                "unit": {
                  "description": "Unit: `AUTO`, or `PIXELS` / `PERCENT` with a `value`.",
                  "type": "string",
                  "enum": [
                    "AUTO",
                    "PIXELS",
                    "PERCENT"
                  ]
                },
                "value": {
                  "description": "The line height; absent for `AUTO`.",
                  "type": "number"
                }
              },
              "if": {
                "type": "object",
                "properties": {
                  "unit": {
                    "enum": [
                      "PIXELS",
                      "PERCENT"
                    ]
                  }
                },
                "required": [
                  "unit"
                ]
              },
              "then": {
                "type": "object",
                "properties": {
                  "value": {
                    "description": "Required for `PIXELS` and `PERCENT`.",
                    "type": "number"
                  }
                },
                "required": [
                  "value"
                ]
              }
            }
          ],
          "x-merge": "replace"
        },
        "textCase": {
          "description": "Text case. Default `\"ORIGINAL\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "ORIGINAL",
                "UPPER",
                "LOWER",
                "TITLE",
                "SMALL_CAPS",
                "SMALL_CAPS_FORCED"
              ]
            }
          ]
        },
        "textDecoration": {
          "description": "Text decoration. Default `\"NONE\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "NONE",
                "UNDERLINE",
                "STRIKETHROUGH"
              ]
            }
          ]
        },
        "paragraphSpacing": {
          "description": "Space after a paragraph. Default `0`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number"
            }
          ]
        },
        "paragraphIndent": {
          "description": "Indent of the first line of a paragraph. Default `0`. In px. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number"
            }
          ]
        },
        "leadingTrim": {
          "description": "Leading trim (TXT-3). Default `\"NONE\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "NONE",
                "CAP_HEIGHT"
              ]
            }
          ]
        },
        "openTypeFeatures": {
          "description": "OpenType features, a map of feature tag to boolean, e.g. `{\"TNUM\": true, \"LIGA\": false, \"SS01\": true}` (TXT-4). Default `{}`. Merges per feature. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "On or off. `null` unsets it.",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "boolean"
                  }
                ]
              }
            }
          ]
        },
        "effects": {
          "description": "`EFFECT` styles: the effects. Default `[]`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "An effect.",
                "$ref": "#/$defs/effect"
              }
            }
          ]
        },
        "layoutGrids": {
          "description": "`GRID` styles: the layout grids. Default `[]`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "A layout grid.",
                "$ref": "#/$defs/layoutGrid"
              }
            }
          ]
        },
        "boundVariables": {
          "description": "Bindings of the style's values to variables (VAR-4), Figma's shape: a map of property name to `{\"type\":\"VARIABLE_ALIAS\",\"id\":\"vr-…\"}`. The plain value stays written next to the binding and is the fallback when the variable is missing (4.4.5). Default `{}`. Merges per property. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "The variable the property is bound to. `null` unsets it.",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/$defs/variableAlias"
                  }
                ],
                "x-merge": "replace"
              }
            }
          ]
        },
        "hiddenFromPublishing": {
          "description": "Not offered by the library. Default `false`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "boolean"
            }
          ]
        },
        "pluginData": {
          "description": "Private data of plugins and scripts (4.4.10): a map of plugin id to a map of key to string. `setPluginData(key, value)` in the Plugin API writes `pluginData[<plugin id>][key]`. Scripts run by `use_figma` have the plugin id `ud`. Merges per key, so two branches that write different keys both survive. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "The keys and values written by one plugin or script. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
                "x-merge": "merge",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "object",
                    "additionalProperties": {
                      "description": "A value. Values are strings, as in Figma; setting a value to `\"\"` removes the key (in a merge patch the key is set to `null`). `null` unsets it.",
                      "anyOf": [
                        {
                          "type": "null"
                        },
                        {
                          "type": "string"
                        }
                      ]
                    }
                  }
                ]
              }
            }
          ]
        },
        "sharedPluginData": {
          "description": "Data shared between plugins (4.4.10): a map of namespace to a map of key to string, written by `setSharedPluginData(namespace, key, value)`. Merges per key. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "The keys and values of one namespace. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
                "x-merge": "merge",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "object",
                    "additionalProperties": {
                      "description": "A value, a string as in Figma. `\"\"` removes the key. `null` unsets it.",
                      "anyOf": [
                        {
                          "type": "null"
                        },
                        {
                          "type": "string"
                        }
                      ]
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    },
    "variableCollection": {
      "description": "A variable collection (4.10, VAR-2) in `tree.variableCollections`, keyed by `vc-` id.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "name": {
          "description": "Collection name. Required.",
          "type": "string"
        },
        "index": {
          "description": "Order among collections. Required.",
          "$ref": "#/$defs/fractionalIndex"
        },
        "modes": {
          "description": "Modes, a map of `md-` id to `{name, index}`, ordered by `index`; at least one. Figma's `modes` array is derived from it. Changed through `mode.*` events.",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/modeId"
          },
          "additionalProperties": {
            "description": "A mode `{name, index}`. Merges per member.",
            "type": "object",
            "additionalProperties": true,
            "properties": {
              "name": {
                "description": "Mode name.",
                "type": "string"
              },
              "index": {
                "description": "Order among the collection's modes.",
                "$ref": "#/$defs/fractionalIndex"
              }
            },
            "required": [
              "name",
              "index"
            ],
            "x-merge": "merge"
          },
          "x-merge": "merge",
          "minProperties": 1
        },
        "defaultModeId": {
          "description": "The mode used when nothing chooses one. Default the mode with the lowest `index`.",
          "$ref": "#/$defs/modeId"
        },
        "hiddenFromPublishing": {
          "description": "Not offered by the library. Default `false`.",
          "type": "boolean"
        },
        "pluginData": {
          "description": "Private data of plugins and scripts (4.4.10): a map of plugin id to a map of key to string. `setPluginData(key, value)` in the Plugin API writes `pluginData[<plugin id>][key]`. Scripts run by `use_figma` have the plugin id `ud`. Merges per key, so two branches that write different keys both survive.",
          "type": "object",
          "additionalProperties": {
            "description": "The keys and values written by one plugin or script.",
            "type": "object",
            "additionalProperties": {
              "description": "A value. Values are strings, as in Figma; setting a value to `\"\"` removes the key (in a merge patch the key is set to `null`).",
              "type": "string"
            },
            "x-merge": "merge"
          },
          "x-merge": "merge"
        },
        "sharedPluginData": {
          "description": "Data shared between plugins (4.4.10): a map of namespace to a map of key to string, written by `setSharedPluginData(namespace, key, value)`. Merges per key.",
          "type": "object",
          "additionalProperties": {
            "description": "The keys and values of one namespace.",
            "type": "object",
            "additionalProperties": {
              "description": "A value, a string as in Figma. `\"\"` removes the key.",
              "type": "string"
            },
            "x-merge": "merge"
          },
          "x-merge": "merge"
        }
      },
      "required": [
        "name",
        "index",
        "modes"
      ]
    },
    "variableCollectionPatch": {
      "description": "A merge patch of a collection (5.9), the `set` of `collection.update`. Modes change through `mode.*` events.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "name": {
          "description": "Collection name. Required. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        },
        "index": {
          "description": "Order among collections. Required. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/fractionalIndex"
            }
          ]
        },
        "defaultModeId": {
          "description": "The mode used when nothing chooses one. Default the mode with the lowest `index`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/modeId"
            }
          ]
        },
        "hiddenFromPublishing": {
          "description": "Not offered by the library. Default `false`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "boolean"
            }
          ]
        },
        "pluginData": {
          "description": "Private data of plugins and scripts (4.4.10): a map of plugin id to a map of key to string. `setPluginData(key, value)` in the Plugin API writes `pluginData[<plugin id>][key]`. Scripts run by `use_figma` have the plugin id `ud`. Merges per key, so two branches that write different keys both survive. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "The keys and values written by one plugin or script. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
                "x-merge": "merge",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "object",
                    "additionalProperties": {
                      "description": "A value. Values are strings, as in Figma; setting a value to `\"\"` removes the key (in a merge patch the key is set to `null`). `null` unsets it.",
                      "anyOf": [
                        {
                          "type": "null"
                        },
                        {
                          "type": "string"
                        }
                      ]
                    }
                  }
                ]
              }
            }
          ]
        },
        "sharedPluginData": {
          "description": "Data shared between plugins (4.4.10): a map of namespace to a map of key to string, written by `setSharedPluginData(namespace, key, value)`. Merges per key. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "The keys and values of one namespace. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
                "x-merge": "merge",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "object",
                    "additionalProperties": {
                      "description": "A value, a string as in Figma. `\"\"` removes the key. `null` unsets it.",
                      "anyOf": [
                        {
                          "type": "null"
                        },
                        {
                          "type": "string"
                        }
                      ]
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    },
    "modePatch": {
      "description": "A merge patch of a mode, the `set` of `mode.update`: renames or reorders it.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "name": {
          "description": "Mode name. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        },
        "index": {
          "description": "Order among the collection's modes. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/fractionalIndex"
            }
          ]
        }
      }
    },
    "variableExpression": {
      "description": "A computed value of a `FLOAT` or `STRING` variable, `{\"type\": \"EXPRESSION\", \"expression\": \"spacing/base * 2\"}` (4.12 extension, VAR-10). References resolve in the same modes as the variable; one that does not evaluate resolves to the type's zero with a warning. Replaced whole.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "type": {
          "description": "Always `EXPRESSION`.",
          "const": "EXPRESSION"
        },
        "expression": {
          "description": "The expression (VAR-10): numbers, `\"strings\"`, `+ - * /`, parentheses, `min`, `max`, `round(x[, decimals])`, `floor`, `ceil`, `abs`, and FLOAT or STRING variables by name or `collection/name` (`{…}` around names with spaces). `+` joins strings.",
          "type": "string",
          "minLength": 1
        }
      },
      "required": [
        "type",
        "expression"
      ]
    },
    "variable": {
      "description": "A variable (4.10) in `tree.variables`, keyed by `vr-` id. Its value for a node is resolved from the nearest `explicitVariableModes`, else the collection's `defaultModeId`; an alias is resolved again; a chain longer than 32 or a cycle resolves to the type's zero.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "name": {
          "description": "Name; groups by `/`: `color/bg/surface`. Unique within the collection. Required.",
          "type": "string"
        },
        "variableCollectionId": {
          "description": "Its collection. Required.",
          "$ref": "#/$defs/variableCollectionId"
        },
        "index": {
          "description": "Order within the collection; Figma's `variableIds` is derived from it. Required.",
          "$ref": "#/$defs/fractionalIndex"
        },
        "resolvedType": {
          "description": "Type of the values. Required; `variable.update` cannot change it.",
          "type": "string",
          "enum": [
            "COLOR",
            "FLOAT",
            "STRING",
            "BOOLEAN"
          ]
        },
        "valuesByMode": {
          "description": "Values, a map of mode id to value or alias. Default `{}`. Merges per mode, so two branches that set two modes both survive.",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/modeRef"
          },
          "additionalProperties": {
            "description": "A value of the variable's type (a colour is `{r,g,b,a}`), an alias `{\"type\": \"VARIABLE_ALIAS\", \"id\": \"vr-…\"}` (VAR-3), or for FLOAT and STRING an expression `{\"type\": \"EXPRESSION\", \"expression\": \"…\"}` (VAR-10). Replaced whole.",
            "anyOf": [
              {
                "$ref": "#/$defs/variableAlias"
              },
              {
                "$ref": "#/$defs/variableExpression"
              },
              {
                "$ref": "#/$defs/color"
              },
              {
                "type": "number"
              },
              {
                "type": "string"
              },
              {
                "type": "boolean"
              }
            ],
            "x-merge": "replace"
          },
          "x-merge": "merge"
        },
        "description": {
          "description": "Description. Default `\"\"`.",
          "type": "string"
        },
        "scopes": {
          "description": "Where the variable is offered (VAR-5). Default `[\"ALL_SCOPES\"]`.",
          "type": "array",
          "items": {
            "description": "A Figma `VariableScope`, e.g. `ALL_SCOPES`, `ALL_FILLS`, `FRAME_FILL`, `TEXT_FILL`, `STROKE_COLOR`, `GAP`, `CORNER_RADIUS`, `WIDTH_HEIGHT`, `FONT_SIZE`.",
            "type": "string",
            "pattern": "^[A-Z][A-Z_]*$"
          }
        },
        "codeSyntax": {
          "description": "Code syntax per platform, `{\"WEB\": \"var(--color-bg)\", \"ANDROID\": \"colorBg\", \"iOS\": \"Color.bg\"}` (VAR-5). Default `{}`. Merges per platform.",
          "type": "object",
          "additionalProperties": {
            "description": "The code for that platform.",
            "type": "string"
          },
          "x-merge": "merge"
        },
        "hiddenFromPublishing": {
          "description": "Not offered by the library. Default `false`.",
          "type": "boolean"
        },
        "pluginData": {
          "description": "Private data of plugins and scripts (4.4.10): a map of plugin id to a map of key to string. `setPluginData(key, value)` in the Plugin API writes `pluginData[<plugin id>][key]`. Scripts run by `use_figma` have the plugin id `ud`. Merges per key, so two branches that write different keys both survive.",
          "type": "object",
          "additionalProperties": {
            "description": "The keys and values written by one plugin or script.",
            "type": "object",
            "additionalProperties": {
              "description": "A value. Values are strings, as in Figma; setting a value to `\"\"` removes the key (in a merge patch the key is set to `null`).",
              "type": "string"
            },
            "x-merge": "merge"
          },
          "x-merge": "merge"
        },
        "sharedPluginData": {
          "description": "Data shared between plugins (4.4.10): a map of namespace to a map of key to string, written by `setSharedPluginData(namespace, key, value)`. Merges per key.",
          "type": "object",
          "additionalProperties": {
            "description": "The keys and values of one namespace.",
            "type": "object",
            "additionalProperties": {
              "description": "A value, a string as in Figma. `\"\"` removes the key.",
              "type": "string"
            },
            "x-merge": "merge"
          },
          "x-merge": "merge"
        }
      },
      "required": [
        "name",
        "variableCollectionId",
        "index",
        "resolvedType"
      ],
      "allOf": [
        {
          "if": {
            "type": "object",
            "properties": {
              "resolvedType": {
                "const": "COLOR"
              }
            },
            "required": [
              "resolvedType"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "valuesByMode": {
                "description": "Values of a `COLOR` variable: values of that type, or aliases.",
                "type": "object",
                "additionalProperties": {
                  "anyOf": [
                    {
                      "$ref": "#/$defs/variableAlias"
                    },
                    {
                      "$ref": "#/$defs/color"
                    }
                  ]
                },
                "x-merge": "merge"
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "resolvedType": {
                "const": "FLOAT"
              }
            },
            "required": [
              "resolvedType"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "valuesByMode": {
                "description": "Values of a `FLOAT` variable: values of that type, aliases or expressions (VAR-10).",
                "type": "object",
                "additionalProperties": {
                  "anyOf": [
                    {
                      "$ref": "#/$defs/variableAlias"
                    },
                    {
                      "$ref": "#/$defs/variableExpression"
                    },
                    {
                      "type": "number"
                    }
                  ]
                },
                "x-merge": "merge"
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "resolvedType": {
                "const": "STRING"
              }
            },
            "required": [
              "resolvedType"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "valuesByMode": {
                "description": "Values of a `STRING` variable: values of that type, aliases or expressions (VAR-10).",
                "type": "object",
                "additionalProperties": {
                  "anyOf": [
                    {
                      "$ref": "#/$defs/variableAlias"
                    },
                    {
                      "$ref": "#/$defs/variableExpression"
                    },
                    {
                      "type": "string"
                    }
                  ]
                },
                "x-merge": "merge"
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "resolvedType": {
                "const": "BOOLEAN"
              }
            },
            "required": [
              "resolvedType"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "valuesByMode": {
                "description": "Values of a `BOOLEAN` variable: values of that type, or aliases.",
                "type": "object",
                "additionalProperties": {
                  "anyOf": [
                    {
                      "$ref": "#/$defs/variableAlias"
                    },
                    {
                      "type": "boolean"
                    }
                  ]
                },
                "x-merge": "merge"
              }
            }
          }
        }
      ]
    },
    "variablePatch": {
      "description": "A merge patch of a variable (5.9), the `set` of `variable.update`. `valuesByMode` merges per mode. A different `resolvedType`, or an alias that would make a cycle, makes the event skipped.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "name": {
          "description": "Name; groups by `/`: `color/bg/surface`. Unique within the collection. Required. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        },
        "variableCollectionId": {
          "description": "Its collection. Required. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/variableCollectionId"
            }
          ]
        },
        "index": {
          "description": "Order within the collection; Figma's `variableIds` is derived from it. Required. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/fractionalIndex"
            }
          ]
        },
        "resolvedType": {
          "description": "Type of the values. Required; `variable.update` cannot change it. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "enum": [
                "COLOR",
                "FLOAT",
                "STRING",
                "BOOLEAN"
              ]
            }
          ]
        },
        "valuesByMode": {
          "description": "Values, a map of mode id to value or alias. Default `{}`. Merges per mode, so two branches that set two modes both survive. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "propertyNames": {
                "$ref": "#/$defs/modeRef"
              },
              "additionalProperties": {
                "description": "A value of the variable's type (a colour is `{r,g,b,a}`), an alias `{\"type\": \"VARIABLE_ALIAS\", \"id\": \"vr-…\"}` (VAR-3), or for FLOAT and STRING an expression `{\"type\": \"EXPRESSION\", \"expression\": \"…\"}` (VAR-10). Replaced whole. `null` unsets it.",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "anyOf": [
                      {
                        "$ref": "#/$defs/variableAlias"
                      },
                      {
                        "$ref": "#/$defs/variableExpression"
                      },
                      {
                        "$ref": "#/$defs/color"
                      },
                      {
                        "type": "number"
                      },
                      {
                        "type": "string"
                      },
                      {
                        "type": "boolean"
                      }
                    ]
                  }
                ],
                "x-merge": "replace"
              }
            }
          ]
        },
        "description": {
          "description": "Description. Default `\"\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        },
        "scopes": {
          "description": "Where the variable is offered (VAR-5). Default `[\"ALL_SCOPES\"]`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "A Figma `VariableScope`, e.g. `ALL_SCOPES`, `ALL_FILLS`, `FRAME_FILL`, `TEXT_FILL`, `STROKE_COLOR`, `GAP`, `CORNER_RADIUS`, `WIDTH_HEIGHT`, `FONT_SIZE`.",
                "type": "string",
                "pattern": "^[A-Z][A-Z_]*$"
              }
            }
          ]
        },
        "codeSyntax": {
          "description": "Code syntax per platform, `{\"WEB\": \"var(--color-bg)\", \"ANDROID\": \"colorBg\", \"iOS\": \"Color.bg\"}` (VAR-5). Default `{}`. Merges per platform. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "The code for that platform. `null` unsets it.",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "string"
                  }
                ]
              }
            }
          ]
        },
        "hiddenFromPublishing": {
          "description": "Not offered by the library. Default `false`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "boolean"
            }
          ]
        },
        "pluginData": {
          "description": "Private data of plugins and scripts (4.4.10): a map of plugin id to a map of key to string. `setPluginData(key, value)` in the Plugin API writes `pluginData[<plugin id>][key]`. Scripts run by `use_figma` have the plugin id `ud`. Merges per key, so two branches that write different keys both survive. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "The keys and values written by one plugin or script. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
                "x-merge": "merge",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "object",
                    "additionalProperties": {
                      "description": "A value. Values are strings, as in Figma; setting a value to `\"\"` removes the key (in a merge patch the key is set to `null`). `null` unsets it.",
                      "anyOf": [
                        {
                          "type": "null"
                        },
                        {
                          "type": "string"
                        }
                      ]
                    }
                  }
                ]
              }
            }
          ]
        },
        "sharedPluginData": {
          "description": "Data shared between plugins (4.4.10): a map of namespace to a map of key to string, written by `setSharedPluginData(namespace, key, value)`. Merges per key. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": {
                "description": "The keys and values of one namespace. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
                "x-merge": "merge",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "object",
                    "additionalProperties": {
                      "description": "A value, a string as in Figma. `\"\"` removes the key. `null` unsets it.",
                      "anyOf": [
                        {
                          "type": "null"
                        },
                        {
                          "type": "string"
                        }
                      ]
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    },
    "library": {
      "description": "A library this file uses (4.11, VAR-7), in `tree.libraries`, keyed by `lib-` id.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "path": {
          "description": "Path of the library file relative to this file, with `/` separators, e.g. `../design-system/tokens.design`. Required.",
          "type": "string"
        },
        "documentId": {
          "description": "The library's `document.id`. A reader that finds another document at `path` looks for this id among the workspace's `.design` files. Required.",
          "$ref": "#/$defs/documentId"
        },
        "name": {
          "description": "Display name. Default the library's name.",
          "type": "string"
        },
        "enabled": {
          "description": "Offered in the Assets panel. Default `true`.",
          "type": "boolean"
        },
        "acceptedHash": {
          "description": "The library's tree hash (6.9) at the last accepted update (VAR-8). Absent until the first accept.",
          "$ref": "#/$defs/treeHash"
        },
        "imported": {
          "description": "Copies of what this file uses from the library, as of `acceptedHash`, so the file renders without the library (4.11). For a component, the copy holds the component and its descendants. Default `{}`. Each entry is replaced whole.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "nodes": {
              "description": "Copies of the library's nodes this file uses, keyed by the library's ids.",
              "type": "object",
              "additionalProperties": {
                "description": "A copy of a node of the library, as in the library's tree.",
                "$ref": "#/$defs/node",
                "x-merge": "replace"
              },
              "x-merge": "merge"
            },
            "styles": {
              "description": "Copies of the library's styles this file uses, keyed by the library's ids.",
              "type": "object",
              "additionalProperties": {
                "description": "A copy of a style of the library, as in the library's tree.",
                "$ref": "#/$defs/style",
                "x-merge": "replace"
              },
              "x-merge": "merge"
            },
            "variableCollections": {
              "description": "Copies of the library's variable collections this file uses, keyed by the library's ids.",
              "type": "object",
              "additionalProperties": {
                "description": "A copy of a variable collection of the library, as in the library's tree.",
                "$ref": "#/$defs/variableCollection",
                "x-merge": "replace"
              },
              "x-merge": "merge"
            },
            "variables": {
              "description": "Copies of the library's variables this file uses, keyed by the library's ids.",
              "type": "object",
              "additionalProperties": {
                "description": "A copy of a variable of the library, as in the library's tree.",
                "$ref": "#/$defs/variable",
                "x-merge": "replace"
              },
              "x-merge": "merge"
            }
          },
          "x-merge": "merge"
        }
      },
      "required": [
        "path",
        "documentId"
      ]
    },
    "libraryPatch": {
      "description": "A merge patch of a library reference (5.9), the `set` of `library.update` (`path` after a move, `enabled`, `name`).",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "path": {
          "description": "Path of the library file relative to this file, with `/` separators, e.g. `../design-system/tokens.design`. Required. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        },
        "documentId": {
          "description": "The library's `document.id`. A reader that finds another document at `path` looks for this id among the workspace's `.design` files. Required. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/documentId"
            }
          ]
        },
        "name": {
          "description": "Display name. Default the library's name. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        },
        "enabled": {
          "description": "Offered in the Assets panel. Default `true`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "boolean"
            }
          ]
        },
        "acceptedHash": {
          "description": "The library's tree hash (6.9) at the last accepted update (VAR-8). Absent until the first accept. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/treeHash"
            }
          ]
        },
        "imported": {
          "description": "Copies of what this file uses from the library, as of `acceptedHash`, so the file renders without the library (4.11). For a component, the copy holds the component and its descendants. Default `{}`. Each entry is replaced whole. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "nodes": {
                  "description": "Copies of the library's nodes this file uses, keyed by the library's ids. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
                  "x-merge": "merge",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "object",
                      "additionalProperties": {
                        "description": "A copy of a node of the library, as in the library's tree. `null` unsets it.",
                        "anyOf": [
                          {
                            "type": "null"
                          },
                          {
                            "$ref": "#/$defs/node"
                          }
                        ],
                        "x-merge": "replace"
                      }
                    }
                  ]
                },
                "styles": {
                  "description": "Copies of the library's styles this file uses, keyed by the library's ids. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
                  "x-merge": "merge",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "object",
                      "additionalProperties": {
                        "description": "A copy of a style of the library, as in the library's tree. `null` unsets it.",
                        "anyOf": [
                          {
                            "type": "null"
                          },
                          {
                            "$ref": "#/$defs/style"
                          }
                        ],
                        "x-merge": "replace"
                      }
                    }
                  ]
                },
                "variableCollections": {
                  "description": "Copies of the library's variable collections this file uses, keyed by the library's ids. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
                  "x-merge": "merge",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "object",
                      "additionalProperties": {
                        "description": "A copy of a variable collection of the library, as in the library's tree. `null` unsets it.",
                        "anyOf": [
                          {
                            "type": "null"
                          },
                          {
                            "$ref": "#/$defs/variableCollection"
                          }
                        ],
                        "x-merge": "replace"
                      }
                    }
                  ]
                },
                "variables": {
                  "description": "Copies of the library's variables this file uses, keyed by the library's ids. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
                  "x-merge": "merge",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "object",
                      "additionalProperties": {
                        "description": "A copy of a variable of the library, as in the library's tree. `null` unsets it.",
                        "anyOf": [
                          {
                            "type": "null"
                          },
                          {
                            "$ref": "#/$defs/variable"
                          }
                        ],
                        "x-merge": "replace"
                      }
                    }
                  ]
                }
              }
            }
          ]
        }
      }
    },
    "flow": {
      "description": "A prototype flow (4.12, PRO-6) in `tree.flows`, keyed by `fl-` id. Figma's `page.flowStartingPoints` is derived from the page's flows.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "pageId": {
          "description": "The page the flow belongs to. Required.",
          "$ref": "#/$defs/pageId"
        },
        "name": {
          "description": "Flow name. Required.",
          "type": "string"
        },
        "index": {
          "description": "Order among the page's flows. Required.",
          "$ref": "#/$defs/fractionalIndex"
        },
        "nodeId": {
          "description": "The starting frame. Required.",
          "$ref": "#/$defs/nodeId"
        },
        "description": {
          "description": "Description. Default `\"\"`.",
          "type": "string"
        },
        "device": {
          "description": "Device frame of the preview player, `{type, rotation}`. Default `{\"type\":\"NONE\"}`. Replaced whole (assumed by this draft).",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "type": {
              "description": "Device kind (FMT-001 does not list the values; Figma uses `NONE`, `PRESET`, `CUSTOM`, `PRESENTATION`).",
              "type": "string"
            },
            "rotation": {
              "description": "Device rotation (FMT-001 does not list the values; Figma uses `NONE`, `CCW_90`).",
              "type": "string"
            }
          },
          "required": [
            "type"
          ],
          "x-merge": "replace"
        },
        "background": {
          "description": "Background in the player. Default the page background.",
          "$ref": "#/$defs/color",
          "x-merge": "replace"
        }
      },
      "required": [
        "pageId",
        "name",
        "index",
        "nodeId"
      ]
    },
    "flowPatch": {
      "description": "A merge patch of a flow (5.9), the `set` of `flow.update`.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "pageId": {
          "description": "The page the flow belongs to. Required. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/pageId"
            }
          ]
        },
        "name": {
          "description": "Flow name. Required. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        },
        "index": {
          "description": "Order among the page's flows. Required. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/fractionalIndex"
            }
          ]
        },
        "nodeId": {
          "description": "The starting frame. Required. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/nodeId"
            }
          ]
        },
        "description": {
          "description": "Description. Default `\"\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        },
        "device": {
          "description": "Device frame of the preview player, `{type, rotation}`. Default `{\"type\":\"NONE\"}`. Replaced whole (assumed by this draft). `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "type": {
                  "description": "Device kind (FMT-001 does not list the values; Figma uses `NONE`, `PRESET`, `CUSTOM`, `PRESENTATION`).",
                  "type": "string"
                },
                "rotation": {
                  "description": "Device rotation (FMT-001 does not list the values; Figma uses `NONE`, `CCW_90`).",
                  "type": "string"
                }
              },
              "required": [
                "type"
              ]
            }
          ],
          "x-merge": "replace"
        },
        "background": {
          "description": "Background in the player. Default the page background. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/color"
            }
          ],
          "x-merge": "replace"
        }
      }
    },
    "comment": {
      "description": "A comment (4.13, COL-3) in `tree.comments`, keyed by `cn-` id: a thread (with `anchor`) or a reply (with `parentId`). Replies are ordered by `at`, then by id.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "parentId": {
          "description": "Absent for the first comment of a thread; the thread's first comment for a reply.",
          "$ref": "#/$defs/commentId"
        },
        "message": {
          "description": "Text; mentions are written `@<name>`. Required.",
          "type": "string"
        },
        "by": {
          "description": "Author: the `by` of the creating event. Required.",
          "type": "string"
        },
        "at": {
          "description": "Time: the `at` of the creating event. Required.",
          "$ref": "#/$defs/timestamp"
        },
        "editedAt": {
          "description": "Last edit. Absent by default.",
          "$ref": "#/$defs/timestamp"
        },
        "anchor": {
          "description": "Where a thread is pinned: `{\"nodeId\": id, \"offset\": {x, y}}` on a node, or `{\"pageId\": id, \"x\": n, \"y\": n}` on the canvas. Required for a thread, absent for replies. Replaced whole by a patch.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "nodeId": {
              "description": "The node the thread is pinned to.",
              "$ref": "#/$defs/nodeRef"
            },
            "offset": {
              "description": "Offset from the node's origin, px.",
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "x": {
                  "description": "Horizontal component, px.",
                  "type": "number"
                },
                "y": {
                  "description": "Vertical component, px.",
                  "type": "number"
                }
              },
              "required": [
                "x",
                "y"
              ],
              "x-merge": "replace"
            },
            "pageId": {
              "description": "The page of a thread pinned to a point of the canvas.",
              "$ref": "#/$defs/pageId"
            },
            "x": {
              "description": "Canvas x of a thread pinned to a point, px.",
              "type": "number"
            },
            "y": {
              "description": "Canvas y of a thread pinned to a point, px.",
              "type": "number"
            }
          },
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "nodeId": {
                  "description": "`nodeId`, as declared above; required in this alternative."
                }
              },
              "required": [
                "nodeId"
              ]
            },
            {
              "type": "object",
              "properties": {
                "pageId": {
                  "description": "`pageId`, as declared above; required in this alternative."
                },
                "x": {
                  "description": "`x`, as declared above; required in this alternative."
                },
                "y": {
                  "description": "`y`, as declared above; required in this alternative."
                }
              },
              "required": [
                "pageId",
                "x",
                "y"
              ]
            }
          ],
          "x-merge": "replace"
        },
        "mentions": {
          "description": "Names mentioned. Default `[]`.",
          "type": "array",
          "items": {
            "description": "A name (git author).",
            "type": "string"
          }
        },
        "reactions": {
          "description": "Reactions, a map of short code without colons to names, e.g. `{\"+1\": [\"Ada\"], \"eyes\": [\"Grace\"]}`. Default `{}`. Changed by `comment.react`; merges per reaction (assumed by this draft).",
          "type": "object",
          "additionalProperties": {
            "description": "Who reacted.",
            "type": "array",
            "items": {
              "description": "A name.",
              "type": "string"
            }
          },
          "x-merge": "merge"
        },
        "resolved": {
          "description": "On a thread: resolved. Default `false`.",
          "type": "boolean"
        },
        "meta": {
          "description": "UI Designer extension of 4.13 for review findings (the ui-designer-review skill and `ud lint`): `category`, `severity`, `findingId`. Absent by default; readers that do not know it keep it. Merged by a patch.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "category": {
              "description": "The review area of a finding, e.g. `contrast`, `naming`, `spacing`.",
              "type": "string"
            },
            "severity": {
              "description": "How serious the finding is.",
              "type": "string",
              "enum": [
                "info",
                "warning",
                "error"
              ]
            },
            "findingId": {
              "description": "The id of the lint finding or review check the comment reports, so a later review updates the thread instead of adding another.",
              "type": "string"
            }
          },
          "x-merge": "merge"
        }
      },
      "required": [
        "message",
        "by",
        "at"
      ],
      "allOf": [
        {
          "if": {
            "type": "object",
            "properties": {
              "parentId": {}
            },
            "required": [
              "parentId"
            ]
          },
          "then": {
            "type": "object",
            "not": {
              "type": "object",
              "properties": {
                "anchor": {
                  "description": "`anchor`, as declared above; required in this alternative."
                }
              },
              "required": [
                "anchor"
              ]
            }
          },
          "else": {
            "type": "object",
            "properties": {
              "anchor": {
                "description": "`anchor`, as declared above; required in this alternative."
              }
            },
            "required": [
              "anchor"
            ]
          }
        }
      ]
    },
    "commentPatch": {
      "description": "A merge patch of a comment, the `set` of `comment.update` (`message`, `anchor`, `mentions`, `resolved`, `meta`). Changing `message` sets `editedAt` to the event's `at`; a patch that sets `editedAt` itself (the undo of an edit) keeps it.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "message": {
          "description": "Text; mentions are written `@<name>`. Required. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        },
        "anchor": {
          "description": "Where a thread is pinned: `{\"nodeId\": id, \"offset\": {x, y}}` on a node, or `{\"pageId\": id, \"x\": n, \"y\": n}` on the canvas. Required for a thread, absent for replies. Replaced whole by a patch. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "nodeId": {
                  "description": "The node the thread is pinned to.",
                  "$ref": "#/$defs/nodeRef"
                },
                "offset": {
                  "description": "Offset from the node's origin, px.",
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "x": {
                      "description": "Horizontal component, px.",
                      "type": "number"
                    },
                    "y": {
                      "description": "Vertical component, px.",
                      "type": "number"
                    }
                  },
                  "required": [
                    "x",
                    "y"
                  ],
                  "x-merge": "replace"
                },
                "pageId": {
                  "description": "The page of a thread pinned to a point of the canvas.",
                  "$ref": "#/$defs/pageId"
                },
                "x": {
                  "description": "Canvas x of a thread pinned to a point, px.",
                  "type": "number"
                },
                "y": {
                  "description": "Canvas y of a thread pinned to a point, px.",
                  "type": "number"
                }
              },
              "anyOf": [
                {
                  "type": "object",
                  "properties": {
                    "nodeId": {
                      "description": "`nodeId`, as declared above; required in this alternative."
                    }
                  },
                  "required": [
                    "nodeId"
                  ]
                },
                {
                  "type": "object",
                  "properties": {
                    "pageId": {
                      "description": "`pageId`, as declared above; required in this alternative."
                    },
                    "x": {
                      "description": "`x`, as declared above; required in this alternative."
                    },
                    "y": {
                      "description": "`y`, as declared above; required in this alternative."
                    }
                  },
                  "required": [
                    "pageId",
                    "x",
                    "y"
                  ]
                }
              ]
            }
          ],
          "x-merge": "replace"
        },
        "mentions": {
          "description": "Names mentioned. Default `[]`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "description": "A name (git author).",
                "type": "string"
              }
            }
          ]
        },
        "resolved": {
          "description": "On a thread: resolved. Default `false`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "boolean"
            }
          ]
        },
        "meta": {
          "description": "UI Designer extension of 4.13 for review findings (the ui-designer-review skill and `ud lint`): `category`, `severity`, `findingId`. Absent by default; readers that do not know it keep it. Merged by a patch. In a patch, members merge and `null` removes one; `null` for the whole object unsets it.",
          "x-merge": "merge",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "category": {
                  "description": "The review area of a finding, e.g. `contrast`, `naming`, `spacing`. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "string"
                    }
                  ]
                },
                "severity": {
                  "description": "How serious the finding is. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "string",
                      "enum": [
                        "info",
                        "warning",
                        "error"
                      ]
                    }
                  ]
                },
                "findingId": {
                  "description": "The id of the lint finding or review check the comment reports, so a later review updates the thread instead of adding another. `null` unsets it.",
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "string"
                    }
                  ]
                }
              }
            }
          ]
        },
        "editedAt": {
          "description": "Last edit. Absent by default. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/timestamp"
            }
          ]
        }
      }
    },
    "version": {
      "description": "A named version (4.14, COL-2) in `tree.versions`, keyed by `vs-` id. Consolidation keeps versions.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "title": {
          "description": "Title. Required.",
          "type": "string"
        },
        "description": {
          "description": "Description. Default `\"\"`.",
          "type": "string"
        },
        "by": {
          "description": "From the `version.save` event.",
          "type": "string"
        },
        "at": {
          "description": "From the `version.save` event.",
          "$ref": "#/$defs/timestamp"
        },
        "treeHash": {
          "description": "The tree hash (6.9) of the document just before the `version.save` event: every earlier event folded. Written by the writer of the event; a reader computes a missing one while folding, with a warning.",
          "$ref": "#/$defs/treeHash"
        },
        "seq": {
          "description": "The `seq` of the `version.save` event in this branch (informative; the hash names the state).",
          "type": "integer",
          "minimum": 1
        }
      },
      "required": [
        "title"
      ]
    },
    "versionPatch": {
      "description": "A merge patch of a named version, the `set` of `version.update` (`title`, `description`).",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "title": {
          "description": "Title. Required. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        },
        "description": {
          "description": "Description. Default `\"\"`. `null` unsets it.",
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        }
      }
    },
    "asset": {
      "description": "Metadata of a file in the assets folder (4.15), in `tree.assets`, keyed by content hash. The bytes are never in the design file.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "kind": {
          "description": "Kind of file. Required.",
          "type": "string",
          "enum": [
            "image",
            "font"
          ]
        },
        "mime": {
          "description": "Media type.",
          "type": "string",
          "enum": [
            "image/png",
            "image/jpeg",
            "image/webp",
            "image/gif",
            "image/avif",
            "image/svg+xml",
            "font/ttf",
            "font/otf",
            "font/woff2"
          ]
        },
        "ext": {
          "description": "File extension without the dot: the file is `<hash>.<ext>`.",
          "type": "string",
          "pattern": "^[a-z0-9]+$"
        },
        "bytes": {
          "description": "File size in bytes.",
          "type": "integer",
          "minimum": 0
        },
        "width": {
          "description": "Images: intrinsic width, px.",
          "type": "integer",
          "minimum": 0
        },
        "height": {
          "description": "Images: intrinsic height, px.",
          "type": "integer",
          "minimum": 0
        },
        "name": {
          "description": "Original file name, for display.",
          "type": "string"
        },
        "family": {
          "description": "Fonts: the font's family.",
          "type": "string"
        },
        "style": {
          "description": "Fonts: the Figma-style style name.",
          "type": "string"
        }
      },
      "required": [
        "kind"
      ]
    },
    "deletedComponent": {
      "description": "A deleted main component (4.16): a snapshot of its subtree, taken when it was deleted while instances used it. Instances whose `componentId` names it render from it; `component.restore` puts it back. No event changes it.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "nodes": {
          "description": "The component and all its descendants (for a `COMPONENT_SET`: the set, its variants and their descendants), keyed by node id.",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/nodeId"
          },
          "additionalProperties": {
            "description": "A node of the snapshot, as it was in `tree.nodes` (with its `parent` and `index`).",
            "type": "object",
            "$ref": "#/$defs/node"
          },
          "x-merge": "replace"
        },
        "deletedAt": {
          "description": "The `at` of the deleting event.",
          "$ref": "#/$defs/timestamp"
        },
        "deletedBy": {
          "description": "The `by` of the deleting event.",
          "type": "string"
        }
      },
      "required": [
        "nodes"
      ]
    },
    "tree": {
      "description": "The consolidated document (4.1): the state after the event numbered `seq`. Rewritten only by consolidation; do not edit it, append events to `wal` instead. Every member is optional; a missing map is empty. Collections that two people can grow at once are maps keyed by id (ordered by a fractional `index` where order matters), so concurrent additions never touch the same line.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "seq": {
          "description": "`seq` of the last event folded into this tree. The next event has `seq` + 1.",
          "type": "integer",
          "minimum": 0
        },
        "document": {
          "description": "Document metadata (4.2).",
          "$ref": "#/$defs/document",
          "x-merge": "merge"
        },
        "pages": {
          "description": "The pages, keyed by page id, ordered by `index` (4.2).",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/pageId"
          },
          "additionalProperties": {
            "description": "A page.",
            "$ref": "#/$defs/page",
            "x-merge": "merge"
          },
          "x-merge": "merge"
        },
        "nodes": {
          "description": "Every node of every page, flat, keyed by node id (4.3). No nested `children` arrays.",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/nodeId"
          },
          "additionalProperties": {
            "description": "A node.",
            "$ref": "#/$defs/node",
            "x-merge": "merge"
          },
          "x-merge": "merge"
        },
        "styles": {
          "description": "Paint, text, effect and grid styles, keyed by style id (4.9).",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/styleId"
          },
          "additionalProperties": {
            "description": "A style.",
            "$ref": "#/$defs/style",
            "x-merge": "merge"
          },
          "x-merge": "merge"
        },
        "variableCollections": {
          "description": "Variable collections with their modes, keyed by collection id (4.10).",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/variableCollectionId"
          },
          "additionalProperties": {
            "description": "A collection.",
            "$ref": "#/$defs/variableCollection",
            "x-merge": "merge"
          },
          "x-merge": "merge"
        },
        "variables": {
          "description": "Variables of all collections, keyed by variable id (4.10).",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/variableId"
          },
          "additionalProperties": {
            "description": "A variable.",
            "$ref": "#/$defs/variable",
            "x-merge": "merge"
          },
          "x-merge": "merge"
        },
        "libraries": {
          "description": "Other design files this one uses, with a copy of what it uses, keyed by library id (4.11).",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/libraryId"
          },
          "additionalProperties": {
            "description": "A library reference.",
            "$ref": "#/$defs/library",
            "x-merge": "merge"
          },
          "x-merge": "merge"
        },
        "flows": {
          "description": "Prototype flows and their starting points, keyed by flow id (4.12).",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/flowId"
          },
          "additionalProperties": {
            "description": "A flow.",
            "$ref": "#/$defs/flow",
            "x-merge": "merge"
          },
          "x-merge": "merge"
        },
        "comments": {
          "description": "Comment threads and replies, keyed by comment id (4.13).",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/commentId"
          },
          "additionalProperties": {
            "description": "A comment.",
            "$ref": "#/$defs/comment",
            "x-merge": "merge"
          },
          "x-merge": "merge"
        },
        "versions": {
          "description": "Named versions, keyed by version id (4.14).",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/versionId"
          },
          "additionalProperties": {
            "description": "A named version.",
            "$ref": "#/$defs/version",
            "x-merge": "merge"
          },
          "x-merge": "merge"
        },
        "assets": {
          "description": "Metadata of the images and fonts in the assets folder, keyed by content hash (4.15).",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/assetHash"
          },
          "additionalProperties": {
            "description": "Asset metadata.",
            "$ref": "#/$defs/asset",
            "x-merge": "merge"
          },
          "x-merge": "merge"
        },
        "deletedComponents": {
          "description": "Snapshots of main components deleted while instances used them, keyed by the component's id (4.16). Consolidation drops an entry no instance refers to.",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/nodeId"
          },
          "additionalProperties": {
            "description": "A deleted component's snapshot.",
            "$ref": "#/$defs/deletedComponent"
          },
          "x-merge": "replace"
        }
      }
    },
    "envelope": {
      "description": "The members every event has (5.1), written first and in this order: `seq`, `at`, `by`, `op`, `group`, `note`; then the payload.",
      "type": "object",
      "additionalProperties": true,
      "required": [
        "seq",
        "at",
        "by",
        "op"
      ],
      "properties": {
        "seq": {
          "description": "One more than the `seq` of the entry before it; the first event after a consolidation has `tree.seq` + 1. A missing or repeated number is renumbered by the reader (9.2). Never change a number already in the file.",
          "type": "integer",
          "minimum": 1
        },
        "at": {
          "description": "When the change was made. Lines are applied in file order, not by `at`.",
          "$ref": "#/$defs/timestamp"
        },
        "by": {
          "description": "The actor (5.8): display name of whoever made the change (`--as`, `UD_ACTOR`, `Claude` inside Claude Code, the git user name, else `Unknown`). A claim, not a signature.",
          "type": "string",
          "minLength": 1
        },
        "op": {
          "description": "The operation (5.11).",
          "type": "string",
          "minLength": 1
        },
        "group": {
          "description": "Optional. The group (transaction) the event belongs to (5.7): consecutive lines with the same `group`, `by` and `at`, written in one edit; one undo step and one history entry.",
          "$ref": "#/$defs/groupId"
        },
        "note": {
          "description": "Optional, on the first event of a group: the group's description, shown in the history panel.",
          "type": "string"
        }
      }
    },
    "walBase": {
      "description": "The `wal.base` marker (5.4): the first entry of `wal`, never an event. It exists so that every event line can start with a comma. It has no `by`; readers skip it wherever it stands.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "seq": {
          "description": "Copy of `tree.seq` when the marker was written. Informative; readers take `tree.seq`.",
          "type": "integer",
          "minimum": 0
        },
        "at": {
          "description": "When the list was last consolidated. Absent in a file never consolidated.",
          "$ref": "#/$defs/timestamp"
        },
        "op": {
          "description": "Always `wal.base`.",
          "const": "wal.base"
        }
      },
      "required": [
        "op"
      ]
    },
    "event.document.update": {
      "description": "`document.update` (5.11): Merge patch of `document` (not `id`). Never skipped.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `document.update`.",
          "const": "document.update"
        },
        "set": {
          "description": "The merge patch.",
          "$ref": "#/$defs/documentPatch"
        }
      },
      "required": [
        "op",
        "set"
      ]
    },
    "event.page.create": {
      "description": "`page.create` (5.11): Adds a page. Skipped when the id exists.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `page.create`.",
          "const": "page.create"
        },
        "page": {
          "description": "The new page, with `id` and `index`; members left out take their defaults.",
          "type": "object",
          "$ref": "#/$defs/page",
          "properties": {
            "id": {
              "description": "The new page id, made by the writer.",
              "$ref": "#/$defs/pageId"
            },
            "index": {
              "description": "`index`, as declared in `page`; required here."
            }
          },
          "required": [
            "id",
            "index"
          ]
        }
      },
      "required": [
        "op",
        "page"
      ]
    },
    "event.page.update": {
      "description": "`page.update` (5.11): Merge patch of the page. Skipped when there is no such page.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `page.update`.",
          "const": "page.update"
        },
        "id": {
          "description": "The page.",
          "$ref": "#/$defs/pageId"
        },
        "set": {
          "description": "The merge patch.",
          "$ref": "#/$defs/pagePatch"
        }
      },
      "required": [
        "op",
        "id",
        "set"
      ]
    },
    "event.page.reorder": {
      "description": "`page.reorder` (5.11): Moves the page among the pages. Skipped when there is no such page.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `page.reorder`.",
          "const": "page.reorder"
        },
        "id": {
          "description": "The page.",
          "$ref": "#/$defs/pageId"
        },
        "index": {
          "description": "The new position.",
          "$ref": "#/$defs/fractionalIndex"
        }
      },
      "required": [
        "op",
        "id",
        "index"
      ]
    },
    "event.page.delete": {
      "description": "`page.delete` (5.11): Removes the page, its nodes (with descendants) and its flows; comment threads anchored on it are removed. Skipped when there is no such page or it is the last page.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `page.delete`.",
          "const": "page.delete"
        },
        "id": {
          "description": "The page.",
          "$ref": "#/$defs/pageId"
        }
      },
      "required": [
        "op",
        "id"
      ]
    },
    "event.node.create": {
      "description": "`node.create` (5.11): Adds the nodes in order. A node's parent exists already or is earlier in the same array. Skipped per node (the id exists; `type` is missing; the parent does not exist, but see 6.5); the other nodes still apply.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `node.create`.",
          "const": "node.create"
        },
        "nodes": {
          "description": "The new nodes.",
          "type": "array",
          "items": {
            "description": "A new node with `id`, `type`, `parent`, `index`.",
            "$ref": "#/$defs/nodeInput"
          },
          "minItems": 1
        }
      },
      "required": [
        "op",
        "nodes"
      ]
    },
    "event.node.update": {
      "description": "`node.update` (5.11): Merge patch of the node (5.9). Skipped when there is no such node.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `node.update`.",
          "const": "node.update"
        },
        "id": {
          "description": "The node.",
          "$ref": "#/$defs/nodeId"
        },
        "set": {
          "description": "The merge patch.",
          "$ref": "#/$defs/nodePatch"
        }
      },
      "required": [
        "op",
        "id",
        "set"
      ]
    },
    "event.node.move": {
      "description": "`node.move` (5.11): Gives the node a new parent and position. Skipped when there is no such node or parent, the move would put the node inside itself, or the parent cannot have children (4.3). A missing parent is handled as an orphan (6.5).",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `node.move`.",
          "const": "node.move"
        },
        "id": {
          "description": "The node to move.",
          "$ref": "#/$defs/nodeId"
        },
        "parent": {
          "description": "The new parent: a page, a node, or an instance slot.",
          "anyOf": [
            {
              "$ref": "#/$defs/pageId"
            },
            {
              "$ref": "#/$defs/nodeRef"
            }
          ]
        },
        "index": {
          "description": "Position among the new siblings.",
          "$ref": "#/$defs/fractionalIndex"
        },
        "x": {
          "description": "Position in the new parent's coordinates, computed by the writer. Optional.",
          "type": "number"
        },
        "y": {
          "description": "Position in the new parent's coordinates, computed by the writer. Optional.",
          "type": "number"
        }
      },
      "required": [
        "op",
        "id",
        "parent",
        "index"
      ]
    },
    "event.node.reorder": {
      "description": "`node.reorder` (5.11): New position among the same siblings: z-order and flow order (DOC-3). Skipped when there is no such node.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `node.reorder`.",
          "const": "node.reorder"
        },
        "id": {
          "description": "The node.",
          "$ref": "#/$defs/nodeId"
        },
        "index": {
          "description": "The new position.",
          "$ref": "#/$defs/fractionalIndex"
        }
      },
      "required": [
        "op",
        "id",
        "index"
      ]
    },
    "event.node.delete": {
      "description": "`node.delete` (5.11): Removes each node and all its descendants. Instances of a deleted main component keep their `componentId` and show \"Missing component\". Skipped per id when there is no such node.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `node.delete`.",
          "const": "node.delete"
        },
        "ids": {
          "description": "The nodes to delete.",
          "type": "array",
          "items": {
            "description": "A node to delete.",
            "$ref": "#/$defs/nodeId"
          },
          "minItems": 1
        },
        "components": {
          "description": "Optional. Snapshots of deleted main components that instances still use (4.16), keyed by component id; they go to `tree.deletedComponents` with this event's `at` and `by`.",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/nodeId"
          },
          "additionalProperties": {
            "description": "A snapshot.",
            "type": "object",
            "properties": {
              "nodes": {
                "description": "The subtree, keyed by node id.",
                "type": "object",
                "propertyNames": {
                  "$ref": "#/$defs/nodeId"
                },
                "additionalProperties": {
                  "description": "A node of the snapshot.",
                  "type": "object",
                  "$ref": "#/$defs/node"
                },
                "x-merge": "replace"
              }
            },
            "required": [
              "nodes"
            ]
          },
          "x-merge": "replace"
        }
      },
      "required": [
        "op",
        "ids"
      ]
    },
    "event.component.create": {
      "description": "`component.create` (5.11): Turns a `FRAME` into a `COMPONENT` with the same id (CMP-1); `set` adds properties in the same step. Skipped when there is no such node or it is not a `FRAME`.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `component.create`.",
          "const": "component.create"
        },
        "id": {
          "description": "The frame.",
          "$ref": "#/$defs/nodeId"
        },
        "set": {
          "description": "Optional. Properties added in the same step.",
          "$ref": "#/$defs/nodePatch"
        }
      },
      "required": [
        "op",
        "id"
      ]
    },
    "event.component.combine": {
      "description": "`component.combine` (5.11): Creates a `COMPONENT_SET` and moves the components into it, keeping their order. Skipped when the set's id exists or any id is not a `COMPONENT`.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `component.combine`.",
          "const": "component.combine"
        },
        "node": {
          "description": "The new `COMPONENT_SET` node.",
          "type": "object",
          "$ref": "#/$defs/nodeInput",
          "properties": {
            "type": {
              "description": "Always `COMPONENT_SET`.",
              "const": "COMPONENT_SET"
            }
          }
        },
        "ids": {
          "description": "The components to combine.",
          "type": "array",
          "items": {
            "description": "A component.",
            "$ref": "#/$defs/nodeId"
          },
          "minItems": 1
        }
      },
      "required": [
        "op",
        "node",
        "ids"
      ]
    },
    "event.component.restore": {
      "description": "`component.restore` (5.11): Puts the snapshot of `tree.deletedComponents[id]` back into `tree.nodes` with its ids (4.16) and removes the entry: under `parent` at `index` when given, else under its old parent when that still exists, else at the top level of its old page (6.5). Skipped when there is no such deleted component, an id of the snapshot exists, or `parent` cannot have children.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `component.restore`.",
          "const": "component.restore"
        },
        "id": {
          "description": "The deleted component.",
          "$ref": "#/$defs/nodeId"
        },
        "parent": {
          "description": "Optional. Where the component goes.",
          "anyOf": [
            {
              "$ref": "#/$defs/pageId"
            },
            {
              "$ref": "#/$defs/nodeId"
            }
          ]
        },
        "index": {
          "description": "Optional. Its position among the children of `parent`.",
          "$ref": "#/$defs/fractionalIndex"
        }
      },
      "required": [
        "op",
        "id"
      ]
    },
    "event.component.property.set": {
      "description": "`component.property.set` (5.11): Adds or replaces one property definition (CMP-5). Skipped when there is no such node, it is not a component or set, or a `VARIANT` key has `#` or another key has none.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `component.property.set`.",
          "const": "component.property.set"
        },
        "id": {
          "description": "The component or component set.",
          "$ref": "#/$defs/nodeId"
        },
        "key": {
          "description": "The property key.",
          "$ref": "#/$defs/componentPropertyKey"
        },
        "definition": {
          "description": "The definition.",
          "$ref": "#/$defs/componentPropertyDefinition"
        }
      },
      "required": [
        "op",
        "id",
        "key",
        "definition"
      ]
    },
    "event.component.property.delete": {
      "description": "`component.property.delete` (5.11): Removes the definition. References in layers and values in instances stay and have no effect. Skipped when there is no such node.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `component.property.delete`.",
          "const": "component.property.delete"
        },
        "id": {
          "description": "The component or component set.",
          "$ref": "#/$defs/nodeId"
        },
        "key": {
          "description": "The property key.",
          "$ref": "#/$defs/componentPropertyKey"
        }
      },
      "required": [
        "op",
        "id",
        "key"
      ]
    },
    "event.instance.override": {
      "description": "`instance.override` (5.11): Merge patch of `overrides[path]` (CMP-3). Skipped when there is no such instance or `path` is empty (use `node.update` for the instance itself).",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `instance.override`.",
          "const": "instance.override"
        },
        "id": {
          "description": "The instance.",
          "$ref": "#/$defs/nodeId"
        },
        "path": {
          "description": "The sublayer.",
          "$ref": "#/$defs/overridePath"
        },
        "set": {
          "description": "The merge patch of the override.",
          "$ref": "#/$defs/nodePatch"
        }
      },
      "required": [
        "op",
        "id",
        "path",
        "set"
      ]
    },
    "event.instance.reset": {
      "description": "`instance.reset` (5.11): Removes overrides: all of them; or those at `path`; or only `keys` at `path`. Also removes the instance's own stored properties named in `keys` when `path` is absent. Skipped when there is no such instance.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `instance.reset`.",
          "const": "instance.reset"
        },
        "id": {
          "description": "The instance.",
          "$ref": "#/$defs/nodeId"
        },
        "path": {
          "description": "Optional. The sublayer whose overrides are removed.",
          "$ref": "#/$defs/overridePath"
        },
        "keys": {
          "description": "Optional. Only these properties.",
          "type": "array",
          "items": {
            "description": "A property name.",
            "type": "string"
          }
        }
      },
      "required": [
        "op",
        "id"
      ]
    },
    "event.instance.swap": {
      "description": "`instance.swap` (5.11): Without `path`: the instance shows another component and its `overrides` become the given ones (the writer keeps those whose layer names match, CMP-6). With `path`: swaps a nested instance, as an override with `componentId`. Skipped when there is no such instance.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `instance.swap`.",
          "const": "instance.swap"
        },
        "id": {
          "description": "The instance.",
          "$ref": "#/$defs/nodeId"
        },
        "componentId": {
          "description": "The new component.",
          "$ref": "#/$defs/componentRef"
        },
        "path": {
          "description": "Optional. The nested instance to swap.",
          "$ref": "#/$defs/overridePath"
        },
        "overrides": {
          "description": "Optional. The remapped overrides, computed by the writer.",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/overridePath"
          },
          "additionalProperties": {
            "description": "An override.",
            "$ref": "#/$defs/nodePatch"
          },
          "x-merge": "replace"
        }
      },
      "required": [
        "op",
        "id",
        "componentId"
      ]
    },
    "event.instance.detach": {
      "description": "`instance.detach` (5.11): Turns the instance into a `FRAME` with the same id, removes `componentId`, `componentProperties` and `overrides`, applies `set` and adds `nodes`, the sublayers as real nodes with new ids. Slot content moves under the new nodes. Skipped when there is no such instance.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `instance.detach`.",
          "const": "instance.detach"
        },
        "id": {
          "description": "The instance.",
          "$ref": "#/$defs/nodeId"
        },
        "set": {
          "description": "The main component's properties, copied by the writer.",
          "$ref": "#/$defs/nodePatch"
        },
        "nodes": {
          "description": "The sublayers as real nodes.",
          "type": "array",
          "items": {
            "description": "A sublayer as a real node with a new id.",
            "$ref": "#/$defs/nodeInput"
          }
        },
        "map": {
          "description": "Optional (an extension of this writer). Override paths of filled slots mapped to the new nodes their content moves under; content of an unmapped slot moves under the frame itself.",
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/overridePath"
          },
          "additionalProperties": {
            "description": "The new node.",
            "$ref": "#/$defs/nodeId"
          },
          "x-merge": "replace"
        }
      },
      "required": [
        "op",
        "id",
        "set",
        "nodes"
      ]
    },
    "event.style.create": {
      "description": "`style.create` (5.11): Adds the style. Skipped when the id exists.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `style.create`.",
          "const": "style.create"
        },
        "style": {
          "description": "The new style with `id`, `type`, `name`, `index`.",
          "type": "object",
          "$ref": "#/$defs/style",
          "properties": {
            "id": {
              "description": "The new style id.",
              "$ref": "#/$defs/styleId"
            }
          },
          "required": [
            "id"
          ]
        }
      },
      "required": [
        "op",
        "style"
      ]
    },
    "event.style.update": {
      "description": "`style.update` (5.11): Merge patch; `index` may be set to reorder. Skipped when there is no such style or `set.type` differs.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `style.update`.",
          "const": "style.update"
        },
        "id": {
          "description": "The style.",
          "$ref": "#/$defs/styleId"
        },
        "set": {
          "description": "The merge patch.",
          "$ref": "#/$defs/stylePatch"
        }
      },
      "required": [
        "op",
        "id",
        "set"
      ]
    },
    "event.style.delete": {
      "description": "`style.delete` (5.11): Removes the style. Nodes that refer to it fall back to their plain values (4.4.5). Skipped when there is no such style.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `style.delete`.",
          "const": "style.delete"
        },
        "id": {
          "description": "The style.",
          "$ref": "#/$defs/styleId"
        }
      },
      "required": [
        "op",
        "id"
      ]
    },
    "event.collection.create": {
      "description": "`collection.create` (5.11): Adds the collection. Skipped when the id exists or it has no modes.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `collection.create`.",
          "const": "collection.create"
        },
        "collection": {
          "description": "The new collection with `id`, `name`, `index`, `modes` (at least one).",
          "type": "object",
          "$ref": "#/$defs/variableCollection",
          "properties": {
            "id": {
              "description": "The new collection id.",
              "$ref": "#/$defs/variableCollectionId"
            }
          },
          "required": [
            "id"
          ]
        }
      },
      "required": [
        "op",
        "collection"
      ]
    },
    "event.collection.update": {
      "description": "`collection.update` (5.11): Merge patch (`name`, `defaultModeId`, `hiddenFromPublishing`, …). Modes change through `mode.*`. Skipped when there is no such collection.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `collection.update`.",
          "const": "collection.update"
        },
        "id": {
          "description": "The collection.",
          "$ref": "#/$defs/variableCollectionId"
        },
        "set": {
          "description": "The merge patch.",
          "$ref": "#/$defs/variableCollectionPatch"
        }
      },
      "required": [
        "op",
        "id",
        "set"
      ]
    },
    "event.collection.delete": {
      "description": "`collection.delete` (5.11): Removes the collection and its variables. Bindings fall back to plain values. Skipped when there is no such collection.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `collection.delete`.",
          "const": "collection.delete"
        },
        "id": {
          "description": "The collection.",
          "$ref": "#/$defs/variableCollectionId"
        }
      },
      "required": [
        "op",
        "id"
      ]
    },
    "event.mode.create": {
      "description": "`mode.create` (5.11): Adds a mode. Variables without a value for it use the default mode's value. Skipped when there is no such collection or the mode id exists.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `mode.create`.",
          "const": "mode.create"
        },
        "collectionId": {
          "description": "The collection.",
          "$ref": "#/$defs/variableCollectionId"
        },
        "mode": {
          "description": "The new mode `{id, name, index}`.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "id": {
              "description": "The new mode id.",
              "$ref": "#/$defs/modeId"
            },
            "name": {
              "description": "Mode name.",
              "type": "string"
            },
            "index": {
              "description": "Order among the modes.",
              "$ref": "#/$defs/fractionalIndex"
            }
          },
          "required": [
            "id",
            "name",
            "index"
          ]
        }
      },
      "required": [
        "op",
        "collectionId",
        "mode"
      ]
    },
    "event.mode.update": {
      "description": "`mode.update` (5.11): Renames or reorders the mode. Skipped when there is no such collection or mode.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `mode.update`.",
          "const": "mode.update"
        },
        "collectionId": {
          "description": "The collection.",
          "$ref": "#/$defs/variableCollectionId"
        },
        "id": {
          "description": "The mode.",
          "$ref": "#/$defs/modeId"
        },
        "set": {
          "description": "The merge patch.",
          "$ref": "#/$defs/modePatch"
        }
      },
      "required": [
        "op",
        "collectionId",
        "id",
        "set"
      ]
    },
    "event.mode.delete": {
      "description": "`mode.delete` (5.11): Removes the mode and the values for it; `explicitVariableModes` naming it fall back to the default mode. Skipped when there is no such collection or mode, it is the last mode, or it is the `defaultModeId`.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `mode.delete`.",
          "const": "mode.delete"
        },
        "collectionId": {
          "description": "The collection.",
          "$ref": "#/$defs/variableCollectionId"
        },
        "id": {
          "description": "The mode.",
          "$ref": "#/$defs/modeId"
        }
      },
      "required": [
        "op",
        "collectionId",
        "id"
      ]
    },
    "event.variable.create": {
      "description": "`variable.create` (5.11): Adds the variable. Skipped when the id exists, there is no such collection, or the name is taken in the collection.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `variable.create`.",
          "const": "variable.create"
        },
        "variable": {
          "description": "The new variable with `id`, `name`, `variableCollectionId`, `resolvedType`, `index`.",
          "type": "object",
          "$ref": "#/$defs/variable",
          "properties": {
            "id": {
              "description": "The new variable id.",
              "$ref": "#/$defs/variableId"
            }
          },
          "required": [
            "id"
          ]
        }
      },
      "required": [
        "op",
        "variable"
      ]
    },
    "event.variable.update": {
      "description": "`variable.update` (5.11): Merge patch; `valuesByMode` merges per mode. Skipped when there is no such variable, `set.resolvedType` differs, or an alias in `set` would make a cycle.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `variable.update`.",
          "const": "variable.update"
        },
        "id": {
          "description": "The variable.",
          "$ref": "#/$defs/variableId"
        },
        "set": {
          "description": "The merge patch.",
          "$ref": "#/$defs/variablePatch"
        }
      },
      "required": [
        "op",
        "id",
        "set"
      ]
    },
    "event.variable.delete": {
      "description": "`variable.delete` (5.11): Removes the variable. Bindings and aliases fall back to plain values or the type's zero. Skipped when there is no such variable.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `variable.delete`.",
          "const": "variable.delete"
        },
        "id": {
          "description": "The variable.",
          "$ref": "#/$defs/variableId"
        }
      },
      "required": [
        "op",
        "id"
      ]
    },
    "event.library.add": {
      "description": "`library.add` (5.11): Adds a library reference. Skipped when the id exists.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `library.add`.",
          "const": "library.add"
        },
        "library": {
          "description": "The library with `id`, `path`, `documentId`; optional `imported`, `acceptedHash`.",
          "type": "object",
          "$ref": "#/$defs/library",
          "properties": {
            "id": {
              "description": "The new library reference id.",
              "$ref": "#/$defs/libraryId"
            }
          },
          "required": [
            "id"
          ]
        }
      },
      "required": [
        "op",
        "library"
      ]
    },
    "event.library.update": {
      "description": "`library.update` (5.11): Merge patch (`path` after a move, `enabled`, `name`). Skipped when there is no such library.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `library.update`.",
          "const": "library.update"
        },
        "id": {
          "description": "The library reference.",
          "$ref": "#/$defs/libraryId"
        },
        "set": {
          "description": "The merge patch.",
          "$ref": "#/$defs/libraryPatch"
        }
      },
      "required": [
        "op",
        "id",
        "set"
      ]
    },
    "event.library.accept": {
      "description": "`library.accept` (5.11): Accepts an update of the library (VAR-8), or starts using another item of it. Skipped when there is no such library.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `library.accept`.",
          "const": "library.accept"
        },
        "id": {
          "description": "The library reference.",
          "$ref": "#/$defs/libraryId"
        },
        "acceptedHash": {
          "description": "The library's tree hash now accepted: the state the copies were taken from.",
          "$ref": "#/$defs/treeHash"
        },
        "imported": {
          "description": "A merge patch of the copies: each entry given replaces the copy, `null` removes it.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "nodes": {
              "description": "Copies of the library's nodes this file uses, keyed by the library's ids. Each entry given replaces the copy; `null` removes it.",
              "type": "object",
              "additionalProperties": {
                "description": "The new copy, or `null` to remove it.",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/$defs/node"
                  }
                ],
                "x-merge": "replace"
              },
              "x-merge": "merge"
            },
            "styles": {
              "description": "Copies of the library's styles this file uses, keyed by the library's ids. Each entry given replaces the copy; `null` removes it.",
              "type": "object",
              "additionalProperties": {
                "description": "The new copy, or `null` to remove it.",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/$defs/style"
                  }
                ],
                "x-merge": "replace"
              },
              "x-merge": "merge"
            },
            "variableCollections": {
              "description": "Copies of the library's variable collections this file uses, keyed by the library's ids. Each entry given replaces the copy; `null` removes it.",
              "type": "object",
              "additionalProperties": {
                "description": "The new copy, or `null` to remove it.",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/$defs/variableCollection"
                  }
                ],
                "x-merge": "replace"
              },
              "x-merge": "merge"
            },
            "variables": {
              "description": "Copies of the library's variables this file uses, keyed by the library's ids. Each entry given replaces the copy; `null` removes it.",
              "type": "object",
              "additionalProperties": {
                "description": "The new copy, or `null` to remove it.",
                "anyOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/$defs/variable"
                  }
                ],
                "x-merge": "replace"
              },
              "x-merge": "merge"
            }
          },
          "x-merge": "merge"
        }
      },
      "required": [
        "op",
        "id",
        "acceptedHash",
        "imported"
      ]
    },
    "event.library.remove": {
      "description": "`library.remove` (5.11): Removes the reference and its copies. References that still use it fall back to plain values; instances show \"Missing component\". Skipped when there is no such library.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `library.remove`.",
          "const": "library.remove"
        },
        "id": {
          "description": "The library reference.",
          "$ref": "#/$defs/libraryId"
        }
      },
      "required": [
        "op",
        "id"
      ]
    },
    "event.flow.create": {
      "description": "`flow.create` (5.11): Adds a flow starting point (PRO-6). Skipped when the id exists or there is no such page.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `flow.create`.",
          "const": "flow.create"
        },
        "flow": {
          "description": "The new flow with `id`, `pageId`, `name`, `index`, `nodeId`.",
          "type": "object",
          "$ref": "#/$defs/flow",
          "properties": {
            "id": {
              "description": "The new flow id.",
              "$ref": "#/$defs/flowId"
            }
          },
          "required": [
            "id"
          ]
        }
      },
      "required": [
        "op",
        "flow"
      ]
    },
    "event.flow.update": {
      "description": "`flow.update` (5.11): Merge patch. Skipped when there is no such flow.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `flow.update`.",
          "const": "flow.update"
        },
        "id": {
          "description": "The flow.",
          "$ref": "#/$defs/flowId"
        },
        "set": {
          "description": "The merge patch.",
          "$ref": "#/$defs/flowPatch"
        }
      },
      "required": [
        "op",
        "id",
        "set"
      ]
    },
    "event.flow.delete": {
      "description": "`flow.delete` (5.11): Removes the flow. Skipped when there is no such flow.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `flow.delete`.",
          "const": "flow.delete"
        },
        "id": {
          "description": "The flow.",
          "$ref": "#/$defs/flowId"
        }
      },
      "required": [
        "op",
        "id"
      ]
    },
    "event.comment.add": {
      "description": "`comment.add` (5.11): Adds a thread or a reply; `by` and `at` come from the envelope. Skipped when the id exists or `parentId` names no thread.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `comment.add`.",
          "const": "comment.add"
        },
        "comment": {
          "description": "The new comment with `id`, `message`, and `anchor` (a thread) or `parentId` (a reply); optional `mentions`.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "id": {
              "description": "The new comment id.",
              "$ref": "#/$defs/commentId"
            },
            "message": {
              "description": "Text; mentions are written `@<name>`. Required.",
              "type": "string"
            },
            "anchor": {
              "description": "Where a thread is pinned: `{\"nodeId\": id, \"offset\": {x, y}}` on a node, or `{\"pageId\": id, \"x\": n, \"y\": n}` on the canvas. Required for a thread, absent for replies. Replaced whole by a patch.",
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "nodeId": {
                  "description": "The node the thread is pinned to.",
                  "$ref": "#/$defs/nodeRef"
                },
                "offset": {
                  "description": "Offset from the node's origin, px.",
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "x": {
                      "description": "Horizontal component, px.",
                      "type": "number"
                    },
                    "y": {
                      "description": "Vertical component, px.",
                      "type": "number"
                    }
                  },
                  "required": [
                    "x",
                    "y"
                  ],
                  "x-merge": "replace"
                },
                "pageId": {
                  "description": "The page of a thread pinned to a point of the canvas.",
                  "$ref": "#/$defs/pageId"
                },
                "x": {
                  "description": "Canvas x of a thread pinned to a point, px.",
                  "type": "number"
                },
                "y": {
                  "description": "Canvas y of a thread pinned to a point, px.",
                  "type": "number"
                }
              },
              "anyOf": [
                {
                  "type": "object",
                  "properties": {
                    "nodeId": {
                      "description": "`nodeId`, as declared above; required in this alternative."
                    }
                  },
                  "required": [
                    "nodeId"
                  ]
                },
                {
                  "type": "object",
                  "properties": {
                    "pageId": {
                      "description": "`pageId`, as declared above; required in this alternative."
                    },
                    "x": {
                      "description": "`x`, as declared above; required in this alternative."
                    },
                    "y": {
                      "description": "`y`, as declared above; required in this alternative."
                    }
                  },
                  "required": [
                    "pageId",
                    "x",
                    "y"
                  ]
                }
              ],
              "x-merge": "replace"
            },
            "parentId": {
              "description": "Absent for the first comment of a thread; the thread's first comment for a reply.",
              "$ref": "#/$defs/commentId"
            },
            "mentions": {
              "description": "Names mentioned. Default `[]`.",
              "type": "array",
              "items": {
                "description": "A name (git author).",
                "type": "string"
              }
            },
            "meta": {
              "description": "UI Designer extension of 4.13 for review findings (the ui-designer-review skill and `ud lint`): `category`, `severity`, `findingId`. Absent by default; readers that do not know it keep it. Merged by a patch.",
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "category": {
                  "description": "The review area of a finding, e.g. `contrast`, `naming`, `spacing`.",
                  "type": "string"
                },
                "severity": {
                  "description": "How serious the finding is.",
                  "type": "string",
                  "enum": [
                    "info",
                    "warning",
                    "error"
                  ]
                },
                "findingId": {
                  "description": "The id of the lint finding or review check the comment reports, so a later review updates the thread instead of adding another.",
                  "type": "string"
                }
              },
              "x-merge": "merge"
            }
          },
          "required": [
            "id",
            "message"
          ],
          "allOf": [
            {
              "if": {
                "type": "object",
                "properties": {
                  "parentId": {}
                },
                "required": [
                  "parentId"
                ]
              },
              "then": {
                "type": "object",
                "not": {
                  "type": "object",
                  "properties": {
                    "anchor": {
                      "description": "`anchor`, as declared above; required in this alternative."
                    }
                  },
                  "required": [
                    "anchor"
                  ]
                }
              },
              "else": {
                "type": "object",
                "properties": {
                  "anchor": {
                    "description": "`anchor`, as declared above; required in this alternative."
                  }
                },
                "required": [
                  "anchor"
                ]
              }
            }
          ]
        }
      },
      "required": [
        "op",
        "comment"
      ]
    },
    "event.comment.update": {
      "description": "`comment.update` (5.11): Merge patch; sets `editedAt` to the event's `at` when `message` changes. Skipped when there is no such comment.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `comment.update`.",
          "const": "comment.update"
        },
        "id": {
          "description": "The comment.",
          "$ref": "#/$defs/commentId"
        },
        "set": {
          "description": "The merge patch (`message`, `anchor`, `mentions`, `resolved`).",
          "$ref": "#/$defs/commentPatch"
        }
      },
      "required": [
        "op",
        "id",
        "set"
      ]
    },
    "event.comment.react": {
      "description": "`comment.react` (5.11): Adds (`on: true`) or removes the event's `by` from `reactions[reaction]`. Separate from `comment.update` so that reactions of two people on two branches both survive. Skipped when there is no such comment.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `comment.react`.",
          "const": "comment.react"
        },
        "id": {
          "description": "The comment.",
          "$ref": "#/$defs/commentId"
        },
        "reaction": {
          "description": "The reaction, a short code without colons, e.g. `+1`.",
          "type": "string",
          "minLength": 1
        },
        "on": {
          "description": "`true` adds the reaction, `false` removes it.",
          "type": "boolean"
        }
      },
      "required": [
        "op",
        "id",
        "reaction",
        "on"
      ]
    },
    "event.comment.delete": {
      "description": "`comment.delete` (5.11): Removes the comment; for a thread, also its replies. Skipped when there is no such comment.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `comment.delete`.",
          "const": "comment.delete"
        },
        "id": {
          "description": "The comment.",
          "$ref": "#/$defs/commentId"
        }
      },
      "required": [
        "op",
        "id"
      ]
    },
    "event.version.save": {
      "description": "`version.save` (5.11): Adds a named version at this event's `seq` (COL-2). Skipped when the id exists.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `version.save`.",
          "const": "version.save"
        },
        "version": {
          "description": "The version `{id, title, description, treeHash}`.",
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "id": {
              "description": "The new version id.",
              "$ref": "#/$defs/versionId"
            },
            "title": {
              "description": "Title. Required.",
              "type": "string"
            },
            "description": {
              "description": "Description. Default `\"\"`.",
              "type": "string"
            },
            "treeHash": {
              "description": "The tree hash (6.9) of the document just before the `version.save` event: every earlier event folded. Written by the writer of the event; a reader computes a missing one while folding, with a warning.",
              "$ref": "#/$defs/treeHash"
            }
          },
          "required": [
            "id",
            "title"
          ]
        }
      },
      "required": [
        "op",
        "version"
      ]
    },
    "event.version.update": {
      "description": "`version.update` (5.11): Merge patch. Skipped when there is no such version.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `version.update`.",
          "const": "version.update"
        },
        "id": {
          "description": "The named version.",
          "$ref": "#/$defs/versionId"
        },
        "set": {
          "description": "The merge patch (`title`, `description`).",
          "$ref": "#/$defs/versionPatch"
        }
      },
      "required": [
        "op",
        "id",
        "set"
      ]
    },
    "event.version.delete": {
      "description": "`version.delete` (5.11): Removes the named version (not the changes). Skipped when there is no such version.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `version.delete`.",
          "const": "version.delete"
        },
        "id": {
          "description": "The named version.",
          "$ref": "#/$defs/versionId"
        }
      },
      "required": [
        "op",
        "id"
      ]
    },
    "event.asset.add": {
      "description": "`asset.add` (5.11): Registers the metadata of a file in the assets folder; the writer writes the file before the event (8.4). Never skipped; a second `asset.add` of the same hash replaces the metadata. No event removes an asset.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "The operation: `asset.add`.",
          "const": "asset.add"
        },
        "asset": {
          "description": "The metadata `{hash, kind, mime, ext, bytes, …}` (4.15).",
          "type": "object",
          "$ref": "#/$defs/asset",
          "properties": {
            "hash": {
              "description": "The content hash of the file.",
              "$ref": "#/$defs/assetHash"
            },
            "kind": {
              "description": "`kind`, as declared in `asset`; required here."
            },
            "mime": {
              "description": "`mime`, as declared in `asset`; required here."
            },
            "ext": {
              "description": "`ext`, as declared in `asset`; required here."
            },
            "bytes": {
              "description": "`bytes`, as declared in `asset`; required here."
            }
          },
          "required": [
            "hash",
            "kind",
            "mime",
            "ext",
            "bytes"
          ]
        }
      },
      "required": [
        "op",
        "asset"
      ]
    },
    "event.unknown": {
      "description": "An event whose `op` is not a known operation (5.12), e.g. one written by a newer build. Valid: a reader skips it with the warning \"Skipped event <seq> (<op>): this build does not know the operation.\", still advances `seq`, and keeps the line. Do not invent operations: a misspelled `op` lands here and does nothing.",
      "type": "object",
      "$ref": "#/$defs/envelope",
      "properties": {
        "op": {
          "description": "An operation this schema does not know.",
          "type": "string",
          "not": {
            "enum": [
              "document.update",
              "page.create",
              "page.update",
              "page.reorder",
              "page.delete",
              "node.create",
              "node.update",
              "node.move",
              "node.reorder",
              "node.delete",
              "component.create",
              "component.combine",
              "component.restore",
              "component.property.set",
              "component.property.delete",
              "instance.override",
              "instance.reset",
              "instance.swap",
              "instance.detach",
              "style.create",
              "style.update",
              "style.delete",
              "collection.create",
              "collection.update",
              "collection.delete",
              "mode.create",
              "mode.update",
              "mode.delete",
              "variable.create",
              "variable.update",
              "variable.delete",
              "library.add",
              "library.update",
              "library.accept",
              "library.remove",
              "flow.create",
              "flow.update",
              "flow.delete",
              "comment.add",
              "comment.update",
              "comment.react",
              "comment.delete",
              "version.save",
              "version.update",
              "version.delete",
              "asset.add",
              "wal.base"
            ]
          }
        }
      }
    },
    "walEntry": {
      "description": "One entry of `wal`, dispatched on `op`: the `wal.base` marker, one of the known events (each validated by `event.<op>`), or `event.unknown`. A known `op` with a wrong payload is invalid; an unknown `op` is valid.",
      "type": "object",
      "required": [
        "op"
      ],
      "properties": {
        "op": {
          "description": "Tells the entries apart.",
          "type": "string"
        }
      },
      "if": {
        "type": "object",
        "properties": {
          "op": {
            "const": "wal.base"
          }
        },
        "required": [
          "op"
        ]
      },
      "then": {
        "$ref": "#/$defs/walBase"
      },
      "else": {
        "if": {
          "type": "object",
          "properties": {
            "op": {
              "enum": [
                "document.update",
                "page.create",
                "page.update",
                "page.reorder",
                "page.delete",
                "node.create",
                "node.update",
                "node.move",
                "node.reorder",
                "node.delete",
                "component.create",
                "component.combine",
                "component.restore",
                "component.property.set",
                "component.property.delete",
                "instance.override",
                "instance.reset",
                "instance.swap",
                "instance.detach",
                "style.create",
                "style.update",
                "style.delete",
                "collection.create",
                "collection.update",
                "collection.delete",
                "mode.create",
                "mode.update",
                "mode.delete",
                "variable.create",
                "variable.update",
                "variable.delete",
                "library.add",
                "library.update",
                "library.accept",
                "library.remove",
                "flow.create",
                "flow.update",
                "flow.delete",
                "comment.add",
                "comment.update",
                "comment.react",
                "comment.delete",
                "version.save",
                "version.update",
                "version.delete",
                "asset.add"
              ]
            }
          },
          "required": [
            "op"
          ]
        },
        "then": {
          "allOf": [
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "document.update"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.document.update"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "page.create"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.page.create"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "page.update"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.page.update"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "page.reorder"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.page.reorder"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "page.delete"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.page.delete"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "node.create"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.node.create"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "node.update"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.node.update"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "node.move"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.node.move"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "node.reorder"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.node.reorder"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "node.delete"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.node.delete"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "component.create"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.component.create"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "component.combine"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.component.combine"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "component.restore"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.component.restore"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "component.property.set"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.component.property.set"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "component.property.delete"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.component.property.delete"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "instance.override"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.instance.override"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "instance.reset"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.instance.reset"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "instance.swap"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.instance.swap"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "instance.detach"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.instance.detach"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "style.create"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.style.create"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "style.update"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.style.update"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "style.delete"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.style.delete"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "collection.create"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.collection.create"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "collection.update"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.collection.update"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "collection.delete"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.collection.delete"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "mode.create"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.mode.create"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "mode.update"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.mode.update"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "mode.delete"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.mode.delete"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "variable.create"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.variable.create"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "variable.update"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.variable.update"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "variable.delete"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.variable.delete"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "library.add"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.library.add"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "library.update"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.library.update"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "library.accept"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.library.accept"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "library.remove"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.library.remove"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "flow.create"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.flow.create"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "flow.update"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.flow.update"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "flow.delete"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.flow.delete"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "comment.add"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.comment.add"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "comment.update"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.comment.update"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "comment.react"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.comment.react"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "comment.delete"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.comment.delete"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "version.save"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.version.save"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "version.update"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.version.update"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "version.delete"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.version.delete"
              }
            },
            {
              "if": {
                "type": "object",
                "properties": {
                  "op": {
                    "const": "asset.add"
                  }
                },
                "required": [
                  "op"
                ]
              },
              "then": {
                "$ref": "#/$defs/event.asset.add"
              }
            }
          ]
        },
        "else": {
          "$ref": "#/$defs/event.unknown"
        }
      }
    },
    "designFile": {
      "description": "A `.design` file (section 3): one UTF-8 JSON object with `$schema`, `$comment`, `designVersion`, `tree` and `wal`, in that order. Members a reader does not know are kept.",
      "type": "object",
      "additionalProperties": true,
      "required": [
        "designVersion",
        "tree",
        "wal"
      ],
      "properties": {
        "$schema": {
          "description": "URL of this JSON Schema. Editors use it for completion and validation; readers ignore it.",
          "type": "string",
          "format": "uri"
        },
        "$comment": {
          "description": "Instructions for agents and people who open the file as text, verbatim: \"SoftForge UI Designer design file (FMT-001). Do not edit `tree`. To change the design, append one event per line to `wal`, starting the line with a comma, or use the `ud` command.\"",
          "type": "string"
        },
        "designVersion": {
          "description": "Format version, `\"<major>.<minor>\"`. This schema describes `\"1.0\"`. Read before anything else (section 10).",
          "const": "1.0"
        },
        "tree": {
          "description": "The consolidated document (section 4). Do not edit it.",
          "$ref": "#/$defs/tree"
        },
        "wal": {
          "description": "The write-append list (section 5): the `wal.base` marker followed by the events since the last consolidation, applied in file order. On disk each entry is one line; each event line starts with four spaces and a comma. To change the design, insert a line before the closing `]`; never change an existing line.",
          "type": "array",
          "prefixItems": [
            {
              "description": "The first entry: the `wal.base` marker.",
              "$ref": "#/$defs/walBase"
            }
          ],
          "items": {
            "description": "One event, on its own line starting with a comma.",
            "$ref": "#/$defs/walEntry"
          },
          "minItems": 1
        }
      }
    }
  }
}
