}
const dateformat = {
weekday: 'long',
month: 'long',
day: 'numeric'
};
function overlapping_logs(a: Log, b: Log, swap: boolean = true): boolean {
return (a.startTime.valueOf() <= b.startTime.valueOf() && b.startTime.valueOf() <= a.endTime.valueOf()) || (swap && overlapping_logs(b, a, false));
}
function longer_log(a: Log, b: Log): Log {
const a_len = a.endTime.valueOf() - a.startTime.valueOf();
const b_len = b.endTime.valueOf() - b.startTime.valueOf();
if (a_len >= b_len) {
return a;
} else {
return b;
}
}
function merge_logs(a: Log, b: Log): Log {
return {
iid: a.iid,
code: a.code,
startTime: a.startTime,
endTime: b.endTime,
fights: a.fights.concat(b.fights)
};
}
// determine if the logs are close enough that its probably a DC split. assumes a < b
function close_logs(a: Log, b: Log, threshold: number = 30 * 60 * 1000): boolean {
return a.endTime.valueOf() < b.startTime.valueOf() && (b.startTime.valueOf() - a.endTime.valueOf()) < threshold
}
// filters the log set, removing logs that overlap (and favoring the longer log
// in such cases) and merging logs that appear to be split due to DCs.
function filter_logs(logs: Log[]): Log[] {
let killSeen = false;
return logs
.map(log => ({ ...log, startTime: new Date(log.startTime), endTime: new Date(log.endTime) }))
.sort((a, b) => a.startTime.valueOf() - b.startTime.valueOf())
.filter(({ fights }) => {
const seen = killSeen;
const kill = fights.some(({ kill }) => kill);
killSeen = kill || killSeen;
return !seen;
})
.reduce((res, log, ix) => {
if(ix === 0) {
res.push(log);
return res;
} else {
const prev = res[res.length - 1];
if(overlapping_logs(prev, log)) {
res.pop();
res.push(longer_log(prev, log));
} else if(close_logs(prev, log)) {
res.pop();
res.push(merge_logs(prev, log));
} else {
res.push(log);
}
return res;
}
}, [] as Log[]);
}
function formatDate(date: Date): string {
return new Intl.DateTimeFormat('en-US', dateformat).format(date);