# HG changeset patch # User durandn # Date 1443774263 -7200 # Node ID 75e3a41722addcb33e040bfb588f3ede9cb943d8 # Parent 0e256f85464b4f41130b0dad0b42341d338f2a8e implement mdplayer changes from oaubert pull request + added a script to build mdplayer from mdplayer local repo diff -r 0e256f85464b -r 75e3a41722ad server/sbin/build/compil-mdp-from-sources.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/sbin/build/compil-mdp-from-sources.sh Fri Oct 02 10:24:23 2015 +0200 @@ -0,0 +1,36 @@ + +if [ $# -eq 0 ] + then + echo "No argument was provided, looking for mdplayer_path" + if [ ! -f "mdplayer_path" ] + then + echo "Error: mdplayer_path file does not exist and no argument was provided" + exit 1 + fi + MDPLAYER_PATH=$(cat mdplayer_path) + if [ -z MDPLAYER_PATH ] + then + echo "File is empty" + exit 1 + fi + else + MDPLAYER_PATH=$1 +fi + +echo "Compiling Metadataplayer" + +sh $MDPLAYER_PATH/sbin/res/ant/bin/ant -f $MDPLAYER_PATH/sbin/build/client.xml + +echo "Copying to Platform :" + +echo " Copying core files and widgets" + +cp -R $MDPLAYER_PATH/test/metadataplayer/* ../../src/remie/static/remie/metadataplayer + +echo " Copying JS libs" + +cp -R $MDPLAYER_PATH/src/js/libs/*.js ../../src/remie/static/remie/js + +echo " Copying SWF libs" + +cp -R $MDPLAYER_PATH/src/js/libs/*.swf ../../src/remie/static/remie/swf diff -r 0e256f85464b -r 75e3a41722ad server/src/README --- a/server/src/README Mon Sep 28 14:32:54 2015 +0200 +++ b/server/src/README Fri Oct 02 10:24:23 2015 +0200 @@ -9,4 +9,16 @@ Then go to /remie/iframetester, where you have a blank page with a few fields that condition the iframe player you'll generate. You can use the local ldt platform to get the id of your test project. Use the generate button to create the iframe and insert it into the page. Currently there is only the segment scenario. -Note: If you want to test multiple users annotations, we don't validate currently logged user so it is entirely possible to generate a remie player for another user than the one currently logged in, and have annotation creation work for that other user. \ No newline at end of file +Note: If you want to test multiple users annotations, we don't validate currently logged user so it is entirely possible to generate a remie player for another user than the one currently logged in, and have annotation creation work for that other user. + +============== +Building Metadataplayer +============== + +Run the script in sbin/build/ folder to build the metadataplayer from the sources. + cd sbin/build + bash compil-mdp-from-sources + +Alternatively you can put a "mdplayer_path" file (containing the ABSOLUTE path to the metadataplayer repository) to the sbin/build repo then call the script without argument + cd sbin/build + bash compil-mdp-from-sources \ No newline at end of file diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/js/jquery.touchsplitter.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/remie/static/remie/js/jquery.touchsplitter.js Fri Oct 02 10:24:23 2015 +0200 @@ -0,0 +1,444 @@ +// Generated by CoffeeScript 1.9.3 + +/* + * Touch Splitter JQuery was created by Cole Lawrence(github:ZombieHippie) + * This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 + * Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/. + */ + +(function() { + var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; + + (function(mod) { + if (typeof exports === "object" && typeof module === "object") { + return mod(require("jquery")); + } else if (typeof define === "function" && define.amd) { + return define(["jquery"], mod); + } else { + return mod(jQuery); + } + })(function(jQuery) { + var $, TouchSplitter; + $ = jQuery; + $.fn.touchSplit = function(options) { + if (options == null) { + options = {}; + } + if (this[0].touchSplitter != null) { + throw "Cannot make a splitter here! '" + this.selector + "' already has a splitter! Use $('" + this.selector + "')[0].touchSplitter.destroy() to remove it!"; + } + if (this.children().length !== 2 && this.children().length !== 0) { + throw "Cannot make a splitter here! Incorrect number of div children in '" + this.selector + "'"; + } + return this[0].touchSplitter = new TouchSplitter(this, options); + }; + return TouchSplitter = (function() { + function TouchSplitter(element, options) { + var barThick, firstdiv, inners, match, splitterHTML, testCalc, testEm, thickness, units; + this.element = element; + this.resize = bind(this.resize, this); + this.onResize = bind(this.onResize, this); + this.onResizeWindow = bind(this.onResizeWindow, this); + this.getSecond = bind(this.getSecond, this); + this.getFirst = bind(this.getFirst, this); + this.stopDragging = bind(this.stopDragging, this); + this.drag = bind(this.drag, this); + this.startDragging = bind(this.startDragging, this); + this.onTouchEnd = bind(this.onTouchEnd, this); + this.onTouchMove = bind(this.onTouchMove, this); + this.onTouchStart = bind(this.onTouchStart, this); + this.onMouseDown = bind(this.onMouseDown, this); + this.setPercentages = bind(this.setPercentages, this); + this.setDock = bind(this.setDock, this); + this.moveBar = bind(this.moveBar, this); + this.on = bind(this.on, this); + this.toggleDock = bind(this.toggleDock, this); + this.setRatios = bind(this.setRatios, this); + this.destroy = bind(this.destroy, this); + this.element.addClass('TouchSplitter'); + this.support = {}; + testEm = $('
'); + testEm.appendTo(this.element); + barThick = testEm.width(); + testEm.remove(); + testCalc = $('
'); + testCalc.appendTo(this.element); + this.support.calc = true; + testCalc.remove(); + if (options.orientation != null) { + if (options.orientation === "vertical") { + this.horizontal = false; + } else if (options.orientation === "horizontal") { + + } else { + console.log("Touch Splitter ERROR: orientation cannot be:'" + options.orientation + "' defaulted to 'horizontal'"); + } + } + if (this.horizontal !== false) { + this.horizontal = true; + } + this.element.addClass(this.horizontal ? "h-ts" : "v-ts"); + this.firstMin = options.leftMin || options.topMin || options.firstMin || 0; + this.firstMax = options.leftMax || options.topMax || options.firstMax || false; + this.secondMin = options.rightMin || options.bottomMin || options.secondMin || 0; + this.secondMax = options.rightMax || options.bottomMax || options.secondMax || false; + if (this.firstMax && this.secondMax) { + console.log("Touch Splitter ERROR: cannot set max bounds of both first and second sections!"); + this.secondMax = false; + } + if (options.dock != null) { + if (/both|left|top|first|right|bottom|second/i.test(options.dock)) { + this.docks = (function() { + switch (false) { + case !/both/i.test(options.dock): + return { + first: true, + second: true, + name: "both" + }; + case !/left|top|first/i.test(options.dock): + return { + first: true, + second: false, + name: "first" + }; + case !/right|bottom|second/i.test(options.dock): + return { + first: false, + second: true, + name: "second" + }; + } + })(); + } + } + if (this.docks) { + this.element.addClass('docks-' + this.docks.name); + } else { + this.docks = { + first: false, + second: false, + name: false + }; + } + if (options.thickness != null) { + thickness = options.thickness; + units = "px"; + if (typeof thickness === 'string') { + if (match = thickness.match(/^([\d\.]+)([a-zA-Z]+)$/)) { + thickness = match[1]; + units = match[2]; + } + thickness = parseFloat(thickness); + } + if (!thickness) { + throw "Unable to parse given thickness: " + options.thickness; + } else { + thickness = (function() { + switch (units) { + case "px": + return barThick = thickness; + case "em": + return barThick *= thickness; + default: + throw "Invalid unit used in given thickness: " + units; + } + })(); + } + } + firstdiv = this.element.find(">div:first"); + splitterHTML = "
" + (this.docks.name && this.docks.name.match(/first|second/) ? '
' : '') + "
"; + if (firstdiv.length === 0) { + inners = this.element.html(); + this.element.html("
" + splitterHTML + "
"); + this.element.find(">div:first").html(inners); + } else { + firstdiv.after(splitterHTML); + } + this.barThicknessPx = barThick / 2; + this.barThickness = .04; + this.barPosition = options.barPosition || 0.5; + this.dragging = false; + this.initMouse = 0; + this.initBarPosition = 0; + this.resize(); + this.element.on('resize', this.onResize); + $(window).on('resize', this.onResizeWindow); + $(window).on('mouseup', this.stopDragging); + $(window).on('mousemove', this.drag); + this.element.find('>.splitter-bar').on('mousedown', this.onMouseDown); + this.element.find('>.splitter-bar').bind('touchstart', this.onTouchStart); + this.element.on('touchmove', this.onTouchMove); + this.element.on('touchend', this.onTouchEnd); + this.element.on('touchleave', this.onTouchEnd); + this.element.on('touchcancel', this.onTouchEnd); + } + + TouchSplitter.prototype.destroy = function(side) { + var toRemove; + this.element.off('resize'); + $(window).off('resize'); + $(window).off('mouseup'); + $(window).off('mousemove'); + this.element.find('>.splitter-bar').off('mousedown'); + this.element.find('>.splitter-bar').off('touchstart'); + this.element.off('touchmove'); + this.element.off('touchend'); + this.element.off('touchleave'); + this.element.off('touchcancel'); + this.element.find('>.splitter-bar').remove(); + this.element.removeClass('TouchSplitter h-ts v-ts docks-first docks-second docks-both'); + if (side != null) { + toRemove = (function() { + switch (side) { + case 'left': + case 'top': + return '>div:first'; + case 'right': + case 'bottom': + return '>div:last'; + case 'both': + return '>div'; + } + })(); + this.element.find(toRemove).remove(); + } + this.element.children().css({ + width: "", + height: "" + }); + return delete this.element[0].touchSplitter; + }; + + TouchSplitter.prototype.setRatios = function() { + var conv, ref, val; + this.splitDistance = this.horizontal ? this.element.width() : this.element.height(); + ref = { + firstMin: this.firstMin, + firstMax: this.firstMax, + secondMin: this.secondMin, + secondMax: this.secondMax + }; + for (conv in ref) { + val = ref[conv]; + if (val) { + this[conv + 'Ratio'] = val / this.splitDistance; + } + } + return this.moveBar(); + }; + + TouchSplitter.prototype.toggleDock = function() { + this.element.toggleClass('docked'); + if (this.docked) { + return this.setDock(false); + } else { + return this.setDock(this.docks.name); + } + }; + + TouchSplitter.prototype.on = function(eventName, fn) { + return this.element.on(eventName, fn); + }; + + TouchSplitter.prototype.moveBar = function(newX) { + var cursorPos, cursorPos2; + cursorPos = this.barPosition; + if (newX != null) { + cursorPos = this.initBarPosition + (newX - this.initMouse) / this.splitDistance; + } + cursorPos2 = 1 - cursorPos; + if (this.docks.name) { + switch (this.docked) { + case 'first': + if (cursorPos > this.firstMinRatio / 2) { + this.setDock(false); + } + break; + case 'second': + if (cursorPos2 > this.secondMinRatio / 2) { + this.setDock(false); + } + break; + default: + if (this.docks.first && cursorPos < this.firstMinRatio / 2) { + this.setDock('first'); + } + if (this.docks.second && cursorPos2 < this.secondMinRatio / 2) { + this.setDock('second'); + } + } + } + if (!this.docked) { + this.barPosition = (function() { + switch (false) { + case !(this.firstMaxRatio && cursorPos > this.firstMaxRatio): + return this.firstMaxRatio; + case !(cursorPos < this.firstMinRatio): + return this.firstMinRatio; + case !(this.secondMaxRatio && cursorPos2 > this.secondMaxRatio): + return 1 - this.secondMaxRatio; + case !(cursorPos2 < this.secondMinRatio): + return 1 - this.secondMinRatio; + default: + return cursorPos; + } + }).call(this); + return this.setPercentages(); + } + }; + + TouchSplitter.prototype.setDock = function(val, lastpos) { + if (lastpos == null) { + lastpos = this.barPosition; + } + this.docked = val; + this.barPosition = this.lastPosition; + this.lastPosition = lastpos; + return this.setPercentages(); + }; + + TouchSplitter.prototype.setPercentages = function() { + var attr, first, firstCss, pos, second, secondCss, shave; + switch (this.docked) { + case 'first': + this.barPosition = 0; + break; + case 'second': + this.barPosition = 1; + } + pos = this.barPosition; + firstCss = secondCss = ""; + if (!this.support.calc) { + if (pos < this.barThickness) { + pos = this.barThickness; + } + if (pos > 1 - this.barThickness) { + pos = 1 - this.barThickness; + } + first = pos - this.barThickness; + second = 1 - pos - this.barThickness; + firstCss = (100 * first - this.barThickness) + "%"; + secondCss = (100 * second - this.barThickness) + "%"; + } else { + shave = this.barThicknessPx; + if (this.docked) { + shave *= 2; + } + pos *= 100; + firstCss = "calc(" + pos + "% - " + shave + "px)"; + secondCss = "calc(" + (100 - pos) + "% - " + shave + "px)"; + } + attr = this.horizontal ? "width" : "height"; + this.getFirst().css(attr, firstCss); + return this.getSecond().css(attr, secondCss); + }; + + TouchSplitter.prototype.onMouseDown = function(event) { + event.preventDefault(); + this.initMouse = this.horizontal ? event.clientX : event.clientY; + return this.startDragging(event); + }; + + TouchSplitter.prototype.onTouchStart = function(event) { + var orig; + orig = event.originalEvent; + this.initMouse = this.horizontal ? orig.changedTouches[0].pageX : orig.changedTouches[0].pageY; + return this.startDragging(event); + }; + + TouchSplitter.prototype.onTouchMove = function(event) { + var orig, page; + if (!this.dragging) { + return; + } + event.preventDefault(); + orig = event.originalEvent; + page = this.horizontal ? orig.changedTouches[0].pageX : orig.changedTouches[0].pageY; + return this.moveBar(page); + }; + + TouchSplitter.prototype.onTouchEnd = function(event) { + return this.stopDragging(event); + }; + + TouchSplitter.prototype.startDragging = function(event) { + this.initBarPosition = this.barPosition; + this.isToggler = !!event.target.parentNode.className.match(/\bsplitter-bar\b/); + this.dragging = true; + return this.element.trigger("dragstart"); + }; + + TouchSplitter.prototype.drag = function(event) { + var client, whichM; + if (!this.dragging) { + return; + } + whichM = typeof event.buttons !== 'undefined' ? event.buttons : event.which; + if (whichM === 0) { + this.stopDragging(); + } + client = this.horizontal ? event.clientX : event.clientY; + return this.moveBar(client); + }; + + TouchSplitter.prototype.stopDragging = function(event) { + if (this.dragging) { + this.dragging = false; + this.element.trigger("dragstop"); + if (this.isToggler) { + return setTimeout((function(_this) { + return function() { + if ((_this.barPosition - _this.initBarPosition) === 0) { + return _this.toggleDock(); + } + }; + })(this), 0); + } + } + }; + + TouchSplitter.prototype.getFirst = function() { + return this.element.find('>div:first'); + }; + + TouchSplitter.prototype.getSecond = function() { + return this.element.find('>div:last'); + }; + + TouchSplitter.prototype.onResizeWindow = function(event) { + return this.resize(); + }; + + TouchSplitter.prototype.onResize = function(event) { + if (event != null) { + event.stopPropagation(); + if (!$(event.target).is(this.element)) { + return; + } + } + return this.resize(); + }; + + TouchSplitter.prototype.resize = function() { + var attr; + this.setRatios(); + attr = this.horizontal ? "width" : "height"; + if (!this.support.calc) { + this.barThickness = this.barThicknessPx / this.splitDistance; + if (this.barThickness > 1) { + this.barThickness = 1; + } + this.element.find('>.splitter-bar').css(attr, this.barThickness * 200 + '%'); + } else { + this.barThickness = 0; + } + return this.setPercentages(); + }; + + return TouchSplitter; + + })(); + }); + +}).call(this); diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/js/popcorn-complete.min.js --- a/server/src/remie/static/remie/js/popcorn-complete.min.js Mon Sep 28 14:32:54 2015 +0200 +++ b/server/src/remie/static/remie/js/popcorn-complete.min.js Fri Oct 02 10:24:23 2015 +0200 @@ -1,160 +1,209 @@ /* - * popcorn.js version 1.3 + * popcorn.js version 1.5.6 * http://popcornjs.org * * Copyright 2011, Mozilla Foundation * Licensed under the MIT license */ -(function(r,f){function n(a,g){return function(){if(d.plugin.debug)return a.apply(this,arguments);try{return a.apply(this,arguments)}catch(l){d.plugin.errors.push({plugin:g,thrown:l,source:a.toString()});this.emit("pluginerror",d.plugin.errors)}}}if(f.addEventListener){var c=Array.prototype,b=Object.prototype,e=c.forEach,h=c.slice,i=b.hasOwnProperty,j=b.toString,p=r.Popcorn,m=[],o=false,q={events:{hash:{},apis:{}}},s=function(){return r.requestAnimationFrame||r.webkitRequestAnimationFrame||r.mozRequestAnimationFrame|| -r.oRequestAnimationFrame||r.msRequestAnimationFrame||function(a){r.setTimeout(a,16)}}(),d=function(a,g){return new d.p.init(a,g||null)};d.version="1.3";d.isSupported=true;d.instances=[];d.p=d.prototype={init:function(a,g){var l,k=this;if(typeof a==="function")if(f.readyState==="complete")a(f,d);else{m.push(a);if(!o){o=true;var t=function(){f.removeEventListener("DOMContentLoaded",t,false);for(var z=0,C=m.length;z=2?v():k.media.addEventListener("loadeddata",v,false);return this}}};d.p.init.prototype= -d.p;d.byId=function(a){for(var g=d.instances,l=g.length,k=0;k=0;l--){k=a.data.running[g][l];k._natives.end.call(a,null,k)}}return a},enable:function(a,g){if(a.data.disabled[g]){a.data.disabled[g]=false;for(var l=a.data.running[g].length-1,k;l>=0;l--){k=a.data.running[g][l];k._natives.start.call(a,null,k)}}return a},destroy:function(a){var g= -a.data.events,l=a.data.trackEvents,k,t,u,v;for(t in g){k=g[t];for(u in k)delete k[u];g[t]=null}for(v in d.registryByName)d.removePlugin(a,v);l.byStart.length=0;l.byEnd.length=0;if(!a.isDestroyed){a.data.timeUpdate&&a.media.removeEventListener("timeupdate",a.data.timeUpdate,false);a.isDestroyed=true}}});d.guid.counter=1;d.extend(d.p,function(){var a={};d.forEach("load play pause currentTime playbackRate volume duration preload playbackRate autoplay loop controls muted buffered readyState seeking paused played seekable ended".split(/\s+/g), -function(g){a[g]=function(l){var k;if(typeof this.media[g]==="function"){if(l!=null&&/play|pause/.test(g))this.media.currentTime=d.util.toSeconds(l);this.media[g]();return this}if(l!=null){k=this.media[g];this.media[g]=l;k!==l&&this.emit("attrchange",{attribute:g,previousValue:k,currentValue:l});return this}return this.media[g]}});return a}());d.forEach("enable disable".split(" "),function(a){d.p[a]=function(g){return d[a](this,g)}});d.extend(d.p,{roundTime:function(){return Math.round(this.media.currentTime)}, -exec:function(a,g,l){var k=arguments.length,t,u;try{u=d.util.toSeconds(a)}catch(v){}if(typeof u==="number")a=u;if(typeof a==="number"&&k===2){l=g;g=a;a=d.guid("cue")}else if(k===1)g=-1;else if(t=this.getTrackEvent(a)){if(typeof a==="string"&&k===2){if(typeof g==="number")l=t._natives.start;if(typeof g==="function"){l=g;g=t.start}}}else if(k>=2){if(typeof g==="string"){try{u=d.util.toSeconds(g)}catch(z){}g=u}if(typeof g==="number")l=d.nop();if(typeof g==="function"){l=g;g=-1}}d.addTrackEvent(this, -{id:a,start:g,end:g+1,_running:false,_natives:{start:l||d.nop,end:d.nop,type:"cue"}});return this},mute:function(a){a=a==null||a===true?"muted":"unmuted";if(a==="unmuted"){this.media.muted=false;this.media.volume=this.data.state.volume}if(a==="muted"){this.data.state.volume=this.media.volume;this.media.muted=true}this.emit(a);return this},unmute:function(a){return this.mute(a==null?false:!a)},position:function(){return d.position(this.media)},toggle:function(a){return d[this.data.disabled[a]?"enable": -"disable"](this,a)},defaults:function(a,g){if(d.isArray(a)){d.forEach(a,function(l){for(var k in l)this.defaults(k,l[k])},this);return this}if(!this.options.defaults)this.options.defaults={};this.options.defaults[a]||(this.options.defaults[a]={});d.extend(this.options.defaults[a],g);return this}});d.Events={UIEvents:"blur focus focusin focusout load resize scroll unload",MouseEvents:"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave click dblclick",Events:"loadstart progress suspend emptied stalled play pause error loadedmetadata loadeddata waiting playing canplay canplaythrough seeking seeked timeupdate ended ratechange durationchange volumechange"}; -d.Events.Natives=d.Events.UIEvents+" "+d.Events.MouseEvents+" "+d.Events.Events;q.events.apiTypes=["UIEvents","MouseEvents","Events"];(function(a,g){for(var l=q.events.apiTypes,k=a.Natives.split(/\s+/g),t=0,u=k.length;t-1&&this.media.addEventListener(a,function(v){d.forEach(l.data.events[a],function(z){typeof z==="function"&&z.call(l,v)})},false);return this},unlisten:function(a,g){if(this.data.events[a]&&this.data.events[a][g]){delete this.data.events[a][g]; -return this}this.data.events[a]=null;return this}},hooks:{canplayall:{bind:"canplaythrough",add:function(a,g){var l=false;if(this.media.readyState){g.call(this,a);l=true}this.data.hooks.canplayall={fired:l}},handler:function(a,g){if(!this.data.hooks.canplayall.fired){g.call(this,a);this.data.hooks.canplayall.fired=true}}}}};d.forEach([["trigger","emit"],["listen","on"],["unlisten","off"]],function(a){d.p[a[0]]=d.p[a[1]]=d.events.fn[a[0]]});d.addTrackEvent=function(a,g){var l,k;if(g.id)l=a.getTrackEvent(g.id); -if(l){k=true;g=d.extend({},l,g);a.removeTrackEvent(g.id)}if(g&&g._natives&&g._natives.type&&a.options.defaults&&a.options.defaults[g._natives.type])g=d.extend({},a.options.defaults[g._natives.type],g);if(g._natives){g._id=g.id||g._id||d.guid(g._natives.type);a.data.history.push(g._id)}g.start=d.util.toSeconds(g.start,a.options.framerate);g.end=d.util.toSeconds(g.end,a.options.framerate);var t=a.data.trackEvents.byStart,u=a.data.trackEvents.byEnd,v;for(v=t.length-1;v>=0;v--)if(g.start>=t[v].start){t.splice(v+ -1,0,g);break}for(t=u.length-1;t>=0;t--)if(g.end>u[t].end){u.splice(t+1,0,g);break}if(g.end>a.media.currentTime&&g.start<=a.media.currentTime){g._running=true;a.data.running[g._natives.type].push(g);a.data.disabled[g._natives.type]||g._natives.start.call(a,null,g)}v<=a.data.trackEvents.startIndex&&g.start<=a.data.trackEvents.previousUpdateTime&&a.data.trackEvents.startIndex++;t<=a.data.trackEvents.endIndex&&g.end-1;){l=a.data.trackEvents.byStart[v];k=a.data.trackEvents.byEnd[v];if(!l._id){C.push(l); -E.push(k)}if(l._id){l._id!==g&&C.push(l);k._id!==g&&E.push(k);if(l._id===g){z=v;l._natives._teardown&&l._natives._teardown.call(a,l)}}v++}u=a.data.trackEvents.animating.length;v=0;if(u)for(;--u>-1;){l=a.data.trackEvents.animating[v];l._id||B.push(l);l._id&&l._id!==g&&B.push(l);v++}z<=a.data.trackEvents.startIndex&&a.data.trackEvents.startIndex--;z<=a.data.trackEvents.endIndex&&a.data.trackEvents.endIndex--;a.data.trackEvents.byStart=C;a.data.trackEvents.byEnd=E;a.data.trackEvents.animating=B;for(u= -0;ul&&B._running===false){B._running=true;a.data.running[w].push(B);if(!a.data.disabled[w]){k.start.call(a,g,B);a.emit("trackstart",d.extend({},B,{plugin:w,type:"trackstart"}))}}v++}else{d.removeTrackEvent(a,B._id);return}}}else if(k>l){for(;t.byStart[v]&&t.byStart[v].start>l;){B=t.byStart[v];w=(k=B._natives)&& -k.type;if(!k||E[w]||a[w]){if(B._running===true){B._running=false;D=a.data.running[w];D.splice(D.indexOf(B),1);if(!a.data.disabled[w]){k.end.call(a,g,B);a.emit("trackend",d.extend({},B,{plugin:w,type:"trackend"}))}}v--}else{d.removeTrackEvent(a,B._id);return}}for(;t.byEnd[u]&&t.byEnd[u].end>l;){B=t.byEnd[u];w=(k=B._natives)&&k.type;if(!k||E[w]||a[w]){if(B.start<=l&&B._running===false){B._running=true;a.data.running[w].push(B);if(!a.data.disabled[w]){k.start.call(a,g,B);a.emit("trackstart",d.extend({}, -B,{plugin:w,type:"trackstart"}))}}u--}else{d.removeTrackEvent(a,B._id);return}}}t.endIndex=u;t.startIndex=v;t.previousUpdateTime=l;t.byStart.length=0)d.error("'"+a+"' is a protected function name");else{var k=["start","end"],t={},u=typeof g==="function",v=["_setup","_teardown","start","end","frame"],z=function(B,w){B=B||d.nop;w=w|| -d.nop;return function(){B.apply(this,arguments);w.apply(this,arguments)}};d.manifest[a]=l=l||g.manifest||{};v.forEach(function(B){g[B]=n(g[B]||d.nop,a)});var C=function(B,w){if(!w)return this;if(w.ranges&&d.isArray(w.ranges)){d.forEach(w.ranges,function(G){G=d.extend({},w,G);delete G.ranges;this[a](G)},this);return this}var D=w._natives={},F="",I;d.extend(D,B);w._natives.type=a;w._running=false;D.start=D.start||D["in"];D.end=D.end||D.out;if(w.once)D.end=z(D.end,function(){this.removeTrackEvent(w._id)}); -D._teardown=z(function(){var G=h.call(arguments),H=this.data.running[D.type];G.unshift(null);G[1]._running&&H.splice(H.indexOf(w),1)&&D.end.apply(this,G)},D._teardown);w.compose=w.compose&&w.compose.split(" ")||[];w.effect=w.effect&&w.effect.split(" ")||[];w.compose=w.compose.concat(w.effect);w.compose.forEach(function(G){F=d.compositions[G]||{};v.forEach(function(H){D[H]=z(D[H],F[H])})});w._natives.manifest=l;if(!("start"in w))w.start=w["in"]||0;if(!w.end&&w.end!==0)w.end=w.out||Number.MAX_VALUE; -if(!i.call(w,"toString"))w.toString=function(){var G=["start: "+w.start,"end: "+w.end,"id: "+(w.id||w._id)];w.target!=null&&G.push("target: "+w.target);return a+" ( "+G.join(", ")+" )"};if(!w.target){I="options"in l&&l.options;w.target=I&&"target"in I&&I.target}if(w._natives)w._id=d.guid(w._natives.type);w._natives._setup&&w._natives._setup.call(this,w);d.addTrackEvent(this,w);d.forEach(B,function(G,H){H!=="type"&&k.indexOf(H)===-1&&this.on(H,G)},this);return this};d.p[a]=t[a]=function(B,w){var D; -if(B&&!w)w=B;else if(D=this.getTrackEvent(B)){w=d.extend({},D,w);d.addTrackEvent(this,w);return this}else w.id=B;this.data.running[a]=this.data.running[a]||[];D=d.extend({},this.options.defaults&&this.options.defaults[a]||{},w);return C.call(this,u?g.call(this,D):g,D)};l&&d.extend(g,{manifest:l});var E={fn:t[a],definition:g,base:g,parents:[],name:a};d.registry.push(d.extend(t,E,{type:a}));d.registryByName[a]=E;return t}};d.plugin.errors=[];d.plugin.debug=d.version==="1.3";d.removePlugin=function(a, -g){if(!g){g=a;a=d.p;if(d.protect.natives.indexOf(g.toLowerCase())>=0){d.error("'"+g+"' is a protected function name");return}var l=d.registry.length,k;for(k=0;k-1){t=t.split(";");u=0;if(g&&typeof g==="number")u=parseFloat(t[1],10)/g;l[k]=parseInt(t[0],10)+u}k=l[0];return{1:parseFloat(k,10),2:parseInt(k,10)*60+parseFloat(l[1],10),3:parseInt(k,10)*3600+parseInt(l[1],10)*60+parseFloat(l[2],10)}[l.length||1]}};d.p.cue=d.p.exec;d.protect={natives:function(a){return Object.keys?Object.keys(a):function(g){var l,k=[];for(l in g)i.call(g,l)&&k.push(l);return k}(a)}(d.p).map(function(a){return a.toLowerCase()})};d.forEach({listen:"on",unlisten:"off", -trigger:"emit",exec:"cue"},function(a,g){var l=d.p[g];d.p[g]=function(){if(typeof console!=="undefined"&&console.warn){console.warn("Deprecated method '"+g+"', "+(a==null?"do not use.":"use '"+a+"' instead."));d.p[g]=l}return d.p[a].apply(this,[].slice.call(arguments))}});r.Popcorn=d}else{r.Popcorn={isSupported:false};for(c="byId forEach extend effects error guid sizeOf isArray nop position disable enable destroyaddTrackEvent removeTrackEvent getTrackEvents getTrackEvent getLastTrackEventId timeUpdate plugin removePlugin compose effect xhr getJSONP getScript".split(/\s+/);c.length;)r.Popcorn[c.shift()]= -function(){}}})(window,window.document);(function(r,f){var n=r.document,c=r.location,b=/:\/\//,e=c.href.replace(c.href.split("/").slice(-1)[0],""),h=function(j,p,m){j=j||0;p=(p||j||0)+1;m=m||1;p=Math.ceil((p-j)/m)||0;var o=0,q=[];for(q.length=p;o= -o["in"]&&j<=o.out)m=q});j+=this.inOuts.ofVideos[m]["in"]-this.inOuts.ofClips[m]["in"];f.addTrackEvent(this.playlist[m],{start:j-1,end:j,_running:false,_natives:{start:p||f.nop,end:f.nop,type:"exec"}});return this},listen:function(j,p){var m=this,o=this.playlist,q=o.length,s=0;if(!p)p=f.nop;if(f.Events.Natives.indexOf(j)>-1)f.forEach(o,function(d){d.listen(j,function(A){A.active=m;if(i.indexOf(j)>-1)p.call(d,A);else++s===q&&p.call(d,A)})});else{this.events[j]||(this.events[j]={});o=p.name||f.guid("__"+ -j);this.events[j][o]=p}return this},unlisten:function(){},trigger:function(j,p){var m=this;if(!(f.Events.Natives.indexOf(j)>-1)){this.events[j]&&f.forEach(this.events[j],function(o){o.call(m,{type:j},p)});return this}}});f.forEach(f.manifest,function(j,p){f.sequence.prototype[p]=function(m){var o={},q=[],s,d,A,y,x;for(s=0;s-1)o[s]=f.extend({},q,{start:d[A],clipIdx:A});if(y>-1)o[s]= -f.extend({},q,{end:d[y],clipIdx:y})}s=Object.keys(o).map(function(g){return+g});q=h(s[0],s[1]);for(s=0;s=0)r.error("'"+n+"' is a protected function name");else{if(typeof c==="function"&&!b){b=c;c=""}if(!(typeof b!=="function"||typeof c!=="string")){var e={};e[n]=function(h,i){if(!h)return this;var j=this;r.xhr({url:h,dataType:c,success:function(p){var m,o,q=0;p=b(p).data||[];if(m=p.length){for(;q=4){o=new Date/1E3;a.dispatchEvent("play");l()}};a.pause=function(){this.paused= -true;a.dispatchEvent("pause")};r.player.defineProperty(a,"currentTime",{get:function(){return q},set:function(k){q=+k;a.dispatchEvent("timeupdate");return q},configurable:true});r.player.defineProperty(a,"volume",{get:function(){return d},set:function(k){d=+k;a.dispatchEvent("volumechange");return d},configurable:true});r.player.defineProperty(a,"muted",{get:function(){return A},set:function(k){A=+k;a.dispatchEvent("volumechange");return A},configurable:true});r.player.defineProperty(a,"readyState", -{get:function(){return s},set:function(k){return s=k},configurable:true});a.addEventListener=function(k,t){y[k]||(y[k]=[]);y[k].push(t);return t};a.removeEventListener=function(k,t){var u,v=y[k];if(v){for(u=y[k].length-1;u>=0;u--)t===v[u]&&v.splice(u,1);return t}};a.dispatchEvent=function(k){var t,u=k.type;if(!u){u=k;if(k=r.events.getInterface(u)){t=document.createEvent(k);t.initEvent(u,true,true,window,1)}}if(y[u])for(k=y[u].length-1;k>=0;k--)y[u][k].call(this,t,this)};a.src=j||"";a.duration=0;a.paused= -true;a.ended=0;p&&p.events&&r.forEach(p.events,function(k,t){a.addEventListener(t,k,false)});if(e._canPlayType(x.nodeName,j)!==false)if(e._setup)e._setup.call(a,p);else{a.readyState=4;a.dispatchEvent("loadedmetadata");a.dispatchEvent("loadeddata");a.dispatchEvent("canplaythrough")}else setTimeout(function(){a.dispatchEvent("error")},0);i=new r.p.init(a,p);if(e._teardown)i.destroy=f(i.destroy,function(){e._teardown.call(a,p)});return i};h.canPlayType=e._canPlayType=e._canPlayType||r.nop;r[b]=r.player.registry[b]= -h}};r.player.registry={};r.player.defineProperty=Object.defineProperty||function(b,e,h){b.__defineGetter__(e,h.get||r.nop);b.__defineSetter__(e,h.set||r.nop)};r.player.playerQueue=function(){var b=[],e=false;return{next:function(){e=false;b.shift();b[0]&&b[0]()},add:function(h){b.push(function(){e=true;h&&h()});!e&&b[0]()}}};r.smart=function(b,e,h){var i=["AUDIO","VIDEO"],j,p=r.dom.find(b),m;j=document.createElement("video");var o={ogg:"video/ogg",ogv:"video/ogg",oga:"audio/ogg",webm:"video/webm", -mp4:"video/mp4",mp3:"audio/mp3"};if(p){if(i.indexOf(p.nodeName)>-1&&!e){if(typeof e==="object")h=e;return r(p,h)}if(typeof e==="string")e=[e];b=0;for(srcLength=e.length;b"+y.title+"

