{
  "schemaVersion": 1,
  "slug": "heart-rate-zone-calculator",
  "category": "health",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "6400742ffc9db772522ead3cffef35c2097e27d0b7a1d9a68993138b86962163",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/heart-rate-zone-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": "HR_p = RHR + p×(208 − 0.7×age − RHR)",
    "vars": [
      [
        "age",
        "Age in years"
      ],
      [
        "RHR",
        "Resting heart rate"
      ],
      [
        "p",
        "Zone fraction of heart-rate reserve"
      ],
      [
        "HR_p",
        "Target heart rate"
      ]
    ],
    "note": "HRmax = 208 − 0.7×age; HR(p) = RHR + p×(HRmax−RHR). p bands: 0.60–0.70, 0.70–0.80, 0.80–0.90, ≥0.90. Population estimate only; not a measured or prescribed target."
  },
  "externalEvidence": null,
  "contract": {
    "compute": "const maxHR=208-0.7*age,hrr=maxHR-restingHR;if(!Number.isFinite(hrr)||hrr<=0)return{__error:'inputError'};const at=p=>Math.round(restingHR+p*hrr);return{maxHR:Math.round(maxHR),zone2Low:at(.6),zone2High:at(.7),zone3Low:at(.7),zone4Low:at(.8),zone5Low:at(.9),zone1Range:at(.5)+' / '+at(.6),zone2Range:at(.6)+' / '+at(.7),zone3Range:at(.7)+' / '+at(.8),zone4Range:at(.8)+' / '+at(.9),zone5Range:at(.9)+' / '+at(1)};",
    "inputs": [
      {
        "name": "age",
        "type": "number",
        "default": 30,
        "min": 18,
        "max": 100,
        "step": 1,
        "requiredValue": true
      },
      {
        "name": "restingHR",
        "type": "number",
        "default": 60,
        "min": 30,
        "max": 120,
        "step": 1,
        "requiredValue": true
      }
    ],
    "outputs": [
      {
        "name": "zone2Range",
        "type": "text",
        "precision": 0,
        "unit": "bpm",
        "range": true
      },
      {
        "name": "zone1Range",
        "type": "text",
        "precision": 0,
        "unit": "bpm",
        "range": true
      },
      {
        "name": "zone3Range",
        "type": "text",
        "precision": 0,
        "unit": "bpm",
        "range": true
      },
      {
        "name": "zone4Range",
        "type": "text",
        "precision": 0,
        "unit": "bpm",
        "range": true
      },
      {
        "name": "zone5Range",
        "type": "text",
        "precision": 0,
        "unit": "bpm",
        "range": true
      },
      {
        "name": "maxHR",
        "precision": 0,
        "unit": "bpm",
        "trimTrailingZeros": true
      },
      {
        "name": "zone2Low",
        "precision": 0,
        "unit": "bpm",
        "trimTrailingZeros": true
      },
      {
        "name": "zone2High",
        "precision": 0,
        "unit": "bpm",
        "trimTrailingZeros": true
      },
      {
        "name": "zone3Low",
        "precision": 0,
        "unit": "bpm",
        "trimTrailingZeros": true
      },
      {
        "name": "zone4Low",
        "precision": 0,
        "unit": "bpm",
        "trimTrailingZeros": true
      },
      {
        "name": "zone5Low",
        "precision": 0,
        "unit": "bpm",
        "trimTrailingZeros": true
      }
    ],
    "interpret": null
  }
}
