{
  "openapi": "3.1.1",
  "info": {
    "title": "Xsheet to Drawing Project API",
    "version": "1.0.0",
    "summary": "Compile reference-based layer timing into an editable Flipline drawing project.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://fliplinexsheetcompiler.usefulweb.app"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Compile reference-based layer timing into an editable Flipline drawing project.",
        "description": "Paste an Xsheet project containing source drawings and independent layer exposures. Merge matching composite ticks, split long holds and download a standard Flipline drawing project. References remain editable in the original Xsheet file; compiled drawings are independent snapshots.\n\nMethodology:\n- Parse the flipline-xsheet version 1 format, including a valid Flipline drawing project, equal-length exposure columns and references from zero to the source drawing count. Each source layer has exactly one column.\n- Merge adjacent identical reference tuples. Split composite holds into chunks of at most ten ticks. Reject more than 24 resulting drawing frames instead of truncating timing.\n- Copy each referenced source cel into the resulting drawing frame. Zero becomes an empty cel. Preserve layer order, visibility, locks, opacity, paper, canvas settings, brushes, pressure, image sources and mark transforms. The source project and exposure cells are not mutated.\n- The fully expanded result must also fit the drawing-board budgets of 2000 marks, 50000 points, 240000 brush dabs and 8 million embedded source characters. Repeated image sources count each time as in ordinary Flipline projects. Input text is limited to 1 million characters; the browser Xsheet workspace accepts larger local project files up to 16 MB.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "flipline_xsheet_compiler",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FliplineXsheetCompilerInput"
              },
              "examples": {
                "example1": {
                  "summary": "Compile the original paper-bird timing study",
                  "value": {
                    "project": "{\"format\":\"flipline-xsheet\",\"version\":1,\"name\":\"Paper bird\",\"fps\":12,\"source\":{\"format\":\"flipline\",\"version\":1,\"name\":\"Paper bird\",\"width\":960,\"height\":540,\"fps\":12,\"background\":\"#FFFAF0\",\"transparent\":false,\"paper\":\"plain\",\"frames\":[{\"id\":\"drawing-1\",\"hold\":2,\"label\":\"\"},{\"id\":\"drawing-2\",\"hold\":2,\"label\":\"\"},{\"id\":\"drawing-3\",\"hold\":2,\"label\":\"\"},{\"id\":\"drawing-4\",\"hold\":2,\"label\":\"\"}],\"layers\":[{\"id\":\"action\",\"name\":\"Bird\",\"visible\":true,\"locked\":false,\"opacity\":1,\"cels\":[[{\"id\":\"tail\",\"kind\":\"pen\",\"color\":\"#304F57\",\"size\":10,\"fill\":false,\"points\":[[0.39,0.53],[0.28,0.48],[0.32,0.58]]},{\"id\":\"body\",\"kind\":\"ellipse\",\"color\":\"#304F57\",\"size\":3,\"fill\":true,\"points\":[[0.37,0.43],[0.59,0.59]]},{\"id\":\"head\",\"kind\":\"ellipse\",\"color\":\"#304F57\",\"size\":3,\"fill\":true,\"points\":[[0.55,0.39],[0.66,0.5]]},{\"id\":\"beak\",\"kind\":\"pen\",\"color\":\"#D8AB5B\",\"size\":7,\"fill\":false,\"points\":[[0.655,0.43],[0.7,0.45],[0.65,0.47]]},{\"id\":\"eye\",\"kind\":\"ellipse\",\"color\":\"#FFFAF0\",\"size\":3,\"fill\":true,\"points\":[[0.62,0.418],[0.631,0.432]]},{\"id\":\"wing\",\"kind\":\"pen\",\"color\":\"#B66645\",\"size\":24,\"fill\":false,\"points\":[[0.47,0.49],[0.38,0.24]]},{\"id\":\"fold\",\"kind\":\"pen\",\"color\":\"#E7BC82\",\"size\":5,\"fill\":false,\"points\":[[0.47,0.49],[0.42,0.27999999999999997]]}],[{\"id\":\"tail\",\"kind\":\"pen\",\"color\":\"#304F57\",\"size\":10,\"fill\":false,\"points\":[[0.39,0.53],[0.28,0.48],[0.32,0.58]]},{\"id\":\"body\",\"kind\":\"ellipse\",\"color\":\"#304F57\",\"size\":3,\"fill\":true,\"points\":[[0.37,0.43],[0.59,0.59]]},{\"id\":\"head\",\"kind\":\"ellipse\",\"color\":\"#304F57\",\"size\":3,\"fill\":true,\"points\":[[0.55,0.39],[0.66,0.5]]},{\"id\":\"beak\",\"kind\":\"pen\",\"color\":\"#D8AB5B\",\"size\":7,\"fill\":false,\"points\":[[0.655,0.43],[0.7,0.45],[0.65,0.47]]},{\"id\":\"eye\",\"kind\":\"ellipse\",\"color\":\"#FFFAF0\",\"size\":3,\"fill\":true,\"points\":[[0.62,0.418],[0.631,0.432]]},{\"id\":\"wing\",\"kind\":\"pen\",\"color\":\"#B66645\",\"size\":24,\"fill\":false,\"points\":[[0.47,0.49],[0.32,0.42]]},{\"id\":\"fold\",\"kind\":\"pen\",\"color\":\"#E7BC82\",\"size\":5,\"fill\":false,\"points\":[[0.47,0.49],[0.36,0.45999999999999996]]}],[{\"id\":\"tail\",\"kind\":\"pen\",\"color\":\"#304F57\",\"size\":10,\"fill\":false,\"points\":[[0.39,0.53],[0.28,0.48],[0.32,0.58]]},{\"id\":\"body\",\"kind\":\"ellipse\",\"color\":\"#304F57\",\"size\":3,\"fill\":true,\"points\":[[0.37,0.43],[0.59,0.59]]},{\"id\":\"head\",\"kind\":\"ellipse\",\"color\":\"#304F57\",\"size\":3,\"fill\":true,\"points\":[[0.55,0.39],[0.66,0.5]]},{\"id\":\"beak\",\"kind\":\"pen\",\"color\":\"#D8AB5B\",\"size\":7,\"fill\":false,\"points\":[[0.655,0.43],[0.7,0.45],[0.65,0.47]]},{\"id\":\"eye\",\"kind\":\"ellipse\",\"color\":\"#FFFAF0\",\"size\":3,\"fill\":true,\"points\":[[0.62,0.418],[0.631,0.432]]},{\"id\":\"wing\",\"kind\":\"pen\",\"color\":\"#B66645\",\"size\":24,\"fill\":false,\"points\":[[0.47,0.49],[0.4,0.72]]},{\"id\":\"fold\",\"kind\":\"pen\",\"color\":\"#E7BC82\",\"size\":5,\"fill\":false,\"points\":[[0.47,0.49],[0.44,0.76]]}],[{\"id\":\"tail\",\"kind\":\"pen\",\"color\":\"#304F57\",\"size\":10,\"fill\":false,\"points\":[[0.39,0.53],[0.28,0.48],[0.32,0.58]]},{\"id\":\"body\",\"kind\":\"ellipse\",\"color\":\"#304F57\",\"size\":3,\"fill\":true,\"points\":[[0.37,0.43],[0.59,0.59]]},{\"id\":\"head\",\"kind\":\"ellipse\",\"color\":\"#304F57\",\"size\":3,\"fill\":true,\"points\":[[0.55,0.39],[0.66,0.5]]},{\"id\":\"beak\",\"kind\":\"pen\",\"color\":\"#D8AB5B\",\"size\":7,\"fill\":false,\"points\":[[0.655,0.43],[0.7,0.45],[0.65,0.47]]},{\"id\":\"eye\",\"kind\":\"ellipse\",\"color\":\"#FFFAF0\",\"size\":3,\"fill\":true,\"points\":[[0.62,0.418],[0.631,0.432]]},{\"id\":\"wing\",\"kind\":\"pen\",\"color\":\"#B66645\",\"size\":24,\"fill\":false,\"points\":[[0.47,0.49],[0.52,0.28]]},{\"id\":\"fold\",\"kind\":\"pen\",\"color\":\"#E7BC82\",\"size\":5,\"fill\":false,\"points\":[[0.47,0.49],[0.56,0.32]]}]]},{\"id\":\"atmosphere\",\"name\":\"Clouds\",\"visible\":true,\"locked\":false,\"opacity\":1,\"cels\":[[{\"id\":\"cloud-a\",\"kind\":\"ellipse\",\"color\":\"#D8E2D9\",\"size\":3,\"fill\":true,\"points\":[[0.12,0.18],[0.28,0.24]]},{\"id\":\"cloud-b\",\"kind\":\"ellipse\",\"color\":\"#D8E2D9\",\"size\":3,\"fill\":true,\"points\":[[0.16999999999999998,0.15],[0.25,0.25]]},{\"id\":\"cloud-c\",\"kind\":\"ellipse\",\"color\":\"#D8E2D9\",\"size\":3,\"fill\":true,\"points\":[[0.74,0.3],[0.89,0.345]]}],[{\"id\":\"cloud-a\",\"kind\":\"ellipse\",\"color\":\"#D8E2D9\",\"size\":3,\"fill\":true,\"points\":[[0.145,0.18],[0.305,0.24]]},{\"id\":\"cloud-b\",\"kind\":\"ellipse\",\"color\":\"#D8E2D9\",\"size\":3,\"fill\":true,\"points\":[[0.195,0.15],[0.275,0.25]]},{\"id\":\"cloud-c\",\"kind\":\"ellipse\",\"color\":\"#D8E2D9\",\"size\":3,\"fill\":true,\"points\":[[0.72,0.3],[0.87,0.345]]}],[{\"id\":\"cloud-a\",\"kind\":\"ellipse\",\"color\":\"#D8E2D9\",\"size\":3,\"fill\":true,\"points\":[[0.16999999999999998,0.18],[0.32999999999999996,0.24]]},{\"id\":\"cloud-b\",\"kind\":\"ellipse\",\"color\":\"#D8E2D9\",\"size\":3,\"fill\":true,\"points\":[[0.21999999999999997,0.15],[0.3,0.25]]},{\"id\":\"cloud-c\",\"kind\":\"ellipse\",\"color\":\"#D8E2D9\",\"size\":3,\"fill\":true,\"points\":[[0.7,0.3],[0.85,0.345]]}],[{\"id\":\"cloud-a\",\"kind\":\"ellipse\",\"color\":\"#D8E2D9\",\"size\":3,\"fill\":true,\"points\":[[0.195,0.18],[0.355,0.24]]},{\"id\":\"cloud-b\",\"kind\":\"ellipse\",\"color\":\"#D8E2D9\",\"size\":3,\"fill\":true,\"points\":[[0.245,0.15],[0.325,0.25]]},{\"id\":\"cloud-c\",\"kind\":\"ellipse\",\"color\":\"#D8E2D9\",\"size\":3,\"fill\":true,\"points\":[[0.6799999999999999,0.3],[0.83,0.345]]}]]},{\"id\":\"scenery\",\"name\":\"Scenery\",\"visible\":true,\"locked\":false,\"opacity\":1,\"cels\":[[{\"id\":\"ground\",\"kind\":\"rect\",\"color\":\"#DED9C2\",\"size\":3,\"fill\":true,\"points\":[[0,0.83],[1,1]]},{\"id\":\"sun\",\"kind\":\"ellipse\",\"color\":\"#D8AB5B\",\"size\":3,\"fill\":true,\"points\":[[0.78,0.08],[0.875,0.25]]},{\"id\":\"hill\",\"kind\":\"pen\",\"color\":\"#9FB5A2\",\"size\":45,\"fill\":false,\"points\":[[0,0.87],[0.16,0.77],[0.33,0.88],[0.72,0.76],[1,0.85]]}],[{\"id\":\"ground\",\"kind\":\"rect\",\"color\":\"#DED9C2\",\"size\":3,\"fill\":true,\"points\":[[0,0.83],[1,1]]},{\"id\":\"sun\",\"kind\":\"ellipse\",\"color\":\"#D8AB5B\",\"size\":3,\"fill\":true,\"points\":[[0.78,0.08],[0.875,0.25]]},{\"id\":\"hill\",\"kind\":\"pen\",\"color\":\"#9FB5A2\",\"size\":45,\"fill\":false,\"points\":[[0,0.87],[0.16,0.77],[0.33,0.88],[0.72,0.76],[1,0.85]]}],[{\"id\":\"ground\",\"kind\":\"rect\",\"color\":\"#DED9C2\",\"size\":3,\"fill\":true,\"points\":[[0,0.83],[1,1]]},{\"id\":\"sun\",\"kind\":\"ellipse\",\"color\":\"#D8AB5B\",\"size\":3,\"fill\":true,\"points\":[[0.78,0.08],[0.875,0.25]]},{\"id\":\"hill\",\"kind\":\"pen\",\"color\":\"#9FB5A2\",\"size\":45,\"fill\":false,\"points\":[[0,0.87],[0.16,0.77],[0.33,0.88],[0.72,0.76],[1,0.85]]}],[{\"id\":\"ground\",\"kind\":\"rect\",\"color\":\"#DED9C2\",\"size\":3,\"fill\":true,\"points\":[[0,0.83],[1,1]]},{\"id\":\"sun\",\"kind\":\"ellipse\",\"color\":\"#D8AB5B\",\"size\":3,\"fill\":true,\"points\":[[0.78,0.08],[0.875,0.25]]},{\"id\":\"hill\",\"kind\":\"pen\",\"color\":\"#9FB5A2\",\"size\":45,\"fill\":false,\"points\":[[0,0.87],[0.16,0.77],[0.33,0.88],[0.72,0.76],[1,0.85]]}]]}]},\"cells\":[[1,1,2,2,3,3,4,4,3,3,2,2,1,1,2,2,3,3,4,4,3,3,2,2,1,1,2,2,3,3,4,4,3,3,2,2,1,1,2,2,3,3,4,4,3,3,2,2],[1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]]}"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FliplineXsheetCompilerResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "FliplineXsheetCompilerInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "project": {
            "title": "Xsheet project JSON (up to 1 million characters)",
            "type": "string",
            "maxLength": 1000000,
            "default": "{\n  \"format\": \"flipline-xsheet\",\n  \"version\": 1,\n  \"name\": \"Paper bird\",\n  \"fps\": 12,\n  \"source\": {\n    \"format\": \"flipline\",\n    \"version\": 1,\n    \"name\": \"Paper bird\",\n    \"width\": 960,\n    \"height\": 540,\n    \"fps\": 12,\n    \"background\": \"#FFFAF0\",\n    \"transparent\": false,\n    \"paper\": \"plain\",\n    \"frames\": [\n      {\n        \"id\": \"drawing-1\",\n        \"hold\": 2,\n        \"label\": \"\"\n      },\n      {\n        \"id\": \"drawing-2\",\n        \"hold\": 2,\n        \"label\": \"\"\n      },\n      {\n        \"id\": \"drawing-3\",\n        \"hold\": 2,\n        \"label\": \"\"\n      },\n      {\n        \"id\": \"drawing-4\",\n        \"hold\": 2,\n        \"label\": \"\"\n      }\n    ],\n    \"layers\": [\n      {\n        \"id\": \"action\",\n        \"name\": \"Bird\",\n        \"visible\": true,\n        \"locked\": false,\n        \"opacity\": 1,\n        \"cels\": [\n          [\n            {\n              \"id\": \"tail\",\n              \"kind\": \"pen\",\n              \"color\": \"#304F57\",\n              \"size\": 10,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0.39,\n                  0.53\n                ],\n                [\n                  0.28,\n                  0.48\n                ],\n                [\n                  0.32,\n                  0.58\n                ]\n              ]\n            },\n            {\n              \"id\": \"body\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#304F57\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.37,\n                  0.43\n                ],\n                [\n                  0.59,\n                  0.59\n                ]\n              ]\n            },\n            {\n              \"id\": \"head\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#304F57\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.55,\n                  0.39\n                ],\n                [\n                  0.66,\n                  0.5\n                ]\n              ]\n            },\n            {\n              \"id\": \"beak\",\n              \"kind\": \"pen\",\n              \"color\": \"#D8AB5B\",\n              \"size\": 7,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0.655,\n                  0.43\n                ],\n                [\n                  0.7,\n                  0.45\n                ],\n                [\n                  0.65,\n                  0.47\n                ]\n              ]\n            },\n            {\n              \"id\": \"eye\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#FFFAF0\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.62,\n                  0.418\n                ],\n                [\n                  0.631,\n                  0.432\n                ]\n              ]\n            },\n            {\n              \"id\": \"wing\",\n              \"kind\": \"pen\",\n              \"color\": \"#B66645\",\n              \"size\": 24,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0.47,\n                  0.49\n                ],\n                [\n                  0.38,\n                  0.24\n                ]\n              ]\n            },\n            {\n              \"id\": \"fold\",\n              \"kind\": \"pen\",\n              \"color\": \"#E7BC82\",\n              \"size\": 5,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0.47,\n                  0.49\n                ],\n                [\n                  0.42,\n                  0.27999999999999997\n                ]\n              ]\n            }\n          ],\n          [\n            {\n              \"id\": \"tail\",\n              \"kind\": \"pen\",\n              \"color\": \"#304F57\",\n              \"size\": 10,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0.39,\n                  0.53\n                ],\n                [\n                  0.28,\n                  0.48\n                ],\n                [\n                  0.32,\n                  0.58\n                ]\n              ]\n            },\n            {\n              \"id\": \"body\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#304F57\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.37,\n                  0.43\n                ],\n                [\n                  0.59,\n                  0.59\n                ]\n              ]\n            },\n            {\n              \"id\": \"head\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#304F57\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.55,\n                  0.39\n                ],\n                [\n                  0.66,\n                  0.5\n                ]\n              ]\n            },\n            {\n              \"id\": \"beak\",\n              \"kind\": \"pen\",\n              \"color\": \"#D8AB5B\",\n              \"size\": 7,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0.655,\n                  0.43\n                ],\n                [\n                  0.7,\n                  0.45\n                ],\n                [\n                  0.65,\n                  0.47\n                ]\n              ]\n            },\n            {\n              \"id\": \"eye\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#FFFAF0\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.62,\n                  0.418\n                ],\n                [\n                  0.631,\n                  0.432\n                ]\n              ]\n            },\n            {\n              \"id\": \"wing\",\n              \"kind\": \"pen\",\n              \"color\": \"#B66645\",\n              \"size\": 24,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0.47,\n                  0.49\n                ],\n                [\n                  0.32,\n                  0.42\n                ]\n              ]\n            },\n            {\n              \"id\": \"fold\",\n              \"kind\": \"pen\",\n              \"color\": \"#E7BC82\",\n              \"size\": 5,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0.47,\n                  0.49\n                ],\n                [\n                  0.36,\n                  0.45999999999999996\n                ]\n              ]\n            }\n          ],\n          [\n            {\n              \"id\": \"tail\",\n              \"kind\": \"pen\",\n              \"color\": \"#304F57\",\n              \"size\": 10,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0.39,\n                  0.53\n                ],\n                [\n                  0.28,\n                  0.48\n                ],\n                [\n                  0.32,\n                  0.58\n                ]\n              ]\n            },\n            {\n              \"id\": \"body\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#304F57\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.37,\n                  0.43\n                ],\n                [\n                  0.59,\n                  0.59\n                ]\n              ]\n            },\n            {\n              \"id\": \"head\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#304F57\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.55,\n                  0.39\n                ],\n                [\n                  0.66,\n                  0.5\n                ]\n              ]\n            },\n            {\n              \"id\": \"beak\",\n              \"kind\": \"pen\",\n              \"color\": \"#D8AB5B\",\n              \"size\": 7,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0.655,\n                  0.43\n                ],\n                [\n                  0.7,\n                  0.45\n                ],\n                [\n                  0.65,\n                  0.47\n                ]\n              ]\n            },\n            {\n              \"id\": \"eye\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#FFFAF0\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.62,\n                  0.418\n                ],\n                [\n                  0.631,\n                  0.432\n                ]\n              ]\n            },\n            {\n              \"id\": \"wing\",\n              \"kind\": \"pen\",\n              \"color\": \"#B66645\",\n              \"size\": 24,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0.47,\n                  0.49\n                ],\n                [\n                  0.4,\n                  0.72\n                ]\n              ]\n            },\n            {\n              \"id\": \"fold\",\n              \"kind\": \"pen\",\n              \"color\": \"#E7BC82\",\n              \"size\": 5,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0.47,\n                  0.49\n                ],\n                [\n                  0.44,\n                  0.76\n                ]\n              ]\n            }\n          ],\n          [\n            {\n              \"id\": \"tail\",\n              \"kind\": \"pen\",\n              \"color\": \"#304F57\",\n              \"size\": 10,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0.39,\n                  0.53\n                ],\n                [\n                  0.28,\n                  0.48\n                ],\n                [\n                  0.32,\n                  0.58\n                ]\n              ]\n            },\n            {\n              \"id\": \"body\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#304F57\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.37,\n                  0.43\n                ],\n                [\n                  0.59,\n                  0.59\n                ]\n              ]\n            },\n            {\n              \"id\": \"head\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#304F57\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.55,\n                  0.39\n                ],\n                [\n                  0.66,\n                  0.5\n                ]\n              ]\n            },\n            {\n              \"id\": \"beak\",\n              \"kind\": \"pen\",\n              \"color\": \"#D8AB5B\",\n              \"size\": 7,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0.655,\n                  0.43\n                ],\n                [\n                  0.7,\n                  0.45\n                ],\n                [\n                  0.65,\n                  0.47\n                ]\n              ]\n            },\n            {\n              \"id\": \"eye\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#FFFAF0\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.62,\n                  0.418\n                ],\n                [\n                  0.631,\n                  0.432\n                ]\n              ]\n            },\n            {\n              \"id\": \"wing\",\n              \"kind\": \"pen\",\n              \"color\": \"#B66645\",\n              \"size\": 24,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0.47,\n                  0.49\n                ],\n                [\n                  0.52,\n                  0.28\n                ]\n              ]\n            },\n            {\n              \"id\": \"fold\",\n              \"kind\": \"pen\",\n              \"color\": \"#E7BC82\",\n              \"size\": 5,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0.47,\n                  0.49\n                ],\n                [\n                  0.56,\n                  0.32\n                ]\n              ]\n            }\n          ]\n        ]\n      },\n      {\n        \"id\": \"atmosphere\",\n        \"name\": \"Clouds\",\n        \"visible\": true,\n        \"locked\": false,\n        \"opacity\": 1,\n        \"cels\": [\n          [\n            {\n              \"id\": \"cloud-a\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#D8E2D9\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.12,\n                  0.18\n                ],\n                [\n                  0.28,\n                  0.24\n                ]\n              ]\n            },\n            {\n              \"id\": \"cloud-b\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#D8E2D9\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.16999999999999998,\n                  0.15\n                ],\n                [\n                  0.25,\n                  0.25\n                ]\n              ]\n            },\n            {\n              \"id\": \"cloud-c\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#D8E2D9\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.74,\n                  0.3\n                ],\n                [\n                  0.89,\n                  0.345\n                ]\n              ]\n            }\n          ],\n          [\n            {\n              \"id\": \"cloud-a\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#D8E2D9\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.145,\n                  0.18\n                ],\n                [\n                  0.305,\n                  0.24\n                ]\n              ]\n            },\n            {\n              \"id\": \"cloud-b\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#D8E2D9\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.195,\n                  0.15\n                ],\n                [\n                  0.275,\n                  0.25\n                ]\n              ]\n            },\n            {\n              \"id\": \"cloud-c\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#D8E2D9\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.72,\n                  0.3\n                ],\n                [\n                  0.87,\n                  0.345\n                ]\n              ]\n            }\n          ],\n          [\n            {\n              \"id\": \"cloud-a\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#D8E2D9\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.16999999999999998,\n                  0.18\n                ],\n                [\n                  0.32999999999999996,\n                  0.24\n                ]\n              ]\n            },\n            {\n              \"id\": \"cloud-b\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#D8E2D9\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.21999999999999997,\n                  0.15\n                ],\n                [\n                  0.3,\n                  0.25\n                ]\n              ]\n            },\n            {\n              \"id\": \"cloud-c\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#D8E2D9\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.7,\n                  0.3\n                ],\n                [\n                  0.85,\n                  0.345\n                ]\n              ]\n            }\n          ],\n          [\n            {\n              \"id\": \"cloud-a\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#D8E2D9\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.195,\n                  0.18\n                ],\n                [\n                  0.355,\n                  0.24\n                ]\n              ]\n            },\n            {\n              \"id\": \"cloud-b\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#D8E2D9\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.245,\n                  0.15\n                ],\n                [\n                  0.325,\n                  0.25\n                ]\n              ]\n            },\n            {\n              \"id\": \"cloud-c\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#D8E2D9\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.6799999999999999,\n                  0.3\n                ],\n                [\n                  0.83,\n                  0.345\n                ]\n              ]\n            }\n          ]\n        ]\n      },\n      {\n        \"id\": \"scenery\",\n        \"name\": \"Scenery\",\n        \"visible\": true,\n        \"locked\": false,\n        \"opacity\": 1,\n        \"cels\": [\n          [\n            {\n              \"id\": \"ground\",\n              \"kind\": \"rect\",\n              \"color\": \"#DED9C2\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0,\n                  0.83\n                ],\n                [\n                  1,\n                  1\n                ]\n              ]\n            },\n            {\n              \"id\": \"sun\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#D8AB5B\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.78,\n                  0.08\n                ],\n                [\n                  0.875,\n                  0.25\n                ]\n              ]\n            },\n            {\n              \"id\": \"hill\",\n              \"kind\": \"pen\",\n              \"color\": \"#9FB5A2\",\n              \"size\": 45,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0,\n                  0.87\n                ],\n                [\n                  0.16,\n                  0.77\n                ],\n                [\n                  0.33,\n                  0.88\n                ],\n                [\n                  0.72,\n                  0.76\n                ],\n                [\n                  1,\n                  0.85\n                ]\n              ]\n            }\n          ],\n          [\n            {\n              \"id\": \"ground\",\n              \"kind\": \"rect\",\n              \"color\": \"#DED9C2\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0,\n                  0.83\n                ],\n                [\n                  1,\n                  1\n                ]\n              ]\n            },\n            {\n              \"id\": \"sun\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#D8AB5B\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.78,\n                  0.08\n                ],\n                [\n                  0.875,\n                  0.25\n                ]\n              ]\n            },\n            {\n              \"id\": \"hill\",\n              \"kind\": \"pen\",\n              \"color\": \"#9FB5A2\",\n              \"size\": 45,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0,\n                  0.87\n                ],\n                [\n                  0.16,\n                  0.77\n                ],\n                [\n                  0.33,\n                  0.88\n                ],\n                [\n                  0.72,\n                  0.76\n                ],\n                [\n                  1,\n                  0.85\n                ]\n              ]\n            }\n          ],\n          [\n            {\n              \"id\": \"ground\",\n              \"kind\": \"rect\",\n              \"color\": \"#DED9C2\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0,\n                  0.83\n                ],\n                [\n                  1,\n                  1\n                ]\n              ]\n            },\n            {\n              \"id\": \"sun\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#D8AB5B\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.78,\n                  0.08\n                ],\n                [\n                  0.875,\n                  0.25\n                ]\n              ]\n            },\n            {\n              \"id\": \"hill\",\n              \"kind\": \"pen\",\n              \"color\": \"#9FB5A2\",\n              \"size\": 45,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0,\n                  0.87\n                ],\n                [\n                  0.16,\n                  0.77\n                ],\n                [\n                  0.33,\n                  0.88\n                ],\n                [\n                  0.72,\n                  0.76\n                ],\n                [\n                  1,\n                  0.85\n                ]\n              ]\n            }\n          ],\n          [\n            {\n              \"id\": \"ground\",\n              \"kind\": \"rect\",\n              \"color\": \"#DED9C2\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0,\n                  0.83\n                ],\n                [\n                  1,\n                  1\n                ]\n              ]\n            },\n            {\n              \"id\": \"sun\",\n              \"kind\": \"ellipse\",\n              \"color\": \"#D8AB5B\",\n              \"size\": 3,\n              \"fill\": true,\n              \"points\": [\n                [\n                  0.78,\n                  0.08\n                ],\n                [\n                  0.875,\n                  0.25\n                ]\n              ]\n            },\n            {\n              \"id\": \"hill\",\n              \"kind\": \"pen\",\n              \"color\": \"#9FB5A2\",\n              \"size\": 45,\n              \"fill\": false,\n              \"points\": [\n                [\n                  0,\n                  0.87\n                ],\n                [\n                  0.16,\n                  0.77\n                ],\n                [\n                  0.33,\n                  0.88\n                ],\n                [\n                  0.72,\n                  0.76\n                ],\n                [\n                  1,\n                  0.85\n                ]\n              ]\n            }\n          ]\n        ]\n      }\n    ]\n  },\n  \"cells\": [\n    [\n      1,\n      1,\n      2,\n      2,\n      3,\n      3,\n      4,\n      4,\n      3,\n      3,\n      2,\n      2,\n      1,\n      1,\n      2,\n      2,\n      3,\n      3,\n      4,\n      4,\n      3,\n      3,\n      2,\n      2,\n      1,\n      1,\n      2,\n      2,\n      3,\n      3,\n      4,\n      4,\n      3,\n      3,\n      2,\n      2,\n      1,\n      1,\n      2,\n      2,\n      3,\n      3,\n      4,\n      4,\n      3,\n      3,\n      2,\n      2\n    ],\n    [\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      2,\n      2,\n      2,\n      2,\n      2,\n      2,\n      3,\n      3,\n      3,\n      3,\n      3,\n      3,\n      4,\n      4,\n      4,\n      4,\n      4,\n      4,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      2,\n      2,\n      2,\n      2,\n      2,\n      2,\n      3,\n      3,\n      3,\n      3,\n      3,\n      3,\n      4,\n      4,\n      4,\n      4,\n      4,\n      4\n    ],\n    [\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1,\n      1\n    ]\n  ]\n}"
          }
        },
        "required": [
          "project"
        ]
      },
      "FliplineXsheetCompilerResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "format",
              "version",
              "name",
              "width",
              "height",
              "fps",
              "background",
              "transparent",
              "frames",
              "layers"
            ],
            "properties": {
              "format": {
                "const": "flipline"
              },
              "version": {
                "const": 1
              },
              "name": {
                "type": "string",
                "maxLength": 120
              },
              "width": {
                "type": "integer",
                "minimum": 32,
                "maximum": 1600
              },
              "height": {
                "type": "integer",
                "minimum": 32,
                "maximum": 1600
              },
              "fps": {
                "type": "integer",
                "minimum": 1,
                "maximum": 30
              },
              "background": {
                "type": "string",
                "pattern": "^#[a-fA-F0-9]{6}$"
              },
              "transparent": {
                "type": "boolean"
              },
              "paper": {
                "enum": [
                  "plain",
                  "grain",
                  "linen"
                ]
              },
              "frames": {
                "type": "array",
                "minItems": 1,
                "maxItems": 24,
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "hold",
                    "label"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 80
                    },
                    "hold": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 10
                    },
                    "label": {
                      "type": "string",
                      "maxLength": 80
                    }
                  }
                }
              },
              "layers": {
                "type": "array",
                "minItems": 1,
                "maxItems": 4,
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "name",
                    "visible",
                    "locked",
                    "opacity",
                    "cels"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 80
                    },
                    "name": {
                      "type": "string",
                      "maxLength": 80
                    },
                    "visible": {
                      "type": "boolean"
                    },
                    "locked": {
                      "type": "boolean"
                    },
                    "opacity": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "cels": {
                      "type": "array",
                      "minItems": 1,
                      "maxItems": 24,
                      "items": {
                        "type": "array",
                        "maxItems": 500,
                        "items": {
                          "type": "object",
                          "additionalProperties": false,
                          "required": [
                            "id",
                            "kind",
                            "points",
                            "color",
                            "size",
                            "fill"
                          ],
                          "properties": {
                            "brush": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "kind",
                                "opacity",
                                "flow",
                                "spacing",
                                "texture",
                                "pressure",
                                "seed"
                              ],
                              "properties": {
                                "kind": {
                                  "enum": [
                                    "ink",
                                    "pencil",
                                    "marker",
                                    "wash",
                                    "airbrush"
                                  ]
                                },
                                "opacity": {
                                  "type": "number",
                                  "minimum": 0,
                                  "maximum": 1
                                },
                                "flow": {
                                  "type": "number",
                                  "minimum": 0,
                                  "maximum": 1
                                },
                                "spacing": {
                                  "type": "number",
                                  "minimum": 0.08,
                                  "maximum": 1
                                },
                                "texture": {
                                  "type": "number",
                                  "minimum": 0,
                                  "maximum": 1
                                },
                                "pressure": {
                                  "type": "boolean"
                                },
                                "seed": {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 4294967295
                                }
                              }
                            },
                            "pressures": {
                              "type": "array",
                              "minItems": 1,
                              "maxItems": 4096,
                              "items": {
                                "type": "number",
                                "minimum": 0,
                                "maximum": 1
                              }
                            },
                            "id": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 80
                            },
                            "kind": {
                              "enum": [
                                "pen",
                                "eraser",
                                "line",
                                "rect",
                                "ellipse",
                                "image"
                              ]
                            },
                            "points": {
                              "type": "array",
                              "minItems": 1,
                              "maxItems": 4096,
                              "items": {
                                "type": "array",
                                "minItems": 2,
                                "maxItems": 2,
                                "items": {
                                  "type": "number",
                                  "minimum": 0,
                                  "maximum": 1
                                }
                              }
                            },
                            "color": {
                              "type": "string",
                              "pattern": "^#[a-fA-F0-9]{6}$"
                            },
                            "size": {
                              "type": "number",
                              "minimum": 1,
                              "maximum": 100
                            },
                            "fill": {
                              "type": "boolean"
                            },
                            "source": {
                              "type": "string",
                              "pattern": "^data:image/(png|jpeg|webp);base64,[A-Za-z0-9+/=]+$"
                            },
                            "angle": {
                              "type": "number",
                              "minimum": -360,
                              "maximum": 360,
                              "description": "Clockwise rotation in degrees around the center of the mark bounds (normalized to -180…180)."
                            },
                            "flipX": {
                              "type": "boolean",
                              "description": "Mirror horizontally around the mark center."
                            },
                            "flipY": {
                              "type": "boolean",
                              "description": "Mirror vertically around the mark center."
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            },
            "description": "Normalized drawing coordinates. Each layer has one cel per frame. At most 2 MP canvas, 50000 points, 2000 marks and 8 million embedded source characters in total. Image/shape marks require two points; IDs are unique within their collection. Optional angle/flipX/flipY transform a mark around the center of its point bounds."
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}