{"files":{"main.py":"from core import run\nfrom policy import POLICY\n\n\ndef evaluate(payload):\n    return run(payload, POLICY)\n","core.py":"from datetime import timedelta\nfrom zoneinfo import ZoneInfo\n\nfrom helpers import parse_datetime, prepare_interval, overlaps\n\n\ndef run(payload, policy):\n    retained = {}\n    for index, row in enumerate(payload['appointments']):\n        identifier = row['id']\n        if identifier not in retained or policy['duplicate_policy'] == 'last':\n            retained[identifier] = (index, row)\n\n    results = {'selected': [], 'blocked': [], 'rejected': []}\n    try:\n        now = parse_datetime(payload['now'])\n        earliest = now + timedelta(minutes=policy['lead_minutes'])\n        zone = ZoneInfo(policy['timezone'])\n    except (ValueError, TypeError, OverflowError, KeyError):\n        results['rejected'] = [(index, identifier) for identifier, (index, row) in retained.items()]\n        return format_results(results, policy)\n\n    candidates = []\n    for identifier, (index, row) in retained.items():\n        try:\n            priority = row['priority']\n            cancelled = row['cancelled']\n            if not isinstance(priority, int) or isinstance(priority, bool):\n                raise ValueError('Priority must be an integer')\n            if not isinstance(cancelled, bool):\n                raise ValueError('Cancelled must be boolean')\n            if cancelled and not policy['cancelled_blocks']:\n                raise ValueError('Cancelled appointment')\n            start, end = prepare_interval(row, earliest, zone, policy)\n        except (ValueError, TypeError, OverflowError, KeyError):\n            results['rejected'].append((index, identifier))\n            continue\n        candidates.append((priority, index, identifier, start, end, cancelled))\n\n    candidates.sort(key=lambda item: (-item[0] if policy['priority_high_first'] else item[0], item[1]))\n    accepted = []\n    for priority, index, identifier, start, end, cancelled in candidates:\n        count = sum(overlaps(start, end, other_start, other_end, policy['adjacency_allowed'])\n                    for other_start, other_end in accepted)\n        if count >= policy['capacity']:\n            results['rejected'].append((index, identifier))\n        else:\n            accepted.append((start, end))\n            category = 'blocked' if cancelled else 'selected'\n            results[category].append((index, identifier))\n    return format_results(results, policy)\n\n\ndef format_results(results, policy):\n    key = (lambda item: item[1]) if policy['report_order'] == 'id' else (lambda item: item[0])\n    return {category: [identifier for index, identifier in sorted(items, key=key)]\n            for category, items in results.items()}\n","policy.py":"POLICY = {\n    'adjacency_allowed': False,\n    'blackout_day': '2026-11-02',\n    'cancelled_blocks': False,\n    'capacity': 2,\n    'cutoff_hour': 18,\n    'cutoff_inclusive': False,\n    'duplicate_policy': 'last',\n    'duration_max': 90,\n    'lead_minutes': 60,\n    'priority_high_first': False,\n    'report_order': 'input',\n    'timezone': 'UTC',\n}\n","helpers.py":"import math\nfrom datetime import datetime, timedelta, timezone\n\n\ndef parse_datetime(value):\n    if not isinstance(value, str):\n        raise ValueError('Datetime must be an ISO string')\n    parsed = datetime.fromisoformat(value)\n    if parsed.tzinfo is None or parsed.utcoffset() is None:\n        raise ValueError('Datetime must have an offset')\n    return parsed.astimezone(timezone.utc)\n\n\ndef prepare_interval(row, earliest, zone, policy):\n    duration = row['duration']\n    if isinstance(duration, bool) or not isinstance(duration, (int, float)):\n        raise ValueError('Duration must be numeric')\n    if not math.isfinite(duration) or not 0 < duration <= policy['duration_max']:\n        raise ValueError('Invalid duration')\n    start = parse_datetime(row['start'])\n    if start < earliest:\n        raise ValueError('Insufficient lead time')\n    end = start + timedelta(minutes=duration)\n    local_start = start.astimezone(zone)\n    if local_start.date().isoformat() == policy['blackout_day']:\n        raise ValueError('Blackout day')\n    cutoff = datetime(local_start.year, local_start.month, local_start.day,\n                      policy['cutoff_hour'], tzinfo=zone).astimezone(timezone.utc)\n    if policy['cutoff_inclusive']:\n        if end > cutoff:\n            raise ValueError('After cutoff')\n    elif end >= cutoff:\n        raise ValueError('At or after cutoff')\n    return start, end\n\n\ndef overlaps(start, end, other_start, other_end, adjacency_allowed):\n    if adjacency_allowed:\n        return start < other_end and other_start < end\n    return start <= other_end and other_start <= end\n"}}