@royalschedule/maps 4.0.31 → 4.0.33
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/dist/Additio/from/courses.js.map +1 -1
- package/dist/Additio/from/events.js.map +1 -1
- package/dist/Additio/from/groups.js.map +1 -1
- package/dist/Additio/from/index.js.map +1 -1
- package/dist/Additio/from/locations.js.map +1 -1
- package/dist/Additio/from/persons.js.map +1 -1
- package/dist/Additio/from/schedules.d.ts +1 -0
- package/dist/Additio/from/schedules.js +2 -4
- package/dist/Additio/from/schedules.js.map +1 -1
- package/dist/Additio/from/teachers.js.map +1 -1
- package/dist/Additio/to/index.d.ts +4 -2
- package/dist/Additio/to/schedules.js +2 -4
- package/dist/Additio/to/schedules.js.map +1 -1
- package/dist/Admentum/from/courses.js.map +1 -1
- package/dist/Admentum/from/events.js.map +1 -1
- package/dist/Admentum/from/groups.js.map +1 -1
- package/dist/Admentum/from/index.js.map +1 -1
- package/dist/Admentum/from/locations.js.map +1 -1
- package/dist/Admentum/from/persons.js.map +1 -1
- package/dist/Admentum/from/schedules.d.ts +1 -0
- package/dist/Admentum/from/schedules.js +3 -6
- package/dist/Admentum/from/schedules.js.map +1 -1
- package/dist/Admentum/from/teachers.js.map +1 -1
- package/dist/Admentum/to/index.d.ts +1 -0
- package/dist/Admentum/to/schedules.js +4 -7
- package/dist/Admentum/to/schedules.js.map +1 -1
- package/dist/Excel/index.d.ts +1 -0
- package/dist/Excel/v1/from/index.js +1 -1
- package/dist/Excel/v1/from/index.js.map +1 -1
- package/dist/Excel/v1/index.d.ts +4 -3
- package/dist/Excel/v2/from/index.js +45 -54
- package/dist/Excel/v2/from/index.js.map +1 -1
- package/dist/Excel/v2/index.d.ts +4 -3
- package/dist/IdunSoft/from/courses.js.map +1 -1
- package/dist/IdunSoft/from/events.js +1 -2
- package/dist/IdunSoft/from/events.js.map +1 -1
- package/dist/IdunSoft/from/groups.js.map +1 -1
- package/dist/IdunSoft/from/index.js.map +1 -1
- package/dist/IdunSoft/from/locations.js.map +1 -1
- package/dist/IdunSoft/from/schedules.d.ts +1 -0
- package/dist/IdunSoft/from/schedules.js.map +1 -1
- package/dist/IdunSoft/from/teachers.js.map +1 -1
- package/dist/IdunSoft/to/index.d.ts +1 -0
- package/dist/IdunSoft/to/schedules.js +3 -6
- package/dist/IdunSoft/to/schedules.js.map +1 -1
- package/dist/InfoMentor/to/index.d.ts +1 -0
- package/dist/InfoMentor/to/schedules.js +1 -2
- package/dist/InfoMentor/to/schedules.js.map +1 -1
- package/dist/PlanDigital/from/index.js.map +1 -1
- package/dist/PlanDigital/from/schedules.js +9 -11
- package/dist/PlanDigital/from/schedules.js.map +1 -1
- package/dist/PlanDigital/index.d.ts +1 -0
- package/dist/Quiculum/file/to/index.d.ts +1 -0
- package/dist/Quiculum/file/to/schedules.js +5 -9
- package/dist/Quiculum/file/to/schedules.js.map +1 -1
- package/dist/RS/from/division.d.ts +1 -0
- package/dist/RS/from/division.js +1 -2
- package/dist/RS/from/division.js.map +1 -1
- package/dist/RS/from/index.js.map +1 -1
- package/dist/RS/from/schedules.d.ts +1 -0
- package/dist/RS/from/schedules.js.map +1 -1
- package/dist/RS/make-connected.d.ts +3 -1
- package/dist/RS/make-connected.js +34 -42
- package/dist/RS/make-connected.js.map +1 -1
- package/dist/RS/to/index.js.map +1 -1
- package/dist/RS/to/initial-configuration.js +4 -6
- package/dist/RS/to/initial-configuration.js.map +1 -1
- package/dist/RS/to/input/collections.js.map +1 -1
- package/dist/RS/to/input/default.js +1 -2
- package/dist/RS/to/input/default.js.map +1 -1
- package/dist/RS/to/input/dependencies.js +1 -2
- package/dist/RS/to/input/dependencies.js.map +1 -1
- package/dist/RS/to/input/dynamic-locked-times.js +1 -2
- package/dist/RS/to/input/dynamic-locked-times.js.map +1 -1
- package/dist/RS/to/input/events.js.map +1 -1
- package/dist/RS/to/input/groups.js.map +1 -1
- package/dist/RS/to/input/individuals.js +1 -2
- package/dist/RS/to/input/individuals.js.map +1 -1
- package/dist/RS/to/input/input.js +1 -2
- package/dist/RS/to/input/input.js.map +1 -1
- package/dist/RS/to/input/intervals.js +2 -4
- package/dist/RS/to/input/intervals.js.map +1 -1
- package/dist/RS/to/input/periods.js +2 -4
- package/dist/RS/to/input/periods.js.map +1 -1
- package/dist/RS/to/input/settings.js.map +1 -1
- package/dist/RS/to/input/teachers.js +1 -1
- package/dist/RS/to/input/teachers.js.map +1 -1
- package/dist/RS/to/input/util/attach-locked-times.js.map +1 -1
- package/dist/RS/to/input/util/parse-days.js.map +1 -1
- package/dist/RS/to/input/util/parse-group-references.js.map +1 -1
- package/dist/RS/to/input/util/parse-intervals.js +2 -4
- package/dist/RS/to/input/util/parse-intervals.js.map +1 -1
- package/dist/RS/to/input/util/parse-location-references.js +1 -2
- package/dist/RS/to/input/util/parse-location-references.js.map +1 -1
- package/dist/RS/to/input/util/parse-max-working-hours.js.map +1 -1
- package/dist/RS/to/input/util/parse-minimum-break-length.js.map +1 -1
- package/dist/RS/to/input/util/util.js +1 -2
- package/dist/RS/to/input/util/util.js.map +1 -1
- package/dist/RS/to/schedules.js.map +1 -1
- package/dist/RS/types/to.d.ts +1 -0
- package/dist/SS12000/from/activities.js +1 -2
- package/dist/SS12000/from/activities.js.map +1 -1
- package/dist/SS12000/from/calendar-events.js.map +1 -1
- package/dist/SS12000/from/duties.js.map +1 -1
- package/dist/SS12000/from/groups.js.map +1 -1
- package/dist/SS12000/from/index.js.map +1 -1
- package/dist/SS12000/from/persons.js.map +1 -1
- package/dist/SS12000/from/resources.js.map +1 -1
- package/dist/SS12000/from/rooms.js.map +1 -1
- package/dist/SS12000/from/syllabuses.js.map +1 -1
- package/dist/SS12000/index.d.ts +41 -6
- package/dist/SS12000/to/activities.js.map +1 -1
- package/dist/SS12000/to/calendar-events.js.map +1 -1
- package/dist/SS12000/to/common.js.map +1 -1
- package/dist/SS12000/to/duties.js.map +1 -1
- package/dist/SS12000/to/groups.js.map +1 -1
- package/dist/SS12000/to/index.d.ts +1 -0
- package/dist/SS12000/to/persons.js.map +1 -1
- package/dist/SS12000/to/resources.js.map +1 -1
- package/dist/SS12000/to/rooms.js.map +1 -1
- package/dist/SS12000/to/syllabuses.js.map +1 -1
- package/dist/SchoolSoft/api/from/index.js.map +1 -1
- package/dist/SchoolSoft/api/from/schedules.js +8 -12
- package/dist/SchoolSoft/api/from/schedules.js.map +1 -1
- package/dist/SchoolSoft/api/index.d.ts +6 -5
- package/dist/SchoolSoft/file/from/index.js.map +1 -1
- package/dist/SchoolSoft/file/from/schedules.js +83 -87
- package/dist/SchoolSoft/file/from/schedules.js.map +1 -1
- package/dist/SchoolSoft/file/index.d.ts +1 -0
- package/dist/SchoolSoft/file/to/index.d.ts +3 -2
- package/dist/SchoolSoft/file/to/schedules.js +1 -2
- package/dist/SchoolSoft/file/to/schedules.js.map +1 -1
- package/dist/SchoolSoft/index.d.ts +1 -0
- package/dist/Schoolity/txt/to/index.d.ts +1 -0
- package/dist/Schoolity/txt/to/schedules.js +5 -12
- package/dist/Schoolity/txt/to/schedules.js.map +1 -1
- package/dist/Skola24/mdb/from/course-and-events.js +3 -5
- package/dist/Skola24/mdb/from/course-and-events.js.map +1 -1
- package/dist/Skola24/mdb/from/groups.js.map +1 -1
- package/dist/Skola24/mdb/from/index.js.map +1 -1
- package/dist/Skola24/mdb/from/locations.js.map +1 -1
- package/dist/Skola24/mdb/from/schedule.d.ts +1 -0
- package/dist/Skola24/mdb/from/schedule.js.map +1 -1
- package/dist/Skola24/mdb/from/teachers.js.map +1 -1
- package/dist/Skola24/txt/from/calendar-exceptions.js +1 -2
- package/dist/Skola24/txt/from/calendar-exceptions.js.map +1 -1
- package/dist/Skola24/txt/from/division.js.map +1 -1
- package/dist/Skola24/txt/from/index.js.map +1 -1
- package/dist/Skola24/txt/from/period.js +31 -34
- package/dist/Skola24/txt/from/period.js.map +1 -1
- package/dist/Skola24/txt/from/schedules.d.ts +1 -0
- package/dist/Skola24/txt/from/schedules.js +6 -10
- package/dist/Skola24/txt/from/schedules.js.map +1 -1
- package/dist/Skola24/txt/from/util.js.map +1 -1
- package/dist/Skola24/txt/index.d.ts +1 -0
- package/dist/Skola24/txt/to/index.d.ts +1 -0
- package/dist/Skola24/txt/to/schedules.js +5 -12
- package/dist/Skola24/txt/to/schedules.js.map +1 -1
- package/dist/common/constants.js.map +1 -1
- package/dist/common/functions.js.map +1 -1
- package/dist/common/get-date.js.map +1 -1
- package/dist/common/make-chainable/index.js.map +1 -1
- package/dist/common/types.d.ts +1 -3
- package/dist/core/from/configurations.js.map +1 -1
- package/dist/core/from/courses.js.map +1 -1
- package/dist/core/from/events.js.map +1 -1
- package/dist/core/from/exceptions.js.map +1 -1
- package/dist/core/from/groups.js.map +1 -1
- package/dist/core/from/index.js.map +1 -1
- package/dist/core/from/locations.js.map +1 -1
- package/dist/core/from/locked-times.js.map +1 -1
- package/dist/core/from/overlap-groups.js.map +1 -1
- package/dist/core/from/periods.js.map +1 -1
- package/dist/core/from/persons.js.map +1 -1
- package/dist/core/from/root-intervals.js.map +1 -1
- package/dist/core/from/schedules.js.map +1 -1
- package/dist/core/from/settings.js.map +1 -1
- package/dist/core/from/syllabuses.js.map +1 -1
- package/dist/core/from/teachers.js.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/interfaces/index.d.ts +23 -0
- package/dist/core/interfaces/other/companies.d.ts +1 -0
- package/dist/core/interfaces/other/companies.js.map +1 -1
- package/dist/core/interfaces/other/index.d.ts +6 -0
- package/dist/core/interfaces/other/operations.d.ts +1 -0
- package/dist/core/interfaces/vertices/companies.d.ts +1 -0
- package/dist/core/interfaces/vertices/configurations.d.ts +1 -0
- package/dist/core/interfaces/vertices/courses.d.ts +1 -0
- package/dist/core/interfaces/vertices/division-settings.d.ts +2 -0
- package/dist/core/interfaces/vertices/divisions.d.ts +1 -0
- package/dist/core/interfaces/vertices/events.d.ts +1 -0
- package/dist/core/interfaces/vertices/exceptions.d.ts +1 -0
- package/dist/core/interfaces/vertices/generations.d.ts +2 -0
- package/dist/core/interfaces/vertices/groups.d.ts +1 -0
- package/dist/core/interfaces/vertices/index.d.ts +1 -0
- package/dist/core/interfaces/vertices/locations.d.ts +1 -0
- package/dist/core/interfaces/vertices/locked-times.d.ts +2 -0
- package/dist/core/interfaces/vertices/overlap-groups.d.ts +1 -0
- package/dist/core/interfaces/vertices/periods.d.ts +3 -0
- package/dist/core/interfaces/vertices/persons.d.ts +1 -0
- package/dist/core/interfaces/vertices/properties/belongs-to.d.ts +1 -0
- package/dist/core/interfaces/vertices/properties/coalesced.d.ts +1 -0
- package/dist/core/interfaces/vertices/root-intervals.d.ts +2 -0
- package/dist/core/interfaces/vertices/syllabuses.d.ts +1 -0
- package/dist/core/interfaces/vertices/teachers.d.ts +1 -0
- package/dist/core/interfaces/vertices/threads.d.ts +6 -4
- package/dist/core/interfaces/vertices/users.d.ts +1 -0
- package/dist/core/interfaces/vertices/util/custom-vertex-export/index.d.ts +6 -6
- package/dist/core/interfaces/vertices/util/custom-vertex-export/util.d.ts +4 -4
- package/dist/core/interfaces/vertices/util/deep-vertex-export/index.d.ts +9 -9
- package/dist/core/interfaces/vertices/util/edges.d.ts +7 -7
- package/dist/core/interfaces/vertices/util/index.d.ts +6 -0
- package/dist/core/interfaces/vertices/util/util.d.ts +20 -24
- package/dist/core/interfaces/vertices/util/vertex-query/index.d.ts +11 -11
- package/dist/core/interfaces/vertices/util/vertex.d.ts +1 -1
- package/dist/core/interfaces/vertices/vertex-query.d.ts +27 -26
- package/dist/core/interfaces/vertices/vertex-query.js.map +1 -1
- package/dist/core/to/configurations.js +1 -2
- package/dist/core/to/configurations.js.map +1 -1
- package/dist/core/to/courses.js +1 -2
- package/dist/core/to/courses.js.map +1 -1
- package/dist/core/to/division.js.map +1 -1
- package/dist/core/to/events.js +1 -2
- package/dist/core/to/events.js.map +1 -1
- package/dist/core/to/exceptions.js +1 -2
- package/dist/core/to/exceptions.js.map +1 -1
- package/dist/core/to/groups.js +1 -2
- package/dist/core/to/groups.js.map +1 -1
- package/dist/core/to/locations.js +1 -2
- package/dist/core/to/locations.js.map +1 -1
- package/dist/core/to/locked-times.js +1 -2
- package/dist/core/to/locked-times.js.map +1 -1
- package/dist/core/to/overlap-groups.js +1 -2
- package/dist/core/to/overlap-groups.js.map +1 -1
- package/dist/core/to/periods.js +1 -2
- package/dist/core/to/periods.js.map +1 -1
- package/dist/core/to/persons.js +1 -2
- package/dist/core/to/persons.js.map +1 -1
- package/dist/core/to/root-intervals.js +1 -2
- package/dist/core/to/root-intervals.js.map +1 -1
- package/dist/core/to/schedules.d.ts +1 -0
- package/dist/core/to/schedules.js.map +1 -1
- package/dist/core/to/settings.js +1 -2
- package/dist/core/to/settings.js.map +1 -1
- package/dist/core/to/syllabuses.js +1 -2
- package/dist/core/to/syllabuses.js.map +1 -1
- package/dist/core/to/teachers.js +1 -2
- package/dist/core/to/teachers.js.map +1 -1
- package/dist/core/to/util.d.ts +2 -0
- package/dist/core/to/util.js +1 -2
- package/dist/core/to/util.js.map +1 -1
- package/dist/core/types/index.d.ts +6 -0
- package/dist/core/util.js +1 -2
- package/dist/core/util.js.map +1 -1
- package/dist/identify/constants/index.js.map +1 -1
- package/dist/identify/index.js +1 -2
- package/dist/identify/index.js.map +1 -1
- package/dist/sdui/from/classes.js.map +1 -1
- package/dist/sdui/from/courses.js.map +1 -1
- package/dist/sdui/from/holidays.js.map +1 -1
- package/dist/sdui/from/index.js.map +1 -1
- package/dist/sdui/from/lessons.js.map +1 -1
- package/dist/sdui/from/rooms.js.map +1 -1
- package/dist/sdui/from/schedules.d.ts +2 -0
- package/dist/sdui/from/schedules.js.map +1 -1
- package/dist/sdui/from/school-years.js.map +1 -1
- package/dist/sdui/from/substitution-plans.js.map +1 -1
- package/dist/sdui/from/teachers.js.map +1 -1
- package/dist/sdui/to/classes.js.map +1 -1
- package/dist/sdui/to/courses.js.map +1 -1
- package/dist/sdui/to/holidays.js.map +1 -1
- package/dist/sdui/to/hours.js.map +1 -1
- package/dist/sdui/to/index.d.ts +2 -0
- package/dist/sdui/to/lessons.js.map +1 -1
- package/dist/sdui/to/rooms.js.map +1 -1
- package/dist/sdui/to/schedules.js.map +1 -1
- package/dist/sdui/to/school-years.js.map +1 -1
- package/dist/sdui/to/substitution-plans.js +3 -6
- package/dist/sdui/to/substitution-plans.js.map +1 -1
- package/dist/sdui/to/teachers.js.map +1 -1
- package/dist/vKlass/from/index.js.map +1 -1
- package/dist/vKlass/from/schedule.d.ts +1 -0
- package/dist/vKlass/from/schedule.js.map +1 -1
- package/dist/vKlass/to/schedules.js +6 -17
- package/dist/vKlass/to/schedules.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"course-and-events.js","names":["weeks: number[]","matches: RegExpExecArray | null","intervals: CoreTypes.interval[]","courseMap: Map<number, OutTypes.course>","subject: string | undefined","event: OutTypes.event","l","classes: Set<string>","days: CoreTypes.day[]","idss: string[]","displayNames: string[]","groups","newCourse: OutTypes.course","x"],"sources":["../../../../src/Skola24/mdb/from/course-and-events.ts"],"sourcesContent":["import moment from 'moment';\nimport { uniqBy } from 'lodash-es';\nimport type { CoreTypes } from '../../../core';\nimport type { OutTypes } from './schedule';\nimport type { Types as Skal24Types } from '../types';\nimport type { BaseOptions } from '../../../common/types';\nimport { makeChainable } from '../../../common/make-chainable';\n\n\nconst separator = ', ';\nconst arbetstid = 'Arbetstid'.toLowerCase();\nconst firstDay = '1970-01-05';\nconst numDays = 5;\nconst defaultDayStart = [8, 0];\nconst defaultDayEnd = [17, 0];\n\nfunction generateDate (\n days: number,\n hours: number,\n minutes: number\n) {\n return moment.utc(firstDay)\n .add(days, 'days')\n .add(hours, 'hours')\n .add(minutes, 'minutes');\n}\n\nfunction startAndEnd (\n lesson: Skal24Types.lesson\n): undefined | { start: moment.Moment, end: moment.Moment, parked: false } {\n if ('Length' in lesson && 'DayOfWeek' in lesson && 'StartTime' in lesson) {\n const dateTimeDate = moment(lesson.StartTime, 'MM/DD/YY hh:mm:ss');\n const hours = dateTimeDate.get('hours');\n const minutes = dateTimeDate.get('minutes');\n\n // let start = moment.utc(firstDay)\n // .add(lesson.DayOfWeek, \"days\")\n // .add(hours, \"hours\")\n // .add(minutes, \"minutes\");\n const start = generateDate(lesson.DayOfWeek!, hours, minutes);\n const end = start.clone().add(lesson.Length, 'minute');\n return { start: start, end: end, parked: false };\n }\n\n return;\n}\n\nfunction parseActualWeeks (val?: string) {\n if (!val) return [];\n\n const weeks: number[] = [];\n\n val\n .split(',')\n .forEach(x => {\n if (x.includes('-')) {\n // multiple weeks\n const [start, end] = x.split('-');\n for (let i = parseInt(start); i <= parseInt(end); i++)\n weeks.push(i);\n } else {\n // single week\n weeks.push(parseInt(x));\n }\n });\n\n return weeks;\n}\n\nfunction addGroupsFromName (\n name: string,\n groupSet: Set<string>,\n groupNamePkMap: Map<string, string>\n) {\n // assumes course names of the type \"10IDS01-EK20C-LAG\"\n const regex = /-([^\\s-]+)/gi;\n\n let matches: RegExpExecArray | null;\n while ((matches = regex.exec(name)) !== null) {\n if (groupNamePkMap.has(matches[1])) {\n const PK = groupNamePkMap.get(matches[1])!;\n groupSet.add(PK);\n }\n }\n}\n\nfunction getDay (mnt: moment.Moment) {\n return mnt.dayOfYear() - moment.utc(firstDay).dayOfYear();\n}\n\nfunction createDefaultIntervals () {\n const intervals: CoreTypes.interval[] = [];\n\n for (let d = 0; d < numDays; d++) {\n intervals.push({\n start: generateDate(d, defaultDayStart[0], defaultDayStart[1]),\n end: generateDate(d, defaultDayEnd[0], defaultDayEnd[1])\n });\n }\n\n return intervals;\n}\n\n\n\n\nexport default function (\n groups: Skal24Types.group[],\n lessons: Skal24Types.lesson[],\n meta: Skal24Types.options & BaseOptions | undefined,\n\n groupPlansMap: Map<number, Set<string> >,\n planMap: Map<number, Skal24Types.plan>,\n\n subjectMap: Map<number, string>,\n planTeachersMap: Map<number, Set<string> >,\n groupClassesMap: Map<string, Set<string> >,\n RSgroups: OutTypes.group[],\n\n groupMap: Map<number, Skal24Types.group>,\n lessonRoomsMap: Map<number, Set<string> >,\n lessonTeachersMap: Map<number, Set<string> >,\n lessonGroupsMap: Map<number, Set<string> >,\n RSteachers: OutTypes.teacher[],\n\n warnings: string[],\n errors: string[]\n): { courses: OutTypes.course[], events: OutTypes.event[] } {\n\n // used when deducing groups from the course name\n const groupNamePkMap = new Map(RSgroups.map(g => [g.displayName!, g.ids!]));\n\n ////\n //// courses\n ////\n let courseMap: Map<number, OutTypes.course> = new Map();\n groups.forEach(x => {\n // need to be a scheduled group\n if (x.bClass) return;\n\n // check if at least one plan intersects our period\n const plans = groupPlansMap.get(x.PK);\n\n // fetch subject via first plan\n let subject: string | undefined;\n if (plans) {\n const subjPK = planMap.get(parseInt([...plans][0]))?.FKSubject;\n if (subjPK) subject = subjectMap.get(subjPK);\n }\n // if (subject) console.log(subject)\n\n const groupSet = groupClassesMap.get(x.PK.toString()) ?? new Set<string>();\n\n // attempt to deduce groups by analyzing the course name\n if (meta?.deduceGroupsFromCourseName && x.ID) {\n addGroupsFromName(x.ID, groupSet, groupNamePkMap);\n }\n\n\n\n // if (groups) console.log(groups)\n\n const teacherSet = new Set<string>();\n groupPlansMap.get(x.PK)?.forEach(p => {\n planTeachersMap.get(parseInt(p))?.forEach(t => teacherSet.add(t));\n });\n // if (teacherSet) console.log(teacherSet)\n\n\n courseMap.set(x.PK, {\n ids: x.PK.toString(),\n displayName: x.ID,\n\n ...( subject && { subject } ),\n ...( groupSet?.size && { groups: [...groupSet ].map(to => ({ to })) } ),\n ...( teacherSet.size && { teachers: [...teacherSet].map(to => ({ to })) } )\n });\n });\n\n\n\n ////\n //// events\n ////\n let numAdditionalCourses = 0;\n const eventMap = new Map<string, OutTypes.event[]>();\n const intervalMap = new Map<string, Map<number, CoreTypes.interval> >();\n lessons.forEach(l => {\n // ignore all lessons which are not scheduled on the week of interest\n if (meta?.week == undefined || !parseActualWeeks(l.CalcActualWeeks).includes(meta.week)) return;\n\n\n const coursesIds = [...(lessonGroupsMap.get(l.PK) ?? new Set())]\n .map(id => groupMap.get(parseInt(id)))\n .filter((g): g is NonNullable<typeof g> => g?.bClass == false)\n .sort((g1, g2) => g1.PK - g2.PK)\n .map(g => g.PK);\n\n const event: OutTypes.event = {\n ids: l.PK.toString(),\n\n duration: l.Length,\n preferredDuration: l.Length,\n ...startAndEnd(l)\n };\n\n // try add room\n const rooms = lessonRoomsMap.get(l.PK);\n if (rooms?.size) {\n event.inLocations = [...rooms];\n event.locations = [...rooms].map(l => ({ locations: [l] }));\n }\n\n // try add teachers\n const teachers = lessonTeachersMap.get(l.PK);\n if (teachers?.size) event.teachers = [...teachers].map(to => ({ to }));\n\n // fetch groups\n const classes: Set<string> = new Set();\n lessonGroupsMap.get(l.PK)?.forEach(scheduleGroupId => {\n groupClassesMap.get(scheduleGroupId)?.forEach(classId => {\n classes.add(classId);\n });\n });\n\n // attempt to deduce groups by analyzing the course name\n // (but only if the event explicitly has groups or its course has none)\n const courseHasGroups = coursesIds.some(x => courseMap.get(x)?.groups);\n if (meta?.deduceGroupsFromCourseName && (!courseHasGroups || classes.size)) {\n coursesIds.map(x => courseMap.get(x)?.displayName)\n .filter(x => x != null)\n .forEach(x => addGroupsFromName(x, classes, groupNamePkMap));\n }\n\n // try add groups\n if (classes.size) event.groups = [...classes].map(to => ({ to }));\n\n\n const subject = subjectMap.get(l.FKSubject!);\n if (subject?.toLowerCase() == arbetstid) {\n // is an interval\n\n // ensure start and end is set\n const start = event.start;\n const end = event.end;\n if (!start || !end) {\n warnings.push('Start or end not set on interval event');\n return;\n }\n\n // interval day\n const day = getDay(moment.utc(start));\n\n if (0 > day || day > numDays - 1) {\n warnings.push('Interval day out of bounds');\n return;\n }\n\n // add interval\n teachers?.forEach(t => {\n if (!intervalMap.has(t)) intervalMap.set(t, new Map());\n intervalMap.get(t)?.set(day, { start, end });\n });\n\n } else {\n // is an event\n\n ////\n //// if there is no course, create it\n //// (can also be interval)\n ////\n if (!coursesIds.length) {\n const id = --numAdditionalCourses;\n\n courseMap.set(id, {\n ids: id.toString(),\n\n ...( subject && { displayName: subject } ),\n ...( subject && { subject } ),\n\n // // makes it easier to se in the table\n // ...( teachers?.size && { teachers: [...teachers] } ),\n // ...( classes?.size && { groups: [...classes] } ),\n });\n\n coursesIds.push(id);\n }\n\n\n // add\n const key = coursesIds.join(separator);\n if (!eventMap.has(key)) eventMap.set(key, []);\n eventMap.get(key)?.push(event);\n }\n\n });\n\n\n ////\n //// set teacher days and intervals\n ////\n intervalMap.forEach((v, k) => {\n // fetch teacher\n const teacher = RSteachers.find(t => t.ids == k);\n if (!teacher) {\n warnings.push(`An interval referred to the unknown teacher with PK = ${k}`);\n return;\n }\n\n // construct\n const intervals = createDefaultIntervals();\n const days: CoreTypes.day[] = [];\n v.forEach((i, d) => {\n days.push({ day: d });\n intervals[d] = i;\n });\n\n // set\n // (set days only if not all are permitted)\n teacher.intervals = intervals;\n if (days.length != numDays) teacher.days = days;\n });\n\n\n ////\n //// merge courses\n ////\n eventMap.forEach((events, key) => {\n const courseIds = key.split(separator).map(x => parseInt(x));\n\n if (courseIds.length > 1) {\n const idss: string[] = [];\n const displayNames: string[] = [];\n\n const subjects = new Set<string>();\n const groups = new Set<string>();\n const teachers = new Set<string>();\n\n // merge courses\n courseIds.map(x => courseMap.get(x))\n .filter(c => c != undefined)\n .forEach(c => {\n if (c.ids) idss.push(c.ids);\n if (c.displayName) displayNames.push(c.displayName);\n\n if (c.subject) subjects.add(c.subject);\n if (c.groups) c.groups.forEach(({ to }) => groups.add(to.toString()));\n if (c.teachers) c.teachers.forEach(({ to }) => teachers.add(to.toString()));\n });\n\n const newKey = --numAdditionalCourses;\n const newCourse: OutTypes.course = {\n ids: idss.join(separator),\n displayName: displayNames.join(separator),\n\n ...( subjects.size && { subject: [...subjects].join(separator) } ),\n\n ...( groups.size && { groups: [...groups].map(to => ({ to })) } ),\n ...( teachers.size && { teachers: [...teachers].map(to => ({ to })) } )\n };\n\n // add courses\n // (leave old courses if they have events) <-- WTF!?\n courseMap.set(newKey, newCourse);\n\n // link events to new course\n eventMap.set(newKey.toString(), [...events]);\n events.length = 0;\n\n // console.log(`The courses with PKs [${courseIds.join(separator)}] needed to be merged.`);\n warnings.push(`The courses with PKs [${courseIds.join(separator)}] needed to be merged.`);\n }\n });\n\n\n\n ////\n //// link events with courses\n ////\n const populatedCourses = new Set<number>();\n eventMap.forEach((events, key) => {\n // need to contain events\n if (!events.length) return;\n\n const courseIds = key.split(separator).map(x => parseInt(x));\n\n if (courseIds.length != 1 && events.length) throw new Error('Well this was unexpected...');\n\n const courseId = courseIds[0];\n const PK = courseMap.get(courseId)?.ids;\n\n if (PK == undefined) {\n // console.log(courseIds, PK, key, events)\n // throw \"Well this was also unexpected...\";\n // console.log(`The events with PKs ${events.map(e => e.ids)} were ignored since their course was not found.`);\n errors.push(`The events with PKs ${events.map(e => e.ids).join(', ')} were ignored since their course was not found.`);\n events.length = 0;\n return;\n }\n\n // link\n events.forEach(e => e.course = PK);\n\n populatedCourses.add(courseId);\n });\n\n\n\n ////\n //// try remove empty courses\n ////\n if (meta?.ignoreEmptyCourses) {\n // filter in place\n const courses = [...courseMap].filter(([k]) => populatedCourses.has(k));\n courseMap = new Map(courses);\n }\n\n\n ////\n //// try promote groups, teachers and locations to the parent course\n //// (if the course has none and all sibling events have the same)\n ////\n const keys = ['groups', 'teachers', 'locations'] as const;\n for (const key of keys) {\n courseMap.forEach((c, courseKey) => {\n // need to use the \"courseKey\" as it is different from the \"c.ids\" if the course has been merged\n const events = eventMap.get(courseKey.toString());\n\n const eventEntries = makeChainable(events ?? [])\n .chain(\n x => x\n .map(e => e[key] ?? c[key])\n .filter(x => x != null),\n x => uniqBy(x, x => x\n .map(x => 'to' in x ? x.to : x.locations[0])\n .sort()\n .join('.')\n )\n )\n .value;\n\n // the event entries must be exactly one\n if (eventEntries.length != 1) return;\n\n // update\n switch (key) {\n case 'groups': c[key] = eventEntries[0] as (typeof c)[typeof key]; break;\n case 'teachers': c[key] = eventEntries[0] as (typeof c)[typeof key]; break;\n case 'locations': c[key] = eventEntries[0] as (typeof c)[typeof key]; break;\n default: throw new Error(`Unknown key \"${key satisfies never as string}\"`);\n }\n events?.forEach(e => delete e[key]);\n });\n }\n\n\n // let eventsArray: Types.courseEvent[] = [];\n return { courses: [...courseMap.values()], events: [...eventMap.values()].flat() };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"course-and-events.js","names":["weeks: number[]","matches: RegExpExecArray | null","intervals: CoreTypes.interval[]","courseMap: Map<number, OutTypes.course>","subject: string | undefined","event: OutTypes.event","l","classes: Set<string>","days: CoreTypes.day[]","idss: string[]","displayNames: string[]","groups","newCourse: OutTypes.course","x"],"sources":["../../../../src/Skola24/mdb/from/course-and-events.ts"],"sourcesContent":["import moment from 'moment';\nimport { uniqBy } from 'lodash-es';\nimport type { CoreTypes } from '../../../core';\nimport type { OutTypes } from './schedule';\nimport type { Types as Skal24Types } from '../types';\nimport type { BaseOptions } from '../../../common/types';\nimport { makeChainable } from '../../../common/make-chainable';\n\n\nconst separator = ', ';\nconst arbetstid = 'Arbetstid'.toLowerCase();\nconst firstDay = '1970-01-05';\nconst numDays = 5;\nconst defaultDayStart = [8, 0];\nconst defaultDayEnd = [17, 0];\n\nfunction generateDate (\n days: number,\n hours: number,\n minutes: number\n) {\n return moment.utc(firstDay)\n .add(days, 'days')\n .add(hours, 'hours')\n .add(minutes, 'minutes');\n}\n\nfunction startAndEnd (\n lesson: Skal24Types.lesson\n): undefined | { start: moment.Moment, end: moment.Moment, parked: false } {\n if ('Length' in lesson && 'DayOfWeek' in lesson && 'StartTime' in lesson) {\n const dateTimeDate = moment(lesson.StartTime, 'MM/DD/YY hh:mm:ss');\n const hours = dateTimeDate.get('hours');\n const minutes = dateTimeDate.get('minutes');\n\n // let start = moment.utc(firstDay)\n // .add(lesson.DayOfWeek, \"days\")\n // .add(hours, \"hours\")\n // .add(minutes, \"minutes\");\n const start = generateDate(lesson.DayOfWeek!, hours, minutes);\n const end = start.clone().add(lesson.Length, 'minute');\n return { start: start, end: end, parked: false };\n }\n\n return;\n}\n\nfunction parseActualWeeks (val?: string) {\n if (!val) return [];\n\n const weeks: number[] = [];\n\n val\n .split(',')\n .forEach(x => {\n if (x.includes('-')) {\n // multiple weeks\n const [start, end] = x.split('-');\n for (let i = parseInt(start); i <= parseInt(end); i++)\n weeks.push(i);\n } else {\n // single week\n weeks.push(parseInt(x));\n }\n });\n\n return weeks;\n}\n\nfunction addGroupsFromName (\n name: string,\n groupSet: Set<string>,\n groupNamePkMap: Map<string, string>\n) {\n // assumes course names of the type \"10IDS01-EK20C-LAG\"\n const regex = /-([^\\s-]+)/gi;\n\n let matches: RegExpExecArray | null;\n while ((matches = regex.exec(name)) !== null) {\n if (groupNamePkMap.has(matches[1])) {\n const PK = groupNamePkMap.get(matches[1])!;\n groupSet.add(PK);\n }\n }\n}\n\nfunction getDay (mnt: moment.Moment) {\n return mnt.dayOfYear() - moment.utc(firstDay).dayOfYear();\n}\n\nfunction createDefaultIntervals () {\n const intervals: CoreTypes.interval[] = [];\n\n for (let d = 0; d < numDays; d++) {\n intervals.push({\n start: generateDate(d, defaultDayStart[0], defaultDayStart[1]),\n end: generateDate(d, defaultDayEnd[0], defaultDayEnd[1])\n });\n }\n\n return intervals;\n}\n\n\n\n\nexport default function (\n groups: Skal24Types.group[],\n lessons: Skal24Types.lesson[],\n meta: Skal24Types.options & BaseOptions | undefined,\n\n groupPlansMap: Map<number, Set<string> >,\n planMap: Map<number, Skal24Types.plan>,\n\n subjectMap: Map<number, string>,\n planTeachersMap: Map<number, Set<string> >,\n groupClassesMap: Map<string, Set<string> >,\n RSgroups: OutTypes.group[],\n\n groupMap: Map<number, Skal24Types.group>,\n lessonRoomsMap: Map<number, Set<string> >,\n lessonTeachersMap: Map<number, Set<string> >,\n lessonGroupsMap: Map<number, Set<string> >,\n RSteachers: OutTypes.teacher[],\n\n warnings: string[],\n errors: string[]\n): { courses: OutTypes.course[], events: OutTypes.event[] } {\n\n // used when deducing groups from the course name\n const groupNamePkMap = new Map(RSgroups.map(g => [g.displayName!, g.ids!]));\n\n ////\n //// courses\n ////\n let courseMap: Map<number, OutTypes.course> = new Map();\n groups.forEach(x => {\n // need to be a scheduled group\n if (x.bClass) return;\n\n // check if at least one plan intersects our period\n const plans = groupPlansMap.get(x.PK);\n\n // fetch subject via first plan\n let subject: string | undefined;\n if (plans) {\n const subjPK = planMap.get(parseInt([...plans][0]))?.FKSubject;\n if (subjPK) subject = subjectMap.get(subjPK);\n }\n // if (subject) console.log(subject)\n\n const groupSet = groupClassesMap.get(x.PK.toString()) ?? new Set<string>();\n\n // attempt to deduce groups by analyzing the course name\n if (meta?.deduceGroupsFromCourseName && x.ID) {\n addGroupsFromName(x.ID, groupSet, groupNamePkMap);\n }\n\n\n\n // if (groups) console.log(groups)\n\n const teacherSet = new Set<string>();\n groupPlansMap.get(x.PK)?.forEach(p => {\n planTeachersMap.get(parseInt(p))?.forEach(t => teacherSet.add(t));\n });\n // if (teacherSet) console.log(teacherSet)\n\n\n courseMap.set(x.PK, {\n ids: x.PK.toString(),\n displayName: x.ID,\n\n ...( subject && { subject } ),\n ...( groupSet?.size && { groups: [...groupSet ].map(to => ({ to })) } ),\n ...( teacherSet.size && { teachers: [...teacherSet].map(to => ({ to })) } )\n });\n });\n\n\n\n ////\n //// events\n ////\n let numAdditionalCourses = 0;\n const eventMap = new Map<string, OutTypes.event[]>();\n const intervalMap = new Map<string, Map<number, CoreTypes.interval> >();\n lessons.forEach(l => {\n // ignore all lessons which are not scheduled on the week of interest\n if (meta?.week == undefined || !parseActualWeeks(l.CalcActualWeeks).includes(meta.week)) return;\n\n\n const coursesIds = [...(lessonGroupsMap.get(l.PK) ?? new Set())]\n .map(id => groupMap.get(parseInt(id)))\n .filter((g): g is NonNullable<typeof g> => g?.bClass == false)\n .sort((g1, g2) => g1.PK - g2.PK)\n .map(g => g.PK);\n\n const event: OutTypes.event = {\n ids: l.PK.toString(),\n\n duration: l.Length,\n preferredDuration: l.Length,\n ...startAndEnd(l)\n };\n\n // try add room\n const rooms = lessonRoomsMap.get(l.PK);\n if (rooms?.size) {\n event.inLocations = [...rooms];\n event.locations = [...rooms].map(l => ({ locations: [l] }));\n }\n\n // try add teachers\n const teachers = lessonTeachersMap.get(l.PK);\n if (teachers?.size) event.teachers = [...teachers].map(to => ({ to }));\n\n // fetch groups\n const classes: Set<string> = new Set();\n lessonGroupsMap.get(l.PK)?.forEach(scheduleGroupId => {\n groupClassesMap.get(scheduleGroupId)?.forEach(classId => {\n classes.add(classId);\n });\n });\n\n // attempt to deduce groups by analyzing the course name\n // (but only if the event explicitly has groups or its course has none)\n const courseHasGroups = coursesIds.some(x => courseMap.get(x)?.groups);\n if (meta?.deduceGroupsFromCourseName && (!courseHasGroups || classes.size)) {\n coursesIds.map(x => courseMap.get(x)?.displayName)\n .filter(x => x != null)\n .forEach(x => addGroupsFromName(x, classes, groupNamePkMap));\n }\n\n // try add groups\n if (classes.size) event.groups = [...classes].map(to => ({ to }));\n\n\n const subject = subjectMap.get(l.FKSubject!);\n if (subject?.toLowerCase() == arbetstid) {\n // is an interval\n\n // ensure start and end is set\n const start = event.start;\n const end = event.end;\n if (!start || !end) {\n warnings.push('Start or end not set on interval event');\n return;\n }\n\n // interval day\n const day = getDay(moment.utc(start));\n\n if (0 > day || day > numDays - 1) {\n warnings.push('Interval day out of bounds');\n return;\n }\n\n // add interval\n teachers?.forEach(t => {\n if (!intervalMap.has(t)) intervalMap.set(t, new Map());\n intervalMap.get(t)?.set(day, { start, end });\n });\n\n } else {\n // is an event\n\n ////\n //// if there is no course, create it\n //// (can also be interval)\n ////\n if (!coursesIds.length) {\n const id = --numAdditionalCourses;\n\n courseMap.set(id, {\n ids: id.toString(),\n\n ...( subject && { displayName: subject } ),\n ...( subject && { subject } ),\n\n // // makes it easier to se in the table\n // ...( teachers?.size && { teachers: [...teachers] } ),\n // ...( classes?.size && { groups: [...classes] } ),\n });\n\n coursesIds.push(id);\n }\n\n\n // add\n const key = coursesIds.join(separator);\n if (!eventMap.has(key)) eventMap.set(key, []);\n eventMap.get(key)?.push(event);\n }\n\n });\n\n\n ////\n //// set teacher days and intervals\n ////\n intervalMap.forEach((v, k) => {\n // fetch teacher\n const teacher = RSteachers.find(t => t.ids == k);\n if (!teacher) {\n warnings.push(`An interval referred to the unknown teacher with PK = ${k}`);\n return;\n }\n\n // construct\n const intervals = createDefaultIntervals();\n const days: CoreTypes.day[] = [];\n v.forEach((i, d) => {\n days.push({ day: d });\n intervals[d] = i;\n });\n\n // set\n // (set days only if not all are permitted)\n teacher.intervals = intervals;\n if (days.length != numDays) teacher.days = days;\n });\n\n\n ////\n //// merge courses\n ////\n eventMap.forEach((events, key) => {\n const courseIds = key.split(separator).map(x => parseInt(x));\n\n if (courseIds.length > 1) {\n const idss: string[] = [];\n const displayNames: string[] = [];\n\n const subjects = new Set<string>();\n const groups = new Set<string>();\n const teachers = new Set<string>();\n\n // merge courses\n courseIds.map(x => courseMap.get(x))\n .filter(c => c != undefined)\n .forEach(c => {\n if (c.ids) idss.push(c.ids);\n if (c.displayName) displayNames.push(c.displayName);\n\n if (c.subject) subjects.add(c.subject);\n if (c.groups) c.groups.forEach(({ to }) => groups.add(to.toString()));\n if (c.teachers) c.teachers.forEach(({ to }) => teachers.add(to.toString()));\n });\n\n const newKey = --numAdditionalCourses;\n const newCourse: OutTypes.course = {\n ids: idss.join(separator),\n displayName: displayNames.join(separator),\n\n ...( subjects.size && { subject: [...subjects].join(separator) } ),\n\n ...( groups.size && { groups: [...groups].map(to => ({ to })) } ),\n ...( teachers.size && { teachers: [...teachers].map(to => ({ to })) } )\n };\n\n // add courses\n // (leave old courses if they have events) <-- WTF!?\n courseMap.set(newKey, newCourse);\n\n // link events to new course\n eventMap.set(newKey.toString(), [...events]);\n events.length = 0;\n\n // console.log(`The courses with PKs [${courseIds.join(separator)}] needed to be merged.`);\n warnings.push(`The courses with PKs [${courseIds.join(separator)}] needed to be merged.`);\n }\n });\n\n\n\n ////\n //// link events with courses\n ////\n const populatedCourses = new Set<number>();\n eventMap.forEach((events, key) => {\n // need to contain events\n if (!events.length) return;\n\n const courseIds = key.split(separator).map(x => parseInt(x));\n\n if (courseIds.length != 1 && events.length) throw new Error('Well this was unexpected...');\n\n const courseId = courseIds[0];\n const PK = courseMap.get(courseId)?.ids;\n\n if (PK == undefined) {\n // console.log(courseIds, PK, key, events)\n // throw \"Well this was also unexpected...\";\n // console.log(`The events with PKs ${events.map(e => e.ids)} were ignored since their course was not found.`);\n errors.push(`The events with PKs ${events.map(e => e.ids).join(', ')} were ignored since their course was not found.`);\n events.length = 0;\n return;\n }\n\n // link\n events.forEach(e => e.course = PK);\n\n populatedCourses.add(courseId);\n });\n\n\n\n ////\n //// try remove empty courses\n ////\n if (meta?.ignoreEmptyCourses) {\n // filter in place\n const courses = [...courseMap].filter(([k]) => populatedCourses.has(k));\n courseMap = new Map(courses);\n }\n\n\n ////\n //// try promote groups, teachers and locations to the parent course\n //// (if the course has none and all sibling events have the same)\n ////\n const keys = ['groups', 'teachers', 'locations'] as const;\n for (const key of keys) {\n courseMap.forEach((c, courseKey) => {\n // need to use the \"courseKey\" as it is different from the \"c.ids\" if the course has been merged\n const events = eventMap.get(courseKey.toString());\n\n const eventEntries = makeChainable(events ?? [])\n .chain(\n x => x\n .map(e => e[key] ?? c[key])\n .filter(x => x != null),\n x => uniqBy(x, x => x\n .map(x => 'to' in x ? x.to : x.locations[0])\n .sort()\n .join('.')\n )\n )\n .value;\n\n // the event entries must be exactly one\n if (eventEntries.length != 1) return;\n\n // update\n switch (key) {\n case 'groups': c[key] = eventEntries[0] as (typeof c)[typeof key]; break;\n case 'teachers': c[key] = eventEntries[0] as (typeof c)[typeof key]; break;\n case 'locations': c[key] = eventEntries[0] as (typeof c)[typeof key]; break;\n default: throw new Error(`Unknown key \"${key satisfies never as string}\"`);\n }\n events?.forEach(e => delete e[key]);\n });\n }\n\n\n // let eventsArray: Types.courseEvent[] = [];\n return { courses: [...courseMap.values()], events: [...eventMap.values()].flat() };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"groups.js","names":[],"sources":["../../../../src/Skola24/mdb/from/groups.ts"],"sourcesContent":["import type { Types as Skola24Types } from '../types';\nimport type { OutTypes } from './schedule';\n\nexport default function (\n groups: Skola24Types.group[],\n warnings: string[],\n errors: string[]\n): OutTypes.group[] {\n return groups.filter(x => x.bClass)\n .map(x => ({\n ids: x.PK.toString(),\n displayName: x.ID,\n species: 'class',\n }));\n}\n"],"mappings":";AAGA,wBACE,QACA,UACA,QACkB;AAClB,QAAO,OAAO,QAAO,MAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"groups.js","names":[],"sources":["../../../../src/Skola24/mdb/from/groups.ts"],"sourcesContent":["import type { Types as Skola24Types } from '../types';\nimport type { OutTypes } from './schedule';\n\nexport default function (\n groups: Skola24Types.group[],\n warnings: string[],\n errors: string[]\n): OutTypes.group[] {\n return groups.filter(x => x.bClass)\n .map(x => ({\n ids: x.PK.toString(),\n displayName: x.ID,\n species: 'class',\n }));\n}\n"],"mappings":";AAGA,wBACE,QACA,UACA,QACkB;AAClB,QAAO,OAAO,QAAO,MAAK,EAAE,OAAO,CAChC,KAAI,OAAM;EACT,KAAa,EAAE,GAAG,UAAU;EAC5B,aAAa,EAAE;EACf,SAAa;EACd,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_schedule"],"sources":["../../../../src/Skola24/mdb/from/index.ts"],"sourcesContent":["import type { FromInterface } from '../../../common/types';\nimport _schedule from './schedule';\n\nexport default {\n schedules: _schedule\n} satisfies FromInterface;\n"],"mappings":";;;AAGA,mBAAe,EACb,WAAWA"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["_schedule"],"sources":["../../../../src/Skola24/mdb/from/index.ts"],"sourcesContent":["import type { FromInterface } from '../../../common/types';\nimport _schedule from './schedule';\n\nexport default {\n schedules: _schedule\n} satisfies FromInterface;\n"],"mappings":";;;AAGA,mBAAe,EACb,WAAWA,kBACZ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locations.js","names":[],"sources":["../../../../src/Skola24/mdb/from/locations.ts"],"sourcesContent":["import type { Types as Skola24Types } from '../types';\nimport type { OutTypes } from './schedule';\n\nexport default function (\n rooms: Skola24Types.room[],\n warnings: string[],\n errors: string[]\n): OutTypes.location[] {\n return rooms.map(x => ({\n ids: x.PK.toString(),\n displayName: x.ID\n }));\n}\n"],"mappings":";AAGA,2BACE,OACA,UACA,QACqB;AACrB,QAAO,MAAM,KAAI,OAAM;EACrB,KAAa,EAAE,GAAG;
|
|
1
|
+
{"version":3,"file":"locations.js","names":[],"sources":["../../../../src/Skola24/mdb/from/locations.ts"],"sourcesContent":["import type { Types as Skola24Types } from '../types';\nimport type { OutTypes } from './schedule';\n\nexport default function (\n rooms: Skola24Types.room[],\n warnings: string[],\n errors: string[]\n): OutTypes.location[] {\n return rooms.map(x => ({\n ids: x.PK.toString(),\n displayName: x.ID\n }));\n}\n"],"mappings":";AAGA,2BACE,OACA,UACA,QACqB;AACrB,QAAO,MAAM,KAAI,OAAM;EACrB,KAAa,EAAE,GAAG,UAAU;EAC5B,aAAa,EAAE;EAChB,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedule.js","names":["warnings: string[]","errors: string[]","_locations","_teachers","_groups","coursesAndEvents"],"sources":["../../../../src/Skola24/mdb/from/schedule.ts"],"sourcesContent":["import type { CoreTypes } from '../../../core';\nimport type { Types as Skola24Types } from '../types';\nimport type { InternalIdKey } from '../../../core/types/common';\nimport { getVertexId } from '../../../core/util';\nimport _locations from './locations';\nimport _teachers from './teachers';\nimport _groups from './groups';\nimport coursesAndEvents from './course-and-events';\nimport type { BaseOptions } from '../../../common/types';\n\nexport namespace OutTypes {\n export type location = Omit<CoreTypes.Serialized.Location, InternalIdKey>;\n export type teacher = Omit<CoreTypes.Serialized.Teacher, InternalIdKey>;\n export type group = Omit<CoreTypes.Serialized.Group, InternalIdKey>;\n export type course = Omit<CoreTypes.Serialized.Course, InternalIdKey>;\n export type event = Omit<CoreTypes.Serialized.Event, InternalIdKey>;\n}\n\ntype Out = {\n locations: OutTypes.location[];\n teachers: OutTypes.teacher[];\n groups: OutTypes.group[];\n courses: OutTypes.course[];\n events: OutTypes.event[];\n meta?: {\n errors?: string[];\n warnings?: string[];\n };\n};\n\nexport default function (\n src: Skola24Types.schedule,\n _options: Skola24Types.options = { }\n): Out {\n const options = Object.assign(_options, { dKey: 'ids' } as BaseOptions);\n\n // gather all import related warnings/errors\n const warnings: string[] = [];\n const errors: string[] = [];\n\n // check which weeks this schedule concern\n if (options?.week == undefined) {\n warnings.push('No events will be imported since no import week was provided');\n }\n\n ////\n //// construct maps\n ////\n\n // groups\n const groupMap = new Map(src.school_tblgroup.map(x => [x.PK, x]));\n\n // courses\n const courseMap = new Map(src.school_tblcourse.map(x => [x.PK, x]));\n\n // plan\n const planMap = new Map(src.school_tblplan.map(x => [x.PK, x]));\n\n // subject\n const subjectMap = new Map(src.school_tblsubject.map(x => [x.PK, x.ID]));\n\n\n // plan-teacher\n const planTeachersMap = new Map<number, Set<string>>();\n src.school_tblplan_teacher.forEach(x => {\n if (!planTeachersMap.has(x.FKPlan)) planTeachersMap.set(x.FKPlan, new Set());\n planTeachersMap.get(x.FKPlan)!.add(x.FKTeacher.toString());\n });\n\n // plan-group\n const planGroupsMap = new Map<number, Set<string>>();\n src.school_tblplan_group.forEach(x => {\n if (!planGroupsMap.has(x.FKPlan)) planGroupsMap.set(x.FKPlan, new Set());\n planGroupsMap.get(x.FKPlan)!.add(x.FKGroup.toString());\n });\n\n // group-plan\n const groupPlansMap = new Map<number, Set<string>>();\n src.school_tblplan_group.forEach(x => {\n if (!groupPlansMap.has(x.FKGroup)) groupPlansMap.set(x.FKGroup, new Set());\n groupPlansMap.get(x.FKGroup)!.add(x.FKPlan.toString());\n });\n\n // lesson-rooms\n const lessonRoomsMap = new Map<number, Set<string> >();\n src.school_tblschedule_room.forEach(x => {\n if (!lessonRoomsMap.has(x.FKSchedule)) lessonRoomsMap.set(x.FKSchedule, new Set());\n lessonRoomsMap.get(x.FKSchedule)!.add(x.FKRoom.toString());\n });\n\n // lesson-teacher\n const lessonTeachersMap = new Map<number, Set<string> >();\n src.school_tblschedule_teacher.forEach(x => {\n if (!lessonTeachersMap.has(x.FKSchedule)) lessonTeachersMap.set(x.FKSchedule, new Set());\n lessonTeachersMap.get(x.FKSchedule)!.add(x.FKTeacher.toString());\n });\n\n // lesson-group\n const lessonGroupsMap = new Map<number, Set<string> >();\n src.school_tblschedule_group.forEach(x => {\n if (!lessonGroupsMap.has(x.FKSchedule)) lessonGroupsMap.set(x.FKSchedule, new Set());\n lessonGroupsMap.get(x.FKSchedule)!.add(x.FKGroup.toString());\n });\n\n // construct a group (= course) to class map\n const groupClassesMap = new Map<string, Set<string> >();\n src.school_tblgroup_group.forEach(x => {\n if (!groupClassesMap.has(x.FKGroup.toString())) groupClassesMap.set(x.FKGroup.toString(), new Set());\n groupClassesMap.get(x.FKGroup.toString())!.add(x.FKGroupCon.toString());\n });\n // class-class not present in the \"school_tblgroup_group\" table, so add manually\n src.school_tblgroup.forEach(x => {\n if (x.bClass) {\n if (!groupClassesMap.has(x.PK.toString())) groupClassesMap.set(x.PK.toString(), new Set());\n groupClassesMap.get(x.PK.toString())!.add(x.PK.toString());\n }\n });\n\n\n ////\n //// map entities\n ////\n const locations = _locations(src.unit_tblroom, warnings, errors);\n let teachers = _teachers (src.school_tblteacher, warnings, errors);\n let groups = _groups (src.school_tblgroup, warnings, errors);\n\n const { courses, events }\n = coursesAndEvents(src.school_tblgroup,\n src.school_tblschedule,\n options,\n\n groupPlansMap,\n planMap,\n\n subjectMap,\n planTeachersMap,\n groupClassesMap,\n groups,\n\n groupMap,\n lessonRoomsMap,\n lessonTeachersMap,\n lessonGroupsMap,\n teachers,\n\n warnings, errors);\n\n\n ////\n //// try filter unreferenced groups and teachers\n ////\n if (options?.removeUnreferencedTeachers) {\n const unreferencedTeacherSet = new Set(teachers.map(x => getVertexId(x, options)));\n events.forEach(e => {\n e.teachers?.forEach(({ to }) => unreferencedTeacherSet.delete(getVertexId(to, options)));\n });\n courses.forEach(c => {\n c.teachers?.forEach(({ to }) => unreferencedTeacherSet.delete(getVertexId(to, options)));\n });\n teachers = teachers.filter(x => !unreferencedTeacherSet.has(getVertexId(x, options)));\n }\n\n if (options?.removeUnreferencedGroups) {\n const unreferencedGroupSet = new Set(groups.map(x => getVertexId(x, options)));\n events.forEach(e => {\n e.groups?.forEach(({ to }) => unreferencedGroupSet.delete(getVertexId(to, options)));\n });\n courses.forEach(c => {\n c.groups?.forEach(({ to }) => unreferencedGroupSet.delete(getVertexId(to, options)));\n });\n groups = groups.filter(x => !unreferencedGroupSet.has(getVertexId(x, options)));\n }\n\n\n return { locations, teachers, groups, courses, events,\n meta: {\n ...( errors.length ? { errors: errors } : { } ),\n ...( warnings.length ? { warnings: warnings } : { } )\n }\n };\n}\n"],"mappings":";;;;;;;AA8BA,0BACE,KACA,WAAiC,
|
|
1
|
+
{"version":3,"file":"schedule.js","names":["warnings: string[]","errors: string[]","_locations","_teachers","_groups","coursesAndEvents"],"sources":["../../../../src/Skola24/mdb/from/schedule.ts"],"sourcesContent":["import type { CoreTypes } from '../../../core';\nimport type { Types as Skola24Types } from '../types';\nimport type { InternalIdKey } from '../../../core/types/common';\nimport { getVertexId } from '../../../core/util';\nimport _locations from './locations';\nimport _teachers from './teachers';\nimport _groups from './groups';\nimport coursesAndEvents from './course-and-events';\nimport type { BaseOptions } from '../../../common/types';\n\nexport namespace OutTypes {\n export type location = Omit<CoreTypes.Serialized.Location, InternalIdKey>;\n export type teacher = Omit<CoreTypes.Serialized.Teacher, InternalIdKey>;\n export type group = Omit<CoreTypes.Serialized.Group, InternalIdKey>;\n export type course = Omit<CoreTypes.Serialized.Course, InternalIdKey>;\n export type event = Omit<CoreTypes.Serialized.Event, InternalIdKey>;\n}\n\ntype Out = {\n locations: OutTypes.location[];\n teachers: OutTypes.teacher[];\n groups: OutTypes.group[];\n courses: OutTypes.course[];\n events: OutTypes.event[];\n meta?: {\n errors?: string[];\n warnings?: string[];\n };\n};\n\nexport default function (\n src: Skola24Types.schedule,\n _options: Skola24Types.options = { }\n): Out {\n const options = Object.assign(_options, { dKey: 'ids' } as BaseOptions);\n\n // gather all import related warnings/errors\n const warnings: string[] = [];\n const errors: string[] = [];\n\n // check which weeks this schedule concern\n if (options?.week == undefined) {\n warnings.push('No events will be imported since no import week was provided');\n }\n\n ////\n //// construct maps\n ////\n\n // groups\n const groupMap = new Map(src.school_tblgroup.map(x => [x.PK, x]));\n\n // courses\n const courseMap = new Map(src.school_tblcourse.map(x => [x.PK, x]));\n\n // plan\n const planMap = new Map(src.school_tblplan.map(x => [x.PK, x]));\n\n // subject\n const subjectMap = new Map(src.school_tblsubject.map(x => [x.PK, x.ID]));\n\n\n // plan-teacher\n const planTeachersMap = new Map<number, Set<string>>();\n src.school_tblplan_teacher.forEach(x => {\n if (!planTeachersMap.has(x.FKPlan)) planTeachersMap.set(x.FKPlan, new Set());\n planTeachersMap.get(x.FKPlan)!.add(x.FKTeacher.toString());\n });\n\n // plan-group\n const planGroupsMap = new Map<number, Set<string>>();\n src.school_tblplan_group.forEach(x => {\n if (!planGroupsMap.has(x.FKPlan)) planGroupsMap.set(x.FKPlan, new Set());\n planGroupsMap.get(x.FKPlan)!.add(x.FKGroup.toString());\n });\n\n // group-plan\n const groupPlansMap = new Map<number, Set<string>>();\n src.school_tblplan_group.forEach(x => {\n if (!groupPlansMap.has(x.FKGroup)) groupPlansMap.set(x.FKGroup, new Set());\n groupPlansMap.get(x.FKGroup)!.add(x.FKPlan.toString());\n });\n\n // lesson-rooms\n const lessonRoomsMap = new Map<number, Set<string> >();\n src.school_tblschedule_room.forEach(x => {\n if (!lessonRoomsMap.has(x.FKSchedule)) lessonRoomsMap.set(x.FKSchedule, new Set());\n lessonRoomsMap.get(x.FKSchedule)!.add(x.FKRoom.toString());\n });\n\n // lesson-teacher\n const lessonTeachersMap = new Map<number, Set<string> >();\n src.school_tblschedule_teacher.forEach(x => {\n if (!lessonTeachersMap.has(x.FKSchedule)) lessonTeachersMap.set(x.FKSchedule, new Set());\n lessonTeachersMap.get(x.FKSchedule)!.add(x.FKTeacher.toString());\n });\n\n // lesson-group\n const lessonGroupsMap = new Map<number, Set<string> >();\n src.school_tblschedule_group.forEach(x => {\n if (!lessonGroupsMap.has(x.FKSchedule)) lessonGroupsMap.set(x.FKSchedule, new Set());\n lessonGroupsMap.get(x.FKSchedule)!.add(x.FKGroup.toString());\n });\n\n // construct a group (= course) to class map\n const groupClassesMap = new Map<string, Set<string> >();\n src.school_tblgroup_group.forEach(x => {\n if (!groupClassesMap.has(x.FKGroup.toString())) groupClassesMap.set(x.FKGroup.toString(), new Set());\n groupClassesMap.get(x.FKGroup.toString())!.add(x.FKGroupCon.toString());\n });\n // class-class not present in the \"school_tblgroup_group\" table, so add manually\n src.school_tblgroup.forEach(x => {\n if (x.bClass) {\n if (!groupClassesMap.has(x.PK.toString())) groupClassesMap.set(x.PK.toString(), new Set());\n groupClassesMap.get(x.PK.toString())!.add(x.PK.toString());\n }\n });\n\n\n ////\n //// map entities\n ////\n const locations = _locations(src.unit_tblroom, warnings, errors);\n let teachers = _teachers (src.school_tblteacher, warnings, errors);\n let groups = _groups (src.school_tblgroup, warnings, errors);\n\n const { courses, events }\n = coursesAndEvents(src.school_tblgroup,\n src.school_tblschedule,\n options,\n\n groupPlansMap,\n planMap,\n\n subjectMap,\n planTeachersMap,\n groupClassesMap,\n groups,\n\n groupMap,\n lessonRoomsMap,\n lessonTeachersMap,\n lessonGroupsMap,\n teachers,\n\n warnings, errors);\n\n\n ////\n //// try filter unreferenced groups and teachers\n ////\n if (options?.removeUnreferencedTeachers) {\n const unreferencedTeacherSet = new Set(teachers.map(x => getVertexId(x, options)));\n events.forEach(e => {\n e.teachers?.forEach(({ to }) => unreferencedTeacherSet.delete(getVertexId(to, options)));\n });\n courses.forEach(c => {\n c.teachers?.forEach(({ to }) => unreferencedTeacherSet.delete(getVertexId(to, options)));\n });\n teachers = teachers.filter(x => !unreferencedTeacherSet.has(getVertexId(x, options)));\n }\n\n if (options?.removeUnreferencedGroups) {\n const unreferencedGroupSet = new Set(groups.map(x => getVertexId(x, options)));\n events.forEach(e => {\n e.groups?.forEach(({ to }) => unreferencedGroupSet.delete(getVertexId(to, options)));\n });\n courses.forEach(c => {\n c.groups?.forEach(({ to }) => unreferencedGroupSet.delete(getVertexId(to, options)));\n });\n groups = groups.filter(x => !unreferencedGroupSet.has(getVertexId(x, options)));\n }\n\n\n return { locations, teachers, groups, courses, events,\n meta: {\n ...( errors.length ? { errors: errors } : { } ),\n ...( warnings.length ? { warnings: warnings } : { } )\n }\n };\n}\n"],"mappings":";;;;;;;AA8BA,0BACE,KACA,WAAiC,EAAG,EAC/B;CACL,MAAM,UAAU,OAAO,OAAO,UAAU,EAAE,MAAM,OAAO,CAAgB;CAGvE,MAAMA,WAAqB,EAAE;CAC7B,MAAMC,SAAqB,EAAE;AAG7B,KAAI,SAAS,QAAQ,OACnB,UAAS,KAAK,+DAA+D;CAQ/E,MAAM,WAAW,IAAI,IAAI,IAAI,gBAAgB,KAAI,MAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;AAG/C,KAAI,IAAI,IAAI,iBAAiB,KAAI,MAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;CAGnE,MAAM,UAAU,IAAI,IAAI,IAAI,eAAe,KAAI,MAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;CAG/D,MAAM,aAAa,IAAI,IAAI,IAAI,kBAAkB,KAAI,MAAK,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;CAIxE,MAAM,kCAAkB,IAAI,KAA0B;AACtD,KAAI,uBAAuB,SAAQ,MAAK;AACtC,MAAI,CAAC,gBAAgB,IAAI,EAAE,OAAO,CAAE,iBAAgB,IAAI,EAAE,wBAAQ,IAAI,KAAK,CAAC;AAC5E,kBAAgB,IAAI,EAAE,OAAO,CAAE,IAAI,EAAE,UAAU,UAAU,CAAC;GAC1D;CAGF,MAAM,gCAAgB,IAAI,KAA0B;AACpD,KAAI,qBAAqB,SAAQ,MAAK;AACpC,MAAI,CAAC,cAAc,IAAI,EAAE,OAAO,CAAE,eAAc,IAAI,EAAE,wBAAQ,IAAI,KAAK,CAAC;AACxE,gBAAc,IAAI,EAAE,OAAO,CAAE,IAAI,EAAE,QAAQ,UAAU,CAAC;GACtD;CAGF,MAAM,gCAAgB,IAAI,KAA0B;AACpD,KAAI,qBAAqB,SAAQ,MAAK;AACpC,MAAI,CAAC,cAAc,IAAI,EAAE,QAAQ,CAAE,eAAc,IAAI,EAAE,yBAAS,IAAI,KAAK,CAAC;AAC1E,gBAAc,IAAI,EAAE,QAAQ,CAAE,IAAI,EAAE,OAAO,UAAU,CAAC;GACtD;CAGF,MAAM,iCAAiB,IAAI,KAA2B;AACtD,KAAI,wBAAwB,SAAQ,MAAK;AACvC,MAAI,CAAC,eAAe,IAAI,EAAE,WAAW,CAAE,gBAAe,IAAI,EAAE,4BAAY,IAAI,KAAK,CAAC;AAClF,iBAAe,IAAI,EAAE,WAAW,CAAE,IAAI,EAAE,OAAO,UAAU,CAAC;GAC1D;CAGF,MAAM,oCAAoB,IAAI,KAA2B;AACzD,KAAI,2BAA2B,SAAQ,MAAK;AAC1C,MAAI,CAAC,kBAAkB,IAAI,EAAE,WAAW,CAAE,mBAAkB,IAAI,EAAE,4BAAY,IAAI,KAAK,CAAC;AACxF,oBAAkB,IAAI,EAAE,WAAW,CAAE,IAAI,EAAE,UAAU,UAAU,CAAC;GAChE;CAGF,MAAM,kCAAkB,IAAI,KAA2B;AACvD,KAAI,yBAAyB,SAAQ,MAAK;AACxC,MAAI,CAAC,gBAAgB,IAAI,EAAE,WAAW,CAAE,iBAAgB,IAAI,EAAE,4BAAY,IAAI,KAAK,CAAC;AACpF,kBAAgB,IAAI,EAAE,WAAW,CAAE,IAAI,EAAE,QAAQ,UAAU,CAAC;GAC5D;CAGF,MAAM,kCAAkB,IAAI,KAA2B;AACvD,KAAI,sBAAsB,SAAQ,MAAK;AACrC,MAAI,CAAC,gBAAgB,IAAI,EAAE,QAAQ,UAAU,CAAC,CAAE,iBAAgB,IAAI,EAAE,QAAQ,UAAU,kBAAE,IAAI,KAAK,CAAC;AACpG,kBAAgB,IAAI,EAAE,QAAQ,UAAU,CAAC,CAAE,IAAI,EAAE,WAAW,UAAU,CAAC;GACvE;AAEF,KAAI,gBAAgB,SAAQ,MAAK;AAC/B,MAAI,EAAE,QAAQ;AACZ,OAAI,CAAC,gBAAgB,IAAI,EAAE,GAAG,UAAU,CAAC,CAAE,iBAAgB,IAAI,EAAE,GAAG,UAAU,kBAAE,IAAI,KAAK,CAAC;AAC1F,mBAAgB,IAAI,EAAE,GAAG,UAAU,CAAC,CAAE,IAAI,EAAE,GAAG,UAAU,CAAC;;GAE5D;CAMF,MAAM,YAAYC,kBAAW,IAAI,cAAmB,UAAU,OAAO;CACrE,IAAM,WAAYC,iBAAW,IAAI,mBAAmB,UAAU,OAAO;CACrE,IAAM,SAAYC,eAAW,IAAI,iBAAmB,UAAU,OAAO;CAErE,MAAM,EAAE,SAAS,WACbC,0BAAiB,IAAI,iBACrB,IAAI,oBACJ,SAEA,eACA,SAEA,YACA,iBACA,iBACA,QAEA,UACA,gBACA,mBACA,iBACA,UAEA,UAAU,OAAO;AAMrB,KAAI,SAAS,4BAA4B;EACvC,MAAM,yBAAyB,IAAI,IAAI,SAAS,KAAI,MAAK,YAAY,GAAG,QAAQ,CAAC,CAAC;AAClF,SAAO,SAAQ,MAAK;AAClB,KAAE,UAAU,SAAS,EAAE,SAAS,uBAAuB,OAAO,YAAY,IAAI,QAAQ,CAAC,CAAC;IACxF;AACF,UAAQ,SAAQ,MAAK;AACnB,KAAE,UAAU,SAAS,EAAE,SAAS,uBAAuB,OAAO,YAAY,IAAI,QAAQ,CAAC,CAAC;IACxF;AACF,aAAW,SAAS,QAAO,MAAK,CAAC,uBAAuB,IAAI,YAAY,GAAG,QAAQ,CAAC,CAAC;;AAGvF,KAAI,SAAS,0BAA0B;EACrC,MAAM,uBAAuB,IAAI,IAAI,OAAO,KAAI,MAAK,YAAY,GAAG,QAAQ,CAAC,CAAC;AAC9E,SAAO,SAAQ,MAAK;AAClB,KAAE,QAAQ,SAAS,EAAE,SAAS,qBAAqB,OAAO,YAAY,IAAI,QAAQ,CAAC,CAAC;IACpF;AACF,UAAQ,SAAQ,MAAK;AACnB,KAAE,QAAQ,SAAS,EAAE,SAAS,qBAAqB,OAAO,YAAY,IAAI,QAAQ,CAAC,CAAC;IACpF;AACF,WAAS,OAAO,QAAO,MAAK,CAAC,qBAAqB,IAAI,YAAY,GAAG,QAAQ,CAAC,CAAC;;AAIjF,QAAO;EAAE;EAAW;EAAU;EAAQ;EAAS;EAC7C,MAAM;GACJ,GAAK,OAAO,SAAW,EAAY,QAAU,GAAG,EAAG;GACnD,GAAK,SAAS,SAAS,EAAY,UAAU,GAAG,EAAG;GACpD;EACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"teachers.js","names":[],"sources":["../../../../src/Skola24/mdb/from/teachers.ts"],"sourcesContent":["import type { Types as Skola24Types } from '../types';\nimport type { OutTypes } from './schedule';\n\nexport default function (\n teachers: Skola24Types.teacher[],\n warnings: string[],\n errors: string[]\n): OutTypes.teacher[] {\n\n return teachers.map(x => ({\n ids: x.PK.toString(),\n displayName: x.FirstName && x.LastName ? x.FirstName + ' ' + x.LastName : x.ID\n }));\n}\n"],"mappings":";AAGA,0BACE,UACA,UACA,QACoB;AAEpB,QAAO,SAAS,KAAI,OAAM;EACxB,KAAa,EAAE,GAAG;
|
|
1
|
+
{"version":3,"file":"teachers.js","names":[],"sources":["../../../../src/Skola24/mdb/from/teachers.ts"],"sourcesContent":["import type { Types as Skola24Types } from '../types';\nimport type { OutTypes } from './schedule';\n\nexport default function (\n teachers: Skola24Types.teacher[],\n warnings: string[],\n errors: string[]\n): OutTypes.teacher[] {\n\n return teachers.map(x => ({\n ids: x.PK.toString(),\n displayName: x.FirstName && x.LastName ? x.FirstName + ' ' + x.LastName : x.ID\n }));\n}\n"],"mappings":";AAGA,0BACE,UACA,UACA,QACoB;AAEpB,QAAO,SAAS,KAAI,OAAM;EACxB,KAAa,EAAE,GAAG,UAAU;EAC5B,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,MAAM,EAAE,WAAW,EAAE;EAC7E,EAAE"}
|
|
@@ -41,8 +41,7 @@ function parseCalendarExceptions(period, startYear, warnings) {
|
|
|
41
41
|
for (let i = 0; i < allowedRanges.length - 1; i++) {
|
|
42
42
|
const x = allowedRanges[i];
|
|
43
43
|
const y = allowedRanges[i + 1];
|
|
44
|
-
|
|
45
|
-
if (diff <= 2) {
|
|
44
|
+
if (y.start.diff(x.end) <= 2) {
|
|
46
45
|
x.end = moment.max(x.end, y.end);
|
|
47
46
|
allowedRanges.splice(i + 1, 1);
|
|
48
47
|
i--;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calendar-exceptions.js","names":["exceptions: { start: moment.Moment, end: moment.Moment }[]"],"sources":["../../../../src/Skola24/txt/from/calendar-exceptions.ts"],"sourcesContent":["import moment from 'moment';\nimport type { Types, Warning } from '../types';\nimport type { OutTypes } from './schedules';\n\nexport function parseCalendarExceptions (\n period: Types.periodGeneral | undefined,\n startYear: number,\n warnings: Warning[]\n): OutTypes.settings['calendarExceptions'] {\n if (!period) return [];\n\n // should warn only once\n let warned = false;\n\n // parse range\n const allowedRanges = (period.SchoolYear ?? '')\n .split(',')\n // parse each range\n .map(x => {\n // date ranges on the form \"20/8-23/8\"\n const [_start, _end] = x.split('-');\n if (!_start || !_end) return;\n\n const start = moment.utc(`${_start}/${startYear}`, 'DD/MM/YYYY').startOf('day');\n const end = moment.utc(`${_end}/${startYear}`, 'DD/MM/YYYY').endOf ('day');\n if (!start.isValid() || !end.isValid()) {\n if (warned) return;\n warned = true;\n warnings.push({\n code: 'calendarExceptions.problem_parsing_range',\n context: period\n });\n return;\n }\n\n return { start, end };\n })\n .filter((x): x is NonNullable<typeof x> => !!x)\n // make the ranges ordered by incrementing by a year if needed\n .reduce<{ start: moment.Moment, end: moment.Moment }[]>((acc, x) => {\n const prev = acc.at(-1);\n if (!prev) {\n acc.push(x);\n } else {\n while (prev.end.isAfter(x.start)) {\n x.start.add(1, 'year');\n x.end .add(1, 'year');\n }\n acc.push(x);\n }\n return acc;\n }, []);\n\n // extend the range to whole week if the end is a friday\n for (let i = 1; i < allowedRanges.length - 1; i++) {\n const x = allowedRanges[i];\n\n if (x.end.isoWeekday() === 5) {\n x.end = x.end.add(2, 'days');\n }\n };\n\n // merge ranges if they are adjacent or overlapping (the latter is not expected)\n for (let i = 0; i < allowedRanges.length - 1; i++) {\n const x = allowedRanges[i];\n const y = allowedRanges[i + 1];\n\n const diff = y.start.diff(x.end); // 1 ms if adjacent, negative if overlapping\n if (diff <= 2) {\n x.end = moment.max(x.end, y.end);\n allowedRanges.splice(i + 1, 1);\n i--;\n }\n }\n\n // invert the allowed ranges to get the exceptions\n const exceptions: { start: moment.Moment, end: moment.Moment }[] = [];\n for (let i = 0; i < allowedRanges.length - 1; i++) {\n const x = allowedRanges[i];\n const y = allowedRanges[i + 1];\n exceptions.push({\n start: x.end .add (1, 'day').startOf('day'),\n end: y.start.subtract(1, 'day').endOf ('day'),\n });\n }\n\n return exceptions.map(x => ({\n start: x.start.toISOString(),\n end: x.end .toISOString(),\n }));\n}"],"mappings":";;;AAIA,SAAgB,wBACd,QACA,WACA,UACyC;AACzC,KAAI,CAAC,OAAQ,QAAO;
|
|
1
|
+
{"version":3,"file":"calendar-exceptions.js","names":["exceptions: { start: moment.Moment, end: moment.Moment }[]"],"sources":["../../../../src/Skola24/txt/from/calendar-exceptions.ts"],"sourcesContent":["import moment from 'moment';\nimport type { Types, Warning } from '../types';\nimport type { OutTypes } from './schedules';\n\nexport function parseCalendarExceptions (\n period: Types.periodGeneral | undefined,\n startYear: number,\n warnings: Warning[]\n): OutTypes.settings['calendarExceptions'] {\n if (!period) return [];\n\n // should warn only once\n let warned = false;\n\n // parse range\n const allowedRanges = (period.SchoolYear ?? '')\n .split(',')\n // parse each range\n .map(x => {\n // date ranges on the form \"20/8-23/8\"\n const [_start, _end] = x.split('-');\n if (!_start || !_end) return;\n\n const start = moment.utc(`${_start}/${startYear}`, 'DD/MM/YYYY').startOf('day');\n const end = moment.utc(`${_end}/${startYear}`, 'DD/MM/YYYY').endOf ('day');\n if (!start.isValid() || !end.isValid()) {\n if (warned) return;\n warned = true;\n warnings.push({\n code: 'calendarExceptions.problem_parsing_range',\n context: period\n });\n return;\n }\n\n return { start, end };\n })\n .filter((x): x is NonNullable<typeof x> => !!x)\n // make the ranges ordered by incrementing by a year if needed\n .reduce<{ start: moment.Moment, end: moment.Moment }[]>((acc, x) => {\n const prev = acc.at(-1);\n if (!prev) {\n acc.push(x);\n } else {\n while (prev.end.isAfter(x.start)) {\n x.start.add(1, 'year');\n x.end .add(1, 'year');\n }\n acc.push(x);\n }\n return acc;\n }, []);\n\n // extend the range to whole week if the end is a friday\n for (let i = 1; i < allowedRanges.length - 1; i++) {\n const x = allowedRanges[i];\n\n if (x.end.isoWeekday() === 5) {\n x.end = x.end.add(2, 'days');\n }\n };\n\n // merge ranges if they are adjacent or overlapping (the latter is not expected)\n for (let i = 0; i < allowedRanges.length - 1; i++) {\n const x = allowedRanges[i];\n const y = allowedRanges[i + 1];\n\n const diff = y.start.diff(x.end); // 1 ms if adjacent, negative if overlapping\n if (diff <= 2) {\n x.end = moment.max(x.end, y.end);\n allowedRanges.splice(i + 1, 1);\n i--;\n }\n }\n\n // invert the allowed ranges to get the exceptions\n const exceptions: { start: moment.Moment, end: moment.Moment }[] = [];\n for (let i = 0; i < allowedRanges.length - 1; i++) {\n const x = allowedRanges[i];\n const y = allowedRanges[i + 1];\n exceptions.push({\n start: x.end .add (1, 'day').startOf('day'),\n end: y.start.subtract(1, 'day').endOf ('day'),\n });\n }\n\n return exceptions.map(x => ({\n start: x.start.toISOString(),\n end: x.end .toISOString(),\n }));\n}"],"mappings":";;;AAIA,SAAgB,wBACd,QACA,WACA,UACyC;AACzC,KAAI,CAAC,OAAQ,QAAO,EAAE;CAGtB,IAAI,SAAS;CAGb,MAAM,iBAAiB,OAAO,cAAc,IACzC,MAAM,IAAI,CAEV,KAAI,MAAK;EAER,MAAM,CAAC,QAAQ,QAAQ,EAAE,MAAM,IAAI;AACnC,MAAI,CAAC,UAAU,CAAC,KAAM;EAEtB,MAAM,QAAQ,OAAO,IAAI,GAAG,OAAO,GAAG,aAAa,aAAa,CAAC,QAAQ,MAAM;EAC/E,MAAM,MAAQ,OAAO,IAAI,GAAG,KAAK,GAAG,aAAe,aAAa,CAAC,MAAQ,MAAM;AAC/E,MAAI,CAAC,MAAM,SAAS,IAAI,CAAC,IAAI,SAAS,EAAE;AACtC,OAAI,OAAQ;AACZ,YAAS;AACT,YAAS,KAAK;IACZ,MAAS;IACT,SAAS;IACV,CAAC;AACF;;AAGF,SAAO;GAAE;GAAO;GAAK;GACrB,CACD,QAAQ,MAAkC,CAAC,CAAC,EAAE,CAE9C,QAAwD,KAAK,MAAM;EAClE,MAAM,OAAO,IAAI,GAAG,GAAG;AACvB,MAAI,CAAC,KACH,KAAI,KAAK,EAAE;OACN;AACL,UAAO,KAAK,IAAI,QAAQ,EAAE,MAAM,EAAE;AAChC,MAAE,MAAM,IAAI,GAAG,OAAO;AACtB,MAAE,IAAM,IAAI,GAAG,OAAO;;AAExB,OAAI,KAAK,EAAE;;AAEb,SAAO;IACN,EAAE,CAAC;AAGR,MAAK,IAAI,IAAI,GAAG,IAAI,cAAc,SAAS,GAAG,KAAK;EACjD,MAAM,IAAI,cAAc;AAExB,MAAI,EAAE,IAAI,YAAY,KAAK,EACzB,GAAE,MAAM,EAAE,IAAI,IAAI,GAAG,OAAO;;AAKhC,MAAK,IAAI,IAAI,GAAG,IAAI,cAAc,SAAS,GAAG,KAAK;EACjD,MAAM,IAAI,cAAc;EACxB,MAAM,IAAI,cAAc,IAAI;AAG5B,MADa,EAAE,MAAM,KAAK,EAAE,IAAI,IACpB,GAAG;AACb,KAAE,MAAM,OAAO,IAAI,EAAE,KAAK,EAAE,IAAI;AAChC,iBAAc,OAAO,IAAI,GAAG,EAAE;AAC9B;;;CAKJ,MAAMA,aAA6D,EAAE;AACrE,MAAK,IAAI,IAAI,GAAG,IAAI,cAAc,SAAS,GAAG,KAAK;EACjD,MAAM,IAAI,cAAc;EACxB,MAAM,IAAI,cAAc,IAAI;AAC5B,aAAW,KAAK;GACd,OAAO,EAAE,IAAM,IAAS,GAAG,MAAM,CAAC,QAAQ,MAAM;GAChD,KAAO,EAAE,MAAM,SAAS,GAAG,MAAM,CAAC,MAAQ,MAAM;GACjD,CAAC;;AAGJ,QAAO,WAAW,KAAI,OAAM;EAC1B,OAAO,EAAE,MAAM,aAAa;EAC5B,KAAO,EAAE,IAAM,aAAa;EAC7B,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"division.js","names":["division: Partial<Pick<CoreTypes.Serialized.Division, 'displayName' | 'start' | 'end'>>","division"],"sources":["../../../../src/Skola24/txt/from/division.ts"],"sourcesContent":["import moment from 'moment';\nimport type { CoreTypes } from '../../../core';\nimport { getStartYear } from './util';\n\n\nexport function extractDivisionName (input: string): undefined | Pick<CoreTypes.Serialized.Division, 'displayName'> {\n // extract base and offset year\n const displayName = input.match(/^School=(.+)$/m)\n ?.at(1)\n ?.trim();\n\n return displayName ? { displayName } : undefined;\n}\n\nexport function extractStartAndEnd (input: string): undefined | Pick<CoreTypes.Serialized.Division, 'start' | 'end'> {\n\n // extract the PeriodGeneral table content\n const match = input.match(/PeriodGeneral \\((?:\\d+)\\)(?:\\r\\n|\\r|\\n)\\[Rows\\](?:\\r\\n|\\r|\\n)SchoolYear \\((?:\\d+)\\)(?:\\r\\n|\\r|\\n)([^\\n]*)/);\n if (!match) return;\n\n // date rangers on the form \"20/8-23/8, 26/8-30/8, ..., 9/6-13/6\"\n const dateRanges = match.at(1)?.trim();\n if (!dateRanges) return;\n\n // extract the first date of the first range and the last date of the last range\n const _start = dateRanges.match(/(\\d{1,2}\\/\\d{1,2})/) ?.at(1);\n const _end = dateRanges.match(/(\\d{1,2}\\/\\d{1,2})$/)?.at(1);\n if (!_start || !_end) return;\n\n // format the dates to YYYY-MM-DD using moment\n const startYear = getStartYear(input);\n if (!startYear) return;\n const start = moment.utc(`${_start}/${startYear}`, 'DD/MM/YYYY').startOf('day');\n const end = moment.utc(`${_end}/${startYear}`, 'DD/MM/YYYY') .endOf ('day');\n if (!start.isValid() || !end.isValid()) return;\n\n // if the start date is after the end date, increase the year of the end date\n while (start.isAfter(end)) end.add(1, 'year');\n\n return { start, end };\n}\n\nexport const division = (input: unknown): Partial<Pick<CoreTypes.Serialized.Division, 'displayName' | 'start' | 'end'>> => {\n const division: Partial<Pick<CoreTypes.Serialized.Division, 'displayName' | 'start' | 'end'>> = {};\n if (typeof input !== 'string') return division;\n\n // division name\n {\n const x = extractDivisionName(input);\n if (x) Object.assign(division, x);\n }\n\n // division range\n {\n const x = extractStartAndEnd(input);\n if (x) Object.assign(division, x);\n }\n\n return division;\n};"],"mappings":";;;;AAKA,SAAgB,oBAAqB,OAA+E;CAElH,MAAM,cAAc,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"division.js","names":["division: Partial<Pick<CoreTypes.Serialized.Division, 'displayName' | 'start' | 'end'>>","division"],"sources":["../../../../src/Skola24/txt/from/division.ts"],"sourcesContent":["import moment from 'moment';\nimport type { CoreTypes } from '../../../core';\nimport { getStartYear } from './util';\n\n\nexport function extractDivisionName (input: string): undefined | Pick<CoreTypes.Serialized.Division, 'displayName'> {\n // extract base and offset year\n const displayName = input.match(/^School=(.+)$/m)\n ?.at(1)\n ?.trim();\n\n return displayName ? { displayName } : undefined;\n}\n\nexport function extractStartAndEnd (input: string): undefined | Pick<CoreTypes.Serialized.Division, 'start' | 'end'> {\n\n // extract the PeriodGeneral table content\n const match = input.match(/PeriodGeneral \\((?:\\d+)\\)(?:\\r\\n|\\r|\\n)\\[Rows\\](?:\\r\\n|\\r|\\n)SchoolYear \\((?:\\d+)\\)(?:\\r\\n|\\r|\\n)([^\\n]*)/);\n if (!match) return;\n\n // date rangers on the form \"20/8-23/8, 26/8-30/8, ..., 9/6-13/6\"\n const dateRanges = match.at(1)?.trim();\n if (!dateRanges) return;\n\n // extract the first date of the first range and the last date of the last range\n const _start = dateRanges.match(/(\\d{1,2}\\/\\d{1,2})/) ?.at(1);\n const _end = dateRanges.match(/(\\d{1,2}\\/\\d{1,2})$/)?.at(1);\n if (!_start || !_end) return;\n\n // format the dates to YYYY-MM-DD using moment\n const startYear = getStartYear(input);\n if (!startYear) return;\n const start = moment.utc(`${_start}/${startYear}`, 'DD/MM/YYYY').startOf('day');\n const end = moment.utc(`${_end}/${startYear}`, 'DD/MM/YYYY') .endOf ('day');\n if (!start.isValid() || !end.isValid()) return;\n\n // if the start date is after the end date, increase the year of the end date\n while (start.isAfter(end)) end.add(1, 'year');\n\n return { start, end };\n}\n\nexport const division = (input: unknown): Partial<Pick<CoreTypes.Serialized.Division, 'displayName' | 'start' | 'end'>> => {\n const division: Partial<Pick<CoreTypes.Serialized.Division, 'displayName' | 'start' | 'end'>> = {};\n if (typeof input !== 'string') return division;\n\n // division name\n {\n const x = extractDivisionName(input);\n if (x) Object.assign(division, x);\n }\n\n // division range\n {\n const x = extractStartAndEnd(input);\n if (x) Object.assign(division, x);\n }\n\n return division;\n};"],"mappings":";;;;AAKA,SAAgB,oBAAqB,OAA+E;CAElH,MAAM,cAAc,MAAM,MAAM,iBAAiB,EAC7C,GAAG,EAAE,EACL,MAAM;AAEV,QAAO,cAAc,EAAE,aAAa,GAAG;;AAGzC,SAAgB,mBAAoB,OAAiF;CAGnH,MAAM,QAAQ,MAAM,MAAM,4GAA4G;AACtI,KAAI,CAAC,MAAO;CAGZ,MAAM,aAAa,MAAM,GAAG,EAAE,EAAE,MAAM;AACtC,KAAI,CAAC,WAAY;CAGjB,MAAM,SAAS,WAAW,MAAM,qBAAqB,EAAG,GAAG,EAAE;CAC7D,MAAM,OAAS,WAAW,MAAM,sBAAsB,EAAE,GAAG,EAAE;AAC7D,KAAI,CAAC,UAAU,CAAC,KAAM;CAGtB,MAAM,YAAY,aAAa,MAAM;AACrC,KAAI,CAAC,UAAW;CAChB,MAAM,QAAQ,OAAO,IAAI,GAAG,OAAO,GAAG,aAAa,aAAa,CAAC,QAAQ,MAAM;CAC/E,MAAM,MAAQ,OAAO,IAAI,GAAG,KAAK,GAAG,aAAa,aAAa,CAAG,MAAQ,MAAM;AAC/E,KAAI,CAAC,MAAM,SAAS,IAAI,CAAC,IAAI,SAAS,CAAE;AAGxC,QAAO,MAAM,QAAQ,IAAI,CAAE,KAAI,IAAI,GAAG,OAAO;AAE7C,QAAO;EAAE;EAAO;EAAK;;AAGvB,MAAa,YAAY,UAAkG;CACzH,MAAMA,aAA0F,EAAE;AAClG,KAAI,OAAO,UAAU,SAAU,QAAOC;CAGtC;EACE,MAAM,IAAI,oBAAoB,MAAM;AACpC,MAAI,EAAG,QAAO,OAAOA,YAAU,EAAE;;CAInC;EACE,MAAM,IAAI,mBAAmB,MAAM;AACnC,MAAI,EAAG,QAAO,OAAOA,YAAU,EAAE;;AAGnC,QAAOA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/Skola24/txt/from/index.ts"],"sourcesContent":["import type { FromInterface } from '../../../common/types';\nimport { division } from './division';\nimport { schedules } from './schedules';\n\nexport default {\n division: division,\n schedules: schedules\n} satisfies FromInterface;"],"mappings":";;;;AAIA,mBAAe;CACF;CACA"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/Skola24/txt/from/index.ts"],"sourcesContent":["import type { FromInterface } from '../../../common/types';\nimport { division } from './division';\nimport { schedules } from './schedules';\n\nexport default {\n division: division,\n schedules: schedules\n} satisfies FromInterface;"],"mappings":";;;;AAIA,mBAAe;CACF;CACA;CACZ"}
|
|
@@ -38,11 +38,9 @@ function parsePeriod(period, scheduleStart, warnings) {
|
|
|
38
38
|
}
|
|
39
39
|
return acc;
|
|
40
40
|
}, []).map((x) => {
|
|
41
|
-
const start = x.start.startOf("isoWeek");
|
|
42
|
-
const end = x.end.endOf("isoWeek");
|
|
43
41
|
return {
|
|
44
|
-
start,
|
|
45
|
-
end
|
|
42
|
+
start: x.start.startOf("isoWeek"),
|
|
43
|
+
end: x.end.endOf("isoWeek")
|
|
46
44
|
};
|
|
47
45
|
}).filter((x, i, arr) => {
|
|
48
46
|
for (let j = i + 1; j < arr.length; j++) if (x.start.isSame(arr[j].start) && x.end.isSame(arr[j].end)) return false;
|
|
@@ -57,39 +55,38 @@ function parsePeriod(period, scheduleStart, warnings) {
|
|
|
57
55
|
function fromWeekNumberRange(ids, weekNumberRange, scheduleStart) {
|
|
58
56
|
const startYear = scheduleStart.year();
|
|
59
57
|
const scheduleStartWeek = scheduleStart.startOf("isoWeek");
|
|
60
|
-
const ranges = weekNumberRange.split(",").map((x) => {
|
|
61
|
-
const interval = x.split("-").map((x$1) => parseInt(x$1.trim()));
|
|
62
|
-
const startWeekNumber = interval[0];
|
|
63
|
-
const endWeekNumber = interval[1] ?? startWeekNumber;
|
|
64
|
-
const start = moment.utc().isoWeekYear(startYear).isoWeek(startWeekNumber).startOf("isoWeek");
|
|
65
|
-
if (start.isBefore(scheduleStartWeek)) start.add(1, "year").isoWeek(startWeekNumber).startOf("isoWeek");
|
|
66
|
-
const end = moment.utc().isoWeekYear(start.year()).isoWeek(endWeekNumber).endOf("isoWeek");
|
|
67
|
-
if (end.isBefore(start)) end.add(1, "year").isoWeek(endWeekNumber).endOf("isoWeek");
|
|
68
|
-
return [start, end];
|
|
69
|
-
}).reduce((acc, x) => {
|
|
70
|
-
const prev = acc.at(-1);
|
|
71
|
-
if (!prev) acc.push({
|
|
72
|
-
start: x[0],
|
|
73
|
-
end: x[1]
|
|
74
|
-
});
|
|
75
|
-
else {
|
|
76
|
-
while (prev.end.isAfter(x[0])) {
|
|
77
|
-
const startWeekNumber = x[0].isoWeek();
|
|
78
|
-
const endWeekNumber = x[1].isoWeek();
|
|
79
|
-
x[0].add(1, "year").isoWeek(startWeekNumber).startOf("isoWeek");
|
|
80
|
-
x[1].add(1, "year").isoWeek(endWeekNumber).endOf("isoWeek");
|
|
81
|
-
}
|
|
82
|
-
acc.push({
|
|
83
|
-
start: x[0],
|
|
84
|
-
end: x[1]
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
return acc;
|
|
88
|
-
}, []);
|
|
89
58
|
return {
|
|
90
59
|
ids,
|
|
91
60
|
displayName: weekNumberRange,
|
|
92
|
-
ranges
|
|
61
|
+
ranges: weekNumberRange.split(",").map((x) => {
|
|
62
|
+
const interval = x.split("-").map((x$1) => parseInt(x$1.trim()));
|
|
63
|
+
const startWeekNumber = interval[0];
|
|
64
|
+
const endWeekNumber = interval[1] ?? startWeekNumber;
|
|
65
|
+
const start = moment.utc().isoWeekYear(startYear).isoWeek(startWeekNumber).startOf("isoWeek");
|
|
66
|
+
if (start.isBefore(scheduleStartWeek)) start.add(1, "year").isoWeek(startWeekNumber).startOf("isoWeek");
|
|
67
|
+
const end = moment.utc().isoWeekYear(start.year()).isoWeek(endWeekNumber).endOf("isoWeek");
|
|
68
|
+
if (end.isBefore(start)) end.add(1, "year").isoWeek(endWeekNumber).endOf("isoWeek");
|
|
69
|
+
return [start, end];
|
|
70
|
+
}).reduce((acc, x) => {
|
|
71
|
+
const prev = acc.at(-1);
|
|
72
|
+
if (!prev) acc.push({
|
|
73
|
+
start: x[0],
|
|
74
|
+
end: x[1]
|
|
75
|
+
});
|
|
76
|
+
else {
|
|
77
|
+
while (prev.end.isAfter(x[0])) {
|
|
78
|
+
const startWeekNumber = x[0].isoWeek();
|
|
79
|
+
const endWeekNumber = x[1].isoWeek();
|
|
80
|
+
x[0].add(1, "year").isoWeek(startWeekNumber).startOf("isoWeek");
|
|
81
|
+
x[1].add(1, "year").isoWeek(endWeekNumber).endOf("isoWeek");
|
|
82
|
+
}
|
|
83
|
+
acc.push({
|
|
84
|
+
start: x[0],
|
|
85
|
+
end: x[1]
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return acc;
|
|
89
|
+
}, [])
|
|
93
90
|
};
|
|
94
91
|
}
|
|
95
92
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"period.js","names":["x"],"sources":["../../../../src/Skola24/txt/from/period.ts"],"sourcesContent":["import moment from 'moment';\nimport type { Types, Warning } from '../types';\nimport { extractId } from './util';\nimport type { OutTypes } from './schedules';\n\nexport function parsePeriod (\n period: Types.period,\n scheduleStart: moment.Moment,\n warnings: Warning[]\n): OutTypes.period {\n // should warn only once\n let warned = false;\n\n // parse range\n const ranges = (period.Calendar ?? '')\n .split(',')\n // parse each range\n .map(x => {\n // date ranges on the form \"20/8-23/8\"\n const [_start, _end] = x.split('-');\n if (!_start || !_end) return;\n\n const start = moment.utc(`${_start}/${scheduleStart.year()}`, 'DD/MM/YYYY');\n const end = moment.utc(`${_end}/${scheduleStart.year()}`, 'DD/MM/YYYY');\n if (!start.isValid() || !end.isValid()) {\n if (warned) return;\n warned = true;\n warnings.push({\n code: 'period.problem_parsing_range',\n context: period\n });\n return;\n }\n\n // add one year to the range if it is before the schedule start\n if (start.isBefore(scheduleStart)) {\n start.add(1, 'year');\n end .add(1, 'year');\n }\n\n return { start, end };\n })\n .filter((x): x is NonNullable<typeof x> => !!x)\n // make the ranges ordered by incrementing by a year if needed\n .reduce<{ start: moment.Moment, end: moment.Moment }[]>((acc, x) => {\n const prev = acc.at(-1);\n if (!prev) {\n acc.push(x);\n } else {\n while (prev.end.isAfter(x.start)) {\n x.start.add(1, 'year');\n x.end .add(1, 'year');\n }\n acc.push(x);\n }\n return acc;\n }, [])\n // convert to whole week\n .map(x => {\n const start = x.start.startOf('isoWeek');\n const end = x.end .endOf ('isoWeek');\n return { start, end };\n })\n // remove duplicates (if a week was split into two ranges)\n .filter((x, i, arr) => {\n for (let j = i + 1; j < arr.length; j++) {\n if (x.start.isSame(arr[j].start) && x.end.isSame(arr[j].end)) return false;\n }\n return true;\n });\n\n return {\n ids: extractId(period.GUID),\n displayName: period.TextBelowSchedule,\n ranges\n };\n}\n\n\nexport function fromWeekNumberRange (\n ids: string,\n weekNumberRange: string,\n scheduleStart: moment.Moment\n): OutTypes.period {\n const startYear = scheduleStart.year();\n const scheduleStartWeek = scheduleStart.startOf('isoWeek');\n\n const ranges = weekNumberRange\n // parse the range to positive intervals that lie after the schedule start\n .split(',')\n .map(x => {\n const interval = x.split('-').map(x => parseInt(x.trim()));\n const startWeekNumber = interval[0];\n const endWeekNumber = interval[1] ?? startWeekNumber;\n\n const start = moment.utc()\n .isoWeekYear(startYear)\n .isoWeek(startWeekNumber)\n .startOf('isoWeek');\n if (start.isBefore(scheduleStartWeek)) {\n start.add(1, 'year')\n .isoWeek(startWeekNumber)\n .startOf('isoWeek');\n }\n\n const end = moment.utc()\n .isoWeekYear(start.year())\n .isoWeek(endWeekNumber)\n .endOf('isoWeek');\n if (end.isBefore(start)) {\n end.add(1, 'year')\n .isoWeek(endWeekNumber)\n .endOf('isoWeek');\n }\n\n return [ start, end ];\n })\n // make the ranges ordered by incrementing by a year if needed\n .reduce<{ start: moment.Moment, end: moment.Moment }[]>((acc, x) => {\n const prev = acc.at(-1);\n if (!prev) {\n acc.push({ start: x[0], end: x[1] });\n } else {\n while (prev.end.isAfter(x[0])) {\n const startWeekNumber = x[0].isoWeek();\n const endWeekNumber = x[1].isoWeek();\n // preserve the week number\n x[0].add(1, 'year').isoWeek(startWeekNumber).startOf('isoWeek');\n x[1].add(1, 'year').isoWeek(endWeekNumber ).endOf ('isoWeek');\n }\n acc.push({ start: x[0], end: x[1] });\n }\n return acc;\n }, []);\n\n return {\n ids,\n displayName: weekNumberRange,\n ranges: ranges\n };\n}"],"mappings":";;;;AAKA,SAAgB,YACd,QACA,eACA,UACiB;CAEjB,IAAI,SAAS;CAGb,MAAM,UAAU,OAAO,YAAY,IAChC,MAAM,
|
|
1
|
+
{"version":3,"file":"period.js","names":["x"],"sources":["../../../../src/Skola24/txt/from/period.ts"],"sourcesContent":["import moment from 'moment';\nimport type { Types, Warning } from '../types';\nimport { extractId } from './util';\nimport type { OutTypes } from './schedules';\n\nexport function parsePeriod (\n period: Types.period,\n scheduleStart: moment.Moment,\n warnings: Warning[]\n): OutTypes.period {\n // should warn only once\n let warned = false;\n\n // parse range\n const ranges = (period.Calendar ?? '')\n .split(',')\n // parse each range\n .map(x => {\n // date ranges on the form \"20/8-23/8\"\n const [_start, _end] = x.split('-');\n if (!_start || !_end) return;\n\n const start = moment.utc(`${_start}/${scheduleStart.year()}`, 'DD/MM/YYYY');\n const end = moment.utc(`${_end}/${scheduleStart.year()}`, 'DD/MM/YYYY');\n if (!start.isValid() || !end.isValid()) {\n if (warned) return;\n warned = true;\n warnings.push({\n code: 'period.problem_parsing_range',\n context: period\n });\n return;\n }\n\n // add one year to the range if it is before the schedule start\n if (start.isBefore(scheduleStart)) {\n start.add(1, 'year');\n end .add(1, 'year');\n }\n\n return { start, end };\n })\n .filter((x): x is NonNullable<typeof x> => !!x)\n // make the ranges ordered by incrementing by a year if needed\n .reduce<{ start: moment.Moment, end: moment.Moment }[]>((acc, x) => {\n const prev = acc.at(-1);\n if (!prev) {\n acc.push(x);\n } else {\n while (prev.end.isAfter(x.start)) {\n x.start.add(1, 'year');\n x.end .add(1, 'year');\n }\n acc.push(x);\n }\n return acc;\n }, [])\n // convert to whole week\n .map(x => {\n const start = x.start.startOf('isoWeek');\n const end = x.end .endOf ('isoWeek');\n return { start, end };\n })\n // remove duplicates (if a week was split into two ranges)\n .filter((x, i, arr) => {\n for (let j = i + 1; j < arr.length; j++) {\n if (x.start.isSame(arr[j].start) && x.end.isSame(arr[j].end)) return false;\n }\n return true;\n });\n\n return {\n ids: extractId(period.GUID),\n displayName: period.TextBelowSchedule,\n ranges\n };\n}\n\n\nexport function fromWeekNumberRange (\n ids: string,\n weekNumberRange: string,\n scheduleStart: moment.Moment\n): OutTypes.period {\n const startYear = scheduleStart.year();\n const scheduleStartWeek = scheduleStart.startOf('isoWeek');\n\n const ranges = weekNumberRange\n // parse the range to positive intervals that lie after the schedule start\n .split(',')\n .map(x => {\n const interval = x.split('-').map(x => parseInt(x.trim()));\n const startWeekNumber = interval[0];\n const endWeekNumber = interval[1] ?? startWeekNumber;\n\n const start = moment.utc()\n .isoWeekYear(startYear)\n .isoWeek(startWeekNumber)\n .startOf('isoWeek');\n if (start.isBefore(scheduleStartWeek)) {\n start.add(1, 'year')\n .isoWeek(startWeekNumber)\n .startOf('isoWeek');\n }\n\n const end = moment.utc()\n .isoWeekYear(start.year())\n .isoWeek(endWeekNumber)\n .endOf('isoWeek');\n if (end.isBefore(start)) {\n end.add(1, 'year')\n .isoWeek(endWeekNumber)\n .endOf('isoWeek');\n }\n\n return [ start, end ];\n })\n // make the ranges ordered by incrementing by a year if needed\n .reduce<{ start: moment.Moment, end: moment.Moment }[]>((acc, x) => {\n const prev = acc.at(-1);\n if (!prev) {\n acc.push({ start: x[0], end: x[1] });\n } else {\n while (prev.end.isAfter(x[0])) {\n const startWeekNumber = x[0].isoWeek();\n const endWeekNumber = x[1].isoWeek();\n // preserve the week number\n x[0].add(1, 'year').isoWeek(startWeekNumber).startOf('isoWeek');\n x[1].add(1, 'year').isoWeek(endWeekNumber ).endOf ('isoWeek');\n }\n acc.push({ start: x[0], end: x[1] });\n }\n return acc;\n }, []);\n\n return {\n ids,\n displayName: weekNumberRange,\n ranges: ranges\n };\n}"],"mappings":"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"}
|
|
@@ -32,23 +32,19 @@ const parseConfig = {
|
|
|
32
32
|
skipEmptyLines: false
|
|
33
33
|
};
|
|
34
34
|
function extractTables(input, warnings) {
|
|
35
|
-
const
|
|
36
|
-
const tables = split.at(1);
|
|
35
|
+
const tables = input.split("[Tables]").at(1);
|
|
37
36
|
if (!tables) throw new Error("Unable to extract tables from input");
|
|
38
|
-
|
|
39
|
-
const matches = [...tables.trim().matchAll(regex)];
|
|
40
|
-
return matches.map((x) => {
|
|
37
|
+
return [...tables.trim().matchAll(/([^\r\n]+)(?:\r\n|\r|\n)\[Rows\](?:\r\n|\r|\n)((?:[^\r\n].+(?:(?:\r\n|\r|\n)|$))*)/gm)].map((x) => {
|
|
41
38
|
const tableName = x.at(1)?.trim().match(/(.*?)(?:\s*\(\d+\))$/m)?.at(1);
|
|
42
39
|
if (!tableName) return;
|
|
43
40
|
const tableContent = x.at(2)?.trim();
|
|
44
41
|
if (!tableContent) return;
|
|
45
|
-
const parsed = Papa.parse(tableContent, {
|
|
46
|
-
...parseConfig,
|
|
47
|
-
transformHeader
|
|
48
|
-
});
|
|
49
42
|
return {
|
|
50
43
|
tableName,
|
|
51
|
-
parsed:
|
|
44
|
+
parsed: Papa.parse(tableContent, {
|
|
45
|
+
...parseConfig,
|
|
46
|
+
transformHeader
|
|
47
|
+
}).data
|
|
52
48
|
};
|
|
53
49
|
}).filter((x) => x != null).reduce((acc, { tableName, parsed }) => {
|
|
54
50
|
acc[tableName] = parsed;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedules.js","names":["warnings: Warning[]","settings: OutTypes.settings","x","uuidv4","teachers","groups","getDate","newCourse: OutTypes.course"],"sources":["../../../../src/Skola24/txt/from/schedules.ts"],"sourcesContent":["import Papa from 'papaparse';\nimport { v4 as uuidv4 } from 'uuid'; // as we cannot use crypto's randomUUID in browser\nimport moment from 'moment';\nimport getDate from '../../../common/get-date';\nimport type { CoreTypes } from '../../../core';\nimport type { Data, Options, Types as Skola24Types, Warning } from '../types';\nimport { extractId } from './util';\nimport { fromWeekNumberRange, parsePeriod } from './period';\nimport { parseCalendarExceptions } from './calendar-exceptions';\nimport { extractStartAndEnd } from './division';\n\n\nconst daysToIndex = {\n 'Måndag': 0,\n 'Tisdag': 1,\n 'Onsdag': 2,\n 'Torsdag': 3,\n 'Fredag': 4,\n 'Lördag': 5,\n 'Söndag': 6,\n\n // and if ÅÄÖ is loaded correctly\n 'M�ndag': 0,\n 'L�rdag': 5,\n 'S�ndag': 6,\n} as Record<string, number | undefined>;\n\n\nfunction transformHeader (header: string) {\n return header.split(/[^a-zA-Z]+/g)[0];\n}\nconst parseConfig = {\n quotes: false, //or array of booleans\n quoteChar: '\"',\n escapeChar: '\"',\n delimiter: '\\t',\n header: true,\n // newline: \"\\r\\n\",\n skipEmptyLines: false, //other option is 'greedy', meaning skip delimiters, quotes, and whitespace.\n} as Papa.ParseConfig;\n\n\nfunction extractTables (input: string, warnings: Warning[]) {\n // split at [Tables] to get meta section and table section\n const split = input.split('[Tables]');\n const tables = split.at(1);\n if (!tables) throw new Error('Unable to extract tables from input');\n\n ////\n //// Capture the TABLE NAME and the TABLE CONTENT using regex\n ////\n //// TABLE NAME\n //// [Rows]\n //// TABLE CONTENT\n ////\n const regex = /([^\\r\\n]+)(?:\\r\\n|\\r|\\n)\\[Rows\\](?:\\r\\n|\\r|\\n)((?:[^\\r\\n].+(?:(?:\\r\\n|\\r|\\n)|$))*)/gm;\n const matches = [...tables.trim().matchAll(regex)];\n\n return matches\n .map(x => {\n // extract only the true table name \"<table name> (<number>)\", i.e., ignore the brackets and the preceding space\n const tableName = x.at(1)\n ?.trim()\n .match(/(.*?)(?:\\s*\\(\\d+\\))$/m)\n ?.at(1);\n if (!tableName) return;\n\n const tableContent = x.at(2)?.trim();\n if (!tableContent) return;\n const parsed = Papa.parse(tableContent, { ...parseConfig, transformHeader });\n return {\n tableName: tableName as keyof Data,\n parsed: parsed.data\n };\n })\n .filter((x): x is NonNullable<typeof x> => x != null)\n .reduce<Data>((acc, { tableName, parsed }) => {\n acc[tableName] = parsed;\n return acc;\n }, {} as Data);\n}\n\n\nfunction parseColor (colorValue: string | undefined) {\n if (colorValue == null) return;\n\n const integerValue = parseInt(colorValue);\n if (isNaN(integerValue)) return;\n\n // convert to decimal string\n const hex = integerValue.toString(16);\n\n // ensure its a valid color\n if (!/^(?:[0-9a-fA-F]{3}){1,2}$/.test(hex)) return;\n return `#${ hex }`;\n}\n\n\nexport namespace OutTypes {\n export type settings = CoreTypes.SerializedWithOptionalId.Settings;\n export type teacher = CoreTypes.SerializedWithOptionalId.Teacher;\n export type person = CoreTypes.SerializedWithOptionalId.Person;\n export type group = CoreTypes.SerializedWithOptionalId.Group;\n export type course = CoreTypes.SerializedWithOptionalId.Course;\n export type location = CoreTypes.SerializedWithOptionalId.Location;\n export type event = CoreTypes.SerializedWithOptionalId.Event;\n export type period = CoreTypes.SerializedWithOptionalId.Period;\n}\n\ntype Out = {\n settings: OutTypes.settings;\n periods: OutTypes.period [];\n teachers: OutTypes.teacher [];\n persons: OutTypes.person [];\n groups: OutTypes.group [];\n locations: OutTypes.location[];\n courses: OutTypes.course [];\n events: OutTypes.event [];\n meta?: {\n warnings: Warning[]\n };\n};\n\n\nexport const schedules = (\n input: string,\n options: Options = {}\n): Out => {\n const warnings: Warning[] = [];\n\n const tables = extractTables(input, warnings);\n\n const _scheduleRange = extractStartAndEnd(input); // need whole input file\n if (!_scheduleRange) throw new Error('Unable to extract schedule range');\n\n const scheduleStart = moment.utc(_scheduleRange.start);\n const startYear = scheduleStart.year();\n\n const settings: OutTypes.settings = {\n discretization: 5,\n numDays: 5,\n dayStart: '8:00',\n potentialCenter: '12:00',\n dayEnd: '17:00',\n calendarExceptions: parseCalendarExceptions(tables.PeriodGeneral?.at(0), startYear, warnings)\n };\n\n\n // Map to core structure\n const teachers = tables.Teacher\n ?.map((x): OutTypes.teacher => ({\n ids: extractId(x.GUID),\n signature: x.Teacher,\n displayName: `${x.FirstName} ${x.LastName}`,\n ...x.Category && {\n tags: [\n {\n type: 'category',\n value: x.Category\n }\n ]\n },\n person: `teacher.${ extractId(x.GUID) }`\n }));\n const teacherPersons = tables.Teacher\n // Filter out where either of firstname, lastname i missing, else it gives invalid persons\n ?.filter(x => x.FirstName && x.LastName)\n ?.map((x): OutTypes.person => ({\n ids: `teacher.${ extractId(x.GUID) }`,\n firstName: x.FirstName,\n lastName: x.LastName,\n ...x.PersonalCode && {\n SSN: {\n value: x.PersonalCode,\n }\n },\n ...x.EMail && {\n emails: [{\n value: x.EMail,\n type: 'organization'\n }]\n },\n ...x.Phone && {\n phoneNumbers: [\n {\n value: x.Phone,\n type: 'organization'\n }\n ]\n }\n }));\n\n const studentMap = new Map<string, string>();\n // create map of student SSN to student GUID\n tables.Student?.forEach(x => {\n const id = extractId(x.GUID);\n if (id) studentMap.set(x.Student, id);\n });\n\n const students = tables.Student?.map((x): OutTypes.person => ({\n ids: extractId(x.GUID),\n firstName: x.FirstName,\n lastName: x.LastName,\n type: 'Student',\n ...x.Student && {\n SSN: {\n value: x.Student,\n }\n },\n ...x.EMail && {\n emails: [{\n value: x.EMail,\n type: 'organization'\n }]\n }\n }));\n\n const groups = tables.Group?.map((x): OutTypes.group => ({\n ids: extractId(x.GUID),\n displayName: x.Group,\n ...(x.Class == '1') && { species: 'class' },\n members: x.Student?.split(',').map(x => studentMap.get(x)).filter(x => x != null) ?? []\n }));\n\n const periodMap = new Map<string, string>();\n const periodsFromWeekRanges = new Set<string>();\n if (tables.Period) {\n tables.Period.forEach(period => {\n const id = extractId(period.GUID);\n if (id) periodMap.set(period.Period, id);\n });\n\n // create additional periods corresponding to the lessons' week/actual weeks\n const _createPeriodsFrom = options.createPeriodsFrom;\n if (_createPeriodsFrom) {\n tables.Lesson?.forEach(x => {\n const key = x[_createPeriodsFrom];\n if (key) periodsFromWeekRanges.add(key);\n });\n periodsFromWeekRanges.forEach(x => periodMap.set(x, uuidv4()));\n }\n }\n\n const teacherMap = new Map<string, string>();\n if (tables.Teacher) {\n tables.Teacher.forEach(teacher => {\n const id = extractId(teacher.GUID);\n if (id) teacherMap.set(teacher.Teacher, id);\n });\n }\n\n const groupMap = new Map<string, string>();\n if (tables.Group) {\n tables.Group.forEach(group => {\n const id = extractId(group.GUID);\n if (id) groupMap.set(group.Group, id);\n });\n }\n\n const locationMap = new Map<string, string>();\n if (tables.Room) {\n tables.Room.forEach(room => {\n const id = extractId(room.GUID);\n if (id) locationMap.set(room.Room, id);\n });\n }\n\n // subject contains BackgroundColor(decimal) and FullText\n const subjectMap = new Map<string, Skola24Types.subject>();\n if (tables.Subject) {\n tables.Subject.forEach(subject => {\n subjectMap.set(subject.Subject, subject);\n });\n }\n\n // Course can contain FullText and Subject\n const parentCourseMap = new Map<string, Skola24Types.course>();\n if (tables.Course) {\n tables.Course.forEach(course => {\n parentCourseMap.set(course.Course, course);\n });\n }\n\n const courseMap = new Map<string, string | undefined>();\n const courses = tables.TA?.map((x): OutTypes.course => {\n const color = parseColor(subjectMap.get(x.Subject)?.BackgroundColor);\n\n // Course name is most specific (eg Administration 1), then subject name (Administration), then course code (eg ADMADM01), then subject code (eg ADM)\n const displayName = parentCourseMap.get(x.Course)?.FullText || subjectMap.get(x.Subject)?.FullText || x.Course || x.Subject;\n\n const teachers = (x.Teacher ?? [])\n .split(',')\n .map(x => teacherMap.get(x.trim()))\n .filter((x): x is NonNullable<typeof x> => !!x)\n .map(to => ({ to }));\n const groups = (x.Group ?? [])\n .split(',')\n .map(x => groupMap.get(x.trim()))\n .filter((x): x is NonNullable<typeof x> => !!x)\n .map(to => ({ to }));\n\n return {\n ids: x.GUID ? extractId(x.GUID) : uuidv4(),\n displayName: displayName,\n color: color,\n subject: x.Subject || parentCourseMap.get(x.Course)?.Subject,\n teachers: teachers,\n groups: groups,\n plannedDuration: x.TotalHours ? `${x.TotalHours} hrs` : (x.Weektime ? `${x.Weektime} min/week` : undefined),\n ...x.Period && { period: periodMap.get(x.Period) },\n } satisfies OutTypes.course;\n }) ?? [];\n\n tables.TA?.forEach(x => {\n courseMap.set(`${x.Subject}.${x.Teacher}.${x.Group}`, x.GUID ? extractId(x.GUID) : undefined);\n });\n\n const locations = tables.Room?.map((x): OutTypes.location => ({\n ids: extractId(x.GUID),\n displayName: x.Room,\n maximumCapacity: x.SeatingCapacity ? parseInt(x.SeatingCapacity) : undefined,\n ...x.Category?.length && {\n tags: [\n {\n type: 'category',\n value: x.Category\n }\n ]\n }\n }));\n\n let lessonMissingCourseWarningsCount = 0;\n\n const events = tables.Lesson\n ?.filter(x => !isNaN(parseInt(x.Length)))\n .map(x => {\n\n const position = (() => {\n const dayIndex = daysToIndex[x.DayOfWeek];\n\n if (dayIndex == null) {\n warnings.push({ code: 'lesson.invalid_day', context: x } satisfies Warning);\n return;\n }\n\n return {\n start: getDate(dayIndex, x.Starttime),\n end: getDate(dayIndex, x.Starttime).add(x.Length, 'minutes'),\n };\n })();\n\n const periodName = options.createPeriodsFrom ? x[options.createPeriodsFrom] : x.Period;\n const periodId = periodMap.get(periodName);\n\n const courseKey = `${x.Subject}.${x.Teacher}.${x.Group}`;\n let courseId = courseMap.get(courseKey);\n\n const inLocations = (x.Room ?? [])\n .split(',')\n .map(x => locationMap.get(x.trim()))\n .filter((x): x is NonNullable<typeof x> => !!x);\n\n // if there is a connected course use its display name\n let displayName = courseId\n ? undefined\n : parentCourseMap.get(x.Course)?.FullText || subjectMap.get(x.Subject)?.FullText || x.Course || x.Subject;\n\n // if there is a connected course use its teachers\n const teachers = courseId\n ? undefined\n : x.Teacher\n ?.split(',')\n .map(x => teacherMap.get(x.trim()))\n .filter((x): x is NonNullable<typeof x> => !!x)\n .map(to => ({ to }));\n\n // if there is a connected course use its groups\n const groups = courseId\n ? undefined\n : x.Group\n ?.split(',')\n .map(x => groupMap.get(x.trim()))\n .filter((x): x is NonNullable<typeof x> => !!x)\n .map(to => ({ to }));\n\n const duration = x.Length ? parseInt(x.Length) : undefined;\n\n // If no courseId found, we handle it according to options.includeEventsMissingCourse\n if (!courseId && options.includeEventsMissingCourse) {\n // Create a new course for this event\n courseId = uuidv4();\n const subject = subjectMap.get(x.Subject);\n const subjectName = subject?.FullText || x.Subject;\n displayName = displayName || subject?.FullText || x.Subject;\n const newCourse: OutTypes.course = {\n ids: courseId,\n displayName: displayName,\n subject: subjectName,\n teachers: teachers,\n groups: groups,\n };\n courses?.push(newCourse);\n } else if (!courseId) {\n lessonMissingCourseWarningsCount += 1;\n return null; // will be filtered out later\n }\n\n return {\n ids: extractId(x.GUID),\n displayName: displayName,\n ...position,\n duration: duration,\n preferredDuration: duration ?? 0,\n course: courseId,\n period: periodId,\n inLocations,\n ...(!options.includeEventsMissingCourse ? { teachers, groups } : undefined),\n } satisfies OutTypes.event;\n }).filter((x): x is NonNullable<typeof x> => x != null);\n\n const periods = tables.Period\n ?.map(x => parsePeriod(x, scheduleStart, warnings))\n .filter(x => x.ranges.length > 0);\n\n periodsFromWeekRanges.forEach(x => {\n const ids = periodMap.get(x);\n if (!ids) {\n throw new Error(`Unable to find period for ${x}`);\n return;\n }\n periods?.push(fromWeekNumberRange(ids, x, scheduleStart));\n });\n\n if (lessonMissingCourseWarningsCount > 0 && !options.includeEventsMissingCourse) {\n warnings.unshift({\n code: 'ignoring_lessons_missing_course',\n context: { count: lessonMissingCourseWarningsCount }\n } satisfies Warning);\n }\n\n return {\n settings,\n periods: periods ?? [],\n teachers: teachers ?? [],\n persons: (students ?? []).concat(teacherPersons ?? []),\n groups: groups ?? [],\n locations: locations ?? [],\n courses: courses ?? [],\n events: events ?? [],\n\n meta: { warnings }\n } satisfies Out;\n};"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"schedules.js","names":["warnings: Warning[]","settings: OutTypes.settings","x","uuidv4","teachers","groups","getDate","newCourse: OutTypes.course"],"sources":["../../../../src/Skola24/txt/from/schedules.ts"],"sourcesContent":["import Papa from 'papaparse';\nimport { v4 as uuidv4 } from 'uuid'; // as we cannot use crypto's randomUUID in browser\nimport moment from 'moment';\nimport getDate from '../../../common/get-date';\nimport type { CoreTypes } from '../../../core';\nimport type { Data, Options, Types as Skola24Types, Warning } from '../types';\nimport { extractId } from './util';\nimport { fromWeekNumberRange, parsePeriod } from './period';\nimport { parseCalendarExceptions } from './calendar-exceptions';\nimport { extractStartAndEnd } from './division';\n\n\nconst daysToIndex = {\n 'Måndag': 0,\n 'Tisdag': 1,\n 'Onsdag': 2,\n 'Torsdag': 3,\n 'Fredag': 4,\n 'Lördag': 5,\n 'Söndag': 6,\n\n // and if ÅÄÖ is loaded correctly\n 'M�ndag': 0,\n 'L�rdag': 5,\n 'S�ndag': 6,\n} as Record<string, number | undefined>;\n\n\nfunction transformHeader (header: string) {\n return header.split(/[^a-zA-Z]+/g)[0];\n}\nconst parseConfig = {\n quotes: false, //or array of booleans\n quoteChar: '\"',\n escapeChar: '\"',\n delimiter: '\\t',\n header: true,\n // newline: \"\\r\\n\",\n skipEmptyLines: false, //other option is 'greedy', meaning skip delimiters, quotes, and whitespace.\n} as Papa.ParseConfig;\n\n\nfunction extractTables (input: string, warnings: Warning[]) {\n // split at [Tables] to get meta section and table section\n const split = input.split('[Tables]');\n const tables = split.at(1);\n if (!tables) throw new Error('Unable to extract tables from input');\n\n ////\n //// Capture the TABLE NAME and the TABLE CONTENT using regex\n ////\n //// TABLE NAME\n //// [Rows]\n //// TABLE CONTENT\n ////\n const regex = /([^\\r\\n]+)(?:\\r\\n|\\r|\\n)\\[Rows\\](?:\\r\\n|\\r|\\n)((?:[^\\r\\n].+(?:(?:\\r\\n|\\r|\\n)|$))*)/gm;\n const matches = [...tables.trim().matchAll(regex)];\n\n return matches\n .map(x => {\n // extract only the true table name \"<table name> (<number>)\", i.e., ignore the brackets and the preceding space\n const tableName = x.at(1)\n ?.trim()\n .match(/(.*?)(?:\\s*\\(\\d+\\))$/m)\n ?.at(1);\n if (!tableName) return;\n\n const tableContent = x.at(2)?.trim();\n if (!tableContent) return;\n const parsed = Papa.parse(tableContent, { ...parseConfig, transformHeader });\n return {\n tableName: tableName as keyof Data,\n parsed: parsed.data\n };\n })\n .filter((x): x is NonNullable<typeof x> => x != null)\n .reduce<Data>((acc, { tableName, parsed }) => {\n acc[tableName] = parsed;\n return acc;\n }, {} as Data);\n}\n\n\nfunction parseColor (colorValue: string | undefined) {\n if (colorValue == null) return;\n\n const integerValue = parseInt(colorValue);\n if (isNaN(integerValue)) return;\n\n // convert to decimal string\n const hex = integerValue.toString(16);\n\n // ensure its a valid color\n if (!/^(?:[0-9a-fA-F]{3}){1,2}$/.test(hex)) return;\n return `#${ hex }`;\n}\n\n\nexport namespace OutTypes {\n export type settings = CoreTypes.SerializedWithOptionalId.Settings;\n export type teacher = CoreTypes.SerializedWithOptionalId.Teacher;\n export type person = CoreTypes.SerializedWithOptionalId.Person;\n export type group = CoreTypes.SerializedWithOptionalId.Group;\n export type course = CoreTypes.SerializedWithOptionalId.Course;\n export type location = CoreTypes.SerializedWithOptionalId.Location;\n export type event = CoreTypes.SerializedWithOptionalId.Event;\n export type period = CoreTypes.SerializedWithOptionalId.Period;\n}\n\ntype Out = {\n settings: OutTypes.settings;\n periods: OutTypes.period [];\n teachers: OutTypes.teacher [];\n persons: OutTypes.person [];\n groups: OutTypes.group [];\n locations: OutTypes.location[];\n courses: OutTypes.course [];\n events: OutTypes.event [];\n meta?: {\n warnings: Warning[]\n };\n};\n\n\nexport const schedules = (\n input: string,\n options: Options = {}\n): Out => {\n const warnings: Warning[] = [];\n\n const tables = extractTables(input, warnings);\n\n const _scheduleRange = extractStartAndEnd(input); // need whole input file\n if (!_scheduleRange) throw new Error('Unable to extract schedule range');\n\n const scheduleStart = moment.utc(_scheduleRange.start);\n const startYear = scheduleStart.year();\n\n const settings: OutTypes.settings = {\n discretization: 5,\n numDays: 5,\n dayStart: '8:00',\n potentialCenter: '12:00',\n dayEnd: '17:00',\n calendarExceptions: parseCalendarExceptions(tables.PeriodGeneral?.at(0), startYear, warnings)\n };\n\n\n // Map to core structure\n const teachers = tables.Teacher\n ?.map((x): OutTypes.teacher => ({\n ids: extractId(x.GUID),\n signature: x.Teacher,\n displayName: `${x.FirstName} ${x.LastName}`,\n ...x.Category && {\n tags: [\n {\n type: 'category',\n value: x.Category\n }\n ]\n },\n person: `teacher.${ extractId(x.GUID) }`\n }));\n const teacherPersons = tables.Teacher\n // Filter out where either of firstname, lastname i missing, else it gives invalid persons\n ?.filter(x => x.FirstName && x.LastName)\n ?.map((x): OutTypes.person => ({\n ids: `teacher.${ extractId(x.GUID) }`,\n firstName: x.FirstName,\n lastName: x.LastName,\n ...x.PersonalCode && {\n SSN: {\n value: x.PersonalCode,\n }\n },\n ...x.EMail && {\n emails: [{\n value: x.EMail,\n type: 'organization'\n }]\n },\n ...x.Phone && {\n phoneNumbers: [\n {\n value: x.Phone,\n type: 'organization'\n }\n ]\n }\n }));\n\n const studentMap = new Map<string, string>();\n // create map of student SSN to student GUID\n tables.Student?.forEach(x => {\n const id = extractId(x.GUID);\n if (id) studentMap.set(x.Student, id);\n });\n\n const students = tables.Student?.map((x): OutTypes.person => ({\n ids: extractId(x.GUID),\n firstName: x.FirstName,\n lastName: x.LastName,\n type: 'Student',\n ...x.Student && {\n SSN: {\n value: x.Student,\n }\n },\n ...x.EMail && {\n emails: [{\n value: x.EMail,\n type: 'organization'\n }]\n }\n }));\n\n const groups = tables.Group?.map((x): OutTypes.group => ({\n ids: extractId(x.GUID),\n displayName: x.Group,\n ...(x.Class == '1') && { species: 'class' },\n members: x.Student?.split(',').map(x => studentMap.get(x)).filter(x => x != null) ?? []\n }));\n\n const periodMap = new Map<string, string>();\n const periodsFromWeekRanges = new Set<string>();\n if (tables.Period) {\n tables.Period.forEach(period => {\n const id = extractId(period.GUID);\n if (id) periodMap.set(period.Period, id);\n });\n\n // create additional periods corresponding to the lessons' week/actual weeks\n const _createPeriodsFrom = options.createPeriodsFrom;\n if (_createPeriodsFrom) {\n tables.Lesson?.forEach(x => {\n const key = x[_createPeriodsFrom];\n if (key) periodsFromWeekRanges.add(key);\n });\n periodsFromWeekRanges.forEach(x => periodMap.set(x, uuidv4()));\n }\n }\n\n const teacherMap = new Map<string, string>();\n if (tables.Teacher) {\n tables.Teacher.forEach(teacher => {\n const id = extractId(teacher.GUID);\n if (id) teacherMap.set(teacher.Teacher, id);\n });\n }\n\n const groupMap = new Map<string, string>();\n if (tables.Group) {\n tables.Group.forEach(group => {\n const id = extractId(group.GUID);\n if (id) groupMap.set(group.Group, id);\n });\n }\n\n const locationMap = new Map<string, string>();\n if (tables.Room) {\n tables.Room.forEach(room => {\n const id = extractId(room.GUID);\n if (id) locationMap.set(room.Room, id);\n });\n }\n\n // subject contains BackgroundColor(decimal) and FullText\n const subjectMap = new Map<string, Skola24Types.subject>();\n if (tables.Subject) {\n tables.Subject.forEach(subject => {\n subjectMap.set(subject.Subject, subject);\n });\n }\n\n // Course can contain FullText and Subject\n const parentCourseMap = new Map<string, Skola24Types.course>();\n if (tables.Course) {\n tables.Course.forEach(course => {\n parentCourseMap.set(course.Course, course);\n });\n }\n\n const courseMap = new Map<string, string | undefined>();\n const courses = tables.TA?.map((x): OutTypes.course => {\n const color = parseColor(subjectMap.get(x.Subject)?.BackgroundColor);\n\n // Course name is most specific (eg Administration 1), then subject name (Administration), then course code (eg ADMADM01), then subject code (eg ADM)\n const displayName = parentCourseMap.get(x.Course)?.FullText || subjectMap.get(x.Subject)?.FullText || x.Course || x.Subject;\n\n const teachers = (x.Teacher ?? [])\n .split(',')\n .map(x => teacherMap.get(x.trim()))\n .filter((x): x is NonNullable<typeof x> => !!x)\n .map(to => ({ to }));\n const groups = (x.Group ?? [])\n .split(',')\n .map(x => groupMap.get(x.trim()))\n .filter((x): x is NonNullable<typeof x> => !!x)\n .map(to => ({ to }));\n\n return {\n ids: x.GUID ? extractId(x.GUID) : uuidv4(),\n displayName: displayName,\n color: color,\n subject: x.Subject || parentCourseMap.get(x.Course)?.Subject,\n teachers: teachers,\n groups: groups,\n plannedDuration: x.TotalHours ? `${x.TotalHours} hrs` : (x.Weektime ? `${x.Weektime} min/week` : undefined),\n ...x.Period && { period: periodMap.get(x.Period) },\n } satisfies OutTypes.course;\n }) ?? [];\n\n tables.TA?.forEach(x => {\n courseMap.set(`${x.Subject}.${x.Teacher}.${x.Group}`, x.GUID ? extractId(x.GUID) : undefined);\n });\n\n const locations = tables.Room?.map((x): OutTypes.location => ({\n ids: extractId(x.GUID),\n displayName: x.Room,\n maximumCapacity: x.SeatingCapacity ? parseInt(x.SeatingCapacity) : undefined,\n ...x.Category?.length && {\n tags: [\n {\n type: 'category',\n value: x.Category\n }\n ]\n }\n }));\n\n let lessonMissingCourseWarningsCount = 0;\n\n const events = tables.Lesson\n ?.filter(x => !isNaN(parseInt(x.Length)))\n .map(x => {\n\n const position = (() => {\n const dayIndex = daysToIndex[x.DayOfWeek];\n\n if (dayIndex == null) {\n warnings.push({ code: 'lesson.invalid_day', context: x } satisfies Warning);\n return;\n }\n\n return {\n start: getDate(dayIndex, x.Starttime),\n end: getDate(dayIndex, x.Starttime).add(x.Length, 'minutes'),\n };\n })();\n\n const periodName = options.createPeriodsFrom ? x[options.createPeriodsFrom] : x.Period;\n const periodId = periodMap.get(periodName);\n\n const courseKey = `${x.Subject}.${x.Teacher}.${x.Group}`;\n let courseId = courseMap.get(courseKey);\n\n const inLocations = (x.Room ?? [])\n .split(',')\n .map(x => locationMap.get(x.trim()))\n .filter((x): x is NonNullable<typeof x> => !!x);\n\n // if there is a connected course use its display name\n let displayName = courseId\n ? undefined\n : parentCourseMap.get(x.Course)?.FullText || subjectMap.get(x.Subject)?.FullText || x.Course || x.Subject;\n\n // if there is a connected course use its teachers\n const teachers = courseId\n ? undefined\n : x.Teacher\n ?.split(',')\n .map(x => teacherMap.get(x.trim()))\n .filter((x): x is NonNullable<typeof x> => !!x)\n .map(to => ({ to }));\n\n // if there is a connected course use its groups\n const groups = courseId\n ? undefined\n : x.Group\n ?.split(',')\n .map(x => groupMap.get(x.trim()))\n .filter((x): x is NonNullable<typeof x> => !!x)\n .map(to => ({ to }));\n\n const duration = x.Length ? parseInt(x.Length) : undefined;\n\n // If no courseId found, we handle it according to options.includeEventsMissingCourse\n if (!courseId && options.includeEventsMissingCourse) {\n // Create a new course for this event\n courseId = uuidv4();\n const subject = subjectMap.get(x.Subject);\n const subjectName = subject?.FullText || x.Subject;\n displayName = displayName || subject?.FullText || x.Subject;\n const newCourse: OutTypes.course = {\n ids: courseId,\n displayName: displayName,\n subject: subjectName,\n teachers: teachers,\n groups: groups,\n };\n courses?.push(newCourse);\n } else if (!courseId) {\n lessonMissingCourseWarningsCount += 1;\n return null; // will be filtered out later\n }\n\n return {\n ids: extractId(x.GUID),\n displayName: displayName,\n ...position,\n duration: duration,\n preferredDuration: duration ?? 0,\n course: courseId,\n period: periodId,\n inLocations,\n ...(!options.includeEventsMissingCourse ? { teachers, groups } : undefined),\n } satisfies OutTypes.event;\n }).filter((x): x is NonNullable<typeof x> => x != null);\n\n const periods = tables.Period\n ?.map(x => parsePeriod(x, scheduleStart, warnings))\n .filter(x => x.ranges.length > 0);\n\n periodsFromWeekRanges.forEach(x => {\n const ids = periodMap.get(x);\n if (!ids) {\n throw new Error(`Unable to find period for ${x}`);\n return;\n }\n periods?.push(fromWeekNumberRange(ids, x, scheduleStart));\n });\n\n if (lessonMissingCourseWarningsCount > 0 && !options.includeEventsMissingCourse) {\n warnings.unshift({\n code: 'ignoring_lessons_missing_course',\n context: { count: lessonMissingCourseWarningsCount }\n } satisfies Warning);\n }\n\n return {\n settings,\n periods: periods ?? [],\n teachers: teachers ?? [],\n persons: (students ?? []).concat(teacherPersons ?? []),\n groups: groups ?? [],\n locations: locations ?? [],\n courses: courses ?? [],\n events: events ?? [],\n\n meta: { warnings }\n } satisfies Out;\n};"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","names":[],"sources":["../../../../src/Skola24/txt/from/util.ts"],"sourcesContent":["\nexport function extractId (id: string) {\n // ensure the id is on the form \"{...}\" where ... is the value to be extracted\n if (id.startsWith('{') && id.endsWith('}')) {\n return id.slice(1, -1);\n }\n throw new Error(`Invalid ID format: ${id}`);\n}\n\n\nexport function getStartYear (input: string): undefined | number {\n // extract base and offset year\n const _baseYear = input.match(/^BaseYear=(\\d{4})$/m) ?.at(1);\n const _offsetYear = input.match(/^OffsetYear=(\\d{1,2})$/m)?.at(1);\n if (_baseYear == null || _offsetYear == null) return;\n\n // the year of the start date\n const startYear = parseInt(_baseYear, 10) + parseInt(_offsetYear, 10);\n if (isNaN(startYear)) return;\n\n return startYear;\n}"],"mappings":";AACA,SAAgB,UAAW,IAAY;AAErC,KAAI,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"util.js","names":[],"sources":["../../../../src/Skola24/txt/from/util.ts"],"sourcesContent":["\nexport function extractId (id: string) {\n // ensure the id is on the form \"{...}\" where ... is the value to be extracted\n if (id.startsWith('{') && id.endsWith('}')) {\n return id.slice(1, -1);\n }\n throw new Error(`Invalid ID format: ${id}`);\n}\n\n\nexport function getStartYear (input: string): undefined | number {\n // extract base and offset year\n const _baseYear = input.match(/^BaseYear=(\\d{4})$/m) ?.at(1);\n const _offsetYear = input.match(/^OffsetYear=(\\d{1,2})$/m)?.at(1);\n if (_baseYear == null || _offsetYear == null) return;\n\n // the year of the start date\n const startYear = parseInt(_baseYear, 10) + parseInt(_offsetYear, 10);\n if (isNaN(startYear)) return;\n\n return startYear;\n}"],"mappings":";AACA,SAAgB,UAAW,IAAY;AAErC,KAAI,GAAG,WAAW,IAAI,IAAI,GAAG,SAAS,IAAI,CACxC,QAAO,GAAG,MAAM,GAAG,GAAG;AAExB,OAAM,IAAI,MAAM,sBAAsB,KAAK;;AAI7C,SAAgB,aAAc,OAAmC;CAE/D,MAAM,YAAc,MAAM,MAAM,sBAAsB,EAAM,GAAG,EAAE;CACjE,MAAM,cAAc,MAAM,MAAM,0BAA0B,EAAE,GAAG,EAAE;AACjE,KAAI,aAAa,QAAQ,eAAe,KAAM;CAG9C,MAAM,YAAY,SAAS,WAAW,GAAG,GAAG,SAAS,aAAa,GAAG;AACrE,KAAI,MAAM,UAAU,CAAE;AAEtB,QAAO"}
|
|
@@ -2,6 +2,7 @@ import { Options, Types, Warning } from "./types/index.js";
|
|
|
2
2
|
import { Types as Types$1 } from "../../core/types/index.js";
|
|
3
3
|
import { OutTypes } from "./from/schedules.js";
|
|
4
4
|
import { export_default } from "./to/index.js";
|
|
5
|
+
import "../../index.js";
|
|
5
6
|
|
|
6
7
|
//#region src/Skola24/txt/index.d.ts
|
|
7
8
|
declare class Map {
|
|
@@ -151,14 +151,9 @@ var schedules_default = (data, options = {}) => {
|
|
|
151
151
|
let period = event.period == null ? course?.period : event.period;
|
|
152
152
|
if (isString(period)) period = periodMap.get(period);
|
|
153
153
|
if (period && !("ranges" in period)) period = void 0;
|
|
154
|
-
const
|
|
155
|
-
const
|
|
156
|
-
const
|
|
157
|
-
const g$1 = event.groups == null ? course?.groups : event.groups;
|
|
158
|
-
const groupIds = g$1?.map((x) => getVertexId(x.to, options));
|
|
159
|
-
const groups$1 = groupIds?.map((id) => groupMap.get(id)).filter(Boolean) ?? [];
|
|
160
|
-
const locationIds = event.inLocations?.map((x) => x ? getVertexId(x, options) : null).filter((x) => x != null);
|
|
161
|
-
const locations$1 = locationIds?.map((id) => locationMap.get(id)).filter(Boolean) ?? [];
|
|
154
|
+
const teachers$1 = ((event.teachers == null ? course?.teachers : event.teachers)?.map((x) => getVertexId(x.to, options)))?.map((id) => teacherMap.get(id)).filter(Boolean) ?? [];
|
|
155
|
+
const groups$1 = ((event.groups == null ? course?.groups : event.groups)?.map((x) => getVertexId(x.to, options)))?.map((id) => groupMap.get(id)).filter(Boolean) ?? [];
|
|
156
|
+
const locations$1 = (event.inLocations?.map((x) => x ? getVertexId(x, options) : null).filter((x) => x != null))?.map((id) => locationMap.get(id)).filter(Boolean) ?? [];
|
|
162
157
|
const dayOfWeek = moment.utc(event.start).toDate().toLocaleDateString("sv-SE", {
|
|
163
158
|
weekday: "long",
|
|
164
159
|
timeZone: "UTC"
|
|
@@ -249,10 +244,8 @@ var schedules_default = (data, options = {}) => {
|
|
|
249
244
|
const totalHoursRegex = /(\d+) hrs/;
|
|
250
245
|
const weekTimeRegex = /(\d+) min\/week/;
|
|
251
246
|
const c = courses?.map((course) => {
|
|
252
|
-
const
|
|
253
|
-
const
|
|
254
|
-
const groupIds = course.groups?.map((x) => getVertexId(x.to, options)).filter(Boolean);
|
|
255
|
-
const groups$1 = groupIds?.map((id) => groupMap.get(id)).filter(Boolean) ?? [];
|
|
247
|
+
const teachers$1 = (course.teachers?.map((x) => getVertexId(x.to, options)).filter(Boolean))?.map((id) => teacherMap.get(id)).filter(Boolean) ?? [];
|
|
248
|
+
const groups$1 = (course.groups?.map((x) => getVertexId(x.to, options)).filter(Boolean))?.map((id) => groupMap.get(id)).filter(Boolean) ?? [];
|
|
256
249
|
const syllabusId = isString(course?.syllabus) ? course.syllabus : course?.syllabus && isObjectIdOrHexString(course?.syllabus) ? (course?.syllabus).toString() : void 0;
|
|
257
250
|
const syllabus = syllabusId ? syllabusMap.get(syllabusId) : course?.syllabus;
|
|
258
251
|
return {
|