Files
lynchmark/tests/7_scheduler/outputs_gemini/gemini-3-pro-preview TEMP_2.js
2025-11-18 22:04:41 +00:00

50 lines
1.4 KiB
JavaScript

export const findAvailableSlots = async (calA, calB, { durationMinutes: dur, searchRange: range, workHours: work }) => {
const { formatISO, addMinutes } = await import('https://esm.sh/date-fns@3.6.0');
const toMs = (d) => new Date(d).getTime();
const slotMs = dur * 6e4;
const limit = toMs(range.end);
const parseTime = t => t.split(':').reduce((h, m) => h * 60 + +m, 0);
const [wStart, wEnd] = [work.start, work.end].map(parseTime);
const busy = [...calA, ...calB]
.map(x => ({ s: toMs(x.start), e: toMs(x.end) }))
.sort((a, b) => a.s - b.s)
.reduce((a, c) => {
const l = a.at(-1);
(l && c.s <= l.e) ? l.e = Math.max(l.e, c.e) : a.push(c);
return a;
}, []);
let now = toMs(range.start);
let bIdx = 0;
const res = [];
while (now + slotMs <= limit) {
const d = new Date(now);
const dayBase = Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate());
const [dayStart, dayEnd] = [dayBase + wStart * 6e4, dayBase + wEnd * 6e4];
if (now < dayStart) {
now = dayStart;
continue;
}
if (now + slotMs > dayEnd) {
now = dayStart + 864e5;
continue;
}
while (busy[bIdx] && busy[bIdx].e <= now) bIdx++;
const b = busy[bIdx];
if (b && b.s < now + slotMs) {
now = b.e;
} else {
res.push({ start: formatISO(now), end: formatISO(addMinutes(now, dur)) });
now += slotMs;
}
}
return res;
};
export default findAvailableSlots;