{
  "schemaVersion": 1,
  "slug": "hair-growth-calculator",
  "category": "household",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "260d934de207189eb8f56115e68630da3c352cebc4d06b46d78269b92a2a4cd9",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/hair-growth-calculator.json",
    "src/engine.js"
  ],
  "runtimeSource": "/sources/engine.txt",
  "runtimeHash": "5c888d8898afbdee36267bb9977829e1e2ac568f6677c8ee87469c139864645c",
  "scope": "The compute function records implemented equations, constants, lookup tables and custom rules. Inputs record defaults and allowed values; outputs record precision and units. Defaults are examples, not recommendations. General background references are not evidence for this specific algorithm.",
  "publishedFormula": {
    "formula": "L = L_0 + max(0, g − t)×m",
    "vars": [
      [
        "L_0",
        "Current length"
      ],
      [
        "g",
        "Monthly growth"
      ],
      [
        "t",
        "Monthly trim amount"
      ],
      [
        "m",
        "Number of months"
      ],
      [
        "L",
        "Projected length"
      ]
    ],
    "note": "Months to target is available only when the target is already met or net modeled growth is positive. If trims equal or exceed modeled growth before reaching the target, no finite time is reported."
  },
  "externalEvidence": null,
  "contract": {
    "compute": "const netGrowth=Math.max(0,growthRate-trimPerMonth); const projectedLength=currentLength+netGrowth*months; const need=Math.max(0,targetLength-currentLength); const already=need===0; const reachable=netGrowth>0; return {netGrowth,projectedLength,projectedLengthCm:projectedLength*2.54,monthsToTarget:reachable?need/netGrowth:already?0:null,targetStatus:already?'Target already met':reachable?'Reachable at this model rate':'Not reached with current growth and trim'};",
    "inputs": [
      {
        "name": "currentLength",
        "type": "number",
        "default": 12,
        "min": 0,
        "max": 60,
        "step": 0.5,
        "slider": true
      },
      {
        "name": "targetLength",
        "type": "number",
        "default": 24,
        "min": 0,
        "max": 80,
        "step": 0.5,
        "slider": true
      },
      {
        "name": "months",
        "type": "number",
        "default": 12,
        "min": 1,
        "max": 240,
        "step": 1,
        "slider": true
      },
      {
        "name": "growthRate",
        "type": "number",
        "default": 0.5,
        "min": 0.1,
        "max": 1.5,
        "step": 0.05,
        "slider": true
      },
      {
        "name": "trimPerMonth",
        "type": "number",
        "default": 0,
        "min": 0,
        "max": 1,
        "step": 0.25
      }
    ],
    "outputs": [
      {
        "name": "netGrowth",
        "precision": 2,
        "unit": "in"
      },
      {
        "name": "projectedLength",
        "precision": 1,
        "unit": "in"
      },
      {
        "name": "projectedLengthCm",
        "precision": 1,
        "unit": "cm"
      },
      {
        "name": "monthsToTarget",
        "precision": 1,
        "unit": "months",
        "optional": true
      },
      {
        "name": "targetStatus",
        "precision": 0,
        "unit": "",
        "type": "text"
      }
    ],
    "interpret": null
  }
}
