diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index d1357d43f..e60e37bce 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -160,7 +160,7 @@ class AccountsController < ApplicationController # 发送验证码 # params[:login] 手机号或者邮箱号 - # params[:type]为事件通知类型 1:用户注册注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱 # 如果有新的继续后面加 + # params[:type]为事件通知类型 1:用户注册注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加 # 发送验证码:send_type 1:注册手机验证码 2:找回密码手机验证码 3:找回密码邮箱验证码 4:绑定手机 5:绑定邮箱 # 6:手机验证码登录 7:邮箱验证码登录 8:邮箱注册验证码 9: 验收手机号有效 def get_verification_code @@ -200,7 +200,7 @@ class AccountsController < ApplicationController session[:user_id] = nil end - # type 事件类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱 # 如果有新的继续后面加 + # type 事件类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加 # login_type 1:手机类型 2:邮箱类型 def verify_type login_type, type case type @@ -212,6 +212,8 @@ class AccountsController < ApplicationController login_type == 1 ? 4 : tip_exception('请填写正确的手机号') when 4 login_type == 1 ? tip_exception('请填写正确的邮箱') : 5 + when 5 + login_type == 1 ? 9 : tip_exception('请填写正确的手机号') end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index e825d53da..2e2c7ff56 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -64,10 +64,10 @@ class ApplicationController < ActionController::Base # 发送及记录激活码 # 发送验证码:type 1:注册手机验证码 2:找回密码手机验证码 3:找回密码邮箱验证码 4:绑定手机 5:绑定邮箱 - # 6:手机验证码登录 7:邮箱验证码登录 8:邮箱注册验证码 + # 6:手机验证码登录 7:邮箱验证码登录 8:邮箱注册验证码 9:验证手机号有效 def check_verification_code(code, send_type, value) case send_type - when 1, 2, 4 + when 1, 2, 4, 9 # 手机类型的发送 sigle_para = {phone: value} status = Educoder::Sms.send(mobile: value, code: code) @@ -241,14 +241,18 @@ class ApplicationController < ActionController::Base User.current = User.find 57703 end - if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除 - User.current = User.find 81403 - elsif params[:debug] == 'student' - User.current = User.find 8686 - elsif params[:debug] == 'admin' - User.current = User.find 1 - end + # 测试版前端需求 + logger.info("######domain: #{request.host}") + if request.host == "47.96.87.25" + if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除 + User.current = User.find 81403 + elsif params[:debug] == 'student' + User.current = User.find 8686 + elsif params[:debug] == 'admin' + User.current = User.find 1 + end + end # User.current = User.find 81403 end @@ -583,4 +587,8 @@ class ApplicationController < ActionController::Base def render_parameter_missing render json: { status: -1, message: '参数缺失' } end + + def set_export_cookies + cookies[:fileDownload] = true + end end diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 9ae909dbc..abc3e4856 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -1027,7 +1027,10 @@ class CoursesController < ApplicationController tip_exception(403,"无权限操作") elsif @all_members.size == 0 normal_status(-1,"课堂暂时没有学生") + elsif params[:export].present? && params[:export] + normal_status(0,"正在下载中") else + set_export_cookies member_to_xlsx(@course, @all_members, @c_homeworks, @c_exercises, @c_tasks) filename_ = "#{current_user.real_name}_#{@course.name}_全部成绩_#{Time.now.strftime('%Y%m%d_%H%M%S')}" render xlsx: "#{format_sheet_name filename_.strip}",template: "courses/export_member_scores_excel.xlsx.axlsx", diff --git a/app/controllers/exercises_controller.rb b/app/controllers/exercises_controller.rb index 7c8c07d01..6f121db5f 100644 --- a/app/controllers/exercises_controller.rb +++ b/app/controllers/exercises_controller.rb @@ -1256,9 +1256,12 @@ class ExercisesController < ApplicationController normal_status(-1,"试卷未发布") elsif (@exercise_users_size == 0) || ( @export_ex_users&.exercise_user_committed.size == 0) normal_status(-1,"暂无用户提交") + elsif params[:export].present? && params[:export] + normal_status(0,"正在下载中") else respond_to do |format| format.xlsx{ + set_export_cookies get_export_users(@exercise,@course,@export_ex_users) exercise_export_name_ = "#{current_user.real_name}_#{@course.name}_#{@exercise.exercise_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" @@ -1281,7 +1284,12 @@ class ExercisesController < ApplicationController @exercise_questions = @exercise.exercise_questions.includes(:exercise_choices).order("question_number ASC") filename_ = "#{@exercise.user.real_name}_#{@course.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}.pdf" stylesheets = "#{Rails.root}/app/templates/exercise_export/exercise_export.css" - render pdf: 'exercise_export/blank_exercise', filename: filename_, stylesheets: stylesheets + if params[:export].present? && params[:export] + normal_status(0,"正在下载中") + else + set_export_cookies + render pdf: 'exercise_export/blank_exercise', filename: filename_, stylesheets: stylesheets + end end #空白试卷预览页面,仅供测试使用,无其他任何用途 diff --git a/app/controllers/games_controller.rb b/app/controllers/games_controller.rb index b2de6dcad..b3b062c1a 100644 --- a/app/controllers/games_controller.rb +++ b/app/controllers/games_controller.rb @@ -116,10 +116,11 @@ class GamesController < ApplicationController @qrcode_str = Base64.encode64( qr.to_img.resize(400,400).to_s ) else - @type = "image" #conv = Iconv.new("GBK", "utf-8") @game_challenge = @game.challenge type = @game_challenge.show_type + @type = shixun_show_type type + workspace_path = @game.try(:picture_path) @answer_path = "#{Rails.root}/#{workspace_path}/#{@game_challenge.expect_picture_path}" @user_path = "#{Rails.root}/#{workspace_path}/#{@game_challenge.picture_path}" diff --git a/app/controllers/graduation_tasks_controller.rb b/app/controllers/graduation_tasks_controller.rb index aeb5c409d..0885eeae2 100644 --- a/app/controllers/graduation_tasks_controller.rb +++ b/app/controllers/graduation_tasks_controller.rb @@ -132,6 +132,8 @@ class GraduationTasksController < ApplicationController tip_exception(403, "无权限操作") elsif complete_works == 0 normal_status(-1,"暂无用户提交") + elsif params[:export].present? && params[:export] + normal_status(0,"正在下载中") else respond_to do |format| format.xlsx{ @@ -148,12 +150,17 @@ class GraduationTasksController < ApplicationController zip_works = @work_excel.where("work_status > 0") status = checkfileSize(zip_works) if status == 0 - respond_to do |format| - format.zip{ - zipfile = zip_homework_common @task, zip_works - file = decode64(zipfile[0][:base64file]) - send_file "#{OUTPUT_FOLDER}/#{file}", filename: filename_for_content_disposition(file), type: 'application/zip' - } + if params[:export].present? && params[:export] + normal_status(0,"正在下载中") + else + respond_to do |format| + format.zip{ + set_export_cookies + zipfile = zip_homework_common @task, zip_works + file = decode64(zipfile[0][:base64file]) + send_file "#{OUTPUT_FOLDER}/#{file}", filename: filename_for_content_disposition(file), type: 'application/zip' + } + end end else normal_status(status,status == -2 ? "500M" : "无附件可下载") diff --git a/app/controllers/graduation_topics_controller.rb b/app/controllers/graduation_topics_controller.rb index 96816c2a6..bd93401f3 100644 --- a/app/controllers/graduation_topics_controller.rb +++ b/app/controllers/graduation_topics_controller.rb @@ -271,7 +271,12 @@ class GraduationTopicsController < ApplicationController students = course.students.joins(user: :user_extension).order("user_extensions.student_id") graduation_topic_to_xlsx(students,course) topic_export_name_ = "#{current_user.real_name}_#{course.name}_毕设选题_#{Time.now.strftime('%Y%m%d_%H%M%S')}" - render xlsx: "#{topic_export_name_.strip}",template: "graduation_topics/export.xlsx.axlsx",locals: {table_columns:@topic_head_cells,topic_users:@topic_body_cells} + if params[:export].present? && params[:export] + normal_status(0,"正在下载中") + else + set_export_cookies + render xlsx: "#{topic_export_name_.strip}",template: "graduation_topics/export.xlsx.axlsx",locals: {table_columns:@topic_head_cells,topic_users:@topic_body_cells} + end rescue Exception => e uid_logger(e.message) missing_template diff --git a/app/controllers/homework_commons_controller.rb b/app/controllers/homework_commons_controller.rb index 481253f5b..603a59920 100644 --- a/app/controllers/homework_commons_controller.rb +++ b/app/controllers/homework_commons_controller.rb @@ -207,9 +207,12 @@ class HomeworkCommonsController < ApplicationController tip_exception(403, "无权限操作") elsif @work_excel.blank? || @work_excel.size == 0 normal_status(-1,"暂无用户提交!") + elsif params[:export].present? && params[:export] + normal_status(0,"正在下载中") else respond_to do |format| format.xlsx{ + set_export_cookies student_work_to_xlsx(@work_excel,@homework) exercise_export_name = "#{current_user.real_name}_#{@course.name}_#{@homework.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" render xlsx: "#{exercise_export_name.strip}",template: "homework_commons/works_list.xlsx.axlsx",locals: @@ -229,12 +232,17 @@ class HomeworkCommonsController < ApplicationController end if status == 0 - respond_to do |format| - format.zip{ - zipfile = zip_homework_common @homework, zip_works - file = decode64(zipfile[0][:base64file]) - send_file "#{OUTPUT_FOLDER}/#{file}", filename: filename_for_content_disposition(file), type: 'application/zip' - } + if params[:export].present? && params[:export] + normal_status(0,"正在下载中") + else + respond_to do |format| + format.zip{ + set_export_cookies + zipfile = zip_homework_common @homework, zip_works + file = decode64(zipfile[0][:base64file]) + send_file "#{OUTPUT_FOLDER}/#{file}", filename: filename_for_content_disposition(file), type: 'application/zip' + } + end end else normal_status(status, status == -2 ? "500M" : "无附件可下载") diff --git a/app/controllers/myshixuns_controller.rb b/app/controllers/myshixuns_controller.rb index fa47fd7f6..1d6b15969 100644 --- a/app/controllers/myshixuns_controller.rb +++ b/app/controllers/myshixuns_controller.rb @@ -24,7 +24,7 @@ class MyshixunsController < ApplicationController ActiveRecord::Base.transaction do begin @shixun = Shixun.select(:id, :identifier).find(@myshixun.shixun_id) - @myshixun.destroy + @myshixun.destroy! StudentWork.where(:myshixun_id => @myshixun.id).update_all(:myshixun_id => 0, :work_status => 0) diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index 87435f743..7d978d722 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -945,9 +945,12 @@ class PollsController < ApplicationController tip_exception(403,"无权限操作") elsif (@poll.polls_status == 1) || (@poll_export_questions.size == 0) || (@poll_commit_ids.size == 0) normal_status(-1,"暂无用户提交") + elsif params[:export].present? && params[:export] + normal_status(0,"正在下载中") else respond_to do |format| format.xlsx{ + set_export_cookies polls_export_name_ = "#{current_user.real_name}_#{@course.name}_#{@poll.polls_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" polls_user_commit = poll_commit_result(@poll,@poll_export_questions,@poll_users,@poll_commit_ids) render xlsx: "#{polls_export_name_.strip}",template: "polls/commit_result.xlsx.axlsx",locals: {polls_user_commit:polls_user_commit} diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index c9ed6c597..672477790 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -1,10 +1,2 @@ class ProjectsController < ApplicationController - def search - query_params = { keyword: params[:keyword], category: 'manage' } - projects = Users::ProjectService.new(current_user, query_params).call - - params[:limit] = params[:per_page].to_i.zero? ? 20 : params[:per_page].to_i - @count = projects.count - @projects = paginate projects - end end \ No newline at end of file diff --git a/app/controllers/users/base_controller.rb b/app/controllers/users/base_controller.rb index fd138a182..969aca320 100644 --- a/app/controllers/users/base_controller.rb +++ b/app/controllers/users/base_controller.rb @@ -43,7 +43,7 @@ class Users::BaseController < ApplicationController page = page_value per_page = per_page_value - return Kaminari.paginate_array(objs).page(page).per(per_page) unless observed_logged_user? && opts[:special] + return Kaminari.paginate_array(objs).page(page).per(per_page) unless opts[:special] && observed_logged_user? # note: 为实现第一页少一条记录,让前端放置新建入口 if page == 1 diff --git a/app/controllers/users/projects_controller.rb b/app/controllers/users/projects_controller.rb index 863b99b37..07f4d5cac 100644 --- a/app/controllers/users/projects_controller.rb +++ b/app/controllers/users/projects_controller.rb @@ -1,4 +1,6 @@ class Users::ProjectsController < Users::BaseController + skip_before_action :check_observed_user_exists!, only: [:search] + def index projects = Users::ProjectService.new(observed_user, query_params).call @@ -6,6 +8,15 @@ class Users::ProjectsController < Users::BaseController @projects = paginate(projects.includes(:project_score, owner: { user_extension: :school }), special: true) end + def search + query_params = { keyword: params[:keyword], category: 'manage' } + projects = Users::ProjectService.new(current_user, query_params).call + + params[:limit] = params[:per_page].to_i.zero? ? 20 : params[:per_page].to_i + @count = projects.count + @projects = paginate projects + end + private def query_params diff --git a/app/controllers/zips_controller.rb b/app/controllers/zips_controller.rb index f4822b96b..3ed1eb8b3 100644 --- a/app/controllers/zips_controller.rb +++ b/app/controllers/zips_controller.rb @@ -8,7 +8,13 @@ class ZipsController < ApplicationController def shixun_report service = BatchExportShixunReportService.new(@homework, @all_student_works) filename_ = filename_for_content_disposition(service.filename) - send_file service.zip, filename: filename_, type: 'application/zip' + if params[:export].present? && params[:export] + normal_status(0,"正在下载中") + else + set_export_cookies + send_file service.zip, filename: filename_, type: 'application/zip' + end + rescue BatchExportShixunReportService::Error => ex normal_status(-1, ex.message) end @@ -18,7 +24,12 @@ class ZipsController < ApplicationController exercises = ExportExercisesService.new(@exercise,@ex_users,@request_url) file_name_ = filename_for_content_disposition(exercises.filename) - send_file exercises.ex_zip, filename: file_name_, type: 'application/zip' + if params[:export].present? && params[:export] + normal_status(0,"正在下载中") + else + set_export_cookies + send_file exercises.ex_zip, filename: file_name_, type: 'application/zip' + end rescue Exception => e normal_status(-1, e.message) end diff --git a/app/helpers/games_helper.rb b/app/helpers/games_helper.rb index aff05904f..5a9871673 100644 --- a/app/helpers/games_helper.rb +++ b/app/helpers/games_helper.rb @@ -6,7 +6,7 @@ module GamesHelper end # 获取目录下所有文件,返回一个文件名的数组 type是查看文件的类型image表示图片 - # type [[1, "图片"], [2, "apk/exe"], [3, "txt"], [4, "html"]] + # type [[1, "图片"], [2, "apk/exe"], [3, "txt"], [4, "html"], [5, "mp3"], [6, "mp4"]] def get_dir_filename(path, type, game_id) answer_picture = [] return answer_picture unless File.directory?(path) @@ -39,6 +39,12 @@ module GamesHelper end f.close @type = 'txt' + elsif extension == 'mp3' && type == 5 + answer_picture << file + @type = 'mp3' + elsif extension == 'mp4' && type == 6 + answer_picture << file + @type = 'mp4' end end @@ -51,4 +57,21 @@ module GamesHelper "编译失败,请在测试结果中查看具体的错误信息" : test_set.try(:actual_output) end end + + def shixun_show_type type + case type.to_i + when 1 + "image" + when 2 + "apk/exe" + when 3 + "txt" + when 4 + "html" + when 5 + "mp3" + when 6 + "mp4" + end + end end diff --git a/app/models/challenge.rb b/app/models/challenge.rb index 0bea54eb4..8e4d2ae42 100644 --- a/app/models/challenge.rb +++ b/app/models/challenge.rb @@ -1,5 +1,6 @@ class Challenge < ApplicationRecord # difficulty: 关卡难度: 1.简单 2.中等 3.困难 + # show_type: 效果展示:-1.无效果 1.图片 2.apk/exe 3.txt 4.html 5.mp3 6.mp4 default_scope { order("challenges.position asc") } belongs_to :shixun, :touch => true, counter_cache: true diff --git a/app/services/private_messages/create_service.rb b/app/services/private_messages/create_service.rb index 560f1a540..88f3a084f 100644 --- a/app/services/private_messages/create_service.rb +++ b/app/services/private_messages/create_service.rb @@ -3,7 +3,7 @@ class PrivateMessages::CreateService < ApplicationService attr_reader :sender, :receiver, :params - def initialize(sender, receiver, **params) + def initialize(sender, receiver, params) @sender = sender @receiver = receiver @params = params diff --git a/app/views/games/picture_display.json.jbuilder b/app/views/games/picture_display.json.jbuilder index 541c478a9..b43efa57e 100644 --- a/app/views/games/picture_display.json.jbuilder +++ b/app/views/games/picture_display.json.jbuilder @@ -24,5 +24,30 @@ elsif @type == "txt" json.contents @contents.html_safe elsif @type =="qrcode" json.qrcode_str @qrcode_str +elsif @type == "mp3" || @type == "mp4" + if @type == "mp4" + json.orignal_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378171/123.mp4"}] + json.user_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378172/456.mp4"}] + json.answer_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378173/789.mp4"}] + else + json.orignal_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378174/58099.mp3"}] + json.user_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378175/654058514.mp3"}] + json.answer_file [{"file_url": "http://120.27.231.56:48080/attachments/download/378175/654058514.mp3"}] + end + # json.orignal_file do + # json.array! @orignal_picture do |file| + # json.file_url attachment_show_users_path(:file_name => file, :path => @original_path) + # end + # end + # json.user_file do + # json.array! @user_picture do |file| + # json.file_url attachment_show_users_path(:file_name => file, :path => @user_path, :time => Time.now.to_i) + # end + # end + # json.answer_file do + # json.array! @answer_picture do |file| + # json.file_url attachment_show_users_path(:file_name => file, :path => @answer_path) + # end + # end end \ No newline at end of file diff --git a/app/views/users/get_user_info.json.jbuilder b/app/views/users/get_user_info.json.jbuilder index d12b950f9..fc2eca762 100644 --- a/app/views/users/get_user_info.json.jbuilder +++ b/app/views/users/get_user_info.json.jbuilder @@ -1,4 +1,5 @@ json.username @user.full_name +json.real_name @user.real_name json.login @user.login json.user_id @user.id json.image_url url_to_avatar(@user) diff --git a/app/views/projects/search.json.jbuilder b/app/views/users/projects/search.json.jbuilder similarity index 100% rename from app/views/projects/search.json.jbuilder rename to app/views/users/projects/search.json.jbuilder diff --git a/config/routes.rb b/config/routes.rb index 1ce0e9d4c..1a573a3c2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -84,7 +84,7 @@ Rails.application.routes.draw do get :system_update resource :trial_apply, only: [:create] - resources :projects, only: [] do + resources :projects, module: :users, only: [] do get :search, on: :collection end diff --git a/public/compatibility.html b/public/compatibility.html index f13c673f5..f28bad2c8 100644 --- a/public/compatibility.html +++ b/public/compatibility.html @@ -5,9 +5,9 @@ EduCoder - - - + + + diff --git a/public/images/educoder/path.png b/public/images/educoder/path.png new file mode 100644 index 000000000..d3d816012 Binary files /dev/null and b/public/images/educoder/path.png differ diff --git a/public/javascripts/media/clappr-playback-rate-plugin.min.js b/public/javascripts/media/clappr-playback-rate-plugin.min.js new file mode 100644 index 000000000..8bbcbfaca --- /dev/null +++ b/public/javascripts/media/clappr-playback-rate-plugin.min.js @@ -0,0 +1 @@ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("clappr")):"function"==typeof define&&define.amd?define("clappr-playback-rate-plugin",["clappr"],e):"object"==typeof exports?exports["clappr-playback-rate-plugin"]=e(require("clappr")):t["clappr-playback-rate-plugin"]=e(t.clappr)}("undefined"!=typeof self?self:this,function(t){return function(t){function e(n){if(a[n])return a[n].exports;var o=a[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,e),o.l=!0,o.exports}var a={};return e.m=t,e.c=a,e.d=function(t,a,n){e.o(t,a)||Object.defineProperty(t,a,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var a=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(a,"a",a),a},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=0)}([function(t,e,a){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function r(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}Object.defineProperty(e,"__esModule",{value:!0});var i=a(1),l=(a.n(i),a(2)),c=a.n(l),s=a(3),u=a.n(s),p=function(){function t(t,e){for(var a=0;a\n <%= title %>\n\n\n'},function(t,e,a){e=t.exports=a(4)(void 0),e.push([t.i,".media-control[data-media-control] .media-control-layer[data-controls] .playback_rate[data-playback-rate-select] {\n float: right;\n margin-top: 5px;\n position: relative; }\n .media-control[data-media-control] .media-control-layer[data-controls] .playback_rate[data-playback-rate-select] button.media-control-button.media-control-icon {\n font-family: Roboto,\"Open Sans\",Arial,sans-serif;\n -webkit-font-smoothing: antialiased;\n font-size: 12px;\n cursor: pointer;\n padding: 10px; }\n .media-control[data-media-control] .media-control-layer[data-controls] .playback_rate[data-playback-rate-select] button.media-control-button.media-control-icon:hover {\n color: #c9c9c9; }\n .media-control[data-media-control] .media-control-layer[data-controls] .playback_rate[data-playback-rate-select] button.media-control-button.media-control-icon.changing {\n -webkit-animation: pulse 0.5s infinite alternate; }\n .media-control[data-media-control] .media-control-layer[data-controls] .playback_rate[data-playback-rate-select] > ul {\n display: none;\n list-style-type: none;\n position: absolute;\n bottom: 25px;\n border: 1px solid black;\n border-radius: 4px;\n background-color: rgba(0, 0, 0, 0.7); }\n .media-control[data-media-control] .media-control-layer[data-controls] .playback_rate[data-playback-rate-select] li {\n position: relative;\n font-size: 12px; }\n .media-control[data-media-control] .media-control-layer[data-controls] .playback_rate[data-playback-rate-select] li[data-title] {\n padding: 5px; }\n .media-control[data-media-control] .media-control-layer[data-controls] .playback_rate[data-playback-rate-select] li a {\n color: #aaa;\n padding: 2px 10px 2px 15px;\n display: block;\n text-decoration: none; }\n .media-control[data-media-control] .media-control-layer[data-controls] .playback_rate[data-playback-rate-select] li a.active {\n background-color: black;\n font-weight: bold;\n color: #fff; }\n .media-control[data-media-control] .media-control-layer[data-controls] .playback_rate[data-playback-rate-select] li a.active:before {\n content: '\\2713';\n position: absolute;\n top: 2px;\n left: 4px; }\n .media-control[data-media-control] .media-control-layer[data-controls] .playback_rate[data-playback-rate-select] li a:hover {\n color: #fff;\n text-decoration: none; }\n\n@-webkit-keyframes pulse {\n 0% {\n color: #fff; }\n 50% {\n color: #ff0101; }\n 100% {\n color: #B80000; } }\n",""])},function(t,e){function a(t,e){var a=t[1]||"",o=t[3];if(!o)return a;if(e&&"function"==typeof btoa){var r=n(o);return[a].concat(o.sources.map(function(t){return"/*# sourceURL="+o.sourceRoot+t+" */"})).concat([r]).join("\n")}return[a].join("\n")}function n(t){return"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(t))))+" */"}t.exports=function(t){var e=[];return e.toString=function(){return this.map(function(e){var n=a(e,t);return e[2]?"@media "+e[2]+"{"+n+"}":n}).join("")},e.i=function(t,a){"string"==typeof t&&(t=[[null,t,""]]);for(var n={},o=0;o0&&e._renderPlugin()})})}},{key:"removeThumbnail",value:function(t){var e=this,n=t.constructor===Array?t:[t];return this._onThumbsLoaded.then(function(){var t=!0,o=!1;return n.forEach(function(n){var i=e._thumbs.some(function(t,o){return t.src===n&&(e._thumbs.splice(o,1),e._getOptions().backdropHeight&&(e._$backdropCarouselImgs[o].remove(),e._$backdropCarouselImgs.splice(o,1)),!0)});i?o=!0:t=!1}),o&&e._renderPlugin(),c.Promise.resolve(t)})}},{key:"_init",value:function(){this._thumbsLoaded&&(this._$backdropCarouselImgs=[],this._createElements(),this._loadBackdrop(),this._renderPlugin())}},{key:"_getOptions",value:function(){if(!("scrubThumbnails"in this.core.options))throw"'scrubThumbnails property missing from options object.";return this.core.options.scrubThumbnails}},{key:"_appendElToMediaControl",value:function(){this.core.mediaControl.$el.find(".media-control-background").first().after(this.el)}},{key:"_onMouseMove",value:function(t){this._calculateHoverPosition(t),this._show=!0,this._renderPlugin()}},{key:"_onMouseLeave",value:function(){this._show=!1,this._renderPlugin()}},{key:"_calculateHoverPosition",value:function(t){var e=t.pageX-this.core.mediaControl.$seekBarContainer.offset().left;this._hoverPosition=Math.min(1,Math.max(e/this.core.mediaControl.$seekBarContainer.width(),0))}},{key:"_buildThumbsFromOptions",value:function(){var t=this,e=this._getOptions().thumbs,n=e.map(function(e){return t._addThumbFromSrc(e)});return c.Promise.all(n)}},{key:"_addThumbFromSrc",value:function(t){var e=this;return new c.Promise(function(e,n){var o=new Image;o.onload=function(){e(o)},o.onerror=n,o.src=t.url}).then(function(n){var o=t.time,i=null;e._thumbs.some(function(t,e){return o0?e._thumbs[i-1]:null;u&&(u.duration=o-u.time);var s=r?r.time-t.time:null,a=n.width,c=n.height,l={imageW:a,imageH:c,x:t.x||0,y:t.y||0,w:t.w||a,h:t.h||c,url:t.url,time:o,duration:s,src:t};return e._thumbs.splice(i,0,l),l})}},{key:"_buildImg",value:function(t,e){var n=e/t.h,o=(0,a.$)("").addClass("thumbnail-img").attr("src",t.url),i=(0,a.$)("
").addClass("thumbnail-container");return i.css("width",t.w*n),i.css("height",e),o.css({height:t.imageH*n,left:-1*t.x*n,top:-1*t.y*n}),i.append(o),i}},{key:"_loadBackdrop",value:function(){if(this._getOptions().backdropHeight)for(var t=this._$carousel,e=0;e=0;n--){var o=e[n];if(o.time<=t)return n}return 0}},{key:"_renderPlugin",value:function(){this._thumbsLoaded&&(this._show&&this._thumbs.length>0?(this.$el.removeClass("hidden"),this._updateCarousel(),this._updateSpotlightThumb()):this.$el.addClass("hidden"))}},{key:"_createElements",value:function(){this.$el.html(this.template({backdropHeight:this._getOptions().backdropHeight,spotlightHeight:this._getOptions().spotlightHeight})),this.$el.append(a.Styler.getStyleFor(d["default"])),this._$spotlight=this.$el.find(".spotlight"),this._$backdrop=this.$el.find(".backdrop"),this._$carousel=this._$backdrop.find(".carousel"),this.$el.addClass("hidden"),this._appendElToMediaControl()}}]),e}(a.UICorePlugin);e["default"]=p,t.exports=e["default"]},function(t,e,n){(function(t,o){"use strict";function i(t,e){this._id=t,this._clearFn=e}var r=n(4).nextTick,u=Function.prototype.apply,s=Array.prototype.slice,a={},c=0;e.setTimeout=function(){return new i(u.call(setTimeout,window,arguments),clearTimeout)},e.setInterval=function(){return new i(u.call(setInterval,window,arguments),clearInterval)},e.clearTimeout=e.clearInterval=function(t){t.close()},i.prototype.unref=i.prototype.ref=function(){},i.prototype.close=function(){this._clearFn.call(window,this._id)},e.enroll=function(t,e){clearTimeout(t._idleTimeoutId),t._idleTimeout=e},e.unenroll=function(t){clearTimeout(t._idleTimeoutId),t._idleTimeout=-1},e._unrefActive=e.active=function(t){clearTimeout(t._idleTimeoutId);var e=t._idleTimeout;e>=0&&(t._idleTimeoutId=setTimeout(function(){t._onTimeout&&t._onTimeout()},e))},e.setImmediate="function"==typeof t?t:function(t){var n=c++,o=!(arguments.length<2)&&s.call(arguments,1);return a[n]=!0,r(function(){a[n]&&(o?t.apply(null,o):t.call(null),e.clearImmediate(n))}),n},e.clearImmediate="function"==typeof o?o:function(t){delete a[t]}}).call(e,n(1).setImmediate,n(1).clearImmediate)},function(t,e){"use strict";t.exports=function(){var t=[];return t.toString=function(){for(var t=[],e=0;e1)for(var n=1;n")},M.garbage=function(t){this.options.recycleVideo&&"VIDEO"===t[0].tagName.toUpperCase()&&(t.children().remove(),D.push(t))},M);function M(){(0,s.default)(this,M)}x.options={recycleVideo:!1};var N=e.DoubleEventHandler=(F.prototype.handle=function(t,e,r){var i=!(2]*>/,Xe=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,Ye=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,Ze=/^(?:body|html)$/i,$e=/([A-Z])/g,_e=["val","css","html","text","data","width","height","offset"],bf=Se.createElement("table"),cf=Se.createElement("tr"),df={tr:Se.createElement("tbody"),tbody:bf,thead:bf,tfoot:bf,td:cf,th:cf,"*":Se.createElement("div")},ef=/complete|loaded|interactive/,ff=/^[\w-]*$/,hf=(gf={}).toString,jf={},mf=Se.createElement("div"),nf={tabindex:"tabIndex",readonly:"readOnly",for:"htmlFor",class:"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},of=Array.isArray||function(t){return t instanceof Array},jf.matches=function(t,e){if(!e||!t||1!==t.nodeType)return!1;var r=t.matches||t.webkitMatchesSelector||t.mozMatchesSelector||t.oMatchesSelector||t.matchesSelector;if(r)return r.call(t,e);var i,n=t.parentNode,a=!n;return a&&(n=mf).appendChild(t),i=~jf.qsa(n,e).indexOf(t),a&&mf.removeChild(t),i},kf=function(t){return t.replace(/-+(.)?/g,function(t,e){return e?e.toUpperCase():""})},lf=function(r){return Qe.call(r,function(t,e){return r.indexOf(t)==e})},jf.fragment=function(t,e,r){var i,n,a;return Xe.test(t)&&(i=Me(Se.createElement(RegExp.$1))),i||(t.replace&&(t=t.replace(Ye,"<$1>")),e===Ke&&(e=We.test(t)&&RegExp.$1),e in df||(e="*"),(a=df[e]).innerHTML=""+t,i=Me.each(Re.call(a.childNodes),function(){a.removeChild(this)})),uf(r)&&(n=Me(i),Me.each(r,function(t,e){-1<_e.indexOf(t)?n[t](e):n.attr(t,e)})),i},jf.Z=function(t,e){return new Df(t,e)},jf.isZ=function(t){return t instanceof jf.Z},jf.init=function(t,e){var r;if(!t)return jf.Z();if("string"==typeof t)if("<"==(t=t.trim())[0]&&We.test(t))r=jf.fragment(t,RegExp.$1,e),t=null;else{if(e!==Ke)return Me(e).find(t);r=jf.qsa(Se,t)}else{if(qf(t))return Me(Se).ready(t);if(jf.isZ(t))return t;if(of(t))r=function(t){return Qe.call(t,function(t){return null!=t})}(t);else if(tf(t))r=[t],t=null;else if(We.test(t))r=jf.fragment(t.trim(),RegExp.$1,e),t=null;else{if(e!==Ke)return Me(e).find(t);r=jf.qsa(Se,t)}}return jf.Z(r,t)},(Me=function(t,e){return jf.init(t,e)}).extend=function(e){var r,t=Re.call(arguments,1);return"boolean"==typeof e&&(r=e,e=t.shift()),t.forEach(function(t){!function t(e,r,i){for(Le in r)i&&(uf(r[Le])||of(r[Le]))?(uf(r[Le])&&!uf(e[Le])&&(e[Le]={}),of(r[Le])&&!of(e[Le])&&(e[Le]=[]),t(e[Le],r[Le],i)):r[Le]!==Ke&&(e[Le]=r[Le])}(e,t,r)}),e},jf.qsa=function(t,e){var r,i="#"==e[0],n=!i&&"."==e[0],a=i||n?e.slice(1):e,o=ff.test(a);return t.getElementById&&o&&i?(r=t.getElementById(a))?[r]:[]:1!==t.nodeType&&9!==t.nodeType&&11!==t.nodeType?[]:Re.call(o&&!i&&t.getElementsByClassName?n?t.getElementsByClassName(a):t.getElementsByTagName(e):t.querySelectorAll(e))},Me.contains=Se.documentElement.contains?function(t,e){return t!==e&&t.contains(e)}:function(t,e){for(;e&&(e=e.parentNode);)if(e===t)return!0;return!1},Me.type=pf,Me.isFunction=qf,Me.isWindow=rf,Me.isArray=of,Me.isPlainObject=uf,Me.isEmptyObject=function(t){var e;for(e in t)return!1;return!0},Me.isNumeric=function(t){var e=Number(t),r=typeof t;return null!=t&&"boolean"!=r&&("string"!=r||t.length)&&!isNaN(e)&&isFinite(e)||!1},Me.inArray=function(t,e,r){return Oe.indexOf.call(e,t,r)},Me.camelCase=kf,Me.trim=function(t){return null==t?"":String.prototype.trim.call(t)},Me.uuid=0,Me.support={},Me.expr={},Me.noop=function(){},Me.map=function(t,e){var r,i,n,a=[];if(vf(t))for(i=0;i)<[^<]*)*<\/script>/gi,Ok=/^(?:text|application)\/javascript/i,Pk=/^(?:text|application)\/xml/i,Qk="application/json",Rk="text/html",Sk=/^\s*$/,Tk=Kk.createElement("a");function Vk(t,e,r,i){if(t.global)return function(t,e,r){var i=Ik.Event(e);return Ik(t).trigger(i,r),!i.isDefaultPrevented()}(e||Kk,r,i)}function Yk(t,e){var r=e.context;if(!1===e.beforeSend.call(r,t,e)||!1===Vk(e,r,"ajaxBeforeSend",[t,e]))return!1;Vk(e,r,"ajaxSend",[t,e])}function Zk(t,e,r,i){var n=r.context,a="success";r.success.call(n,t,a,e),i&&i.resolveWith(n,[t,a,e]),Vk(r,n,"ajaxSuccess",[e,r,t]),_k(a,e,r)}function $k(t,e,r,i,n){var a=i.context;i.error.call(a,r,e,t),n&&n.rejectWith(a,[r,e,t]),Vk(i,a,"ajaxError",[r,i,t||e]),_k(e,r,i)}function _k(t,e,r){var i=r.context;r.complete.call(i,e,t),Vk(r,i,"ajaxComplete",[e,r]),function(t){t.global&&!--Ik.active&&Vk(t,null,"ajaxStop")}(r)}function bl(){}function dl(t,e){return""==e?t:(t+"&"+e).replace(/[&?]{1,2}/,"?")}function fl(t,e,r,i){return Ik.isFunction(e)&&(i=r,r=e,e=void 0),Ik.isFunction(r)||(i=r,r=void 0),{url:t,data:e,success:r,dataType:i}}Tk.href=window.location.href,Ik.active=0,Ik.ajaxJSONP=function(r,i){if(!("type"in r))return Ik.ajax(r);function t(t){Ik(s).triggerHandler("error",t||"abort")}var n,a,e=r.jsonpCallback,o=(Ik.isFunction(e)?e():e)||"Zepto"+Jk++,s=Kk.createElement("script"),l=window[o],u={abort:t};return i&&i.promise(u),Ik(s).on("load error",function(t,e){clearTimeout(a),Ik(s).off().remove(),"error"!=t.type&&n?Zk(n[0],u,r,i):$k(null,e||"error",u,r,i),window[o]=l,n&&Ik.isFunction(l)&&l(n[0]),l=n=void 0}),!1===Yk(u,r)?t("abort"):(window[o]=function(){n=arguments},s.src=r.url.replace(/\?(.+)=\?/,"?$1="+o),Kk.head.appendChild(s),0").html(t.replace(Nk,"")).find(i):t),s&&s.apply(n,arguments)},Ik.ajax(o),this};var gl=encodeURIComponent;Ik.param=function(t,e){var r=[];return r.add=function(t,e){Ik.isFunction(e)&&(e=e()),null==e&&(e=""),this.push(gl(t)+"="+gl(e))},function r(i,t,n,a){var o,s=Ik.isArray(t),l=Ik.isPlainObject(t);Ik.each(t,function(t,e){o=Ik.type(e),a&&(t=n?a:a+"["+(l||"object"==o||"array"==o?t:"")+"]"),!a&&s?i.add(e.name,e.value):"array"==o||!n&&"object"==o?r(i,e,n,t):i.add(t,e)})}(r,t,e),r.join("&").replace(/%20/g,"+")}}(Je),(_m=Je).Callbacks=function(i){i=_m.extend({},i);var e,r,n,a,o,s,l=[],u=!i.once&&[],d=function(t){for(e=i.memory&&t,r=!0,s=a||0,a=0,o=l.length,n=!0;l&&s/,Sq="Zepto"+ +new Date,Lq.qsa=function(a,o){return Tq(o,function(t,r,i){try{var e;!t&&r?t="*":Rq.test(t)&&(e=Kq(a).addClass(Sq),t="."+Sq+" "+t);var n=Mq(a,t)}catch(t){throw console.error("error performing selector: %o",o),t}finally{e&&e.removeClass(Sq)}return r?Lq.uniq(Kq.map(n,function(t,e){return r.call(t,e,n,i)})):n})},Lq.matches=function(i,t){return Tq(t,function(t,e,r){return(!t||Nq(i,t))&&(!e||e.call(i,null,r)===i)})},He.exports=Je},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0});function n(t){return null===t?"":(""+t).replace(o,function(t){return a[t]})}function i(a,t){var e,r=new RegExp([(l.escape||u).source,(l.interpolate||u).source,(l.evaluate||u).source].join("|")+"|$","g"),o=0,s="__p+='";a.replace(r,function(t,e,r,i,n){return s+=a.slice(o,n).replace(c,function(t){return"\\"+d[t]}),e&&(s+="'+\n((__t=("+e+"))==null?'':escapeExpr(__t))+\n'"),r&&(s+="'+\n((__t=("+r+"))==null?'':__t)+\n'"),i&&(s+="';\n"+i+"\n__p+='"),o=n+t.length,t}),s+="';\n",l.variable||(s="with(obj||{}){\n"+s+"}\n"),s="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+s+"return __p;\n//# sourceURL=/microtemplates/source["+f+++"]";try{e=new Function(l.variable||"obj","escapeExpr",s)}catch(t){throw t.source=s,t}if(t)return e(t,n);function i(t){return e.call(this,t,n)}return i.source="function("+(l.variable||"obj")+"){\n"+s+"}",i}var l={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g},u=/(.)^/,d={"'":"'","\\":"\\","\r":"r","\n":"n","\t":"t","\u2028":"u2028","\u2029":"u2029"},c=/\\|'|\r|\n|\t|\u2028|\u2029/g,a={"&":"&","<":"<",">":">",'"':""","'":"'"},o=new RegExp("[&<>\"']","g"),f=0;i.settings=l,e.default=i,t.exports=e.default},function(t,e){t.exports=function(r){var o=[];return o.toString=function(){return this.map(function(t){var e=function(t,e){var r=t[1]||"",i=t[3];if(!i)return r;if(e&&"function"==typeof btoa){var n=function(t){return"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(t))))+" */"}(i),a=i.sources.map(function(t){return"/*# sourceURL="+i.sourceRoot+t+" */"});return[r].concat(a).concat([n]).join("\n")}return[r].join("\n")}(t,r);return t[2]?"@media "+t[2]+"{"+e+"}":e}).join("")},o.i=function(t,e){"string"==typeof t&&(t=[[null,t,""]]);for(var r={},i=0;i=e.length?{value:void 0,done:!0}:(t=i(e,r),this._i+=t.length,{value:t,done:!1})})},function(t,e){t.exports=!0},function(t,e,i){function n(){}var a=i(21),o=i(116),s=i(51),l=i(49)("IE_PROTO"),u="prototype",d=function(){var t,e=i(67)("iframe"),r=s.length;for(e.style.display="none",i(117).appendChild(e),e.src="javascript:",(t=e.contentWindow.document).open(),t.write("