FA-76486 / Email MIME structure / Open access
Resolve cid: references inside multipart/related: start presence · case 01
Without a start parameter, a part lacking a Content-ID is chosen as the root.
ROOT CAUSE
The start presence decision evaluates `root = ids.index(start) if start in ids else 0` where the contract requires `root = ids.index(start) if start and start in ids else 0`.
THE FAILURE
The start presence decision evaluates `root = ids.index(start) if start in ids else 0` where the contract requires `root = ids.index(start) if start and start in ids else 0`.
Unsuccessful approach: Requiring a unique match still matches the empty id of a single id-less part. The attempted `root = ids.index(start) if start in ids and ids.count(start) == 1 else 0` still disagrees with a fixture.
Case contract
related has params (optional start, with angle brackets) and parts with optional cid values such as " <img@x> ". Content ids are compared after trimming spaces and angle brackets. The root is the part whose id equals the start id, else the first part. Each reference is a URL; the "cid:" scheme is case-insensitive and the rest is percent-decoded. A reference resolves to the first non-root part with an equal id, else None. Result {root, resolved [[ref, index]...], unused: non-root indexes nobody referenced}.
Why this case matters
Inline images and style sheets in HTML mail are located through Content-ID references.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
from urllib.parse import unquote
N = 1
observations = []
def solve(related, html_refs):
def norm(c):
return (c or '').strip().strip('<>').strip()
ids = [norm(p.get('cid')) for p in related['parts']]
start = norm(related.get('params', {}).get('start'))
root = ids.index(start) if start in ids else 0
resolved = []
used = set()
for ref in html_refs:
target = unquote(ref[4:]) if ref[:4].lower() == 'cid:' else None
hit = None
for i, c in enumerate(ids):
if i != root and target and c == target:
hit = i
break
if hit is not None:
used.add(hit)
resolved.append([ref, hit])
unused = [i for i in range(len(ids)) if i != root and i not in used]
return {'root': root, 'resolved': resolved, 'unused': unused}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('padded content id', ({'parts': [{'cid': '<root@x>'}, {'cid': ' <pic1@x> '}]}, ['cid:pic1@x']), {'resolved': [['cid:pic1@x', 1]], 'root': 0, 'unused': []}), ('scheme casing', ({'parts': [{'cid': '<root@x>'}, {'cid': '<pic@x>'}]}, ['CID:pic@x', 'Cid:pic@x', 'http://pic@x']), {'resolved': [['CID:pic@x', 1], ['Cid:pic@x', 1], ['http://pic@x', None]], 'root': 0, 'unused': []}), ('percent-encoded reference', ({'parts': [{}, {'cid': '<a+b1@x>'}]}, ['cid:a%2Bb1%40x']), {'resolved': [['cid:a%2Bb1%40x', 1]], 'root': 0, 'unused': []}), ('root referenced by itself', ({'params': {'start': '<root@x>'}, 'parts': [{'cid': '<pic@x>'}, {'cid': '<root@x>'}]}, ['cid:root@x', 'cid:pic@x']), {'resolved': [['cid:root@x', None], ['cid:pic@x', 0]], 'root': 1, 'unused': []}), ('no start and an id-less part', ({'params': {}, 'parts': [{'cid': '<doc@x>'}, {}, {'cid': '<p1@x>'}]}, ['cid:p1@x']), {'resolved': [['cid:p1@x', 2]], 'root': 0, 'unused': [1]}), ('unused parts with late root', ({'params': {'start': '<r@x>'}, 'parts': [{'cid': '<a@x>'}, {'cid': '<b@x>'}, {'cid': '<r@x>'}]}, ['cid:a@x']), {'resolved': [['cid:a@x', 0]], 'root': 2, 'unused': [1]})], 2: [('padded content id', ({'parts': [{'cid': '<root@x>'}, {'cid': ' <pic2@x> '}]}, ['cid:pic2@x']), {'resolved': [['cid:pic2@x', 1]], 'root': 0, 'unused': []}), ('scheme casing', ({'parts': [{'cid': '<root@x>'}, {'cid': '<pic@x>'}]}, ['CID:pic@x', 'Cid:pic@x', 'http://pic@x']), {'resolved': [['CID:pic@x', 1], ['Cid:pic@x', 1], ['http://pic@x', None]], 'root': 0, 'unused': []}), ('percent-encoded reference', ({'parts': [{}, {'cid': '<a+b2@x>'}]}, ['cid:a%2Bb2%40x']), {'resolved': [['cid:a%2Bb2%40x', 1]], 'root': 0, 'unused': []}), ('root referenced by itself', ({'params': {'start': '<root@x>'}, 'parts': [{'cid': '<pic@x>'}, {'cid': '<root@x>'}]}, ['cid:root@x', 'cid:pic@x']), {'resolved': [['cid:root@x', None], ['cid:pic@x', 0]], 'root': 1, 'unused': []}), ('no start and an id-less part', ({'params': {}, 'parts': [{'cid': '<doc@x>'}, {}, {'cid': '<p2@x>'}]}, ['cid:p2@x']), {'resolved': [['cid:p2@x', 2]], 'root': 0, 'unused': [1]}), ('unused parts with late root', ({'params': {'start': '<r@x>'}, 'parts': [{'cid': '<a@x>'}, {'cid': '<b@x>'}, {'cid': '<r@x>'}]}, ['cid:a@x']), {'resolved': [['cid:a@x', 0]], 'root': 2, 'unused': [1]})], 3: [('padded content id', ({'parts': [{'cid': '<root@x>'}, {'cid': ' <pic3@x> '}]}, ['cid:pic3@x']), {'resolved': [['cid:pic3@x', 1]], 'root': 0, 'unused': []}), ('scheme casing', ({'parts': [{'cid': '<root@x>'}, {'cid': '<pic@x>'}]}, ['CID:pic@x', 'Cid:pic@x', 'http://pic@x']), {'resolved': [['CID:pic@x', 1], ['Cid:pic@x', 1], ['http://pic@x', None]], 'root': 0, 'unused': []}), ('percent-encoded reference', ({'parts': [{}, {'cid': '<a+b3@x>'}]}, ['cid:a%2Bb3%40x']), {'resolved': [['cid:a%2Bb3%40x', 1]], 'root': 0, 'unused': []}), ('root referenced by itself', ({'params': {'start': '<root@x>'}, 'parts': [{'cid': '<pic@x>'}, {'cid': '<root@x>'}]}, ['cid:root@x', 'cid:pic@x']), {'resolved': [['cid:root@x', None], ['cid:pic@x', 0]], 'root': 1, 'unused': []}), ('no start and an id-less part', ({'params': {}, 'parts': [{'cid': '<doc@x>'}, {}, {'cid': '<p3@x>'}]}, ['cid:p3@x']), {'resolved': [['cid:p3@x', 2]], 'root': 0, 'unused': [1]}), ('unused parts with late root', ({'params': {'start': '<r@x>'}, 'parts': [{'cid': '<a@x>'}, {'cid': '<b@x>'}, {'cid': '<r@x>'}]}, ['cid:a@x']), {'resolved': [['cid:a@x', 0]], 'root': 2, 'unused': [1]})], 4: [('padded content id', ({'parts': [{'cid': '<root@x>'}, {'cid': ' <pic4@x> '}]}, ['cid:pic4@x']), {'resolved': [['cid:pic4@x', 1]], 'root': 0, 'unused': []}), ('scheme casing', ({'parts': [{'cid': '<root@x>'}, {'cid': '<pic@x>'}]}, ['CID:pic@x', 'Cid:pic@x', 'http://pic@x']), {'resolved': [['CID:pic@x', 1], ['Cid:pic@x', 1], ['http://pic@x', None]], 'root': 0, 'unused': []}), ('percent-encoded reference', ({'parts': [{}, {'cid': '<a+b4@x>'}]}, ['cid:a%2Bb4%40x']), {'resolved': [['cid:a%2Bb4%40x', 1]], 'root': 0, 'unused': []}), ('root referenced by itself', ({'params': {'start': '<root@x>'}, 'parts': [{'cid': '<pic@x>'}, {'cid': '<root@x>'}]}, ['cid:root@x', 'cid:pic@x']), {'resolved': [['cid:root@x', None], ['cid:pic@x', 0]], 'root': 1, 'unused': []}), ('no start and an id-less part', ({'params': {}, 'parts': [{'cid': '<doc@x>'}, {}, {'cid': '<p4@x>'}]}, ['cid:p4@x']), {'resolved': [['cid:p4@x', 2]], 'root': 0, 'unused': [1]}), ('unused parts with late root', ({'params': {'start': '<r@x>'}, 'parts': [{'cid': '<a@x>'}, {'cid': '<b@x>'}, {'cid': '<r@x>'}]}, ['cid:a@x']), {'resolved': [['cid:a@x', 0]], 'root': 2, 'unused': [1]})], 5: [('padded content id', ({'parts': [{'cid': '<root@x>'}, {'cid': ' <pic5@x> '}]}, ['cid:pic5@x']), {'resolved': [['cid:pic5@x', 1]], 'root': 0, 'unused': []}), ('scheme casing', ({'parts': [{'cid': '<root@x>'}, {'cid': '<pic@x>'}]}, ['CID:pic@x', 'Cid:pic@x', 'http://pic@x']), {'resolved': [['CID:pic@x', 1], ['Cid:pic@x', 1], ['http://pic@x', None]], 'root': 0, 'unused': []}), ('percent-encoded reference', ({'parts': [{}, {'cid': '<a+b5@x>'}]}, ['cid:a%2Bb5%40x']), {'resolved': [['cid:a%2Bb5%40x', 1]], 'root': 0, 'unused': []}), ('root referenced by itself', ({'params': {'start': '<root@x>'}, 'parts': [{'cid': '<pic@x>'}, {'cid': '<root@x>'}]}, ['cid:root@x', 'cid:pic@x']), {'resolved': [['cid:root@x', None], ['cid:pic@x', 0]], 'root': 1, 'unused': []}), ('no start and an id-less part', ({'params': {}, 'parts': [{'cid': '<doc@x>'}, {}, {'cid': '<p5@x>'}]}, ['cid:p5@x']), {'resolved': [['cid:p5@x', 2]], 'root': 0, 'unused': [1]}), ('unused parts with late root', ({'params': {'start': '<r@x>'}, 'parts': [{'cid': '<a@x>'}, {'cid': '<b@x>'}, {'cid': '<r@x>'}]}, ['cid:a@x']), {'resolved': [['cid:a@x', 0]], 'root': 2, 'unused': [1]})]}
for _label, _args, _expected in _CASES[N]:
check(_label, solve(*_args), _expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| padded content id | {'resolved': [['cid:pic1@x', 1]], 'root': 0, 'unused': []} | {'resolved': [['cid:pic1@x', 1]], 'root': 0, 'unused': []} | Passed |
| scheme casing | {'resolved': [['CID:pic@x', 1], ['Cid:pic@x', 1], ['http://pic@x', None]], 'root': 0, 'unused': []} | {'resolved': [['CID:pic@x', 1], ['Cid:pic@x', 1], ['http://pic@x', None]], 'root': 0, 'unused': []} | Passed |
| percent-encoded reference | {'resolved': [['cid:a%2Bb1%40x', 1]], 'root': 0, 'unused': []} | {'resolved': [['cid:a%2Bb1%40x', 1]], 'root': 0, 'unused': []} | Passed |
| root referenced by itself | {'resolved': [['cid:root@x', None], ['cid:pic@x', 0]], 'root': 1, 'unused': []} | {'resolved': [['cid:root@x', None], ['cid:pic@x', 0]], 'root': 1, 'unused': []} | Passed |
| no start and an id-less part | {'resolved': [['cid:p1@x', 2]], 'root': 1, 'unused': [0]} | {'resolved': [['cid:p1@x', 2]], 'root': 0, 'unused': [1]} | Failed |
| unused parts with late root | {'resolved': [['cid:a@x', 0]], 'root': 2, 'unused': [1]} | {'resolved': [['cid:a@x', 0]], 'root': 2, 'unused': [1]} | Passed |
SHA-256 / 7b30818b27535471ee04d8ca1d3e9aebf17d828b9b3e05eb140f41288fd8ff38
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
from urllib.parse import unquote
N = 1
observations = []
def solve(related, html_refs):
def norm(c):
return (c or '').strip().strip('<>').strip()
ids = [norm(p.get('cid')) for p in related['parts']]
start = norm(related.get('params', {}).get('start'))
root = ids.index(start) if start in ids and ids.count(start) == 1 else 0
resolved = []
used = set()
for ref in html_refs:
target = unquote(ref[4:]) if ref[:4].lower() == 'cid:' else None
hit = None
for i, c in enumerate(ids):
if i != root and target and c == target:
hit = i
break
if hit is not None:
used.add(hit)
resolved.append([ref, hit])
unused = [i for i in range(len(ids)) if i != root and i not in used]
return {'root': root, 'resolved': resolved, 'unused': unused}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('padded content id', ({'parts': [{'cid': '<root@x>'}, {'cid': ' <pic1@x> '}]}, ['cid:pic1@x']), {'resolved': [['cid:pic1@x', 1]], 'root': 0, 'unused': []}), ('scheme casing', ({'parts': [{'cid': '<root@x>'}, {'cid': '<pic@x>'}]}, ['CID:pic@x', 'Cid:pic@x', 'http://pic@x']), {'resolved': [['CID:pic@x', 1], ['Cid:pic@x', 1], ['http://pic@x', None]], 'root': 0, 'unused': []}), ('percent-encoded reference', ({'parts': [{}, {'cid': '<a+b1@x>'}]}, ['cid:a%2Bb1%40x']), {'resolved': [['cid:a%2Bb1%40x', 1]], 'root': 0, 'unused': []}), ('root referenced by itself', ({'params': {'start': '<root@x>'}, 'parts': [{'cid': '<pic@x>'}, {'cid': '<root@x>'}]}, ['cid:root@x', 'cid:pic@x']), {'resolved': [['cid:root@x', None], ['cid:pic@x', 0]], 'root': 1, 'unused': []}), ('no start and an id-less part', ({'params': {}, 'parts': [{'cid': '<doc@x>'}, {}, {'cid': '<p1@x>'}]}, ['cid:p1@x']), {'resolved': [['cid:p1@x', 2]], 'root': 0, 'unused': [1]}), ('unused parts with late root', ({'params': {'start': '<r@x>'}, 'parts': [{'cid': '<a@x>'}, {'cid': '<b@x>'}, {'cid': '<r@x>'}]}, ['cid:a@x']), {'resolved': [['cid:a@x', 0]], 'root': 2, 'unused': [1]})], 2: [('padded content id', ({'parts': [{'cid': '<root@x>'}, {'cid': ' <pic2@x> '}]}, ['cid:pic2@x']), {'resolved': [['cid:pic2@x', 1]], 'root': 0, 'unused': []}), ('scheme casing', ({'parts': [{'cid': '<root@x>'}, {'cid': '<pic@x>'}]}, ['CID:pic@x', 'Cid:pic@x', 'http://pic@x']), {'resolved': [['CID:pic@x', 1], ['Cid:pic@x', 1], ['http://pic@x', None]], 'root': 0, 'unused': []}), ('percent-encoded reference', ({'parts': [{}, {'cid': '<a+b2@x>'}]}, ['cid:a%2Bb2%40x']), {'resolved': [['cid:a%2Bb2%40x', 1]], 'root': 0, 'unused': []}), ('root referenced by itself', ({'params': {'start': '<root@x>'}, 'parts': [{'cid': '<pic@x>'}, {'cid': '<root@x>'}]}, ['cid:root@x', 'cid:pic@x']), {'resolved': [['cid:root@x', None], ['cid:pic@x', 0]], 'root': 1, 'unused': []}), ('no start and an id-less part', ({'params': {}, 'parts': [{'cid': '<doc@x>'}, {}, {'cid': '<p2@x>'}]}, ['cid:p2@x']), {'resolved': [['cid:p2@x', 2]], 'root': 0, 'unused': [1]}), ('unused parts with late root', ({'params': {'start': '<r@x>'}, 'parts': [{'cid': '<a@x>'}, {'cid': '<b@x>'}, {'cid': '<r@x>'}]}, ['cid:a@x']), {'resolved': [['cid:a@x', 0]], 'root': 2, 'unused': [1]})], 3: [('padded content id', ({'parts': [{'cid': '<root@x>'}, {'cid': ' <pic3@x> '}]}, ['cid:pic3@x']), {'resolved': [['cid:pic3@x', 1]], 'root': 0, 'unused': []}), ('scheme casing', ({'parts': [{'cid': '<root@x>'}, {'cid': '<pic@x>'}]}, ['CID:pic@x', 'Cid:pic@x', 'http://pic@x']), {'resolved': [['CID:pic@x', 1], ['Cid:pic@x', 1], ['http://pic@x', None]], 'root': 0, 'unused': []}), ('percent-encoded reference', ({'parts': [{}, {'cid': '<a+b3@x>'}]}, ['cid:a%2Bb3%40x']), {'resolved': [['cid:a%2Bb3%40x', 1]], 'root': 0, 'unused': []}), ('root referenced by itself', ({'params': {'start': '<root@x>'}, 'parts': [{'cid': '<pic@x>'}, {'cid': '<root@x>'}]}, ['cid:root@x', 'cid:pic@x']), {'resolved': [['cid:root@x', None], ['cid:pic@x', 0]], 'root': 1, 'unused': []}), ('no start and an id-less part', ({'params': {}, 'parts': [{'cid': '<doc@x>'}, {}, {'cid': '<p3@x>'}]}, ['cid:p3@x']), {'resolved': [['cid:p3@x', 2]], 'root': 0, 'unused': [1]}), ('unused parts with late root', ({'params': {'start': '<r@x>'}, 'parts': [{'cid': '<a@x>'}, {'cid': '<b@x>'}, {'cid': '<r@x>'}]}, ['cid:a@x']), {'resolved': [['cid:a@x', 0]], 'root': 2, 'unused': [1]})], 4: [('padded content id', ({'parts': [{'cid': '<root@x>'}, {'cid': ' <pic4@x> '}]}, ['cid:pic4@x']), {'resolved': [['cid:pic4@x', 1]], 'root': 0, 'unused': []}), ('scheme casing', ({'parts': [{'cid': '<root@x>'}, {'cid': '<pic@x>'}]}, ['CID:pic@x', 'Cid:pic@x', 'http://pic@x']), {'resolved': [['CID:pic@x', 1], ['Cid:pic@x', 1], ['http://pic@x', None]], 'root': 0, 'unused': []}), ('percent-encoded reference', ({'parts': [{}, {'cid': '<a+b4@x>'}]}, ['cid:a%2Bb4%40x']), {'resolved': [['cid:a%2Bb4%40x', 1]], 'root': 0, 'unused': []}), ('root referenced by itself', ({'params': {'start': '<root@x>'}, 'parts': [{'cid': '<pic@x>'}, {'cid': '<root@x>'}]}, ['cid:root@x', 'cid:pic@x']), {'resolved': [['cid:root@x', None], ['cid:pic@x', 0]], 'root': 1, 'unused': []}), ('no start and an id-less part', ({'params': {}, 'parts': [{'cid': '<doc@x>'}, {}, {'cid': '<p4@x>'}]}, ['cid:p4@x']), {'resolved': [['cid:p4@x', 2]], 'root': 0, 'unused': [1]}), ('unused parts with late root', ({'params': {'start': '<r@x>'}, 'parts': [{'cid': '<a@x>'}, {'cid': '<b@x>'}, {'cid': '<r@x>'}]}, ['cid:a@x']), {'resolved': [['cid:a@x', 0]], 'root': 2, 'unused': [1]})], 5: [('padded content id', ({'parts': [{'cid': '<root@x>'}, {'cid': ' <pic5@x> '}]}, ['cid:pic5@x']), {'resolved': [['cid:pic5@x', 1]], 'root': 0, 'unused': []}), ('scheme casing', ({'parts': [{'cid': '<root@x>'}, {'cid': '<pic@x>'}]}, ['CID:pic@x', 'Cid:pic@x', 'http://pic@x']), {'resolved': [['CID:pic@x', 1], ['Cid:pic@x', 1], ['http://pic@x', None]], 'root': 0, 'unused': []}), ('percent-encoded reference', ({'parts': [{}, {'cid': '<a+b5@x>'}]}, ['cid:a%2Bb5%40x']), {'resolved': [['cid:a%2Bb5%40x', 1]], 'root': 0, 'unused': []}), ('root referenced by itself', ({'params': {'start': '<root@x>'}, 'parts': [{'cid': '<pic@x>'}, {'cid': '<root@x>'}]}, ['cid:root@x', 'cid:pic@x']), {'resolved': [['cid:root@x', None], ['cid:pic@x', 0]], 'root': 1, 'unused': []}), ('no start and an id-less part', ({'params': {}, 'parts': [{'cid': '<doc@x>'}, {}, {'cid': '<p5@x>'}]}, ['cid:p5@x']), {'resolved': [['cid:p5@x', 2]], 'root': 0, 'unused': [1]}), ('unused parts with late root', ({'params': {'start': '<r@x>'}, 'parts': [{'cid': '<a@x>'}, {'cid': '<b@x>'}, {'cid': '<r@x>'}]}, ['cid:a@x']), {'resolved': [['cid:a@x', 0]], 'root': 2, 'unused': [1]})]}
for _label, _args, _expected in _CASES[N]:
check(_label, solve(*_args), _expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| padded content id | {'resolved': [['cid:pic1@x', 1]], 'root': 0, 'unused': []} | {'resolved': [['cid:pic1@x', 1]], 'root': 0, 'unused': []} | Passed |
| scheme casing | {'resolved': [['CID:pic@x', 1], ['Cid:pic@x', 1], ['http://pic@x', None]], 'root': 0, 'unused': []} | {'resolved': [['CID:pic@x', 1], ['Cid:pic@x', 1], ['http://pic@x', None]], 'root': 0, 'unused': []} | Passed |
| percent-encoded reference | {'resolved': [['cid:a%2Bb1%40x', 1]], 'root': 0, 'unused': []} | {'resolved': [['cid:a%2Bb1%40x', 1]], 'root': 0, 'unused': []} | Passed |
| root referenced by itself | {'resolved': [['cid:root@x', None], ['cid:pic@x', 0]], 'root': 1, 'unused': []} | {'resolved': [['cid:root@x', None], ['cid:pic@x', 0]], 'root': 1, 'unused': []} | Passed |
| no start and an id-less part | {'resolved': [['cid:p1@x', 2]], 'root': 1, 'unused': [0]} | {'resolved': [['cid:p1@x', 2]], 'root': 0, 'unused': [1]} | Failed |
| unused parts with late root | {'resolved': [['cid:a@x', 0]], 'root': 2, 'unused': [1]} | {'resolved': [['cid:a@x', 0]], 'root': 2, 'unused': [1]} | Passed |
SHA-256 / 12c95a158db21884fd0a8ad8ce2731f2b80fe1cc9dcdc8d4e7999640d243dee0
HELD IN THE MEMBER ARCHIVE
The verified repair and its recorded checks are member-only.
This mechanism has 6 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.
Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.
Member access is invitation-based. Sign in with your invited account to inspect the repair.
Sign in to the archive ↗Verification & scope
Stipulated offline model over pre-parsed MIME dictionaries; not a conforming MIME parser, generator or mail client. 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.
Observations recorded using Python 3.12.14 at 2026-09-29T14:49:16.754755+00:00.
Case digest / 85eea97d61c2729a89b1a4792770b57c52fb54f255f6245f239dbb6106affe06