You are an oncology clinic schedule optimizer. Assign start_time and end_time to each treatment row. Output ONLY CSV between markers — no reasoning.

## RULES
- T = Schedule Time Block (from CLINIC TIMING below). end_time = start_time + (service_duration × T minutes)
- All times align to T-minute boundaries in HH:MM:SS format
- Each profile has exactly ONE service (treatment). No contiguity rules needed.
- If a profile cannot fit: set start_time="00:00:00" end_time="00:00:00"
- Return rows in same order as input. Only modify start_time and end_time.

## HARD CONSTRAINTS (ABSOLUTE — mark profile UNASSIGNED rather than violate ANY of these)

### 1. CHAIR CAPACITY (most critical)
- Each patient occupies exactly 1 chair from their start_time until their end_time.
- For ANY time slot S, count ALL patients whose treatment overlaps that slot:
  total_in_chair_at_S = count of patients where (patient_start_time <= S) AND (patient_end_time > S)
  This includes patients STARTING in this slot + patients IN PROGRESS from earlier slots.
- total_in_chair_at_S must NEVER exceed max_chair_capacity at ANY slot.
- Before placing a profile: check EVERY slot from proposed_start to proposed_end. If ANY slot would exceed max chairs → do NOT place, try next slot or mark UNASSIGNED.

### 2. RN STAFFING (must NEVER exceed available RNs)
- For each slot S, calculate:
  starts_in_S = number of treatments that BEGIN at slot S
  ends_in_S = number of treatments that END at slot S
  in_progress_in_S = patients who started BEFORE S and end AFTER S (mid-treatment)
  RN_demand = starts_in_S + ends_in_S + ceil(in_progress_in_S × nurse_factor)
- RN_demand must NEVER exceed RN_available for that slot.
- Before placing a profile: check ALL slots it would affect (start slot for +1 start, end slot for +1 end, all middle slots for +nurse_factor). If ANY slot would make RN_demand > RN_available → try next slot or mark UNASSIGNED.

### 3. MAX STARTS PER SLOT (per-slot limit — read EACH slot's specific limit from config)
- Each time slot has its OWN maximum number of treatments that can START in it.
- These limits VARY by time of day. For example: 07:00 may allow 2 starts, 13:00 may allow 3 starts.
- Before placing a profile at slot S: if starts_already_at_S >= max_starts_limit_for_S → slot S is FULL, try next slot.
- Do NOT assume all slots have the same limit. Read the EXACT value for each slot from the config.

### 4. DO NOT START / DO NOT BOOK
- No treatment can BEGIN during these time windows (treatments already running may continue through them).

### 5. CLINIC HOURS
- All treatments: start_time >= treatment_room_start AND end_time <= treatment_room_end.

## ALGORITHM
1. Sort profiles by service_duration DESCENDING, then profile_id ASC for ties.
2. For each profile, scan slots from earliest to latest to find the FIRST valid slot where ALL 5 constraints pass:
   a. starts_at_slot < max_starts_limit for that SPECIFIC slot
   b. For EVERY slot this treatment would occupy: total_in_chair + 1 <= max_chair_capacity
   c. For EVERY affected slot: RN_demand (with this profile added) <= RN_available
   d. end_time <= treatment_room_end
   e. Start slot is NOT in a Do Not Start / Do Not Book window
3. If valid slot found: ASSIGN and IMMEDIATELY update all counters (chairs, starts, RN) for every affected slot before processing next profile.
4. If NO valid slot exists → mark UNASSIGNED (start_time="00:00:00", end_time="00:00:00").
   NEVER force a profile into a slot that violates constraints. UNASSIGNED is correct. Violation is WRONG.

## GOALS (in strict priority order)
1. ZERO constraint violations — unassigned is acceptable, ANY violation is NOT
2. Maximize assigned profiles (schedule as many as possible within constraints)
3. Spread load across the full day — do not front-load morning slots
4. AM/PM balance: target 50% starts before 12:00, 50% at 12:00 or later
5. Long treatments start earlier, short treatments fill later slots

## FULL-DAY UTILIZATION
Do NOT cluster all starts in the first 2 hours. When multiple valid slots exist, prefer the one that keeps peak chair occupancy lowest. Target 50/50 AM/PM split.

## TIME CALCULATION
- end_minutes = (HH×60 + MM) + (service_duration × T)
- Convert back: HH = end_minutes ÷ 60, MM = end_minutes mod 60
- Minutes NEVER exceed 59.

EXAMPLES (T=15):
- start=07:00, dur=8:  420+120=540 → 09:00:00
- start=07:30, dur=14: 450+210=660 → 11:00:00
- start=08:30, dur=6:  510+90=600  → 10:00:00
- start=10:00, dur=14: 600+210=810 → 13:30:00

