iobroker.webuntis2 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.de.md +79 -0
- package/README.md +74 -0
- package/admin/build/index.css +2 -0
- package/admin/build/index.css.map +7 -0
- package/admin/build/index.js +171 -0
- package/admin/build/index.js.map +7 -0
- package/admin/index.html +24 -0
- package/admin/index_m.html +24 -0
- package/admin/style.css +32 -0
- package/admin/webuntis2.png +0 -0
- package/build/lib/LegacyNamespaceCleanup.js +33 -0
- package/build/lib/LegacyNamespaceCleanup.js.map +7 -0
- package/build/lib/webuntis/CurrentNextLesson.js +98 -0
- package/build/lib/webuntis/CurrentNextLesson.js.map +7 -0
- package/build/lib/webuntis/Holidays.js +138 -0
- package/build/lib/webuntis/Holidays.js.map +7 -0
- package/build/lib/webuntis/SchoolDiscovery.js +145 -0
- package/build/lib/webuntis/SchoolDiscovery.js.map +7 -0
- package/build/lib/webuntis/Timetable.js +210 -0
- package/build/lib/webuntis/Timetable.js.map +7 -0
- package/build/lib/webuntis/WebUntisClient.js +593 -0
- package/build/lib/webuntis/WebUntisClient.js.map +7 -0
- package/build/lib/webuntis/WebUntisErrors.js +53 -0
- package/build/lib/webuntis/WebUntisErrors.js.map +7 -0
- package/build/lib/webuntis/WebUntisService.js +252 -0
- package/build/lib/webuntis/WebUntisService.js.map +7 -0
- package/build/lib/webuntis/WebUntisTypes.js +17 -0
- package/build/lib/webuntis/WebUntisTypes.js.map +7 -0
- package/build/main.js +514 -0
- package/build/main.js.map +7 -0
- package/io-package.json +151 -0
- package/package.json +111 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var Timetable_exports = {};
|
|
20
|
+
__export(Timetable_exports, {
|
|
21
|
+
assertTimetableResponse: () => assertTimetableResponse,
|
|
22
|
+
dateNumber: () => dateNumber,
|
|
23
|
+
dayRange: () => dayRange,
|
|
24
|
+
lessonChannelName: () => lessonChannelName,
|
|
25
|
+
normalizeLesson: () => normalizeLesson,
|
|
26
|
+
normalizeLessons: () => normalizeLessons,
|
|
27
|
+
resolveTimetableReferences: () => resolveTimetableReferences,
|
|
28
|
+
splitTimetable: () => splitTimetable,
|
|
29
|
+
summarizeTimetable: () => summarizeTimetable,
|
|
30
|
+
weekRange: () => weekRange
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(Timetable_exports);
|
|
33
|
+
var import_node_crypto = require("node:crypto");
|
|
34
|
+
var import_WebUntisErrors = require("./WebUntisErrors");
|
|
35
|
+
function lessonChannelName(lesson) {
|
|
36
|
+
const time = lesson.startTime && lesson.endTime ? `${lesson.startTime}\u2013${lesson.endTime}` : lesson.startTime || lesson.endTime;
|
|
37
|
+
return [time, lesson.subjectLong || lesson.subject, lesson.teacher, lesson.room].map((value) => value.trim()).filter(Boolean).join(" \xB7 ");
|
|
38
|
+
}
|
|
39
|
+
function text(value) {
|
|
40
|
+
return typeof value === "string" || typeof value === "number" ? String(value) : "";
|
|
41
|
+
}
|
|
42
|
+
function firstName(value, long = false) {
|
|
43
|
+
var _a, _b;
|
|
44
|
+
if (!Array.isArray(value) || !value.length || typeof value[0] !== "object" || value[0] === null) {
|
|
45
|
+
return "";
|
|
46
|
+
}
|
|
47
|
+
const item = value[0];
|
|
48
|
+
return text((_b = (_a = item[long ? "longname" : "name"]) != null ? _a : item.longName) != null ? _b : item.name);
|
|
49
|
+
}
|
|
50
|
+
function dateString(value) {
|
|
51
|
+
const raw = text(value);
|
|
52
|
+
if (/^\d{8}$/.test(raw)) {
|
|
53
|
+
return `${raw.slice(0, 4)}-${raw.slice(4, 6)}-${raw.slice(6)}`;
|
|
54
|
+
}
|
|
55
|
+
return raw;
|
|
56
|
+
}
|
|
57
|
+
function timeString(value) {
|
|
58
|
+
const raw = text(value).padStart(4, "0");
|
|
59
|
+
return /^\d{4}$/.test(raw) ? `${raw.slice(0, 2)}:${raw.slice(2)}` : text(value);
|
|
60
|
+
}
|
|
61
|
+
function bool(value) {
|
|
62
|
+
return value === true || value === 1 || value === "1" || value === "true";
|
|
63
|
+
}
|
|
64
|
+
function stableId(period) {
|
|
65
|
+
var _a, _b;
|
|
66
|
+
const id = (_b = (_a = period.id) != null ? _a : period.lessonId) != null ? _b : period.periodId;
|
|
67
|
+
if (typeof id === "number" || typeof id === "string") {
|
|
68
|
+
return `period-${id}`;
|
|
69
|
+
}
|
|
70
|
+
const key = [period.date, period.startTime, period.endTime, firstName(period.su), firstName(period.kl)].join("|");
|
|
71
|
+
return `period-${(0, import_node_crypto.createHash)("sha1").update(key).digest("hex").slice(0, 16)}`;
|
|
72
|
+
}
|
|
73
|
+
function normalizeLesson(period) {
|
|
74
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
75
|
+
const substitution = text((_b = (_a = period.substText) != null ? _a : period.substitution) != null ? _b : period.subst);
|
|
76
|
+
const cancelled = bool((_d = (_c = period.cancelled) != null ? _c : period.isCancelled) != null ? _d : period.cancelledLesson);
|
|
77
|
+
const changed = cancelled || Boolean(substitution) || Boolean((_f = (_e = period.substTeacher) != null ? _e : period.substRoom) != null ? _f : period.substSubject);
|
|
78
|
+
return {
|
|
79
|
+
id: stableId(period),
|
|
80
|
+
date: dateString(period.date),
|
|
81
|
+
startTime: timeString(period.startTime),
|
|
82
|
+
endTime: timeString(period.endTime),
|
|
83
|
+
subject: firstName(period.su),
|
|
84
|
+
subjectLong: firstName(period.su, true),
|
|
85
|
+
teacher: firstName(period.te),
|
|
86
|
+
room: firstName(period.ro),
|
|
87
|
+
class: firstName(period.kl),
|
|
88
|
+
lessonId: typeof period.id === "number" ? period.id : null,
|
|
89
|
+
periodId: typeof period.periodId === "number" ? period.periodId : null,
|
|
90
|
+
status: text((_g = period.activityType) != null ? _g : period.status),
|
|
91
|
+
changed,
|
|
92
|
+
cancelled,
|
|
93
|
+
substitution,
|
|
94
|
+
originalTeacher: firstName((_h = period.origTe) != null ? _h : period.originalTeacher),
|
|
95
|
+
originalRoom: firstName((_i = period.origRo) != null ? _i : period.originalRoom),
|
|
96
|
+
originalSubject: firstName((_j = period.origSu) != null ? _j : period.originalSubject)
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function resolveReferences(value, masterData) {
|
|
100
|
+
if (!Array.isArray(value)) {
|
|
101
|
+
return value;
|
|
102
|
+
}
|
|
103
|
+
const byId = new Map(
|
|
104
|
+
masterData.flatMap((item) => {
|
|
105
|
+
var _a;
|
|
106
|
+
const id = (_a = item.id) != null ? _a : item.elementId;
|
|
107
|
+
return typeof id === "string" || typeof id === "number" ? [[String(id), item]] : [];
|
|
108
|
+
})
|
|
109
|
+
);
|
|
110
|
+
return value.map((item) => {
|
|
111
|
+
if (typeof item !== "object" || item === null) {
|
|
112
|
+
return item;
|
|
113
|
+
}
|
|
114
|
+
const id = item.id;
|
|
115
|
+
return byId.get(String(id)) || item;
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
function resolveTimetableReferences(periods, masterData) {
|
|
119
|
+
return periods.map((period) => ({
|
|
120
|
+
...period,
|
|
121
|
+
kl: resolveReferences(period.kl, masterData.klassen),
|
|
122
|
+
te: resolveReferences(period.te, masterData.teachers),
|
|
123
|
+
su: resolveReferences(period.su, masterData.subjects),
|
|
124
|
+
ro: resolveReferences(period.ro, masterData.rooms),
|
|
125
|
+
origTe: resolveReferences(period.origTe, masterData.teachers),
|
|
126
|
+
origRo: resolveReferences(period.origRo, masterData.rooms),
|
|
127
|
+
origSu: resolveReferences(period.origSu, masterData.subjects)
|
|
128
|
+
}));
|
|
129
|
+
}
|
|
130
|
+
function normalizeLessons(periods) {
|
|
131
|
+
return periods.map(normalizeLesson).sort((a, b) => `${a.date}${a.startTime}${a.id}`.localeCompare(`${b.date}${b.startTime}${b.id}`));
|
|
132
|
+
}
|
|
133
|
+
function durationMinutes(startTime, endTime) {
|
|
134
|
+
const start = /^([0-9]{2}):([0-9]{2})$/.exec(startTime);
|
|
135
|
+
const end = /^([0-9]{2}):([0-9]{2})$/.exec(endTime);
|
|
136
|
+
if (!start || !end) {
|
|
137
|
+
return 0;
|
|
138
|
+
}
|
|
139
|
+
const startMinutes = Number(start[1]) * 60 + Number(start[2]);
|
|
140
|
+
const endMinutes = Number(end[1]) * 60 + Number(end[2]);
|
|
141
|
+
return Math.max(0, endMinutes - startMinutes);
|
|
142
|
+
}
|
|
143
|
+
function summarizeTimetable(lessons) {
|
|
144
|
+
var _a, _b, _c, _d, _e, _f;
|
|
145
|
+
const subjects = lessons.map((lesson) => lesson.subjectLong || lesson.subject).filter((subject, index, values) => subject !== "" && values.indexOf(subject) === index);
|
|
146
|
+
return {
|
|
147
|
+
hasSchool: lessons.length > 0,
|
|
148
|
+
lessonCount: lessons.length,
|
|
149
|
+
// Cancelled lessons count as periods but have no actual teaching duration.
|
|
150
|
+
lessonDurationMinutes: lessons.reduce(
|
|
151
|
+
(total, lesson) => total + (lesson.cancelled ? 0 : durationMinutes(lesson.startTime, lesson.endTime)),
|
|
152
|
+
0
|
|
153
|
+
),
|
|
154
|
+
schoolStart: ((_a = lessons[0]) == null ? void 0 : _a.startTime) || "",
|
|
155
|
+
schoolEnd: ((_b = lessons.at(-1)) == null ? void 0 : _b.endTime) || "",
|
|
156
|
+
subjects: subjects.join(", "),
|
|
157
|
+
subjectCount: subjects.length,
|
|
158
|
+
firstSubject: ((_c = lessons[0]) == null ? void 0 : _c.subjectLong) || ((_d = lessons[0]) == null ? void 0 : _d.subject) || "",
|
|
159
|
+
lastSubject: ((_e = lessons.at(-1)) == null ? void 0 : _e.subjectLong) || ((_f = lessons.at(-1)) == null ? void 0 : _f.subject) || "",
|
|
160
|
+
hasChanges: lessons.some((lesson) => lesson.changed || Boolean(lesson.substitution)),
|
|
161
|
+
changeCount: lessons.filter((lesson) => lesson.changed || Boolean(lesson.substitution)).length,
|
|
162
|
+
cancellationCount: lessons.filter((lesson) => lesson.cancelled).length
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function dateNumber(date) {
|
|
166
|
+
return Number(
|
|
167
|
+
`${date.getFullYear()}${String(date.getMonth() + 1).padStart(2, "0")}${String(date.getDate()).padStart(2, "0")}`
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
function dayRange(date) {
|
|
171
|
+
return { startDate: dateNumber(date), endDate: dateNumber(date) };
|
|
172
|
+
}
|
|
173
|
+
function weekRange(date) {
|
|
174
|
+
const start = new Date(date);
|
|
175
|
+
start.setDate(start.getDate() - start.getDay() + 1);
|
|
176
|
+
const end = new Date(start);
|
|
177
|
+
end.setDate(start.getDate() + 4);
|
|
178
|
+
return { startDate: dateNumber(start), endDate: dateNumber(end) };
|
|
179
|
+
}
|
|
180
|
+
function splitTimetable(lessons, today) {
|
|
181
|
+
const todayKey = dateNumber(today).toString();
|
|
182
|
+
const tomorrow = new Date(today);
|
|
183
|
+
tomorrow.setDate(today.getDate() + 1);
|
|
184
|
+
const tomorrowKey = dateNumber(tomorrow).toString();
|
|
185
|
+
const dateKey = (value) => value.replaceAll("-", "");
|
|
186
|
+
return {
|
|
187
|
+
today: lessons.filter((lesson) => dateKey(lesson.date) === todayKey),
|
|
188
|
+
tomorrow: lessons.filter((lesson) => dateKey(lesson.date) === tomorrowKey),
|
|
189
|
+
week: lessons
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function assertTimetableResponse(value) {
|
|
193
|
+
if (!Array.isArray(value) || !value.every((period) => typeof period === "object" && period !== null)) {
|
|
194
|
+
throw new import_WebUntisErrors.WebUntisError("INVALID_RESPONSE", "Invalid WebUntis timetable result");
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
198
|
+
0 && (module.exports = {
|
|
199
|
+
assertTimetableResponse,
|
|
200
|
+
dateNumber,
|
|
201
|
+
dayRange,
|
|
202
|
+
lessonChannelName,
|
|
203
|
+
normalizeLesson,
|
|
204
|
+
normalizeLessons,
|
|
205
|
+
resolveTimetableReferences,
|
|
206
|
+
splitTimetable,
|
|
207
|
+
summarizeTimetable,
|
|
208
|
+
weekRange
|
|
209
|
+
});
|
|
210
|
+
//# sourceMappingURL=Timetable.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/lib/webuntis/Timetable.ts"],
|
|
4
|
+
"sourcesContent": ["/* eslint-disable jsdoc/require-jsdoc, jsdoc/require-param, jsdoc/no-blank-blocks */\n\nimport { createHash } from \"node:crypto\";\nimport { WebUntisError } from \"./WebUntisErrors\";\nimport type { WebUntisPeriod } from \"./WebUntisTypes\";\n\n/**\n *\n */\nexport interface TimetableLesson {\n\t/**\n\t *\n\t */\n\tid: string;\n\t/**\n\t *\n\t */\n\tdate: string;\n\t/**\n\t *\n\t */\n\tstartTime: string;\n\t/**\n\t *\n\t */\n\tendTime: string;\n\t/**\n\t *\n\t */\n\tsubject: string;\n\t/**\n\t *\n\t */\n\tsubjectLong: string;\n\t/**\n\t *\n\t */\n\tteacher: string;\n\t/**\n\t *\n\t */\n\troom: string;\n\t/**\n\t *\n\t */\n\tclass: string;\n\t/**\n\t *\n\t */\n\tlessonId: number | null;\n\t/**\n\t *\n\t */\n\tperiodId: number | null;\n\t/**\n\t *\n\t */\n\tstatus: string;\n\t/**\n\t *\n\t */\n\tchanged: boolean;\n\t/**\n\t *\n\t */\n\tcancelled: boolean;\n\t/**\n\t *\n\t */\n\tsubstitution: string;\n\t/**\n\t *\n\t */\n\toriginalTeacher: string;\n\t/**\n\t *\n\t */\n\toriginalRoom: string;\n\t/**\n\t *\n\t */\n\toriginalSubject: string;\n}\n\nexport interface TimetableSummary {\n\thasSchool: boolean;\n\tlessonCount: number;\n\tlessonDurationMinutes: number;\n\tschoolStart: string;\n\tschoolEnd: string;\n\tsubjects: string;\n\tsubjectCount: number;\n\tfirstSubject: string;\n\tlastSubject: string;\n\thasChanges: boolean;\n\tchangeCount: number;\n\tcancellationCount: number;\n}\n\nexport interface TimetableMasterData {\n\tsubjects: WebUntisPeriod[];\n\tteachers: WebUntisPeriod[];\n\trooms: WebUntisPeriod[];\n\tklassen: WebUntisPeriod[];\n}\n\nexport function lessonChannelName(lesson: TimetableLesson): string {\n\tconst time =\n\t\tlesson.startTime && lesson.endTime\n\t\t\t? `${lesson.startTime}\u2013${lesson.endTime}`\n\t\t\t: lesson.startTime || lesson.endTime;\n\treturn [time, lesson.subjectLong || lesson.subject, lesson.teacher, lesson.room]\n\t\t.map(value => value.trim())\n\t\t.filter(Boolean)\n\t\t.join(\" \u00B7 \");\n}\n\nfunction text(value: unknown): string {\n\treturn typeof value === \"string\" || typeof value === \"number\" ? String(value) : \"\";\n}\n\nfunction firstName(value: unknown, long = false): string {\n\tif (!Array.isArray(value) || !value.length || typeof value[0] !== \"object\" || value[0] === null) {\n\t\treturn \"\";\n\t}\n\tconst item = value[0] as Record<string, unknown>;\n\treturn text(item[long ? \"longname\" : \"name\"] ?? item.longName ?? item.name);\n}\n\nfunction dateString(value: unknown): string {\n\tconst raw = text(value);\n\tif (/^\\d{8}$/.test(raw)) {\n\t\treturn `${raw.slice(0, 4)}-${raw.slice(4, 6)}-${raw.slice(6)}`;\n\t}\n\treturn raw;\n}\n\nfunction timeString(value: unknown): string {\n\tconst raw = text(value).padStart(4, \"0\");\n\treturn /^\\d{4}$/.test(raw) ? `${raw.slice(0, 2)}:${raw.slice(2)}` : text(value);\n}\n\nfunction bool(value: unknown): boolean {\n\treturn value === true || value === 1 || value === \"1\" || value === \"true\";\n}\n\nfunction stableId(period: WebUntisPeriod): string {\n\tconst id = period.id ?? period.lessonId ?? period.periodId;\n\tif (typeof id === \"number\" || typeof id === \"string\") {\n\t\treturn `period-${id}`;\n\t}\n\tconst key = [period.date, period.startTime, period.endTime, firstName(period.su), firstName(period.kl)].join(\"|\");\n\treturn `period-${createHash(\"sha1\").update(key).digest(\"hex\").slice(0, 16)}`;\n}\n\n/**\n *\n */\nexport function normalizeLesson(period: WebUntisPeriod): TimetableLesson {\n\tconst substitution = text(period.substText ?? period.substitution ?? period.subst);\n\tconst cancelled = bool(period.cancelled ?? period.isCancelled ?? period.cancelledLesson);\n\tconst changed =\n\t\tcancelled || Boolean(substitution) || Boolean(period.substTeacher ?? period.substRoom ?? period.substSubject);\n\treturn {\n\t\tid: stableId(period),\n\t\tdate: dateString(period.date),\n\t\tstartTime: timeString(period.startTime),\n\t\tendTime: timeString(period.endTime),\n\t\tsubject: firstName(period.su),\n\t\tsubjectLong: firstName(period.su, true),\n\t\tteacher: firstName(period.te),\n\t\troom: firstName(period.ro),\n\t\tclass: firstName(period.kl),\n\t\tlessonId: typeof period.id === \"number\" ? period.id : null,\n\t\tperiodId: typeof period.periodId === \"number\" ? period.periodId : null,\n\t\tstatus: text(period.activityType ?? period.status),\n\t\tchanged,\n\t\tcancelled,\n\t\tsubstitution,\n\t\toriginalTeacher: firstName(period.origTe ?? period.originalTeacher),\n\t\toriginalRoom: firstName(period.origRo ?? period.originalRoom),\n\t\toriginalSubject: firstName(period.origSu ?? period.originalSubject),\n\t};\n}\n\nfunction resolveReferences(value: unknown, masterData: WebUntisPeriod[]): unknown {\n\tif (!Array.isArray(value)) {\n\t\treturn value;\n\t}\n\tconst byId = new Map(\n\t\tmasterData.flatMap(item => {\n\t\t\tconst id = item.id ?? item.elementId;\n\t\t\treturn typeof id === \"string\" || typeof id === \"number\" ? [[String(id), item] as const] : [];\n\t\t}),\n\t);\n\treturn value.map(item => {\n\t\tif (typeof item !== \"object\" || item === null) {\n\t\t\treturn item;\n\t\t}\n\t\tconst id = (item as Record<string, unknown>).id;\n\t\treturn byId.get(String(id)) || item;\n\t});\n}\n\nexport function resolveTimetableReferences(\n\tperiods: WebUntisPeriod[],\n\tmasterData: TimetableMasterData,\n): WebUntisPeriod[] {\n\treturn periods.map(period => ({\n\t\t...period,\n\t\tkl: resolveReferences(period.kl, masterData.klassen),\n\t\tte: resolveReferences(period.te, masterData.teachers),\n\t\tsu: resolveReferences(period.su, masterData.subjects),\n\t\tro: resolveReferences(period.ro, masterData.rooms),\n\t\torigTe: resolveReferences(period.origTe, masterData.teachers),\n\t\torigRo: resolveReferences(period.origRo, masterData.rooms),\n\t\torigSu: resolveReferences(period.origSu, masterData.subjects),\n\t}));\n}\n\n/**\n *\n */\nexport function normalizeLessons(periods: WebUntisPeriod[]): TimetableLesson[] {\n\treturn periods\n\t\t.map(normalizeLesson)\n\t\t.sort((a, b) => `${a.date}${a.startTime}${a.id}`.localeCompare(`${b.date}${b.startTime}${b.id}`));\n}\n\nfunction durationMinutes(startTime: string, endTime: string): number {\n\tconst start = /^([0-9]{2}):([0-9]{2})$/.exec(startTime);\n\tconst end = /^([0-9]{2}):([0-9]{2})$/.exec(endTime);\n\tif (!start || !end) {\n\t\treturn 0;\n\t}\n\tconst startMinutes = Number(start[1]) * 60 + Number(start[2]);\n\tconst endMinutes = Number(end[1]) * 60 + Number(end[2]);\n\treturn Math.max(0, endMinutes - startMinutes);\n}\n\nexport function summarizeTimetable(lessons: TimetableLesson[]): TimetableSummary {\n\tconst subjects = lessons\n\t\t.map(lesson => lesson.subjectLong || lesson.subject)\n\t\t.filter((subject, index, values) => subject !== \"\" && values.indexOf(subject) === index);\n\treturn {\n\t\thasSchool: lessons.length > 0,\n\t\tlessonCount: lessons.length,\n\t\t// Cancelled lessons count as periods but have no actual teaching duration.\n\t\tlessonDurationMinutes: lessons.reduce(\n\t\t\t(total, lesson) => total + (lesson.cancelled ? 0 : durationMinutes(lesson.startTime, lesson.endTime)),\n\t\t\t0,\n\t\t),\n\t\tschoolStart: lessons[0]?.startTime || \"\",\n\t\tschoolEnd: lessons.at(-1)?.endTime || \"\",\n\t\tsubjects: subjects.join(\", \"),\n\t\tsubjectCount: subjects.length,\n\t\tfirstSubject: lessons[0]?.subjectLong || lessons[0]?.subject || \"\",\n\t\tlastSubject: lessons.at(-1)?.subjectLong || lessons.at(-1)?.subject || \"\",\n\t\thasChanges: lessons.some(lesson => lesson.changed || Boolean(lesson.substitution)),\n\t\tchangeCount: lessons.filter(lesson => lesson.changed || Boolean(lesson.substitution)).length,\n\t\tcancellationCount: lessons.filter(lesson => lesson.cancelled).length,\n\t};\n}\n\n/**\n *\n */\nexport function dateNumber(date: Date): number {\n\treturn Number(\n\t\t`${date.getFullYear()}${String(date.getMonth() + 1).padStart(2, \"0\")}${String(date.getDate()).padStart(2, \"0\")}`,\n\t);\n}\n\n/**\n *\n */\nexport function dayRange(date: Date): {\n\t/**\n\t *\n\t */\n\tstartDate: number;\n\t/**\n\t *\n\t */\n\tendDate: number;\n} {\n\treturn { startDate: dateNumber(date), endDate: dateNumber(date) };\n}\n\n/**\n *\n */\nexport function weekRange(date: Date): {\n\t/**\n\t *\n\t */\n\tstartDate: number;\n\t/**\n\t *\n\t */\n\tendDate: number;\n} {\n\tconst start = new Date(date);\n\tstart.setDate(start.getDate() - start.getDay() + 1);\n\tconst end = new Date(start);\n\tend.setDate(start.getDate() + 4);\n\treturn { startDate: dateNumber(start), endDate: dateNumber(end) };\n}\n\n/**\n *\n */\nexport function splitTimetable(\n\tlessons: TimetableLesson[],\n\ttoday: Date,\n): {\n\t/**\n\t *\n\t */\n\ttoday: TimetableLesson[];\n\t/**\n\t *\n\t */\n\ttomorrow: TimetableLesson[];\n\t/**\n\t *\n\t */\n\tweek: TimetableLesson[];\n} {\n\tconst todayKey = dateNumber(today).toString();\n\tconst tomorrow = new Date(today);\n\ttomorrow.setDate(today.getDate() + 1);\n\tconst tomorrowKey = dateNumber(tomorrow).toString();\n\tconst dateKey = (value: string): string => value.replaceAll(\"-\", \"\");\n\treturn {\n\t\ttoday: lessons.filter(lesson => dateKey(lesson.date) === todayKey),\n\t\ttomorrow: lessons.filter(lesson => dateKey(lesson.date) === tomorrowKey),\n\t\tweek: lessons,\n\t};\n}\n\n/**\n *\n */\nexport function assertTimetableResponse(value: unknown): asserts value is WebUntisPeriod[] {\n\tif (!Array.isArray(value) || !value.every(period => typeof period === \"object\" && period !== null)) {\n\t\tthrow new WebUntisError(\"INVALID_RESPONSE\", \"Invalid WebUntis timetable result\");\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|