{
  "openapi": "3.1.1",
  "info": {
    "title": "Twinworks API",
    "version": "1.0.0",
    "summary": "Deterministic tools for people and AI agents.",
    "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://twinworks.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/tools": {
      "get": {
        "operationId": "listTools",
        "summary": "Catalog of all tools",
        "responses": {
          "200": {
            "description": "Tool list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/{id}": {
      "get": {
        "operationId": "getTool",
        "summary": "Definition of one tool",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "twinworks-simulate",
                "twinworks-bottleneck-analysis",
                "twinworks-line-balance",
                "twinworks-buffer-sweep",
                "twinworks-queue-formulas"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/twinworks-simulate/calculate": {
      "post": {
        "operationId": "calculateTwinworksSimulate",
        "summary": "Simulate a production line: throughput, lead time, WIP, OEE and the bottleneck, with CIs.",
        "description": "Runs the Twinworks discrete-event simulation on a factory model (sources, buffers, machines with failures and setups, assembly, conveyors, quality checks, operators and shift calendars). Returns throughput per hour, lead time, WIP with a Little’s-law check, per-station states and OEE, the bottleneck and a cost per good part, with Student-t confidence intervals across seeded replications.\n\nMethodology:\n- Discrete-event simulation with a binary-heap event calendar; ties are processed in (time, priority, insertion order) so every run is reproducible.\n- Parts are pushed downstream with blocking after service: a machine that cannot hand its part on is “blocked”; a machine without parts is “starved/idle”.\n- Each random quantity (arrivals, cycle times, failures, routing choices) has its own seeded stream, so scenario changes do not shift other random numbers (common random numbers).\n- Statistics are reset after the warm-up. Replications use derived seeds; intervals are Student-t intervals of the replication means.\n- Little’s law is checked as L (time-average WIP) versus λ·W (departure rate × mean time in system); differences above 5 % signal a non-stationary system or too short a run.\n- OEE = availability × performance × quality with planned time = time on shift minus planned maintenance; availability losses = breakdowns + setups; performance = ideal cycle time × parts ÷ run time (starving and blocking reduce it); quality = good ÷ processed.\n- Bottleneck: active-period method (Roser et al.) — at each moment the station with the longest uninterrupted active period (working, setup, repair, maintenance, waiting for an operator) is the bottleneck; overlaps between consecutive bottlenecks count as shifting.\n\nA simulation is only as good as its input data. Validate cycle times, failure data and routings against your shop floor before making investment decisions.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "twinworks_simulate",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TwinworksSimulateInput"
              },
              "examples": {
                "example1": {
                  "summary": "3-station line template, 5 replications",
                  "value": {
                    "template": "three-station-line",
                    "replications": 5
                  }
                },
                "example2": {
                  "summary": "Own model: two machines and a buffer, deterministic",
                  "value": {
                    "model": "{\"name\":\"Two machines\",\"settings\":{\"horizon\":7200,\"warmup\":600},\"nodes\":[{\"id\":\"S\",\"type\":\"source\",\"arrival\":\"saturated\"},{\"id\":\"M1\",\"type\":\"machine\",\"cycle\":{\"type\":\"constant\",\"value\":30}},{\"id\":\"B\",\"type\":\"buffer\",\"capacity\":3},{\"id\":\"M2\",\"type\":\"machine\",\"cycle\":{\"type\":\"constant\",\"value\":40}},{\"id\":\"OUT\",\"type\":\"sink\"}],\"links\":[{\"from\":\"S\",\"to\":\"M1\"},{\"from\":\"M1\",\"to\":\"B\"},{\"from\":\"B\",\"to\":\"M2\"},{\"from\":\"M2\",\"to\":\"OUT\"}]}",
                    "replications": 1
                  }
                },
                "example3": {
                  "summary": "Line with failures over 2 days, 3 replications",
                  "value": {
                    "template": "line-with-failures",
                    "horizonHours": 48,
                    "warmupMinutes": 120,
                    "replications": 3
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TwinworksSimulateResult"
                }
              }
            }
          },
          "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/tools/twinworks-bottleneck-analysis/calculate": {
      "post": {
        "operationId": "calculateTwinworksBottleneckAnalysis",
        "summary": "Find the constraint of a production line and test fixes: ranked bottlenecks with what-if gains.",
        "description": "Ranks the stations of a Twinworks factory model by how often they constrain the line (active-period method: sole and shifting bottleneck shares), explains the dominant loss (working, breakdowns, setups, waiting for operators) and simulates typical improvements of the top bottleneck — an extra server, a 10 % faster cycle, faster repairs, shorter setups, more operators or a bigger buffer — with paired confidence intervals.\n\nMethodology:\n- Each replication records, per station, every active period (uninterrupted time working, in setup, under repair/maintenance or waiting for an operator; starved and blocked times end a period).\n- At every instant the station with the longest current active period is the bottleneck. Where the periods of consecutive bottlenecks overlap, both are shifting bottlenecks; otherwise the station is the sole bottleneck (Roser, Nakano & Tanaka 2001).\n- Stations are ranked by sole + shifting share (averaged over the window of replication 1, votes = how often a station was the top bottleneck across replications); ties are broken by active percentage.\n- What-if options for the top station are simulated with the same seeds as the baseline (common random numbers); the gain interval is a paired Student-t interval of the throughput differences.\n\nImprovement options are illustrative single changes; real fixes have costs and side effects that the model may not capture.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "twinworks_bottleneck_analysis",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TwinworksBottleneckAnalysisInput"
              },
              "examples": {
                "example1": {
                  "summary": "Bottleneck demo (5 stations, tiny buffers)",
                  "value": {
                    "template": "bottleneck-buffer-sizing",
                    "replications": 5,
                    "horizonHours": 8
                  }
                },
                "example2": {
                  "summary": "Job shop with setups on the mill",
                  "value": {
                    "template": "job-shop-routings",
                    "replications": 4,
                    "whatIf": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TwinworksBottleneckAnalysisResult"
                }
              }
            }
          },
          "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/tools/twinworks-line-balance/calculate": {
      "post": {
        "operationId": "calculateTwinworksLineBalance",
        "summary": "Assign assembly tasks to stations for a takt time: efficiency, balance delay and smoothness index.",
        "description": "Solves the simple assembly line balancing problem (type 1) with the Ranked Positional Weight (Helgeson–Birnie) and Largest Candidate rules: tasks with times and precedence relations are assigned to as few stations as possible without exceeding the takt time. Returns the station assignment, line efficiency, balance delay, smoothness index and a ready-to-simulate Twinworks model of the balanced line.\n\nMethodology:\n- Takt time = available production time ÷ demand (or as given). Theoretical minimum stations = ⌈Σ task times ÷ takt⌉.\n- RPW: positional weight = own time + times of all direct and indirect successors; LCR: task time. Stations are filled one by one with the highest-priority task whose predecessors are all assigned and that still fits into the remaining takt time.\n- Efficiency = Σ task times ÷ (stations × takt); balance delay = 1 − efficiency; smoothness index = √Σ(max station time − station time)².\n- The result includes a Twinworks model (one constant-time machine per station, single-place buffers) so the balance can be simulated or opened in the app.\n\nHeuristics give good but not always optimal balances. Zoning constraints, operator skills and task variability are not considered.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "twinworks_line_balance",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TwinworksLineBalanceInput"
              },
              "examples": {
                "example1": {
                  "summary": "Wheelbarrow-style example: 8 tasks, 450 min shift, demand 270",
                  "value": {
                    "tasks": [
                      {
                        "id": "A",
                        "name": "Fit frame",
                        "time": 60,
                        "predecessors": ""
                      },
                      {
                        "id": "B",
                        "name": "Mount axle",
                        "time": 40,
                        "predecessors": "A"
                      },
                      {
                        "id": "C",
                        "name": "Fit wheel",
                        "time": 55,
                        "predecessors": "B"
                      },
                      {
                        "id": "D",
                        "name": "Attach tray",
                        "time": 50,
                        "predecessors": "A"
                      },
                      {
                        "id": "E",
                        "name": "Fit legs",
                        "time": 30,
                        "predecessors": "D"
                      },
                      {
                        "id": "F",
                        "name": "Attach handles",
                        "time": 45,
                        "predecessors": "D"
                      },
                      {
                        "id": "G",
                        "name": "Grips",
                        "time": 20,
                        "predecessors": "F"
                      },
                      {
                        "id": "H",
                        "name": "Final check",
                        "time": 35,
                        "predecessors": "C,E,G"
                      }
                    ],
                    "availableMinutes": 450,
                    "demand": 270,
                    "method": "best"
                  }
                },
                "example2": {
                  "summary": "Six tasks with a fixed takt time of 10 s",
                  "value": {
                    "tasks": [
                      {
                        "id": "1",
                        "time": 4,
                        "predecessors": ""
                      },
                      {
                        "id": "2",
                        "time": 3,
                        "predecessors": "1"
                      },
                      {
                        "id": "3",
                        "time": 5,
                        "predecessors": "1"
                      },
                      {
                        "id": "4",
                        "time": 6,
                        "predecessors": "2"
                      },
                      {
                        "id": "5",
                        "time": 2,
                        "predecessors": "3"
                      },
                      {
                        "id": "6",
                        "time": 4,
                        "predecessors": "4,5"
                      }
                    ],
                    "taktTime": 10,
                    "method": "rpw"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TwinworksLineBalanceResult"
                }
              }
            }
          },
          "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/tools/twinworks-buffer-sweep/calculate": {
      "post": {
        "operationId": "calculateTwinworksBufferSweep",
        "summary": "Sweep a buffer size (or any parameter) and get the throughput curve with confidence intervals.",
        "description": "Runs a Twinworks factory model repeatedly while one parameter changes — typically the capacity of a buffer from 1 to 10 places, but also servers, cycle times, MTTR, batch sizes, conveyor speed or the number of operators. Returns throughput, lead time and WIP per value with confidence intervals, plus the knee point where extra capacity stops paying off.\n\nMethodology:\n- For each parameter value the model is copied, the parameter is set and the model is simulated with the same seeds (common random numbers), so differences between values are not masked by random noise.\n- Throughput, lead time and WIP are reported as Student-t intervals across replications.\n- Knee point = smallest value whose mean throughput is at least 98 % of the best mean throughput in the sweep: beyond it, more buffer mostly adds WIP and lead time (Little’s law).\n\nThe sweep varies one parameter at a time; interactions between buffers are not optimised jointly.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "twinworks_buffer_sweep",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TwinworksBufferSweepInput"
              },
              "examples": {
                "example1": {
                  "summary": "Bottleneck demo: buffer B2 from 1 to 10",
                  "value": {
                    "template": "bottleneck-buffer-sizing",
                    "target": "B2",
                    "parameter": "capacity",
                    "from": 1,
                    "to": 10,
                    "step": 1,
                    "replications": 4,
                    "horizonHours": 6
                  }
                },
                "example2": {
                  "summary": "3-station line: arrival interval 45…70 s",
                  "value": {
                    "template": "three-station-line",
                    "target": "SRC1",
                    "parameter": "interval.mean",
                    "from": 45,
                    "to": 70,
                    "step": 5,
                    "replications": 3
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TwinworksBufferSweepResult"
                }
              }
            }
          },
          "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/tools/twinworks-queue-formulas/calculate": {
      "post": {
        "operationId": "calculateTwinworksQueueFormulas",
        "summary": "M/M/1, M/M/c, M/D/1, M/G/1 and Kingman waiting times — optionally verified by simulation.",
        "description": "Closed-form queueing results for a single workstation: utilization, mean waiting time, queue length and time in system for M/M/1, M/M/c (Erlang C), M/D/1, M/G/1 (Pollaczek–Khinchine) and the Kingman G/G/1 approximation. Optionally runs the Twinworks simulation of the same station and reports whether the theory lies inside the simulated confidence interval.\n\nMethodology:\n- M/M/1: Wq = ρ/(μ−λ). M/M/c: Wq = C(c, a)/(cμ−λ) with the Erlang C probability C computed by a stable recursion. M/G/1: Wq = λE[S²]/(2(1−ρ)) (Pollaczek–Khinchine), M/D/1 is the special case SCV = 0. Kingman: Wq ≈ ((ca²+cs²)/2)·(ρ/(1−ρ))·te.\n- L = λW and Lq = λWq (Little’s law).\n- Verification builds a source → unlimited queue → station → sink model, simulates long replications (≈ 20 000 arrivals each, 5 % warm-up) and checks whether the theoretical Wq lies inside the Student-t interval of the simulated mean wait.\n\nFormulas assume steady state, infinite queue capacity and FIFO service. Kingman is an approximation.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "twinworks_queue_formulas",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TwinworksQueueFormulasInput"
              },
              "examples": {
                "example1": {
                  "summary": "M/M/1 at 80 % utilization, verified by simulation",
                  "value": {
                    "queue": "mm1",
                    "arrivalsPerHour": 60,
                    "serviceTime": 48,
                    "verify": true,
                    "replications": 10
                  }
                },
                "example2": {
                  "summary": "Two operators (M/M/2)",
                  "value": {
                    "queue": "mmc",
                    "arrivalsPerHour": 100,
                    "serviceTime": 60,
                    "servers": 2
                  }
                },
                "example3": {
                  "summary": "Kingman: low arrival variability, high process variability",
                  "value": {
                    "queue": "gg1",
                    "arrivalsPerHour": 50,
                    "serviceTime": 60,
                    "arrivalScv": 0.25,
                    "serviceScv": 1.5
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TwinworksQueueFormulasResult"
                }
              }
            }
          },
          "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/workflows": {
      "get": {
        "operationId": "listWorkflows",
        "summary": "Multi-tool workflows",
        "responses": {
          "200": {
            "description": "Workflow list.",
            "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"
                }
              }
            }
          }
        }
      },
      "TwinworksSimulateInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "model": {
            "title": "Model or project JSON",
            "description": "A Twinworks project (.twinworks.json, format \"twinworks-project\") or a bare model with \"nodes\" and \"links\". Times in seconds, lengths in metres. Leave empty and pick a template instead.",
            "type": "string",
            "maxLength": 400000
          },
          "template": {
            "title": "Or start from a template",
            "type": "string",
            "enum": [
              "",
              "three-station-line",
              "line-with-failures",
              "assembly-two-feeders",
              "job-shop-routings",
              "bottleneck-buffer-sizing",
              "conveyor-packaging",
              "mm1-validation"
            ],
            "default": ""
          },
          "horizonHours": {
            "title": "Run length per replication",
            "description": "Overrides the model setting (includes the warm-up).",
            "type": "number",
            "minimum": 0.01,
            "maximum": 2400,
            "x-unit": "h"
          },
          "warmupMinutes": {
            "title": "Warm-up",
            "description": "Statistics are reset after the warm-up. Overrides the model setting.",
            "type": "number",
            "minimum": 0,
            "maximum": 144000,
            "x-unit": "min"
          },
          "seed": {
            "title": "Random seed",
            "description": "Same seed → same result. Replication r uses a seed derived from it.",
            "type": "integer",
            "minimum": 0,
            "maximum": 4294967295
          },
          "replications": {
            "title": "Replications",
            "description": "Independent runs with different seeds; used for the confidence intervals.",
            "type": "integer",
            "minimum": 1,
            "maximum": 30
          },
          "confidence": {
            "title": "Confidence level",
            "type": "string",
            "enum": [
              "",
              "0.9",
              "0.95",
              "0.99"
            ],
            "default": ""
          }
        },
        "required": []
      },
      "TwinworksSimulateResult": {
        "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",
            "required": [
              "modelName",
              "replications",
              "confidence",
              "horizonSeconds",
              "warmupSeconds",
              "throughputPerHour",
              "leadTime",
              "wip",
              "little",
              "good",
              "scrap",
              "stations",
              "bottleneck",
              "cost"
            ],
            "properties": {
              "modelName": {
                "type": "string"
              },
              "replications": {
                "type": "integer"
              },
              "confidence": {
                "type": "number"
              },
              "horizonSeconds": {
                "type": "number"
              },
              "warmupSeconds": {
                "type": "number"
              },
              "seeds": {
                "type": "array",
                "items": {
                  "type": "integer"
                }
              },
              "throughputPerHour": {
                "type": "object",
                "required": [
                  "mean",
                  "lo",
                  "hi",
                  "halfWidth",
                  "n"
                ],
                "properties": {
                  "mean": {
                    "type": "number"
                  },
                  "lo": {
                    "type": "number"
                  },
                  "hi": {
                    "type": "number"
                  },
                  "halfWidth": {
                    "type": "number"
                  },
                  "n": {
                    "type": "integer"
                  }
                }
              },
              "leadTime": {
                "type": "object",
                "required": [
                  "mean",
                  "p50",
                  "p90",
                  "p95",
                  "max",
                  "meanCi"
                ],
                "properties": {
                  "mean": {
                    "type": "number"
                  },
                  "p50": {
                    "type": "number"
                  },
                  "p90": {
                    "type": "number"
                  },
                  "p95": {
                    "type": "number"
                  },
                  "max": {
                    "type": "number"
                  },
                  "meanCi": {
                    "type": "object",
                    "required": [
                      "mean",
                      "lo",
                      "hi",
                      "halfWidth",
                      "n"
                    ],
                    "properties": {
                      "mean": {
                        "type": "number"
                      },
                      "lo": {
                        "type": "number"
                      },
                      "hi": {
                        "type": "number"
                      },
                      "halfWidth": {
                        "type": "number"
                      },
                      "n": {
                        "type": "integer"
                      }
                    }
                  }
                }
              },
              "wip": {
                "type": "object",
                "required": [
                  "avg",
                  "max",
                  "avgCi"
                ],
                "properties": {
                  "avg": {
                    "type": "number"
                  },
                  "max": {
                    "type": "number"
                  },
                  "avgCi": {
                    "type": "object",
                    "required": [
                      "mean",
                      "lo",
                      "hi",
                      "halfWidth",
                      "n"
                    ],
                    "properties": {
                      "mean": {
                        "type": "number"
                      },
                      "lo": {
                        "type": "number"
                      },
                      "hi": {
                        "type": "number"
                      },
                      "halfWidth": {
                        "type": "number"
                      },
                      "n": {
                        "type": "integer"
                      }
                    }
                  }
                }
              },
              "little": {
                "type": "object",
                "required": [
                  "L",
                  "lambdaPerHour",
                  "W",
                  "lambdaW",
                  "relError",
                  "ok"
                ],
                "properties": {
                  "L": {
                    "type": "number"
                  },
                  "lambdaPerHour": {
                    "type": "number"
                  },
                  "W": {
                    "type": "number"
                  },
                  "lambdaW": {
                    "type": "number"
                  },
                  "relError": {
                    "type": "number"
                  },
                  "ok": {
                    "type": "boolean"
                  }
                }
              },
              "good": {
                "type": "integer"
              },
              "scrap": {
                "type": "integer"
              },
              "scrapPct": {
                "type": "number"
              },
              "stations": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "id",
                    "name",
                    "type",
                    "servers",
                    "processed",
                    "throughputPerHour",
                    "utilization",
                    "states",
                    "availability",
                    "performance",
                    "quality",
                    "oee"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string"
                    },
                    "servers": {
                      "type": "integer"
                    },
                    "processed": {
                      "type": "integer"
                    },
                    "throughputPerHour": {
                      "type": "number"
                    },
                    "utilization": {
                      "type": "number"
                    },
                    "utilizationCi": {
                      "type": "object",
                      "required": [
                        "mean",
                        "lo",
                        "hi",
                        "halfWidth",
                        "n"
                      ],
                      "properties": {
                        "mean": {
                          "type": "number"
                        },
                        "lo": {
                          "type": "number"
                        },
                        "hi": {
                          "type": "number"
                        },
                        "halfWidth": {
                          "type": "number"
                        },
                        "n": {
                          "type": "integer"
                        }
                      }
                    },
                    "states": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "number"
                      }
                    },
                    "availability": {
                      "type": "number"
                    },
                    "performance": {
                      "type": "number"
                    },
                    "quality": {
                      "type": "number"
                    },
                    "oee": {
                      "type": "number"
                    },
                    "oeeCi": {
                      "type": "object",
                      "required": [
                        "mean",
                        "lo",
                        "hi",
                        "halfWidth",
                        "n"
                      ],
                      "properties": {
                        "mean": {
                          "type": "number"
                        },
                        "lo": {
                          "type": "number"
                        },
                        "hi": {
                          "type": "number"
                        },
                        "halfWidth": {
                          "type": "number"
                        },
                        "n": {
                          "type": "integer"
                        }
                      }
                    },
                    "failures": {
                      "type": "integer"
                    },
                    "setups": {
                      "type": "integer"
                    }
                  }
                }
              },
              "buffers": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string"
                    },
                    "capacity": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "avgContents": {
                      "type": "number"
                    },
                    "maxContents": {
                      "type": "number"
                    },
                    "avgWait": {
                      "type": "number"
                    }
                  }
                }
              },
              "bottleneck": {
                "type": "object",
                "required": [
                  "primary",
                  "ranking",
                  "recommendations"
                ],
                "properties": {
                  "primary": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "ranking": {
                    "type": "array"
                  },
                  "recommendations": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "votes": {
                    "type": "object"
                  }
                }
              },
              "cost": {
                "type": "object",
                "required": [
                  "currency",
                  "total",
                  "costPerGoodPart"
                ],
                "properties": {
                  "currency": {
                    "type": "string"
                  },
                  "total": {
                    "type": "number"
                  },
                  "costPerGoodPart": {
                    "type": "number"
                  },
                  "costPerGoodPartCi": {
                    "type": "object",
                    "required": [
                      "mean",
                      "lo",
                      "hi",
                      "halfWidth",
                      "n"
                    ],
                    "properties": {
                      "mean": {
                        "type": "number"
                      },
                      "lo": {
                        "type": "number"
                      },
                      "hi": {
                        "type": "number"
                      },
                      "halfWidth": {
                        "type": "number"
                      },
                      "n": {
                        "type": "integer"
                      }
                    }
                  },
                  "scrapCost": {
                    "type": "number"
                  },
                  "labour": {
                    "type": "number"
                  },
                  "machineTime": {
                    "type": "number"
                  },
                  "material": {
                    "type": "number"
                  },
                  "variable": {
                    "type": "number"
                  },
                  "overhead": {
                    "type": "number"
                  },
                  "revenue": {
                    "type": "number"
                  },
                  "profit": {
                    "type": "number"
                  }
                }
              },
              "openInAppUrl": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "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"
              }
            }
          }
        }
      },
      "TwinworksBottleneckAnalysisInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "model": {
            "title": "Model or project JSON",
            "description": "A Twinworks project (.twinworks.json, format \"twinworks-project\") or a bare model with \"nodes\" and \"links\". Times in seconds, lengths in metres. Leave empty and pick a template instead.",
            "type": "string",
            "maxLength": 400000
          },
          "template": {
            "title": "Or start from a template",
            "type": "string",
            "enum": [
              "",
              "three-station-line",
              "line-with-failures",
              "assembly-two-feeders",
              "job-shop-routings",
              "bottleneck-buffer-sizing",
              "conveyor-packaging",
              "mm1-validation"
            ],
            "default": ""
          },
          "replications": {
            "title": "Replications",
            "type": "integer",
            "minimum": 2,
            "maximum": 20,
            "default": 5
          },
          "horizonHours": {
            "title": "Run length per replication",
            "description": "Overrides the model setting.",
            "type": "number",
            "minimum": 0.1,
            "maximum": 2400,
            "x-unit": "h"
          },
          "whatIf": {
            "title": "Simulate improvement options for the top bottleneck",
            "type": "boolean",
            "default": true
          }
        },
        "required": []
      },
      "TwinworksBottleneckAnalysisResult": {
        "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",
            "required": [
              "primary",
              "ranking",
              "recommendations",
              "baselineThroughput",
              "whatIf"
            ],
            "properties": {
              "primary": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "primaryName": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "ranking": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "rank",
                    "id",
                    "name",
                    "sole",
                    "shifting",
                    "total",
                    "activePct",
                    "utilization",
                    "dominantState",
                    "votes"
                  ],
                  "properties": {
                    "rank": {
                      "type": "integer"
                    },
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "sole": {
                      "type": "number"
                    },
                    "shifting": {
                      "type": "number"
                    },
                    "total": {
                      "type": "number"
                    },
                    "activePct": {
                      "type": "number"
                    },
                    "utilization": {
                      "type": "number"
                    },
                    "dominantState": {
                      "type": "string"
                    },
                    "votes": {
                      "type": "integer"
                    }
                  }
                }
              },
              "recommendations": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "baselineThroughput": {
                "type": "object",
                "required": [
                  "mean",
                  "lo",
                  "hi",
                  "halfWidth",
                  "n"
                ],
                "properties": {
                  "mean": {
                    "type": "number"
                  },
                  "lo": {
                    "type": "number"
                  },
                  "hi": {
                    "type": "number"
                  },
                  "halfWidth": {
                    "type": "number"
                  },
                  "n": {
                    "type": "integer"
                  }
                }
              },
              "whatIf": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "id",
                    "label",
                    "throughput",
                    "gain",
                    "gainPct"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "label": {
                      "type": "string"
                    },
                    "throughput": {
                      "type": "object",
                      "required": [
                        "mean",
                        "lo",
                        "hi",
                        "halfWidth",
                        "n"
                      ],
                      "properties": {
                        "mean": {
                          "type": "number"
                        },
                        "lo": {
                          "type": "number"
                        },
                        "hi": {
                          "type": "number"
                        },
                        "halfWidth": {
                          "type": "number"
                        },
                        "n": {
                          "type": "integer"
                        }
                      }
                    },
                    "gain": {
                      "type": "object",
                      "required": [
                        "mean",
                        "lo",
                        "hi",
                        "halfWidth",
                        "n"
                      ],
                      "properties": {
                        "mean": {
                          "type": "number"
                        },
                        "lo": {
                          "type": "number"
                        },
                        "hi": {
                          "type": "number"
                        },
                        "halfWidth": {
                          "type": "number"
                        },
                        "n": {
                          "type": "integer"
                        }
                      }
                    },
                    "gainPct": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "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"
              }
            }
          }
        }
      },
      "TwinworksLineBalanceInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "tasks": {
            "title": "Tasks",
            "type": "array",
            "minItems": 1,
            "maxItems": 200,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "id": {
                  "title": "Task id",
                  "type": "string",
                  "maxLength": 20
                },
                "name": {
                  "title": "Description",
                  "type": "string",
                  "maxLength": 80
                },
                "time": {
                  "title": "Time (s)",
                  "type": "number",
                  "minimum": 0,
                  "maximum": 100000
                },
                "predecessors": {
                  "title": "Predecessors (comma-separated ids)",
                  "type": "string",
                  "maxLength": 400
                }
              },
              "required": [
                "id",
                "time"
              ]
            }
          },
          "taktTime": {
            "title": "Takt time",
            "description": "Leave empty to compute it from available time ÷ demand.",
            "type": "number",
            "minimum": 0.001,
            "maximum": 10000000,
            "x-unit": "s"
          },
          "availableMinutes": {
            "title": "Available production time",
            "description": "Per period, e.g. 450 min per shift.",
            "type": "number",
            "minimum": 1,
            "maximum": 1000000,
            "x-unit": "min"
          },
          "demand": {
            "title": "Demand in that period",
            "type": "number",
            "minimum": 1,
            "maximum": 1000000000,
            "x-unit": "units"
          },
          "method": {
            "title": "Heuristic",
            "type": "string",
            "enum": [
              "best",
              "rpw",
              "lcr"
            ],
            "default": "best"
          }
        },
        "required": [
          "tasks"
        ]
      },
      "TwinworksLineBalanceResult": {
        "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",
            "required": [
              "method",
              "taktTime",
              "totalWork",
              "theoreticalMin",
              "stationCount",
              "stations",
              "efficiency",
              "balanceDelay",
              "smoothnessIndex",
              "cycleTime",
              "maxThroughputPerHour",
              "model"
            ],
            "properties": {
              "method": {
                "type": "string"
              },
              "taktTime": {
                "type": "number"
              },
              "totalWork": {
                "type": "number"
              },
              "theoreticalMin": {
                "type": "integer"
              },
              "stationCount": {
                "type": "integer"
              },
              "stations": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "station",
                    "tasks",
                    "time",
                    "idle",
                    "utilization"
                  ],
                  "properties": {
                    "station": {
                      "type": "integer"
                    },
                    "tasks": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "time": {
                      "type": "number"
                    },
                    "idle": {
                      "type": "number"
                    },
                    "utilization": {
                      "type": "number"
                    }
                  }
                }
              },
              "efficiency": {
                "type": "number"
              },
              "balanceDelay": {
                "type": "number"
              },
              "smoothnessIndex": {
                "type": "number"
              },
              "cycleTime": {
                "type": "number"
              },
              "maxThroughputPerHour": {
                "type": "number"
              },
              "positionalWeights": {
                "type": "object",
                "additionalProperties": {
                  "type": "number"
                }
              },
              "alternative": {
                "type": [
                  "object",
                  "null"
                ]
              },
              "model": {
                "type": "object"
              }
            }
          },
          "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"
              }
            }
          }
        }
      },
      "TwinworksBufferSweepInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "model": {
            "title": "Model or project JSON",
            "description": "A Twinworks project (.twinworks.json, format \"twinworks-project\") or a bare model with \"nodes\" and \"links\". Times in seconds, lengths in metres. Leave empty and pick a template instead.",
            "type": "string",
            "maxLength": 400000
          },
          "template": {
            "title": "Or start from a template",
            "type": "string",
            "enum": [
              "",
              "three-station-line",
              "line-with-failures",
              "assembly-two-feeders",
              "job-shop-routings",
              "bottleneck-buffer-sizing",
              "conveyor-packaging",
              "mm1-validation"
            ],
            "default": ""
          },
          "target": {
            "title": "Object id",
            "description": "Id of the buffer/machine/conveyor/source to change, or pool:<id> for an operator pool. Default for the bottleneck template: B2.",
            "type": "string",
            "maxLength": 60
          },
          "parameter": {
            "title": "Parameter",
            "type": "string",
            "enum": [
              "capacity",
              "servers",
              "cycle.value",
              "cycle.mean",
              "batchSize",
              "interval.mean",
              "interval.value",
              "speed",
              "length",
              "failure.mttr.mean",
              "failure.mtbf.mean",
              "setup.value",
              "scrapPct",
              "count"
            ],
            "default": "capacity"
          },
          "from": {
            "title": "From",
            "type": "number",
            "minimum": 0,
            "maximum": 10000000,
            "default": 1
          },
          "to": {
            "title": "To",
            "type": "number",
            "minimum": 0,
            "maximum": 10000000,
            "default": 10
          },
          "step": {
            "title": "Step",
            "type": "number",
            "minimum": 0.0001,
            "maximum": 10000000,
            "default": 1
          },
          "replications": {
            "title": "Replications per value",
            "type": "integer",
            "minimum": 1,
            "maximum": 20,
            "default": 4
          },
          "horizonHours": {
            "title": "Run length per replication",
            "description": "Overrides the model setting.",
            "type": "number",
            "minimum": 0.1,
            "maximum": 2400,
            "x-unit": "h"
          }
        },
        "required": []
      },
      "TwinworksBufferSweepResult": {
        "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",
            "required": [
              "target",
              "parameter",
              "points",
              "knee",
              "bestThroughput"
            ],
            "properties": {
              "target": {
                "type": "string"
              },
              "parameter": {
                "type": "string"
              },
              "points": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "value",
                    "throughput",
                    "leadTime",
                    "wip"
                  ],
                  "properties": {
                    "value": {
                      "type": "number"
                    },
                    "throughput": {
                      "type": "object",
                      "required": [
                        "mean",
                        "lo",
                        "hi",
                        "halfWidth",
                        "n"
                      ],
                      "properties": {
                        "mean": {
                          "type": "number"
                        },
                        "lo": {
                          "type": "number"
                        },
                        "hi": {
                          "type": "number"
                        },
                        "halfWidth": {
                          "type": "number"
                        },
                        "n": {
                          "type": "integer"
                        }
                      }
                    },
                    "leadTime": {
                      "type": "object",
                      "required": [
                        "mean",
                        "lo",
                        "hi",
                        "halfWidth",
                        "n"
                      ],
                      "properties": {
                        "mean": {
                          "type": "number"
                        },
                        "lo": {
                          "type": "number"
                        },
                        "hi": {
                          "type": "number"
                        },
                        "halfWidth": {
                          "type": "number"
                        },
                        "n": {
                          "type": "integer"
                        }
                      }
                    },
                    "wip": {
                      "type": "object",
                      "required": [
                        "mean",
                        "lo",
                        "hi",
                        "halfWidth",
                        "n"
                      ],
                      "properties": {
                        "mean": {
                          "type": "number"
                        },
                        "lo": {
                          "type": "number"
                        },
                        "hi": {
                          "type": "number"
                        },
                        "halfWidth": {
                          "type": "number"
                        },
                        "n": {
                          "type": "integer"
                        }
                      }
                    },
                    "costPerGoodPart": {
                      "type": "object",
                      "required": [
                        "mean",
                        "lo",
                        "hi",
                        "halfWidth",
                        "n"
                      ],
                      "properties": {
                        "mean": {
                          "type": "number"
                        },
                        "lo": {
                          "type": "number"
                        },
                        "hi": {
                          "type": "number"
                        },
                        "halfWidth": {
                          "type": "number"
                        },
                        "n": {
                          "type": "integer"
                        }
                      }
                    },
                    "bottleneck": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              },
              "knee": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "Smallest value reaching 98 % of the best mean throughput."
              },
              "bestThroughput": {
                "type": "number"
              }
            }
          },
          "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"
              }
            }
          }
        }
      },
      "TwinworksQueueFormulasInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "queue": {
            "title": "Queue model",
            "type": "string",
            "enum": [
              "mm1",
              "mmc",
              "md1",
              "mg1",
              "gg1"
            ],
            "default": "mm1"
          },
          "arrivalsPerHour": {
            "title": "Arrival rate",
            "type": "number",
            "minimum": 0.0001,
            "maximum": 10000000,
            "default": 60,
            "x-unit": "parts/h"
          },
          "serviceTime": {
            "title": "Mean service (cycle) time",
            "type": "number",
            "minimum": 0.0001,
            "maximum": 10000000,
            "default": 48,
            "x-unit": "s"
          },
          "servers": {
            "title": "Servers (M/M/c)",
            "type": "integer",
            "minimum": 1,
            "maximum": 200,
            "default": 2
          },
          "serviceScv": {
            "title": "Service SCV (variance ÷ mean²)",
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "default": 1
          },
          "arrivalScv": {
            "title": "Inter-arrival SCV (G/G/1)",
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "default": 1
          },
          "verify": {
            "title": "Verify by simulation",
            "description": "Runs the same station in Twinworks (M/M/1, M/M/c, M/D/1 only).",
            "type": "boolean",
            "default": false
          },
          "replications": {
            "title": "Replications for the check",
            "type": "integer",
            "minimum": 3,
            "maximum": 20,
            "default": 10
          }
        },
        "required": [
          "arrivalsPerHour",
          "serviceTime"
        ]
      },
      "TwinworksQueueFormulasResult": {
        "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",
            "required": [
              "model",
              "rho",
              "stable",
              "Wq",
              "W",
              "Lq",
              "L",
              "exact",
              "verification"
            ],
            "properties": {
              "model": {
                "type": "string"
              },
              "rho": {
                "type": "number"
              },
              "stable": {
                "type": "boolean"
              },
              "Wq": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "W": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "Lq": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "L": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "pWait": {
                "type": "number"
              },
              "exact": {
                "type": "boolean"
              },
              "verification": {
                "type": [
                  "object",
                  "null"
                ],
                "properties": {
                  "WqSim": {
                    "type": "object",
                    "required": [
                      "mean",
                      "lo",
                      "hi",
                      "halfWidth",
                      "n"
                    ],
                    "properties": {
                      "mean": {
                        "type": "number"
                      },
                      "lo": {
                        "type": "number"
                      },
                      "hi": {
                        "type": "number"
                      },
                      "halfWidth": {
                        "type": "number"
                      },
                      "n": {
                        "type": "integer"
                      }
                    }
                  },
                  "utilizationSim": {
                    "type": "object",
                    "required": [
                      "mean",
                      "lo",
                      "hi",
                      "halfWidth",
                      "n"
                    ],
                    "properties": {
                      "mean": {
                        "type": "number"
                      },
                      "lo": {
                        "type": "number"
                      },
                      "hi": {
                        "type": "number"
                      },
                      "halfWidth": {
                        "type": "number"
                      },
                      "n": {
                        "type": "integer"
                      }
                    }
                  },
                  "insideCi": {
                    "type": "boolean"
                  },
                  "replications": {
                    "type": "integer"
                  },
                  "horizonSeconds": {
                    "type": "number"
                  }
                }
              }
            }
          },
          "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"
              }
            }
          }
        }
      }
    }
  }
}