## PRE-OUTPUT VALIDATION (check every slot before outputting)
For each slot from clinic_open to clinic_close, verify:
✓ total_in_chair (starts + in_progress) <= max_chairs. If violated → move last-placed profile to UNASSIGNED.
✓ starts_count <= max_starts_limit for that slot. If violated → move violating profile to UNASSIGNED.
✓ RN_demand <= RN_available. If violated → move last-placed profile at that slot to UNASSIGNED.
✓ No start in Do Not Start / Do Not Book window.
✓ Every end_time = start_time + (service_duration × T). No invalid times (minutes >= 60).
✓ Output has exactly same number of rows as input.

If ANY violation remains after checking, mark the violating profiles as UNASSIGNED. Output must have ZERO violations.

## OUTPUT FORMAT
Output ONLY CSV between ---CSV_START--- and ---CSV_END--- markers.
No header row. No reasoning. No commentary.
Columns: schedule_date,clinic_id,clinic_name,profile_id,service_id,start_time,service_duration,end_time,service_sequence_id,service_name


## SCHEDULING ALGORITHM
Use the **First Fit Decreasing** strategy:
Sort all profiles by total duration DESCENDING (longest first). For each profile in sorted order, assign it to the EARLIEST available time slot that satisfies ALL constraints (chairs, staff, max starts, clinic hours). Once placed, lock it and move to the next profile. Never revisit a placed profile. This is the recommended construction heuristic from Timefold's scheduling algorithms — it prevents long profiles from being blocked later and naturally spreads load across the day.

## CLINIC CONFIGURATION (dynamically loaded from CSV)
### CLINIC TIMING (for Monday)
- Clinic Hours: 7:00:00 - 17:00:00
- Treatment Room (TTCNP): start >= 7:00:00, end <= 17:00:00
- Lab Hours: start >= 7:00:00, end <= 17:00:00
- Nurse Factor (ongoing mid-treatment): 16% per patient → 1 RN covers up to 6.2 concurrent mid-treatment patients
- Schedule Time Block: 15 minutes per slot (all time calculations use this interval)
- *** IMPORTANT: T = 15. Use 15 minutes for ALL duration calculations, not 15. duration_minutes = service_duration × 15 ***

### RESOURCES (Physical Chairs)
- Treatment Chairs: 24 (max 24 patients using this resource simultaneously)
- Lab Chairs: 2 (max 2 patients using this resource simultaneously)
- Injection Chairs: 1 (max 1 patients using this resource simultaneously)

### STAFF AVAILABILITY (for Monday, Available only)
- RN (Registered Nurse): 07:30:00-16:45:00, 12 available per slot
- Lab Tech: 07:30:00-16:15:00, 1 available per slot
- LPN (Injection Nurse): 07:30:00-17:00:00, 1 available per slot
- MD (Provider): 08:00:00-16:15:00, 2 available per slot
- MA: 07:15:00-16:45:00, 1 available per slot

### DO NOT START RULES (for Monday)
  No Do Not Start rules configured.

### DO NOT BOOK RULES (for Monday)
  No Do Not Book rules configured.

### MAX TREATMENT STARTS PER SLOT (for Monday)
The maximum number of treatments that can START in each 15-minute slot is defined per slot below.
This is a HARD constraint — even if chairs and RNs are available, do not exceed these limits.
  - 07:00:00: max 0 treatment start(s)
  - 07:15:00: max 0 treatment start(s)
  - 07:30:00: max 1 treatment start(s)
  - 07:45:00: max 2 treatment start(s)
  - 08:00:00: max 2 treatment start(s)
  - 08:15:00: max 2 treatment start(s)
  - 08:30:00: max 3 treatment start(s)
  - 08:45:00: max 3 treatment start(s)
  - 09:00:00: max 3 treatment start(s)
  - 09:15:00: max 3 treatment start(s)
  - 09:30:00: max 3 treatment start(s)
  - 09:45:00: max 3 treatment start(s)
  - 10:00:00: max 3 treatment start(s)
  - 10:15:00: max 3 treatment start(s)
  - 10:30:00: max 3 treatment start(s)
  - 10:45:00: max 3 treatment start(s)
  - 11:00:00: max 3 treatment start(s)
  - 11:15:00: max 3 treatment start(s)
  - 11:30:00: max 3 treatment start(s)
  - 11:45:00: max 3 treatment start(s)
  - 12:00:00: max 3 treatment start(s)
  - 12:15:00: max 3 treatment start(s)
  - 12:30:00: max 3 treatment start(s)
  - 12:45:00: max 3 treatment start(s)
  - 13:00:00: max 3 treatment start(s)
  - 13:15:00: max 3 treatment start(s)
  - 13:30:00: max 3 treatment start(s)
  - 13:45:00: max 3 treatment start(s)
  - 14:00:00: max 3 treatment start(s)
  - 14:15:00: max 3 treatment start(s)
  - 14:30:00: max 3 treatment start(s)
  - 14:45:00: max 3 treatment start(s)
  - 15:00:00: max 3 treatment start(s)
  - 15:15:00: max 3 treatment start(s)
  - 15:30:00: max 3 treatment start(s)
  - 15:45:00: max 3 treatment start(s)
  - 16:00:00: max 3 treatment start(s)
  - 16:15:00: max 3 treatment start(s)
  - 16:30:00: max 0 treatment start(s)
  - 16:45:00: max 0 treatment start(s)
  - 17:00:00: max 0 treatment start(s)
  - 17:15:00: max 0 treatment start(s)
  - 17:30:00: max 0 treatment start(s)


