sbin/res/jsdoc/LdtPlayer-release.js
changeset 1072 ac1eacb3aa33
parent 1071 02c04d2c8fd8
child 1073 687133dc13cf
--- a/sbin/res/jsdoc/LdtPlayer-release.js	Sun Nov 12 22:07:33 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3541 +0,0 @@
-/* 
- * 	
- *	Copyright 2010 Institut de recherche et d'innovation 
- *	contributor(s) : Samuel Huron 
- *	 
- *	contact@iri.centrepompidou.fr
- *	http://www.iri.centrepompidou.fr 
- *	 
- *	This software is a computer program whose purpose is to show and add annotations on a video .
- *	This software is governed by the CeCILL-C license under French law and
- *	abiding by the rules of distribution of free software. You can  use, 
- *	modify and/ or redistribute the software under the terms of the CeCILL-C
- *	license as circulated by CEA, CNRS and INRIA at the following URL
- *	"http://www.cecill.info". 
- *	
- *	The fact that you are presently reading this means that you have had
- *	knowledge of the CeCILL-C license and that you accept its terms.
-*/
-/*! LAB.js (LABjs :: Loading And Blocking JavaScript)
-    v2.0.3 (c) Kyle Simpson
-    MIT License
-*/
-
-(function(global){
-	var _$LAB = global.$LAB,
-	
-		// constants for the valid keys of the options object
-		_UseLocalXHR = "UseLocalXHR",
-		_AlwaysPreserveOrder = "AlwaysPreserveOrder",
-		_AllowDuplicates = "AllowDuplicates",
-		_CacheBust = "CacheBust",
-		/*!START_DEBUG*/_Debug = "Debug",/*!END_DEBUG*/
-		_BasePath = "BasePath",
-		
-		// stateless variables used across all $LAB instances
-		root_page = /^[^?#]*\//.exec(location.href)[0],
-		root_domain = /^\w+\:\/\/\/?[^\/]+/.exec(root_page)[0],
-		append_to = document.head || document.getElementsByTagName("head"),
-		
-		// inferences... ick, but still necessary
-		opera_or_gecko = (global.opera && Object.prototype.toString.call(global.opera) == "[object Opera]") || ("MozAppearance" in document.documentElement.style),
-
-/*!START_DEBUG*/
-		// console.log() and console.error() wrappers
-		log_msg = function(){}, 
-		log_error = log_msg,
-/*!END_DEBUG*/
-		
-		// feature sniffs (yay!)
-		test_script_elem = document.createElement("script"),
-		explicit_preloading = typeof test_script_elem.preload == "boolean", // http://wiki.whatwg.org/wiki/Script_Execution_Control#Proposal_1_.28Nicholas_Zakas.29
-		real_preloading = explicit_preloading || (test_script_elem.readyState && test_script_elem.readyState == "uninitialized"), // will a script preload with `src` set before DOM append?
-		script_ordered_async = !real_preloading && test_script_elem.async === true, // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
-		
-		// XHR preloading (same-domain) and cache-preloading (remote-domain) are the fallbacks (for some browsers)
-		xhr_or_cache_preloading = !real_preloading && !script_ordered_async && !opera_or_gecko
-	;
-
-/*!START_DEBUG*/
-	// define console wrapper functions if applicable
-	if (global.console && global.console.log) {
-		if (!global.console.error) global.console.error = global.console.log;
-		log_msg = function(msg) { global.console.log(msg); };
-		log_error = function(msg,err) { global.console.error(msg,err); };
-	}
-/*!END_DEBUG*/
-
-	// test for function
-	function is_func(func) { return Object.prototype.toString.call(func) == "[object Function]"; }
-
-	// test for array
-	function is_array(arr) { return Object.prototype.toString.call(arr) == "[object Array]"; }
-
-	// make script URL absolute/canonical
-	function canonical_uri(src,base_path) {
-		var absolute_regex = /^\w+\:\/\//;
-		
-		// is `src` is protocol-relative (begins with // or ///), prepend protocol
-		if (/^\/\/\/?/.test(src)) {
-			src = location.protocol + src;
-		}
-		// is `src` page-relative? (not an absolute URL, and not a domain-relative path, beginning with /)
-		else if (!absolute_regex.test(src) && src.charAt(0) != "/") {
-			// prepend `base_path`, if any
-			src = (base_path || "") + src;
-		}
-		// make sure to return `src` as absolute
-		return absolute_regex.test(src) ? src : ((src.charAt(0) == "/" ? root_domain : root_page) + src);
-	}
-
-	// merge `source` into `target`
-	function merge_objs(source,target) {
-		for (var k in source) { if (source.hasOwnProperty(k)) {
-			target[k] = source[k]; // TODO: does this need to be recursive for our purposes?
-		}}
-		return target;
-	}
-
-	// does the chain group have any ready-to-execute scripts?
-	function check_chain_group_scripts_ready(chain_group) {
-		var any_scripts_ready = false;
-		for (var i=0; i<chain_group.scripts.length; i++) {
-			if (chain_group.scripts[i].ready && chain_group.scripts[i].exec_trigger) {
-				any_scripts_ready = true;
-				chain_group.scripts[i].exec_trigger();
-				chain_group.scripts[i].exec_trigger = null;
-			}
-		}
-		return any_scripts_ready;
-	}
-
-	// creates a script load listener
-	function create_script_load_listener(elem,registry_item,flag,onload) {
-		elem.onload = elem.onreadystatechange = function() {
-			if ((elem.readyState && elem.readyState != "complete" && elem.readyState != "loaded") || registry_item[flag]) return;
-			elem.onload = elem.onreadystatechange = null;
-			onload();
-		};
-	}
-
-	// script executed handler
-	function script_executed(registry_item) {
-		registry_item.ready = registry_item.finished = true;
-		for (var i=0; i<registry_item.finished_listeners.length; i++) {
-			registry_item.finished_listeners[i]();
-		}
-		registry_item.ready_listeners = [];
-		registry_item.finished_listeners = [];
-	}
-
-	// make the request for a scriptha
-	function request_script(chain_opts,script_obj,registry_item,onload,preload_this_script) {
-		// setTimeout() "yielding" prevents some weird race/crash conditions in older browsers
-		setTimeout(function(){
-			var script, src = script_obj.real_src, xhr;
-			
-			// don't proceed until `append_to` is ready to append to
-			if ("item" in append_to) { // check if `append_to` ref is still a live node list
-				if (!append_to[0]) { // `append_to` node not yet ready
-					// try again in a little bit -- note: will re-call the anonymous function in the outer setTimeout, not the parent `request_script()`
-					setTimeout(arguments.callee,25);
-					return;
-				}
-				// reassign from live node list ref to pure node ref -- avoids nasty IE bug where changes to DOM invalidate live node lists
-				append_to = append_to[0];
-			}
-			script = document.createElement("script");
-			if (script_obj.type) script.type = script_obj.type;
-			if (script_obj.charset) script.charset = script_obj.charset;
-			
-			// should preloading be used for this script?
-			if (preload_this_script) {
-				// real script preloading?
-				if (real_preloading) {
-					/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script preload: "+src);/*!END_DEBUG*/
-					registry_item.elem = script;
-					if (explicit_preloading) { // explicit preloading (aka, Zakas' proposal)
-						script.preload = true;
-						script.onpreload = onload;
-					}
-					else {
-						script.onreadystatechange = function(){
-							if (script.readyState == "loaded") onload();
-						};
-					}
-					script.src = src;
-					// NOTE: no append to DOM yet, appending will happen when ready to execute
-				}
-				// same-domain and XHR allowed? use XHR preloading
-				else if (preload_this_script && src.indexOf(root_domain) == 0 && chain_opts[_UseLocalXHR]) {
-					xhr = new XMLHttpRequest(); // note: IE never uses XHR (it supports true preloading), so no more need for ActiveXObject fallback for IE <= 7
-					/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script preload (xhr): "+src);/*!END_DEBUG*/
-					xhr.onreadystatechange = function() {
-						if (xhr.readyState == 4) {
-							xhr.onreadystatechange = function(){}; // fix a memory leak in IE
-							registry_item.text = xhr.responseText + "\n//@ sourceURL=" + src; // http://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/
-							onload();
-						}
-					};
-					xhr.open("GET",src);
-					xhr.send();
-				}
-				// as a last resort, use cache-preloading
-				else {
-					/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script preload (cache): "+src);/*!END_DEBUG*/
-					script.type = "text/cache-script";
-					create_script_load_listener(script,registry_item,"ready",function() {
-						append_to.removeChild(script);
-						onload();
-					});
-					script.src = src;
-					append_to.insertBefore(script,append_to.firstChild);
-				}
-			}
-			// use async=false for ordered async? parallel-load-serial-execute http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
-			else if (script_ordered_async) {
-				/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script load (ordered async): "+src);/*!END_DEBUG*/
-				script.async = false;
-				create_script_load_listener(script,registry_item,"finished",onload);
-				script.src = src;
-				append_to.insertBefore(script,append_to.firstChild);
-			}
-			// otherwise, just a normal script element
-			else {
-				/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script load: "+src);/*!END_DEBUG*/
-				create_script_load_listener(script,registry_item,"finished",onload);
-				script.src = src;
-				append_to.insertBefore(script,append_to.firstChild);
-			}
-		},0);
-	}
-		
-	// create a clean instance of $LAB
-	function create_sandbox() {
-		var global_defaults = {},
-			can_use_preloading = real_preloading || xhr_or_cache_preloading,
-			queue = [],
-			registry = {},
-			instanceAPI
-		;
-		
-		// global defaults
-		global_defaults[_UseLocalXHR] = true;
-		global_defaults[_AlwaysPreserveOrder] = false;
-		global_defaults[_AllowDuplicates] = false;
-		global_defaults[_CacheBust] = false;
-		/*!START_DEBUG*/global_defaults[_Debug] = false;/*!END_DEBUG*/
-		global_defaults[_BasePath] = "";
-
-		// execute a script that has been preloaded already
-		function execute_preloaded_script(chain_opts,script_obj,registry_item) {
-			var script;
-			
-			function preload_execute_finished() {
-				if (script != null) { // make sure this only ever fires once
-					script = null;
-					script_executed(registry_item);
-				}
-			}
-			
-			if (registry[script_obj.src].finished) return;
-			if (!chain_opts[_AllowDuplicates]) registry[script_obj.src].finished = true;
-			
-			script = registry_item.elem || document.createElement("script");
-			if (script_obj.type) script.type = script_obj.type;
-			if (script_obj.charset) script.charset = script_obj.charset;
-			create_script_load_listener(script,registry_item,"finished",preload_execute_finished);
-			
-			// script elem was real-preloaded
-			if (registry_item.elem) {
-				registry_item.elem = null;
-			}
-			// script was XHR preloaded
-			else if (registry_item.text) {
-				script.onload = script.onreadystatechange = null;	// script injection doesn't fire these events
-				script.text = registry_item.text;
-			}
-			// script was cache-preloaded
-			else {
-				script.src = script_obj.real_src;
-			}
-			append_to.insertBefore(script,append_to.firstChild);
-
-			// manually fire execution callback for injected scripts, since events don't fire
-			if (registry_item.text) {
-				preload_execute_finished();
-			}
-		}
-	
-		// process the script request setup
-		function do_script(chain_opts,script_obj,chain_group,preload_this_script) {
-			var registry_item,
-				registry_items,
-				ready_cb = function(){ script_obj.ready_cb(script_obj,function(){ execute_preloaded_script(chain_opts,script_obj,registry_item); }); },
-				finished_cb = function(){ script_obj.finished_cb(script_obj,chain_group); }
-			;
-			
-			script_obj.src = canonical_uri(script_obj.src,chain_opts[_BasePath]);
-			script_obj.real_src = script_obj.src + 
-				// append cache-bust param to URL?
-				(chain_opts[_CacheBust] ? ((/\?.*$/.test(script_obj.src) ? "&_" : "?_") + ~~(Math.random()*1E9) + "=") : "")
-			;
-			
-			if (!registry[script_obj.src]) registry[script_obj.src] = {items:[],finished:false};
-			registry_items = registry[script_obj.src].items;
-
-			// allowing duplicates, or is this the first recorded load of this script?
-			if (chain_opts[_AllowDuplicates] || registry_items.length == 0) {
-				registry_item = registry_items[registry_items.length] = {
-					ready:false,
-					finished:false,
-					ready_listeners:[ready_cb],
-					finished_listeners:[finished_cb]
-				};
-
-				request_script(chain_opts,script_obj,registry_item,
-					// which callback type to pass?
-					(
-					 	(preload_this_script) ? // depends on script-preloading
-						function(){
-							registry_item.ready = true;
-							for (var i=0; i<registry_item.ready_listeners.length; i++) {
-								registry_item.ready_listeners[i]();
-							}
-							registry_item.ready_listeners = [];
-						} :
-						function(){ script_executed(registry_item); }
-					),
-					// signal if script-preloading should be used or not
-					preload_this_script
-				);
-			}
-			else {
-				registry_item = registry_items[0];
-				if (registry_item.finished) {
-					finished_cb();
-				}
-				else {
-					registry_item.finished_listeners.push(finished_cb);
-				}
-			}
-		}
-
-		// creates a closure for each separate chain spawned from this $LAB instance, to keep state cleanly separated between chains
-		function create_chain() {
-			var chainedAPI,
-				chain_opts = merge_objs(global_defaults,{}),
-				chain = [],
-				exec_cursor = 0,
-				scripts_currently_loading = false,
-				group
-			;
-			
-			// called when a script has finished preloading
-			function chain_script_ready(script_obj,exec_trigger) {
-				/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("script preload finished: "+script_obj.real_src);/*!END_DEBUG*/
-				script_obj.ready = true;
-				script_obj.exec_trigger = exec_trigger;
-				advance_exec_cursor(); // will only check for 'ready' scripts to be executed
-			}
-
-			// called when a script has finished executing
-			function chain_script_executed(script_obj,chain_group) {
-				/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("script execution finished: "+script_obj.real_src);/*!END_DEBUG*/
-				script_obj.ready = script_obj.finished = true;
-				script_obj.exec_trigger = null;
-				// check if chain group is all finished
-				for (var i=0; i<chain_group.scripts.length; i++) {
-					if (!chain_group.scripts[i].finished) return;
-				}
-				// chain_group is all finished if we get this far
-				chain_group.finished = true;
-				advance_exec_cursor();
-			}
-
-			// main driver for executing each part of the chain
-			function advance_exec_cursor() {
-				while (exec_cursor < chain.length) {
-					if (is_func(chain[exec_cursor])) {
-						/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("$LAB.wait() executing: "+chain[exec_cursor]);/*!END_DEBUG*/
-						try { chain[exec_cursor++](); } catch (err) {
-							/*!START_DEBUG*/if (chain_opts[_Debug]) log_error("$LAB.wait() error caught: ",err);/*!END_DEBUG*/
-						}
-						continue;
-					}
-					else if (!chain[exec_cursor].finished) {
-						if (check_chain_group_scripts_ready(chain[exec_cursor])) continue;
-						break;
-					}
-					exec_cursor++;
-				}
-				// we've reached the end of the chain (so far)
-				if (exec_cursor == chain.length) {
-					scripts_currently_loading = false;
-					group = false;
-				}
-			}
-			
-			// setup next chain script group
-			function init_script_chain_group() {
-				if (!group || !group.scripts) {
-					chain.push(group = {scripts:[],finished:true});
-				}
-			}
-
-			// API for $LAB chains
-			chainedAPI = {
-				// start loading one or more scripts
-				script:function(){
-					for (var i=0; i<arguments.length; i++) {
-						(function(script_obj,script_list){
-							var splice_args;
-							
-							if (!is_array(script_obj)) {
-								script_list = [script_obj];
-							}
-							for (var j=0; j<script_list.length; j++) {
-								init_script_chain_group();
-								script_obj = script_list[j];
-								
-								if (is_func(script_obj)) script_obj = script_obj();
-								if (!script_obj) continue;
-								if (is_array(script_obj)) {
-									// set up an array of arguments to pass to splice()
-									splice_args = [].slice.call(script_obj); // first include the actual array elements we want to splice in
-									splice_args.unshift(j,1); // next, put the `index` and `howMany` parameters onto the beginning of the splice-arguments array
-									[].splice.apply(script_list,splice_args); // use the splice-arguments array as arguments for splice()
-									j--; // adjust `j` to account for the loop's subsequent `j++`, so that the next loop iteration uses the same `j` index value
-									continue;
-								}
-								if (typeof script_obj == "string") script_obj = {src:script_obj};
-								script_obj = merge_objs(script_obj,{
-									ready:false,
-									ready_cb:chain_script_ready,
-									finished:false,
-									finished_cb:chain_script_executed
-								});
-								group.finished = false;
-								group.scripts.push(script_obj);
-								
-								do_script(chain_opts,script_obj,group,(can_use_preloading && scripts_currently_loading));
-								scripts_currently_loading = true;
-								
-								if (chain_opts[_AlwaysPreserveOrder]) chainedAPI.wait();
-							}
-						})(arguments[i],arguments[i]);
-					}
-					return chainedAPI;
-				},
-				// force LABjs to pause in execution at this point in the chain, until the execution thus far finishes, before proceeding
-				wait:function(){
-					if (arguments.length > 0) {
-						for (var i=0; i<arguments.length; i++) {
-							chain.push(arguments[i]);
-						}
-						group = chain[chain.length-1];
-					}
-					else group = false;
-					
-					advance_exec_cursor();
-					
-					return chainedAPI;
-				}
-			};
-
-			// the first chain link API (includes `setOptions` only this first time)
-			return {
-				script:chainedAPI.script, 
-				wait:chainedAPI.wait, 
-				setOptions:function(opts){
-					merge_objs(opts,chain_opts);
-					return chainedAPI;
-				}
-			};
-		}
-
-		// API for each initial $LAB instance (before chaining starts)
-		instanceAPI = {
-			// main API functions
-			setGlobalDefaults:function(opts){
-				merge_objs(opts,global_defaults);
-				return instanceAPI;
-			},
-			setOptions:function(){
-				return create_chain().setOptions.apply(null,arguments);
-			},
-			script:function(){
-				return create_chain().script.apply(null,arguments);
-			},
-			wait:function(){
-				return create_chain().wait.apply(null,arguments);
-			},
-
-			// built-in queuing for $LAB `script()` and `wait()` calls
-			// useful for building up a chain programmatically across various script locations, and simulating
-			// execution of the chain
-			queueScript:function(){
-				queue[queue.length] = {type:"script", args:[].slice.call(arguments)};
-				return instanceAPI;
-			},
-			queueWait:function(){
-				queue[queue.length] = {type:"wait", args:[].slice.call(arguments)};
-				return instanceAPI;
-			},
-			runQueue:function(){
-				var $L = instanceAPI, len=queue.length, i=len, val;
-				for (;--i>=0;) {
-					val = queue.shift();
-					$L = $L[val.type].apply(null,val.args);
-				}
-				return $L;
-			},
-
-			// rollback `[global].$LAB` to what it was before this file was loaded, the return this current instance of $LAB
-			noConflict:function(){
-				global.$LAB = _$LAB;
-				return instanceAPI;
-			},
-
-			// create another clean instance of $LAB
-			sandbox:function(){
-				return create_sandbox();
-			}
-		};
-
-		return instanceAPI;
-	}
-
-	// create the main instance of $LAB
-	global.$LAB = create_sandbox();
-
-
-	/* The following "hack" was suggested by Andrea Giammarchi and adapted from: http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html
-	   NOTE: this hack only operates in FF and then only in versions where document.readyState is not present (FF < 3.6?).
-	   
-	   The hack essentially "patches" the **page** that LABjs is loaded onto so that it has a proper conforming document.readyState, so that if a script which does 
-	   proper and safe dom-ready detection is loaded onto a page, after dom-ready has passed, it will still be able to detect this state, by inspecting the now hacked 
-	   document.readyState property. The loaded script in question can then immediately trigger any queued code executions that were waiting for the DOM to be ready. 
-	   For instance, jQuery 1.4+ has been patched to take advantage of document.readyState, which is enabled by this hack. But 1.3.2 and before are **not** safe or 
-	   fixed by this hack, and should therefore **not** be lazy-loaded by script loader tools such as LABjs.
-	*/ 
-	(function(addEvent,domLoaded,handler){
-		if (document.readyState == null && document[addEvent]){
-			document.readyState = "loading";
-			document[addEvent](domLoaded,handler = function(){
-				document.removeEventListener(domLoaded,handler,false);
-				document.readyState = "complete";
-			},false);
-		}
-	})("addEventListener","DOMContentLoaded");
-
-})(this);/*
-  mustache.js — Logic-less templates in JavaScript
-
-  See http://mustache.github.com/ for more info.
-*/
-
-var Mustache = function() {
-  var Renderer = function() {};
-
-  Renderer.prototype = {
-    otag: "{{",
-    ctag: "}}",
-    pragmas: {},
-    buffer: [],
-    pragmas_implemented: {
-      "IMPLICIT-ITERATOR": true
-    },
-    context: {},
-
-    render: function(template, context, partials, in_recursion) {
-      // reset buffer & set context
-      if(!in_recursion) {
-        this.context = context;
-        this.buffer = []; // TODO: make this non-lazy
-      }
-
-      // fail fast
-      if(!this.includes("", template)) {
-        if(in_recursion) {
-          return template;
-        } else {
-          this.send(template);
-          return;
-        }
-      }
-
-      template = this.render_pragmas(template);
-      var html = this.render_section(template, context, partials);
-      if(in_recursion) {
-        return this.render_tags(html, context, partials, in_recursion);
-      }
-
-      this.render_tags(html, context, partials, in_recursion);
-    },
-
-    /*
-      Sends parsed lines
-    */
-    send: function(line) {
-      if(line !== "") {
-        this.buffer.push(line);
-      }
-    },
-
-    /*
-      Looks for %PRAGMAS
-    */
-    render_pragmas: function(template) {
-      // no pragmas
-      if(!this.includes("%", template)) {
-        return template;
-      }
-
-      var that = this;
-      var regex = new RegExp(this.otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" +
-            this.ctag, "g");
-      return template.replace(regex, function(match, pragma, options) {
-        if(!that.pragmas_implemented[pragma]) {
-          throw({message: 
-            "This implementation of mustache doesn't understand the '" +
-            pragma + "' pragma"});
-        }
-        that.pragmas[pragma] = {};
-        if(options) {
-          var opts = options.split("=");
-          that.pragmas[pragma][opts[0]] = opts[1];
-        }
-        return "";
-        // ignore unknown pragmas silently
-      });
-    },
-
-    /*
-      Tries to find a partial in the curent scope and render it
-    */
-    render_partial: function(name, context, partials) {
-      name = this.trim(name);
-      if(!partials || partials[name] === undefined) {
-        throw({message: "unknown_partial '" + name + "'"});
-      }
-      if(typeof(context[name]) != "object") {
-        return this.render(partials[name], context, partials, true);
-      }
-      return this.render(partials[name], context[name], partials, true);
-    },
-
-    /*
-      Renders inverted (^) and normal (#) sections
-    */
-    render_section: function(template, context, partials) {
-      if(!this.includes("#", template) && !this.includes("^", template)) {
-        return template;
-      }
-
-      var that = this;
-      // CSW - Added "+?" so it finds the tighest bound, not the widest
-      var regex = new RegExp(this.otag + "(\\^|\\#)\\s*(.+)\\s*" + this.ctag +
-              "\n*([\\s\\S]+?)" + this.otag + "\\/\\s*\\2\\s*" + this.ctag +
-              "\\s*", "mg");
-
-      // for each {{#foo}}{{/foo}} section do...
-      return template.replace(regex, function(match, type, name, content) {
-        var value = that.find(name, context);
-        if(type == "^") { // inverted section
-          if(!value || that.is_array(value) && value.length === 0) {
-            // false or empty list, render it
-            return that.render(content, context, partials, true);
-          } else {
-            return "";
-          }
-        } else if(type == "#") { // normal section
-          if(that.is_array(value)) { // Enumerable, Let's loop!
-            return that.map(value, function(row) {
-              return that.render(content, that.create_context(row),
-                partials, true);
-            }).join("");
-          } else if(that.is_object(value)) { // Object, Use it as subcontext!
-            return that.render(content, that.create_context(value),
-              partials, true);
-          } else if(typeof value === "function") {
-            // higher order section
-            return value.call(context, content, function(text) {
-              return that.render(text, context, partials, true);
-            });
-          } else if(value) { // boolean section
-            return that.render(content, context, partials, true);
-          } else {
-            return "";
-          }
-        }
-      });
-    },
-
-    /*
-      Replace {{foo}} and friends with values from our view
-    */
-    render_tags: function(template, context, partials, in_recursion) {
-      // tit for tat
-      var that = this;
-
-      var new_regex = function() {
-        return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?" +
-          that.ctag + "+", "g");
-      };
-
-      var regex = new_regex();
-      var tag_replace_callback = function(match, operator, name) {
-        switch(operator) {
-        case "!": // ignore comments
-          return "";
-        case "=": // set new delimiters, rebuild the replace regexp
-          that.set_delimiters(name);
-          regex = new_regex();
-          return "";
-        case ">": // render partial
-          return that.render_partial(name, context, partials);
-        case "{": // the triple mustache is unescaped
-          return that.find(name, context);
-        default: // escape the value
-          return that.escape(that.find(name, context));
-        }
-      };
-      var lines = template.split("\n");
-      for(var i = 0; i < lines.length; i++) {
-        lines[i] = lines[i].replace(regex, tag_replace_callback, this);
-        if(!in_recursion) {
-          this.send(lines[i]);
-        }
-      }
-
-      if(in_recursion) {
-        return lines.join("\n");
-      }
-    },
-
-    set_delimiters: function(delimiters) {
-      var dels = delimiters.split(" ");
-      this.otag = this.escape_regex(dels[0]);
-      this.ctag = this.escape_regex(dels[1]);
-    },
-
-    escape_regex: function(text) {
-      // thank you Simon Willison
-      if(!arguments.callee.sRE) {
-        var specials = [
-          '/', '.', '*', '+', '?', '|',
-          '(', ')', '[', ']', '{', '}', '\\'
-        ];
-        arguments.callee.sRE = new RegExp(
-          '(\\' + specials.join('|\\') + ')', 'g'
-        );
-      }
-      return text.replace(arguments.callee.sRE, '\\$1');
-    },
-
-    /*
-      find `name` in current `context`. That is find me a value
-      from the view object
-    */
-    find: function(name, context) {
-      name = this.trim(name);
-
-      // Checks whether a value is thruthy or false or 0
-      function is_kinda_truthy(bool) {
-        return bool === false || bool === 0 || bool;
-      }
-
-      var value;
-      if(is_kinda_truthy(context[name])) {
-        value = context[name];
-      } else if(is_kinda_truthy(this.context[name])) {
-        value = this.context[name];
-      }
-
-      if(typeof value === "function") {
-        return value.apply(context);
-      }
-      if(value !== undefined) {
-        return value;
-      }
-      // silently ignore unkown variables
-      return "";
-    },
-
-    // Utility methods
-
-    /* includes tag */
-    includes: function(needle, haystack) {
-      return haystack.indexOf(this.otag + needle) != -1;
-    },
-
-    /*
-      Does away with nasty characters
-    */
-    escape: function(s) {
-      s = String(s === null ? "" : s);
-      return s.replace(/&(?!\w+;)|["'<>\\]/g, function(s) {
-        switch(s) {
-        case "&": return "&amp;";
-        case "\\": return "\\\\";
-        case '"': return '&quot;';
-        case "'": return '&#39;';
-        case "<": return "&lt;";
-        case ">": return "&gt;";
-        default: return s;
-        }
-      });
-    },
-
-    // by @langalex, support for arrays of strings
-    create_context: function(_context) {
-      if(this.is_object(_context)) {
-        return _context;
-      } else {
-        var iterator = ".";
-        if(this.pragmas["IMPLICIT-ITERATOR"]) {
-          iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator;
-        }
-        var ctx = {};
-        ctx[iterator] = _context;
-        return ctx;
-      }
-    },
-
-    is_object: function(a) {
-      return a && typeof a == "object";
-    },
-
-    is_array: function(a) {
-      return Object.prototype.toString.call(a) === '[object Array]';
-    },
-
-    /*
-      Gets rid of leading and trailing whitespace
-    */
-    trim: function(s) {
-      return s.replace(/^\s*|\s*$/g, "");
-    },
-
-    /*
-      Why, why, why? Because IE. Cry, cry cry.
-    */
-    map: function(array, fn) {
-      if (typeof array.map == "function") {
-        return array.map(fn);
-      } else {
-        var r = [];
-        var l = array.length;
-        for(var i = 0; i < l; i++) {
-          r.push(fn(array[i]));
-        }
-        return r;
-      }
-    }
-  };
-
-  return({
-    name: "mustache.js",
-    version: "0.3.1-dev",
-
-    /*
-      Turns a template and view into HTML
-    */
-    to_html: function(template, view, partials, send_fun) {
-      var renderer = new Renderer();
-      if(send_fun) {
-        renderer.send = send_fun;
-      }
-      renderer.render(template, view, partials);
-      if(!send_fun) {
-        return renderer.buffer.join("\n");
-      }
-    }
-  });
-}();
-// Underscore.js 1.2.3
-// (c) 2009-2011 Jeremy Ashkenas, DocumentCloud Inc.
-// Underscore is freely distributable under the MIT license.
-// Portions of Underscore are inspired or borrowed from Prototype,
-// Oliver Steele's Functional, and John Resig's Micro-Templating.
-// For all details and documentation:
-// http://documentcloud.github.com/underscore
-(function(){function r(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
-c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&r(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(m.call(a,h)&&(f++,!(g=m.call(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(m.call(c,
-h)&&!f--)break;g=!f}}d.pop();return g}var s=this,F=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,G=k.concat,H=k.unshift,l=p.toString,m=p.hasOwnProperty,v=k.forEach,w=k.map,x=k.reduce,y=k.reduceRight,z=k.filter,A=k.every,B=k.some,q=k.indexOf,C=k.lastIndexOf,p=Array.isArray,I=Object.keys,t=Function.prototype.bind,b=function(a){return new n(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else typeof define==="function"&&
-define.amd?define("underscore",function(){return b}):s._=b;b.VERSION="1.2.3";var j=b.each=b.forEach=function(a,c,b){if(a!=null)if(v&&a.forEach===v)a.forEach(c,b);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(b,a[e],e,a)===o)break}else for(e in a)if(m.call(a,e)&&c.call(b,a[e],e,a)===o)break};b.map=function(a,c,b){var e=[];if(a==null)return e;if(w&&a.map===w)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});return e};b.reduce=b.foldl=b.inject=function(a,
-c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(x&&a.reduce===x)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(y&&a.reduceRight===y)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,
-c,d,e):b.reduce(g,c)};b.find=b.detect=function(a,c,b){var e;D(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(z&&a.filter===z)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(A&&a.every===A)return a.every(c,
-b);j(a,function(a,g,h){if(!(e=e&&c.call(b,a,g,h)))return o});return e};var D=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(B&&a.some===B)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return q&&a.indexOf===q?a.indexOf(c)!=-1:b=D(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(c.call?c||a:a[c]).apply(a,
-d)})};b.pluck=function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,
-computed:b})});return e.value};b.shuffle=function(a){var c=[],b;j(a,function(a,f){f==0?c[0]=a:(b=Math.floor(Math.random()*(f+1)),c[f]=c[b],c[b]=a)});return c};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,c){var b=a.criteria,d=c.criteria;return b<d?-1:b>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=
-function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-
-1]};b.rest=b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},
-[]);return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,
-c,d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(q&&a.indexOf===q)return a.indexOf(c);for(d=0,e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(C&&a.lastIndexOf===C)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};
-var E=function(){};b.bind=function(a,c){var d,e;if(a.bind===t&&t)return t.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));E.prototype=a.prototype;var b=new E,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,
-c){var d={};c||(c=b.identity);return function(){var b=c.apply(this,arguments);return m.call(d,b)?d[b]:d[b]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true:
-a.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=G.apply([a],arguments);return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=
-function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=I||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var b=[],d;for(d in a)m.call(a,d)&&(b[b.length]=d);return b};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)b[d]!==void 0&&(a[d]=b[d])});return a};b.defaults=function(a){j(i.call(arguments,
-1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(m.call(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===
-Object(a)};b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!m.call(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)==
-"[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.noConflict=function(){s._=F;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;")};b.mixin=function(a){j(b.functions(a),function(c){J(c,
-b[c]=a[c])})};var K=0;b.uniqueId=function(a){var b=K++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape,function(a,b){return"',_.escape("+b.replace(/\\'/g,"'")+"),'"}).replace(d.interpolate,function(a,b){return"',"+b.replace(/\\'/g,
-"'")+",'"}).replace(d.evaluate||null,function(a,b){return"');"+b.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};var n=function(a){this._wrapped=a};b.prototype=n.prototype;var u=function(a,c){return c?b(a).chain():a},J=function(a,c){n.prototype[a]=function(){var a=i.call(arguments);H.call(a,this._wrapped);return u(c.apply(b,
-a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];n.prototype[a]=function(){b.apply(this._wrapped,arguments);return u(this._wrapped,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];n.prototype[a]=function(){return u(b.apply(this._wrapped,arguments),this._chain)}});n.prototype.chain=function(){this._chain=true;return this};n.prototype.value=function(){return this._wrapped}}).call(this);
-/* main file */
-
-if ( window.IriSP === undefined && window.__IriSP === undefined ) { 
-	var IriSP = {}; 
-	var __IriSP = IriSP; /* for backward compatibility */
-}
-
-IriSP.loadLibs = function( libs, config, metadata_url, callback ) {
-    // Localize jQuery variable
-		IriSP.jQuery = null;
-    var $L = $LAB.script(libs.jQuery).script(libs.swfObject)
-                .script(libs.jQueryUI)
-                                   
-    if (config.player.type === "jwplayer") {
-      // load our popcorn.js lookalike
-      $L = $L.script(libs.jwplayer);
-    } else {
-      // load the real popcorn
-      $L = $L.script(libs.popcorn).script(libs["popcorn.code"]);
-      if (config.player.type === "youtube") {
-        $L = $L.script(libs["popcorn.youtube"]);
-      } 
-      if (config.player.type === "vimeo")
-        $L = $L.script(libs["popcorn.vimeo"]);
-      
-      /* do nothing for html5 */
-    }       
-    
-    /* widget specific requirements */
-    for (var idx in config.gui.widgets) {
-      if (config.gui.widgets[idx].type === "PolemicWidget") {        
-        $L.script(libs.raphael);
-      }
-    }
-    
-    // same for modules
-    /*
-    for (var idx in config.modules) {
-      if (config.modules[idx].type === "PolemicWidget")
-        $L.script(libs.raphaelJs);
-    }
-    */
-
-    $L.wait(function() {
-      IriSP.jQuery = window.jQuery.noConflict( true );
-      IriSP._ = window._.noConflict();
-      IriSP.underscore = IriSP._;
-      
-      var css_link_jquery = IriSP.jQuery( "<link>", { 
-        rel: "stylesheet", 
-        type: "text/css", 
-        href: libs.cssjQueryUI,
-        'class': "dynamic_css"
-      } );
-      var css_link_custom = IriSP.jQuery( "<link>", { 
-        rel: "stylesheet", 
-        type: "text/css", 
-        href: config.gui.css,
-        'class': "dynamic_css"
-      } );
-      
-      css_link_jquery.appendTo('head');
-      css_link_custom.appendTo('head');
-          
-      IriSP.setupDataLoader();
-      IriSP.__dataloader.get(metadata_url, 
-          function(data) {
-            /* save the data so that we could re-use it to
-               configure the video
-            */
-            IriSP.__jsonMetadata = data;
-            callback.call(window) });
-    });
-};
-IriSP.annotation_template = "{{! template for an annotation displayed in a segmentWidget }}<div title='{{divTitle}}' id='{{id}}'	class='Ldt-iri-chapter' 	style='left: {{startPixel}}px;          width: {{pxWidth}}px;          background-color:#{{hexa_color}};' 	></div>";
-IriSP.annotationWidget_template = "{{! template for the annotation widget }}<div class='Ldt-AnnotationsWidget'>  <!-- ugly div because we want to have a double border -->  <div class='Ldt-Annotation-DoubleBorder'>      <div class='Ldt-AnnotationContent'>        <div class='Ldt-AnnotationShareIcons'>         <a class='Ldt-fbShare' href=''><img src='{{img_dir}}/facebook.png' alt='share on facebook'></img></a>         <a class='Ldt-TwShare' href=''><img src='{{img_dir}}/twitter.png' alt='share on twitter'></img></a>         <a class='Ldt-GplusShare' href=''><img src='{{img_dir}}/google.png' alt='share on google+'></img></a>      </div>		  <div class='Ldt-SaTitle'></div>	  	<div class='Ldt-SaDescription'></div>    </div>  </div></div>";
-IriSP.annotation_loading_template = "{{! template shown while the annotation widget is loading }}<div id='Ldt-load-container'><div id='Ldt-loader'>&nbsp;</div> Chargement... </div>";
-IriSP.arrowWidget_template = "<div class='Ldt-arrowWidget'></div>";
-IriSP.overlay_marker_template = "{{! the template for the small bars which is z-indexed over our segment widget }}<div class='Ldt-SegmentPositionMarker' style='background-color: #F7268E;'></div>";
-IriSP.player_template = "{{! template for the radio player }}<div class='Ldt-controler demo'>	<div class='Ldt-LeftPlayerControls'>    <div class='Ldt-button Ldt-CtrlPlay'></div>		<div class='Ldt-button Ldt-CtrlAnnotate'></div>    <div class='Ldt-button Ldt-CtrlSearch'></div>	</div>		<div class='Ldt-RightPlayerControls'>    <div class='Ldt-Time'>      <div class='Ldt-ElapsedTime'></div>      <div class='Ldt-TimeSeparator'>/</div>      <div class='Ldt-TotalTime'></div>    </div>		<div class='Ldt-button Ldt-CtrlSound'></div>	</div></div>";
-IriSP.search_template = "{{! template for the search container }}<div class='LdtSearchContainer'	style='margin-left: {{margin_left}}; position: absolute; margin-top: -60px;'>	<div class='LdtSearch'		style='display: none; background-color: #EEE; width: 165px; boder: 1px; border-color: #CFCFCF; position: absolute; text-align: center;'>		<input class='LdtSearchInput'			style='margin-top: 2px; margin-bottom: 2px;' />	</div></div><div class='cleaner'></div>";
-IriSP.share_template = "{{! social network sharing template }}<a onclick='__IriSP.MyApiPlayer.share(\'delicious\');' title='partager avec delicious'><span class='share shareDelicious'>&nbsp;</span></a>		<a onclick='__IriSP.MyApiPlayer.share(\'facebook\');' title='partager avec facebook'> <span class='share shareFacebook'>&nbsp;</span></a><a onclick='__IriSP.MyApiPlayer.share(\'twitter\');' title='partager avec twitter'>  <span class='share shareTwitter'>&nbsp;</span></a><a onclick='__IriSP.MyApiPlayer.share(\'myspace\');' title='partager avec Myspace'>  <span class='share shareMySpace'>&nbsp;</span></a>";
-IriSP.sliderWidget_template = "{{! template for the slider widget - it's composed of two divs we one overlayed on top    of the other }}<div class='Ldt-sliderBackground'></div><div class='Ldt-sliderForeground'></div><div class='Ldt-sliderPositionMarker'></div>";
-IriSP.tooltip_template = "{{! template used by the jquery ui tooltip }}<div class='Ldt-tooltip'>  <div class='title'>{{title}}</div>  <div class='time'>{{begin}} : {{end}} </div>  <div class='description'>{{description}}</div></div>";
-IriSP.tooltipWidget_template = "{{! template for the tooltip widget }}<div class='tip'>	<div class='tipcolor' style='height:10px;width:10px'></div>	<div class='tiptext'></div>";
-IriSP.tweetWidget_template = "{{! template for the tweet widget }}<div class='Ldt-tweetWidget'>  <div class='Ldt-tweet-DoubleBorder'>      <img src='{{img_dir}}/minimize.png' class='Ldt-tweetWidgetKeepOpen' alt='dont minimize automatically'></img>      <img src='{{img_dir}}/minimize.png' class='Ldt-tweetWidgetMinimize' alt='minimize window'></img>      <div class='Ldt-tweetAvatar'></div>      <img src='{{img_dir}}/profile_arrow.png' class='Ldt-tweetAvatar-profileArrow'></img>      <div class='Ldt-tweetContents'></div>      <a href='' target='_blank' class='Ldt-Retweet'><div class='Ldt-RetweetIcon'></div> - Retweet </a>      <a href='' target='_blank' class='Ldt-TweetReply'><div class='Ldt-TweetReplyIcon'></div> - Reply</a>  </div></div>";/* wrapper that simulates popcorn.js because
-   popcorn is a bit unstable at the time */
-
-IriSP.PopcornReplacement = {
-  msgPump : {} /* used by jquery to receive and send messages */
-};
-
-IriSP.PopcornReplacement.media = { 
-  "paused": true,
-  "muted": false
-};
-
-IriSP.PopcornReplacement.listen = function(msg, callback) {
-//  IriSP.jQuery(IriSP.PopcornReplacement.msgPump).bind(msg, function(event, rest) { callback(rest); });
-  if (!IriSP.PopcornReplacement.msgPump.hasOwnProperty(msg))
-    IriSP.PopcornReplacement.msgPump[msg] = [];
-
-  IriSP.PopcornReplacement.msgPump[msg].push(callback);
-};
-
-IriSP.PopcornReplacement.trigger = function(msg, params) {
-//  IriSP.jQuery(IriSP.PopcornReplacement.msgPump).trigger(msg, params);
-  
-  if (!IriSP.PopcornReplacement.msgPump.hasOwnProperty(msg))
-    return;
-
-  var d = IriSP.PopcornReplacement.msgPump[msg];
-  for(var entry in d) {
-    d[entry].call(window, params);
-  }
-
-};
-
-IriSP.PopcornReplacement.guid = function(prefix) {
-  var str = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
-      var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
-      return v.toString(16);
-   });
-
-  return prefix + str;
-};
-
-IriSP.PopcornReplacement.__initApi = function() {
-  IriSP.PopcornReplacement.trigger("loadedmetadata"); // we've done more than loading metadata of course,
-                                                      // but popcorn doesn't need to know more.
-  IriSP.PopcornReplacement.media.muted = jwplayer(IriSP.PopcornReplacement._container).getMute();
-};
-
-IriSP.PopcornReplacement.jwplayer = function(container, options) {
-  IriSP.PopcornReplacement._container = container.slice(1); //eschew the '#'
-  options.events = {
-      onReady: IriSP.PopcornReplacement.__initApi,
-      onTime: IriSP.PopcornReplacement.__timeHandler,
-      onPlay: IriSP.PopcornReplacement.__playHandler,
-      onPause: IriSP.PopcornReplacement.__pauseHandler,
-      onSeek: IriSP.PopcornReplacement.__seekHandler 
-      }
-    
-  jwplayer(IriSP.PopcornReplacement._container).setup(options);
-  IriSP.PopcornReplacement.media.duration = options.duration;
-  return IriSP.PopcornReplacement;
-};
-
-IriSP.PopcornReplacement.currentTime = function(time) {
-  if (typeof(time) === "undefined") {
-      return jwplayer(IriSP.PopcornReplacement._container).getPosition();            
-  } else {
-     var currentTime = +time;
-     jwplayer( IriSP.PopcornReplacement._container ).seek( currentTime );
-     IriSP.PopcornReplacement.trigger("seeked");
-     return jwplayer(IriSP.PopcornReplacement._container).getPosition();            
-  }
-};
-
-IriSP.PopcornReplacement.play = function() {
-      IriSP.PopcornReplacement.media.paused = false;
-      IriSP.PopcornReplacement.trigger("play");
-//      IriSP.PopcornReplacement.trigger("playing");
-      jwplayer( IriSP.PopcornReplacement._container ).play();
-};
-    
-IriSP.PopcornReplacement.pause = function() {
-      if ( !IriSP.PopcornReplacement.media.paused ) {
-        IriSP.PopcornReplacement.media.paused = true;
-        IriSP.PopcornReplacement.trigger( "pause" );
-        jwplayer( IriSP.PopcornReplacement._container ).pause();
-      }
-};
-
-IriSP.PopcornReplacement.muted = function(val) {
-  if (typeof(val) !== "undefined") {
-
-    if (jwplayer(IriSP.PopcornReplacement._container).getMute() !== val) {
-      if (val) {
-        jwplayer(IriSP.PopcornReplacement._container).setMute(true);
-        IriSP.PopcornReplacement.media.muted = true;
-      } else {
-        jwplayer( IriSP.PopcornReplacement._container ).setMute(false);
-        IriSP.PopcornReplacement.media.muted = false;
-      }
-
-      IriSP.PopcornReplacement.trigger( "volumechange" );
-    }
-    
-    return jwplayer( IriSP.PopcornReplacement._container ).getMute();
-  } else {
-    return jwplayer( IriSP.PopcornReplacement._container ).getMute();
-  }
-};
-
-IriSP.PopcornReplacement.mute = IriSP.PopcornReplacement.muted;
-
-IriSP.PopcornReplacement.__codes = [];
-IriSP.PopcornReplacement.code = function(options) {
-  IriSP.PopcornReplacement.__codes.push(options);
-  return IriSP.PopcornReplacement;
-};
-
-IriSP.PopcornReplacement.__runCode = function() {
-  var currentTime = jwplayer(IriSP.PopcornReplacement._container).getPosition();
-  var i = 0;
-  for(i = 0; i < IriSP.PopcornReplacement.__codes.length; i++) {
-    var c = IriSP.PopcornReplacement.__codes[i];
-    if (currentTime == c.start) {
-      c.onStart();
-    }
-    
-    if (currentTime == c.end) {
-      c.onEnd();
-    }
-
-  }
-};
-
-/* called everytime the player updates itself 
-   (onTime event)
- */
-
-IriSP.PopcornReplacement.__timeHandler = function(event) {
-  var pos = event.position;
-
-  var i = 0;
-  for(i = 0; i < IriSP.PopcornReplacement.__codes.length; i++) {
-     var c = IriSP.PopcornReplacement.__codes[i];
-     
-     if (pos >= c.start && pos < c.end && 
-         pos - 0.1 <= c.start) {       
-        c.onStart();
-     }
- 
-     if (pos > c.start && pos > c.end && 
-         pos - 0.1 <= c.end) {
-         console.log("eonedn");
-        c.onEnd();
-     }
-   
-  }
- 
-  IriSP.PopcornReplacement.trigger("timeupdate");
-};
-
-IriSP.PopcornReplacement.__seekHandler = function(event) {
-  var i = 0;
-  
-  for(i = 0; i < IriSP.PopcornReplacement.__codes.length; i++) {
-     var c = IriSP.PopcornReplacement.__codes[i];
-    
-     if (event.position >= c.start && event.position < c.end) {        
-        c.onEnd();
-     }         
-   }
-
-   for(i = 0; i < IriSP.PopcornReplacement.__codes.length; i++) {
-     var c = IriSP.PopcornReplacement.__codes[i];
-
-     if (typeof(event.offset) === "undefined")
-       event.offset = 0;
-           
-     if (event.offset >= c.start && event.offset < c.end) { 
-       c.onStart();
-     }
-     
-   }
-
-  IriSP.PopcornReplacement.trigger("timeupdate");
-};
-
-
-IriSP.PopcornReplacement.__playHandler = function(event) {
-  IriSP.PopcornReplacement.media.paused = false;
-  IriSP.PopcornReplacement.trigger("play");
-};
-
-IriSP.PopcornReplacement.__pauseHandler = function(event) {
-  IriSP.PopcornReplacement.media.paused = true;
-  IriSP.PopcornReplacement.trigger("pause");
-};
-
-IriSP.PopcornReplacement.roundTime = function() {
-  var currentTime = IriSP.PopcornReplacement.currentTime();
-  return Math.round(currentTime);
-};
-/* utils.js - various utils that don't belong anywhere else */
-
-/* trace function, for debugging */
-
-IriSP.traceNum = 0;
-IriSP.trace = function( msg, value ) {
-/*
-	if( IriSP.config.gui.debug === true ) {
-		IriSP.traceNum += 1;
-		IriSP.jQuery( "<div>"+IriSP.traceNum+" - "+msg+" : "+value+"</div>" ).appendTo( "#Ldt-output" );
-	}
-*/
-};
-
-/* used in callbacks - because in callbacks we lose "this",
-   we need to have a special function which wraps "this" in 
-   a closure. This way, the 
-*/   
-IriSP.wrap = function (obj, fn) {
-  return function() {    
-    var args = Array.prototype.slice.call(arguments, 0);
-    return fn.apply(obj, args);
-  }
-}
-
-/* convert a time to a percentage in the media */
-IriSP.timeToPourcent = function(time, timetotal){
-	var time = Math.abs(time);
-  var timetotal = Math.abs(timetotal);
-  
-	return Math.floor((time/timetotal) * 100);
-};
-
-IriSP.padWithZeros = function(num) {
-  if (Math.abs(num) < 10) {
-    return "0" + num.toString();
-  } else {
-    return num.toString();
-  }
-};
-/* convert a number of seconds to a tuple of the form 
-   [hours, minutes, seconds]
-*/
-IriSP.secondsToTime = function(secs) {  
-  var hours = Math.abs(parseInt( secs / 3600 ) % 24);
-  var minutes = Math.abs(parseInt( secs / 60 ) % 60);
-  var seconds = parseFloat(Math.abs(secs % 60).toFixed(0));
-  
-  var toString_fn = function() {
-    var ret = "";
-    if (hours > 0)
-       ret = IriSP.padWithZeros(this.hours) + ":";
-    ret += IriSP.padWithZeros(this.minutes) + ":" + IriSP.padWithZeros(this.seconds);
-
-    return ret;
-  }
-  return {"hours" : hours, "minutes" : minutes, "seconds" : seconds, toString: toString_fn};
-};
-
-IriSP.secondsToString
-
-/* format a tweet - replaces @name by a link to the profile, #hashtag, etc. */
-IriSP.formatTweet = function(tweet) {
-  /*
-    an array of arrays which hold a regexp and its replacement.
-  */
-  var regExps = [
-    /* copied from http://codegolf.stackexchange.com/questions/464/shortest-url-regex-match-in-javascript/480#480 */
-    [/((https?:\/\/)?[\w-]+(\.[\w-]+)+\.?(:\d+)?(\/\S*)?)/gi, "<a href='$1'>$1</a>"],
-    [/@(\w+)/gi, "<a href='http://twitter.com/$1'>@$1</a>"], // matches a @handle
-    [/#(\w+)/gi, "<a href='http://twitter.com/search?q=%23$1'>#$1</a>"],// matches a hashtag
-    [/(\+\+)/gi, "<span class='Ldt-PolemicPlusPlus'>$1</span>"],
-    [/(--)/gi, "<span class='Ldt-PolemicMinusMinus'>$1</span>"],
-    [/(==)/gi, "<span class='Ldt-PolemicEqualEqual'>$1</span>"],
-    [/(\?\?)/gi, "<span class='Ldt-PolemicQuestion'>$1</span>"]
-  ]; 
-
-  var i = 0;
-  for(i = 0; i < regExps.length; i++) {
-     tweet = tweet.replace(regExps[i][0], regExps[i][1]);
-  }
-  
-  return tweet;
-};
-
-IriSP.countProperties = function(obj) {
-    var count = 0;
-
-    for(var prop in obj) {
-        if(obj.hasOwnProperty(prop))
-                ++count;
-    }
-
-    return count;
-};
-
-// conversion de couleur Decimal vers HexaDecimal || 000 si fff
-IriSP.DEC_HEXA_COLOR = function (dec) {
-	 var hexa='0123456789ABCDEF';
-   var hex='';
-	 var tmp;
-	 while (dec>15){
-		  tmp = dec-(Math.floor(dec/16))*16;
-		  hex = hexa.charAt(tmp)+hex;
-		  dec = Math.floor(dec/16);
-	 }
-	 hex = hexa.charAt(dec)+hex;	 
-	 return(hex);
-};
-
-/* shortcut to have global variables in templates */
-IriSP.templToHTML = function(template, values) {
-  var params = IriSP.jQuery.extend(IriSP.default_templates_vars, values);
-  return Mustache.to_html(template, params);
-};
-
-/* we need to be stricter than encodeURIComponent,
-   because of twitter
-*/  
-IriSP.encodeURI = function(str) {
-  return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').  
-                                 replace(/\)/g, '%29').replace(/\*/g, '%2A');  
-}  
-
-IriSP.__guidCounter = 0;
-IriSP.guid = function(prefix) {
-  IriSP.__guidCounter += 1;
-  return prefix + IriSP.__guidCounter;
-};
-/* for ie compatibility
-if (Object.prototype.__defineGetter__&&!Object.defineProperty) {
-   Object.defineProperty=function(obj,prop,desc) {
-      if ("get" in desc) obj.__defineGetter__(prop,desc.get);
-      if ("set" in desc) obj.__defineSetter__(prop,desc.set);
-   }
-}
-*/
-/* data.js - this file deals with how the players gets and sends data */
-
-IriSP.DataLoader = function() {
-  this._cache = {};
-  
-  /*
-    A structure to hold callbacks for specific urls. We need it because
-    ajax calls are asynchronous, so it means that sometimes we ask
-    multiple times for a ressource because the first call hasn't been
-    received yet.
-  */
-  this._callbacks = {};
-};
-
-IriSP.DataLoader.prototype.get = function(url, callback) {
-
-  var base_url = url.split("&")[0]
-  if (this._cache.hasOwnProperty(base_url)) {
-    callback(this._cache[base_url]);
-  } else {  
-    if (!this._callbacks.hasOwnProperty(base_url)) {
-      this._callbacks[base_url] = [];
-      this._callbacks[base_url].push(callback);   
-      /* we need a closure because this gets lost when it's called back */
-  
-      // uncomment you don't want to use caching.
-      // IriSP.jQuery.get(url, callback);
-      
-      var func = function(data) {
-                  this._cache[base_url] = data;                                
-                  var i = 0;
-                  
-                  for (i = 0; i < this._callbacks[base_url].length; i++) {
-                    this._callbacks[base_url][i](this._cache[base_url]);                                  
-                  }
-      };
-      
-      /* automagically choose between json and jsonp */
-      if (url.indexOf(document.location.hostname) === -1 &&
-          url.indexOf("http://") !== -1 /* not a relative url */ ) {
-        // we contacting a foreign domain, use JSONP
-
-        IriSP.jQuery.get(url, {}, IriSP.wrap(this, func), "jsonp");
-      } else {
-
-        // otherwise, hey, whatever rows your boat
-        IriSP.jQuery.get(url, IriSP.wrap(this, func));
-      }
-    
-    } else {
-      /* simply push the callback - it'll get called when the ressource
-         has been received */
-      
-      this._callbacks[base_url].push(callback);   
-   
-    }
-  }
-}
-
-/* the base abstract "class" */
-IriSP.Serializer = function(DataLoader, url) {
-  this._DataLoader = DataLoader;
-  this._url = url;
-  this._data = [];
-};
-
-IriSP.Serializer.prototype.serialize = function(data) { };
-IriSP.Serializer.prototype.deserialize = function(data) {};
-
-IriSP.Serializer.prototype.currentMedia = function() {  
-};
-
-IriSP.Serializer.prototype.sync = function(callback) {  
-  callback.call(this, this._data);  
-};
-
-IriSP.SerializerFactory = function(DataLoader) {
-  this._dataloader = DataLoader;
-};
-
-IriSP.SerializerFactory.prototype.getSerializer = function(metadataOptions) {
-  /* This function returns serializer set-up with the correct
-     configuration - takes a metadata struct describing the metadata source
-  */
-  
-  if (metadataOptions === undefined)
-    /* return an empty serializer */
-    return IriSP.Serializer("", "");
-            
-  switch(metadataOptions.type) {
-    case "json":
-      return new IriSP.JSONSerializer(this._dataloader, metadataOptions.src);
-      break;
-    
-    case "dummy": /* only used for unit testing - not defined in production */
-      return new IriSP.MockSerializer(this._dataloader, metadataOptions.src);
-      break;
-    
-    case "empty":
-      return new IriSP.Serializer("", "empty");
-      break;
-      
-    default:      
-      return undefined;
-  }
-};
-/* site.js - all our site-dependent config : player chrome, cdn locations, etc...*/
-
-IriSP.lib = { 
-		jQuery : "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js",
-		jQueryUI : "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/jquery-ui.js",
-		jQueryToolTip : "http://cdn.jquerytools.org/1.2.4/all/jquery.tools.min.js",
-		swfObject : "http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js",
-		cssjQueryUI : "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/themes/base/jquery-ui.css",
-    popcorn : "/mdp/src/js/libs/popcorn.js",
-    jwplayer : "/mdp/src/js/libs/jwplayer.js",
-    popcornReplacement: "/mdp/src/js/libs/pop.js",
-    raphael: "/mdp/src/js/libs/raphael.js",
-    "popcorn.mediafragment" : "/mdp/src/js/libs/popcorn.mediafragment.js",
-    "popcorn.code" : "/mdp/src/js/libs/popcorn.code.js",
-    "popcorn.jwplayer": "/mdp/src/js/libs/popcorn.jwplayer.js",
-    "popcorn.youtube": "/mdp/src/js/libs/popcorn.youtube.js"
-};
-
-//Player Configuration 
-IriSP.config = undefined;
-
-IriSP.widgetsDefaults = {
-  "LayoutManager" : {spacer_div_height : "0px" },
-  "PlayerWidget" : {},
-  "AnnotationsWidget": {
-    "share_text" : "I'm watching ",     
-    "fb_link" : "http://www.facebook.com/share.php?u=",
-    "tw_link" : "http://twitter.com/home?status=",
-    "gplus_link" : ""
-    },
-  "TweetsWidget" : {
-      default_profile_picture : "https://si0.twimg.com/sticky/default_profile_images/default_profile_1_normal.png",
-      tweet_display_period: 10000 // how long do we show a tweet ?
-  },
-  "SliderWidget" : {
-      minimize_period: 850 // how long does the slider stays maximized after the user leaves the zone ?
-  },
-  "Main" : {
-      autoplay: true
-  }
-  
-};
-
-IriSP.paths = {
-//  "imgs": "/tweetlive/res/metadataplayer/src/css/imgs"
-  "imgs": "/mdp/src/css/imgs"
-};
-IriSP.default_templates_vars = {
-  "img_dir" : IriSP.paths.imgs 
-};
-
-/* ui.js - ui related functions */
-
-/* FIXME: use an sharing library */
-IriSP.LdtShareTool = IriSP.share_template; /* the contents come from share.html */
-
-IriSP.createPlayerChrome = function(){
-	var width = IriSP.config.gui.width;
-	var height = IriSP.config.gui.height;
-	var heightS = IriSP.config.gui.height-20;
-	
-	// AUDIO  */
-	// PB dans le html : ; 
-	IriSP.trace( "__IriSP.createMyHtml",IriSP.config.gui.container );
-
-	
-	/* FIXME : factor this in another file */
-	if( IriSP.config.gui.mode=="radio" ){
-
-		IriSP.jQuery( "#"+IriSP.config.gui.container ).before(IriSP.search_template);
-		var radioPlayer = Mustache.to_html(IriSP.radio_template, {"share_template" : IriSP.share_template});
-		IriSP.jQuery(radioPlayer).appendTo("#"+IriSP.config.gui.container);
-
-		// special tricks for IE 7
-		if (IriSP.jQuery.browser.msie==true && IriSP.jQuery.browser.version=="7.0"){
-			//LdtSearchContainer
-			//__IriSP.jQuery("#LdtPlayer").attr("margin-top","50px");
-			IriSP.jQuery("#Ldt-Root").css("padding-top","25px");
-			IriSP.trace("__IriSP.createHtml","IE7 SPECIAL ");
-		}
-	} else if(IriSP.config.gui.mode=="video") {
-	
-		var videoPlayer = Mustache.to_html(IriSP.video_template, {"share_template" : IriSP.share_template, "heightS" : heightS});
-		IriSP.jQuery(videoPlayer).appendTo("#"+IriSP.config.gui.container);
-	}
-	
-	IriSP.jQuery("#Ldt-Annotations").width(width-(75*2));
-	IriSP.jQuery("#Ldt-Show-Arrow-container").width(width-(75*2));
-	IriSP.jQuery("#Ldt-ShowAnnotation-audio").width(width-10);
-	IriSP.jQuery("#Ldt-ShowAnnotation-video").width(width-10);
-	IriSP.jQuery("#Ldt-SaKeyword").width(width-10);
-	IriSP.jQuery("#Ldt-controler").width(width-10);
-	IriSP.jQuery("#Ldt-Control").attr("z-index","100");
-	IriSP.jQuery("#Ldt-controler").hide();
-	
-	IriSP.jQuery(IriSP.annotation_loading_template).appendTo("#Ldt-ShowAnnotation-audio");
-
-	if(IriSP.config.gui.mode=='radio'){
-		IriSP.jQuery("#Ldt-load-container").attr("width",IriSP.config.gui.width);
-	}
-	// Show or not the output
-	if(IriSP.config.gui.debug===true){
-		IriSP.jQuery("#Ldt-output").show();
-	} else {
-		IriSP.jQuery("#Ldt-output").hide();
-	}
-	
-};
-
-
-/* create the buttons and the slider   */
-IriSP.createInterface = function( width, height, duration ) {
-		
-		IriSP.jQuery( "#Ldt-controler" ).show();
-		//__IriSP.jQuery("#Ldt-Root").css('display','visible');
-		IriSP.trace( "__IriSP.createInterface" , width+","+height+","+duration+"," );
-		
-		IriSP.jQuery( "#Ldt-ShowAnnotation").click( function () { 
-			 //__IriSP.jQuery(this).slideUp(); 
-		} );
-
-		var LdtpPlayerY = IriSP.jQuery("#Ldt-PlaceHolder").attr("top");
-		var LdtpPlayerX = IriSP.jQuery("#Ldt-PlaceHolder").attr("left");
-		
-		IriSP.jQuery( "#slider-range-min" ).slider( { //range: "min",
-			value: 0,
-			min: 1,
-			max: duration/1000,//1:54:52.66 = 3600+3240+
-			step: 0.1,
-			slide: function(event, ui) {
-				
-				//__IriSP.jQuery("#amount").val(ui.value+" s");
-				//player.sendEvent('SEEK', ui.value)
-				IriSP.MyApiPlayer.seek(ui.value);
-				//changePageUrlOffset(ui.value);
-				//player.sendEvent('PAUSE')
-			}
-		} );
-		
-		IriSP.trace("__IriSP.createInterface","ICI");
-		IriSP.jQuery("#amount").val(IriSP.jQuery("#slider-range-min").slider("value")+" s");
-		IriSP.jQuery(".Ldt-Control1 button:first").button({
-			icons: {
-				primary: 'ui-icon-play'
-			},
-			text: false
-		}).next().button({
-			icons: {
-				primary: 'ui-icon-seek-next'
-			},
-			 text: false
-		});
-		IriSP.jQuery(".Ldt-Control2 button:first").button({
-			icons: {
-				primary: 'ui-icon-search'//,
-				//secondary: 'ui-icon-volume-off'
-			},
-			text: false
-		}).next().button({
-			icons: {
-				primary: 'ui-icon-volume-on'
-			},
-			 text: false
-		});
-
-		// /!\ PB A MODIFIER 
-		//__IriSP.MyTags.draw();
-		IriSP.trace("__IriSP.createInterface","ICI2");
-		IriSP.jQuery( "#ldt-CtrlPlay" ).attr( "style", "background-color:#CD21C24;" );
-		
-		IriSP.jQuery( "#Ldt-load-container" ).hide();
-		
-		if( IriSP.config.gui.mode=="radio" & IriSP.jQuery.browser.msie != true ) {
-			IriSP.jQuery( "#Ldtplayer1" ).attr( "height", "0" );
-		}
-		IriSP.trace( "__IriSP.createInterface" , "3" );
-
-		IriSP.trace( "__IriSP.createInterface", "END" );
-		
-	};
-/* the widget classes and definitions */
-
-IriSP.Widget = function(Popcorn, config, Serializer) {
-
-  if (config === undefined || config === null) {
-    config = {}
-  }
-  
-  this._Popcorn = Popcorn;
-  this._config = config;  
-  this._serializer = Serializer;
-  
-  if (config.hasOwnProperty("container")) {
-     this._id = config.container;
-     this.selector = IriSP.jQuery("#" + this._id);
-  }
-
-  if (config.hasOwnProperty("spacer")) {
-     this._spacerId = config.spacer;
-     this.spacer = IriSP.jQuery("#" + this._spacerId);
-  }
-
-
-  if (config.hasOwnProperty("width")) {
-     // this.width and not this._width because we consider it public.
-     this.width = config.width;     
-  }
-  
-  if (config.hasOwnProperty("height")) {    
-     this.height = config.height;     
-  }
-  
-  if (config.hasOwnProperty("heightmax")) {
-     this.heightmax = config.heightmax;     
-  }
-
-  if (config.hasOwnProperty("widthmax")) {
-     this.widthmax = config.widthmax;     
-  }
-  
-};
-
-IriSP.Widget.prototype.draw = function() {
-  /* implemented by "sub-classes" */  
-};
-
-IriSP.Widget.prototype.redraw = function() {
-  /* implemented by "sub-classes" */  
-};
-/* modules are non-graphical entities, similar to widgets */
-
-IriSP.Module = function(Popcorn, config, Serializer) {
-
-  if (config === undefined || config === null) {
-    config = {}
-  }
-  
-  this._Popcorn = Popcorn;
-  this._config = config;  
-  this._serializer = Serializer;
-};
-/* layout.js - very basic layout management */
-
-/*
-  a layout manager manages a div and the layout of objects
-  inside it.
-*/
-
-IriSP.LayoutManager = function(options) {
-    this._Popcorn = null;
-    this._widgets = [];
-    
-    this._div = "LdtPlayer";
-    this._width = 640;
-    
-    if (options === undefined) {
-      options = {};
-    };
-    
-    if (options.hasOwnProperty('container')) {
-      this._div = options.container;
-    }
-
-    if (options.hasOwnProperty('width')) {
-      this._width = options.width;
-    }    
-    
-    if (options.hasOwnProperty('height')) {
-      this._height = options.height;
-    } 
-    
-    /* this is a shortcut */
-    this.selector = IriSP.jQuery("#" + this._div);
-    
-    this.selector.css("width", this._width);
-    
-    if (this._height !== undefined)
-      this.selector.css("height", this._height);
-};
-
-/* we need this special setter because of a chicken and egg problem :
-   we want the manager to use popcorn but the popcorn div will be managed
-   by the manager. So we need a way to set the instance the manager uses
-*/
-   
-IriSP.LayoutManager.prototype.setPopcornInstance = function(popcorn) {
-    this._Popcorn = popcorn;
-}
-
-/* stem is a string to append to the id of the widget */
-IriSP.LayoutManager.prototype.createDiv = function(stem) {
-    if (typeof(stem) === "undefined")
-       stem = "";
-
-    var newDiv = IriSP.guid(this._div + "_widget_" + stem + "_");
-    var spacerDiv = IriSP.guid("LdtPlayer_spacer_");
-    this._widgets.push(newDiv);
-
-    var divTempl = "<div id='{{id}}' style='width: {{width}}px; position: relative;'></div";
-    var spacerTempl = "<div id='{{spacer_id}}' style='width: {{width}}px; position: relative; height: {{spacer_div_height}};'></div";
-    
-    var divCode = Mustache.to_html(divTempl, {id: newDiv, width: this._width});
-    var spacerCode = Mustache.to_html(spacerTempl, {spacer_id: spacerDiv, width: this._width,
-                                                    spacer_div_height: IriSP.widgetsDefaults.LayoutManager.spacer_div_height });
-
-    this.selector.append(divCode);
-    this.selector.append(spacerCode);
-
-    return [newDiv, spacerDiv];
-};
-/* init.js - initialization and configuration of Popcorn and the widgets
-exemple json configuration:
- 
- */
-
-IriSP.setupDataLoader = function() {
-  /* we set it up separately because we need to
-     get data at the very beginning, for instance when
-     setting up the video */
-  IriSP.__dataloader = new IriSP.DataLoader();
-};
-
-IriSP.configurePopcorn = function (layoutManager, options) {
-    var pop;
-    var ret = layoutManager.createDiv(); 
-    var containerDiv = ret[0];
-    
-    switch(options.type) {
-      /*
-        todo : dynamically create the div/video tag which
-        will contain the video.
-      */
-      case "html5":
-           var tmpId = Popcorn.guid("video"); 
-           IriSP.jQuery("#" + containerDiv).append("<video src='" + options.file + "' id='" + tmpId + "'></video>");
-
-           if (options.hasOwnProperty("width"))
-             IriSP.jQuery("#" + containerDiv).css("width", options.width);
-           
-           if (options.hasOwnProperty("height"))
-             IriSP.jQuery("#" + containerDiv).css("height", options.height);
-
-           pop = Popcorn("#" + tmpId);
-        break;
-        
-      case "jwplayer":
-          var opts = IriSP.jQuery.extend({}, options);
-          delete opts.container;
-
-          if (options.provider === "rtmp") {
-            /* exit if we can't access the metadata */
-            if (typeof(IriSP.__jsonMetadata) === "undefined") {
-                break;
-            };
-
-
-            // the json format is totally illogical
-            opts.streamer = IriSP.__jsonMetadata["medias"][0]["meta"]["item"]["value"];
-            var source = IriSP.__jsonMetadata["medias"][0]["href"];
-
-            // the source if a full url but jwplayer wants an url relative to the
-            // streamer url, so we've got to remove the common part.
-            opts.file = source.slice(opts.streamer.length);
-          } else {
-            /* other providers type, video for instance -
-               pass everything as is */
-          }
-
-          pop = IriSP.PopcornReplacement.jwplayer("#" + containerDiv, opts);
-        break;
-      
-      case "youtube":
-          var opts = IriSP.jQuery.extend({}, options);
-          delete opts.container;
-          opts.controls = 0;
-          opts.autostart = false;
-          templ = "width: {{width}}px; height: {{height}}px;";
-          var str = Mustache.to_html(templ, {width: opts.width, height: opts.height});    
-          // Popcorn.youtube wants us to specify the size of the player in the style attribute of its container div.
-          IriSP.jQuery("#" + containerDiv).attr("style", str);
-          
-          pop = Popcorn.youtube("#" + containerDiv, opts.video, opts);
-        break;
-        
-      default:
-        pop = undefined;
-    };
-    
-    return pop;
-};
-
-IriSP.configureWidgets = function (popcornInstance, layoutManager, guiOptions) {
- 
-  var serialFactory = new IriSP.SerializerFactory(IriSP.__dataloader);
-  var params = {width: guiOptions.width, height: guiOptions.height};
-
-  var ret_widgets = [];
-  var index;
-  
-  for (index = 0; index < guiOptions.widgets.length; index++) {    
-    var widgetConfig = guiOptions.widgets[index];
-    var widget = IriSP.instantiateWidget(popcornInstance, serialFactory, layoutManager, widgetConfig);
-    ret_widgets.push(widget);
-   
-  };
-
-  return ret_widgets;
-};
-
-IriSP.configureModules = function (popcornInstance, modulesList) {
- 
-  var serialFactory = new IriSP.SerializerFactory(IriSP.__dataloader);
-  var ret_modules = [];
-  var index;
-  
-  for (index = 0; index < modulesList.length; index++) {    
-    var moduleConfig = modulesList[index];
-    
-    var serializer = serialFactory.getSerializer(moduleConfig.metadata);
-    var module = new IriSP[moduleConfig.type](popcornInstance, moduleConfig, serializer);    
-    ret_modules.push(module);
-  };
-
-  return ret_modules;
-};
-
-IriSP.instantiateWidget = function(popcornInstance, serialFactory, layoutManager, widgetConfig) {
-    /* create div returns us a container for the widget and a spacer */
-    var ret = layoutManager.createDiv(widgetConfig.type);        
-    var container = ret[0];
-    var spacer = ret[1];
-
-    var arr = IriSP.jQuery.extend({}, widgetConfig);
-    arr.container = container;
-    arr.spacer = spacer;
-    
-    var serializer = serialFactory.getSerializer(widgetConfig.metadata);    
-    
-    if (typeof serializer == "undefined")   
-      debugger;
-    
-    // instantiate the object passed as a string
-    var widget = new IriSP[widgetConfig.type](popcornInstance, arr, serializer);    
-    
-    if (widgetConfig.hasOwnProperty("requires")) {
-      // also create the widgets this one depends on.
-      // the dependency widget is available in the parent widget context as
-      // this.WidgetName (for instance, this.TipWidget);
-      
-      var i = 0;
-      for(i = 0; i < widgetConfig.requires.length; i++) {
-        var widgetName = widgetConfig.requires[i]["type"];
-        widget[widgetName] = IriSP.instantiateWidget(popcornInstance, serialFactory, layoutManager, widgetConfig.requires[i]);
-      }
-    }       
-     
-    serializer.sync(IriSP.wrap(widget, function() { this.draw(); }));
-    return widget;
-};
-/* mediafragment module */
-
-IriSP.MediaFragment = function(Popcorn, config, Serializer) {
-  IriSP.Module.call(this, Popcorn, config, Serializer);
-
-  this.mutex = false; /* a mutex because we access the url from two different functions */
-
-  this._Popcorn.listen( "loadedmetadata", IriSP.wrap(this, IriSP.MediaFragment.advanceTime));
-  this._Popcorn.listen( "pause", IriSP.wrap(this, IriSP.MediaFragment.updateTime));
-  this._Popcorn.listen( "seeked", IriSP.wrap(this, IriSP.MediaFragment.updateTime));
-  this._Popcorn.listen( "IriSP.PolemicTweet.click", IriSP.wrap(this, IriSP.MediaFragment.updateAnnotation));
-  this._Popcorn.listen( "IriSP.SegmentsWidget.click", IriSP.wrap(this, IriSP.MediaFragment.updateAnnotation));
-};
-
-IriSP.MediaFragment.advanceTime = function() {
-             var url = window.location.href;
-
-              if ( url.split( "#" )[ 1 ] != null ) {
-                  pageoffset = url.split( "#" )[1];
-
-                  if ( pageoffset.substring(0, 2) === "t=") {
-                    // timecode 
-                    if ( pageoffset.substring( 2 ) != null ) {
-                    var offsettime = pageoffset.substring( 2 );
-                    this._Popcorn.currentTime( parseFloat( offsettime ) );
-                    }
-                  } else if ( pageoffset.substring(0, 2) === "a=") {
-                    // annotation
-                    var annotationId = pageoffset.substring( 2 );
-
-                    // there's no better way than that because
-                    // of possible race conditions
-                    this._serializer.sync(IriSP.wrap(this, function() {
-                          IriSP.MediaFragment.lookupAnnotation.call(this, annotationId); 
-                          }));
-                  }
-              }
-};
-
-IriSP.MediaFragment.updateTime = function() {
-  if (this.mutex === true) {
-    return;
-  }
-
-  var history = window.history;
-  if ( !history.pushState ) {
-    return false;
-  }
-  
-  splitArr = window.location.href.split( "#" )
-  history.replaceState( {}, "", splitArr[0] + "#t=" + this._Popcorn.currentTime().toFixed( 2 ) );
-};
-
-
-IriSP.MediaFragment.updateAnnotation = function(annotationId) {
-  var _this = this;
-  this.mutex = true;
-
-  var history = window.history;
-  if ( !history.pushState ) {
-    return false;
-  }
-  
-  splitArr = window.location.href.split( "#" )
-  history.replaceState( {}, "", splitArr[0] + "#a=" + annotationId);
- 
-  window.setTimeout(function() { _this.mutex = false }, 50);
-};
-
-// lookup and seek to the beginning of an annotation
-IriSP.MediaFragment.lookupAnnotation = function(annotationId) {
-  var annotation = undefined;
-  var annotations = this._serializer._data.annotations;
-
-  var i;
-  for (i = 0; i < annotations.length; i++) {
-      if (annotations[i].id === annotationId) {
-        annotation = annotations[i];
-        break;
-      }
-  }
-
-  if (typeof(annotation) !== "undefined") {
-    this._Popcorn.currentTime(annotation.begin / 1000);
-  }
-};
-IriSP.AnnotationsWidget = function(Popcorn, config, Serializer) {
-  IriSP.Widget.call(this, Popcorn, config, Serializer);
-  
-};
-
-
-IriSP.AnnotationsWidget.prototype = new IriSP.Widget();
-
-IriSP.AnnotationsWidget.prototype.clear = function() {
-    this.selector.find(".Ldt-SaTitle").text("");
-    this.selector.find(".Ldt-SaDescription").text("");
-    this.selector.find(".Ldt-SaKeywordText").text("");
-};
-
-IriSP.AnnotationsWidget.prototype.displayAnnotation = function(annotation) {   
-
-    var title = annotation.content.title;
-    var description = annotation.content.description;
-    var keywords =  "" // FIXME;
-    var begin = +annotation.begin / 1000;
-    var end = +annotation.end / 1000;
-    var duration = +this._serializer.currentMedia().meta["dc:duration"];
-    
-    var title_templ = "{{title}} - ( {{begin}} - {{end}} )";
-    var endstr = Mustache.to_html(title_templ, {title: title, begin: IriSP.secondsToTime(begin), end: IriSP.secondsToTime(end)});
-
-    this.selector.find(".Ldt-SaTitle").text(endstr);
-    this.selector.find(".Ldt-SaDescription").text(description);
-    
-    // update sharing buttons
-    var defaults = IriSP.widgetsDefaults.AnnotationsWidget;
-    var text = defaults.share_text;
-    var fb_link = defaults.fb_link;
-    var tw_link = defaults.tw_link;
-    var gplus_link = defaults.gplus_link;
-    var url = document.location.href + "#a=" + annotation.id;
-    this.selector.find(".Ldt-fbShare").attr("href", fb_link + IriSP.encodeURI(text) + IriSP.encodeURI(url));
-    this.selector.find(".Ldt-TwShare").attr("href", tw_link + IriSP.encodeURI(text) + IriSP.encodeURI(url));
-    this.selector.find(".Ldt-GplusShare").attr("href", fb_link + IriSP.encodeURI(text) + IriSP.encodeURI(url));
-};
-
-IriSP.AnnotationsWidget.prototype.clearWidget = function() {
-
-    
-    /* retract the pane between two annotations */
-    this.selector.find(".Ldt-SaTitle").text("");
-    this.selector.find(".Ldt-SaDescription").text("");
-    this.selector.find(".Ldt-SaKeywordText").html("");
-    this.selector.find(".Ldt-ShowAnnotation").slideUp();
-};
-
-IriSP.AnnotationsWidget.prototype.draw = function() {
-  var _this = this;
-
-  var annotationMarkup = IriSP.templToHTML(IriSP.annotationWidget_template);
-	this.selector.append(annotationMarkup);
-  var view;
-
-  if (typeof(this._serializer._data.views) !== "undefined" && this._serializer._data.views !== null)
-     view = this._serializer._data.views[0];
-
-  var view_type = "";
-
-  if(typeof(view) !== "undefined" && typeof(view.annotation_types) !== "undefined" && view.annotation_types.length > 1) {
-          view_type = view.annotation_types[0];
-  }
- 
-  var annotations = this._serializer._data.annotations;
-  var i;
-  
-	for (i in annotations) {    
-    var annotation = annotations[i];
-    var begin = Math.round((+ annotation.begin) / 1000);
-    var end = Math.round((+ annotation.end) / 1000);
-
-    if (view_type != "" && typeof(annotation.meta) !== "undefined" && typeof(annotation.meta["id-ref"]) !== "undefined"
-          && annotation.meta["id-ref"] != view_type) {
-        continue;
-    }
-
-
-    var conf = {start: begin, end: end, 
-                onStart: 
-                       function(annotation) { 
-                        return function() { 
-                            _this.displayAnnotation(annotation); 
-                          
-                        } }(annotation),
-                onEnd: 
-                       function() { _this.clearWidget.call(_this); }
-                };
-    this._Popcorn = this._Popcorn.code(conf);                                             
-  }
-
-};
-IriSP.ArrowWidget = function(Popcorn, config, Serializer) {
-  IriSP.Widget.call(this, Popcorn, config, Serializer);
-
-  this._oldAnnotation = null;
-  
-};
-
-
-IriSP.ArrowWidget.prototype = new IriSP.Widget();
-
-IriSP.ArrowWidget.prototype.clear = function() {
-
-};
-
-IriSP.ArrowWidget.prototype.clearWidget = function() {
-};
-
-IriSP.ArrowWidget.prototype.draw = function() {
-  var templ = Mustache.to_html(IriSP.arrowWidget_template, {});
-  this.selector.append(templ);
-  this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.timeUpdateHandler));
-};
-
-IriSP.ArrowWidget.prototype.timeUpdateHandler = function(percents) {
-  var currentTime = this._Popcorn.currentTime();
-  var currentAnnotation = this._serializer.currentAnnotations(currentTime)[0]; // FIXME : use the others ?
-
-  /* move the arrow only if the current annotation changes */
-  if (currentAnnotation != this._oldAnnotation) {
-    var begin = (+ currentAnnotation.begin) / 1000;
-    var end = (+ currentAnnotation.end) / 1000;
-
-    var duration = +this._serializer.currentMedia().meta["dc:duration"] / 1000;
-    var middle_time = (begin + end) / 2;
-    var percents = Math.floor((middle_time / duration) * 100);
-
-    // we need to apply a fix because the arrow has a certain length
-    // it's half the length of the arrow (27 / 2). We need to convert
-    // it in percents though.
-    var totalWidth = this.selector.width();
-    var correction = ((27 / 2) / totalWidth) * 100;
-    var corrected_percents = percents - correction;
-
-    /* don't move out of the screen */
-    if (corrected_percents <= 0)
-      corrected_percents = 0;
-
-    this.selector.children(".Ldt-arrowWidget").animate({"left" : corrected_percents + "%"});
-
-    this._oldAnnotation = currentAnnotation;
-  }
-}
-IriSP.PlayerWidget = function(Popcorn, config, Serializer) {
-  IriSP.Widget.call(this, Popcorn, config, Serializer);
-  
-  this._searchBlockOpen = false;
-  this._searchLastValue = "";
-};
-
-IriSP.PlayerWidget.prototype = new IriSP.Widget();
-
-IriSP.PlayerWidget.prototype.draw = function() {
-  var self = this;
-  var width = this.width;
-	var height = this.height;
-	var heightS = this.height-20;
-	  
-	var Player_templ = Mustache.to_html(IriSP.player_template, {"share_template" : IriSP.share_template});
-  this.selector.append(Player_templ);		
-	
-  this.selector.children(".Ldt-controler").show();
-    
-  // handle clicks by the user on the video.
-  this._Popcorn.listen("play", IriSP.wrap(this, this.playButtonUpdater));
-  this._Popcorn.listen("pause", IriSP.wrap(this, this.playButtonUpdater));
-  
-  this._Popcorn.listen("volumechange", IriSP.wrap(this, this.muteButtonUpdater));
-
-  this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.timeDisplayUpdater));
-  this._Popcorn.listen("IriSP.search.matchFound", IriSP.wrap(this, this.searchMatch));
-  this._Popcorn.listen("IriSP.search.noMatchFound", IriSP.wrap(this, this.searchNoMatch));
-  
-  
-  this.selector.find(".Ldt-CtrlPlay").click(function() { self.playHandler.call(self); });
-  this.selector.find(".Ldt-CtrlNext").click(function() { });
-  this.selector.find(".Ldt-CtrlSearch").click(function() { self.searchButtonHandler.call(self); });
-  
-  this.selector.find('.Ldt-CtrlSound').click(function() { self.muteHandler.call(self); } );
-
-  this.selector.find(".Ldt-CtrlPlay").attr( "style", "background-color:#CD21C24;" );
-  
-  var searchButtonPos = this.selector.find(".Ldt-CtrlSearch").position();
-  var searchBox = Mustache.to_html(IriSP.search_template, {margin_left : searchButtonPos.left + "px"});
-  this.selector.append(searchBox);
-  
-  // trigger an IriSP.PlayerWidget.MouseOver to the widgets that are interested (i.e : sliderWidget)
-  this.selector.hover(function() { self._Popcorn.trigger("IriSP.PlayerWidget.MouseOver"); }, 
-                      function() { self._Popcorn.trigger("IriSP.PlayerWidget.MouseOut"); });
- 
-  this.muteButtonUpdater(); /* some player - jwplayer notable - save the state of the mute button between sessions */
-};
-
-/* Update the elasped time div */
-IriSP.PlayerWidget.prototype.timeDisplayUpdater = function() {
-  
-  if (this._previousSecond === undefined)
-    this._previousSecond = this._Popcorn.roundTime();
-  
-  else {
-    /* we're still in the same second, so it's not necessary to update time */
-    if (this._Popcorn.roundTime() == this._previousSecond)
-      return;
-      
-  }
-  
-  // we get it at each call because it may change.
-  var duration = +this._serializer.currentMedia().meta["dc:duration"] / 1000; 
-  var totalTime = IriSP.secondsToTime(duration);
-  var elapsedTime = IriSP.secondsToTime(this._Popcorn.currentTime());
-  
-  this.selector.find(".Ldt-ElapsedTime").html(elapsedTime.toString());
-  this.selector.find(".Ldt-TotalTime").html(totalTime.toString());
-  this._previousSecond = this._Popcorn.roundTime();
-};
-
-/* update the icon of the button - separate function from playHandler
-   because in some cases (for instance, when the user directly clicks on
-   the jwplayer window) we have to change the icon without playing/pausing
-*/
-IriSP.PlayerWidget.prototype.playButtonUpdater = function() {
-  var status = this._Popcorn.media.paused;
-  
-  if ( status == true ){        
-    this.selector.find(".Ldt-CtrlPlay").attr("title", "Play");
-   
-    // we use templToHTML because it has some predefined
-    // vars like where to get the images
-    var templ = IriSP.templToHTML("url({{img_dir}}/play_sprite.png)");
-    this.selector.find(".Ldt-CtrlPlay").css("background-image", templ);
-
-  } else {
-    this.selector.find(".Ldt-CtrlPlay").attr("title", "Pause");
-
-    // we use templToHTML because it has some predefined
-    // vars like where to get the images
-    var templ = IriSP.templToHTML("url({{img_dir}}/pause_sprite.png)");
-    this.selector.find(".Ldt-CtrlPlay").css("background-image", templ);
-  }  
-
-  return;
-};
-
-
-IriSP.PlayerWidget.prototype.playHandler = function() {
-  var status = this._Popcorn.media.paused;
-  
-  if ( status == true ){        
-    this._Popcorn.play();   
-  } else {
-    this._Popcorn.pause();
-  }  
-};
-
-IriSP.PlayerWidget.prototype.muteHandler = function() {
-  if (!this._Popcorn.muted()) {    
-      this._Popcorn.mute(true);
-    } else {
-      this._Popcorn.mute(false);
-    }
-};
-
-IriSP.PlayerWidget.prototype.muteButtonUpdater = function() {
-  var status = this._Popcorn.media.muted;
-  
-  if ( status == true ){        
-    this.selector.find(".Ldt-CtrlSound").attr("title", "Unmute");
-   
-    // we use templToHTML because it has some predefined
-    // vars like where to get the images
-    var templ = IriSP.templToHTML("url({{img_dir}}/sound_sprite.png)");
-    this.selector.find(".Ldt-CtrlSound").css("background-image", templ);
-
-  } else {
-    this.selector.find(".Ldt-CtrlSound").attr("title", "Mute");
-
-    // we use templToHTML because it has some predefined
-    // vars like where to get the images
-    var templ = IriSP.templToHTML("url({{img_dir}}/mute_sprite.png)");
-    this.selector.find(".Ldt-CtrlSound").css("background-image", templ);
-  }  
-
-  return;
-};
-
-
-IriSP.PlayerWidget.prototype.searchButtonHandler = function() {
-    var self = this;
-
-    /* show the search field if it is not shown */
-  	if ( this._searchBlockOpen == false ) {      
-      this.selector.find(".LdtSearch").show(100);
-      
-      this.selector.find(".LdtSearchInput").css('background-color','#fff');
-      this.selector.find(".LdtSearchInput").focus();
-      this.selector.find(".LdtSearchInput").attr('value', this._searchLastValue);      
-      this._Popcorn.trigger("IriSP.search", this._searchLastValue); // trigger the search to make it more natural.
-      
-      this._searchBlockOpen = true;           
-      this.selector.find(".LdtSearchInput").bind('keyup', null, function() { self.searchHandler.call(self); } );
-      
-      // we need this variable because some widget can find a match in
-      // their data while at the same time other's don't. As we want the
-      // search field to become green when there's a match, we need a 
-      // variable to remember that we had one.
-      this._positiveMatch = false;
-
-      // tell the world the field is open
-      this._Popcorn.trigger("IriSP.search.open");
-      
-	} else {
-      this._searchLastValue = this.selector.find(".LdtSearchInput").attr('value');
-      this.selector.find(".LdtSearchInput").attr('value','');
-      this.selector.find(".LdtSearch").hide(100);
-      
-      // unbind the watcher event.
-      this.selector.find(".LdtSearchInput").unbind('keypress set');
-      this._searchBlockOpen = false;
-
-      this._positiveMatch = false;
-      
-      this._Popcorn.trigger("IriSP.search.closed");
-  }
-};
-
-/* this handler is called whenever the content of the search
-   field changes */
-IriSP.PlayerWidget.prototype.searchHandler = function() {
-  this._searchLastValue = this.selector.find(".LdtSearchInput").attr('value');
-  this._positiveMatch = false;
-  
-  // do nothing if the search field is empty, instead of highlighting everything.
-  if (this._searchLastValue == "") {
-    this._Popcorn.trigger("IriSP.search.cleared");
-    this.selector.find(".LdtSearchInput").css('background-color','');
-  } else {
-    this._Popcorn.trigger("IriSP.search", this._searchLastValue);
-  }
-};
-
-/*
-  handler for the IriSP.search.found message, which is sent by some views when they
-  highlight a match.
-*/
-IriSP.PlayerWidget.prototype.searchMatch = function() {
-  this._positiveMatch = true;
-  this.selector.find(".LdtSearchInput").css('background-color','#e1ffe1');
-}
-
-/* the same, except that no value could be found */
-IriSP.PlayerWidget.prototype.searchNoMatch = function() {
-  if (this._positiveMatch !== true)
-    this.selector.find(".LdtSearchInput").css('background-color', "#d62e3a");
-}
-
-/* 
- *   
- *  Copyright 2010 Institut de recherche et d'innovation 
- *  contributor(s) : Samuel Huron 
- *   
- *  contact@iri.centrepompidou.fr
- *  http://www.iri.centrepompidou.fr 
- *   
- *  This software is a computer program whose purpose is to show and add annotations on a video .
- *  This software is governed by the CeCILL-C license under French law and
- *  abiding by the rules of distribution of free software. You can  use, 
- *  modify and/ or redistribute the software under the terms of the CeCILL-C
- *  license as circulated by CEA, CNRS and INRIA at the following URL
- *  "http://www.cecill.info". 
- *  
- *  The fact that you are presently reading this means that you have had
- *  knowledge of the CeCILL-C license and that you accept its terms.
-*/
-// CHART TIMELINE / VERSION PROTOTYPE  ::
-
-IriSP.PolemicWidget = function(Popcorn, config, Serializer) {
-  IriSP.Widget.call(this, Popcorn, config, Serializer);
- 
-  this.userPol    = new Array();
-  this.userNoPol  = new Array();
-  this.userst      = new Array();
-  this.numberOfTweet = 0;
-  this.Users;
-  this.TweetPolemic;
-  this.yMax        = this.height; 
-  this.PaperSlider;
-  this.heightOfChart;
-  this.tweets  = new Array();
-  this.svgElements = {};
-  
-  // Make and define the Raphael area
-  this.paper = Raphael(document.getElementById(this._id), config.width, config.height);
-  
-  this.oldSearchMatches = [];
-
-  // event handlers
-  this._Popcorn.listen("IriSP.search", IriSP.wrap(this, function(searchString) { this.searchHandler(searchString); }));
-  this._Popcorn.listen("IriSP.search.closed", IriSP.wrap(this, this.searchFieldClosedHandler));
-  this._Popcorn.listen("IriSP.search.cleared", IriSP.wrap(this, this.searchFieldClearedHandler));
-
-};
-
-IriSP.PolemicWidget.prototype = new IriSP.Widget();
-  
-IriSP.PolemicWidget.prototype.draw = function() {
-  
-    // variable 
-    // yMax
-    
-    var self = this;
-    var yCoef        = 2;             // coef for height of 1 tweet 
-    var frameSize     = 5;             // frame size 
-    var margin         = 1;            // marge between frame
-    var lineSize      = this.width;        // timeline pixel width 
-    var nbrframes     = lineSize/frameSize;     // frame numbers
-    var numberOfTweet   = 0;            // number of tweet overide later 
-    var duration      = +this._serializer.currentMedia().meta["dc:duration"];      // timescale width 
-    var frameLength   = lineSize / frameSize;    // frame timescale  
-    var timeline;
-    var colors  = new Array("","#1D973D","#C5A62D","#CE0A15","#036AAE","#585858");
-    
-    // array 
-    //var tweets  = new Array();
-    var element = new Array();
-    var cluster = new Array();
-    var frames  = new Array(frameLength);
-    var slices  = new Array();
-    
-    
-    // Classes =======================================================================
-    var Frames = function(){
-      
-      var Myclusters;
-      var x;
-      var y;
-      var width;
-      var height;
-    };
-    Frames = function(json){
-      // make my clusters
-      // ou Frame vide 
-    };
-    Frames.prototype.draw = function(){
-    };
-    Frames.prototype.zoom = function(){
-    };
-    Frames.prototype.inside = function(){
-    };
-    var Clusters = function(){
-      var Object;
-      var yDist;
-      var x;
-      var y;
-      var width;
-      var height;
-    };
-    Clusters = function(json){
-      // make my object
-    };
-    var Tweet = function(){
-    };
-    // Classes =======================================================================
-
-    // Refactoring (parametere) ************************************************************
-    // color translastion
-    var qTweet_0  =0;
-    var qTweet_Q  =0;
-    var qTweet_REF=0;
-    var qTweet_OK =0;
-    var qTweet_KO =0;
-    function colorTranslation(value){
-      if(value == "Q"){
-        qTweet_Q+=1;
-        return 2;
-      }else if(value =="REF"){
-        qTweet_REF+=1;
-        return 4;
-      }else if(value =="OK"){
-        qTweet_OK+=1;
-        return 1;
-      }else if(value =="KO"){
-        qTweet_KO+=1;
-        return 3;
-      }else if(value ==""){
-        qTweet_0+=1;
-        return 5;
-      }
-    }
-    
-
-      this._serializer.sync(function(data) { loaded_callback.call(self, data) });
-      
-      function loaded_callback (json) {
-
-        // get current view (the first ???)
-        view = json.views[0];
-        
-        // the tweets are by definition of the second annotation type FIXME ?
-        tweet_annot_type = null;
-        if(typeof(view.annotation_types) !== "undefined" && view.annotation_types.length > 1) {
-          tweet_annot_type = view.annotation_types[1];
-        }
-      
-      for(var i = 0; i < json.annotations.length; i++) {
-        var item = json.annotations[i];        
-        var MyTime  = Math.floor(item.begin/duration*lineSize);
-        var Myframe = Math.floor(MyTime/lineSize*frameLength);
-
-        if (typeof(item.meta) !== "undefined" 
-          && typeof(item.meta["id-ref"]) !== "undefined"
-          && item.meta["id-ref"] === tweet_annot_type) {
-            
-          var MyTJson = JSON.parse(item.meta['dc:source']['content']);
-          
-            if (item.content['polemics'] != undefined 
-            && item.content['polemics'][0] != null) {
-            
-              // a tweet can have many polemics at the same time.
-              for(var j=0; j<item.content['polemics'].length; j++){
-                  
-                  this.tweets[numberOfTweet] = {
-                        id:i,
-                        qualification:colorTranslation(item.content['polemics'][j]),
-                        yIndicator:MyTime,
-                        yframe:Myframe,
-                        title:item.content['title'],
-                        timeframe:item.begin,
-                        userId: MyTJson.id,
-                        userScreenName: MyTJson.screen_name,
-                        tsource:MyTJson,
-                        cinecast_id: item.id
-                        };
-                  numberOfTweet+=1;
-                  
-              }
-          }
-          else {
-            this.tweets[numberOfTweet] = {
-                  id:i,
-                  qualification:colorTranslation(""),
-                  yIndicator:MyTime,
-                  yframe:Myframe,
-                  title:item.content['title'],
-                  timeframe:item.begin,
-                  userId: MyTJson.id,
-                  userScreenName: MyTJson.screen_name,
-                  tsource:MyTJson,
-                  cinecast_id: item.id
-            };
-            numberOfTweet+=1;
-          }
-          
-        } 
-      };  
-      
-       DrawTweets.call (this); // FIXME: ugly.
-       
-      };      
-
-    // tweet Drawing (in raphael) 
-    function DrawTweets (){
-    // GROUPES TWEET ============================================
-    // Count nbr of cluster and tweet in a frame an save int in "frames"
-      numberOfTweet = this.tweets.length;
-      for(var i=0; i<nbrframes; i++) {  
-        for(var j=0; j<numberOfTweet; j++) {  
-        
-          if (i==this.tweets[j].yframe){
-            
-            var k = this.tweets[j].qualification;
-            
-            // make array for frame cluster
-            if(frames[i]==undefined){
-              frames[i] = {id:i,
-                     qualifVol:new Array(),
-                     mytweetsID:new Array()
-                    };
-            }
-            // add my tweet to frame
-            frames[i].mytweetsID.push(this.tweets[j]);
-            
-            // count opinion by frame
-            if( frames[i].qualifVol[k] == undefined){
-              frames[i].qualifVol[k] = 1;
-            }else{
-              frames[i].qualifVol[k] += 1;
-            }
-            
-          }
-        }
-      }
-    
-    // GROUPES TWEET ============================================    
-    // max of tweet by Frame 
-      var max = 0; 
-      for(var i = 0; i < nbrframes; i++) {
-        var moy  = 0;
-        for (var j = 0; j < 6; j++) {    
-          if (frames[i] != undefined) {
-            if (frames[i].qualifVol[j] != undefined) {
-              moy += frames[i].qualifVol[j];
-            }
-          }
-        }
-        
-        if (moy > max) {
-          max = moy;
-        }
-      }
-    
-      var tweetDrawed = new Array();
-      var TweetHeight = 5;
-      
-      // DRAW  TWEETS ============================================
-      for(var i = 0; i < nbrframes; i++) {
-        var addEheight = 5;
-        if (frames[i] != undefined){                
-          // by type 
-          
-          for (var j = 6; j > -1; j--) {
-            if (frames[i].qualifVol[j] != undefined) {
-              // show tweet by type 
-              for (var k = 0; k < frames[i].mytweetsID.length; k++) {
-              
-                if (frames[i].mytweetsID[k].qualification == j) {                
-                  var x = i * frameSize;
-                  var y = this.heightmax - addEheight;
-                  
-                  if (this.yMax > y) {
-                    this.yMax = y;
-                  }
-                  
-                  var e = this.paper.rect(x, y, frameSize - margin, TweetHeight /* height */)
-                                    .attr({stroke:"#00","stroke-width":0.1,  fill: colors[j]});  
-                  
-                  addEheight += TweetHeight;
-                  
-                  e.color = colors[j];
-                  e.time = frames[i].mytweetsID[k].timeframe;
-                  e.title = frames[i].mytweetsID[k].title;
-                  e.id = frames[i].mytweetsID[k].cinecast_id;
-
-                  this.svgElements[e.id] = e;
-
-                  /*
-                  e.mouseover(function(element) { return function (event) {
-                        // event.clientX and event.clientY are to raphael what event.pageX and pageY are to jquery.                        
-                        self.TooltipWidget.show.call(self.TooltipWidget, element.title, element.attr("fill"), event.clientX - 106, event.clientY - 160);
-                        element.displayed = true;
-                  }}(e)).mouseout(function(element) { return function () {                          
-                          self.TooltipWidget.hide.call(self.TooltipWidget);
-                  }}(e)).mousedown(function () {
-                    self._Popcorn.currentTime(this.time/1000);
-                    self._Popcorn.trigger("IriSP.PolemicTweet.click", this.id); 
-                  });
-                  */
-                  
-                  IriSP.jQuery(e.node).mouseenter(function(element) { return function (event) {                        
-                        // event.clientX and event.clientY are to raphael what event.pageX and pageY are to jquery.                        
-                        self.TooltipWidget.show.call(self.TooltipWidget, element.title, element.attr("fill"), event.pageX - 106, event.pageY - 160);
-                        element.displayed = true;
-                  }}(e)).mousedown(function(element) { return function () {                    
-                    self._Popcorn.currentTime(element.time/1000);
-                    self._Popcorn.trigger("IriSP.PolemicTweet.click", element.id); 
-                    }
-                  }(e));                  
-                  
-                  IriSP.jQuery(e.node).attr('id', 't' + k + '');
-                  IriSP.jQuery(e.node).attr('title', frames[i].mytweetsID[k].title);
-                  IriSP.jQuery(e.node).attr('begin',  frames[i].mytweetsID[k].timeframe);                  
-                }
-              }
-            }
-          }
-        }
-
-      }    
-      // DRAW UI :: resize border and bgd      
-      this.paperBackground = this.paper.rect(0, 0, this.width, this.heightmax).attr({fill:"#F8F8F8","stroke-width":0.1,opacity: 1});  
-
-      // outer borders
-      this.outerBorders   = [];
-      this.outerBorders.push(this.paper.rect(0, this.height - 1, this.width, 1).attr({fill:"#ababab",stroke: "none",opacity: 1}));  
-      this.outerBorders.push(this.paper.rect(0, 0, this.width, 1).attr({fill:"#ababab",stroke: "none",opacity: 1}));  
-
-      // inner borders
-      this.innerBorders   = [];
-      this.innerBorders.push(this.paper.rect(1, this.height - 2, this.width, 1).attr({fill:"#efefef",stroke: "none",opacity: 1}));  
-      this.innerBorders.push(this.paper.rect(1, 1, this.width, 1).attr({fill:"#efefef",stroke: "none",opacity: 1}));  
-      this.innerBorders.push(this.paper.rect(1, 1, 1, this.height - 2).attr({fill:"#d0d1d1",stroke: "none",opacity: 0.8}));  
-      this.innerBorders.push(this.paper.rect(this.width - 2, 1, 1, this.height - 2).attr({fill:"#efefef",stroke: "none",opacity: 1}));  
-
-
-
-      this.paperSlider   = this.paper.rect(0, 0, 0, this.heightmax).attr({fill:"#D4D5D5", stroke: "none", opacity: 1});
-      
-      // the small white line displayed over the slider.
-      this.sliderTip = this.paper.rect(0, 0, 1, this.heightmax).attr({fill:"#fc00ff", stroke: "none", opacity: 1});
-      // decalage 
-      // tweetSelection = this.paper.rect(-100,-100,5,5).attr({fill:"#fff",stroke: "none",opacity: 1});  
-      
-      
-      this.paperSlider.toBack();
-      this.paperBackground.toBack();
-      this.sliderTip.toFront();
-    }
-    
-    this.selector.mouseleave(IriSP.wrap(this, function() { self.TooltipWidget.hide.call(self.TooltipWidget); }));
-    this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.sliderUpdater));
-}
-
-IriSP.PolemicWidget.prototype.sliderUpdater = function() {
-
-    var time = +this._Popcorn.currentTime();
-    var duration = +this._serializer.currentMedia().meta["dc:duration"];
-    
-    this.paperSlider.attr("width", time * (this.width / (duration / 1000)));
-        
-    this.sliderTip.attr("x", time * (this.width / (duration / 1000)));
-};
-    
-IriSP.PolemicWidget.prototype.searchHandler = function(searchString) {
-  if (searchString == "")
-    return;
-
-  var matches = this._serializer.searchTweetsOccurences(searchString);
-
-  if (IriSP.countProperties(matches) > 0) {
-    this._Popcorn.trigger("IriSP.search.matchFound");
-  } else {
-    this._Popcorn.trigger("IriSP.search.noMatchFound");
-  }
-
-  for (var id in matches) {
-    if (this.svgElements.hasOwnProperty(id)) {
-      var e = this.svgElements[id];
-      this.svgElements[id].attr({fill: "#fc00ff"});
-    }
-  }
-
-  // clean up the blocks that were in the previous search
-  // but who aren't in the current one.
-  for (var id in this.oldSearchMatches) {
-    if (!matches.hasOwnProperty(id)) {
-      var e = this.svgElements[id];
-      e.attr({fill: e.color});
-    }
-  }
-  
-  this.oldSearchMatches = matches;
-};
-
-IriSP.PolemicWidget.prototype.searchFieldClearedHandler = function() {
-  // clean up the blocks that were in the previous search
-  // but who aren't in the current one.
-  for (var id in this.oldSearchMatches) {
-      var e = this.svgElements[id];
-      e.attr({fill: e.color});
-  }
- 
-};
-
-IriSP.PolemicWidget.prototype.searchFieldClosedHandler = function() {
-  // clean up the blocks that were in the previous search
-  // but who aren't in the current one.
-  for (var id in this.oldSearchMatches) {
-      var e = this.svgElements[id];
-      e.attr({fill: e.color});
-  }
- 
-};
-   
-IriSP.SegmentsWidget = function(Popcorn, config, Serializer) {
-
-  var self = this;
-  IriSP.Widget.call(this, Popcorn, config, Serializer);
-  this.oldSearchMatches = [];
-
-  // event handlers
-  this._Popcorn.listen("IriSP.search", function(searchString) { self.searchHandler.call(self, searchString); });
-  this._Popcorn.listen("IriSP.search.closed", function() { self.searchFieldClosedHandler.call(self); });
-  this._Popcorn.listen("IriSP.search.cleared", function() { self.searchFieldClearedHandler.call(self); });
-};
-
-IriSP.SegmentsWidget.prototype = new IriSP.Widget();
-
-/* Get the width of a segment, in pixels. */
-IriSP.SegmentsWidget.prototype.segmentToPixel = function(annotation) {  
-  var begin = Math.round((+ annotation.begin) / 1000);
-  var end = Math.round((+ annotation.end) / 1000);    
-  var duration = this._serializer.currentMedia().meta["dc:duration"] / 1000;
-  
-  var startPourcent 	= IriSP.timeToPourcent(begin, duration);
-  var startPixel = Math.floor(this.selector.parent().width() * (startPourcent / 100));
-  
-  var endPourcent 	= Math.floor(IriSP.timeToPourcent(end, duration) - startPourcent);
-  var endPixel = Math.floor(this.selector.parent().width() * (endPourcent / 100));
-  
-  return endPixel;
-};
-
-/* compute the total length of a group of segments */
-IriSP.SegmentsWidget.prototype.segmentsLength = function(segmentsList) {
-  var self = this;
-  var total = 0;
-  
-  for (var i = 0; i < segmentsList.length; i++)
-    total += self.segmentToPixel(segmentsList[i].annotation);
-  
-  return total;  
-};
-
-IriSP.SegmentsWidget.prototype.draw = function() {
-
-  var self = this;
-  var annotations = this._serializer._data.annotations;
-
-  this.selector.addClass("Ldt-SegmentsWidget");
-  this.selector.append(Mustache.to_html(IriSP.overlay_marker_template));
-          
-  var view_type = this._serializer.getNonTweetIds()[0];    
-  
-  this.positionMarker = this.selector.children(":first");
-  
-  this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.positionUpdater));
-  
-  
-  var i = 0;
-  
-  var segments_annotations = [];
-  
-  for (i = 0; i < annotations.length; i++) {
-    var annotation = annotations[i];
-
-    /* filter the annotations whose type is not the one we want */
-    if (view_type != "" && typeof(annotation.meta) !== "undefined" && typeof(annotation.meta["id-ref"]) !== "undefined"
-          && annotation.meta["id-ref"] != view_type) {
-        continue;
-    }
-
-    segments_annotations.push(annotation);
-  }
-    
-  var totalWidth = this.selector.width() - segments_annotations.length;
-  var lastSegment = IriSP.underscore.max(segments_annotations, function(annotation) { return annotation.end; });
-  
-  for (i = 0; i < segments_annotations.length; i++) {
-  
-    var annotation = segments_annotations[i];
-    var begin = (+ annotation.begin);
-    var end = (+ annotation.end);
-    var duration = this._serializer.currentMedia().meta["dc:duration"];
-    var id = annotation.id;
-        
-    var startPixel = Math.floor(this.selector.parent().width() * (begin / duration));
-
-    var endPixel = Math.floor(this.selector.parent().width() * (end / duration));
-    
-    if (annotation.id !== lastSegment.id) 
-      var pxWidth = endPixel - startPixel -1;
-    else
-      /* the last segment has no segment following it */
-      var pxWidth = endPixel - startPixel;
- 
-    var divTitle = (annotation.content.title + " - " + annotation.content.description).substr(0,55);
-
-    if (typeof(annotation.content.color) !== "undefined")
-      var color = annotation.content.color;
-    else
-      var color = annotation.color;
-    
-    var hexa_color = IriSP.DEC_HEXA_COLOR(color);
-
-    if (hexa_color === "FFCC00")
-      hexa_color = "333";
-    if (hexa_color.length == 4)
-      hexa_color = hexa_color + '00';
-    
-    var annotationTemplate = Mustache.to_html(IriSP.annotation_template,
-        {"divTitle" : divTitle, "id" : id, "startPixel" : startPixel,
-        "pxWidth" : pxWidth, "hexa_color" : hexa_color,
-        "seekPlace" : Math.round(begin/1000)});
-
-        
-    this.selector.append(annotationTemplate);
-    
-    /* add a special class to the last segment and change its border */
-    if (annotation.id === lastSegment.id) {
-        this.selector.find("#" + id).addClass("Ldt-lastSegment");        
-        this.selector.find(".Ldt-lastSegment").css("border-color", "#" + hexa_color);        
-    }
-
-    IriSP.jQuery("#" + id).fadeTo(0, 0.3);
-
-    IriSP.jQuery("#" + id).mouseover(
-    /* we wrap the handler in another function because js's scoping
-       rules are function-based - otherwise, the internal vars like
-       divTitle are preserved but they are looked-up from the draw
-       method scope, so after that the loop is run, so they're not
-       preserved */
-    (function(divTitle) { 
-     return function(event) {
-          IriSP.jQuery(this).animate({opacity: 0.6}, 5);
-          var offset = IriSP.jQuery(this).offset();
-          var correction = IriSP.jQuery(this).outerWidth() / 2;
-
-          var offset_x = offset.left + correction - 106;
-          if (offset_x < 0)
-            offset_x = 0;
-                    
-          self.TooltipWidget.show(divTitle, color, offset_x, event.pageY - 160);
-    } })(divTitle)).mouseout(function(){
-      IriSP.jQuery(this).animate({opacity: 0.3}, 5);
-      self.TooltipWidget.hide();
-    });
-
-    IriSP.jQuery("#" + id).click(function(_this, annotation) {
-                                    return function() { _this.clickHandler(annotation)};
-                                 }(this, annotation));
-  }
-};
-
-/* restores the view after a search */
-IriSP.SegmentsWidget.prototype.clear = function() {
-  this.selector.children(".Ldt-iri-chapter").animate({opacity:0.3}, 100);
-};
-
-IriSP.SegmentsWidget.prototype.clickHandler = function(annotation) {
-  this._Popcorn.trigger("IriSP.SegmentsWidget.click", annotation.id);
-  var begin = (+ annotation.begin) / 1000;
-  this._Popcorn.currentTime(Math.round(begin));
-};
-
-IriSP.SegmentsWidget.prototype.searchHandler = function(searchString) {
-
-  if (searchString == "")
-    return;
-
-  var matches = this._serializer.searchOccurences(searchString);
-
-  if (IriSP.countProperties(matches) > 0) {
-    this._Popcorn.trigger("IriSP.search.matchFound");
-  } else {
-    this._Popcorn.trigger("IriSP.search.noMatchFound");
-  }
-
-  // un-highlight all the blocks
-  this.selector.children(".Ldt-iri-chapter").css("opacity", 0.1);
- 
-  // then highlight the ones with matches.
-  for (var id in matches) {
-    var factor = 0.5 + matches[id] * 0.2;
-    this.selector.find("#"+id).dequeue();
-    this.selector.find("#"+id).animate({opacity:factor}, 200);
-  }
-
- 
-  this.oldSearchMatches = matches;
-};
-
-IriSP.SegmentsWidget.prototype.searchFieldClearedHandler = function() {
-  this.clear();
-};
-
-IriSP.SegmentsWidget.prototype.searchFieldClosedHandler = function() {
-  this.clear();
-};
-
-IriSP.SegmentsWidget.prototype.positionUpdater = function() {  
-  var duration = this._serializer.currentMedia().meta["dc:duration"] / 1000;
-  var time = this._Popcorn.currentTime();
-  //var position 	= ((time / duration) * 100).toFixed(2);
-  var position 	= ((time / duration) * 100).toFixed(2);
-
-  this.positionMarker.css("left", position + "%");  
-};
-IriSP.SliderWidget = function(Popcorn, config, Serializer) {
-  IriSP.Widget.call(this, Popcorn, config, Serializer);
-};
-
-IriSP.SliderWidget.prototype = new IriSP.Widget();
-
-IriSP.SliderWidget.prototype.draw = function() {
-  var self = this;
-
-  this.selector.append(Mustache.to_html(IriSP.sliderWidget_template, {}));
-  this.selector.addClass("Ldt-SliderMinimized");
-
-  this.sliderBackground = this.selector.find(".Ldt-sliderBackground");
-  this.sliderForeground = this.selector.find(".Ldt-sliderForeground");
-  this.positionMarker = this.selector.find(".Ldt-sliderPositionMarker");
-
-
-  // a special variable to stop methods from tinkering
-  // with the positionMarker when the user is dragging it
-  this.draggingOngoing = false;
-
-  // another special variable used by the timeout handler to
-  // open or close the slider.
-  this.sliderMaximized = false;
-  this.timeOutId = null;
-
-  
-  this.positionMarker.draggable({axis: "x",
-  start: IriSP.wrap(this, this.positionMarkerDraggingStartedHandler),
-  stop: IriSP.wrap(this, this.positionMarkerDraggedHandler),
-  containment: "parent"
-  });
-  this.positionMarker.css("position", "absolute");
-  
-  this.sliderBackground.click(function(event) { self.backgroundClickHandler.call(self, event); });
-  this.sliderForeground.click(function(event) { self.foregroundClickHandler.call(self, event); });
-
-  this.selector.hover(IriSP.wrap(this, this.mouseOverHandler), IriSP.wrap(this, this.mouseOutHandler));
-
-  // update the positions
-  this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.sliderUpdater));
-
-  // special messages :
-  this._Popcorn.listen("IriSP.PlayerWidget.MouseOver", IriSP.wrap(this, this.mouseOverHandler));
-  this._Popcorn.listen("IriSP.PlayerWidget.MouseOut", IriSP.wrap(this, this.mouseOutHandler));
-};
-
-/* update the slider and the position marker as time passes */
-IriSP.SliderWidget.prototype.sliderUpdater = function() {
-  if(this.draggingOngoing || this._disableUpdate)
-    return;
-  
-  var time = this._Popcorn.currentTime();
-
-  var duration = this._serializer.currentMedia().meta["dc:duration"] / 1000;
-  var percent = ((time / duration) * 100).toFixed(2);
-  
-  /* we do these complicated calculations to center exactly
-     the position Marker */
-  var pixels_to_percents = 100 / this.selector.width(); /* how much is a pixel in percents */
-  var positionMarker_width = this.positionMarker.width();
-  var correction = (pixels_to_percents * positionMarker_width) / 2;
-
-  var newPos = percent - correction;
-  if (newPos <= 0)
-    newPos = 0;
-  
-	this.sliderForeground.css("width", percent + "%");
-	this.positionMarker.css("left", newPos + "%");
-
-};
-
-IriSP.SliderWidget.prototype.backgroundClickHandler = function(event) {
-  /* this piece of code is a little bit convoluted - here's how it works :
-     we want to handle clicks on the progress bar and convert those to seeks in the media.
-     However, jquery only gives us a global position, and we want a number of pixels relative
-     to our container div, so we get the parent position, and compute an offset to this position,
-     and finally compute the progress ratio in the media.
-     Finally we multiply this ratio with the duration to get the correct time
-  */
-
-  var parentOffset = this.sliderBackground.parent().offset();
-  var width = this.sliderBackground.width();
-  var relX = event.pageX - parentOffset.left;
-
-  var duration = this._serializer.currentMedia().meta["dc:duration"] / 1000;
-  var newTime = ((relX / width) * duration).toFixed(2);
-
-  this._Popcorn.currentTime(newTime);
-};
-
-/* same function as the previous one, except that it handles clicks
-   on the foreground element */
-IriSP.SliderWidget.prototype.foregroundClickHandler = function(event) {
-  var parentOffset = this.sliderForeground.parent().offset();
-  var width = this.sliderBackground.width();
-  var relX = event.pageX - parentOffset.left;
-
-  var duration = this._serializer.currentMedia().meta["dc:duration"] / 1000;
-  var newTime = ((relX / width) * duration).toFixed(2);
-
-  this._Popcorn.currentTime(newTime);
-};
-
-/* handles mouse over the slider */
-IriSP.SliderWidget.prototype.mouseOverHandler = function(event) {
-  
-  if (this.timeOutId !== null) {
-    window.clearTimeout(this.timeOutId);
-  }
- 
-  this.sliderMaximized = true;
-
-  this.sliderBackground.animate({"height": "9px"}, 100);
-  this.sliderForeground.animate({"height": "9px"}, 100);
-  this.positionMarker.animate({"height": "9px", "width": "9px"}, 100);
-  //this.positionMarker.css("margin-top", "-4px");
-  
-//  this.selector.removeClass("Ldt-SliderMinimized");
-//  this.selector.addClass("Ldt-SliderMaximized");
-};
-
-/* handles when the mouse leaves the slider */
-IriSP.SliderWidget.prototype.mouseOutHandler = function(event) {
-
-  this.timeOutId = window.setTimeout(IriSP.wrap(this, this.minimizeOnTimeout),
-                                     IriSP.widgetsDefaults.SliderWidget.minimize_period);
-};
-
-IriSP.SliderWidget.prototype.minimizeOnTimeout = function(event) {
-  this.sliderBackground.animate({"height": "5px"}, 100);
-  this.sliderForeground.animate({"height": "5px"}, 100);
-  this.positionMarker.animate({"height": "5px", "width": "5px"}, 100);
-  this.positionMarker.css("margin-top", "0px");
-  this.sliderMinimized = true;
-  
-//  this.selector.removeClass("Ldt-SliderMaximized");
-//  this.selector.addClass("Ldt-SliderMinimized");
-
-};
-
-// called when the user starts dragging the position indicator
-IriSP.SliderWidget.prototype.positionMarkerDraggingStartedHandler = function(event, ui) {  
-  this.draggingOngoing = true;
-};
-
-IriSP.SliderWidget.prototype.positionMarkerDraggedHandler = function(event, ui) {   
-  this._disableUpdate = true; // disable slider position updates while dragging is ongoing.
-  window.setTimeout(IriSP.wrap(this, function() { this._disableUpdate = false; }), 500);
-
-  var parentOffset = this.sliderForeground.parent().offset();
-  var width = this.sliderBackground.width();
-  var relX = event.pageX - parentOffset.left;
-
-  var duration = this._serializer.currentMedia().meta["dc:duration"] / 1000;
-  var newTime = ((relX / width) * duration).toFixed(2);
-
-  this._Popcorn.currentTime(newTime);
-  
-  this.draggingOngoing = false;
-};
-
-/* this widget displays a small tooltip */
-IriSP.TooltipWidget = function(Popcorn, config, Serializer) {
-  IriSP.Widget.call(this, Popcorn, config, Serializer);
-  this._shown = false;
-  this._displayedText = "";
-  this._hideTimeout = -1;
-};
-
-
-IriSP.TooltipWidget.prototype = new IriSP.Widget();
-
-IriSP.TooltipWidget.prototype.draw = function() {
-  var templ = Mustache.to_html(IriSP.tooltipWidget_template);
-
-  this.selector.append(templ);
-  this.hide();
-
-};
-
-IriSP.TooltipWidget.prototype.clear = function() {
-	this.selector.find(".tiptext").text("");
-};
-
-IriSP.TooltipWidget.prototype.show = function(text, color, x, y) {
-
-  if (this._displayedText == text)
-    return;
-  
-  this.selector.find(".tipcolor").css("background-color", color);
-  this._displayedText = text;
-	this.selector.find(".tiptext").text(text);
-  //this.selector.find(".tip").css("left", x).css("top", y);  
-  this.selector.find(".tip").css("left", x).css("top", y);
-  this.selector.find(".tip").show();
-  this._shown = true;
-};
-
-IriSP.TooltipWidget.prototype.hide = function() {                                                   
-  this.selector.find(".tip").hide();
-  this._shown = false;  
-};/* a widget that displays tweet - used in conjunction with the polemicWidget */
-
-IriSP.TweetsWidget = function(Popcorn, config, Serializer) {
-  IriSP.Widget.call(this, Popcorn, config, Serializer);
-
-  this._displayingTweet = false;
-  this._timeoutId = undefined;  
-};
-
-
-IriSP.TweetsWidget.prototype = new IriSP.Widget();
-
-
-IriSP.TweetsWidget.prototype.drawTweet = function(annotation) {
-    
-    var title = IriSP.formatTweet(annotation.content.title);
-    var img = annotation.content.img.src;
-    if (typeof(img) === "undefined" || img === "" || img === "None") {
-      img = IriSP.widgetsDefaults.TweetsWidget.default_profile_picture;
-    }
-
-    var imageMarkup = IriSP.templToHTML("<img src='{{src}}' alt='user image'></img>", 
-                                       {src : img});
-    
-    if (typeof(annotation.meta["dc:source"].content) !== "undefined") {
-      var tweetContents = JSON.parse(annotation.meta["dc:source"].content);
-      var creator = tweetContents.user.screen_name;
-      var real_name = tweetContents.user.name;
-
-      imageMarkup = IriSP.templToHTML("<a href='http://twitter.com/{{creator}}'><img src='{{src}}' alt='user image'></img></a>", 
-                                       {src : img, creator: creator});
-            
-      var formatted_date = new Date(tweetContents.created_at).toLocaleDateString();
-      title = IriSP.templToHTML("<a class='Ldt-tweet_userHandle' href='http://twitter.com/{{creator}}'>@{{creator}}</a> - " + 
-                                "<div class='Ldt-tweet_realName'>{{real_name}}</div>" +
-                                "<div class='Ldt-tweet_tweetContents'>{{{ contents }}}</div>" +
-                                "<div class='Ldt-tweet_date'>{{ date }}</div>", 
-                                {creator: creator, real_name: real_name, contents : title, date : formatted_date});
-
-      this.selector.find(".Ldt-TweetReply").attr("href", "http://twitter.com/home?status=@" + creator + ":%20");
-
-
-      var rtText = Mustache.to_html("http://twitter.com/home?status=RT @{{creator}}: {{text}}",
-                                    {creator: creator, text: IriSP.encodeURI(annotation.content.title)});
-      this.selector.find(".Ldt-Retweet").attr("href", rtText);
-    }
-
-    this.selector.find(".Ldt-tweetContents").html(title);
-    this.selector.find(".Ldt-tweetAvatar").html(imageMarkup);
-    this.selector.show("blind", 250); 
-};
-
-IriSP.TweetsWidget.prototype.displayTweet = function(annotation) {
-  if (this._displayingTweet === false) {
-    this._displayingTweet = true;
-  } else {
-    window.clearTimeout(this._timeoutId);
-  }
-
-  this.drawTweet(annotation);
-
-  var time = this._Popcorn.currentTime();  
-  this._timeoutId = window.setTimeout(IriSP.wrap(this, this.clearPanel), IriSP.widgetsDefaults.TweetsWidget.tweet_display_period);
-};
-
-
-IriSP.TweetsWidget.prototype.clearPanel = function() {  
-    this._displayingTweet = false;
-    this._timeoutId = undefined;
-    this.closePanel();
-    
-};
-
-IriSP.TweetsWidget.prototype.closePanel = function() {
-    if (this._timeoutId != undefined) {
-      /* we're called from the "close window" link */
-      /* cancel the timeout */
-      window.clearTimeout(this._timeoutId);
-      this._timeoutId = null;
-    }
-    
-    this.selector.hide("blind", 400);
-    
-};
-
-/* cancel the timeout if the user clicks on the keep panel open button */
-IriSP.TweetsWidget.prototype.keepPanel = function() {
-    if (this._timeoutId != undefined) {
-      /* we're called from the "close window" link */
-      /* cancel the timeout */
-      window.clearTimeout(this._timeoutId);
-      this._timeoutId = null;
-    }
-};
-
-IriSP.TweetsWidget.prototype.draw = function() {
-  var _this = this;
-  
-  var tweetMarkup = IriSP.templToHTML(IriSP.tweetWidget_template, {"share_template" : IriSP.share_template});
-  this.selector.append(tweetMarkup);
-  this.selector.hide();
-  this.selector.find(".Ldt-tweetWidgetMinimize").click(IriSP.wrap(this, this.closePanel));
-  this.selector.find(".Ldt-tweetWidgetKeepOpen").click(IriSP.wrap(this, this.keepPanel));
-  
-  this._Popcorn.listen("IriSP.PolemicTweet.click", IriSP.wrap(this, this.PolemicTweetClickHandler));
-};
-
-IriSP.TweetsWidget.prototype.PolemicTweetClickHandler = function(tweet_id) {  
-  var index, annotation;
-  for (index in this._serializer._data.annotations) {
-    annotation = this._serializer._data.annotations[index];
-    
-    if (annotation.id === tweet_id)
-      break;
-  }
-    
-  if (annotation.id !== tweet_id)
-      /* we haven't found it */
-      return;
-  
-  this.displayTweet(annotation);
-  return;
-};
-
-IriSP.JSONSerializer = function(DataLoader, url) {
-  IriSP.Serializer.call(this, DataLoader, url);
-};
-
-IriSP.JSONSerializer.prototype = new IriSP.Serializer();
-
-IriSP.JSONSerializer.prototype.serialize = function(data) {
-  return JSON.stringify(data);
-};
-
-IriSP.JSONSerializer.prototype.deserialize = function(data) {
-  return JSON.parse(data);
-};
-
-IriSP.JSONSerializer.prototype.sync = function(callback) {
-  /* we don't have to do much because jQuery handles json for us */
-
-  var self = this;
-
-  var fn = function(data) {      
-      self._data = data;      
-      // sort the data too     
-      self._data["annotations"].sort(function(a, b) 
-          { var a_begin = +a.begin;
-            var b_begin = +b.begin;
-            return a_begin - b_begin;
-          });
-     
-      callback(data);      
-  };
-  
-  this._DataLoader.get(this._url, fn);
-};
-
-IriSP.JSONSerializer.prototype.currentMedia = function() {  
-  return this._data.medias[0]; /* FIXME: don't hardcode it */
-};
-
-/* this function searches for an annotation which matches title, description and keyword 
-   "" matches any field. 
-   Note: it ignores tweets.
-*/    
-IriSP.JSONSerializer.prototype.searchAnnotations = function(title, description, keyword) {
-    /* we can have many types of annotations. We want search to only look for regular segments */
-    /* the next two lines are a bit verbose because for some test data, _serializer.data.view is either
-       null or undefined.
-    */
-    var view;
-
-    if (typeof(this._data.views) !== "undefined" && this._data.views !== null)
-       view = this._data.views[0];
-
-    var searchViewType = "";
-
-    if(typeof(view) !== "undefined" && typeof(view.annotation_types) !== "undefined" && view.annotation_types.length > 1) {
-            searchViewType = view.annotation_types[0];
-    }
-
-    var filterfn = function(annotation) {
-      if( searchViewType  != "" && 
-          typeof(annotation.meta) !== "undefined" && 
-          typeof(annotation.meta["id-ref"]) !== "undefined" &&
-          annotation.meta["id-ref"] !== searchViewType) {
-        return true; // don't pass
-      } else {
-          return false;
-      }
-    };
-
-    return this.searchAnnotationsFilter(title, description, keyword, filterfn);
-
-};
-
-/* only look for tweets */
-IriSP.JSONSerializer.prototype.searchTweets = function(title, description, keyword) {
-    /* we can have many types of annotations. We want search to only look for regular segments */
-    /* the next two lines are a bit verbose because for some test data, _serializer.data.view is either
-       null or undefined.
-    */
-    var view;
-
-    if (typeof(this._data.views) !== "undefined" && this._data.views !== null)
-       view = this._data.views[0];
-
-    var searchViewType = "";
-
-    if(typeof(view) !== "undefined" && typeof(view.annotation_types) !== "undefined" && view.annotation_types.length > 1) {
-            searchViewType = view.annotation_types[0];
-    }
-
-    var filterfn = function(annotation) {
-      if( searchViewType  != "" && 
-          typeof(annotation.meta) !== "undefined" && 
-          typeof(annotation.meta["id-ref"]) !== "undefined" &&
-          annotation.meta["id-ref"] !== searchViewType) {
-        return false; // pass
-      } else {
-          return true;
-      }
-    };
-
-    return this.searchAnnotationsFilter(title, description, keyword, filterfn);
-
-};
-
-/*
-  the previous function call this one, which is more general:
- */    
-IriSP.JSONSerializer.prototype.searchAnnotationsFilter = function(title, description, keyword, filter) {
-
-    var rTitle;
-    var rDescription;
-    var rKeyword;
-    /* match anything if given the empty string */
-    if (title == "")
-      title = ".*";
-    if (description == "")
-      description = ".*";
-    if (keyword == "")
-      keyword = ".*";
-    
-    rTitle = new RegExp(title, "i");  
-    rDescription = new RegExp(description, "i");  
-    rKeyword = new RegExp(keyword, "i");  
-    
-    var ret_array = [];
-    
-    var i;
-    for (i in this._data.annotations) {
-      var annotation = this._data.annotations[i];
-      
-      /* filter the annotations whose type is not the one we want */
-      if (filter(annotation)) {
-          continue;
-      }
-      
-      if (rTitle.test(annotation.content.title) && 
-          rDescription.test(annotation.content.description)) {
-          /* FIXME : implement keyword support */
-          ret_array.push(annotation);
-      }
-    }
-    
-    return ret_array;
-};
-
-/* breaks a string in words and searches each of these words. Returns an array
-   of objects with the id of the annotation and its number of occurences.
-   
-   FIXME: optimize ? seems to be n^2 in the worst case.
-*/
-IriSP.JSONSerializer.prototype.searchOccurences = function(searchString) {
-  var ret = { };
-  var keywords = searchString.split(/\s+/);
-  
-  for (var i in keywords) {
-    var keyword = keywords[i];
-    
-    // search this keyword in descriptions and title
-    var found_annotations = []
-    found_annotations = found_annotations.concat(this.searchAnnotations(keyword, "", ""));
-    found_annotations = found_annotations.concat(this.searchAnnotations("", keyword, ""));
-    
-    for (var j in found_annotations) {
-      var current_annotation = found_annotations[j];
-      
-      if (!ret.hasOwnProperty(current_annotation.id)) {
-        ret[current_annotation.id] = 1;
-      } else {
-        ret[current_annotation.id] += 1;
-      }
-      
-    }
-
-  };
-  
-  return ret;
-};
-
-/* breaks a string in words and searches each of these words. Returns an array
-   of objects with the id of the annotation and its number of occurences.
-   
-   FIXME: optimize ? seems to be n^2 in the worst case.
-*/
-IriSP.JSONSerializer.prototype.searchTweetsOccurences = function(searchString) {
-  var ret = { };
-  var keywords = searchString.split(/\s+/);
-  
-  for (var i in keywords) {
-    var keyword = keywords[i];
-    
-    // search this keyword in descriptions and title
-    var found_annotations = []
-    found_annotations = found_annotations.concat(this.searchTweets(keyword, "", ""));
-    found_annotations = found_annotations.concat(this.searchTweets("", keyword, ""));
-    
-    for (var j in found_annotations) {
-      var current_annotation = found_annotations[j];
-      
-      if (!ret.hasOwnProperty(current_annotation.id)) {
-        ret[current_annotation.id] = 1;
-      } else {
-        ret[current_annotation.id] += 1;
-      }
-      
-    }
-
-  };
-  
-  return ret;
-};
-
-/* takes the currentTime and returns all the annotations that are displayable at the moment 
-   NB: only takes account the first type of annotations - ignores tweets 
-   currentTime is in seconds.
- */
-
-IriSP.JSONSerializer.prototype.currentAnnotations = function(currentTime) {
-  var view;
-  var currentTimeMs = 1000 * currentTime;
-
-  if (typeof(this._data.views) !== "undefined" && this._data.views !== null)
-     view = this._data.views[0];
-
-  var view_type = "";
-
-  if(typeof(view) !== "undefined" && typeof(view.annotation_types) !== "undefined" && view.annotation_types.length >= 1) {
-          view_type = view.annotation_types[0];
-  }
-
-  var ret_array = [];
-  
-  var i;
- 
-  for (i in this._data.annotations) {
-    var annotation = this._data.annotations[i];
-    
-    if (annotation.meta["id-ref"] === view_type && annotation.begin <= currentTimeMs && annotation.end >= currentTimeMs)
-      ret_array.push(annotation);
-  }
-
-  return ret_array;
-};
-
-
-/* this function returns a list of ids of tweet lines */
-IriSP.JSONSerializer.prototype.getTweetIds = function() {
-  if (typeof(this._data.lists) === "undefined" || this._data.lists === null)
-    return [];
-
-  var tweetsId = [];
-  
-  /* first get the list containing the tweets */
-  var tweets = IriSP.underscore.filter(this._data.lists, function(entry) { return entry.id.indexOf("tweet") !== -1 });
-  
-  // FIXME: collect tweets from multiple sources ?
-  tweetsId = IriSP.underscore.pluck(tweets[0].items, "id-ref");
-
-  return tweetsId;
-};
-
-/* this function returns a list of lines which are not tweet lines */
-IriSP.JSONSerializer.prototype.getNonTweetIds = function() {
-  if (typeof(this._data.lists) === "undefined" || this._data.lists === null)
-    return [];
-  
-  /* get all the ids */
-  var ids = IriSP.underscore.map(this._data.lists, function(entry) {                                                         
-                                                         return IriSP.underscore.pluck(entry.items, "id-ref"); });
-                                                         
-  var illegal_values = this.getTweetIds();
-  return IriSP.underscore.difference(ids, illegal_values);
-  
-};