{"abstract":"Lowercase pairs receive the tighter uppercase kerning value.","category":"Typography line breaking","checks":8,"contract":"Input [words, width]. Glyph widths: i,l,j,.,, 4; t,f 6; m 15; w 14; M 16; W 18; other lowercase 10; other uppercase 13; space 5. Within a word, fi/fl/ff form ligatures (11/11/12) with no kerning into or out of them; case-sensitive kern pairs apply between adjacent glyphs; \"|\" is a non-joiner (invisible, blocks ligatures and kerning). No kerning across spaces. Greedy fill. Return [[text, width]].","evaluation_group":"w2-typography-line-breaking-kern-ligature-measure","failed_approach":"Falling back to the lowercase pair kerns mixed-case pairs that have no entry.","family":"w2-typography-line-breaking-kern-ligature-measure-kern-pair-case-sensitivity","id":"FA-80166","implementations":{"attempt":{"sha256":"4e7433b7c47152208e87300d1794e7a71c2a92a34c9982333e7891322e46cfa6","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    words, width = x\n    W = {'i': 4, 'l': 4, 'j': 4, '.': 4, ',': 4, 't': 6, 'f': 6, 'm': 15, 'w': 14, 'M': 16, 'W': 18}\n    LIG = {'fi': 11, 'fl': 11, 'ff': 12}\n    KERN = {'AV': -3, 'VA': -3, 'To': -2, 'Ta': -2, 'Yo': -2, 'LT': -3, 'Wa': -2, 'av': -1, 'va': -1, 'y.': -2, 'r.': -2, 'l.': -1, 'f.': -1, 'Va': -2}\n    SPACE = 5\n    def glyph(c):\n        return W.get(c, 13 if c.isupper() else 10)\n    def measure(w):\n        total, prev, i = 0, None, 0\n        while i < len(w):\n            if w[i] == '|':\n                prev = None\n                i += 1\n                continue\n            pair = w[i:i + 2]\n            if pair in LIG:\n                total += LIG[pair]\n                prev = None\n                i += 2\n                continue\n            g = w[i]\n            total += glyph(g)\n            if prev is not None:\n                total += KERN.get(prev + g, 0) or KERN.get((prev + g).lower(), 0)\n            prev = g\n            i += 1\n        return total\n    def line_width(ws):\n        return sum(measure(t) for t in ws) + SPACE * (len(ws) - 1)\n    lines, cur = [], []\n    for w in words:\n        cand = cur + [w]\n        if not cur or line_width(cand) <= width:\n            cur = cand\n        else:\n            lines.append(cur)\n            cur = [w]\n    if cur:\n        lines.append(cur)\n    return [[' '.join(t.replace('|', '') for t in ln), line_width(ln)] for ln in lines]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('regression: kern pair case sensitivity', [['y.', 'Yo', 'fi', 'wolf|like'], 47], [['y. Yo', 38], ['fi', 11], ['wolflike', 62]]), ('regression: kern pair case sensitivity', [['Av', 'fly.', 'LA|VALLE', 'y.', 'office', 'raffle', 'VIA'], 77], [['Av fly.', 51], ['LAVALLE', 88], ['y. office', 63], ['raffle', 46], ['VIA', 39]]), ('regression: kern pair case sensitivity', [['Av', 'flow'], 132], [['Av flow', 63]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('control layout', [['VIA', 'LA|VALLE', 'Wavy', 'wolf|like'], 72], [['VIA', 39], ['LAVALLE', 88], ['Wavy', 45], ['wolflike', 62]]), ('control layout', [['AVAIL', 'shelf|life', 'AT'], 140], [['AVAIL shelflife', 128], ['AT', 26]])], [('regression: kern pair case sensitivity', [['LT', 'Vat', 'office', 'LA', 'dry.', 'dry.', 'dry.'], 122], [['LT Vat office', 106], ['LA dry. dry.', 100], ['dry.', 32]]), ('regression: kern pair case sensitivity', [['office', 'wolf|like', 'flow', 'VIA', 'LT', 'Ta'], 45], [['office', 46], ['wolflike', 62], ['flow', 35], ['VIA', 39], ['LT', 23], ['Ta', 21]]), ('regression: kern pair case sensitivity', [['our', 'Av', 'fly.', 'av'], 83], [['our Av', 58], ['fly. av', 47]]), ('regression: kern pair case sensitivity', [['Av', 'Tofu'], 41], [['Av', 23], ['Tofu', 37]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('control layout', [['AT', 'flow'], 114], [['AT flow', 66]]), ('control layout', [['shelf|life', 'our'], 55], [['shelflife', 64], ['our', 30]])], [('regression: kern pair case sensitivity', [['fly.', 'Yo'], 43], [['fly.', 23], ['Yo', 21]]), ('regression: kern pair case sensitivity', [['staff.', 'Av', 'Av', 'Av', 'LT'], 91], [['staff. Av', 70], ['Av Av LT', 79]]), ('regression: kern pair case sensitivity', [['flow', 'Ta', 'Ta', 'Av', 'LA|VALLE'], 115], [['flow Ta Ta Av', 115], ['LAVALLE', 88]]), ('regression: kern pair case sensitivity', [['LA|VALLE', 'av', 'Av', 'AT'], 122], [['LAVALLE av', 112], ['Av AT', 54]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('control layout', [['office', 'VIA'], 112], [['office VIA', 90]]), ('control layout', [['LA|VALLE', 'office', 'raffle', 'LA', 'staff.'], 129], [['LAVALLE', 88], ['office raffle LA', 128], ['staff.', 42]])], [('regression: kern pair case sensitivity', [['Tofu', 'Av'], 95], [['Tofu Av', 65]]), ('regression: kern pair case sensitivity', [['Wavy', 'VIA', 'y.', 'wolf|like', 'fi'], 95], [['Wavy VIA', 89], ['y. wolflike fi', 95]]), ('regression: kern pair case sensitivity', [['Av', 'Tofu'], 41], [['Av', 23], ['Tofu', 37]]), ('regression: kern pair case sensitivity', [['Av', 'LA', 'Tofu', 'y.'], 125], [['Av LA Tofu y.', 113]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('control layout', [['staff.', 'office'], 111], [['staff. office', 93]]), ('control layout', [['AVAIL', 'raffle', 'raffle', 'LA', 'office', 'VIA', 'AT'], 79], [['AVAIL', 59], ['raffle', 46], ['raffle LA', 77], ['office', 46], ['VIA AT', 70]])], [('regression: kern pair case sensitivity', [['Vat', 'office', 'flow', 'LA', 'staff.', 'AT'], 44], [['Vat', 27], ['office', 46], ['flow', 35], ['LA', 26], ['staff.', 42], ['AT', 26]]), ('regression: kern pair case sensitivity', [['LT', 'staff.', 'LA|VALLE', 'LA|VALLE', 'Vat', 'office'], 95], [['LT staff.', 70], ['LAVALLE', 88], ['LAVALLE', 88], ['Vat office', 78]]), ('regression: kern pair case sensitivity', [['LA|VALLE', 'av', 'Av', 'AT'], 122], [['LAVALLE av', 112], ['Av AT', 54]]), ('regression: kern pair case sensitivity', [['Av', 'LA|VALLE', 'Ta', 'VIA'], 53], [['Av', 23], ['LAVALLE', 88], ['Ta', 21], ['VIA', 39]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('control layout', [['office', 'VIA'], 112], [['office VIA', 90]]), ('control layout', [['staff.', 'office'], 118], [['staff. office', 93]])]]\nfor label, args, expected in fixtures[N - 1]:\n    check(label, solve(args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"12c6c0aac30a5b608ba9b615ee06592e5db376a57c99ffb961f0daef34e8e3e9","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    words, width = x\n    W = {'i': 4, 'l': 4, 'j': 4, '.': 4, ',': 4, 't': 6, 'f': 6, 'm': 15, 'w': 14, 'M': 16, 'W': 18}\n    LIG = {'fi': 11, 'fl': 11, 'ff': 12}\n    KERN = {'AV': -3, 'VA': -3, 'To': -2, 'Ta': -2, 'Yo': -2, 'LT': -3, 'Wa': -2, 'av': -1, 'va': -1, 'y.': -2, 'r.': -2, 'l.': -1, 'f.': -1, 'Va': -2}\n    SPACE = 5\n    def glyph(c):\n        return W.get(c, 13 if c.isupper() else 10)\n    def measure(w):\n        total, prev, i = 0, None, 0\n        while i < len(w):\n            if w[i] == '|':\n                prev = None\n                i += 1\n                continue\n            pair = w[i:i + 2]\n            if pair in LIG:\n                total += LIG[pair]\n                prev = None\n                i += 2\n                continue\n            g = w[i]\n            total += glyph(g)\n            if prev is not None:\n                total += KERN.get((prev + g).upper(), 0)\n            prev = g\n            i += 1\n        return total\n    def line_width(ws):\n        return sum(measure(t) for t in ws) + SPACE * (len(ws) - 1)\n    lines, cur = [], []\n    for w in words:\n        cand = cur + [w]\n        if not cur or line_width(cand) <= width:\n            cur = cand\n        else:\n            lines.append(cur)\n            cur = [w]\n    if cur:\n        lines.append(cur)\n    return [[' '.join(t.replace('|', '') for t in ln), line_width(ln)] for ln in lines]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('regression: kern pair case sensitivity', [['y.', 'Yo', 'fi', 'wolf|like'], 47], [['y. Yo', 38], ['fi', 11], ['wolflike', 62]]), ('regression: kern pair case sensitivity', [['Av', 'fly.', 'LA|VALLE', 'y.', 'office', 'raffle', 'VIA'], 77], [['Av fly.', 51], ['LAVALLE', 88], ['y. office', 63], ['raffle', 46], ['VIA', 39]]), ('regression: kern pair case sensitivity', [['Av', 'flow'], 132], [['Av flow', 63]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('control layout', [['VIA', 'LA|VALLE', 'Wavy', 'wolf|like'], 72], [['VIA', 39], ['LAVALLE', 88], ['Wavy', 45], ['wolflike', 62]]), ('control layout', [['AVAIL', 'shelf|life', 'AT'], 140], [['AVAIL shelflife', 128], ['AT', 26]])], [('regression: kern pair case sensitivity', [['LT', 'Vat', 'office', 'LA', 'dry.', 'dry.', 'dry.'], 122], [['LT Vat office', 106], ['LA dry. dry.', 100], ['dry.', 32]]), ('regression: kern pair case sensitivity', [['office', 'wolf|like', 'flow', 'VIA', 'LT', 'Ta'], 45], [['office', 46], ['wolflike', 62], ['flow', 35], ['VIA', 39], ['LT', 23], ['Ta', 21]]), ('regression: kern pair case sensitivity', [['our', 'Av', 'fly.', 'av'], 83], [['our Av', 58], ['fly. av', 47]]), ('regression: kern pair case sensitivity', [['Av', 'Tofu'], 41], [['Av', 23], ['Tofu', 37]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('control layout', [['AT', 'flow'], 114], [['AT flow', 66]]), ('control layout', [['shelf|life', 'our'], 55], [['shelflife', 64], ['our', 30]])], [('regression: kern pair case sensitivity', [['fly.', 'Yo'], 43], [['fly.', 23], ['Yo', 21]]), ('regression: kern pair case sensitivity', [['staff.', 'Av', 'Av', 'Av', 'LT'], 91], [['staff. Av', 70], ['Av Av LT', 79]]), ('regression: kern pair case sensitivity', [['flow', 'Ta', 'Ta', 'Av', 'LA|VALLE'], 115], [['flow Ta Ta Av', 115], ['LAVALLE', 88]]), ('regression: kern pair case sensitivity', [['LA|VALLE', 'av', 'Av', 'AT'], 122], [['LAVALLE av', 112], ['Av AT', 54]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('control layout', [['office', 'VIA'], 112], [['office VIA', 90]]), ('control layout', [['LA|VALLE', 'office', 'raffle', 'LA', 'staff.'], 129], [['LAVALLE', 88], ['office raffle LA', 128], ['staff.', 42]])], [('regression: kern pair case sensitivity', [['Tofu', 'Av'], 95], [['Tofu Av', 65]]), ('regression: kern pair case sensitivity', [['Wavy', 'VIA', 'y.', 'wolf|like', 'fi'], 95], [['Wavy VIA', 89], ['y. wolflike fi', 95]]), ('regression: kern pair case sensitivity', [['Av', 'Tofu'], 41], [['Av', 23], ['Tofu', 37]]), ('regression: kern pair case sensitivity', [['Av', 'LA', 'Tofu', 'y.'], 125], [['Av LA Tofu y.', 113]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('control layout', [['staff.', 'office'], 111], [['staff. office', 93]]), ('control layout', [['AVAIL', 'raffle', 'raffle', 'LA', 'office', 'VIA', 'AT'], 79], [['AVAIL', 59], ['raffle', 46], ['raffle LA', 77], ['office', 46], ['VIA AT', 70]])], [('regression: kern pair case sensitivity', [['Vat', 'office', 'flow', 'LA', 'staff.', 'AT'], 44], [['Vat', 27], ['office', 46], ['flow', 35], ['LA', 26], ['staff.', 42], ['AT', 26]]), ('regression: kern pair case sensitivity', [['LT', 'staff.', 'LA|VALLE', 'LA|VALLE', 'Vat', 'office'], 95], [['LT staff.', 70], ['LAVALLE', 88], ['LAVALLE', 88], ['Vat office', 78]]), ('regression: kern pair case sensitivity', [['LA|VALLE', 'av', 'Av', 'AT'], 122], [['LAVALLE av', 112], ['Av AT', 54]]), ('regression: kern pair case sensitivity', [['Av', 'LA|VALLE', 'Ta', 'VIA'], 53], [['Av', 23], ['LAVALLE', 88], ['Ta', 21], ['VIA', 39]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('control layout', [['office', 'VIA'], 112], [['office VIA', 90]]), ('control layout', [['staff.', 'office'], 118], [['staff. office', 93]])]]\nfor label, args, expected in fixtures[N - 1]:\n    check(label, solve(args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"fixed":{"sha256":"2b50db8a106812322b8f40f721fb40600252a5cf9ad1f3d9401584105efd65db","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    words, width = x\n    W = {'i': 4, 'l': 4, 'j': 4, '.': 4, ',': 4, 't': 6, 'f': 6, 'm': 15, 'w': 14, 'M': 16, 'W': 18}\n    LIG = {'fi': 11, 'fl': 11, 'ff': 12}\n    KERN = {'AV': -3, 'VA': -3, 'To': -2, 'Ta': -2, 'Yo': -2, 'LT': -3, 'Wa': -2, 'av': -1, 'va': -1, 'y.': -2, 'r.': -2, 'l.': -1, 'f.': -1, 'Va': -2}\n    SPACE = 5\n    def glyph(c):\n        return W.get(c, 13 if c.isupper() else 10)\n    def measure(w):\n        total, prev, i = 0, None, 0\n        while i < len(w):\n            if w[i] == '|':\n                prev = None\n                i += 1\n                continue\n            pair = w[i:i + 2]\n            if pair in LIG:\n                total += LIG[pair]\n                prev = None\n                i += 2\n                continue\n            g = w[i]\n            total += glyph(g)\n            if prev is not None:\n                total += KERN.get(prev + g, 0)\n            prev = g\n            i += 1\n        return total\n    def line_width(ws):\n        return sum(measure(t) for t in ws) + SPACE * (len(ws) - 1)\n    lines, cur = [], []\n    for w in words:\n        cand = cur + [w]\n        if not cur or line_width(cand) <= width:\n            cur = cand\n        else:\n            lines.append(cur)\n            cur = [w]\n    if cur:\n        lines.append(cur)\n    return [[' '.join(t.replace('|', '') for t in ln), line_width(ln)] for ln in lines]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('regression: kern pair case sensitivity', [['y.', 'Yo', 'fi', 'wolf|like'], 47], [['y. Yo', 38], ['fi', 11], ['wolflike', 62]]), ('regression: kern pair case sensitivity', [['Av', 'fly.', 'LA|VALLE', 'y.', 'office', 'raffle', 'VIA'], 77], [['Av fly.', 51], ['LAVALLE', 88], ['y. office', 63], ['raffle', 46], ['VIA', 39]]), ('regression: kern pair case sensitivity', [['Av', 'flow'], 132], [['Av flow', 63]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('control layout', [['VIA', 'LA|VALLE', 'Wavy', 'wolf|like'], 72], [['VIA', 39], ['LAVALLE', 88], ['Wavy', 45], ['wolflike', 62]]), ('control layout', [['AVAIL', 'shelf|life', 'AT'], 140], [['AVAIL shelflife', 128], ['AT', 26]])], [('regression: kern pair case sensitivity', [['LT', 'Vat', 'office', 'LA', 'dry.', 'dry.', 'dry.'], 122], [['LT Vat office', 106], ['LA dry. dry.', 100], ['dry.', 32]]), ('regression: kern pair case sensitivity', [['office', 'wolf|like', 'flow', 'VIA', 'LT', 'Ta'], 45], [['office', 46], ['wolflike', 62], ['flow', 35], ['VIA', 39], ['LT', 23], ['Ta', 21]]), ('regression: kern pair case sensitivity', [['our', 'Av', 'fly.', 'av'], 83], [['our Av', 58], ['fly. av', 47]]), ('regression: kern pair case sensitivity', [['Av', 'Tofu'], 41], [['Av', 23], ['Tofu', 37]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('control layout', [['AT', 'flow'], 114], [['AT flow', 66]]), ('control layout', [['shelf|life', 'our'], 55], [['shelflife', 64], ['our', 30]])], [('regression: kern pair case sensitivity', [['fly.', 'Yo'], 43], [['fly.', 23], ['Yo', 21]]), ('regression: kern pair case sensitivity', [['staff.', 'Av', 'Av', 'Av', 'LT'], 91], [['staff. Av', 70], ['Av Av LT', 79]]), ('regression: kern pair case sensitivity', [['flow', 'Ta', 'Ta', 'Av', 'LA|VALLE'], 115], [['flow Ta Ta Av', 115], ['LAVALLE', 88]]), ('regression: kern pair case sensitivity', [['LA|VALLE', 'av', 'Av', 'AT'], 122], [['LAVALLE av', 112], ['Av AT', 54]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('control layout', [['office', 'VIA'], 112], [['office VIA', 90]]), ('control layout', [['LA|VALLE', 'office', 'raffle', 'LA', 'staff.'], 129], [['LAVALLE', 88], ['office raffle LA', 128], ['staff.', 42]])], [('regression: kern pair case sensitivity', [['Tofu', 'Av'], 95], [['Tofu Av', 65]]), ('regression: kern pair case sensitivity', [['Wavy', 'VIA', 'y.', 'wolf|like', 'fi'], 95], [['Wavy VIA', 89], ['y. wolflike fi', 95]]), ('regression: kern pair case sensitivity', [['Av', 'Tofu'], 41], [['Av', 23], ['Tofu', 37]]), ('regression: kern pair case sensitivity', [['Av', 'LA', 'Tofu', 'y.'], 125], [['Av LA Tofu y.', 113]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('control layout', [['staff.', 'office'], 111], [['staff. office', 93]]), ('control layout', [['AVAIL', 'raffle', 'raffle', 'LA', 'office', 'VIA', 'AT'], 79], [['AVAIL', 59], ['raffle', 46], ['raffle LA', 77], ['office', 46], ['VIA AT', 70]])], [('regression: kern pair case sensitivity', [['Vat', 'office', 'flow', 'LA', 'staff.', 'AT'], 44], [['Vat', 27], ['office', 46], ['flow', 35], ['LA', 26], ['staff.', 42], ['AT', 26]]), ('regression: kern pair case sensitivity', [['LT', 'staff.', 'LA|VALLE', 'LA|VALLE', 'Vat', 'office'], 95], [['LT staff.', 70], ['LAVALLE', 88], ['LAVALLE', 88], ['Vat office', 78]]), ('regression: kern pair case sensitivity', [['LA|VALLE', 'av', 'Av', 'AT'], 122], [['LAVALLE av', 112], ['Av AT', 54]]), ('regression: kern pair case sensitivity', [['Av', 'LA|VALLE', 'Ta', 'VIA'], 53], [['Av', 23], ['LAVALLE', 88], ['Ta', 21], ['VIA', 39]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('control layout', [['office', 'VIA'], 112], [['office VIA', 90]]), ('control layout', [['staff.', 'office'], 118], [['staff. office', 93]])]]\nfor label, args, expected in fixtures[N - 1]:\n    check(label, solve(args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":"A deterministic toy typesetting model with integer widths and a stipulated rule set; it does not claim conformance to any engine. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.","method":"Deterministic executable model with adversarial boundary fixtures.","provenance":{"created_by":"Failure Map","dependencies":"Python standard library","family":"w2-typography-line-breaking-kern-ligature-measure-kern-pair-case-sensitivity","generated_at":"2026-09-29T14:49:51.509376+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Line breaking decides where paragraphs wrap on screen and in print; a wrong decision point shifts every following line.","repair":"Look up kern pairs exactly as they appear.","root_cause":"Kern lookups uppercase the pair before searching the table.","sha256":"a3240a82118c1626c0c16e8bf32de6ede3dd7ed342ac72d0fd395f5dd211ca07","title":"Kerning and ligature line measure: kern pair case sensitivity · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":43.472,"exit_code":1,"observations":[{"actual":[["LA Vat",58]],"check":"cross-word pair must not kern","expected":[["LA Vat",58]],"passed":true},{"actual":[["y. Yo",38],["fi",11],["wolflike",62]],"check":"regression: kern pair case sensitivity","expected":[["y. Yo",38],["fi",11],["wolflike",62]],"passed":true},{"actual":[["Av fly.",50],["LAVALLE",88],["y. office",63],["raffle",46],["VIA",39]],"check":"regression: kern pair case sensitivity","expected":[["Av fly.",51],["LAVALLE",88],["y. office",63],["raffle",46],["VIA",39]],"passed":false},{"actual":[["Av flow",62]],"check":"regression: kern pair case sensitivity","expected":[["Av flow",63]],"passed":false},{"actual":[["shelflife",64]],"check":"non-joiner blocks ligature","expected":[["shelflife",64]],"passed":true},{"actual":[["Av av",46]],"check":"case-sensitive pair","expected":[["Av av",47]],"passed":false},{"actual":[["VIA",39],["LAVALLE",88],["Wavy",45],["wolflike",62]],"check":"control layout","expected":[["VIA",39],["LAVALLE",88],["Wavy",45],["wolflike",62]],"passed":true},{"actual":[["AVAIL shelflife",128],["AT",26]],"check":"control layout","expected":[["AVAIL shelflife",128],["AT",26]],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"cross-word pair must not kern\", \"actual\": [[\"LA Vat\", 58]], \"expected\": [[\"LA Vat\", 58]], \"passed\": true}, {\"check\": \"regression: kern pair case sensitivity\", \"actual\": [[\"y. Yo\", 38], [\"fi\", 11], [\"wolflike\", 62]], \"expected\": [[\"y. Yo\", 38], [\"fi\", 11], [\"wolflike\", 62]], \"passed\": true}, {\"check\": \"regression: kern pair case sensitivity\", \"actual\": [[\"Av fly.\", 50], [\"LAVALLE\", 88], [\"y. office\", 63], [\"raffle\", 46], [\"VIA\", 39]], \"expected\": [[\"Av fly.\", 51], [\"LAVALLE\", 88], [\"y. office\", 63], [\"raffle\", 46], [\"VIA\", 39]], \"passed\": false}, {\"check\": \"regression: kern pair case sensitivity\", \"actual\": [[\"Av flow\", 62]], \"expected\": [[\"Av flow\", 63]], \"passed\": false}, {\"check\": \"non-joiner blocks ligature\", \"actual\": [[\"shelflife\", 64]], \"expected\": [[\"shelflife\", 64]], \"passed\": true}, {\"check\": \"case-sensitive pair\", \"actual\": [[\"Av av\", 46]], \"expected\": [[\"Av av\", 47]], \"passed\": false}, {\"check\": \"control layout\", \"actual\": [[\"VIA\", 39], [\"LAVALLE\", 88], [\"Wavy\", 45], [\"wolflike\", 62]], \"expected\": [[\"VIA\", 39], [\"LAVALLE\", 88], [\"Wavy\", 45], [\"wolflike\", 62]], \"passed\": true}, {\"check\": \"control layout\", \"actual\": [[\"AVAIL shelflife\", 128], [\"AT\", 26]], \"expected\": [[\"AVAIL shelflife\", 128], [\"AT\", 26]], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":47.037,"exit_code":1,"observations":[{"actual":[["LA Vat",57]],"check":"cross-word pair must not kern","expected":[["LA Vat",58]],"passed":false},{"actual":[["y. Yo",42],["fi",11],["wolflike",62]],"check":"regression: kern pair case sensitivity","expected":[["y. Yo",38],["fi",11],["wolflike",62]],"passed":false},{"actual":[["Av fly.",50],["LAVALLE",88],["y. office",65],["raffle",46],["VIA",39]],"check":"regression: kern pair case sensitivity","expected":[["Av fly.",51],["LAVALLE",88],["y. office",63],["raffle",46],["VIA",39]],"passed":false},{"actual":[["Av flow",60]],"check":"regression: kern pair case sensitivity","expected":[["Av flow",63]],"passed":false},{"actual":[["shelflife",64]],"check":"non-joiner blocks ligature","expected":[["shelflife",64]],"passed":true},{"actual":[["Av av",42]],"check":"case-sensitive pair","expected":[["Av av",47]],"passed":false},{"actual":[["VIA",39],["LAVALLE",88],["Wavy",45],["wolflike",62]],"check":"control layout","expected":[["VIA",39],["LAVALLE",88],["Wavy",45],["wolflike",62]],"passed":true},{"actual":[["AVAIL shelflife",128],["AT",26]],"check":"control layout","expected":[["AVAIL shelflife",128],["AT",26]],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"cross-word pair must not kern\", \"actual\": [[\"LA Vat\", 57]], \"expected\": [[\"LA Vat\", 58]], \"passed\": false}, {\"check\": \"regression: kern pair case sensitivity\", \"actual\": [[\"y. Yo\", 42], [\"fi\", 11], [\"wolflike\", 62]], \"expected\": [[\"y. Yo\", 38], [\"fi\", 11], [\"wolflike\", 62]], \"passed\": false}, {\"check\": \"regression: kern pair case sensitivity\", \"actual\": [[\"Av fly.\", 50], [\"LAVALLE\", 88], [\"y. office\", 65], [\"raffle\", 46], [\"VIA\", 39]], \"expected\": [[\"Av fly.\", 51], [\"LAVALLE\", 88], [\"y. office\", 63], [\"raffle\", 46], [\"VIA\", 39]], \"passed\": false}, {\"check\": \"regression: kern pair case sensitivity\", \"actual\": [[\"Av flow\", 60]], \"expected\": [[\"Av flow\", 63]], \"passed\": false}, {\"check\": \"non-joiner blocks ligature\", \"actual\": [[\"shelflife\", 64]], \"expected\": [[\"shelflife\", 64]], \"passed\": true}, {\"check\": \"case-sensitive pair\", \"actual\": [[\"Av av\", 42]], \"expected\": [[\"Av av\", 47]], \"passed\": false}, {\"check\": \"control layout\", \"actual\": [[\"VIA\", 39], [\"LAVALLE\", 88], [\"Wavy\", 45], [\"wolflike\", 62]], \"expected\": [[\"VIA\", 39], [\"LAVALLE\", 88], [\"Wavy\", 45], [\"wolflike\", 62]], \"passed\": true}, {\"check\": \"control layout\", \"actual\": [[\"AVAIL shelflife\", 128], [\"AT\", 26]], \"expected\": [[\"AVAIL shelflife\", 128], [\"AT\", 26]], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":45.839,"exit_code":0,"observations":[{"actual":[["LA Vat",58]],"check":"cross-word pair must not kern","expected":[["LA Vat",58]],"passed":true},{"actual":[["y. Yo",38],["fi",11],["wolflike",62]],"check":"regression: kern pair case sensitivity","expected":[["y. Yo",38],["fi",11],["wolflike",62]],"passed":true},{"actual":[["Av fly.",51],["LAVALLE",88],["y. office",63],["raffle",46],["VIA",39]],"check":"regression: kern pair case sensitivity","expected":[["Av fly.",51],["LAVALLE",88],["y. office",63],["raffle",46],["VIA",39]],"passed":true},{"actual":[["Av flow",63]],"check":"regression: kern pair case sensitivity","expected":[["Av flow",63]],"passed":true},{"actual":[["shelflife",64]],"check":"non-joiner blocks ligature","expected":[["shelflife",64]],"passed":true},{"actual":[["Av av",47]],"check":"case-sensitive pair","expected":[["Av av",47]],"passed":true},{"actual":[["VIA",39],["LAVALLE",88],["Wavy",45],["wolflike",62]],"check":"control layout","expected":[["VIA",39],["LAVALLE",88],["Wavy",45],["wolflike",62]],"passed":true},{"actual":[["AVAIL shelflife",128],["AT",26]],"check":"control layout","expected":[["AVAIL shelflife",128],["AT",26]],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"cross-word pair must not kern\", \"actual\": [[\"LA Vat\", 58]], \"expected\": [[\"LA Vat\", 58]], \"passed\": true}, {\"check\": \"regression: kern pair case sensitivity\", \"actual\": [[\"y. Yo\", 38], [\"fi\", 11], [\"wolflike\", 62]], \"expected\": [[\"y. Yo\", 38], [\"fi\", 11], [\"wolflike\", 62]], \"passed\": true}, {\"check\": \"regression: kern pair case sensitivity\", \"actual\": [[\"Av fly.\", 51], [\"LAVALLE\", 88], [\"y. office\", 63], [\"raffle\", 46], [\"VIA\", 39]], \"expected\": [[\"Av fly.\", 51], [\"LAVALLE\", 88], [\"y. office\", 63], [\"raffle\", 46], [\"VIA\", 39]], \"passed\": true}, {\"check\": \"regression: kern pair case sensitivity\", \"actual\": [[\"Av flow\", 63]], \"expected\": [[\"Av flow\", 63]], \"passed\": true}, {\"check\": \"non-joiner blocks ligature\", \"actual\": [[\"shelflife\", 64]], \"expected\": [[\"shelflife\", 64]], \"passed\": true}, {\"check\": \"case-sensitive pair\", \"actual\": [[\"Av av\", 47]], \"expected\": [[\"Av av\", 47]], \"passed\": true}, {\"check\": \"control layout\", \"actual\": [[\"VIA\", 39], [\"LAVALLE\", 88], [\"Wavy\", 45], [\"wolflike\", 62]], \"expected\": [[\"VIA\", 39], [\"LAVALLE\", 88], [\"Wavy\", 45], [\"wolflike\", 62]], \"passed\": true}, {\"check\": \"control layout\", \"actual\": [[\"AVAIL shelflife\", 128], [\"AT\", 26]], \"expected\": [[\"AVAIL shelflife\", 128], [\"AT\", 26]], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}