## PROFILE LIST TO OPTIMIZE (CSV):
schedule_date,location_id,clinic_name,profile_id,service_id,start_time,service_duration,end_time,service_sequence_id,service_name
5/25/2026,20001,PostFalls,2001001,3,7:00:00,2,7:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001002,3,7:00:00,2,7:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001003,3,7:00:00,2,7:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001004,3,7:00:00,2,7:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001005,3,7:00:00,2,7:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001006,3,7:00:00,2,7:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001007,3,7:00:00,3,7:45:00,4,Treatment
5/25/2026,20001,PostFalls,2001008,3,7:00:00,3,7:45:00,4,Treatment
5/25/2026,20001,PostFalls,2001009,3,7:00:00,3,7:45:00,4,Treatment
5/25/2026,20001,PostFalls,2001010,3,7:00:00,3,7:45:00,4,Treatment
5/25/2026,20001,PostFalls,2001011,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001012,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001013,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001014,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001015,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001016,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001017,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001018,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001019,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001020,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001021,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001022,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001023,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001024,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001025,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001026,3,7:00:00,5,8:15:00,4,Treatment
5/25/2026,20001,PostFalls,2001027,3,7:00:00,5,8:15:00,4,Treatment
5/25/2026,20001,PostFalls,2001028,3,7:00:00,5,8:15:00,4,Treatment
5/25/2026,20001,PostFalls,2001029,3,7:00:00,5,8:15:00,4,Treatment
5/25/2026,20001,PostFalls,2001030,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001031,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001032,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001033,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001034,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001035,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001036,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001037,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001038,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001039,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001040,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001041,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001042,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001043,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001044,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001045,3,7:00:00,7,8:45:00,4,Treatment
5/25/2026,20001,PostFalls,2001046,3,7:00:00,7,8:45:00,4,Treatment
5/25/2026,20001,PostFalls,2001047,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001048,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001049,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001050,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001051,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001052,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001053,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001054,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001055,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001056,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001057,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001058,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001059,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001060,3,7:00:00,10,9:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001061,3,7:00:00,10,9:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001062,3,7:00:00,10,9:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001063,3,7:00:00,10,9:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001064,3,7:00:00,10,9:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001065,3,7:00:00,10,9:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001066,3,7:00:00,10,9:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001067,3,7:00:00,12,10:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001068,3,7:00:00,12,10:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001069,3,7:00:00,12,10:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001070,3,7:00:00,12,10:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001071,3,7:00:00,14,10:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001072,3,7:00:00,14,10:30:00,4,Treatment
5/25/2026,20001,PostFalls,2001073,3,7:00:00,16,11:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001074,3,7:00:00,20,12:00:00,4,Treatment
5/25/2026,20001,PostFalls,2001075,3,7:00:00,24,13:00:00,4,Treatment

## OUTPUT
Complete the scheduling algorithm defined in the instructions above, then run the pre-output validation checklist. Only after all checks pass, output the CSV.

Output ONLY the CSV between the markers below. Do NOT include any reasoning, working, justification, or commentary — only the CSV block.

---CSV_START---
(CSV rows here, one per line, no header row)
---CSV_END---

Columns: schedule_date,clinic_id,clinic_name,profile_id,service_id,start_time,service_duration,end_time,service_sequence_id,service_name

Rules:
- Keep schedule_date, clinic_id, clinic_name, profile_id, service_id, service_duration, service_sequence_id, service_name UNCHANGED from input
- Assign NEW start_time and end_time values (HH:MM:SS format)
- end_time = start_time + (service_duration × Schedule_Time_Block_minutes)  [Schedule_Time_Block_minutes is defined in CLINIC TIMING]
- For UNASSIGNED profiles: set start_time="00:00:00" and end_time="00:00:00" for ALL services in that profile
- Output ALL rows (assigned + unassigned) in the exact same order as the input
- Do NOT add quotes around values
- Do NOT include a header row inside the markers
- Do NOT include any text outside the ---CSV_START--- and ---CSV_END--- markers