{"files": {"main.py": "from core import run\nfrom policy import POLICY\ndef evaluate(payload):\n    return run(payload, POLICY)\n", "core.py": "import copy\nimport math\nfrom datetime import datetime, timedelta, timezone\nfrom zoneinfo import ZoneInfo\nfrom helpers import parse_aware_datetime, intervals_overlap, report_sort_key\n\ndef _is_int_like(value):\n    return isinstance(value, int) and not isinstance(value, bool)\n\ndef _duration_value(item):\n    for key in ('duration_minutes', 'duration', 'minutes', 'duration_min', 'length_minutes'):\n        if key in item:\n            return item[key]\n    return None\n\ndef run(payload, policy):\n    result = {'selected': [], 'blocked': [], 'rejected': []}\n    if not isinstance(payload, dict) or not isinstance(policy, dict):\n        return result\n    data = copy.deepcopy(payload)\n    appointments = data.get('appointments')\n    if not isinstance(appointments, list):\n        return result\n    duplicate_policy = policy.get('duplicate_policy', 'first')\n    retained = {}\n    order = []\n    anonymous = []\n    for idx, item in enumerate(appointments):\n        if not isinstance(item, dict) or 'id' not in item:\n            anonymous.append((idx, item))\n            continue\n        ident = item.get('id')\n        try:\n            hash(ident)\n        except Exception:\n            anonymous.append((idx, item))\n            continue\n        if ident not in retained:\n            retained[ident] = (idx, item)\n            order.append(ident)\n        elif duplicate_policy == 'last':\n            retained[ident] = (idx, item)\n    entries = [retained[ident] for ident in order]\n    selected = []\n    blocked = []\n    rejected = []\n    for idx, item in anonymous:\n        rejected.append((idx, None))\n    now_dt = parse_aware_datetime(data.get('now'))\n    try:\n        tz = ZoneInfo(str(policy.get('timezone', 'UTC')))\n    except Exception:\n        tz = timezone.utc\n    duration_max = policy.get('duration_max')\n    lead_minutes = policy.get('lead_minutes', 0)\n    capacity = policy.get('capacity', 0)\n    cutoff_hour = policy.get('cutoff_hour')\n    cutoff_inclusive = bool(policy.get('cutoff_inclusive', False))\n    cancelled_blocks = bool(policy.get('cancelled_blocks', False))\n    adjacency_allowed = bool(policy.get('adjacency_allowed', True))\n    blackout_day = policy.get('blackout_day')\n    if blackout_day is not None:\n        blackout_day = str(blackout_day)\n    candidates = []\n    for orig_idx, item in entries:\n        ident = item.get('id')\n        valid = True\n        if isinstance(ident, bool) or not isinstance(ident, (str, int)) or (isinstance(ident, str) and ident == ''):\n            valid = False\n        start_raw = item.get('start', item.get('start_time')) if isinstance(item, dict) else None\n        start_dt = parse_aware_datetime(start_raw)\n        if start_dt is None:\n            valid = False\n        duration = _duration_value(item) if isinstance(item, dict) else None\n        if isinstance(duration, bool) or not isinstance(duration, (int, float)) or not math.isfinite(float(duration)):\n            valid = False\n            duration_value = None\n        else:\n            if isinstance(duration, float) and not duration.is_integer():\n                valid = False\n            duration_value = float(duration)\n            if duration_value <= 0:\n                valid = False\n            if duration_max is not None:\n                try:\n                    if duration_value > float(duration_max):\n                        valid = False\n                except Exception:\n                    valid = False\n        priority = item.get('priority') if isinstance(item, dict) else None\n        if not _is_int_like(priority):\n            valid = False\n        cancelled = item.get('cancelled', item.get('canceled')) if isinstance(item, dict) else None\n        if not isinstance(cancelled, bool):\n            valid = False\n        if now_dt is None:\n            valid = False\n        start_utc = None\n        end_utc = None\n        if valid:\n            start_utc = start_dt.astimezone(timezone.utc)\n            end_utc = start_utc + timedelta(minutes=duration_value)\n            try:\n                earliest = now_dt.astimezone(timezone.utc) + timedelta(minutes=float(lead_minutes))\n                if start_utc < earliest:\n                    valid = False\n            except Exception:\n                valid = False\n        if valid:\n            start_local = start_utc.astimezone(tz)\n            if blackout_day is not None and start_local.date().isoformat() == blackout_day:\n                valid = False\n        if valid and cutoff_hour is not None:\n            try:\n                local_date = start_utc.astimezone(tz).date()\n                cutoff = datetime(local_date.year, local_date.month, local_date.day, int(cutoff_hour), 0, tzinfo=tz)\n                if cutoff_inclusive:\n                    if end_utc > cutoff.astimezone(timezone.utc):\n                        valid = False\n                else:\n                    if end_utc >= cutoff.astimezone(timezone.utc):\n                        valid = False\n            except Exception:\n                valid = False\n        if not valid:\n            rejected.append((orig_idx, ident))\n            continue\n        if cancelled and not cancelled_blocks:\n            rejected.append((orig_idx, ident))\n            continue\n        candidates.append({'index': orig_idx, 'id': ident, 'priority': priority, 'cancelled': cancelled, 'start': start_utc, 'end': end_utc})\n    if bool(policy.get('priority_high_first', False)):\n        candidates.sort(key=lambda c: (-c['priority'], c['index']))\n    else:\n        candidates.sort(key=lambda c: (c['priority'], c['index']))\n    accepted_intervals = []\n    try:\n        cap_value = int(capacity)\n    except Exception:\n        cap_value = 0\n    for cand in candidates:\n        count = 0\n        for other_start, other_end in accepted_intervals:\n            if intervals_overlap(cand['start'], cand['end'], other_start, other_end, adjacency_allowed):\n                count += 1\n        if count < cap_value:\n            accepted_intervals.append((cand['start'], cand['end']))\n            if cand['cancelled']:\n                blocked.append((cand['index'], cand['id']))\n            else:\n                selected.append((cand['index'], cand['id']))\n        else:\n            rejected.append((cand['index'], cand['id']))\n    report_order = policy.get('report_order', 'input')\n    def sort_entries(items):\n        return [ident for _, ident in sorted(items, key=lambda pair: report_sort_key(pair, report_order)) if ident is not None]\n    result['selected'] = sort_entries(selected)\n    result['blocked'] = sort_entries(blocked)\n    result['rejected'] = sort_entries(rejected)\n    return result\n", "policy.py": "POLICY = {\"adjacency_allowed\": false, \"blackout_day\": \"2026-11-02\", \"cancelled_blocks\": false, \"capacity\": 2, \"cutoff_hour\": 18, \"cutoff_inclusive\": false, \"duplicate_policy\": \"last\", \"duration_max\": 90, \"lead_minutes\": 60, \"priority_high_first\": false, \"report_order\": \"input\", \"timezone\": \"UTC\"}\n", "helpers.py": "from datetime import datetime\n\ndef parse_aware_datetime(value):\n    if isinstance(value, datetime):\n        parsed = value\n    elif isinstance(value, str):\n        text = value.strip()\n        if text.endswith(('Z', 'z')):\n            text = text[:-1] + '+00:00'\n        try:\n            parsed = datetime.fromisoformat(text)\n        except Exception:\n            return None\n    else:\n        return None\n    if parsed.tzinfo is None or parsed.utcoffset() is None:\n        return None\n    return parsed\n\ndef intervals_overlap(a_start, a_end, b_start, b_end, adjacency_allowed):\n    if adjacency_allowed:\n        return a_start < b_end and b_start < a_end\n    return a_start <= b_end and b_start <= a_end\n\ndef report_sort_key(pair, report_order):\n    index, ident = pair\n    if report_order == 'id':\n        if isinstance(ident, bool):\n            return (2, 0, str(ident))\n        if isinstance(ident, (int, float)):\n            return (0, ident, '')\n        return (1, 0, str(ident))\n    return (index,)\n"}}