";r.forEach(y.items,function(a,g){if(g"']/g,function(e){return c[e]||e})}function n(b,e){var h=b.container=document.createElement("div"),i=h.style,j=b.media,p=function(){var m=b.position();i.fontSize="18px";i.width=j.offsetWidth+"px";i.top=m.top+j.offsetHeight-h.offsetHeight-40+"px";i.left=m.left+"px";setTimeout(p,10)};h.id=e||"";i.position="absolute";i.color="white";i.textShadow="black 2px 2px 6px";i.fontWeight="bold";i.textAlign="center";p();b.media.parentNode.appendChild(h); -return h}var c={"&":"&","<":"<",">":">",'"':""","'":"'"};r.plugin("text",{manifest:{about:{name:"Popcorn Text Plugin",version:"0.1",author:"@humphd"},options:{start:{elem:"input",type:"number",label:"Start"},end:{elem:"input",type:"number",label:"End"},text:{elem:"input",type:"text",label:"Text","default":"Popcorn.js"},escape:{elem:"input",type:"checkbox",label:"Escape"},multiline:{elem:"input",type:"checkbox",label:"Multiline"}}},_setup:function(b){var e,h,i=b._container=document.createElement("div"); -i.style.display="none";if(b.target)if(e=r.dom.find(b.target)){if(["VIDEO","AUDIO"].indexOf(e.nodeName)>-1)e=n(this,b.target+"-overlay")}else e=n(this,b.target);else e=this.container?this.container:n(this);b._target=e;h=b.escape?f(b.text):b.text;h=b.multiline?h.replace(/\r?\n/gm,"
"):h;i.innerHTML=h||"";e.appendChild(i)},start:function(b,e){e._container.style.display="inline"},end:function(b,e){e._container.style.display="none"},_teardown:function(b){var e=b._target;e&&e.removeChild(b._container)}})})(Popcorn);var googleCallback; -(function(r){function f(i,j,p){i=i.type?i.type.toUpperCase():"HYBRID";var m;if(i==="STAMEN-WATERCOLOR"||i==="STAMEN-TERRAIN"||i==="STAMEN-TONER")m=i.replace("STAMEN-","").toLowerCase();p=new google.maps.Map(p,{mapTypeId:m?m:google.maps.MapTypeId[i],mapTypeControlOptions:{mapTypeIds:[]}});m&&p.mapTypes.set(m,new google.maps.StamenMapType(m));p.getDiv().style.display="none";return p}var n=1,c=false,b=false,e,h;googleCallback=function(i){if(typeof google!=="undefined"&&google.maps&&google.maps.Geocoder&& -google.maps.LatLng){e=new google.maps.Geocoder;r.getScript("//maps.stamen.com/js/tile.stamen.js",function(){b=true})}else setTimeout(function(){googleCallback(i)},1)};h=function(){if(document.body){c=true;r.getScript("//maps.google.com/maps/api/js?sensor=false&callback=googleCallback")}else setTimeout(function(){h()},1)};r.plugin("googlemap",function(i){var j,p,m,o=document.getElementById(i.target);i.type=i.type||"ROADMAP";i.zoom=i.zoom||1;i.lat=i.lat||0;i.lng=i.lng||0;c||h();j=document.createElement("div"); -j.id="actualmap"+n;j.style.width=i.width||"100%";j.style.height=i.height?i.height:o&&o.clientHeight?o.clientHeight+"px":"100%";n++;o&&o.appendChild(j);var q=function(){if(b){if(j)if(i.location)e.geocode({address:i.location},function(s,d){if(j&&d===google.maps.GeocoderStatus.OK){i.lat=s[0].geometry.location.lat();i.lng=s[0].geometry.location.lng();m=new google.maps.LatLng(i.lat,i.lng);p=f(i,m,j)}});else{m=new google.maps.LatLng(i.lat,i.lng);p=f(i,m,j)}}else setTimeout(function(){q()},5)};q();return{start:function(s, -d){var A=this,y,x=function(){if(p){d._map=p;p.getDiv().style.display="block";google.maps.event.trigger(p,"resize");p.setCenter(m);if(d.zoom&&typeof d.zoom!=="number")d.zoom=+d.zoom;p.setZoom(d.zoom);if(d.heading&&typeof d.heading!=="number")d.heading=+d.heading;if(d.pitch&&typeof d.pitch!=="number")d.pitch=+d.pitch;if(d.type==="STREETVIEW"){p.setStreetView(y=new google.maps.StreetViewPanorama(j,{position:m,pov:{heading:d.heading=d.heading||0,pitch:d.pitch=d.pitch||0,zoom:d.zoom}}));var a=function(z, -C){var E=google.maps.geometry.spherical.computeHeading;setTimeout(function(){var B=A.media.currentTime;if(typeof d.tween==="object"){for(var w=0,D=z.length;w=F.interval*(w+1)/1E3&&(B<=F.interval*(w+2)/1E3||B>=F.interval*D/1E3)){u.setPosition(new google.maps.LatLng(F.position.lat,F.position.lng));u.setPov({heading:F.pov.heading||E(F,z[w+1])||0,zoom:F.pov.zoom||0,pitch:F.pov.pitch||0})}}a(z,z[0].interval)}else{w=0;for(D=z.length;w=F*(w+1)/1E3&&(B<=F* -(w+2)/1E3||B>=F*D/1E3)){g.setPov({heading:E(z[w],z[w+1])||0,zoom:d.zoom,pitch:d.pitch||0});g.setPosition(l[w])}}a(l,d.interval)}},C)};if(d.location&&typeof d.tween==="string"){var g=y,l=[],k=new google.maps.DirectionsService,t=new google.maps.DirectionsRenderer(g);k.route({origin:d.location,destination:d.tween,travelMode:google.maps.TravelMode.DRIVING},function(z,C){if(C==google.maps.DirectionsStatus.OK){t.setDirections(z);for(var E=z.routes[0].overview_path,B=0,w=E.length;B-1){b.trackedContainer=f(h);b.trackedContainer.element.appendChild(b.anchor)}else h&&h.appendChild(b.anchor); -e.addEventListener("load",function(){e.style.borderStyle="none";b.anchor.href=b.href||b.src||"#";b.anchor.target="_blank";var i,j;e.style.height=h.style.height;e.style.width=h.style.width;b.anchor.appendChild(e);if(b.text){i=e.height/12+"px";j=document.createElement("div");r.extend(j.style,{color:"black",fontSize:i,fontWeight:"bold",position:"relative",textAlign:"center",width:e.style.width||e.width+"px",zIndex:"10"});j.innerHTML=b.text||"";j.style.top=(e.style.height.replace("px","")||e.height)/ -2-j.offsetHeight/2+"px";b.anchor.insertBefore(j,e)}},false);e.src=b.src},start:function(b,e){e.anchor.style.display="inline";e.trackedContainer&&e.trackedContainer.start()},end:function(b,e){e.anchor.style.display="none";e.trackedContainer&&e.trackedContainer.stop()},_teardown:function(b){if(b.trackedContainer)b.trackedContainer.destroy();else b.anchor.parentNode&&b.anchor.parentNode.removeChild(b.anchor)}})})(Popcorn);(function(r){var f=1,n=false;r.plugin("googlefeed",function(c){var b=function(){var j=false,p=0,m=document.getElementsByTagName("link"),o=m.length,q=document.head||document.getElementsByTagName("head")[0],s=document.createElement("link");if(window.GFdynamicFeedControl)n=true;else r.getScript("//www.google.com/uds/solutions/dynamicfeed/gfdynamicfeedcontrol.js",function(){n=true});for(;p")); -n=n.replace(/((<(.|\n)+?>)|(\((.*?)\) )|(\[(.*?)\]))/g,"");n=n.split(" ");f._desc.innerHTML=n.slice(0,n.length>=f.numberofwords?f.numberofwords:n.length).join(" ")+" ...";f._fired=true};f.src&&r.getScript("//"+f.lang+".wikipedia.org/w/api.php?action=parse&props=text&redirects&page="+f.src.slice(f.src.lastIndexOf("/")+1)+"&format=json&callback=wikiCallback"+c)},start:function(f,n){var c=function(){if(n._fired){if(n._link&&n._desc)if(document.getElementById(n.target)){document.getElementById(n.target).appendChild(n._link); -document.getElementById(n.target).appendChild(n._desc);n._added=true}}else setTimeout(function(){c()},13)};c()},end:function(f,n){if(n._added){document.getElementById(n.target).removeChild(n._link);document.getElementById(n.target).removeChild(n._desc)}},_teardown:function(f){if(f._added){f._link.parentNode&&document.getElementById(f.target).removeChild(f._link);f._desc.parentNode&&document.getElementById(f.target).removeChild(f._desc);delete f.target}}})})(Popcorn);(function(r){r.plugin("mustache",function(f){var n,c,b,e;r.getScript("http://mustache.github.com/extras/mustache.js");var h=!!f.dynamic,i=typeof f.template,j=typeof f.data,p=document.getElementById(f.target);f.container=p||document.createElement("div");if(i==="function")if(h)b=f.template;else e=f.template(f);else e=i==="string"?f.template:"";if(j==="function")if(h)n=f.data;else c=f.data(f);else c=j==="string"?JSON.parse(f.data):j==="object"?f.data:"";return{start:function(m,o){var q=function(){if(window.Mustache){if(n)c= -n(o);if(b)e=b(o);var s=Mustache.to_html(e,c).replace(/^\s*/mg,"");o.container.innerHTML=s}else setTimeout(function(){q()},10)};q()},end:function(m,o){o.container.innerHTML=""},_teardown:function(){n=c=b=e=null}}},{about:{name:"Popcorn Mustache Plugin",version:"0.1",author:"David Humphrey (@humphd)",website:"http://vocamus.net/dave"},options:{start:{elem:"input",type:"number",label:"Start"},end:{elem:"input",type:"number",label:"End"},target:"mustache-container",template:{elem:"input",type:"text", -label:"Template"},data:{elem:"input",type:"text",label:"Data"},dynamic:{elem:"input",type:"checkbox",label:"Dynamic","default":true}}})})(Popcorn);(function(r){function f(c,b){if(c.map)c.map.div.style.display=b;else setTimeout(function(){f(c,b)},10)}var n=1;r.plugin("openmap",function(c){var b,e,h,i,j,p,m,o,q=document.getElementById(c.target);b=document.createElement("div");b.id="openmapdiv"+n;b.style.width="100%";b.style.height="100%";n++;q&&q.appendChild(b);o=function(){if(window.OpenLayers&&window.OpenLayers.Layer.Stamen){if(c.location){location=new OpenLayers.LonLat(0,0);r.getJSONP("//tinygeocoder.com/create-api.php?q="+c.location+"&callback=jsonp", -function(d){e=new OpenLayers.LonLat(d[1],d[0])})}else e=new OpenLayers.LonLat(c.lng,c.lat);c.type=c.type||"ROADMAP";switch(c.type){case "SATELLITE":c.map=new OpenLayers.Map({div:b,maxResolution:0.28125,tileSize:new OpenLayers.Size(512,512)});var s=new OpenLayers.Layer.WorldWind("LANDSAT","//worldwind25.arc.nasa.gov/tile/tile.aspx",2.25,4,{T:"105"});c.map.addLayer(s);i=new OpenLayers.Projection("EPSG:4326");h=new OpenLayers.Projection("EPSG:4326");break;case "TERRAIN":i=new OpenLayers.Projection("EPSG:4326"); -h=new OpenLayers.Projection("EPSG:4326");c.map=new OpenLayers.Map({div:b,projection:h});s=new OpenLayers.Layer.WMS("USGS Terraserver","//terraserver-usa.org/ogcmap.ashx?",{layers:"DRG"});c.map.addLayer(s);break;case "STAMEN-TONER":case "STAMEN-WATERCOLOR":case "STAMEN-TERRAIN":s=c.type.replace("STAMEN-","").toLowerCase();s=new OpenLayers.Layer.Stamen(s);i=new OpenLayers.Projection("EPSG:4326");h=new OpenLayers.Projection("EPSG:900913");e=e.transform(i,h);c.map=new OpenLayers.Map({div:b,projection:h, -displayProjection:i,controls:[new OpenLayers.Control.Navigation,new OpenLayers.Control.PanPanel,new OpenLayers.Control.ZoomPanel]});c.map.addLayer(s);break;default:h=new OpenLayers.Projection("EPSG:900913");i=new OpenLayers.Projection("EPSG:4326");e=e.transform(i,h);c.map=new OpenLayers.Map({div:b,projection:h,displayProjection:i});s=new OpenLayers.Layer.OSM;c.map.addLayer(s)}if(c.map){c.map.setCenter(e,c.zoom||10);c.map.div.style.display="none"}}else setTimeout(function(){o()},50)};o();return{_setup:function(s){window.OpenLayers|| -r.getScript("//openlayers.org/api/OpenLayers.js",function(){r.getScript("//maps.stamen.com/js/tile.stamen.js")});var d=function(){if(s.map){s.zoom=s.zoom||2;if(s.zoom&&typeof s.zoom!=="number")s.zoom=+s.zoom;s.map.setCenter(e,s.zoom);if(s.markers){var A=OpenLayers.Util.extend({},OpenLayers.Feature.Vector.style["default"]),y=function(v){clickedFeature=v.feature;if(clickedFeature.attributes.text){m=new OpenLayers.Popup.FramedCloud("featurePopup",clickedFeature.geometry.getBounds().getCenterLonLat(), -new OpenLayers.Size(120,250),clickedFeature.attributes.text,null,true,function(){p.unselect(this.feature)});clickedFeature.popup=m;m.feature=clickedFeature;s.map.addPopup(m)}},x=function(v){feature=v.feature;if(feature.popup){m.feature=null;s.map.removePopup(feature.popup);feature.popup.destroy();feature.popup=null}},a=function(v){r.getJSONP("//tinygeocoder.com/create-api.php?q="+v.location+"&callback=jsonp",function(z){z=(new OpenLayers.Geometry.Point(z[1],z[0])).transform(i,h);var C=OpenLayers.Util.extend({}, -A);if(!v.size||isNaN(v.size))v.size=14;C.pointRadius=v.size;C.graphicOpacity=1;C.externalGraphic=v.icon;z=new OpenLayers.Feature.Vector(z,null,C);if(v.text)z.attributes={text:v.text};j.addFeatures([z])})};j=new OpenLayers.Layer.Vector("Point Layer",{style:A});s.map.addLayer(j);for(var g=0,l=s.markers.length;g0;D--)M[D].end>B&&j.removeTrackEvent(M[D]._id);for(M=0;MB&&j.removeTrackEvent(K[M]._id);j.data.trackEvents.byEnd.push({start:Q,end:Q});j.data.trackEvents.byStart.push({start:Q,end:Q})};j.media.addEventListener("durationchange", +j.data.durationChange,false)}if(j.options.frameAnimation){j.data.timeUpdate=function(){f.timeUpdate(j,{});f.forEach(f.manifest,function(B,Q){if(v=j.data.running[Q]){y=v.length;for(var K=0;K=1?z():j.media.addEventListener("loadedmetadata",z,false);return this}}};f.p.init.prototype=f.p;f.byId=function(a){for(var c=f.instances,n=c.length,j=0;j=0;n--){j=a.data.running[c][n];j._natives.end.call(a, +null,j);a.emit("trackend",f.extend({},j,{plugin:j.type,type:"trackend"}))}return a}},enable:function(a,c){if(a.data.disabled[c]){a.data.disabled[c]=false;if(c in f.registryByName&&a.data.running[c])for(var n=a.data.running[c].length-1,j;n>=0;n--){j=a.data.running[c][n];j._natives.start.call(a,null,j);a.emit("trackstart",f.extend({},j,{plugin:j.type,type:"trackstart",track:j}))}return a}},destroy:function(a){var c=a.data.events,n=a.data.trackEvents,j,w,x,z;for(w in c){j=c[w];for(x in j)delete j[x]; +c[w]=null}for(z in f.registryByName)f.removePlugin(a,z);n.byStart.length=0;n.byEnd.length=0;if(!a.isDestroyed){a.data.timeUpdate&&a.media.removeEventListener("timeupdate",a.data.timeUpdate,false);a.isDestroyed=true}f.instances.splice(f.instances.indexOf(a),1)}});f.guid.counter=1;f.extend(f.p,function(){var a={};f.forEach("load play pause currentTime playbackRate volume duration preload playbackRate autoplay loop controls muted buffered readyState seeking paused played seekable ended".split(/\s+/g), +function(c){a[c]=function(n){var j;if(typeof this.media[c]==="function"){if(n!=null&&/play|pause/.test(c))this.media.currentTime=f.util.toSeconds(n);this.media[c]();return this}if(n!=null){j=this.media[c];this.media[c]=n;j!==n&&this.emit("attrchange",{attribute:c,previousValue:j,currentValue:n});return this}return this.media[c]}});return a}());f.forEach("enable disable".split(" "),function(a){f.p[a]=function(c){return f[a](this,c)}});f.extend(f.p,{roundTime:function(){return Math.round(this.media.currentTime)}, +exec:function(a,c,n){var j=arguments.length,w="trackadded",x,z;try{z=f.util.toSeconds(a)}catch(F){}if(typeof z==="number")a=z;if(typeof a==="number"&&j===2){n=c;c=a;a=f.guid("cue")}else if(j===1)c=-1;else if(x=this.getTrackEvent(a)){this.data.trackEvents.remove(a);l.end(this,x);f.removeTrackEvent.ref(this,a);w="cuechange";if(typeof a==="string"&&j===2){if(typeof c==="number")n=x._natives.start;if(typeof c==="function"){n=c;c=x.start}}}else if(j>=2){if(typeof c==="string"){try{z=f.util.toSeconds(c)}catch(v){}c= +z}if(typeof c==="number")n=n||f.nop();if(typeof c==="function"){n=c;c=-1}}j={id:a,start:c,end:c+1,_running:false,_natives:{start:n||f.nop,end:f.nop,type:"cue"}};if(x)j=f.extend(x,j);if(w==="cuechange"){j._id=j.id||j._id||f.guid(j._natives.type);this.data.trackEvents.add(j);l.start(this,j);this.timeUpdate(this,null,true);f.addTrackEvent.ref(this,j);this.emit(w,f.extend({},j,{id:a,type:w,previousValue:{time:x.start,fn:x._natives.start},currentValue:{time:c,fn:n||f.nop},track:x}))}else f.addTrackEvent(this, +j);return this},mute:function(a){a=a==null||a===true?"muted":"unmuted";if(a==="unmuted"){this.media.muted=false;this.media.volume=this.data.state.volume}if(a==="muted"){this.data.state.volume=this.media.volume;this.media.muted=true}this.emit(a);return this},unmute:function(a){return this.mute(a==null?false:!a)},position:function(){return f.position(this.media)},toggle:function(a){return f[this.data.disabled[a]?"enable":"disable"](this,a)},defaults:function(a,c){if(f.isArray(a)){f.forEach(a,function(n){for(var j in n)this.defaults(j, +n[j])},this);return this}if(!this.options.defaults)this.options.defaults={};this.options.defaults[a]||(this.options.defaults[a]={});f.extend(this.options.defaults[a],c);return this}});f.Events={UIEvents:"blur focus focusin focusout load resize scroll unload",MouseEvents:"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave click dblclick",Events:"loadstart progress suspend emptied stalled play pause error loadedmetadata loadeddata waiting playing canplay canplaythrough seeking seeked timeupdate ended ratechange durationchange volumechange"}; +f.Events.Natives=f.Events.UIEvents+" "+f.Events.MouseEvents+" "+f.Events.Events;u.events.apiTypes=["UIEvents","MouseEvents","Events"];(function(a,c){for(var n=u.events.apiTypes,j=a.Natives.split(/\s+/g),w=0,x=j.length;w-1&&this.media.addEventListener(a,function(F){if(n.data.events[a])for(x=n.data.events[a].slice();x.length;)x.shift().call(n,F)},false);return this},unlisten:function(a,c){var n,j=this.data.events[a];if(j){if(typeof c=== +"string"){for(n=0;na.media.currentTime&&c.start<=a.media.currentTime&&!c._running){c._running=true;a.data.running[c._natives.type].push(c);if(!a.data.disabled[c._natives.type]){c._natives.start.call(a,null,c);a.emit("trackstart",f.extend({},c,{plugin:c._natives.type,type:"trackstart",track:c}))}}};l.end=function(a,c){var n;if((c.end<=a.media.currentTime||c.start> +a.media.currentTime)&&c._running){n=a.data.running[c._natives.type];c._running=false;n.splice(n.indexOf(c),1);if(!a.data.disabled[c._natives.type]){c._natives.end.call(a,null,c);a.emit("trackend",f.extend({},c,{plugin:c._natives.type,type:"trackend",track:c}))}}};d.prototype.where=function(a){return(this.parent.getTrackEvents()||[]).filter(function(c){var n,j;if(!a)return true;for(n in a){j=a[n];if(c[n]&&c[n]===j||c._natives[n]&&c._natives[n]===j)return true}return false})};d.prototype.add=function(a){var c= +this.byStart,n=this.byEnd,j;a&&a._id&&this.parent.data.history.push(a._id);a.start=f.util.toSeconds(a.start,this.parent.options.framerate);a.end=f.util.toSeconds(a.end,this.parent.options.framerate);for(j=c.length-1;j>=0;j--)if(a.start>=c[j].start){c.splice(j+1,0,a);break}for(c=n.length-1;c>=0;c--)if(a.end>n[c].end){n.splice(c+1,0,a);break}j<=this.parent.data.trackEvents.startIndex&&a.start<=this.parent.data.trackEvents.previousUpdateTime&&this.parent.data.trackEvents.startIndex++;c<=this.parent.data.trackEvents.endIndex&& +a.end-1;){c=this.byStart[w];n=this.byEnd[w];if(!c._id){z.push(c);F.push(n)}if(c._id){c._id!==a&&z.push(c);n._id!==a&&F.push(n);if(c._id===a)x=w}w++}j=this.animating.length; +w=0;if(j)for(;--j>-1;){c=this.animating[w];c._id||v.push(c);c._id&&c._id!==a&&v.push(c);w++}x<=this.startIndex&&this.startIndex--;x<=this.endIndex&&this.endIndex--;this.byStart=z;this.byEnd=F;this.animating=v;this.count--;j=this.parent.data.history.length;for(w=0;wn&&y._running===false){y._running=true;a.data.running[s].push(y);if(!a.data.disabled[s]){j.start.call(a,c, +y);a.emit("trackstart",f.extend({},y,{plugin:s,type:"trackstart",track:y}))}}z++}else{f.removeTrackEvent(a,y._id);return}}}else if(j>n){for(;w.byStart[z]&&w.byStart[z].start>n;){y=w.byStart[z];s=(j=y._natives)&&j.type;if(!j||L[s]||a[s]){if(y._running===true){y._running=false;B=a.data.running[s];B.splice(B.indexOf(y),1);if(!a.data.disabled[s]){j.end.call(a,c,y);a.emit("trackend",f.extend({},y,{plugin:s,type:"trackend",track:y}))}}z--}else{f.removeTrackEvent(a,y._id);return}}for(;w.byEnd[x]&&w.byEnd[x].end> +n;){y=w.byEnd[x];s=(j=y._natives)&&j.type;if(!j||L[s]||a[s]){if(y.start<=n&&y._running===false){y._running=true;a.data.running[s].push(y);if(!a.data.disabled[s]){j.start.call(a,c,y);a.emit("trackstart",f.extend({},y,{plugin:s,type:"trackstart",track:y}))}}x--}else{f.removeTrackEvent(a,y._id);return}}}w.endIndex=x;w.startIndex=z;w.previousUpdateTime=n;w.byStart.length= +0)f.error("'"+a+"' is a protected function name");else{var j=typeof c==="function",w=["start","end","type","manifest"],x=["_setup","_teardown","start","end","frame"],z={},F=function(y,s){y=y||f.nop;s=s||f.nop;return function(){y.apply(this,arguments);s.apply(this,arguments)}};f.manifest[a]=n=n||c.manifest||{};x.forEach(function(y){c[y]=b(c[y]||f.nop,a)});var v=function(y,s){if(!s)return this;if(s.ranges&&f.isArray(s.ranges)){f.forEach(s.ranges,function(M){M=f.extend({},s,M);delete M.ranges;this[a](M)}, +this);return this}var B=s._natives={},Q="",K;f.extend(B,y);s._natives.type=s._natives.plugin=a;s._running=false;B.start=B.start||B["in"];B.end=B.end||B.out;if(s.once)B.end=F(B.end,function(){this.removeTrackEvent(s._id)});B._teardown=F(function(){var M=k.call(arguments),D=this.data.running[B.type];M.unshift(null);M[1]._running&&D.splice(D.indexOf(s),1)&&B.end.apply(this,M);M[1]._running=false;this.emit("trackend",f.extend({},s,{plugin:B.type,type:"trackend",track:f.getTrackEvent(this,s.id||s._id)}))}, +B._teardown);B._teardown=F(B._teardown,function(){this.emit("trackteardown",f.extend({},s,{plugin:a,type:"trackteardown",track:f.getTrackEvent(this,s.id||s._id)}))});s.compose=s.compose||[];if(typeof s.compose==="string")s.compose=s.compose.split(" ");s.effect=s.effect||[];if(typeof s.effect==="string")s.effect=s.effect.split(" ");s.compose=s.compose.concat(s.effect);s.compose.forEach(function(M){Q=f.compositions[M]||{};x.forEach(function(D){B[D]=F(B[D],Q[D])})});s._natives.manifest=n;if(!("start"in +s))s.start=s["in"]||0;if(!s.end&&s.end!==0)s.end=s.out||Number.MAX_VALUE;if(!r.call(s,"toString"))s.toString=function(){var M=["start: "+s.start,"end: "+s.end,"id: "+(s.id||s._id)];s.target!=null&&M.push("target: "+s.target);return a+" ( "+M.join(", ")+" )"};if(!s.target){K="options"in n&&n.options;s.target=K&&"target"in K&&K.target}if(!s._id&&s._natives)s._id=f.guid(s._natives.type);if(s instanceof l){if(s._natives){s._id=s.id||s._id||f.guid(s._natives.type);if(s._natives._setup){s._natives._setup.call(this, +s);this.emit("tracksetup",f.extend({},s,{plugin:s._natives.type,type:"tracksetup",track:s}))}}this.data.trackEvents.add(s);l.start(this,s);this.timeUpdate(this,null,true);s._id&&f.addTrackEvent.ref(this,s)}else f.addTrackEvent(this,s);f.forEach(y,function(M,D){w.indexOf(D)===-1&&this.on(D,M)},this);return this};f.p[a]=z[a]=function(y,s){var B,Q;if(y&&!s)s=y;else if(B=this.getTrackEvent(y)){Q=s;var K={},M;for(M in B)if(r.call(Q,M)&&r.call(B,M))K[M]=B[M];if(B._natives._update){this.data.trackEvents.remove(B); +if(r.call(s,"start"))B.start=s.start;if(r.call(s,"end"))B.end=s.end;l.end(this,B);j&&c.call(this,B);B._natives._update.call(this,B,s);this.data.trackEvents.add(B);l.start(this,B)}else{f.extend(B,s);this.data.trackEvents.remove(y);B._natives._teardown&&B._natives._teardown.call(this,B);f.removeTrackEvent.ref(this,y);if(j)v.call(this,c.call(this,B),B);else{B._id=B.id||B._id||f.guid(B._natives.type);if(B._natives&&B._natives._setup){B._natives._setup.call(this,B);this.emit("tracksetup",f.extend({},B, +{plugin:B._natives.type,type:"tracksetup",track:B}))}this.data.trackEvents.add(B);l.start(this,B);this.timeUpdate(this,null,true);f.addTrackEvent.ref(this,B)}this.emit("trackchange",{id:B.id,type:"trackchange",previousValue:K,currentValue:B,track:B});return this}B._natives.type!=="cue"&&this.emit("trackchange",{id:B.id,type:"trackchange",previousValue:K,currentValue:Q,track:B});return this}else s.id=y;this.data.running[a]=this.data.running[a]||[];B=f.extend({},this.options.defaults&&this.options.defaults[a]|| +{},s);v.call(this,j?c.call(this,B):c,B);return this};n&&f.extend(c,{manifest:n});var L={fn:z[a],definition:c,base:c,parents:[],name:a};f.registry.push(f.extend(z,L,{type:a}));f.registryByName[a]=L;return z}};f.plugin.errors=[];f.plugin.debug=f.version==="1.5.6";f.removePlugin=function(a,c){if(!c){c=a;a=f.p;if(f.protect.natives.indexOf(c.toLowerCase())>=0){f.error("'"+c+"' is a protected function name");return}var n=f.registry.length,j;for(j=0;j-1){w=w.split(";");x=0;if(c&&typeof c==="number")x=parseFloat(w[1],10)/c;n[j]=parseInt(w[0],10)+x}j=n[0];return{1:parseFloat(j,10),2:parseInt(j,10)*60+parseFloat(n[1],10),3:parseInt(j,10)*3600+parseInt(n[1],10)*60+parseFloat(n[2],10)}[n.length||1]}};f.p.cue=f.p.exec;f.protect={natives:function(a){return Object.keys?Object.keys(a):function(c){var n,j=[];for(n in c)r.call(c,n)&&j.push(n);return j}(a)}(f.p).map(function(a){return a.toLowerCase()})}; +f.forEach({listen:"on",unlisten:"off",trigger:"emit",exec:"cue"},function(a,c){var n=f.p[c];f.p[c]=function(){if(typeof console!=="undefined"&&console.warn){console.warn("Deprecated method '"+c+"', "+(a==null?"do not use.":"use '"+a+"' instead."));f.p[c]=n}return f.p[a].apply(this,[].slice.call(arguments))}});p.Popcorn=f}else{p.Popcorn={isSupported:false};for(h="byId forEach extend effects error guid sizeOf isArray nop position disable enable destroyaddTrackEvent removeTrackEvent getTrackEvents getTrackEvent getLastTrackEventId timeUpdate plugin removePlugin compose effect xhr getJSONP getScript".split(/\s+/);h.length;)p.Popcorn[h.shift()]= +function(){}}})(window,window.document);(function(p,e){var l=p.document,d=p.location,b=/:\/\//,h=d.href.replace(d.href.split("/").slice(-1)[0],""),i=function(k,r,m){k=k||0;r=(r||k||0)+1;m=m||1;r=Math.ceil((r-k)/m)||0;var t=0,q=[];for(q.length=r;t= +t["in"]&&k<=t.out)m=q});k+=this.inOuts.ofVideos[m]["in"]-this.inOuts.ofClips[m]["in"];e.addTrackEvent(this.playlist[m],{start:k-1,end:k,_running:false,_natives:{start:r||e.nop,end:e.nop,type:"exec"}});return this},listen:function(k,r){var m=this,t=this.playlist,q=t.length,o=0;if(!r)r=e.nop;if(e.Events.Natives.indexOf(k)>-1)e.forEach(t,function(u){u.listen(k,function(E){E.active=m;if(g.indexOf(k)>-1)r.call(u,E);else++o===q&&r.call(u,E)})});else{this.events[k]||(this.events[k]={});t=r.name||e.guid("__"+ +k);this.events[k][t]=r}return this},unlisten:function(){},trigger:function(k,r){var m=this;if(!(e.Events.Natives.indexOf(k)>-1)){this.events[k]&&e.forEach(this.events[k],function(t){t.call(m,{type:k},r)});return this}}});e.forEach(e.manifest,function(k,r){e.sequence.prototype[r]=function(m){var t={},q=[],o,u,E,C,f;for(o=0;o-1)t[o]=e.extend({},q,{start:u[E],clipIdx:E});if(C>-1)t[o]= +e.extend({},q,{end:u[C],clipIdx:C})}o=Object.keys(t).map(function(A){return+A});q=i(o[0],o[1]);for(o=0;o=4){r=new Date/1E3;C.dispatchEvent("play");G()}};C.pause=function(){this.paused=true;C.dispatchEvent("pause")};p.player.defineProperty(C,"currentTime",{get:function(){return m}, +set:function(A){m=+A;C.dispatchEvent("timeupdate");return m},configurable:true});p.player.defineProperty(C,"volume",{get:function(){return q},set:function(A){q=+A;C.dispatchEvent("volumechange");return q},configurable:true});p.player.defineProperty(C,"muted",{get:function(){return o},set:function(A){o=+A;C.dispatchEvent("volumechange");return o},configurable:true});p.player.defineProperty(C,"readyState",{get:function(){return t},set:function(A){return t=A},configurable:true});C.addEventListener=function(A, +O){u[A]||(u[A]=[]);u[A].push(O);return O};C.removeEventListener=function(A,O){var a,c=u[A];if(c){for(a=u[A].length-1;a>=0;a--)O===c[a]&&c.splice(a,1);return O}};C.dispatchEvent=function(A){var O,a=A.type;if(!a){a=A;if(A=p.events.getInterface(a)){O=document.createEvent(A);O.initEvent(a,true,true,window,1)}}if(u[a])for(A=u[a].length-1;A>=0;A--)u[a][A].call(this,O,this)};C.src=i||"";C.duration=0;C.paused=true;C.ended=0;g&&g.events&&p.forEach(g.events,function(A,O){C.addEventListener(O,A,false)});if(d._canPlayType(E.nodeName, +i)!==false)if(d._setup)d._setup.call(C,g);else{C.readyState=4;C.dispatchEvent("loadedmetadata");C.dispatchEvent("loadeddata");C.dispatchEvent("canplaythrough")}else setTimeout(function(){C.dispatchEvent("error")},0);h=new p.p.init(C,g);if(d._teardown)h.destroy=e(h.destroy,function(){d._teardown.call(C,g)});return h};b.canPlayType=d._canPlayType=d._canPlayType||p.nop;p[l]=p.player.registry[l]=b}};p.player.registry={};p.player.defineProperty=Object.defineProperty||function(l,d,b){l.__defineGetter__(d, +b.get||p.nop);l.__defineSetter__(d,b.set||p.nop)};p.player.playerQueue=function(){var l=[],d=false;return{next:function(){d=false;l.shift();l[0]&&l[0]()},add:function(b){l.push(function(){d=true;b&&b()});!d&&l[0]()}}};p.smart=function(l,d,b){var h=typeof l==="string"?p.dom.find(l):l,i,g,k,r,m,t="HTMLYouTubeVideoElement HTMLVimeoVideoElement HTMLSoundCloudAudioElement HTMLNullVideoElement".split(" ");if(h){d=typeof d==="string"?[d]:d;l=0;for(m=d.length;l';l=0;for(m=d.length;l';t+="";g.innerHTML=t;b&&b.events&&b.events.error&&h.addEventListener("error",b.events.error,false);return p("#"+q,b)}else p.error("Specified target `"+l+"` was not found.")}})(Popcorn);(function(p){var e=Object.prototype.hasOwnProperty;p.parsers={};p.parser=function(l,d,b){if(p.protect.natives.indexOf(l.toLowerCase())>=0)p.error("'"+l+"' is a protected function name");else{if(typeof d==="function"&&!b){b=d;d=""}if(!(typeof b!=="function"||typeof d!=="string")){var h={};h[l]=function(i,g,k){if(!i)return this;if(typeof g!=="function"&&!k){k=g;g=null}var r=this;p.xhr({url:i,dataType:d,success:function(m){var t,q,o=0;m=b(m,k).data||[];if(t=m.length){for(;o1)throw"Volume value must be between 0.0 and 1.0";w(P)}},muted:{get:function(){return v.muted},set:function(P){x(z._util.isAttributeSet(P))}}, +error:{get:function(){return v.error}},buffered:{get:function(){var P={start:function(S){if(S===0)return 0;throw"INDEX_SIZE_ERR: DOM Exception 1";},end:function(S){if(S===0){S=K.getDuration();if(!S)return 0;return S*(K.getBuffer()/100)}throw"INDEX_SIZE_ERR: DOM Exception 1";}};Object.defineProperties(P,{length:{get:function(){return 1}}});return P}}});z._canPlaySrc=p.HTMLJWPlayerVideoElement._canPlaySrc;z.canPlayType=p.HTMLJWPlayerVideoElement.canPlayType;return z}var g="",k=false,r=false,m=[];p.HTMLJWPlayerVideoElement= +function(t){return new i(t)};p.HTMLJWPlayerVideoElement._canPlaySrc=function(){return"probably"};p.HTMLJWPlayerVideoElement.canPlayType=function(){return"probably"}})(Popcorn,window,document);(function(p,e){function l(i){this.startTime=0;this.currentTime=i.currentTime||0;this.duration=i.duration||NaN;this.playInterval=null;this.paused=true;this.playbackRate=this.defaultPlaybackRate=1;this.ended=i.endedCallback||p.nop}function d(i){function g(a){A.push(a)}function k(){if(!C)return 0;return f.currentTime}function r(a){if(a!==k())if(C){G.seeking=true;o.dispatchEvent("seeking");f.seekTo(a);G.ended=false;G.seeking=false;o.dispatchEvent("timeupdate");o.dispatchEvent("seeked");o.dispatchEvent("canplay"); +o.dispatchEvent("canplaythrough")}else g(function(){r(a)})}function m(){o.dispatchEvent("timeupdate")}function t(){G.paused=true;clearInterval(O);o.dispatchEvent("pause")}function q(){if(G.loop){r(0);o.play()}else{G.ended=true;t();o.dispatchEvent("timeupdate");o.dispatchEvent("ended")}}var o=new p._MediaElementProto,u=typeof i==="string"?e.querySelector(i):i,E=e.createElement("div"),C=false,f,G={src:b,networkState:o.NETWORK_EMPTY,readyState:o.HAVE_NOTHING,autoplay:b,preload:b,controls:b,loop:false, +poster:b,volume:1,muted:false,width:u.width|0?u.width:o._util.MIN_WIDTH,height:u.height|0?u.height:o._util.MIN_HEIGHT,seeking:false,ended:false,paused:1,error:null},A=[],O;o._eventNamespace=p.guid("HTMLNullVideoElement::");o.parentNode=u;o._util.type="NullVideo";o.play=function(){if(C){f.play();if(G.paused){if(G.paused===1){G.paused=false;o.dispatchEvent("play");o.dispatchEvent("playing")}else{if(G.ended){r(0);G.ended=false}if(G.paused){G.paused=false;G.loop||o.dispatchEvent("play");o.dispatchEvent("playing")}}O= +setInterval(m,o._util.TIMEUPDATE_MS)}}else g(function(){o.play()})};o.pause=function(){if(C){f.pause();G.paused||t()}else g(function(){o.pause()})};Object.defineProperties(o,{src:{get:function(){return G.src},set:function(a){if(a&&a!==G.src)if(o._canPlaySrc(a)){G.src=a;if(C)if(C&&f){f.pause();f=null;u.removeChild(E);E=e.createElement("div")}E.width=G.width;E.height=G.height;u.appendChild(E);a=h.exec(a);f=new l({currentTime:+a[1],duration:+a[2],endedCallback:q});o.dispatchEvent("loadstart");o.dispatchEvent("progress"); +o.dispatchEvent("durationchange");C=true;G.networkState=o.NETWORK_IDLE;G.readyState=o.HAVE_METADATA;o.dispatchEvent("loadedmetadata");o.dispatchEvent("loadeddata");G.readyState=o.HAVE_FUTURE_DATA;o.dispatchEvent("canplay");G.readyState=o.HAVE_ENOUGH_DATA;for(o.dispatchEvent("canplaythrough");A.length;){a=A.shift();a()}G.autoplay&&o.play()}else{G.error={name:"MediaError",message:"Media Source Not Supported",code:MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED};o.dispatchEvent("error")}}},autoplay:{get:function(){return G.autoplay}, +set:function(a){G.autoplay=o._util.isAttributeSet(a)}},loop:{get:function(){return G.loop},set:function(a){G.loop=o._util.isAttributeSet(a)}},width:{get:function(){return E.width},set:function(a){E.width=a;G.width=E.width}},height:{get:function(){return E.height},set:function(a){E.height=a;G.height=E.height}},currentTime:{get:function(){return k()},set:function(a){r(a)}},duration:{get:function(){return f?f.duration:NaN}},ended:{get:function(){return G.ended}},paused:{get:function(){return G.paused}}, +seeking:{get:function(){return G.seeking}},readyState:{get:function(){return G.readyState}},networkState:{get:function(){return G.networkState}},volume:{get:function(){return G.volume},set:function(a){if(a<0||a>1)throw"Volume value must be between 0.0 and 1.0";G.volume=a;o.dispatchEvent("volumechange")}},muted:{get:function(){return G.muted},set:function(a){a=o._util.isAttributeSet(a);G.muted=a;o.dispatchEvent("volumechange")}},playbackRate:{get:function(){return f.playbackRate},set:function(a){f.playbackRate= +a;o.dispatchEvent("ratechange")}},error:{get:function(){return G.error}}});o._canPlaySrc=p.HTMLNullVideoElement._canPlaySrc;o.canPlayType=p.HTMLNullVideoElement.canPlayType;return o}var b="",h=/#t=(\d+\.?\d*)?,?(\d+\.?\d*)/;l.prototype={play:function(){var i=this;if(this.paused){this.paused=false;this.startTime=Date.now();this.playInterval=setInterval(function(){i.currentTime+=(Date.now()-i.startTime)/(1E3/i.playbackRate);i.startTime=Date.now();if(i.currentTime>=i.duration){i.pause(i.duration);i.ended()}i.currentTime< +0&&i.pause(0)},16)}},pause:function(){if(!this.paused){this.paused=true;clearInterval(this.playInterval)}},seekTo:function(i){i=i<0?0:i;this.currentTime=i=i>this.duration?this.duration:i}};p.HTMLNullVideoElement=function(i){return new d(i)};p.HTMLNullVideoElement._canPlaySrc=function(i){return h.test(i)?"probably":b};p.HTMLNullVideoElement.canPlayType=function(i){return i==="video/x-nullvideo"?"probably":b}})(Popcorn,document);(function(p,e,l){function d(k){var r=this,m=k.src.split("?")[0];if(m.substr(0,2)==="//")m=e.location.protocol+m;"play pause paused seekTo unload getCurrentTime getDuration getVideoEmbedCode getVideoHeight getVideoWidth getVideoUrl getColor setColor setLoop getVolume setVolume addEventListener".split(" ").forEach(function(t){r[t]=function(q){q=JSON.stringify({method:t,value:q});k.contentWindow&&k.contentWindow.postMessage(q,m)}})}function b(k){function r(y){z.unshift(y)}function m(y){var s=c.duration; +if(s!==y){c.duration=y;A.dispatchEvent("durationchange");if(isNaN(s)){c.networkState=A.NETWORK_IDLE;c.readyState=A.HAVE_METADATA;A.dispatchEvent("loadedmetadata");A.dispatchEvent("loadeddata");c.readyState=A.HAVE_FUTURE_DATA;A.dispatchEvent("canplay");c.readyState=A.HAVE_ENOUGH_DATA;A.dispatchEvent("canplaythrough");c.autoplay&&A.play();for(y=z.length;y--;){z[y]();delete z[y]}}}}function t(y){if(n){c.seeking=true;A.dispatchEvent("seeking");w.seekTo(y)}else r(function(){t(y)})}function q(){A.dispatchEvent("timeupdate")} +function o(y){(c.currentTime=y)!==L&&A.dispatchEvent("timeupdate");L=c.currentTime}function u(y){if(y.origin===g){var s;try{s=JSON.parse(y.data)}catch(B){console.warn(B)}if(s.player_id==j)switch(s.event){case "ready":w=new d(a);w.addEventListener("loadProgress");w.addEventListener("pause");w.setVolume(0);w.play();break;case "loadProgress":if(parseFloat(s.data.duration)>0&&!n){n=true;w.pause()}break;case "pause":w.setVolume(1);e.removeEventListener("message",u,false);e.addEventListener("message",E, +false);w.addEventListener("loadProgress");w.addEventListener("playProgress");w.addEventListener("play");w.addEventListener("pause");w.addEventListener("finish");w.addEventListener("seek");w.getDuration();c.networkState=A.NETWORK_LOADING;A.dispatchEvent("loadstart");A.dispatchEvent("progress")}}}function E(y){if(y.origin===g){var s;try{s=JSON.parse(y.data)}catch(B){console.warn(B)}if(s.player_id==j){switch(s.method){case "getCurrentTime":o(parseFloat(s.value));break;case "getDuration":m(parseFloat(s.value)); +break;case "getVolume":y=parseFloat(s.value);if(c.volume!==y){c.volume=y;A.dispatchEvent("volumechange")}}switch(s.event){case "loadProgress":A.dispatchEvent("progress");m(parseFloat(s.data.duration));break;case "playProgress":o(parseFloat(s.data.seconds));break;case "play":c.ended&&t(0);if(!v){v=setInterval(C,h);c.loop&&A.dispatchEvent("play")}F=setInterval(q,A._util.TIMEUPDATE_MS);c.paused=false;if(x){x=false;c.loop||A.dispatchEvent("play");A.dispatchEvent("playing")}break;case "pause":c.paused= +true;if(!x){x=true;clearInterval(F);A.dispatchEvent("pause")}break;case "finish":if(c.loop){t(0);A.play()}else{c.ended=true;A.dispatchEvent("ended")}break;case "seek":o(parseFloat(s.data.seconds));c.seeking=false;A.dispatchEvent("timeupdate");A.dispatchEvent("seeked");A.dispatchEvent("canplay");A.dispatchEvent("canplaythrough")}}}}function C(){w.getCurrentTime()}function f(y){c.volume=y;if(n){w.setVolume(y);A.dispatchEvent("volumechange")}else r(function(){f(y)})}function G(y){if(n)if(y){c.muted= +c.volume;f(0)}else{c.muted=0;f(c.muted)}else{c.muted=y?1:0;r(function(){G(y)})}}if(!e.postMessage)throw"ERROR: HTMLVimeoVideoElement requires window.postMessage";var A=new p._MediaElementProto,O=typeof k==="string"?p.dom.find(k):k,a=l.createElement("iframe"),c={src:i,networkState:A.NETWORK_EMPTY,readyState:A.HAVE_NOTHING,seeking:false,autoplay:i,preload:i,controls:false,loop:false,poster:i,volume:1,muted:0,currentTime:0,duration:NaN,ended:false,paused:true,error:null},n=false,j=p.guid(),w,x=true, +z=[],F,v,L=0;A._eventNamespace=p.guid("HTMLVimeoVideoElement::");A.parentNode=O;A._util.type="Vimeo";A.play=function(){c.paused=false;n?w.play():r(function(){A.play()})};A.pause=function(){c.paused=true;n?w.pause():r(function(){A.pause()})};Object.defineProperties(A,{src:{get:function(){return c.src},set:function(y){if(y&&y!==c.src)if(A._canPlaySrc(y)){c.src=y;if(n)if(n&&w){clearInterval(v);w.pause();e.removeEventListener("message",E,false);O.removeChild(a);a=l.createElement("iframe")}n=false;y=A._util.parseUri(y); +var s=y.queryKey,B,Q=["api=1","player_id="+j,"title=0","byline=0","portrait=0"];c.loop=s.loop==="1"||c.loop;delete s.loop;c.autoplay=s.autoplay==="1"||c.autoplay;delete s.autoplay;y=g+"/video/"+/\d+$/.exec(y.path)+"?";for(B in s)s.hasOwnProperty(B)&&Q.push(encodeURIComponent(B)+"="+encodeURIComponent(s[B]));y+=Q.join("&");a.id=j;a.style.width="100%";a.style.height="100%";a.frameBorder=0;a.webkitAllowFullScreen=true;a.mozAllowFullScreen=true;a.allowFullScreen=true;O.appendChild(a);a.src=y;e.addEventListener("message", +u,false)}else{c.error={name:"MediaError",message:"Media Source Not Supported",code:MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED};A.dispatchEvent("error")}}},autoplay:{get:function(){return c.autoplay},set:function(y){c.autoplay=A._util.isAttributeSet(y)}},loop:{get:function(){return c.loop},set:function(y){c.loop=A._util.isAttributeSet(y)}},width:{get:function(){return A.parentNode.offsetWidth}},height:{get:function(){return A.parentNode.offsetHeight}},currentTime:{get:function(){return c.currentTime}, +set:function(y){t(y)}},duration:{get:function(){return c.duration}},ended:{get:function(){return c.ended}},paused:{get:function(){return c.paused}},seeking:{get:function(){return c.seeking}},readyState:{get:function(){return c.readyState}},networkState:{get:function(){return c.networkState}},volume:{get:function(){return c.muted>0?c.muted:c.volume},set:function(y){if(y<0||y>1)throw"Volume value must be between 0.0 and 1.0";f(y)}},muted:{get:function(){return c.muted>0},set:function(y){G(A._util.isAttributeSet(y))}}, +error:{get:function(){return c.error}}});A._canPlaySrc=p.HTMLVimeoVideoElement._canPlaySrc;A.canPlayType=p.HTMLVimeoVideoElement.canPlayType;return A}var h=16,i="",g="https://player.vimeo.com";p.HTMLVimeoVideoElement=function(k){return new b(k)};p.HTMLVimeoVideoElement._canPlaySrc=function(k){return/player.vimeo.com\/video\/\d+/.test(k)||/vimeo.com\/\d+/.test(k)?"probably":i};p.HTMLVimeoVideoElement.canPlayType=function(k){return k==="video/x-vimeo"?"probably":i}})(Popcorn,window,document);(function(p,e){function l(){return"maybe"}function d(b,h){var i=typeof b==="string"?e.querySelector(b):b,g=e.createElement(h);i.appendChild(g);g._canPlaySrc=l;return g}p.HTMLVideoElement=function(b){return d(b,"video")};p.HTMLVideoElement._canPlaySrc=l;p.HTMLAudioElement=function(b){return d(b,"audio")};p.HTMLAudioElement._canPlaySrc=l})(Popcorn,window.document);(function(p,e,l){function d(){var u;if(YT.loaded)for(t=true;o.length;){u=o.shift();u()}else setTimeout(d,250)}function b(){var u;if(!q){if(e.YT)d();else{u=l.createElement("script");u.addEventListener("load",d,false);u.src="https://www.youtube.com/iframe_api";l.head.appendChild(u)}q=true}return t}function h(u){o.push(u)}function i(u){function E(J){W.push(J)}function C(){R.pauseVideo();j("play",C);n("play",K)}function f(){n("pause",M);j("pause",f)}function G(){var J=function(){if(R.isMuted()){n("play", +c);R.playVideo()}else setTimeout(J,0)};V=true;R.mute();J()}function A(J){var N={name:"MediaError"};switch(J.data){case 2:N.message="Invalid video parameter.";N.code=MediaError.MEDIA_ERR_ABORTED;break;case 5:N.message="The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred.";N.code=MediaError.MEDIA_ERR_DECODE;case 100:N.message="Video not found.";N.code=MediaError.MEDIA_ERR_NETWORK;break;case 101:case 150:N.message="Video not usable.";N.code= +MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED;break;default:N.message="Unknown error.";N.code=5}H.error=N;I.dispatchEvent("error")}function O(){n("play",K);n("pause",M);if(H.autoplay||!H.paused){j("play",O);H.paused=false;E(function(){H.paused||K()})}H.muted||R.unMute();H.readyState=I.HAVE_METADATA;I.dispatchEvent("loadedmetadata");aa=setInterval(v,g);I.dispatchEvent("loadeddata");H.readyState=I.HAVE_FUTURE_DATA;I.dispatchEvent("canplay");U=true;for(ba=setInterval(L,50);W.length;){W[0]();W.shift()}H.readyState= +I.HAVE_ENOUGH_DATA;I.dispatchEvent("canplaythrough")}function a(){j("pause",a);if(R.getCurrentTime()>0)setTimeout(a,0);else if(H.autoplay||!H.paused){n("play",O);R.playVideo()}else O()}function c(){j("play",c);if(R.getCurrentTime()===0)setTimeout(c,0);else{n("pause",a);R.seekTo(0);R.pauseVideo()}}function n(J,N){I.addEventListener("youtube-"+J,N,false)}function j(J,N){I.removeEventListener("youtube-"+J,N,false)}function w(J){I.dispatchEvent("youtube-"+J)}function x(){H.networkState=I.NETWORK_LOADING; +I.dispatchEvent("waiting")}function z(J){switch(J.data){case YT.PlayerState.ENDED:w("ended");break;case YT.PlayerState.PLAYING:w("play");break;case YT.PlayerState.PAUSED:R.getDuration()!==R.getCurrentTime()&&w("pause");break;case YT.PlayerState.BUFFERING:w("buffering")}J.data!==YT.PlayerState.BUFFERING&&ca===YT.PlayerState.BUFFERING&&I.dispatchEvent("progress");ca=J.data}function F(J){if(I._canPlaySrc(J)){H.src=J;if(b()){if(V)if(U){if(V&&R){j("buffering",x);j("ended",D);j("play",K);j("pause",M);M(); +Z=U=false;H.currentTime=0;W=[];clearInterval(aa);clearInterval(ba);R.stopVideo();R.clearVideo();R.destroy();S=l.createElement("div")}}else{E(function(){F(J)});return}P.appendChild(S);var N=I._util.parseUri(J).queryKey;delete N.v;H.autoplay=N.autoplay==="1"||H.autoplay;delete N.autoplay;H.loop=N.loop==="1"||H.loop;delete N.loop;N.rel=N.rel||0;N.modestbranding=N.modestbranding||1;N.iv_load_policy=N.iv_load_policy||3;N.disablekb=N.disablekb||1;N.showinfo=N.showinfo||0;var ea=e.location.protocol==="file:"? +"*":e.location.protocol+"//"+e.location.host;N.origin=N.origin||ea;N.controls=N.controls||H.controls?2:0;H.controls=N.controls;N.wmode=N.wmode||"opaque";J=r.exec(J)[1];p.getJSONP("https://gdata.youtube.com/feeds/api/videos/"+J+"?v=2&alt=jsonc&callback=?",function(X){if(X.error)console.warn("failed to retreive duration data, reason: "+X.error.message);else if(X.data){H.duration=X.data.duration;I.dispatchEvent("durationchange");R=new YT.Player(S,{width:"100%",height:"100%",wmode:N.wmode,videoId:J,playerVars:N, +events:{onReady:G,onError:A,onStateChange:z}});H.networkState=I.NETWORK_LOADING;I.dispatchEvent("loadstart");I.dispatchEvent("progress")}else console.warn("failed to retreive duration data, reason: no response data")})}else h(function(){F(J)})}else{H.error={name:"MediaError",message:"Media Source Not Supported",code:MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED};I.dispatchEvent("error")}}function v(){var J=R.getCurrentTime();if(H.seeking)m(J-H.currentTime)<1&&Q();else{if(m(H.currentTime-J)>g){B();Q()}H.currentTime= +J}}function L(){var J=R.getVideoLoadedFraction();if(J&&$!==J){$=J;I.dispatchEvent("progress")}}function y(J){if(J!==H.currentTime){H.currentTime=J;if(U){B();R.seekTo(J)}else E(function(){B();R.seekTo(J)})}}function s(){I.dispatchEvent("timeupdate")}function B(){n("pause",f);j("pause",M);H.seeking=true;I.dispatchEvent("seeking")}function Q(){H.ended=false;H.seeking=false;I.dispatchEvent("timeupdate");I.dispatchEvent("seeked");I.dispatchEvent("canplay");I.dispatchEvent("canplaythrough")}function K(){if(H.ended){y(0); +H.ended=false}da=setInterval(s,I._util.TIMEUPDATE_MS);H.paused=false;if(Y){Y=false;if(H.loop&&!Z||!H.loop){Z=true;I.dispatchEvent("play")}I.dispatchEvent("playing")}}function M(){H.paused=true;if(!Y){Y=true;clearInterval(da);I.dispatchEvent("pause")}}function D(){if(H.loop){y(0);I.play()}else{H.ended=true;M();n("play",C);j("play",K);I.dispatchEvent("timeupdate");I.dispatchEvent("ended")}}function T(J){H.muted=J;if(U){R[J?"mute":"unMute"]();I.dispatchEvent("volumechange")}else E(function(){T(H.muted)})} +if(!e.postMessage)throw"ERROR: HTMLYouTubeVideoElement requires window.postMessage";var I=new p._MediaElementProto,P=typeof u==="string"?l.querySelector(u):u,S=l.createElement("div"),H={src:k,networkState:I.NETWORK_EMPTY,readyState:I.HAVE_NOTHING,seeking:false,autoplay:k,preload:k,controls:false,loop:false,poster:k,volume:1,muted:false,currentTime:0,duration:NaN,ended:false,paused:true,error:null},V=false,U=false,Z=false,R,Y=true,W=[],ca=-1,ba,$=0,aa,da;I._eventNamespace=p.guid("HTMLYouTubeVideoElement::"); +I.parentNode=P;I._util.type="YouTube";n("buffering",x);n("ended",D);I.play=function(){H.paused=false;U?R.playVideo():E(function(){I.play()})};I.pause=function(){H.paused=true;if(U){f();R.pauseVideo()}else E(function(){I.pause()})};Object.defineProperties(I,{src:{get:function(){return H.src},set:function(J){J&&J!==H.src&&F(J)}},autoplay:{get:function(){return H.autoplay},set:function(J){H.autoplay=I._util.isAttributeSet(J)}},loop:{get:function(){return H.loop},set:function(J){H.loop=I._util.isAttributeSet(J)}}, +width:{get:function(){return I.parentNode.offsetWidth}},height:{get:function(){return I.parentNode.offsetHeight}},currentTime:{get:function(){return H.currentTime},set:function(J){y(J)}},duration:{get:function(){return H.duration}},ended:{get:function(){return H.ended}},paused:{get:function(){return H.paused}},seeking:{get:function(){return H.seeking}},readyState:{get:function(){return H.readyState}},networkState:{get:function(){return H.networkState}},volume:{get:function(){return H.volume},set:function(J){if(J< +0||J>1)throw"Volume value must be between 0.0 and 1.0";H.volume=J;if(U){R.setVolume(H.volume*100);I.dispatchEvent("volumechange")}else E(function(){I.volume=J})}},muted:{get:function(){return H.muted},set:function(J){T(I._util.isAttributeSet(J))}},error:{get:function(){return H.error}},buffered:{get:function(){var J={start:function(N){if(N===0)return 0;throw"INDEX_SIZE_ERR: DOM Exception 1";},end:function(N){if(N===0){if(!H.duration)return 0;return H.duration*$}throw"INDEX_SIZE_ERR: DOM Exception 1"; +}};Object.defineProperties(J,{length:{get:function(){return 1}}});return J},configurable:true}});I._canPlaySrc=p.HTMLYouTubeVideoElement._canPlaySrc;I.canPlayType=p.HTMLYouTubeVideoElement.canPlayType;return I}var g=10,k="",r=/^.*(?:\/|v=)(.{11})/,m=Math.abs,t=false,q=false,o=[];p.HTMLYouTubeVideoElement=function(u){return new i(u)};p.HTMLYouTubeVideoElement._canPlaySrc=function(u){return/(?:http:\/\/www\.|http:\/\/|www\.|\.|^)(youtu).*(?:\/|v=)(.{11})/.test(u)?"probably":k};p.HTMLYouTubeVideoElement.canPlayType= +function(u){return u==="video/x-youtube"?"probably":k}})(Popcorn,window,document);(function(p,e,l){function d(){if(!r){p.getScript("https://w.soundcloud.com/player/api.js",function(){p.getScript("https://connect.soundcloud.com/sdk.js",function(){k=true;SC.initialize({client_id:"PRaNFlda6Bhf5utPjUsptg"});for(var t=m.length;t--;){m[t]();delete m[t]}})});r=true}return k}function b(t){m.unshift(t)}function h(t){function q(D){B.unshift(D)}function o(){s.bind(SC.Widget.Events.LOAD_PROGRESS,function(D){O({type:"loadProgress",data:D.currentPosition/1E3})});s.bind(SC.Widget.Events.PLAY_PROGRESS, +function(D){O({type:"playProgress",data:D.currentPosition/1E3})});s.bind(SC.Widget.Events.PLAY,function(){O({type:"play"})});s.bind(SC.Widget.Events.PAUSE,function(){O({type:"pause"})});s.bind(SC.Widget.Events.SEEK,function(){s.getPosition(function(D){D=D/1E3;if(v.seeking)if(Math.floor(D)!==Math.floor(v.currentTime))s.seekTo(v.currentTime*1E3);else{v.ended=false;v.seeking=false;x.dispatchEvent("timeupdate");x.dispatchEvent("seeked");x.dispatchEvent("canplay");x.dispatchEvent("canplaythrough")}else O({type:"seek", +data:D})})});s.bind(SC.Widget.Events.FINISH,function(){O({type:"finish"})});L=true;s.getDuration(E)}function u(){s.bind(SC.Widget.Events.PLAY_PROGRESS,function(D){s.setVolume(0);if(D.currentPosition>0){s.unbind(SC.Widget.Events.PLAY_PROGRESS);s.bind(SC.Widget.Events.PAUSE,function(){s.unbind(SC.Widget.Events.PAUSE);s.setVolume(100);s.bind(SC.Widget.Events.SEEK,function(){s.unbind(SC.Widget.Events.SEEK);o()});s.seekTo(0)});s.pause()}});s.play()}function E(D){D/=1E3;var T=v.duration;if(T!==D){v.duration= +D;x.dispatchEvent("durationchange");if(isNaN(T)){v.networkState=x.NETWORK_IDLE;v.readyState=x.HAVE_METADATA;x.dispatchEvent("loadedmetadata");x.dispatchEvent("loadeddata");v.readyState=x.HAVE_FUTURE_DATA;x.dispatchEvent("canplay");v.readyState=x.HAVE_ENOUGH_DATA;x.dispatchEvent("canplaythrough");for(D=B.length;D--;){B[D]();delete B[D]}v.paused&&v.autoplay&&x.play()}}}function C(D){function T(){v.seeking=true;x.dispatchEvent("seeking");s.seekTo(D)}v.currentTime=D;D*=1E3;L?T():addMediaReadyCallback(T)} +function f(){v.paused=true;if(!y){y=true;clearInterval(Q);x.dispatchEvent("pause")}}function G(){x.dispatchEvent("timeupdate")}function A(D){v.currentTime=D;D!==M&&x.dispatchEvent("timeupdate");M=D}function O(D){switch(D.type){case "loadProgress":x.dispatchEvent("progress");break;case "playProgress":A(D.data);break;case "play":if(!K){K=setInterval(a,i);v.loop&&x.dispatchEvent("play")}Q=setInterval(G,x._util.TIMEUPDATE_MS);v.paused=false;if(y){y=false;v.loop||x.dispatchEvent("play");x.dispatchEvent("playing")}break; +case "pause":f();break;case "finish":if(v.loop){C(0);x.play()}else{v.ended=true;x.pause();f();x.dispatchEvent("timeupdate");x.dispatchEvent("ended")}break;case "seek":A(D.data)}}function a(){v.ended||s.getPosition(function(D){A(D/1E3)})}function c(D){if(x._canPlaySrc(D)){v.src=D;if(L)if(L&&s){clearInterval(K);s.pause();s.unbind(SC.Widget.Events.READY);s.unbind(SC.Widget.Events.LOAD_PROGRESS);s.unbind(SC.Widget.Events.PLAY_PROGRESS);s.unbind(SC.Widget.Events.PLAY);s.unbind(SC.Widget.Events.PAUSE); +s.unbind(SC.Widget.Events.SEEK);s.unbind(SC.Widget.Events.FINISH);z.removeChild(F);F=l.createElement("iframe")}if(d()){L=false;SC.get("/resolve",{url:D},function(T){var I;if(T.errors){I={name:"MediaError"};if(T.errors[0])if(T.errors[0].error_message==="404 - Not Found"){I.message="Video not found.";I.code=MediaError.MEDIA_ERR_NETWORK}v.error=I;x.dispatchEvent("error")}F.id=p.guid("soundcloud-");F.width=v.width;F.height=v.height;F.frameBorder=0;F.webkitAllowFullScreen=true;F.mozAllowFullScreen=true; +F.allowFullScreen=true;w(v.controls);z.appendChild(F);F.onload=function(){F.onload=null;s=SC.Widget(F);s.bind(SC.Widget.Events.READY,u);v.networkState=x.NETWORK_LOADING;x.dispatchEvent("loadstart");x.dispatchEvent("progress")};F.src="https://w.soundcloud.com/player/?url="+T.uri+"&show_artwork=false&buying=false&liking=false&sharing=false&download=false&show_comments=false&show_user=false&single_active=false"})}else b(function(){c(D)})}else{v.error={name:"MediaError",message:"Media Source Not Supported", +code:MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED};x.dispatchEvent("error")}}function n(D){v.volume=D;if(L){s.setVolume(D);x.dispatchEvent("volumechange")}else q(function(){n(D)})}function j(D){if(L)if(D){v.muted=v.volume;n(0)}else{v.muted=0;n(v.muted)}else{v.muted=D?1:0;q(function(){j(D)})}}function w(D){if(L){F.style.position="absolute";F.style.visibility=D?"visible":"hidden"}else{F.style.opacity=D?"1":"0";F.style.pointerEvents=D?"auto":"none"}v.controls=D}if(!e.postMessage)throw"ERROR: HTMLSoundCloudAudioElement requires window.postMessage"; +var x=new p._MediaElementProto,z=typeof t==="string"?p.dom.find(t):t,F=l.createElement("iframe"),v={src:g,networkState:x.NETWORK_EMPTY,readyState:x.HAVE_NOTHING,seeking:false,autoplay:g,preload:g,controls:false,loop:false,poster:g,volume:100,muted:0,currentTime:0,duration:NaN,ended:false,paused:true,width:z.width|0?z.width:x._util.MIN_WIDTH,height:z.height|0?z.height:x._util.MIN_HEIGHT,error:null},L=false,y=true,s,B=[],Q,K,M=0;x._eventNamespace=p.guid("HTMLSoundCloudAudioElement::");x.parentNode= +z;x._util.type="SoundCloud";x.play=function(){v.paused=false;if(L){v.ended&&C(0);s.play()}else q(function(){x.play()})};x.pause=function(){v.paused=true;L?s.pause():q(function(){x.pause()})};Object.defineProperties(x,{src:{get:function(){return v.src},set:function(D){D&&D!==v.src&&c(D)}},autoplay:{get:function(){return v.autoplay},set:function(D){v.autoplay=x._util.isAttributeSet(D)}},loop:{get:function(){return v.loop},set:function(D){v.loop=x._util.isAttributeSet(D)}},width:{get:function(){return F.width}, +set:function(D){F.width=D;v.width=F.width}},height:{get:function(){return F.height},set:function(D){F.height=D;v.height=F.height}},currentTime:{get:function(){return v.currentTime},set:function(D){C(D)}},duration:{get:function(){return v.duration}},ended:{get:function(){return v.ended}},paused:{get:function(){return v.paused}},seeking:{get:function(){return v.seeking}},readyState:{get:function(){return v.readyState}},networkState:{get:function(){return v.networkState}},volume:{get:function(){return(v.muted> +0?v.muted:v.volume)/100},set:function(D){if(D<0||D>1)throw"Volume value must be between 0.0 and 1.0";D*=100;n(D)}},muted:{get:function(){return v.muted>0},set:function(D){j(x._util.isAttributeSet(D))}},error:{get:function(){return v.error}},controls:{get:function(){return v.controls},set:function(D){w(!!D)}}});x._canPlaySrc=p.HTMLSoundCloudAudioElement._canPlaySrc;x.canPlayType=p.HTMLSoundCloudAudioElement.canPlayType;return x}var i=16,g="",k=false,r=false,m=[];p.HTMLSoundCloudAudioElement=function(t){return new h(t)}; +p.HTMLSoundCloudAudioElement._canPlaySrc=function(t){return/(?:https?:\/\/www\.|https?:\/\/|www\.|\.|^)(soundcloud)/.test(t)?"probably":g};p.HTMLSoundCloudAudioElement.canPlayType=function(t){return t==="audio/x-soundcloud"?"probably":g}})(Popcorn,window,document);(function(p){var e=function(l,d){var b=0,h=0,i;p.forEach(d.classes,function(g,k){i=[];if(g==="parent")i[0]=document.querySelectorAll("#"+d.target)[0].parentNode;else i=document.querySelectorAll("#"+d.target+" "+g);b=0;for(h=i.length;b"+ -n.title+"
"+n.text+"
"+n.innerHTML;return{start:function(i,j){b.style.display="block";if(j.direction==="down")e.scrollTop=e.scrollHeight},end:function(){b.style.display="none"},_teardown:function(){e&&b&&e.removeChild(b)&&!e.firstChild&&c.removeChild(e)}}},{about:{name:"Popcorn Timeline Plugin",version:"0.1",author:"David Seifried @dcseifried",website:"dseifried.wordpress.com"},options:{start:{elem:"input",type:"number",label:"Start"}, -end:{elem:"input",type:"number",label:"End"},target:"feed-container",title:{elem:"input",type:"text",label:"Title"},text:{elem:"input",type:"text",label:"Text"},innerHTML:{elem:"input",type:"text",label:"HTML Code",optional:true},direction:{elem:"select",options:["DOWN","UP"],label:"Direction",optional:true}}})})(Popcorn);(function(r,f){var n={};r.plugin("documentcloud",{manifest:{about:{name:"Popcorn Document Cloud Plugin",version:"0.1",author:"@humphd, @ChrisDeCairos",website:"http://vocamus.net/dave"},options:{start:{elem:"input",type:"number",label:"Start"},end:{elem:"input",type:"number",label:"End"},target:"documentcloud-container",width:{elem:"input",type:"text",label:"Width",optional:true},height:{elem:"input",type:"text",label:"Height",optional:true},src:{elem:"input",type:"url",label:"PDF URL","default":"http://www.documentcloud.org/documents/70050-urbina-day-1-in-progress.html"}, -preload:{elem:"input",type:"checkbox",label:"Preload","default":true},page:{elem:"input",type:"number",label:"Page Number",optional:true},aid:{elem:"input",type:"number",label:"Annotation Id",optional:true}}},_setup:function(c){function b(){function m(v){c._key=v.api.getId();c._changeView=function(z){c.aid?z.pageSet.showAnnotation(z.api.getAnnotation(c.aid)):z.api.setCurrentPage(c.page)}}function o(){n[c._key]={num:1,id:c._containerId};h.loaded=true}h.loaded=false;var q=c.url.replace(/\.html$/,".js"), -s=c.target,d=f.getElementById(s),A=f.createElement("div"),y=r.position(d),x=c.width||y.width;y=c.height||y.height;var a=c.sidebar||true,g=c.text||true,l=c.pdf||true,k=c.showAnnotations||true,t=c.zoom||700,u=c.search||true;if(!function(v){var z=false;r.forEach(h.viewers,function(C){if(C.api.getSchema().canonicalURL===v){m(C);C=n[c._key];c._containerId=C.id;C.num+=1;z=true;h.loaded=true}});return z}(c.url)){A.id=c._containerId=r.guid(s);s="#"+A.id;d.appendChild(A);i.trigger("documentready");h.load(q, -{width:x,height:y,sidebar:a,text:g,pdf:l,showAnnotations:k,zoom:t,search:u,container:s,afterLoad:c.page||c.aid?function(v){m(v);c._changeView(v);A.style.visibility="hidden";v.elements.pages.hide();o()}:function(v){m(v);o();A.style.visibility="hidden";v.elements.pages.hide()}})}}function e(){window.DV.loaded?b():setTimeout(e,25)}var h=window.DV=window.DV||{},i=this;if(h.loading)e();else{h.loading=true;h.recordHit="//www.documentcloud.org/pixel.gif";var j=f.createElement("link"),p=f.getElementsByTagName("head")[0]; -j.rel="stylesheet";j.type="text/css";j.media="screen";j.href="//s3.documentcloud.org/viewer/viewer-datauri.css";p.appendChild(j);h.loaded=false;r.getScript("http://s3.documentcloud.org/viewer/viewer.js",function(){h.loading=false;b()})}},start:function(c,b){var e=f.getElementById(b._containerId),h=DV.viewers[b._key];(b.page||b.aid)&&h&&b._changeView(h);if(e&&h){e.style.visibility="visible";h.elements.pages.show()}},end:function(c,b){var e=f.getElementById(b._containerId);if(e&&DV.viewers[b._key]){e.style.visibility= -"hidden";DV.viewers[b._key].elements.pages.hide()}},_teardown:function(c){var b=f.getElementById(c._containerId);if((c=c._key)&&DV.viewers[c]&&--n[c].num===0){for(DV.viewers[c].api.unload();b.hasChildNodes();)b.removeChild(b.lastChild);b.parentNode.removeChild(b)}}})})(Popcorn,window.document);(function(r){r.parser("parseJSON","JSON",function(f){var n={title:"",remote:"",data:[]};r.forEach(f.data,function(c){n.data.push(c)});return n})})(Popcorn);(function(r){r.parser("parseSBV",function(f){var n={title:"",remote:"",data:[]},c=[],b=0,e=0,h=function(q){q=q.split(":");var s=q.length-1,d;try{d=parseInt(q[s-1],10)*60+parseFloat(q[s],10);if(s===2)d+=parseInt(q[0],10)*3600}catch(A){throw"Bad cue";}return d},i=function(q,s){var d={};d[q]=s;return d};f=f.text.split(/(?:\r\n|\r|\n)/gm);for(e=f.length;b");c.push(i("subtitle",j))}catch(o){for(;b< -e&&f[b];)b++}for(;b=0&&!c[h];)h--;m=h+1;for(h=0;h[\t ]*/); -o.start=n(j[0]);i=j[1].indexOf(" ");if(i!==-1)j[1]=j[1].substr(0,i);for(o.end=n(j[1]);h/g,">");o.text=o.text.replace(/<(\/?(font|b|u|i|s))((\s+(\w|\w[\w\-]*\w)(\s*=\s*(?:\".*?\"|'.*?'|[^'\">\s]+))?)+\s*|\s*)(\/?)>/gi,"<$1$3$7>");o.text=o.text.replace(/\\N/gi,"
");e.push(f("subtitle",o))}b.data=e;return b})})(Popcorn);(function(r){function f(b,e){var h=b.substr(10).split(","),i;i={start:n(h[e.start]),end:n(h[e.end])};if(i.start===-1||i.end===-1)throw"Invalid time";var j=q.call(m,/\{(\\[\w]+\(?([\w\d]+,?)+\)?)+\}/gi,""),p=j.replace,m;m=h.length;q=[];for(var o=e.text;o");return i}function n(b){var e=b.split(":");if(b.length!==10||e.length<3)return-1;return parseInt(e[0],10)*3600+parseInt(e[1],10)*60+parseFloat(e[2],10)}function c(b, -e){var h={};h[b]=e;return h}r.parser("parseSSA",function(b){var e={title:"",remote:"",data:[]},h=[],i=0,j;b=b.text.split(/(?:\r\n|\r|\n)/gm);for(j=b.length;i");m.id=i.getAttribute("xml:id")||i.getAttribute("id");m.start=b(i.getAttribute("begin"),j); -m.end=b(i.getAttribute("end"),j);m.target=n(i,p);if(m.end<0){m.end=b(i.getAttribute("duration"),0);if(m.end>=0)m.end+=m.start;else m.end=Number.MAX_VALUE}return{subtitle:m}}function b(i,j){var p;if(!i)return-1;try{return r.util.toSeconds(i)}catch(m){for(var o=i.length-1;o>=0&&i[o]<="9"&&i[o]>="0";)o--;p=o;o=parseFloat(i.substring(0,p));p=i.substring(p);return o*({h:3600,m:60,s:1,ms:0.0010}[p]||-1)+(j||0)}}var e=/^[\s]+|[\s]+$/gm,h=/(?:\r\n|\r|\n)/gm;r.parser("parseTTML",function(i){var j={title:"", -remote:"",data:[]};if(!i.xml||!i.xml.documentElement)return j;i=i.xml.documentElement.firstChild;if(!i)return j;for(;i.nodeName!=="body";)i=i.nextSibling;if(i)j.data=f(i,0);return j})})(Popcorn);(function(r){r.parser("parseTTXT",function(f){var n={title:"",remote:"",data:[]},c=function(j){j=j.split(":");var p=0;try{return parseFloat(j[0],10)*60*60+parseFloat(j[1],10)*60+parseFloat(j[2],10)}catch(m){p=0}return p},b=function(j,p){var m={};m[j]=p;return m};f=f.xml.lastChild.lastChild;for(var e=Number.MAX_VALUE,h=[];f;){if(f.nodeType===1&&f.nodeName==="TextSample"){var i={};i.start=c(f.getAttribute("sampleTime"));i.text=f.getAttribute("text");if(i.text){i.end=e-0.0010;h.push(b("subtitle",i))}e= -i.start}f=f.previousSibling}n.data=h.reverse();return n})})(Popcorn);(function(r){function f(c){var b=c.split(":");c=c.length;var e;if(c!==12&&c!==9)throw"Bad cue";c=b.length-1;try{e=parseInt(b[c-1],10)*60+parseFloat(b[c],10);if(c===2)e+=parseInt(b[0],10)*3600}catch(h){throw"Bad cue";}return e}function n(c,b){var e={};e[c]=b;return e}r.parser("parseVTT",function(c){var b={title:"",remote:"",data:[]},e=[],h=0,i=0,j,p;c=c.text.split(/(?:\r\n|\r|\n)/gm);i=c.length;if(i===0||c[0]!=="WEBVTT")return b;for(h++;h")===-1)throw"Bad cue";m=o.replace(/--\>/," --\> ").split(/[\t ]+/);if(m.length<2)throw"Bad cue";q.id=o;q.start=f(m[0]);q.end=f(m[2]);for(p=q;h");e.push(n("subtitle",p))}catch(s){for(h=h;h")); +l=l.replace(/((<(.|\n)+?>)|(\((.*?)\) )|(\[(.*?)\]))/g,"");l=l.split(" ");e._desc.innerHTML=l.slice(0,l.length>=e.numberofwords?e.numberofwords:l.length).join(" ")+" ...";e._fired=true};e.src&&p.getScript("//"+e.lang+".wikipedia.org/w/api.php?action=parse&props=text&redirects&page="+e.src.slice(e.src.lastIndexOf("/")+1)+"&format=json&callback=wikiCallback"+d);e.toString=function(){return e.src||e._natives.manifest.options.src["default"]}},start:function(e,l){var d=function(){if(l._fired){if(l._link&& +l._desc)if(document.getElementById(l.target)){document.getElementById(l.target).appendChild(l._link);document.getElementById(l.target).appendChild(l._desc);l._added=true}}else setTimeout(function(){d()},13)};d()},end:function(e,l){if(l._added){document.getElementById(l.target).removeChild(l._link);document.getElementById(l.target).removeChild(l._desc)}},_teardown:function(e){if(e._added){e._link.parentNode&&document.getElementById(e.target).removeChild(e._link);e._desc.parentNode&&document.getElementById(e.target).removeChild(e._desc); +delete e.target}}})})(Popcorn);(function(p){var e=0,l=function(d,b){var h=d.container=document.createElement("div"),i=h.style,g=d.media,k=function(){var r=d.position();i.fontSize="18px";i.width=g.offsetWidth+"px";i.top=r.top+g.offsetHeight-h.offsetHeight-40+"px";i.left=r.left+"px";setTimeout(k,10)};h.id=b||p.guid();i.position="absolute";i.color="white";i.textShadow="black 2px 2px 6px";i.fontWeight="bold";i.textAlign="center";k();d.media.parentNode.appendChild(h);return h};p.plugin("subtitle",{manifest:{about:{name:"Popcorn Subtitle Plugin", +version:"0.1",author:"Scott Downe",website:"http://scottdowne.wordpress.com/"},options:{start:{elem:"input",type:"text",label:"Start"},end:{elem:"input",type:"text",label:"End"},target:"subtitle-container",text:{elem:"input",type:"text",label:"Text"}}},_setup:function(d){var b=document.createElement("div");b.id="subtitle-"+e++;b.style.display="none";!this.container&&(!d.target||d.target==="subtitle-container")&&l(this);d.container=d.target&&d.target!=="subtitle-container"?document.getElementById(d.target)|| +l(this,d.target):this.container;document.getElementById(d.container.id)&&document.getElementById(d.container.id).appendChild(b);d.innerContainer=b;d.showSubtitle=function(){d.innerContainer.innerHTML=d.text||""}},start:function(d,b){b.innerContainer.style.display="inline";b.showSubtitle(b,b.text)},end:function(d,b){b.innerContainer.style.display="none";b.innerContainer.innerHTML=""},_teardown:function(d){d.container.removeChild(d.innerContainer)}})})(Popcorn);(function(p,e){var l={};p.plugin("documentcloud",{manifest:{about:{name:"Popcorn Document Cloud Plugin",version:"0.1",author:"@humphd, @ChrisDeCairos",website:"http://vocamus.net/dave"},options:{start:{elem:"input",type:"number",label:"Start"},end:{elem:"input",type:"number",label:"End"},target:"documentcloud-container",width:{elem:"input",type:"text",label:"Width",optional:true},height:{elem:"input",type:"text",label:"Height",optional:true},src:{elem:"input",type:"url",label:"PDF URL","default":"http://www.documentcloud.org/documents/70050-urbina-day-1-in-progress.html"}, +preload:{elem:"input",type:"checkbox",label:"Preload","default":true},page:{elem:"input",type:"number",label:"Page Number",optional:true},aid:{elem:"input",type:"number",label:"Annotation Id",optional:true}}},_setup:function(d){function b(){function m(j){d._key=j.api.getId();d._changeView=function(w){d.aid?w.pageSet.showAnnotation(w.api.getAnnotation(d.aid)):w.api.setCurrentPage(d.page)}}function t(){l[d._key]={num:1,id:d._containerId};i.loaded=true}i.loaded=false;var q=d.url.replace(/\.html$/,".js"), +o=d.target,u=e.getElementById(o),E=e.createElement("div"),C=p.position(u),f=d.width||C.width;C=d.height||C.height;var G=d.sidebar||true,A=d.text||true,O=d.pdf||true,a=d.showAnnotations||true,c=d.zoom||700,n=d.search||true;if(!function(j){var w=false;p.forEach(i.viewers,function(x){if(x.api.getSchema().canonicalURL===j){m(x);x=l[d._key];d._containerId=x.id;x.num+=1;w=true;i.loaded=true}});return w}(d.url)){E.id=d._containerId=p.guid(o);o="#"+E.id;u.appendChild(E);g.trigger("documentready");i.load(q, +{width:f,height:C,sidebar:G,text:A,pdf:O,showAnnotations:a,zoom:c,search:n,container:o,afterLoad:d.page||d.aid?function(j){m(j);d._changeView(j);E.style.visibility="hidden";j.elements.pages.hide();t()}:function(j){m(j);t();E.style.visibility="hidden";j.elements.pages.hide()}})}}function h(){window.DV.loaded?b():setTimeout(h,25)}var i=window.DV=window.DV||{},g=this;if(i.loading)h();else{i.loading=true;i.recordHit="//www.documentcloud.org/pixel.gif";var k=e.createElement("link"),r=e.getElementsByTagName("head")[0]; +k.rel="stylesheet";k.type="text/css";k.media="screen";k.href="//s3.documentcloud.org/viewer/viewer-datauri.css";r.appendChild(k);i.loaded=false;p.getScript("http://s3.documentcloud.org/viewer/viewer.js",function(){i.loading=false;b()})}d.toString=function(){return d.src||d._natives.manifest.options.src["default"]}},start:function(d,b){var h=e.getElementById(b._containerId),i=DV.viewers[b._key];(b.page||b.aid)&&i&&b._changeView(i);if(h&&i){h.style.visibility="visible";i.elements.pages.show()}},end:function(d, +b){var h=e.getElementById(b._containerId);if(h&&DV.viewers[b._key]){h.style.visibility="hidden";DV.viewers[b._key].elements.pages.hide()}},_teardown:function(d){var b=e.getElementById(d._containerId);if((d=d._key)&&DV.viewers[d]&&--l[d].num===0){for(DV.viewers[d].api.unload();b.hasChildNodes();)b.removeChild(b.lastChild);b.parentNode.removeChild(b)}}})})(Popcorn,window.document);(function(p){var e=/(?:http:\/\/www\.|http:\/\/|www\.|\.|^)(youtu|vimeo|soundcloud|baseplayer)/,l={},d={vimeo:false,youtube:false,soundcloud:false,module:false};Object.defineProperty(l,void 0,{get:function(){return d[void 0]},set:function(b){d[void 0]=b}});p.plugin("mediaspawner",{manifest:{about:{name:"Popcorn Media Spawner Plugin",version:"0.1",author:"Matthew Schranz, @mjschranz",website:"mschranz.wordpress.com"},options:{source:{elem:"input",type:"text",label:"Media Source","default":"http://www.youtube.com/watch?v=CXDstfD9eJ0"}, +caption:{elem:"input",type:"text",label:"Media Caption","default":"Popcorn Popping",optional:true},target:"mediaspawner-container",start:{elem:"input",type:"number",label:"Start"},end:{elem:"input",type:"number",label:"End"},autoplay:{elem:"input",type:"checkbox",label:"Autoplay Video",optional:true},width:{elem:"input",type:"number",label:"Media Width","default":400,units:"px",optional:true},height:{elem:"input",type:"number",label:"Media Height","default":200,units:"px",optional:true}}},_setup:function(b){function h(){function t(){if(k!== +"HTML5"&&!window.Popcorn[k])setTimeout(function(){t()},300);else{b.id=b._container.id;b._container.style.width=b.width+"px";b._container.style.height=b.height+"px";b.popcorn=p.smart("#"+b.id,b.source);k==="HTML5"&&b.popcorn.controls(true);b._container.style.width="0px";b._container.style.height="0px";b._container.style.visibility="hidden";b._container.style.overflow="hidden"}}if(k!=="HTML5"&&!window.Popcorn[k]&&!l[k]){l[k]=true;p.getScript("http://popcornjs.org/code/players/"+k+"/popcorn."+k+".js", +function(){t()})}else t()}function i(){window.Popcorn.player?h():setTimeout(function(){i()},300)}var g=document.getElementById(b.target)||{},k,r,m;if(r=e.exec(b.source)){k=r[1];if(k==="youtu")k="youtube"}else k="HTML5";b._type=k;b._container=document.createElement("div");r=b._container;r.id="mediaSpawnerdiv-"+p.guid();b.width=b.width||400;b.height=b.height||200;if(b.caption){m=document.createElement("div");m.innerHTML=b.caption;m.style.display="none";b._capCont=m;r.appendChild(m)}g&&g.appendChild(r); +if(!window.Popcorn.player&&!l.module){l.module=true;p.getScript("http://popcornjs.org/code/modules/player/popcorn.player.js",i)}else i();b.toString=function(){return b.source||b._natives.manifest.options.source["default"]}},start:function(b,h){if(h._capCont)h._capCont.style.display="";h._container.style.width=h.width+"px";h._container.style.height=h.height+"px";h._container.style.visibility="visible";h._container.style.overflow="visible";h.autoplay&&h.popcorn.play()},end:function(b,h){if(h._capCont)h._capCont.style.display= +"none";h._container.style.width="0px";h._container.style.height="0px";h._container.style.visibility="hidden";h._container.style.overflow="hidden";h.popcorn.pause()},_teardown:function(b){b.popcorn&&b.popcorn.destory&&b.popcorn.destroy();document.getElementById(b.target)&&document.getElementById(b.target).removeChild(b._container)}})})(Popcorn,this);(function(p){var e=1;p.plugin("timeline",function(l){var d=document.getElementById(l.target),b=document.createElement("div"),h,i=true;if(d&&!d.firstChild){d.appendChild(h=document.createElement("div"));h.style.width="inherit";h.style.height="inherit";h.style.overflow="auto"}else h=d.firstChild;b.style.display="none";b.id="timelineDiv"+e;l.direction=l.direction||"up";if(l.direction.toLowerCase()==="down")i=false;if(d&&h)i?h.insertBefore(b,h.firstChild):h.appendChild(b);e++;b.innerHTML="

"+ +l.title+"
"+l.text+"
"+l.innerHTML;return{start:function(g,k){b.style.display="block";if(k.direction==="down")h.scrollTop=h.scrollHeight},end:function(){b.style.display="none"},_teardown:function(){h&&b&&h.removeChild(b)&&!h.firstChild&&d.removeChild(h)}}},{about:{name:"Popcorn Timeline Plugin",version:"0.1",author:"David Seifried @dcseifried",website:"dseifried.wordpress.com"},options:{start:{elem:"input",type:"number",label:"Start"}, +end:{elem:"input",type:"number",label:"End"},target:"feed-container",title:{elem:"input",type:"text",label:"Title"},text:{elem:"input",type:"text",label:"Text"},innerHTML:{elem:"input",type:"text",label:"HTML Code",optional:true},direction:{elem:"select",options:["DOWN","UP"],label:"Direction",optional:true}}})})(Popcorn);(function(p){var e=0;p.plugin("flickr",function(l){var d,b=document.getElementById(l.target),h,i,g,k,r=l.numberofimages||4,m=l.height||"50px",t=l.width||"50px",q=l.padding||"5px",o=l.border||"0px";d=document.createElement("div");d.id="flickr"+e;d.style.width="100%";d.style.height="100%";d.style.display="none";e++;b&&b.appendChild(d);var u=function(){if(h)setTimeout(function(){u()},5);else{i="http://api.flickr.com/services/rest/?method=flickr.people.findByUsername&";i+="username="+l.username+"&api_key="+ +l.apikey+"&format=json&jsoncallback=flickr";p.getJSONP(i,function(C){h=C.user.nsid;E()})}},E=function(){i="http://api.flickr.com/services/feeds/photos_public.gne?";if(h)i+="id="+h+"&";if(l.tags)i+="tags="+l.tags+"&";i+="lang=en-us&format=json&jsoncallback=flickr";p.xhr.getJSONP(i,function(C){var f=document.createElement("div");f.innerHTML="

"+C.title+"

";p.forEach(C.items,function(G,A){if(A=y.interval*(v+1)/1E3&&(F<=y.interval*(v+2)/1E3||F>=y.interval*L/1E3)){n.setPosition(new google.maps.LatLng(y.position.lat,y.position.lng));n.setPov({heading:y.pov.heading||z(y,w[v+1])||0,zoom:y.pov.zoom||0,pitch:y.pov.pitch|| +0})}}G(w,w[0].interval)}else{v=0;for(L=w.length;v=y*(v+1)/1E3&&(F<=y*(v+2)/1E3||F>=y*L/1E3)){A.setPov({heading:z(w[v],w[v+1])||0,zoom:u.zoom,pitch:u.pitch||0});A.setPosition(O[v])}}G(O,u.interval)}},x)};if(u.location&&typeof u.tween==="string"){var A=C,O=[],a=new google.maps.DirectionsService,c=new google.maps.DirectionsRenderer(A);a.route({origin:u.location,destination:u.tween,travelMode:google.maps.TravelMode.DRIVING},function(w,x){if(x==google.maps.DirectionsStatus.OK){c.setDirections(w); +for(var z=w.routes[0].overview_path,F=0,v=z.length;F"']/g,function(h){return d[h]||h})}function l(b,h){var i=b.container=document.createElement("div"),g=i.style,k=b.media,r=function(){var m=b.position();g.fontSize="18px";g.width=k.offsetWidth+"px";g.top=m.top+k.offsetHeight-i.offsetHeight-40+"px";g.left=m.left+"px";setTimeout(r,10)};i.id=h||"";g.position="absolute";g.color="white";g.textShadow="black 2px 2px 6px";g.fontWeight="bold";g.textAlign="center";r();b.media.parentNode.appendChild(i); +return i}var d={"&":"&","<":"<",">":">",'"':""","'":"'"};p.plugin("text",{manifest:{about:{name:"Popcorn Text Plugin",version:"0.1",author:"@humphd"},options:{start:{elem:"input",type:"number",label:"Start"},end:{elem:"input",type:"number",label:"End"},text:{elem:"input",type:"text",label:"Text","default":"Popcorn.js"},escape:{elem:"input",type:"checkbox",label:"Escape"},multiline:{elem:"input",type:"checkbox",label:"Multiline"}}},_setup:function(b){var h,i,g=b._container=document.createElement("div"); +g.style.display="none";if(b.target)if(h=p.dom.find(b.target)){if(["VIDEO","AUDIO"].indexOf(h.nodeName)>-1)h=l(this,b.target+"-overlay")}else h=l(this,b.target);else h=this.container?this.container:l(this);b._target=h;i=b.escape?e(b.text):b.text;i=b.multiline?i.replace(/\r?\n/gm,"
"):i;g.innerHTML=i||"";h.appendChild(g);b.toString=function(){return b.text||b._natives.manifest.options.text["default"]}},start:function(b,h){h._container.style.display="inline"},end:function(b,h){h._container.style.display= +"none"},_teardown:function(b){var h=b._target;h&&h.removeChild(b._container)}})})(Popcorn);(function(p){p.plugin("code",function(e){var l=false,d=this,b=function(){var h=function(i){return function(g,k){var r=function(){l&&g.call(d,k);l&&i(r)};r()}};return window.webkitRequestAnimationFrame?h(window.webkitRequestAnimationFrame):window.mozRequestAnimationFrame?h(window.mozRequestAnimationFrame):h(function(i){window.setTimeout(i,16)})}();if(!e.onStart||typeof e.onStart!=="function")e.onStart=p.nop;if(e.onEnd&&typeof e.onEnd!=="function")e.onEnd=undefined;if(e.onFrame&&typeof e.onFrame!== +"function")e.onFrame=undefined;return{start:function(h,i){i.onStart.call(d,i);if(i.onFrame){l=true;b(i.onFrame,i)}},end:function(h,i){if(i.onFrame)l=false;i.onEnd&&i.onEnd.call(d,i)}}},{about:{name:"Popcorn Code Plugin",version:"0.1",author:"David Humphrey (@humphd)",website:"http://vocamus.net/dave"},options:{start:{elem:"input",type:"number",label:"Start"},end:{elem:"input",type:"number",label:"End"},onStart:{elem:"input",type:"function",label:"onStart"},onFrame:{elem:"input",type:"function",label:"onFrame", +optional:true},onEnd:{elem:"input",type:"function",label:"onEnd"}}})})(Popcorn);(function(p){function e(b){function h(){var r=b.getBoundingClientRect(),m=g.getBoundingClientRect();if(m.left!==r.left)g.style.left=r.left+"px";if(m.top!==r.top)g.style.top=r.top+"px"}var i=-1,g=document.createElement("div"),k=getComputedStyle(b).zIndex;g.setAttribute("data-popcorn-helper-container",true);g.style.position="absolute";g.style.zIndex=isNaN(k)?l:k+1;document.body.appendChild(g);return{element:g,start:function(){i=setInterval(h,d)},stop:function(){clearInterval(i);i=-1},destroy:function(){document.body.removeChild(g); +i!==-1&&clearInterval(i)}}}var l=2E3,d=10;p.plugin("image",{manifest:{about:{name:"Popcorn image Plugin",version:"0.1",author:"Scott Downe",website:"http://scottdowne.wordpress.com/"},options:{start:{elem:"input",type:"number",label:"Start"},end:{elem:"input",type:"number",label:"End"},src:{elem:"input",type:"url",label:"Image URL","default":"http://mozillapopcorn.org/wp-content/themes/popcorn/images/for_developers.png"},href:{elem:"input",type:"url",label:"Link","default":"http://mozillapopcorn.org/wp-content/themes/popcorn/images/for_developers.png", +optional:true},target:"image-container",text:{elem:"input",type:"text",label:"Caption","default":"Popcorn.js",optional:true}}},_setup:function(b){var h=document.createElement("img"),i=document.getElementById(b.target);b.anchor=document.createElement("a");b.anchor.style.position="relative";b.anchor.style.textDecoration="none";b.anchor.style.display="none";if(i)if(["VIDEO","AUDIO"].indexOf(i.nodeName)>-1){b.trackedContainer=e(i);b.trackedContainer.element.appendChild(b.anchor)}else i&&i.appendChild(b.anchor); +h.addEventListener("load",function(){h.style.borderStyle="none";b.anchor.href=b.href||b.src||"#";b.anchor.target="_blank";var g,k;h.style.height=i.style.height;h.style.width=i.style.width;b.anchor.appendChild(h);if(b.text){g=h.height/12+"px";k=document.createElement("div");p.extend(k.style,{color:"black",fontSize:g,fontWeight:"bold",position:"relative",textAlign:"center",width:h.style.width||h.width+"px",zIndex:"10"});k.innerHTML=b.text||"";k.style.top=(h.style.height.replace("px","")||h.height)/ +2-k.offsetHeight/2+"px";b.anchor.insertBefore(k,h)}},false);h.src=b.src;b.toString=function(){var g=b.src||b._natives.manifest.options.src["default"],k=g.replace(/.*\//g,"");return k.length?k:g}},start:function(b,h){h.anchor.style.display="inline";h.trackedContainer&&h.trackedContainer.start()},end:function(b,h){h.anchor.style.display="none";h.trackedContainer&&h.trackedContainer.stop()},_teardown:function(b){if(b.trackedContainer)b.trackedContainer.destroy();else b.anchor.parentNode&&b.anchor.parentNode.removeChild(b.anchor)}})})(Popcorn);(function(p){p.parser("parseXML","XML",function(e){var l={title:"",remote:"",data:[]},d={},b=function(m){m=m.split(":");if(m.length===1)return parseFloat(m[0],10);else if(m.length===2)return parseFloat(m[0],10)+parseFloat(m[1]/12,10);else if(m.length===3)return parseInt(m[0]*60,10)+parseFloat(m[1],10)+parseFloat(m[2]/12,10);else if(m.length===4)return parseInt(m[0]*3600,10)+parseInt(m[1]*60,10)+parseFloat(m[2],10)+parseFloat(m[3]/12,10)},h=function(m){for(var t={},q=0,o=m.length;q");d.push(g("subtitle",k))}catch(t){for(;b< +h&&e[b];)b++}for(;b");m.id=g.getAttribute("xml:id")||g.getAttribute("id");m.start=b(g.getAttribute("begin"),k); +m.end=b(g.getAttribute("end"),k);m.target=l(g,r);if(m.end<0){m.end=b(g.getAttribute("duration"),0);if(m.end>=0)m.end+=m.start;else m.end=Number.MAX_VALUE}return{subtitle:m}}function b(g,k){var r;if(!g)return-1;try{return p.util.toSeconds(g)}catch(m){for(var t=g.length-1;t>=0&&g[t]<="9"&&g[t]>="0";)t--;r=t;t=parseFloat(g.substring(0,r));r=g.substring(r);return t*({h:3600,m:60,s:1,ms:0.0010}[r]||-1)+(k||0)}}var h=/^[\s]+|[\s]+$/gm,i=/(?:\r\n|\r|\n)/gm;p.parser("parseTTML",function(g){var k={title:"", +remote:"",data:[]};if(!g.xml||!g.xml.documentElement)return k;g=g.xml.documentElement.firstChild;if(!g)return k;for(;g.nodeName!=="body";)g=g.nextSibling;if(g)k.data=e(g,0);return k})})(Popcorn);(function(p){function e(d){var b=d.split(":");d=d.length;var h;if(d!==12&&d!==9)throw"Bad cue";d=b.length-1;try{h=parseInt(b[d-1],10)*60+parseFloat(b[d],10);if(d===2)h+=parseInt(b[0],10)*3600}catch(i){throw"Bad cue";}return h}function l(d,b){var h={};h[d]=b;return h}p.parser("parseVTT",function(d){var b={title:"",remote:"",data:[]},h=[],i=0,g=0,k,r;d=d.text.split(/(?:\r\n|\r|\n)/gm);g=d.length;if(g===0||d[0]!=="WEBVTT")return b;for(i++;i")===-1)throw"Bad cue";m=t.replace(/--\>/," --\> ").split(/[\t ]+/);if(m.length<2)throw"Bad cue";q.id=t;q.start=e(m[0]);q.end=e(m[2]);for(r=q;i");h.push(l("subtitle",r))}catch(o){for(i=i;i");return g}function l(b){var h=b.split(":");if(b.length!==10||h.length<3)return-1;return parseInt(h[0],10)*3600+parseInt(h[1],10)*60+parseFloat(h[2],10)}function d(b, +h){var i={};i[b]=h;return i}p.parser("parseSSA",function(b){var h={title:"",remote:"",data:[]},i=[],g=0,k;b=b.text.split(/(?:\r\n|\r|\n)/gm);for(k=b.length;g=0&&!r[t];)t--;q=t+1;for(g=0;g[\t ]*/);o.start=l(m[0]);k=m[1].indexOf(" ");if(k!==-1)m[1]=m[1].substr(0,k);for(o.end=l(m[1]);g/g,">");o.text=o.text.replace(/<(\/?(font|b|u|i|s))((\s+(\w|\w[\w\-]*\w)(\s*=\s*(?:\".*?\"|'.*?'|[^'\">\s]+))?)+\s*|\s*)(\/?)>/gi,"<$1$3$7>");o.text=o.text.replace(/\\N/gi,"
");if(b&&b.target)o.target=b.target;i.push(e("subtitle", +o))}h.data=i;return h})})(Popcorn);(function(p,e){e.player("vimeo",{_canPlayType:function(l,d){return typeof d==="string"&&e.HTMLVimeoVideoElement._canPlaySrc(d)}});e.vimeo=function(l,d,b){typeof console!=="undefined"&&console.warn&&console.warn("Deprecated player 'vimeo'. Please use Popcorn.HTMLVimeoVideoElement directly.");var h=e.HTMLVimeoVideoElement(l);l=e(h,b);setTimeout(function(){h.src=d},0);return l}})(window,Popcorn);(function(p,e){var l=function(d,b){return typeof b==="string"&&e.HTMLYouTubeVideoElement._canPlaySrc(b)};e.player("youtube",{_canPlayType:l});e.youtube=function(d,b,h){typeof console!=="undefined"&&console.warn&&console.warn("Deprecated player 'youtube'. Please use Popcorn.HTMLYouTubeVideoElement directly.");var i=e.HTMLYouTubeVideoElement(d);d=e(i,h);setTimeout(function(){i.src=b},0);return d};e.youtube.canPlayType=l})(window,Popcorn);(function(p,e){e.player("soundcloud",{_canPlayType:function(l,d){return typeof d==="string"&&e.HTMLSoundCloudAudioElement._canPlaySrc(d)&&l.toLowerCase()!=="audio"}});e.soundcloud=function(l,d,b){typeof console!=="undefined"&&console.warn&&console.warn("Deprecated player 'soundcloud'. Please use Popcorn.HTMLSoundCloudAudioElement directly.");var h=e.HTMLSoundCloudAudioElement(l);l=e(h,b);setTimeout(function(){h.src=d},0);return l}})(window,Popcorn); diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/js/tracemanager.js --- a/server/src/remie/static/remie/js/tracemanager.js Mon Sep 28 14:32:54 2015 +0200 +++ b/server/src/remie/static/remie/js/tracemanager.js Fri Oct 02 10:24:23 2015 +0200 @@ -21,12 +21,19 @@ window.tracemanager = (function($) { // If there are more than MAX_FAILURE_COUNT synchronisation // failures, then disable synchronisation - MAX_FAILURE_COUNT = 20; + var MAX_FAILURE_COUNT = 20; // If there are more than MAX_BUFFER_SIZE obsels in the buffer, // then "compress" them as a single "ktbsFullBuffer" - MAX_BUFFER_SIZE = 500; + var MAX_BUFFER_SIZE = 500; + var _replacement = { + ';': '"', + '"': ';', + '#': '%23', + '&': '%26', + '?': '%3F' + }; var BufferedService_prototype = { /* * Buffered service for traces @@ -60,7 +67,7 @@ // Swap " (very frequent, which will be // serialized into %22) and ; (rather rare), this // saves some bytes - data = data.replace(/[;"#]/g, function(s){ return s == ';' ? '"' : ( s == '"' ? ';' : '%23'); }); + data = data.replace(/[;"#?&]/g, function(s){ return _replacement[s]; }); // FIXME: check data length (< 2K is safe) var request=$('').error( function() { this.failureCount += 1; }) .load( function() { this.failureCount = 0; }) diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/metadataplayer/Annotation.js --- a/server/src/remie/static/remie/metadataplayer/Annotation.js Mon Sep 28 14:32:54 2015 +0200 +++ b/server/src/remie/static/remie/metadataplayer/Annotation.js Fri Oct 02 10:24:23 2015 +0200 @@ -179,6 +179,9 @@ this.onMdpEvent("Annotation.maximize","maximize"); this.onMdpEvent("Annotation.getBounds","sendBounds"); this.$.find(".Ldt-Annotation-MaxMinButton").click(this.functionWrapper("toggleSize")); + this.$.on("resize", function () { _this.width = _this.$.parent().width(); + _this.$.css({ width: _this.width }); + }); this.getWidgetAnnotations().forEach(function(_a) { _a.on("enter", function() { drawAnnotation(_a); @@ -194,7 +197,8 @@ image: currentAnnotation.thumbnail, uri: (typeof currentAnnotation.url !== "undefined" ? currentAnnotation.url - : (document.location.href.replace(/#.*$/,'') + '#id=' + currentAnnotation.id)) + : (document.location.href.replace(/#.*$/,'') + '#id=' + currentAnnotation.id)), + text: '[' + currentAnnotation.begin.toString() + '] ' + currentAnnotation.title }; }); }; diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/metadataplayer/AnnotationsList.css --- a/server/src/remie/static/remie/metadataplayer/AnnotationsList.css Mon Sep 28 14:32:54 2015 +0200 +++ b/server/src/remie/static/remie/metadataplayer/AnnotationsList.css Fri Oct 02 10:24:23 2015 +0200 @@ -8,7 +8,6 @@ .Ldt-AnnotationsListWidget { border: none; margin: 0; padding: 0; overflow: auto; - max-height: 380px; } .Ldt-AnnotationsListWidget a { text-decoration: none; @@ -56,7 +55,8 @@ clear: both; margin: 2px 0; padding: 2px 0; - min-height: 60px; + min-height: 3em; + position: relative; } .Ldt-AnnotationsList-li.selected { background-image: url(img/pinstripe-grey.png); @@ -66,7 +66,8 @@ width: 80px; height: 50px; text-align: center; - margin: 2px 0; + margin: 10px 2px; + box-shadow: #808080 0px 0px 2px; } .Ldt-AnnotationsList-Thumbnail { border: none; @@ -113,6 +114,10 @@ color: #0068c4; } +.Ldt-AnnotationsList-Creator { + color: #aaa; +} + p.Ldt-AnnotationsList-Description { margin: 2px 0 2px 82px; font-size: 12px; @@ -162,6 +167,50 @@ background-position: 0 bottom; } +.Ldt-AnnotationsList-EditControls { + opacity: 0; + position: absolute; + bottom: 2px; + right: 8px; +} + +.Ldt-AnnotationsList-li:hover .Ldt-AnnotationsList-EditControls { + display: inline-block; + opacity: .8; + transition: opacity 1000ms ease-in-out; +} + +.Ldt-AnnotationsList-EditControls > div { + display: inline-block; + width: 16px; + height: 16px; + cursor: pointer; + margin-left: 8px; +} + +.Ldt-AnnotationsList-Delete { + background: url(img/delete.png); +} + +.Ldt-AnnotationsList-Edit { + background: url(img/edit.png); +} + +.Ldt-AnnotationsList-PublishAnnotation { + background: url(img/publish_annotation.png); +} + +.published .Ldt-AnnotationsList-PublishAnnotation { + background: url(img/published_annotation.png); +} + +.editing { + display: none; +} + +.editableInput { + width: 80%; + .Ldt-AnnotationsList-ScreenMain{ margin: 0px; padding: 0px; diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/metadataplayer/AnnotationsList.js --- a/server/src/remie/static/remie/metadataplayer/AnnotationsList.js Mon Sep 28 14:32:54 2015 +0200 +++ b/server/src/remie/static/remie/metadataplayer/AnnotationsList.js Fri Oct 02 10:24:23 2015 +0200 @@ -2,11 +2,12 @@ IriSP.Widgets.Widget.call(this, player, config); this.lastIds = []; var _this = this; - this.throttledRefresh = IriSP._.throttle(function() { - _this.refresh(false); + this.throttledRefresh = IriSP._.throttle(function(full) { + _this.refresh(full); }, 800); this.searchString = false; this.lastSearch = false; + this.localSource = undefined; }; IriSP.Widgets.AnnotationsList.prototype = new IriSP.Widgets.Widget(); @@ -25,7 +26,7 @@ * number of milliseconds before/after the current timecode when calling the * segment API */ - ajax_granularity : 600000, + ajax_granularity : 600000, default_thumbnail : "", /* * URL when the annotation is not in the current project, e.g. @@ -36,6 +37,25 @@ refresh_interval : 0, limit_count : 20, newest_first : false, + show_title: true, + show_audio: true, + show_creator: true, + show_controls: false, + show_end_time: true, + show_publish: false, + show_twitter: false, + twitter_hashtag: '', + // Callback for Edit action. Leave undefined for default action. + on_edit: undefined, + publish_type: "PublicContribution", + // Used to publish annotations + api_endpoint_template: "", + api_serializer: "ldt_annotate", + api_method: "POST", + editable: false, + // Id that will be used as localStorage key + editable_storage: "", + always_visible : false, start_visible: true, show_audio : true, @@ -77,6 +97,7 @@ * Show a text field that filter annotations by username */ tags : true, + polemics : [{ keyword: "++", background_color: "#c9ecc6" @@ -93,12 +114,12 @@ }; IriSP.Widgets.AnnotationsList.prototype.importUsers = function(){ - if (!this.source.users_data){ + if (!this.source.users_data && this.api_users_endpoint){ this.usernames = Array(); var _this = this, _list = this.getWidgetAnnotations(), usernames_list_string = ""; - + _list.forEach(function(_annotation){ if(_this.usernames.indexOf(_annotation.creator) == -1){ _this.usernames.push(_annotation.creator); @@ -129,6 +150,16 @@ en: { voice_annotation: "Voice Annotation", now_playing: "Now playing...", + previous: "Previous", + next: "Next", + set_time: "Double-click to update to current player time", + edit_annotation: "Edit note", + delete_annotation: "Delete note", + publish_annotation: "Make note public", + import_annotations: "Paste or load notes in this field and press Import.", + confirm_delete_message: "You are about to delete {{ annotation.title }}. Are you sure you want to delete it?", + confirm_publish_message: "You are about to publish {{ annotation.title }}. Are you sure you want to make it public?", + tweet_annotation: "Tweet annotation", everyone: "Everyone", header: "Annotations for this content", segment_filter: "All cuttings", @@ -144,6 +175,16 @@ fr: { voice_annotation: "Annotation Vocale", now_playing: "Lecture en cours...", + previous: "Précédent", + next: "Suivant", + set_time: "Double-cliquer pour fixer au temps du lecteur", + edit_annotation: "Éditer la note", + delete_annotation: "Supprimer la note", + publish_annotation: "Rendre la note publique", + import_annotations: "Copiez ou chargez des notes dans ce champ et appuyez sur Import", + confirm_delete_message: "Vous allez supprimer {{ annotation.title }}. Êtes-vous certain(e) ?", + confirm_publish_message: "Vous allez publier {{ annotation.title }}. Êtes-vous certain(e) ?", + tweet_annotation: "Tweeter l'annotation", everyone: "Tous", header: "Annotations sur ce contenu", segment_filter: "Tous les segments", @@ -174,61 +215,69 @@ + '{{#latest_contributions_filter}}{{/latest_contributions_filter}}' + '' + '{{/show_filters}}' + + '{{#show_controls}}

{{ l10n.previous }} | {{ l10n.next }}
{{/show_controls}}' + '{{#show_audio}}
{{/show_audio}}' + '
    ' + '
' + '' + '{{#allow_annotations_deletion}}' - + '
' + + '
' + '' + '
    ' + '{{l10n.annotation_deletion_delete}} {{l10n.confirm}} {{l10n.cancel}}' + '
    ' - + '
    ' + + '
    ' + '' + '{{l10n.annotation_deletion_sending}}' + '
    ' - + '
    ' + + '
    ' + '' + '{{l10n.annotation_deletion_success}}' + '
    ' - + '
    ' + + '
    ' + '' + '{{l10n.annotation_deletion_error}}' + '
    ' + '{{/allow_annotations_deletion}}' + '
    '; -IriSP.Widgets.AnnotationsList.prototype.annotationTemplate = - '
  • ' - + '
    ' - + '' - + '' - + '' +IriSP.Widgets.AnnotationsList.prototype.annotationTemplate = + '
  • ' + + '
    ' + + '' + + '' + + '' + '
    ' + '{{#allow_annotations_deletion}}' - + '
    ' + + '
    ' + '{{/allow_annotations_deletion}}' - + '{{#show_timecode}}
    {{begin}} - {{end}}
    {{/show_timecode}}' - + '

    ' - + '{{{htitle}}}' + + '{{#show_timecode}}
    {{begin}}{{#show_end_time}} - {{end}}{{/show_end_time}}
    {{/show_timecode}}' + + '

    ' + + '{{#show_title}}{{{htitle}}}{{/show_title}}' + + '{{#show_creator}}{{ creator }}{{/show_creator}}' + '

    ' - + '

    {{{hdescription}}}

    ' + + '

    {{{hdescription}}}

    ' + '{{#created}}' + '
    {{{created}}}
    ' + '{{/created}}' + '{{#tags.length}}' + '
      ' - + '{{#tags}}' - + '{{#.}}' - + '
    • ' - + '{{.}}' - + '
    • ' - + '{{/.}}' - + '{{/tags}}' + + '{{#tags}}' + + '{{#.}}' + + '
    • ' + + '{{.}}' + + '
    • ' + + '{{/.}}' + + '{{/tags}}' + '
    ' + '{{/tags.length}}' - + '{{#audio}}
    {{l10n.voice_annotation}}
    {{/audio}}' + + '{{#audio}}
    {{l10n.voice_annotation}}
    {{/audio}}' + + '
    ' + + '{{#show_twitter}}{{/show_twitter}}' + + '{{#show_publish}}
    {{/show_publish}}' + + '{{#editable}}
    ' + + '
    {{/editable}}' + + '
    ' + '
  • '; // obj.url = this.project_url + "/" + media + "/" + annotations[i].meta.project @@ -270,6 +319,78 @@ } }; +/* + * Import annotations + */ +IriSP.Widgets.AnnotationsList.prototype.importAnnotations = function () { + var widget = this; + var $ = IriSP.jQuery; + var textarea = $("' - + '
    ' - + '{{#preview_mode}}{{/preview_mode}}' - + '{{^preview_mode}}{{/preview_mode}}' - + '' + + '{{#show_controls}}
    ' + + 'In' + + 'Out' + + 'Play' + + '
    {{/show_controls}}' + + '' + + '{{#show_creator_field}}
    {{/show_creator_field}}' + + '
    ' + + '{{#preview_mode}}{{/preview_mode}}' + + '{{^preview_mode}}{{/preview_mode}}' + + '' + + '
    00:00
    ' + + '
    ' + '{{#show_mic_record}}
    Add voice annotation
    ' + ' ' + ' ' @@ -212,10 +235,7 @@ show_arrow: this.show_arrow, annotation_type: this.slice_annotation_type, onBoundsChanged: function(_from, _to) { - _this.begin = new IriSP.Model.Time(_from || 0); - _this.end = new IriSP.Model.Time(_to || 0); - _this.$.find(".Ldt-CreateAnnotation-Begin").html(_this.begin.toString()); - _this.$.find(".Ldt-CreateAnnotation-End").html(_this.end.toString()); + _this.setBeginEnd(_from, _to); } }, "slice" @@ -225,12 +245,13 @@ this.insertSubwidget(this.$.find(".Ldt-CreateAnnotation-Arrow"), {type: "Arrow"},"arrow"); } this.onMediaEvent("timeupdate", function(_time) { - _this.begin = new IriSP.Model.Time(_time || 0); - _this.end = new IriSP.Model.Time(_time || 0); - _this.$.find(".Ldt-CreateAnnotation-Begin").html(_this.begin.toString()); - if (_this.arrow) { - _this.arrow.moveToTime(_time); - } + // Do not update timecode if description is not empty + if (_this.$.find(".Ldt-CreateAnnotation-Description").val().trim() == "") { + _this.setBeginEnd(_time, _time); + if (_this.arrow) { + _this.arrow.moveToTime(_time); + } + }; }); } this.$.find(".Ldt-CreateAnnotation-Cancel").click(function() { @@ -261,7 +282,25 @@ if (this.show_creator_field) { this.$.find(".Ldt-CreateAnnotation-Creator").bind("change keyup input paste", this.functionWrapper("onCreatorChange")); } - + this.$.find("[class^='Ldt-CreateAnnotation-Control-']").click(function() { + var action = this.className.replace('Ldt-CreateAnnotation-Control-', ''); + switch (action) { + case "In": + // Set In bound to current player time + this.setBegin(_this.media.getCurrentTime()); + break; + case "Out": + // Set In bound to current player time + this.setEnd(_this.media.getCurrentTime() || _this.media.duration); + break; + case "Play": + this.media.setCurrentTime(_this.begin); + this.media.play(); + break; + } + return false; + }); + if (this.start_visible) { this.show(); } else { @@ -275,10 +314,25 @@ this.$.find("form").submit(this.functionWrapper("onSubmit")); }; +IriSP.Widgets.CreateAnnotation.prototype.setBegin = function (t) { + this.begin = new IriSP.Model.Time(t || 0); + this.$.find(".Ldt-CreateAnnotation-Begin").html(this.begin.toString()); +}; + +IriSP.Widgets.CreateAnnotation.prototype.setEnd = function (t) { + this.end = new IriSP.Model.Time(t || 0); + this.$.find(".Ldt-CreateAnnotation-End").html(this.end.toString()); +}; + +IriSP.Widgets.CreateAnnotation.prototype.setBeginEnd = function (begin, end) { + this.setBegin(begin); + this.setEnd(end); +}; + IriSP.Widgets.CreateAnnotation.prototype.showScreen = function(_screenName) { this.$.find('.Ldt-CreateAnnotation-' + _screenName).show() .siblings().hide(); -} +}; IriSP.Widgets.CreateAnnotation.prototype.show = function() { if (!this.visible){ @@ -325,7 +379,14 @@ if (this.visible) { this.hide(); } else { + var t = _this.media.getCurrentTime() || 0; + this.setBeginEnd(t, t); + if (this.slice_widget) { + this.slice_widget.setBounds(this.begin, this.end); + } this.show(); + // Set focus on textarea + this.$.find(".Ldt-CreateAnnotation-Description").focus(); } } }; @@ -348,7 +409,12 @@ } }; -IriSP.Widgets.CreateAnnotation.prototype.onDescriptionChange = function() { +IriSP.Widgets.CreateAnnotation.prototype.onDescriptionChange = function(e) { + if (e !== undefined && e.keyCode == 13 && !e.shiftKey) { + // Return: submit. Use shift-Return to insert a LF + this.onSubmit(); + return true; + } var _field = this.$.find(".Ldt-CreateAnnotation-Description"), _contents = _field.val(); _field.css("border-color", !!_contents ? "#666666" : "#ff0000"); @@ -396,9 +462,8 @@ return !!_contents; }; -/* Fonction effectuant l'envoi des annotations */ IriSP.Widgets.CreateAnnotation.prototype.onSubmit = function() { - /* Si les champs obligatoires sont vides, on annule l'envoi */ + /* If mandatory fields are empty, we cancel the sending */ if (!this.onDescriptionChange() || (this.show_title_field && !this.onTitleChange()) || (this.show_creator_field && !this.onCreatorChange())) { return false; } @@ -408,26 +473,27 @@ } var _this = this, - _exportedAnnotations = new IriSP.Model.List(this.player.sourceManager), /* Création d'une liste d'annotations contenant une annotation afin de l'envoyer au serveur */ - _export = this.player.sourceManager.newLocalSource({serializer: IriSP.serializers[this.api_serializer]}), /* Création d'un objet source utilisant un sérialiseur spécifique pour l'export */ - _annotation = new IriSP.Model.Annotation(false, _export), /* Création d'une annotation dans cette source avec un ID généré à la volée (param. false) */ - _annotationTypes = this.source.getAnnotationTypes().searchByTitle(this.annotation_type, true), /* Récupération du type d'annotation dans lequel l'annotation doit être ajoutée */ - _annotationType = (_annotationTypes.length ? _annotationTypes[0] : new IriSP.Model.AnnotationType(false, _export)), /* Si le Type d'Annotation n'existe pas, il est créé à la volée */ - _url = Mustache.to_html(this.api_endpoint_template, {id: this.source.projectId}); /* Génération de l'URL à laquelle l'annotation doit être envoyée, qui doit inclure l'ID du projet */ + _exportedAnnotations = new IriSP.Model.List(this.player.sourceManager), /* We create a List to send to the server that will contains the annotation */ + _export = this.player.sourceManager.newLocalSource({serializer: IriSP.serializers[this.api_serializer]}), /* We create a source object using a specific serializer for export */ + _local_export = this.player.sourceManager.newLocalSource({serializer: IriSP.serializers['ldt_localstorage']}), /* Source object using a specific serializer for local export */ + _annotation = new IriSP.Model.Annotation(false, _export), /* We create an annotation in the source with a generated ID (param. false) */ + _annotationTypes = this.source.getAnnotationTypes().searchByTitle(this.annotation_type, true), /* We get the AnnotationType in which the annotation will be added */ + _annotationType = (_annotationTypes.length ? _annotationTypes[0] : new IriSP.Model.AnnotationType(false, _export)), /* If it doesn't already exists, we create it */ + _url = Mustache.to_html(this.api_endpoint_template, {id: this.source.projectId}); /* We make the url to send the request to, must include project id */ - /* Si nous avons dû générer un ID d'annotationType à la volée... */ + /* If we created an AnnotationType on the spot ... */ if (!_annotationTypes.length) { - /* Il ne faudra pas envoyer l'ID généré au serveur */ + /* ... We must not send its id to the server ... */ _annotationType.dont_send_id = true; - /* Il faut inclure le titre dans le type d'annotation */ + /* ... And we must include its title. */ _annotationType.title = this.annotation_type; } /* - * Nous remplissons les données de l'annotation générée à la volée - * ATTENTION: Si nous sommes sur un MASHUP, ces éléments doivent se référer AU MEDIA D'ORIGINE + * Will fill the generated annotation object's data + * WARNING: If we're on a MASHUP, these datas must refer the ORIGINAL MEDIA * */ - _annotation.setMedia(this.source.currentMedia.id); /* Id du média annoté */ + _annotation.setMedia(this.source.currentMedia.id); /* Annotated media ID */ if (this.post_at_segment_time){ var _currentTime = this.media.getCurrentTime() @@ -436,32 +502,31 @@ return (_currentTime >= _segment.begin && _currentTime <= _segment.end) }); if (_currentSegments.length == 0){ - _annotation.setBegin(this.begin); /* Timecode de début du widget */ - _annotation.setEnd(this.end); /* Timecode de fin du widget */ + _annotation.setBegin(this.begin); /* Widget starting timecode */ + _annotation.setEnd(this.end); /* Widget end timecode */ } else { - _annotation.setBegin(_currentSegments[0].begin); /* Timecode de début du segment */ - _annotation.setEnd(_currentSegments[0].end); /* Timecode de fin du segment */ + _annotation.setBegin(_currentSegments[0].begin); /* Segment starting timecode */ + _annotation.setEnd(_currentSegments[0].end); /* Segment end timecode */ } } else { - _annotation.setBegin(this.begin); /*Timecode de début du widget */ - _annotation.setEnd(this.end); /* Timecode de fin du widget */ + _annotation.setBeginEnd(this.begin, this.end); /* Widget end/start timecodes */ } - _annotation.setAnnotationType(_annotationType.id); /* Id du type d'annotation */ + _annotation.setAnnotationType(_annotationType.id); /* Annotation type ID */ if (this.show_title_field) { - /* Champ titre, seulement s'il est visible */ + /* Title field, only if it's visible */ _annotation.title = this.$.find(".Ldt-CreateAnnotation-Title").val(); }if (this.project_id != ""){ - /* Champ id projet, seulement si on l'a renseigné dans la config */ + /* Project id, only if it's been specifiec in the config */ _annotation.project_id = this.project_id; } - _annotation.created = new Date(); /* Date de création de l'annotation */ - _annotation.description = this.$.find(".Ldt-CreateAnnotation-Description").val(); /* Champ description */ + _annotation.created = new Date(); /* Annotation creation date */ + _annotation.description = this.$.find(".Ldt-CreateAnnotation-Description").val(); /* Description field */ var tagIds = Array.prototype.map.call( this.$.find(".Ldt-CreateAnnotation-TagLi.selected"), - function(el) { return IriSP.jQuery(el).attr("tag-id")} + function(el) { return IriSP.jQuery(el).attr("tag-id"); } ); IriSP._(_annotation.description.match(/#[^\s#.,;]+/g)).each(function(_tt) { @@ -478,10 +543,8 @@ if (tagIds.indexOf(_tag.id) === -1) { tagIds.push(_tag.id); } - - }) - - _annotation.setTags(IriSP._(tagIds).uniq()); /*Liste des ids de tags */ + }); + _annotation.setTags(IriSP._(tagIds).uniq()); /* Tag ids list */ if (this.audio_url) { _annotation.audio = { src: "mic", @@ -495,46 +558,66 @@ _annotation.creator = this.creator_name; } _exportedAnnotations.push(_annotation); /* Ajout de l'annotation à la liste à exporter */ - _export.addList("annotation",_exportedAnnotations); /* Ajout de la liste à exporter à l'objet Source */ - var _this = this; - /* Envoi de l'annotation via AJAX au serveur ! */ - IriSP.jQuery.ajax({ - url: _url, - type: this.api_method, - contentType: 'application/json', - data: _export.serialize(), /* L'objet Source est sérialisé */ - success: function(_data) { - _this.showScreen('Saved'); /* Si l'appel a fonctionné, on affiche l'écran "Annotation enregistrée" */ - if (_this.after_send_timeout) { /* Selon les options de configuration, on revient à l'écran principal ou on ferme le widget, ou rien */ - window.setTimeout( - function() { - _this.close_after_send - ? _this.player.trigger("CreateAnnotation.hide") - : _this.player.trigger("CreateAnnotation.show"); - }, - _this.after_send_timeout - ); + + if (this.editable_storage != '') { + // Append to localStorage annotations + + // FIXME: handle movie ids + _local_export.addList("annotation", _exportedAnnotations); /* Ajout de la liste à exporter à l'objet Source */ + _this.source.merge(_local_export); /* On ajoute la nouvelle annotation au recueil original */ + // Import previously saved local annotations + if (window.localStorage[this.editable_storage]) { + _local_export.deSerialize(window.localStorage[this.editable_storage]); + } + // Save everything back + window.localStorage[_this.editable_storage] = _local_export.serialize(); + _this.player.trigger("AnnotationsList.refresh"); /* On force le rafraîchissement du widget AnnotationsList */ + _this.player.trigger("Annotation.create", _annotation); + _this.$.find(".Ldt-CreateAnnotation-Description").val(""); + } + + if (_url !== "") { + _exportedAnnotations.push(_annotation); /* We add the annotation in the list to export */ + _export.addList("annotation",_exportedAnnotations); /* We add the list to the source object */ + var _this = this; + /* We send the AJAX request to the server ! */ + IriSP.jQuery.ajax({ + url: _url, + type: this.api_method, + contentType: 'application/json', + data: _export.serialize(), /* Source is serialized */ + success: function(_data) { + _this.showScreen('Saved'); + if (_this.after_send_timeout) { + window.setTimeout( + function() { + _this.close_after_send + ? _this.player.trigger("CreateAnnotation.hide") + : _this.player.trigger("CreateAnnotation.show"); + }, + _this.after_send_timeout + ); + } + _export.getAnnotations().removeElement(_annotation, true); /* We delete the sent annotation to avoid redundancy */ + _export.deSerialize(_data); /* Data deserialization */ + _this.source.merge(_export); /* We merge the deserialized data with the current source data */ + if (_this.pause_on_write && _this.media.getPaused()) { + _this.media.play(); + } + _this.player.trigger("AnnotationsList.refresh"); + }, + error: function(_xhr, _error, _thrown) { + IriSP.log("Error when sending annotation", _thrown); + _export.getAnnotations().removeElement(_annotation, true); + _this.showScreen('Error'); + window.setTimeout(function(){ + _this.showScreen("Main") + }, + (_this.after_send_timeout || 5000)); } - _export.getAnnotations().removeElement(_annotation, true); /* Pour éviter les doublons, on supprime l'annotation qui a été envoyée */ - _export.deSerialize(_data); /* On désérialise les données reçues pour les réinjecter */ - _this.source.merge(_export); /* On récupère les données réimportées dans l'espace global des données */ - if (_this.pause_on_write && _this.media.getPaused()) { - _this.media.play(); - } - _this.player.trigger("AnnotationsList.refresh"); /* On force le rafraîchissement du widget AnnotationsList */ - }, - error: function(_xhr, _error, _thrown) { - IriSP.log("Error when sending annotation", _thrown); - _export.getAnnotations().removeElement(_annotation, true); - _this.showScreen('Error'); - window.setTimeout(function(){ - _this.showScreen("Main") - }, - (_this.after_send_timeout || 5000)); - } - }); - this.showScreen('Wait'); - + }); + this.showScreen('Wait'); + }; return false; }; diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/metadataplayer/CurrentSegmentInfobox.js --- a/server/src/remie/static/remie/metadataplayer/CurrentSegmentInfobox.js Mon Sep 28 14:32:54 2015 +0200 +++ b/server/src/remie/static/remie/metadataplayer/CurrentSegmentInfobox.js Fri Oct 02 10:24:23 2015 +0200 @@ -218,9 +218,9 @@ new_description = this.$.find(".Ldt-CurrentSegmentInfobox-DescriptionInput").val() var _this = this, - _exportedAnnotations = new IriSP.Model.List(this.player.sourceManager), /* Création d'une liste d'annotations contenant une annotation afin de l'envoyer au serveur */ - _export = this.player.sourceManager.newLocalSource({serializer: IriSP.serializers[this.api_serializer]}), - _annotation = new IriSP.Model.Annotation(this.currentSegment.id, _export); /* Création d'une annotation dans cette source avec un ID généré à la volée (param. false) */ + _exportedAnnotations = new IriSP.Model.List(this.player.sourceManager), /* We create an Annotations List to send to the server */ + _export = this.player.sourceManager.newLocalSource({serializer: IriSP.serializers[this.api_serializer]}), /* We create a source object using a specific serializer for export */ + _annotation = new IriSP.Model.Annotation(this.currentSegment.id, _export); /* We create an annotation in the source with a generated ID (param. false) */ _annotation.setAnnotationType(this.currentSegment.getAnnotationType().id); _annotation.setMedia(this.currentSegment.getMedia().id); @@ -228,8 +228,8 @@ _annotation.setEnd(this.currentSegment.end); _annotation.created = this.currentSegment.created; _annotation.creator = this.currentSegment.creator; - _annotation.title = new_title /* Champ titre */ - _annotation.description = new_description /* Champ description */ + _annotation.title = new_title /* Title field */ + _annotation.description = new_description /* Description field */ var _tagIds = IriSP._(new_tags_titles).map(function(_title) { var _tags = _this.source.getTags(true).searchByTitle(_title, true); if (_tags.length) { @@ -245,8 +245,8 @@ _annotation.setTags(_tagIds); _annotation.project_id = this.project_id; - _exportedAnnotations.push(_annotation); /* Ajout de l'annotation à la liste à exporter */ - _export.addList("annotation",_exportedAnnotations); /* Ajout de la liste à exporter à l'objet Source */ + _exportedAnnotations.push(_annotation); /* We add the annotation in the list to export */ + _export.addList("annotation",_exportedAnnotations); /* We add the list to the source object */ _url = Mustache.to_html(this.api_endpoint_template, {annotation_id: this.currentSegment.id}); @@ -254,11 +254,11 @@ url: _url, type: this.api_method, contentType: 'application/json', - data: _export.serialize(), /* L'objet Source est sérialisé */ + data: _export.serialize(), /* Source is serialized */ success: function(_data) { - _export.getAnnotations().removeElement(_annotation, true); /* Pour éviter les doublons, on supprime l'annotation qui a été envoyée */ - _export.deSerialize(_data); /* On désérialise les données reçues pour les réinjecter */ - _this.source.merge(_export); /* On récupère les données réimportées dans l'espace global des données */ + _export.getAnnotations().removeElement(_annotation, true); /* We delete the sent annotation to avoid redundancy */ + _export.deSerialize(_data); /* Data deserialization */ + _this.source.merge(_export); /* We merge the deserialized data with the current source data */ _this.segments.forEach(function(_segment){ if (_segment.id == _annotation.id){ _this.segments.removeElement(_segment) diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/metadataplayer/DailymotionPlayer.js --- a/server/src/remie/static/remie/metadataplayer/DailymotionPlayer.js Mon Sep 28 14:32:54 2015 +0200 +++ b/server/src/remie/static/remie/metadataplayer/DailymotionPlayer.js Fri Oct 02 10:24:23 2015 +0200 @@ -9,96 +9,142 @@ }; IriSP.Widgets.DailymotionPlayer.prototype.draw = function() { - + if (typeof this.video === "undefined") { this.video = this.media.video; } this.height = this.height || Math.floor(this.width / this.aspect_ratio); - + var _media = this.media, + videoid = null, _this = this, - _pauseState = true; - - /* Dailymotion utilise un système de fonctions référencées dans - * des variables globales pour la gestion des événements. - */ - - window.onDailymotionPlayerReady = function() { + state = { + pause: true, + apiready: false, + volume: 0, + time: 0, + duration: 0 + }; + + var m = this.video.match(/www.dailymotion.com\/video\/(.+)/); + if (m) { + videoid = m[1]; + } - var _player = document.getElementById(_this.container); - + var player_url = Mustache.to_html('{{ protocol }}//www.dailymotion.com/embed/video/{{ videoid }}', { + protocol: document.location.protocol.search('http') == 0 ? document.location.protocol : 'http:', + videoid: videoid + }); + var params = { + 'api': 'postMessage', + 'chromeless': 1, + 'id': 'dm_player', + 'related': 0, + 'autoplay': 1 + }; + + _this.$.html(Mustache.to_html('', { + player_url: player_url, + params: Object.keys(params).reduce(function(a,k){a.push(k+'='+encodeURIComponent(params[k]));return a;},[]).join('&'), + width: this.width, + height: this.height, + id: params.id + })); + + function setup_media_methods () { + var dest = _this.$.find("#" + params.id)[0].contentWindow; + var execute = function(c, v) { + if (v !== undefined) + c = c + "=" + v; + dest.postMessage(c, "*"); + }; + _media.getCurrentTime = function() { - return new IriSP.Model.Time(1000*_player.getCurrentTime()); + return state.time; }; _media.getVolume = function() { - return _player.getVolume() / 100; + return state.volume; }; _media.getPaused = function() { - return _pauseState; + return state.pause; }; _media.getMuted = function() { - return _player.isMuted(); + return state.muted; }; _media.setCurrentTime = function(_milliseconds) { - _seekPause = _pauseState; - return _player.seekTo(_milliseconds / 1000); + execute("seek", _milliseconds / 1000); }; _media.setVolume = function(_vol) { - return _player.setVolume(Math.floor(_vol*100)); + execute("volume", _vol * 100); }; _media.mute = function() { - return _player.mute(); + execute("muted", 1); }; _media.unmute = function() { - return _player.unMute(); + execute("muted", 0); }; _media.play = function() { - return _player.playVideo(); + execute("play"); }; _media.pause = function() { - return _player.pauseVideo(); + execute("pause"); }; - - _player.addEventListener("onStateChange", "onDailymotionStateChange"); - _player.addEventListener("onVideoProgress", "onDailymotionVideoProgress"); - - _player.cueVideoByUrl(_this.video); - - _media.trigger("loadedmetadata"); - }; - - window.onDailymotionStateChange = function(_state) { - switch(_state) { - case 1: - _media.trigger("play"); - _pauseState = false; - break; - - case 2: - _media.trigger("pause"); - _pauseState = true; - break; - - case 3: - _media.trigger("seeked"); - break; - } - }; - - window.onDailymotionVideoProgress = function(_progress) { - _media.trigger("timeupdate", new IriSP.Model.Time(_progress.mediaTime * 1000)); - }; - - var params = { - "allowScriptAccess" : "always", - "wmode": "opaque" - }; - - var atts = { - id : this.container }; - swfobject.embedSWF("http://www.dailymotion.com/swf?chromeless=1&enableApi=1", this.container, this.width, this.height, "8", null, null, params, atts); - -}; \ No newline at end of file + window.addEventListener("message", function (event) { + // Parse event.data (query-string for to object) + + // Duck-checking if event.data is a string + if (event.data.split === undefined) + return; + + var info = event.data.split("&").map( function(s) { return s.split("="); }).reduce( function(o, v) { o[v[0]] = decodeURIComponent(v[1]); return o; }, {}); + + switch (info.event) { + case "apiready": + state.apiready = true; + setup_media_methods(); + break; + //case "canplay": + // break; + case "durationchange": + if (info.duration.slice(-2) == "sc") { + state.duration = 1000 * Number(info.duration.slice(0, -2)); + _media.setDuration(state.duration); + } + break; + case "ended": + state.pause = true; + break; + case "loadedmetadata": + _media.trigger("loadedmetadata"); + break; + case "pause": + state.pause = true; + _media.trigger("pause"); + break; + case "play": + state.pause = false; + _media.trigger("play"); + break; + //case "playing": + // break; + //case "progress": + // Loading progress + // break; + case "seeked": + state.time = new IriSP.Model.Time(1000 * Number(info.time)); + _media.trigger("seeked"); + break; + case "timeupdate": + state.time = new IriSP.Model.Time(1000 * Number(info.time)); + _media.trigger("timeupdate", state.time); + break; + case "volumechange": + state.muted = (info.muted == "true"); + state.volume = Number(info.volume) / 100; + break; + } + }, false); +}; diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/metadataplayer/EnrichedPlan.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/remie/static/remie/metadataplayer/EnrichedPlan.css Fri Oct 02 10:24:23 2015 +0200 @@ -0,0 +1,207 @@ +.Ldt-EnrichedPlan-Slide { + border-bottom: 2px dotted #ccc; + padding-top: 4px; + cursor: pointer; +} + +.Ldt-EnrichedPlan-SlideItem { + max-height: 3000px; + transition: max-height .6s; +} + +.Ldt-EnrichedPlan-SlideItem.filtered_out { + max-height: 0px; + overflow: hidden; +} + +.Ldt-EnrichedPlan-SlideTimecode { + display: inline-block; + width: 24px; + color: #999 !important; + font-size: 9px !important; + width: 24px; + vertical-align: top; +} + +.Ldt-EnrichedPlan-SlideThumbnail { + display: inline-block; + width: 180px; + height: 100px; + padding-left: 10px; + margin: 0; + vertical-align: top; +} + +.Ldt-EnrichedPlan-SlideThumbnail img { + max-width: 180px; + max-height: 100px; + margin: auto; + border: 1px solid #ccc; +} + +.Ldt-EnrichedPlan-SlideContent { + display: inline-block; + width: calc(100% - 220px); + transition: width .4s; +} + +.Ldt-EnrichedPlan-SlideThumbnail.filtered_out + .Ldt-EnrichedPlan-SlideContent { + width: calc(100% - 40px); +} + +.Ldt-EnrichedPlan-SlideTitle { + display: inline-block; + font-size: 14px; + width: 100%; + height: 1em; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.Ldt-EnrichedPlan-SlideTitle1 { + text-transform: uppercase; + font-size: 13px; + font-weight: 600; +} + +.Ldt-EnrichedPlan-Note { + font-weight: normal; + font-size: 14px; + font-family: Roboto-italic; +} +.Ldt-EnrichedPlan-Note:hover { + background-color: #eee; +} + +.Ldt-EnrichedPlan-Note-Teacher { + color: #e5007e; + font-style: italic; +} +.Ldt-EnrichedPlan-Note-Own { + color: #66ccff; +} +.Ldt-EnrichedPlan-Note-Other { + color: #996633; +} + +.Ldt-EnrichedPlan-Note-Text { + line-height: 22px; + word-wrap: break-word; +} + +.Ldt-EnrichedPlan-Note-Author { + text-transform: uppercase; + font-size: 10px; +} + +.Ldt-EnrichedPlan-Content { + margin-top: 37px; +} + +.Ldt-EnrichedPlan-Controls { + height: 36px; + padding: 9px 0px 6px 0px; + border-bottom: 1px solid #000; + overflow-y: hidden; + overflow-x: hidden; + position: absolute; + top: 0px; + left: 0px; + right: 0px; + z-index: 1; + background-color: #fff; +} + +.Ldt-EnrichedPlan-Control-Label { + display: inline-block; + text-transform: uppercase; + line-height: 10px; + font-family: Roboto; + font-size: 10px; + font-weight: 100; + width: 80px; + position: relative; +} +.Ldt-EnrichedPlan-Controls .Ldt-EnrichedPlan-Search-Input { + float: right; + font-family: Roboto; + font-size: 16px; + width: calc(100% - 340px); +} + +.Ldt-EnrichedPlan-Note.non_matching { + display: none; +} + +.Ldt-EnrichedPlan-Control- { + font-style: normal; +} + /**********************************************************/ +/* Base for label styling */ +.Ldt-EnrichedPlan-Control-Checkbox:not(:checked), +.Ldt-EnrichedPlan-Control-Checkbox:checked { + position: absolute; + left: -9999px; +} +.Ldt-EnrichedPlan-Control-Checkbox:not(:checked) + label, +.Ldt-EnrichedPlan-Control-Checkbox:checked + label { + position: relative; + padding-left: 20px; + cursor: pointer; +} + +/* checkbox aspect */ +.Ldt-EnrichedPlan-Control-Checkbox:not(:checked) + label:before, +.Ldt-EnrichedPlan-Control-Checkbox:checked + label:before { + content: ''; + position: absolute; + left:0; top: 2px; + width: 13px; height: 13px; + border: 1px solid #aaa; +} +/* checked mark aspect */ +.Ldt-EnrichedPlan-Control-Checkbox:not(:checked) + label:after, +.Ldt-EnrichedPlan-Control-Checkbox:checked + label:after { + content: '\2a2f'; + font-style: normal; + position: absolute; + top: 3px; left: -1px; + font-size: 20px; + transition: all .2s; +} +/* checked mark aspect changes */ +.Ldt-EnrichedPlan-Control-Checkbox:not(:checked) + label:after { + opacity: 0; +} +.Ldt-EnrichedPlan-Control-Checkbox:checked + label:after { + opacity: 1; +} +/* disabled checkbox */ +.Ldt-EnrichedPlan-Control-Checkbox:disabled:not(:checked) + label:before, +.Ldt-EnrichedPlan-Control-Checkbox:disabled:checked + label:before { + box-shadow: none; + border-color: #bbb; + background-color: #ddd; +} +.Ldt-EnrichedPlan-Control-Checkbox:disabled:checked + label:after { + color: #999; +} +.Ldt-EnrichedPlan-Control-Checkbox:disabled + label { + color: #aaa; +} +/* accessibility */ +.Ldt-EnrichedPlan-Control-Checkbox:checked:focus + label:before, +.Ldt-EnrichedPlan-Control-Checkbox:not(:checked):focus + label:before { + border: 1px dotted blue; +} + +/* hover style just for information */ +label:hover:before { + border: 1px solid #4778d9!important; +} + +/* hover style just for information */ +label:hover:before { + background-color: #ededed; +} diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/metadataplayer/EnrichedPlan.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/remie/static/remie/metadataplayer/EnrichedPlan.js Fri Oct 02 10:24:23 2015 +0200 @@ -0,0 +1,145 @@ +/* TODO +- add callbacks + */ + +IriSP.Widgets.EnrichedPlan = function(player, config) { + IriSP.Widgets.Widget.call(this, player, config); +} + +IriSP.Widgets.EnrichedPlan.prototype = new IriSP.Widgets.Widget(); + +IriSP.Widgets.EnrichedPlan.prototype.defaults = { + // Main type for slide segmentation + annotation_type: "Slides", + // If no annotation type list is specified, use all other types + annotation_types: [], + show_controls: true, + show_slides: true, + show_teacher_notes: true, + show_other_notes: true, + show_own_notes: true +} + +IriSP.Widgets.EnrichedPlan.prototype.template = + '
    ' + + '{{#show_controls}}
    ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '
    {{/show_controls}}' + + '
    ' + + '
    '; + +IriSP.Widgets.EnrichedPlan.prototype.slideTemplate = + '
    ' + + '
    {{ begin }}
    ' + + '
    ' + + '
    ' + + '
    {{ atitle }}
    ' + + '
    {{{ notes }}}
    ' + + '
    ' + + '
    '; + +IriSP.Widgets.EnrichedPlan.prototype.annotationTemplate = '
    {{{ text }}} {{ author }}
    '; + +IriSP.Widgets.EnrichedPlan.prototype.draw = function() { + var _this = this; + // Generate a unique prefix, so that ids of input fields + // (necessary for label association) are unique too. + _this.prefix = "TODO"; + // slides content: title, level (for toc) + var _slides = this.getWidgetAnnotations().sortBy(function(_annotation) { + return _annotation.begin; + }); + // All other annotations + var _annotations = this.media.getAnnotations().filter( function (a) { + return a.getAnnotationType().title != _this.annotation_type; + }).sortBy(function(_annotation) { + return _annotation.begin; + }); + + // Reference annotations in each slide: assume that end time is + // correctly set. + _slides.forEach( function (slide) { + slide.annotations = _annotations.filter( function (a) { + return a.begin >= slide.begin && a.begin <= slide.end; + }); + }); + + _this.renderTemplate(); + var container = _this.$.find('.Ldt-EnrichedPlan-Container'); + var content = _this.$.find('.Ldt-EnrichedPlan-Content'); + + // Returns the note category: Own, Other, Teacher + function note_category(a) { + return a.title.indexOf('Anonyme') < 0 ? "Own" : "Other"; + }; + + _slides.forEach(function(slide) { + var _html = Mustache.to_html(_this.slideTemplate, { + id : slide.id, + atitle : IriSP.textFieldHtml(slide.title), + level: slide.content.level || 1, + begin : slide.begin.toString(), + begintc: slide.begin.milliseconds, + thumbnail: slide.thumbnail, + show_slides: _this.show_slides, + notes: slide.annotations.map( function (a) { + return Mustache.to_html(_this.annotationTemplate, { + id: a.id, + text: IriSP.textFieldHtml(a.description || a.title), + author: a.creator, + begin: a.begin.toString(), + begintc: a.begin.milliseconds, + atitle: a.title.slice(0, 20), + // FIXME: Temporary hack waiting for a proper metadata definition + category: "Ldt-EnrichedPlan-Note-" + note_category(a), + filtered: ( (note_category(a) == 'Own' && ! _this.show_own_notes) + || (note_category(a) == 'Other' && ! _this.show_other_notes) + || (note_category(a) == 'Teacher' && ! _this.show_teacher_notes) ) ? 'filtered_out' : '' + }); + }).join("\n") + }); + var _el = IriSP.jQuery(_html); + content.append(_el); + }); + + container.on("click", "[data-timecode]", function () { + _this.media.setCurrentTime(Number(this.dataset.timecode)); + }); + + container.on("click", ".Ldt-EnrichedPlan-Control-Checkbox", function () { + var classname = _.first(_.filter(this.classList, function (s) { return s != "Ldt-EnrichedPlan-Control-Checkbox"; })); + if (classname !== undefined) { + if ($(this).is(':checked')) { + content.find(".Ldt-EnrichedPlan-Slide ." + classname).removeClass("filtered_out"); + } else { + content.find(".Ldt-EnrichedPlan-Slide ." + classname).addClass("filtered_out"); + } + } + + }); + + container.find(".Ldt-EnrichedPlan-Search-Input").on("search", function () { + var q = $(this).val().toLocaleLowerCase(); + if (q === "") { + // Show all + content.find(".Ldt-EnrichedPlan-Note").removeClass("non_matching"); + } else { + $(".Ldt-EnrichedPlan-Note").each( function () { + var node = $(this); + if (node.text().toLocaleLowerCase().indexOf(q) > -1) { + node.removeClass("non_matching"); + } else { + node.addClass("non_matching"); + } + }); + } + }); +}; diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/metadataplayer/ImageDisplay.css --- a/server/src/remie/static/remie/metadataplayer/ImageDisplay.css Mon Sep 28 14:32:54 2015 +0200 +++ b/server/src/remie/static/remie/metadataplayer/ImageDisplay.css Fri Oct 02 10:24:23 2015 +0200 @@ -1,6 +1,10 @@ -/* Nothing */ .Ldt-ImageDisplay-Container { - margin: auto; + width: 100%; + height: 100%; + background-color: white; + background-repeat: no-repeat; + background-position: center; + background-size: contain; } .Ldt-ImageDisplay-Image { @@ -9,7 +13,7 @@ } .Ldt-ImageDisplay-Overlay { - width: 20%; + width: 30%; min-width: 20px; height: 100%; opacity: 0.1; @@ -23,10 +27,10 @@ .Ldt-ImageDisplay-Overlay-Left { left: 0px; - cursor: url(img/hand_left.png), pointer; + cursor: url(img/left_arrow.svg) 20 20, pointer; } .Ldt-ImageDisplay-Overlay-Right { right: 0px; - cursor: url(img/hand_right.png), pointer; + cursor: url(img/right_arrow.svg) 20 20, pointer; } diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/metadataplayer/ImageDisplay.js --- a/server/src/remie/static/remie/metadataplayer/ImageDisplay.js Mon Sep 28 14:32:54 2015 +0200 +++ b/server/src/remie/static/remie/metadataplayer/ImageDisplay.js Fri Oct 02 10:24:23 2015 +0200 @@ -7,27 +7,27 @@ IriSP.Widgets.ImageDisplay.prototype = new IriSP.Widgets.Widget(); IriSP.Widgets.ImageDisplay.prototype.defaults = { - annotation_type: "Slides", + annotation_type: "Slides" // container: "imageContainer" } -IriSP.Widgets.ImageDisplay.prototype.template = '
    Slide Image
    '; +IriSP.Widgets.ImageDisplay.prototype.template = '
    '; IriSP.Widgets.ImageDisplay.prototype.annotationTemplate = ''; IriSP.Widgets.ImageDisplay.prototype.update = function(annotation) { // Update the widget with data corresponding to the annotation - this.image.setAttribute("title", IriSP.textFieldHtml(annotation.title) + " - " + annotation.begin.toString()); - this.image.setAttribute("src", annotation.thumbnail); + this.image.css("background-image", "url(" + annotation.thumbnail + ")"); + this.image.attr("title", IriSP.textFieldHtml(annotation.title) + " - " + annotation.begin.toString()); }; -IriSP.Widgets.ImageDisplay.prototype.draw = function() { +IriSP.Widgets.ImageDisplay.prototype.draw = function() { var _annotations = this.getWidgetAnnotations().sortBy(function(_annotation) { return _annotation.begin; }); var _this = this; _this.renderTemplate(); - _this.image = _this.$.find("img")[0]; + _this.image = _this.$.find(".Ldt-ImageDisplay-Container"); _this.$.find(".Ldt-ImageDisplay-Overlay-Left").on("click", function () { _this.navigate(-1); }); _this.$.find(".Ldt-ImageDisplay-Overlay-Right").on("click", function () { _this.navigate(+1); }); diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/metadataplayer/LatestAnnotation.js --- a/server/src/remie/static/remie/metadataplayer/LatestAnnotation.js Mon Sep 28 14:32:54 2015 +0200 +++ b/server/src/remie/static/remie/metadataplayer/LatestAnnotation.js Fri Oct 02 10:24:23 2015 +0200 @@ -116,7 +116,7 @@ _annotation.on("click", function(){ var _user = {}, _user_display_string = "", - _users = _this.source.users_data.filter(function(_user_data){ + _users = this.source.users_data.filter(function(_user_data){ return _user_data.username == _annotation.creator }); if (_users.length == 0){ diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/metadataplayer/LdtPlayer-core.js --- a/server/src/remie/static/remie/metadataplayer/LdtPlayer-core.js Mon Sep 28 14:32:54 2015 +0200 +++ b/server/src/remie/static/remie/metadataplayer/LdtPlayer-core.js Fri Oct 02 10:24:23 2015 +0200 @@ -82,7 +82,7 @@ var list = [], positions = [], text = _text.replace(/(^\s+|\s+$)/g,''); - + function addToList(_rx, _startHtml, _endHtml) { while(true) { var result = _rx.exec(text); @@ -101,11 +101,11 @@ positions.push(end); } } - + if (_regexp) { addToList(_regexp, '', ''); } - + addToList(/(https?:\/\/)?[\w\d\-]+\.[\w\d\-]+\S+/gm, function(matches) { return ''; }, ''); @@ -114,19 +114,19 @@ }, ''); addToList(/\*[^*]+\*/gm, '', ''); addToList(/[\n\r]+/gm, '', '
    '); - + IriSP._(_extend).each(function(x) { addToList.apply(null, x); }); - + positions = IriSP._(positions) .chain() .uniq() .sortBy(function(p) { return parseInt(p); }) .value(); - + var res = "", lastIndex = 0; - + for (var i = 0; i < positions.length; i++) { var pos = positions[i]; res += text.substring(lastIndex, pos); @@ -144,11 +144,11 @@ } lastIndex = pos; } - + res += text.substring(lastIndex); - + return res; - + }; IriSP.log = function() { @@ -161,11 +161,27 @@ jqSel.attr("draggable", "true").on("dragstart", function(_event) { var d = (typeof data === "function" ? data.call(this) : data); try { + if (d.html === undefined && d.uri && d.text) { + d.html = '' + d.text + ''; + } IriSP._(d).each(function(v, k) { - if (v) { + if (v && k != 'text' && k != 'html') { _event.originalEvent.dataTransfer.setData("text/x-iri-" + k, v); } }); + if (d.uri && d.text) { + _event.originalEvent.dataTransfer.setData("text/x-moz-url", d.uri + "\n" + d.text.replace("\n", " ")); + _event.originalEvent.dataTransfer.setData("text/plain", d.text + " " + d.uri); + } + // Define generic text/html and text/plain last (least + // specific types, see + // https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Drag_operations#Drag_Data) + if (d.html !== undefined) { + _event.originalEvent.dataTransfer.setData("text/html", d.html); + } + if (d.text !== undefined && ! d.uri) { + _event.originalEvent.dataTransfer.setData("text/plain", d.text); + } } catch(err) { _event.originalEvent.dataTransfer.setData("Text", JSON.stringify(d)); } @@ -180,6 +196,62 @@ }); }; +IriSP.timestamp2ms = function(t) { + // Convert timestamp to numeric value + // It accepts the following forms: + // [h:mm:ss] [mm:ss] [ss] + var s = t.split(":").reverse(); + while (s.length < 3) { + s.push("0"); + } + return 1000 * (3600 * parseInt(s[2], 10) + 60 * parseInt(s[1], 10) + parseInt(s[0], 10)); +}; + +IriSP.setFullScreen= function(elem, value) { + // Set fullscreen on or off + if (value) { + if (elem.requestFullscreen) { + elem.requestFullscreen(); + } else if (elem.mozRequestFullScreen) { + elem.mozRequestFullScreen(); + } else if (elem.webkitRequestFullscreen) { + elem.webkitRequestFullscreen(); + } else if (elem.msRequestFullscreen) { + elem.msRequestFullscreen(); + } + } else { + if (document.exitFullscreen) { + document.exitFullscreen(); + } else if (document.msExitFullscreen) { + document.msExitFullscreen(); + } else if (document.mozCancelFullScreen) { + document.mozCancelFullScreen(); + } else if (document.webkitExitFullscreen) { + document.webkitExitFullscreen(); + } + } +}; + +IriSP.isFullscreen = function() { + return (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement); +}; + +IriSP.getFullscreenElement = function () { + return (document.fullscreenElement + || document.webkitFullscreenElement + || document.mozFullScreenElement + || document.msFullscreenElement + || undefined); +}; + +IriSP.getFullscreenEventname = function () { + return ((document.exitFullscreen && "fullscreenchange") + || (document.webkitExitFullscreen && "webkitfullscreenchange") + || (document.mozExitFullScreen && "mozfullscreenchange") + || (document.msExitFullscreen && "msfullscreenchange") + || ""); +}; + /* js is where data is stored in a standard form, whatever the serializer */ //TODO: Separate Project-specific data from Source @@ -943,6 +1015,19 @@ extendPrototype(Annotation, BaseElement); +/* Set begin and end in one go, to avoid undesired side-effects in + * setBegin/setEnd interaction */ +Annotation.prototype.setBeginEnd = function(_beginMs, _endMs) { + _beginMs = Math.max(0,_beginMs); + _endMs = Math.max(0,_endMs); + if (_endMs < _beginMs) + _endMs = _beginMs; + this.begin.setMilliseconds(_beginMs); + this.end.setMilliseconds(_endMs); + this.trigger("change-begin"); + this.trigger("change-end"); +}; + Annotation.prototype.setBegin = function(_beginMs) { this.begin.setMilliseconds(Math.max(0,_beginMs)); this.trigger("change-begin"); @@ -1470,7 +1555,17 @@ videoEl.append(_srcNode); } } - + if (opts.subtitle) { + var _trackNode = IriSP.jQuery(''); + _trackNode.attr({ + label: "Subtitles", + kind: "subtitles", + srclang: "fr", + src: opts.subtitle, + default: "" + }); + videoEl.append(_trackNode); + } jqselector.html(videoEl); var mediaEl = videoEl[0]; @@ -1569,6 +1664,13 @@ media.trigger("seeked"); }); + videoEl.on("click", function() { + if (mediaEl.paused) { + media.play(); + } else { + media.pause(); + }; + }); }; /* START contentapi-serializer.js */ @@ -1745,7 +1847,7 @@ if (typeof _data.content.img !== "undefined" && _data.content.img.src !== "undefined") { _res.thumbnail = _data.content.img.src; } - _res.created = IriSP.Model.isoToDate(_data.created); + _res.created = IriSP.Model.isoToDate((_data.meta ? _data.meta['dc:created'] : "") ||_data.created); if (typeof _data.color !== "undefined") { var _c = parseInt(_data.color).toString(16); while (_c.length < 6) { @@ -1758,8 +1860,7 @@ _res.setAnnotationType(_data.meta["id-ref"]); _res.setTags(IriSP._(_data.tags).pluck("id-ref")); _res.keywords = _res.getTagTexts(); - _res.setBegin(_data.begin); - _res.setEnd(_data.end); + _res.setBeginEnd(_data.begin, _data.end); _res.creator = _data.meta["dc:creator"] || ""; _res.project = _data.meta.project || ""; if (typeof _data.meta["dc:source"] !== "undefined" && typeof _data.meta["dc:source"].content !== "undefined") { @@ -1957,9 +2058,11 @@ serializeAnnotation : function(_data, _source) { var _annType = _data.getAnnotationType(); return { + id: _data.id, begin: _data.begin.milliseconds, end: _data.end.milliseconds, content: { + data: (_data.content ? _data.content.data || {} : {}), description: _data.description, title: _data.title, audio: _data.audio @@ -1972,7 +2075,9 @@ type: ( typeof _annType.dont_send_id !== "undefined" && _annType.dont_send_id ? "" : _annType.id ), meta: { created: _data.created, - creator: _data.creator + creator: _data.creator, + modified: _data.modified, + contributor: _data.contributor } }; }, @@ -2003,11 +2108,13 @@ return _tag.id; }); _ann.setTags(_tagIds); - _ann.setBegin(_anndata.begin); - _ann.setEnd(_anndata.end); + _ann.setBeginEnd(_anndata.begin, _anndata.end); if (typeof _anndata.content.audio !== "undefined" && _anndata.content.audio.href) { _ann.audio = _anndata.content.audio; - } + }; + if (_anndata.content.data) { + _ann.content = { data: _anndata.content.data }; + }; _source.getAnnotations().push(_ann); }, serialize : function(_source) { @@ -2017,7 +2124,7 @@ if (typeof _data == "string") { _data = JSON.parse(_data); } - + _source.addList('tag', new IriSP.Model.List(_source.directory)); _source.addList('annotationType', new IriSP.Model.List(_source.directory)); _source.addList('annotation', new IriSP.Model.List(_source.directory)); @@ -2025,7 +2132,8 @@ } }; -/* End ldt_annotate serializer *//* ldt_localstorage serializer: Used to store personal annotations in local storage */ +/* End ldt_annotate serializer */ +/* ldt_localstorage serializer: Used to store personal annotations in local storage */ if (typeof IriSP.serializers === "undefined") { IriSP.serializers = {}; @@ -2035,9 +2143,11 @@ serializeAnnotation : function(_data, _source) { var _annType = _data.getAnnotationType(); return { + id: _data.id, begin: _data.begin.milliseconds, end: _data.end.milliseconds, content: { + data: (_data.content ? _data.content.data || {} : {}), description: _data.description, title: _data.title, audio: _data.audio @@ -2048,7 +2158,9 @@ type: ( typeof _annType.dont_send_id !== "undefined" && _annType.dont_send_id ? "" : _annType.id ), meta: { created: _data.created, - creator: _data.creator + creator: _data.creator, + modified: _data.modified, + contributor: _data.contributor } }; }, @@ -2058,6 +2170,8 @@ _ann.title = _anndata.content.title || ""; _ann.creator = _anndata.meta.creator || ""; _ann.created = new Date(_anndata.meta.created); + _ann.contributor = _anndata.meta.contributor || ""; + _ann.modified = new Date(_anndata.meta.modified); _ann.setMedia(_anndata.media, _source); var _anntype = _source.getElement(_anndata.type); if (!_anntype) { @@ -2079,11 +2193,13 @@ return _tag.id; }); _ann.setTags(_tagIds); - _ann.setBegin(_anndata.begin); - _ann.setEnd(_anndata.end); + _ann.setBeginEnd(_anndata.begin, _anndata.end); if (typeof _anndata.content.audio !== "undefined" && _anndata.content.audio.href) { _ann.audio = _anndata.content.audio; - } + }; + if (_anndata.content.data) { + _ann.content = { data: _anndata.content.data }; + }; _source.getAnnotations().push(_ann); }, serialize : function(_source) { @@ -2168,8 +2284,8 @@ backboneRelational: "backbone-relational.js", paper: "paper.js", jqueryMousewheel: "jquery.mousewheel.min.js", - splitter: "jquery.splitter.js", - cssSplitter: "jquery.splitter.css", + splitter: "jquery.touchsplitter.js", + cssSplitter: "jquery.touchsplitter.css", renkanPublish: "renkan.js", processing: "processing-1.3.6.min.js", recordMicSwf: "record_mic.swf", @@ -2259,7 +2375,7 @@ }; IriSP.guiDefaults = { - width : 640, + width : 640, container : 'LdtPlayer', spacer_div_height : 0, widgets: [] @@ -2312,23 +2428,21 @@ ns.log("IriSP.Metadataplayer.prototype.loadLibs"); var $L = $LAB .queueScript(ns.getLib("Mustache")); - formerJQuery = !!window.jQuery; former$ = !!window.$; formerUnderscore = !!window._; - + if (typeof ns.jQuery === "undefined") { $L.queueScript(ns.getLib("jQuery")); } - + if (typeof ns._ === "undefined") { $L.queueScript(ns.getLib("underscore")); } - + if (typeof window.JSON == "undefined") { $L.queueScript(ns.getLib("json")); } - $L.queueWait().queueScript(ns.getLib("jQueryUI")).queueWait(); /* widget specific requirements */ @@ -2340,9 +2454,8 @@ } } } - + var _this = this; - $L.queueWait(function() { _this.onLibsLoaded(); }); @@ -2352,7 +2465,7 @@ Metadataplayer.prototype.onLibsLoaded = function() { ns.log("IriSP.Metadataplayer.prototype.onLibsLoaded"); - + if (typeof ns.jQuery === "undefined" && typeof window.jQuery !== "undefined") { ns.jQuery = window.jQuery; if (former$ || formerJQuery) { @@ -2368,7 +2481,7 @@ ns.loadCss(ns.getLib("cssjQueryUI")); ns.loadCss(this.config.css); - + this.$ = ns.jQuery('#' + this.config.container); this.$.css({ "width": this.config.width, @@ -2377,7 +2490,7 @@ if (typeof this.config.height !== "undefined") { this.$.css("height", this.config.height); } - + this.widgets = []; var _this = this; ns._(this.config.widgets).each(function(widgetconf, key) { @@ -2390,9 +2503,9 @@ }); }); this.$.find('.Ldt-Loader').detach(); - + this.widgetsLoaded = false; - + this.on("widget-loaded", function() { if (_this.widgetsLoaded) { return; @@ -2404,7 +2517,44 @@ _this.widgetsLoaded = true; _this.trigger("widgets-loaded"); } - }); + }); +}; + +Metadataplayer.prototype.loadLocalAnnotations = function(localsourceidentifier) { + if (this.localSource === undefined) + this.localSource = this.sourceManager.newLocalSource({serializer: IriSP.serializers['ldt_localstorage']}); + // Load current local annotations + if (localsourceidentifier) { + // Allow to override localsourceidentifier when necessary (usually at init time) + this.localSource.identifier = localsourceidentifier; + } + this.localSource.deSerialize(window.localStorage[this.localSource.identifier] || "[]"); + return this.localSource; +}; + +Metadataplayer.prototype.saveLocalAnnotations = function() { + // Save annotations back to localstorage + window.localStorage[this.localSource.identifier] = this.localSource.serialize(); + // Merge modifications into widget source + // this.source.merge(this.localSource); +}; + +Metadataplayer.prototype.addLocalAnnotation = function(a) { + this.loadLocalAnnotations(); + this.localSource.getAnnotations().push(a); + this.saveLocalAnnotations(); +}; + +Metadataplayer.prototype.deleteLocalAnnotation = function(ident) { + this.localSource.getAnnotations().removeId(ident, true); + this.saveLocalAnnotations(); +}; + +Metadataplayer.prototype.getLocalAnnotation = function (ident) { + this.loadLocalAnnotations(); + // We cannot use .getElement since it fetches + // elements from the global Directory + return IriSP._.first(IriSP._.filter(this.localSource.getAnnotations(), function (a) { return a.id == ident; })); }; Metadataplayer.prototype.loadMetadata = function(_metadataInfo) { @@ -2427,9 +2577,9 @@ var _divs = this.layoutDivs(_widgetConfig.type); _widgetConfig.container = _divs[0]; } - + var _this = this; - + if (typeof ns.Widgets[_widgetConfig.type] !== "undefined") { ns._.defer(function() { _callback(new ns.Widgets[_widgetConfig.type](_this, _widgetConfig)); @@ -2474,7 +2624,7 @@ if (typeof _height !== "undefined") { divHtml.css("height", _height); } - + this.$.append(divHtml); this.$.append(spacerHtml); @@ -2483,7 +2633,8 @@ })(IriSP); -/* End of widgets-container/metadataplayer.js *//* widgetsDefinition of an ancestor for the Widget classes */ +/* End of widgets-container/metadataplayer.js */ +/* widgetsDefinition of an ancestor for the Widget classes */ if (typeof IriSP.Widgets === "undefined") { IriSP.Widgets = {}; @@ -2502,44 +2653,44 @@ IriSP.Widgets.Widget = function(player, config) { - + if( typeof player === "undefined") { /* Probably an abstract call of the class when * individual widgets set their prototype */ return; } - + this.__subwidgets = []; - + /* Setting all the configuration options */ var _type = config.type || "(unknown)", _config = IriSP._.defaults({}, config, (player && player.config ? player.config.default_options : {}), this.defaults), _this = this; - + IriSP._(_config).forEach(function(_value, _key) { _this[_key] = _value; }); - + this.$ = IriSP.jQuery('#' + this.container); - + if (typeof this.width === "undefined") { this.width = this.$.width(); } else { this.$.css("width", this.width); } - + if (typeof this.height !== "undefined") { this.$.css("height", this.height); } - + /* Setting this.player at the end in case it's been overriden * by a configuration option of the same name :-( */ this.player = player || new IriSP.FakeClass(["on","trigger","off","loadWidget","loadMetadata"]); - + /* Adding classes and html attributes */ this.$.addClass("Ldt-TraceMe Ldt-Widget").attr("widget-type", _type); - + this.l10n = ( typeof this.messages[IriSP.language] !== "undefined" ? this.messages[IriSP.language] @@ -2549,10 +2700,14 @@ : this.messages["en"] ) ); - + /* Loading Metadata if required */ - + function onsourceloaded() { + if (_this.localannotations) { + _this.localsource = player.loadLocalAnnotations(_this.localannotations); + _this.source.merge(_this.localsource); + } if (_this.media_id) { _this.media = this.getElement(_this.media_id); } else { @@ -2561,8 +2716,6 @@ }; _this.media = _this.source.getCurrentMedia(_mediaopts); } - - if (_this.pre_draw_callback){ IriSP.jQuery.when(_this.pre_draw_callback()).done(_this.draw()); } @@ -2571,11 +2724,10 @@ } _this.player.trigger("widget-loaded"); } - + if (this.metadata) { /* Getting metadata */ this.source = player.loadMetadata(this.metadata); - /* Call draw when loaded */ this.source.onLoad(onsourceloaded); } else { @@ -2583,8 +2735,8 @@ onsourceloaded(); } } - - + + }; IriSP.Widgets.Widget.prototype.defaults = {}; @@ -2702,7 +2854,7 @@ // offset is normally either -1 (previous slide) or +1 (next slide) var _this = this; var currentTime = _this.media.getCurrentTime(); - var annotations = _this.source.getAnnotations().sortBy(function(_annotation) { + var annotations = _this.getWidgetAnnotations().sortBy(function(_annotation) { return _annotation.begin; }); for (var i = 0; i < annotations.length; i++) { @@ -2715,6 +2867,51 @@ }; }; +/* + * Propose an export of the widget's annotations + * + * Parameter: a list of annotations. If not specified, the widget's annotations will be exported. + */ +IriSP.Widgets.Widget.prototype.exportAnnotations = function(annotations) { + var widget = this; + if (annotations === undefined) + annotations = this.getWidgetAnnotations(); + var $ = IriSP.jQuery; + + // FIXME: this should belong to a proper serialize/deserialize component? + var content = Mustache.to_html("[video:{{url}}]\n", {url: widget.media.url}) + annotations.map( function(a) { return Mustache.to_html("[{{ a.begin }}]{{ a.title }} {{ a.description }}[{{ a.end }}]", { a: a }); }).join("\n"); + + var el = $("
    ")
    +            .addClass("exportContainer")
    +            .text(content)
    +            .dialog({
    +                title: "Annotation export",
    +                open: function( event, ui ) {
    +                    // Select text
    +                    var range;
    +                    if (document.selection) {
    +		                range = document.body.createTextRange();
    +                        range.moveToElementText(this[0]);
    +		                range.select();
    +		            } else if (window.getSelection) {
    +		                range = document.createRange();
    +		                range.selectNode(this[0]);
    +		                window.getSelection().addRange(range);
    +		            }
    +                },
    +                autoOpen: true,
    +                width: '80%',
    +                minHeight: '400',
    +                height: 400,
    +                buttons: [ { text: "Close", click: function() { $( this ).dialog( "close" ); } },
    +                           { text: "Download", click: function () {
    +                               a = document.createElement('a');
    +                               a.setAttribute('href', 'data:text/plain;base64,' + btoa(content));
    +                               a.setAttribute('download', 'Annotations - ' + widget.media.title.replace(/[^ \w]/g, '') + '.txt');
    +                               a.click();
    +                           } } ]
    +            });
    +};
     
     /**
      * This method responsible of drawing a widget on screen.
    diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/metadataplayer/Markers.js
    --- a/server/src/remie/static/remie/metadataplayer/Markers.js	Mon Sep 28 14:32:54 2015 +0200
    +++ b/server/src/remie/static/remie/metadataplayer/Markers.js	Fri Oct 02 10:24:23 2015 +0200
    @@ -205,7 +205,7 @@
             this.showScreen("ConfirmDelete");
         }
         else {
    -        // Clic sur - sans marqueur sélectionné = retour à l'état initial
    +        // Click on "x" without a selected marker: back to initial state
             this.cancelEdit();
         }
     }
    @@ -247,7 +247,7 @@
     
     IriSP.Widgets.Markers.prototype.cancelEdit = function(){
         if (this.selectedMarker){
    -        // Clic sur "cancel" pendant édition d'un marqueur = retour à l'état visualisation
    +        // Click on "cancel" while editing a marker: back to visualization state
             _divHtml = Mustache.to_html(this.infoTemplate, {
                 edit: false,
                 marker_info: this.selectedMarker.description,
    @@ -258,7 +258,7 @@
             }
         }
         else {
    -        // Clic sur "cancel" pendant la création d'un marqueur = retour à l'état initial
    +        // Click on "cancel" while editing a marker: back to initial state
             this.hidePlaceholder();
             this.$.find(".Ldt-Markers-Info").html("");
             this.$.find(".Ldt-Markers-RoundButton").hide()
    @@ -440,85 +440,78 @@
     
     IriSP.Widgets.Markers.prototype.onSubmit = function(){
         
    -    /* Si les champs obligatoires sont vides, on annule l'envoi */
    +    /* If mandatory fields are empty, we cancel the sending */
         if (!this.allow_empty_markers && !this.onDescriptionChange()){
             return false;
         }
         
    -    /* On pause la vidéo si elle est encore en train de tourner */
    +    /* We pause the video if it's still playing */
         if (!this.media.getPaused()){
             this.media.pause();
         }
         
         var _this = this,
    -        _exportedAnnotations = new IriSP.Model.List(this.player.sourceManager); /* Création d'une liste d'annotations contenant une annotation afin de l'envoyer au serveur */        
    +        _exportedAnnotations = new IriSP.Model.List(this.player.sourceManager), /* We create a List to send to the server that will contains the annotation */
    +        _export = this.player.sourceManager.newLocalSource({serializer: IriSP.serializers[this.api_serializer]}), /* We create a source object using a specific serializer for export */
    +        _annotationTypes = this.source.getAnnotationTypes().searchByTitle(this.annotation_type, true), /* We get the AnnotationType in which the annotation will be added */
    +        _annotationType = (_annotationTypes.length ? _annotationTypes[0] : new IriSP.Model.AnnotationType(false, _export)); /* If it doesn't already exists, we create it */
         if (this.selectedMarker){
    -        var _export = this.player.sourceManager.newLocalSource({serializer: IriSP.serializers[this.api_serializer]})
    -            _annotation = this.selectedMarker,
    +        var _annotation = this.selectedMarker,
                 _url = Mustache.to_html(this.api_endpoint_template_edit, {annotation_id: this.selectedMarker ? this.selectedMarker.id : ""});
             _annotation.source = _export
    -        _annotation.description = this.$.find(".Ldt-Markers-MarkerTextArea").val(), /* Champ description */
    -        _annotationTypes = this.source.getAnnotationTypes().searchByTitle(this.annotation_type, true), /* Récupération du type d'annotation dans lequel l'annotation doit être ajoutée */
    -        _annotationType = (_annotationTypes.length ? _annotationTypes[0] : new IriSP.Model.AnnotationType(false, _export)); /* Si le Type d'Annotation n'existe pas, il est créé à la volée */
    +        _annotation.description = this.$.find(".Ldt-Markers-MarkerTextArea").val(), /* Description field */
         }
         else {
    -        var _export = this.player.sourceManager.newLocalSource({serializer: IriSP.serializers[this.api_serializer]}), /* Création d'un objet source utilisant un sérialiseur spécifique pour l'export */
    -            _annotation = new IriSP.Model.Annotation(false, _export); /* Création d'une annotation dans cette source avec un ID généré à la volée (param. false) */
    -            _annotationTypes = this.source.getAnnotationTypes().searchByTitle(this.annotation_type, true), /* Récupération du type d'annotation dans lequel l'annotation doit être ajoutée */
    -            _annotationType = (_annotationTypes.length ? _annotationTypes[0] : new IriSP.Model.AnnotationType(false, _export)), /* Si le Type d'Annotation n'existe pas, il est créé à la volée */
    +        var _annotation = new IriSP.Model.Annotation(false, _export),
                 _url = Mustache.to_html(this.api_endpoint_template_create);
    -        /* Si nous avons dû générer un ID d'annotationType à la volée... */
    +        
    +        /* If we created an AnnotationType on the spot ... */
             if (!_annotationTypes.length) {
    -            /* Il ne faudra pas envoyer l'ID généré au serveur */
    +            /* ... We must not send its id to the server ... */
                 _annotationType.dont_send_id = true;
    -            /* Il faut inclure le titre dans le type d'annotation */
    +            /* ... And we must include its title. */
                 _annotationType.title = this.annotation_type;
             }
             
    -        _annotation.setMedia(this.source.currentMedia.id); /* Id du média annoté */
    +        _annotation.setMedia(this.source.currentMedia.id); /* Annotated media ID */
             if (!this.selectedMarker){
                 _annotation.setBegin(this.newMarkerCurrentTime);
                 _annotation.setEnd(this.newMarkerCurrentTime);
             }
    -        _annotation.setAnnotationType(_annotationType.id); /* Id du type d'annotation */
    +        _annotation.setAnnotationType(_annotationType.id); /* AnnotationType ID */
             if (this.project_id != ""){
    -            /* Champ id projet, seulement si on l'a renseigné dans la config */
    +            /* Project id, only if it's been specifiec in the config */
                 _annotation.project_id = this.project_id;
             }
    -        _annotation.created = new Date(); /* Date de création de l'annotation */
    -        _annotation.description = this.$.find(".Ldt-Markers-MarkerTextArea").val(); /* Champ description */
    +        _annotation.created = new Date(); /* Creation date */
    +        _annotation.description = this.$.find(".Ldt-Markers-MarkerTextArea").val(); /* Description field */
             _annotation.creator = this.creator_name;
         }
         _annotation.project_id = this.project_id;
         
    -    /*
    -     * Nous remplissons les données de l'annotation générée à la volée
    -     * ATTENTION: Si nous sommes sur un MASHUP, ces éléments doivent se référer AU MEDIA D'ORIGINE
    -     * */
    +    _exportedAnnotations.push(_annotation); /* We add the annotation in the list to export */
    +    _export.addList("annotation",_exportedAnnotations); /* We add the list to the source object */ 
         
    -    _exportedAnnotations.push(_annotation); /* Ajout de l'annotation à la liste à exporter */
    -    _export.addList("annotation",_exportedAnnotations); /* Ajout de la liste à exporter à l'objet Source */
    -    
    -    /* Envoi de l'annotation via AJAX au serveur ! */
    +    /* We send the AJAX request to the server ! */
         IriSP.jQuery.ajax({
             url: _url,
             type: this.selectedMarker ? this.api_method_edit : this.api_method_create,
             contentType: 'application/json',
    -        data: _export.serialize(), /* L'objet Source est sérialisé */
    +        data: _export.serialize(),
             success: function(_data) {
    -            _this.showScreen('Success'); /* Si l'appel a fonctionné, on affiche l'écran "Annotation enregistrée" */
    +            _this.showScreen('Success');
                 window.setTimeout(_this.functionWrapper("revertToMainScreen"),(_this.after_send_timeout || 5000));
    -            _export.getAnnotations().removeElement(_annotation, true); /* Pour éviter les doublons, on supprime l'annotation qui a été envoyée */
    -            _export.deSerialize(_data); /* On désérialise les données reçues pour les réinjecter */
    +            _export.getAnnotations().removeElement(_annotation, true); /* We delete the sent annotation to avoid redundancy */
    +            _export.deSerialize(_data); /* Data deserialization */
                 _annotation.id = _data.id;
    -            _this.source.merge(_export); /* On récupère les données réimportées dans l'espace global des données */
    +            _this.source.merge(_export); /* We merge the deserialized data with the current source data */
                 if (_this.pause_on_write && _this.media.getPaused() && _this.play_on_submit) {
                     _this.media.play();
                 }
                 _this.markers.push(_annotation);
                 _this.selectedMarker = _annotation;
                 _this.drawMarkers();
    -            _this.player.trigger("AnnotationsList.refresh"); /* On force le rafraîchissement du widget AnnotationsList */
    +            _this.player.trigger("AnnotationsList.refresh");
                 _this.player.trigger("Markers.refresh");
             },
             error: function(_xhr, _error, _thrown) {
    @@ -541,14 +534,14 @@
             type: this.api_method_delete,
             contentType: 'application/json',
             success: function(_data) {
    -            _this.showScreen('DeleteSuccess'); /* Si l'appel a fonctionné, on affiche l'écran "Annotation enregistrée" */
    +            _this.showScreen('DeleteSuccess');
                 window.setTimeout(_this.functionWrapper("revertToMainScreen"),(_this.after_send_timeout || 5000));
                 if (_this.pause_on_write && _this.media.getPaused() && _this.play_on_submit) {
                     _this.media.play();
                 }
                 _this.markers.removeElement(_this.selectedMarker);
                 _this.selectedMarker = false
    -            _this.player.trigger("AnnotationsList.refresh"); /* On force le rafraîchissement du widget AnnotationsList */
    +            _this.player.trigger("AnnotationsList.refresh");
                 _this.player.trigger("Markers.refresh");
             },
             error: function(_xhr, _error, _thrown) {
    diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/metadataplayer/Mediafragment.js
    --- a/server/src/remie/static/remie/metadataplayer/Mediafragment.js	Mon Sep 28 14:32:54 2015 +0200
    +++ b/server/src/remie/static/remie/metadataplayer/Mediafragment.js	Fri Oct 02 10:24:23 2015 +0200
    @@ -2,6 +2,9 @@
         IriSP.Widgets.Widget.call(this, player, config);
         this.last_hash_key = "";
         this.last_hash_value = "";
    +    this.last_extra_key = "";
    +    this.last_extra_value = "";
    +
         window.onhashchange = this.functionWrapper("goToHash");
         if (typeof window.addEventListener !== "undefined") {
             var _this = this;
    @@ -22,7 +25,7 @@
         var _this = this;
         this.getWidgetAnnotations().forEach(function(_annotation) {
             _annotation.on("click", function() {
    -            _this.setHashToAnnotation(_annotation.id);
    +            _this.setHashToAnnotation(_annotation);
             });
         });
         if (this.media.loadedMetadata) {
    @@ -48,6 +51,9 @@
         if (this.last_hash_key) {
             _tab.push(this.last_hash_key + '=' + this.last_hash_value);
         }
    +    if (this.last_extra_key) {
    +        _tab.push(this.last_extra_key + '=' + this.last_extra_value);
    +    }
         return '#' + _tab.join('&');
     };
     
    @@ -63,10 +69,13 @@
                         var _annotation = this.source.getElement(this.last_hash_value);
                         if (typeof _annotation !== "undefined") {
                             this.media.setCurrentTime(_annotation.begin);
    +                    } else {
    +                        /* Proceed parsing elements, maybe a t was specified */
    +                        continue;
                         }
                     }
                     if (this.last_hash_key == "t") {
    -                    this.media.setCurrentTime(1000*this.last_hash_value);
    +                    this.media.setCurrentTime(1000 * this.last_hash_value);
                     }
                     break;
                 }
    @@ -74,18 +83,21 @@
         }
     };
     
    -IriSP.Widgets.Mediafragment.prototype.setHashToAnnotation = function(_annotationId) {
    -    this.setHash( 'id', _annotationId );
    +IriSP.Widgets.Mediafragment.prototype.setHashToAnnotation = function(_annotation) {
    +    this.setHash( 'id', _annotation.id, 't', _annotation.begin / 1000.0 );
     };
     
     IriSP.Widgets.Mediafragment.prototype.setHashToTime = function() {
         this.setHash( 't', this.media.getCurrentTime().getSeconds() );
     };
     
    -IriSP.Widgets.Mediafragment.prototype.setHash = function(_key, _value) {
    +IriSP.Widgets.Mediafragment.prototype.setHash = function(_key, _value, _key2, _value2) {
         if (!this.blocked && (this.last_hash_key !== _key || this.last_hash_value !== _value)) {
             this.last_hash_key = _key;
             this.last_hash_value = _value;
    +        this.last_extra_key = _key2;
    +        this.last_extra_value = _value2;
    +
             var _hash = this.getLastHash();
             this.setWindowHash(_hash);
             if (window.parent !== window) {
    diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/metadataplayer/MultiSegments.js
    --- a/server/src/remie/static/remie/metadataplayer/MultiSegments.js	Mon Sep 28 14:32:54 2015 +0200
    +++ b/server/src/remie/static/remie/metadataplayer/MultiSegments.js	Fri Oct 02 10:24:23 2015 +0200
    @@ -80,7 +80,7 @@
                     IriSP._({
                         type: "Segments",
                         annotation_type: _anntype,
    -                    width: _this.width
    +                    width: '100%'
                     }).extend(segmentsopts)
                 );
                 
    @@ -89,7 +89,7 @@
                     IriSP._({
                         type: "Annotation",
                         annotation_type: _anntype,
    -                    width: _this.width
    +                    width: '100%'
                     }).extend(annotationopts)
                 );
                 
    diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/metadataplayer/NoteTaking.css
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/server/src/remie/static/remie/metadataplayer/NoteTaking.css	Fri Oct 02 10:24:23 2015 +0200
    @@ -0,0 +1,5 @@
    +/* NoteTaking widget */
    +.Ldt-NoteTaking-Text {
    +    width: 100%;
    +    min-height: 360px;
    +}
    diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/metadataplayer/NoteTaking.js
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/server/src/remie/static/remie/metadataplayer/NoteTaking.js	Fri Oct 02 10:24:23 2015 +0200
    @@ -0,0 +1,91 @@
    +/* This widget displays a note-taking view, that can be saved to localStorage */
    +
    +IriSP.Widgets.NoteTaking = function(player, config) {
    +    IriSP.Widgets.Widget.call(this, player, config);
    +}
    +
    +IriSP.Widgets.NoteTaking.prototype = new IriSP.Widgets.Widget();
    +
    +IriSP.Widgets.NoteTaking.prototype.defaults = {
    +    // Id that will be used as localStorage key
    +    editable_storage: ""
    +}
    +
    +IriSP.Widgets.NoteTaking.prototype.template = '';
    +
    +IriSP.Widgets.NoteTaking.prototype.draw = function() {
    +    var widget = this;
    +    var content;
    +    var $ = IriSP.jQuery;
    +
    +    widget.renderTemplate();
    +    content = widget.$.find('.Ldt-NoteTaking-Text');
    +
    +    function load_content() {
    +        $(content).val(window.localStorage[widget.editable_storage]);
    +    }
    +    function save_content() {
    +        window.localStorage[widget.editable_storage] = $(content).val();
    +    }
    +
    +    // Load current transcript
    +    if (window.localStorage[widget.editable_storage]) {
    +        load_content();
    +    }
    +
    +    // Thanks to http://stackoverflow.com/questions/4456545/how-to-insert-text-at-the-current-caret-position-in-a-textarea
    +    $.fn.insertAtCaret = function(text) {
    +        return this.each(function() {
    +            if (this.selectionStart !== undefined) {
    +                // mozilla/netscape support
    +                var startPos = this.selectionStart,
    +                    endPos = this.selectionEnd,
    +                    scrollTop = this.scrollTop;
    +                this.value = this.value.substring(0, startPos) + text + this.value.substring(endPos, this.value.length);
    +                this.focus();
    +                this.selectionStart = startPos + text.length;
    +                this.selectionEnd = startPos + text.length;
    +                this.scrollTop = scrollTop;
    +            } else {
    +                // IE input[type=text] and other browsers
    +                this.value += text;
    +                this.focus();
    +                this.value = this.value;    // forces cursor to end
    +            }
    +        });
    +    };
    +
    +    function getAroundCaret(el, length) {
    +        // Return a selection of 2 * length characters around the caret
    +        var startPos = el.selectionStart;
    +        return el.value.substring(startPos - length, startPos + length);
    +    };
    +
    +
    +    $(content).keydown(function (_event) {
    +        if (_event.keyCode == 13 && (_event.ctrlKey || _event.metaKey)) {
    +            // Insert current timestamp
    +            _event.preventDefault();
    +            // Get current value
    +            var match = /\[([\d:]+)\]/.exec(getAroundCaret(content[0], 8));
    +            if (match) {
    +                // Found a timecode. Go to position.
    +                widget.media.setCurrentTime(IriSP.timestamp2ms(match[1]));
    +            } else {
    +                $(content).insertAtCaret("[" + (new IriSP.Model.Time(widget.media.getCurrentTime())).toString() + "]");
    +                save_content();
    +            }
    +        }
    +    }).on("input", function (_event) {
    +        console.log("Change");
    +        // Store updated value
    +        save_content();
    +    }).on("dblclick", function (_event) {
    +            var match = /\[([\d:]+)\]/.exec(getAroundCaret(content[0], 8));
    +            if (match) {
    +                // Found a timecode. Go to position.
    +                _event.preventDefault();
    +                widget.media.setCurrentTime(IriSP.timestamp2ms(match[1]));
    +            };
    +    });
    +};
    diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/metadataplayer/Polemic.js
    --- a/server/src/remie/static/remie/metadataplayer/Polemic.js	Mon Sep 28 14:32:54 2015 +0200
    +++ b/server/src/remie/static/remie/metadataplayer/Polemic.js	Fri Oct 02 10:24:23 2015 +0200
    @@ -144,7 +144,8 @@
                     	image: _annotation.thumbnail,
                     	uri: (typeof _annotation.url !== "undefined" 
     		                ? _annotation.url
    -		                : (document.location.href.replace(/#.*$/,'') + '#id='  + _annotation.id))
    +		                : (document.location.href.replace(/#.*$/,'') + '#id='  + _annotation.id)),
    +                text: '[' + _annotation.begin.toString() + '] ' + _annotation.title
                     });
                 	// test if annotation has several colors.
                 	var colAr = [];
    diff -r 0e256f85464b -r 75e3a41722ad server/src/remie/static/remie/metadataplayer/PopcornPlayer.js
    --- a/server/src/remie/static/remie/metadataplayer/PopcornPlayer.js	Mon Sep 28 14:32:54 2015 +0200
    +++ b/server/src/remie/static/remie/metadataplayer/PopcornPlayer.js	Fri Oct 02 10:24:23 2015 +0200
    @@ -10,26 +10,19 @@
     };
     
     IriSP.Widgets.PopcornPlayer.prototype.draw = function() {
    -
    -    
         if (typeof this.video === "undefined") {
             this.video = this.media.video;
         }
    -    
    +
         if (this.url_transform) {
             this.video = this.url_transform(this.video);
         }
    -    
    +
         if (/^(https?:\/\/)?(www\.)?vimeo\.com/.test(this.video)) {
    -        
             /* VIMEO */
    -        
             var _popcorn = Popcorn.vimeo(this.container, this.video);
    -        
         } else if (/^(https?:\/\/)?(www\.)?youtube\.com/.test(this.video)) {
    -        
             /* YOUTUBE */
    -       
             var _urlparts = this.video.split(/[?&]/),
                 _params = {};
             for (var i = 1; i < _urlparts.length; i++) {
    @@ -42,13 +35,11 @@
                 _params.autoplay = 1;
             }
             _url = _urlparts[0] + '?' + IriSP.jQuery.param(_params);
    -        
    +
             var _popcorn = Popcorn.youtube(this.container, _url);
    -        
    +
         } else {
    -        
             /* DEFAULT HTML5 */
    -        
             var _tmpId = IriSP._.uniqueId("popcorn"),
                 _videoEl = IriSP.jQuery('