{
  "schemaVersion": 1,
  "slug": "love-compatibility-calculator",
  "category": "fun",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "f55387ce47933b253c986ed9cbeca017207bcd66789a2047297a05df8f8c7bd0",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/love-compatibility-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": "shared = |A ∩ B|; union = |A ∪ B|; score = round(shared ÷ union × 100)",
    "vars": [
      [
        "A",
        "set of distinct letters in name 1"
      ],
      [
        "B",
        "set of distinct letters in name 2"
      ],
      [
        "shared",
        "letters present in both names, |A ∩ B|"
      ],
      [
        "union",
        "letters present in at least one name, |A ∪ B|"
      ],
      [
        "score",
        "0–100 compatibility"
      ]
    ],
    "note": "A and B are sets of distinct Unicode letters; score = |A ∩ B| ÷ |A ∪ B| × 100. Accents and non-Latin scripts are included; this is a word game only."
  },
  "externalEvidence": null,
  "contract": {
    "compute": "const letters=s=>Array.from(String(s).normalize('NFC').toLocaleLowerCase()).filter(ch=>/\\p{L}/u.test(ch));const A=new Set(letters(name1)),B=new Set(letters(name2));if(!A.size||!B.size)return{score:null,sharedLetters:null,sharedCount:null,unionCount:null,verdict:null,__error:'inputError'};const shared=[...A].filter(ch=>B.has(ch)).sort(),un=new Set([...A,...B]),score=Math.round(shared.length/un.size*100);return{score,sharedLetters:shared.join(', ')||'—',sharedCount:shared.length,unionCount:un.size,verdict:score>=70?'Very close names':score>=45?'Some common ground':score>=20?'Quite different':'Almost nothing shared'};",
    "inputs": [
      {
        "name": "name1",
        "type": "text",
        "default": "Alex",
        "step": 1
      },
      {
        "name": "name2",
        "type": "text",
        "default": "Alexis",
        "step": 1
      }
    ],
    "outputs": [
      {
        "name": "score",
        "precision": 0,
        "unit": "%"
      },
      {
        "name": "sharedLetters",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "sharedCount",
        "precision": 0,
        "unit": ""
      },
      {
        "name": "unionCount",
        "precision": 0,
        "unit": ""
      },
      {
        "name": "verdict",
        "precision": 0,
        "unit": "",
        "type": "text"
      }
    ],
    "interpret": null
  }
}
