| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | import { Utils } from "../../Utils" | 
					
						
							|  |  |  | import opening_hours from "opening_hours" | 
					
						
							| 
									
										
										
										
											2020-10-04 12:55:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-02 19:00:24 +02:00
										 |  |  | export interface OpeningHour { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     weekday: number // 0 is monday, 1 is tuesday, ...
 | 
					
						
							|  |  |  |     startHour: number | 
					
						
							|  |  |  |     startMinutes: number | 
					
						
							|  |  |  |     endHour: number | 
					
						
							| 
									
										
										
										
											2020-10-02 19:00:24 +02:00
										 |  |  |     endMinutes: number | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Various utilities manipulating opening hours | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  | export class OH { | 
					
						
							| 
									
										
										
										
											2020-10-04 12:55:44 +02:00
										 |  |  |     private static readonly days = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"] | 
					
						
							|  |  |  |     private static readonly daysIndexed = { | 
					
						
							|  |  |  |         mo: 0, | 
					
						
							|  |  |  |         tu: 1, | 
					
						
							|  |  |  |         we: 2, | 
					
						
							|  |  |  |         th: 3, | 
					
						
							|  |  |  |         fr: 4, | 
					
						
							|  |  |  |         sa: 5, | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         su: 6, | 
					
						
							| 
									
										
										
										
											2020-10-04 12:55:44 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-08 19:03:00 +02:00
										 |  |  |     public static hhmm(h: number, m: number): string { | 
					
						
							|  |  |  |         if (h == 24) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return "00:00" | 
					
						
							| 
									
										
										
										
											2020-10-08 19:03:00 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return Utils.TwoDigits(h) + ":" + Utils.TwoDigits(m) | 
					
						
							| 
									
										
										
										
											2020-10-08 19:03:00 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-21 02:00:50 +01:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |      * const rules = [{weekday: 6,endHour: 17,endMinutes: 0,startHour: 13,startMinutes: 0}, | 
					
						
							|  |  |  |      *                {weekday: 1,endHour: 12,endMinutes: 0,startHour: 10,startMinutes: 0}] | 
					
						
							|  |  |  |      * OH.ToString(rules) // =>  "Tu 10:00-12:00; Su 13:00-17:00"
 | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * const rules = [{weekday: 3,endHour: 17,endMinutes: 0,startHour: 13,startMinutes: 0}, {weekday: 1,endHour: 12,endMinutes: 0,startHour: 10,startMinutes: 0}] | 
					
						
							|  |  |  |      * OH.ToString(rules) // => "Tu 10:00-12:00; Th 13:00-17:00"
 | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * const rules = [ { weekday: 1, endHour: 17, endMinutes: 0, startHour: 13, startMinutes: 0 }, { weekday: 1, endHour: 12, endMinutes: 0, startHour: 10, startMinutes: 0 }]); | 
					
						
							|  |  |  |      * OH.ToString(rules) // => "Tu 10:00-12:00, 13:00-17:00"
 | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * const rules = [ { weekday: 0, endHour: 12, endMinutes: 0, startHour: 10, startMinutes: 0 }, { weekday: 0, endHour: 17, endMinutes: 0, startHour: 13, startMinutes: 0}, { weekday: 1, endHour: 17, endMinutes: 0, startHour: 13, startMinutes: 0 }, { weekday: 1, endHour: 12, endMinutes: 0, startHour: 10, startMinutes: 0 }]; | 
					
						
							|  |  |  |      * OH.ToString(rules) // => "Mo-Tu 10:00-12:00, 13:00-17:00"
 | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2022-03-21 02:00:50 +01:00
										 |  |  |      * // should merge overlapping opening hours
 | 
					
						
							|  |  |  |      * const timerange0 = {weekday: 1, endHour: 23, endMinutes: 30, startHour: 23, startMinutes: 0 } | 
					
						
							|  |  |  |      * const touchingTimeRange = {  weekday: 1, endHour: 0, endMinutes: 0, startHour: 23, startMinutes: 30 } | 
					
						
							|  |  |  |      * OH.ToString(OH.MergeTimes([timerange0, touchingTimeRange])) // => "Tu 23:00-00:00"
 | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * // should merge touching opening hours
 | 
					
						
							|  |  |  |      * const timerange0 = {weekday: 1, endHour: 23, endMinutes: 30, startHour: 23, startMinutes: 0 } | 
					
						
							|  |  |  |      * const overlappingTimeRange =  { weekday: 1, endHour: 24, endMinutes: 0, startHour: 23, startMinutes: 30 } | 
					
						
							|  |  |  |      * OH.ToString(OH.MergeTimes([timerange0, overlappingTimeRange])) // => "Tu 23:00-00:00"
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |      * | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-04 12:55:44 +02:00
										 |  |  |     public static ToString(ohs: OpeningHour[]) { | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |         if (ohs.length == 0) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return "" | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const partsPerWeekday: string[][] = [[], [], [], [], [], [], []] | 
					
						
							| 
									
										
										
										
											2020-10-04 12:55:44 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for (const oh of ohs) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             partsPerWeekday[oh.weekday].push( | 
					
						
							|  |  |  |                 OH.hhmm(oh.startHour, oh.startMinutes) + "-" + OH.hhmm(oh.endHour, oh.endMinutes) | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const stringPerWeekday = partsPerWeekday.map((parts) => parts.sort().join(", ")) | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const rules = [] | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         let rangeStart = 0 | 
					
						
							|  |  |  |         let rangeEnd = 0 | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         function pushRule() { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             const rule = stringPerWeekday[rangeStart] | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |             if (rule === "") { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 return | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             if (rangeStart == rangeEnd - 1) { | 
					
						
							|  |  |  |                 rules.push(`${OH.days[rangeStart]} ${rule}`) | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 rules.push(`${OH.days[rangeStart]}-${OH.days[rangeEnd - 1]} ${rule}`) | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-10-06 02:09:09 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |         for (; rangeEnd < 7; rangeEnd++) { | 
					
						
							|  |  |  |             if (stringPerWeekday[rangeStart] != stringPerWeekday[rangeEnd]) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 pushRule() | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |                 rangeStart = rangeEnd | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-10-04 12:55:44 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         pushRule() | 
					
						
							| 
									
										
										
										
											2020-10-04 12:55:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-08 19:03:00 +02:00
										 |  |  |         const oh = rules.join("; ") | 
					
						
							|  |  |  |         if (oh === "Mo-Su 00:00-00:00") { | 
					
						
							| 
									
										
										
										
											2020-10-06 02:09:09 +02:00
										 |  |  |             return "24/7" | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return oh | 
					
						
							| 
									
										
										
										
											2020-10-04 12:55:44 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Merge duplicate opening-hour element in place. | 
					
						
							|  |  |  |      * Returns true if something changed | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2022-03-21 02:00:50 +01:00
										 |  |  |      * // should merge overlapping opening hours
 | 
					
						
							|  |  |  |      * const oh1: OpeningHour = { weekday: 0, startHour: 10, startMinutes: 0, endHour: 11, endMinutes: 0 }; | 
					
						
							|  |  |  |      * const oh0: OpeningHour = { weekday: 0, startHour: 10, startMinutes: 30, endHour: 12, endMinutes: 0 }; | 
					
						
							|  |  |  |      * OH.MergeTimes([oh0, oh1]) // => [{ weekday: 0, startHour: 10, startMinutes: 0, endHour: 12, endMinutes: 0 }]
 | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * // should merge touching opening hours
 | 
					
						
							|  |  |  |      * const oh1: OpeningHour = { weekday: 0, startHour: 10, startMinutes: 0, endHour: 11, endMinutes: 0 }; | 
					
						
							|  |  |  |      * const oh0: OpeningHour = { weekday: 0, startHour: 11, startMinutes: 0, endHour: 12, endMinutes: 0 }; | 
					
						
							|  |  |  |      * OH.MergeTimes([oh0, oh1]) // => [{ weekday: 0, startHour: 10, startMinutes: 0, endHour: 12, endMinutes: 0 }]
 | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |      */ | 
					
						
							|  |  |  |     public static MergeTimes(ohs: OpeningHour[]): OpeningHour[] { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const queue = ohs.map((oh) => { | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |             if (oh.endHour === 0 && oh.endMinutes === 0) { | 
					
						
							|  |  |  |                 const newOh = { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     ...oh, | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |                 newOh.endHour = 24 | 
					
						
							|  |  |  |                 return newOh | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return oh | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         const newList = [] | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |         while (queue.length > 0) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             let maybeAdd = queue.pop() | 
					
						
							| 
									
										
										
										
											2020-10-04 12:55:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             let doAddEntry = true | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |             if (maybeAdd.weekday == undefined) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 doAddEntry = false | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-10-04 12:55:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |             for (let i = newList.length - 1; i >= 0 && doAddEntry; i--) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 let guard = newList[i] | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |                 if (maybeAdd.weekday != guard.weekday) { | 
					
						
							|  |  |  |                     // Not the same day
 | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 if ( | 
					
						
							|  |  |  |                     OH.startTimeLiesInRange(maybeAdd, guard) && | 
					
						
							|  |  |  |                     OH.endTimeLiesInRange(maybeAdd, guard) | 
					
						
							|  |  |  |                 ) { | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |                     // Guard fully covers 'maybeAdd': we can safely ignore maybeAdd
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     doAddEntry = false | 
					
						
							|  |  |  |                     break | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 if ( | 
					
						
							|  |  |  |                     OH.startTimeLiesInRange(guard, maybeAdd) && | 
					
						
							|  |  |  |                     OH.endTimeLiesInRange(guard, maybeAdd) | 
					
						
							|  |  |  |                 ) { | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |                     // 'maybeAdd'  fully covers Guard - the guard is killed
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     newList.splice(i, 1) | 
					
						
							|  |  |  |                     break | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 if ( | 
					
						
							|  |  |  |                     OH.startTimeLiesInRange(maybeAdd, guard) || | 
					
						
							|  |  |  |                     OH.endTimeLiesInRange(maybeAdd, guard) || | 
					
						
							|  |  |  |                     OH.startTimeLiesInRange(guard, maybeAdd) || | 
					
						
							|  |  |  |                     OH.endTimeLiesInRange(guard, maybeAdd) | 
					
						
							|  |  |  |                 ) { | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |                     // At this point, the maybeAdd overlaps the guard: we should extend the guard and retest it
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     newList.splice(i, 1) | 
					
						
							|  |  |  |                     let startHour = guard.startHour | 
					
						
							|  |  |  |                     let startMinutes = guard.startMinutes | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |                     if (OH.startTime(maybeAdd) < OH.startTime(guard)) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                         startHour = maybeAdd.startHour | 
					
						
							|  |  |  |                         startMinutes = maybeAdd.startMinutes | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     let endHour = guard.endHour | 
					
						
							|  |  |  |                     let endMinutes = guard.endMinutes | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |                     if (OH.endTime(maybeAdd) > OH.endTime(guard)) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                         endHour = maybeAdd.endHour | 
					
						
							|  |  |  |                         endMinutes = maybeAdd.endMinutes | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |                     } | 
					
						
							| 
									
										
										
										
											2020-10-04 12:55:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |                     queue.push({ | 
					
						
							|  |  |  |                         startHour: startHour, | 
					
						
							|  |  |  |                         startMinutes: startMinutes, | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |                         endHour: endHour, | 
					
						
							|  |  |  |                         endMinutes: endMinutes, | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                         weekday: guard.weekday, | 
					
						
							|  |  |  |                     }) | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     doAddEntry = false | 
					
						
							|  |  |  |                     break | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (doAddEntry) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 newList.push(maybeAdd) | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // New list can only differ from the old list by merging entries
 | 
					
						
							|  |  |  |         // This means that the list is changed only if the lengths are different.
 | 
					
						
							|  |  |  |         // If the lengths are the same, we might just as well return the old list and be a bit more stable
 | 
					
						
							|  |  |  |         if (newList.length !== ohs.length) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return newList | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return ohs | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Gives the number of hours since the start of day. | 
					
						
							|  |  |  |      * E.g. | 
					
						
							|  |  |  |      * startTime({startHour: 9, startMinuts: 15}) == 9.25 | 
					
						
							|  |  |  |      * @param oh | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-10-08 19:03:00 +02:00
										 |  |  |     public static startTime(oh: OpeningHour): number { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return oh.startHour + oh.startMinutes / 60 | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-08 19:03:00 +02:00
										 |  |  |     public static endTime(oh: OpeningHour): number { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return oh.endHour + oh.endMinutes / 60 | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public static startTimeLiesInRange(checked: OpeningHour, mightLieIn: OpeningHour) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return ( | 
					
						
							|  |  |  |             OH.startTime(mightLieIn) <= OH.startTime(checked) && | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |             OH.startTime(checked) <= OH.endTime(mightLieIn) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public static endTimeLiesInRange(checked: OpeningHour, mightLieIn: OpeningHour) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return ( | 
					
						
							|  |  |  |             OH.startTime(mightLieIn) <= OH.endTime(checked) && | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |             OH.endTime(checked) <= OH.endTime(mightLieIn) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-10-04 12:55:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-08 19:03:00 +02:00
										 |  |  |     public static parseHHMMRange(hhmmhhmm: string): { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         startHour: number | 
					
						
							|  |  |  |         startMinutes: number | 
					
						
							|  |  |  |         endHour: number | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |         endMinutes: number | 
					
						
							|  |  |  |     } { | 
					
						
							| 
									
										
										
										
											2020-10-08 19:03:00 +02:00
										 |  |  |         if (hhmmhhmm == "off") { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return null | 
					
						
							| 
									
										
										
										
											2020-10-06 02:09:09 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-10-08 19:03:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const timings = hhmmhhmm.split("-") | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |         const start = OH.parseHHMM(timings[0]) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const end = OH.parseHHMM(timings[1]) | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |         return { | 
					
						
							|  |  |  |             startHour: start.hours, | 
					
						
							|  |  |  |             startMinutes: start.minutes, | 
					
						
							|  |  |  |             endHour: end.hours, | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             endMinutes: end.minutes, | 
					
						
							| 
									
										
										
										
											2020-10-04 12:55:44 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-10-04 12:55:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-15 13:40:23 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Converts an OH-syntax rule into an object | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |      * | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2022-03-15 13:40:23 +01:00
										 |  |  |      * const rules = OH.ParsePHRule("PH 12:00-17:00") | 
					
						
							|  |  |  |      * rules.mode // => " "
 | 
					
						
							|  |  |  |      * rules.start // => "12:00"
 | 
					
						
							|  |  |  |      * rules.end // => "17:00"
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2022-03-15 13:40:23 +01:00
										 |  |  |      * OH.ParseRule("PH 12:00-17:00") // => null
 | 
					
						
							|  |  |  |      * OH.ParseRule("Th[-1] off") // => null
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2022-03-15 13:40:23 +01:00
										 |  |  |      * const rules = OH.Parse("24/7"); | 
					
						
							|  |  |  |      * rules.length // => 7
 | 
					
						
							|  |  |  |      * rules[0].startHour // => 0
 | 
					
						
							|  |  |  |      * OH.ToString(rules) // => "24/7"
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2022-03-18 13:04:12 +01:00
										 |  |  |      * const rules = OH.ParseRule("11:00-19:00"); | 
					
						
							|  |  |  |      * rules.length // => 7
 | 
					
						
							|  |  |  |      * rules[0].weekday // => 0
 | 
					
						
							|  |  |  |      * rules[0].startHour // => 11
 | 
					
						
							|  |  |  |      * rules[3].endHour // => 19
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2022-03-18 13:04:12 +01:00
										 |  |  |      * const rules = OH.ParseRule("Mo-Th 11:00-19:00"); | 
					
						
							|  |  |  |      * rules.length // => 4
 | 
					
						
							|  |  |  |      * rules[0].weekday // => 0
 | 
					
						
							|  |  |  |      * rules[0].startHour // => 11
 | 
					
						
							|  |  |  |      * rules[3].endHour // => 19
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2022-03-15 13:40:23 +01:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |     public static ParseRule(rule: string): OpeningHour[] { | 
					
						
							| 
									
										
										
										
											2020-10-08 19:03:00 +02:00
										 |  |  |         try { | 
					
						
							|  |  |  |             if (rule.trim() == "24/7") { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 return OH.multiply( | 
					
						
							|  |  |  |                     [0, 1, 2, 3, 4, 5, 6], | 
					
						
							|  |  |  |                     [ | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             startHour: 0, | 
					
						
							|  |  |  |                             startMinutes: 0, | 
					
						
							|  |  |  |                             endHour: 24, | 
					
						
							|  |  |  |                             endMinutes: 0, | 
					
						
							|  |  |  |                         }, | 
					
						
							|  |  |  |                     ] | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2020-10-08 19:03:00 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-10-06 02:09:09 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             const split = rule.trim().replace(/, */g, ",").split(" ") | 
					
						
							| 
									
										
										
										
											2020-10-08 19:03:00 +02:00
										 |  |  |             if (split.length == 1) { | 
					
						
							|  |  |  |                 // First, try to parse this rule as a rule without weekdays
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 let timeranges = OH.ParseHhmmRanges(rule) | 
					
						
							|  |  |  |                 let weekdays = [0, 1, 2, 3, 4, 5, 6] | 
					
						
							|  |  |  |                 return OH.multiply(weekdays, timeranges) | 
					
						
							| 
									
										
										
										
											2020-10-08 19:03:00 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-10-04 12:55:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-08 19:03:00 +02:00
										 |  |  |             if (split.length == 2) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 const weekdays = OH.ParseWeekdayRanges(split[0]) | 
					
						
							|  |  |  |                 const timeranges = OH.ParseHhmmRanges(split[1]) | 
					
						
							|  |  |  |                 return OH.multiply(weekdays, timeranges) | 
					
						
							| 
									
										
										
										
											2020-10-08 19:03:00 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return null | 
					
						
							| 
									
										
										
										
											2020-10-08 19:03:00 +02:00
										 |  |  |         } catch (e) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             console.log("Could not parse weekday rule ", rule) | 
					
						
							|  |  |  |             return null | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-29 16:57:29 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2022-06-29 16:57:29 +02:00
										 |  |  |      * OH.ParsePHRule("PH Off") // => {mode: "off"}
 | 
					
						
							|  |  |  |      * OH.ParsePHRule("PH OPEN") // => {mode: "open"}
 | 
					
						
							|  |  |  |      * OH.ParsePHRule("PH 10:00-12:00") // => {mode: " ", start: "10:00", end: "12:00"}
 | 
					
						
							|  |  |  |      * OH.ParsePHRule(undefined) // => null
 | 
					
						
							|  |  |  |      * OH.ParsePHRule(null) // => null
 | 
					
						
							|  |  |  |      * OH.ParsePHRule("some random string") // => null
 | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |     public static ParsePHRule(str: string): { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         mode: string | 
					
						
							|  |  |  |         start?: string | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         end?: string | 
					
						
							|  |  |  |     } { | 
					
						
							| 
									
										
										
										
											2022-06-29 16:57:29 +02:00
										 |  |  |         if (str === undefined || str === null) { | 
					
						
							| 
									
										
										
										
											2021-09-02 21:22:34 +02:00
										 |  |  |             return null | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         str = str.trim() | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         if (!str.startsWith("PH")) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return null | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         str = str.trim() | 
					
						
							| 
									
										
										
										
											2022-06-29 16:57:29 +02:00
										 |  |  |         if (str.toLowerCase() === "ph off") { | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |             return { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 mode: "off", | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-29 16:57:29 +02:00
										 |  |  |         if (str.toLowerCase() === "ph open") { | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |             return { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 mode: "open", | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!str.startsWith("PH ")) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return null | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         try { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             const timerange = OH.parseHHMMRange(str.substring(2)) | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |             if (timerange === null) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 return null | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return { | 
					
						
							|  |  |  |                 mode: " ", | 
					
						
							|  |  |  |                 start: OH.hhmm(timerange.startHour, timerange.startMinutes), | 
					
						
							|  |  |  |                 end: OH.hhmm(timerange.endHour, timerange.endMinutes), | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } catch (e) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return null | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  |     public static simplify(str: string): string { | 
					
						
							| 
									
										
										
										
											2022-01-07 04:14:53 +01:00
										 |  |  |         return OH.ToString(OH.MergeTimes(OH.Parse(str))) | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-05 02:24:14 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Parses a string into Opening Hours | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  |     public static Parse(rules: string): OpeningHour[] { | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |         if (rules === undefined || rules === "") { | 
					
						
							|  |  |  |             return [] | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  |         const ohs: OpeningHour[] = [] | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const split = rules.split(";") | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for (const rule of split) { | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |             if (rule === "") { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |             try { | 
					
						
							| 
									
										
										
										
											2020-10-08 19:03:00 +02:00
										 |  |  |                 const parsed = OH.ParseRule(rule) | 
					
						
							|  |  |  |                 if (parsed !== null) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     ohs.push(...parsed) | 
					
						
							| 
									
										
										
										
											2020-10-08 19:03:00 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2020-10-04 12:55:44 +02:00
										 |  |  |             } catch (e) { | 
					
						
							| 
									
										
										
										
											2020-10-06 01:37:02 +02:00
										 |  |  |                 console.error("Could not parse ", rule, ": ", e) | 
					
						
							| 
									
										
										
										
											2020-10-04 12:55:44 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return ohs | 
					
						
							| 
									
										
										
										
											2020-10-04 12:55:44 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* | 
					
						
							|  |  |  |  This function converts a number of ranges (generated by OpeningHours.js) into all the hours of day that a change occurs. | 
					
						
							|  |  |  |  E.g. | 
					
						
							|  |  |  |  Monday, some business is opended from 9:00 till 17:00 | 
					
						
							|  |  |  |  Tuesday from 9:30 till 18:00 | 
					
						
							|  |  |  |  Wednesday from 9:30 till 12:30 | 
					
						
							|  |  |  |  This function will extract all those moments of change and will return 9:00, 9:30, 12:30, 17:00 and 18:00 | 
					
						
							|  |  |  |  This list will be sorted | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     public static allChangeMoments( | 
					
						
							|  |  |  |         ranges: { | 
					
						
							|  |  |  |             isOpen: boolean | 
					
						
							|  |  |  |             isSpecial: boolean | 
					
						
							|  |  |  |             comment: string | 
					
						
							|  |  |  |             startDate: Date | 
					
						
							|  |  |  |             endDate: Date | 
					
						
							|  |  |  |         }[][] | 
					
						
							|  |  |  |     ): [number[], string[]] { | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |         const changeHours: number[] = [] | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const changeHourText: string[] = [] | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |         const extrachangeHours: number[] = [] | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const extrachangeHourText: string[] = [] | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for (const weekday of ranges) { | 
					
						
							|  |  |  |             for (const range of weekday) { | 
					
						
							|  |  |  |                 if (!range.isOpen && !range.isSpecial) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 const startOfDay: Date = new Date(range.startDate) | 
					
						
							|  |  |  |                 startOfDay.setHours(0, 0, 0, 0) | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |                 // The number of seconds since the start of the day
 | 
					
						
							|  |  |  |                 // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 const changeMoment: number = (range.startDate - startOfDay) / 1000 | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |                 if (changeHours.indexOf(changeMoment) < 0) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     changeHours.push(changeMoment) | 
					
						
							|  |  |  |                     changeHourText.push( | 
					
						
							|  |  |  |                         OH.hhmm(range.startDate.getHours(), range.startDate.getMinutes()) | 
					
						
							|  |  |  |                     ) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // The number of seconds till between the start of the day and closing
 | 
					
						
							|  |  |  |                 // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 let changeMomentEnd: number = (range.endDate - startOfDay) / 1000 | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |                 if (changeMomentEnd >= 24 * 60 * 60) { | 
					
						
							|  |  |  |                     if (extrachangeHours.indexOf(changeMomentEnd) < 0) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                         extrachangeHours.push(changeMomentEnd) | 
					
						
							|  |  |  |                         extrachangeHourText.push( | 
					
						
							|  |  |  |                             OH.hhmm(range.endDate.getHours(), range.endDate.getMinutes()) | 
					
						
							|  |  |  |                         ) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  |                 } else if (changeHours.indexOf(changeMomentEnd) < 0) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     changeHours.push(changeMomentEnd) | 
					
						
							|  |  |  |                     changeHourText.push( | 
					
						
							|  |  |  |                         OH.hhmm(range.endDate.getHours(), range.endDate.getMinutes()) | 
					
						
							|  |  |  |                     ) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Note that 'changeHours' and 'changeHourText' will be more or less in sync - one is in numbers, the other in 'HH:MM' format.
 | 
					
						
							|  |  |  |         // But both can be sorted without problem; they'll stay in sync
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         changeHourText.sort() | 
					
						
							|  |  |  |         changeHours.sort() | 
					
						
							|  |  |  |         extrachangeHourText.sort() | 
					
						
							|  |  |  |         extrachangeHours.sort() | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         changeHourText.push(...extrachangeHourText) | 
					
						
							|  |  |  |         changeHours.push(...extrachangeHours) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return [changeHours, changeHourText] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     public static CreateOhObject( | 
					
						
							|  |  |  |         tags: object & { _lat: number; _lon: number; _country?: string }, | 
					
						
							|  |  |  |         textToParse: string | 
					
						
							|  |  |  |     ) { | 
					
						
							| 
									
										
										
										
											2022-04-28 00:32:15 +02:00
										 |  |  |         // noinspection JSPotentiallyInvalidConstructorUsage
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return new opening_hours( | 
					
						
							|  |  |  |             textToParse, | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 lat: tags._lat, | 
					
						
							|  |  |  |                 lon: tags._lon, | 
					
						
							|  |  |  |                 address: { | 
					
						
							|  |  |  |                     country_code: tags._country.toLowerCase(), | 
					
						
							|  |  |  |                     state: undefined, | 
					
						
							|  |  |  |                 }, | 
					
						
							| 
									
										
										
										
											2022-04-28 00:32:15 +02:00
										 |  |  |             }, | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             <any>{ tag_key: "opening_hours" } | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2022-04-28 00:32:15 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |     /* | 
					
						
							|  |  |  |  Calculates when the business is opened (or on holiday) between two dates. | 
					
						
							|  |  |  |  Returns a matrix of ranges, where [0] is a list of ranges when it is opened on monday, [1] is a list of ranges for tuesday, ... | 
					
						
							|  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     public static GetRanges( | 
					
						
							|  |  |  |         oh: any, | 
					
						
							|  |  |  |         from: Date, | 
					
						
							|  |  |  |         to: Date | 
					
						
							|  |  |  |     ): { | 
					
						
							|  |  |  |         isOpen: boolean | 
					
						
							|  |  |  |         isSpecial: boolean | 
					
						
							|  |  |  |         comment: string | 
					
						
							|  |  |  |         startDate: Date | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |         endDate: Date | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     }[][] { | 
					
						
							|  |  |  |         const values = [[], [], [], [], [], [], []] | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const start = new Date(from) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |         // We go one day more into the past, in order to force rendering of holidays in the start of the period
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         start.setDate(from.getDate() - 1) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const iterator = oh.getIterator(start) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         let prevValue = undefined | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |         while (iterator.advance(to)) { | 
					
						
							|  |  |  |             if (prevValue) { | 
					
						
							|  |  |  |                 prevValue.endDate = iterator.getDate() as Date | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             const endDate = new Date(iterator.getDate()) as Date | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             endDate.setHours(0, 0, 0, 0) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             endDate.setDate(endDate.getDate() + 1) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             const value = { | 
					
						
							|  |  |  |                 isSpecial: iterator.getUnknown(), | 
					
						
							|  |  |  |                 isOpen: iterator.getState(), | 
					
						
							|  |  |  |                 comment: iterator.getComment(), | 
					
						
							|  |  |  |                 startDate: iterator.getDate() as Date, | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 endDate: endDate, // Should be overwritten by the next iteration
 | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             prevValue = value | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (value.comment === undefined && !value.isOpen && !value.isSpecial) { | 
					
						
							|  |  |  |                 // simply closed, nothing special here
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (value.startDate < from) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |             // Get day: sunday is 0, monday is 1. We move everything so that monday == 0
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             values[(value.startDate.getDay() + 6) % 7].push(value) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return values | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     private static parseHHMM(hhmm: string): { hours: number; minutes: number } { | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         if (hhmm === undefined || hhmm == null) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return null | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const spl = hhmm.trim().split(":") | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         if (spl.length != 2) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return null | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const hm = { hours: Number(spl[0].trim()), minutes: Number(spl[1].trim()) } | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         if (isNaN(hm.hours) || isNaN(hm.minutes)) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return null | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return hm | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private static ParseHhmmRanges(hhmms: string): { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         startHour: number | 
					
						
							|  |  |  |         startMinutes: number | 
					
						
							|  |  |  |         endHour: number | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         endMinutes: number | 
					
						
							|  |  |  |     }[] { | 
					
						
							|  |  |  |         if (hhmms === "off") { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return [] | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return hhmms | 
					
						
							|  |  |  |             .split(",") | 
					
						
							|  |  |  |             .map((s) => s.trim()) | 
					
						
							|  |  |  |             .filter((str) => str !== "") | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |             .map(OH.parseHHMMRange) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             .filter((v) => v != null) | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private static ParseWeekday(weekday: string): number { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return OH.daysIndexed[weekday.trim().toLowerCase()] | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private static ParseWeekdayRange(weekdays: string): number[] { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const split = weekdays.split("-") | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         if (split.length == 1) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             const parsed = OH.ParseWeekday(weekdays) | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |             if (parsed == null) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 return null | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return [parsed] | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         } else if (split.length == 2) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             let start = OH.ParseWeekday(split[0]) | 
					
						
							|  |  |  |             let end = OH.ParseWeekday(split[1]) | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |             if ((start ?? null) === null || (end ?? null) === null) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 return null | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             let range = [] | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |             for (let i = start; i <= end; i++) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 range.push(i) | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return range | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return null | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private static ParseWeekdayRanges(weekdays: string): number[] { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         let ranges = [] | 
					
						
							|  |  |  |         let split = weekdays.split(",") | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         for (const weekday of split) { | 
					
						
							|  |  |  |             const parsed = OH.ParseWeekdayRange(weekday) | 
					
						
							|  |  |  |             if (parsed === undefined || parsed === null) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 return null | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             ranges.push(...parsed) | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return ranges | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     private static multiply( | 
					
						
							|  |  |  |         weekdays: number[], | 
					
						
							|  |  |  |         timeranges: { | 
					
						
							|  |  |  |             startHour: number | 
					
						
							|  |  |  |             startMinutes: number | 
					
						
							|  |  |  |             endHour: number | 
					
						
							|  |  |  |             endMinutes: number | 
					
						
							|  |  |  |         }[] | 
					
						
							|  |  |  |     ) { | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         if ((weekdays ?? null) == null || (timeranges ?? null) == null) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return null | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         const ohs: OpeningHour[] = [] | 
					
						
							|  |  |  |         for (const timerange of timeranges) { | 
					
						
							|  |  |  |             for (const weekday of weekdays) { | 
					
						
							|  |  |  |                 ohs.push({ | 
					
						
							|  |  |  |                     weekday: weekday, | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     startHour: timerange.startHour, | 
					
						
							|  |  |  |                     startMinutes: timerange.startMinutes, | 
					
						
							|  |  |  |                     endHour: timerange.endHour, | 
					
						
							|  |  |  |                     endMinutes: timerange.endMinutes, | 
					
						
							|  |  |  |                 }) | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return ohs | 
					
						
							| 
									
										
										
										
											2021-06-16 16:39:48 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-04-28 00:32:15 +02:00
										 |  |  |     public static getMondayBefore(d) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         d = new Date(d) | 
					
						
							|  |  |  |         const day = d.getDay() | 
					
						
							|  |  |  |         const diff = d.getDate() - day + (day == 0 ? -6 : 1) // adjust when day is sunday
 | 
					
						
							|  |  |  |         return new Date(d.setDate(diff)) | 
					
						
							| 
									
										
										
										
											2022-04-28 00:32:15 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-10-04 01:04:46 +02:00
										 |  |  | } |