     classroom = null
     courses = null
     courseLevels = []
+    courseInteractives = []
     sessions = null
+    interactiveSessions = null
     users = null
     userMap = {}
+    userLevelPlaytimeMap = {}
     Promise.resolve(new Classroom().fetchByCode(classCode))
     .then (model) =>
       classroom = new Classroom({ _id: model.data._id })

      sessions = new LevelSessions()
      Promise.resolve($.when(sessions.fetchForAllClassroomMembers(classroom)...))
    .then (models) =>
      userLevelPlaytimeMap = {}
      for session in sessions.models
        continue unless session.get('state')?.complete
        levelID = session.get('level').original
        userID = session.get('creator')
        userLevelPlaytimeMap[userID] ?= {}
        userLevelPlaytimeMap[userID][levelID] ?= {}
        userLevelPlaytimeMap[userID][levelID] = session.get('playtime')

      userPlaytimes = []
      for userID, user of userMap
        playtimes = [user.get('name') ? 'Anonymous']
        for level in courseLevels
          if userLevelPlaytimeMap[userID]?[level.levelID]?
            rawSeconds = parseInt(userLevelPlaytimeMap[userID][level.levelID])
            hours = Math.floor(rawSeconds / 60 / 60)
            minutes = Math.floor(rawSeconds / 60 - hours * 60)
            seconds = Math.round(rawSeconds - hours * 60 - minutes * 60)
            hours = "0#{hours}" if hours < 10
            minutes = "0#{minutes}" if minutes < 10
            seconds = "0#{seconds}" if seconds < 10
            playtimes.push "#{hours}:#{minutes}:#{seconds}"
          else
            playtimes.push 'Incomplete'
        userPlaytimes.push(playtimes)

      columnLabels = "Username"
      currentLevel = 1
      courseLabelIndexes = CS: 1, GD: 0, WD: 0
      lastCourseIndex = 1
      lastCourseLabel = 'CS1'
      for level in courseLevels
        unless level.courseIndex is lastCourseIndex

          acronym = switch
            when /game-dev/.test(level.courseSlug) then 'GD'
            when /web-dev/.test(level.courseSlug) then 'WD'
            when /chapter/.test(level.courseSlug) then 'CH'
            else 'CS'
          lastCourseLabel = acronym + ++courseLabelIndexes[acronym]
        columnLabels += ",#{lastCourseLabel}.#{currentLevel++} #{level.slug}"
      currentInteractive = 1
      courseLabelIndexes.CH = 1
      lastCourseIndex = 1
      lastCourseLabel = 'CH1'
      for interactive in courseInteractives
        unless interactive.courseIndex is lastCourseIndex
          currentInteractive = 1
          lastCourseIndex = interactive.courseIndex
          acronym = 'CH'
          lastCourseLabel = acronym + ++courseLabelIndexes[acronym]
        columnLabels += ",#{lastCourseLabel}.#{currentInteractive++} #{interactive.interactiveID}"
      csvContent = "data:text/csv;charset=utf-8,#{columnLabels}\n"
      for studentRow in userRows
        csvContent += studentRow.join(',') + "\n"
      csvContent = csvContent.substring(0, csvContent.length - 1)
      encodedUri = encodeURI(csvContent)
