       ; Returns a map containing information to make it easier to remove the
       ; lesson
       {:day day, :rowNum rowNum, :startTime startTime, :endTime endTime,
-       :divElem divElem})))
+       :divElem $divElem})))
 
 (defn- add-module-lesson-group
   "Adds a lesson group of a module to the timetable."

        thElem (.find (nth HTML-Timetable day) "tr > th")]
    (attr thElem "rowspan" nrRows)))

(defn- timetable-mark-lesson-slots-occupied
  "Given a 0-indexed row number obtained by `find-free-row-for-lesson`, marks
   the timeslots for the lesson in that row as occupied."
  [day rowNum startTime endTime modInfo]
  (set! Timetable
        (update-in
          Timetable [day rowNum]
          (fn [ttRow]
            {
              :nrLessons (inc (:nrLessons ttRow))
              :occupied       (reduce (fn [occupiedVec idx]
                                        (assoc occupiedVec idx modInfo))
                                      (:occupied ttRow)
                                      (range startTime endTime))
            }))))

(defn- timetable-mark-lesson-slots-free
  "Marks the timeslots for a lesson as free. The `lessonInfo` parameter must be
   a map with the following keys:

     :day       -> 0-indexed day
     :row       -> 0-indexed row in the day
     :startTime -> 0-indexed start time of the lesson
     :endTime   -> 0-indexed end time of the lesson"
  [lessonInfo]
  (let [day         (:day lessonInfo)
        row         (:rowNum lessonInfo)
        startTime   (:startTime lessonInfo)

  "Returns the 0-indexed row which can accomodate the given lesson (timeslots
   for the lesson are not occupied). If no existing row can accomodate the
   lesson, then the total number of existing rows is returned to indicate that
   a new row must be created.

   The `moduleMapLesson` parameter should be a lesson from the `ModulesMap`
   global"
  [moduleMapLesson]
  (let [ttDay     (get-timetable-day (:day moduleMapLesson))
        startTime (:startTime moduleMapLesson)
        endTime   (:endTime moduleMapLesson)]
    (:rowIndex
      (reduce
        (fn [result ttRow]
          (cond
            (:foundFreeRow result) result
            (zero? (count ttRow))  (assoc result :foundFreeRow true)

            (empty?
              ; Find any existing lessons which overlap with our new lesson.
              ; The row is free if there are no existing overlapping lessons.
              ; 4 types of overlap:
              ;
              ; ONE:
              ;        |-- exist --|
              ; |-- new --|
              ;
              ; TWO:
              ; |-- exist --|
              ;       |-- new --|
              ;
              ; THREE:
              ;     |-- exist --|
              ; |------- new -------|
              ;
              ; FOUR:
              ; |------- exist -------|
              ;      |-- new --|
              (filter (fn [[ttLessonInfo _]]
                        (and (>= (dec endTime) (:startTime ttLessonInfo))
                             (< startTime (:endTime ttLessonInfo))))
                      ttRow))
            (assoc result :foundFreeRow true)

            :else (update-in result [:rowIndex] inc)))
        {:foundFreeRow false, :rowIndex 0}
        ttDay))))

(defn- get-css-hour-minute-classes-for-time
