{
  "schemaVersion": 1,
  "slug": "roofing-calculator",
  "category": "construction",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "e109650ce2c2bae83d218609915cc8a0c054409e5670610d5b79e79e8094aa3a",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/roofing-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": "A = F × √(144 + P²) ÷ 12 × (1 + w ÷ 100); B = ceil(3A ÷ 100)",
    "vars": [
      [
        "F",
        "Footprint area (sq ft)"
      ],
      [
        "P",
        "Pitch (per 12 in)"
      ],
      [
        "w",
        "Waste allowance (%)"
      ],
      [
        "A",
        "Sloped roof area (sq ft)"
      ],
      [
        "B",
        "Shingle bundles"
      ]
    ],
    "note": "A roofing square is 100 sq ft. This calculator assumes 3 shingle bundles per square and 1 underlayment roll per 10 squares; actual package coverage varies. Cost uses fractional squares after waste and is not a supplier-ready rounded purchase quote."
  },
  "externalEvidence": null,
  "contract": {
    "compute": "const multiplier = Math.sqrt(144+pitch*pitch)/12; const surfaceArea = footprintArea*multiplier*(1+waste/100); const squares = surfaceArea/100; return { surfaceArea, squares, bundles: Math.ceil(squares*3), underlaymentRolls: Math.ceil(squares/10), cost: squares*pricePerSquare };",
    "inputs": [
      {
        "name": "footprintArea",
        "type": "number",
        "default": 1500,
        "min": 1,
        "max": 200000,
        "step": 1
      },
      {
        "name": "pitch",
        "type": "number",
        "default": 6,
        "min": 1,
        "max": 24,
        "step": 1,
        "slider": true
      },
      {
        "name": "waste",
        "type": "number",
        "default": 10,
        "min": 0,
        "max": 30,
        "step": 1,
        "slider": true
      },
      {
        "name": "pricePerSquare",
        "type": "number",
        "default": 130,
        "min": 0,
        "max": 2000,
        "step": 5,
        "slider": true
      }
    ],
    "outputs": [
      {
        "name": "surfaceArea",
        "precision": 0,
        "unit": "sq ft"
      },
      {
        "name": "squares",
        "precision": 2,
        "unit": "squares"
      },
      {
        "name": "bundles",
        "precision": 0,
        "unit": ""
      },
      {
        "name": "underlaymentRolls",
        "precision": 0,
        "unit": ""
      },
      {
        "name": "cost",
        "precision": 2,
        "unit": "$"
      }
    ],
    "interpret": null
  }
}
