export type TemplateId = | "t54w-door-unlock" | "t54w-door-unlock-with-sp" | "t57w-door-unlock-with-sp" | "t58w-door-unlock"; export interface SharedParkingSlot { readonly blfNo: number; readonly value: string; } export interface SlotContract { readonly reserved: readonly number[]; readonly sharedParking: readonly SharedParkingSlot[]; readonly ownLine: number; readonly managedStart: number; readonly managedEnd: number; } export const SLOT_CONTRACT: Record = { "t54w-door-unlock": { reserved: [2], sharedParking: [], ownLine: 1, managedStart: 3, managedEnd: 12, }, "t54w-door-unlock-with-sp": { reserved: [2], sharedParking: [ { blfNo: 3, value: "SP1" }, { blfNo: 4, value: "SP2" }, { blfNo: 5, value: "SP3" }, ], ownLine: 1, managedStart: 6, managedEnd: 15, }, "t57w-door-unlock-with-sp": { reserved: [2], sharedParking: [ { blfNo: 3, value: "SP1" }, { blfNo: 4, value: "SP2" }, { blfNo: 5, value: "SP3" }, ], ownLine: 1, managedStart: 6, managedEnd: 15, }, "t58w-door-unlock": { reserved: [2, 3, 4], sharedParking: [], ownLine: 1, managedStart: 5, managedEnd: 14, }, }; const TEMPLATE_MATCHERS: { id: TemplateId; needle: string }[] = [ { id: "t57w-door-unlock-with-sp", needle: "yealinkT57W-door-unlock-with-sp" }, { id: "t54w-door-unlock-with-sp", needle: "yealinkT54W-door-unlock-with-sp" }, { id: "t54w-door-unlock", needle: "yealinkT54W-door-unlock" }, { id: "t58w-door-unlock", needle: "yealinkT58W-door-unlock" }, ]; export function resolveTemplateId(...candidates: Array): TemplateId | undefined { const haystack = candidates.filter(Boolean).join(" "); if (!haystack) { return undefined; } for (const matcher of TEMPLATE_MATCHERS) { if (haystack.includes(matcher.needle)) { return matcher.id; } } return undefined; } export function isManagedSlot(contract: SlotContract, blfNo: number): boolean { return blfNo >= contract.managedStart && blfNo <= contract.managedEnd; } export function isReservedSlot(contract: SlotContract, blfNo: number): boolean { return contract.reserved.includes(blfNo); } export function isSharedParkingSlot(contract: SlotContract, blfNo: number): boolean { return contract.sharedParking.some((slot) => slot.blfNo === blfNo); } export function managedSlotCount(contract: SlotContract): number { return contract.managedEnd - contract.managedStart + 1; }