{
  "schemaVersion": 1,
  "slug": "vacation-day-calculator",
  "category": "travel",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "84642c10e4120c1142681f31e0cbd46c3cb3705246c1a1b0c98d54ab30536010",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/vacation-day-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": "Monthly: R = min(c,c_max) + A₀÷12×m − u − p; front-loaded: R = min(c,c_max) + A₀ − u − p; F = max(0,c−c_max)",
    "vars": [
      [
        "A₀",
        "Annual allowance (days)"
      ],
      [
        "m",
        "Months worked"
      ],
      [
        "c",
        "Carryover (days)"
      ],
      [
        "c_max",
        "Entered carryover cap"
      ],
      [
        "u",
        "Days already used"
      ],
      [
        "p",
        "Days planned for the trip"
      ],
      [
        "R",
        "Remaining after the trip"
      ],
      [
        "F",
        "Carryover above the entered cap"
      ]
    ],
    "note": "Unlimited PTO returns no numeric day balance; it does not imply trip approval. Monthly accrual is a simple annual/12 × months model; front-loaded grants the full allowance at year start. F is only the amount above the entered cap, not a legal forfeiture determination."
  },
  "externalEvidence": null,
  "contract": {
    "compute": "const accrued=accrualType==='frontLoaded'?annualAllowance:accrualType==='unlimited'?null:annualAllowance/12*Math.min(12,monthsWorked);const unlimited=accrualType==='unlimited';const total=unlimited?null:Math.min(carryover,maxCarryover)+accrued;const available=unlimited?null:total-daysUsed;const remaining=unlimited?null:available-plannedDays;const forfeit=unlimited?null:Math.max(0,carryover-maxCarryover);return {accrued,available,remaining,forfeit,verdict:unlimited?'Unlimited PTO — check approval and notice rules':remaining>=0?'Within entered balance':'Exceeds entered balance'};",
    "inputs": [
      {
        "name": "annualAllowance",
        "type": "number",
        "default": 20,
        "min": 0,
        "max": 365,
        "step": 0.5,
        "slider": true
      },
      {
        "name": "monthsWorked",
        "type": "number",
        "default": 8,
        "min": 0,
        "max": 12,
        "step": 0.5,
        "slider": true
      },
      {
        "name": "daysUsed",
        "type": "number",
        "default": 6,
        "min": 0,
        "max": 365,
        "step": 0.5,
        "slider": true
      },
      {
        "name": "accrualType",
        "type": "select",
        "default": "monthly",
        "options": [
          {
            "value": "monthly"
          },
          {
            "value": "frontLoaded"
          },
          {
            "value": "unlimited"
          }
        ]
      },
      {
        "name": "carryover",
        "type": "number",
        "default": 2,
        "min": 0,
        "max": 100,
        "step": 0.5,
        "slider": true
      },
      {
        "name": "maxCarryover",
        "type": "number",
        "default": 5,
        "min": 0,
        "max": 100,
        "step": 0.5,
        "slider": true
      },
      {
        "name": "plannedDays",
        "type": "number",
        "default": 10,
        "min": 0,
        "max": 200,
        "step": 0.5,
        "slider": true
      }
    ],
    "outputs": [
      {
        "name": "accrued",
        "precision": 1,
        "unit": "days",
        "optional": true
      },
      {
        "name": "available",
        "precision": 1,
        "unit": "days",
        "optional": true
      },
      {
        "name": "remaining",
        "precision": 1,
        "unit": "days",
        "optional": true
      },
      {
        "name": "forfeit",
        "precision": 1,
        "unit": "days",
        "optional": true
      },
      {
        "name": "verdict",
        "precision": 0,
        "unit": "",
        "type": "text"
      }
    ],
    "interpret": null
  }
}
