{
  "schemaVersion": 1,
  "slug": "travel-packing-list-calculator",
  "category": "travel",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "e36879001c8d5c7f6fa8fcbb72882c970d136c023009dc4230ec079836d84f65",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/travel-packing-list-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": "p₀ = { min(d,l), l > 0; d, l = 0 }; p = { p₀, c = 1; min(p₀,5), c = 0 }; tops = ⌈p ÷ 1.5⌉; bottoms = ⌈p ÷ 3⌉; underwear = p + 1; socks = p",
    "vars": [
      [
        "p,p₀",
        "Packing days; laundry-limited days"
      ],
      [
        "d",
        "Trip days"
      ],
      [
        "l",
        "Laundry interval (days)"
      ],
      [
        "c",
        "Checked-bag flag (1 yes, 0 no)"
      ],
      [
        "tops,bottoms",
        "Tops; bottoms"
      ]
    ],
    "note": "Shoes = 2 pairs (3 for active/beach); climate and activity extras come from lookup tables (text)."
  },
  "externalEvidence": null,
  "contract": {
    "compute": "const baseDays = laundryDays > 0 ? Math.min(days, laundryDays) : days; const packingDays = checkedBag === 'no' ? Math.min(baseDays, 5) : baseDays; const tops = Math.ceil(packingDays/1.5); const bottoms = Math.ceil(packingDays/3); const underwear = packingDays+1; const socks = packingDays; const shoes = activities === 'active' ? 3 : activities === 'beach' ? 3 : 2; const C = { hot: 'Lightweight breathable fabrics, sun hat, insect repellent, refillable water bottle', temperate: 'Layers, a light rain jacket and a compact umbrella', cold: 'Thermal base layers, insulated jacket, gloves and a hat', mixed: 'Layers that work together — a packable shell is the key item', formal: 'Smart outfit, dress shoes and a travel steamer or wrinkle-release spray' }; const A = { leisure: 'Comfortable walking shoes and a day bag', active: 'Technical layers, blister plasters and a hydration plan', beach: 'Swimwear, quick-dry towel and reef-safe sunscreen', city: 'A crossbody bag and a power bank for long days out' }; return { packingSummary: [tops,bottoms,underwear,socks,shoes].join(\" / \"), packingDays, tops, bottoms, underwear, socks, shoes, extras: C[climate]+'  |  '+A[activities] };",
    "inputs": [
      {
        "name": "days",
        "type": "number",
        "default": 10,
        "min": 1,
        "max": 365,
        "step": 1,
        "slider": true
      },
      {
        "name": "laundryDays",
        "type": "number",
        "default": 0,
        "min": 0,
        "max": 60,
        "step": 1,
        "slider": true
      },
      {
        "name": "climate",
        "type": "select",
        "default": "temperate",
        "options": [
          {
            "value": "hot"
          },
          {
            "value": "temperate"
          },
          {
            "value": "cold"
          },
          {
            "value": "mixed"
          },
          {
            "value": "formal"
          }
        ]
      },
      {
        "name": "activities",
        "type": "select",
        "default": "leisure",
        "options": [
          {
            "value": "leisure"
          },
          {
            "value": "active"
          },
          {
            "value": "beach"
          },
          {
            "value": "city"
          }
        ]
      },
      {
        "name": "checkedBag",
        "type": "select",
        "default": "yes",
        "options": [
          {
            "value": "yes"
          },
          {
            "value": "no"
          }
        ]
      }
    ],
    "outputs": [
      {
        "name": "packingSummary",
        "type": "text",
        "components": [
          "tops",
          "bottoms",
          "underwear",
          "socks",
          "shoes"
        ],
        "unit": ""
      },
      {
        "name": "packingDays",
        "precision": 0,
        "unit": "days"
      },
      {
        "name": "tops",
        "precision": 0,
        "unit": "",
        "checklist": true
      },
      {
        "name": "bottoms",
        "precision": 0,
        "unit": "",
        "checklist": true
      },
      {
        "name": "underwear",
        "precision": 0,
        "unit": "",
        "checklist": true
      },
      {
        "name": "socks",
        "precision": 0,
        "unit": "",
        "checklist": true
      },
      {
        "name": "shoes",
        "precision": 0,
        "unit": "",
        "checklist": true
      },
      {
        "name": "extras",
        "precision": 0,
        "unit": "",
        "type": "text",
        "display": "list",
        "separator": "|"
      }
    ],
    "interpret": null
  }
}
